From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from mail-ej1-f47.google.com (mail-ej1-f47.google.com [209.85.218.47]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id EEA634949F7 for ; Tue, 9 Jun 2026 15:13:38 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.218.47 ARC-Seal:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1781018057; cv=none; b=L/q+Px4caYDwqthYJYhDyu9F8WhJUBPo0pl7Sao05HWadHskDo8kiDBoff0/anlnLRnf3wCUaaez31phUUpgimnuSbD1i+SjCrPFLwXd3CiaF8OrNfSoe8rIRF2RwkpA/OgV8+ECORkce8/UQLDIeoCpWzb+iKXsT5WYnLrA92w= ARC-Message-Signature:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1781018057; c=relaxed/simple; bh=+Pu2E4VZnz1S5xXsqNUU+6Q45LW8bmcdw9UWWWyuaEI=; h=From:To:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=TZYXmEf4RMMf4M2czf4bI71m7wHsGvuRFR3+KEunCMk1K1dtOCWZU497Jqdo9OIQK4pi4kXdwpWFiVsbUTTGuwwjpI3fNHUQpDunr9TCWwqe9FyU/xnQMKIQQyxQRqJ2fjuFSrnDxb6guz5+CtZN1Wgd1/T0kCf2tYO8X8HV5gE= ARC-Authentication-Results:i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com; spf=pass smtp.mailfrom=gmail.com; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b=ryY7/Yyv; arc=none smtp.client-ip=209.85.218.47 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=gmail.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="ryY7/Yyv" Received: by mail-ej1-f47.google.com with SMTP id a640c23a62f3a-bdb3fd39045so810358866b.3 for ; Tue, 09 Jun 2026 08:13:38 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20251104; t=1781018017; x=1781622817; darn=vger.kernel.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:to:from:from:to:cc:subject:date:message-id :reply-to; bh=ZBRAVfY7jIae0WbjP9a9eYWDDd9cqvl4P3244tcqAMs=; b=ryY7/YyvgkHfmQ+0NdR1kTiQVJ3wOh6MT5ykjyrUyx2zCslOxLVndsHiA89CjTSU2H vH0me+8a/eDpvZGpt6CBmjQ1jGODGHL3wW4we0BVTFu9C92zaMUuJ7/W6Ar6QxvVu5kN 1tP2kIuKVr07wu6wQuPbCS4hHneUFR0l21fXObE+O8QXZv3rmJ6CHo7ZSc6n6NHF0dlV Dt6emtYSeSfzG0IXIIVFyE/I4mU2UyOaMh5bZCUO95z+JkLEqXfOc3caMoT5usg5Go3D n6ryg7tzEB/i7k9WvpcaVtDmHbC0ikGGmWB7KykihIldmleNS1QXZd81gU1jifbKYjyn KYWw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1781018017; x=1781622817; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:to:from:x-gm-gg:x-gm-message-state:from:to :cc:subject:date:message-id:reply-to; bh=ZBRAVfY7jIae0WbjP9a9eYWDDd9cqvl4P3244tcqAMs=; b=mI2UJXttaBNFLZWSmxSi/N+xaO4ppCChAiCVHTQyzJayp7mbgXlAD+fk6OINaDNxsB sipfCRFvGqm9TVBoI9LKgXBjvB1I7qk1PsGd4Sh2dxl70pC8rDPPE1TroaQ0SQ0GTlSu uINhAW+M5fKj5ZJcAm/uDmMBGBycSw5MULAcRdIoNrdcmevISlueroKNW1fD+Hxax6Yo UrjfLEQLRii/raGzQodDNdpaFh61uAPzflOQKSzYu+aGN653dqwbKOf/sd0OQhE0zU8v G2P7X6SkoyR4LMNXtPc2fDU/amJbwjVj3/Vcn4O2ZhmMfOJcf6QQnTLfKe1GqSN9ujep Gwdg== X-Forwarded-Encrypted: i=1; AFNElJ9oJd382pl3v4K2qadsaEcfc1U+iO1kbUMtWRKm1UwvFo45m2o+fjTY62RHYpSKRaV7AlNtvDQbM7Rz@vger.kernel.org X-Gm-Message-State: AOJu0YyqIJ4eV8Mv9nMk71iG5eU2UPXv7Gq9ZaI9iPZvw4KFIy9pkTDC 96/z2dvvRBFvXf5UOAf/OlLdJvfUustDNXcBMqXZX9wsWY5LobK9ck5j X-Gm-Gg: Acq92OEQwolJCyWDldHsjbJSAq+mivNkMoc+KFhQvQXhEryxrWv/55I3zVGBLx++JLI rUxXQ0n4J08N25GwtSXKzdHRWLcNjUxjEyiOJKKOWJhAMcmpEYfEJrFqx5/cRRIFUajQP1mXJo0 Z7UXPUpkPH+wiErddY5QL1z71UC3/veSUULs2PArzYvt7heaErAFfWrkI3HSMyMr/P32B5iSbf9 NzF9SMHKpmS0eZ3/meXWrABHBH3MCYrIA/GQ+1VPJvr84/Wfbh2Kq1LSepLs+cbJZqEwStCeoul 3DTvHUb0kIJig/w+3sHtOFujx9baCA4S93Tju2w/UrGv6sT06iRwPzFD0EBTuH9Ou50cf38xGMR bIkfolhcPyE3rmxzzV4SRdBFME3WZJ+bPWzTQ26/FRA0+2e9fTzPooOYcklEURBsAeoFqEPLRqs 58hM5Ul/BpBc4fwbYndxmau64R4cOjM/re X-Received: by 2002:a17:907:a0b:b0:bcc:3dd8:58da with SMTP id a640c23a62f3a-bf37234c643mr1036567166b.27.1781018015892; Tue, 09 Jun 2026 08:13:35 -0700 (PDT) Received: from Ansuel-XPS24 ([2.195.136.12]) by smtp.googlemail.com with ESMTPSA id a640c23a62f3a-bf0517721e5sm1073637866b.9.2026.06.09.08.13.32 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 09 Jun 2026 08:13:35 -0700 (PDT) From: Christian Marangi To: Andrew Lunn , "David S. Miller" , Eric Dumazet , Jakub Kicinski , Paolo Abeni , Rob Herring , Krzysztof Kozlowski , Conor Dooley , Simon Horman , Jonathan Corbet , Shuah Khan , Christian Marangi , Lorenzo Bianconi , Heiner Kallweit , Russell King , Saravana Kannan , Philipp Zabel , Nathan Chancellor , Nick Desaulniers , Bill Wendling , Justin Stitt , netdev@vger.kernel.org, devicetree@vger.kernel.org, linux-kernel@vger.kernel.org, linux-doc@vger.kernel.org, linux-arm-kernel@lists.infradead.org, linux-mediatek@lists.infradead.org, llvm@lists.linux.dev Subject: [PATCH net-next v6 11/12] net: pcs: airoha: add PCS driver for Airoha AN7581 SoC Date: Tue, 9 Jun 2026 17:12:07 +0200 Message-ID: <20260609151212.29469-12-ansuelsmth@gmail.com> X-Mailer: git-send-email 2.53.0 In-Reply-To: <20260609151212.29469-1-ansuelsmth@gmail.com> References: <20260609151212.29469-1-ansuelsmth@gmail.com> Precedence: bulk X-Mailing-List: devicetree@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: 8bit Add PCS driver for Airoha AN7581 SoC for Ethernet/PON/PCIe/USB SERDES and permit usage of external PHY or connected SFP cage. Supported modes are USXGMII, 10G-BASER, 2500BASE-X, 1000BASE-X and SGMII. The driver probe and register the various needed registers and register as a PCS provider for fwnode usage. Signed-off-by: Christian Marangi --- drivers/net/pcs/Kconfig | 2 + drivers/net/pcs/Makefile | 2 + drivers/net/pcs/airoha/Kconfig | 12 + drivers/net/pcs/airoha/Makefile | 7 + drivers/net/pcs/airoha/pcs-airoha-common.c | 1313 ++++++++++++ drivers/net/pcs/airoha/pcs-airoha.h | 1309 ++++++++++++ drivers/net/pcs/airoha/pcs-an7581.c | 2093 ++++++++++++++++++++ 7 files changed, 4738 insertions(+) create mode 100644 drivers/net/pcs/airoha/Kconfig create mode 100644 drivers/net/pcs/airoha/Makefile create mode 100644 drivers/net/pcs/airoha/pcs-airoha-common.c create mode 100644 drivers/net/pcs/airoha/pcs-airoha.h create mode 100644 drivers/net/pcs/airoha/pcs-an7581.c diff --git a/drivers/net/pcs/Kconfig b/drivers/net/pcs/Kconfig index 2ce89d4bff6b..10ac9af04594 100644 --- a/drivers/net/pcs/Kconfig +++ b/drivers/net/pcs/Kconfig @@ -41,4 +41,6 @@ config PCS_RZN1_MIIC Renesas RZ/N1, RZ/N2H, and RZ/T2H SoCs. This PCS converts MII to RMII/RGMII, or can be set in pass-through mode for MII. +source "drivers/net/pcs/airoha/Kconfig" + endmenu diff --git a/drivers/net/pcs/Makefile b/drivers/net/pcs/Makefile index 3005cdd89ab7..91593aa8d926 100644 --- a/drivers/net/pcs/Makefile +++ b/drivers/net/pcs/Makefile @@ -9,3 +9,5 @@ obj-$(CONFIG_PCS_XPCS) += pcs_xpcs.o obj-$(CONFIG_PCS_LYNX) += pcs-lynx.o obj-$(CONFIG_PCS_MTK_LYNXI) += pcs-mtk-lynxi.o obj-$(CONFIG_PCS_RZN1_MIIC) += pcs-rzn1-miic.o + +obj-$(CONFIG_PCS_AIROHA) += airoha/ diff --git a/drivers/net/pcs/airoha/Kconfig b/drivers/net/pcs/airoha/Kconfig new file mode 100644 index 000000000000..4ddd527b365f --- /dev/null +++ b/drivers/net/pcs/airoha/Kconfig @@ -0,0 +1,12 @@ +# SPDX-License-Identifier: GPL-2.0-only + +config PCS_AIROHA + tristate + select FWNODE_PCS + +config PCS_AIROHA_AN7581 + tristate "Airoha AN7581 PCS driver" + select PCS_AIROHA + help + This module provides helper to phylink for managing the Airoha + AN7581 PCS for SoC Ethernet and PON SERDES. diff --git a/drivers/net/pcs/airoha/Makefile b/drivers/net/pcs/airoha/Makefile new file mode 100644 index 000000000000..25cb8f090c21 --- /dev/null +++ b/drivers/net/pcs/airoha/Makefile @@ -0,0 +1,7 @@ +# SPDX-License-Identifier: GPL-2.0 + +obj-y := pcs-airoha.o +pcs-airoha-objs := pcs-airoha-common.o +ifdef CONFIG_PCS_AIROHA_AN7581 +pcs-airoha-objs += pcs-an7581.o +endif diff --git a/drivers/net/pcs/airoha/pcs-airoha-common.c b/drivers/net/pcs/airoha/pcs-airoha-common.c new file mode 100644 index 000000000000..ead0bc808396 --- /dev/null +++ b/drivers/net/pcs/airoha/pcs-airoha-common.c @@ -0,0 +1,1313 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Copyright (c) 2024 AIROHA Inc + * Author: Christian Marangi + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "pcs-airoha.h" + +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 void airoha_pcs_setup_scu_pcie(struct airoha_pcs_priv *priv, + int index, phy_interface_t interface) +{ + u32 xsi_sel; + + if (index == 0) { + switch (interface) { + case PHY_INTERFACE_MODE_SGMII: + case PHY_INTERFACE_MODE_1000BASEX: + case PHY_INTERFACE_MODE_2500BASEX: + xsi_sel = AIROHA_SCU_PCIE_XSI0_HSGMII; + break; + case PHY_INTERFACE_MODE_USXGMII: + case PHY_INTERFACE_MODE_10GBASER: + default: + xsi_sel = AIROHA_SCU_PCIE_XSI0_USXGMII; + } + + regmap_update_bits(priv->scu, AIROHA_SCU_SSTR, + AIROHA_SCU_PCIE_XSI0_SEL, + xsi_sel); + } else { + switch (interface) { + case PHY_INTERFACE_MODE_SGMII: + case PHY_INTERFACE_MODE_1000BASEX: + case PHY_INTERFACE_MODE_2500BASEX: + xsi_sel = AIROHA_SCU_PCIE_XSI1_HSGMII; + break; + case PHY_INTERFACE_MODE_USXGMII: + case PHY_INTERFACE_MODE_10GBASER: + default: + xsi_sel = AIROHA_SCU_PCIE_XSI1_USXGMII; + } + + regmap_update_bits(priv->scu, AIROHA_SCU_SSTR, + AIROHA_SCU_PCIE_XSI1_SEL, + xsi_sel); + } +} + +static int airoha_pcs_setup_scu(struct airoha_pcs_priv *priv, + int index, phy_interface_t interface) +{ + const struct airoha_pcs_match_data *data = priv->data; + int ret; + + switch (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; + case AIROHA_PCS_PCIE: + airoha_pcs_setup_scu_pcie(priv, index, interface); + break; + case AIROHA_PCS_USB: + break; + } + + /* TODO better handle reset from MAC */ + 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, int index) +{ + struct airoha_pcs_maps *maps = &priv->maps[index]; + + regmap_set_bits(maps->multi_sgmii, AIROHA_PCS_MULTI_SGMII_MSG_RX_CTRL_0, + AIROHA_PCS_HSGMII_XFI_SEL); + + /* Disable Hibernation */ + regmap_clear_bits(maps->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(maps->usxgmii_pcs, AIROHA_PCS_USGMII_VENDOR_DEFINE_116, 0); +} + +static void airoha_pcs_init_hsgmii(struct airoha_pcs_priv *priv, int index) +{ + struct airoha_pcs_maps *maps = &priv->maps[index]; + + regmap_clear_bits(maps->multi_sgmii, AIROHA_PCS_MULTI_SGMII_MSG_RX_CTRL_0, + AIROHA_PCS_HSGMII_XFI_SEL); + + regmap_update_bits(maps->hsgmii_pcs, AIROHA_PCS_HSGMII_PCS_CTROL_1, + AIROHA_PCS_TBI_10B_MODE, + priv->phy ? 0 : AIROHA_PCS_TBI_10B_MODE); +} + +static void airoha_pcs_init_sgmii(struct airoha_pcs_priv *priv, int index) +{ + struct airoha_pcs_maps *maps = &priv->maps[index]; + + regmap_clear_bits(maps->multi_sgmii, AIROHA_PCS_MULTI_SGMII_MSG_RX_CTRL_0, + AIROHA_PCS_HSGMII_XFI_SEL); + + regmap_set_bits(maps->hsgmii_pcs, AIROHA_PCS_HSGMII_PCS_CTROL_1, + AIROHA_PCS_TBI_10B_MODE); + + regmap_update_bits(maps->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(maps->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, + int index, phy_interface_t interface) +{ + switch (interface) { + case PHY_INTERFACE_MODE_SGMII: + case PHY_INTERFACE_MODE_1000BASEX: + airoha_pcs_init_sgmii(priv, index); + break; + case PHY_INTERFACE_MODE_2500BASEX: + airoha_pcs_init_hsgmii(priv, index); + break; + case PHY_INTERFACE_MODE_USXGMII: + case PHY_INTERFACE_MODE_10GBASER: + airoha_pcs_init_usxgmii(priv, index); + break; + default: + return; + } +} + +static void airoha_pcs_interrupt_init_sgmii(struct airoha_pcs_priv *priv, + int index) +{ + struct airoha_pcs_maps *maps = &priv->maps[index]; + + /* Disable every interrupt */ + regmap_clear_bits(maps->hsgmii_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(maps->hsgmii_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(maps->hsgmii_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, + int index) +{ + struct airoha_pcs_maps *maps = &priv->maps[index]; + + /* Disable every Interrupt */ + regmap_clear_bits(maps->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(maps->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(maps->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(maps->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(maps->usxgmii_pcs, AIROHA_PCS_USXGMII_PCS_CTRL_4, + AIROHA_PCS_USXGMII_LINK_DOWN_ST_INT_EN); + + /* Clear any pending interrupt */ + regmap_set_bits(maps->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(maps->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(maps->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, + int index, 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, index); + case PHY_INTERFACE_MODE_USXGMII: + case PHY_INTERFACE_MODE_10GBASER: + return airoha_pcs_interrupt_init_usxgmii(priv, index); + default: + return; + } +} + +static void airoha_pcs_get_state_sgmii(struct airoha_pcs_priv *priv, + unsigned int neg_mode, int index, + struct phylink_link_state *state) +{ + struct airoha_pcs_maps *maps = &priv->maps[index]; + u32 bmsr, lpa; + + regmap_read(maps->hsgmii_an, AIROHA_PCS_HSGMII_AN_SGMII_REG_AN_1, + &bmsr); + regmap_read(maps->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_hsgmii(struct airoha_pcs_priv *priv, int index, + struct phylink_link_state *state) +{ + struct airoha_pcs_maps *maps = &priv->maps[index]; + u32 bmsr; + + regmap_read(maps->hsgmii_an, AIROHA_PCS_HSGMII_AN_SGMII_REG_AN_1, + &bmsr); + + 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; + + state->link = !!(bmsr & BMSR_LSTATUS); + state->an_complete = !!(bmsr & BMSR_ANEGCOMPLETE); + state->speed = SPEED_2500; + state->duplex = DUPLEX_FULL; +} + +static void airoha_pcs_get_state_usxgmii(struct airoha_pcs_priv *priv, int index, + struct phylink_link_state *state) +{ + const struct airoha_pcs_match_data *data = priv->data; + struct airoha_pcs_maps *maps = &priv->maps[index]; + u32 an_done, lpa; + + /* Trigger HW workaround if needed. If an error is reported, + * consider link down and test again later. + */ + if (data->rxlock_workaround && data->rxlock_workaround(priv, index)) { + state->link = false; + return; + } + + /* Toggle AN Status */ + regmap_set_bits(maps->usxgmii_pcs, AIROHA_PCS_USXGMII_PCS_AN_CONTROL_6, + AIROHA_PCS_USXGMII_TOG_PCS_AUTONEG_STS); + regmap_clear_bits(maps->usxgmii_pcs, AIROHA_PCS_USXGMII_PCS_AN_CONTROL_6, + AIROHA_PCS_USXGMII_TOG_PCS_AUTONEG_STS); + + regmap_read(maps->usxgmii_pcs, AIROHA_PCS_USXGMII_PCS_AN_STATS_0, &lpa); + regmap_read(maps->usxgmii_pcs, AIROHA_PCS_USXGMII_PCS_AN_STATS_2, &an_done); + + state->link = !!(lpa & MDIO_USXGMII_LINK); + state->an_complete = !!(an_done & AIROHA_PCS_USXGMII_PCS_AN_COMPLETE); + + phylink_decode_usxgmii_word(state, lpa); +} + +static void airoha_pcs_get_state_10gbaser(struct airoha_pcs_priv *priv, int index, + struct phylink_link_state *state) +{ + struct airoha_pcs_maps *maps = &priv->maps[index]; + u32 status, curr_mode; + + /* Toggle AN Status */ + regmap_set_bits(maps->usxgmii_pcs, AIROHA_PCS_USXGMII_PCS_AN_CONTROL_6, + AIROHA_PCS_USXGMII_TOG_PCS_AUTONEG_STS); + regmap_clear_bits(maps->usxgmii_pcs, AIROHA_PCS_USXGMII_PCS_AN_CONTROL_6, + AIROHA_PCS_USXGMII_TOG_PCS_AUTONEG_STS); + + regmap_read(maps->usxgmii_pcs, AIROHA_PCS_USXGMII_BASE_R_10GB_T_PCS_STUS_1, + &status); + regmap_read(maps->usxgmii_pcs, AIROHA_PCS_USXGMII_PCS_AN_STATS_0, &curr_mode); + + state->link = !!(status & AIROHA_PCS_USXGMII_RX_LINK_STUS); + + switch (curr_mode & AIROHA_PCS_USXGMII_CUR_USXGMII_MODE) { + case AIROHA_PCS_USXGMII_CUR_USXGMII_MODE_10G: + state->speed = SPEED_10000; + break; + case AIROHA_PCS_USXGMII_CUR_USXGMII_MODE_5G: + state->speed = SPEED_5000; + break; + case AIROHA_PCS_USXGMII_CUR_USXGMII_MODE_2_5G: + state->speed = SPEED_2500; + break; + default: + state->speed = SPEED_UNKNOWN; + return; + } + + state->duplex = DUPLEX_FULL; +} + +static void airoha_pcs_get_state(struct phylink_pcs *pcs, + unsigned int neg_mode, + struct phylink_link_state *state) +{ + struct airoha_pcs_port *port = to_airoha_pcs_port(pcs); + struct airoha_pcs_priv *priv = port->priv; + + switch (state->interface) { + case PHY_INTERFACE_MODE_SGMII: + case PHY_INTERFACE_MODE_1000BASEX: + airoha_pcs_get_state_sgmii(priv, neg_mode, port->index, state); + break; + case PHY_INTERFACE_MODE_2500BASEX: + airoha_pcs_get_state_hsgmii(priv, port->index, state); + break; + case PHY_INTERFACE_MODE_USXGMII: + airoha_pcs_get_state_usxgmii(priv, port->index, state); + break; + case PHY_INTERFACE_MODE_10GBASER: + airoha_pcs_get_state_10gbaser(priv, port->index, 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_port *port = to_airoha_pcs_port(pcs); + struct airoha_pcs_priv *priv = port->priv; + const struct airoha_pcs_match_data *data; + struct airoha_pcs_maps *maps; + int index = port->index; + u32 rate_adapt; + int ret; + + maps = &priv->maps[port->index]; + priv->interface = interface; + data = priv->data; + + /* Apply Analog and Digital configuration for PCS */ + if (data->bringup) { + ret = data->bringup(priv, index, interface); + if (ret) + return ret; + } + + /* Set final configuration for various modes */ + airoha_pcs_init(priv, index, interface); + + /* Configure Interrupt for various modes */ + airoha_pcs_interrupt_init(priv, index, interface); + + rate_adapt = AIROHA_PCS_HSGMII_RATE_ADAPT_RX_EN | + AIROHA_PCS_HSGMII_RATE_ADAPT_TX_EN; + + if (interface == PHY_INTERFACE_MODE_SGMII) + rate_adapt |= AIROHA_PCS_HSGMII_RATE_ADAPT_RX_BYPASS | + AIROHA_PCS_HSGMII_RATE_ADAPT_TX_BYPASS; + + /* AN Auto Settings (Rate Adaptation) */ + regmap_update_bits(maps->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 (interface == PHY_INTERFACE_MODE_USXGMII) { + if (neg_mode == PHYLINK_PCS_NEG_INBAND_ENABLED) + regmap_set_bits(maps->usxgmii_pcs, + AIROHA_PCS_USXGMII_PCS_AN_CONTROL_0, + AIROHA_PCS_USXGMII_AN_ENABLE); + else + regmap_clear_bits(maps->usxgmii_pcs, + AIROHA_PCS_USXGMII_PCS_AN_CONTROL_0, + AIROHA_PCS_USXGMII_AN_ENABLE); + + regmap_clear_bits(maps->usxgmii_pcs, + AIROHA_PCS_USXGMII_PCS_AN_CONTROL_7, + AIROHA_PCS_USXGMII_RATE_UPDATE_MODE); + } else { + regmap_clear_bits(maps->usxgmii_pcs, + AIROHA_PCS_USXGMII_PCS_AN_CONTROL_0, + AIROHA_PCS_USXGMII_AN_ENABLE); + + regmap_set_bits(maps->usxgmii_pcs, + AIROHA_PCS_USXGMII_PCS_AN_CONTROL_7, + AIROHA_PCS_USXGMII_RATE_UPDATE_MODE); + } + } + + /* 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(maps->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(maps->hsgmii_rate_adp, + AIROHA_PCS_HSGMII_RATE_ADP_P0_CTRL_0, + AIROHA_PCS_HSGMII_P0_DIS_MII_MODE); + else + regmap_set_bits(maps->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) { + 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(maps->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(maps->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) { + if (neg_mode == PHYLINK_PCS_NEG_INBAND_ENABLED) { + int advertise = phylink_mii_c22_pcs_encode_advertisement(interface, + advertising); + if (advertise < 0) + return advertise; + + regmap_update_bits(maps->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)); + + regmap_set_bits(maps->hsgmii_an, AIROHA_PCS_HSGMII_AN_SGMII_REG_AN_0, + AIROHA_PCS_HSGMII_AN_SGMII_RA_ENABLE); + } else { + regmap_clear_bits(maps->hsgmii_an, AIROHA_PCS_HSGMII_AN_SGMII_REG_AN_0, + AIROHA_PCS_HSGMII_AN_SGMII_RA_ENABLE); + } + } + + if (interface == PHY_INTERFACE_MODE_2500BASEX) { + regmap_clear_bits(maps->hsgmii_an, AIROHA_PCS_HSGMII_AN_SGMII_REG_AN_0, + AIROHA_PCS_HSGMII_AN_SGMII_RA_ENABLE); + + regmap_set_bits(maps->hsgmii_pcs, AIROHA_PCS_HSGMII_PCS_CTROL_6, + AIROHA_PCS_HSGMII_PCS_TX_ENABLE); + } + + if (interface == PHY_INTERFACE_MODE_SGMII || + interface == PHY_INTERFACE_MODE_1000BASEX) { + u32 if_mode = AIROHA_PCS_HSGMII_AN_SIDEBAND_EN; + + /* Toggle SGMII or 1000base-x mode */ + if (interface == PHY_INTERFACE_MODE_SGMII) + if_mode |= AIROHA_PCS_HSGMII_AN_SGMII_EN; + + if (neg_mode & PHYLINK_PCS_NEG_INBAND) + regmap_set_bits(maps->hsgmii_an, AIROHA_PCS_HSGMII_AN_SGMII_REG_AN_13, + AIROHA_PCS_HSGMII_AN_SGMII_REMOTE_FAULT_DIS); + else + regmap_clear_bits(maps->hsgmii_an, AIROHA_PCS_HSGMII_AN_SGMII_REG_AN_13, + AIROHA_PCS_HSGMII_AN_SGMII_REMOTE_FAULT_DIS); + + if (neg_mode == PHYLINK_PCS_NEG_INBAND_ENABLED) { + /* Clear force speed bits and MAC mode */ + regmap_clear_bits(maps->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 { + /* Enable compatibility with MAC PCS Layer */ + if_mode |= AIROHA_PCS_HSGMII_AN_SGMII_COMPAT_EN; + + /* AN off force rate adaption, speed is set later in Link Up */ + regmap_set_bits(maps->hsgmii_pcs, AIROHA_PCS_HSGMII_PCS_CTROL_6, + AIROHA_PCS_HSGMII_PCS_MAC_MODE | + AIROHA_PCS_HSGMII_PCS_FORCE_RATEADAPT); + } + + regmap_update_bits(maps->hsgmii_an, AIROHA_PCS_HSGMII_AN_SGMII_REG_AN_13, + AIROHA_PCS_HSGMII_AN_SGMII_IF_MODE_5_0, if_mode); + + regmap_set_bits(maps->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(maps->hsgmii_pcs, AIROHA_PCS_HSGMII_PCS_CTROL_1, + AIROHA_PCS_SGMII_SEND_AN_ERR_EN); + + regmap_set_bits(maps->hsgmii_pcs, AIROHA_PCS_HSGMII_AN_SGMII_REG_AN_FORCE_CL37, + AIROHA_PCS_HSGMII_AN_FORCE_AN_DONE); + } + + if (interface == PHY_INTERFACE_MODE_2500BASEX) { + regmap_set_bits(maps->hsgmii_an, AIROHA_PCS_HSGMII_AN_SGMII_REG_AN_0, + AIROHA_PCS_HSGMII_AN_SGMII_RESET_PHY); + } + + /* Configure Flow Control on XFI */ + regmap_update_bits(maps->pcs_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_port *port = to_airoha_pcs_port(pcs); + struct airoha_pcs_priv *priv = port->priv; + struct airoha_pcs_maps *maps; + + maps = &priv->maps[port->index]; + + switch (priv->interface) { + case PHY_INTERFACE_MODE_SGMII: + case PHY_INTERFACE_MODE_1000BASEX: + case PHY_INTERFACE_MODE_2500BASEX: + regmap_set_bits(maps->hsgmii_an, AIROHA_PCS_HSGMII_AN_SGMII_REG_AN_0, + AIROHA_PCS_HSGMII_AN_SGMII_AN_RESTART); + udelay(3); + regmap_clear_bits(maps->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(maps->usxgmii_pcs, AIROHA_PCS_USXGMII_PCS_AN_CONTROL_0, + AIROHA_PCS_USXGMII_AN_RESTART); + udelay(3); + regmap_clear_bits(maps->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_port *port = to_airoha_pcs_port(pcs); + struct airoha_pcs_priv *priv = port->priv; + const struct airoha_pcs_match_data *data; + struct airoha_pcs_maps *maps; + + maps = &priv->maps[port->index]; + data = priv->data; + + if (neg_mode == PHYLINK_PCS_NEG_INBAND_ENABLED) { + if (interface == PHY_INTERFACE_MODE_SGMII) { + regmap_update_bits(maps->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(maps->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; + } + + /* Force USXGMII to selected speed */ + regmap_update_bits(maps->usxgmii_pcs, AIROHA_PCS_USXGMII_PCS_AN_CONTROL_7, + AIROHA_PCS_USXGMII_MODE, mode); + + if (interface == PHY_INTERFACE_MODE_10GBASER) + regmap_update_bits(maps->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(maps->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(maps->hsgmii_an, AIROHA_PCS_HSGMII_AN_SGMII_REG_AN_13, + AIROHA_PCS_HSGMII_AN_SPEED_FORCE_MODE, + if_mode); + + regmap_update_bits(maps->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(maps->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); + } + } + + if (data->link_up) + data->link_up(priv, port->index); + + /* BPI BMI enable */ + regmap_clear_bits(maps->pcs_mac, AIROHA_PCS_XFI_MAC_XFI_GIB_CFG, + AIROHA_PCS_XFI_RXMPI_STOP | + AIROHA_PCS_XFI_RXMBI_STOP | + AIROHA_PCS_XFI_TXMPI_STOP | + AIROHA_PCS_XFI_TXMBI_STOP); +} + +static void airoha_pcs_link_down(struct phylink_pcs *pcs) +{ + struct airoha_pcs_port *port = to_airoha_pcs_port(pcs); + struct airoha_pcs_priv *priv = port->priv; + struct airoha_pcs_maps *maps; + + maps = &priv->maps[port->index]; + + /* MPI MBI disable */ + regmap_set_bits(maps->pcs_mac, AIROHA_PCS_XFI_MAC_XFI_GIB_CFG, + AIROHA_PCS_XFI_RXMPI_STOP | + AIROHA_PCS_XFI_RXMBI_STOP | + AIROHA_PCS_XFI_TXMPI_STOP | + AIROHA_PCS_XFI_TXMBI_STOP); +} + +static void airoha_pcs_pre_config(struct phylink_pcs *pcs, + phy_interface_t interface) +{ + struct airoha_pcs_port *port = to_airoha_pcs_port(pcs); + struct airoha_pcs_priv *priv = port->priv; + struct airoha_pcs_maps *maps; + + maps = &priv->maps[port->index]; + + /* Select HSGMII or USXGMII in SCU regs */ + airoha_pcs_setup_scu(priv, port->index, interface); + + /* MPI MBI disable */ + regmap_set_bits(maps->pcs_mac, AIROHA_PCS_XFI_MAC_XFI_GIB_CFG, + AIROHA_PCS_XFI_RXMPI_STOP | + AIROHA_PCS_XFI_RXMBI_STOP | + AIROHA_PCS_XFI_TXMPI_STOP | + AIROHA_PCS_XFI_TXMBI_STOP); + + /* Write 1 to trigger reset and clear */ + regmap_clear_bits(maps->pcs_mac, AIROHA_PCS_XFI_MAC_XFI_LOGIC_RST, + AIROHA_PCS_XFI_MAC_LOGIC_RST); + regmap_set_bits(maps->pcs_mac, AIROHA_PCS_XFI_MAC_XFI_LOGIC_RST, + AIROHA_PCS_XFI_MAC_LOGIC_RST); + + usleep_range(1000, 2000); + + /* Clear XFI MAC counter */ + regmap_set_bits(maps->pcs_mac, AIROHA_PCS_XFI_MAC_XFI_CNT_CLR, + AIROHA_PCS_XFI_GLB_CNT_CLR); +} + +static int airoha_pcs_post_config(struct phylink_pcs *pcs, + phy_interface_t interface) +{ + struct airoha_pcs_port *port = to_airoha_pcs_port(pcs); + struct airoha_pcs_priv *priv = port->priv; + struct airoha_pcs_maps *maps; + + maps = &priv->maps[port->index]; + + /* Frag disable */ + regmap_update_bits(maps->pcs_mac, AIROHA_PCS_XFI_MAC_XFI_GIB_CFG, + AIROHA_PCS_XFI_RX_FRAG_LEN, + FIELD_PREP(AIROHA_PCS_XFI_RX_FRAG_LEN, 31)); + regmap_update_bits(maps->pcs_mac, AIROHA_PCS_XFI_MAC_XFI_GIB_CFG, + AIROHA_PCS_XFI_TX_FRAG_LEN, + FIELD_PREP(AIROHA_PCS_XFI_TX_FRAG_LEN, 31)); + + /* IPG NUM */ + regmap_update_bits(maps->pcs_mac, AIROHA_PCS_XFI_MAC_XFI_GIB_CFG, + AIROHA_PCS_XFI_IPG_NUM, + FIELD_PREP(AIROHA_PCS_XFI_IPG_NUM, 10)); + + /* Enable TX/RX flow control */ + regmap_set_bits(maps->pcs_mac, AIROHA_PCS_XFI_MAC_XFI_GIB_CFG, + AIROHA_PCS_XFI_TX_FC_EN); + regmap_set_bits(maps->pcs_mac, AIROHA_PCS_XFI_MAC_XFI_GIB_CFG, + AIROHA_PCS_XFI_RX_FC_EN); + + return 0; +} + +static unsigned int airoha_pcs_inband_caps(struct phylink_pcs *pcs, + phy_interface_t interface) +{ + return LINK_INBAND_ENABLE | LINK_INBAND_DISABLE; +} + +static const struct phylink_pcs_ops airoha_pcs_ops = { + .pcs_inband_caps = airoha_pcs_inband_caps, + .pcs_pre_config = airoha_pcs_pre_config, + .pcs_post_config = airoha_pcs_post_config, + .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, + .pcs_link_down = airoha_pcs_link_down, +}; + +static int airoha_pcs_init_named_regmap(struct platform_device *pdev, + const char *name, struct regmap **regmap) +{ + struct regmap_config regmap_config = { }; + void *base; + + base = devm_platform_ioremap_resource_byname(pdev, name); + if (IS_ERR(base)) + return PTR_ERR(base); + + regmap_config.name = name; + regmap_config.reg_bits = 32, + regmap_config.val_bits = 32, + regmap_config.reg_stride = 4, + + *regmap = devm_regmap_init_mmio(&pdev->dev, base, ®map_config); + + return PTR_ERR_OR_ZERO(*regmap); +} + +static int airoha_pcs_alloc_maps(struct platform_device *pdev, + struct airoha_pcs_priv *priv) +{ + struct airoha_pcs_maps *maps = &priv->maps[0]; + int ret; + + ret = airoha_pcs_init_named_regmap(pdev, "pcs_mac", &maps->pcs_mac); + if (ret) + return ret; + + ret = airoha_pcs_init_named_regmap(pdev, "hsgmii_an", &maps->hsgmii_an); + if (ret) + return ret; + + ret = airoha_pcs_init_named_regmap(pdev, "hsgmii_pcs", &maps->hsgmii_pcs); + if (ret) + return ret; + + ret = airoha_pcs_init_named_regmap(pdev, "hsgmii_rate_adp", &maps->hsgmii_rate_adp); + if (ret) + return ret; + + ret = airoha_pcs_init_named_regmap(pdev, "multi_sgmii", &maps->multi_sgmii); + if (ret) + return ret; + + ret = airoha_pcs_init_named_regmap(pdev, "usxgmii", &maps->usxgmii_pcs); + if (ret) + return ret; + + ret = airoha_pcs_init_named_regmap(pdev, "pcs_pma", &priv->pcs_pma[0]); + if (ret) + return ret; + + return airoha_pcs_init_named_regmap(pdev, "pcs_ana", &priv->pcs_ana); +} + +static int airoha_pcs_usb_alloc_maps(struct platform_device *pdev, + struct airoha_pcs_priv *priv) +{ + struct airoha_pcs_maps *maps = &priv->maps[0]; + int ret; + + ret = airoha_pcs_init_named_regmap(pdev, "pcs_mac", &maps->pcs_mac); + if (ret) + return ret; + + ret = airoha_pcs_init_named_regmap(pdev, "hsgmii_an", &maps->hsgmii_an); + if (ret) + return ret; + + ret = airoha_pcs_init_named_regmap(pdev, "hsgmii_pcs", &maps->hsgmii_pcs); + if (ret) + return ret; + + ret = airoha_pcs_init_named_regmap(pdev, "hsgmii_rate_adp", &maps->hsgmii_rate_adp); + if (ret) + return ret; + + ret = airoha_pcs_init_named_regmap(pdev, "multi_sgmii", &maps->multi_sgmii); + if (ret) + return ret; + + return airoha_pcs_init_named_regmap(pdev, "pcs_ana", &priv->pcs_ana); +} + +static int airoha_pcs_pcie_alloc_maps(struct platform_device *pdev, + struct airoha_pcs_priv *priv) +{ + struct airoha_pcs_maps *maps = priv->maps; + int ret; + + ret = airoha_pcs_init_named_regmap(pdev, "pcs_mac0", &maps[0].pcs_mac); + if (ret) + return ret; + + ret = airoha_pcs_init_named_regmap(pdev, "hsgmii_an0", &maps[0].hsgmii_an); + if (ret) + return ret; + + ret = airoha_pcs_init_named_regmap(pdev, "hsgmii_pcs0", &maps[0].hsgmii_pcs); + if (ret) + return ret; + + ret = airoha_pcs_init_named_regmap(pdev, "hsgmii_rate_adp0", &maps[0].hsgmii_rate_adp); + if (ret) + return ret; + + ret = airoha_pcs_init_named_regmap(pdev, "multi_sgmii0", &maps[0].multi_sgmii); + if (ret) + return ret; + + ret = airoha_pcs_init_named_regmap(pdev, "usxgmii0", &maps[0].usxgmii_pcs); + if (ret) + return ret; + + ret = airoha_pcs_init_named_regmap(pdev, "pcs_mac1", &maps[1].pcs_mac); + if (ret) + return ret; + + ret = airoha_pcs_init_named_regmap(pdev, "hsgmii_an1", &maps[1].hsgmii_an); + if (ret) + return ret; + + ret = airoha_pcs_init_named_regmap(pdev, "hsgmii_pcs1", &maps[1].hsgmii_pcs); + if (ret) + return ret; + + ret = airoha_pcs_init_named_regmap(pdev, "hsgmii_rate_adp1", &maps[1].hsgmii_rate_adp); + if (ret) + return ret; + + ret = airoha_pcs_init_named_regmap(pdev, "multi_sgmii1", &maps[1].multi_sgmii); + if (ret) + return ret; + + ret = airoha_pcs_init_named_regmap(pdev, "usxgmii1", &maps[1].usxgmii_pcs); + if (ret) + return ret; + + ret = airoha_pcs_init_named_regmap(pdev, "pcs_pma0", &priv->pcs_pma[0]); + if (ret) + return ret; + + ret = airoha_pcs_init_named_regmap(pdev, "pcs_pma1", &priv->pcs_pma[1]); + if (ret) + return ret; + + return airoha_pcs_init_named_regmap(pdev, "pcs_ana", &priv->pcs_ana); +} + +static struct phylink_pcs *airoha_pcs_get(struct fwnode_reference_args *pcsspec, + void *data) +{ + struct airoha_pcs_priv *priv = data; + struct device *dev = priv->dev; + int index = 0; + + switch (priv->data->port_type) { + case AIROHA_PCS_ETH: + case AIROHA_PCS_PON: + case AIROHA_PCS_USB: + if (pcsspec->nargs) { + dev_err(dev, "invalid number of cells in 'pcs' property\n"); + return ERR_PTR(-EINVAL); + } + + break; + case AIROHA_PCS_PCIE: + if (pcsspec->nargs != 1) { + dev_err(dev, "invalid number of cells in 'pcs' property\n"); + return ERR_PTR(-EINVAL); + } + + break; + } + + if (pcsspec->nargs) + index = pcsspec->args[0]; + + return &priv->ports[index].pcs; +} + +static int airoha_pcs_probe(struct platform_device *pdev) +{ + const struct airoha_pcs_match_data *data; + struct device *dev = &pdev->dev; + struct airoha_pcs_priv *priv; + int index, ret; + + data = of_device_get_match_data(dev); + + priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL); + if (!priv) + return -ENOMEM; + + priv->ports = devm_kcalloc(dev, data->num_port, + sizeof(*priv->ports), GFP_KERNEL); + if (!priv->ports) + return -ENOMEM; + + priv->dev = dev; + priv->data = data; + + if (data->port_type == AIROHA_PCS_USB) { + struct phy *phy; + + phy = devm_phy_get(dev, NULL); + if (IS_ERR(phy)) + return dev_err_probe(dev, PTR_ERR(phy), "failed to get phy\n"); + + priv->phy = phy; + } + + switch (data->port_type) { + case AIROHA_PCS_ETH: + case AIROHA_PCS_PON: + ret = airoha_pcs_alloc_maps(pdev, priv); + if (ret) + return ret; + + break; + case AIROHA_PCS_PCIE: + ret = airoha_pcs_pcie_alloc_maps(pdev, priv); + if (ret) + return ret; + + break; + case AIROHA_PCS_USB: + ret = airoha_pcs_usb_alloc_maps(pdev, priv); + if (ret) + return ret; + + break; + } + + if (data->alloc_regmap_fields) { + ret = data->alloc_regmap_fields(priv); + if (ret) + return ret; + } + + /* SCU is used to toggle XFI or HSGMII in global SoC registers */ + if (!priv->phy) { + priv->scu = syscon_regmap_lookup_by_phandle(dev->of_node, "airoha,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_optional_exclusive(dev, ARRAY_SIZE(priv->rsts), + priv->rsts); + if (ret) + return dev_err_probe(dev, ret, "failed to get bulk reset lines\n"); + + /* For Ethernet PCS, read the AN7581 SoC revision to check if + * manual rx calibration is needed. This is only limited to + * any SoC revision before E2. + */ + if (device_is_compatible(dev, "airoha,an7581-pcs-eth")) { + u32 val; + + ret = regmap_read(priv->scu, AIROHA_SCU_PDIDR, &val); + if (ret) + return ret; + + if (FIELD_GET(AIROHA_SCU_PRODUCT_ID, val) < 0x2) + priv->manual_rx_calib = true; + } + + for (index = 0; index < data->num_port; index++) { + struct airoha_pcs_port *port = &priv->ports[index]; + + port->priv = priv; + port->index = index; + port->pcs.poll = true; + port->pcs.ops = &airoha_pcs_ops; + + switch (data->port_type) { + case AIROHA_PCS_ETH: + case AIROHA_PCS_PON: + case AIROHA_PCS_PCIE: + __set_bit(PHY_INTERFACE_MODE_10GBASER, + port->pcs.supported_interfaces); + __set_bit(PHY_INTERFACE_MODE_USXGMII, + port->pcs.supported_interfaces); + fallthrough; + case AIROHA_PCS_USB: + __set_bit(PHY_INTERFACE_MODE_SGMII, + port->pcs.supported_interfaces); + __set_bit(PHY_INTERFACE_MODE_1000BASEX, + port->pcs.supported_interfaces); + __set_bit(PHY_INTERFACE_MODE_2500BASEX, + port->pcs.supported_interfaces); + break; + } + } + + platform_set_drvdata(pdev, priv); + + return fwnode_pcs_add_provider(dev_fwnode(dev), airoha_pcs_get, + &priv); +} + +static void airoha_pcs_remove(struct platform_device *pdev) +{ + struct airoha_pcs_priv *priv = platform_get_drvdata(pdev); + const struct airoha_pcs_match_data *data = priv->data; + int i; + + fwnode_pcs_del_provider(dev_fwnode(&pdev->dev)); + + rtnl_lock(); + + for (i = 0; i < data->num_port; i++) { + struct airoha_pcs_port *port = &priv->ports[i]; + + phylink_release_pcs(&port->pcs); + } + + rtnl_unlock(); +} + +static const struct airoha_pcs_match_data an7581_pcs_eth = { + .num_port = 1, + .port_type = AIROHA_PCS_ETH, + .alloc_regmap_fields = an7581_pcs_alloc_regmap_fields, + .bringup = an7581_pcs_bringup, + .link_up = an7581_pcs_phya_link_up, + .rxlock_workaround = an7581_pcs_rxlock_workaround, +}; + +static const struct airoha_pcs_match_data an7581_pcs_pon = { + .num_port = 1, + .port_type = AIROHA_PCS_PON, + .alloc_regmap_fields = an7581_pcs_alloc_regmap_fields, + .bringup = an7581_pcs_bringup, + .link_up = an7581_pcs_phya_link_up, +}; + +static const struct airoha_pcs_match_data an7581_pcs_pcie = { + .num_port = 2, + .port_type = AIROHA_PCS_PCIE, + .alloc_regmap_fields = an7581_pcs_pcie_alloc_regmap_fields, + .bringup = an7581_pcs_bringup, + .link_up = an7581_pcs_phya_link_up, +}; + +static const struct airoha_pcs_match_data an7581_pcs_usb = { + .num_port = 1, + .port_type = AIROHA_PCS_USB, + .bringup = an7581_pcs_usb_bringup, +}; + +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 }, + { .compatible = "airoha,an7581-pcs-pcie", .data = &an7581_pcs_pcie }, + { .compatible = "airoha,an7581-pcs-usb", .data = &an7581_pcs_usb }, + { /* 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 "); diff --git a/drivers/net/pcs/airoha/pcs-airoha.h b/drivers/net/pcs/airoha/pcs-airoha.h new file mode 100644 index 000000000000..aac2521caf4e --- /dev/null +++ b/drivers/net/pcs/airoha/pcs-airoha.h @@ -0,0 +1,1309 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * Copyright (c) 2024 AIROHA Inc + * Author: Christian Marangi + */ + +#include +#include +#include +#include +#include + +/* SCU*/ +#define AIROHA_SCU_PDIDR 0x5c +#define AIROHA_SCU_PRODUCT_ID GENMASK(15, 0) +#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_PCIE_XSI0_SEL GENMASK(14, 13) +#define AIROHA_SCU_PCIE_XSI0_USXGMII FIELD_PREP_CONST(AIROHA_SCU_PCIE_XSI0_SEL, 0x1) +#define AIROHA_SCU_PCIE_XSI0_HSGMII FIELD_PREP_CONST(AIROHA_SCU_PCIE_XSI0_SEL, 0x2) +#define AIROHA_SCU_PCIE_XSI1_SEL GENMASK(12, 11) +#define AIROHA_SCU_PCIE_XSI1_USXGMII FIELD_PREP_CONST(AIROHA_SCU_PCIE_XSI1_SEL, 0x1) +#define AIROHA_SCU_PCIE_XSI1_HSGMII FIELD_PREP_CONST(AIROHA_SCU_PCIE_XSI1_SEL, 0x2) +#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) + +/* XFI_MAC */ +#define AIROHA_PCS_XFI_MAC_XFI_GIB_CFG 0x0 +#define AIROHA_PCS_XFI_RX_FRAG_LEN GENMASK(26, 22) +#define AIROHA_PCS_XFI_TX_FRAG_LEN GENMASK(21, 17) +#define AIROHA_PCS_XFI_IPG_NUM GENMASK(15, 10) +#define AIROHA_PCS_XFI_TX_FC_EN BIT(5) +#define AIROHA_PCS_XFI_RX_FC_EN BIT(4) +#define AIROHA_PCS_XFI_RXMPI_STOP BIT(3) +#define AIROHA_PCS_XFI_RXMBI_STOP BIT(2) +#define AIROHA_PCS_XFI_TXMPI_STOP BIT(1) +#define AIROHA_PCS_XFI_TXMBI_STOP BIT(0) +#define AIROHA_PCS_XFI_MAC_XFI_LOGIC_RST 0x10 +#define AIROHA_PCS_XFI_MAC_LOGIC_RST BIT(0) +#define AIROHA_PCS_XFI_MAC_XFI_MACADDRH 0x60 +#define AIROHA_PCS_XFI_MAC_MACADDRH GENMASK(15, 0) +#define AIROHA_PCS_XFI_MAC_XFI_MACADDRL 0x64 +#define AIROHA_PCS_XFI_MAC_MACADDRL GENMASK(31, 0) +#define AIROHA_PCS_XFI_MAC_XFI_CNT_CLR 0x100 +#define AIROHA_PCS_XFI_GLB_CNT_CLR BIT(0) + +/* HSGMII_AN */ +#define AIROHA_PCS_HSGMII_AN_SGMII_REG_AN_0 0x0 +#define AIROHA_PCS_HSGMII_AN_SGMII_RESET_PHY BIT(15) +#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) + +/* HSGMII_ANA */ +#define AIROHA_PCS_HSGMII_ANA_SGMII_PHYA_6 0x18 +#define AIROHA_PCS_HSGMII_ANA_FORCE_CDR_BIC BIT(20) +#define AIROHA_PCS_HSGMII_ANA_SGMII_PHYA_8 0x20 +#define AIROHA_PCS_HSGMII_ANA_SSUSB_CDR_BICLTR GENMASK(11, 8) +#define AIROHA_PCS_HSGMII_ANA_SSUSB_CDR_BICLTD1 GENMASK(7, 4) +#define AIROHA_PCS_HSGMII_ANA_SSUSB_CDR_BICLTD0 GENMASK(3, 0) +#define AIROHA_PCS_HSGMII_ANA_SGMII_PHYA_11 0x2c +#define AIROHA_PCS_HSGMII_ANA_TPHY_SPEED GENMASK(3, 2) +#define AIROHA_PCS_HSGMII_ANA_TPHY_SPEED_SGMII FIELD_PREP_CONST(AIROHA_PCS_HSGMII_ANA_TPHY_SPEED, 0x0) +#define AIROHA_PCS_HSGMII_ANA_TPHY_SPEED_HSGMII FIELD_PREP_CONST(AIROHA_PCS_HSGMII_ANA_TPHY_SPEED, 0x1) +#define AIROHA_PCS_HSGMII_ANA_TPHY_MODE GENMASK(1, 0) +#define AIROHA_PCS_HSGMII_ANA_SGMII_PHYA_18 0x48 +#define AIROHA_PCS_HSGMII_ANA_SSUSB_BG_DIV GENMASK(28, 27) +#define AIROHA_PCS_HSGMII_ANA_SGMII_PHYA_19 0x4c +#define AIROHA_PCS_HSGMII_ANA_SSUSB_XTAL_TOP_RESERVE GENMASK(25, 10) +#define AIROHA_PCS_HSGMII_ANA_SSUSB_XTAL_TOP_RESERVE_HV GENMASK(15, 8) +#define AIROHA_PCS_HSGMII_ANA_SSUSB_XTAL_TOP_RESERVE_LV GENMASK(7, 0) +#define AIROHA_PCS_HSGMII_ANA_SSUSB_XTAL_TOP_RESERVE_MONCKBG GENMASK(2, 0) +#define AIROHA_PCS_HSGMII_ANA_SSUSB_XTAL_TOP_RESERVE_GND FIELD_PREP_CONST(AIROHA_PCS_HSGMII_ANA_SSUSB_XTAL_TOP_RESERVE_MONCKBG, 0x0) +#define AIROHA_PCS_HSGMII_ANA_SSUSB_XTAL_TOP_RESERVE_NS_MONFBK_CK FIELD_PREP_CONST(AIROHA_PCS_HSGMII_ANA_SSUSB_XTAL_TOP_RESERVE_MONCKBG, 0x1) +#define AIROHA_PCS_HSGMII_ANA_SSUSB_XTAL_TOP_RESERVE_NS_MONPLL_CK FIELD_PREP_CONST(AIROHA_PCS_HSGMII_ANA_SSUSB_XTAL_TOP_RESERVE_MONCKBG, 0x2) +#define AIROHA_PCS_HSGMII_ANA_SSUSB_XTAL_TOP_RESERVE_NS_MONREF_CK FIELD_PREP_CONST(AIROHA_PCS_HSGMII_ANA_SSUSB_XTAL_TOP_RESERVE_MONCKBG, 0x3) +#define AIROHA_PCS_HSGMII_ANA_SSUSB_XTAL_TOP_RESERVE_NS_SSUSB_SYSPLL_CKMON FIELD_PREP_CONST(AIROHA_PCS_HSGMII_ANA_SSUSB_XTAL_TOP_RESERVE_MONCKBG, 0x4) +#define AIROHA_PCS_HSGMII_ANA_SSUSB_XTAL_TOP_RESERVE_NS_SSUSB_SYSPLL_FBCKMON FIELD_PREP_CONST(AIROHA_PCS_HSGMII_ANA_SSUSB_XTAL_TOP_RESERVE_MONCKBG, 0x5) +#define AIROHA_PCS_HSGMII_ANA_SSUSB_XTAL_TOP_RESERVE_TX2500M_A FIELD_PREP_CONST(AIROHA_PCS_HSGMII_ANA_SSUSB_XTAL_TOP_RESERVE_MONCKBG, 0x6) +#define AIROHA_PCS_HSGMII_ANA_SSUSB_XTAL_TOP_RESERVE_NS_SSUSB_CDR_250M_CK FIELD_PREP_CONST(AIROHA_PCS_HSGMII_ANA_SSUSB_XTAL_TOP_RESERVE_MONCKBG, 0x7) +#define AIROHA_PCS_HSGMII_ANA_SGMII_PHYA_24 0x60 +#define AIROHA_PCS_HSGMII_ANA_SSUSB_LN0_CDR_RESERVE GENMASK(31, 24) +#define AIROHA_PCS_HSGMII_ANA_SGMII_PHYA_26 0x68 +#define AIROHA_PCS_HSGMII_ANA_SSUSB_LN0_CDR_RST_DLY GENMASK(7, 6) +#define AIROHA_PCS_HSGMII_ANA_SSUSB_LN0_CDR_RST_DLY_32 FIELD_PREP_CONST(AIROHA_PCS_HSGMII_ANA_SSUSB_LN0_CDR_RST_DLY, 0x0) +#define AIROHA_PCS_HSGMII_ANA_SSUSB_LN0_CDR_RST_DLY_64 FIELD_PREP_CONST(AIROHA_PCS_HSGMII_ANA_SSUSB_LN0_CDR_RST_DLY, 0x1) +#define AIROHA_PCS_HSGMII_ANA_SSUSB_LN0_CDR_RST_DLY_128 FIELD_PREP_CONST(AIROHA_PCS_HSGMII_ANA_SSUSB_LN0_CDR_RST_DLY, 0x2) +#define AIROHA_PCS_HSGMII_ANA_SSUSB_LN0_CDR_RST_DLY_216 FIELD_PREP_CONST(AIROHA_PCS_HSGMII_ANA_SSUSB_LN0_CDR_RST_DLY, 0x3) + +/* 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 0x4 +#define AIROHA_PCS_USXGMII_PCS_RX_LINK_STATUS BIT(2) +#define AIROHA_PCS_USXGMII_PCS_RX_LINK_STATUS_UP \ + FIELD_PREP_CONST(AIROHA_PCS_USXGMII_PCS_RX_LINK_STATUS, 0x1) +#define AIROHA_PCS_USXGMII_PCS_RX_LINK_STATUS_DOWN \ + FIELD_PREP_CONST(AIROHA_PCS_USXGMII_PCS_RX_LINK_STATUS, 0x0) +#define AIROHA_PCS_USXGMII_BASE_R_10GB_T_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_CONST(AIROHA_PCS_USXGMII_MODE, 0x0) +#define AIROHA_PCS_USXGMII_MODE_5000 FIELD_PREP_CONST(AIROHA_PCS_USXGMII_MODE, 0x1) +#define AIROHA_PCS_USXGMII_MODE_2500 FIELD_PREP_CONST(AIROHA_PCS_USXGMII_MODE, 0x2) +#define AIROHA_PCS_USXGMII_MODE_1000 FIELD_PREP_CONST(AIROHA_PCS_USXGMII_MODE, 0x3) +#define AIROHA_PCS_USXGMII_MODE_100 FIELD_PREP_CONST(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 0x0 +#define AIROHA_PCS_ANA_JCPLL_MMD_PREDIV_MODE_3 0x1 +#define AIROHA_PCS_ANA_JCPLL_MMD_PREDIV_MODE_4 0x2 +#define AIROHA_PCS_ANA_JCPLL_MMD_PREDIV_MODE_1 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 0x0 +#define AIROHA_PCS_ANA_JCPLL_SDM_DI_LS_2_21 0x1 +#define AIROHA_PCS_ANA_JCPLL_SDM_DI_LS_2_19 0x2 +#define AIROHA_PCS_ANA_JCPLL_SDM_DI_LS_2_15 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 0x1 +#define AIROHA_PCS_ANA_JCPLL_RST_DLY_40_50 0x2 +#define AIROHA_PCS_ANA_JCPLL_RST_DLY_80_100 0x3 +#define AIROHA_PCS_ANA_JCPLL_RST_DLY_150_200 0x4 +#define AIROHA_PCS_ANA_JCPLL_RST_DLY_300_400 0x5 +#define AIROHA_PCS_ANA_JCPLL_RST_DLY_600_800 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 0x0 +#define AIROHA_PCS_ANA_JCPLL_SDM_ORD_1SDM 0x1 +#define AIROHA_PCS_ANA_JCPLL_SDM_ORD_2SDM 0x2 +#define AIROHA_PCS_ANA_JCPLL_SDM_ORD_3SDM 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 0x0 +#define AIROHA_PCS_ANA_JCPLL_TCL_AMP_GAIN_4 0x1 +#define AIROHA_PCS_ANA_JCPLL_TCL_AMP_GAIN_6 0x2 +#define AIROHA_PCS_ANA_JCPLL_TCL_AMP_GAIN_8 0x3 +#define AIROHA_PCS_ANA_JCPLL_TCL_AMP_GAIN_10 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 0x0 +#define AIROHA_PCS_ANA_JCPLL_TCL_LPF_BW_1 0x1 +#define AIROHA_PCS_ANA_JCPLL_TCL_LPF_BW_2 0x2 +#define AIROHA_PCS_ANA_JCPLL_TCL_LPF_BW_4 0x3 +#define AIROHA_PCS_ANA_JCPLL_TCL_LPF_BW_8 0x4 +#define AIROHA_PCS_ANA_JCPLL_TCL_LPF_BW_16 0x6 +#define AIROHA_PCS_ANA_JCPLL_TCL_LPF_EN BIT(16) +#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 0x0 +#define AIROHA_PCS_ANA_JCPLL_VCODIV_2 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 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 0x0 +#define AIROHA_PCS_ANA_TXPLL_MMD_PREDIV_MODE_3 0x1 +#define AIROHA_PCS_ANA_TXPLL_MMD_PREDIV_MODE_4 0x2 +#define AIROHA_PCS_ANA_TXPLL_MMD_PREDIV_MODE_1 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 0x0 +#define AIROHA_PCS_ANA_TXPLL_REFIN_DIV_2 0x1 +#define AIROHA_PCS_ANA_TXPLL_REFIN_DIV_3 0x2 +#define AIROHA_PCS_ANA_TXPLL_REFIN_DIV_4 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 0x0 +#define AIROHA_PCS_ANA_TXPLL_SDM_DI_LS_2_21 0x1 +#define AIROHA_PCS_ANA_TXPLL_SDM_DI_LS_2_19 0x2 +#define AIROHA_PCS_ANA_TXPLL_SDM_DI_LS_2_15 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 0x0 +#define AIROHA_PCS_ANA_TXPLL_SDM_ORD_1SDM 0x1 +#define AIROHA_PCS_ANA_TXPLL_SDM_ORD_2SDM 0x2 +#define AIROHA_PCS_ANA_TXPLL_SDM_ORD_3SDM 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 0x0 +#define AIROHA_PCS_ANA_TXPLL_TCL_AMP_GAIN_2_5 0x1 +#define AIROHA_PCS_ANA_TXPLL_TCL_AMP_GAIN_3 0x2 +#define AIROHA_PCS_ANA_TXPLL_TCL_AMP_GAIN_4 0x3 +#define AIROHA_PCS_ANA_TXPLL_TCL_AMP_GAIN_6 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 0x0 +#define AIROHA_PCS_ANA_TXPLL_VCODIV_2 0x1 +#define AIROHA_PCS_ANA_TXPLL_TCL_LPF_BW GENMASK(10, 8) +#define AIROHA_PCS_ANA_TXPLL_TCL_LPF_BW_0_5 0x0 +#define AIROHA_PCS_ANA_TXPLL_TCL_LPF_BW_1 0x1 +#define AIROHA_PCS_ANA_TXPLL_TCL_LPF_BW_2 0x2 +#define AIROHA_PCS_ANA_TXPLL_TCL_LPF_BW_4 0x3 +#define AIROHA_PCS_ANA_TXPLL_TCL_LPF_BW_8 0x4 +#define AIROHA_PCS_ANA_TXPLL_TCL_LPF_BW_16 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) +#define AIROHA_PCS_ANA_RX_PHY_CK_SEL_FROM_PR 0x0 +#define AIROHA_PCS_ANA_RX_PHY_CK_SEL_FROM_DES 0x1 +#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_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_MONPI_EN BIT(1) +#define AIROHA_PCS_ANA_CDR_PR_MONPR_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_RX_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 BIT(0) +#define AIROHA_PCS_ANA_RX_OSCAL_FORCE_VGA2IOS BIT(1) +#define AIROHA_PCS_ANA_RX_OSCAL_FORCE_VGA1VOS BIT(2) +#define AIROHA_PCS_ANA_RX_OSCAL_FORCE_VGA1IOS BIT(3) +#define AIROHA_PCS_ANA_RX_OSCAL_FORCE_CTLE2VOS BIT(4) +#define AIROHA_PCS_ANA_RX_OSCAL_FORCE_CTLE2IOS BIT(5) +#define AIROHA_PCS_ANA_RX_OSCAL_FORCE_CTLE1VOS BIT(6) +#define AIROHA_PCS_ANA_RX_OSCAL_FORCE_CTLE1IOS BIT(7) +#define AIROHA_PCS_ANA_RX_OSCAL_FORCE_LVSH BIT(8) +#define AIROHA_PCS_ANA_RX_OSCAL_FORCE_COMPOS 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 BIT(0) +#define AIROHA_PCS_ANA_AEQ_OFORCE_DFETP1 BIT(1) +#define AIROHA_PCS_ANA_AEQ_OFORCE_DFETP2 BIT(2) +#define AIROHA_PCS_ANA_AEQ_OFORCE_DFETP3 BIT(3) +#define AIROHA_PCS_ANA_AEQ_OFORCE_DFETP4 BIT(4) +#define AIROHA_PCS_ANA_AEQ_OFORCE_DFETP5 BIT(5) +#define AIROHA_PCS_ANA_AEQ_OFORCE_DFETP6 BIT(6) +#define AIROHA_PCS_ANA_AEQ_OFORCE_DFETP7 BIT(7) +#define AIROHA_PCS_ANA_AEQ_OFORCE_VGA BIT(8) +#define AIROHA_PCS_ANA_AEQ_OFORCE_CTLE BIT(9) +#define AIROHA_PCS_ANA_AEQ_OFORCE_ATT 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_PHYA 2L */ +#define AIROHA_PCS_ANA_PXP_2L_CMN_EN 0x0 +#define AIROHA_PCS_ANA_2L_CMN_EN BIT(0) +#define AIROHA_PCS_ANA_PXP_2L_JCPLL_IB_EXT_EN 0x4 +#define AIROHA_PCS_ANA_2L_JCPLL_CHP_IOFST GENMASK(29, 24) +#define AIROHA_PCS_ANA_2L_JCPLL_CHP_IBIAS GENMASK(21, 16) +#define AIROHA_PCS_ANA_2L_JCPLL_LPF_SHCK_EN BIT(8) +#define AIROHA_PCS_ANA_PXP_2L_JCPLL_LPF_BR 0x8 +#define AIROHA_PCS_ANA_2L_JCPLL_LPF_BWR GENMASK(28, 24) +#define AIROHA_PCS_ANA_2L_JCPLL_LPF_BP GENMASK(20, 16) +#define AIROHA_PCS_ANA_2L_JCPLL_LPF_BC GENMASK(12, 8) +#define AIROHA_PCS_ANA_2L_JCPLL_LPF_BR GENMASK(4, 0) +#define AIROHA_PCS_ANA_PXP_2L_JCPLL_LPF_BWC 0xc +#define AIROHA_PCS_ANA_2L_JCPLL_KBAND_DIV GENMASK(26, 24) +#define AIROHA_PCS_ANA_2L_JCPLL_KBAND_CODE GENMASK(23, 16) +#define AIROHA_PCS_ANA_2L_JCPLL_KBAND_OPTION BIT(8) +#define AIROHA_PCS_ANA_2L_JCPLL_LPF_BWC GENMASK(4, 0) +#define AIROHA_PCS_ANA_PXP_2L_JCPLL_KBAND_KFC 0x10 +#define AIROHA_PCS_ANA_2L_JCPLL_KBAND_KS GENMASK(17, 16) +#define AIROHA_PCS_ANA_2L_JCPLL_KBAND_KF GENMASK(9, 8) +#define AIROHA_PCS_ANA_2L_JCPLL_KBAND_KFC GENMASK(1, 0) +#define AIROHA_PCS_ANA_PXP_2L_JCPLL_MMD_PREDIV_MODE 0x14 +#define AIROHA_PCS_ANA_2L_JCPLL_POSTDIV_D5 BIT(24) +#define AIROHA_PCS_ANA_2L_JCPLL_MMD_PREDIV_MODE GENMASK(1, 0) +#define AIROHA_PCS_ANA_2L_JCPLL_MMD_PREDIV_MODE_2 0x0 +#define AIROHA_PCS_ANA_2L_JCPLL_MMD_PREDIV_MODE_3 0x1 +#define AIROHA_PCS_ANA_2L_JCPLL_MMD_PREDIV_MODE_4 0x2 +#define AIROHA_PCS_ANA_2L_JCPLL_MMD_PREDIV_MODE_1 0x3 +#define AIROHA_PCS_ANA_PXP_2L_JCPLL_RST_DLY 0x1c +#define AIROHA_PCS_ANA_2L_JCPLL_SDM_DI_LS GENMASK(25, 24) +#define AIROHA_PCS_ANA_2L_JCPLL_SDM_DI_LS_2_23 0x0 +#define AIROHA_PCS_ANA_2L_JCPLL_SDM_DI_LS_2_21 0x1 +#define AIROHA_PCS_ANA_2L_JCPLL_SDM_DI_LS_2_19 0x2 +#define AIROHA_PCS_ANA_2L_JCPLL_SDM_DI_LS_2_15 0x3 +#define AIROHA_PCS_ANA_2L_JCPLL_SDM_DI_EN BIT(16) +#define AIROHA_PCS_ANA_2L_JCPLL_PLL_RSTB BIT(8) +#define AIROHA_PCS_ANA_2L_JCPLL_RST_DLY GENMASK(2, 0) +#define AIROHA_PCS_ANA_2L_JCPLL_RST_DLY_20_25 0x1 +#define AIROHA_PCS_ANA_2L_JCPLL_RST_DLY_40_50 0x2 +#define AIROHA_PCS_ANA_2L_JCPLL_RST_DLY_80_100 0x3 +#define AIROHA_PCS_ANA_2L_JCPLL_RST_DLY_150_200 0x4 +#define AIROHA_PCS_ANA_2L_JCPLL_RST_DLY_300_400 0x5 +#define AIROHA_PCS_ANA_2L_JCPLL_RST_DLY_600_800 0x6 +#define AIROHA_PCS_ANA_PXP_2L_JCPLL_SDM_IFM 0x20 +#define AIROHA_PCS_ANA_2L_JCPLL_SDM_OUT BIT(24) +#define AIROHA_PCS_ANA_2L_JCPLL_SDM_ORD GENMASK(17, 16) +#define AIROHA_PCS_ANA_2L_JCPLL_SDM_ORD_INT 0x0 +#define AIROHA_PCS_ANA_2L_JCPLL_SDM_ORD_1SDM 0x1 +#define AIROHA_PCS_ANA_2L_JCPLL_SDM_ORD_2SDM 0x2 +#define AIROHA_PCS_ANA_2L_JCPLL_SDM_ORD_3SDM 0x3 +#define AIROHA_PCS_ANA_2L_JCPLL_SDM_MODE GENMASK(9, 8) +#define AIROHA_PCS_ANA_2L_JCPLL_SDM_IFM BIT(0) +#define AIROHA_PCS_ANA_PXP_2L_JCPLL_SDM_HREN 0x24 +#define AIROHA_PCS_ANA_2L_JCPLL_TCL_AMP_VREF GENMASK(28, 24) +#define AIROHA_PCS_ANA_2L_JCPLL_TCL_AMP_GAIN GENMASK(18, 16) +#define AIROHA_PCS_ANA_2L_JCPLL_TCL_AMP_GAIN_2 0x0 +#define AIROHA_PCS_ANA_2L_JCPLL_TCL_AMP_GAIN_4 0x1 +#define AIROHA_PCS_ANA_2L_JCPLL_TCL_AMP_GAIN_6 0x2 +#define AIROHA_PCS_ANA_2L_JCPLL_TCL_AMP_GAIN_8 0x3 +#define AIROHA_PCS_ANA_2L_JCPLL_TCL_AMP_GAIN_10 0x4 +#define AIROHA_PCS_ANA_2L_JCPLL_TCL_AMP_EN BIT(8) +#define AIROHA_PCS_ANA_2L_JCPLL_SDM_HREN BIT(0) +#define AIROHA_PCS_ANA_PXP_2L_JCPLL_TCL_CMP_EN 0x28 +#define AIROHA_PCS_ANA_2L_JCPLL_TCL_LPF_BW GENMASK(26, 24) +#define AIROHA_PCS_ANA_2L_JCPLL_TCL_LPF_BW_0_5 0x0 +#define AIROHA_PCS_ANA_2L_JCPLL_TCL_LPF_BW_1 0x1 +#define AIROHA_PCS_ANA_2L_JCPLL_TCL_LPF_BW_2 0x2 +#define AIROHA_PCS_ANA_2L_JCPLL_TCL_LPF_BW_4 0x3 +#define AIROHA_PCS_ANA_2L_JCPLL_TCL_LPF_BW_8 0x4 +#define AIROHA_PCS_ANA_2L_JCPLL_TCL_LPF_BW_16 0x6 +#define AIROHA_PCS_ANA_2L_JCPLL_TCL_LPF_EN BIT(16) +#define AIROHA_PCS_ANA_2L_JCPLL_TCL_LPF_BW GENMASK(26, 24) +#define AIROHA_PCS_ANA_PXP_2L_JCPLL_VCODIV 0x2c +#define AIROHA_PCS_ANA_2L_JCPLL_VCO_SCAPWR GENMASK(26, 24) +#define AIROHA_PCS_ANA_2L_JCPLL_VCO_HALFLSB_EN BIT(16) +#define AIROHA_PCS_ANA_2L_JCPLL_VCO_CFIX GENMASK(9, 8) +#define AIROHA_PCS_ANA_2L_JCPLL_VCODIV GENMASK(1, 0) +#define AIROHA_PCS_ANA_2L_JCPLL_VCODIV_1 0x0 +#define AIROHA_PCS_ANA_2L_JCPLL_VCODIV_2 0x1 +#define AIROHA_PCS_ANA_PXP_2L_JCPLL_VCO_TCLVAR 0x30 +#define AIROHA_PCS_ANA_2L_JCPLL_VCO_VCOVAR_BIAS_L GENMASK(18, 16) +#define AIROHA_PCS_ANA_2L_JCPLL_VCO_VCOVAR_BIAS_H GENMASK(10, 8) +#define AIROHA_PCS_ANA_2L_JCPLL_VCO_TCLVAR GENMASK(2, 0) +#define AIROHA_PCS_ANA_PXP_2L_JCPLL_SSC_EN 0x38 +#define AIROHA_PCS_ANA_2L_JCPLL_SSC_TRI_EN BIT(16) +#define AIROHA_PCS_ANA_PXP_2L_JCPLL_SSC_DELTA1 0x3c +#define AIROHA_PCS_ANA_2L_JCPLL_SSC_DELTA GENMASK(31, 16) +#define AIROHA_PCS_ANA_2L_JCPLL_SSC_DELTA1 GENMASK(15, 0) +#define AIROHA_PCS_ANA_PXP_2L_JCPLL_SSC_PERIOD 0x40 +#define AIROHA_PCS_ANA_2L_JCPLL_SSC_PERIOD GENMASK(15, 0) +#define AIROHA_PCS_ANA_PXP_2L_JCPLL_TCL_VTP_EN 0x4c +#define AIROHA_PCS_ANA_2L_JCPLL_SPARE_L GENMASK(31, 24) +#define AIROHA_PCS_ANA_2L_JCPLL_SPARE_L_LDO FIELD_PREP_CONST(AIROHA_PCS_ANA_JCPLL_SPARE_L, BIT(5)) +#define AIROHA_PCS_ANA_PXP_2L_JCPLL_TCL_KBAND_VREF 0x50 +#define AIROHA_PCS_ANA_2L_JCPLL_TCL_KBAND_VREF GENMASK(4, 0) +#define AIROHA_PCS_ANA_PXP_2L_750M_SYS_CK_EN 0x54 +#define AIROHA_PCS_ANA_2L_TXPLL_CHP_IBIAS GENMASK(29, 24) +#define AIROHA_PCS_ANA_PXP_2L_TXPLL_CHP_IOFST 0x58 +#define AIROHA_PCS_ANA_2L_TXPLL_LPF_BP GENMASK(28, 24) +#define AIROHA_PCS_ANA_2L_TXPLL_LPF_BC GENMASK(20, 16) +#define AIROHA_PCS_ANA_2L_TXPLL_LPF_BR GENMASK(12, 8) +#define AIROHA_PCS_ANA_2L_TXPLL_CHP_IOFST GENMASK(5, 0) +#define AIROHA_PCS_ANA_PXP_2L_TXPLL_LPF_BWR 0x5c +#define AIROHA_PCS_ANA_2L_TXPLL_KBAND_CODE GENMASK(31, 24) +#define AIROHA_PCS_ANA_2L_TXPLL_KBAND_OPTION BIT(16) +#define AIROHA_PCS_ANA_2L_TXPLL_LPF_BWC GENMASK(12, 8) +#define AIROHA_PCS_ANA_2L_TXPLL_LPF_BWR GENMASK(4, 0) +#define AIROHA_PCS_ANA_PXP_2L_TXPLL_KBAND_DIV 0x60 +#define AIROHA_PCS_ANA_2L_TXPLL_KBAND_KS GENMASK(25, 24) +#define AIROHA_PCS_ANA_2L_TXPLL_KBAND_KF GENMASK(17, 16) +#define AIROHA_PCS_ANA_2L_TXPLL_KBAND_KFC GENMASK(9, 8) +#define AIROHA_PCS_ANA_2L_TXPLL_KBAND_DIV GENMASK(2, 0) +#define AIROHA_PCS_ANA_PXP_2L_TXPLL_POSTDIV_EN 0x64 +#define AIROHA_PCS_ANA_2L_TXPLL_MMD_PREDIV_MODE GENMASK(9, 8) +#define AIROHA_PCS_ANA_2L_TXPLL_MMD_PREDIV_MODE_2 0x0 +#define AIROHA_PCS_ANA_2L_TXPLL_MMD_PREDIV_MODE_3 0x1 +#define AIROHA_PCS_ANA_2L_TXPLL_MMD_PREDIV_MODE_4 0x2 +#define AIROHA_PCS_ANA_2L_TXPLL_MMD_PREDIV_MODE_1 0x3 +#define AIROHA_PCS_ANA_2L_TXPLL_POSTDIV_EN BIT(0) +#define AIROHA_PCS_ANA_PXP_2L_TXPLL_PHY_CK2_EN 0x68 +#define AIROHA_PCS_ANA_2L_TXPLL_REFIN_INTERNAL BIT(24) +#define AIROHA_PCS_ANA_PXP_2L_TXPLL_REFIN_DIV 0x6c +#define AIROHA_PCS_ANA_2L_TXPLL_SDM_DI_EN BIT(24) +#define AIROHA_PCS_ANA_2L_TXPLL_PLL_RSTB BIT(16) +#define AIROHA_PCS_ANA_2L_TXPLL_RST_DLY GENMASK(10, 8) +#define AIROHA_PCS_ANA_2L_TXPLL_REFIN_DIV GENMASK(1, 0) +#define AIROHA_PCS_ANA_2L_TXPLL_REFIN_DIV_1 0x0 +#define AIROHA_PCS_ANA_2L_TXPLL_REFIN_DIV_2 0x1 +#define AIROHA_PCS_ANA_2L_TXPLL_REFIN_DIV_3 0x2 +#define AIROHA_PCS_ANA_2L_TXPLL_REFIN_DIV_4 0x3 +#define AIROHA_PCS_ANA_PXP_2L_TXPLL_SDM_DI_LS 0x70 +#define AIROHA_PCS_ANA_2L_TXPLL_SDM_ORD GENMASK(25, 24) +#define AIROHA_PCS_ANA_2L_TXPLL_SDM_ORD_INT 0x0 +#define AIROHA_PCS_ANA_2L_TXPLL_SDM_ORD_1SDM 0x1 +#define AIROHA_PCS_ANA_2L_TXPLL_SDM_ORD_2SDM 0x2 +#define AIROHA_PCS_ANA_2L_TXPLL_SDM_ORD_3SDM 0x3 +#define AIROHA_PCS_ANA_2L_TXPLL_SDM_MODE GENMASK(17, 16) +#define AIROHA_PCS_ANA_2L_TXPLL_SDM_IFM BIT(8) +#define AIROHA_PCS_ANA_2L_TXPLL_SDM_DI_LS GENMASK(1, 0) +#define AIROHA_PCS_ANA_2L_TXPLL_SDM_DI_LS_2_23 0x0 +#define AIROHA_PCS_ANA_2L_TXPLL_SDM_DI_LS_2_21 0x1 +#define AIROHA_PCS_ANA_2L_TXPLL_SDM_DI_LS_2_19 0x2 +#define AIROHA_PCS_ANA_2L_TXPLL_SDM_DI_LS_2_15 0x3 +#define AIROHA_PCS_ANA_PXP_2L_TXPLL_SDM_OUT 0x74 +#define AIROHA_PCS_ANA_2L_TXPLL_TCL_AMP_GAIN GENMASK(26, 24) +#define AIROHA_PCS_ANA_2L_TXPLL_TCL_AMP_GAIN_2 0x0 +#define AIROHA_PCS_ANA_2L_TXPLL_TCL_AMP_GAIN_2_5 0x1 +#define AIROHA_PCS_ANA_2L_TXPLL_TCL_AMP_GAIN_3 0x2 +#define AIROHA_PCS_ANA_2L_TXPLL_TCL_AMP_GAIN_4 0x3 +#define AIROHA_PCS_ANA_2L_TXPLL_TCL_AMP_GAIN_6 0x4 +#define AIROHA_PCS_ANA_2L_TXPLL_TCL_AMP_EN BIT(16) +#define AIROHA_PCS_ANA_2L_TXPLL_SDM_HREN BIT(8) +#define AIROHA_PCS_ANA_2L_TXPLL_SDM_OUT BIT(0) +#define AIROHA_PCS_ANA_PXP_2L_TXPLL_TCL_AMP_VREF 0x78 +#define AIROHA_PCS_ANA_2L_TXPLL_TCL_LPF_EN BIT(24) +#define AIROHA_PCS_ANA_2L_TXPLL_TCL_AMP_VREF GENMASK(4, 0) +#define AIROHA_PCS_ANA_PXP_2L_TXPLL_TCL_LPF_BW 0x7c +#define AIROHA_PCS_ANA_2L_TXPLL_VCO_HALFLSB_EN BIT(24) +#define AIROHA_PCS_ANA_2L_TXPLL_VCO_CFIX GENMASK(17, 16) +#define AIROHA_PCS_ANA_2L_TXPLL_VCODIV GENMASK(9, 8) +#define AIROHA_PCS_ANA_2L_TXPLL_VCODIV_1 0x0 +#define AIROHA_PCS_ANA_2L_TXPLL_VCODIV_2 0x1 +#define AIROHA_PCS_ANA_2L_TXPLL_TCL_LPF_BW GENMASK(2, 0) +#define AIROHA_PCS_ANA_2L_TXPLL_TCL_LPF_BW_0_5 0x0 +#define AIROHA_PCS_ANA_2L_TXPLL_TCL_LPF_BW_1 0x1 +#define AIROHA_PCS_ANA_2L_TXPLL_TCL_LPF_BW_2 0x2 +#define AIROHA_PCS_ANA_2L_TXPLL_TCL_LPF_BW_4 0x3 +#define AIROHA_PCS_ANA_2L_TXPLL_TCL_LPF_BW_8 0x4 +#define AIROHA_PCS_ANA_2L_TXPLL_TCL_LPF_BW_16 0x6 +#define AIROHA_PCS_ANA_PXP_2L_TXPLL_VCO_SCAPWR 0x80 +#define AIROHA_PCS_ANA_2L_TXPLL_VCO_VCOVAR_BIAS_L GENMASK(26, 24) +#define AIROHA_PCS_ANA_2L_TXPLL_VCO_VCOVAR_BIAS_H GENMASK(18, 16) +#define AIROHA_PCS_ANA_2L_TXPLL_VCO_TCLVAR GENMASK(10, 8) +#define AIROHA_PCS_ANA_2L_TXPLL_VCO_SCAPWR GENMASK(2, 0) +#define AIROHA_PCS_ANA_PXP_2L_TXPLL_SSC_EN 0x84 +#define AIROHA_PCS_ANA_2L_TXPLL_SSC_TRI_EN BIT(16) +#define AIROHA_PCS_ANA_2L_TXPLL_SSC_PHASE_INI BIT(8) +#define AIROHA_PCS_ANA_2L_TXPLL_SSC_EN BIT(0) +#define AIROHA_PCS_ANA_PXP_2L_TXPLL_SSC_DELTA1 0x88 +#define AIROHA_PCS_ANA_2L_TXPLL_SSC_DELTA GENMASK(31, 16) +#define AIROHA_PCS_ANA_2L_TXPLL_SSC_DELTA1 GENMASK(15, 0) +#define AIROHA_PCS_ANA_PXP_2L_TXPLL_SSC_PERIOD 0x8c +#define AIROHA_PCS_ANA_2L_TXPLL_LDO_VCO_OUT GENMASK(25, 24) +#define AIROHA_PCS_ANA_2L_TXPLL_LDO_OUT GENMASK(17, 16) +#define AIROHA_PCS_ANA_2L_TXPLL_SSC_PERIOD GENMASK(15, 0) +#define AIROHA_PCS_ANA_PXP_2L_TXPLL_TCL_KBAND_VREF 0x9c +#define AIROHA_PCS_ANA_2L_TXPLL_TCL_KBAND_VREF GENMASK(4, 0) +#define AIROHA_PCS_ANA_PXP_2L_TX0_CKLDO_EN 0xcc +#define AIROHA_PCS_ANA_2L_TX0_DMEDGEGEN_EN BIT(24) +#define AIROHA_PCS_ANA_2L_TX0_CKLDO_EN BIT(0) +#define AIROHA_PCS_ANA_PXP_2L_TX1_CKLDO_EN 0xe8 +#define AIROHA_PCS_ANA_2L_TX1_DMEDGEGEN_EN BIT(24) +#define AIROHA_PCS_ANA_2L_TX1_CKLDO_EN BIT(0) +#define AIROHA_PCS_ANA_PXP_2L_RX0_BUSBIT_SEL 0xf4 +#define AIROHA_PCS_ANA_2L_RX0_PHY_CK_SEL_FORCE BIT(24) +#define AIROHA_PCS_ANA_2L_RX0_PHY_CK_SEL BIT(16) +#define AIROHA_PCS_ANA_2L_RX0_PHY_CK_SEL_FROM_PR 0x0 +#define AIROHA_PCS_ANA_2L_RX0_PHY_CK_SEL_FROM_DES 0x1 +#define AIROHA_PCS_ANA_PXP_2L_RX0_REV_0 0xfc +#define AIROHA_PCS_ANA_2L_RX0_REV_1 GENMASK(31, 16) +#define AIROHA_PCS_ANA_2L_REV_1_FE_EQ_BIAS_CTRL GENMASK(30, 28) +#define AIROHA_PCS_ANA_2L_REV_1_FE_BUF1_BIAS_CTRL GENMASK(26, 24) +#define AIROHA_PCS_ANA_2L_REV_1_FE_BUF2_BIAS_CTRL GENMASK(22, 20) +#define AIROHA_PCS_ANA_2L_REV_1_SIGDET_ILEAK GENMASK(19, 18) +#define AIROHA_PCS_ANA_2L_REV_1_FECUR_PWDB BIT(16) +#define AIROHA_PCS_ANA_2L_RX0_REV_0 GENMASK(15, 0) +#define AIROHA_PCS_ANA_2L_REV_0_FE_BUF2_BIAS_TYPE GENMASK(13, 12) +#define AIROHA_PCS_ANA_2L_REV_0_OSCAL_FE_MODE_SET_SEL BIT(11) +#define AIROHA_PCS_ANA_2L_REV_0_FE_EQ_GAIN_MODE_TRAINING BIT(10) +#define AIROHA_PCS_ANA_2L_REV_0_FE_BUF_GAIN_MODE_TRAINING GENMASK(9, 8) +#define AIROHA_PCS_ANA_2L_REV_0_FE_EQ_GAIN_MODE_NORMAL BIT(6) +#define AIROHA_PCS_ANA_2L_REV_0_FE_BUF_GAIN_MODE_NORMAL GENMASK(5, 4) +#define AIROHA_PCS_ANA_2L_REV_0_VOS_PNINV GENMASK(3, 2) +#define AIROHA_PCS_ANA_2L_REV_0_PLEYEBD4 BIT(1) +#define AIROHA_PCS_ANA_2L_REV_0_PLEYE_XOR_MON_EN BIT(0) +#define AIROHA_PCS_ANA_PXP_2L_RX0_PHYCK_DIV 0x100 +#define AIROHA_PCS_ANA_2L_RX0_TDC_CK_SEL BIT(24) +#define AIROHA_PCS_ANA_2L_RX0_PHYCK_RSTB BIT(16) +#define AIROHA_PCS_ANA_2L_RX0_PHYCK_SEL GENMASK(9, 8) +#define AIROHA_PCS_ANA_2L_RX0_PHYCK_DIV GENMASK(7, 0) +#define AIROHA_PCS_ANA_PXP_2L_CDR0_PD_PICAL_CKD8_INV 0x104 +#define AIROHA_PCS_ANA_2L_CDR0_PD_EDGE_DIS BIT(8) +#define AIROHA_PCS_ANA_2L_CDR0_PD_PICAL_CKD8_INV BIT(0) +#define AIROHA_PCS_ANA_PXP_2L_CDR0_LPF_RATIO 0x110 +#define AIROHA_PCS_ANA_2L_CDR0_LPF_TOP_LIM GENMASK(26, 8) +#define AIROHA_PCS_ANA_2L_CDR0_LPF_RATIO GENMASK(1, 0) +#define AIROHA_PCS_ANA_PXP_2L_CDR0_PR_INJ_MODE 0x11c +#define AIROHA_PCS_ANA_2L_CDR0_PR_INJ_FORCE_OFF BIT(24) +#define AIROHA_PCS_ANA_PXP_2L_CDR0_PR_BETA_DAC 0x120 +#define AIROHA_PCS_ANA_2L_CDR0_PR_KBAND_DIV GENMASK(26, 24) +#define AIROHA_PCS_ANA_2L_CDR0_PR_BETA_SEL GENMASK(19, 16) +#define AIROHA_PCS_ANA_2L_CDR0_PR_VCOADC_OS GENMASK(11, 8) +#define AIROHA_PCS_ANA_2L_CDR0_PR_BETA_DAC GENMASK(6, 0) +#define AIROHA_PCS_ANA_PXP_2L_CDR0_PR_VREG_IBAND_VAL 0x124 +#define AIROHA_PCS_ANA_2L_CDR0_PR_FBKSEL GENMASK(25, 24) +#define AIROHA_PCS_ANA_2L_CDR0_PR_DAC_BAND GENMASK(20, 16) +#define AIROHA_PCS_ANA_2L_CDR0_PR_VREG_CKBUF_VAL GENMASK(10, 8) +#define AIROHA_PCS_ANA_2L_CDR0_PR_VREG_IBAND_VAL GENMASK(2, 0) +#define AIROHA_PCS_ANA_PXP_2L_CDR0_PR_COR_HBW_EN 0x130 +#define AIROHA_PCS_ANA_2L_CDR0_PR_MONPR_EN BIT(24) +#define AIROHA_PCS_ANA_PXP_2L_CDR0_PR_MONPI_EN 0x134 +#define AIROHA_PCS_ANA_2L_CDR0_PR_XFICK_EN BIT(8) +#define AIROHA_PCS_ANA_2L_CDR0_PR_MONPI_EN BIT(0) +#define AIROHA_PCS_ANA_PXP_2L_CDR0_PR_BUF_IN_SR 0x138 +#define AIROHA_PCS_ANA_2L_CDR0_PR_CAP_EN BIT(8) +#define AIROHA_PCS_ANA_2L_CDR0_PR_BUF_IN_SR GENMASK(2, 0) +#define AIROHA_PCS_ANA_PXP_2L_RX0_DAC_MON 0x13c +#define AIROHA_PCS_ANA_2L_RX0_DAC_MON GENMASK(4, 0) +#define AIROHA_PCS_ANA_PXP_2L_RX0_SIGDET_DCTEST_EN 0x140 +#define AIROHA_PCS_ANA_2L_RX0_SIGDET_PEAK GENMASK(25, 24) +#define AIROHA_PCS_ANA_2L_RX0_SIGDET_LPF_CTRL GENMASK(9, 8) +#define AIROHA_PCS_ANA_PXP_2L_RX0_SIGDET_VTH_SEL 0x144 +#define AIROHA_PCS_ANA_2L_RX0_FE_VB_EQ1_EN BIT(24) +#define AIROHA_PCS_ANA_2L_RX0_FE_EQ_HZEN BIT(16) +#define AIROHA_PCS_ANA_2L_RX0_SIGDET_VTH_SEL GENMASK(4, 0) +#define AIROHA_PCS_ANA_PXP_2L_RX0_FE_VB_EQ2_EN 0x148 +#define AIROHA_PCS_ANA_2L_RX0_FE_VCM_GEN_PWDB BIT(16) +#define AIROHA_PCS_ANA_2L_RX0_FE_VB_EQ3_EN BIT(8) +#define AIROHA_PCS_ANA_2L_RX0_FE_VB_EQ2_EN BIT(0) +#define AIROHA_PCS_ANA_PXP_2L_RX0_OSCAL_FORCE 0x150 +#define AIROHA_PCS_ANA_2L_RX0_OSCAL_FORCE GENMASK(17, 8) +#define AIROHA_PCS_ANA_2L_RX0_OSCAL_FORCE_VGA2VOS BIT(0) +#define AIROHA_PCS_ANA_2L_RX0_OSCAL_FORCE_VGA2IOS BIT(1) +#define AIROHA_PCS_ANA_2L_RX0_OSCAL_FORCE_VGA1VOS BIT(2) +#define AIROHA_PCS_ANA_2L_RX0_OSCAL_FORCE_VGA1IOS BIT(3) +#define AIROHA_PCS_ANA_2L_RX0_OSCAL_FORCE_CTLE2VOS BIT(4) +#define AIROHA_PCS_ANA_2L_RX0_OSCAL_FORCE_CTLE2IOS BIT(5) +#define AIROHA_PCS_ANA_2L_RX0_OSCAL_FORCE_CTLE1VOS BIT(6) +#define AIROHA_PCS_ANA_2L_RX0_OSCAL_FORCE_CTLE1IOS BIT(7) +#define AIROHA_PCS_ANA_2L_RX0_OSCAL_FORCE_LVSH BIT(8) +#define AIROHA_PCS_ANA_2L_RX0_OSCAL_FORCE_COMPOS BIT(9) +#define AIROHA_PCS_ANA_PXP_2L_AEQ0_CFORCE 0x170 +#define AIROHA_PCS_ANA_2L_AEQ0_OFORCE GENMASK(19, 8) +#define AIROHA_PCS_ANA_2L_AEQ0_OFORCE_SAOS BIT(0) +#define AIROHA_PCS_ANA_2L_AEQ0_OFORCE_DFETP1 BIT(1) +#define AIROHA_PCS_ANA_2L_AEQ0_OFORCE_DFETP2 BIT(2) +#define AIROHA_PCS_ANA_2L_AEQ0_OFORCE_DFETP3 BIT(3) +#define AIROHA_PCS_ANA_2L_AEQ0_OFORCE_DFETP4 BIT(4) +#define AIROHA_PCS_ANA_2L_AEQ0_OFORCE_DFETP5 BIT(5) +#define AIROHA_PCS_ANA_2L_AEQ0_OFORCE_DFETP6 BIT(6) +#define AIROHA_PCS_ANA_2L_AEQ0_OFORCE_DFETP7 BIT(7) +#define AIROHA_PCS_ANA_2L_AEQ0_OFORCE_VGA BIT(8) +#define AIROHA_PCS_ANA_2L_AEQ0_OFORCE_CTLE BIT(9) +#define AIROHA_PCS_ANA_2L_AEQ0_OFORCE_ATT BIT(10) +#define AIROHA_PCS_ANA_PXP_2L_RX0_DAC_D0_BYPASS_AEQ 0x17c +#define AIROHA_PCS_ANA_2L_RX0_DAC_E1_BYPASS_AEQ BIT(24) +#define AIROHA_PCS_ANA_2L_RX0_DAC_E0_BYPASS_AEQ BIT(16) +#define AIROHA_PCS_ANA_2L_RX0_DAC_D1_BYPASS_AEQ BIT(8) +#define AIROHA_PCS_ANA_2L_RX0_DAC_D0_BYPASS_AEQ BIT(0) +#define AIROHA_PCS_ANA_PXP_2L_RX0_DAC_EYE_BYPASS_AEQ 0x180 +#define AIROHA_PCS_ANA_2L_RX0_DAC_EYE_BYPASS_AEQ BIT(0) +#define AIROHA_PCS_ANA_PXP_2L_RX1_FE_PEACKING_CTRL_LSB 0x234 +#define AIROHA_PCS_ANA_2L_RX1_DAC_D0_BYPASS_AEQ BIT(24) +#define AIROHA_PCS_ANA_PXP_2L_RX1_BUSBIT_SEL 0x1ac +#define AIROHA_PCS_ANA_2L_RX1_PHY_CK_SEL_FORCE BIT(24) +#define AIROHA_PCS_ANA_2L_RX1_PHY_CK_SEL BIT(16) +#define AIROHA_PCS_ANA_2L_RX0_PHY_CK_SEL_FROM_PR 0x0 +#define AIROHA_PCS_ANA_2L_RX0_PHY_CK_SEL_FROM_DES 0x1 +#define AIROHA_PCS_ANA_PXP_2L_RX1_REV_0 0x1b4 +#define AIROHA_PCS_ANA_2L_RX1_REV_1 GENMASK(31, 16) +#define AIROHA_PCS_ANA_2L_REV_1_FE_EQ_BIAS_CTRL GENMASK(30, 28) +#define AIROHA_PCS_ANA_2L_REV_1_FE_BUF1_BIAS_CTRL GENMASK(26, 24) +#define AIROHA_PCS_ANA_2L_REV_1_FE_BUF2_BIAS_CTRL GENMASK(22, 20) +#define AIROHA_PCS_ANA_2L_REV_1_SIGDET_ILEAK GENMASK(19, 18) +#define AIROHA_PCS_ANA_2L_REV_1_FECUR_PWDB BIT(16) +#define AIROHA_PCS_ANA_2L_RX1_REV_0 GENMASK(15, 0) +#define AIROHA_PCS_ANA_2L_REV_0_FE_BUF2_BIAS_TYPE GENMASK(13, 12) +#define AIROHA_PCS_ANA_2L_REV_0_OSCAL_FE_MODE_SET_SEL BIT(11) +#define AIROHA_PCS_ANA_2L_REV_0_FE_EQ_GAIN_MODE_TRAINING BIT(10) +#define AIROHA_PCS_ANA_2L_REV_0_FE_BUF_GAIN_MODE_TRAINING GENMASK(9, 8) +#define AIROHA_PCS_ANA_2L_REV_0_FE_EQ_GAIN_MODE_NORMAL BIT(6) +#define AIROHA_PCS_ANA_2L_REV_0_FE_BUF_GAIN_MODE_NORMAL GENMASK(5, 4) +#define AIROHA_PCS_ANA_2L_REV_0_VOS_PNINV GENMASK(3, 2) +#define AIROHA_PCS_ANA_2L_REV_0_PLEYEBD4 BIT(1) +#define AIROHA_PCS_ANA_2L_REV_0_PLEYE_XOR_MON_EN BIT(0) +#define AIROHA_PCS_ANA_PXP_2L_RX1_PHYCK_DIV 0x1b8 +#define AIROHA_PCS_ANA_2L_RX1_TDC_CK_SEL BIT(24) +#define AIROHA_PCS_ANA_2L_RX1_PHYCK_RSTB BIT(16) +#define AIROHA_PCS_ANA_2L_RX1_PHYCK_SEL GENMASK(9, 8) +#define AIROHA_PCS_ANA_2L_RX1_PHYCK_DIV GENMASK(7, 0) +#define AIROHA_PCS_ANA_PXP_2L_CDR1_PD_PICAL_CKD8_INV 0x1bc +#define AIROHA_PCS_ANA_2L_CDR1_PD_EDGE_DIS BIT(8) +#define AIROHA_PCS_ANA_2L_CDR1_PD_PICAL_CKD8_INV BIT(0) +#define AIROHA_PCS_ANA_PXP_2L_CDR1_LPF_RATIO 0x1c8 +#define AIROHA_PCS_ANA_2L_CDR1_LPF_TOP_LIM GENMASK(26, 8) +#define AIROHA_PCS_ANA_2L_CDR1_LPF_RATIO GENMASK(1, 0) +#define AIROHA_PCS_ANA_PXP_2L_CDR1_PR_INJ_MODE 0x1d4 +#define AIROHA_PCS_ANA_2L_CDR1_PR_INJ_FORCE_OFF BIT(24) +#define AIROHA_PCS_ANA_PXP_2L_CDR1_PR_BETA_DAC 0x1d8 +#define AIROHA_PCS_ANA_2L_CDR1_PR_KBAND_DIV GENMASK(26, 24) +#define AIROHA_PCS_ANA_2L_CDR1_PR_BETA_SEL GENMASK(19, 16) +#define AIROHA_PCS_ANA_2L_CDR1_PR_VCOADC_OS GENMASK(11, 8) +#define AIROHA_PCS_ANA_2L_CDR1_PR_BETA_DAC GENMASK(6, 0) +#define AIROHA_PCS_ANA_PXP_2L_CDR1_PR_VREG_IBAND_VAL 0x1dc +#define AIROHA_PCS_ANA_2L_CDR1_PR_FBKSEL GENMASK(25, 24) +#define AIROHA_PCS_ANA_2L_CDR1_PR_DAC_BAND GENMASK(20, 16) +#define AIROHA_PCS_ANA_2L_CDR1_PR_VREG_CKBUF_VAL GENMASK(10, 8) +#define AIROHA_PCS_ANA_2L_CDR1_PR_VREG_IBAND_VAL GENMASK(2, 0) +#define AIROHA_PCS_ANA_PXP_2L_CDR1_PR_COR_HBW_EN 0x1e8 +#define AIROHA_PCS_ANA_2L_CDR1_PR_MONPR_EN BIT(24) +#define AIROHA_PCS_ANA_PXP_2L_CDR1_PR_MONPI_EN 0x1ec +#define AIROHA_PCS_ANA_2L_CDR1_PR_XFICK_EN BIT(8) +#define AIROHA_PCS_ANA_2L_CDR1_PR_MONPI_EN BIT(0) +#define AIROHA_PCS_ANA_PXP_2L_CDR1_PR_BUF_IN_SR 0x1f0 +#define AIROHA_PCS_ANA_2L_RX1_DAC_MON GENMASK(20, 16) +#define AIROHA_PCS_ANA_2L_CDR1_PR_CAP_EN BIT(8) +#define AIROHA_PCS_ANA_2L_CDR1_PR_BUF_IN_SR GENMASK(2, 0) +#define AIROHA_PCS_ANA_PXP_2L_RX1_DAC_RANGE_EYE 0x1f4 +#define AIROHA_PCS_ANA_2L_RX1_SIGDET_LPF_CTRL GENMASK(25, 24) +#define AIROHA_PCS_ANA_PXP_2L_RX1_SIGDET_NOVTH 0x1f8 +#define AIROHA_PCS_ANA_2L_RX1_SIGDET_VTH_SEL GENMASK(20, 16) +#define AIROHA_PCS_ANA_2L_RX1_SIGDET_PEAK GENMASK(9, 8) +#define AIROHA_PCS_ANA_PXP_2L_RX1_FE_50OHMS_SEL 0x1fc +#define AIROHA_PCS_ANA_2L_RX1_FE_EQ_HZEN BIT(24) +#define AIROHA_PCS_ANA_PXP_2L_RX1_FE_VB_EQ1_EN 0x200 +#define AIROHA_PCS_ANA_2L_RX1_FE_VCM_GEN_PWDB BIT(24) +#define AIROHA_PCS_ANA_2L_RX1_FE_VB_EQ3_EN BIT(16) +#define AIROHA_PCS_ANA_2L_RX1_FE_VB_EQ2_EN BIT(8) +#define AIROHA_PCS_ANA_2L_RX1_FE_VB_EQ1_EN BIT(0) +#define AIROHA_PCS_ANA_PXP_2L_RX1_OSCAL_WATCH_WNDW 0x208 +#define AIROHA_PCS_ANA_2L_RX1_OSCAL_FORCE GENMASK(25, 16) +#define AIROHA_PCS_ANA_2L_RX1_OSCAL_FORCE_VGA2VOS BIT(0) +#define AIROHA_PCS_ANA_2L_RX1_OSCAL_FORCE_VGA2IOS BIT(1) +#define AIROHA_PCS_ANA_2L_RX1_OSCAL_FORCE_VGA1VOS BIT(2) +#define AIROHA_PCS_ANA_2L_RX1_OSCAL_FORCE_VGA1IOS BIT(3) +#define AIROHA_PCS_ANA_2L_RX1_OSCAL_FORCE_CTLE2VOS BIT(4) +#define AIROHA_PCS_ANA_2L_RX1_OSCAL_FORCE_CTLE2IOS BIT(5) +#define AIROHA_PCS_ANA_2L_RX1_OSCAL_FORCE_CTLE1VOS BIT(6) +#define AIROHA_PCS_ANA_2L_RX1_OSCAL_FORCE_CTLE1IOS BIT(7) +#define AIROHA_PCS_ANA_2L_RX1_OSCAL_FORCE_LVSH BIT(8) +#define AIROHA_PCS_ANA_2L_RX1_OSCAL_FORCE_COMPOS BIT(9) +#define AIROHA_PCS_ANA_PXP_2L_AEQ1_CFORCE 0x228 +#define AIROHA_PCS_ANA_2L_AEQ1_OFORCE GENMASK(27, 16) +#define AIROHA_PCS_ANA_2L_AEQ1_OFORCE_SAOS BIT(0) +#define AIROHA_PCS_ANA_2L_AEQ1_OFORCE_DFETP1 BIT(1) +#define AIROHA_PCS_ANA_2L_AEQ1_OFORCE_DFETP2 BIT(2) +#define AIROHA_PCS_ANA_2L_AEQ1_OFORCE_DFETP3 BIT(3) +#define AIROHA_PCS_ANA_2L_AEQ1_OFORCE_DFETP4 BIT(4) +#define AIROHA_PCS_ANA_2L_AEQ1_OFORCE_DFETP5 BIT(5) +#define AIROHA_PCS_ANA_2L_AEQ1_OFORCE_DFETP6 BIT(6) +#define AIROHA_PCS_ANA_2L_AEQ1_OFORCE_DFETP7 BIT(7) +#define AIROHA_PCS_ANA_2L_AEQ1_OFORCE_VGA BIT(8) +#define AIROHA_PCS_ANA_2L_AEQ1_OFORCE_CTLE BIT(9) +#define AIROHA_PCS_ANA_2L_AEQ1_OFORCE_ATT BIT(10) +#define AIROHA_PCS_ANA_PXP_2L_RX1_DAC_D1_BYPASS_AEQ 0x238 +#define AIROHA_PCS_ANA_2L_RX1_DAC_EYE_BYPASS_AEQ BIT(24) +#define AIROHA_PCS_ANA_2L_RX1_DAC_E1_BYPASS_AEQ BIT(16) +#define AIROHA_PCS_ANA_2L_RX1_DAC_E0_BYPASS_AEQ BIT(8) +#define AIROHA_PCS_ANA_2L_RX1_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_2 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_SS_DA_XPON_PWDB_0 0x34c +#define AIROHA_PCS_PMA_XPON_CDR_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_TRIGGER_RX_SIDGET_SCAN GENMASK(17, 16) +#define AIROHA_PCS_PMA_XPON_RX_RESERVED_1 0x374 +#define AIROHA_PCS_PMA_XPON_RX_RATE_CTRL GENMASK(1, 0) +#define AIROHA_PCS_PMA_DIG_RO_RESERVE_2 0x380 +#define AIROHA_PCS_RX_SIGDET BIT(8) +#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_ADD_XPON_MODE_1 0x414 +#define AIROHA_PCS_PMA_XFI_RX_MODE GENMASK(11, 9) +#define AIROHA_PCS_PMA_XFI_RX_MODE_10G3 FIELD_PREP_CONST(AIROHA_PCS_PMA_XFI_RX_MODE, 0x0) +#define AIROHA_PCS_PMA_XFI_RX_MODE_5G15 FIELD_PREP_CONST(AIROHA_PCS_PMA_XFI_RX_MODE, 0x1) +#define AIROHA_PCS_PMA_XFI_RX_MODE_6G25 FIELD_PREP_CONST(AIROHA_PCS_PMA_XFI_RX_MODE, 0x2) +#define AIROHA_PCS_PMA_XFI_RX_MODE_2G57 FIELD_PREP_CONST(AIROHA_PCS_PMA_XFI_RX_MODE, 0x3) +#define AIROHA_PCS_PMA_XFI_RX_MODE_3G12 FIELD_PREP_CONST(AIROHA_PCS_PMA_XFI_RX_MODE, 0x4) +#define AIROHA_PCS_PMA_XFI_RX_MODE_1G25 FIELD_PREP_CONST(AIROHA_PCS_PMA_XFI_RX_MODE, 0x5) +#define AIROHA_PCS_PMA_R2T_MODE BIT(8) +#define AIROHA_PCS_PMA_XFI_TX_MODE GENMASK(5, 3) +#define AIROHA_PCS_PMA_XFI_TX_MODE_10G3 FIELD_PREP_CONST(AIROHA_PCS_PMA_XFI_TX_MODE, 0x0) +#define AIROHA_PCS_PMA_XFI_TX_MODE_5G15 FIELD_PREP_CONST(AIROHA_PCS_PMA_XFI_TX_MODE, 0x1) +#define AIROHA_PCS_PMA_XFI_TX_MODE_6G25 FIELD_PREP_CONST(AIROHA_PCS_PMA_XFI_TX_MODE, 0x2) +#define AIROHA_PCS_PMA_XFI_TX_MODE_2G57 FIELD_PREP_CONST(AIROHA_PCS_PMA_XFI_TX_MODE, 0x3) +#define AIROHA_PCS_PMA_XFI_TX_MODE_3G12 FIELD_PREP_CONST(AIROHA_PCS_PMA_XFI_TX_MODE, 0x4) +#define AIROHA_PCS_PMA_XFI_TX_MODE_1G25 FIELD_PREP_CONST(AIROHA_PCS_PMA_XFI_TX_MODE, 0x5) +#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_XFI_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_FE_PEAKING_CTRL BIT(24) +#define AIROHA_PCS_PMA_FORCE_DA_RX_FE_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_PMA_DIG_RESERVE_29 0x910 +#define AIROHA_PCS_PMA_2L_TX_RATE_CTRL GENMASK(1, 0) +#define AIROHA_PCS_PMA_2L_RX_RATE_CTRL GENMASK(5, 4) + +#define AIROHA_PCS_MAX_CALIBRATION_TRY 50 +#define AIROHA_PCS_MAX_NUM_RSTS 2 + +enum xfi_port_type { + AIROHA_PCS_ETH, + AIROHA_PCS_PON, + AIROHA_PCS_USB, + AIROHA_PCS_PCIE, +}; + +struct airoha_pcs_maps { + struct regmap *pcs_mac; + struct regmap *hsgmii_an; + struct regmap *hsgmii_pcs; + struct regmap *hsgmii_rate_adp; + struct regmap *multi_sgmii; + struct regmap *usxgmii_pcs; +}; + +struct airoha_pcs_priv { + struct device *dev; + const struct airoha_pcs_match_data *data; + phy_interface_t interface; + + struct airoha_pcs_port *ports; + + struct regmap *scu; + + struct airoha_pcs_maps maps[2]; + + struct regmap *pcs_pma[2]; + struct regmap *pcs_ana; + struct regmap_field **pcs_ana_fields[2]; + + struct reset_control_bulk_data rsts[AIROHA_PCS_MAX_NUM_RSTS]; + + struct phy *phy; + + bool manual_rx_calib; +}; + +struct airoha_pcs_port { + struct airoha_pcs_priv *priv; + int index; + + struct phylink_pcs pcs; +}; + +struct airoha_pcs_match_data { + int num_port; + enum xfi_port_type port_type; + + int (*alloc_regmap_fields)(struct airoha_pcs_priv *priv); + int (*bringup)(struct airoha_pcs_priv *priv, + int index, phy_interface_t interface); + void (*link_up)(struct airoha_pcs_priv *priv, int index); + int (*rxlock_workaround)(struct airoha_pcs_priv *priv, int index); +}; + +#define to_airoha_pcs_port(n) container_of(n, struct airoha_pcs_port, pcs) + +#ifdef CONFIG_PCS_AIROHA_AN7581 +int an7581_pcs_alloc_regmap_fields(struct airoha_pcs_priv *priv); +int an7581_pcs_pcie_alloc_regmap_fields(struct airoha_pcs_priv *priv); +int an7581_pcs_bringup(struct airoha_pcs_priv *priv, + int index, phy_interface_t interface); +int an7581_pcs_usb_bringup(struct airoha_pcs_priv *priv, + int index, phy_interface_t interface); + +void an7581_pcs_phya_link_up(struct airoha_pcs_priv *priv, int index); +int an7581_pcs_rxlock_workaround(struct airoha_pcs_priv *priv, int index); +#else +static inline int an7581_pcs_alloc_regmap_fields(struct airoha_pcs_priv *priv) +{ + return -EOPNOTSUPP; +} + +static inline int an7581_pcs_pcie_alloc_regmap_fields(struct airoha_pcs_priv *priv) +{ + return -EOPNOTSUPP; +} + +static inline int an7581_pcs_bringup(struct airoha_pcs_priv *priv, + int index, phy_interface_t interface) +{ + return -EOPNOTSUPP; +} + +static inline int an7581_pcs_usb_bringup(struct airoha_pcs_priv *priv, + int index, phy_interface_t interface) +{ + return -EOPNOTSUPP; +} + +static inline void an7581_pcs_phya_link_up(struct airoha_pcs_priv *priv, + int index) +{ +} + +static inline int an7581_pcs_rxlock_workaround(struct airoha_pcs_priv *priv, + int index) +{ + return 0; +} +#endif diff --git a/drivers/net/pcs/airoha/pcs-an7581.c b/drivers/net/pcs/airoha/pcs-an7581.c new file mode 100644 index 000000000000..22cf7b4b0108 --- /dev/null +++ b/drivers/net/pcs/airoha/pcs-an7581.c @@ -0,0 +1,2093 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Copyright (c) 2024 AIROHA Inc + * Author: Christian Marangi + */ +#include +#include +#include + +#include "pcs-airoha.h" + +#include + +enum { + AN7581_PCS_CMN_EN, + + AN7581_PCS_JCPLL_SPARE_L, + AN7581_PCS_JCPLL_RST_DLY, + AN7581_PCS_JCPLL_PLL_RSTB, + AN7581_PCS_JCPLL_SDM_DI_LS, + AN7581_PCS_JCPLL_SDM_DI_EN, + + AN7581_PCS_JCPLL_SDM_OUT, + AN7581_PCS_JCPLL_SDM_ORD, + AN7581_PCS_JCPLL_SDM_MODE, + AN7581_PCS_JCPLL_SDM_IFM, + AN7581_PCS_JCPLL_SDM_HREN, + + AN7581_PCS_JCPLL_CHP_IOFST, + AN7581_PCS_JCPLL_CHP_IBIAS, + AN7581_PCS_JCPLL_LPF_SHCK_EN, + + AN7581_PCS_JCPLL_LPF_BWR, + AN7581_PCS_JCPLL_LPF_BP, + AN7581_PCS_JCPLL_LPF_BC, + AN7581_PCS_JCPLL_LPF_BR, + AN7581_PCS_JCPLL_LPF_BWC, + + AN7581_PCS_JCPLL_VCO_SCAPWR, + AN7581_PCS_JCPLL_VCO_HALFLSB_EN, + AN7581_PCS_JCPLL_VCO_CFIX, + AN7581_PCS_JCPLL_VCODIV, + AN7581_PCS_JCPLL_VCO_VCOVAR_BIAS_L, + AN7581_PCS_JCPLL_VCO_VCOVAR_BIAS_H, + AN7581_PCS_JCPLL_VCO_TCLVAR, + + AN7581_PCS_JCPLL_POSTDIV_D5, + AN7581_PCS_JCPLL_MMD_PREDIV_MODE, + + AN7581_PCS_JCPLL_KBAND_KS, + AN7581_PCS_JCPLL_KBAND_KF, + AN7581_PCS_JCPLL_KBAND_KFC, + AN7581_PCS_JCPLL_KBAND_DIV, + AN7581_PCS_JCPLL_KBAND_CODE, + AN7581_PCS_JCPLL_KBAND_OPTION, + + AN7581_PCS_JCPLL_TCL_AMP_VREF, + AN7581_PCS_JCPLL_TCL_AMP_GAIN, + AN7581_PCS_JCPLL_TCL_AMP_EN, + + AN7581_PCS_JCPLL_TCL_LPF_BW, + AN7581_PCS_JCPLL_TCL_LPF_EN, + + AN7581_PCS_JCPLL_SSC_DELTA, + AN7581_PCS_JCPLL_SSC_DELTA1, + AN7581_PCS_JCPLL_SSC_PERIOD, + AN7581_PCS_JCPLL_SSC_TRI_EN, + AN7581_PCS_JCPLL_SSC_EN, + AN7581_PCS_JCPLL_SSC_PHASE_INI, + AN7581_PCS_JCPLL_TCL_KBAND_VREF, + + AN7581_PCS_TXPLL_LDO_VCO_OUT, + AN7581_PCS_TXPLL_LDO_OUT, + AN7581_PCS_TXPLL_PLL_RSTB, + AN7581_PCS_TXPLL_RST_DLY, + AN7581_PCS_TXPLL_REFIN_DIV, + AN7581_PCS_TXPLL_REFIN_INTERNAL, + AN7581_PCS_TXPLL_SDM_MODE, + AN7581_PCS_TXPLL_SDM_IFM, + AN7581_PCS_TXPLL_SDM_DI_LS, + AN7581_PCS_TXPLL_SDM_DI_EN, + AN7581_PCS_TXPLL_SDM_HREN, + AN7581_PCS_TXPLL_SDM_ORD, + AN7581_PCS_TXPLL_SDM_OUT, + AN7581_PCS_TXPLL_SSC_DELTA1, + AN7581_PCS_TXPLL_SSC_DELTA, + AN7581_PCS_TXPLL_SSC_TRI_EN, + AN7581_PCS_TXPLL_SSC_PHASE_INI, + AN7581_PCS_TXPLL_SSC_EN, + AN7581_PCS_TXPLL_SSC_PERIOD, + AN7581_PCS_TXPLL_LPF_BC, + AN7581_PCS_TXPLL_LPF_BR, + AN7581_PCS_TXPLL_LPF_BP, + AN7581_PCS_TXPLL_LPF_BWC, + AN7581_PCS_TXPLL_LPF_BWR, + AN7581_PCS_TXPLL_CHP_IOFST, + AN7581_PCS_TXPLL_CHP_IBIAS, + AN7581_PCS_TXPLL_VCO_CFIX, + AN7581_PCS_TXPLL_VCO_VCOVAR_BIAS_L, + AN7581_PCS_TXPLL_VCO_VCOVAR_BIAS_H, + AN7581_PCS_TXPLL_VCO_TCLVAR, + AN7581_PCS_TXPLL_VCO_SCAPWR, + AN7581_PCS_TXPLL_VCO_HALFLSB_EN, + AN7581_PCS_TXPLL_KBAND_CODE, + AN7581_PCS_TXPLL_KBAND_OPTION, + AN7581_PCS_TXPLL_KBAND_KS, + AN7581_PCS_TXPLL_KBAND_KF, + AN7581_PCS_TXPLL_KBAND_KFC, + AN7581_PCS_TXPLL_KBAND_DIV, + AN7581_PCS_TXPLL_MMD_PREDIV_MODE, + AN7581_PCS_TXPLL_POSTDIV_EN, + AN7581_PCS_TXPLL_VCODIV, + AN7581_PCS_TXPLL_TCL_KBAND_VREF, + AN7581_PCS_TXPLL_TCL_AMP_GAIN, + AN7581_PCS_TXPLL_TCL_AMP_VREF, + AN7581_PCS_TXPLL_TCL_LPF_BW, + AN7581_PCS_TXPLL_TCL_LPF_EN, + AN7581_PCS_TXPLL_TCL_AMP_EN, + + AN7581_PCS_TX_DMEDGEGEN_EN, + AN7581_PCS_TX_CKLDO_EN, + + AN7581_PCS_RX_DAC_EYE_BYPASS_AEQ, + AN7581_PCS_RX_DAC_E1_BYPASS_AEQ, + AN7581_PCS_RX_DAC_E0_BYPASS_AEQ, + AN7581_PCS_RX_DAC_D1_BYPASS_AEQ, + AN7581_PCS_RX_DAC_D0_BYPASS_AEQ, + AN7581_PCS_RX_FE_VCM_GEN_PWDB, + AN7581_PCS_RX_OSCAL_FORCE, + AN7581_PCS_RX_DAC_MON, + AN7581_PCS_RX_REV_1_FE_BUF1_BIAS_CTRL, + AN7581_PCS_RX_REV_1_FE_BUF2_BIAS_CTRL, + AN7581_PCS_RX_REV_1_SIGDET_ILEAK, + AN7581_PCS_RX_FE_VB_EQ3_EN, + AN7581_PCS_RX_FE_VB_EQ2_EN, + AN7581_PCS_RX_FE_VB_EQ1_EN, + AN7581_PCS_RX_FE_EQ_HZEN, + AN7581_PCS_RX_SIGDET_VTH_SEL, + AN7581_PCS_RX_SIGDET_PEAK, + AN7581_PCS_RX_SIGDET_LPF_CTRL, + AN7581_PCS_RX_TDC_CK_SEL, + AN7581_PCS_RX_PHYCK_RSTB, + AN7581_PCS_RX_PHYCK_SEL, + AN7581_PCS_RX_PHYCK_DIV, + AN7581_PCS_RX_PHY_CK_SEL_FORCE, + AN7581_PCS_RX_PHY_CK_SEL, + + AN7581_PCS_AEQ_OFORCE, + + AN7581_PCS_CDR_PD_EDGE_DIS, + AN7581_PCS_CDR_PD_PICAL_CKD8_INV, + + AN7581_PCS_CDR_PR_XFICK_EN, + AN7581_PCS_CDR_PR_MONPI_EN, + AN7581_PCS_CDR_PR_MONPR_EN, + AN7581_PCS_CDR_PR_KBAND_DIV, + AN7581_PCS_CDR_PR_BETA_SEL, + AN7581_PCS_CDR_PR_VCOADC_OS, + AN7581_PCS_CDR_PR_BETA_DAC, + AN7581_PCS_CDR_PR_FBKSEL, + AN7581_PCS_CDR_PR_DAC_BAND, + AN7581_PCS_CDR_PR_VREG_CKBUF_VAL, + AN7581_PCS_CDR_PR_VREG_IBAND_VAL, + AN7581_PCS_CDR_PR_CAP_EN, + AN7581_PCS_CDR_PR_INJ_FORCE_OFF, + + AN7581_PCS_CDR_BUF_IN_SR, + + AN7581_PCS_CDR_LPF_TOP_LIM, + AN7581_PCS_CDR_LPF_RATIO, + + AN7581_PCS_FIELDS_MAX, +}; + +static const struct reg_field an7581_pcs_fields[AN7581_PCS_FIELDS_MAX] = { + [AN7581_PCS_CMN_EN] = REG_FIELD(AIROHA_PCS_ANA_PXP_CMN_EN, 0, 0), + + [AN7581_PCS_JCPLL_SPARE_L] = REG_FIELD(AIROHA_PCS_ANA_PXP_JCPLL_SPARE_H, 8, 15), + + [AN7581_PCS_JCPLL_RST_DLY] = REG_FIELD(AIROHA_PCS_ANA_PXP_JCPLL_RST_DLY, 0, 2), + [AN7581_PCS_JCPLL_PLL_RSTB] = REG_FIELD(AIROHA_PCS_ANA_PXP_JCPLL_RST_DLY, 8, 8), + [AN7581_PCS_JCPLL_SDM_DI_LS] = REG_FIELD(AIROHA_PCS_ANA_PXP_JCPLL_RST_DLY, 16, 16), + [AN7581_PCS_JCPLL_SDM_DI_EN] = REG_FIELD(AIROHA_PCS_ANA_PXP_JCPLL_RST_DLY, 24, 25), + + [AN7581_PCS_JCPLL_SDM_OUT] = REG_FIELD(AIROHA_PCS_ANA_PXP_JCPLL_SDM_IFM, 24, 24), + [AN7581_PCS_JCPLL_SDM_ORD] = REG_FIELD(AIROHA_PCS_ANA_PXP_JCPLL_SDM_IFM, 16, 17), + [AN7581_PCS_JCPLL_SDM_MODE] = REG_FIELD(AIROHA_PCS_ANA_PXP_JCPLL_SDM_IFM, 8, 9), + [AN7581_PCS_JCPLL_SDM_IFM] = REG_FIELD(AIROHA_PCS_ANA_PXP_JCPLL_SDM_IFM, 0, 0), + [AN7581_PCS_JCPLL_SDM_HREN] = REG_FIELD(AIROHA_PCS_ANA_PXP_JCPLL_SDM_HREN, 0, 0), + + [AN7581_PCS_JCPLL_SSC_PERIOD] = REG_FIELD(AIROHA_PCS_ANA_PXP_JCPLL_SSC_DELTA, 16, 31), + [AN7581_PCS_JCPLL_SSC_DELTA] = REG_FIELD(AIROHA_PCS_ANA_PXP_JCPLL_SSC_DELTA, 0, 15), + [AN7581_PCS_JCPLL_SSC_DELTA1] = REG_FIELD(AIROHA_PCS_ANA_PXP_JCPLL_SSC_TRI_EN, 8, 23), + [AN7581_PCS_JCPLL_SSC_TRI_EN] = REG_FIELD(AIROHA_PCS_ANA_PXP_JCPLL_SSC_TRI_EN, 0, 0), + [AN7581_PCS_JCPLL_SSC_PHASE_INI] = REG_FIELD(AIROHA_PCS_ANA_PXP_JCPLL_VCO_TCLVAR, 17, 17), + [AN7581_PCS_JCPLL_SSC_EN] = REG_FIELD(AIROHA_PCS_ANA_PXP_JCPLL_VCO_TCLVAR, 16, 16), + [AN7581_PCS_JCPLL_TCL_KBAND_VREF] = REG_FIELD(AIROHA_PCS_ANA_PXP_JCPLL_SPARE_H, 16, 20), + + [AN7581_PCS_JCPLL_CHP_IOFST] = REG_FIELD(AIROHA_PCS_ANA_PXP_JCPLL_IB_EXT_EN, 24, 29), + [AN7581_PCS_JCPLL_CHP_IBIAS] = REG_FIELD(AIROHA_PCS_ANA_PXP_JCPLL_IB_EXT_EN, 16, 21), + [AN7581_PCS_JCPLL_LPF_SHCK_EN] = REG_FIELD(AIROHA_PCS_ANA_PXP_JCPLL_IB_EXT_EN, 8, 8), + + [AN7581_PCS_JCPLL_LPF_BWR] = REG_FIELD(AIROHA_PCS_ANA_PXP_JCPLL_LPF_BR, 24, 28), + [AN7581_PCS_JCPLL_LPF_BP] = REG_FIELD(AIROHA_PCS_ANA_PXP_JCPLL_LPF_BR, 16, 20), + [AN7581_PCS_JCPLL_LPF_BC] = REG_FIELD(AIROHA_PCS_ANA_PXP_JCPLL_LPF_BR, 8, 12), + [AN7581_PCS_JCPLL_LPF_BR] = REG_FIELD(AIROHA_PCS_ANA_PXP_JCPLL_LPF_BR, 0, 4), + [AN7581_PCS_JCPLL_LPF_BWC] = REG_FIELD(AIROHA_PCS_ANA_PXP_JCPLL_LPF_BWC, 0, 4), + + [AN7581_PCS_JCPLL_VCO_SCAPWR] = REG_FIELD(AIROHA_PCS_ANA_PXP_JCPLL_VCODIV, 24, 26), + [AN7581_PCS_JCPLL_VCO_HALFLSB_EN] = REG_FIELD(AIROHA_PCS_ANA_PXP_JCPLL_VCODIV, 16, 16), + [AN7581_PCS_JCPLL_VCO_CFIX] = REG_FIELD(AIROHA_PCS_ANA_PXP_JCPLL_VCODIV, 8, 9), + [AN7581_PCS_JCPLL_VCODIV] = REG_FIELD(AIROHA_PCS_ANA_PXP_JCPLL_VCODIV, 0, 1), + [AN7581_PCS_JCPLL_VCO_VCOVAR_BIAS_L] = REG_FIELD(AIROHA_PCS_ANA_PXP_JCPLL_VCO_TCLVAR, 8, 10), + [AN7581_PCS_JCPLL_VCO_VCOVAR_BIAS_H] = REG_FIELD(AIROHA_PCS_ANA_PXP_JCPLL_VCO_TCLVAR, 3, 5), + [AN7581_PCS_JCPLL_VCO_TCLVAR] = REG_FIELD(AIROHA_PCS_ANA_PXP_JCPLL_VCO_TCLVAR, 0, 2), + + [AN7581_PCS_JCPLL_POSTDIV_D5] = REG_FIELD(AIROHA_PCS_ANA_PXP_JCPLL_MMD_PREDIV_MODE, 24, 24), + [AN7581_PCS_JCPLL_MMD_PREDIV_MODE] = REG_FIELD(AIROHA_PCS_ANA_PXP_JCPLL_MMD_PREDIV_MODE, 0, 1), + + [AN7581_PCS_JCPLL_KBAND_KS] = REG_FIELD(AIROHA_PCS_ANA_PXP_JCPLL_KBAND_KFC, 16, 17), + [AN7581_PCS_JCPLL_KBAND_KF] = REG_FIELD(AIROHA_PCS_ANA_PXP_JCPLL_KBAND_KFC, 8, 9), + [AN7581_PCS_JCPLL_KBAND_KFC] = REG_FIELD(AIROHA_PCS_ANA_PXP_JCPLL_KBAND_KFC, 0, 1), + [AN7581_PCS_JCPLL_KBAND_DIV] = REG_FIELD(AIROHA_PCS_ANA_PXP_JCPLL_LPF_BWC, 24, 26), + [AN7581_PCS_JCPLL_KBAND_CODE] = REG_FIELD(AIROHA_PCS_ANA_PXP_JCPLL_LPF_BWC, 16, 23), + [AN7581_PCS_JCPLL_KBAND_OPTION] = REG_FIELD(AIROHA_PCS_ANA_PXP_JCPLL_LPF_BWC, 8, 8), + + [AN7581_PCS_JCPLL_TCL_AMP_VREF] = REG_FIELD(AIROHA_PCS_ANA_PXP_JCPLL_SDM_HREN, 24, 28), + [AN7581_PCS_JCPLL_TCL_AMP_GAIN] = REG_FIELD(AIROHA_PCS_ANA_PXP_JCPLL_SDM_HREN, 16, 18), + [AN7581_PCS_JCPLL_TCL_AMP_EN] = REG_FIELD(AIROHA_PCS_ANA_PXP_JCPLL_SDM_HREN, 8, 8), + + [AN7581_PCS_JCPLL_TCL_LPF_BW] = REG_FIELD(AIROHA_PCS_ANA_PXP_JCPLL_TCL_CMP_EN, 24, 26), + [AN7581_PCS_JCPLL_TCL_LPF_EN] = REG_FIELD(AIROHA_PCS_ANA_PXP_JCPLL_TCL_CMP_EN, 16, 16), + + [AN7581_PCS_TXPLL_LDO_VCO_OUT] = REG_FIELD(AIROHA_PCS_ANA_PXP_TXPLL_SSC_PERIOD, 24, 25), + [AN7581_PCS_TXPLL_LDO_OUT] = REG_FIELD(AIROHA_PCS_ANA_PXP_TXPLL_SSC_PERIOD, 16, 17), + [AN7581_PCS_TXPLL_PLL_RSTB] = REG_FIELD(AIROHA_PCS_ANA_PXP_TXPLL_REFIN_INTERNAL, 24, 24), + [AN7581_PCS_TXPLL_RST_DLY] = REG_FIELD(AIROHA_PCS_ANA_PXP_TXPLL_REFIN_INTERNAL, 16, 18), + [AN7581_PCS_TXPLL_REFIN_DIV] = REG_FIELD(AIROHA_PCS_ANA_PXP_TXPLL_REFIN_INTERNAL, 8, 9), + [AN7581_PCS_TXPLL_REFIN_INTERNAL] = REG_FIELD(AIROHA_PCS_ANA_PXP_TXPLL_REFIN_INTERNAL, 0, 0), + [AN7581_PCS_TXPLL_SDM_MODE] = REG_FIELD(AIROHA_PCS_ANA_PXP_TXPLL_SDM_DI_EN, 24, 25), + [AN7581_PCS_TXPLL_SDM_IFM] = REG_FIELD(AIROHA_PCS_ANA_PXP_TXPLL_SDM_DI_EN, 16, 16), + [AN7581_PCS_TXPLL_SDM_DI_LS] = REG_FIELD(AIROHA_PCS_ANA_PXP_TXPLL_SDM_DI_EN, 8, 9), + [AN7581_PCS_TXPLL_SDM_DI_EN] = REG_FIELD(AIROHA_PCS_ANA_PXP_TXPLL_SDM_DI_EN, 0, 0), + [AN7581_PCS_TXPLL_SDM_HREN] = REG_FIELD(AIROHA_PCS_ANA_PXP_TXPLL_SDM_ORD, 16, 16), + [AN7581_PCS_TXPLL_SDM_OUT] = REG_FIELD(AIROHA_PCS_ANA_PXP_TXPLL_SDM_ORD, 8, 8), + [AN7581_PCS_TXPLL_SDM_ORD] = REG_FIELD(AIROHA_PCS_ANA_PXP_TXPLL_SDM_ORD, 0, 1), + [AN7581_PCS_TXPLL_SSC_DELTA1] = REG_FIELD(AIROHA_PCS_ANA_PXP_TXPLL_SSC_DELTA1, 16, 31), + [AN7581_PCS_TXPLL_SSC_DELTA] = REG_FIELD(AIROHA_PCS_ANA_PXP_TXPLL_SSC_DELTA1, 0, 15), + [AN7581_PCS_TXPLL_SSC_TRI_EN] = REG_FIELD(AIROHA_PCS_ANA_PXP_TXPLL_SSC_EN, 16, 16), + [AN7581_PCS_TXPLL_SSC_PHASE_INI] = REG_FIELD(AIROHA_PCS_ANA_PXP_TXPLL_SSC_EN, 8, 8), + [AN7581_PCS_TXPLL_SSC_EN] = REG_FIELD(AIROHA_PCS_ANA_PXP_TXPLL_SSC_EN, 0, 0), + [AN7581_PCS_TXPLL_SSC_PERIOD] = REG_FIELD(AIROHA_PCS_ANA_PXP_TXPLL_SSC_PERIOD, 0, 15), + [AN7581_PCS_TXPLL_LPF_BC] = REG_FIELD(AIROHA_PCS_ANA_PXP_TXPLL_CHP_IBIAS, 24, 28), + [AN7581_PCS_TXPLL_LPF_BR] = REG_FIELD(AIROHA_PCS_ANA_PXP_TXPLL_CHP_IBIAS, 16, 20), + [AN7581_PCS_TXPLL_CHP_IOFST] = REG_FIELD(AIROHA_PCS_ANA_PXP_TXPLL_CHP_IBIAS, 8, 13), + [AN7581_PCS_TXPLL_CHP_IBIAS] = REG_FIELD(AIROHA_PCS_ANA_PXP_TXPLL_CHP_IBIAS, 0, 5), + [AN7581_PCS_TXPLL_LPF_BWC] = REG_FIELD(AIROHA_PCS_ANA_PXP_TXPLL_LPF_BP, 16, 20), + [AN7581_PCS_TXPLL_LPF_BWR] = REG_FIELD(AIROHA_PCS_ANA_PXP_TXPLL_LPF_BP, 8, 12), + [AN7581_PCS_TXPLL_LPF_BP] = REG_FIELD(AIROHA_PCS_ANA_PXP_TXPLL_LPF_BP, 0, 4), + [AN7581_PCS_TXPLL_VCO_CFIX] = REG_FIELD(AIROHA_PCS_ANA_PXP_TXPLL_TCL_LPF_EN, 24, 25), + [AN7581_PCS_TXPLL_VCO_VCOVAR_BIAS_L] = REG_FIELD(AIROHA_PCS_ANA_PXP_TXPLL_VCO_HALFLSB_EN, 27, 29), + [AN7581_PCS_TXPLL_VCO_VCOVAR_BIAS_H] = REG_FIELD(AIROHA_PCS_ANA_PXP_TXPLL_VCO_HALFLSB_EN, 24, 26), + [AN7581_PCS_TXPLL_VCO_TCLVAR] = REG_FIELD(AIROHA_PCS_ANA_PXP_TXPLL_VCO_HALFLSB_EN, 16, 18), + [AN7581_PCS_TXPLL_VCO_SCAPWR] = REG_FIELD(AIROHA_PCS_ANA_PXP_TXPLL_VCO_HALFLSB_EN, 8, 10), + [AN7581_PCS_TXPLL_VCO_HALFLSB_EN] = REG_FIELD(AIROHA_PCS_ANA_PXP_TXPLL_VCO_HALFLSB_EN, 0, 0), + [AN7581_PCS_TXPLL_KBAND_CODE] = REG_FIELD(AIROHA_PCS_ANA_PXP_TXPLL_KBAND_CODE, 0, 7), + [AN7581_PCS_TXPLL_KBAND_OPTION] = REG_FIELD(AIROHA_PCS_ANA_PXP_TXPLL_LPF_BP, 24, 24), + [AN7581_PCS_TXPLL_KBAND_KS] = REG_FIELD(AIROHA_PCS_ANA_PXP_TXPLL_KBAND_KS, 0, 1), + [AN7581_PCS_TXPLL_KBAND_KF] = REG_FIELD(AIROHA_PCS_ANA_PXP_TXPLL_KBAND_CODE, 24, 25), + [AN7581_PCS_TXPLL_KBAND_KFC] = REG_FIELD(AIROHA_PCS_ANA_PXP_TXPLL_KBAND_CODE, 16, 17), + [AN7581_PCS_TXPLL_KBAND_DIV] = REG_FIELD(AIROHA_PCS_ANA_PXP_TXPLL_KBAND_CODE, 8, 10), + [AN7581_PCS_TXPLL_MMD_PREDIV_MODE] = REG_FIELD(AIROHA_PCS_ANA_PXP_TXPLL_KBAND_KS, 16, 17), + [AN7581_PCS_TXPLL_POSTDIV_EN] = REG_FIELD(AIROHA_PCS_ANA_PXP_TXPLL_KBAND_KS, 8, 8), + [AN7581_PCS_TXPLL_VCODIV] = REG_FIELD(AIROHA_PCS_ANA_PXP_TXPLL_TCL_LPF_EN, 16, 17), + [AN7581_PCS_TXPLL_TCL_KBAND_VREF] = REG_FIELD(AIROHA_PCS_ANA_PXP_TXPLL_TCL_KBAND_VREF, 0, 4), + [AN7581_PCS_TXPLL_TCL_AMP_GAIN] = REG_FIELD(AIROHA_PCS_ANA_PXP_TXPLL_TCL_AMP_GAIN, 0, 2), + [AN7581_PCS_TXPLL_TCL_AMP_VREF] = REG_FIELD(AIROHA_PCS_ANA_PXP_TXPLL_TCL_AMP_GAIN, 8, 12), + [AN7581_PCS_TXPLL_TCL_LPF_BW] = REG_FIELD(AIROHA_PCS_ANA_PXP_TXPLL_TCL_LPF_EN, 8, 10), + [AN7581_PCS_TXPLL_TCL_LPF_EN] = REG_FIELD(AIROHA_PCS_ANA_PXP_TXPLL_TCL_LPF_EN, 0, 0), + [AN7581_PCS_TXPLL_TCL_AMP_EN] = REG_FIELD(AIROHA_PCS_ANA_PXP_TXPLL_SDM_ORD, 24, 24), + + [AN7581_PCS_TX_DMEDGEGEN_EN] = REG_FIELD(AIROHA_PCS_ANA_PXP_TX_CKLDO_EN, 24, 24), + [AN7581_PCS_TX_CKLDO_EN] = REG_FIELD(AIROHA_PCS_ANA_PXP_TX_CKLDO_EN, 0, 0), + + [AN7581_PCS_RX_DAC_EYE_BYPASS_AEQ] = REG_FIELD(AIROHA_PCS_ANA_PXP_RX_DAC_D1_BYPASS_AEQ, 24, 24), + [AN7581_PCS_RX_DAC_E1_BYPASS_AEQ] = REG_FIELD(AIROHA_PCS_ANA_PXP_RX_DAC_D1_BYPASS_AEQ, 16, 16), + [AN7581_PCS_RX_DAC_E0_BYPASS_AEQ] = REG_FIELD(AIROHA_PCS_ANA_PXP_RX_DAC_D1_BYPASS_AEQ, 8, 8), + [AN7581_PCS_RX_DAC_D1_BYPASS_AEQ] = REG_FIELD(AIROHA_PCS_ANA_PXP_RX_DAC_D1_BYPASS_AEQ, 0, 0), + [AN7581_PCS_RX_DAC_D0_BYPASS_AEQ] = REG_FIELD(AIROHA_PCS_ANA_PXP_RX_FE_PEAKING_CTRL_MSB, 24, 24), + [AN7581_PCS_RX_FE_VCM_GEN_PWDB] = REG_FIELD(AIROHA_PCS_ANA_PXP_RX_FE_VCM_GEN_PWDB, 0, 0), + + [AN7581_PCS_AEQ_OFORCE] = REG_FIELD(AIROHA_PCS_ANA_PXP_AEQ_CFORCE, 8, 19), + [AN7581_PCS_RX_OSCAL_FORCE] = REG_FIELD(AIROHA_PCS_ANA_PXP_RX_OSCAL_WATCH_WNDW, 8, 17), + + [AN7581_PCS_CDR_PD_EDGE_DIS] = REG_FIELD(AIROHA_PCS_ANA_PXP_CDR_PD_PICAL_CKD8_INV, 8, 8), + [AN7581_PCS_CDR_PD_PICAL_CKD8_INV] = REG_FIELD(AIROHA_PCS_ANA_PXP_CDR_PD_PICAL_CKD8_INV, 0, 0), + + [AN7581_PCS_RX_DAC_MON] = REG_FIELD(AIROHA_PCS_ANA_PXP_CDR_PR_MONPR_EN, 24, 28), + [AN7581_PCS_CDR_PR_XFICK_EN] = REG_FIELD(AIROHA_PCS_ANA_PXP_CDR_PR_MONPR_EN, 2, 2), + [AN7581_PCS_CDR_PR_MONPI_EN] = REG_FIELD(AIROHA_PCS_ANA_PXP_CDR_PR_MONPR_EN, 1, 1), + [AN7581_PCS_CDR_PR_MONPR_EN] = REG_FIELD(AIROHA_PCS_ANA_PXP_CDR_PR_MONPR_EN, 0, 0), + + [AN7581_PCS_RX_REV_1_FE_BUF1_BIAS_CTRL] = REG_FIELD(AIROHA_PCS_ANA_PXP_RX_REV_0, 24, 26), + [AN7581_PCS_RX_REV_1_FE_BUF2_BIAS_CTRL] = REG_FIELD(AIROHA_PCS_ANA_PXP_RX_REV_0, 20, 22), + [AN7581_PCS_RX_REV_1_SIGDET_ILEAK] = REG_FIELD(AIROHA_PCS_ANA_PXP_RX_REV_0, 18, 19), + + [AN7581_PCS_CDR_LPF_TOP_LIM] = REG_FIELD(AIROHA_PCS_ANA_PXP_CDR_LPF_RATIO, 8, 26), + [AN7581_PCS_CDR_LPF_RATIO] = REG_FIELD(AIROHA_PCS_ANA_PXP_CDR_LPF_RATIO, 0, 1), + + [AN7581_PCS_CDR_PR_KBAND_DIV] = REG_FIELD(AIROHA_PCS_ANA_PXP_CDR_PR_BETA_DAC, 24, 26), + [AN7581_PCS_CDR_PR_BETA_SEL] = REG_FIELD(AIROHA_PCS_ANA_PXP_CDR_PR_BETA_DAC, 16, 19), + [AN7581_PCS_CDR_PR_VCOADC_OS] = REG_FIELD(AIROHA_PCS_ANA_PXP_CDR_PR_BETA_DAC, 8, 11), + [AN7581_PCS_CDR_PR_BETA_DAC] = REG_FIELD(AIROHA_PCS_ANA_PXP_CDR_PR_BETA_DAC, 0, 6), + [AN7581_PCS_CDR_PR_FBKSEL] = REG_FIELD(AIROHA_PCS_ANA_PXP_CDR_PR_VREG_IBAND_VAL, 24, 25), + [AN7581_PCS_CDR_PR_DAC_BAND] = REG_FIELD(AIROHA_PCS_ANA_PXP_CDR_PR_VREG_IBAND_VAL, 16, 20), + [AN7581_PCS_CDR_PR_VREG_CKBUF_VAL] = REG_FIELD(AIROHA_PCS_ANA_PXP_CDR_PR_VREG_IBAND_VAL, 8, 10), + [AN7581_PCS_CDR_PR_VREG_IBAND_VAL] = REG_FIELD(AIROHA_PCS_ANA_PXP_CDR_PR_VREG_IBAND_VAL, 0, 2), + + [AN7581_PCS_RX_FE_VB_EQ3_EN] = REG_FIELD(AIROHA_PCS_ANA_PXP_RX_FE_EQ_HZEN, 24, 24), + [AN7581_PCS_RX_FE_VB_EQ2_EN] = REG_FIELD(AIROHA_PCS_ANA_PXP_RX_FE_EQ_HZEN, 16, 16), + [AN7581_PCS_RX_FE_VB_EQ1_EN] = REG_FIELD(AIROHA_PCS_ANA_PXP_RX_FE_EQ_HZEN, 8, 8), + [AN7581_PCS_RX_FE_EQ_HZEN] = REG_FIELD(AIROHA_PCS_ANA_PXP_RX_FE_EQ_HZEN, 0, 0), + + [AN7581_PCS_CDR_PR_CAP_EN] = REG_FIELD(AIROHA_PCS_ANA_PXP_CDR_PR_MONPR_EN, 19, 19), + [AN7581_PCS_CDR_BUF_IN_SR] = REG_FIELD(AIROHA_PCS_ANA_PXP_CDR_PR_MONPR_EN, 16, 18), + + [AN7581_PCS_RX_SIGDET_VTH_SEL] = REG_FIELD(AIROHA_PCS_ANA_PXP_RX_SIGDET_NOVTH, 16, 20), + [AN7581_PCS_RX_SIGDET_PEAK] = REG_FIELD(AIROHA_PCS_ANA_PXP_RX_SIGDET_NOVTH, 8, 9), + [AN7581_PCS_RX_SIGDET_LPF_CTRL] = REG_FIELD(AIROHA_PCS_ANA_PXP_RX_DAC_RANGE, 24, 25), + + [AN7581_PCS_RX_TDC_CK_SEL] = REG_FIELD(AIROHA_PCS_ANA_PXP_RX_PHYCK_DIV, 24, 24), + [AN7581_PCS_RX_PHYCK_RSTB] = REG_FIELD(AIROHA_PCS_ANA_PXP_RX_PHYCK_DIV, 16, 16), + [AN7581_PCS_RX_PHYCK_SEL] = REG_FIELD(AIROHA_PCS_ANA_PXP_RX_PHYCK_DIV, 8, 9), + [AN7581_PCS_RX_PHYCK_DIV] = REG_FIELD(AIROHA_PCS_ANA_PXP_RX_PHYCK_DIV, 0, 7), + [AN7581_PCS_RX_PHY_CK_SEL_FORCE] = REG_FIELD(AIROHA_PCS_ANA_PXP_RX_BUSBIT_SEL, 24, 24), + [AN7581_PCS_RX_PHY_CK_SEL] = REG_FIELD(AIROHA_PCS_ANA_PXP_RX_BUSBIT_SEL, 16, 16), + + [AN7581_PCS_CDR_PR_INJ_FORCE_OFF] = REG_FIELD(AIROHA_PCS_ANA_PXP_CDR_PR_INJ_MODE, 24, 24), +}; + +static const struct reg_field an7581_pcs_pcie0_fields[AN7581_PCS_FIELDS_MAX] = { + [AN7581_PCS_CMN_EN] = REG_FIELD(AIROHA_PCS_ANA_PXP_2L_CMN_EN, 0, 0), + + [AN7581_PCS_JCPLL_SPARE_L] = REG_FIELD(AIROHA_PCS_ANA_PXP_2L_JCPLL_TCL_VTP_EN, 24, 31), + + [AN7581_PCS_JCPLL_RST_DLY] = REG_FIELD(AIROHA_PCS_ANA_PXP_2L_JCPLL_RST_DLY, 0, 2), + [AN7581_PCS_JCPLL_PLL_RSTB] = REG_FIELD(AIROHA_PCS_ANA_PXP_2L_JCPLL_RST_DLY, 8, 8), + [AN7581_PCS_JCPLL_SDM_DI_LS] = REG_FIELD(AIROHA_PCS_ANA_PXP_2L_JCPLL_RST_DLY, 16, 16), + [AN7581_PCS_JCPLL_SDM_DI_EN] = REG_FIELD(AIROHA_PCS_ANA_PXP_2L_JCPLL_RST_DLY, 24, 25), + + [AN7581_PCS_JCPLL_SDM_OUT] = REG_FIELD(AIROHA_PCS_ANA_PXP_2L_JCPLL_SDM_IFM, 24, 24), + [AN7581_PCS_JCPLL_SDM_ORD] = REG_FIELD(AIROHA_PCS_ANA_PXP_2L_JCPLL_SDM_IFM, 16, 17), + [AN7581_PCS_JCPLL_SDM_MODE] = REG_FIELD(AIROHA_PCS_ANA_PXP_2L_JCPLL_SDM_IFM, 8, 9), + [AN7581_PCS_JCPLL_SDM_IFM] = REG_FIELD(AIROHA_PCS_ANA_PXP_2L_JCPLL_SDM_IFM, 0, 0), + [AN7581_PCS_JCPLL_SDM_HREN] = REG_FIELD(AIROHA_PCS_ANA_PXP_2L_JCPLL_SDM_HREN, 0, 0), + + [AN7581_PCS_JCPLL_CHP_IOFST] = REG_FIELD(AIROHA_PCS_ANA_PXP_2L_JCPLL_IB_EXT_EN, 24, 29), + [AN7581_PCS_JCPLL_CHP_IBIAS] = REG_FIELD(AIROHA_PCS_ANA_PXP_2L_JCPLL_IB_EXT_EN, 16, 21), + [AN7581_PCS_JCPLL_LPF_SHCK_EN] = REG_FIELD(AIROHA_PCS_ANA_PXP_2L_JCPLL_IB_EXT_EN, 8, 8), + + [AN7581_PCS_JCPLL_LPF_BWR] = REG_FIELD(AIROHA_PCS_ANA_PXP_2L_JCPLL_LPF_BR, 24, 28), + [AN7581_PCS_JCPLL_LPF_BP] = REG_FIELD(AIROHA_PCS_ANA_PXP_2L_JCPLL_LPF_BR, 16, 20), + [AN7581_PCS_JCPLL_LPF_BC] = REG_FIELD(AIROHA_PCS_ANA_PXP_2L_JCPLL_LPF_BR, 8, 12), + [AN7581_PCS_JCPLL_LPF_BR] = REG_FIELD(AIROHA_PCS_ANA_PXP_2L_JCPLL_LPF_BR, 0, 4), + [AN7581_PCS_JCPLL_LPF_BWC] = REG_FIELD(AIROHA_PCS_ANA_PXP_2L_JCPLL_LPF_BWC, 0, 4), + + [AN7581_PCS_JCPLL_VCO_SCAPWR] = REG_FIELD(AIROHA_PCS_ANA_PXP_2L_JCPLL_VCODIV, 24, 26), + [AN7581_PCS_JCPLL_VCO_HALFLSB_EN] = REG_FIELD(AIROHA_PCS_ANA_PXP_2L_JCPLL_VCODIV, 16, 16), + [AN7581_PCS_JCPLL_VCO_CFIX] = REG_FIELD(AIROHA_PCS_ANA_PXP_2L_JCPLL_VCODIV, 8, 9), + [AN7581_PCS_JCPLL_VCODIV] = REG_FIELD(AIROHA_PCS_ANA_PXP_2L_JCPLL_VCODIV, 0, 1), + [AN7581_PCS_JCPLL_VCO_VCOVAR_BIAS_L] = REG_FIELD(AIROHA_PCS_ANA_PXP_2L_JCPLL_VCO_TCLVAR, 16, 18), + [AN7581_PCS_JCPLL_VCO_VCOVAR_BIAS_H] = REG_FIELD(AIROHA_PCS_ANA_PXP_2L_JCPLL_VCO_TCLVAR, 8, 10), + [AN7581_PCS_JCPLL_VCO_TCLVAR] = REG_FIELD(AIROHA_PCS_ANA_PXP_2L_JCPLL_VCO_TCLVAR, 0, 2), + + [AN7581_PCS_JCPLL_SSC_DELTA] = REG_FIELD(AIROHA_PCS_ANA_PXP_2L_JCPLL_SSC_DELTA1, 16, 31), + [AN7581_PCS_JCPLL_SSC_DELTA1] = REG_FIELD(AIROHA_PCS_ANA_PXP_2L_JCPLL_SSC_DELTA1, 0, 15), + [AN7581_PCS_JCPLL_SSC_PERIOD] = REG_FIELD(AIROHA_PCS_ANA_PXP_2L_JCPLL_SSC_PERIOD, 0, 15), + [AN7581_PCS_JCPLL_SSC_TRI_EN] = REG_FIELD(AIROHA_PCS_ANA_PXP_2L_JCPLL_SSC_EN, 16, 16), + [AN7581_PCS_JCPLL_SSC_PHASE_INI] = REG_FIELD(AIROHA_PCS_ANA_PXP_2L_JCPLL_SSC_EN, 8, 8), + [AN7581_PCS_JCPLL_SSC_EN] = REG_FIELD(AIROHA_PCS_ANA_PXP_2L_JCPLL_SSC_EN, 0, 0), + [AN7581_PCS_JCPLL_TCL_KBAND_VREF] = REG_FIELD(AIROHA_PCS_ANA_PXP_2L_JCPLL_TCL_KBAND_VREF, 0, 4), + + [AN7581_PCS_JCPLL_POSTDIV_D5] = REG_FIELD(AIROHA_PCS_ANA_PXP_2L_JCPLL_MMD_PREDIV_MODE, 24, 24), + [AN7581_PCS_JCPLL_MMD_PREDIV_MODE] = REG_FIELD(AIROHA_PCS_ANA_PXP_2L_JCPLL_MMD_PREDIV_MODE, 0, 1), + + [AN7581_PCS_JCPLL_KBAND_KS] = REG_FIELD(AIROHA_PCS_ANA_PXP_2L_JCPLL_KBAND_KFC, 16, 17), + [AN7581_PCS_JCPLL_KBAND_KF] = REG_FIELD(AIROHA_PCS_ANA_PXP_2L_JCPLL_KBAND_KFC, 8, 9), + [AN7581_PCS_JCPLL_KBAND_KFC] = REG_FIELD(AIROHA_PCS_ANA_PXP_2L_JCPLL_KBAND_KFC, 0, 1), + [AN7581_PCS_JCPLL_KBAND_DIV] = REG_FIELD(AIROHA_PCS_ANA_PXP_2L_JCPLL_LPF_BWC, 24, 26), + [AN7581_PCS_JCPLL_KBAND_CODE] = REG_FIELD(AIROHA_PCS_ANA_PXP_2L_JCPLL_LPF_BWC, 16, 23), + [AN7581_PCS_JCPLL_KBAND_OPTION] = REG_FIELD(AIROHA_PCS_ANA_PXP_2L_JCPLL_LPF_BWC, 8, 8), + + [AN7581_PCS_JCPLL_TCL_AMP_VREF] = REG_FIELD(AIROHA_PCS_ANA_PXP_2L_JCPLL_SDM_HREN, 24, 28), + [AN7581_PCS_JCPLL_TCL_AMP_GAIN] = REG_FIELD(AIROHA_PCS_ANA_PXP_2L_JCPLL_SDM_HREN, 16, 18), + [AN7581_PCS_JCPLL_TCL_AMP_EN] = REG_FIELD(AIROHA_PCS_ANA_PXP_2L_JCPLL_SDM_HREN, 8, 8), + + [AN7581_PCS_JCPLL_TCL_LPF_BW] = REG_FIELD(AIROHA_PCS_ANA_PXP_2L_JCPLL_TCL_CMP_EN, 24, 26), + [AN7581_PCS_JCPLL_TCL_LPF_EN] = REG_FIELD(AIROHA_PCS_ANA_PXP_2L_JCPLL_TCL_CMP_EN, 16, 16), + + [AN7581_PCS_TXPLL_LDO_VCO_OUT] = REG_FIELD(AIROHA_PCS_ANA_PXP_2L_TXPLL_SSC_PERIOD, 24, 25), + [AN7581_PCS_TXPLL_LDO_OUT] = REG_FIELD(AIROHA_PCS_ANA_PXP_2L_TXPLL_SSC_PERIOD, 16, 17), + [AN7581_PCS_TXPLL_PLL_RSTB] = REG_FIELD(AIROHA_PCS_ANA_PXP_2L_TXPLL_REFIN_DIV, 16, 16), + [AN7581_PCS_TXPLL_RST_DLY] = REG_FIELD(AIROHA_PCS_ANA_PXP_2L_TXPLL_REFIN_DIV, 8, 10), + [AN7581_PCS_TXPLL_REFIN_DIV] = REG_FIELD(AIROHA_PCS_ANA_PXP_2L_TXPLL_REFIN_DIV, 0, 1), + [AN7581_PCS_TXPLL_REFIN_INTERNAL] = REG_FIELD(AIROHA_PCS_ANA_PXP_2L_TXPLL_PHY_CK2_EN, 24, 24), + [AN7581_PCS_TXPLL_SDM_MODE] = REG_FIELD(AIROHA_PCS_ANA_PXP_2L_TXPLL_SDM_DI_LS, 16, 17), + [AN7581_PCS_TXPLL_SDM_IFM] = REG_FIELD(AIROHA_PCS_ANA_PXP_2L_TXPLL_SDM_DI_LS, 8, 8), + [AN7581_PCS_TXPLL_SDM_DI_LS] = REG_FIELD(AIROHA_PCS_ANA_PXP_2L_TXPLL_SDM_DI_LS, 0, 1), + [AN7581_PCS_TXPLL_SDM_DI_EN] = REG_FIELD(AIROHA_PCS_ANA_PXP_2L_TXPLL_REFIN_DIV, 24, 24), + [AN7581_PCS_TXPLL_SDM_HREN] = REG_FIELD(AIROHA_PCS_ANA_PXP_2L_TXPLL_SDM_OUT, 8, 8), + [AN7581_PCS_TXPLL_SDM_OUT] = REG_FIELD(AIROHA_PCS_ANA_PXP_2L_TXPLL_SDM_OUT, 0, 0), + [AN7581_PCS_TXPLL_SDM_ORD] = REG_FIELD(AIROHA_PCS_ANA_PXP_2L_TXPLL_SDM_DI_LS, 24, 25), + [AN7581_PCS_TXPLL_SSC_DELTA1] = REG_FIELD(AIROHA_PCS_ANA_PXP_2L_TXPLL_SSC_DELTA1, 16, 31), + [AN7581_PCS_TXPLL_SSC_DELTA] = REG_FIELD(AIROHA_PCS_ANA_PXP_2L_TXPLL_SSC_DELTA1, 0, 15), + [AN7581_PCS_TXPLL_SSC_TRI_EN] = REG_FIELD(AIROHA_PCS_ANA_PXP_2L_TXPLL_SSC_EN, 16, 16), + [AN7581_PCS_TXPLL_SSC_PHASE_INI] = REG_FIELD(AIROHA_PCS_ANA_PXP_2L_TXPLL_SSC_EN, 8, 8), + [AN7581_PCS_TXPLL_SSC_EN] = REG_FIELD(AIROHA_PCS_ANA_PXP_2L_TXPLL_SSC_EN, 0, 0), + [AN7581_PCS_TXPLL_SSC_PERIOD] = REG_FIELD(AIROHA_PCS_ANA_PXP_2L_TXPLL_SSC_PERIOD, 0, 15), + [AN7581_PCS_TXPLL_LPF_BC] = REG_FIELD(AIROHA_PCS_ANA_PXP_2L_TXPLL_CHP_IOFST, 16, 20), + [AN7581_PCS_TXPLL_LPF_BR] = REG_FIELD(AIROHA_PCS_ANA_PXP_2L_TXPLL_CHP_IOFST, 8, 12), + [AN7581_PCS_TXPLL_CHP_IOFST] = REG_FIELD(AIROHA_PCS_ANA_PXP_2L_TXPLL_CHP_IOFST, 0, 5), + [AN7581_PCS_TXPLL_CHP_IBIAS] = REG_FIELD(AIROHA_PCS_ANA_PXP_2L_750M_SYS_CK_EN, 24, 29), + [AN7581_PCS_TXPLL_LPF_BWC] = REG_FIELD(AIROHA_PCS_ANA_PXP_2L_TXPLL_LPF_BWR, 8, 12), + [AN7581_PCS_TXPLL_LPF_BWR] = REG_FIELD(AIROHA_PCS_ANA_PXP_2L_TXPLL_LPF_BWR, 0, 4), + [AN7581_PCS_TXPLL_LPF_BP] = REG_FIELD(AIROHA_PCS_ANA_PXP_2L_TXPLL_CHP_IOFST, 24, 28), + [AN7581_PCS_TXPLL_VCO_CFIX] = REG_FIELD(AIROHA_PCS_ANA_PXP_2L_TXPLL_TCL_LPF_BW, 16, 17), + [AN7581_PCS_TXPLL_VCO_VCOVAR_BIAS_L] = REG_FIELD(AIROHA_PCS_ANA_PXP_2L_TXPLL_VCO_SCAPWR, 24, 26), + [AN7581_PCS_TXPLL_VCO_VCOVAR_BIAS_H] = REG_FIELD(AIROHA_PCS_ANA_PXP_2L_TXPLL_VCO_SCAPWR, 16, 18), + [AN7581_PCS_TXPLL_VCO_TCLVAR] = REG_FIELD(AIROHA_PCS_ANA_PXP_2L_TXPLL_VCO_SCAPWR, 8, 10), + [AN7581_PCS_TXPLL_VCO_SCAPWR] = REG_FIELD(AIROHA_PCS_ANA_PXP_2L_TXPLL_VCO_SCAPWR, 0, 2), + [AN7581_PCS_TXPLL_VCO_HALFLSB_EN] = REG_FIELD(AIROHA_PCS_ANA_PXP_2L_TXPLL_TCL_LPF_BW, 24, 24), + [AN7581_PCS_TXPLL_KBAND_CODE] = REG_FIELD(AIROHA_PCS_ANA_PXP_2L_TXPLL_LPF_BWR, 24, 31), + [AN7581_PCS_TXPLL_KBAND_OPTION] = REG_FIELD(AIROHA_PCS_ANA_PXP_2L_TXPLL_LPF_BWR, 16, 16), + [AN7581_PCS_TXPLL_KBAND_KS] = REG_FIELD(AIROHA_PCS_ANA_PXP_2L_TXPLL_KBAND_DIV, 24, 25), + [AN7581_PCS_TXPLL_KBAND_KF] = REG_FIELD(AIROHA_PCS_ANA_PXP_2L_TXPLL_KBAND_DIV, 16, 17), + [AN7581_PCS_TXPLL_KBAND_KFC] = REG_FIELD(AIROHA_PCS_ANA_PXP_2L_TXPLL_KBAND_DIV, 8, 9), + [AN7581_PCS_TXPLL_KBAND_DIV] = REG_FIELD(AIROHA_PCS_ANA_PXP_2L_TXPLL_KBAND_DIV, 0, 2), + [AN7581_PCS_TXPLL_MMD_PREDIV_MODE] = REG_FIELD(AIROHA_PCS_ANA_PXP_2L_TXPLL_POSTDIV_EN, 8, 9), + [AN7581_PCS_TXPLL_POSTDIV_EN] = REG_FIELD(AIROHA_PCS_ANA_PXP_2L_TXPLL_POSTDIV_EN, 0, 0), + [AN7581_PCS_TXPLL_VCODIV] = REG_FIELD(AIROHA_PCS_ANA_PXP_2L_TXPLL_TCL_LPF_BW, 8, 9), + [AN7581_PCS_TXPLL_TCL_KBAND_VREF] = REG_FIELD(AIROHA_PCS_ANA_PXP_2L_TXPLL_TCL_KBAND_VREF, 0, 4), + [AN7581_PCS_TXPLL_TCL_AMP_GAIN] = REG_FIELD(AIROHA_PCS_ANA_PXP_2L_TXPLL_SDM_OUT, 24, 26), + [AN7581_PCS_TXPLL_TCL_AMP_VREF] = REG_FIELD(AIROHA_PCS_ANA_PXP_2L_TXPLL_TCL_AMP_VREF, 0, 4), + [AN7581_PCS_TXPLL_TCL_LPF_BW] = REG_FIELD(AIROHA_PCS_ANA_PXP_2L_TXPLL_TCL_LPF_BW, 0, 2), + [AN7581_PCS_TXPLL_TCL_LPF_EN] = REG_FIELD(AIROHA_PCS_ANA_PXP_TXPLL_TCL_LPF_EN, 0, 0), + [AN7581_PCS_TXPLL_TCL_AMP_EN] = REG_FIELD(AIROHA_PCS_ANA_PXP_2L_TXPLL_TCL_AMP_VREF, 24, 24), + + [AN7581_PCS_TX_DMEDGEGEN_EN] = REG_FIELD(AIROHA_PCS_ANA_PXP_2L_TX0_CKLDO_EN, 24, 24), + [AN7581_PCS_TX_CKLDO_EN] = REG_FIELD(AIROHA_PCS_ANA_PXP_2L_TX0_CKLDO_EN, 0, 0), + + [AN7581_PCS_RX_DAC_EYE_BYPASS_AEQ] = REG_FIELD(AIROHA_PCS_ANA_PXP_2L_RX0_DAC_EYE_BYPASS_AEQ, 0, 0), + [AN7581_PCS_RX_DAC_E1_BYPASS_AEQ] = REG_FIELD(AIROHA_PCS_ANA_PXP_2L_RX0_DAC_D0_BYPASS_AEQ, 24, 24), + [AN7581_PCS_RX_DAC_E0_BYPASS_AEQ] = REG_FIELD(AIROHA_PCS_ANA_PXP_2L_RX0_DAC_D0_BYPASS_AEQ, 16, 16), + [AN7581_PCS_RX_DAC_D1_BYPASS_AEQ] = REG_FIELD(AIROHA_PCS_ANA_PXP_2L_RX0_DAC_D0_BYPASS_AEQ, 8, 8), + [AN7581_PCS_RX_DAC_D0_BYPASS_AEQ] = REG_FIELD(AIROHA_PCS_ANA_PXP_2L_RX0_DAC_D0_BYPASS_AEQ, 0, 0), + [AN7581_PCS_RX_FE_VCM_GEN_PWDB] = REG_FIELD(AIROHA_PCS_ANA_PXP_2L_RX0_FE_VB_EQ2_EN, 16, 16), + + [AN7581_PCS_AEQ_OFORCE] = REG_FIELD(AIROHA_PCS_ANA_PXP_2L_AEQ0_CFORCE, 8, 19), + [AN7581_PCS_RX_OSCAL_FORCE] = REG_FIELD(AIROHA_PCS_ANA_PXP_2L_RX0_OSCAL_FORCE, 8, 17), + + [AN7581_PCS_CDR_PD_EDGE_DIS] = REG_FIELD(AIROHA_PCS_ANA_PXP_2L_CDR0_PD_PICAL_CKD8_INV, 8, 8), + [AN7581_PCS_CDR_PD_PICAL_CKD8_INV] = REG_FIELD(AIROHA_PCS_ANA_PXP_2L_CDR0_PD_PICAL_CKD8_INV, 0, 0), + + [AN7581_PCS_RX_DAC_MON] = REG_FIELD(AIROHA_PCS_ANA_PXP_2L_RX0_DAC_MON, 0, 4), + [AN7581_PCS_CDR_PR_XFICK_EN] = REG_FIELD(AIROHA_PCS_ANA_PXP_2L_CDR0_PR_MONPI_EN, 8, 8), + [AN7581_PCS_CDR_PR_MONPI_EN] = REG_FIELD(AIROHA_PCS_ANA_PXP_2L_CDR0_PR_MONPI_EN, 0, 0), + [AN7581_PCS_CDR_PR_MONPR_EN] = REG_FIELD(AIROHA_PCS_ANA_PXP_2L_CDR0_PR_COR_HBW_EN, 24, 24), + + [AN7581_PCS_RX_REV_1_FE_BUF1_BIAS_CTRL] = REG_FIELD(AIROHA_PCS_ANA_PXP_2L_RX0_REV_0, 24, 26), + [AN7581_PCS_RX_REV_1_FE_BUF2_BIAS_CTRL] = REG_FIELD(AIROHA_PCS_ANA_PXP_2L_RX0_REV_0, 20, 22), + [AN7581_PCS_RX_REV_1_SIGDET_ILEAK] = REG_FIELD(AIROHA_PCS_ANA_PXP_2L_RX0_REV_0, 18, 19), + + [AN7581_PCS_CDR_LPF_TOP_LIM] = REG_FIELD(AIROHA_PCS_ANA_PXP_2L_CDR0_LPF_RATIO, 8, 26), + [AN7581_PCS_CDR_LPF_RATIO] = REG_FIELD(AIROHA_PCS_ANA_PXP_2L_CDR0_LPF_RATIO, 0, 1), + + [AN7581_PCS_CDR_PR_KBAND_DIV] = REG_FIELD(AIROHA_PCS_ANA_PXP_2L_CDR0_PR_BETA_DAC, 24, 26), + [AN7581_PCS_CDR_PR_BETA_SEL] = REG_FIELD(AIROHA_PCS_ANA_PXP_2L_CDR0_PR_BETA_DAC, 16, 19), + [AN7581_PCS_CDR_PR_VCOADC_OS] = REG_FIELD(AIROHA_PCS_ANA_PXP_2L_CDR0_PR_BETA_DAC, 8, 11), + [AN7581_PCS_CDR_PR_BETA_DAC] = REG_FIELD(AIROHA_PCS_ANA_PXP_2L_CDR0_PR_BETA_DAC, 0, 6), + [AN7581_PCS_CDR_PR_FBKSEL] = REG_FIELD(AIROHA_PCS_ANA_PXP_2L_CDR0_PR_VREG_IBAND_VAL, 24, 25), + [AN7581_PCS_CDR_PR_DAC_BAND] = REG_FIELD(AIROHA_PCS_ANA_PXP_2L_CDR0_PR_VREG_IBAND_VAL, 16, 20), + [AN7581_PCS_CDR_PR_VREG_CKBUF_VAL] = REG_FIELD(AIROHA_PCS_ANA_PXP_2L_CDR0_PR_VREG_IBAND_VAL, 8, 10), + [AN7581_PCS_CDR_PR_VREG_IBAND_VAL] = REG_FIELD(AIROHA_PCS_ANA_PXP_2L_CDR0_PR_VREG_IBAND_VAL, 0, 2), + + [AN7581_PCS_RX_FE_VB_EQ3_EN] = REG_FIELD(AIROHA_PCS_ANA_PXP_2L_RX0_FE_VB_EQ2_EN, 8, 8), + [AN7581_PCS_RX_FE_VB_EQ2_EN] = REG_FIELD(AIROHA_PCS_ANA_PXP_2L_RX0_FE_VB_EQ2_EN, 0, 0), + [AN7581_PCS_RX_FE_VB_EQ1_EN] = REG_FIELD(AIROHA_PCS_ANA_PXP_2L_RX0_SIGDET_VTH_SEL, 24, 24), + [AN7581_PCS_RX_FE_EQ_HZEN] = REG_FIELD(AIROHA_PCS_ANA_PXP_2L_RX0_SIGDET_VTH_SEL, 16, 16), + + [AN7581_PCS_CDR_PR_CAP_EN] = REG_FIELD(AIROHA_PCS_ANA_PXP_2L_CDR0_PR_BUF_IN_SR, 8, 8), + [AN7581_PCS_CDR_BUF_IN_SR] = REG_FIELD(AIROHA_PCS_ANA_PXP_2L_CDR0_PR_BUF_IN_SR, 0, 2), + + [AN7581_PCS_RX_SIGDET_VTH_SEL] = REG_FIELD(AIROHA_PCS_ANA_PXP_2L_RX0_SIGDET_VTH_SEL, 0, 4), + [AN7581_PCS_RX_SIGDET_PEAK] = REG_FIELD(AIROHA_PCS_ANA_PXP_2L_RX0_SIGDET_DCTEST_EN, 24, 25), + [AN7581_PCS_RX_SIGDET_LPF_CTRL] = REG_FIELD(AIROHA_PCS_ANA_PXP_2L_RX0_SIGDET_DCTEST_EN, 8, 9), + + [AN7581_PCS_RX_TDC_CK_SEL] = REG_FIELD(AIROHA_PCS_ANA_PXP_2L_RX0_PHYCK_DIV, 24, 24), + [AN7581_PCS_RX_PHYCK_RSTB] = REG_FIELD(AIROHA_PCS_ANA_PXP_2L_RX0_PHYCK_DIV, 16, 16), + [AN7581_PCS_RX_PHYCK_SEL] = REG_FIELD(AIROHA_PCS_ANA_PXP_2L_RX0_PHYCK_DIV, 8, 9), + [AN7581_PCS_RX_PHYCK_DIV] = REG_FIELD(AIROHA_PCS_ANA_PXP_2L_RX0_PHYCK_DIV, 0, 7), + [AN7581_PCS_RX_PHY_CK_SEL_FORCE] = REG_FIELD(AIROHA_PCS_ANA_PXP_2L_RX0_BUSBIT_SEL, 24, 24), + [AN7581_PCS_RX_PHY_CK_SEL] = REG_FIELD(AIROHA_PCS_ANA_PXP_2L_RX0_BUSBIT_SEL, 16, 16), + + [AN7581_PCS_CDR_PR_INJ_FORCE_OFF] = REG_FIELD(AIROHA_PCS_ANA_PXP_2L_CDR0_PR_INJ_MODE, 24, 24), +}; + +static const struct reg_field an7581_pcs_pcie1_fields[AN7581_PCS_FIELDS_MAX] = { + [AN7581_PCS_CMN_EN] = REG_FIELD(AIROHA_PCS_ANA_PXP_2L_CMN_EN, 0, 0), + + [AN7581_PCS_JCPLL_SPARE_L] = REG_FIELD(AIROHA_PCS_ANA_PXP_2L_JCPLL_TCL_VTP_EN, 24, 31), + + [AN7581_PCS_JCPLL_RST_DLY] = REG_FIELD(AIROHA_PCS_ANA_PXP_2L_JCPLL_RST_DLY, 0, 2), + [AN7581_PCS_JCPLL_PLL_RSTB] = REG_FIELD(AIROHA_PCS_ANA_PXP_2L_JCPLL_RST_DLY, 8, 8), + [AN7581_PCS_JCPLL_SDM_DI_LS] = REG_FIELD(AIROHA_PCS_ANA_PXP_2L_JCPLL_RST_DLY, 16, 16), + [AN7581_PCS_JCPLL_SDM_DI_EN] = REG_FIELD(AIROHA_PCS_ANA_PXP_2L_JCPLL_RST_DLY, 24, 25), + + [AN7581_PCS_JCPLL_SDM_OUT] = REG_FIELD(AIROHA_PCS_ANA_PXP_2L_JCPLL_SDM_IFM, 24, 24), + [AN7581_PCS_JCPLL_SDM_ORD] = REG_FIELD(AIROHA_PCS_ANA_PXP_2L_JCPLL_SDM_IFM, 16, 17), + [AN7581_PCS_JCPLL_SDM_MODE] = REG_FIELD(AIROHA_PCS_ANA_PXP_2L_JCPLL_SDM_IFM, 8, 9), + [AN7581_PCS_JCPLL_SDM_IFM] = REG_FIELD(AIROHA_PCS_ANA_PXP_2L_JCPLL_SDM_IFM, 0, 0), + [AN7581_PCS_JCPLL_SDM_HREN] = REG_FIELD(AIROHA_PCS_ANA_PXP_2L_JCPLL_SDM_HREN, 0, 0), + + [AN7581_PCS_JCPLL_CHP_IOFST] = REG_FIELD(AIROHA_PCS_ANA_PXP_2L_JCPLL_IB_EXT_EN, 24, 29), + [AN7581_PCS_JCPLL_CHP_IBIAS] = REG_FIELD(AIROHA_PCS_ANA_PXP_2L_JCPLL_IB_EXT_EN, 16, 21), + [AN7581_PCS_JCPLL_LPF_SHCK_EN] = REG_FIELD(AIROHA_PCS_ANA_PXP_2L_JCPLL_IB_EXT_EN, 8, 8), + + [AN7581_PCS_JCPLL_LPF_BWR] = REG_FIELD(AIROHA_PCS_ANA_PXP_2L_JCPLL_LPF_BR, 24, 28), + [AN7581_PCS_JCPLL_LPF_BP] = REG_FIELD(AIROHA_PCS_ANA_PXP_2L_JCPLL_LPF_BR, 16, 20), + [AN7581_PCS_JCPLL_LPF_BC] = REG_FIELD(AIROHA_PCS_ANA_PXP_2L_JCPLL_LPF_BR, 8, 12), + [AN7581_PCS_JCPLL_LPF_BR] = REG_FIELD(AIROHA_PCS_ANA_PXP_2L_JCPLL_LPF_BR, 0, 4), + [AN7581_PCS_JCPLL_LPF_BWC] = REG_FIELD(AIROHA_PCS_ANA_PXP_2L_JCPLL_LPF_BWC, 0, 4), + + [AN7581_PCS_JCPLL_VCO_SCAPWR] = REG_FIELD(AIROHA_PCS_ANA_PXP_2L_JCPLL_VCODIV, 24, 26), + [AN7581_PCS_JCPLL_VCO_HALFLSB_EN] = REG_FIELD(AIROHA_PCS_ANA_PXP_2L_JCPLL_VCODIV, 16, 16), + [AN7581_PCS_JCPLL_VCO_CFIX] = REG_FIELD(AIROHA_PCS_ANA_PXP_2L_JCPLL_VCODIV, 8, 9), + [AN7581_PCS_JCPLL_VCODIV] = REG_FIELD(AIROHA_PCS_ANA_PXP_2L_JCPLL_VCODIV, 0, 1), + [AN7581_PCS_JCPLL_VCO_VCOVAR_BIAS_L] = REG_FIELD(AIROHA_PCS_ANA_PXP_2L_JCPLL_VCO_TCLVAR, 16, 18), + [AN7581_PCS_JCPLL_VCO_VCOVAR_BIAS_H] = REG_FIELD(AIROHA_PCS_ANA_PXP_2L_JCPLL_VCO_TCLVAR, 8, 10), + [AN7581_PCS_JCPLL_VCO_TCLVAR] = REG_FIELD(AIROHA_PCS_ANA_PXP_2L_JCPLL_VCO_TCLVAR, 0, 2), + + [AN7581_PCS_JCPLL_SSC_DELTA] = REG_FIELD(AIROHA_PCS_ANA_PXP_2L_JCPLL_SSC_DELTA1, 16, 31), + [AN7581_PCS_JCPLL_SSC_DELTA1] = REG_FIELD(AIROHA_PCS_ANA_PXP_2L_JCPLL_SSC_DELTA1, 0, 15), + [AN7581_PCS_JCPLL_SSC_PERIOD] = REG_FIELD(AIROHA_PCS_ANA_PXP_2L_JCPLL_SSC_PERIOD, 0, 15), + [AN7581_PCS_JCPLL_SSC_TRI_EN] = REG_FIELD(AIROHA_PCS_ANA_PXP_2L_JCPLL_SSC_EN, 16, 16), + [AN7581_PCS_JCPLL_SSC_PHASE_INI] = REG_FIELD(AIROHA_PCS_ANA_PXP_2L_JCPLL_SSC_EN, 8, 8), + [AN7581_PCS_JCPLL_SSC_EN] = REG_FIELD(AIROHA_PCS_ANA_PXP_2L_JCPLL_SSC_EN, 0, 0), + [AN7581_PCS_JCPLL_TCL_KBAND_VREF] = REG_FIELD(AIROHA_PCS_ANA_PXP_2L_JCPLL_TCL_KBAND_VREF, 0, 4), + + [AN7581_PCS_JCPLL_POSTDIV_D5] = REG_FIELD(AIROHA_PCS_ANA_PXP_2L_JCPLL_MMD_PREDIV_MODE, 24, 24), + [AN7581_PCS_JCPLL_MMD_PREDIV_MODE] = REG_FIELD(AIROHA_PCS_ANA_PXP_2L_JCPLL_MMD_PREDIV_MODE, 0, 1), + + [AN7581_PCS_JCPLL_KBAND_KS] = REG_FIELD(AIROHA_PCS_ANA_PXP_2L_JCPLL_KBAND_KFC, 16, 17), + [AN7581_PCS_JCPLL_KBAND_KF] = REG_FIELD(AIROHA_PCS_ANA_PXP_2L_JCPLL_KBAND_KFC, 8, 9), + [AN7581_PCS_JCPLL_KBAND_KFC] = REG_FIELD(AIROHA_PCS_ANA_PXP_2L_JCPLL_KBAND_KFC, 0, 1), + [AN7581_PCS_JCPLL_KBAND_DIV] = REG_FIELD(AIROHA_PCS_ANA_PXP_2L_JCPLL_LPF_BWC, 24, 26), + [AN7581_PCS_JCPLL_KBAND_CODE] = REG_FIELD(AIROHA_PCS_ANA_PXP_2L_JCPLL_LPF_BWC, 16, 23), + [AN7581_PCS_JCPLL_KBAND_OPTION] = REG_FIELD(AIROHA_PCS_ANA_PXP_2L_JCPLL_LPF_BWC, 8, 8), + + [AN7581_PCS_JCPLL_TCL_AMP_VREF] = REG_FIELD(AIROHA_PCS_ANA_PXP_2L_JCPLL_SDM_HREN, 24, 28), + [AN7581_PCS_JCPLL_TCL_AMP_GAIN] = REG_FIELD(AIROHA_PCS_ANA_PXP_2L_JCPLL_SDM_HREN, 16, 18), + [AN7581_PCS_JCPLL_TCL_AMP_EN] = REG_FIELD(AIROHA_PCS_ANA_PXP_2L_JCPLL_SDM_HREN, 8, 8), + + [AN7581_PCS_JCPLL_TCL_LPF_BW] = REG_FIELD(AIROHA_PCS_ANA_PXP_2L_JCPLL_TCL_CMP_EN, 24, 26), + [AN7581_PCS_JCPLL_TCL_LPF_EN] = REG_FIELD(AIROHA_PCS_ANA_PXP_2L_JCPLL_TCL_CMP_EN, 16, 16), + + [AN7581_PCS_TXPLL_LDO_VCO_OUT] = REG_FIELD(AIROHA_PCS_ANA_PXP_2L_TXPLL_SSC_PERIOD, 24, 25), + [AN7581_PCS_TXPLL_LDO_OUT] = REG_FIELD(AIROHA_PCS_ANA_PXP_2L_TXPLL_SSC_PERIOD, 16, 17), + [AN7581_PCS_TXPLL_PLL_RSTB] = REG_FIELD(AIROHA_PCS_ANA_PXP_2L_TXPLL_REFIN_DIV, 16, 16), + [AN7581_PCS_TXPLL_RST_DLY] = REG_FIELD(AIROHA_PCS_ANA_PXP_2L_TXPLL_REFIN_DIV, 8, 10), + [AN7581_PCS_TXPLL_REFIN_DIV] = REG_FIELD(AIROHA_PCS_ANA_PXP_2L_TXPLL_REFIN_DIV, 0, 1), + [AN7581_PCS_TXPLL_REFIN_INTERNAL] = REG_FIELD(AIROHA_PCS_ANA_PXP_2L_TXPLL_PHY_CK2_EN, 24, 24), + [AN7581_PCS_TXPLL_SDM_MODE] = REG_FIELD(AIROHA_PCS_ANA_PXP_2L_TXPLL_SDM_DI_LS, 16, 17), + [AN7581_PCS_TXPLL_SDM_IFM] = REG_FIELD(AIROHA_PCS_ANA_PXP_2L_TXPLL_SDM_DI_LS, 8, 8), + [AN7581_PCS_TXPLL_SDM_DI_LS] = REG_FIELD(AIROHA_PCS_ANA_PXP_2L_TXPLL_SDM_DI_LS, 0, 1), + [AN7581_PCS_TXPLL_SDM_DI_EN] = REG_FIELD(AIROHA_PCS_ANA_PXP_2L_TXPLL_REFIN_DIV, 24, 24), + [AN7581_PCS_TXPLL_SDM_HREN] = REG_FIELD(AIROHA_PCS_ANA_PXP_2L_TXPLL_SDM_OUT, 8, 8), + [AN7581_PCS_TXPLL_SDM_OUT] = REG_FIELD(AIROHA_PCS_ANA_PXP_2L_TXPLL_SDM_OUT, 0, 0), + [AN7581_PCS_TXPLL_SDM_ORD] = REG_FIELD(AIROHA_PCS_ANA_PXP_2L_TXPLL_SDM_DI_LS, 24, 25), + [AN7581_PCS_TXPLL_SSC_DELTA1] = REG_FIELD(AIROHA_PCS_ANA_PXP_2L_TXPLL_SSC_DELTA1, 16, 31), + [AN7581_PCS_TXPLL_SSC_DELTA] = REG_FIELD(AIROHA_PCS_ANA_PXP_2L_TXPLL_SSC_DELTA1, 0, 15), + [AN7581_PCS_TXPLL_SSC_TRI_EN] = REG_FIELD(AIROHA_PCS_ANA_PXP_2L_TXPLL_SSC_EN, 16, 16), + [AN7581_PCS_TXPLL_SSC_PHASE_INI] = REG_FIELD(AIROHA_PCS_ANA_PXP_2L_TXPLL_SSC_EN, 8, 8), + [AN7581_PCS_TXPLL_SSC_EN] = REG_FIELD(AIROHA_PCS_ANA_PXP_2L_TXPLL_SSC_EN, 0, 0), + [AN7581_PCS_TXPLL_SSC_PERIOD] = REG_FIELD(AIROHA_PCS_ANA_PXP_2L_TXPLL_SSC_PERIOD, 0, 15), + [AN7581_PCS_TXPLL_LPF_BC] = REG_FIELD(AIROHA_PCS_ANA_PXP_2L_TXPLL_CHP_IOFST, 16, 20), + [AN7581_PCS_TXPLL_LPF_BR] = REG_FIELD(AIROHA_PCS_ANA_PXP_2L_TXPLL_CHP_IOFST, 8, 12), + [AN7581_PCS_TXPLL_CHP_IOFST] = REG_FIELD(AIROHA_PCS_ANA_PXP_2L_TXPLL_CHP_IOFST, 0, 5), + [AN7581_PCS_TXPLL_CHP_IBIAS] = REG_FIELD(AIROHA_PCS_ANA_PXP_2L_750M_SYS_CK_EN, 24, 29), + [AN7581_PCS_TXPLL_LPF_BWC] = REG_FIELD(AIROHA_PCS_ANA_PXP_2L_TXPLL_LPF_BWR, 8, 12), + [AN7581_PCS_TXPLL_LPF_BWR] = REG_FIELD(AIROHA_PCS_ANA_PXP_2L_TXPLL_LPF_BWR, 0, 4), + [AN7581_PCS_TXPLL_LPF_BP] = REG_FIELD(AIROHA_PCS_ANA_PXP_2L_TXPLL_CHP_IOFST, 24, 28), + [AN7581_PCS_TXPLL_VCO_CFIX] = REG_FIELD(AIROHA_PCS_ANA_PXP_2L_TXPLL_TCL_LPF_BW, 16, 17), + [AN7581_PCS_TXPLL_VCO_VCOVAR_BIAS_L] = REG_FIELD(AIROHA_PCS_ANA_PXP_2L_TXPLL_VCO_SCAPWR, 24, 26), + [AN7581_PCS_TXPLL_VCO_VCOVAR_BIAS_H] = REG_FIELD(AIROHA_PCS_ANA_PXP_2L_TXPLL_VCO_SCAPWR, 16, 18), + [AN7581_PCS_TXPLL_VCO_TCLVAR] = REG_FIELD(AIROHA_PCS_ANA_PXP_2L_TXPLL_VCO_SCAPWR, 8, 10), + [AN7581_PCS_TXPLL_VCO_SCAPWR] = REG_FIELD(AIROHA_PCS_ANA_PXP_2L_TXPLL_VCO_SCAPWR, 0, 2), + [AN7581_PCS_TXPLL_VCO_HALFLSB_EN] = REG_FIELD(AIROHA_PCS_ANA_PXP_2L_TXPLL_TCL_LPF_BW, 24, 24), + [AN7581_PCS_TXPLL_KBAND_CODE] = REG_FIELD(AIROHA_PCS_ANA_PXP_2L_TXPLL_LPF_BWR, 24, 31), + [AN7581_PCS_TXPLL_KBAND_OPTION] = REG_FIELD(AIROHA_PCS_ANA_PXP_2L_TXPLL_LPF_BWR, 16, 16), + [AN7581_PCS_TXPLL_KBAND_KS] = REG_FIELD(AIROHA_PCS_ANA_PXP_2L_TXPLL_KBAND_DIV, 24, 25), + [AN7581_PCS_TXPLL_KBAND_KF] = REG_FIELD(AIROHA_PCS_ANA_PXP_2L_TXPLL_KBAND_DIV, 16, 17), + [AN7581_PCS_TXPLL_KBAND_KFC] = REG_FIELD(AIROHA_PCS_ANA_PXP_2L_TXPLL_KBAND_DIV, 8, 9), + [AN7581_PCS_TXPLL_KBAND_DIV] = REG_FIELD(AIROHA_PCS_ANA_PXP_2L_TXPLL_KBAND_DIV, 0, 2), + [AN7581_PCS_TXPLL_MMD_PREDIV_MODE] = REG_FIELD(AIROHA_PCS_ANA_PXP_2L_TXPLL_POSTDIV_EN, 8, 9), + [AN7581_PCS_TXPLL_POSTDIV_EN] = REG_FIELD(AIROHA_PCS_ANA_PXP_2L_TXPLL_POSTDIV_EN, 0, 0), + [AN7581_PCS_TXPLL_VCODIV] = REG_FIELD(AIROHA_PCS_ANA_PXP_2L_TXPLL_TCL_LPF_BW, 8, 9), + [AN7581_PCS_TXPLL_TCL_KBAND_VREF] = REG_FIELD(AIROHA_PCS_ANA_PXP_2L_TXPLL_TCL_KBAND_VREF, 0, 4), + [AN7581_PCS_TXPLL_TCL_AMP_GAIN] = REG_FIELD(AIROHA_PCS_ANA_PXP_2L_TXPLL_SDM_OUT, 24, 26), + [AN7581_PCS_TXPLL_TCL_AMP_VREF] = REG_FIELD(AIROHA_PCS_ANA_PXP_2L_TXPLL_TCL_AMP_VREF, 0, 4), + [AN7581_PCS_TXPLL_TCL_LPF_BW] = REG_FIELD(AIROHA_PCS_ANA_PXP_2L_TXPLL_TCL_LPF_BW, 0, 2), + [AN7581_PCS_TXPLL_TCL_LPF_EN] = REG_FIELD(AIROHA_PCS_ANA_PXP_TXPLL_TCL_LPF_EN, 0, 0), + [AN7581_PCS_TXPLL_TCL_AMP_EN] = REG_FIELD(AIROHA_PCS_ANA_PXP_2L_TXPLL_TCL_AMP_VREF, 24, 24), + + [AN7581_PCS_TX_DMEDGEGEN_EN] = REG_FIELD(AIROHA_PCS_ANA_PXP_2L_TX1_CKLDO_EN, 24, 24), + [AN7581_PCS_TX_CKLDO_EN] = REG_FIELD(AIROHA_PCS_ANA_PXP_2L_TX1_CKLDO_EN, 0, 0), + + [AN7581_PCS_RX_DAC_EYE_BYPASS_AEQ] = REG_FIELD(AIROHA_PCS_ANA_PXP_2L_RX1_DAC_D1_BYPASS_AEQ, 24, 24), + [AN7581_PCS_RX_DAC_E1_BYPASS_AEQ] = REG_FIELD(AIROHA_PCS_ANA_PXP_2L_RX1_DAC_D1_BYPASS_AEQ, 16, 16), + [AN7581_PCS_RX_DAC_E0_BYPASS_AEQ] = REG_FIELD(AIROHA_PCS_ANA_PXP_2L_RX1_DAC_D1_BYPASS_AEQ, 8, 8), + [AN7581_PCS_RX_DAC_D1_BYPASS_AEQ] = REG_FIELD(AIROHA_PCS_ANA_PXP_2L_RX1_DAC_D1_BYPASS_AEQ, 0, 0), + [AN7581_PCS_RX_DAC_D0_BYPASS_AEQ] = REG_FIELD(AIROHA_PCS_ANA_PXP_2L_RX1_FE_PEACKING_CTRL_LSB, 24, 24), + [AN7581_PCS_RX_FE_VCM_GEN_PWDB] = REG_FIELD(AIROHA_PCS_ANA_PXP_2L_RX1_FE_VB_EQ1_EN, 24, 24), + + [AN7581_PCS_AEQ_OFORCE] = REG_FIELD(AIROHA_PCS_ANA_PXP_2L_AEQ1_CFORCE, 16, 27), + [AN7581_PCS_RX_OSCAL_FORCE] = REG_FIELD(AIROHA_PCS_ANA_PXP_2L_RX1_OSCAL_WATCH_WNDW, 16, 25), + + [AN7581_PCS_CDR_PD_EDGE_DIS] = REG_FIELD(AIROHA_PCS_ANA_PXP_2L_CDR1_PD_PICAL_CKD8_INV, 8, 8), + [AN7581_PCS_CDR_PD_PICAL_CKD8_INV] = REG_FIELD(AIROHA_PCS_ANA_PXP_2L_CDR1_PD_PICAL_CKD8_INV, 0, 0), + + [AN7581_PCS_RX_DAC_MON] = REG_FIELD(AIROHA_PCS_ANA_PXP_2L_CDR1_PR_BUF_IN_SR, 16, 20), + [AN7581_PCS_CDR_PR_XFICK_EN] = REG_FIELD(AIROHA_PCS_ANA_PXP_2L_CDR1_PR_MONPI_EN, 8, 8), + [AN7581_PCS_CDR_PR_MONPI_EN] = REG_FIELD(AIROHA_PCS_ANA_PXP_2L_CDR1_PR_MONPI_EN, 0, 0), + [AN7581_PCS_CDR_PR_MONPR_EN] = REG_FIELD(AIROHA_PCS_ANA_PXP_2L_CDR1_PR_COR_HBW_EN, 24, 24), + + [AN7581_PCS_RX_REV_1_FE_BUF1_BIAS_CTRL] = REG_FIELD(AIROHA_PCS_ANA_PXP_2L_RX1_REV_0, 24, 26), + [AN7581_PCS_RX_REV_1_FE_BUF2_BIAS_CTRL] = REG_FIELD(AIROHA_PCS_ANA_PXP_2L_RX1_REV_0, 20, 22), + [AN7581_PCS_RX_REV_1_SIGDET_ILEAK] = REG_FIELD(AIROHA_PCS_ANA_PXP_2L_RX1_REV_0, 18, 19), + + [AN7581_PCS_CDR_LPF_TOP_LIM] = REG_FIELD(AIROHA_PCS_ANA_PXP_2L_CDR1_LPF_RATIO, 8, 26), + [AN7581_PCS_CDR_LPF_RATIO] = REG_FIELD(AIROHA_PCS_ANA_PXP_2L_CDR1_LPF_RATIO, 0, 1), + + [AN7581_PCS_CDR_PR_KBAND_DIV] = REG_FIELD(AIROHA_PCS_ANA_PXP_2L_CDR1_PR_BETA_DAC, 24, 26), + [AN7581_PCS_CDR_PR_BETA_SEL] = REG_FIELD(AIROHA_PCS_ANA_PXP_2L_CDR1_PR_BETA_DAC, 16, 19), + [AN7581_PCS_CDR_PR_VCOADC_OS] = REG_FIELD(AIROHA_PCS_ANA_PXP_2L_CDR1_PR_BETA_DAC, 8, 11), + [AN7581_PCS_CDR_PR_BETA_DAC] = REG_FIELD(AIROHA_PCS_ANA_PXP_2L_CDR1_PR_BETA_DAC, 0, 6), + [AN7581_PCS_CDR_PR_FBKSEL] = REG_FIELD(AIROHA_PCS_ANA_PXP_2L_CDR1_PR_VREG_IBAND_VAL, 24, 25), + [AN7581_PCS_CDR_PR_DAC_BAND] = REG_FIELD(AIROHA_PCS_ANA_PXP_2L_CDR1_PR_VREG_IBAND_VAL, 16, 20), + [AN7581_PCS_CDR_PR_VREG_CKBUF_VAL] = REG_FIELD(AIROHA_PCS_ANA_PXP_2L_CDR1_PR_VREG_IBAND_VAL, 8, 10), + [AN7581_PCS_CDR_PR_VREG_IBAND_VAL] = REG_FIELD(AIROHA_PCS_ANA_PXP_2L_CDR1_PR_VREG_IBAND_VAL, 0, 2), + + [AN7581_PCS_RX_FE_VB_EQ3_EN] = REG_FIELD(AIROHA_PCS_ANA_PXP_2L_RX1_FE_VB_EQ1_EN, 16, 16), + [AN7581_PCS_RX_FE_VB_EQ2_EN] = REG_FIELD(AIROHA_PCS_ANA_PXP_2L_RX1_FE_VB_EQ1_EN, 8, 8), + [AN7581_PCS_RX_FE_VB_EQ1_EN] = REG_FIELD(AIROHA_PCS_ANA_PXP_2L_RX1_FE_VB_EQ1_EN, 0, 0), + [AN7581_PCS_RX_FE_EQ_HZEN] = REG_FIELD(AIROHA_PCS_ANA_PXP_2L_RX1_FE_50OHMS_SEL, 24, 24), + + [AN7581_PCS_CDR_PR_CAP_EN] = REG_FIELD(AIROHA_PCS_ANA_PXP_2L_CDR1_PR_BUF_IN_SR, 8, 8), + [AN7581_PCS_CDR_BUF_IN_SR] = REG_FIELD(AIROHA_PCS_ANA_PXP_2L_CDR1_PR_BUF_IN_SR, 0, 2), + + [AN7581_PCS_RX_SIGDET_VTH_SEL] = REG_FIELD(AIROHA_PCS_ANA_PXP_2L_RX1_SIGDET_NOVTH, 16, 20), + [AN7581_PCS_RX_SIGDET_PEAK] = REG_FIELD(AIROHA_PCS_ANA_PXP_2L_RX1_SIGDET_NOVTH, 8, 9), + [AN7581_PCS_RX_SIGDET_LPF_CTRL] = REG_FIELD(AIROHA_PCS_ANA_PXP_2L_RX1_DAC_RANGE_EYE, 24, 25), + + [AN7581_PCS_RX_TDC_CK_SEL] = REG_FIELD(AIROHA_PCS_ANA_PXP_2L_RX1_PHYCK_DIV, 24, 24), + [AN7581_PCS_RX_PHYCK_RSTB] = REG_FIELD(AIROHA_PCS_ANA_PXP_2L_RX1_PHYCK_DIV, 16, 16), + [AN7581_PCS_RX_PHYCK_SEL] = REG_FIELD(AIROHA_PCS_ANA_PXP_2L_RX1_PHYCK_DIV, 8, 9), + [AN7581_PCS_RX_PHYCK_DIV] = REG_FIELD(AIROHA_PCS_ANA_PXP_2L_RX1_PHYCK_DIV, 0, 7), + [AN7581_PCS_RX_PHY_CK_SEL_FORCE] = REG_FIELD(AIROHA_PCS_ANA_PXP_2L_RX1_BUSBIT_SEL, 24, 24), + [AN7581_PCS_RX_PHY_CK_SEL] = REG_FIELD(AIROHA_PCS_ANA_PXP_2L_RX1_BUSBIT_SEL, 16, 16), + + [AN7581_PCS_CDR_PR_INJ_FORCE_OFF] = REG_FIELD(AIROHA_PCS_ANA_PXP_2L_CDR1_PR_INJ_MODE, 24, 24), +}; + +static void an7581_pcs_jcpll_bringup(struct airoha_pcs_priv *priv, + int index, phy_interface_t interface) +{ + struct regmap_field **pcs_ana_fields = priv->pcs_ana_fields[index]; + struct regmap *pcs_pma; + 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; + } + + /* This comment only apply to Serdes PCIe that expose + * 2 PCS. + * + * The Serdes PCIe expose 2 PCS but always require + * the PMA for the first PCS to be configured + * for correct functionality for JCPLL. + */ + pcs_pma = priv->pcs_pma[0]; + + /* Setup LDO */ + usleep_range(200, 300); + + regmap_field_set_bits(pcs_ana_fields[AN7581_PCS_JCPLL_SPARE_L], + AIROHA_PCS_ANA_JCPLL_SPARE_L_LDO); + + /* Setup RSTB */ + regmap_field_write(pcs_ana_fields[AN7581_PCS_JCPLL_RST_DLY], + AIROHA_PCS_ANA_JCPLL_RST_DLY_150_200); + regmap_field_write(pcs_ana_fields[AN7581_PCS_JCPLL_PLL_RSTB], 0x1); + + /* Enable PLL force selection and Force Disable */ + regmap_update_bits(pcs_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_field_write(pcs_ana_fields[AN7581_PCS_JCPLL_SDM_DI_LS], + AIROHA_PCS_ANA_JCPLL_SDM_DI_LS_2_23); + regmap_field_write(pcs_ana_fields[AN7581_PCS_JCPLL_SDM_DI_EN], 0x0); + + regmap_field_write(pcs_ana_fields[AN7581_PCS_JCPLL_SDM_OUT], 0x0); + regmap_field_write(pcs_ana_fields[AN7581_PCS_JCPLL_SDM_ORD], + AIROHA_PCS_ANA_JCPLL_SDM_ORD_3SDM); + regmap_field_write(pcs_ana_fields[AN7581_PCS_JCPLL_SDM_MODE], 0x0); + regmap_field_write(pcs_ana_fields[AN7581_PCS_JCPLL_SDM_IFM], 0x0); + regmap_field_write(pcs_ana_fields[AN7581_PCS_JCPLL_SDM_HREN], 0x0); + + /* Setup SSC */ + regmap_field_write(pcs_ana_fields[AN7581_PCS_JCPLL_SSC_DELTA], 0); + regmap_field_write(pcs_ana_fields[AN7581_PCS_JCPLL_SSC_DELTA1], 0); + regmap_field_write(pcs_ana_fields[AN7581_PCS_JCPLL_SSC_PERIOD], 0); + regmap_field_write(pcs_ana_fields[AN7581_PCS_JCPLL_SSC_TRI_EN], 0); + regmap_field_write(pcs_ana_fields[AN7581_PCS_JCPLL_SSC_EN], 0); + regmap_field_write(pcs_ana_fields[AN7581_PCS_JCPLL_SSC_PHASE_INI], 0); + regmap_field_write(pcs_ana_fields[AN7581_PCS_JCPLL_VCO_TCLVAR], 0x0); + regmap_field_write(pcs_ana_fields[AN7581_PCS_JCPLL_VCO_VCOVAR_BIAS_L], 0); + + /* Setup LPF */ + regmap_field_write(pcs_ana_fields[AN7581_PCS_JCPLL_CHP_IOFST], 0x0); + regmap_field_write(pcs_ana_fields[AN7581_PCS_JCPLL_CHP_IBIAS], 0x18); + regmap_field_write(pcs_ana_fields[AN7581_PCS_JCPLL_LPF_SHCK_EN], 0); + + regmap_field_write(pcs_ana_fields[AN7581_PCS_JCPLL_LPF_BWR], 0x0); + regmap_field_write(pcs_ana_fields[AN7581_PCS_JCPLL_LPF_BP], 0x10); + regmap_field_write(pcs_ana_fields[AN7581_PCS_JCPLL_LPF_BC], 0x1f); + regmap_field_write(pcs_ana_fields[AN7581_PCS_JCPLL_LPF_BR], BIT(3) | BIT(1)); + regmap_field_write(pcs_ana_fields[AN7581_PCS_JCPLL_LPF_BWC], 0x0); + + /* Setup VCO */ + regmap_field_write(pcs_ana_fields[AN7581_PCS_JCPLL_VCO_SCAPWR], 0x4); + regmap_field_write(pcs_ana_fields[AN7581_PCS_JCPLL_VCO_HALFLSB_EN], 0x1); + regmap_field_write(pcs_ana_fields[AN7581_PCS_JCPLL_VCO_CFIX], 0x1); + regmap_field_write(pcs_ana_fields[AN7581_PCS_JCPLL_VCO_VCOVAR_BIAS_L], 0x0); + regmap_field_write(pcs_ana_fields[AN7581_PCS_JCPLL_VCO_VCOVAR_BIAS_H], 0x3); + regmap_field_write(pcs_ana_fields[AN7581_PCS_JCPLL_VCO_TCLVAR], 0x3); + + /* Setup PCW */ + regmap_update_bits(pcs_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(pcs_pma, AIROHA_PCS_PMA_PXP_RX_FE_VOS, + AIROHA_PCS_PMA_FORCE_SEL_DA_JCPLL_SDM_PCW); + + /* Setup DIV */ + regmap_field_write(pcs_ana_fields[AN7581_PCS_JCPLL_POSTDIV_D5], 0x0); + regmap_field_write(pcs_ana_fields[AN7581_PCS_JCPLL_MMD_PREDIV_MODE], + AIROHA_PCS_ANA_JCPLL_MMD_PREDIV_MODE_2); + + regmap_field_write(pcs_ana_fields[AN7581_PCS_JCPLL_VCODIV], + AIROHA_PCS_ANA_JCPLL_VCODIV_1); + + /* Setup KBand */ + regmap_field_write(pcs_ana_fields[AN7581_PCS_JCPLL_KBAND_KS], 0x0); + regmap_field_write(pcs_ana_fields[AN7581_PCS_JCPLL_KBAND_KF], 0x3); + regmap_field_write(pcs_ana_fields[AN7581_PCS_JCPLL_KBAND_KFC], 0x0); + regmap_field_write(pcs_ana_fields[AN7581_PCS_JCPLL_KBAND_DIV], 0x2); + regmap_field_write(pcs_ana_fields[AN7581_PCS_JCPLL_KBAND_CODE], 0xe4); + regmap_field_write(pcs_ana_fields[AN7581_PCS_JCPLL_KBAND_OPTION], 0x0); + + /* Setup TCL */ + regmap_field_write(pcs_ana_fields[AN7581_PCS_JCPLL_TCL_KBAND_VREF], + kband_vref); + + regmap_field_write(pcs_ana_fields[AN7581_PCS_JCPLL_TCL_AMP_VREF], 0x5); + regmap_field_write(pcs_ana_fields[AN7581_PCS_JCPLL_TCL_AMP_GAIN], + AIROHA_PCS_ANA_JCPLL_TCL_AMP_GAIN_4); + regmap_field_write(pcs_ana_fields[AN7581_PCS_JCPLL_TCL_AMP_EN], 0x1); + + regmap_field_write(pcs_ana_fields[AN7581_PCS_JCPLL_TCL_LPF_BW], + AIROHA_PCS_ANA_JCPLL_TCL_LPF_BW_1); + regmap_field_write(pcs_ana_fields[AN7581_PCS_JCPLL_TCL_LPF_EN], 0x1); + + /* Enable PLL */ + regmap_set_bits(pcs_pma, AIROHA_PCS_PMA_PXP_JCPLL_CKOUT_EN, + AIROHA_PCS_PMA_FORCE_DA_JCPLL_EN); + + /* Enale PLL Output */ + regmap_set_bits(pcs_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 an7581_pcs_txpll_bringup(struct airoha_pcs_priv *priv, + int index, phy_interface_t interface) +{ + struct regmap_field **pcs_ana_fields = priv->pcs_ana_fields[index]; + u32 lpf_chp_ibias, lpf_bp, lpf_bwr, lpf_bwc; + struct regmap *pcs_pma; + u32 tcl_amp_vref; + bool sdm_hren; + u32 vco_cfix; + bool vcodiv; + u32 pcw; + + 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; + } + + /* This comment only apply to Serdes PCIe that expose + * 2 PCS. + * + * The Serdes PCIe expose 2 PCS but always require + * the PMA for the first PCS to be configured + * for correct functionality for TXPLL. + */ + pcs_pma = priv->pcs_pma[0]; + + /* Setup VCO LDO Output */ + regmap_field_write(pcs_ana_fields[AN7581_PCS_TXPLL_LDO_VCO_OUT], 0x1); + regmap_field_write(pcs_ana_fields[AN7581_PCS_TXPLL_LDO_OUT], 0x1); + + /* Setup RSTB */ + regmap_field_write(pcs_ana_fields[AN7581_PCS_TXPLL_PLL_RSTB], 0x1); + regmap_field_write(pcs_ana_fields[AN7581_PCS_TXPLL_RST_DLY], 0x4); + regmap_field_write(pcs_ana_fields[AN7581_PCS_TXPLL_REFIN_DIV], + AIROHA_PCS_ANA_TXPLL_REFIN_DIV_1); + regmap_field_write(pcs_ana_fields[AN7581_PCS_TXPLL_REFIN_INTERNAL], 0x1); + + /* Enable PLL force selection and Force Disable */ + regmap_update_bits(pcs_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_field_write(pcs_ana_fields[AN7581_PCS_TXPLL_SDM_MODE], 0x0); + regmap_field_write(pcs_ana_fields[AN7581_PCS_TXPLL_SDM_IFM], 0x0); + regmap_field_write(pcs_ana_fields[AN7581_PCS_TXPLL_SDM_DI_LS], + AIROHA_PCS_ANA_TXPLL_SDM_DI_LS_2_23); + regmap_field_write(pcs_ana_fields[AN7581_PCS_TXPLL_SDM_DI_EN], 0x0); + regmap_field_write(pcs_ana_fields[AN7581_PCS_TXPLL_SDM_HREN], sdm_hren); + regmap_field_write(pcs_ana_fields[AN7581_PCS_TXPLL_SDM_OUT], 0x0); + regmap_field_write(pcs_ana_fields[AN7581_PCS_TXPLL_SDM_ORD], + AIROHA_PCS_ANA_TXPLL_SDM_ORD_3SDM); + + /* Setup SSC */ + regmap_field_write(pcs_ana_fields[AN7581_PCS_TXPLL_SSC_DELTA1], 0x0); + regmap_field_write(pcs_ana_fields[AN7581_PCS_TXPLL_SSC_DELTA], 0x0); + regmap_field_write(pcs_ana_fields[AN7581_PCS_TXPLL_SSC_TRI_EN], 0x0); + regmap_field_write(pcs_ana_fields[AN7581_PCS_TXPLL_SSC_PHASE_INI], 0x0); + regmap_field_write(pcs_ana_fields[AN7581_PCS_TXPLL_SSC_EN], 0x0); + regmap_field_write(pcs_ana_fields[AN7581_PCS_TXPLL_SSC_PERIOD], 0x0); + + /* Setup LPF */ + regmap_field_write(pcs_ana_fields[AN7581_PCS_TXPLL_CHP_IBIAS], + lpf_chp_ibias); + regmap_field_write(pcs_ana_fields[AN7581_PCS_TXPLL_CHP_IOFST], 0x0); + regmap_field_write(pcs_ana_fields[AN7581_PCS_TXPLL_LPF_BC], 0x1f); + regmap_field_write(pcs_ana_fields[AN7581_PCS_TXPLL_LPF_BR], 0x5); + regmap_field_write(pcs_ana_fields[AN7581_PCS_TXPLL_LPF_BWC], lpf_bwc); + regmap_field_write(pcs_ana_fields[AN7581_PCS_TXPLL_LPF_BWR], lpf_bwr); + regmap_field_write(pcs_ana_fields[AN7581_PCS_TXPLL_LPF_BP], lpf_bp); + + /* Setup VCO */ + regmap_field_write(pcs_ana_fields[AN7581_PCS_TXPLL_VCO_CFIX], vco_cfix); + regmap_field_write(pcs_ana_fields[AN7581_PCS_TXPLL_VCO_VCOVAR_BIAS_L], 0x0); + regmap_field_write(pcs_ana_fields[AN7581_PCS_TXPLL_VCO_VCOVAR_BIAS_H], 0x4); + regmap_field_write(pcs_ana_fields[AN7581_PCS_TXPLL_VCO_TCLVAR], 0x4); + regmap_field_write(pcs_ana_fields[AN7581_PCS_TXPLL_VCO_SCAPWR], 0x7); + regmap_field_write(pcs_ana_fields[AN7581_PCS_TXPLL_VCO_HALFLSB_EN], 0x1); + + /* Setup PCW */ + regmap_update_bits(pcs_pma, AIROHA_PCS_PMA_PXP_TXPLL_SDM_PCW, + AIROHA_PCS_PMA_FORCE_DA_TXPLL_SDM_PCW, pcw); + + regmap_set_bits(pcs_pma, AIROHA_PCS_PMA_PXP_CDR_PR_IDAC, + AIROHA_PCS_PMA_FORCE_SEL_DA_TXPLL_SDM_PCW); + + /* Setup KBand */ + regmap_field_write(pcs_ana_fields[AN7581_PCS_TXPLL_KBAND_CODE], 0xe4); + regmap_field_write(pcs_ana_fields[AN7581_PCS_TXPLL_KBAND_OPTION], 0x0); + regmap_field_write(pcs_ana_fields[AN7581_PCS_TXPLL_KBAND_KS], 0x1); + regmap_field_write(pcs_ana_fields[AN7581_PCS_TXPLL_KBAND_KF], 0x3); + regmap_field_write(pcs_ana_fields[AN7581_PCS_TXPLL_KBAND_KFC], 0x0); + regmap_field_write(pcs_ana_fields[AN7581_PCS_TXPLL_KBAND_DIV], 0x4); + + /* Setup DIV */ + regmap_field_write(pcs_ana_fields[AN7581_PCS_TXPLL_POSTDIV_EN], 0x0); + regmap_field_write(pcs_ana_fields[AN7581_PCS_TXPLL_MMD_PREDIV_MODE], + AIROHA_PCS_ANA_TXPLL_MMD_PREDIV_MODE_2); + regmap_field_write(pcs_ana_fields[AN7581_PCS_TXPLL_VCODIV], + vcodiv ? AIROHA_PCS_ANA_TXPLL_VCODIV_2 : + AIROHA_PCS_ANA_TXPLL_VCODIV_1); + + /* Setup TCL */ + regmap_field_write(pcs_ana_fields[AN7581_PCS_TXPLL_TCL_KBAND_VREF], 0xf); + regmap_field_write(pcs_ana_fields[AN7581_PCS_TXPLL_TCL_AMP_VREF], + tcl_amp_vref); + regmap_field_write(pcs_ana_fields[AN7581_PCS_TXPLL_TCL_AMP_GAIN], + AIROHA_PCS_ANA_TXPLL_TCL_AMP_GAIN_4); + regmap_field_write(pcs_ana_fields[AN7581_PCS_TXPLL_TCL_LPF_BW], + AIROHA_PCS_ANA_TXPLL_TCL_LPF_BW_0_5); + regmap_field_write(pcs_ana_fields[AN7581_PCS_TXPLL_TCL_LPF_EN], 0x1); + regmap_field_write(pcs_ana_fields[AN7581_PCS_TXPLL_TCL_AMP_EN], 0x1); + + /* Enable PLL */ + regmap_set_bits(pcs_pma, AIROHA_PCS_PMA_PXP_TXPLL_CKOUT_EN, + AIROHA_PCS_PMA_FORCE_DA_TXPLL_EN); + + /* Enale PLL Output */ + regmap_set_bits(pcs_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 an7581_pcs_tx_bringup(struct airoha_pcs_priv *priv, + int index, phy_interface_t interface) +{ + struct regmap_field **pcs_ana_fields = priv->pcs_ana_fields[index]; + struct regmap *pcs_pma = priv->pcs_pma[index]; + u32 fir_cn1, fir_c0b, fir_c1; + u32 tx_rate_ctrl; + u32 ckin_divisor; + u32 xfi_tx_mode; + + 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; + xfi_tx_mode = AIROHA_PCS_PMA_XFI_TX_MODE_1G25; + break; + case PHY_INTERFACE_MODE_2500BASEX: + ckin_divisor = BIT(2); + tx_rate_ctrl = BIT(0); + fir_cn1 = 0; + fir_c0b = 11; + fir_c1 = 1; + xfi_tx_mode = AIROHA_PCS_PMA_XFI_TX_MODE_3G12; + 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; + xfi_tx_mode = AIROHA_PCS_PMA_XFI_TX_MODE_10G3; + break; + default: + return; + } + + /* Set TX rate ctrl */ + if (priv->data->port_type == AIROHA_PCS_PCIE) { + regmap_update_bits(pcs_pma, AIROHA_PCS_PMA_DIG_RESERVE_29, + AIROHA_PCS_PMA_2L_TX_RATE_CTRL, + FIELD_PREP(AIROHA_PCS_PMA_2L_TX_RATE_CTRL, + tx_rate_ctrl)); + + regmap_update_bits(pcs_pma, AIROHA_PCS_PMA_ADD_XPON_MODE_1, + AIROHA_PCS_PMA_XFI_TX_MODE, + xfi_tx_mode); + } else { + regmap_update_bits(pcs_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_field_write(pcs_ana_fields[AN7581_PCS_TX_DMEDGEGEN_EN], 0x1); + regmap_field_write(pcs_ana_fields[AN7581_PCS_TX_CKLDO_EN], 0x1); + + udelay(1); + + regmap_set_bits(pcs_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(pcs_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)); + + if (priv->data->port_type != AIROHA_PCS_PCIE) { + regmap_update_bits(pcs_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(pcs_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(pcs_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(pcs_pma, AIROHA_PCS_PMA_TX_RST_B, + AIROHA_PCS_PMA_TXCALIB_RST_B | AIROHA_PCS_PMA_TX_TOP_RST_B); +} + +static void an7581_pcs_rx_bringup(struct airoha_pcs_priv *priv, + int index, phy_interface_t interface) +{ + struct regmap_field **pcs_ana_fields = priv->pcs_ana_fields[index]; + struct regmap *pcs_pma = priv->pcs_pma[index]; + u32 phyck_div, phyck_sel; + u32 pr_cdr_beta_dac; + u32 cdr_pr_buf_in_sr; + bool cdr_pr_cap_en; + u32 sigdet_vth_sel; + u32 rx_rate_ctrl; + u32 xfi_rx_mode; + u32 osr; + + 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); + xfi_rx_mode = AIROHA_PCS_PMA_XFI_TX_MODE_1G25; + 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); + xfi_rx_mode = AIROHA_PCS_PMA_XFI_RX_MODE_3G12; + 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); + xfi_rx_mode = AIROHA_PCS_PMA_XFI_RX_MODE_10G3; + break; + default: + return; + } + + /* Set RX rate ctrl */ + if (interface == PHY_INTERFACE_MODE_2500BASEX) + regmap_update_bits(pcs_pma, AIROHA_PCS_PMA_RX_FLL_2, + AIROHA_PCS_PMA_CK_RATE, + AIROHA_PCS_PMA_CK_RATE_10); + + if (priv->data->port_type == AIROHA_PCS_PCIE) { + regmap_update_bits(pcs_pma, AIROHA_PCS_PMA_DIG_RESERVE_29, + AIROHA_PCS_PMA_2L_RX_RATE_CTRL, + FIELD_PREP(AIROHA_PCS_PMA_2L_RX_RATE_CTRL, + rx_rate_ctrl)); + + regmap_update_bits(pcs_pma, AIROHA_PCS_PMA_ADD_XPON_MODE_1, + AIROHA_PCS_PMA_XFI_RX_MODE, + xfi_rx_mode); + } else { + regmap_update_bits(pcs_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(pcs_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_field_write(pcs_ana_fields[AN7581_PCS_RX_DAC_EYE_BYPASS_AEQ], 0x1); + regmap_field_write(pcs_ana_fields[AN7581_PCS_RX_DAC_E1_BYPASS_AEQ], 0x1); + regmap_field_write(pcs_ana_fields[AN7581_PCS_RX_DAC_E0_BYPASS_AEQ], 0x1); + regmap_field_write(pcs_ana_fields[AN7581_PCS_RX_DAC_D1_BYPASS_AEQ], 0x1); + regmap_field_write(pcs_ana_fields[AN7581_PCS_RX_DAC_D0_BYPASS_AEQ], 0x1); + regmap_field_write(pcs_ana_fields[AN7581_PCS_RX_FE_VCM_GEN_PWDB], 0x1); + + regmap_set_bits(pcs_pma, AIROHA_PCS_PMA_SS_LCPLL_PWCTL_SETTING_1, + AIROHA_PCS_PMA_LCPLL_MAN_PWDB); + + regmap_field_write(pcs_ana_fields[AN7581_PCS_AEQ_OFORCE], + AIROHA_PCS_ANA_AEQ_OFORCE_CTLE); + + regmap_field_write(pcs_ana_fields[AN7581_PCS_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(pcs_pma, AIROHA_PCS_PMA_RX_DISB_MODE_4, + AIROHA_PCS_PMA_DISB_BLWC_OFFSET); + + regmap_clear_bits(pcs_pma, AIROHA_PCS_PMA_RX_EXTRAL_CTRL, + AIROHA_PCS_PMA_DISB_LEQ); + + regmap_field_write(pcs_ana_fields[AN7581_PCS_CDR_PD_EDGE_DIS], 0x0); + regmap_field_write(pcs_ana_fields[AN7581_PCS_CDR_PD_PICAL_CKD8_INV], 0x0); + + regmap_update_bits(pcs_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(pcs_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_field_write(pcs_ana_fields[AN7581_PCS_RX_DAC_MON], 0x0); + regmap_field_write(pcs_ana_fields[AN7581_PCS_CDR_PR_XFICK_EN], 0x1); + regmap_field_write(pcs_ana_fields[AN7581_PCS_CDR_PR_MONPI_EN], 0x0); + regmap_field_write(pcs_ana_fields[AN7581_PCS_CDR_PR_MONPR_EN], 0x0); + + /* Setup FE Gain and FE Peacking */ + regmap_update_bits(pcs_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(pcs_pma, AIROHA_PCS_PMA_PXP_JCPLL_SDM_SCAN, + AIROHA_PCS_PMA_FORCE_SEL_DA_RX_FE_PEAKING_CTRL | + AIROHA_PCS_PMA_FORCE_DA_RX_FE_PEAKING_CTRL, + FIELD_PREP(AIROHA_PCS_PMA_FORCE_DA_RX_FE_PEAKING_CTRL, 0x0)); + + /* Setup FE VOS */ + if (interface != PHY_INTERFACE_MODE_USXGMII && + interface != PHY_INTERFACE_MODE_10GBASER) + regmap_update_bits(pcs_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(pcs_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(pcs_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(pcs_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_field_write(pcs_ana_fields[AN7581_PCS_RX_REV_1_FE_BUF1_BIAS_CTRL], + BIT(2)); + regmap_field_write(pcs_ana_fields[AN7581_PCS_RX_REV_1_FE_BUF2_BIAS_CTRL], + BIT(2)); + regmap_field_write(pcs_ana_fields[AN7581_PCS_RX_REV_1_SIGDET_ILEAK], 0x0); + + /* Setup Rdy Timeout */ + regmap_update_bits(pcs_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(pcs_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(pcs_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(pcs_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(pcs_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(pcs_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(pcs_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*/ + /* Setup RX OSR */ + regmap_update_bits(pcs_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)); + + regmap_field_write(pcs_ana_fields[AN7581_PCS_CDR_PD_EDGE_DIS], !!osr); + + /* Setup CDR LPF Ratio */ + regmap_field_write(pcs_ana_fields[AN7581_PCS_CDR_LPF_TOP_LIM], 0x20000); + regmap_field_write(pcs_ana_fields[AN7581_PCS_CDR_LPF_RATIO], osr); + + /* Setup CDR PR */ + regmap_field_write(pcs_ana_fields[AN7581_PCS_CDR_PR_KBAND_DIV], 0x4); + regmap_field_write(pcs_ana_fields[AN7581_PCS_CDR_PR_BETA_SEL], 0x1); + regmap_field_write(pcs_ana_fields[AN7581_PCS_CDR_PR_VCOADC_OS], 0x8); + regmap_field_write(pcs_ana_fields[AN7581_PCS_CDR_PR_BETA_DAC], + pr_cdr_beta_dac); + regmap_field_write(pcs_ana_fields[AN7581_PCS_CDR_PR_FBKSEL], 0x0); + regmap_field_write(pcs_ana_fields[AN7581_PCS_CDR_PR_DAC_BAND], + pr_cdr_beta_dac); + regmap_field_write(pcs_ana_fields[AN7581_PCS_CDR_PR_VREG_CKBUF_VAL], 0x6); + regmap_field_write(pcs_ana_fields[AN7581_PCS_CDR_PR_VREG_IBAND_VAL], 0x6); + + /* Setup Eye Mon */ + regmap_update_bits(pcs_pma, AIROHA_PCS_PMA_PHY_EQ_CTRL_2, + 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(pcs_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(pcs_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(pcs_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(pcs_pma, AIROHA_PCS_PMA_RX_DISB_MODE_8, + AIROHA_PCS_PMA_DISB_FBCK_LOCK); + + regmap_set_bits(pcs_pma, AIROHA_PCS_PMA_RX_FORCE_MODE_9, + AIROHA_PCS_PMA_FORCE_FBCK_LOCK); + + /* Enable CMLEQ */ + regmap_field_write(pcs_ana_fields[AN7581_PCS_RX_FE_EQ_HZEN], 0x0); + regmap_field_write(pcs_ana_fields[AN7581_PCS_RX_FE_VB_EQ3_EN], 0x1); + regmap_field_write(pcs_ana_fields[AN7581_PCS_RX_FE_VB_EQ2_EN], 0x1); + regmap_field_write(pcs_ana_fields[AN7581_PCS_RX_FE_VB_EQ1_EN], 0x1); + + /* Setup CDR PR */ + regmap_field_write(pcs_ana_fields[AN7581_PCS_CDR_PR_CAP_EN], + cdr_pr_cap_en); + regmap_field_write(pcs_ana_fields[AN7581_PCS_CDR_BUF_IN_SR], + cdr_pr_buf_in_sr); + + /* Setup CDR xxx Pwdb, set force and disable */ + regmap_update_bits(pcs_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(pcs_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(pcs_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(pcs_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(pcs_pma, AIROHA_PCS_PMA_SS_DA_XPON_PWDB_0, + AIROHA_PCS_PMA_XPON_CDR_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->pcs_ana, AIROHA_PCS_ANA_PXP_RX_SIGDET_NOVTH, + * AIROHA_PCS_ANA_RX_FE_50OHMS_SEL); + */ + + /* Setup SigDet */ + regmap_field_write(pcs_ana_fields[AN7581_PCS_RX_SIGDET_VTH_SEL], + sigdet_vth_sel); + regmap_field_write(pcs_ana_fields[AN7581_PCS_RX_SIGDET_PEAK], + BIT(1)); + regmap_field_write(pcs_ana_fields[AN7581_PCS_RX_SIGDET_LPF_CTRL], + BIT(1) | BIT(0)); + + /* Disable SigDet Pwdb */ + regmap_clear_bits(pcs_pma, AIROHA_PCS_PMA_SS_DA_XPON_PWDB_1, + AIROHA_PCS_PMA_RX_SIDGET_PWDB); + + /* Setup PHYCK */ + regmap_field_write(pcs_ana_fields[AN7581_PCS_RX_TDC_CK_SEL], 0x0); + regmap_field_write(pcs_ana_fields[AN7581_PCS_RX_PHYCK_RSTB], 0x1); + regmap_field_write(pcs_ana_fields[AN7581_PCS_RX_PHYCK_SEL], + phyck_sel); + regmap_field_write(pcs_ana_fields[AN7581_PCS_RX_PHYCK_DIV], + phyck_div); + regmap_field_write(pcs_ana_fields[AN7581_PCS_RX_PHY_CK_SEL_FORCE], 0x1); + regmap_field_write(pcs_ana_fields[AN7581_PCS_RX_PHY_CK_SEL], 0x0); + + usleep_range(100, 200); + + /* Enable CDR xxx Pwdb */ + regmap_set_bits(pcs_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(pcs_pma, AIROHA_PCS_PMA_PXP_CDR_PD_PWDB, + AIROHA_PCS_PMA_FORCE_DA_CDR_PR_PD_PWDB); + + regmap_set_bits(pcs_pma, AIROHA_PCS_PMA_PXP_RX_FE_PWDB, + AIROHA_PCS_PMA_FORCE_DA_RX_FE_PWDB); + + regmap_set_bits(pcs_pma, AIROHA_PCS_PMA_PXP_RX_SCAN_RST_B, + AIROHA_PCS_PMA_FORCE_DA_RX_SIGDET_PWDB); + + regmap_set_bits(pcs_pma, AIROHA_PCS_PMA_SS_DA_XPON_PWDB_0, + AIROHA_PCS_PMA_XPON_CDR_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(pcs_pma, AIROHA_PCS_PMA_SS_DA_XPON_PWDB_1, + AIROHA_PCS_PMA_RX_SIDGET_PWDB); +} + +static unsigned int an7581_pcs_apply_cdr_pr_idac(struct airoha_pcs_priv *priv, + int index, u32 cdr_pr_idac) +{ + struct regmap *pcs_pma = priv->pcs_pma[index]; + u32 val; + + regmap_update_bits(pcs_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(pcs_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(pcs_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(pcs_pma, AIROHA_PCS_PMA_RX_FREQDET, &val); + + return FIELD_GET(AIROHA_PCS_PMA_FL_OUT, val); +} + +static u32 an7581_pcs_rx_prcal_idac_major(struct airoha_pcs_priv *priv, + int index, u32 target_fl_out) +{ + unsigned int fl_out_diff = UINT_MAX; + unsigned int prcal_search; + u32 cdr_pr_idac = 0; + + for (prcal_search = 0; prcal_search < 8 ; prcal_search++) { + unsigned int fl_out_diff_new; + unsigned int fl_out; + 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 = an7581_pcs_apply_cdr_pr_idac(priv, index, cdr_pr_idac_tmp); + + /* Use absolute values to find the closest one to target */ + fl_out_diff_new = abs(fl_out - target_fl_out); + dev_dbg(priv->dev, "Tested CDR Pr Idac: %x Fl Out: %x Diff: %u\n", + cdr_pr_idac_tmp, fl_out, fl_out_diff_new); + if (fl_out_diff_new < fl_out_diff) { + cdr_pr_idac = cdr_pr_idac_tmp; + fl_out_diff = fl_out_diff_new; + } + } + + return cdr_pr_idac; +} + +static u32 an7581_pcs_rx_prcal_idac_minor(struct airoha_pcs_priv *priv, int index, + u32 target_fl_out, u32 cdr_pr_idac_major) +{ + unsigned int remaining_prcal_search_bits = 0; + u32 cdr_pr_idac = cdr_pr_idac_major; + unsigned int fl_out, fl_out_diff; + int best_prcal_search_bit = -1; + int prcal_search_bit; + + fl_out = an7581_pcs_apply_cdr_pr_idac(priv, index, cdr_pr_idac); + fl_out_diff = abs(fl_out - target_fl_out); + + /* Deadline search part. + * We start from top bits to bottom as we progressively decrease the + * signal. + */ + for (prcal_search_bit = 7; prcal_search_bit >= 0; prcal_search_bit--) { + unsigned int fl_out_diff_new; + u32 cdr_pr_idac_tmp; + + cdr_pr_idac_tmp = cdr_pr_idac | BIT(prcal_search_bit); + fl_out = an7581_pcs_apply_cdr_pr_idac(priv, index, cdr_pr_idac_tmp); + + /* Use absolute values to find the closest one to target */ + fl_out_diff_new = abs(fl_out - target_fl_out); + dev_dbg(priv->dev, "Tested CDR Pr Idac: %x Fl Out: %x Diff: %u\n", + cdr_pr_idac_tmp, fl_out, fl_out_diff_new); + if (fl_out_diff_new < fl_out_diff) { + best_prcal_search_bit = prcal_search_bit; + fl_out_diff = fl_out_diff_new; + } + } + + /* Set the idac with the best value we found and + * reset the search bit to start from bottom to top. + */ + if (best_prcal_search_bit >= 0) { + cdr_pr_idac |= BIT(best_prcal_search_bit); + remaining_prcal_search_bits = best_prcal_search_bit; + prcal_search_bit = 0; + } + + /* Fine tune part. + * Test remaining bits to find an even closer signal level to target + * by increasing the signal. + */ + 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 = an7581_pcs_apply_cdr_pr_idac(priv, index, 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) + */ + dev_dbg(priv->dev, "Tested CDR Pr Idac: %x Fl Out: %x Diff: %u\n", + cdr_pr_idac_tmp, fl_out, fl_out_diff_new); + 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) + break; + + /* We found the deadline, set the value to the previous + * bit, and reset the loop to fine tune with the + * remaining values. + */ + cdr_pr_idac |= BIT(prcal_search_bit - 1); + remaining_prcal_search_bits = prcal_search_bit - 1; + prcal_search_bit = 0; + } 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 reset the loop to fine tune with the remainig + * values. + */ + if (prcal_search_bit == remaining_prcal_search_bits - 1) { + cdr_pr_idac |= BIT(prcal_search_bit); + remaining_prcal_search_bits = prcal_search_bit; + prcal_search_bit = 0; + } else { + prcal_search_bit++; + } + } + } + + return cdr_pr_idac; +} + +static void an7581_pcs_rx_prcal(struct airoha_pcs_priv *priv, + int index, phy_interface_t interface) +{ + struct regmap_field **pcs_ana_fields = priv->pcs_ana_fields[index]; + struct regmap *pcs_pma = priv->pcs_pma[index]; + u32 cdr_pr_idac_major, cdr_pr_idac; + unsigned int fl_out, fl_out_diff; + + 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(pcs_pma, AIROHA_PCS_PMA_SW_RST_SET, + AIROHA_PCS_PMA_SW_REF_RST_N); + + usleep_range(100, 200); + + regmap_update_bits(pcs_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(pcs_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(pcs_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(pcs_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_field_write(pcs_ana_fields[AN7581_PCS_CDR_PR_INJ_FORCE_OFF], 0x1); + + regmap_update_bits(pcs_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(pcs_pma, AIROHA_PCS_PMA_PXP_CDR_PR_IDAC, + AIROHA_PCS_PMA_FORCE_SEL_DA_CDR_PR_IDAC); + + regmap_set_bits(pcs_pma, AIROHA_PCS_PMA_PXP_CDR_PR_PIEYE_PWDB, + AIROHA_PCS_PMA_FORCE_SEL_DA_CDR_PR_PWDB); + + regmap_clear_bits(pcs_pma, AIROHA_PCS_PMA_PXP_CDR_PR_PIEYE_PWDB, + AIROHA_PCS_PMA_FORCE_DA_CDR_PR_PWDB); + + regmap_set_bits(pcs_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 is closer to + * the target. + * + * Then check each remaining 7 bits in search of the deadline + * where the signal gets farther than signal target. + * + * Finally fine tune for the remaining bits to find the one that + * produce the closest signal level. + */ + cdr_pr_idac_major = an7581_pcs_rx_prcal_idac_major(priv, index, target_fl_out); + + cdr_pr_idac = an7581_pcs_rx_prcal_idac_minor(priv, index, + target_fl_out, cdr_pr_idac_major); + + fl_out = an7581_pcs_apply_cdr_pr_idac(priv, index, cdr_pr_idac); + fl_out_diff = abs(fl_out - target_fl_out); + if (fl_out_diff > 100) { + u32 pr_idac_major = FIELD_GET(AIROHA_PCS_PMA_FORCE_CDR_PR_IDAC_MAJOR, + cdr_pr_idac_major); + unsigned int fl_out_tmp, fl_out_diff_tmp; + u32 cdr_pr_idac_tmp; + + if (pr_idac_major > 0) { + cdr_pr_idac_tmp = FIELD_PREP(AIROHA_PCS_PMA_FORCE_CDR_PR_IDAC_MAJOR, + pr_idac_major - 1); + + dev_dbg(priv->dev, "Fl Out is %d far from target %d with Pr Idac %x. Trying with Pr Idac %x.\n", + fl_out_diff, target_fl_out, cdr_pr_idac_major, cdr_pr_idac_tmp); + + cdr_pr_idac_tmp = an7581_pcs_rx_prcal_idac_minor(priv, index, + target_fl_out, + cdr_pr_idac_tmp); + + fl_out_tmp = an7581_pcs_apply_cdr_pr_idac(priv, index, + cdr_pr_idac_tmp); + fl_out_diff_tmp = abs(fl_out_tmp - target_fl_out); + if (fl_out_diff_tmp < fl_out_diff) { + fl_out = fl_out_tmp; + fl_out_diff = fl_out_diff_tmp; + cdr_pr_idac = cdr_pr_idac_tmp; + } + } + } + dev_dbg(priv->dev, "Selected CDR Pr Idac: %x Fl Out: %x\n", cdr_pr_idac, fl_out); + if (fl_out_diff > 100) + dev_dbg(priv->dev, "Fl Out is %d far from target %d on intermediate calibration.\n", + fl_out_diff, target_fl_out); + + /* Setup Load Band */ + regmap_field_write(pcs_ana_fields[AN7581_PCS_CDR_PR_INJ_FORCE_OFF], 0x0); + + /* Disable force of LPF C previously enabled */ + regmap_clear_bits(pcs_pma, AIROHA_PCS_PMA_PXP_CDR_PR_LPF_C_EN, + AIROHA_PCS_PMA_FORCE_SEL_DA_CDR_PR_LPF_C_EN); + + regmap_clear_bits(pcs_pma, AIROHA_PCS_PMA_PXP_CDR_PR_IDAC, + AIROHA_PCS_PMA_FORCE_SEL_DA_CDR_PR_IDAC); + + regmap_set_bits(pcs_pma, AIROHA_PCS_PMA_RX_FLL_B, + AIROHA_PCS_PMA_LOAD_EN); + + regmap_update_bits(pcs_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(pcs_pma, AIROHA_PCS_PMA_PXP_CDR_PR_PIEYE_PWDB, + AIROHA_PCS_PMA_FORCE_DA_CDR_PR_PWDB); + + regmap_set_bits(pcs_pma, AIROHA_PCS_PMA_PXP_CDR_PR_PIEYE_PWDB, + AIROHA_PCS_PMA_FORCE_DA_CDR_PR_PWDB); + + regmap_clear_bits(pcs_pma, AIROHA_PCS_PMA_PXP_CDR_PR_PIEYE_PWDB, + AIROHA_PCS_PMA_FORCE_SEL_DA_CDR_PR_PWDB); + + regmap_clear_bits(pcs_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 an7581_pcs_cdr_reset(struct airoha_pcs_priv *priv, int index, + phy_interface_t interface, bool calibrate) +{ + struct regmap *pcs_pma = priv->pcs_pma[index]; + + /* Setup LPF L2D force and disable */ + regmap_update_bits(pcs_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) + an7581_pcs_rx_prcal(priv, index, interface); + + /* Setup LPF RSTB force and disable */ + regmap_update_bits(pcs_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(pcs_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(pcs_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(pcs_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(pcs_pma, AIROHA_PCS_PMA_PXP_CDR_LPF_LCK_2DATA, + AIROHA_PCS_PMA_FORCE_SEL_DA_CDR_LPF_LCK2DATA); +} + +static int an7581_pcs_phya_bringup(struct airoha_pcs_priv *priv, + int index, phy_interface_t interface) +{ + struct regmap *pcs_pma = priv->pcs_pma[index]; + int calibration_try = 0; + u32 val; + + an7581_pcs_tx_bringup(priv, index, interface); + an7581_pcs_rx_bringup(priv, index, interface); + + usleep_range(100, 200); + +retry_calibration: + an7581_pcs_cdr_reset(priv, index, interface, priv->manual_rx_calib); + + /* Global reset clear */ + regmap_update_bits(pcs_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_XFI_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(pcs_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_XFI_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); + + an7581_pcs_cdr_reset(priv, index, interface, false); + + /* Manual RX calibration is required only for SoC before E2 + * revision. E2+ SoC autocalibrate RX and only CDR reset is needed. + */ + if (!priv->manual_rx_calib) + return 0; + + /* It was discovered that after a global reset and auto mode gets + * actually enabled, the fl_out from calibration might change and + * might deviates a lot from the expected value it was calibrated for. + * 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(pcs_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 an7581_pcs_pll_bringup(struct airoha_pcs_priv *priv, + int index, phy_interface_t interface) +{ + an7581_pcs_jcpll_bringup(priv, index, interface); + + usleep_range(200, 300); + + an7581_pcs_txpll_bringup(priv, index, interface); + + usleep_range(200, 300); +} + +int an7581_pcs_bringup(struct airoha_pcs_priv *priv, int index, + phy_interface_t interface) +{ + struct regmap_field **pcs_ana_fields = priv->pcs_ana_fields[index]; + + /* Enable Analog Common Lane */ + regmap_field_write(pcs_ana_fields[AN7581_PCS_CMN_EN], 0x1); + + /* Setup PLL */ + an7581_pcs_pll_bringup(priv, index, interface); + + msleep(100); + + /* Setup PHYA */ + return an7581_pcs_phya_bringup(priv, index, interface); +} + +int an7581_pcs_usb_bringup(struct airoha_pcs_priv *priv, + int index, phy_interface_t interface) +{ + int ret; + + ret = phy_set_mode_ext(priv->phy, PHY_MODE_ETHERNET, interface); + if (ret) + return ret; + + if (interface == PHY_INTERFACE_MODE_2500BASEX) { + regmap_update_bits(priv->pcs_ana, AIROHA_PCS_HSGMII_ANA_SGMII_PHYA_8, + AIROHA_PCS_HSGMII_ANA_SSUSB_CDR_BICLTR | + AIROHA_PCS_HSGMII_ANA_SSUSB_CDR_BICLTD1 | + AIROHA_PCS_HSGMII_ANA_SSUSB_CDR_BICLTD0, + FIELD_PREP(AIROHA_PCS_HSGMII_ANA_SSUSB_CDR_BICLTR, 0xf) | + FIELD_PREP(AIROHA_PCS_HSGMII_ANA_SSUSB_CDR_BICLTD1, 0xc) | + FIELD_PREP(AIROHA_PCS_HSGMII_ANA_SSUSB_CDR_BICLTD0, 0x3)); + + regmap_set_bits(priv->pcs_ana, AIROHA_PCS_HSGMII_ANA_SGMII_PHYA_6, + AIROHA_PCS_HSGMII_ANA_FORCE_CDR_BIC); + } else { + regmap_clear_bits(priv->pcs_ana, AIROHA_PCS_HSGMII_ANA_SGMII_PHYA_6, + AIROHA_PCS_HSGMII_ANA_FORCE_CDR_BIC); + } + + regmap_update_bits(priv->pcs_ana, AIROHA_PCS_HSGMII_ANA_SGMII_PHYA_26, + AIROHA_PCS_HSGMII_ANA_SSUSB_LN0_CDR_RST_DLY, + AIROHA_PCS_HSGMII_ANA_SSUSB_LN0_CDR_RST_DLY_32); + + regmap_clear_bits(priv->pcs_ana, AIROHA_PCS_HSGMII_ANA_SGMII_PHYA_24, + AIROHA_PCS_HSGMII_ANA_SSUSB_LN0_CDR_RESERVE); + + regmap_update_bits(priv->pcs_ana, AIROHA_PCS_HSGMII_ANA_SGMII_PHYA_18, + AIROHA_PCS_HSGMII_ANA_SSUSB_BG_DIV, + FIELD_PREP(AIROHA_PCS_HSGMII_ANA_SSUSB_BG_DIV, 0x1)); + + regmap_update_bits(priv->pcs_ana, AIROHA_PCS_HSGMII_ANA_SGMII_PHYA_19, + AIROHA_PCS_HSGMII_ANA_SSUSB_XTAL_TOP_RESERVE, + FIELD_PREP(AIROHA_PCS_HSGMII_ANA_SSUSB_XTAL_TOP_RESERVE, + FIELD_PREP(AIROHA_PCS_HSGMII_ANA_SSUSB_XTAL_TOP_RESERVE_HV, + AIROHA_PCS_HSGMII_ANA_SSUSB_XTAL_TOP_RESERVE_NS_MONPLL_CK))); + + if (interface == PHY_INTERFACE_MODE_2500BASEX) + regmap_update_bits(priv->pcs_ana, AIROHA_PCS_HSGMII_ANA_SGMII_PHYA_11, + AIROHA_PCS_HSGMII_ANA_TPHY_SPEED, + AIROHA_PCS_HSGMII_ANA_TPHY_SPEED_HSGMII); + else + regmap_update_bits(priv->pcs_ana, AIROHA_PCS_HSGMII_ANA_SGMII_PHYA_11, + AIROHA_PCS_HSGMII_ANA_TPHY_SPEED, + AIROHA_PCS_HSGMII_ANA_TPHY_SPEED_SGMII); + + return 0; +} + +void an7581_pcs_phya_link_up(struct airoha_pcs_priv *priv, int index) +{ + struct regmap *pcs_pma = priv->pcs_pma[index]; + + /* Reset TXPCS on link up */ + regmap_clear_bits(pcs_pma, AIROHA_PCS_PMA_SW_RST_SET, + AIROHA_PCS_PMA_SW_HSG_TXPCS_RST_N); + + usleep_range(100, 200); + + regmap_set_bits(pcs_pma, AIROHA_PCS_PMA_SW_RST_SET, + AIROHA_PCS_PMA_SW_HSG_TXPCS_RST_N); +} + +static int __an7581_pcs_alloc_regmap_fields(struct airoha_pcs_priv *priv, int index, + const struct reg_field *fields) +{ + struct device *dev = priv->dev; + int i; + + priv->pcs_ana_fields[index] = devm_kcalloc(dev, AN7581_PCS_FIELDS_MAX, + sizeof(*priv->pcs_ana_fields[index]), + GFP_KERNEL); + if (!priv->pcs_ana_fields[index]) + return -ENOMEM; + + for (i = 0; i < AN7581_PCS_FIELDS_MAX; i++) { + struct regmap_field *field; + + field = devm_regmap_field_alloc(dev, priv->pcs_ana, + fields[i]); + if (IS_ERR(field)) + return PTR_ERR(field); + + priv->pcs_ana_fields[index][i] = field; + } + + return 0; +} + +int an7581_pcs_alloc_regmap_fields(struct airoha_pcs_priv *priv) +{ + return __an7581_pcs_alloc_regmap_fields(priv, 0, an7581_pcs_fields); +} + +int an7581_pcs_pcie_alloc_regmap_fields(struct airoha_pcs_priv *priv) +{ + int ret; + + ret = __an7581_pcs_alloc_regmap_fields(priv, 0, an7581_pcs_pcie0_fields); + if (ret) + return ret; + + return __an7581_pcs_alloc_regmap_fields(priv, 1, an7581_pcs_pcie1_fields); +} + +static bool an7581_pcs_have_rx_signal(struct airoha_pcs_priv *priv, int index) +{ + struct regmap *pcs_pma = priv->pcs_pma[index]; + unsigned int count = 0; + u32 val; + int i; + + regmap_write(pcs_pma, AIROHA_PCS_PMA_DIG_RESERVE_0, + AIROHA_PCS_TRIGGER_RX_SIDGET_SCAN); + + /* Scan 5 times for RX sigdet module to detect RX signal */ + for (i = 0; i <= 5; i++) { + regmap_read(pcs_pma, AIROHA_PCS_PMA_DIG_RO_RESERVE_2, + &val); + if (val & AIROHA_PCS_RX_SIGDET) + count++; + } + + /* Consider signal presence if we detect signal at least 4 times */ + return count >= 4; +} + +int an7581_pcs_rxlock_workaround(struct airoha_pcs_priv *priv, int index) +{ + struct airoha_pcs_maps *maps = &priv->maps[index]; + u32 val; + + /* Check if PCS is UP or Down */ + regmap_read(maps->usxgmii_pcs, AIROHA_PCS_USXGMII_PCS_STUS_1, &val); + if (val & AIROHA_PCS_USXGMII_PCS_RX_LINK_STATUS_UP) + return 0; + + /* Validate if this is consistent with RX SigDet module */ + if (!an7581_pcs_have_rx_signal(priv, index)) + return 0; + + /* If PCS is down but RX SigDet module detected signal, + * trigger CDR reset. + */ + an7581_pcs_cdr_reset(priv, index, PHY_INTERFACE_MODE_NA, false); + + /* Report there is an error with Link Detection and we + * should test again later. + */ + return -EINVAL; +} -- 2.53.0