Re: [net-next PATCH 5/6] net: pcs: airoha: add PCS driver for Airoha SoC

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



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




[Index of Archives]     [Device Tree Compilter]     [Device Tree Spec]     [Linux Driver Backports]     [Video for Linux]     [Linux USB Devel]     [Linux PCI Devel]     [Linux Audio Users]     [Linux Kernel]     [Linux SCSI]     [XFree86]     [Yosemite Backpacking]


  Powered by Linux