mirror of https://lore.kernel.org/lkml/
 help / color / mirror / Atom feed
From: Zhengping Zhang <zhengping.zhang@airoha.com>
To: Christian Marangi <ansuelsmth@gmail.com>
Cc: Vinod Koul <vkoul@kernel.org>,
	Neil Armstrong <neil.armstrong@linaro.org>,
	Rob Herring <robh@kernel.org>,
	Krzysztof Kozlowski <krzk+dt@kernel.org>,
	Conor Dooley <conor+dt@kernel.org>,
	<linux-phy@lists.infradead.org>, <devicetree@vger.kernel.org>,
	<linux-kernel@vger.kernel.org>, <lei.dong@airoha.com>,
	<yalei.zang@airoha.com>, <zhengping.zhang@airoha.com>
Subject: Re: [PATCH v4 3/3] phy: airoha: Add support for Airoha AN7583 USB PHY
Date: Wed, 16 Sep 2026 22:00:50 +0800	[thread overview]
Message-ID: <aqqhErGXHUf7FQMx@mediatek.com> (raw)
In-Reply-To: <20260901123933.15388-4-ansuelsmth@gmail.com>

Tested-by: Zhengping Zhang <zhengping.zhang@airoha.com>

On Tue, Sep 01, 2026 at 02:39:33PM +0200, Christian Marangi wrote:
> Add support for USB PHY for Airoha AN7583 SoC, this share some U2 init
> from AN7581 but use a totally different init phase for PLL and
> calibration for U3. Also on AN7583 there is a single USB PHY that init 2
> U2 port and one U3 port. (the USB controller expose 2 hub, one with 2
> usb 2.0 port and one with one 3.0 port)
> 
> A second USB PHY is used for PCIe Gen2 controller and follow the same
> calibration and setup logic of USB.
> 
> Signed-off-by: Christian Marangi <ansuelsmth@gmail.com>
> ---
>  drivers/phy/Kconfig                 |    1 +
>  drivers/phy/Makefile                |    3 +-
>  drivers/phy/airoha/Kconfig          |   11 +
>  drivers/phy/airoha/Makefile         |    3 +
>  drivers/phy/airoha/phy-an7583-usb.c | 2023 +++++++++++++++++++++++++++
>  5 files changed, 2040 insertions(+), 1 deletion(-)
>  create mode 100644 drivers/phy/airoha/Kconfig
>  create mode 100644 drivers/phy/airoha/Makefile
>  create mode 100644 drivers/phy/airoha/phy-an7583-usb.c
> 
> diff --git a/drivers/phy/Kconfig b/drivers/phy/Kconfig
> index 19f3b7d12b7d..80b7c50fd768 100644
> --- a/drivers/phy/Kconfig
> +++ b/drivers/phy/Kconfig
> @@ -168,6 +168,7 @@ config PHY_XGENE
>  	help
>  	  This option enables support for APM X-Gene SoC multi-purpose PHY.
>  
> +source "drivers/phy/airoha/Kconfig"
>  source "drivers/phy/allwinner/Kconfig"
>  source "drivers/phy/amlogic/Kconfig"
>  source "drivers/phy/apple/Kconfig"
> diff --git a/drivers/phy/Makefile b/drivers/phy/Makefile
> index d7aa516bcc49..0baf0b7fd077 100644
> --- a/drivers/phy/Makefile
> +++ b/drivers/phy/Makefile
> @@ -20,7 +20,8 @@ obj-$(CONFIG_PHY_PISTACHIO_USB)		+= phy-pistachio-usb.o
>  obj-$(CONFIG_PHY_SNPS_EUSB2)		+= phy-snps-eusb2.o
>  obj-$(CONFIG_PHY_XGENE)			+= phy-xgene.o
>  
> -obj-$(CONFIG_GENERIC_PHY)		+= allwinner/	\
> +obj-$(CONFIG_GENERIC_PHY)		+= airoha/	\
> +					   allwinner/	\
>  					   amlogic/	\
>  					   apple/	\
>  					   axiado/	\
> diff --git a/drivers/phy/airoha/Kconfig b/drivers/phy/airoha/Kconfig
> new file mode 100644
> index 000000000000..13e49ff947e3
> --- /dev/null
> +++ b/drivers/phy/airoha/Kconfig
> @@ -0,0 +1,11 @@
> +# SPDX-License-Identifier: GPL-2.0-only
> +
> +config PHY_AIROHA_AN7583_USB
> +	tristate "Airoha AN7583 USB PHY Driver"
> +	depends on ARCH_AIROHA || COMPILE_TEST
> +	depends on OF
> +	select GENERIC_PHY
> +	help
> +	  Say 'Y' here to add support for Airoha AN7583 USB PHY driver.
> + 	  This driver create the basic PHY instance and provides initialize
> + 	  callback for USB port.
> diff --git a/drivers/phy/airoha/Makefile b/drivers/phy/airoha/Makefile
> new file mode 100644
> index 000000000000..e484a803505b
> --- /dev/null
> +++ b/drivers/phy/airoha/Makefile
> @@ -0,0 +1,3 @@
> +# SPDX-License-Identifier: GPL-2.0
> +
> +obj-$(CONFIG_PHY_AIROHA_AN7583_USB)	+= phy-an7583-usb.o
> diff --git a/drivers/phy/airoha/phy-an7583-usb.c b/drivers/phy/airoha/phy-an7583-usb.c
> new file mode 100644
> index 000000000000..46b5f09582cf
> --- /dev/null
> +++ b/drivers/phy/airoha/phy-an7583-usb.c
> @@ -0,0 +1,2023 @@
> +// SPDX-License-Identifier: GPL-2.0
> +/*
> + * Author: Christian Marangi <ansuelsmth@gmail.com>
> + */
> +
> +#include <dt-bindings/phy/phy.h>
> +#include <linux/bitfield.h>
> +#include <linux/math.h>
> +#include <linux/module.h>
> +#include <linux/phy.h>
> +#include <linux/phy/phy.h>
> +#include <linux/platform_device.h>
> +#include <linux/regmap.h>
> +#include <linux/mfd/syscon.h>
> +
> +/* PHY */
> +#define AIROHA_USB_PHY_FMCR0			0x100
> +#define   AIROHA_USB_PHY_MONCLK_SEL		GENMASK(27, 26)
> +#define   AIROHA_USB_PHY_MONCLK_SEL0		FIELD_PREP_CONST(AIROHA_USB_PHY_MONCLK_SEL, 0x0)
> +#define   AIROHA_USB_PHY_MONCLK_SEL1		FIELD_PREP_CONST(AIROHA_USB_PHY_MONCLK_SEL, 0x1)
> +#define   AIROHA_USB_PHY_MONCLK_SEL2		FIELD_PREP_CONST(AIROHA_USB_PHY_MONCLK_SEL, 0x2)
> +#define   AIROHA_USB_PHY_MONCLK_SEL3		FIELD_PREP_CONST(AIROHA_USB_PHY_MONCLK_SEL, 0x3)
> +#define   AIROHA_USB_PHY_FREQDET_EN		BIT(24)
> +#define   AIROHA_USB_PHY_CYCLECNT		GENMASK(23, 0)
> +#define AIROHA_USB_PHY_FMMONR0			0x10c
> +#define   AIROHA_USB_PHY_USB_FM_OUT		GENMASK(31, 0)
> +#define AIROHA_USB_PHY_FMMONR1			0x110
> +#define   AIROHA_USB_PHY_FRCK_EN		BIT(8)
> +
> +#define AIROHA_USB_PHY_USBPHYACR2		0x308
> +#define   AIROHA_USB_PHY_SIFSLV_MAC_BANDGAP_EN	BIT(17)
> +#define AIROHA_USB_PHY_USBPHYACR4		0x310
> +#define   AIROHA_USB_PHY_USB20_FS_CR		GENMASK(10, 8)
> +#define   AIROHA_USB_PHY_USB20_FS_CR_MAX	FIELD_PREP_CONST(AIROHA_USB_PHY_USB20_FS_CR, 0x0)
> +#define   AIROHA_USB_PHY_USB20_FS_CR_NORMAL	FIELD_PREP_CONST(AIROHA_USB_PHY_USB20_FS_CR, 0x2)
> +#define   AIROHA_USB_PHY_USB20_FS_CR_SMALLER	FIELD_PREP_CONST(AIROHA_USB_PHY_USB20_FS_CR, 0x4)
> +#define   AIROHA_USB_PHY_USB20_FS_CR_MIN	FIELD_PREP_CONST(AIROHA_USB_PHY_USB20_FS_CR, 0x6)
> +#define   AIROHA_USB_PHY_USB20_FS_SR		GENMASK(2, 0)
> +#define   AIROHA_USB_PHY_USB20_FS_SR_MAX	FIELD_PREP_CONST(AIROHA_USB_PHY_USB20_FS_SR, 0x0)
> +#define   AIROHA_USB_PHY_USB20_FS_SR_NORMAL	FIELD_PREP_CONST(AIROHA_USB_PHY_USB20_FS_SR, 0x2)
> +#define   AIROHA_USB_PHY_USB20_FS_SR_SMALLER	FIELD_PREP_CONST(AIROHA_USB_PHY_USB20_FS_SR, 0x4)
> +#define   AIROHA_USB_PHY_USB20_FS_SR_MIN	FIELD_PREP_CONST(AIROHA_USB_PHY_USB20_FS_SR, 0x6)
> +#define AIROHA_USB_PHY_USBPHYACR5		0x314
> +#define   AIROHA_USB_PHY_USB20_DISC_FIT_EN	BIT(28)
> +#define   AIROHA_USB_PHY_USB20_HSTX_SRCAL_EN	BIT(15)
> +#define   AIROHA_USB_PHY_USB20_HSTX_SRCTRL	GENMASK(14, 12)
> +#define AIROHA_USB_PHY_USBPHYACR6		0x318
> +#define   AIROHA_USB_PHY_USB20_BC11_SW_EN	BIT(23)
> +#define   AIROHA_USB_PHY_USB20_HSRX_BIAS_EN_SEL	 GENMASK(10, 9)
> +#define   AIROHA_USB_PHY_USB20_HSRX_BIAS_EN_SEL_ENPLL \
> +	FIELD_PREP_CONST(AIROHA_USB_PHY_USB20_HSRX_BIAS_EN_SEL, 0x0)
> +#define   AIROHA_USB_PHY_USB20_HSRX_BIAS_EN_SEL_IDLEB_RCV_EN \
> +	FIELD_PREP_CONST(AIROHA_USB_PHY_USB20_HSRX_BIAS_EN_SEL, 0x1)
> +#define   AIROHA_USB_PHY_USB20_HSRX_BIAS_EN_SEL_NO_ENPLL_FS_BIAS_EN \
> +	FIELD_PREP_CONST(AIROHA_USB_PHY_USB20_HSRX_BIAS_EN_SEL, 0x2)
> +#define   AIROHA_USB_PHY_USB20_HSRX_BIAS_EN_SEL_USB20_HSRX_TMODE_EN \
> +	FIELD_PREP_CONST(AIROHA_USB_PHY_USB20_HSRX_BIAS_EN_SEL, 0x3)
> +#define   AIROHA_USB_PHY_USB20_DISCTH		GENMASK(7, 4)
> +#define   AIROHA_USB_PHY_USB20_DISCTH_400	FIELD_PREP_CONST(AIROHA_USB_PHY_USB20_DISCTH, 0x0)
> +#define   AIROHA_USB_PHY_USB20_DISCTH_420	FIELD_PREP_CONST(AIROHA_USB_PHY_USB20_DISCTH, 0x1)
> +#define   AIROHA_USB_PHY_USB20_DISCTH_440	FIELD_PREP_CONST(AIROHA_USB_PHY_USB20_DISCTH, 0x2)
> +#define   AIROHA_USB_PHY_USB20_DISCTH_460	FIELD_PREP_CONST(AIROHA_USB_PHY_USB20_DISCTH, 0x3)
> +#define   AIROHA_USB_PHY_USB20_DISCTH_480	FIELD_PREP_CONST(AIROHA_USB_PHY_USB20_DISCTH, 0x4)
> +#define   AIROHA_USB_PHY_USB20_DISCTH_500	FIELD_PREP_CONST(AIROHA_USB_PHY_USB20_DISCTH, 0x5)
> +#define   AIROHA_USB_PHY_USB20_DISCTH_520	FIELD_PREP_CONST(AIROHA_USB_PHY_USB20_DISCTH, 0x6)
> +#define   AIROHA_USB_PHY_USB20_DISCTH_540	FIELD_PREP_CONST(AIROHA_USB_PHY_USB20_DISCTH, 0x7)
> +#define   AIROHA_USB_PHY_USB20_DISCTH_560	FIELD_PREP_CONST(AIROHA_USB_PHY_USB20_DISCTH, 0x8)
> +#define   AIROHA_USB_PHY_USB20_DISCTH_580	FIELD_PREP_CONST(AIROHA_USB_PHY_USB20_DISCTH, 0x9)
> +#define   AIROHA_USB_PHY_USB20_DISCTH_600	FIELD_PREP_CONST(AIROHA_USB_PHY_USB20_DISCTH, 0xa)
> +#define   AIROHA_USB_PHY_USB20_DISCTH_620	FIELD_PREP_CONST(AIROHA_USB_PHY_USB20_DISCTH, 0xb)
> +#define   AIROHA_USB_PHY_USB20_DISCTH_640	FIELD_PREP_CONST(AIROHA_USB_PHY_USB20_DISCTH, 0xc)
> +#define   AIROHA_USB_PHY_USB20_DISCTH_660	FIELD_PREP_CONST(AIROHA_USB_PHY_USB20_DISCTH, 0xd)
> +#define   AIROHA_USB_PHY_USB20_DISCTH_680	FIELD_PREP_CONST(AIROHA_USB_PHY_USB20_DISCTH, 0xe)
> +#define   AIROHA_USB_PHY_USB20_DISCTH_700	FIELD_PREP_CONST(AIROHA_USB_PHY_USB20_DISCTH, 0xf)
> +#define   AIROHA_USB_PHY_USB20_SQTH		GENMASK(3, 0)
> +#define   AIROHA_USB_PHY_USB20_SQTH_85		FIELD_PREP_CONST(AIROHA_USB_PHY_USB20_SQTH, 0x0)
> +#define   AIROHA_USB_PHY_USB20_SQTH_90		FIELD_PREP_CONST(AIROHA_USB_PHY_USB20_SQTH, 0x1)
> +#define   AIROHA_USB_PHY_USB20_SQTH_95		FIELD_PREP_CONST(AIROHA_USB_PHY_USB20_SQTH, 0x2)
> +#define   AIROHA_USB_PHY_USB20_SQTH_100		FIELD_PREP_CONST(AIROHA_USB_PHY_USB20_SQTH, 0x3)
> +#define   AIROHA_USB_PHY_USB20_SQTH_105		FIELD_PREP_CONST(AIROHA_USB_PHY_USB20_SQTH, 0x4)
> +#define   AIROHA_USB_PHY_USB20_SQTH_110		FIELD_PREP_CONST(AIROHA_USB_PHY_USB20_SQTH, 0x5)
> +#define   AIROHA_USB_PHY_USB20_SQTH_115		FIELD_PREP_CONST(AIROHA_USB_PHY_USB20_SQTH, 0x6)
> +#define   AIROHA_USB_PHY_USB20_SQTH_120		FIELD_PREP_CONST(AIROHA_USB_PHY_USB20_SQTH, 0x7)
> +#define   AIROHA_USB_PHY_USB20_SQTH_125		FIELD_PREP_CONST(AIROHA_USB_PHY_USB20_SQTH, 0x8)
> +#define   AIROHA_USB_PHY_USB20_SQTH_130		FIELD_PREP_CONST(AIROHA_USB_PHY_USB20_SQTH, 0x9)
> +#define   AIROHA_USB_PHY_USB20_SQTH_135		FIELD_PREP_CONST(AIROHA_USB_PHY_USB20_SQTH, 0xa)
> +#define   AIROHA_USB_PHY_USB20_SQTH_140		FIELD_PREP_CONST(AIROHA_USB_PHY_USB20_SQTH, 0xb)
> +#define   AIROHA_USB_PHY_USB20_SQTH_145		FIELD_PREP_CONST(AIROHA_USB_PHY_USB20_SQTH, 0xc)
> +#define   AIROHA_USB_PHY_USB20_SQTH_150		FIELD_PREP_CONST(AIROHA_USB_PHY_USB20_SQTH, 0xd)
> +#define   AIROHA_USB_PHY_USB20_SQTH_155		FIELD_PREP_CONST(AIROHA_USB_PHY_USB20_SQTH, 0xe)
> +#define   AIROHA_USB_PHY_USB20_SQTH_160		FIELD_PREP_CONST(AIROHA_USB_PHY_USB20_SQTH, 0xf)
> +
> +#define AIROHA_USB_PHY_U2PHYACR3		0x31c
> +#define   AIROHA_USB_PHY_USB20_HSTX_I_EN_MODE	GENMASK(25, 24)
> +#define   AIROHA_USB_PHY_USB20_HSTX_I_EN_MODE_TOGGLE FIELD_PREP_CONST(AIROHA_USB_PHY_USB20_HSTX_I_EN_MODE, 0x0)
> +#define   AIROHA_USB_PHY_USB20_HSTX_I_EN_MODE_HS_TERM FIELD_PREP_CONST(AIROHA_USB_PHY_USB20_HSTX_I_EN_MODE, 0x1)
> +#define   AIROHA_USB_PHY_USB20_HSTX_I_EN_MODE_FORCE_DISABLE FIELD_PREP_CONST(AIROHA_USB_PHY_USB20_HSTX_I_EN_MODE, 0x2)
> +#define   AIROHA_USB_PHY_USB20_HSTX_I_EN_MODE_FORCE_ENABLE FIELD_PREP_CONST(AIROHA_USB_PHY_USB20_HSTX_I_EN_MODE, 0x3)
> +#define   AIROHA_USB_PHY_USB20_USB11_TMODE_EN	BIT(19)
> +#define   AIROHA_USB_PHY_USB20_TMODE_FS_LS_TX_EN BIT(18)
> +#define   AIROHA_USB_PHY_USB20_PUPD_BIST_EN	BIT(12)
> +#define AIROHA_USB_PHY_U2PHYDTM0		0x368
> +#define   AIROHA_USB_PHY_FORCE_XCVRSEL		BIT(19)
> +#define   AIROHA_USB_PHY_FORCE_SUSPENDDM	BIT(18)
> +#define   AIROHA_USB_PHY_FORCE_TERMSEL		BIT(17)
> +#define   AIROHA_USB_PHY_XCVRSEL		GENMASK(5, 4)
> +#define   AIROHA_USB_PHY_TERMSEL		BIT(2)
> +#define AIROHA_USB_PHY_U2PHYDTM1		0x36c
> +#define   AIROHA_USB_PHY_FORCE_IDDIG		BIT(9)
> +#define   AIROHA_USB_PHY_IDDIG			BIT(1)
> +
> +#define AIROHA_USB_PHY_GPIO_CTLD		0x80c
> +#define   AIROHA_USB_PHY_C60802_GPIO_CTLD	GENMASK(31, 0)
> +#define     AIROHA_USB_PHY_SSUSB_IP_SW_RST	BIT(31)
> +#define     AIROHA_USB_PHY_MCU_BUS_CK_GATE_EN	BIT(30)
> +#define     AIROHA_USB_PHY_FORCE_SSUSB_IP_SW_RST BIT(29)
> +#define     AIROHA_USB_PHY_SSUSB_SW_RST		BIT(28)
> +
> +#define AIROHA_USB_PHY_U3_PHYA_REG0		0xb00
> +#define   AIROHA_USB_PHY_SSUSB_BG_DIV		GENMASK(29, 28)
> +#define   AIROHA_USB_PHY_SSUSB_BG_DIV_2		FIELD_PREP_CONST(AIROHA_USB_PHY_SSUSB_BG_DIV, 0x0)
> +#define   AIROHA_USB_PHY_SSUSB_BG_DIV_4		FIELD_PREP_CONST(AIROHA_USB_PHY_SSUSB_BG_DIV, 0x1)
> +#define   AIROHA_USB_PHY_SSUSB_BG_DIV_8		FIELD_PREP_CONST(AIROHA_USB_PHY_SSUSB_BG_DIV, 0x2)
> +#define   AIROHA_USB_PHY_SSUSB_BG_DIV_16	FIELD_PREP_CONST(AIROHA_USB_PHY_SSUSB_BG_DIV, 0x3)
> +#define AIROHA_USB_PHY_U3_PHYA_REG1		0xb04
> +#define   AIROHA_USB_PHY_SSUSB_XTAL_TOP_RESERVE	GENMASK(25, 10)
> +#define AIROHA_USB_PHY_U3_PHYA_REG6		0xb18
> +#define   AIROHA_USB_PHY_SSUSB_CDR_RESERVE	GENMASK(31, 24)
> +#define AIROHA_USB_PHY_U3_PHYA_REG8		0xb20
> +#define   AIROHA_USB_PHY_SSUSB_CDR_RST_DLY	GENMASK(7, 6)
> +#define   AIROHA_USB_PHY_SSUSB_CDR_RST_DLY_32	FIELD_PREP_CONST(AIROHA_USB_PHY_SSUSB_CDR_RST_DLY, 0x0)
> +#define   AIROHA_USB_PHY_SSUSB_CDR_RST_DLY_64	FIELD_PREP_CONST(AIROHA_USB_PHY_SSUSB_CDR_RST_DLY, 0x1)
> +#define   AIROHA_USB_PHY_SSUSB_CDR_RST_DLY_128	FIELD_PREP_CONST(AIROHA_USB_PHY_SSUSB_CDR_RST_DLY, 0x2)
> +#define   AIROHA_USB_PHY_SSUSB_CDR_RST_DLY_216	FIELD_PREP_CONST(AIROHA_USB_PHY_SSUSB_CDR_RST_DLY, 0x3)
> +
> +#define AIROHA_USB_PHY_U3_PHYA_DA_REG19		0xc38
> +#define   AIROHA_USB_PHY_SSUSB_PLL_SSC_DELTA1_U3 GENMASK(15, 0)
> +
> +/* ANA */
> +#define AIROHA_USB_ANA_RXAFE_RESERVE		0x4
> +#define   AIROHA_USB_ANA_CDR_PD_10B_EN		BIT(11)
> +#define   AIROHA_USB_ANA_CDR_PD_EDGE_DIS	BIT(10)
> +#define AIROHA_USB_ANA_CDR_LPF_BOT_LIM		0x8
> +#define   AIROHA_USB_ANA_CDR_LPF_KP_GAIN	GENMASK(26, 24)
> +#define   AIROHA_USB_ANA_CDR_LPF_KI_GAIN	GENMASK(22, 20)
> +#define AIROHA_USB_ANA_CDR_LPF_MJV_LIM		0xc
> +#define   AIROHA_USB_ANA_CDR_LPF_RATIO		GENMASK(5, 4)
> +#define AIROHA_USB_ANA_CDR_PR_CKREF_DIV1	0x18
> +#define   AIROHA_USB_ANA_CDR_PR_KBAND_DIV	GENMASK(26, 24)
> +#define   AIROHA_USB_ANA_CDR_PR_DAC_BAND	GENMASK(12, 8)
> +#define AIROHA_USB_ANA_CDR_PR_KBAND_DIV_PCIE_REG 0x1c
> +#define   AIROHA_USB_ANA_CDR_PR_XFICK_EN	BIT(30)
> +#define   AIROHA_USB_ANA_CDR_PR_KBAND_PCIE_MODE	BIT(6)
> +#define   AIROHA_USB_ANA_CDR_PR_KBAND_DIV_PCIE	GENMASK(5, 0)
> +#define AIROHA_USB_ANA_CDR_FORCE_IBANDLPF_R_OFF	0x20
> +#define   AIROHA_USB_ANA_CDR_PHYCK_RSTB		BIT(13)
> +#define AIROHA_USB_ANA_QP_TX_MODE_16B_EN	0x28
> +#define   AIROHA_USB_QP_TX_RESERVE		GENMASK(31, 16)
> +#define     AIROHA_USB_ANA_TX_VLMON_EN		BIT(2)
> +#define     AIROHA_USB_ANA_TX_RESERVE_8		BIT(8)
> +#define AIROHA_USB_ANA_RXLBTX_EN		0x2c
> +#define   AIROHA_USB_ANA_TX_DMEDGEGEN_EN	BIT(27)
> +#define   AIROHA_USB_ANA_TX_RXDET_METHOD	BIT(25)
> +#define AIROHA_USB_ANA_SSUSB_BGR_EN		0x30
> +#define   AIROHA_USB_ANA_BIAS_V2V_CAL		GENMASK(26, 21)
> +#define   AIROHA_USB_ANA_SSUSB_BG_DIV		GENMASK(3, 2)
> +#define   AIROHA_USB_ANA_SSUSB_CHPEN		BIT(1)
> +#define AIROHA_USB_ANA_CLKDRV_IMPSEL		0x34
> +#define   AIROHA_USB_ANA_PCIE_CLKDRV_AMP	GENMASK(27, 25)
> +#define   AIROHA_USB_ANA_PCIE_CLKDRV_FORCEIN	GENMASK(24, 23)
> +#define   AIROHA_USB_ANA_PCIE_CLKDRV_HZ		BIT(14)
> +#define   AIROHA_USB_ANA_PCIE_CLKDRV_RP		GENMASK(13, 9)
> +#define   AIROHA_USB_ANA_PCIE_CLKDRV_IMPSEL	GENMASK(4, 0)
> +#define AIROHA_USB_ANA_TDC_FT_CK_EN		0x38
> +#define   AIROHA_USB_ANA_PLL_DEBUG_SEL		BIT(19)
> +#define   AIROHA_USB_ANA_VUSB10_ON		BIT(8)
> +#define AIROHA_USB_ANA_PLL_IPLL_DIG_PWR_SEL	0x3c
> +#define   AIROHA_USB_ANA_PLL_PREDIV		GENMASK(26, 25)
> +#define   AIROHA_USB_ANA_PLL_OSCAL_ENB		BIT(19)
> +#define   AIROHA_USB_ANA_PLL_MON_LDO_SEL	GENMASK(18, 16)
> +#define   AIROHA_USB_ANA_PLL_MONVC_EN		BIT(14)
> +#define   AIROHA_USB_ANA_PLL_LDOLPF_VSEL	GENMASK(6, 5)
> +#define AIROHA_USB_ANA_PLL_SDM_ORD		0x40
> +#define   AIROHA_USB_ANA_PLL_SSC_TRI_EN		BIT(4)
> +#define   AIROHA_USB_ANA_PLL_SSC_PHASE_INI	BIT(3)
> +
> +/* PMA */
> +#define AIROHA_USB_PMA_TX_DA_CTRL_0		0x0
> +#define   AIROHA_USB_PMA_RXDET_RD_WAIT_TIMER	GENMASK(15, 12)
> +#define   AIROHA_USB_PMA_RXDET_EN_WINDOW	GENMASK(9, 4)
> +#define AIROHA_USB_PMA_TX_DA_CTRL_1		0x4
> +#define   AIROHA_USB_PMA_FORCE_TX_BIT_INVERSE	BIT(7)
> +#define AIROHA_USB_PMA_TX_DA_CTRL_2		0x8
> +#define   AIROHA_USB_PMA_FORCE_TX_DEM_SEL	BIT(27)
> +#define AIROHA_USB_PMA_TX_DA_CTRL_3		0xc
> +#define   AIROHA_USB_PMA_TX_DATA_RATE_SEL	GENMASK(30, 28)
> +#define AIROHA_USB_PMA_PON_RXFEDIG_CTRL_0	0x100
> +#define   AIROHA_USB_PMA_EQ_RX500M_CK_SEL	BIT(12)
> +#define AIROHA_USB_PMA_PON_RXFEDIG_CTRL_8	0x120
> +#define   AIROHA_USB_PMA_QP_EQ_EYE_MASK		GENMASK(9, 0)
> +#define AIROHA_USB_PMA_PON_RXFEDIG_CTRL_10	0x128
> +#define   AIROHA_USB_PMA_QP_EQ_PIEYE_INI	GENMASK(22, 16)
> +#define AIROHA_USB_PMA_SS_LCPLL_PWCTL_SETTING_2	0x208
> +#define   AIROHA_USB_PMA_NCPO_ANA_MSB		GENMASK(17, 16)
> +#define AIROHA_USB_PMA_SS_LCPLL_TDC_FLT_2	0x230
> +#define   AIROHA_USB_PMA_LCPLL_NCPO_VALUE	GENMASK(30, 0)
> +#define AIROHA_USB_PMA_SS_LCPLL_TDC_FLT_5	0x23c
> +#define   AIROHA_USB_PMA_LCPLL_NCPO_CHG		BIT(24)
> +#define AIROHA_USB_PMA_SS_LCPLL_TDC_PCW_1	0x248
> +#define   AIROHA_USB_PMA_LCPLL_PON_HRDDS_PCW_NCPO_GPON GENMASK(30, 0)
> +#define AIROHA_USB_PMA_INTF_CTRL_5		0x314
> +#define   AIROHA_USB_PMA_RX_HZ_SEL		BIT(5)
> +#define   AIROHA_USB_PMA_RX_HZ_FORCE		BIT(4)
> +#define AIROHA_USB_PMA_INTF_CTRL_6		0x318
> +#define   AIROHA_USB_PMA_TX_DATA_EN_SEL		BIT(13)
> +#define   AIROHA_USB_PMA_TX_DATA_EN_FORCE	BIT(12)
> +#define AIROHA_USB_PMA_INTF_CTRL_7		0x31c
> +#define   AIROHA_USB_PMA_PLL_EN_SEL		BIT(5)
> +#define   AIROHA_USB_PMA_PLL_EN_FORCE		BIT(4)
> +#define AIROHA_USB_PMA_INTF_CTRL_8		0x320
> +#define   AIROHA_USB_PMA_XTAL_EXT_EN_SEL	BIT(13)
> +#define   AIROHA_USB_PMA_XTAL_EXT_EN_FORCE	GENMASK(12, 11)
> +#define   AIROHA_USB_PMA_TX_TERM_SEL_SEL	BIT(7)
> +#define   AIROHA_USB_PMA_TX_TERM_SEL_FORCE	GENMASK(6, 5)
> +#define AIROHA_USB_PMA_INTF_STS_9		0x364
> +#define   AIROHA_USB_PMA_RX_IMP_SEL_SEL		BIT(31)
> +#define   AIROHA_USB_PMA_RX_IMP_SEL_FORCE	GENMASK(30, 26)
> +#define   AIROHA_USB_PMA_ADDR_INTF_STS_PLL_VCOCAL GENMASK(23, 16)
> +#define AIROHA_USB_PMA_PLL_CTRL_0		0x400
> +#define   AIROHA_USB_PMA_AUTO_INIT		BIT(0)
> +#define AIROHA_USB_PMA_PLL_CTRL_1		0x404
> +#define   AIROHA_USB_PMA_PLL_SSC_EN		BIT(30)
> +#define AIROHA_USB_PMA_PLL_CTRL_2		0x408
> +#define   AIROHA_USB_PMA_PLL_SDM_IFM_INTF	BIT(30)
> +#define   AIROHA_USB_PMA_PLL_RICO_SEL_INTF	BIT(29)
> +#define   AIROHA_USB_PMA_PLL_PHY_CK_EN_INTF	BIT(27)
> +#define   AIROHA_USB_PMA_PLL_PCK_SEL_INTF	BIT(22)
> +#define   AIROHA_USB_PMA_PLL_KBAND_PREDIV_INTF	GENMASK(21, 20)
> +#define   AIROHA_USB_PMA_PLL_IR_INTF		GENMASK(19, 16)
> +#define   AIROHA_USB_PMA_PLL_ICOIQ_EN_INTF	BIT(14)
> +#define   AIROHA_USB_PMA_PLL_FBKSEL_INTF	GENMASK(13, 12)
> +#define   AIROHA_USB_PMA_PLL_BR_INTF		GENMASK(10, 8)
> +#define   AIROHA_USB_PMA_PLL_BPB_INTF		GENMASK(7, 6)
> +#define   AIROHA_USB_PMA_PLL_BPA_INTF		GENMASK(4, 2)
> +#define   AIROHA_USB_PMA_PLL_BC_INTF		GENMASK(1, 0)
> +#define AIROHA_USB_PMA_PLL_CTRL_3		0x40c
> +#define   AIROHA_USB_PMA_PLL_SSC_PERIOD_INTF	GENMASK(31, 16)
> +#define   AIROHA_USB_PMA_PLL_SSC_DELTA_INTF	GENMASK(15, 0)
> +#define AIROHA_USB_PMA_PLL_CTRL_4		0x410
> +#define   AIROHA_USB_PMA_PLL_SDM_HREN_INTF	GENMASK(4, 3)
> +#define   AIROHA_USB_PMA_PLL_ICOLP_EN_INTF	BIT(2)
> +#define AIROHA_USB_PMA_PLL_CK_CTRL_0		0x414
> +#define   AIROHA_USB_PMA_PCIE_CLKTX_EN_INTF	BIT(5)
> +#define   AIROHA_USB_PMA_PCIE_CLKRX_EN_INTF	BIT(4)
> +#define AIROHA_USB_PMA_PLL_CK_CTRL_1		0x418
> +#define   AIROHA_USB_PMA_PLL_FORCE_UNSTABLE	BIT(19)
> +#define   AIROHA_USB_PMA_PLL_FORCE_STABLE	BIT(18)
> +#define AIROHA_USB_PMA_PLL_CK_CTRL_2		0x41c
> +#define   AIROHA_USB_PMA_PCIE_MODE_PLL_AUTO_OFF_EN BIT(2)
> +#define   AIROHA_USB_PMA_PCIE_MODE_PLL_AUTO_ON_EN BIT(1)
> +#define   AIROHA_USB_PMA_PCIE_MODE_PLL_AUTO_EN	BIT(0)
> +#define AIROHA_USB_PMA_RX_SYS_CTRL_0		0x600
> +#define   AIROHA_USB_PMA_ROC_CK_EN		BIT(1)
> +#define AIROHA_USB_PMA_RX_DLY_0			0x614
> +#define   AIROHA_USB_PMA_RX_PI_CAL_EN_H_DLY	GENMASK(7, 0)
> +#define AIROHA_USB_PMA_RX_CTRL_2		0x630
> +#define   AIROHA_USB_PMA_RX_EQ_EN_H_DLY		GENMASK(28, 16)
> +#define AIROHA_USB_PMA_RX_CTRL_5		0x63c
> +#define   AIROHA_USB_PMA_FREDET_CHK_CYCLE	GENMASK(29, 10)
> +#define AIROHA_USB_PMA_RX_CTRL_6		0x640
> +#define   AIROHA_USB_PMA_FREDET_GOLDEN_CYCLE	GENMASK(19, 0)
> +#define AIROHA_USB_PMA_RX_CTRL_7		0x644
> +#define   AIROHA_USB_PMA_FREDET_TOLERATE_CYCLE	GENMASK(19, 0)
> +#define AIROHA_USB_PMA_RX_CTRL_10		0x650
> +#define   AIROHA_USB_PMA_CRSDET_RSTB		BIT(1)
> +#define AIROHA_USB_PMA_RX_CTRL_11		0x654
> +#define   AIROHA_USB_PMA_FORCE_SIGDET_5G	BIT(19)
> +#define AIROHA_USB_PMA_RX_CTRL_26		0x690
> +#define   AIROHA_USB_PMA_QP_EQ_RETRAIN_ONLY_EN	BIT(26)
> +#define   AIROHA_USB_PMA_LINK_ERRO_EN		BIT(23)
> +#define AIROHA_USB_PMA_RX_CTRL_27		0x694
> +#define   AIROHA_USB_PMA_QP_LINK_ERRO_CNT	GENMASK(31, 0)
> +#define AIROHA_USB_PMA_RX_CTRL_36		0x6b8
> +#define   AIROHA_USB_PMA_PCIE_USB_SYSTEM	BIT(26)
> +#define   AIROHA_USB_PMA_LCK2DATA_DLY_TIME	GENMASK(23, 16)
> +#define AIROHA_USB_PMA_RX_CTRL_38		0x6C0
> +#define   AIROHA_USB_PMA_RESERVE_3		GENMASK(31, 24)
> +#define AIROHA_USB_PMA_RX_CTRL_45		0x6dc
> +#define   AIROHA_USB_PMA_EQ_EN_DLY		GENMASK(12, 0)
> +#define AIROHA_USB_PMA_RX_CTRL_46		0x6e0
> +#define   AIROHA_USB_PMA_PCIE_USB_BYPASS_EQ_P3_TO_P0_EN	BIT(29)
> +#define   AIROHA_USB_PMA_PCIE_USB_BYPASS_EQ_P2_TO_P0_EN	BIT(28)
> +#define   AIROHA_USB_PMA_PCIE_USB_BYPASS_EQ_P1_TO_P0_EN	BIT(27)
> +#define   AIROHA_USB_PMA_REBACK_P0_LCK2REF_EN	BIT(26)
> +#define AIROHA_USB_PMA_RX_CTRL_49		0x6ec
> +#define   AIROHA_USB_PMA_LFPS_FINISH_TIME	GENMASK(31, 21)
> +#define AIROHA_USB_PMA_RX_CTRL_50		0x6f0
> +#define   AIROHA_USB_PMA_P3_TO_P0_DO_EQ_USB	BIT(28)
> +#define   AIROHA_USB_PMA_P2_TO_P0_DO_EQ_USB	BIT(27)
> +#define   AIROHA_USB_PMA_P1_TO_P0_DO_EQ_USB	BIT(26)
> +#define   AIROHA_USB_PMA_EQ_EN_DLY_SHORT	GENMASK(25, 13)
> +#define   AIROHA_USB_PMA_RX_EQ_EN_H_DLY_SHORT	GENMASK(12, 0)
> +
> +/* DIG */
> +#define AIROHA_USB_DIG_CK_RST_CTRL_3		0x30c
> +#define   AIROHA_USB_DIG_NS_CK_DIV_SEL		BIT(25)
> +#define   AIROHA_USB_DIG_US_CK_DIV_SEL		BIT(24)
> +#define AIROHA_USB_DIG_MODE_CTRL_0		0x324
> +#define   AIROHA_USB_DIG_SGMII_AN_EN		BIT(0)
> +#define AIROHA_USB_DIG_MODE_CTRL_1		0x330
> +#define   AIROHA_USB_DIG_TPHY_SPEED		GENMASK(3, 2)
> +#define AIROHA_USB_DIG_CK_RST_CTRL_7		0x340
> +#define   AIROHA_USB_DIG_MULTI_USB2P5_EN	BIT(26)
> +#define   AIROHA_USB_DIG_MULTI_USB5_EN		BIT(25)
> +#define   AIROHA_USB_DIG_MULTI_PHY_USB_EN	BIT(24)
> +
> +#define AIROHA_USB_PHY_U2_FM_DET_CYCLE_CNT	1024
> +#define AIROHA_USB_PHY_REF_CK			20
> +#define AIROHA_USB_PHY_U2_SR_COEF		28
> +#define AIROHA_USB_PHY_U2_SR_COEF_DIVISOR	1000
> +
> +#define AIROHA_USB_PHY_FREQDET_SLEEP		1000 /* 1ms */
> +#define AIROHA_USB_PHY_FREQDET_TIMEOUT		(AIROHA_USB_PHY_FREQDET_SLEEP * 10)
> +
> +#define AIROHA_USB_PHY_U3_MAX_CALIB_TRY		50
> +#define AIROHA_USB_PHY_MAX_INSTANCE		3
> +#define AIROHA_PCIE_PHY_MAX_INSTANCE		1
> +
> +struct an7583_usb_phy_instance {
> +	struct device_node *node;
> +	u32 type;
> +
> +	u32 offset;
> +	unsigned int monclk_sel;
> +	struct phy *serdes_phy;
> +};
> +
> +enum an7583_usb_phy_regs {
> +	AIROHA_USB_PHY_PHY,
> +	AIROHA_USB_PHY_ANA,
> +	AIROHA_USB_PHY_PMA,
> +	AIROHA_USB_PHY_DIG,
> +
> +	AIROHA_USB_PHY_REGS_MAX,
> +};
> +
> +struct an7583_usb_phy_priv {
> +	struct regmap *regs[AIROHA_USB_PHY_REGS_MAX];
> +
> +	struct phy *phys[AIROHA_USB_PHY_MAX_INSTANCE];
> +};
> +
> +struct an7583_usb_phy_match_data {
> +	int max_instance;
> +	const char * const *regs_name;
> +	int regs_num;
> +	int (*parse_ports)(struct device *dev,
> +			   struct an7583_usb_phy_priv *priv,
> +			   int index, struct device_node *subnode);
> +};
> +
> +static int an7583_usb_phy_u2_slew_rate_calibration(struct phy *phy)
> +{
> +	struct an7583_usb_phy_instance *instance = phy_get_drvdata(phy);
> +	struct an7583_usb_phy_priv *priv;
> +	struct device *dev;
> +	u32 offset, srctrl;
> +	u32 fm_out = 0;
> +
> +	dev = phy->dev.parent;
> +	priv = dev_get_drvdata(dev);
> +	offset = instance->offset;
> +
> +	/* Enable HS TX SR calibration */
> +	regmap_set_bits(priv->regs[AIROHA_USB_PHY_PHY],
> +			AIROHA_USB_PHY_USBPHYACR5 + offset,
> +			AIROHA_USB_PHY_USB20_HSTX_SRCAL_EN);
> +
> +	usleep_range(1000, 1500);
> +
> +	/* Enable Free run clock */
> +	regmap_set_bits(priv->regs[AIROHA_USB_PHY_PHY],
> +			AIROHA_USB_PHY_FMMONR1 + offset,
> +			AIROHA_USB_PHY_FRCK_EN);
> +
> +	/* Select Monitor Clock */
> +	regmap_update_bits(priv->regs[AIROHA_USB_PHY_PHY],
> +			   AIROHA_USB_PHY_FMCR0 + offset,
> +			   AIROHA_USB_PHY_MONCLK_SEL,
> +			   FIELD_PREP(AIROHA_USB_PHY_MONCLK_SEL,
> +				      instance->monclk_sel));
> +
> +	/* Set cyclecnt */
> +	regmap_update_bits(priv->regs[AIROHA_USB_PHY_PHY],
> +			   AIROHA_USB_PHY_FMCR0 + offset,
> +			   AIROHA_USB_PHY_CYCLECNT,
> +			   FIELD_PREP(AIROHA_USB_PHY_CYCLECNT,
> +				      AIROHA_USB_PHY_U2_FM_DET_CYCLE_CNT));
> +
> +	/* Enable Frequency meter */
> +	regmap_set_bits(priv->regs[AIROHA_USB_PHY_PHY],
> +			AIROHA_USB_PHY_FMCR0 + offset,
> +			AIROHA_USB_PHY_FREQDET_EN);
> +
> +	/* Timeout can happen and we will apply workaround at the end */
> +	regmap_read_poll_timeout(priv->regs[AIROHA_USB_PHY_PHY],
> +				 AIROHA_USB_PHY_FMMONR0 + offset,
> +				 fm_out, fm_out, AIROHA_USB_PHY_FREQDET_SLEEP,
> +				 AIROHA_USB_PHY_FREQDET_TIMEOUT);
> +
> +	/* Disable Frequency meter */
> +	regmap_clear_bits(priv->regs[AIROHA_USB_PHY_PHY],
> +			  AIROHA_USB_PHY_FMCR0 + offset,
> +			  AIROHA_USB_PHY_FREQDET_EN);
> +
> +	/* Disable Free run clock */
> +	regmap_clear_bits(priv->regs[AIROHA_USB_PHY_PHY],
> +			  AIROHA_USB_PHY_FMMONR1 + offset,
> +			  AIROHA_USB_PHY_FRCK_EN);
> +
> +	/* Disable HS TX SR calibration */
> +	regmap_clear_bits(priv->regs[AIROHA_USB_PHY_PHY],
> +			  AIROHA_USB_PHY_USBPHYACR5 + offset,
> +			  AIROHA_USB_PHY_USB20_HSTX_SRCAL_EN);
> +
> +	usleep_range(1000, 1500);
> +
> +	/* Frequency was not detected, use default SR calibration value */
> +	if (!fm_out) {
> +		srctrl = 0x5;
> +		dev_err(dev, "Frequency not detected, using default SR calibration.\n");
> +	/* (1024 / FM_OUT) * REF_CK * U2_SR_COEF (round to the nearest digits) */
> +	} else {
> +		srctrl = AIROHA_USB_PHY_REF_CK * AIROHA_USB_PHY_U2_SR_COEF;
> +		srctrl = (srctrl * AIROHA_USB_PHY_U2_FM_DET_CYCLE_CNT) / fm_out;
> +		srctrl = DIV_ROUND_CLOSEST(srctrl, AIROHA_USB_PHY_U2_SR_COEF_DIVISOR);
> +		dev_dbg(dev, "SR calibration applied: %x\n", srctrl);
> +	}
> +
> +	regmap_update_bits(priv->regs[AIROHA_USB_PHY_PHY],
> +			   AIROHA_USB_PHY_USBPHYACR5 + offset,
> +			   AIROHA_USB_PHY_USB20_HSTX_SRCTRL,
> +			   FIELD_PREP(AIROHA_USB_PHY_USB20_HSTX_SRCTRL, srctrl));
> +
> +	return 0;
> +}
> +
> +static bool an7583_usb_phy_u3_kband_is_calibrated(struct an7583_usb_phy_priv *priv)
> +{
> +	u32 val, res;
> +
> +	/* Default ICO setting */
> +	regmap_clear_bits(priv->regs[AIROHA_USB_PHY_PMA],
> +			  AIROHA_USB_PMA_PLL_CTRL_4,
> +			  AIROHA_USB_PMA_PLL_ICOLP_EN_INTF);
> +
> +	regmap_update_bits(priv->regs[AIROHA_USB_PHY_ANA],
> +			   AIROHA_USB_ANA_SSUSB_BGR_EN,
> +			   AIROHA_USB_ANA_BIAS_V2V_CAL,
> +			   FIELD_PREP(AIROHA_USB_ANA_BIAS_V2V_CAL, 0x15));
> +
> +	regmap_update_bits(priv->regs[AIROHA_USB_PHY_ANA],
> +			   AIROHA_USB_ANA_PLL_IPLL_DIG_PWR_SEL,
> +			   AIROHA_USB_ANA_PLL_OSCAL_ENB |
> +			   AIROHA_USB_ANA_PLL_LDOLPF_VSEL,
> +			   AIROHA_USB_ANA_PLL_OSCAL_ENB |
> +			   FIELD_PREP(AIROHA_USB_ANA_PLL_LDOLPF_VSEL, 0x1));
> +
> +	regmap_set_bits(priv->regs[AIROHA_USB_PHY_PMA],
> +			AIROHA_USB_PMA_PLL_CTRL_2,
> +			AIROHA_USB_PMA_PLL_RICO_SEL_INTF);
> +
> +	regmap_clear_bits(priv->regs[AIROHA_USB_PHY_PMA],
> +			  AIROHA_USB_PMA_INTF_CTRL_8,
> +			  AIROHA_USB_PMA_XTAL_EXT_EN_SEL |
> +			  AIROHA_USB_PMA_XTAL_EXT_EN_FORCE);
> +
> +	regmap_set_bits(priv->regs[AIROHA_USB_PHY_PMA],
> +			AIROHA_USB_PMA_PLL_CTRL_2,
> +			AIROHA_USB_PMA_PLL_ICOIQ_EN_INTF);
> +
> +	/* Read KBand */
> +	regmap_clear_bits(priv->regs[AIROHA_USB_PHY_ANA],
> +			  AIROHA_USB_ANA_TDC_FT_CK_EN,
> +			  AIROHA_USB_ANA_PLL_DEBUG_SEL);
> +
> +	usleep_range(5000, 6000);
> +
> +	regmap_read(priv->regs[AIROHA_USB_PHY_PMA],
> +		    AIROHA_USB_PMA_INTF_STS_9, &val);
> +	res = FIELD_GET(AIROHA_USB_PMA_ADDR_INTF_STS_PLL_VCOCAL, val) << 4;
> +
> +	regmap_set_bits(priv->regs[AIROHA_USB_PHY_ANA],
> +			AIROHA_USB_ANA_TDC_FT_CK_EN,
> +			AIROHA_USB_ANA_PLL_DEBUG_SEL);
> +
> +	usleep_range(5000, 6000);
> +
> +	regmap_read(priv->regs[AIROHA_USB_PHY_PMA],
> +		    AIROHA_USB_PMA_INTF_STS_9, &val);
> +	res |= FIELD_GET(AIROHA_USB_PMA_ADDR_INTF_STS_PLL_VCOCAL, val);
> +
> +	/*
> +	 * KBand is calibrated if KBand Code is NOT 0xfff and
> +	 * KBand Done is set.
> +	 */
> +	return res != 0xfff && res & 0x800;
> +}
> +
> +static int an7583_usb_phy_u2_init(struct phy *phy)
> +{
> +	struct an7583_usb_phy_instance *instance = phy_get_drvdata(phy);
> +	struct an7583_usb_phy_priv *priv;
> +	struct device *dev;
> +	u32 offset;
> +
> +	dev = phy->dev.parent;
> +	priv = dev_get_drvdata(dev);
> +	offset = instance->offset;
> +
> +	mdelay(1);
> +
> +	regmap_update_bits(priv->regs[AIROHA_USB_PHY_PHY],
> +			   AIROHA_USB_PHY_USBPHYACR4 + offset,
> +			   AIROHA_USB_PHY_USB20_FS_CR,
> +			   AIROHA_USB_PHY_USB20_FS_CR_MIN);
> +
> +	regmap_update_bits(priv->regs[AIROHA_USB_PHY_PHY],
> +			   AIROHA_USB_PHY_USBPHYACR4 + offset,
> +			   AIROHA_USB_PHY_USB20_FS_SR,
> +			   AIROHA_USB_PHY_USB20_FS_SR_NORMAL);
> +
> +	/* FIXME: evaluate if needed */
> +	regmap_update_bits(priv->regs[AIROHA_USB_PHY_PHY],
> +			   AIROHA_USB_PHY_USBPHYACR6 + offset,
> +			   AIROHA_USB_PHY_USB20_SQTH,
> +			   AIROHA_USB_PHY_USB20_SQTH_125);
> +
> +	regmap_update_bits(priv->regs[AIROHA_USB_PHY_PHY],
> +			   AIROHA_USB_PHY_USBPHYACR6 + offset,
> +			   AIROHA_USB_PHY_USB20_DISCTH,
> +			   AIROHA_USB_PHY_USB20_DISCTH_580);
> +
> +	/* Enable the USB port and then disable after calibration */
> +	regmap_clear_bits(priv->regs[AIROHA_USB_PHY_PHY],
> +			  AIROHA_USB_PHY_USBPHYACR6 + offset,
> +			  AIROHA_USB_PHY_USB20_BC11_SW_EN);
> +
> +	an7583_usb_phy_u2_slew_rate_calibration(phy);
> +
> +	regmap_set_bits(priv->regs[AIROHA_USB_PHY_PHY],
> +			AIROHA_USB_PHY_USBPHYACR6 + offset,
> +			AIROHA_USB_PHY_USB20_BC11_SW_EN);
> +
> +	usleep_range(1000, 1500);
> +
> +	return 0;
> +}
> +
> +static int an7583_usb_phy_eth_init_sgmii(struct an7583_usb_phy_priv *priv)
> +{
> +	regmap_update_bits(priv->regs[AIROHA_USB_PHY_PMA], AIROHA_USB_PMA_RX_CTRL_27,
> +			   AIROHA_USB_PMA_QP_LINK_ERRO_CNT,
> +			   FIELD_PREP(AIROHA_USB_PMA_QP_LINK_ERRO_CNT, 0x100000));
> +
> +	regmap_update_bits(priv->regs[AIROHA_USB_PHY_PMA],
> +			   AIROHA_USB_PMA_SS_LCPLL_TDC_PCW_1,
> +			   AIROHA_USB_PMA_LCPLL_PON_HRDDS_PCW_NCPO_GPON,
> +			   FIELD_PREP(AIROHA_USB_PMA_LCPLL_PON_HRDDS_PCW_NCPO_GPON,
> +				      0x48000000));
> +
> +	regmap_update_bits(priv->regs[AIROHA_USB_PHY_DIG],
> +			   AIROHA_USB_DIG_MODE_CTRL_1,
> +			   AIROHA_USB_DIG_TPHY_SPEED,
> +			   FIELD_PREP(AIROHA_USB_DIG_TPHY_SPEED, 0x0));
> +
> +	regmap_update_bits(priv->regs[AIROHA_USB_PHY_PMA], AIROHA_USB_PMA_PLL_CTRL_2,
> +			   AIROHA_USB_PMA_PLL_PCK_SEL_INTF |
> +			   AIROHA_USB_PMA_PLL_IR_INTF,
> +			   AIROHA_USB_PMA_PLL_PCK_SEL_INTF |
> +			   FIELD_PREP(AIROHA_USB_PMA_PLL_IR_INTF, 0x4));
> +
> +	regmap_update_bits(priv->regs[AIROHA_USB_PHY_PMA],
> +			   AIROHA_USB_PMA_SS_LCPLL_TDC_FLT_2,
> +			   AIROHA_USB_PMA_LCPLL_NCPO_VALUE,
> +			   FIELD_PREP(AIROHA_USB_PMA_LCPLL_NCPO_VALUE, 0x48000000));
> +
> +	regmap_update_bits(priv->regs[AIROHA_USB_PHY_ANA],
> +			   AIROHA_USB_ANA_CDR_LPF_MJV_LIM,
> +			   AIROHA_USB_ANA_CDR_LPF_RATIO,
> +			   FIELD_PREP(AIROHA_USB_ANA_CDR_LPF_RATIO, 0x2));
> +
> +	regmap_update_bits(priv->regs[AIROHA_USB_PHY_ANA],
> +			   AIROHA_USB_ANA_CDR_PR_CKREF_DIV1,
> +			   AIROHA_USB_ANA_CDR_PR_DAC_BAND,
> +			   FIELD_PREP(AIROHA_USB_ANA_CDR_PR_DAC_BAND, 0xc));
> +
> +	regmap_update_bits(priv->regs[AIROHA_USB_PHY_ANA],
> +			   AIROHA_USB_ANA_CDR_LPF_BOT_LIM,
> +			   AIROHA_USB_ANA_CDR_LPF_KP_GAIN |
> +			   AIROHA_USB_ANA_CDR_LPF_KI_GAIN,
> +			   FIELD_PREP(AIROHA_USB_ANA_CDR_LPF_KP_GAIN, 0x6) |
> +			   FIELD_PREP(AIROHA_USB_ANA_CDR_LPF_KI_GAIN, 0x6));
> +
> +	regmap_update_bits(priv->regs[AIROHA_USB_PHY_PMA], AIROHA_USB_PMA_RX_CTRL_5,
> +			   AIROHA_USB_PMA_FREDET_CHK_CYCLE,
> +			   FIELD_PREP(AIROHA_USB_PMA_FREDET_CHK_CYCLE, 0x28));
> +
> +	return 0;
> +}
> +
> +static int an7583_usb_phy_eth_init_hsgmii(struct an7583_usb_phy_priv *priv)
> +{
> +	regmap_update_bits(priv->regs[AIROHA_USB_PHY_PMA],
> +			   AIROHA_USB_PMA_SS_LCPLL_TDC_PCW_1,
> +			   AIROHA_USB_PMA_LCPLL_PON_HRDDS_PCW_NCPO_GPON,
> +			   FIELD_PREP(AIROHA_USB_PMA_LCPLL_PON_HRDDS_PCW_NCPO_GPON,
> +				      0x7a000000));
> +
> +	regmap_update_bits(priv->regs[AIROHA_USB_PHY_DIG],
> +			   AIROHA_USB_DIG_MODE_CTRL_1,
> +			   AIROHA_USB_DIG_TPHY_SPEED,
> +			   FIELD_PREP(AIROHA_USB_DIG_TPHY_SPEED, 0x1));
> +
> +	regmap_update_bits(priv->regs[AIROHA_USB_PHY_PMA], AIROHA_USB_PMA_PLL_CTRL_2,
> +			   AIROHA_USB_PMA_PLL_PCK_SEL_INTF |
> +			   AIROHA_USB_PMA_PLL_IR_INTF,
> +			   AIROHA_USB_PMA_PLL_PCK_SEL_INTF |
> +			   FIELD_PREP(AIROHA_USB_PMA_PLL_IR_INTF, 0x6));
> +
> +	regmap_update_bits(priv->regs[AIROHA_USB_PHY_PMA],
> +			   AIROHA_USB_PMA_SS_LCPLL_TDC_FLT_2,
> +			   AIROHA_USB_PMA_LCPLL_NCPO_VALUE,
> +			   FIELD_PREP(AIROHA_USB_PMA_LCPLL_NCPO_VALUE, 0x7a000000));
> +
> +	regmap_update_bits(priv->regs[AIROHA_USB_PHY_ANA],
> +			   AIROHA_USB_ANA_CDR_LPF_MJV_LIM,
> +			   AIROHA_USB_ANA_CDR_LPF_RATIO,
> +			   FIELD_PREP(AIROHA_USB_ANA_CDR_LPF_RATIO, 0x1));
> +
> +	regmap_update_bits(priv->regs[AIROHA_USB_PHY_ANA],
> +			   AIROHA_USB_ANA_CDR_PR_CKREF_DIV1,
> +			   AIROHA_USB_ANA_CDR_PR_DAC_BAND,
> +			   FIELD_PREP(AIROHA_USB_ANA_CDR_PR_DAC_BAND, 0xf));
> +
> +	regmap_update_bits(priv->regs[AIROHA_USB_PHY_ANA],
> +			   AIROHA_USB_ANA_CDR_LPF_BOT_LIM,
> +			   AIROHA_USB_ANA_CDR_LPF_KP_GAIN |
> +			   AIROHA_USB_ANA_CDR_LPF_KI_GAIN,
> +			   FIELD_PREP(AIROHA_USB_ANA_CDR_LPF_KP_GAIN, 0x5) |
> +			   FIELD_PREP(AIROHA_USB_ANA_CDR_LPF_KI_GAIN, 0x5));
> +
> +	regmap_update_bits(priv->regs[AIROHA_USB_PHY_PMA], AIROHA_USB_PMA_RX_CTRL_5,
> +			   AIROHA_USB_PMA_FREDET_CHK_CYCLE,
> +			   FIELD_PREP(AIROHA_USB_PMA_FREDET_CHK_CYCLE, 0x10));
> +
> +	return 0;
> +}
> +
> +static int an7583_usb_phy_set_mode_eth(struct phy *phy, int submode)
> +{
> +	struct an7583_usb_phy_priv *priv = dev_get_drvdata(phy->dev.parent);
> +
> +	/* TODO handle efuse */
> +	regmap_update_bits(priv->regs[AIROHA_USB_PHY_PMA], AIROHA_USB_PMA_INTF_CTRL_8,
> +			   AIROHA_USB_PMA_TX_TERM_SEL_SEL |
> +			   AIROHA_USB_PMA_TX_TERM_SEL_FORCE,
> +			   AIROHA_USB_PMA_TX_TERM_SEL_SEL |
> +			   FIELD_PREP(AIROHA_USB_PMA_TX_TERM_SEL_FORCE, 0x1));
> +
> +	regmap_update_bits(priv->regs[AIROHA_USB_PHY_PMA], AIROHA_USB_PMA_INTF_STS_9,
> +			   AIROHA_USB_PMA_RX_IMP_SEL_SEL |
> +			   AIROHA_USB_PMA_RX_IMP_SEL_FORCE,
> +			   AIROHA_USB_PMA_RX_IMP_SEL_SEL |
> +			   FIELD_PREP(AIROHA_USB_PMA_RX_IMP_SEL_FORCE, 0x1));
> +
> +	regmap_set_bits(priv->regs[AIROHA_USB_PHY_PMA], AIROHA_USB_PMA_RX_CTRL_26,
> +			AIROHA_USB_PMA_QP_EQ_RETRAIN_ONLY_EN |
> +			AIROHA_USB_PMA_LINK_ERRO_EN);
> +
> +	regmap_update_bits(priv->regs[AIROHA_USB_PHY_ANA], AIROHA_USB_ANA_SSUSB_BGR_EN,
> +			   AIROHA_USB_ANA_SSUSB_BG_DIV,
> +			   FIELD_PREP(AIROHA_USB_ANA_SSUSB_BG_DIV, 0x1));
> +
> +	/* Digital CLK trigger reverse */
> +	regmap_clear_bits(priv->regs[AIROHA_USB_PHY_PMA], AIROHA_USB_PMA_PON_RXFEDIG_CTRL_0,
> +			  AIROHA_USB_PMA_EQ_RX500M_CK_SEL);
> +
> +	/* Common Setting */
> +	regmap_set_bits(priv->regs[AIROHA_USB_PHY_DIG], AIROHA_USB_DIG_CK_RST_CTRL_3,
> +			AIROHA_USB_DIG_NS_CK_DIV_SEL |
> +			AIROHA_USB_DIG_US_CK_DIV_SEL);
> +
> +	regmap_clear_bits(priv->regs[AIROHA_USB_PHY_PMA], AIROHA_USB_PMA_TX_DA_CTRL_1,
> +			  AIROHA_USB_PMA_FORCE_TX_BIT_INVERSE);
> +
> +	/* TODO check they report 0x8400000 */
> +	regmap_set_bits(priv->regs[AIROHA_USB_PHY_PMA], AIROHA_USB_PMA_TX_DA_CTRL_2,
> +			AIROHA_USB_PMA_FORCE_TX_DEM_SEL);
> +
> +	/* PLL */
> +	regmap_update_bits(priv->regs[AIROHA_USB_PHY_PMA], AIROHA_USB_PMA_PLL_CTRL_2,
> +			   AIROHA_USB_PMA_PLL_BR_INTF |
> +			   AIROHA_USB_PMA_PLL_BPB_INTF |
> +			   AIROHA_USB_PMA_PLL_BPA_INTF |
> +			   AIROHA_USB_PMA_PLL_BC_INTF,
> +			   FIELD_PREP(AIROHA_USB_PMA_PLL_BR_INTF, 0x3) |
> +			   FIELD_PREP(AIROHA_USB_PMA_PLL_BPB_INTF, 0x0) |
> +			   FIELD_PREP(AIROHA_USB_PMA_PLL_BPA_INTF, 0x5) |
> +			   FIELD_PREP(AIROHA_USB_PMA_PLL_BC_INTF, 0x1));
> +
> +	regmap_update_bits(priv->regs[AIROHA_USB_PHY_ANA],
> +			   AIROHA_USB_ANA_PLL_IPLL_DIG_PWR_SEL,
> +			   AIROHA_USB_ANA_PLL_PREDIV,
> +			   FIELD_PREP(AIROHA_USB_ANA_PLL_PREDIV, 0x1));
> +
> +	regmap_set_bits(priv->regs[AIROHA_USB_PHY_PMA], AIROHA_USB_PMA_PLL_CTRL_4,
> +			AIROHA_USB_PMA_PLL_ICOLP_EN_INTF);
> +
> +	regmap_clear_bits(priv->regs[AIROHA_USB_PHY_DIG], AIROHA_USB_DIG_MODE_CTRL_0,
> +			  AIROHA_USB_DIG_SGMII_AN_EN);
> +
> +	regmap_set_bits(priv->regs[AIROHA_USB_PHY_ANA], AIROHA_USB_ANA_RXLBTX_EN,
> +			AIROHA_USB_ANA_TX_DMEDGEGEN_EN);
> +
> +	regmap_set_bits(priv->regs[AIROHA_USB_PHY_ANA], AIROHA_USB_ANA_QP_TX_MODE_16B_EN,
> +			FIELD_PREP(AIROHA_USB_QP_TX_RESERVE,
> +				   AIROHA_USB_ANA_TX_RESERVE_8 |
> +				   AIROHA_USB_ANA_TX_VLMON_EN));
> +
> +	if (submode == PHY_INTERFACE_MODE_2500BASEX)
> +		an7583_usb_phy_eth_init_hsgmii(priv);
> +	else
> +		an7583_usb_phy_eth_init_sgmii(priv);
> +
> +	regmap_clear_bits(priv->regs[AIROHA_USB_PHY_PMA], AIROHA_USB_PMA_SS_LCPLL_TDC_FLT_5,
> +			  AIROHA_USB_PMA_LCPLL_NCPO_CHG);
> +
> +	regmap_set_bits(priv->regs[AIROHA_USB_PHY_PMA], AIROHA_USB_PMA_SS_LCPLL_TDC_FLT_5,
> +			AIROHA_USB_PMA_LCPLL_NCPO_CHG);
> +
> +	regmap_update_bits(priv->regs[AIROHA_USB_PHY_PMA],
> +			   AIROHA_USB_PMA_SS_LCPLL_PWCTL_SETTING_2,
> +			   AIROHA_USB_PMA_NCPO_ANA_MSB,
> +			   FIELD_PREP(AIROHA_USB_PMA_NCPO_ANA_MSB, 0x1));
> +
> +	regmap_set_bits(priv->regs[AIROHA_USB_PHY_ANA],
> +			AIROHA_USB_ANA_RXAFE_RESERVE,
> +			AIROHA_USB_ANA_CDR_PD_10B_EN);
> +
> +	regmap_update_bits(priv->regs[AIROHA_USB_PHY_PMA],
> +			   AIROHA_USB_PMA_PON_RXFEDIG_CTRL_10,
> +			   AIROHA_USB_PMA_QP_EQ_PIEYE_INI,
> +			   FIELD_PREP(AIROHA_USB_PMA_QP_EQ_PIEYE_INI, 0x0));
> +
> +	regmap_update_bits(priv->regs[AIROHA_USB_PHY_PMA],
> +			   AIROHA_USB_PMA_PON_RXFEDIG_CTRL_8,
> +			   AIROHA_USB_PMA_QP_EQ_EYE_MASK,
> +			   FIELD_PREP(AIROHA_USB_PMA_QP_EQ_EYE_MASK, 0x2aa));
> +
> +	regmap_update_bits(priv->regs[AIROHA_USB_PHY_PMA], AIROHA_USB_PMA_RX_CTRL_6,
> +			   AIROHA_USB_PMA_FREDET_GOLDEN_CYCLE,
> +			   FIELD_PREP(AIROHA_USB_PMA_FREDET_GOLDEN_CYCLE, 0x64));
> +
> +	regmap_update_bits(priv->regs[AIROHA_USB_PHY_PMA], AIROHA_USB_PMA_RX_CTRL_7,
> +			   AIROHA_USB_PMA_FREDET_TOLERATE_CYCLE,
> +			   FIELD_PREP(AIROHA_USB_PMA_FREDET_TOLERATE_CYCLE, 0x2710));
> +
> +	/* PLL auto init */
> +	regmap_clear_bits(priv->regs[AIROHA_USB_PHY_PMA], AIROHA_USB_PMA_PLL_CTRL_0,
> +			  AIROHA_USB_PMA_AUTO_INIT);
> +
> +	regmap_set_bits(priv->regs[AIROHA_USB_PHY_PMA], AIROHA_USB_PMA_PLL_CTRL_0,
> +			AIROHA_USB_PMA_AUTO_INIT);
> +
> +	usleep_range(100, 200);
> +
> +	return 0;
> +}
> +
> +static void an7583_usb_phy_tx_pll_enable(struct an7583_usb_phy_priv *priv)
> +{
> +	/* PLL Reset to default */
> +	regmap_clear_bits(priv->regs[AIROHA_USB_PHY_ANA],
> +			  AIROHA_USB_ANA_PLL_IPLL_DIG_PWR_SEL,
> +			  AIROHA_USB_ANA_PLL_MON_LDO_SEL |
> +			  AIROHA_USB_ANA_PLL_MONVC_EN);
> +
> +	regmap_clear_bits(priv->regs[AIROHA_USB_PHY_PMA],
> +			  AIROHA_USB_PMA_INTF_CTRL_7,
> +			  AIROHA_USB_PMA_PLL_EN_SEL |
> +			  AIROHA_USB_PMA_PLL_EN_FORCE);
> +
> +	/* PLL Auto Mode (For PMA) */
> +	regmap_set_bits(priv->regs[AIROHA_USB_PHY_PMA],
> +			AIROHA_USB_PMA_PLL_CK_CTRL_1,
> +			AIROHA_USB_PMA_PLL_FORCE_UNSTABLE);
> +	regmap_set_bits(priv->regs[AIROHA_USB_PHY_PMA],
> +			AIROHA_USB_PMA_PLL_CK_CTRL_1,
> +			AIROHA_USB_PMA_PLL_FORCE_STABLE);
> +	regmap_clear_bits(priv->regs[AIROHA_USB_PHY_PMA],
> +			  AIROHA_USB_PMA_PLL_CK_CTRL_1,
> +			  AIROHA_USB_PMA_PLL_FORCE_UNSTABLE);
> +	regmap_clear_bits(priv->regs[AIROHA_USB_PHY_PMA],
> +			  AIROHA_USB_PMA_PLL_CK_CTRL_1,
> +			  AIROHA_USB_PMA_PLL_FORCE_STABLE);
> +
> +	/* TX Auto Mode */
> +	regmap_set_bits(priv->regs[AIROHA_USB_PHY_PMA], AIROHA_USB_PMA_INTF_CTRL_6,
> +			AIROHA_USB_PMA_TX_DATA_EN_FORCE);
> +	regmap_clear_bits(priv->regs[AIROHA_USB_PHY_PMA], AIROHA_USB_PMA_INTF_CTRL_6,
> +			  AIROHA_USB_PMA_TX_DATA_EN_SEL);
> +	regmap_clear_bits(priv->regs[AIROHA_USB_PHY_PMA], AIROHA_USB_PMA_INTF_CTRL_6,
> +			  AIROHA_USB_PMA_TX_DATA_EN_FORCE);
> +}
> +
> +static void an7583_usb_phy_kband_calibrate(struct an7583_usb_phy_priv *priv)
> +{
> +	/* PLL Disable */
> +	regmap_update_bits(priv->regs[AIROHA_USB_PHY_PMA],
> +			   AIROHA_USB_PMA_INTF_CTRL_8,
> +			   AIROHA_USB_PMA_XTAL_EXT_EN_SEL |
> +			   AIROHA_USB_PMA_XTAL_EXT_EN_FORCE,
> +			   AIROHA_USB_PMA_XTAL_EXT_EN_SEL |
> +			   FIELD_PREP(AIROHA_USB_PMA_XTAL_EXT_EN_FORCE, 0x3));
> +
> +	regmap_update_bits(priv->regs[AIROHA_USB_PHY_PMA],
> +			   AIROHA_USB_PMA_INTF_CTRL_7,
> +			   AIROHA_USB_PMA_PLL_EN_SEL |
> +			   AIROHA_USB_PMA_PLL_EN_FORCE,
> +			   AIROHA_USB_PMA_PLL_EN_SEL);
> +
> +	/* PLL Config for CPR */
> +	regmap_set_bits(priv->regs[AIROHA_USB_PHY_PMA],
> +			AIROHA_USB_PMA_PLL_CTRL_4,
> +			AIROHA_USB_PMA_PLL_ICOLP_EN_INTF);
> +
> +	regmap_update_bits(priv->regs[AIROHA_USB_PHY_ANA],
> +			   AIROHA_USB_ANA_SSUSB_BGR_EN,
> +			   AIROHA_USB_ANA_BIAS_V2V_CAL,
> +			   FIELD_PREP(AIROHA_USB_ANA_BIAS_V2V_CAL, 0x0));
> +
> +	regmap_update_bits(priv->regs[AIROHA_USB_PHY_ANA],
> +			   AIROHA_USB_ANA_PLL_IPLL_DIG_PWR_SEL,
> +			   AIROHA_USB_ANA_PLL_OSCAL_ENB |
> +			   AIROHA_USB_ANA_PLL_LDOLPF_VSEL,
> +			   FIELD_PREP(AIROHA_USB_ANA_PLL_LDOLPF_VSEL, 0x3));
> +
> +	regmap_clear_bits(priv->regs[AIROHA_USB_PHY_PMA],
> +			  AIROHA_USB_PMA_PLL_CTRL_2,
> +			  AIROHA_USB_PMA_PLL_RICO_SEL_INTF |
> +			  AIROHA_USB_PMA_PLL_ICOIQ_EN_INTF);
> +
> +	regmap_update_bits(priv->regs[AIROHA_USB_PHY_ANA],
> +			   AIROHA_USB_ANA_PLL_IPLL_DIG_PWR_SEL,
> +			   AIROHA_USB_ANA_PLL_MON_LDO_SEL |
> +			   AIROHA_USB_ANA_PLL_MONVC_EN,
> +			   FIELD_PREP(AIROHA_USB_ANA_PLL_MON_LDO_SEL, 0x3) |
> +			   AIROHA_USB_ANA_PLL_MONVC_EN);
> +
> +	/* PLL Enable */
> +	regmap_set_bits(priv->regs[AIROHA_USB_PHY_PMA],
> +			AIROHA_USB_PMA_INTF_CTRL_7,
> +			AIROHA_USB_PMA_PLL_EN_SEL |
> +			AIROHA_USB_PMA_PLL_EN_FORCE);
> +}
> +
> +static int an7583_usb_phy_u3_init(struct phy *phy)
> +{
> +	struct an7583_usb_phy_priv *priv;
> +	struct device *dev;
> +
> +	dev = phy->dev.parent;
> +	priv = dev_get_drvdata(dev);
> +
> +	/* Digital CLK trigger reverse */
> +	regmap_clear_bits(priv->regs[AIROHA_USB_PHY_PMA], AIROHA_USB_PMA_PON_RXFEDIG_CTRL_0,
> +			  AIROHA_USB_PMA_EQ_RX500M_CK_SEL);
> +
> +	/* RX USB PCIE enable */
> +	regmap_set_bits(priv->regs[AIROHA_USB_PHY_PMA], AIROHA_USB_PMA_RX_CTRL_36,
> +			AIROHA_USB_PMA_PCIE_USB_SYSTEM);
> +
> +	regmap_clear_bits(priv->regs[AIROHA_USB_PHY_PMA], AIROHA_USB_PMA_RX_SYS_CTRL_0,
> +			  AIROHA_USB_PMA_ROC_CK_EN);
> +
> +	/* 50MHz XTAL */
> +	regmap_update_bits(priv->regs[AIROHA_USB_PHY_ANA], AIROHA_USB_ANA_SSUSB_BGR_EN,
> +			   AIROHA_USB_ANA_SSUSB_BG_DIV |
> +			   AIROHA_USB_ANA_SSUSB_CHPEN,
> +			   FIELD_PREP(AIROHA_USB_ANA_SSUSB_BG_DIV, 0x1) |
> +			   AIROHA_USB_ANA_SSUSB_CHPEN);
> +
> +	regmap_update_bits(priv->regs[AIROHA_USB_PHY_ANA],
> +			   AIROHA_USB_ANA_PLL_IPLL_DIG_PWR_SEL,
> +			   AIROHA_USB_ANA_PLL_PREDIV,
> +			   FIELD_PREP(AIROHA_USB_ANA_PLL_PREDIV, 0x1));
> +
> +	regmap_clear_bits(priv->regs[AIROHA_USB_PHY_PMA], AIROHA_USB_PMA_PLL_CTRL_4,
> +			  AIROHA_USB_PMA_PLL_ICOLP_EN_INTF);
> +
> +	regmap_clear_bits(priv->regs[AIROHA_USB_PHY_DIG], AIROHA_USB_DIG_CK_RST_CTRL_7,
> +			  AIROHA_USB_DIG_MULTI_USB2P5_EN |
> +			  AIROHA_USB_DIG_MULTI_USB5_EN);
> +
> +	regmap_set_bits(priv->regs[AIROHA_USB_PHY_DIG], AIROHA_USB_DIG_CK_RST_CTRL_7,
> +			AIROHA_USB_DIG_MULTI_USB2P5_EN |
> +			AIROHA_USB_DIG_MULTI_USB5_EN |
> +			AIROHA_USB_DIG_MULTI_PHY_USB_EN);
> +
> +	/* PLL */
> +	regmap_update_bits(priv->regs[AIROHA_USB_PHY_PMA], AIROHA_USB_PMA_PLL_CTRL_2,
> +			   AIROHA_USB_PMA_PLL_PHY_CK_EN_INTF |
> +			   AIROHA_USB_PMA_PLL_PCK_SEL_INTF |
> +			   AIROHA_USB_PMA_PLL_KBAND_PREDIV_INTF |
> +			   AIROHA_USB_PMA_PLL_IR_INTF |
> +			   AIROHA_USB_PMA_PLL_ICOIQ_EN_INTF |
> +			   AIROHA_USB_PMA_PLL_FBKSEL_INTF |
> +			   AIROHA_USB_PMA_PLL_BPB_INTF |
> +			   AIROHA_USB_PMA_PLL_BPA_INTF |
> +			   AIROHA_USB_PMA_PLL_BC_INTF,
> +			   AIROHA_USB_PMA_PLL_PHY_CK_EN_INTF |
> +			   AIROHA_USB_PMA_PLL_PCK_SEL_INTF |
> +			   FIELD_PREP(AIROHA_USB_PMA_PLL_KBAND_PREDIV_INTF, 0x0) |
> +			   FIELD_PREP(AIROHA_USB_PMA_PLL_IR_INTF, 0x4) |
> +			   AIROHA_USB_PMA_PLL_ICOIQ_EN_INTF |
> +			   FIELD_PREP(AIROHA_USB_PMA_PLL_FBKSEL_INTF, 0x0) |
> +			   FIELD_PREP(AIROHA_USB_PMA_PLL_BPB_INTF, 0x1) |
> +			   FIELD_PREP(AIROHA_USB_PMA_PLL_BPA_INTF, 0x5) |
> +			   FIELD_PREP(AIROHA_USB_PMA_PLL_BC_INTF, 0x3));
> +
> +	regmap_update_bits(priv->regs[AIROHA_USB_PHY_PMA], AIROHA_USB_PMA_PLL_CTRL_4,
> +			   AIROHA_USB_PMA_PLL_SDM_HREN_INTF,
> +			   FIELD_PREP(AIROHA_USB_PMA_PLL_SDM_HREN_INTF, 0x1));
> +
> +	regmap_set_bits(priv->regs[AIROHA_USB_PHY_PMA], AIROHA_USB_PMA_PLL_CTRL_2,
> +			AIROHA_USB_PMA_PLL_SDM_IFM_INTF);
> +
> +	regmap_update_bits(priv->regs[AIROHA_USB_PHY_PMA], AIROHA_USB_PMA_PLL_CTRL_3,
> +			   AIROHA_USB_PMA_PLL_SSC_PERIOD_INTF |
> +			   AIROHA_USB_PMA_PLL_SSC_DELTA_INTF,
> +			   FIELD_PREP(AIROHA_USB_PMA_PLL_SSC_PERIOD_INTF, 0x18c) |
> +			   FIELD_PREP(AIROHA_USB_PMA_PLL_SSC_DELTA_INTF, 0x21e));
> +
> +	regmap_set_bits(priv->regs[AIROHA_USB_PHY_PMA], AIROHA_USB_PMA_PLL_CTRL_1,
> +			AIROHA_USB_PMA_PLL_SSC_EN);
> +
> +	regmap_update_bits(priv->regs[AIROHA_USB_PHY_PMA],
> +			   AIROHA_USB_PMA_SS_LCPLL_TDC_PCW_1,
> +			   AIROHA_USB_PMA_LCPLL_PON_HRDDS_PCW_NCPO_GPON,
> +			   FIELD_PREP(AIROHA_USB_PMA_LCPLL_PON_HRDDS_PCW_NCPO_GPON,
> +				      0x48000000));
> +
> +	regmap_update_bits(priv->regs[AIROHA_USB_PHY_PMA],
> +			   AIROHA_USB_PMA_SS_LCPLL_PWCTL_SETTING_2,
> +			   AIROHA_USB_PMA_NCPO_ANA_MSB,
> +			   FIELD_PREP(AIROHA_USB_PMA_NCPO_ANA_MSB, 0x1));
> +
> +	regmap_update_bits(priv->regs[AIROHA_USB_PHY_PMA],
> +			   AIROHA_USB_PMA_SS_LCPLL_TDC_FLT_2,
> +			   AIROHA_USB_PMA_LCPLL_NCPO_VALUE,
> +			   FIELD_PREP(AIROHA_USB_PMA_LCPLL_NCPO_VALUE, 0x48000000));
> +
> +	/* RX 5G */
> +	regmap_update_bits(priv->regs[AIROHA_USB_PHY_ANA],
> +			   AIROHA_USB_ANA_CDR_LPF_MJV_LIM,
> +			   AIROHA_USB_ANA_CDR_LPF_RATIO,
> +			   FIELD_PREP(AIROHA_USB_ANA_CDR_LPF_RATIO, 0x0));
> +
> +	regmap_set_bits(priv->regs[AIROHA_USB_PHY_ANA],
> +			AIROHA_USB_ANA_RXAFE_RESERVE,
> +			AIROHA_USB_ANA_CDR_PD_10B_EN);
> +
> +	regmap_update_bits(priv->regs[AIROHA_USB_PHY_ANA],
> +			   AIROHA_USB_ANA_CDR_PR_CKREF_DIV1,
> +			   AIROHA_USB_ANA_CDR_PR_DAC_BAND,
> +			   FIELD_PREP(AIROHA_USB_ANA_CDR_PR_DAC_BAND, 0xc));
> +
> +	regmap_clear_bits(priv->regs[AIROHA_USB_PHY_ANA],
> +			  AIROHA_USB_ANA_CDR_FORCE_IBANDLPF_R_OFF,
> +			  AIROHA_USB_ANA_CDR_PHYCK_RSTB);
> +
> +	regmap_update_bits(priv->regs[AIROHA_USB_PHY_ANA],
> +			   AIROHA_USB_ANA_CDR_PR_KBAND_DIV_PCIE_REG,
> +			   AIROHA_USB_ANA_CDR_PR_XFICK_EN |
> +			   AIROHA_USB_ANA_CDR_PR_KBAND_PCIE_MODE,
> +			   AIROHA_USB_ANA_CDR_PR_KBAND_PCIE_MODE);
> +
> +	regmap_update_bits(priv->regs[AIROHA_USB_PHY_ANA],
> +			   AIROHA_USB_ANA_CDR_PR_CKREF_DIV1,
> +			   AIROHA_USB_ANA_CDR_PR_KBAND_DIV,
> +			   FIELD_PREP(AIROHA_USB_ANA_CDR_PR_KBAND_DIV, 0x3));
> +
> +	regmap_update_bits(priv->regs[AIROHA_USB_PHY_ANA],
> +			   AIROHA_USB_ANA_CDR_PR_KBAND_DIV_PCIE_REG,
> +			   AIROHA_USB_ANA_CDR_PR_KBAND_DIV_PCIE,
> +			   FIELD_PREP(AIROHA_USB_ANA_CDR_PR_KBAND_DIV_PCIE, 0x19));
> +
> +	regmap_set_bits(priv->regs[AIROHA_USB_PHY_PMA], AIROHA_USB_PMA_RX_CTRL_46,
> +			AIROHA_USB_PMA_REBACK_P0_LCK2REF_EN);
> +
> +	regmap_update_bits(priv->regs[AIROHA_USB_PHY_PMA], AIROHA_USB_PMA_RX_CTRL_49,
> +			   AIROHA_USB_PMA_LFPS_FINISH_TIME,
> +			   FIELD_PREP(AIROHA_USB_PMA_LFPS_FINISH_TIME, 0x1f0));
> +
> +	/* EQ all */
> +	regmap_clear_bits(priv->regs[AIROHA_USB_PHY_PMA], AIROHA_USB_PMA_RX_CTRL_50,
> +			  AIROHA_USB_PMA_P3_TO_P0_DO_EQ_USB |
> +			  AIROHA_USB_PMA_P2_TO_P0_DO_EQ_USB |
> +			  AIROHA_USB_PMA_P1_TO_P0_DO_EQ_USB);
> +
> +	regmap_set_bits(priv->regs[AIROHA_USB_PHY_PMA], AIROHA_USB_PMA_RX_CTRL_46,
> +			AIROHA_USB_PMA_PCIE_USB_BYPASS_EQ_P3_TO_P0_EN |
> +			AIROHA_USB_PMA_PCIE_USB_BYPASS_EQ_P2_TO_P0_EN |
> +			AIROHA_USB_PMA_PCIE_USB_BYPASS_EQ_P1_TO_P0_EN);
> +
> +	/* FIXME: ask Airoha why reserve7 is at 6c4 NOT 6c0 */
> +	regmap_clear_bits(priv->regs[AIROHA_USB_PHY_PMA], AIROHA_USB_PMA_RX_CTRL_38,
> +			  FIELD_PREP(AIROHA_USB_PMA_RESERVE_3, BIT(7)));
> +
> +	regmap_set_bits(priv->regs[AIROHA_USB_PHY_PMA], AIROHA_USB_PMA_RX_CTRL_11,
> +			AIROHA_USB_PMA_FORCE_SIGDET_5G);
> +
> +	regmap_update_bits(priv->regs[AIROHA_USB_PHY_PMA], AIROHA_USB_PMA_RX_CTRL_36,
> +			   AIROHA_USB_PMA_LCK2DATA_DLY_TIME,
> +			   FIELD_PREP(AIROHA_USB_PMA_LCK2DATA_DLY_TIME, 0x2));
> +
> +	/* PI Cal */
> +	regmap_update_bits(priv->regs[AIROHA_USB_PHY_PMA], AIROHA_USB_PMA_RX_DLY_0,
> +			   AIROHA_USB_PMA_RX_PI_CAL_EN_H_DLY,
> +			   FIELD_PREP(AIROHA_USB_PMA_RX_PI_CAL_EN_H_DLY, 0x10));
> +
> +	regmap_set_bits(priv->regs[AIROHA_USB_PHY_ANA], AIROHA_USB_ANA_PLL_SDM_ORD,
> +			AIROHA_USB_ANA_PLL_SSC_TRI_EN |
> +			AIROHA_USB_ANA_PLL_SSC_PHASE_INI);
> +
> +	regmap_clear_bits(priv->regs[AIROHA_USB_PHY_PMA], AIROHA_USB_PMA_TX_DA_CTRL_3,
> +			  AIROHA_USB_PMA_TX_DATA_RATE_SEL);
> +
> +	regmap_clear_bits(priv->regs[AIROHA_USB_PHY_ANA], AIROHA_USB_ANA_RXAFE_RESERVE,
> +			  AIROHA_USB_ANA_CDR_PD_EDGE_DIS);
> +
> +	/* Common Setting */
> +	regmap_set_bits(priv->regs[AIROHA_USB_PHY_DIG], AIROHA_USB_DIG_CK_RST_CTRL_3,
> +			AIROHA_USB_DIG_NS_CK_DIV_SEL |
> +			AIROHA_USB_DIG_US_CK_DIV_SEL);
> +
> +	regmap_update_bits(priv->regs[AIROHA_USB_PHY_PMA], AIROHA_USB_PMA_TX_DA_CTRL_0,
> +			   AIROHA_USB_PMA_RXDET_RD_WAIT_TIMER |
> +			   AIROHA_USB_PMA_RXDET_EN_WINDOW,
> +			   FIELD_PREP(AIROHA_USB_PMA_RXDET_RD_WAIT_TIMER, 0x4) |
> +			   FIELD_PREP(AIROHA_USB_PMA_RXDET_EN_WINDOW, 0xa));
> +
> +	regmap_update_bits(priv->regs[AIROHA_USB_PHY_ANA], AIROHA_USB_ANA_RXLBTX_EN,
> +			   AIROHA_USB_ANA_TX_DMEDGEGEN_EN |
> +			   AIROHA_USB_ANA_TX_RXDET_METHOD,
> +			   AIROHA_USB_ANA_TX_DMEDGEGEN_EN);
> +
> +	regmap_set_bits(priv->regs[AIROHA_USB_PHY_PMA], AIROHA_USB_PMA_PLL_CK_CTRL_2,
> +			AIROHA_USB_PMA_PCIE_MODE_PLL_AUTO_OFF_EN |
> +			AIROHA_USB_PMA_PCIE_MODE_PLL_AUTO_ON_EN |
> +			AIROHA_USB_PMA_PCIE_MODE_PLL_AUTO_EN);
> +
> +	/* RX Speed Up */
> +	regmap_update_bits(priv->regs[AIROHA_USB_PHY_PMA], AIROHA_USB_PMA_RX_CTRL_5,
> +			   AIROHA_USB_PMA_FREDET_CHK_CYCLE,
> +			   FIELD_PREP(AIROHA_USB_PMA_FREDET_CHK_CYCLE, 0x28));
> +
> +	regmap_update_bits(priv->regs[AIROHA_USB_PHY_PMA], AIROHA_USB_PMA_RX_CTRL_6,
> +			   AIROHA_USB_PMA_FREDET_GOLDEN_CYCLE,
> +			   FIELD_PREP(AIROHA_USB_PMA_FREDET_GOLDEN_CYCLE, 0x64));
> +
> +	regmap_update_bits(priv->regs[AIROHA_USB_PHY_PMA], AIROHA_USB_PMA_RX_CTRL_7,
> +			   AIROHA_USB_PMA_FREDET_TOLERATE_CYCLE,
> +			   FIELD_PREP(AIROHA_USB_PMA_FREDET_TOLERATE_CYCLE, 0x2710));
> +
> +	regmap_update_bits(priv->regs[AIROHA_USB_PHY_PMA], AIROHA_USB_PMA_RX_CTRL_2,
> +			   AIROHA_USB_PMA_RX_EQ_EN_H_DLY,
> +			   FIELD_PREP(AIROHA_USB_PMA_RX_EQ_EN_H_DLY, 0x9c4));
> +
> +	regmap_update_bits(priv->regs[AIROHA_USB_PHY_PMA], AIROHA_USB_PMA_RX_CTRL_45,
> +			   AIROHA_USB_PMA_EQ_EN_DLY,
> +			   FIELD_PREP(AIROHA_USB_PMA_EQ_EN_DLY, 0x9c4));
> +
> +	regmap_update_bits(priv->regs[AIROHA_USB_PHY_PMA], AIROHA_USB_PMA_RX_CTRL_50,
> +			   AIROHA_USB_PMA_EQ_EN_DLY_SHORT |
> +			   AIROHA_USB_PMA_RX_EQ_EN_H_DLY_SHORT,
> +			   FIELD_PREP(AIROHA_USB_PMA_EQ_EN_DLY_SHORT, 0x9c4) |
> +			   FIELD_PREP(AIROHA_USB_PMA_RX_EQ_EN_H_DLY_SHORT, 0x9c4));
> +
> +	/* TCL avoid LT noice impact */
> +	regmap_set_bits(priv->regs[AIROHA_USB_PHY_ANA], AIROHA_USB_ANA_QP_TX_MODE_16B_EN,
> +			AIROHA_USB_ANA_TX_RESERVE_8);
> +
> +	/* PLL auto init */
> +	regmap_set_bits(priv->regs[AIROHA_USB_PHY_PMA], AIROHA_USB_PMA_PLL_CTRL_0,
> +			AIROHA_USB_PMA_AUTO_INIT);
> +
> +	usleep_range(100, 300);
> +
> +	regmap_clear_bits(priv->regs[AIROHA_USB_PHY_PMA], AIROHA_USB_PMA_PLL_CK_CTRL_2,
> +			  AIROHA_USB_PMA_PCIE_MODE_PLL_AUTO_EN);
> +
> +	if (!an7583_usb_phy_u3_kband_is_calibrated(priv)) {
> +		int i;
> +
> +		/* TX Force Disable */
> +		regmap_update_bits(priv->regs[AIROHA_USB_PHY_PMA],
> +				   AIROHA_USB_PMA_INTF_CTRL_6,
> +				   AIROHA_USB_PMA_TX_DATA_EN_SEL |
> +				   AIROHA_USB_PMA_TX_DATA_EN_FORCE,
> +				   AIROHA_USB_PMA_TX_DATA_EN_SEL);
> +
> +		/* PLL Force Unstable */
> +		regmap_set_bits(priv->regs[AIROHA_USB_PHY_PMA],
> +				AIROHA_USB_PMA_PLL_CK_CTRL_1,
> +				AIROHA_USB_PMA_PLL_FORCE_UNSTABLE);
> +
> +		for (i = 0; i < AIROHA_USB_PHY_U3_MAX_CALIB_TRY; i++) {
> +			an7583_usb_phy_kband_calibrate(priv);
> +
> +			/* Exit as soon as we manage to calibrate */
> +			if (an7583_usb_phy_u3_kband_is_calibrated(priv))
> +				break;
> +		}
> +	}
> +
> +	an7583_usb_phy_tx_pll_enable(priv);
> +
> +	return !an7583_usb_phy_u3_kband_is_calibrated(priv) ? -EINVAL : 0;
> +}
> +
> +static int an7583_usb_phy_pcie_init(struct phy *phy)
> +{
> +	struct an7583_usb_phy_priv *priv;
> +	struct device *dev;
> +	int i;
> +
> +	dev = phy->dev.parent;
> +	priv = dev_get_drvdata(dev);
> +
> +	/* TX Force Disable */
> +	regmap_update_bits(priv->regs[AIROHA_USB_PHY_PMA],
> +			   AIROHA_USB_PMA_INTF_CTRL_6,
> +			   AIROHA_USB_PMA_TX_DATA_EN_SEL |
> +			   AIROHA_USB_PMA_TX_DATA_EN_FORCE,
> +			   AIROHA_USB_PMA_TX_DATA_EN_SEL);
> +
> +	/* PLL Force Unstable */
> +	regmap_set_bits(priv->regs[AIROHA_USB_PHY_PMA],
> +			AIROHA_USB_PMA_PLL_CK_CTRL_1,
> +			AIROHA_USB_PMA_PLL_FORCE_UNSTABLE);
> +
> +	/* PLL Disable */
> +	regmap_clear_bits(priv->regs[AIROHA_USB_PHY_PMA], AIROHA_USB_PMA_PLL_CTRL_0,
> +			  AIROHA_USB_PMA_AUTO_INIT);
> +
> +	usleep_range(1000, 1500);
> +
> +	regmap_set_bits(priv->regs[AIROHA_USB_PHY_PMA], AIROHA_USB_PMA_PLL_CTRL_0,
> +			AIROHA_USB_PMA_AUTO_INIT);
> +
> +	regmap_update_bits(priv->regs[AIROHA_USB_PHY_PMA],
> +			   AIROHA_USB_PMA_INTF_CTRL_7,
> +			   AIROHA_USB_PMA_PLL_EN_SEL |
> +			   AIROHA_USB_PMA_PLL_EN_FORCE,
> +			   AIROHA_USB_PMA_PLL_EN_SEL);
> +
> +	regmap_set_bits(priv->regs[AIROHA_USB_PHY_PMA], AIROHA_USB_PMA_RX_CTRL_36,
> +			AIROHA_USB_PMA_PCIE_USB_SYSTEM);
> +
> +	/* 50MHz XTAL */
> +	regmap_update_bits(priv->regs[AIROHA_USB_PHY_ANA], AIROHA_USB_ANA_SSUSB_BGR_EN,
> +			   AIROHA_USB_ANA_SSUSB_BG_DIV,
> +			   FIELD_PREP(AIROHA_USB_ANA_SSUSB_BG_DIV, 0x1));
> +
> +	regmap_update_bits(priv->regs[AIROHA_USB_PHY_ANA],
> +			   AIROHA_USB_ANA_PLL_IPLL_DIG_PWR_SEL,
> +			   AIROHA_USB_ANA_PLL_PREDIV,
> +			   FIELD_PREP(AIROHA_USB_ANA_PLL_PREDIV, 0x1));
> +
> +	regmap_clear_bits(priv->regs[AIROHA_USB_PHY_PMA], AIROHA_USB_PMA_PLL_CTRL_4,
> +			  AIROHA_USB_PMA_PLL_ICOLP_EN_INTF);
> +
> +	regmap_clear_bits(priv->regs[AIROHA_USB_PHY_DIG], AIROHA_USB_DIG_CK_RST_CTRL_7,
> +			  AIROHA_USB_DIG_MULTI_USB2P5_EN |
> +			  AIROHA_USB_DIG_MULTI_USB5_EN);
> +
> +	regmap_set_bits(priv->regs[AIROHA_USB_PHY_DIG], AIROHA_USB_DIG_CK_RST_CTRL_7,
> +			AIROHA_USB_DIG_MULTI_USB2P5_EN |
> +			AIROHA_USB_DIG_MULTI_USB5_EN |
> +			AIROHA_USB_DIG_MULTI_PHY_USB_EN);
> +
> +	/* PLL RG */
> +	regmap_update_bits(priv->regs[AIROHA_USB_PHY_PMA], AIROHA_USB_PMA_PLL_CTRL_2,
> +			   AIROHA_USB_PMA_PLL_PHY_CK_EN_INTF |
> +			   AIROHA_USB_PMA_PLL_PCK_SEL_INTF |
> +			   AIROHA_USB_PMA_PLL_KBAND_PREDIV_INTF |
> +			   AIROHA_USB_PMA_PLL_IR_INTF |
> +			   AIROHA_USB_PMA_PLL_ICOIQ_EN_INTF |
> +			   AIROHA_USB_PMA_PLL_FBKSEL_INTF |
> +			   AIROHA_USB_PMA_PLL_BPB_INTF |
> +			   AIROHA_USB_PMA_PLL_BPA_INTF |
> +			   AIROHA_USB_PMA_PLL_BC_INTF,
> +			   AIROHA_USB_PMA_PLL_PCK_SEL_INTF |
> +			   FIELD_PREP(AIROHA_USB_PMA_PLL_KBAND_PREDIV_INTF, 0x0) |
> +			   FIELD_PREP(AIROHA_USB_PMA_PLL_IR_INTF, 0x4) |
> +			   AIROHA_USB_PMA_PLL_ICOIQ_EN_INTF |
> +			   FIELD_PREP(AIROHA_USB_PMA_PLL_FBKSEL_INTF, 0x0) |
> +			   FIELD_PREP(AIROHA_USB_PMA_PLL_BPB_INTF, 0x1) |
> +			   FIELD_PREP(AIROHA_USB_PMA_PLL_BPA_INTF, 0x5) |
> +			   FIELD_PREP(AIROHA_USB_PMA_PLL_BC_INTF, 0x3));
> +
> +	regmap_update_bits(priv->regs[AIROHA_USB_PHY_PMA], AIROHA_USB_PMA_PLL_CTRL_4,
> +			   AIROHA_USB_PMA_PLL_SDM_HREN_INTF,
> +			   FIELD_PREP(AIROHA_USB_PMA_PLL_SDM_HREN_INTF, 0x1));
> +
> +	regmap_set_bits(priv->regs[AIROHA_USB_PHY_PMA], AIROHA_USB_PMA_PLL_CTRL_2,
> +			AIROHA_USB_PMA_PLL_SDM_IFM_INTF);
> +
> +	regmap_update_bits(priv->regs[AIROHA_USB_PHY_PMA], AIROHA_USB_PMA_PLL_CTRL_3,
> +			   AIROHA_USB_PMA_PLL_SSC_PERIOD_INTF |
> +			   AIROHA_USB_PMA_PLL_SSC_DELTA_INTF,
> +			   FIELD_PREP(AIROHA_USB_PMA_PLL_SSC_PERIOD_INTF, 0x91c) |
> +			   FIELD_PREP(AIROHA_USB_PMA_PLL_SSC_DELTA_INTF, 0x1fd));
> +
> +	regmap_set_bits(priv->regs[AIROHA_USB_PHY_PMA], AIROHA_USB_PMA_PLL_CTRL_1,
> +			AIROHA_USB_PMA_PLL_SSC_EN);
> +
> +	regmap_update_bits(priv->regs[AIROHA_USB_PHY_PMA],
> +			   AIROHA_USB_PMA_SS_LCPLL_TDC_PCW_1,
> +			   AIROHA_USB_PMA_LCPLL_PON_HRDDS_PCW_NCPO_GPON,
> +			   FIELD_PREP(AIROHA_USB_PMA_LCPLL_PON_HRDDS_PCW_NCPO_GPON,
> +				      0x48000000));
> +
> +	regmap_update_bits(priv->regs[AIROHA_USB_PHY_PMA],
> +			   AIROHA_USB_PMA_SS_LCPLL_PWCTL_SETTING_2,
> +			   AIROHA_USB_PMA_NCPO_ANA_MSB,
> +			   FIELD_PREP(AIROHA_USB_PMA_NCPO_ANA_MSB, 0x1));
> +
> +	regmap_update_bits(priv->regs[AIROHA_USB_PHY_PMA],
> +			   AIROHA_USB_PMA_SS_LCPLL_TDC_FLT_2,
> +			   AIROHA_USB_PMA_LCPLL_NCPO_VALUE,
> +			   FIELD_PREP(AIROHA_USB_PMA_LCPLL_NCPO_VALUE, 0x48000000));
> +
> +	/* RX RG */
> +	regmap_update_bits(priv->regs[AIROHA_USB_PHY_ANA],
> +			   AIROHA_USB_ANA_CDR_LPF_MJV_LIM,
> +			   AIROHA_USB_ANA_CDR_LPF_RATIO,
> +			   FIELD_PREP(AIROHA_USB_ANA_CDR_LPF_RATIO, 0x1));
> +
> +	regmap_set_bits(priv->regs[AIROHA_USB_PHY_ANA],
> +			AIROHA_USB_ANA_RXAFE_RESERVE,
> +			AIROHA_USB_ANA_CDR_PD_10B_EN);
> +
> +	regmap_update_bits(priv->regs[AIROHA_USB_PHY_ANA],
> +			   AIROHA_USB_ANA_CDR_PR_CKREF_DIV1,
> +			   AIROHA_USB_ANA_CDR_PR_DAC_BAND,
> +			   FIELD_PREP(AIROHA_USB_ANA_CDR_PR_DAC_BAND, 0xc));
> +
> +	regmap_clear_bits(priv->regs[AIROHA_USB_PHY_ANA],
> +			  AIROHA_USB_ANA_CDR_FORCE_IBANDLPF_R_OFF,
> +			  AIROHA_USB_ANA_CDR_PHYCK_RSTB);
> +
> +	regmap_update_bits(priv->regs[AIROHA_USB_PHY_ANA],
> +			   AIROHA_USB_ANA_CDR_PR_KBAND_DIV_PCIE_REG,
> +			   AIROHA_USB_ANA_CDR_PR_XFICK_EN |
> +			   AIROHA_USB_ANA_CDR_PR_KBAND_PCIE_MODE,
> +			   AIROHA_USB_ANA_CDR_PR_KBAND_PCIE_MODE);
> +
> +	regmap_update_bits(priv->regs[AIROHA_USB_PHY_ANA],
> +			   AIROHA_USB_ANA_CDR_PR_CKREF_DIV1,
> +			   AIROHA_USB_ANA_CDR_PR_KBAND_DIV,
> +			   FIELD_PREP(AIROHA_USB_ANA_CDR_PR_KBAND_DIV, 0x3));
> +
> +	regmap_update_bits(priv->regs[AIROHA_USB_PHY_ANA],
> +			   AIROHA_USB_ANA_CDR_PR_KBAND_DIV_PCIE_REG,
> +			   AIROHA_USB_ANA_CDR_PR_KBAND_DIV_PCIE,
> +			   FIELD_PREP(AIROHA_USB_ANA_CDR_PR_KBAND_DIV_PCIE, 0x19));
> +
> +	/* Init L0/L0S U0/U1 */
> +	regmap_set_bits(priv->regs[AIROHA_USB_PHY_PMA], AIROHA_USB_PMA_RX_CTRL_46,
> +			AIROHA_USB_PMA_REBACK_P0_LCK2REF_EN |
> +			AIROHA_USB_PMA_PCIE_USB_BYPASS_EQ_P1_TO_P0_EN);
> +
> +	regmap_set_bits(priv->regs[AIROHA_USB_PHY_PMA], AIROHA_USB_PMA_RX_CTRL_11,
> +			AIROHA_USB_PMA_FORCE_SIGDET_5G);
> +
> +	regmap_update_bits(priv->regs[AIROHA_USB_PHY_PMA], AIROHA_USB_PMA_RX_CTRL_36,
> +			   AIROHA_USB_PMA_LCK2DATA_DLY_TIME,
> +			   FIELD_PREP(AIROHA_USB_PMA_LCK2DATA_DLY_TIME, 0x2));
> +
> +	regmap_clear_bits(priv->regs[AIROHA_USB_PHY_ANA], AIROHA_USB_ANA_RXAFE_RESERVE,
> +			  AIROHA_USB_ANA_CDR_PD_EDGE_DIS);
> +
> +	/* PI Calibration */
> +	regmap_update_bits(priv->regs[AIROHA_USB_PHY_PMA], AIROHA_USB_PMA_RX_DLY_0,
> +			   AIROHA_USB_PMA_RX_PI_CAL_EN_H_DLY,
> +			   FIELD_PREP(AIROHA_USB_PMA_RX_PI_CAL_EN_H_DLY, 0x10));
> +
> +	/* CRS detect and CLK TRX Control */
> +	regmap_set_bits(priv->regs[AIROHA_USB_PHY_PMA], AIROHA_USB_PMA_RX_CTRL_10,
> +			AIROHA_USB_PMA_CRSDET_RSTB);
> +
> +	regmap_set_bits(priv->regs[AIROHA_USB_PHY_ANA], AIROHA_USB_ANA_PLL_SDM_ORD,
> +			AIROHA_USB_ANA_PLL_SSC_TRI_EN |
> +			AIROHA_USB_ANA_PLL_SSC_PHASE_INI);
> +
> +	regmap_update_bits(priv->regs[AIROHA_USB_PHY_PMA], AIROHA_USB_PMA_PLL_CK_CTRL_0,
> +			   AIROHA_USB_PMA_PCIE_CLKTX_EN_INTF |
> +			   AIROHA_USB_PMA_PCIE_CLKRX_EN_INTF,
> +			   AIROHA_USB_PMA_PCIE_CLKTX_EN_INTF);
> +
> +	regmap_update_bits(priv->regs[AIROHA_USB_PHY_ANA], AIROHA_USB_ANA_CLKDRV_IMPSEL,
> +			   AIROHA_USB_ANA_PCIE_CLKDRV_AMP |
> +			   AIROHA_USB_ANA_PCIE_CLKDRV_FORCEIN |
> +			   AIROHA_USB_ANA_PCIE_CLKDRV_HZ |
> +			   AIROHA_USB_ANA_PCIE_CLKDRV_RP |
> +			   AIROHA_USB_ANA_PCIE_CLKDRV_IMPSEL,
> +			   FIELD_PREP(AIROHA_USB_ANA_PCIE_CLKDRV_AMP, 0x4) |
> +			   FIELD_PREP(AIROHA_USB_ANA_PCIE_CLKDRV_FORCEIN, 0x1) |
> +			   FIELD_PREP(AIROHA_USB_ANA_PCIE_CLKDRV_RP, 0xc) |
> +			   FIELD_PREP(AIROHA_USB_ANA_PCIE_CLKDRV_IMPSEL, 0x12));
> +
> +	regmap_update_bits(priv->regs[AIROHA_USB_PHY_PMA], AIROHA_USB_PMA_TX_DA_CTRL_3,
> +			   AIROHA_USB_PMA_TX_DATA_RATE_SEL,
> +			   FIELD_PREP(AIROHA_USB_PMA_TX_DATA_RATE_SEL, 0x1));
> +
> +	/* Common Setting */
> +	regmap_set_bits(priv->regs[AIROHA_USB_PHY_DIG], AIROHA_USB_DIG_CK_RST_CTRL_3,
> +			AIROHA_USB_DIG_NS_CK_DIV_SEL |
> +			AIROHA_USB_DIG_US_CK_DIV_SEL);
> +
> +	regmap_update_bits(priv->regs[AIROHA_USB_PHY_PMA], AIROHA_USB_PMA_TX_DA_CTRL_0,
> +			   AIROHA_USB_PMA_RXDET_RD_WAIT_TIMER |
> +			   AIROHA_USB_PMA_RXDET_EN_WINDOW,
> +			   FIELD_PREP(AIROHA_USB_PMA_RXDET_RD_WAIT_TIMER, 0x4) |
> +			   FIELD_PREP(AIROHA_USB_PMA_RXDET_EN_WINDOW, 0xa));
> +
> +	regmap_update_bits(priv->regs[AIROHA_USB_PHY_ANA], AIROHA_USB_ANA_RXLBTX_EN,
> +			   AIROHA_USB_ANA_TX_DMEDGEGEN_EN |
> +			   AIROHA_USB_ANA_TX_RXDET_METHOD,
> +			   AIROHA_USB_ANA_TX_DMEDGEGEN_EN);
> +
> +	/* PLL auto ON/OFF at L2/U3 state */
> +	regmap_set_bits(priv->regs[AIROHA_USB_PHY_PMA], AIROHA_USB_PMA_PLL_CK_CTRL_2,
> +			AIROHA_USB_PMA_PCIE_MODE_PLL_AUTO_OFF_EN |
> +			AIROHA_USB_PMA_PCIE_MODE_PLL_AUTO_ON_EN |
> +			AIROHA_USB_PMA_PCIE_MODE_PLL_AUTO_EN);
> +
> +	/* RX speed up */
> +	regmap_update_bits(priv->regs[AIROHA_USB_PHY_PMA], AIROHA_USB_PMA_RX_CTRL_5,
> +			   AIROHA_USB_PMA_FREDET_CHK_CYCLE,
> +			   FIELD_PREP(AIROHA_USB_PMA_FREDET_CHK_CYCLE, 0x28));
> +
> +	regmap_update_bits(priv->regs[AIROHA_USB_PHY_PMA], AIROHA_USB_PMA_RX_CTRL_6,
> +			   AIROHA_USB_PMA_FREDET_GOLDEN_CYCLE,
> +			   FIELD_PREP(AIROHA_USB_PMA_FREDET_GOLDEN_CYCLE, 0x64));
> +
> +	regmap_update_bits(priv->regs[AIROHA_USB_PHY_PMA], AIROHA_USB_PMA_RX_CTRL_7,
> +			   AIROHA_USB_PMA_FREDET_TOLERATE_CYCLE,
> +			   FIELD_PREP(AIROHA_USB_PMA_FREDET_TOLERATE_CYCLE, 0x2710));
> +
> +	regmap_update_bits(priv->regs[AIROHA_USB_PHY_PMA], AIROHA_USB_PMA_RX_CTRL_2,
> +			   AIROHA_USB_PMA_RX_EQ_EN_H_DLY,
> +			   FIELD_PREP(AIROHA_USB_PMA_RX_EQ_EN_H_DLY, 0x9c4));
> +
> +	regmap_update_bits(priv->regs[AIROHA_USB_PHY_PMA], AIROHA_USB_PMA_RX_CTRL_45,
> +			   AIROHA_USB_PMA_EQ_EN_DLY,
> +			   FIELD_PREP(AIROHA_USB_PMA_EQ_EN_DLY, 0x9c4));
> +
> +	regmap_update_bits(priv->regs[AIROHA_USB_PHY_PMA], AIROHA_USB_PMA_RX_CTRL_50,
> +			   AIROHA_USB_PMA_EQ_EN_DLY_SHORT |
> +			   AIROHA_USB_PMA_RX_EQ_EN_H_DLY_SHORT,
> +			   FIELD_PREP(AIROHA_USB_PMA_EQ_EN_DLY_SHORT, 0x9c4) |
> +			   FIELD_PREP(AIROHA_USB_PMA_RX_EQ_EN_H_DLY_SHORT, 0x9c4));
> +
> +	regmap_set_bits(priv->regs[AIROHA_USB_PHY_ANA], AIROHA_USB_ANA_QP_TX_MODE_16B_EN,
> +			AIROHA_USB_ANA_TX_RESERVE_8);
> +
> +	regmap_clear_bits(priv->regs[AIROHA_USB_PHY_PMA], AIROHA_USB_PMA_PON_RXFEDIG_CTRL_0,
> +			  AIROHA_USB_PMA_EQ_RX500M_CK_SEL);
> +
> +	regmap_set_bits(priv->regs[AIROHA_USB_PHY_PMA], AIROHA_USB_PMA_PLL_CTRL_0,
> +			AIROHA_USB_PMA_AUTO_INIT);
> +
> +	/* Select PLL_EN to Force mode */
> +	regmap_set_bits(priv->regs[AIROHA_USB_PHY_PMA],
> +			AIROHA_USB_PMA_INTF_CTRL_7,
> +			AIROHA_USB_PMA_PLL_EN_SEL |
> +			AIROHA_USB_PMA_PLL_EN_FORCE);
> +
> +	/* Try to calibrate KBand up to AIROHA_USB_PHY_U3_MAX_CALIB_TRY times */
> +	for (i = 0; i < AIROHA_USB_PHY_U3_MAX_CALIB_TRY; i++) {
> +		/* Check if KBand is calibrated */
> +		if (an7583_usb_phy_u3_kband_is_calibrated(priv))
> +			break;
> +
> +		/* Trigger KBand calibration */
> +		an7583_usb_phy_kband_calibrate(priv);
> +	}
> +
> +	an7583_usb_phy_tx_pll_enable(priv);
> +
> +	return !an7583_usb_phy_u3_kband_is_calibrated(priv) ? -EINVAL : 0;
> +}
> +
> +static int an7583_usb_phy_init(struct phy *phy)
> +{
> +	struct an7583_usb_phy_instance *instance = phy_get_drvdata(phy);
> +
> +	switch (instance->type) {
> +	case PHY_TYPE_USB2:
> +		return an7583_usb_phy_u2_init(phy);
> +	case PHY_TYPE_USB3:
> +		if (phy_get_mode(phy) == PHY_MODE_ETHERNET)
> +			return 0;
> +
> +		return an7583_usb_phy_u3_init(phy);
> +	case PHY_TYPE_PCIE:
> +		if (phy_get_mode(phy) == PHY_MODE_ETHERNET)
> +			return 0;
> +
> +		return an7583_usb_phy_pcie_init(phy);
> +	default:
> +		return -EINVAL;
> +	}
> +}
> +
> +static int an7583_usb_phy_exit(struct phy *phy)
> +{
> +	return 0;
> +}
> +
> +static int an7583_usb_phy_u2_power_on(struct phy *phy)
> +{
> +	struct an7583_usb_phy_instance *instance = phy_get_drvdata(phy);
> +	struct an7583_usb_phy_priv *priv;
> +	struct device *dev;
> +	u32 offset;
> +
> +	dev = phy->dev.parent;
> +	priv = dev_get_drvdata(dev);
> +	offset = instance->offset;
> +
> +	regmap_clear_bits(priv->regs[AIROHA_USB_PHY_PHY],
> +			  AIROHA_USB_PHY_USBPHYACR6 + offset,
> +			  AIROHA_USB_PHY_USB20_BC11_SW_EN);
> +
> +	regmap_set_bits(priv->regs[AIROHA_USB_PHY_PHY],
> +			AIROHA_USB_PHY_USBPHYACR2 + offset,
> +			AIROHA_USB_PHY_SIFSLV_MAC_BANDGAP_EN);
> +
> +	regmap_update_bits(priv->regs[AIROHA_USB_PHY_PHY],
> +			   AIROHA_USB_PHY_U2PHYACR3 + offset,
> +			   AIROHA_USB_PHY_USB20_HSTX_I_EN_MODE,
> +			   AIROHA_USB_PHY_USB20_HSTX_I_EN_MODE_TOGGLE);
> +
> +	regmap_clear_bits(priv->regs[AIROHA_USB_PHY_PHY],
> +			  AIROHA_USB_PHY_U2PHYDTM0 + offset,
> +			  AIROHA_USB_PHY_FORCE_XCVRSEL |
> +			  AIROHA_USB_PHY_XCVRSEL);
> +
> +	regmap_update_bits(priv->regs[AIROHA_USB_PHY_PHY],
> +			   AIROHA_USB_PHY_USBPHYACR6 + offset,
> +			   AIROHA_USB_PHY_USB20_HSRX_BIAS_EN_SEL,
> +			   AIROHA_USB_PHY_USB20_HSRX_BIAS_EN_SEL_NO_ENPLL_FS_BIAS_EN);
> +
> +	regmap_set_bits(priv->regs[AIROHA_USB_PHY_PHY],
> +			AIROHA_USB_PHY_USBPHYACR5 + offset,
> +			AIROHA_USB_PHY_USB20_DISC_FIT_EN);
> +
> +	regmap_clear_bits(priv->regs[AIROHA_USB_PHY_PHY],
> +			  AIROHA_USB_PHY_U2PHYDTM0 + offset,
> +			  AIROHA_USB_PHY_FORCE_SUSPENDDM);
> +
> +	regmap_clear_bits(priv->regs[AIROHA_USB_PHY_PHY],
> +			  AIROHA_USB_PHY_U2PHYACR3 + offset,
> +			  AIROHA_USB_PHY_USB20_USB11_TMODE_EN);
> +
> +	regmap_set_bits(priv->regs[AIROHA_USB_PHY_PHY],
> +			AIROHA_USB_PHY_U2PHYACR3 + offset,
> +			AIROHA_USB_PHY_USB20_TMODE_FS_LS_TX_EN);
> +
> +	regmap_clear_bits(priv->regs[AIROHA_USB_PHY_PHY],
> +			  AIROHA_USB_PHY_U2PHYDTM0 + offset,
> +			  AIROHA_USB_PHY_FORCE_TERMSEL |
> +			  AIROHA_USB_PHY_TERMSEL);
> +
> +	regmap_clear_bits(priv->regs[AIROHA_USB_PHY_PHY],
> +			  AIROHA_USB_PHY_U2PHYACR3 + offset,
> +			  AIROHA_USB_PHY_USB20_PUPD_BIST_EN);
> +
> +	return 0;
> +}
> +
> +static int an7583_usb_phy_u3_power_on(struct phy *phy)
> +{
> +	struct an7583_usb_phy_priv *priv;
> +	struct device *dev;
> +
> +	dev = phy->dev.parent;
> +	priv = dev_get_drvdata(dev);
> +
> +	regmap_set_bits(priv->regs[AIROHA_USB_PHY_ANA], AIROHA_USB_ANA_TDC_FT_CK_EN,
> +			AIROHA_USB_ANA_VUSB10_ON);
> +
> +	usleep_range(1000, 1500);
> +
> +	regmap_clear_bits(priv->regs[AIROHA_USB_PHY_PHY], AIROHA_USB_PHY_GPIO_CTLD,
> +			  AIROHA_USB_PHY_SSUSB_IP_SW_RST);
> +
> +	usleep_range(1000, 1500);
> +
> +	regmap_clear_bits(priv->regs[AIROHA_USB_PHY_PHY], AIROHA_USB_PHY_GPIO_CTLD,
> +			  AIROHA_USB_PHY_FORCE_SSUSB_IP_SW_RST);
> +
> +	usleep_range(1000, 1500);
> +
> +	regmap_clear_bits(priv->regs[AIROHA_USB_PHY_PMA], AIROHA_USB_PMA_INTF_CTRL_5,
> +			  AIROHA_USB_PMA_RX_HZ_FORCE);
> +
> +	usleep_range(1000, 1500);
> +
> +	regmap_clear_bits(priv->regs[AIROHA_USB_PHY_PMA], AIROHA_USB_PMA_INTF_CTRL_5,
> +			  AIROHA_USB_PMA_RX_HZ_SEL);
> +
> +	return 0;
> +}
> +
> +static int an7583_usb_phy_power_on(struct phy *phy)
> +{
> +	struct an7583_usb_phy_instance *instance = phy_get_drvdata(phy);
> +
> +	switch (instance->type) {
> +	case PHY_TYPE_USB2:
> +		return an7583_usb_phy_u2_power_on(phy);
> +	case PHY_TYPE_USB3:
> +		return an7583_usb_phy_u3_power_on(phy);
> +	case PHY_TYPE_PCIE:
> +		return 0;
> +	default:
> +		return -EINVAL;
> +	}
> +}
> +
> +static int an7583_usb_phy_u2_power_off(struct phy *phy)
> +{
> +	struct an7583_usb_phy_instance *instance = phy_get_drvdata(phy);
> +	struct an7583_usb_phy_priv *priv;
> +	struct device *dev;
> +	u32 offset;
> +
> +	dev = phy->dev.parent;
> +	priv = dev_get_drvdata(dev);
> +	offset = instance->offset;
> +
> +	regmap_set_bits(priv->regs[AIROHA_USB_PHY_PHY],
> +			AIROHA_USB_PHY_U2PHYACR3 + offset,
> +			AIROHA_USB_PHY_USB20_PUPD_BIST_EN);
> +
> +	regmap_set_bits(priv->regs[AIROHA_USB_PHY_PHY],
> +			AIROHA_USB_PHY_U2PHYDTM0 + offset,
> +			AIROHA_USB_PHY_FORCE_TERMSEL |
> +			AIROHA_USB_PHY_TERMSEL);
> +
> +	regmap_clear_bits(priv->regs[AIROHA_USB_PHY_PHY],
> +			  AIROHA_USB_PHY_U2PHYACR3 + offset,
> +			  AIROHA_USB_PHY_USB20_TMODE_FS_LS_TX_EN);
> +
> +	regmap_set_bits(priv->regs[AIROHA_USB_PHY_PHY],
> +			AIROHA_USB_PHY_U2PHYACR3 + offset,
> +			AIROHA_USB_PHY_USB20_USB11_TMODE_EN);
> +
> +	regmap_set_bits(priv->regs[AIROHA_USB_PHY_PHY],
> +			AIROHA_USB_PHY_U2PHYDTM0 + offset,
> +			AIROHA_USB_PHY_FORCE_SUSPENDDM);
> +
> +	regmap_clear_bits(priv->regs[AIROHA_USB_PHY_PHY],
> +			  AIROHA_USB_PHY_USBPHYACR5 + offset,
> +			  AIROHA_USB_PHY_USB20_DISC_FIT_EN);
> +
> +	regmap_update_bits(priv->regs[AIROHA_USB_PHY_PHY],
> +			   AIROHA_USB_PHY_USBPHYACR6 + offset,
> +			   AIROHA_USB_PHY_USB20_HSRX_BIAS_EN_SEL,
> +			   AIROHA_USB_PHY_USB20_HSRX_BIAS_EN_SEL_USB20_HSRX_TMODE_EN);
> +
> +	regmap_update_bits(priv->regs[AIROHA_USB_PHY_PHY],
> +			   AIROHA_USB_PHY_U2PHYDTM0 + offset,
> +			   AIROHA_USB_PHY_FORCE_XCVRSEL |
> +			   AIROHA_USB_PHY_XCVRSEL,
> +			   AIROHA_USB_PHY_FORCE_XCVRSEL |
> +			   FIELD_PREP(AIROHA_USB_PHY_XCVRSEL, 0x1));
> +
> +	regmap_update_bits(priv->regs[AIROHA_USB_PHY_PHY],
> +			   AIROHA_USB_PHY_U2PHYACR3 + offset,
> +			   AIROHA_USB_PHY_USB20_HSTX_I_EN_MODE,
> +			   AIROHA_USB_PHY_USB20_HSTX_I_EN_MODE_FORCE_DISABLE);
> +
> +	regmap_clear_bits(priv->regs[AIROHA_USB_PHY_PHY],
> +			  AIROHA_USB_PHY_USBPHYACR2 + offset,
> +			  AIROHA_USB_PHY_SIFSLV_MAC_BANDGAP_EN);
> +
> +	regmap_set_bits(priv->regs[AIROHA_USB_PHY_PHY],
> +			AIROHA_USB_PHY_USBPHYACR6 + offset,
> +			AIROHA_USB_PHY_USB20_BC11_SW_EN);
> +
> +	return 0;
> +}
> +
> +static int an7583_usb_phy_u3_power_off(struct phy *phy)
> +{
> +	struct an7583_usb_phy_priv *priv;
> +	struct device *dev;
> +
> +	dev = phy->dev.parent;
> +	priv = dev_get_drvdata(dev);
> +
> +	regmap_set_bits(priv->regs[AIROHA_USB_PHY_PHY], AIROHA_USB_PHY_GPIO_CTLD,
> +			AIROHA_USB_PHY_FORCE_SSUSB_IP_SW_RST);
> +
> +	usleep_range(1000, 1500);
> +
> +	regmap_set_bits(priv->regs[AIROHA_USB_PHY_PHY], AIROHA_USB_PHY_GPIO_CTLD,
> +			AIROHA_USB_PHY_SSUSB_IP_SW_RST);
> +
> +	usleep_range(1000, 1500);
> +
> +	regmap_set_bits(priv->regs[AIROHA_USB_PHY_PMA], AIROHA_USB_PMA_INTF_CTRL_5,
> +			AIROHA_USB_PMA_RX_HZ_FORCE);
> +
> +	usleep_range(1000, 1500);
> +
> +	regmap_set_bits(priv->regs[AIROHA_USB_PHY_PMA], AIROHA_USB_PMA_INTF_CTRL_5,
> +			AIROHA_USB_PMA_RX_HZ_SEL);
> +
> +	usleep_range(1000, 1500);
> +
> +	regmap_clear_bits(priv->regs[AIROHA_USB_PHY_ANA], AIROHA_USB_ANA_TDC_FT_CK_EN,
> +			  AIROHA_USB_ANA_VUSB10_ON);
> +
> +	return 0;
> +}
> +
> +static int an7583_usb_phy_power_off(struct phy *phy)
> +{
> +	struct an7583_usb_phy_instance *instance = phy_get_drvdata(phy);
> +
> +	switch (instance->type) {
> +	case PHY_TYPE_USB2:
> +		return an7583_usb_phy_u2_power_off(phy);
> +	case PHY_TYPE_USB3:
> +		return an7583_usb_phy_u3_power_off(phy);
> +	case PHY_TYPE_PCIE:
> +		return 0;
> +	default:
> +		return -EINVAL;
> +	}
> +}
> +
> +static int an7583_usb_phy_u2_set_mode(struct phy *phy, enum phy_mode mode)
> +{
> +	struct an7583_usb_phy_instance *instance = phy_get_drvdata(phy);
> +	struct an7583_usb_phy_priv *priv;
> +	struct device *dev;
> +	u32 val = 0;
> +	u32 offset;
> +
> +	dev = phy->dev.parent;
> +	priv = dev_get_drvdata(dev);
> +	offset = instance->offset;
> +
> +	/*
> +	 * For Device and Host mode, enable force IDDIG.
> +	 * For Device set IDDIG, for Host clear IDDIG.
> +	 * For OTG disable force and clear IDDIG bit while at it.
> +	 */
> +	switch (mode) {
> +	case PHY_MODE_USB_DEVICE:
> +		val |= AIROHA_USB_PHY_IDDIG;
> +		fallthrough;
> +	case PHY_MODE_USB_HOST:
> +		val |= AIROHA_USB_PHY_FORCE_IDDIG;
> +		break;
> +	case PHY_MODE_USB_OTG:
> +		break;
> +	default:
> +		return 0;
> +	}
> +
> +	regmap_update_bits(priv->regs[AIROHA_USB_PHY_PHY],
> +			   AIROHA_USB_PHY_U2PHYDTM1 + offset,
> +			   AIROHA_USB_PHY_FORCE_IDDIG |
> +			   AIROHA_USB_PHY_IDDIG, val);
> +
> +	return 0;
> +}
> +
> +static int an7583_usb_phy_u3_set_mode(struct phy *phy, enum phy_mode mode,
> +				      int submode)
> +{
> +	struct an7583_usb_phy_instance *instance = phy_get_drvdata(phy);
> +	int ret;
> +
> +	switch (mode) {
> +	case PHY_MODE_ETHERNET:
> +		if (submode != PHY_INTERFACE_MODE_SGMII &&
> +		    submode != PHY_INTERFACE_MODE_1000BASEX &&
> +		    submode != PHY_INTERFACE_MODE_2500BASEX)
> +			return -EOPNOTSUPP;
> +
> +		break;
> +	case PHY_MODE_USB_DEVICE_SS:
> +		break;
> +	default:
> +		return -EOPNOTSUPP;
> +	}
> +
> +	ret = phy_set_mode_ext(instance->serdes_phy, mode, submode);
> +	if (ret)
> +		return ret;
> +
> +	if (mode == PHY_MODE_ETHERNET)
> +		an7583_usb_phy_set_mode_eth(phy, submode);
> +
> +	return 0;
> +}
> +
> +static int an7583_usb_phy_pcie_set_mode(struct phy *phy, enum phy_mode mode,
> +					int submode)
> +{
> +	struct an7583_usb_phy_instance *instance = phy_get_drvdata(phy);
> +	int ret;
> +
> +	switch (mode) {
> +	case PHY_MODE_ETHERNET:
> +		if (submode != PHY_INTERFACE_MODE_SGMII &&
> +		    submode != PHY_INTERFACE_MODE_1000BASEX &&
> +		    submode != PHY_INTERFACE_MODE_2500BASEX)
> +			return -EOPNOTSUPP;
> +
> +		break;
> +	case PHY_MODE_PCIE:
> +		break;
> +	default:
> +		return -EOPNOTSUPP;
> +	}
> +
> +	ret = phy_set_mode_ext(instance->serdes_phy, mode, submode);
> +	if (ret)
> +		return ret;
> +
> +	if (mode == PHY_MODE_ETHERNET)
> +		an7583_usb_phy_set_mode_eth(phy, submode);
> +
> +	return 0;
> +}
> +
> +static int an7583_usb_phy_set_mode(struct phy *phy, enum phy_mode mode, int submode)
> +{
> +	struct an7583_usb_phy_instance *instance = phy_get_drvdata(phy);
> +
> +	switch (instance->type) {
> +	case PHY_TYPE_USB2:
> +		return an7583_usb_phy_u2_set_mode(phy, mode);
> +	case PHY_TYPE_USB3:
> +		return an7583_usb_phy_u3_set_mode(phy, mode, submode);
> +	case PHY_TYPE_PCIE:
> +		return an7583_usb_phy_pcie_set_mode(phy, mode, submode);
> +	default:
> +		return 0;
> +	}
> +}
> +
> +static struct phy *an7583_usb_phy_xlate(struct device *dev,
> +					const struct of_phandle_args *args)
> +{
> +	struct an7583_usb_phy_priv *priv = dev_get_drvdata(dev);
> +	const struct an7583_usb_phy_match_data *data;
> +	struct device_node *phy_np = args->np;
> +	struct phy *phy = NULL;
> +	int type, index;
> +
> +	data = of_device_get_match_data(dev);
> +
> +	if (args->args_count != 1) {
> +		dev_err(dev, "invalid number of cells in 'phy' property\n");
> +		return ERR_PTR(-EINVAL);
> +	}
> +
> +	for (index = 0; index < data->max_instance; index++) {
> +		if (!priv->phys[index])
> +			continue;
> +
> +		if (phy_np == priv->phys[index]->dev.of_node) {
> +			phy = priv->phys[index];
> +			break;
> +		}
> +	}
> +
> +	if (!phy) {
> +		dev_err(dev, "failed to find appropriate phy\n");
> +		return ERR_PTR(-EINVAL);
> +	}
> +
> +	type = args->args[0];
> +	if (!(type == PHY_TYPE_USB2 || type == PHY_TYPE_USB3 ||
> +	      type == PHY_TYPE_PCIE)) {
> +		dev_err(dev, "unsupported device type: %d\n", type);
> +		return ERR_PTR(-EINVAL);
> +	}
> +
> +	return phy;
> +}
> +
> +static const struct phy_ops airoha_phy = {
> +	.init		= an7583_usb_phy_init,
> +	.exit		= an7583_usb_phy_exit,
> +	.power_on	= an7583_usb_phy_power_on,
> +	.power_off	= an7583_usb_phy_power_off,
> +	.set_mode	= an7583_usb_phy_set_mode,
> +	.owner		= THIS_MODULE,
> +};
> +
> +static const char * const an7583_usb_phy_regs_name[AIROHA_USB_PHY_REGS_MAX] = {
> +	[AIROHA_USB_PHY_PHY] = "phy",
> +	[AIROHA_USB_PHY_ANA] = "ana",
> +	[AIROHA_USB_PHY_PMA] = "pma",
> +	[AIROHA_USB_PHY_DIG] = "dig",
> +};
> +
> +static const char * const airoha_pcie_phy_regs_name[AIROHA_USB_PHY_REGS_MAX] = {
> +	[AIROHA_USB_PHY_ANA] = "ana",
> +	[AIROHA_USB_PHY_PMA] = "pma",
> +	[AIROHA_USB_PHY_DIG] = "dig",
> +};
> +
> +static int an7583_usb_phy_parse_ports(struct device *dev,
> +				      struct an7583_usb_phy_priv *priv,
> +				      int index, struct device_node *subnode)
> +{
> +	const struct an7583_usb_phy_match_data *data;
> +	struct an7583_usb_phy_instance  *instance;
> +	struct phy *phy;
> +	int ret;
> +
> +	data = of_device_get_match_data(dev);
> +
> +	if (index >= data->max_instance)
> +		return -EINVAL;
> +
> +	if (!of_device_is_available(subnode))
> +		return 0;
> +
> +	instance = devm_kzalloc(dev, sizeof(*instance), GFP_KERNEL);
> +	if (!instance)
> +		return -ENOMEM;
> +
> +	instance->serdes_phy = devm_of_phy_optional_get(dev, subnode, NULL);
> +	if (IS_ERR(instance->serdes_phy))
> +		return dev_err_probe(dev, PTR_ERR(instance->serdes_phy), "error on serdes phy for USB 3.0\n");
> +
> +	if (!instance->serdes_phy &&
> +	    !of_property_present(subnode, "airoha,usb2-monitor-clk-sel"))
> +		return dev_err_probe(dev, -EINVAL, "monitor clock selection or serdes PHY is mandatory for USB PHY\n");
> +
> +	if (instance->serdes_phy) {
> +		instance->type = PHY_TYPE_USB3;
> +	} else {
> +		ret = of_property_read_u32(subnode, "airoha,usb2-monitor-clk-sel",
> +					   &instance->monclk_sel);
> +		if (ret)
> +			return dev_err_probe(dev, ret, "failed to parse Monitor clock selection\n");
> +
> +		ret = of_property_read_u32(subnode, "reg",
> +					   &instance->offset);
> +		if (ret)
> +			return dev_err_probe(dev, ret, "missing reg for U2 PHY\n");
> +
> +		instance->type = PHY_TYPE_USB2;
> +	}
> +
> +	phy = devm_phy_create(dev, subnode, &airoha_phy);
> +	if (IS_ERR(phy))
> +		return dev_err_probe(dev, PTR_ERR(phy), "failed to create phy\n");
> +
> +	priv->phys[index] = phy;
> +	phy_set_drvdata(phy, instance);
> +
> +	return 0;
> +}
> +
> +static int airoha_pcie_phy_parse_ports(struct device *dev,
> +				       struct an7583_usb_phy_priv *priv,
> +				       int index, struct device_node *subnode)
> +{
> +	const struct an7583_usb_phy_match_data *data;
> +	struct an7583_usb_phy_instance  *instance;
> +	struct phy *phy;
> +
> +	data = of_device_get_match_data(dev);
> +
> +	if (index >= data->max_instance)
> +		return -EINVAL;
> +
> +	if (!of_device_is_available(subnode))
> +		return 0;
> +
> +	instance = devm_kzalloc(dev, sizeof(*instance), GFP_KERNEL);
> +	if (!instance)
> +		return -ENOMEM;
> +
> +	instance->serdes_phy = devm_phy_get(dev, NULL);
> +	if (IS_ERR(instance->serdes_phy))
> +		return dev_err_probe(dev, PTR_ERR(instance->serdes_phy), "error on serdes phy for PCIe PHY\n");
> +
> +	instance->type = PHY_TYPE_PCIE;
> +
> +	phy = devm_phy_create(dev, subnode, &airoha_phy);
> +	if (IS_ERR(phy))
> +		return dev_err_probe(dev, PTR_ERR(phy), "failed to create phy\n");
> +
> +	priv->phys[index] = phy;
> +	phy_set_drvdata(phy, instance);
> +
> +	return 0;
> +}
> +
> +static int an7583_usb_phy_probe(struct platform_device *pdev)
> +{
> +	const struct an7583_usb_phy_match_data *data;
> +	struct phy_provider *phy_provider;
> +	struct an7583_usb_phy_priv *priv;
> +	struct device *dev = &pdev->dev;
> +	struct device_node *child_np;
> +	int i, ret;
> +
> +	data = of_device_get_match_data(dev);
> +
> +	priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);
> +	if (!priv)
> +		return -ENOMEM;
> +
> +	for (i = 0; i < AIROHA_USB_PHY_REGS_MAX; i++) {
> +		struct regmap_config conf = {
> +			.reg_bits = 32,
> +			.val_bits = 32,
> +			.reg_stride = 4,
> +		};
> +		void *base;
> +
> +		if (!data->regs_name[i])
> +			continue;
> +
> +		conf.name = data->regs_name[i];
> +		base = devm_platform_ioremap_resource_byname(pdev,
> +							     data->regs_name[i]);
> +		if (IS_ERR(base))
> +			return PTR_ERR(base);
> +
> +		priv->regs[i] = devm_regmap_init_mmio(dev, base, &conf);
> +		if (IS_ERR(priv->regs[i]))
> +			return PTR_ERR(priv->regs[i]);
> +	}
> +
> +	platform_set_drvdata(pdev, priv);
> +
> +	if (device_is_compatible(dev, "airoha,an7583-usb-phy")) {
> +		u8 port;
> +
> +		port = 0;
> +		for_each_child_of_node(dev->of_node, child_np) {
> +			ret = data->parse_ports(dev, priv, port, child_np);
> +			if (ret) {
> +				of_node_put(child_np);
> +				return ret;
> +			}
> +
> +			port++;
> +		}
> +	} else {
> +		ret = data->parse_ports(dev, priv, 0, dev->of_node);
> +		if (ret)
> +			return ret;
> +	}
> +
> +	phy_provider = devm_of_phy_provider_register(dev, an7583_usb_phy_xlate);
> +
> +	return PTR_ERR_OR_ZERO(phy_provider);
> +}
> +
> +static const struct an7583_usb_phy_match_data an7583_usb_phy = {
> +	.max_instance = AIROHA_USB_PHY_MAX_INSTANCE,
> +	.regs_name = an7583_usb_phy_regs_name,
> +	.parse_ports = an7583_usb_phy_parse_ports,
> +};
> +
> +static const struct an7583_usb_phy_match_data an7583_pcie_phy = {
> +	.max_instance = AIROHA_PCIE_PHY_MAX_INSTANCE,
> +	.regs_name = airoha_pcie_phy_regs_name,
> +	.parse_ports = airoha_pcie_phy_parse_ports,
> +};
> +
> +static const struct of_device_id airoha_phy_id_table[] = {
> +	{ .compatible = "airoha,an7583-usb-phy", .data = &an7583_usb_phy },
> +	{ .compatible = "airoha,an7583-pcie-gen2-phy", .data = &an7583_pcie_phy },
> +	{ },
> +};
> +MODULE_DEVICE_TABLE(of, airoha_phy_id_table);
> +
> +static struct platform_driver an7583_usb_driver = {
> +	.probe		= an7583_usb_phy_probe,
> +	.driver		= {
> +		.name	= "airoha-an7583-usb-phy",
> +		.of_match_table = airoha_phy_id_table,
> +	},
> +};
> +
> +module_platform_driver(an7583_usb_driver);
> +
> +MODULE_DESCRIPTION("Airoha AN7583 USB PHY driver");
> +MODULE_AUTHOR("Christian Marangi <ansuelsmth@gmail.com>");
> +MODULE_LICENSE("GPL");
> -- 
> 2.53.0
> 

      reply	other threads:[~2026-09-16 14:00 UTC|newest]

Thread overview: 8+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-09-01 12:39 [PATCH v4 0/3] phy: " Christian Marangi
2026-09-01 12:39 ` [PATCH v4 1/3] dt-bindings: phy: airoha: Document support for " Christian Marangi
2026-09-07  6:35   ` Krzysztof Kozlowski
2026-09-07  9:00     ` Christian Marangi
2026-09-16 15:00       ` Krzysztof Kozlowski
2026-09-01 12:39 ` [PATCH v4 2/3] dt-bindings: phy: airoha: Document support for AN7583 Gen2 PCIe PHY Christian Marangi
2026-09-01 12:39 ` [PATCH v4 3/3] phy: airoha: Add support for Airoha AN7583 USB PHY Christian Marangi
2026-09-16 14:00   ` Zhengping Zhang [this message]

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=aqqhErGXHUf7FQMx@mediatek.com \
    --to=zhengping.zhang@airoha.com \
    --cc=ansuelsmth@gmail.com \
    --cc=conor+dt@kernel.org \
    --cc=devicetree@vger.kernel.org \
    --cc=krzk+dt@kernel.org \
    --cc=lei.dong@airoha.com \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux-phy@lists.infradead.org \
    --cc=neil.armstrong@linaro.org \
    --cc=robh@kernel.org \
    --cc=vkoul@kernel.org \
    --cc=yalei.zang@airoha.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox

all inboxes | Powered by JetHome®