Re: [net-next PATCH 5/6] net: pcs: airoha: add PCS driver for Airoha SoC
From: Christian Marangi
Date: Wed Mar 19 2025 - 05:14:44 EST
On Wed, Mar 19, 2025 at 12:58:41AM +0100, Christian Marangi wrote:
> Add PCS driver for Airoha SoC for Ethernet Serdes and PCS and permit
> usage of external PHY or connected SFP cage. Supported modes are
> USXGMII, 10-BASER, 2500BASE-X, 1000BASE-X and SGMII.
>
> The driver register as a PCS provider and supports poll mode to detect
> PCS port state. While interrupt is supported by the HW, there are some
> defect with the interrupt not fired on cable detach.
>
> The PCS require complex calibration to correctly work and might require
> multiple try until the signal detection module "lock" on the signal
> level to correct work with the attached PHY.
>
> Signed-off-by: Christian Marangi <ansuelsmth@xxxxxxxxx>
> ---
> drivers/net/pcs/Kconfig | 6 +
> drivers/net/pcs/Makefile | 1 +
> drivers/net/pcs/pcs-airoha.c | 2858 ++++++++++++++++++++++++++++++++
> include/linux/pcs/pcs-airoha.h | 11 +
> 4 files changed, 2876 insertions(+)
> create mode 100644 drivers/net/pcs/pcs-airoha.c
> create mode 100644 include/linux/pcs/pcs-airoha.h
>
> diff --git a/drivers/net/pcs/Kconfig b/drivers/net/pcs/Kconfig
> index 8c3b720de6fd..f0ad087286be 100644
> --- a/drivers/net/pcs/Kconfig
> +++ b/drivers/net/pcs/Kconfig
> @@ -12,6 +12,12 @@ config OF_PCS
> help
> OpenFirmware PCS accessors
>
> +config PCS_AIROHA
> + tristate "Airoha PCS driver"
> + help
> + This module provides helper to phylink for managing the Airoha
> + PCS for SoC Ethernet Serdes and PCS.
> +
In adding the final changes from staging, it was forgot to add
select OF_PCS to PCS_AIROHA. This will be fixed in v2.
(the cause of the compilation error)
> config PCS_XPCS
> tristate "Synopsys DesignWare Ethernet XPCS"
> select PHYLINK
> diff --git a/drivers/net/pcs/Makefile b/drivers/net/pcs/Makefile
> index 29881f0f981f..4ce759cd6ad9 100644
> --- a/drivers/net/pcs/Makefile
> +++ b/drivers/net/pcs/Makefile
> @@ -2,6 +2,7 @@
> # Makefile for Linux PCS drivers
>
> obj-$(CONFIG_OF_PCS) += pcs.o
> +obj-$(CONFIG_PCS_AIROHA) += pcs-airoha.o
> pcs_xpcs-$(CONFIG_PCS_XPCS) := pcs-xpcs.o pcs-xpcs-plat.o \
> pcs-xpcs-nxp.o pcs-xpcs-wx.o
>
> diff --git a/drivers/net/pcs/pcs-airoha.c b/drivers/net/pcs/pcs-airoha.c
> new file mode 100644
> index 000000000000..7f33d5c0799e
> --- /dev/null
> +++ b/drivers/net/pcs/pcs-airoha.c
> @@ -0,0 +1,2858 @@
> +// SPDX-License-Identifier: GPL-2.0
> +/*
> + * Copyright (c) 2024 AIROHA Inc
> + * Author: Christian Marangi <ansuelsmth@xxxxxxxxx>
> + */
> +
> +#include <linux/device.h>
> +#include <linux/mfd/syscon.h>
> +#include <linux/of.h>
> +#include <linux/of_platform.h>
> +#include <linux/pcs/pcs-airoha.h>
> +#include <linux/pcs/pcs-provider.h>
> +#include <linux/phylink.h>
> +#include <linux/platform_device.h>
> +#include <linux/regmap.h>
> +#include <linux/reset.h>
> +
> +/* SCU*/
> +#define AIROHA_SCU_WAN_CONF 0x70
> +#define AIROHA_SCU_WAN_SEL GENMASK(7, 0)
> +#define AIROHA_SCU_WAN_SEL_SGMII FIELD_PREP_CONST(AIROHA_SCU_WAN_SEL, 0x10)
> +#define AIROHA_SCU_WAN_SEL_HSGMII FIELD_PREP_CONST(AIROHA_SCU_WAN_SEL, 0x11)
> +#define AIROHA_SCU_WAN_SEL_USXGMII FIELD_PREP_CONST(AIROHA_SCU_WAN_SEL, 0x12)
> +#define AIROHA_SCU_SSR3 0x94
> +#define AIROHA_SCU_ETH_XSI_SEL GENMASK(14, 13)
> +#define AIROHA_SCU_ETH_XSI_USXGMII FIELD_PREP_CONST(AIROHA_SCU_ETH_XSI_SEL, 0x1)
> +#define AIROHA_SCU_ETH_XSI_HSGMII FIELD_PREP_CONST(AIROHA_SCU_ETH_XSI_SEL, 0x2)
> +#define AIROHA_SCU_SSTR 0x9c
> +#define AIROHA_SCU_PON_XSI_SEL GENMASK(10, 9)
> +#define AIROHA_SCU_PON_XSI_USXGMII FIELD_PREP_CONST(AIROHA_SCU_PON_XSI_SEL, 0x1)
> +#define AIROHA_SCU_PON_XSI_HSGMII FIELD_PREP_CONST(AIROHA_SCU_PON_XSI_SEL, 0x2)
> +
> +/* HSGMII_AN */
> +#define AIROHA_PCS_HSGMII_AN_SGMII_REG_AN_0 0x0
> +#define AIROHA_PCS_HSGMII_AN_SGMII_RA_ENABLE BIT(12)
> +#define AIROHA_PCS_HSGMII_AN_SGMII_AN_RESTART BIT(9)
> +#define AIROHA_PCS_HSGMII_AN_SGMII_REG_AN_1 0x4 /* BMSR */
> +#define AIROHA_PCS_HSGMII_AN_SGMII_UNIDIR_ABILITY BIT(6)
> +#define AIROHA_PCS_HSGMII_AN_SGMII_AN_COMPLETE BIT(5)
> +#define AIROHA_PCS_HSGMII_AN_SGMII_REMOTE_FAULT BIT(4)
> +#define AIROHA_PCS_HSGMII_AN_SGMII_AN_ABILITY BIT(3)
> +#define AIROHA_PCS_HSGMII_AN_SGMII_LINK_STATUS BIT(2)
> +#define AIROHA_PCS_HSGMII_AN_SGMII_REG_AN_4 0x10
> +#define AIROHA_PCS_HSGMII_AN_SGMII_DEV_ABILITY GENMASK(15, 0)
> +#define AIROHA_PCS_HSGMII_AN_SGMII_REG_AN_5 0x14 /* LPA */
> +#define AIROHA_PCS_HSGMII_AN_SGMII_PARTNER_ABILITY GENMASK(15, 0)
> +#define AIROHA_PCS_HSGMII_AN_SGMII_REG_AN_11 0x2c
> +#define AIROHA_PCS_HSGMII_AN_SGMII_LINK_TIMER GENMASK(19, 0)
> +#define AIROHA_PCS_HSGMII_AN_SGMII_REG_AN_13 0x34
> +#define AIROHA_PCS_HSGMII_AN_SGMII_REMOTE_FAULT_DIS BIT(8)
> +#define AIROHA_PCS_HSGMII_AN_SGMII_IF_MODE_5_0 GENMASK(5, 0)
> +#define AIROHA_PCS_HSGMII_AN_SGMII_COMPAT_EN BIT(5)
> +#define AIROHA_PCS_HSGMII_AN_DUPLEX_FORCE_MODE BIT(4)
> +#define AIROHA_PCS_HSGMII_AN_SPEED_FORCE_MODE GENMASK(3, 2)
> +#define AIROHA_PCS_HSGMII_AN_SPEED_FORCE_MODE_1000 FIELD_PREP_CONST(AIROHA_PCS_HSGMII_AN_SPEED_FORCE_MODE, 0x2)
> +#define AIROHA_PCS_HSGMII_AN_SPEED_FORCE_MODE_100 FIELD_PREP_CONST(AIROHA_PCS_HSGMII_AN_SPEED_FORCE_MODE, 0x1)
> +#define AIROHA_PCS_HSGMII_AN_SPEED_FORCE_MODE_10 FIELD_PREP_CONST(AIROHA_PCS_HSGMII_AN_SPEED_FORCE_MODE, 0x0)
> +#define AIROHA_PCS_HSGMII_AN_SIDEBAND_EN BIT(1)
> +#define AIROHA_PCS_HSGMII_AN_SGMII_EN BIT(0)
> +#define AIROHA_PCS_HSGMII_AN_SGMII_REG_AN_FORCE_CL37 0x60
> +#define AIROHA_PCS_HSGMII_AN_FORCE_AN_DONE BIT(0)
> +
> +/* HSGMII_PCS */
> +#define AIROHA_PCS_HSGMII_PCS_CTROL_1 0x0
> +#define AIROHA_PCS_TBI_10B_MODE BIT(30)
> +#define AIROHA_PCS_SGMII_SEND_AN_ERR_EN BIT(24)
> +#define AIROHA_PCS_REMOTE_FAULT_DIS BIT(12)
> +#define AIROHA_PCS_HSGMII_PCS_CTROL_3 0x8
> +#define AIROHA_PCS_HSGMII_PCS_LINK_STSTIME GENMASK(19, 0)
> +#define AIROHA_PCS_HSGMII_PCS_CTROL_6 0x14
> +#define AIROHA_PCS_HSGMII_PCS_SGMII_SPD_FORCE_10 BIT(14)
> +#define AIROHA_PCS_HSGMII_PCS_SGMII_SPD_FORCE_100 BIT(13)
> +#define AIROHA_PCS_HSGMII_PCS_SGMII_SPD_FORCE_1000 BIT(12)
> +#define AIROHA_PCS_HSGMII_PCS_MAC_MODE BIT(8)
> +#define AIROHA_PCS_HSGMII_PCS_TX_ENABLE BIT(4)
> +#define AIROHA_PCS_HSGMII_PCS_FORCE_RATEADAPT_VAL GENMASK(3, 2)
> +#define AIROHA_PCS_HSGMII_PCS_FORCE_RATEADAPT_VAL_1000 FIELD_PREP_CONST(AIROHA_PCS_HSGMII_PCS_FORCE_RATEADAPT_VAL, 0x0)
> +#define AIROHA_PCS_HSGMII_PCS_FORCE_RATEADAPT_VAL_100 FIELD_PREP_CONST(AIROHA_PCS_HSGMII_PCS_FORCE_RATEADAPT_VAL, 0x1)
> +#define AIROHA_PCS_HSGMII_PCS_FORCE_RATEADAPT_VAL_10 FIELD_PREP_CONST(AIROHA_PCS_HSGMII_PCS_FORCE_RATEADAPT_VAL, 0x2)
> +#define AIROHA_PCS_HSGMII_PCS_FORCE_RATEADAPT BIT(1)
> +#define AIROHA_PCS_HSGMII_PCS_MODE2_EN BIT(0)
> +#define AIROHA_PCS_HSGMII_PCS_HSGMII_MODE_INTERRUPT 0x20
> +#define AIROHA_PCS_HSGMII_MODE2_REMOVE_FAULT_OCCUR_INT_CLEAR BIT(11)
> +#define AIROHA_PCS_HSGMII_MODE2_REMOVE_FAULT_OCCUR_INT BIT(10)
> +#define AIROHA_PCS_HSGMII_MODE2_AN_CL37_TIMERDONE_INT_CLEAR BIT(9)
> +#define AIROHA_PCS_HSGMII_MODE2_AN_CL37_TIMERDONE_INT BIT(8)
> +#define AIROHA_PCS_HSGMII_MODE2_AN_MIS_INT_CLEAR BIT(5)
> +#define AIROHA_PCS_HSGMII_MODE2_AN_MIS_INT BIT(4)
> +#define AIROHA_PCS_HSGMII_MODE2_RX_SYN_DONE_INT_CLEAR BIT(3)
> +#define AIROHA_PCS_HSGMII_MODE2_AN_DONE_INT_CLEAR BIT(2)
> +#define AIROHA_PCS_HSGMII_MODE2_RX_SYN_DONE_INT BIT(1)
> +#define AIROHA_PCS_HSGMII_MODE2_AN_DONE_INT BIT(0)
> +#define AIROHA_PCS_HSGMII_PCS_AN_SGMII_MODE_FORCE 0x24
> +#define AIROHA_PCS_HSGMII_PCS_FORCE_CUR_SGMII_MODE GENMASK(5, 4)
> +#define AIROHA_PCS_HSGMII_PCS_FORCE_CUR_SGMII_MODE_1000 FIELD_PREP_CONST(AIROHA_PCS_HSGMII_PCS_FORCE_CUR_SGMII_MODE, 0x0)
> +#define AIROHA_PCS_HSGMII_PCS_FORCE_CUR_SGMII_MODE_100 FIELD_PREP_CONST(AIROHA_PCS_HSGMII_PCS_FORCE_CUR_SGMII_MODE, 0x1)
> +#define AIROHA_PCS_HSGMII_PCS_FORCE_CUR_SGMII_MODE_10 FIELD_PREP_CONST(AIROHA_PCS_HSGMII_PCS_FORCE_CUR_SGMII_MODE, 0x2)
> +#define AIROHA_PCS_HSGMII_PCS_FORCE_CUR_SGMII_MODE_SEL BIT(0)
> +#define ARIOHA_PCS_HSGMII_PCS_STATE_2 0x104
> +#define AIROHA_PCS_HSGMII_PCS_RX_SYNC BIT(5)
> +#define AIROHA_PCS_HSGMII_PCS_AN_DONE BIT(0)
> +#define AIROHA_PCS_HSGMII_PCS_INT_STATE 0x15c
> +#define AIROHA_PCS_HSGMII_PCS_MODE2_REMOTE_FAULT_OCCUR_INT BIT(4)
> +#define AIROHA_PCS_HSGMII_PCS_MODE2_AN_MLS BIT(3)
> +#define AIROHA_PCS_HSGMII_PCS_MODE2_AN_CL37_TIMERDONE_INT BIT(2)
> +#define AIROHA_PCS_HSGMII_PCS_MODE2_RX_SYNC BIT(1)
> +#define AIROHA_PCS_HSGMII_PCS_MODE2_AN_DONE BIT(0)
> +
> +/* MULTI_SGMII */
> +#define AIROHA_PCS_MULTI_SGMII_INTERRUPT_EN_0 0x14
> +#define AIROHA_PCS_MULTI_SGMII_PCS_INT_EN_0 BIT(0)
> +#define AIROHA_PCS_MULTI_SGMII_SGMII_STS_CTRL_0 0x18
> +#define AIROHA_PCS_LINK_MODE_P0 GENMASK(5, 4)
> +#define AIROHA_PCS_LINK_MODE_P0_2_5G FIELD_PREP_CONST(AIROHA_PCS_LINK_MODE_P0, 0x3)
> +#define AIROHA_PCS_LINK_MODE_P0_1G FIELD_PREP_CONST(AIROHA_PCS_LINK_MODE_P0, 0x2)
> +#define AIROHA_PCS_LINK_MODE_P0_100M FIELD_PREP_CONST(AIROHA_PCS_LINK_MODE_P0, 0x1)
> +#define AIROHA_PCS_LINK_MODE_P0_10M FIELD_PREP_CONST(AIROHA_PCS_LINK_MODE_P0, 0x0)
> +#define AIROHA_PCS_FORCE_SPD_MODE_P0 BIT(2)
> +#define AIROHA_PCS_FORCE_LINKDOWN_P0 BIT(1)
> +#define AIROHA_PCS_FORCE_LINKUP_P0 BIT(0)
> +#define AIROHA_PCS_MULTI_SGMII_MSG_RX_CTRL_0 0x100
> +#define AIROHA_PCS_HSGMII_XFI_SEL BIT(28)
> +#define AIROHA_PCS_MULTI_SGMII_INTERRUPT_SEL 0x14c
> +#define AIROHA_PCS_HSGMII_PCS_INT BIT(0)
> +#define AIROHA_PCS_MULTI_SGMII_MSG_RX_STS_15 0x43c
> +#define AIROHA_PCS_LINK_STS_P0 BIT(3)
> +#define AIROHA_PCS_SPEED_STS_P0 GENMASK(2, 0)
> +#define AIROHA_PCS_SPEED_STS_P0_1G FIELD_PREP_CONST(AIROHA_PCS_SPEED_STS_P0, 0x2)
> +#define AIROHA_PCS_SPEED_STS_P0_100M FIELD_PREP_CONST(AIROHA_PCS_SPEED_STS_P0, 0x1)
> +#define AIROHA_PCS_SPEED_STS_P0_10M FIELD_PREP_CONST(AIROHA_PCS_SPEED_STS_P0, 0x0)
> +#define AIROHA_PCS_MULTI_SGMII_MSG_RX_STS_18 0x448
> +#define AIROHA_PCS_P0_SGMII_IS_10 BIT(2)
> +#define AIROHA_PCS_P0_SGMII_IS_100 BIT(1)
> +#define AIROHA_PCS_P0_SGMII_IS_1000 BIT(0)
> +
> +/* HSGMII_RATE_ADP */
> +#define AIROHA_PCS_HSGMII_RATE_ADAPT_CTRL_0 0x0
> +#define AIROHA_PCS_HSGMII_RATE_ADAPT_RX_BYPASS BIT(27)
> +#define AIROHA_PCS_HSGMII_RATE_ADAPT_TX_BYPASS BIT(26)
> +#define AIROHA_PCS_HSGMII_RATE_ADAPT_RX_EN BIT(4)
> +#define AIROHA_PCS_HSGMII_RATE_ADAPT_TX_EN BIT(0)
> +#define AIROHA_PCS_HSGMII_RATE_ADAPT_CTRL_1 0x4
> +#define AIROHA_PCS_HSGMII_RATE_ADAPT_RX_AFIFO_WR_THR GENMASK(20, 16)
> +#define AIROHA_PCS_HSGMII_RATE_ADAPT_RX_AFIFO_RD_THR GENMASK(28, 24)
> +#define AIROHA_PCS_HSGMII_RATE_ADAPT_CTRL_6 0x18
> +#define AIROHA_PCS_HSGMII_RATE_ADAPT_RX_AFIFO_DOUT_L GENMASK(31, 0)
> +#define AIROHA_PCS_HSGMII_RATE_ADAPT_CTRL_8 0x20
> +#define AIROHA_PCS_HSGMII_RATE_ADAPT_RX_AFIFO_DOUT_C GENMASK(7, 0)
> +#define AIROHA_PCS_HSGMII_RATE_ADAPT_CTRL_11 0x2c
> +#define AIROHA_PCS_HSGMII_RATE_ADPT_FORCE_RATE_ADAPT_MODE_EN BIT(8)
> +#define AIROHA_PCS_HSGMII_RATE_ADPT_FORCE_RATE_ADAPT_MODE GENMASK(15, 12)
> +#define AIROHA_PCS_HSGMII_RATE_ADPT_FORCE_RATE_ADAPT_MODE_10000 \
> + FIELD_PREP_CONST(AIROHA_PCS_HSGMII_RATE_ADPT_FORCE_RATE_ADAPT_MODE, 0x0)
> +#define AIROHA_PCS_HSGMII_RATE_ADPT_FORCE_RATE_ADAPT_MODE_5000 \
> + FIELD_PREP_CONST(AIROHA_PCS_HSGMII_RATE_ADPT_FORCE_RATE_ADAPT_MODE, 0x1)
> +#define AIROHA_PCS_HSGMII_RATE_ADPT_FORCE_RATE_ADAPT_MODE_2500 \
> + FIELD_PREP_CONST(AIROHA_PCS_HSGMII_RATE_ADPT_FORCE_RATE_ADAPT_MODE, 0x2)
> +#define AIROHA_PCS_HSGMII_RATE_ADPT_FORCE_RATE_ADAPT_MODE_1000 \
> + FIELD_PREP_CONST(AIROHA_PCS_HSGMII_RATE_ADPT_FORCE_RATE_ADAPT_MODE, 0x4)
> +#define AIROHA_PCS_HSGMII_RATE_ADPT_FORCE_RATE_ADAPT_MODE_100 \
> + FIELD_PREP_CONST(AIROHA_PCS_HSGMII_RATE_ADPT_FORCE_RATE_ADAPT_MODE, 0x6)
> +#define AIROHA_PCS_HSGMII_RATE_ADP_P0_CTRL_0 0x100
> +#define AIROHA_PCS_HSGMII_P0_DIS_MII_MODE BIT(31)
> +
> +/* USXGMII */
> +#define AIROHA_PCS_USXGMII_PCS_CTROL_1 0x0
> +#define AIROHA_PCS_USXGMII_SPEED_SEL_H BIT(13)
> +#define AIROHA_PCS_USXGMII_PCS_STUS_1 0x30
> +#define AIROHA_PCS_USXGMII_RX_LINK_STUS BIT(12)
> +#define AIROHA_PCS_USXGMII_PRBS9_PATT_TST_ABILITY BIT(3)
> +#define AIROHA_PCS_USXGMII_PRBS31_PATT_TST_ABILITY BIT(2)
> +#define AIROHA_PCS_USXGMII_PCS_BLK_LK BIT(0)
> +#define AIROHA_PCS_USGMII_VENDOR_DEFINE_116 0x22c
> +#define AIROHA_PCS_USXGMII_PCS_CTRL_0 0x2c0
> +#define AIROHA_PCS_USXGMII_T_TYPE_T_INT_EN BIT(24)
> +#define AIROHA_PCS_USXGMII_T_TYPE_D_INT_EN BIT(16)
> +#define AIROHA_PCS_USXGMII_T_TYPE_C_INT_EN BIT(8)
> +#define AIROHA_PCS_USXGMII_T_TYPE_S_INT_EN BIT(0)
> +#define AIROHA_PCS_USXGMII_PCS_CTRL_1 0x2c4
> +#define AIROHA_PCS_USXGMII_R_TYPE_C_INT_EN BIT(24)
> +#define AIROHA_PCS_USXGMII_R_TYPE_S_INT_EN BIT(16)
> +#define AIROHA_PCS_USXGMII_TXPCS_FSM_ENC_ERR_INT_EN BIT(8)
> +#define AIROHA_PCS_USXGMII_T_TYPE_E_INT_EN BIT(0)
> +#define AIROHA_PCS_USXGMII_PCS_CTRL_2 0x2c8
> +#define AIROHA_PCS_USXGMII_RPCS_FSM_DEC_ERR_INT_EN BIT(24)
> +#define AIROHA_PCS_USXGMII_R_TYPE_E_INT_EN BIT(16)
> +#define AIROHA_PCS_USXGMII_R_TYPE_T_INT_EN BIT(8)
> +#define AIROHA_PCS_USXGMII_R_TYPE_D_INT_EN BIT(0)
> +#define AIROHA_PCS_USXGMII_PCS_CTRL_3 0x2cc
> +#define AIROHA_PCS_USXGMII_FAIL_SYNC_XOR_ST_INT_EN BIT(24)
> +#define AIROHA_PCS_USXGMII_RX_BLOCK_LOCK_ST_INT_EN BIT(16)
> +#define AIROHA_PCS_USXGMII_LINK_UP_ST_INT_EN BIT(8)
> +#define AIROHA_PCS_USXGMII_HI_BER_ST_INT_EN BIT(0)
> +#define AIROHA_PCS_USXGMII_PCS_INT_STA_2 0x2d8
> +#define AIROHA_PCS_USXGMII_RPCS_FSM_DEC_ERR_INT BIT(24)
> +#define AIROHA_PCS_USXGMII_R_TYPE_E_INT BIT(16)
> +#define AIROHA_PCS_USXGMII_R_TYPE_T_INT BIT(8)
> +#define AIROHA_PCS_USXGMII_R_TYPE_D_INT BIT(0)
> +#define AIROHA_PCS_USXGMII_PCS_INT_STA_3 0x2dc
> +#define AIROHA_PCS_USXGMII_FAIL_SYNC_XOR_ST_INT BIT(24)
> +#define AIROHA_PCS_USXGMII_RX_BLOCK_LOCK_ST_INT BIT(16)
> +#define AIROHA_PCS_USXGMII_LINK_UP_ST_INT BIT(8)
> +#define AIROHA_PCS_USXGMII_HI_BER_ST_INT BIT(0)
> +#define AIROHA_PCS_USXGMII_PCS_CTRL_4 0x2e0
> +#define AIROHA_PCS_USXGMII_LINK_DOWN_ST_INT_EN BIT(0)
> +#define AIROHA_PCS_USXGMII_PCS_INT_STA_4 0x2e4
> +#define AIROHA_PCS_USXGMII_LINK_DOWN_ST_INT BIT(0)
> +#define AIROHA_PCS_USXGMII_PCS_AN_CONTROL_0 0x2f8
> +#define AIROHA_PCS_USXGMII_AN_RESTART BIT(8)
> +#define AIROHA_PCS_USXGMII_AN_ENABLE BIT(0)
> +#define AIROHA_PCS_USXGMII_PCS_AN_STATS_0 0x310
> +#define AIROHA_PCS_USXGMII_CUR_USXGMII_MODE GENMASK(30, 28)
> +#define AIROHA_PCS_USXGMII_CUR_USXGMII_MODE_10G FIELD_PREP_CONST(AIROHA_PCS_USXGMII_CUR_USXGMII_MODE, 0x0)
> +#define AIROHA_PCS_USXGMII_CUR_USXGMII_MODE_5G FIELD_PREP_CONST(AIROHA_PCS_USXGMII_CUR_USXGMII_MODE, 0x1)
> +#define AIROHA_PCS_USXGMII_CUR_USXGMII_MODE_2_5G FIELD_PREP_CONST(AIROHA_PCS_USXGMII_CUR_USXGMII_MODE, 0x2)
> +#define AIROHA_PCS_USXGMII_CUR_USXGMII_MODE_1G FIELD_PREP_CONST(AIROHA_PCS_USXGMII_CUR_USXGMII_MODE, 0x3)
> +#define AIROHA_PCS_USXGMII_CUR_USXGMII_MODE_100M FIELD_PREP_CONST(AIROHA_PCS_USXGMII_CUR_USXGMII_MODE, 0x4)
> +#define AIROHA_PCS_USXGMII_PARTNER_ABILITY GENMASK(15, 0)
> +#define AIROHA_PCS_USXGMII_PCS_AN_STATS_2 0x318
> +#define AIROHA_PCS_USXGMII_PCS_AN_COMPLETE BIT(24)
> +#define AIROHA_PCS_USXGMII_PCS_AN_CONTROL_6 0x31c
> +#define AIROHA_PCS_USXGMII_TOG_PCS_AUTONEG_STS BIT(0)
> +#define AIROHA_PCS_USXGMII_PCS_AN_CONTROL_7 0x320
> +#define AIROHA_PCS_USXGMII_RATE_UPDATE_MODE BIT(12)
> +#define AIROHA_PCS_USXGMII_MODE GENMASK(10, 8)
> +#define AIROHA_PCS_USXGMII_MODE_10000 FIELD_PREP(AIROHA_PCS_USXGMII_MODE, 0x0)
> +#define AIROHA_PCS_USXGMII_MODE_5000 FIELD_PREP(AIROHA_PCS_USXGMII_MODE, 0x1)
> +#define AIROHA_PCS_USXGMII_MODE_2500 FIELD_PREP(AIROHA_PCS_USXGMII_MODE, 0x2)
> +#define AIROHA_PCS_USXGMII_MODE_1000 FIELD_PREP(AIROHA_PCS_USXGMII_MODE, 0x3)
> +#define AIROHA_PCS_USXGMII_MODE_100 FIELD_PREP(AIROHA_PCS_USXGMII_MODE, 0x4)
> +
> +/* PMA_PHYA */
> +#define AIROHA_PCS_ANA_PXP_CMN_EN 0x0
> +#define AIROHA_PCS_ANA_CMN_EN BIT(0)
> +#define AIROHA_PCS_ANA_PXP_JCPLL_IB_EXT_EN 0x4
> +#define AIROHA_PCS_ANA_JCPLL_CHP_IOFST GENMASK(29, 24)
> +#define AIROHA_PCS_ANA_JCPLL_CHP_IBIAS GENMASK(21, 16)
> +#define AIROHA_PCS_ANA_JCPLL_LPF_SHCK_EN BIT(8)
> +#define AIROHA_PCS_ANA_PXP_JCPLL_LPF_BR 0x8
> +#define AIROHA_PCS_ANA_JCPLL_LPF_BWR GENMASK(28, 24)
> +#define AIROHA_PCS_ANA_JCPLL_LPF_BP GENMASK(20, 16)
> +#define AIROHA_PCS_ANA_JCPLL_LPF_BC GENMASK(12, 8)
> +#define AIROHA_PCS_ANA_JCPLL_LPF_BR GENMASK(4, 0)
> +#define AIROHA_PCS_ANA_PXP_JCPLL_LPF_BWC 0xc
> +#define AIROHA_PCS_ANA_JCPLL_KBAND_DIV GENMASK(26, 24)
> +#define AIROHA_PCS_ANA_JCPLL_KBAND_CODE GENMASK(23, 16)
> +#define AIROHA_PCS_ANA_JCPLL_KBAND_OPTION BIT(8)
> +#define AIROHA_PCS_ANA_JCPLL_LPF_BWC GENMASK(4, 0)
> +#define AIROHA_PCS_ANA_PXP_JCPLL_KBAND_KFC 0x10
> +#define AIROHA_PCS_ANA_JCPLL_KBAND_KS GENMASK(17, 16)
> +#define AIROHA_PCS_ANA_JCPLL_KBAND_KF GENMASK(9, 8)
> +#define AIROHA_PCS_ANA_JCPLL_KBAND_KFC GENMASK(1, 0)
> +#define AIROHA_PCS_ANA_PXP_JCPLL_MMD_PREDIV_MODE 0x14
> +#define AIROHA_PCS_ANA_JCPLL_POSTDIV_D5 BIT(24)
> +#define AIROHA_PCS_ANA_JCPLL_MMD_PREDIV_MODE GENMASK(1, 0)
> +#define AIROHA_PCS_ANA_JCPLL_MMD_PREDIV_MODE_2 FIELD_PREP_CONST(AIROHA_PCS_ANA_JCPLL_MMD_PREDIV_MODE, 0x0)
> +#define AIROHA_PCS_ANA_JCPLL_MMD_PREDIV_MODE_3 FIELD_PREP_CONST(AIROHA_PCS_ANA_JCPLL_MMD_PREDIV_MODE, 0x1)
> +#define AIROHA_PCS_ANA_JCPLL_MMD_PREDIV_MODE_4 FIELD_PREP_CONST(AIROHA_PCS_ANA_JCPLL_MMD_PREDIV_MODE, 0x2)
> +#define AIROHA_PCS_ANA_JCPLL_MMD_PREDIV_MODE_1 FIELD_PREP_CONST(AIROHA_PCS_ANA_JCPLL_MMD_PREDIV_MODE, 0x3)
> +#define AIROHA_PCS_ANA_PXP_JCPLL_RST_DLY 0x1c
> +#define AIROHA_PCS_ANA_JCPLL_SDM_DI_LS GENMASK(25, 24)
> +#define AIROHA_PCS_ANA_JCPLL_SDM_DI_LS_2_23 FIELD_PREP_CONST(AIROHA_PCS_ANA_JCPLL_SDM_DI_LS, 0x0)
> +#define AIROHA_PCS_ANA_JCPLL_SDM_DI_LS_2_21 FIELD_PREP_CONST(AIROHA_PCS_ANA_JCPLL_SDM_DI_LS, 0x1)
> +#define AIROHA_PCS_ANA_JCPLL_SDM_DI_LS_2_19 FIELD_PREP_CONST(AIROHA_PCS_ANA_JCPLL_SDM_DI_LS, 0x2)
> +#define AIROHA_PCS_ANA_JCPLL_SDM_DI_LS_2_15 FIELD_PREP_CONST(AIROHA_PCS_ANA_JCPLL_SDM_DI_LS, 0x3)
> +#define AIROHA_PCS_ANA_JCPLL_SDM_DI_EN BIT(16)
> +#define AIROHA_PCS_ANA_JCPLL_PLL_RSTB BIT(8)
> +#define AIROHA_PCS_ANA_JCPLL_RST_DLY GENMASK(2, 0)
> +#define AIROHA_PCS_ANA_JCPLL_RST_DLY_20_25 FIELD_PREP_CONST(AIROHA_PCS_ANA_JCPLL_RST_DLY, 0x1)
> +#define AIROHA_PCS_ANA_JCPLL_RST_DLY_40_50 FIELD_PREP_CONST(AIROHA_PCS_ANA_JCPLL_RST_DLY, 0x2)
> +#define AIROHA_PCS_ANA_JCPLL_RST_DLY_80_100 FIELD_PREP_CONST(AIROHA_PCS_ANA_JCPLL_RST_DLY, 0x3)
> +#define AIROHA_PCS_ANA_JCPLL_RST_DLY_150_200 FIELD_PREP_CONST(AIROHA_PCS_ANA_JCPLL_RST_DLY, 0x4)
> +#define AIROHA_PCS_ANA_JCPLL_RST_DLY_300_400 FIELD_PREP_CONST(AIROHA_PCS_ANA_JCPLL_RST_DLY, 0x5)
> +#define AIROHA_PCS_ANA_JCPLL_RST_DLY_600_800 FIELD_PREP_CONST(AIROHA_PCS_ANA_JCPLL_RST_DLY, 0x6)
> +#define AIROHA_PCS_ANA_PXP_JCPLL_SDM_IFM 0x20
> +#define AIROHA_PCS_ANA_JCPLL_SDM_OUT BIT(24)
> +#define AIROHA_PCS_ANA_JCPLL_SDM_ORD GENMASK(17, 16)
> +#define AIROHA_PCS_ANA_JCPLL_SDM_ORD_INT FIELD_PREP_CONST(AIROHA_PCS_ANA_JCPLL_SDM_ORD, 0x0)
> +#define AIROHA_PCS_ANA_JCPLL_SDM_ORD_1SDM FIELD_PREP_CONST(AIROHA_PCS_ANA_JCPLL_SDM_ORD, 0x1)
> +#define AIROHA_PCS_ANA_JCPLL_SDM_ORD_2SDM FIELD_PREP_CONST(AIROHA_PCS_ANA_JCPLL_SDM_ORD, 0x2)
> +#define AIROHA_PCS_ANA_JCPLL_SDM_ORD_3SDM FIELD_PREP_CONST(AIROHA_PCS_ANA_JCPLL_SDM_ORD, 0x3)
> +#define AIROHA_PCS_ANA_JCPLL_SDM_MODE GENMASK(9, 8)
> +#define AIROHA_PCS_ANA_JCPLL_SDM_IFM BIT(0)
> +#define AIROHA_PCS_ANA_PXP_JCPLL_SDM_HREN 0x24
> +#define AIROHA_PCS_ANA_JCPLL_TCL_AMP_VREF GENMASK(28, 24)
> +#define AIROHA_PCS_ANA_JCPLL_TCL_AMP_GAIN GENMASK(18, 16)
> +#define AIROHA_PCS_ANA_JCPLL_TCL_AMP_GAIN_2 FIELD_PREP_CONST(AIROHA_PCS_ANA_JCPLL_TCL_AMP_GAIN, 0x0)
> +#define AIROHA_PCS_ANA_JCPLL_TCL_AMP_GAIN_4 FIELD_PREP_CONST(AIROHA_PCS_ANA_JCPLL_TCL_AMP_GAIN, 0x1)
> +#define AIROHA_PCS_ANA_JCPLL_TCL_AMP_GAIN_6 FIELD_PREP_CONST(AIROHA_PCS_ANA_JCPLL_TCL_AMP_GAIN, 0x2)
> +#define AIROHA_PCS_ANA_JCPLL_TCL_AMP_GAIN_8 FIELD_PREP_CONST(AIROHA_PCS_ANA_JCPLL_TCL_AMP_GAIN, 0x3)
> +#define AIROHA_PCS_ANA_JCPLL_TCL_AMP_GAIN_10 FIELD_PREP_CONST(AIROHA_PCS_ANA_JCPLL_TCL_AMP_GAIN, 0x4)
> +#define AIROHA_PCS_ANA_JCPLL_TCL_AMP_EN BIT(8)
> +#define AIROHA_PCS_ANA_JCPLL_SDM_HREN BIT(0)
> +#define AIROHA_PCS_ANA_PXP_JCPLL_TCL_CMP_EN 0x28
> +#define AIROHA_PCS_ANA_JCPLL_TCL_LPF_BW GENMASK(26, 24)
> +#define AIROHA_PCS_ANA_JCPLL_TCL_LPF_BW_0_5 FIELD_PREP_CONST(AIROHA_PCS_ANA_JCPLL_TCL_LPF_BW, 0x0)
> +#define AIROHA_PCS_ANA_JCPLL_TCL_LPF_BW_1 FIELD_PREP_CONST(AIROHA_PCS_ANA_JCPLL_TCL_LPF_BW, 0x1)
> +#define AIROHA_PCS_ANA_JCPLL_TCL_LPF_BW_2 FIELD_PREP_CONST(AIROHA_PCS_ANA_JCPLL_TCL_LPF_BW, 0x2)
> +#define AIROHA_PCS_ANA_JCPLL_TCL_LPF_BW_4 FIELD_PREP_CONST(AIROHA_PCS_ANA_JCPLL_TCL_LPF_BW, 0x3)
> +#define AIROHA_PCS_ANA_JCPLL_TCL_LPF_BW_8 FIELD_PREP_CONST(AIROHA_PCS_ANA_JCPLL_TCL_LPF_BW, 0x4)
> +#define AIROHA_PCS_ANA_JCPLL_TCL_LPF_BW_16 FIELD_PREP_CONST(AIROHA_PCS_ANA_JCPLL_TCL_LPF_BW, 0x6)
> +#define AIROHA_PCS_ANA_JCPLL_TCL_LPF_EN BIT(16)
> +#define AIROHA_PCS_ANA_JCPLL_TCL_LPF_BW GENMASK(26, 24)
> +#define AIROHA_PCS_ANA_PXP_JCPLL_VCODIV 0x2c
> +#define AIROHA_PCS_ANA_JCPLL_VCO_SCAPWR GENMASK(26, 24)
> +#define AIROHA_PCS_ANA_JCPLL_VCO_HALFLSB_EN BIT(16)
> +#define AIROHA_PCS_ANA_JCPLL_VCO_CFIX GENMASK(9, 8)
> +#define AIROHA_PCS_ANA_JCPLL_VCODIV GENMASK(1, 0)
> +#define AIROHA_PCS_ANA_JCPLL_VCODIV_1 FIELD_PREP_CONST(AIROHA_PCS_ANA_JCPLL_VCODIV, 0x0)
> +#define AIROHA_PCS_ANA_JCPLL_VCODIV_2 FIELD_PREP_CONST(AIROHA_PCS_ANA_JCPLL_VCODIV, 0x1)
> +#define AIROHA_PCS_ANA_PXP_JCPLL_VCO_TCLVAR 0x30
> +#define AIROHA_PCS_ANA_JCPLL_SSC_PHASE_INI BIT(17)
> +#define AIROHA_PCS_ANA_JCPLL_SSC_EN BIT(16)
> +#define AIROHA_PCS_ANA_JCPLL_VCO_VCOVAR_BIAS_L GENMASK(10, 8)
> +#define AIROHA_PCS_ANA_JCPLL_VCO_VCOVAR_BIAS_H GENMASK(5, 3)
> +#define AIROHA_PCS_ANA_JCPLL_VCO_TCLVAR GENMASK(2, 0)
> +#define AIROHA_PCS_ANA_PXP_JCPLL_SSC_TRI_EN 0x34
> +#define AIROHA_PCS_ANA_JCPLL_SSC_DELTA1 GENMASK(23, 8)
> +#define AIROHA_PCS_ANA_JCPLL_SSC_TRI_EN BIT(0)
> +#define AIROHA_PCS_ANA_PXP_JCPLL_SSC_DELTA 0x38
> +#define AIROHA_PCS_ANA_JCPLL_SSC_PERIOD GENMASK(31, 16)
> +#define AIROHA_PCS_ANA_JCPLL_SSC_DELTA GENMASK(15, 0)
> +#define AIROHA_PCS_ANA_PXP_JCPLL_SPARE_H 0x48
> +#define AIROHA_PCS_ANA_JCPLL_TCL_KBAND_VREF GENMASK(20, 16)
> +#define AIROHA_PCS_ANA_JCPLL_SPARE_L GENMASK(15, 8)
> +#define AIROHA_PCS_ANA_JCPLL_SPARE_L_LDO FIELD_PREP_CONST(AIROHA_PCS_ANA_JCPLL_SPARE_L, BIT(5))
> +#define AIROHA_PCS_ANA_PXP_TXPLL_CHP_IBIAS 0x50
> +#define AIROHA_PCS_ANA_TXPLL_LPF_BC GENMASK(28, 24)
> +#define AIROHA_PCS_ANA_TXPLL_LPF_BR GENMASK(20, 16)
> +#define AIROHA_PCS_ANA_TXPLL_CHP_IOFST GENMASK(13, 8)
> +#define AIROHA_PCS_ANA_TXPLL_CHP_IBIAS GENMASK(5, 0)
> +#define AIROHA_PCS_ANA_PXP_TXPLL_LPF_BP 0x54
> +#define AIROHA_PCS_ANA_TXPLL_KBAND_OPTION BIT(24)
> +#define AIROHA_PCS_ANA_TXPLL_LPF_BWC GENMASK(20, 16)
> +#define AIROHA_PCS_ANA_TXPLL_LPF_BWR GENMASK(12, 8)
> +#define AIROHA_PCS_ANA_TXPLL_LPF_BP GENMASK(4, 0)
> +#define AIROHA_PCS_ANA_PXP_TXPLL_KBAND_CODE 0x58
> +#define AIROHA_PCS_ANA_TXPLL_KBAND_KF GENMASK(25, 24)
> +#define AIROHA_PCS_ANA_TXPLL_KBAND_KFC GENMASK(17, 16)
> +#define AIROHA_PCS_ANA_TXPLL_KBAND_DIV GENMASK(10, 8)
> +#define AIROHA_PCS_ANA_TXPLL_KBAND_CODE GENMASK(7, 0)
> +#define AIROHA_PCS_ANA_PXP_TXPLL_KBAND_KS 0x5c
> +#define AIROHA_PCS_ANA_TXPLL_MMD_PREDIV_MODE GENMASK(17, 16)
> +#define AIROHA_PCS_ANA_TXPLL_MMD_PREDIV_MODE_2 FIELD_PREP_CONST(AIROHA_PCS_ANA_TXPLL_MMD_PREDIV_MODE, 0x0)
> +#define AIROHA_PCS_ANA_TXPLL_MMD_PREDIV_MODE_3 FIELD_PREP_CONST(AIROHA_PCS_ANA_TXPLL_MMD_PREDIV_MODE, 0x1)
> +#define AIROHA_PCS_ANA_TXPLL_MMD_PREDIV_MODE_4 FIELD_PREP_CONST(AIROHA_PCS_ANA_TXPLL_MMD_PREDIV_MODE, 0x2)
> +#define AIROHA_PCS_ANA_TXPLL_MMD_PREDIV_MODE_1 FIELD_PREP_CONST(AIROHA_PCS_ANA_TXPLL_MMD_PREDIV_MODE, 0x3)
> +#define AIROHA_PCS_ANA_TXPLL_POSTDIV_EN BIT(8)
> +#define AIROHA_PCS_ANA_TXPLL_KBAND_KS GENMASK(1, 0)
> +#define AIROHA_PCS_ANA_PXP_TXPLL_REFIN_INTERNAL 0x64
> +#define AIROHA_PCS_ANA_TXPLL_PLL_RSTB BIT(24)
> +#define AIROHA_PCS_ANA_TXPLL_RST_DLY GENMASK(18, 16)
> +#define AIROHA_PCS_ANA_TXPLL_REFIN_DIV GENMASK(9, 8)
> +#define AIROHA_PCS_ANA_TXPLL_REFIN_DIV_1 FIELD_PREP_CONST(AIROHA_PCS_ANA_TXPLL_REFIN_DIV, 0x0)
> +#define AIROHA_PCS_ANA_TXPLL_REFIN_DIV_2 FIELD_PREP_CONST(AIROHA_PCS_ANA_TXPLL_REFIN_DIV, 0x1)
> +#define AIROHA_PCS_ANA_TXPLL_REFIN_DIV_3 FIELD_PREP_CONST(AIROHA_PCS_ANA_TXPLL_REFIN_DIV, 0x2)
> +#define AIROHA_PCS_ANA_TXPLL_REFIN_DIV_4 FIELD_PREP_CONST(AIROHA_PCS_ANA_TXPLL_REFIN_DIV, 0x3)
> +#define AIROHA_PCS_ANA_TXPLL_REFIN_INTERNAL BIT(0)
> +#define AIROHA_PCS_ANA_PXP_TXPLL_SDM_DI_EN 0x68
> +#define AIROHA_PCS_ANA_TXPLL_SDM_MODE GENMASK(25, 24)
> +#define AIROHA_PCS_ANA_TXPLL_SDM_IFM BIT(16)
> +#define AIROHA_PCS_ANA_TXPLL_SDM_DI_LS GENMASK(9, 8)
> +#define AIROHA_PCS_ANA_TXPLL_SDM_DI_LS_2_23 FIELD_PREP_CONST(AIROHA_PCS_ANA_TXPLL_SDM_DI_LS, 0x0)
> +#define AIROHA_PCS_ANA_TXPLL_SDM_DI_LS_2_21 FIELD_PREP_CONST(AIROHA_PCS_ANA_TXPLL_SDM_DI_LS, 0x1)
> +#define AIROHA_PCS_ANA_TXPLL_SDM_DI_LS_2_19 FIELD_PREP_CONST(AIROHA_PCS_ANA_TXPLL_SDM_DI_LS, 0x2)
> +#define AIROHA_PCS_ANA_TXPLL_SDM_DI_LS_2_15 FIELD_PREP_CONST(AIROHA_PCS_ANA_TXPLL_SDM_DI_LS, 0x3)
> +#define AIROHA_PCS_ANA_TXPLL_SDM_DI_EN BIT(0)
> +#define AIROHA_PCS_ANA_PXP_TXPLL_SDM_ORD 0x6c
> +#define AIROHA_PCS_ANA_TXPLL_TCL_AMP_EN BIT(24)
> +#define AIROHA_PCS_ANA_TXPLL_SDM_HREN BIT(16)
> +#define AIROHA_PCS_ANA_TXPLL_SDM_OUT BIT(8)
> +#define AIROHA_PCS_ANA_TXPLL_SDM_ORD GENMASK(1, 0)
> +#define AIROHA_PCS_ANA_TXPLL_SDM_ORD_INT FIELD_PREP_CONST(AIROHA_PCS_ANA_TXPLL_SDM_ORD, 0x0)
> +#define AIROHA_PCS_ANA_TXPLL_SDM_ORD_1SDM FIELD_PREP_CONST(AIROHA_PCS_ANA_TXPLL_SDM_ORD, 0x1)
> +#define AIROHA_PCS_ANA_TXPLL_SDM_ORD_2SDM FIELD_PREP_CONST(AIROHA_PCS_ANA_TXPLL_SDM_ORD, 0x2)
> +#define AIROHA_PCS_ANA_TXPLL_SDM_ORD_3SDM FIELD_PREP_CONST(AIROHA_PCS_ANA_TXPLL_SDM_ORD, 0x3)
> +#define AIROHA_PCS_ANA_PXP_TXPLL_TCL_AMP_GAIN 0x70
> +#define AIROHA_PCS_ANA_TXPLL_TCL_AMP_VREF GENMASK(12, 8)
> +#define AIROHA_PCS_ANA_TXPLL_TCL_AMP_GAIN GENMASK(2, 0)
> +#define AIROHA_PCS_ANA_TXPLL_TCL_AMP_GAIN_2 FIELD_PREP_CONST(AIROHA_PCS_ANA_TXPLL_TCL_AMP_GAIN, 0x0)
> +#define AIROHA_PCS_ANA_TXPLL_TCL_AMP_GAIN_2_5 FIELD_PREP_CONST(AIROHA_PCS_ANA_TXPLL_TCL_AMP_GAIN, 0x1)
> +#define AIROHA_PCS_ANA_TXPLL_TCL_AMP_GAIN_3 FIELD_PREP_CONST(AIROHA_PCS_ANA_TXPLL_TCL_AMP_GAIN, 0x2)
> +#define AIROHA_PCS_ANA_TXPLL_TCL_AMP_GAIN_4 FIELD_PREP_CONST(AIROHA_PCS_ANA_TXPLL_TCL_AMP_GAIN, 0x3)
> +#define AIROHA_PCS_ANA_TXPLL_TCL_AMP_GAIN_6 FIELD_PREP_CONST(AIROHA_PCS_ANA_TXPLL_TCL_AMP_GAIN, 0x4)
> +#define AIROHA_PCS_ANA_PXP_TXPLL_TCL_LPF_EN 0x74
> +#define AIROHA_PCS_ANA_TXPLL_VCO_CFIX GENMASK(25, 24)
> +#define AIROHA_PCS_ANA_TXPLL_VCODIV GENMASK(17, 16)
> +#define AIROHA_PCS_ANA_TXPLL_VCODIV_1 FIELD_PREP_CONST(AIROHA_PCS_ANA_TXPLL_VCODIV, 0x0)
> +#define AIROHA_PCS_ANA_TXPLL_VCODIV_2 FIELD_PREP_CONST(AIROHA_PCS_ANA_TXPLL_VCODIV, 0x1)
> +#define AIROHA_PCS_ANA_TXPLL_VCODIV_2 FIELD_PREP_CONST(AIROHA_PCS_ANA_TXPLL_VCODIV, 0x1)
> +#define AIROHA_PCS_ANA_TXPLL_TCL_LPF_BW GENMASK(10, 8)
> +#define AIROHA_PCS_ANA_TXPLL_TCL_LPF_BW_0_5 FIELD_PREP_CONST(AIROHA_PCS_ANA_TXPLL_TCL_LPF_BW, 0x0)
> +#define AIROHA_PCS_ANA_TXPLL_TCL_LPF_BW_1 FIELD_PREP_CONST(AIROHA_PCS_ANA_TXPLL_TCL_LPF_BW, 0x1)
> +#define AIROHA_PCS_ANA_TXPLL_TCL_LPF_BW_2 FIELD_PREP_CONST(AIROHA_PCS_ANA_TXPLL_TCL_LPF_BW, 0x2)
> +#define AIROHA_PCS_ANA_TXPLL_TCL_LPF_BW_4 FIELD_PREP_CONST(AIROHA_PCS_ANA_TXPLL_TCL_LPF_BW, 0x3)
> +#define AIROHA_PCS_ANA_TXPLL_TCL_LPF_BW_8 FIELD_PREP_CONST(AIROHA_PCS_ANA_TXPLL_TCL_LPF_BW, 0x4)
> +#define AIROHA_PCS_ANA_TXPLL_TCL_LPF_BW_16 FIELD_PREP_CONST(AIROHA_PCS_ANA_TXPLL_TCL_LPF_BW, 0x6)
> +#define AIROHA_PCS_ANA_TXPLL_TCL_LPF_EN BIT(0)
> +#define AIROHA_PCS_ANA_PXP_TXPLL_VCO_HALFLSB_EN 0x78
> +#define AIROHA_PCS_ANA_TXPLL_VCO_VCOVAR_BIAS_L GENMASK(29, 27)
> +#define AIROHA_PCS_ANA_TXPLL_VCO_VCOVAR_BIAS_H GENMASK(26, 24)
> +#define AIROHA_PCS_ANA_TXPLL_VCO_TCLVAR GENMASK(18, 16)
> +#define AIROHA_PCS_ANA_TXPLL_VCO_SCAPWR GENMASK(10, 8)
> +#define AIROHA_PCS_ANA_TXPLL_VCO_HALFLSB_EN BIT(0)
> +#define AIROHA_PCS_ANA_PXP_TXPLL_SSC_EN 0x7c
> +#define AIROHA_PCS_ANA_TXPLL_SSC_TRI_EN BIT(16)
> +#define AIROHA_PCS_ANA_TXPLL_SSC_PHASE_INI BIT(8)
> +#define AIROHA_PCS_ANA_TXPLL_SSC_EN BIT(0)
> +#define AIROHA_PCS_ANA_PXP_TXPLL_SSC_DELTA1 0x80
> +#define AIROHA_PCS_ANA_TXPLL_SSC_DELTA GENMASK(31, 16)
> +#define AIROHA_PCS_ANA_TXPLL_SSC_DELTA1 GENMASK(15, 0)
> +#define AIROHA_PCS_ANA_PXP_TXPLL_SSC_PERIOD 0x84
> +#define AIROHA_PCS_ANA_TXPLL_LDO_VCO_OUT GENMASK(25, 24)
> +#define AIROHA_PCS_ANA_TXPLL_LDO_OUT GENMASK(17, 16)
> +#define AIROHA_PCS_ANA_TXPLL_SSC_PERIOD GENMASK(15, 0)
> +#define AIROHA_PCS_ANA_PXP_TXPLL_TCL_KBAND_VREF 0x94
> +#define AIROHA_PCS_ANA_TXPLL_TCL_KBAND_VREF GENMASK(4, 0)
> +#define AIROHA_PCS_ANA_PXP_TX_CKLDO_EN 0xc4
> +#define AIROHA_PCS_ANA_TX_DMEDGEGEN_EN BIT(24)
> +#define AIROHA_PCS_ANA_TX_CKLDO_EN BIT(0)
> +#define AIROHA_PCS_ANA_PXP_RX_BUSBIT_SEL 0xcc
> +#define AIROHA_PCS_ANA_RX_PHY_CK_SEL_FORCE BIT(24)
> +#define AIROHA_PCS_ANA_RX_PHY_CK_SEL BIT(16) /* 0: from PR 1: from DES */
> +#define AIROHA_PCS_ANA_PXP_RX_REV_0 0xd4
> +#define AIROHA_PCS_ANA_RX_REV_1 GENMASK(31, 16)
> +#define AIROHA_PCS_ANA_REV_1_FE_EQ_BIAS_CTRL GENMASK(30, 28)
> +#define AIROHA_PCS_ANA_REV_1_FE_BUF1_BIAS_CTRL GENMASK(26, 24)
> +#define AIROHA_PCS_ANA_REV_1_FE_BUF2_BIAS_CTRL GENMASK(22, 20)
> +#define AIROHA_PCS_ANA_REV_1_SIGDET_ILEAK GENMASK(19, 18)
> +#define AIROHA_PCS_ANA_REV_1_FECUR_PWDB BIT(16)
> +#define AIROHA_PCS_ANA_PXP_RX_PHYCK_DIV 0xd8
> +#define AIROHA_PCS_ANA_RX_TDC_CK_SEL BIT(24)
> +#define AIROHA_PCS_ANA_RX_PHYCK_RSTB BIT(16)
> +#define AIROHA_PCS_ANA_RX_PHYCK_SEL GENMASK(9, 8)
> +#define AIROHA_PCS_ANA_RX_PHYCK_DIV GENMASK(7, 0)
> +#define AIROHA_PCS_ANA_PXP_CDR_PD_PICAL_CKD8_INV 0xdc
> +#define AIROHA_PCS_ANA_CDR_PD_EDGE_DIS BIT(8)
> +#define AIROHA_PCS_ANA_CDR_PD_PICAL_CKD8_INV BIT(0)
> +#define AIROHA_PCS_ANA_PXP_CDR_LPF_RATIO 0xe8
> +#define AIROHA_PCS_ANA_CDR_LPF_TOP_LIM GENMASK(26, 8)
> +#define AIROHA_PCS_ANA_CDR_LPF_RATIO GENMASK(1, 0)
> +#define AIROHA_PCS_ANA_PXP_CDR_PR_INJ_MODE 0xf4
> +#define AIROHA_PCS_ANA_CDR_PR_INJ_FORCE_OFF BIT(24)
> +#define AIROHA_PCS_ANA_PXP_CDR_PR_BETA_DAC 0xf8
> +#define AIROHA_PCS_ANA_CDR_PR_KBAND_DIV GENMASK(26, 24)
> +#define AIROHA_PCS_ANA_CDR_PR_BETA_SEL GENMASK(19, 16)
> +#define AIROHA_PCS_ANA_CDR_PR_VCOADC_OS GENMASK(11, 8)
> +#define AIROHA_PCS_ANA_CDR_PR_BETA_DAC GENMASK(6, 0)
> +#define AIROHA_PCS_ANA_PXP_CDR_PR_VREG_IBAND_VAL 0xfc
> +#define AIROHA_PCS_ANA_CDR_PR_FBKSEL GENMASK(25, 24)
> +#define AIROHA_PCS_ANA_CDR_PR_VREG_DAC_BAND GENMASK(20, 16)
> +#define AIROHA_PCS_ANA_CDR_PR_VREG_CKBUF_VAL GENMASK(10, 8)
> +#define AIROHA_PCS_ANA_CDR_PR_VREG_IBAND_VAL GENMASK(2, 0)
> +#define AIROHA_PCS_ANA_PXP_CDR_PR_MONPR_EN 0x10c
> +#define AIROHA_PCS_ANA_RX_DAC_MON GENMASK(28, 24)
> +#define AIROHA_PCS_ANA_CDR_PR_CAP_EN BIT(19)
> +#define AIROHA_PCS_ANA_CDR_BUF_IN_SR GENMASK(18, 16)
> +#define AIROHA_PCS_ANA_CDR_PR_XFICK_EN BIT(2)
> +#define AIROHA_PCS_ANA_CDR_PR_MONDPI_EN BIT(1)
> +#define AIROHA_PCS_ANA_CDR_PR_MONDPR_EN BIT(0)
> +#define AIROHA_PCS_ANA_PXP_RX_DAC_RANGE 0x110
> +#define AIROHA_PCS_ANA_RX_SIGDET_LPF_CTRL GENMASK(25, 24)
> +#define AIROHA_PCS_ANA_PXP_RX_SIGDET_NOVTH 0x114
> +#define AIROHA_PCS_ANA_RX_FE_50OHMS_SEL GENMASK(25, 24)
> +#define AIROHA_PCS_ANA_RX_SIGDET_VTH_SEL GENMASK(20, 16)
> +#define AIROHA_PCS_ANA_RX_SIGDET_PEAK GENMASK(9, 8)
> +#define AIROHA_PCS_ANA_PXP_RX_FE_EQ_HZEN 0x118
> +#define AIROHA_PCS_ANA_RX_FE_VB_EQ3_EN BIT(24)
> +#define AIROHA_PCS_ANA_RX_FE_VB_EQ2_EN BIT(16)
> +#define AIROHA_PCS_ANA_RX_FE_VB_EQ1_EN BIT(8)
> +#define AIROHA_PCS_ANA_RX_FE_EQ_HZEN BIT(0)
> +#define AIROHA_PCS_ANA_PXP_RX_FE_VCM_GEN_PWDB 0x11c
> +#define AIROHA_PCS_ANA_FE_VCM_GEN_PWDB BIT(0)
> +#define AIROHA_PCS_ANA_PXP_RX_OSCAL_WATCH_WNDW 0x120
> +#define AIROHA_PCS_ANA_RX_OSCAL_FORCE GENMASK(17, 8)
> +#define AIROHA_PCS_ANA_RX_OSCAL_FORCE_VGA2VOS FIELD_PREP_CONST(AIROHA_PCS_ANA_RX_OSCAL_FORCE, BIT(0))
> +#define AIROHA_PCS_ANA_RX_OSCAL_FORCE_VGA2IOS FIELD_PREP_CONST(AIROHA_PCS_ANA_RX_OSCAL_FORCE, BIT(1))
> +#define AIROHA_PCS_ANA_RX_OSCAL_FORCE_VGA1VOS FIELD_PREP_CONST(AIROHA_PCS_ANA_RX_OSCAL_FORCE, BIT(2))
> +#define AIROHA_PCS_ANA_RX_OSCAL_FORCE_VGA1IOS FIELD_PREP_CONST(AIROHA_PCS_ANA_RX_OSCAL_FORCE, BIT(3))
> +#define AIROHA_PCS_ANA_RX_OSCAL_FORCE_CTLE2VOS FIELD_PREP_CONST(AIROHA_PCS_ANA_RX_OSCAL_FORCE, BIT(4))
> +#define AIROHA_PCS_ANA_RX_OSCAL_FORCE_CTLE2IOS FIELD_PREP_CONST(AIROHA_PCS_ANA_RX_OSCAL_FORCE, BIT(5))
> +#define AIROHA_PCS_ANA_RX_OSCAL_FORCE_CTLE1VOS FIELD_PREP_CONST(AIROHA_PCS_ANA_RX_OSCAL_FORCE, BIT(6))
> +#define AIROHA_PCS_ANA_RX_OSCAL_FORCE_CTLE1IOS FIELD_PREP_CONST(AIROHA_PCS_ANA_RX_OSCAL_FORCE, BIT(7))
> +#define AIROHA_PCS_ANA_RX_OSCAL_FORCE_LVSH FIELD_PREP_CONST(AIROHA_PCS_ANA_RX_OSCAL_FORCE, BIT(8))
> +#define AIROHA_PCS_ANA_RX_OSCAL_FORCE_COMPOS FIELD_PREP_CONST(AIROHA_PCS_ANA_RX_OSCAL_FORCE, BIT(9))
> +#define AIROHA_PCS_ANA_PXP_AEQ_CFORCE 0x13c
> +#define AIROHA_PCS_ANA_AEQ_OFORCE GENMASK(19, 8)
> +#define AIROHA_PCS_ANA_AEQ_OFORCE_SAOS FIELD_PREP_CONST(AIROHA_PCS_ANA_AEQ_OFORCE, BIT(0))
> +#define AIROHA_PCS_ANA_AEQ_OFORCE_DFETP1 FIELD_PREP_CONST(AIROHA_PCS_ANA_AEQ_OFORCE, BIT(1))
> +#define AIROHA_PCS_ANA_AEQ_OFORCE_DFETP2 FIELD_PREP_CONST(AIROHA_PCS_ANA_AEQ_OFORCE, BIT(2))
> +#define AIROHA_PCS_ANA_AEQ_OFORCE_DFETP3 FIELD_PREP_CONST(AIROHA_PCS_ANA_AEQ_OFORCE, BIT(3))
> +#define AIROHA_PCS_ANA_AEQ_OFORCE_DFETP4 FIELD_PREP_CONST(AIROHA_PCS_ANA_AEQ_OFORCE, BIT(4))
> +#define AIROHA_PCS_ANA_AEQ_OFORCE_DFETP5 FIELD_PREP_CONST(AIROHA_PCS_ANA_AEQ_OFORCE, BIT(5))
> +#define AIROHA_PCS_ANA_AEQ_OFORCE_DFETP6 FIELD_PREP_CONST(AIROHA_PCS_ANA_AEQ_OFORCE, BIT(6))
> +#define AIROHA_PCS_ANA_AEQ_OFORCE_DFETP7 FIELD_PREP_CONST(AIROHA_PCS_ANA_AEQ_OFORCE, BIT(7))
> +#define AIROHA_PCS_ANA_AEQ_OFORCE_VGA FIELD_PREP_CONST(AIROHA_PCS_ANA_AEQ_OFORCE, BIT(8))
> +#define AIROHA_PCS_ANA_AEQ_OFORCE_CTLE FIELD_PREP_CONST(AIROHA_PCS_ANA_AEQ_OFORCE, BIT(9))
> +#define AIROHA_PCS_ANA_AEQ_OFORCE_ATT FIELD_PREP_CONST(AIROHA_PCS_ANA_AEQ_OFORCE, BIT(10))
> +#define AIROHA_PCS_ANA_PXP_RX_FE_PEAKING_CTRL_MSB 0x144
> +#define AIROHA_PCS_ANA_RX_DAC_D0_BYPASS_AEQ BIT(24)
> +#define AIROHA_PCS_ANA_PXP_RX_DAC_D1_BYPASS_AEQ 0x148
> +#define AIROHA_PCS_ANA_RX_DAC_EYE_BYPASS_AEQ BIT(24)
> +#define AIROHA_PCS_ANA_RX_DAC_E1_BYPASS_AEQ BIT(16)
> +#define AIROHA_PCS_ANA_RX_DAC_E0_BYPASS_AEQ BIT(8)
> +#define AIROHA_PCS_ANA_RX_DAC_D1_BYPASS_AEQ BIT(0)
> +
> +/* PMA_PHYD */
> +#define AIROHA_PCS_PMA_SS_LCPLL_PWCTL_SETTING_0 0x0
> +#define AIROHA_PCS_PMA_SW_LCPLL_EN BIT(24)
> +#define AIROHA_PCS_PMA_SS_LCPLL_PWCTL_SETTING_1 0x4
> +#define AIROHA_PCS_PMA_LCPLL_MAN_PWDB BIT(0)
> +#define AIROHA_PCS_PMA_RX_EYE_TOP_EYECNT_CTRL_2 0x88
> +#define AIROHA_PCS_PMA_DATA_SHIFT BIT(8)
> +#define AIROHA_PCS_PMA_EYECNT_FAST BIT(0)
> +#define AIROHA_PCS_PMA_RX_CTRL_SEQUENCE_CTRL_0 0x8c
> +#define AIROHA_PCS_PMA_RX_OS_START GENMASK(23, 8)
> +#define AIROHA_PCS_PMA_OSC_SPEED_OPT GENMASK(2, 0)
> +#define AIROHA_PCS_PMA_OSC_SPEED_OPT_0_05 FIELD_PREP_CONST(AIROHA_PCS_PMA_OSC_SPEED_OPT, 0x0)
> +#define AIROHA_PCS_PMA_OSC_SPEED_OPT_0_1 FIELD_PREP_CONST(AIROHA_PCS_PMA_OSC_SPEED_OPT, 0x1)
> +#define AIROHA_PCS_PMA_OSC_SPEED_OPT_0_2 FIELD_PREP_CONST(AIROHA_PCS_PMA_OSC_SPEED_OPT, 0x2)
> +#define AIROHA_PCS_PMA_OSC_SPEED_OPT_0_4 FIELD_PREP_CONST(AIROHA_PCS_PMA_OSC_SPEED_OPT, 0x3)
> +#define AIROHA_PCS_PMA_OSC_SPEED_OPT_0_8 FIELD_PREP_CONST(AIROHA_PCS_PMA_OSC_SPEED_OPT, 0x4)
> +#define AIROHA_PCS_PMA_OSC_SPEED_OPT_1_6 FIELD_PREP_CONST(AIROHA_PCS_PMA_OSC_SPEED_OPT, 0x5)
> +#define AIROHA_PCS_PMA_OSC_SPEED_OPT_3_2 FIELD_PREP_CONST(AIROHA_PCS_PMA_OSC_SPEED_OPT, 0x6)
> +#define AIROHA_PCS_PMA_OSC_SPEED_OPT_6_4 FIELD_PREP_CONST(AIROHA_PCS_PMA_OSC_SPEED_OPT, 0x7)
> +#define AIROHA_PCS_PMA_RX_CTRL_SEQUENCE_CTRL_1 0x90
> +#define AIROHA_PCS_PMA_RX_PICAL_END GENMASK(31, 16)
> +#define AIROHA_PCS_PMA_RX_PICAL_START GENMASK(15, 0)
> +#define AIROHA_PCS_PMA_RX_CTRL_SEQUENCE_CTRL_2 0x94
> +#define AIROHA_PCS_PMA_RX_PDOS_END GENMASK(31, 16)
> +#define AIROHA_PCS_PMA_RX_PDOS_START GENMASK(15, 0)
> +#define AIROHA_PCS_PMA_RX_CTRL_SEQUENCE_CTRL_3 0x98
> +#define AIROHA_PCS_PMA_RX_FEOS_END GENMASK(31, 16)
> +#define AIROHA_PCS_PMA_RX_FEOS_START GENMASK(15, 0)
> +#define AIROHA_PCS_PMA_RX_CTRL_SEQUENCE_CTRL_4 0x9c
> +#define AIROHA_PCS_PMA_RX_SDCAL_END GENMASK(31, 16)
> +#define AIROHA_PCS_PMA_RX_SDCAL_START GENMASK(15, 0)
> +#define AIROHA_PCS_PMA_RX_CTRL_SEQUENCE_CTRL_5 0x100
> +#define AIROHA_PCS_PMA_RX_RDY GENMASK(31, 16)
> +#define AIROHA_PCS_PMA_RX_BLWC_RDY_EN GENMASK(15, 0)
> +#define AIROHA_PCS_PMA_RX_CTRL_SEQUENCE_CTRL_6 0x104
> +#define AIROHA_PCS_PMA_RX_OS_END GENMASK(15, 0)
> +#define AIROHA_PCS_PMA_RX_CTRL_SEQUENCE_DISB_CTRL_1 0x10c
> +#define AIROHA_PCS_PMA_DISB_RX_RDY BIT(24)
> +#define AIROHA_PCS_PMA_RX_CTRL_SEQUENCE_FORCE_CTRL_1 0x114
> +#define AIROHA_PCS_PMA_FORCE_RX_RDY BIT(24)
> +#define AIROHA_PCS_PMA_PHY_EQ_CTRL_3 0x120
> +#define AIROHA_PCS_PMA_EQ_DEBUG_SEL GENMASK(17, 16)
> +#define AIROHA_PCS_PMA_FOM_NUM_ORDER GENMASK(12, 8)
> +#define AIROHA_PCS_PMA_A_SEL GENMASK(1, 0)
> +#define AIROHA_PCS_PMA_SS_RX_FREQ_DET_1 0x14c
> +#define AIROHA_PCS_PMA_UNLOCK_CYCLECNT GENMASK(31, 16)
> +#define AIROHA_PCS_PMA_LOCK_CYCLECNT GENMASK(15, 0)
> +#define AIROHA_PCS_PMA_SS_RX_FREQ_DET_2 0x150
> +#define AIROHA_PCS_PMA_LOCK_TARGET_END GENMASK(31, 16)
> +#define AIROHA_PCS_PMA_LOCK_TARGET_BEG GENMASK(15, 0)
> +#define AIROHA_PCS_PMA_SS_RX_FREQ_DET_3 0x154
> +#define AIROHA_PCS_PMA_UNLOCK_TARGET_END GENMASK(31, 16)
> +#define AIROHA_PCS_PMA_UNLOCK_TARGET_BEG GENMASK(15, 0)
> +#define AIROHA_PCS_PMA_SS_RX_FREQ_DET_4 0x158
> +#define AIROHA_PCS_PMA_LOCK_UNLOCKTH GENMASK(15, 12)
> +#define AIROHA_PCS_PMA_LOCK_LOCKTH GENMASK(11, 8)
> +#define AIROHA_PCS_PMA_FREQLOCK_DET_EN GENMASK(2, 0)
> +#define AIROHA_PCS_PMA_FREQLOCK_DET_EN_FORCE_0 FIELD_PREP_CONST(AIROHA_PCS_PMA_FREQLOCK_DET_EN, 0x0)
> +#define AIROHA_PCS_PMA_FREQLOCK_DET_EN_FORCE_1 FIELD_PREP_CONST(AIROHA_PCS_PMA_FREQLOCK_DET_EN, 0x1)
> +#define AIROHA_PCS_PMA_FREQLOCK_DET_EN_WAIT FIELD_PREP_CONST(AIROHA_PCS_PMA_FREQLOCK_DET_EN, 0x2)
> +#define AIROHA_PCS_PMA_FREQLOCK_DET_EN_NORMAL FIELD_PREP_CONST(AIROHA_PCS_PMA_FREQLOCK_DET_EN, 0x3)
> +#define AIROHA_PCS_PMA_FREQLOCK_DET_EN_RX_STATE FIELD_PREP_CONST(AIROHA_PCS_PMA_FREQLOCK_DET_EN, 0x7)
> +#define AIROHA_PCS_PMA_SS_RX_SIGDET_1 0x16c
> +#define AIROHA_PCS_PMA_SIGDET_EN BIT(0)
> +#define AIROHA_PCS_PMA_RX_FLL_1 0x174
> +#define AIROHA_PCS_PMA_LPATH_IDAC GENMASK(10, 0)
> +#define AIROHA_PCS_PMA_RX_FLL_2 0x178
> +#define AIROHA_PCS_PMA_CK_RATE GENMASK(18, 16)
> +#define AIROHA_PCS_PMA_CK_RATE_20 FIELD_PREP_CONST(AIROHA_PCS_PMA_CK_RATE, 0x0)
> +#define AIROHA_PCS_PMA_CK_RATE_10 FIELD_PREP_CONST(AIROHA_PCS_PMA_CK_RATE, 0x1)
> +#define AIROHA_PCS_PMA_CK_RATE_5 FIELD_PREP_CONST(AIROHA_PCS_PMA_CK_RATE, 0x2)
> +#define AIROHA_PCS_PMA_RX_FLL_5 0x184
> +#define AIROHA_PCS_PMA_FLL_IDAC_MIN GENMASK(26, 16)
> +#define AIROHA_PCS_PMA_FLL_IDAC_MAX GENMASK(10, 0)
> +#define AIROHA_PCS_PMA_RX_FLL_B 0x19c
> +#define AIROHA_PCS_PMA_LOAD_EN BIT(0)
> +#define AIROHA_PCS_PMA_RX_RESET_1 0x208
> +#define AIROHA_PCS_PMA_SIGDET_RST_B BIT(8)
> +#define AIROHA_PCS_PMA_TX_RST_B 0x260
> +#define AIROHA_PCS_PMA_TXCALIB_RST_B BIT(8)
> +#define AIROHA_PCS_PMA_TX_TOP_RST_B BIT(0)
> +#define AIROHA_PCS_PMA_RX_DISB_MODE_4 0x320
> +#define AIROHA_PCS_PMA_DISB_BLWC_OFFSET BIT(24)
> +#define AIROHA_PCS_PMA_RX_FORCE_MODE_9 0x330
> +#define AIROHA_PCS_PMA_FORCE_FBCK_LOCK BIT(0)
> +#define AIROHA_PCS_PMA_RX_DISB_MODE_8 0x33c
> +#define AIROHA_PCS_PMA_DISB_FBCK_LOCK BIT(0)
> +#define AIROHA_PCS_PMA_RX_SYS_EN_SEL_0 0x38c
> +#define AIROHA_PCS_PMA_RX_SYS_EN_SEL GENMASK(1, 0)
> +#define AIROHA_PCS_PMA_PLL_TDC_FREQDET_0 0x390
> +#define AIROHA_PCS_PMA_PLL_LOCK_CYCLECNT GENMASK(15, 0)
> +#define AIROHA_PCS_PMA_PLL_TDC_FREQDET_1 0x394
> +#define AIROHA_PCS_PMA_PLL_LOCK_TARGET_END GENMASK(31, 16)
> +#define AIROHA_PCS_PMA_PLL_LOCK_TARGET_BEG GENMASK(15, 0)
> +#define AIROHA_PCS_PMA_PLL_TDC_FREQDET_3 0x39c
> +#define AIROHA_PCS_PMA_PLL_LOCK_LOCKTH GENMASK(11, 8)
> +#define AIROHA_PCS_PMA_RX_EXTRAL_CTRL 0x48c
> +#define AIROHA_PCS_PMA_DISB_LEQ BIT(0)
> +#define AIROHA_PCS_PMA_SS_DA_XPON_PWDB_0 0x34c
> +#define AIROHA_PCS_PMA_XPON_CDR_PR_PD_PWDB BIT(24)
> +#define AIROHA_PCS_PMA_XPON_CDR_PR_PIEYE_PWDB BIT(16)
> +#define AIROHA_PCS_PMA_XPON_CDR_PW_PWDB BIT(8)
> +#define AIROHA_PCS_PMA_XPON_RX_FE_PWDB BIT(0)
> +#define AIROHA_PCS_PMA_SS_DA_XPON_PWDB_1 0x350
> +#define AIROHA_PCS_PMA_RX_SIDGET_PWDB BIT(0)
> +#define AIROHA_PCS_PMA_DIG_RESERVE_0 0x360
> +#define AIROHA_PCS_PMA_DIG_RO_RESERVE_2 0x380
> +#define AIROHA_PCS_PMA_XPON_RX_RESERVED_1 0x374
> +#define AIROHA_PCS_PMA_XPON_RX_RATE_CTRL GENMASK(1, 0)
> +#define AIROHA_PCS_PMA_SW_RST_SET 0x460
> +#define AIROHA_PCS_PMA_SW_HSG_RXPCS_RST_N BIT(11)
> +#define AIROHA_PCS_PMA_SW_HSG_TXPCS_RST_N BIT(10)
> +#define AIROHA_PCS_PMA_SW_HSG_RXPCS_BIST_RST_N BIT(9)
> +#define AIROHA_PCS_PMA_SW_XFI_RXPCS_RST_N BIT(8)
> +#define AIROHA_PCS_PMA_SW_XFI_TXPCS_RST_N BIT(7)
> +#define AIROHA_PCS_PMA_SW_TX_FIFO_RST_N BIT(6)
> +#define AIROHA_PCS_PMA_SW_REF_RST_N BIT(5)
> +#define AIROHA_PCS_PMA_SW_ALLPCS_RST_N BIT(4)
> +#define AIROHA_PCS_PMA_SW_PMA_RST_N BIT(3)
> +#define AIROHA_PCS_PMA_SW_TX_RST_N BIT(2)
> +#define AIROHA_PCS_PMA_SW_RX_RST_N BIT(1)
> +#define AIROHA_PCS_PMA_SW_RX_FIFO_RST_N BIT(0)
> +#define AIROHA_PCS_PMA_XPON_INT_EN_3 0x474
> +#define AIROHA_PCS_PMA_RX_SIGDET_INT_EN BIT(16)
> +#define AIROHA_PCS_PMA_XPON_INT_STA_3 0x47c
> +#define AIROHA_PCS_PMA_RX_SIGDET_INT BIT(16)
> +#define AIROHA_PCS_PMA_RX_EXTRAL_CTRL 0x48c
> +#define AIROHA_PCS_PMA_DISB_LEQ BIT(0)
> +#define AIROHA_PCS_PMA_RX_FREQDET 0x530
> +#define AIROHA_PCS_PMA_FL_OUT GENMASK(31, 16)
> +#define AIROHA_PCS_PMA_FBCK_LOCK BIT(0)
> +#define AIROHA_PCS_PMA_XPON_TX_RATE_CTRL 0x580
> +#define AIROHA_PCS_PMA_PON_TX_RATE_CTRL GENMASK(1, 0)
> +#define AIROHA_PCS_PMA_PXP_JCPLL_SDM_SCAN 0x768
> +#define AIROHA_PCS_PMA_FORCE_SEL_DA_RX_PEAKING_CTRL BIT(24)
> +#define AIROHA_PCS_PMA_FORCE_DA_RX_PEAKING_CTRL GENMASK(19, 16)
> +#define AIROHA_PCS_PMA_PXP_AEQ_SPEED 0x76c
> +#define AIROHA_PCS_PMA_FORCE_SEL_DA_OSR_SEL BIT(24)
> +#define AIROHA_PCS_PMA_FORCE_DA_OSR_SEL GENMASK(17, 16)
> +#define AIROHA_PCS_PMA_PXP_TX_FIR_C0B 0x778
> +#define AIROHA_PCS_PMA_FORCE_SEL_DA_TX_FIR_CN1 BIT(24)
> +#define AIROHA_PCS_PMA_FORCE_DA_TX_FIR_CN1 GENMASK(20, 16)
> +#define AIROHA_PCS_PMA_FORCE_SEL_DA_TX_FIR_C0B BIT(8)
> +#define AIROHA_PCS_PMA_FORCE_DA_TX_FIR_C0B GENMASK(5, 0)
> +#define AIROHA_PCS_PMA_PXP_TX_TERM_SEL 0x77c
> +#define AIROHA_PCS_PMA_FORCE_SEL_DA_TX_CKIN_DIVISOR BIT(24)
> +#define AIROHA_PCS_PMA_FORCE_DA_TX_CKIN_DIVISOR GENMASK(19, 16)
> +#define AIROHA_PCS_PMA_FORCE_SEL_DA_TX_TERM_SEL BIT(8)
> +#define AIROHA_PCS_PMA_FORCE_DA_TX_TERM_SEL GENMASK(2, 0)
> +#define AIROHA_PCS_PMA_PXP_TX_FIR_C1 0x780
> +#define AIROHA_PCS_PMA_FORCE_SEL_DA_TX_FIR_C2 BIT(24)
> +#define AIROHA_PCS_PMA_FORCE_DA_TX_FIR_C2 GENMASK(20, 16)
> +#define AIROHA_PCS_PMA_FORCE_SEL_DA_TX_FIR_C1 BIT(8)
> +#define AIROHA_PCS_PMA_FORCE_DA_TX_FIR_C1 GENMASK(5, 0)
> +#define AIROHA_PCS_PMA_PXP_TX_RATE_CTRL 0x784
> +#define AIROHA_PCS_PMA_FORCE_SEL_DA_TX_RATE_CTRL BIT(8)
> +#define AIROHA_PCS_PMA_FORCE_DA_TX_RATE_CTRL GENMASK(1, 0)
> +#define AIROHA_PCS_PMA_PXP_CDR_PR_IDAC 0x794
> +#define AIROHA_PCS_PMA_FORCE_SEL_DA_TXPLL_SDM_PCW BIT(24)
> +#define AIROHA_PCS_PMA_FORCE_SEL_DA_CDR_PR_IDAC BIT(16)
> +#define AIROHA_PCS_PMA_FORCE_CDR_PR_IDAC GENMASK(10, 0)
> +#define AIROHA_PCS_PMA_FORCE_CDR_PR_IDAC_MAJOR GENMASK(10, 8)
> +#define AIROHA_PCS_PMA_PXP_TXPLL_SDM_PCW 0x798
> +#define AIROHA_PCS_PMA_FORCE_DA_TXPLL_SDM_PCW GENMASK(30, 0)
> +#define AIROHA_PCS_PMA_PXP_RX_FE_VOS 0x79c
> +#define AIROHA_PCS_PMA_FORCE_SEL_DA_JCPLL_SDM_PCW BIT(16)
> +#define AIROHA_PCS_PMA_FORCE_SEL_DA_FE_VOS BIT(8)
> +#define AIROHA_PCS_PMA_FORCE_DA_FE_VOS GENMASK(5, 0)
> +#define AIROHA_PCS_PMA_PXP_JCPLL_SDM_PCW 0x800
> +#define AIROHA_PCS_PMA_FORCE_DA_JCPLL_SDM_PCW GENMASK(30, 0)
> +#define AIROHA_PCS_PMA_PXP_AEQ_BYPASS 0x80c
> +#define AIROHA_PCS_PMA_FORCE_SEL_DA_AEQ_CKON BIT(24)
> +#define AIROHA_PCS_PMA_FORCE_DA_AEQ_CKON BIT(16)
> +#define AIROHA_PCS_PMA_PXP_AEQ_RSTB 0x814
> +#define AIROHA_PCS_PMA_FORCE_SEL_DA_CDR_INJCK_SEL BIT(24)
> +#define AIROHA_PCS_PMA_FORCE_DA_CDR_INJCK_SEL BIT(16)
> +#define AIROHA_PCS_PMA_PXP_CDR_LPF_LCK_2DATA 0x818
> +#define AIROHA_PCS_PMA_FORCE_SEL_DA_CDR_LPF_RSTB BIT(24)
> +#define AIROHA_PCS_PMA_FORCE_DA_CDR_LPF_RSTB BIT(16)
> +#define AIROHA_PCS_PMA_FORCE_SEL_DA_CDR_LPF_LCK2DATA BIT(8)
> +#define AIROHA_PCS_PMA_FORCE_DA_CDR_LPF_LCK2DATA BIT(0)
> +#define AIROHA_PCS_PMA_PXP_CDR_PD_PWDB 0x81c
> +#define AIROHA_PCS_PMA_FORCE_SEL_DA_CDR_PR_KBAND_RSTB BIT(24)
> +#define AIROHA_PCS_PMA_FORCE_DA_CDR_PR_KBAND_RSTB BIT(16)
> +#define AIROHA_PCS_PMA_FORCE_SEL_DA_CDR_PD_PWDB BIT(8)
> +#define AIROHA_PCS_PMA_FORCE_DA_CDR_PR_PD_PWDB BIT(0)
> +#define AIROHA_PCS_PMA_PXP_CDR_PR_LPF_C_EN 0x820
> +#define AIROHA_PCS_PMA_FORCE_SEL_DA_CDR_PR_LPF_R_EN BIT(24)
> +#define AIROHA_PCS_PMA_FORCE_DA_CDR_PR_LPF_R_EN BIT(16)
> +#define AIROHA_PCS_PMA_FORCE_SEL_DA_CDR_PR_LPF_C_EN BIT(8)
> +#define AIROHA_PCS_PMA_FORCE_DA_CDR_PR_LPF_C_EN BIT(0)
> +#define AIROHA_PCS_PMA_PXP_CDR_PR_PIEYE_PWDB 0x824
> +#define AIROHA_PCS_PMA_FORCE_SEL_DA_CDR_PR_PWDB BIT(24)
> +#define AIROHA_PCS_PMA_FORCE_DA_CDR_PR_PWDB BIT(16)
> +#define AIROHA_PCS_PMA_FORCE_SEL_DA_CDR_PR_PIEYE_PWDB BIT(8)
> +#define AIROHA_PCS_PMA_FORCE_DA_CDR_PR_PIEYE_PWDB BIT(0)
> +#define AIROHA_PCS_PMA_PXP_JCPLL_CKOUT_EN 0x828
> +#define AIROHA_PCS_PMA_FORCE_SEL_DA_JCPLL_EN BIT(24)
> +#define AIROHA_PCS_PMA_FORCE_DA_JCPLL_EN BIT(16)
> +#define AIROHA_PCS_PMA_FORCE_SEL_DA_JCPLL_CKOUT_EN BIT(8)
> +#define AIROHA_PCS_PMA_FORCE_DA_JCPLL_CKOUT_EN BIT(0)
> +#define AIROHA_PCS_PMA_PXP_RX_SCAN_RST_B 0x84c
> +#define AIROHA_PCS_PMA_FORCE_SEL_DA_RX_SIGDET_PWDB BIT(24)
> +#define AIROHA_PCS_PMA_FORCE_DA_RX_SIGDET_PWDB BIT(16)
> +#define AIROHA_PCS_PMA_FORCE_SEL_DA_RX_SCAN_RST_B BIT(8)
> +#define AIROHA_PCS_PMA_FORCE_DA_RX_SCAN_RST_B BIT(0)
> +#define AIROHA_PCS_PMA_PXP_TXPLL_CKOUT_EN 0x854
> +#define AIROHA_PCS_PMA_FORCE_SEL_DA_TXPLL_EN BIT(24)
> +#define AIROHA_PCS_PMA_FORCE_DA_TXPLL_EN BIT(16)
> +#define AIROHA_PCS_PMA_FORCE_SEL_DA_TXPLL_CKOUT_EN BIT(8)
> +#define AIROHA_PCS_PMA_FORCE_DA_TXPLL_CKOUT_EN BIT(0)
> +#define AIROHA_PCS_PMA_PXP_TX_ACJTAG_EN 0x874
> +#define AIROHA_PCS_PMA_FORCE_SEL_DA_TX_CKIN_SEL BIT(24)
> +#define AIROHA_PCS_PMA_FORCE_DA_TX_CKIN_SEL BIT(16)
> +#define AIROHA_PCS_PMA_PXP_FE_GAIN_CTRL 0x88c
> +#define AIROHA_PCS_PMA_FORCE_SEL_DA_RX_FE_GAIN_CTRL BIT(8)
> +#define AIROHA_PCS_PMA_FORCE_DA_RX_FE_GAIN_CTRL GENMASK(1, 0)
> +#define AIROHA_PCS_PMA_PXP_RX_FE_PWDB 0x894
> +#define AIROHA_PCS_PMA_FORCE_SEL_DA_RX_PDOSCAL_EN BIT(24)
> +#define AIROHA_PCS_PMA_FORCE_DA_RX_PDOSCAL_EN BIT(16)
> +#define AIROHA_PCS_PMA_FORCE_SEL_DA_RX_FE_PWDB BIT(8)
> +#define AIROHA_PCS_PMA_FORCE_DA_RX_FE_PWDB BIT(0)
> +
> +#define AIROHA_PCS_MAX_CALIBRATION_TRY 50
> +#define AIROHA_PCS_MAX_NUM_RSTS 2
> +
> +enum xfi_port_type {
> + AIROHA_PCS_ETH,
> + AIROHA_PCS_PON,
> +};
> +
> +struct airoha_pcs_match_data {
> + enum xfi_port_type port_type;
> +};
> +
> +struct airoha_pcs_priv {
> + struct device *dev;
> + const struct airoha_pcs_match_data *data;
> + phy_interface_t interface;
> +
> + struct regmap *scu;
> +
> + struct regmap *xfi_mac;
> + struct regmap *hsgmii_an;
> + struct regmap *hsgmii_pcs;
> + struct regmap *hsgmii_rate_adp;
> + struct regmap *multi_sgmii;
> + struct regmap *usxgmii_pcs;
> +
> + struct regmap *xfi_pma;
> + struct regmap *xfi_ana;
> +
> + struct reset_control_bulk_data rsts[AIROHA_PCS_MAX_NUM_RSTS];
> +
> + struct phylink_pcs pcs;
> +};
> +
> +static struct airoha_pcs_priv *phylink_pcs_to_airoha_pcs_port(struct phylink_pcs *pcs)
> +{
> + return container_of(pcs, struct airoha_pcs_priv, pcs);
> +}
> +
> +static void airoha_pcs_setup_scu_eth(struct airoha_pcs_priv *priv,
> + phy_interface_t interface)
> +{
> + u32 xsi_sel;
> +
> + switch (interface) {
> + case PHY_INTERFACE_MODE_SGMII:
> + case PHY_INTERFACE_MODE_1000BASEX:
> + case PHY_INTERFACE_MODE_2500BASEX:
> + xsi_sel = AIROHA_SCU_ETH_XSI_HSGMII;
> + break;
> + case PHY_INTERFACE_MODE_USXGMII:
> + case PHY_INTERFACE_MODE_10GBASER:
> + default:
> + xsi_sel = AIROHA_SCU_ETH_XSI_USXGMII;
> + }
> +
> + regmap_update_bits(priv->scu, AIROHA_SCU_SSR3,
> + AIROHA_SCU_ETH_XSI_SEL,
> + xsi_sel);
> +}
> +
> +static void airoha_pcs_setup_scu_pon(struct airoha_pcs_priv *priv,
> + phy_interface_t interface)
> +{
> + u32 xsi_sel, wan_sel;
> +
> + switch (interface) {
> + case PHY_INTERFACE_MODE_SGMII:
> + case PHY_INTERFACE_MODE_1000BASEX:
> + wan_sel = AIROHA_SCU_WAN_SEL_SGMII;
> + xsi_sel = AIROHA_SCU_PON_XSI_HSGMII;
> + break;
> + case PHY_INTERFACE_MODE_2500BASEX:
> + wan_sel = AIROHA_SCU_WAN_SEL_HSGMII;
> + xsi_sel = AIROHA_SCU_PON_XSI_HSGMII;
> + break;
> + case PHY_INTERFACE_MODE_USXGMII:
> + case PHY_INTERFACE_MODE_10GBASER:
> + default:
> + wan_sel = AIROHA_SCU_WAN_SEL_USXGMII;
> + xsi_sel = AIROHA_SCU_PON_XSI_USXGMII;
> + }
> +
> + regmap_update_bits(priv->scu, AIROHA_SCU_SSTR,
> + AIROHA_SCU_PON_XSI_SEL,
> + xsi_sel);
> +
> + regmap_update_bits(priv->scu, AIROHA_SCU_WAN_CONF,
> + AIROHA_SCU_WAN_SEL,
> + wan_sel);
> +}
> +
> +static int airoha_pcs_setup_scu(struct airoha_pcs_priv *priv,
> + phy_interface_t interface)
> +{
> + int ret;
> +
> + switch (priv->data->port_type) {
> + case AIROHA_PCS_ETH:
> + airoha_pcs_setup_scu_eth(priv, interface);
> + break;
> + case AIROHA_PCS_PON:
> + airoha_pcs_setup_scu_pon(priv, interface);
> + break;
> + }
> +
> + ret = reset_control_bulk_assert(ARRAY_SIZE(priv->rsts),
> + priv->rsts);
> + if (ret)
> + return ret;
> +
> + ret = reset_control_bulk_deassert(ARRAY_SIZE(priv->rsts),
> + priv->rsts);
> + if (ret)
> + return ret;
> +
> + return 0;
> +}
> +
> +static void airoha_pcs_init_usxgmii(struct airoha_pcs_priv *priv)
> +{
> + regmap_set_bits(priv->multi_sgmii, AIROHA_PCS_MULTI_SGMII_MSG_RX_CTRL_0,
> + AIROHA_PCS_HSGMII_XFI_SEL);
> +
> + /* Disable Hibernation */
> + regmap_clear_bits(priv->usxgmii_pcs, AIROHA_PCS_USXGMII_PCS_CTROL_1,
> + AIROHA_PCS_USXGMII_SPEED_SEL_H);
> +
> + /* FIXME: wait Airoha */
> + /* Avoid PCS sending garbage to MAC in some HW revision (E0) */
> + regmap_write(priv->usxgmii_pcs, AIROHA_PCS_USGMII_VENDOR_DEFINE_116, 0);
> +}
> +
> +static void airoha_pcs_init_hsgmii(struct airoha_pcs_priv *priv)
> +{
> + regmap_clear_bits(priv->multi_sgmii, AIROHA_PCS_MULTI_SGMII_MSG_RX_CTRL_0,
> + AIROHA_PCS_HSGMII_XFI_SEL);
> +
> + regmap_set_bits(priv->hsgmii_pcs, AIROHA_PCS_HSGMII_PCS_CTROL_1,
> + AIROHA_PCS_TBI_10B_MODE);
> +}
> +
> +static void airoha_pcs_init_sgmii(struct airoha_pcs_priv *priv)
> +{
> + regmap_clear_bits(priv->multi_sgmii, AIROHA_PCS_MULTI_SGMII_MSG_RX_CTRL_0,
> + AIROHA_PCS_HSGMII_XFI_SEL);
> +
> + regmap_set_bits(priv->hsgmii_pcs, AIROHA_PCS_HSGMII_PCS_CTROL_1,
> + AIROHA_PCS_TBI_10B_MODE);
> +
> + regmap_update_bits(priv->hsgmii_rate_adp, AIROHA_PCS_HSGMII_RATE_ADAPT_CTRL_6,
> + AIROHA_PCS_HSGMII_RATE_ADAPT_RX_AFIFO_DOUT_L,
> + FIELD_PREP(AIROHA_PCS_HSGMII_RATE_ADAPT_RX_AFIFO_DOUT_L, 0x07070707));
> +
> + regmap_update_bits(priv->hsgmii_rate_adp, AIROHA_PCS_HSGMII_RATE_ADAPT_CTRL_8,
> + AIROHA_PCS_HSGMII_RATE_ADAPT_RX_AFIFO_DOUT_C,
> + FIELD_PREP(AIROHA_PCS_HSGMII_RATE_ADAPT_RX_AFIFO_DOUT_C, 0xff));
> +}
> +
> +static void airoha_pcs_init(struct airoha_pcs_priv *priv,
> + phy_interface_t interface)
> +{
> + switch (interface) {
> + case PHY_INTERFACE_MODE_SGMII:
> + case PHY_INTERFACE_MODE_1000BASEX:
> + airoha_pcs_init_sgmii(priv);
> + break;
> + case PHY_INTERFACE_MODE_2500BASEX:
> + airoha_pcs_init_hsgmii(priv);
> + break;
> + case PHY_INTERFACE_MODE_USXGMII:
> + case PHY_INTERFACE_MODE_10GBASER:
> + airoha_pcs_init_usxgmii(priv);
> + break;
> + default:
> + return;
> + }
> +}
> +
> +static void airoha_pcs_interrupt_init_sgmii(struct airoha_pcs_priv *priv)
> +{
> + /* Disable every interrupt */
> + regmap_clear_bits(priv->usxgmii_pcs, AIROHA_PCS_HSGMII_PCS_HSGMII_MODE_INTERRUPT,
> + AIROHA_PCS_HSGMII_MODE2_REMOVE_FAULT_OCCUR_INT |
> + AIROHA_PCS_HSGMII_MODE2_AN_CL37_TIMERDONE_INT |
> + AIROHA_PCS_HSGMII_MODE2_AN_MIS_INT |
> + AIROHA_PCS_HSGMII_MODE2_RX_SYN_DONE_INT |
> + AIROHA_PCS_HSGMII_MODE2_AN_DONE_INT);
> +
> + /* Clear interrupt */
> + regmap_set_bits(priv->usxgmii_pcs, AIROHA_PCS_HSGMII_PCS_HSGMII_MODE_INTERRUPT,
> + AIROHA_PCS_HSGMII_MODE2_REMOVE_FAULT_OCCUR_INT_CLEAR |
> + AIROHA_PCS_HSGMII_MODE2_AN_CL37_TIMERDONE_INT_CLEAR |
> + AIROHA_PCS_HSGMII_MODE2_AN_MIS_INT_CLEAR |
> + AIROHA_PCS_HSGMII_MODE2_RX_SYN_DONE_INT_CLEAR |
> + AIROHA_PCS_HSGMII_MODE2_AN_DONE_INT_CLEAR);
> +
> + regmap_clear_bits(priv->usxgmii_pcs, AIROHA_PCS_HSGMII_PCS_HSGMII_MODE_INTERRUPT,
> + AIROHA_PCS_HSGMII_MODE2_REMOVE_FAULT_OCCUR_INT_CLEAR |
> + AIROHA_PCS_HSGMII_MODE2_AN_CL37_TIMERDONE_INT_CLEAR |
> + AIROHA_PCS_HSGMII_MODE2_AN_MIS_INT_CLEAR |
> + AIROHA_PCS_HSGMII_MODE2_RX_SYN_DONE_INT_CLEAR |
> + AIROHA_PCS_HSGMII_MODE2_AN_DONE_INT_CLEAR);
> +}
> +
> +static void airoha_pcs_interrupt_init_usxgmii(struct airoha_pcs_priv *priv)
> +{
> + /* Disable every Interrupt */
> + regmap_clear_bits(priv->usxgmii_pcs, AIROHA_PCS_USXGMII_PCS_CTRL_0,
> + AIROHA_PCS_USXGMII_T_TYPE_T_INT_EN |
> + AIROHA_PCS_USXGMII_T_TYPE_D_INT_EN |
> + AIROHA_PCS_USXGMII_T_TYPE_C_INT_EN |
> + AIROHA_PCS_USXGMII_T_TYPE_S_INT_EN);
> +
> + regmap_clear_bits(priv->usxgmii_pcs, AIROHA_PCS_USXGMII_PCS_CTRL_1,
> + AIROHA_PCS_USXGMII_R_TYPE_C_INT_EN |
> + AIROHA_PCS_USXGMII_R_TYPE_S_INT_EN |
> + AIROHA_PCS_USXGMII_TXPCS_FSM_ENC_ERR_INT_EN |
> + AIROHA_PCS_USXGMII_T_TYPE_E_INT_EN);
> +
> + regmap_clear_bits(priv->usxgmii_pcs, AIROHA_PCS_USXGMII_PCS_CTRL_2,
> + AIROHA_PCS_USXGMII_RPCS_FSM_DEC_ERR_INT_EN |
> + AIROHA_PCS_USXGMII_R_TYPE_E_INT_EN |
> + AIROHA_PCS_USXGMII_R_TYPE_T_INT_EN |
> + AIROHA_PCS_USXGMII_R_TYPE_D_INT_EN);
> +
> + regmap_clear_bits(priv->usxgmii_pcs, AIROHA_PCS_USXGMII_PCS_CTRL_3,
> + AIROHA_PCS_USXGMII_FAIL_SYNC_XOR_ST_INT_EN |
> + AIROHA_PCS_USXGMII_RX_BLOCK_LOCK_ST_INT_EN |
> + AIROHA_PCS_USXGMII_LINK_UP_ST_INT_EN |
> + AIROHA_PCS_USXGMII_HI_BER_ST_INT_EN);
> +
> + regmap_clear_bits(priv->usxgmii_pcs, AIROHA_PCS_USXGMII_PCS_CTRL_4,
> + AIROHA_PCS_USXGMII_LINK_DOWN_ST_INT_EN);
> +
> + /* Clear any pending interrupt */
> + regmap_set_bits(priv->usxgmii_pcs, AIROHA_PCS_USXGMII_PCS_INT_STA_2,
> + AIROHA_PCS_USXGMII_RPCS_FSM_DEC_ERR_INT |
> + AIROHA_PCS_USXGMII_R_TYPE_E_INT |
> + AIROHA_PCS_USXGMII_R_TYPE_T_INT |
> + AIROHA_PCS_USXGMII_R_TYPE_D_INT);
> +
> + regmap_set_bits(priv->usxgmii_pcs, AIROHA_PCS_USXGMII_PCS_INT_STA_3,
> + AIROHA_PCS_USXGMII_FAIL_SYNC_XOR_ST_INT |
> + AIROHA_PCS_USXGMII_RX_BLOCK_LOCK_ST_INT |
> + AIROHA_PCS_USXGMII_LINK_UP_ST_INT |
> + AIROHA_PCS_USXGMII_HI_BER_ST_INT);
> +
> + regmap_set_bits(priv->usxgmii_pcs, AIROHA_PCS_USXGMII_PCS_INT_STA_4,
> + AIROHA_PCS_USXGMII_LINK_DOWN_ST_INT);
> +
> + /* Interrupt saddly seems to be not weel supported for Link Down.
> + * PCS Poll is a must to correctly read and react on Cable Deatch
> + * as only cable attach interrupt are fired and Link Down interrupt
> + * are fired only in special case like AN restart.
> + */
> +}
> +
> +static void airoha_pcs_interrupt_init(struct airoha_pcs_priv *priv,
> + phy_interface_t interface)
> +{
> + switch (interface) {
> + case PHY_INTERFACE_MODE_SGMII:
> + case PHY_INTERFACE_MODE_1000BASEX:
> + case PHY_INTERFACE_MODE_2500BASEX:
> + return airoha_pcs_interrupt_init_sgmii(priv);
> + case PHY_INTERFACE_MODE_USXGMII:
> + case PHY_INTERFACE_MODE_10GBASER:
> + return airoha_pcs_interrupt_init_usxgmii(priv);
> + default:
> + return;
> + }
> +}
> +
> +static void airoha_pcs_jcpll_bringup(struct airoha_pcs_priv *priv,
> + phy_interface_t interface)
> +{
> + u32 kband_vref;
> +
> + switch (interface) {
> + case PHY_INTERFACE_MODE_SGMII:
> + case PHY_INTERFACE_MODE_1000BASEX:
> + case PHY_INTERFACE_MODE_2500BASEX:
> + kband_vref = 0x10;
> + break;
> + case PHY_INTERFACE_MODE_USXGMII:
> + case PHY_INTERFACE_MODE_10GBASER:
> + kband_vref = 0xf;
> + break;
> + default:
> + return;
> + }
> +
> + /* Setup LDO */
> + usleep_range(200, 300);
> +
> + regmap_set_bits(priv->xfi_ana, AIROHA_PCS_ANA_PXP_JCPLL_SPARE_H,
> + AIROHA_PCS_ANA_JCPLL_SPARE_L_LDO);
> +
> + /* Setup RSTB */
> + regmap_update_bits(priv->xfi_ana, AIROHA_PCS_ANA_PXP_JCPLL_RST_DLY,
> + AIROHA_PCS_ANA_JCPLL_RST_DLY,
> + AIROHA_PCS_ANA_JCPLL_RST_DLY_150_200);
> +
> + regmap_set_bits(priv->xfi_ana, AIROHA_PCS_ANA_PXP_JCPLL_RST_DLY,
> + AIROHA_PCS_ANA_JCPLL_PLL_RSTB);
> +
> + /* Enable PLL force selection and Force Disable */
> + regmap_update_bits(priv->xfi_pma, AIROHA_PCS_PMA_PXP_JCPLL_CKOUT_EN,
> + AIROHA_PCS_PMA_FORCE_SEL_DA_JCPLL_EN |
> + AIROHA_PCS_PMA_FORCE_DA_JCPLL_EN,
> + AIROHA_PCS_PMA_FORCE_SEL_DA_JCPLL_EN);
> +
> + /* Setup SDM */
> + regmap_update_bits(priv->xfi_ana, AIROHA_PCS_ANA_PXP_JCPLL_RST_DLY,
> + AIROHA_PCS_ANA_JCPLL_SDM_DI_LS |
> + AIROHA_PCS_ANA_JCPLL_SDM_DI_EN,
> + AIROHA_PCS_ANA_JCPLL_SDM_DI_LS_2_23);
> +
> + regmap_update_bits(priv->xfi_ana, AIROHA_PCS_ANA_PXP_JCPLL_SDM_IFM,
> + AIROHA_PCS_ANA_JCPLL_SDM_OUT |
> + AIROHA_PCS_ANA_JCPLL_SDM_ORD |
> + AIROHA_PCS_ANA_JCPLL_SDM_MODE |
> + AIROHA_PCS_ANA_JCPLL_SDM_IFM,
> + FIELD_PREP(AIROHA_PCS_ANA_JCPLL_SDM_ORD, 0x0) |
> + AIROHA_PCS_ANA_JCPLL_SDM_ORD_3SDM |
> + FIELD_PREP(AIROHA_PCS_ANA_JCPLL_SDM_MODE, 0x0));
> +
> + regmap_clear_bits(priv->xfi_ana, AIROHA_PCS_ANA_PXP_JCPLL_SDM_HREN,
> + AIROHA_PCS_ANA_JCPLL_SDM_HREN);
> +
> + /* Setup SSC */
> + regmap_update_bits(priv->xfi_ana, AIROHA_PCS_ANA_PXP_JCPLL_SSC_DELTA,
> + AIROHA_PCS_ANA_JCPLL_SSC_PERIOD |
> + AIROHA_PCS_ANA_JCPLL_SSC_DELTA,
> + FIELD_PREP(AIROHA_PCS_ANA_JCPLL_SSC_PERIOD, 0x0) |
> + FIELD_PREP(AIROHA_PCS_ANA_JCPLL_SSC_DELTA, 0x0));
> +
> + regmap_update_bits(priv->xfi_ana, AIROHA_PCS_ANA_PXP_JCPLL_SSC_TRI_EN,
> + AIROHA_PCS_ANA_JCPLL_SSC_DELTA1 |
> + AIROHA_PCS_ANA_JCPLL_SSC_TRI_EN,
> + FIELD_PREP(AIROHA_PCS_ANA_JCPLL_SSC_DELTA1, 0x0));
> +
> + regmap_update_bits(priv->xfi_ana, AIROHA_PCS_ANA_PXP_JCPLL_VCO_TCLVAR,
> + AIROHA_PCS_ANA_JCPLL_SSC_PHASE_INI |
> + AIROHA_PCS_ANA_JCPLL_SSC_EN |
> + AIROHA_PCS_ANA_JCPLL_VCO_VCOVAR_BIAS_L |
> + AIROHA_PCS_ANA_JCPLL_VCO_TCLVAR,
> + FIELD_PREP(AIROHA_PCS_ANA_JCPLL_VCO_VCOVAR_BIAS_L, 0x0) |
> + FIELD_PREP(AIROHA_PCS_ANA_JCPLL_VCO_TCLVAR, 0x0));
> +
> + /* Setup LPF */
> + regmap_update_bits(priv->xfi_ana, AIROHA_PCS_ANA_PXP_JCPLL_IB_EXT_EN,
> + AIROHA_PCS_ANA_JCPLL_CHP_IOFST |
> + AIROHA_PCS_ANA_JCPLL_CHP_IBIAS |
> + AIROHA_PCS_ANA_JCPLL_LPF_SHCK_EN,
> + FIELD_PREP(AIROHA_PCS_ANA_JCPLL_CHP_IOFST, 0x0) |
> + FIELD_PREP(AIROHA_PCS_ANA_JCPLL_CHP_IBIAS, 0x18));
> +
> + regmap_update_bits(priv->xfi_ana, AIROHA_PCS_ANA_PXP_JCPLL_LPF_BR,
> + AIROHA_PCS_ANA_JCPLL_LPF_BWR |
> + AIROHA_PCS_ANA_JCPLL_LPF_BP |
> + AIROHA_PCS_ANA_JCPLL_LPF_BC |
> + AIROHA_PCS_ANA_JCPLL_LPF_BR,
> + FIELD_PREP(AIROHA_PCS_ANA_JCPLL_LPF_BWR, 0x0) |
> + FIELD_PREP(AIROHA_PCS_ANA_JCPLL_LPF_BP, 0x10) |
> + FIELD_PREP(AIROHA_PCS_ANA_JCPLL_LPF_BC, 0x1f) |
> + FIELD_PREP(AIROHA_PCS_ANA_JCPLL_LPF_BR, BIT(3) | BIT(1)));
> +
> + regmap_update_bits(priv->xfi_ana, AIROHA_PCS_ANA_PXP_JCPLL_LPF_BWC,
> + AIROHA_PCS_ANA_JCPLL_LPF_BWC,
> + FIELD_PREP(AIROHA_PCS_ANA_JCPLL_LPF_BWC, 0x0));
> +
> + /* Setup VCO */
> + regmap_update_bits(priv->xfi_ana, AIROHA_PCS_ANA_PXP_JCPLL_VCODIV,
> + AIROHA_PCS_ANA_JCPLL_VCO_SCAPWR |
> + AIROHA_PCS_ANA_JCPLL_VCO_HALFLSB_EN |
> + AIROHA_PCS_ANA_JCPLL_VCO_CFIX,
> + FIELD_PREP(AIROHA_PCS_ANA_JCPLL_VCO_SCAPWR, 0x4) |
> + AIROHA_PCS_ANA_JCPLL_VCO_HALFLSB_EN |
> + FIELD_PREP(AIROHA_PCS_ANA_JCPLL_VCO_CFIX, 0x1));
> +
> + regmap_update_bits(priv->xfi_ana, AIROHA_PCS_ANA_PXP_JCPLL_VCO_TCLVAR,
> + AIROHA_PCS_ANA_JCPLL_VCO_VCOVAR_BIAS_L |
> + AIROHA_PCS_ANA_JCPLL_VCO_VCOVAR_BIAS_H |
> + AIROHA_PCS_ANA_JCPLL_VCO_TCLVAR,
> + FIELD_PREP(AIROHA_PCS_ANA_JCPLL_VCO_VCOVAR_BIAS_L, 0x0) |
> + FIELD_PREP(AIROHA_PCS_ANA_JCPLL_VCO_VCOVAR_BIAS_H, 0x3) |
> + FIELD_PREP(AIROHA_PCS_ANA_JCPLL_VCO_TCLVAR, 0x3));
> +
> + /* Setup PCW */
> + regmap_update_bits(priv->xfi_pma, AIROHA_PCS_PMA_PXP_JCPLL_SDM_PCW,
> + AIROHA_PCS_PMA_FORCE_DA_JCPLL_SDM_PCW,
> + FIELD_PREP(AIROHA_PCS_PMA_FORCE_DA_JCPLL_SDM_PCW, 0x25800000));
> +
> + regmap_set_bits(priv->xfi_pma, AIROHA_PCS_PMA_PXP_RX_FE_VOS,
> + AIROHA_PCS_PMA_FORCE_SEL_DA_JCPLL_SDM_PCW);
> +
> + /* Setup DIV */
> + regmap_update_bits(priv->xfi_ana, AIROHA_PCS_ANA_PXP_JCPLL_MMD_PREDIV_MODE,
> + AIROHA_PCS_ANA_JCPLL_POSTDIV_D5 |
> + AIROHA_PCS_ANA_JCPLL_MMD_PREDIV_MODE,
> + AIROHA_PCS_ANA_JCPLL_MMD_PREDIV_MODE_2);
> +
> + regmap_update_bits(priv->xfi_ana, AIROHA_PCS_ANA_PXP_JCPLL_VCODIV,
> + AIROHA_PCS_ANA_JCPLL_VCODIV,
> + AIROHA_PCS_ANA_JCPLL_VCODIV_1);
> +
> + /* Setup KBand */
> + regmap_update_bits(priv->xfi_ana, AIROHA_PCS_ANA_PXP_JCPLL_KBAND_KFC,
> + AIROHA_PCS_ANA_JCPLL_KBAND_KS |
> + AIROHA_PCS_ANA_JCPLL_KBAND_KF |
> + AIROHA_PCS_ANA_JCPLL_KBAND_KFC,
> + FIELD_PREP(AIROHA_PCS_ANA_JCPLL_KBAND_KS, 0x0) |
> + FIELD_PREP(AIROHA_PCS_ANA_JCPLL_KBAND_KF, 0x3) |
> + FIELD_PREP(AIROHA_PCS_ANA_JCPLL_KBAND_KFC, 0x0));
> +
> + regmap_update_bits(priv->xfi_ana, AIROHA_PCS_ANA_PXP_JCPLL_LPF_BWC,
> + AIROHA_PCS_ANA_JCPLL_KBAND_DIV |
> + AIROHA_PCS_ANA_JCPLL_KBAND_CODE |
> + AIROHA_PCS_ANA_JCPLL_KBAND_OPTION,
> + FIELD_PREP(AIROHA_PCS_ANA_JCPLL_KBAND_DIV, 0x2) |
> + FIELD_PREP(AIROHA_PCS_ANA_JCPLL_KBAND_CODE, 0xe4));
> +
> + /* Setup TCL */
> + regmap_update_bits(priv->xfi_ana, AIROHA_PCS_ANA_PXP_JCPLL_SPARE_H,
> + AIROHA_PCS_ANA_JCPLL_TCL_KBAND_VREF,
> + FIELD_PREP(AIROHA_PCS_ANA_JCPLL_TCL_KBAND_VREF, kband_vref));
> +
> + regmap_update_bits(priv->xfi_ana, AIROHA_PCS_ANA_PXP_JCPLL_SDM_HREN,
> + AIROHA_PCS_ANA_JCPLL_TCL_AMP_VREF |
> + AIROHA_PCS_ANA_JCPLL_TCL_AMP_GAIN |
> + AIROHA_PCS_ANA_JCPLL_TCL_AMP_EN,
> + FIELD_PREP(AIROHA_PCS_ANA_JCPLL_TCL_AMP_VREF, 0x5) |
> + AIROHA_PCS_ANA_JCPLL_TCL_AMP_GAIN_4 |
> + AIROHA_PCS_ANA_JCPLL_TCL_AMP_EN);
> +
> + regmap_update_bits(priv->xfi_ana, AIROHA_PCS_ANA_PXP_JCPLL_TCL_CMP_EN,
> + AIROHA_PCS_ANA_JCPLL_TCL_LPF_BW |
> + AIROHA_PCS_ANA_JCPLL_TCL_LPF_EN,
> + AIROHA_PCS_ANA_JCPLL_TCL_LPF_BW_1 |
> + AIROHA_PCS_ANA_JCPLL_TCL_LPF_EN);
> +
> + /* Enable PLL */
> + regmap_set_bits(priv->xfi_pma, AIROHA_PCS_PMA_PXP_JCPLL_CKOUT_EN,
> + AIROHA_PCS_PMA_FORCE_DA_JCPLL_EN);
> +
> + /* Enale PLL Output */
> + regmap_set_bits(priv->xfi_pma, AIROHA_PCS_PMA_PXP_JCPLL_CKOUT_EN,
> + AIROHA_PCS_PMA_FORCE_SEL_DA_JCPLL_CKOUT_EN |
> + AIROHA_PCS_PMA_FORCE_DA_JCPLL_CKOUT_EN);
> +}
> +
> +static void airoha_pcs_txpll_bringup(struct airoha_pcs_priv *priv,
> + phy_interface_t interface)
> +{
> + u32 lpf_chp_ibias, lpf_bp, lpf_bwr, lpf_bwc;
> + u32 vco_cfix;
> + u32 pcw;
> + u32 tcl_amp_vref;
> + bool sdm_hren;
> + bool vcodiv;
> +
> + switch (interface) {
> + case PHY_INTERFACE_MODE_SGMII:
> + case PHY_INTERFACE_MODE_1000BASEX:
> + lpf_chp_ibias = 0xf;
> + lpf_bp = BIT(1);
> + lpf_bwr = BIT(3) | BIT(1) | BIT(0);
> + lpf_bwc = BIT(4) | BIT(3);
> + vco_cfix = BIT(1) | BIT(0);
> + pcw = BIT(27);
> + tcl_amp_vref = BIT(3) | BIT(1) | BIT(0);
> + vcodiv = false;
> + sdm_hren = false;
> + break;
> + case PHY_INTERFACE_MODE_2500BASEX:
> + lpf_chp_ibias = 0xa;
> + lpf_bp = BIT(2) | BIT(0);
> + lpf_bwr = 0;
> + lpf_bwc = 0;
> + vco_cfix = 0;
> + pcw = BIT(27) | BIT(25);
> + tcl_amp_vref = BIT(3) | BIT(2) | BIT(0);
> + vcodiv = true;
> + sdm_hren = false;
> + break;
> + case PHY_INTERFACE_MODE_USXGMII:
> + case PHY_INTERFACE_MODE_10GBASER:
> + lpf_chp_ibias = 0xf;
> + lpf_bp = BIT(1);
> + lpf_bwr = BIT(3) | BIT(1) | BIT(0);
> + lpf_bwc = BIT(4) | BIT(3);
> + vco_cfix = BIT(0);
> + pcw = BIT(27) | BIT(22);
> + tcl_amp_vref = BIT(3) | BIT(1) | BIT(0);
> + vcodiv = false;
> + sdm_hren = true;
> + break;
> + default:
> + return;
> + }
> +
> + /* Setup VCO LDO Output */
> + regmap_update_bits(priv->xfi_ana, AIROHA_PCS_ANA_PXP_TXPLL_SSC_PERIOD,
> + AIROHA_PCS_ANA_TXPLL_LDO_VCO_OUT |
> + AIROHA_PCS_ANA_TXPLL_LDO_OUT,
> + FIELD_PREP(AIROHA_PCS_ANA_TXPLL_LDO_VCO_OUT, 0x1) |
> + FIELD_PREP(AIROHA_PCS_ANA_TXPLL_LDO_OUT, 0x1));
> +
> + /* Setup RSTB */
> + regmap_update_bits(priv->xfi_ana, AIROHA_PCS_ANA_PXP_TXPLL_REFIN_INTERNAL,
> + AIROHA_PCS_ANA_TXPLL_PLL_RSTB |
> + AIROHA_PCS_ANA_TXPLL_RST_DLY |
> + AIROHA_PCS_ANA_TXPLL_REFIN_DIV |
> + AIROHA_PCS_ANA_TXPLL_REFIN_INTERNAL,
> + AIROHA_PCS_ANA_TXPLL_PLL_RSTB |
> + FIELD_PREP(AIROHA_PCS_ANA_TXPLL_RST_DLY, 0x4) |
> + AIROHA_PCS_ANA_TXPLL_REFIN_DIV_1 |
> + AIROHA_PCS_ANA_TXPLL_REFIN_INTERNAL);
> +
> + /* Enable PLL force selection and Force Disable */
> + regmap_update_bits(priv->xfi_pma, AIROHA_PCS_PMA_PXP_TXPLL_CKOUT_EN,
> + AIROHA_PCS_PMA_FORCE_SEL_DA_TXPLL_EN |
> + AIROHA_PCS_PMA_FORCE_DA_TXPLL_EN,
> + AIROHA_PCS_PMA_FORCE_SEL_DA_TXPLL_EN);
> +
> + /* Setup SDM */
> + regmap_update_bits(priv->xfi_ana, AIROHA_PCS_ANA_PXP_TXPLL_SDM_DI_EN,
> + AIROHA_PCS_ANA_TXPLL_SDM_MODE |
> + AIROHA_PCS_ANA_TXPLL_SDM_IFM |
> + AIROHA_PCS_ANA_TXPLL_SDM_DI_LS |
> + AIROHA_PCS_ANA_TXPLL_SDM_DI_EN,
> + FIELD_PREP(AIROHA_PCS_ANA_TXPLL_SDM_MODE, 0) |
> + AIROHA_PCS_ANA_TXPLL_SDM_DI_LS_2_23);
> +
> + regmap_update_bits(priv->xfi_ana, AIROHA_PCS_ANA_PXP_TXPLL_SDM_ORD,
> + AIROHA_PCS_ANA_TXPLL_SDM_HREN |
> + AIROHA_PCS_ANA_TXPLL_SDM_OUT |
> + AIROHA_PCS_ANA_TXPLL_SDM_ORD,
> + (sdm_hren ? AIROHA_PCS_ANA_TXPLL_SDM_HREN : 0) |
> + AIROHA_PCS_ANA_TXPLL_SDM_ORD_3SDM);
> +
> + /* Setup SSC */
> + regmap_update_bits(priv->xfi_ana, AIROHA_PCS_ANA_PXP_TXPLL_SSC_DELTA1,
> + AIROHA_PCS_ANA_TXPLL_SSC_DELTA |
> + AIROHA_PCS_ANA_TXPLL_SSC_DELTA1,
> + FIELD_PREP(AIROHA_PCS_ANA_TXPLL_SSC_DELTA, 0x0) |
> + FIELD_PREP(AIROHA_PCS_ANA_TXPLL_SSC_DELTA1, 0x0));
> +
> + regmap_clear_bits(priv->xfi_ana, AIROHA_PCS_ANA_PXP_TXPLL_SSC_EN,
> + AIROHA_PCS_ANA_TXPLL_SSC_TRI_EN |
> + AIROHA_PCS_ANA_TXPLL_SSC_PHASE_INI |
> + AIROHA_PCS_ANA_TXPLL_SSC_EN);
> +
> + regmap_update_bits(priv->xfi_ana, AIROHA_PCS_ANA_PXP_TXPLL_SSC_PERIOD,
> + AIROHA_PCS_ANA_TXPLL_SSC_PERIOD,
> + FIELD_PREP(AIROHA_PCS_ANA_TXPLL_SSC_PERIOD, 0x0));
> +
> + /* Setup LPF */
> + regmap_update_bits(priv->xfi_ana, AIROHA_PCS_ANA_PXP_TXPLL_CHP_IBIAS,
> + AIROHA_PCS_ANA_TXPLL_LPF_BC |
> + AIROHA_PCS_ANA_TXPLL_LPF_BR |
> + AIROHA_PCS_ANA_TXPLL_CHP_IOFST |
> + AIROHA_PCS_ANA_TXPLL_CHP_IBIAS,
> + FIELD_PREP(AIROHA_PCS_ANA_TXPLL_LPF_BC, 0x1f) |
> + FIELD_PREP(AIROHA_PCS_ANA_TXPLL_LPF_BR, 0x5) |
> + FIELD_PREP(AIROHA_PCS_ANA_TXPLL_CHP_IOFST, 0x0) |
> + FIELD_PREP(AIROHA_PCS_ANA_TXPLL_CHP_IBIAS, lpf_chp_ibias));
> +
> + regmap_update_bits(priv->xfi_ana, AIROHA_PCS_ANA_PXP_TXPLL_LPF_BP,
> + AIROHA_PCS_ANA_TXPLL_LPF_BWC |
> + AIROHA_PCS_ANA_TXPLL_LPF_BWR |
> + AIROHA_PCS_ANA_TXPLL_LPF_BP,
> + FIELD_PREP(AIROHA_PCS_ANA_TXPLL_LPF_BWC, lpf_bwc) |
> + FIELD_PREP(AIROHA_PCS_ANA_TXPLL_LPF_BWR, lpf_bwr) |
> + FIELD_PREP(AIROHA_PCS_ANA_TXPLL_LPF_BP, lpf_bp));
> +
> + /* Setup VCO */
> + regmap_update_bits(priv->xfi_ana, AIROHA_PCS_ANA_PXP_TXPLL_TCL_LPF_EN,
> + AIROHA_PCS_ANA_TXPLL_VCO_CFIX,
> + FIELD_PREP(AIROHA_PCS_ANA_TXPLL_VCO_CFIX, vco_cfix));
> +
> + regmap_update_bits(priv->xfi_ana, AIROHA_PCS_ANA_PXP_TXPLL_VCO_HALFLSB_EN,
> + AIROHA_PCS_ANA_TXPLL_VCO_VCOVAR_BIAS_L |
> + AIROHA_PCS_ANA_TXPLL_VCO_VCOVAR_BIAS_H |
> + AIROHA_PCS_ANA_TXPLL_VCO_TCLVAR |
> + AIROHA_PCS_ANA_TXPLL_VCO_SCAPWR |
> + AIROHA_PCS_ANA_TXPLL_VCO_HALFLSB_EN,
> + FIELD_PREP(AIROHA_PCS_ANA_TXPLL_VCO_VCOVAR_BIAS_L, 0x0) |
> + FIELD_PREP(AIROHA_PCS_ANA_TXPLL_VCO_VCOVAR_BIAS_H, 0x4) |
> + FIELD_PREP(AIROHA_PCS_ANA_TXPLL_VCO_TCLVAR, 0x4) |
> + FIELD_PREP(AIROHA_PCS_ANA_TXPLL_VCO_SCAPWR, 0x7) |
> + AIROHA_PCS_ANA_TXPLL_VCO_HALFLSB_EN);
> +
> + /* Setup PCW */
> + regmap_update_bits(priv->xfi_pma, AIROHA_PCS_PMA_PXP_TXPLL_SDM_PCW,
> + AIROHA_PCS_PMA_FORCE_DA_TXPLL_SDM_PCW, pcw);
> +
> + regmap_set_bits(priv->xfi_pma, AIROHA_PCS_PMA_PXP_CDR_PR_IDAC,
> + AIROHA_PCS_PMA_FORCE_SEL_DA_TXPLL_SDM_PCW);
> +
> + /* Setup KBand */
> + regmap_update_bits(priv->xfi_ana, AIROHA_PCS_ANA_PXP_TXPLL_KBAND_CODE,
> + AIROHA_PCS_ANA_TXPLL_KBAND_KF |
> + AIROHA_PCS_ANA_TXPLL_KBAND_KFC |
> + AIROHA_PCS_ANA_TXPLL_KBAND_DIV |
> + AIROHA_PCS_ANA_TXPLL_KBAND_CODE,
> + FIELD_PREP(AIROHA_PCS_ANA_TXPLL_KBAND_KF, 0x3) |
> + FIELD_PREP(AIROHA_PCS_ANA_TXPLL_KBAND_KFC, 0x0) |
> + FIELD_PREP(AIROHA_PCS_ANA_TXPLL_KBAND_DIV, 0x4) |
> + FIELD_PREP(AIROHA_PCS_ANA_TXPLL_KBAND_CODE, 0xe4));
> +
> + regmap_update_bits(priv->xfi_ana, AIROHA_PCS_ANA_PXP_TXPLL_KBAND_KS,
> + AIROHA_PCS_ANA_TXPLL_KBAND_KS,
> + FIELD_PREP(AIROHA_PCS_ANA_TXPLL_KBAND_KS, 0x1));
> +
> + regmap_clear_bits(priv->xfi_ana, AIROHA_PCS_ANA_PXP_TXPLL_LPF_BP,
> + AIROHA_PCS_ANA_TXPLL_KBAND_OPTION);
> +
> + /* Setup DIV */
> + regmap_update_bits(priv->xfi_ana, AIROHA_PCS_ANA_PXP_TXPLL_KBAND_KS,
> + AIROHA_PCS_ANA_TXPLL_MMD_PREDIV_MODE |
> + AIROHA_PCS_ANA_TXPLL_POSTDIV_EN,
> + AIROHA_PCS_ANA_TXPLL_MMD_PREDIV_MODE_2);
> +
> + regmap_update_bits(priv->xfi_ana, AIROHA_PCS_ANA_PXP_TXPLL_TCL_LPF_EN,
> + AIROHA_PCS_ANA_TXPLL_VCODIV,
> + vcodiv ? AIROHA_PCS_ANA_TXPLL_VCODIV_2 :
> + AIROHA_PCS_ANA_TXPLL_VCODIV_1);
> +
> + /* Setup TCL */
> + regmap_update_bits(priv->xfi_ana, AIROHA_PCS_ANA_PXP_TXPLL_TCL_KBAND_VREF,
> + AIROHA_PCS_ANA_TXPLL_TCL_KBAND_VREF,
> + FIELD_PREP(AIROHA_PCS_ANA_TXPLL_TCL_KBAND_VREF, 0xf));
> +
> + regmap_update_bits(priv->xfi_ana, AIROHA_PCS_ANA_PXP_TXPLL_TCL_AMP_GAIN,
> + AIROHA_PCS_ANA_TXPLL_TCL_AMP_VREF |
> + AIROHA_PCS_ANA_TXPLL_TCL_AMP_GAIN,
> + FIELD_PREP(AIROHA_PCS_ANA_TXPLL_TCL_AMP_VREF, tcl_amp_vref) |
> + AIROHA_PCS_ANA_TXPLL_TCL_AMP_GAIN_4);
> +
> + regmap_update_bits(priv->xfi_ana, AIROHA_PCS_ANA_PXP_TXPLL_TCL_LPF_EN,
> + AIROHA_PCS_ANA_TXPLL_TCL_LPF_BW |
> + AIROHA_PCS_ANA_TXPLL_TCL_LPF_EN,
> + AIROHA_PCS_ANA_TXPLL_TCL_LPF_BW_0_5 |
> + AIROHA_PCS_ANA_TXPLL_TCL_LPF_EN);
> +
> + regmap_set_bits(priv->xfi_ana, AIROHA_PCS_ANA_PXP_TXPLL_SDM_ORD,
> + AIROHA_PCS_ANA_TXPLL_TCL_AMP_EN);
> +
> + /* Enable PLL */
> + regmap_set_bits(priv->xfi_pma, AIROHA_PCS_PMA_PXP_TXPLL_CKOUT_EN,
> + AIROHA_PCS_PMA_FORCE_DA_TXPLL_EN);
> +
> + /* Enale PLL Output */
> + regmap_set_bits(priv->xfi_pma, AIROHA_PCS_PMA_PXP_TXPLL_CKOUT_EN,
> + AIROHA_PCS_PMA_FORCE_SEL_DA_TXPLL_CKOUT_EN |
> + AIROHA_PCS_PMA_FORCE_DA_TXPLL_CKOUT_EN);
> +}
> +
> +static void airoha_pcs_pll_bringup(struct airoha_pcs_priv *priv,
> + phy_interface_t interface)
> +{
> + airoha_pcs_jcpll_bringup(priv, interface);
> +
> + usleep_range(200, 300);
> +
> + airoha_pcs_txpll_bringup(priv, interface);
> +
> + usleep_range(200, 300);
> +}
> +
> +static void airoha_pcs_tx_bringup(struct airoha_pcs_priv *priv,
> + phy_interface_t interface)
> +{
> + u32 tx_rate_ctrl;
> + u32 ckin_divisor;
> + u32 fir_cn1, fir_c0b, fir_c1;
> +
> + switch (interface) {
> + case PHY_INTERFACE_MODE_SGMII:
> + case PHY_INTERFACE_MODE_1000BASEX:
> + ckin_divisor = BIT(1);
> + tx_rate_ctrl = BIT(0);
> + fir_cn1 = 0;
> + fir_c0b = 12;
> + fir_c1 = 0;
> + break;
> + case PHY_INTERFACE_MODE_2500BASEX:
> + ckin_divisor = BIT(2);
> + tx_rate_ctrl = BIT(0);
> + fir_cn1 = 0;
> + fir_c0b = 11;
> + fir_c1 = 1;
> + break;
> + case PHY_INTERFACE_MODE_USXGMII:
> + case PHY_INTERFACE_MODE_10GBASER:
> + ckin_divisor = BIT(2) | BIT(0);
> + tx_rate_ctrl = BIT(1);
> + fir_cn1 = 1;
> + fir_c0b = 1;
> + fir_c1 = 11;
> + break;
> + default:
> + return;
> + }
> +
> + /* Set TX rate ctrl */
> + regmap_update_bits(priv->xfi_pma, AIROHA_PCS_PMA_XPON_TX_RATE_CTRL,
> + AIROHA_PCS_PMA_PON_TX_RATE_CTRL,
> + FIELD_PREP(AIROHA_PCS_PMA_PON_TX_RATE_CTRL,
> + tx_rate_ctrl));
> +
> + /* Setup TX Config */
> + regmap_set_bits(priv->xfi_ana, AIROHA_PCS_ANA_PXP_TX_CKLDO_EN,
> + AIROHA_PCS_ANA_TX_DMEDGEGEN_EN |
> + AIROHA_PCS_ANA_TX_CKLDO_EN);
> +
> + udelay(1);
> +
> + regmap_set_bits(priv->xfi_pma, AIROHA_PCS_PMA_PXP_TX_ACJTAG_EN,
> + AIROHA_PCS_PMA_FORCE_SEL_DA_TX_CKIN_SEL |
> + AIROHA_PCS_PMA_FORCE_DA_TX_CKIN_SEL);
> +
> + /* FIXME: Ask Airoha TX term is OK to reset? */
> + regmap_update_bits(priv->xfi_pma, AIROHA_PCS_PMA_PXP_TX_TERM_SEL,
> + AIROHA_PCS_PMA_FORCE_SEL_DA_TX_CKIN_DIVISOR |
> + AIROHA_PCS_PMA_FORCE_DA_TX_CKIN_DIVISOR |
> + AIROHA_PCS_PMA_FORCE_SEL_DA_TX_TERM_SEL |
> + AIROHA_PCS_PMA_FORCE_DA_TX_TERM_SEL,
> + AIROHA_PCS_PMA_FORCE_SEL_DA_TX_CKIN_DIVISOR |
> + FIELD_PREP(AIROHA_PCS_PMA_FORCE_DA_TX_CKIN_DIVISOR,
> + ckin_divisor) |
> + FIELD_PREP(AIROHA_PCS_PMA_FORCE_DA_TX_TERM_SEL, 0x0));
> +
> + regmap_update_bits(priv->xfi_pma, AIROHA_PCS_PMA_PXP_TX_RATE_CTRL,
> + AIROHA_PCS_PMA_FORCE_SEL_DA_TX_RATE_CTRL |
> + AIROHA_PCS_PMA_FORCE_DA_TX_RATE_CTRL,
> + AIROHA_PCS_PMA_FORCE_SEL_DA_TX_RATE_CTRL |
> + FIELD_PREP(AIROHA_PCS_PMA_FORCE_DA_TX_RATE_CTRL,
> + tx_rate_ctrl));
> +
> + /* Setup TX FIR Load Parameters (Reference 660mV) */
> + regmap_update_bits(priv->xfi_pma, AIROHA_PCS_PMA_PXP_TX_FIR_C0B,
> + AIROHA_PCS_PMA_FORCE_SEL_DA_TX_FIR_CN1 |
> + AIROHA_PCS_PMA_FORCE_DA_TX_FIR_CN1 |
> + AIROHA_PCS_PMA_FORCE_SEL_DA_TX_FIR_C0B |
> + AIROHA_PCS_PMA_FORCE_DA_TX_FIR_C0B,
> + AIROHA_PCS_PMA_FORCE_SEL_DA_TX_FIR_CN1 |
> + FIELD_PREP(AIROHA_PCS_PMA_FORCE_DA_TX_FIR_CN1, fir_cn1) |
> + AIROHA_PCS_PMA_FORCE_SEL_DA_TX_FIR_C0B |
> + FIELD_PREP(AIROHA_PCS_PMA_FORCE_DA_TX_FIR_C0B, fir_c0b));
> +
> + regmap_update_bits(priv->xfi_pma, AIROHA_PCS_PMA_PXP_TX_FIR_C1,
> + AIROHA_PCS_PMA_FORCE_SEL_DA_TX_FIR_C2 |
> + AIROHA_PCS_PMA_FORCE_DA_TX_FIR_C2 |
> + AIROHA_PCS_PMA_FORCE_SEL_DA_TX_FIR_C1 |
> + AIROHA_PCS_PMA_FORCE_DA_TX_FIR_C1,
> + AIROHA_PCS_PMA_FORCE_SEL_DA_TX_FIR_C1 |
> + FIELD_PREP(AIROHA_PCS_PMA_FORCE_DA_TX_FIR_C1, fir_c1));
> +
> + /* Reset TX Bar */
> + regmap_set_bits(priv->xfi_pma, AIROHA_PCS_PMA_TX_RST_B,
> + AIROHA_PCS_PMA_TXCALIB_RST_B | AIROHA_PCS_PMA_TX_TOP_RST_B);
> +}
> +
> +static void airoha_pcs_rx_bringup(struct airoha_pcs_priv *priv,
> + phy_interface_t interface)
> +{
> + u32 rx_rate_ctrl;
> + u32 osr;
> + u32 pr_cdr_beta_dac;
> + u32 cdr_pr_buf_in_sr;
> + bool cdr_pr_cap_en;
> + u32 sigdet_vth_sel;
> + u32 phyck_div, phyck_sel;
> +
> + switch (interface) {
> + case PHY_INTERFACE_MODE_SGMII:
> + case PHY_INTERFACE_MODE_1000BASEX:
> + osr = BIT(1) | BIT(0); /* 1.25G */
> + pr_cdr_beta_dac = BIT(3);
> + rx_rate_ctrl = 0;
> + cdr_pr_cap_en = false;
> + cdr_pr_buf_in_sr = BIT(2) | BIT(1) | BIT(0);
> + sigdet_vth_sel = BIT(2) | BIT(1);
> + phyck_div = BIT(5) | BIT(3) | BIT(0);
> + phyck_sel = BIT(0);
> + break;
> + case PHY_INTERFACE_MODE_2500BASEX:
> + osr = BIT(0); /* 2.5G */
> + pr_cdr_beta_dac = BIT(2) | BIT(1);
> + rx_rate_ctrl = 0;
> + cdr_pr_cap_en = true;
> + cdr_pr_buf_in_sr = BIT(2) | BIT(1);
> + sigdet_vth_sel = BIT(2) | BIT(1);
> + phyck_div = BIT(3) | BIT(1) | BIT(0);
> + phyck_sel = BIT(0);
> + break;
> + case PHY_INTERFACE_MODE_USXGMII:
> + case PHY_INTERFACE_MODE_10GBASER:
> + osr = 0; /* 10G */
> + cdr_pr_cap_en = false;
> + pr_cdr_beta_dac = BIT(3);
> + rx_rate_ctrl = BIT(1);
> + cdr_pr_buf_in_sr = BIT(2) | BIT(1) | BIT(0);
> + sigdet_vth_sel = BIT(1);
> + phyck_div = BIT(6) | BIT(1);
> + phyck_sel = BIT(1);
> + break;
> + default:
> + return;
> + }
> +
> + /* Set RX rate ctrl */
> + if (interface == PHY_INTERFACE_MODE_2500BASEX)
> + regmap_update_bits(priv->xfi_pma, AIROHA_PCS_PMA_RX_FLL_2,
> + AIROHA_PCS_PMA_CK_RATE,
> + AIROHA_PCS_PMA_CK_RATE_10);
> +
> + regmap_update_bits(priv->xfi_pma, AIROHA_PCS_PMA_XPON_RX_RESERVED_1,
> + AIROHA_PCS_PMA_XPON_RX_RATE_CTRL,
> + FIELD_PREP(AIROHA_PCS_PMA_XPON_RX_RATE_CTRL, rx_rate_ctrl));
> +
> + /* Setup RX Path */
> + regmap_update_bits(priv->xfi_pma, AIROHA_PCS_PMA_RX_FLL_5,
> + AIROHA_PCS_PMA_FLL_IDAC_MIN |
> + AIROHA_PCS_PMA_FLL_IDAC_MAX,
> + FIELD_PREP(AIROHA_PCS_PMA_FLL_IDAC_MIN, 0x400) |
> + FIELD_PREP(AIROHA_PCS_PMA_FLL_IDAC_MAX, 0x3ff));
> +
> + regmap_set_bits(priv->xfi_ana, AIROHA_PCS_ANA_PXP_RX_DAC_D1_BYPASS_AEQ,
> + AIROHA_PCS_ANA_RX_DAC_EYE_BYPASS_AEQ |
> + AIROHA_PCS_ANA_RX_DAC_E1_BYPASS_AEQ |
> + AIROHA_PCS_ANA_RX_DAC_E0_BYPASS_AEQ |
> + AIROHA_PCS_ANA_RX_DAC_D1_BYPASS_AEQ);
> +
> + regmap_set_bits(priv->xfi_ana, AIROHA_PCS_ANA_PXP_RX_FE_PEAKING_CTRL_MSB,
> + AIROHA_PCS_ANA_RX_DAC_D0_BYPASS_AEQ);
> +
> + regmap_set_bits(priv->xfi_ana, AIROHA_PCS_ANA_PXP_RX_FE_VCM_GEN_PWDB,
> + AIROHA_PCS_ANA_FE_VCM_GEN_PWDB);
> +
> + regmap_set_bits(priv->xfi_pma, AIROHA_PCS_PMA_SS_LCPLL_PWCTL_SETTING_1,
> + AIROHA_PCS_PMA_LCPLL_MAN_PWDB);
> +
> + regmap_update_bits(priv->xfi_ana, AIROHA_PCS_ANA_PXP_AEQ_CFORCE,
> + AIROHA_PCS_ANA_AEQ_OFORCE,
> + AIROHA_PCS_ANA_AEQ_OFORCE_CTLE);
> +
> + regmap_update_bits(priv->xfi_ana, AIROHA_PCS_ANA_PXP_RX_OSCAL_WATCH_WNDW,
> + AIROHA_PCS_ANA_RX_OSCAL_FORCE,
> + AIROHA_PCS_ANA_RX_OSCAL_FORCE_VGA2VOS |
> + AIROHA_PCS_ANA_RX_OSCAL_FORCE_VGA2IOS |
> + AIROHA_PCS_ANA_RX_OSCAL_FORCE_VGA1VOS |
> + AIROHA_PCS_ANA_RX_OSCAL_FORCE_VGA1IOS |
> + AIROHA_PCS_ANA_RX_OSCAL_FORCE_CTLE2VOS |
> + AIROHA_PCS_ANA_RX_OSCAL_FORCE_CTLE2IOS |
> + AIROHA_PCS_ANA_RX_OSCAL_FORCE_CTLE1VOS |
> + AIROHA_PCS_ANA_RX_OSCAL_FORCE_CTLE1IOS |
> + AIROHA_PCS_ANA_RX_OSCAL_FORCE_LVSH |
> + AIROHA_PCS_ANA_RX_OSCAL_FORCE_COMPOS);
> +
> + regmap_clear_bits(priv->xfi_pma, AIROHA_PCS_PMA_RX_DISB_MODE_4,
> + AIROHA_PCS_PMA_DISB_BLWC_OFFSET);
> +
> + regmap_clear_bits(priv->xfi_pma, AIROHA_PCS_PMA_RX_EXTRAL_CTRL,
> + AIROHA_PCS_PMA_DISB_LEQ);
> +
> + regmap_clear_bits(priv->xfi_ana, AIROHA_PCS_ANA_PXP_CDR_PD_PICAL_CKD8_INV,
> + AIROHA_PCS_ANA_CDR_PD_EDGE_DIS |
> + AIROHA_PCS_ANA_CDR_PD_PICAL_CKD8_INV);
> +
> + regmap_update_bits(priv->xfi_pma, AIROHA_PCS_PMA_PXP_AEQ_BYPASS,
> + AIROHA_PCS_PMA_FORCE_SEL_DA_AEQ_CKON |
> + AIROHA_PCS_PMA_FORCE_DA_AEQ_CKON,
> + AIROHA_PCS_PMA_FORCE_SEL_DA_AEQ_CKON);
> +
> + regmap_set_bits(priv->xfi_pma, AIROHA_PCS_PMA_PXP_AEQ_RSTB,
> + AIROHA_PCS_PMA_FORCE_SEL_DA_CDR_INJCK_SEL |
> + AIROHA_PCS_PMA_FORCE_DA_CDR_INJCK_SEL);
> +
> + regmap_update_bits(priv->xfi_ana, AIROHA_PCS_ANA_PXP_CDR_PR_MONPR_EN,
> + AIROHA_PCS_ANA_RX_DAC_MON |
> + AIROHA_PCS_ANA_CDR_PR_XFICK_EN |
> + AIROHA_PCS_ANA_CDR_PR_MONDPI_EN |
> + AIROHA_PCS_ANA_CDR_PR_MONDPR_EN,
> + FIELD_PREP(AIROHA_PCS_ANA_RX_DAC_MON, 0x0) |
> + AIROHA_PCS_ANA_CDR_PR_XFICK_EN);
> +
> + /* Setup FE Gain and FE Peacking */
> + regmap_update_bits(priv->xfi_pma, AIROHA_PCS_PMA_PXP_FE_GAIN_CTRL,
> + AIROHA_PCS_PMA_FORCE_SEL_DA_RX_FE_GAIN_CTRL |
> + AIROHA_PCS_PMA_FORCE_DA_RX_FE_GAIN_CTRL,
> + FIELD_PREP(AIROHA_PCS_PMA_FORCE_DA_RX_FE_GAIN_CTRL, 0x0));
> +
> + regmap_update_bits(priv->xfi_pma, AIROHA_PCS_PMA_PXP_JCPLL_SDM_SCAN,
> + AIROHA_PCS_PMA_FORCE_SEL_DA_RX_PEAKING_CTRL |
> + AIROHA_PCS_PMA_FORCE_DA_RX_PEAKING_CTRL,
> + FIELD_PREP(AIROHA_PCS_PMA_FORCE_DA_RX_PEAKING_CTRL, 0x0));
> +
> + /* Setup FE VOS */
> + if (interface != PHY_INTERFACE_MODE_USXGMII &&
> + interface != PHY_INTERFACE_MODE_10GBASER)
> + regmap_update_bits(priv->xfi_pma, AIROHA_PCS_PMA_PXP_RX_FE_VOS,
> + AIROHA_PCS_PMA_FORCE_SEL_DA_FE_VOS |
> + AIROHA_PCS_PMA_FORCE_DA_FE_VOS,
> + AIROHA_PCS_PMA_FORCE_SEL_DA_FE_VOS |
> + FIELD_PREP(AIROHA_PCS_PMA_FORCE_DA_FE_VOS, 0x0));
> +
> + /* Setup FLL PR FMeter (no bypass mode)*/
> + regmap_update_bits(priv->xfi_pma, AIROHA_PCS_PMA_PLL_TDC_FREQDET_0,
> + AIROHA_PCS_PMA_PLL_LOCK_CYCLECNT,
> + FIELD_PREP(AIROHA_PCS_PMA_PLL_LOCK_CYCLECNT, 0x1));
> +
> + regmap_update_bits(priv->xfi_pma, AIROHA_PCS_PMA_PLL_TDC_FREQDET_1,
> + AIROHA_PCS_PMA_PLL_LOCK_TARGET_END |
> + AIROHA_PCS_PMA_PLL_LOCK_TARGET_BEG,
> + FIELD_PREP(AIROHA_PCS_PMA_PLL_LOCK_TARGET_END, 0xffff) |
> + FIELD_PREP(AIROHA_PCS_PMA_PLL_LOCK_TARGET_BEG, 0x0));
> +
> + regmap_update_bits(priv->xfi_pma, AIROHA_PCS_PMA_PLL_TDC_FREQDET_3,
> + AIROHA_PCS_PMA_PLL_LOCK_LOCKTH,
> + FIELD_PREP(AIROHA_PCS_PMA_PLL_LOCK_LOCKTH, 0x1));
> +
> + /* FIXME: Warn and Ask Airoha about typo in air_eth_xsgmii.c line 1391 */
> + /* AIROHA_PCS_ANA_REV_1_FE_BUF1_BIAS_CTRL is set 0x0 in SDK but seems a typo */
> + /* Setup REV */
> + regmap_update_bits(priv->xfi_ana, AIROHA_PCS_ANA_PXP_RX_REV_0,
> + AIROHA_PCS_ANA_REV_1_FE_BUF1_BIAS_CTRL |
> + AIROHA_PCS_ANA_REV_1_FE_BUF2_BIAS_CTRL |
> + AIROHA_PCS_ANA_REV_1_SIGDET_ILEAK,
> + FIELD_PREP(AIROHA_PCS_ANA_REV_1_FE_BUF1_BIAS_CTRL, BIT(2)) |
> + FIELD_PREP(AIROHA_PCS_ANA_REV_1_FE_BUF2_BIAS_CTRL, BIT(2)) |
> + FIELD_PREP(AIROHA_PCS_ANA_REV_1_SIGDET_ILEAK, 0x0));
> +
> + /* Setup Rdy Timeout */
> + regmap_update_bits(priv->xfi_pma, AIROHA_PCS_PMA_RX_CTRL_SEQUENCE_CTRL_5,
> + AIROHA_PCS_PMA_RX_RDY |
> + AIROHA_PCS_PMA_RX_BLWC_RDY_EN,
> + FIELD_PREP(AIROHA_PCS_PMA_RX_RDY, 0xa) |
> + FIELD_PREP(AIROHA_PCS_PMA_RX_BLWC_RDY_EN, 0x5));
> +
> + /* Setup CaBoundry Init */
> + regmap_update_bits(priv->xfi_pma, AIROHA_PCS_PMA_RX_CTRL_SEQUENCE_CTRL_0,
> + AIROHA_PCS_PMA_RX_OS_START |
> + AIROHA_PCS_PMA_OSC_SPEED_OPT,
> + FIELD_PREP(AIROHA_PCS_PMA_RX_OS_START, 0x1) |
> + AIROHA_PCS_PMA_OSC_SPEED_OPT_0_1);
> +
> + regmap_update_bits(priv->xfi_pma, AIROHA_PCS_PMA_RX_CTRL_SEQUENCE_CTRL_6,
> + AIROHA_PCS_PMA_RX_OS_END,
> + FIELD_PREP(AIROHA_PCS_PMA_RX_OS_END, 0x2));
> +
> + regmap_update_bits(priv->xfi_pma, AIROHA_PCS_PMA_RX_CTRL_SEQUENCE_CTRL_1,
> + AIROHA_PCS_PMA_RX_PICAL_END |
> + AIROHA_PCS_PMA_RX_PICAL_START,
> + FIELD_PREP(AIROHA_PCS_PMA_RX_PICAL_END, 0x32) |
> + FIELD_PREP(AIROHA_PCS_PMA_RX_PICAL_START, 0x2));
> +
> + regmap_update_bits(priv->xfi_pma, AIROHA_PCS_PMA_RX_CTRL_SEQUENCE_CTRL_4,
> + AIROHA_PCS_PMA_RX_SDCAL_END |
> + AIROHA_PCS_PMA_RX_SDCAL_START,
> + FIELD_PREP(AIROHA_PCS_PMA_RX_SDCAL_END, 0x32) |
> + FIELD_PREP(AIROHA_PCS_PMA_RX_SDCAL_START, 0x2));
> +
> + regmap_update_bits(priv->xfi_pma, AIROHA_PCS_PMA_RX_CTRL_SEQUENCE_CTRL_2,
> + AIROHA_PCS_PMA_RX_PDOS_END |
> + AIROHA_PCS_PMA_RX_PDOS_START,
> + FIELD_PREP(AIROHA_PCS_PMA_RX_PDOS_END, 0x32) |
> + FIELD_PREP(AIROHA_PCS_PMA_RX_PDOS_START, 0x2));
> +
> + regmap_update_bits(priv->xfi_pma, AIROHA_PCS_PMA_RX_CTRL_SEQUENCE_CTRL_3,
> + AIROHA_PCS_PMA_RX_FEOS_END |
> + AIROHA_PCS_PMA_RX_FEOS_START,
> + FIELD_PREP(AIROHA_PCS_PMA_RX_FEOS_END, 0x32) |
> + FIELD_PREP(AIROHA_PCS_PMA_RX_FEOS_START, 0x2));
> +
> + /* Setup By Serdes*/
> + regmap_update_bits(priv->xfi_pma, AIROHA_PCS_PMA_PXP_AEQ_SPEED,
> + AIROHA_PCS_PMA_FORCE_SEL_DA_OSR_SEL |
> + AIROHA_PCS_PMA_FORCE_DA_OSR_SEL,
> + AIROHA_PCS_PMA_FORCE_SEL_DA_OSR_SEL |
> + FIELD_PREP(AIROHA_PCS_PMA_FORCE_DA_OSR_SEL, osr));
> +
> + /* Setup RX OSR */
> + regmap_update_bits(priv->xfi_ana, AIROHA_PCS_ANA_PXP_CDR_PD_PICAL_CKD8_INV,
> + AIROHA_PCS_ANA_CDR_PD_EDGE_DIS,
> + osr ? AIROHA_PCS_ANA_CDR_PD_EDGE_DIS : 0);
> +
> + /* Setup CDR LPF Ratio */
> + regmap_update_bits(priv->xfi_ana, AIROHA_PCS_ANA_PXP_CDR_LPF_RATIO,
> + AIROHA_PCS_ANA_CDR_LPF_TOP_LIM |
> + AIROHA_PCS_ANA_CDR_LPF_RATIO,
> + FIELD_PREP(AIROHA_PCS_ANA_CDR_LPF_TOP_LIM, 0x20000) |
> + FIELD_PREP(AIROHA_PCS_ANA_CDR_LPF_RATIO, osr));
> +
> + /* Setup CDR PR */
> + regmap_update_bits(priv->xfi_ana, AIROHA_PCS_ANA_PXP_CDR_PR_BETA_DAC,
> + AIROHA_PCS_ANA_CDR_PR_KBAND_DIV |
> + AIROHA_PCS_ANA_CDR_PR_BETA_SEL |
> + AIROHA_PCS_ANA_CDR_PR_VCOADC_OS |
> + AIROHA_PCS_ANA_CDR_PR_BETA_DAC,
> + FIELD_PREP(AIROHA_PCS_ANA_CDR_PR_KBAND_DIV, 0x4) |
> + FIELD_PREP(AIROHA_PCS_ANA_CDR_PR_BETA_SEL, 0x1) |
> + FIELD_PREP(AIROHA_PCS_ANA_CDR_PR_VCOADC_OS, 0x8) |
> + FIELD_PREP(AIROHA_PCS_ANA_CDR_PR_BETA_DAC, pr_cdr_beta_dac));
> +
> + regmap_update_bits(priv->xfi_ana, AIROHA_PCS_ANA_PXP_CDR_PR_VREG_IBAND_VAL,
> + AIROHA_PCS_ANA_CDR_PR_FBKSEL |
> + AIROHA_PCS_ANA_CDR_PR_VREG_DAC_BAND |
> + AIROHA_PCS_ANA_CDR_PR_VREG_CKBUF_VAL |
> + AIROHA_PCS_ANA_CDR_PR_VREG_IBAND_VAL,
> + FIELD_PREP(AIROHA_PCS_ANA_CDR_PR_FBKSEL, 0x0) |
> + FIELD_PREP(AIROHA_PCS_ANA_CDR_PR_VREG_DAC_BAND, pr_cdr_beta_dac) |
> + FIELD_PREP(AIROHA_PCS_ANA_CDR_PR_VREG_CKBUF_VAL, 0x6) |
> + FIELD_PREP(AIROHA_PCS_ANA_CDR_PR_VREG_IBAND_VAL, 0x6));
> +
> + /* Setup Eye Mon */
> + regmap_update_bits(priv->xfi_pma, AIROHA_PCS_PMA_PHY_EQ_CTRL_3,
> + AIROHA_PCS_PMA_EQ_DEBUG_SEL |
> + AIROHA_PCS_PMA_FOM_NUM_ORDER |
> + AIROHA_PCS_PMA_A_SEL,
> + FIELD_PREP(AIROHA_PCS_PMA_EQ_DEBUG_SEL, 0x0) |
> + FIELD_PREP(AIROHA_PCS_PMA_FOM_NUM_ORDER, 0x1) |
> + FIELD_PREP(AIROHA_PCS_PMA_A_SEL, 0x3));
> +
> + regmap_update_bits(priv->xfi_pma, AIROHA_PCS_PMA_RX_EYE_TOP_EYECNT_CTRL_2,
> + AIROHA_PCS_PMA_DATA_SHIFT |
> + AIROHA_PCS_PMA_EYECNT_FAST,
> + AIROHA_PCS_PMA_EYECNT_FAST);
> +
> + /* Calibration Start */
> +
> + /* Enable SYS */
> + regmap_update_bits(priv->xfi_pma, AIROHA_PCS_PMA_RX_SYS_EN_SEL_0,
> + AIROHA_PCS_PMA_RX_SYS_EN_SEL,
> + FIELD_PREP(AIROHA_PCS_PMA_RX_SYS_EN_SEL, 0x1));
> +
> + regmap_set_bits(priv->xfi_pma, AIROHA_PCS_PMA_SS_LCPLL_PWCTL_SETTING_0,
> + AIROHA_PCS_PMA_SW_LCPLL_EN);
> +
> + usleep_range(500, 600);
> +
> + /* Setup FLL PR FMeter (bypass mode)*/
> + regmap_clear_bits(priv->xfi_pma, AIROHA_PCS_PMA_RX_DISB_MODE_8,
> + AIROHA_PCS_PMA_DISB_FBCK_LOCK);
> +
> + regmap_set_bits(priv->xfi_pma, AIROHA_PCS_PMA_RX_FORCE_MODE_9,
> + AIROHA_PCS_PMA_FORCE_FBCK_LOCK);
> +
> + /* Enable CMLEQ */
> + regmap_update_bits(priv->xfi_ana, AIROHA_PCS_ANA_PXP_RX_FE_EQ_HZEN,
> + AIROHA_PCS_ANA_RX_FE_VB_EQ3_EN |
> + AIROHA_PCS_ANA_RX_FE_VB_EQ2_EN |
> + AIROHA_PCS_ANA_RX_FE_VB_EQ1_EN |
> + AIROHA_PCS_ANA_RX_FE_EQ_HZEN,
> + AIROHA_PCS_ANA_RX_FE_VB_EQ3_EN |
> + AIROHA_PCS_ANA_RX_FE_VB_EQ2_EN |
> + AIROHA_PCS_ANA_RX_FE_VB_EQ1_EN);
> +
> + /* Setup CDR PR */
> + regmap_update_bits(priv->xfi_ana, AIROHA_PCS_ANA_PXP_CDR_PR_MONPR_EN,
> + AIROHA_PCS_ANA_CDR_PR_CAP_EN |
> + AIROHA_PCS_ANA_CDR_BUF_IN_SR,
> + (cdr_pr_cap_en ? AIROHA_PCS_ANA_CDR_PR_CAP_EN : 0) |
> + FIELD_PREP(AIROHA_PCS_ANA_CDR_BUF_IN_SR, cdr_pr_buf_in_sr));
> +
> + /* Setup CDR xxx Pwdb, set force and disable */
> + regmap_update_bits(priv->xfi_pma, AIROHA_PCS_PMA_PXP_CDR_PR_PIEYE_PWDB,
> + AIROHA_PCS_PMA_FORCE_SEL_DA_CDR_PR_PWDB |
> + AIROHA_PCS_PMA_FORCE_DA_CDR_PR_PWDB |
> + AIROHA_PCS_PMA_FORCE_SEL_DA_CDR_PR_PIEYE_PWDB |
> + AIROHA_PCS_PMA_FORCE_DA_CDR_PR_PIEYE_PWDB,
> + AIROHA_PCS_PMA_FORCE_SEL_DA_CDR_PR_PWDB |
> + AIROHA_PCS_PMA_FORCE_SEL_DA_CDR_PR_PIEYE_PWDB);
> +
> + regmap_update_bits(priv->xfi_pma, AIROHA_PCS_PMA_PXP_CDR_PD_PWDB,
> + AIROHA_PCS_PMA_FORCE_SEL_DA_CDR_PR_KBAND_RSTB |
> + AIROHA_PCS_PMA_FORCE_DA_CDR_PR_KBAND_RSTB |
> + AIROHA_PCS_PMA_FORCE_SEL_DA_CDR_PD_PWDB |
> + AIROHA_PCS_PMA_FORCE_DA_CDR_PR_PD_PWDB,
> + AIROHA_PCS_PMA_FORCE_SEL_DA_CDR_PD_PWDB);
> +
> + regmap_update_bits(priv->xfi_pma, AIROHA_PCS_PMA_PXP_RX_FE_PWDB,
> + AIROHA_PCS_PMA_FORCE_SEL_DA_RX_PDOSCAL_EN |
> + AIROHA_PCS_PMA_FORCE_DA_RX_PDOSCAL_EN |
> + AIROHA_PCS_PMA_FORCE_SEL_DA_RX_FE_PWDB |
> + AIROHA_PCS_PMA_FORCE_DA_RX_FE_PWDB,
> + AIROHA_PCS_PMA_FORCE_SEL_DA_RX_FE_PWDB);
> +
> + regmap_update_bits(priv->xfi_pma, AIROHA_PCS_PMA_PXP_RX_SCAN_RST_B,
> + AIROHA_PCS_PMA_FORCE_SEL_DA_RX_SIGDET_PWDB |
> + AIROHA_PCS_PMA_FORCE_DA_RX_SIGDET_PWDB |
> + AIROHA_PCS_PMA_FORCE_SEL_DA_RX_SCAN_RST_B |
> + AIROHA_PCS_PMA_FORCE_DA_RX_SCAN_RST_B,
> + AIROHA_PCS_PMA_FORCE_SEL_DA_RX_SIGDET_PWDB);
> +
> + regmap_clear_bits(priv->xfi_pma, AIROHA_PCS_PMA_SS_DA_XPON_PWDB_0,
> + AIROHA_PCS_PMA_XPON_CDR_PR_PD_PWDB |
> + AIROHA_PCS_PMA_XPON_CDR_PR_PIEYE_PWDB |
> + AIROHA_PCS_PMA_XPON_CDR_PW_PWDB |
> + AIROHA_PCS_PMA_XPON_RX_FE_PWDB);
> +
> + /* FIXME: Ask Airoha WHY it's cleared? */
> + /* regmap_clear_bits(priv->xfi_ana, AIROHA_PCS_ANA_PXP_RX_SIGDET_NOVTH,
> + * AIROHA_PCS_ANA_RX_FE_50OHMS_SEL);
> + */
> +
> + /* Setup SigDet */
> + regmap_update_bits(priv->xfi_ana, AIROHA_PCS_ANA_PXP_RX_SIGDET_NOVTH,
> + AIROHA_PCS_ANA_RX_SIGDET_VTH_SEL |
> + AIROHA_PCS_ANA_RX_SIGDET_PEAK,
> + FIELD_PREP(AIROHA_PCS_ANA_RX_SIGDET_VTH_SEL, sigdet_vth_sel) |
> + FIELD_PREP(AIROHA_PCS_ANA_RX_SIGDET_PEAK, BIT(1)));
> +
> + regmap_update_bits(priv->xfi_ana, AIROHA_PCS_ANA_PXP_RX_DAC_RANGE,
> + AIROHA_PCS_ANA_RX_SIGDET_LPF_CTRL,
> + FIELD_PREP(AIROHA_PCS_ANA_RX_SIGDET_LPF_CTRL, BIT(1) | BIT(0)));
> +
> + /* Disable SigDet Pwdb */
> + regmap_clear_bits(priv->xfi_pma, AIROHA_PCS_PMA_SS_DA_XPON_PWDB_1,
> + AIROHA_PCS_PMA_RX_SIDGET_PWDB);
> +
> + /* Setup PHYCK */
> + regmap_update_bits(priv->xfi_ana, AIROHA_PCS_ANA_PXP_RX_PHYCK_DIV,
> + AIROHA_PCS_ANA_RX_TDC_CK_SEL |
> + AIROHA_PCS_ANA_RX_PHYCK_RSTB |
> + AIROHA_PCS_ANA_RX_PHYCK_SEL |
> + AIROHA_PCS_ANA_RX_PHYCK_DIV,
> + AIROHA_PCS_ANA_RX_PHYCK_RSTB |
> + FIELD_PREP(AIROHA_PCS_ANA_RX_PHYCK_SEL, phyck_sel) |
> + FIELD_PREP(AIROHA_PCS_ANA_RX_PHYCK_DIV, phyck_div));
> +
> + regmap_update_bits(priv->xfi_ana, AIROHA_PCS_ANA_PXP_RX_BUSBIT_SEL,
> + AIROHA_PCS_ANA_RX_PHY_CK_SEL_FORCE |
> + AIROHA_PCS_ANA_RX_PHY_CK_SEL,
> + AIROHA_PCS_ANA_RX_PHY_CK_SEL_FORCE);
> +
> + usleep_range(100, 200);
> +
> + /* Enable CDR xxx Pwdb */
> + regmap_set_bits(priv->xfi_pma, AIROHA_PCS_PMA_PXP_CDR_PR_PIEYE_PWDB,
> + AIROHA_PCS_PMA_FORCE_DA_CDR_PR_PWDB |
> + AIROHA_PCS_PMA_FORCE_DA_CDR_PR_PIEYE_PWDB);
> +
> + regmap_set_bits(priv->xfi_pma, AIROHA_PCS_PMA_PXP_CDR_PD_PWDB,
> + AIROHA_PCS_PMA_FORCE_DA_CDR_PR_PD_PWDB);
> +
> + regmap_set_bits(priv->xfi_pma, AIROHA_PCS_PMA_PXP_RX_FE_PWDB,
> + AIROHA_PCS_PMA_FORCE_DA_RX_FE_PWDB);
> +
> + regmap_set_bits(priv->xfi_pma, AIROHA_PCS_PMA_PXP_RX_SCAN_RST_B,
> + AIROHA_PCS_PMA_FORCE_DA_RX_SIGDET_PWDB);
> +
> + regmap_set_bits(priv->xfi_pma, AIROHA_PCS_PMA_SS_DA_XPON_PWDB_0,
> + AIROHA_PCS_PMA_XPON_CDR_PR_PD_PWDB |
> + AIROHA_PCS_PMA_XPON_CDR_PR_PIEYE_PWDB |
> + AIROHA_PCS_PMA_XPON_CDR_PW_PWDB |
> + AIROHA_PCS_PMA_XPON_RX_FE_PWDB);
> +
> + /* Enable SigDet Pwdb */
> + regmap_set_bits(priv->xfi_pma, AIROHA_PCS_PMA_SS_DA_XPON_PWDB_1,
> + AIROHA_PCS_PMA_RX_SIDGET_PWDB);
> +}
> +
> +static unsigned int airoha_pcs_apply_cdr_pr_idac(struct airoha_pcs_priv *priv,
> + u32 cdr_pr_idac)
> +{
> + u32 val;
> +
> + regmap_update_bits(priv->xfi_pma, AIROHA_PCS_PMA_PXP_CDR_PR_IDAC,
> + AIROHA_PCS_PMA_FORCE_CDR_PR_IDAC,
> + FIELD_PREP(AIROHA_PCS_PMA_FORCE_CDR_PR_IDAC,
> + cdr_pr_idac));
> +
> + regmap_update_bits(priv->xfi_pma, AIROHA_PCS_PMA_SS_RX_FREQ_DET_4,
> + AIROHA_PCS_PMA_FREQLOCK_DET_EN,
> + AIROHA_PCS_PMA_FREQLOCK_DET_EN_FORCE_0);
> +
> + regmap_update_bits(priv->xfi_pma, AIROHA_PCS_PMA_SS_RX_FREQ_DET_4,
> + AIROHA_PCS_PMA_FREQLOCK_DET_EN,
> + AIROHA_PCS_PMA_FREQLOCK_DET_EN_NORMAL);
> +
> + usleep_range(5000, 7000);
> +
> + regmap_read(priv->xfi_pma, AIROHA_PCS_PMA_RX_FREQDET, &val);
> +
> + return FIELD_GET(AIROHA_PCS_PMA_FL_OUT, val);
> +}
> +
> +static void airoha_pcs_rx_prcal(struct airoha_pcs_priv *priv,
> + phy_interface_t interface)
> +{
> + unsigned int remaining_prcal_search_bits = 8;
> + unsigned int prcal_search_bit;
> + bool prcal_search_from_bottom;
> + unsigned int prcal_search;
> + unsigned int fl_out_diff = UINT_MAX;
> + unsigned int fl_out;
> + int cdr_pr_idac = 0;
> +
> + u32 target_fl_out;
> + u32 cyclecnt;
> +
> + switch (interface) {
> + case PHY_INTERFACE_MODE_SGMII: /* DS_1.25G / US_1.25G */
> + case PHY_INTERFACE_MODE_1000BASEX:
> + target_fl_out = 0xa3d6;
> + cyclecnt = 32767;
> + break;
> + case PHY_INTERFACE_MODE_2500BASEX: /* DS_9.95328G / US_9.95328G */
> + target_fl_out = 0xa000;
> + cyclecnt = 20000;
> + break;
> + case PHY_INTERFACE_MODE_USXGMII: /* DS_10.3125G / US_1.25G */
> + case PHY_INTERFACE_MODE_10GBASER:
> + target_fl_out = 0x9edf;
> + cyclecnt = 32767;
> + break;
> + default:
> + return;
> + }
> +
> + regmap_set_bits(priv->xfi_pma, AIROHA_PCS_PMA_SW_RST_SET,
> + AIROHA_PCS_PMA_SW_REF_RST_N);
> +
> + usleep_range(100, 200);
> +
> + regmap_update_bits(priv->xfi_pma, AIROHA_PCS_PMA_SS_RX_FREQ_DET_2,
> + AIROHA_PCS_PMA_LOCK_TARGET_END |
> + AIROHA_PCS_PMA_LOCK_TARGET_BEG,
> + FIELD_PREP(AIROHA_PCS_PMA_LOCK_TARGET_END, target_fl_out + 100) |
> + FIELD_PREP(AIROHA_PCS_PMA_LOCK_TARGET_BEG, target_fl_out - 100));
> +
> + regmap_update_bits(priv->xfi_pma, AIROHA_PCS_PMA_SS_RX_FREQ_DET_1,
> + AIROHA_PCS_PMA_UNLOCK_CYCLECNT |
> + AIROHA_PCS_PMA_LOCK_CYCLECNT,
> + FIELD_PREP(AIROHA_PCS_PMA_UNLOCK_CYCLECNT, cyclecnt) |
> + FIELD_PREP(AIROHA_PCS_PMA_LOCK_CYCLECNT, cyclecnt));
> +
> + regmap_update_bits(priv->xfi_pma, AIROHA_PCS_PMA_SS_RX_FREQ_DET_4,
> + AIROHA_PCS_PMA_LOCK_UNLOCKTH |
> + AIROHA_PCS_PMA_LOCK_LOCKTH,
> + FIELD_PREP(AIROHA_PCS_PMA_LOCK_UNLOCKTH, 3) |
> + FIELD_PREP(AIROHA_PCS_PMA_LOCK_LOCKTH, 3));
> +
> + regmap_update_bits(priv->xfi_pma, AIROHA_PCS_PMA_SS_RX_FREQ_DET_3,
> + AIROHA_PCS_PMA_UNLOCK_TARGET_END |
> + AIROHA_PCS_PMA_UNLOCK_TARGET_BEG,
> + FIELD_PREP(AIROHA_PCS_PMA_UNLOCK_TARGET_END, target_fl_out + 100) |
> + FIELD_PREP(AIROHA_PCS_PMA_UNLOCK_TARGET_BEG, target_fl_out - 100));
> +
> + regmap_set_bits(priv->xfi_ana, AIROHA_PCS_ANA_PXP_CDR_PR_INJ_MODE,
> + AIROHA_PCS_ANA_CDR_PR_INJ_FORCE_OFF);
> +
> + regmap_update_bits(priv->xfi_pma, AIROHA_PCS_PMA_PXP_CDR_PR_LPF_C_EN,
> + AIROHA_PCS_PMA_FORCE_SEL_DA_CDR_PR_LPF_R_EN |
> + AIROHA_PCS_PMA_FORCE_DA_CDR_PR_LPF_R_EN |
> + AIROHA_PCS_PMA_FORCE_SEL_DA_CDR_PR_LPF_C_EN |
> + AIROHA_PCS_PMA_FORCE_DA_CDR_PR_LPF_C_EN,
> + AIROHA_PCS_PMA_FORCE_SEL_DA_CDR_PR_LPF_R_EN |
> + AIROHA_PCS_PMA_FORCE_DA_CDR_PR_LPF_R_EN |
> + AIROHA_PCS_PMA_FORCE_SEL_DA_CDR_PR_LPF_C_EN);
> +
> + regmap_set_bits(priv->xfi_pma, AIROHA_PCS_PMA_PXP_CDR_PR_IDAC,
> + AIROHA_PCS_PMA_FORCE_SEL_DA_CDR_PR_IDAC);
> +
> + regmap_set_bits(priv->xfi_pma, AIROHA_PCS_PMA_PXP_CDR_PR_PIEYE_PWDB,
> + AIROHA_PCS_PMA_FORCE_SEL_DA_CDR_PR_PWDB);
> +
> + regmap_clear_bits(priv->xfi_pma, AIROHA_PCS_PMA_PXP_CDR_PR_PIEYE_PWDB,
> + AIROHA_PCS_PMA_FORCE_DA_CDR_PR_PWDB);
> +
> + regmap_set_bits(priv->xfi_pma, AIROHA_PCS_PMA_PXP_CDR_PR_PIEYE_PWDB,
> + AIROHA_PCS_PMA_FORCE_DA_CDR_PR_PWDB);
> +
> + /* Calibration logic:
> + * First check the major value by looping with every
> + * value in the last 3 bit of CDR_PR_IDAC.
> + * Get the signal level and save the value that if closer to
> + * the target.
> + *
> + * Then fine tune for the remaining 7 bit to find the one that
> + * produce the closest signal level.
> + */
> + for (prcal_search = 0; prcal_search < 8 ; prcal_search++) {
> + u32 cdr_pr_idac_tmp;
> +
> + /* try to find the upper value by setting the last 3 bit */
> + cdr_pr_idac_tmp = FIELD_PREP(AIROHA_PCS_PMA_FORCE_CDR_PR_IDAC_MAJOR,
> + prcal_search);
> + fl_out = airoha_pcs_apply_cdr_pr_idac(priv, cdr_pr_idac_tmp);
> +
> + /* Use absolute values to find the closest one to target */
> + if (abs(fl_out - target_fl_out) < fl_out_diff) {
> + cdr_pr_idac = cdr_pr_idac_tmp;
> + fl_out_diff = abs(fl_out - target_fl_out);
> + }
> + }
> +
> + /* Understand if we need to fine tune by increasing or decreasing fl_out.
> + * This is done by setting BIT (7) and check if the abs fl_out diff from target
> + * increase or decrease.
> + * If it does increase, we need to decrease fl_out, hence we search from MAX to MIN.
> + * If it does decrease, we need to increase fl_out, hence we search from MIN to MAX.
> + */
> + fl_out = airoha_pcs_apply_cdr_pr_idac(priv, cdr_pr_idac | BIT(7));
> + if (abs(fl_out - target_fl_out) < fl_out_diff) {
> + prcal_search_from_bottom = false;
> + prcal_search_bit = 7;
> + } else {
> + prcal_search_from_bottom = true;
> + prcal_search_bit = 0;
> + }
> +
> + /* Fine tune part.
> + * Continue searching until we find a deadline where the signal
> + * level starts to increase/decrease. Once that is reached, start
> + * the loop again to progressely find a closer signal level to
> + * the target.
> + */
> + while (remaining_prcal_search_bits) {
> + unsigned int fl_out_diff_new;
> + u32 cdr_pr_idac_tmp;
> +
> + cdr_pr_idac_tmp = cdr_pr_idac | BIT(prcal_search_bit);
> + fl_out = airoha_pcs_apply_cdr_pr_idac(priv, cdr_pr_idac_tmp);
> +
> + /* Use absolute values to find the closest one to target */
> + fl_out_diff_new = abs(fl_out - target_fl_out);
> + /* Assume we found the deadline when the new absolue signal difference
> + * from target is greater than the previous and the difference is at
> + * least 10% greater between the old and new value.
> + * This is to account for signal detection level tollerance making
> + * sure we are actually over a deadline (AKA we are getting farther
> + * from target)
> + */
> + if (fl_out_diff_new > fl_out_diff &&
> + (abs(fl_out_diff_new - fl_out_diff) * 100) / fl_out_diff > 10) {
> + /* Exit early if we are already at the deadline */
> + if (prcal_search_bit == 0 || prcal_search_bit == 7)
> + break;
> +
> + /* We found the deadline, set the value to the previous
> + * bit, and reset the loop to fine tune with the
> + * remaining values.
> + */
> + if (prcal_search_from_bottom) {
> + cdr_pr_idac |= BIT(prcal_search_bit - 1);
> + remaining_prcal_search_bits = prcal_search_bit - 1;
> + prcal_search_bit = 0;
> + } else {
> + cdr_pr_idac |= BIT(prcal_search_bit + 1);
> + remaining_prcal_search_bits = prcal_search_bit + 1;
> + }
> + } else {
> + /* Update the signal level diff and try the next bit */
> + fl_out_diff = fl_out_diff_new;
> +
> + /* If we didn't found the deadline, set the last bit
> + * and stop searching. This should not happen as it's expected
> + * we find an high signal level and we decrease it as it's
> + * much harder to reach target level by increasing the
> + * signal (by using a lower DAC value).
> + */
> + if (prcal_search_from_bottom) {
> + if (prcal_search_bit == 7) {
> + cdr_pr_idac |= BIT(prcal_search_bit);
> + break;
> + }
> +
> + prcal_search_bit++;
> + } else {
> + if (prcal_search_bit == 0) {
> + cdr_pr_idac |= BIT(prcal_search_bit);
> + break;
> + }
> +
> + prcal_search_bit--;
> + }
> + }
> + }
> +
> + fl_out = airoha_pcs_apply_cdr_pr_idac(priv, cdr_pr_idac);
> + dev_dbg(priv->dev, "Selected CDR Pr Idac: %x Fl Out: %x\n", cdr_pr_idac, fl_out);
> + if (abs(fl_out - target_fl_out) > 100)
> + dev_warn(priv->dev, "Fl Out is %d far from target %d. PCS might not function properly.\n",
> + abs(fl_out - target_fl_out), target_fl_out);
> +
> + /* Setup Load Band */
> + regmap_clear_bits(priv->xfi_ana, AIROHA_PCS_ANA_PXP_CDR_PR_INJ_MODE,
> + AIROHA_PCS_ANA_CDR_PR_INJ_FORCE_OFF);
> +
> + /* Disable force of LPF C previously enabled */
> + regmap_clear_bits(priv->xfi_pma, AIROHA_PCS_PMA_PXP_CDR_PR_LPF_C_EN,
> + AIROHA_PCS_PMA_FORCE_SEL_DA_CDR_PR_LPF_C_EN);
> +
> + regmap_clear_bits(priv->xfi_pma, AIROHA_PCS_PMA_PXP_CDR_PR_IDAC,
> + AIROHA_PCS_PMA_FORCE_SEL_DA_CDR_PR_IDAC);
> +
> + regmap_set_bits(priv->xfi_pma, AIROHA_PCS_PMA_RX_FLL_B,
> + AIROHA_PCS_PMA_LOAD_EN);
> +
> + regmap_update_bits(priv->xfi_pma, AIROHA_PCS_PMA_RX_FLL_1,
> + AIROHA_PCS_PMA_LPATH_IDAC,
> + FIELD_PREP(AIROHA_PCS_PMA_LPATH_IDAC, cdr_pr_idac));
> +
> + regmap_clear_bits(priv->xfi_pma, AIROHA_PCS_PMA_PXP_CDR_PR_PIEYE_PWDB,
> + AIROHA_PCS_PMA_FORCE_DA_CDR_PR_PWDB);
> +
> + regmap_set_bits(priv->xfi_pma, AIROHA_PCS_PMA_PXP_CDR_PR_PIEYE_PWDB,
> + AIROHA_PCS_PMA_FORCE_DA_CDR_PR_PWDB);
> +
> + regmap_clear_bits(priv->xfi_pma, AIROHA_PCS_PMA_PXP_CDR_PR_PIEYE_PWDB,
> + AIROHA_PCS_PMA_FORCE_SEL_DA_CDR_PR_PWDB);
> +
> + regmap_clear_bits(priv->xfi_pma, AIROHA_PCS_PMA_SW_RST_SET,
> + AIROHA_PCS_PMA_SW_REF_RST_N);
> +
> + usleep_range(100, 200);
> +}
> +
> +/* This is used to both calibrate and lock to signal (after a previous
> + * calibration) after a global reset.
> + */
> +static void airoha_pcs_cdr_reset(struct airoha_pcs_priv *priv,
> + phy_interface_t interface, bool calibrate)
> +{
> + /* Setup LPF L2D force and disable */
> + regmap_update_bits(priv->xfi_pma, AIROHA_PCS_PMA_PXP_CDR_LPF_LCK_2DATA,
> + AIROHA_PCS_PMA_FORCE_SEL_DA_CDR_LPF_LCK2DATA |
> + AIROHA_PCS_PMA_FORCE_DA_CDR_LPF_LCK2DATA,
> + AIROHA_PCS_PMA_FORCE_SEL_DA_CDR_LPF_LCK2DATA);
> +
> + /* Calibrate IDAC and setup Load Band */
> + if (calibrate)
> + airoha_pcs_rx_prcal(priv, interface);
> +
> + /* Setup LPF RSTB force and disable */
> + regmap_update_bits(priv->xfi_pma, AIROHA_PCS_PMA_PXP_CDR_LPF_LCK_2DATA,
> + AIROHA_PCS_PMA_FORCE_SEL_DA_CDR_LPF_RSTB |
> + AIROHA_PCS_PMA_FORCE_DA_CDR_LPF_RSTB,
> + AIROHA_PCS_PMA_FORCE_SEL_DA_CDR_LPF_RSTB);
> +
> + usleep_range(700, 1000);
> +
> + /* Force Enable LPF RSTB */
> + regmap_set_bits(priv->xfi_pma, AIROHA_PCS_PMA_PXP_CDR_LPF_LCK_2DATA,
> + AIROHA_PCS_PMA_FORCE_DA_CDR_LPF_RSTB);
> +
> + usleep_range(100, 200);
> +
> + /* Force Enable LPF L2D */
> + regmap_set_bits(priv->xfi_pma, AIROHA_PCS_PMA_PXP_CDR_LPF_LCK_2DATA,
> + AIROHA_PCS_PMA_FORCE_DA_CDR_LPF_LCK2DATA);
> +
> + /* Disable LPF RSTB force bit */
> + regmap_clear_bits(priv->xfi_pma, AIROHA_PCS_PMA_PXP_CDR_LPF_LCK_2DATA,
> + AIROHA_PCS_PMA_FORCE_SEL_DA_CDR_LPF_RSTB);
> +
> + /* Disable LPF L2D force bit */
> + regmap_clear_bits(priv->xfi_pma, AIROHA_PCS_PMA_PXP_CDR_LPF_LCK_2DATA,
> + AIROHA_PCS_PMA_FORCE_SEL_DA_CDR_LPF_LCK2DATA);
> +}
> +
> +static int airoha_pcs_phya_bringup(struct airoha_pcs_priv *priv,
> + phy_interface_t interface)
> +{
> + int calibration_try = 0;
> + u32 val;
> +
> + airoha_pcs_tx_bringup(priv, interface);
> + airoha_pcs_rx_bringup(priv, interface);
> +
> + usleep_range(100, 200);
> +
> +retry_calibration:
> + airoha_pcs_cdr_reset(priv, interface, true);
> +
> + /* Global reset clear */
> + regmap_update_bits(priv->xfi_pma, AIROHA_PCS_PMA_SW_RST_SET,
> + AIROHA_PCS_PMA_SW_HSG_RXPCS_RST_N |
> + AIROHA_PCS_PMA_SW_HSG_TXPCS_RST_N |
> + AIROHA_PCS_PMA_SW_HSG_RXPCS_BIST_RST_N |
> + AIROHA_PCS_PMA_SW_XFI_RXPCS_RST_N |
> + AIROHA_PCS_PMA_SW_XFI_TXPCS_RST_N |
> + AIROHA_PCS_PMA_SW_TX_FIFO_RST_N |
> + AIROHA_PCS_PMA_SW_REF_RST_N |
> + AIROHA_PCS_PMA_SW_ALLPCS_RST_N |
> + AIROHA_PCS_PMA_SW_PMA_RST_N |
> + AIROHA_PCS_PMA_SW_TX_RST_N |
> + AIROHA_PCS_PMA_SW_RX_RST_N |
> + AIROHA_PCS_PMA_SW_RX_FIFO_RST_N,
> + AIROHA_PCS_PMA_SW_REF_RST_N);
> +
> + usleep_range(100, 200);
> +
> + /* Global reset */
> + regmap_set_bits(priv->xfi_pma, AIROHA_PCS_PMA_SW_RST_SET,
> + AIROHA_PCS_PMA_SW_HSG_RXPCS_RST_N |
> + AIROHA_PCS_PMA_SW_HSG_TXPCS_RST_N |
> + AIROHA_PCS_PMA_SW_HSG_RXPCS_BIST_RST_N |
> + AIROHA_PCS_PMA_SW_XFI_RXPCS_RST_N |
> + AIROHA_PCS_PMA_SW_XFI_TXPCS_RST_N |
> + AIROHA_PCS_PMA_SW_TX_FIFO_RST_N |
> + AIROHA_PCS_PMA_SW_REF_RST_N |
> + AIROHA_PCS_PMA_SW_ALLPCS_RST_N |
> + AIROHA_PCS_PMA_SW_PMA_RST_N |
> + AIROHA_PCS_PMA_SW_TX_RST_N |
> + AIROHA_PCS_PMA_SW_RX_RST_N |
> + AIROHA_PCS_PMA_SW_RX_FIFO_RST_N);
> +
> + usleep_range(5000, 7000);
> +
> + airoha_pcs_cdr_reset(priv, interface, false);
> +
> + /* 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.
> + * To correctly work, the PCS FreqDet module needs to Lock to the fl_out
> + * (frequency level output) or no signal can correctly be transmitted.
> + * This is detected by checking the FreqDet module Lock bit.
> + *
> + * If it's detected that the FreqDet module is not locked, retry
> + * calibration. From observation on real hardware with a 10g SFP module,
> + * it required a maximum of an additional calibration to actually make
> + * the FreqDet module to lock. Try 10 times before failing to handle
> + * really strange case.
> + */
> + regmap_read(priv->xfi_pma, AIROHA_PCS_PMA_RX_FREQDET, &val);
> + if (!(val & AIROHA_PCS_PMA_FBCK_LOCK)) {
> + if (calibration_try > AIROHA_PCS_MAX_CALIBRATION_TRY) {
> + dev_err(priv->dev, "No FBCK Lock from FreqDet module after %d calibration try. PCS won't work.\n",
> + AIROHA_PCS_MAX_CALIBRATION_TRY);
> + return -EIO;
> + }
> +
> + calibration_try++;
> +
> + dev_dbg(priv->dev, "No FBCK Lock from FreqDet module, retry calibration.\n");
> + goto retry_calibration;
> + }
> +
> + return 0;
> +}
> +
> +static void airoha_pcs_get_state_sgmii(struct airoha_pcs_priv *priv,
> + unsigned int neg_mode,
> + struct phylink_link_state *state)
> +{
> + u32 bmsr, lpa;
> +
> + regmap_read(priv->hsgmii_an, AIROHA_PCS_HSGMII_AN_SGMII_REG_AN_1,
> + &bmsr);
> + regmap_read(priv->hsgmii_an, AIROHA_PCS_HSGMII_AN_SGMII_REG_AN_5,
> + &lpa);
> +
> + bmsr = (AIROHA_PCS_HSGMII_AN_SGMII_AN_COMPLETE |
> + AIROHA_PCS_HSGMII_AN_SGMII_REMOTE_FAULT |
> + AIROHA_PCS_HSGMII_AN_SGMII_AN_ABILITY |
> + AIROHA_PCS_HSGMII_AN_SGMII_LINK_STATUS) & bmsr;
> + lpa = AIROHA_PCS_HSGMII_AN_SGMII_PARTNER_ABILITY & lpa;
> +
> + phylink_mii_c22_pcs_decode_state(state, neg_mode, bmsr, lpa);
> +}
> +
> +static void airoha_pcs_get_state_usxgmii(struct airoha_pcs_priv *priv,
> + struct phylink_link_state *state)
> +{
> + u32 lpa;
> +
> + /* Toggle AN Status */
> + regmap_set_bits(priv->usxgmii_pcs, AIROHA_PCS_USXGMII_PCS_AN_CONTROL_6,
> + AIROHA_PCS_USXGMII_TOG_PCS_AUTONEG_STS);
> + regmap_clear_bits(priv->usxgmii_pcs, AIROHA_PCS_USXGMII_PCS_AN_CONTROL_6,
> + AIROHA_PCS_USXGMII_TOG_PCS_AUTONEG_STS);
> +
> + regmap_read(priv->usxgmii_pcs, AIROHA_PCS_USXGMII_PCS_AN_STATS_0, &lpa);
> +
> + state->link = !!(lpa & MDIO_USXGMII_LINK);
> + state->an_complete = state->link;
> +
> + phylink_decode_usxgmii_word(state, lpa);
> +}
> +
> +static void airoha_pcs_get_state(struct phylink_pcs *pcs,
> + unsigned int neg_mode,
> + struct phylink_link_state *state)
> +{
> + struct airoha_pcs_priv *priv = phylink_pcs_to_airoha_pcs_port(pcs);
> +
> + switch (state->interface) {
> + case PHY_INTERFACE_MODE_SGMII:
> + case PHY_INTERFACE_MODE_1000BASEX:
> + case PHY_INTERFACE_MODE_2500BASEX:
> + airoha_pcs_get_state_sgmii(priv, neg_mode, state);
> + break;
> + case PHY_INTERFACE_MODE_USXGMII:
> + case PHY_INTERFACE_MODE_10GBASER:
> + airoha_pcs_get_state_usxgmii(priv, state);
> + break;
> + default:
> + return;
> + }
> +}
> +
> +static int airoha_pcs_config(struct phylink_pcs *pcs, unsigned int neg_mode,
> + phy_interface_t interface,
> + const unsigned long *advertising,
> + bool permit_pause_to_mac)
> +{
> + struct airoha_pcs_priv *priv = phylink_pcs_to_airoha_pcs_port(pcs);
> + u32 rate_adapt;
> + int ret;
> +
> + priv->interface = interface;
> +
> + /* Select HSGMII or USXGMII in SCU regs */
> + airoha_pcs_setup_scu(priv, interface);
> +
> + /* Enable Analog Common Lane */
> + regmap_set_bits(priv->xfi_ana, AIROHA_PCS_ANA_PXP_CMN_EN,
> + AIROHA_PCS_ANA_CMN_EN);
> +
> + /* Setup PLL */
> + airoha_pcs_pll_bringup(priv, interface);
> +
> + /* Setup PHYA */
> + ret = airoha_pcs_phya_bringup(priv, interface);
> + if (ret)
> + return ret;
> +
> + /* Set final configuration for various modes */
> + airoha_pcs_init(priv, interface);
> +
> + /* Configure Interrupt for various modes */
> + airoha_pcs_interrupt_init(priv, interface);
> +
> + if (neg_mode == PHYLINK_PCS_NEG_INBAND_ENABLED)
> + rate_adapt = AIROHA_PCS_HSGMII_RATE_ADAPT_RX_EN |
> + AIROHA_PCS_HSGMII_RATE_ADAPT_TX_EN;
> + else
> + rate_adapt = AIROHA_PCS_HSGMII_RATE_ADAPT_RX_BYPASS |
> + AIROHA_PCS_HSGMII_RATE_ADAPT_TX_BYPASS |
> + AIROHA_PCS_HSGMII_RATE_ADAPT_RX_EN |
> + AIROHA_PCS_HSGMII_RATE_ADAPT_TX_EN;
> +
> + /* AN Auto Settings (Rate Adaptation) */
> + regmap_update_bits(priv->hsgmii_rate_adp, AIROHA_PCS_HSGMII_RATE_ADAPT_CTRL_0,
> + AIROHA_PCS_HSGMII_RATE_ADAPT_RX_BYPASS |
> + AIROHA_PCS_HSGMII_RATE_ADAPT_TX_BYPASS |
> + AIROHA_PCS_HSGMII_RATE_ADAPT_RX_EN |
> + AIROHA_PCS_HSGMII_RATE_ADAPT_TX_EN, rate_adapt);
> +
> + if (interface == PHY_INTERFACE_MODE_USXGMII ||
> + interface == PHY_INTERFACE_MODE_10GBASER) {
> + if (neg_mode == PHYLINK_PCS_NEG_INBAND_ENABLED)
> + regmap_set_bits(priv->usxgmii_pcs,
> + AIROHA_PCS_USXGMII_PCS_AN_CONTROL_0,
> + AIROHA_PCS_USXGMII_AN_ENABLE);
> + else
> + regmap_clear_bits(priv->usxgmii_pcs,
> + AIROHA_PCS_USXGMII_PCS_AN_CONTROL_0,
> + AIROHA_PCS_USXGMII_AN_ENABLE);
> + }
> +
> + /* Clear any force bit that my be set by bootloader */
> + if (interface == PHY_INTERFACE_MODE_SGMII ||
> + interface == PHY_INTERFACE_MODE_1000BASEX ||
> + interface == PHY_INTERFACE_MODE_2500BASEX) {
> + regmap_clear_bits(priv->multi_sgmii, AIROHA_PCS_MULTI_SGMII_SGMII_STS_CTRL_0,
> + AIROHA_PCS_LINK_MODE_P0 |
> + AIROHA_PCS_FORCE_SPD_MODE_P0 |
> + AIROHA_PCS_FORCE_LINKDOWN_P0 |
> + AIROHA_PCS_FORCE_LINKUP_P0);
> + }
> +
> + /* Toggle Rate Adaption for SGMII/HSGMII mode */
> + if (interface == PHY_INTERFACE_MODE_SGMII ||
> + interface == PHY_INTERFACE_MODE_1000BASEX ||
> + interface == PHY_INTERFACE_MODE_2500BASEX) {
> + if (neg_mode == PHYLINK_PCS_NEG_INBAND_ENABLED)
> + regmap_clear_bits(priv->hsgmii_rate_adp,
> + AIROHA_PCS_HSGMII_RATE_ADP_P0_CTRL_0,
> + AIROHA_PCS_HSGMII_P0_DIS_MII_MODE);
> + else
> + regmap_set_bits(priv->hsgmii_rate_adp,
> + AIROHA_PCS_HSGMII_RATE_ADP_P0_CTRL_0,
> + AIROHA_PCS_HSGMII_P0_DIS_MII_MODE);
> + }
> +
> + /* Setup AN Link Timer */
> + if (interface == PHY_INTERFACE_MODE_SGMII ||
> + interface == PHY_INTERFACE_MODE_1000BASEX ||
> + interface == PHY_INTERFACE_MODE_2500BASEX) {
> + u32 an_timer;
> +
> + an_timer = phylink_get_link_timer_ns(interface);
> +
> + /* Value needs to be shifted by 4, seems value is internally * 16 */
> + regmap_update_bits(priv->hsgmii_an, AIROHA_PCS_HSGMII_AN_SGMII_REG_AN_11,
> + AIROHA_PCS_HSGMII_AN_SGMII_LINK_TIMER,
> + FIELD_PREP(AIROHA_PCS_HSGMII_AN_SGMII_LINK_TIMER,
> + an_timer >> 4));
> +
> + regmap_update_bits(priv->hsgmii_pcs, AIROHA_PCS_HSGMII_PCS_CTROL_3,
> + AIROHA_PCS_HSGMII_PCS_LINK_STSTIME,
> + FIELD_PREP(AIROHA_PCS_HSGMII_PCS_LINK_STSTIME,
> + an_timer >> 4));
> + }
> +
> + /* Setup SGMII AN and advertisement in DEV_ABILITY */
> + if (interface == PHY_INTERFACE_MODE_SGMII &&
> + neg_mode == PHYLINK_PCS_NEG_INBAND_ENABLED) {
> + int advertise = phylink_mii_c22_pcs_encode_advertisement(interface,
> + advertising);
> + if (advertise < 0)
> + return advertise;
> +
> + regmap_set_bits(priv->hsgmii_an, AIROHA_PCS_HSGMII_AN_SGMII_REG_AN_0,
> + AIROHA_PCS_HSGMII_AN_SGMII_RA_ENABLE);
> +
> + regmap_update_bits(priv->hsgmii_an, AIROHA_PCS_HSGMII_AN_SGMII_REG_AN_4,
> + AIROHA_PCS_HSGMII_AN_SGMII_DEV_ABILITY,
> + FIELD_PREP(AIROHA_PCS_HSGMII_AN_SGMII_DEV_ABILITY,
> + advertise));
> + } else {
> + regmap_clear_bits(priv->hsgmii_an, AIROHA_PCS_HSGMII_AN_SGMII_REG_AN_0,
> + AIROHA_PCS_HSGMII_AN_SGMII_RA_ENABLE);
> + }
> +
> + if (interface == PHY_INTERFACE_MODE_SGMII ||
> + interface == PHY_INTERFACE_MODE_1000BASEX) {
> + u32 if_mode = AIROHA_PCS_HSGMII_AN_SGMII_EN |
> + AIROHA_PCS_HSGMII_AN_SIDEBAND_EN;
> +
> + if (neg_mode == PHYLINK_PCS_NEG_INBAND_ENABLED) {
> + regmap_set_bits(priv->hsgmii_an, AIROHA_PCS_HSGMII_AN_SGMII_REG_AN_13,
> + AIROHA_PCS_HSGMII_AN_SGMII_REMOTE_FAULT_DIS);
> +
> + /* Clear force speed bits and MAC mode */
> + regmap_clear_bits(priv->hsgmii_pcs, AIROHA_PCS_HSGMII_PCS_CTROL_6,
> + AIROHA_PCS_HSGMII_PCS_SGMII_SPD_FORCE_10 |
> + AIROHA_PCS_HSGMII_PCS_SGMII_SPD_FORCE_100 |
> + AIROHA_PCS_HSGMII_PCS_SGMII_SPD_FORCE_1000 |
> + AIROHA_PCS_HSGMII_PCS_MAC_MODE |
> + AIROHA_PCS_HSGMII_PCS_FORCE_RATEADAPT_VAL |
> + AIROHA_PCS_HSGMII_PCS_FORCE_RATEADAPT);
> + } else {
> + if_mode |= AIROHA_PCS_HSGMII_AN_SGMII_COMPAT_EN;
> +
> + regmap_clear_bits(priv->hsgmii_an, AIROHA_PCS_HSGMII_AN_SGMII_REG_AN_13,
> + AIROHA_PCS_HSGMII_AN_SGMII_REMOTE_FAULT_DIS);
> +
> + /* AN off force rate adaption, speed is set later in Link Up */
> + regmap_update_bits(priv->hsgmii_pcs, AIROHA_PCS_HSGMII_PCS_CTROL_6,
> + AIROHA_PCS_HSGMII_PCS_MAC_MODE |
> + AIROHA_PCS_HSGMII_PCS_FORCE_RATEADAPT,
> + AIROHA_PCS_HSGMII_PCS_FORCE_RATEADAPT);
> + }
> +
> + regmap_update_bits(priv->hsgmii_an, AIROHA_PCS_HSGMII_AN_SGMII_REG_AN_13,
> + AIROHA_PCS_HSGMII_AN_SGMII_IF_MODE_5_0, if_mode);
> +
> + /* FIXME: Airoha apply a different configuration here */
> + /* They force rate adaption */
> + regmap_set_bits(priv->hsgmii_pcs, AIROHA_PCS_HSGMII_PCS_CTROL_6,
> + AIROHA_PCS_HSGMII_PCS_TX_ENABLE |
> + AIROHA_PCS_HSGMII_PCS_MODE2_EN);
> + }
> +
> + if (interface == PHY_INTERFACE_MODE_1000BASEX &&
> + neg_mode != PHYLINK_PCS_NEG_INBAND_ENABLED) {
> + regmap_set_bits(priv->hsgmii_pcs, AIROHA_PCS_HSGMII_PCS_CTROL_1,
> + AIROHA_PCS_SGMII_SEND_AN_ERR_EN);
> +
> + regmap_set_bits(priv->hsgmii_pcs, AIROHA_PCS_HSGMII_AN_SGMII_REG_AN_FORCE_CL37,
> + AIROHA_PCS_HSGMII_AN_FORCE_AN_DONE);
> + }
> +
> + /* Configure Flow Control on XFI */
> + regmap_update_bits(priv->xfi_mac, AIROHA_PCS_XFI_MAC_XFI_GIB_CFG,
> + AIROHA_PCS_XFI_TX_FC_EN | AIROHA_PCS_XFI_RX_FC_EN,
> + permit_pause_to_mac ?
> + AIROHA_PCS_XFI_TX_FC_EN | AIROHA_PCS_XFI_RX_FC_EN :
> + 0);
> +
> + return 0;
> +}
> +
> +static void airoha_pcs_an_restart(struct phylink_pcs *pcs)
> +{
> + struct airoha_pcs_priv *priv = phylink_pcs_to_airoha_pcs_port(pcs);
> +
> + switch (priv->interface) {
> + case PHY_INTERFACE_MODE_SGMII:
> + case PHY_INTERFACE_MODE_1000BASEX:
> + case PHY_INTERFACE_MODE_2500BASEX:
> + regmap_set_bits(priv->hsgmii_an, AIROHA_PCS_HSGMII_AN_SGMII_REG_AN_0,
> + AIROHA_PCS_HSGMII_AN_SGMII_AN_RESTART);
> + udelay(3);
> + regmap_clear_bits(priv->hsgmii_an, AIROHA_PCS_HSGMII_AN_SGMII_REG_AN_0,
> + AIROHA_PCS_HSGMII_AN_SGMII_AN_RESTART);
> + break;
> + case PHY_INTERFACE_MODE_USXGMII:
> + regmap_set_bits(priv->usxgmii_pcs, AIROHA_PCS_USXGMII_PCS_AN_CONTROL_0,
> + AIROHA_PCS_USXGMII_AN_RESTART);
> + udelay(3);
> + regmap_clear_bits(priv->usxgmii_pcs, AIROHA_PCS_USXGMII_PCS_AN_CONTROL_0,
> + AIROHA_PCS_USXGMII_AN_RESTART);
> + default:
> + return;
> + }
> +}
> +
> +static void airoha_pcs_link_up(struct phylink_pcs *pcs, unsigned int neg_mode,
> + phy_interface_t interface, int speed, int duplex)
> +{
> + struct airoha_pcs_priv *priv = phylink_pcs_to_airoha_pcs_port(pcs);
> +
> + if (neg_mode == PHYLINK_PCS_NEG_INBAND_ENABLED) {
> + if (interface == PHY_INTERFACE_MODE_SGMII) {
> + regmap_update_bits(priv->hsgmii_rate_adp,
> + AIROHA_PCS_HSGMII_RATE_ADAPT_CTRL_1,
> + AIROHA_PCS_HSGMII_RATE_ADAPT_RX_AFIFO_WR_THR |
> + AIROHA_PCS_HSGMII_RATE_ADAPT_RX_AFIFO_RD_THR,
> + FIELD_PREP(AIROHA_PCS_HSGMII_RATE_ADAPT_RX_AFIFO_WR_THR, 0x0) |
> + FIELD_PREP(AIROHA_PCS_HSGMII_RATE_ADAPT_RX_AFIFO_RD_THR, 0x0));
> + udelay(1);
> + regmap_update_bits(priv->hsgmii_rate_adp,
> + AIROHA_PCS_HSGMII_RATE_ADAPT_CTRL_1,
> + AIROHA_PCS_HSGMII_RATE_ADAPT_RX_AFIFO_WR_THR |
> + AIROHA_PCS_HSGMII_RATE_ADAPT_RX_AFIFO_RD_THR,
> + FIELD_PREP(AIROHA_PCS_HSGMII_RATE_ADAPT_RX_AFIFO_WR_THR, 0xf) |
> + FIELD_PREP(AIROHA_PCS_HSGMII_RATE_ADAPT_RX_AFIFO_RD_THR, 0x5));
> + }
> + } else {
> + if (interface == PHY_INTERFACE_MODE_USXGMII ||
> + interface == PHY_INTERFACE_MODE_10GBASER) {
> + u32 mode;
> + u32 rate_adapt;
> +
> + switch (speed) {
> + case SPEED_10000:
> + rate_adapt = AIROHA_PCS_HSGMII_RATE_ADPT_FORCE_RATE_ADAPT_MODE_10000;
> + mode = AIROHA_PCS_USXGMII_MODE_10000;
> + break;
> + case SPEED_5000:
> + rate_adapt = AIROHA_PCS_HSGMII_RATE_ADPT_FORCE_RATE_ADAPT_MODE_5000;
> + mode = AIROHA_PCS_USXGMII_MODE_5000;
> + break;
> + case SPEED_2500:
> + rate_adapt = AIROHA_PCS_HSGMII_RATE_ADPT_FORCE_RATE_ADAPT_MODE_2500;
> + mode = AIROHA_PCS_USXGMII_MODE_2500;
> + break;
> + case SPEED_1000:
> + rate_adapt = AIROHA_PCS_HSGMII_RATE_ADPT_FORCE_RATE_ADAPT_MODE_1000;
> + mode = AIROHA_PCS_USXGMII_MODE_1000;
> + break;
> + case SPEED_100:
> + rate_adapt = AIROHA_PCS_HSGMII_RATE_ADPT_FORCE_RATE_ADAPT_MODE_100;
> + mode = AIROHA_PCS_USXGMII_MODE_100;
> + break;
> + }
> +
> + /* Trigger USXGMII change mode and force selected speed */
> + regmap_update_bits(priv->usxgmii_pcs, AIROHA_PCS_USXGMII_PCS_AN_CONTROL_7,
> + AIROHA_PCS_USXGMII_RATE_UPDATE_MODE |
> + AIROHA_PCS_USXGMII_MODE,
> + AIROHA_PCS_USXGMII_RATE_UPDATE_MODE | mode);
> +
> + regmap_update_bits(priv->hsgmii_rate_adp, AIROHA_PCS_HSGMII_RATE_ADAPT_CTRL_11,
> + AIROHA_PCS_HSGMII_RATE_ADPT_FORCE_RATE_ADAPT_MODE_EN |
> + AIROHA_PCS_HSGMII_RATE_ADPT_FORCE_RATE_ADAPT_MODE,
> + AIROHA_PCS_HSGMII_RATE_ADPT_FORCE_RATE_ADAPT_MODE_EN |
> + rate_adapt);
> + }
> +
> + if (interface == PHY_INTERFACE_MODE_SGMII ||
> + interface == PHY_INTERFACE_MODE_1000BASEX) {
> + u32 force_speed;
> + u32 rate_adapt;
> +
> + switch (speed) {
> + case SPEED_1000:
> + force_speed = AIROHA_PCS_HSGMII_PCS_SGMII_SPD_FORCE_1000;
> + rate_adapt = AIROHA_PCS_HSGMII_PCS_FORCE_RATEADAPT_VAL_1000;
> + break;
> + case SPEED_100:
> + force_speed = AIROHA_PCS_HSGMII_PCS_SGMII_SPD_FORCE_100;
> + rate_adapt = AIROHA_PCS_HSGMII_PCS_FORCE_RATEADAPT_VAL_100;
> + break;
> + case SPEED_10:
> + force_speed = AIROHA_PCS_HSGMII_PCS_SGMII_SPD_FORCE_10;
> + rate_adapt = AIROHA_PCS_HSGMII_PCS_FORCE_RATEADAPT_VAL_10;
> + break;
> + }
> +
> + regmap_update_bits(priv->hsgmii_pcs, AIROHA_PCS_HSGMII_PCS_CTROL_6,
> + AIROHA_PCS_HSGMII_PCS_SGMII_SPD_FORCE_10 |
> + AIROHA_PCS_HSGMII_PCS_SGMII_SPD_FORCE_100 |
> + AIROHA_PCS_HSGMII_PCS_SGMII_SPD_FORCE_1000 |
> + AIROHA_PCS_HSGMII_PCS_FORCE_RATEADAPT_VAL,
> + force_speed | rate_adapt);
> + }
> +
> + if (interface == PHY_INTERFACE_MODE_SGMII ||
> + interface == PHY_INTERFACE_MODE_2500BASEX) {
> + u32 ck_gen_mode;
> + u32 speed_reg;
> + u32 if_mode;
> +
> + switch (speed) {
> + case SPEED_2500:
> + speed_reg = AIROHA_PCS_LINK_MODE_P0_2_5G;
> + break;
> + case SPEED_1000:
> + speed_reg = AIROHA_PCS_LINK_MODE_P0_1G;
> + if_mode = AIROHA_PCS_HSGMII_AN_SPEED_FORCE_MODE_1000;
> + ck_gen_mode = AIROHA_PCS_HSGMII_PCS_FORCE_CUR_SGMII_MODE_1000;
> + break;
> + case SPEED_100:
> + speed_reg = AIROHA_PCS_LINK_MODE_P0_100M;
> + if_mode = AIROHA_PCS_HSGMII_AN_SPEED_FORCE_MODE_100;
> + ck_gen_mode = AIROHA_PCS_HSGMII_PCS_FORCE_CUR_SGMII_MODE_100;
> + break;
> + case SPEED_10:
> + speed_reg = AIROHA_PCS_LINK_MODE_P0_100M;
> + if_mode = AIROHA_PCS_HSGMII_AN_SPEED_FORCE_MODE_10;
> + ck_gen_mode = AIROHA_PCS_HSGMII_PCS_FORCE_CUR_SGMII_MODE_10;
> + break;
> + }
> +
> + if (interface == PHY_INTERFACE_MODE_SGMII) {
> + regmap_update_bits(priv->hsgmii_an, AIROHA_PCS_HSGMII_AN_SGMII_REG_AN_13,
> + AIROHA_PCS_HSGMII_AN_SPEED_FORCE_MODE,
> + if_mode);
> +
> + regmap_update_bits(priv->hsgmii_pcs, AIROHA_PCS_HSGMII_PCS_AN_SGMII_MODE_FORCE,
> + AIROHA_PCS_HSGMII_PCS_FORCE_CUR_SGMII_MODE |
> + AIROHA_PCS_HSGMII_PCS_FORCE_CUR_SGMII_MODE_SEL,
> + ck_gen_mode |
> + AIROHA_PCS_HSGMII_PCS_FORCE_CUR_SGMII_MODE_SEL);
> + }
> +
> + regmap_update_bits(priv->multi_sgmii, AIROHA_PCS_MULTI_SGMII_SGMII_STS_CTRL_0,
> + AIROHA_PCS_LINK_MODE_P0 |
> + AIROHA_PCS_FORCE_SPD_MODE_P0,
> + speed_reg |
> + AIROHA_PCS_FORCE_SPD_MODE_P0);
> + }
> + }
> +
> + /* Reset TXPCS on link up */
> + regmap_clear_bits(priv->xfi_pma, AIROHA_PCS_PMA_SW_RST_SET,
> + AIROHA_PCS_PMA_SW_HSG_TXPCS_RST_N);
> +
> + usleep_range(100, 200);
> +
> + regmap_set_bits(priv->xfi_pma, AIROHA_PCS_PMA_SW_RST_SET,
> + AIROHA_PCS_PMA_SW_HSG_TXPCS_RST_N);
> +}
> +
> +static const struct phylink_pcs_ops airoha_pcs_ops = {
> + .pcs_get_state = airoha_pcs_get_state,
> + .pcs_config = airoha_pcs_config,
> + .pcs_an_restart = airoha_pcs_an_restart,
> + .pcs_link_up = airoha_pcs_link_up,
> +};
> +
> +static const struct regmap_config airoha_pcs_regmap_config = {
> + .reg_bits = 32,
> + .val_bits = 32,
> + .reg_stride = 4,
> +};
> +
> +static int airoha_pcs_probe(struct platform_device *pdev)
> +{
> + struct regmap_config syscon_config = airoha_pcs_regmap_config;
> + struct device *dev = &pdev->dev;
> + struct airoha_pcs_priv *priv;
> + void *base;
Missing __iomem type here, will be fixed in v2.
> + int ret;
> +
> + priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);
> + if (!priv)
> + return -ENOMEM;
> +
> + priv->dev = dev;
> + priv->data = of_device_get_match_data(dev);
> +
> + base = devm_platform_ioremap_resource_byname(pdev, "xfi_mac");
> + if (IS_ERR(base))
> + return PTR_ERR(base);
> +
> + syscon_config.name = "xfi_mac";
> + priv->xfi_mac = devm_regmap_init_mmio(dev, base, &syscon_config);
> + if (IS_ERR(priv->xfi_mac))
> + return PTR_ERR(priv->xfi_mac);
> +
> + base = devm_platform_ioremap_resource_byname(pdev, "hsgmii_an");
> + if (IS_ERR(base))
> + return PTR_ERR(base);
> +
> + syscon_config.name = "hsgmii_an";
> + priv->hsgmii_an = devm_regmap_init_mmio(dev, base, &syscon_config);
> + if (IS_ERR(priv->hsgmii_an))
> + return PTR_ERR(priv->hsgmii_an);
> +
> + base = devm_platform_ioremap_resource_byname(pdev, "hsgmii_pcs");
> + if (IS_ERR(base))
> + return PTR_ERR(base);
> +
> + syscon_config.name = "hsgmii_pcs";
> + priv->hsgmii_pcs = devm_regmap_init_mmio(dev, base, &syscon_config);
> + if (IS_ERR(priv->hsgmii_pcs))
> + return PTR_ERR(priv->hsgmii_pcs);
> +
> + base = devm_platform_ioremap_resource_byname(pdev, "hsgmii_rate_adp");
> + if (IS_ERR(base))
> + return PTR_ERR(base);
> +
> + syscon_config.name = "hsgmii_rate_adp";
> + priv->hsgmii_rate_adp = devm_regmap_init_mmio(dev, base, &syscon_config);
> + if (IS_ERR(priv->hsgmii_rate_adp))
> + return PTR_ERR(priv->hsgmii_rate_adp);
> +
> + base = devm_platform_ioremap_resource_byname(pdev, "multi_sgmii");
> + if (IS_ERR(base))
> + return PTR_ERR(base);
> +
> + syscon_config.name = "multi_sgmii";
> + priv->multi_sgmii = devm_regmap_init_mmio(dev, base, &syscon_config);
> + if (IS_ERR(priv->multi_sgmii))
> + return PTR_ERR(priv->multi_sgmii);
> +
> + base = devm_platform_ioremap_resource_byname(pdev, "usxgmii");
> + if (IS_ERR(base) && PTR_ERR(base) != -ENOENT)
> + return PTR_ERR(base);
> +
> + syscon_config.name = "usxgmii";
> + priv->usxgmii_pcs = devm_regmap_init_mmio(dev, base, &syscon_config);
> + if (IS_ERR(priv->usxgmii_pcs))
> + return PTR_ERR(priv->usxgmii_pcs);
> +
> + base = devm_platform_ioremap_resource_byname(pdev, "xfi_pma");
> + if (IS_ERR(base) && PTR_ERR(base) != -ENOENT)
> + return PTR_ERR(base);
> +
> + syscon_config.name = "xfi_pma";
> + priv->xfi_pma = devm_regmap_init_mmio(dev, base, &syscon_config);
> + if (IS_ERR(priv->xfi_pma))
> + return PTR_ERR(priv->xfi_pma);
> +
> + base = devm_platform_ioremap_resource_byname(pdev, "xfi_ana");
> + if (IS_ERR(base) && PTR_ERR(base) != -ENOENT)
> + return PTR_ERR(base);
> +
> + syscon_config.name = "xfi_ana";
> + priv->xfi_ana = devm_regmap_init_mmio(dev, base, &syscon_config);
> + if (IS_ERR(priv->xfi_ana))
> + return PTR_ERR(priv->xfi_ana);
> +
> + /* SCU is used to toggle XFI or HSGMII in global SoC registers */
> + priv->scu = syscon_regmap_lookup_by_compatible("airoha,en7581-scu");
> + if (IS_ERR(priv->scu))
> + return PTR_ERR(priv->scu);
> +
> + priv->rsts[0].id = "mac";
> + priv->rsts[1].id = "phy";
> + ret = devm_reset_control_bulk_get_exclusive(dev, ARRAY_SIZE(priv->rsts),
> + priv->rsts);
> + if (ret)
> + return dev_err_probe(dev, ret, "failed to get bulk reset lines\n");
> +
> + platform_set_drvdata(pdev, priv);
> +
> + priv->pcs.ops = &airoha_pcs_ops;
> + priv->pcs.poll = true;
> +
> + __set_bit(PHY_INTERFACE_MODE_SGMII, priv->pcs.supported_interfaces);
> + __set_bit(PHY_INTERFACE_MODE_1000BASEX, priv->pcs.supported_interfaces);
> + __set_bit(PHY_INTERFACE_MODE_2500BASEX, priv->pcs.supported_interfaces);
> + __set_bit(PHY_INTERFACE_MODE_10GBASER, priv->pcs.supported_interfaces);
> + __set_bit(PHY_INTERFACE_MODE_USXGMII, priv->pcs.supported_interfaces);
> +
> + return of_pcs_add_provider(dev->of_node, of_pcs_simple_get,
> + &priv->pcs);
> +}
> +
> +static void airoha_pcs_remove(struct platform_device *pdev)
> +{
> + struct airoha_pcs_priv *priv = platform_get_drvdata(pdev);
> +
> + phylink_pcs_release(&priv->pcs);
> +
> + of_pcs_del_provider(pdev->dev.of_node);
> +}
> +
> +static const struct airoha_pcs_match_data an7581_pcs_eth = {
> + .port_type = AIROHA_PCS_ETH,
> +};
> +
> +static const struct airoha_pcs_match_data an7581_pcs_pon = {
> + .port_type = AIROHA_PCS_PON,
> +};
> +
> +static const struct of_device_id airoha_pcs_of_table[] = {
> + { .compatible = "airoha,an7581-pcs-eth", .data = &an7581_pcs_eth },
> + { .compatible = "airoha,an7581-pcs-pon", .data = &an7581_pcs_pon },
> + { /* sentinel */ },
> +};
> +MODULE_DEVICE_TABLE(of, airoha_pcs_of_table);
> +
> +static struct platform_driver airoha_pcs_driver = {
> + .driver = {
> + .name = "airoha-pcs",
> + .of_match_table = airoha_pcs_of_table,
> + },
> + .probe = airoha_pcs_probe,
> + .remove = airoha_pcs_remove,
> +};
> +module_platform_driver(airoha_pcs_driver);
> +
> +MODULE_LICENSE("GPL");
> +MODULE_DESCRIPTION("Airoha PCS driver");
> +MODULE_AUTHOR("Christian Marangi <ansuelsmth@xxxxxxxxx>");
> diff --git a/include/linux/pcs/pcs-airoha.h b/include/linux/pcs/pcs-airoha.h
> new file mode 100644
> index 000000000000..07797645ff15
> --- /dev/null
> +++ b/include/linux/pcs/pcs-airoha.h
> @@ -0,0 +1,11 @@
> +/* SPDX-License-Identifier: GPL-2.0 */
> +
> +#ifndef __LINUX_PCS_AIROHA_H
> +#define __LINUX_PCS_AIROHA_H
> +
> +/* XFI_MAC */
> +#define AIROHA_PCS_XFI_MAC_XFI_GIB_CFG 0x0
> +#define AIROHA_PCS_XFI_TX_FC_EN BIT(5)
> +#define AIROHA_PCS_XFI_RX_FC_EN BIT(4)
> +
> +#endif /* __LINUX_PCS_AIROHA_H */
> --
> 2.48.1
>
--
Ansuel