ARCH:=arm
BOARD:=airoha
BOARDNAME:=Airoha ARM
-SUBTARGETS:=en7523 an7581
+SUBTARGETS:=en7523 an7581 an7583
FEATURES:=dt squashfs nand ramdisk gpio
KERNEL_PATCHVER:=6.12
CONFIG_LZO_DECOMPRESS=y
CONFIG_MDIO_BUS=y
CONFIG_MDIO_DEVICE=y
+# CONFIG_MDIO_AIROHA is not set
CONFIG_MDIO_DEVRES=y
# CONFIG_MEDIATEK_GE_SOC_PHY is not set
# CONFIG_MEMCG is not set
CONFIG_PCI_DOMAINS_GENERIC=y
CONFIG_PCI_MSI=y
CONFIG_PCS_AIROHA_AN7581=y
+# CONFIG_PCS_AIROHA_AN7583 is not set
CONFIG_PERF_EVENTS=y
CONFIG_PER_VMA_LOCK=y
CONFIG_PGTABLE_LEVELS=3
--- /dev/null
+#
+# Copyright (c) 2015 The Linux Foundation. All rights reserved.
+# Copyright (c) 2011-2015 OpenWrt.org
+#
+
+. /lib/functions/uci-defaults.sh
+. /lib/functions/system.sh
+
+an7583_setup_interfaces()
+{
+ local board="$1"
+
+ case "$board" in
+ airoha,an7583-evb)
+ ucidef_set_interface_lan "lan1 lan2 lan3 lan4 eth1"
+ ;;
+ *)
+ echo "Unsupported hardware. Network interfaces not initialized"
+ ;;
+ esac
+}
+
+board_config_update
+board=$(board_name)
+an7583_setup_interfaces $board
+board_config_flush
+
+exit 0
--- /dev/null
+CONFIG_64BIT=y
+CONFIG_AIROHA_CPU_PM_DOMAIN=y
+CONFIG_AIROHA_SCU_SSR=y
+CONFIG_AIROHA_THERMAL=y
+CONFIG_AIROHA_WATCHDOG=y
+CONFIG_AMPERE_ERRATUM_AC03_CPU_38=y
+CONFIG_ARCH_AIROHA=y
+CONFIG_ARCH_BINFMT_ELF_EXTRA_PHDRS=y
+CONFIG_ARCH_CORRECT_STACKTRACE_ON_KRETPROBE=y
+CONFIG_ARCH_DEFAULT_KEXEC_IMAGE_VERIFY_SIG=y
+CONFIG_ARCH_DMA_ADDR_T_64BIT=y
+CONFIG_ARCH_FORCE_MAX_ORDER=10
+CONFIG_ARCH_KEEP_MEMBLOCK=y
+CONFIG_ARCH_MHP_MEMMAP_ON_MEMORY_ENABLE=y
+CONFIG_ARCH_MMAP_RND_BITS=18
+CONFIG_ARCH_MMAP_RND_BITS_MAX=24
+CONFIG_ARCH_MMAP_RND_BITS_MIN=18
+CONFIG_ARCH_MMAP_RND_COMPAT_BITS_MIN=11
+CONFIG_ARCH_PROC_KCORE_TEXT=y
+CONFIG_ARCH_SPARSEMEM_ENABLE=y
+CONFIG_ARCH_STACKWALK=y
+CONFIG_ARCH_SUSPEND_POSSIBLE=y
+CONFIG_ARCH_WANTS_NO_INSTR=y
+CONFIG_ARCH_WANTS_THP_SWAP=y
+CONFIG_ARM64=y
+CONFIG_ARM64_4K_PAGES=y
+CONFIG_ARM64_ERRATUM_843419=y
+CONFIG_ARM64_LD_HAS_FIX_ERRATUM_843419=y
+CONFIG_ARM64_PA_BITS=48
+CONFIG_ARM64_PA_BITS_48=y
+CONFIG_ARM64_PLATFORM_DEVICES=y
+CONFIG_ARM64_TAGGED_ADDR_ABI=y
+CONFIG_ARM64_VA_BITS=39
+CONFIG_ARM64_VA_BITS_39=y
+# CONFIG_ARM64_VA_BITS_48 is not set
+# CONFIG_ARM64_VA_BITS_52 is not set
+CONFIG_ARM_AIROHA_SOC_CPUFREQ=y
+CONFIG_ARM_AMBA=y
+CONFIG_ARM_ARCH_TIMER=y
+CONFIG_ARM_ARCH_TIMER_EVTSTREAM=y
+# CONFIG_ARM_DEBUG_WX is not set
+CONFIG_ARM_GIC=y
+CONFIG_ARM_GIC_V2M=y
+CONFIG_ARM_GIC_V3=y
+CONFIG_ARM_GIC_V3_ITS=y
+CONFIG_ARM_PMU=y
+CONFIG_ARM_PMUV3=y
+CONFIG_ARM_PSCI_FW=y
+CONFIG_ARM_SMCCC_SOC_ID=y
+# CONFIG_ARM_SMMU is not set
+# CONFIG_ARM_SMMU_V3 is not set
+CONFIG_AUDIT_ARCH_COMPAT_GENERIC=y
+CONFIG_BLK_MQ_PCI=y
+CONFIG_BLK_PM=y
+CONFIG_BUFFER_HEAD=y
+CONFIG_BUILTIN_RETURN_ADDRESS_STRIPS_PAC=y
+CONFIG_CC_HAVE_SHADOW_CALL_STACK=y
+CONFIG_CC_HAVE_STACKPROTECTOR_SYSREG=y
+CONFIG_CLONE_BACKWARDS=y
+CONFIG_COMMON_CLK=y
+CONFIG_COMMON_CLK_EN7523=y
+CONFIG_COMPACT_UNEVICTABLE_DEFAULT=1
+# CONFIG_COMPAT_32BIT_TIME is not set
+# CONFIG_COMPRESSED_INSTALL is not set
+CONFIG_CONTEXT_TRACKING=y
+CONFIG_CONTEXT_TRACKING_IDLE=y
+CONFIG_CPUFREQ_DT=y
+CONFIG_CPUFREQ_DT_PLATDEV=y
+CONFIG_CPU_FREQ=y
+CONFIG_CPU_FREQ_DEFAULT_GOV_ONDEMAND=y
+# CONFIG_CPU_FREQ_DEFAULT_GOV_PERFORMANCE is not set
+CONFIG_CPU_FREQ_GOV_ATTR_SET=y
+CONFIG_CPU_FREQ_GOV_COMMON=y
+CONFIG_CPU_FREQ_GOV_CONSERVATIVE=y
+CONFIG_CPU_FREQ_GOV_ONDEMAND=y
+CONFIG_CPU_FREQ_GOV_PERFORMANCE=y
+CONFIG_CPU_FREQ_GOV_POWERSAVE=y
+CONFIG_CPU_FREQ_GOV_USERSPACE=y
+CONFIG_CPU_FREQ_STAT=y
+CONFIG_CPU_LITTLE_ENDIAN=y
+CONFIG_CPU_RMAP=y
+CONFIG_CRC16=y
+CONFIG_CRC_CCITT=y
+CONFIG_CRYPTO_CRC32C=y
+CONFIG_CRYPTO_DEFLATE=y
+CONFIG_CRYPTO_DEV_EIP93=y
+CONFIG_CRYPTO_DRBG=y
+CONFIG_CRYPTO_DRBG_HMAC=y
+CONFIG_CRYPTO_DRBG_MENU=y
+CONFIG_CRYPTO_ECB=y
+CONFIG_CRYPTO_HASH_INFO=y
+CONFIG_CRYPTO_HMAC=y
+CONFIG_CRYPTO_JITTERENTROPY=y
+CONFIG_CRYPTO_JITTERENTROPY_MEMORY_BLOCKS=64
+CONFIG_CRYPTO_JITTERENTROPY_MEMORY_BLOCKSIZE=32
+CONFIG_CRYPTO_JITTERENTROPY_OSR=1
+CONFIG_CRYPTO_LIB_BLAKE2S_GENERIC=y
+CONFIG_CRYPTO_LIB_GF128MUL=y
+CONFIG_CRYPTO_LIB_SHA1=y
+CONFIG_CRYPTO_LIB_SHA256=y
+CONFIG_CRYPTO_LIB_UTILS=y
+CONFIG_CRYPTO_LZO=y
+CONFIG_CRYPTO_RNG=y
+CONFIG_CRYPTO_RNG2=y
+CONFIG_CRYPTO_RNG_DEFAULT=y
+CONFIG_CRYPTO_SHA256=y
+CONFIG_CRYPTO_SHA3=y
+CONFIG_CRYPTO_SHA512=y
+CONFIG_CRYPTO_ZSTD=y
+CONFIG_DCACHE_WORD_ACCESS=y
+CONFIG_DEBUG_MISC=y
+CONFIG_DMADEVICES=y
+CONFIG_DMA_BOUNCE_UNALIGNED_KMALLOC=y
+CONFIG_DMA_DIRECT_REMAP=y
+CONFIG_DMA_ENGINE=y
+CONFIG_DMA_NEED_SYNC=y
+CONFIG_DMA_OF=y
+CONFIG_DMA_OPS_HELPERS=y
+CONFIG_DTC=y
+CONFIG_EDAC_SUPPORT=y
+CONFIG_EXT4_FS=y
+CONFIG_FIXED_PHY=y
+CONFIG_FIX_EARLYCON_MEM=y
+CONFIG_FRAME_POINTER=y
+CONFIG_FS_IOMAP=y
+CONFIG_FS_MBCACHE=y
+CONFIG_FUNCTION_ALIGNMENT=4
+CONFIG_FUNCTION_ALIGNMENT_4B=y
+CONFIG_FWNODE_MDIO=y
+CONFIG_FW_CACHE=y
+# CONFIG_FW_LOADER_USER_HELPER is not set
+CONFIG_GCC_SUPPORTS_DYNAMIC_FTRACE_WITH_ARGS=y
+CONFIG_GENERIC_ALLOCATOR=y
+CONFIG_GENERIC_ARCH_TOPOLOGY=y
+CONFIG_GENERIC_BUG=y
+CONFIG_GENERIC_BUG_RELATIVE_POINTERS=y
+CONFIG_GENERIC_CLOCKEVENTS=y
+CONFIG_GENERIC_CLOCKEVENTS_BROADCAST=y
+CONFIG_GENERIC_CPU_AUTOPROBE=y
+CONFIG_GENERIC_CPU_DEVICES=y
+CONFIG_GENERIC_CPU_VULNERABILITIES=y
+CONFIG_GENERIC_CSUM=y
+CONFIG_GENERIC_EARLY_IOREMAP=y
+CONFIG_GENERIC_GETTIMEOFDAY=y
+CONFIG_GENERIC_IDLE_POLL_SETUP=y
+CONFIG_GENERIC_IOREMAP=y
+CONFIG_GENERIC_IRQ_EFFECTIVE_AFF_MASK=y
+CONFIG_GENERIC_IRQ_SHOW=y
+CONFIG_GENERIC_IRQ_SHOW_LEVEL=y
+CONFIG_GENERIC_LIB_DEVMEM_IS_ALLOWED=y
+CONFIG_GENERIC_MSI_IRQ=y
+CONFIG_GENERIC_PCI_IOMAP=y
+CONFIG_GENERIC_PHY=y
+CONFIG_GENERIC_PINCONF=y
+CONFIG_GENERIC_PINCTRL_GROUPS=y
+CONFIG_GENERIC_PINMUX_FUNCTIONS=y
+CONFIG_GENERIC_SCHED_CLOCK=y
+CONFIG_GENERIC_SMP_IDLE_THREAD=y
+CONFIG_GENERIC_STRNCPY_FROM_USER=y
+CONFIG_GENERIC_STRNLEN_USER=y
+CONFIG_GENERIC_TIME_VSYSCALL=y
+CONFIG_GLOB=y
+CONFIG_GPIOLIB_IRQCHIP=y
+CONFIG_GPIO_CDEV=y
+CONFIG_GPIO_EN7523=y
+CONFIG_GPIO_GENERIC=y
+CONFIG_GRO_CELLS=y
+CONFIG_HARDIRQS_SW_RESEND=y
+CONFIG_HAS_DMA=y
+CONFIG_HAS_IOMEM=y
+CONFIG_HAS_IOPORT=y
+CONFIG_HAS_IOPORT_MAP=y
+CONFIG_HOTPLUG_CORE_SYNC=y
+CONFIG_HOTPLUG_CORE_SYNC_DEAD=y
+CONFIG_HOTPLUG_CPU=y
+CONFIG_HW_RANDOM=y
+CONFIG_HW_RANDOM_AIROHA=y
+# CONFIG_HISILICON_ERRATUM_162100801 is not set
+# CONFIG_IDPF is not set
+CONFIG_ILLEGAL_POINTER_VALUE=0xdead000000000000
+CONFIG_INET_AH=y
+CONFIG_INET_ESP=y
+# CONFIG_INET_ESP_OFFLOAD is not set
+CONFIG_INET_IPCOMP=y
+CONFIG_INET_TUNNEL=y
+CONFIG_INET_XFRM_TUNNEL=y
+CONFIG_IO_URING=y
+CONFIG_IPC_NS=y
+CONFIG_IPV6=y
+CONFIG_IPV6_MULTIPLE_TABLES=y
+# CONFIG_IPV6_SUBTREES is not set
+CONFIG_IP_MROUTE=y
+CONFIG_IP_MROUTE_COMMON=y
+# CONFIG_IP_MROUTE_MULTIPLE_TABLES is not set
+CONFIG_IP_PNP=y
+# CONFIG_IP_PNP_BOOTP is not set
+# CONFIG_IP_PNP_DHCP is not set
+# CONFIG_IP_PNP_RARP is not set
+# CONFIG_IP_ROUTE_MULTIPATH is not set
+# CONFIG_IP_ROUTE_VERBOSE is not set
+CONFIG_IRQCHIP=y
+CONFIG_IRQ_DOMAIN=y
+CONFIG_IRQ_DOMAIN_HIERARCHY=y
+CONFIG_IRQ_FORCED_THREADING=y
+CONFIG_IRQ_MSI_LIB=y
+CONFIG_IRQ_WORK=y
+CONFIG_JBD2=y
+CONFIG_LIBFDT=y
+CONFIG_LOCK_DEBUGGING_SUPPORT=y
+CONFIG_LOCK_SPIN_ON_OWNER=y
+CONFIG_LRU_GEN_WALKS_MMU=y
+CONFIG_LZO_COMPRESS=y
+CONFIG_LZO_DECOMPRESS=y
+CONFIG_MDIO_BUS=y
+CONFIG_MDIO_DEVICE=y
+CONFIG_MDIO_AIROHA=y
+CONFIG_MDIO_DEVRES=y
+# CONFIG_MEDIATEK_GE_SOC_PHY is not set
+# CONFIG_MEMCG is not set
+CONFIG_MFD_SYSCON=y
+CONFIG_MIGRATION=y
+CONFIG_MMC=y
+CONFIG_MMC_BLOCK=y
+CONFIG_MMC_CQHCI=y
+CONFIG_MMC_MTK=y
+CONFIG_MMU_LAZY_TLB_REFCOUNT=y
+CONFIG_MODULES_TREE_LOOKUP=y
+CONFIG_MODULES_USE_ELF_RELA=y
+CONFIG_MTD_NAND_CORE=y
+CONFIG_MTD_NAND_ECC=y
+CONFIG_MTD_NAND_MTK_BMT=y
+CONFIG_MTD_RAW_NAND=y
+CONFIG_MTD_SPI_NAND=y
+CONFIG_MTD_SPLIT_FIRMWARE=y
+CONFIG_MTD_SPLIT_FIT_FW=y
+CONFIG_MTD_UBI=y
+CONFIG_MTD_UBI_BEB_LIMIT=20
+CONFIG_MTD_UBI_BLOCK=y
+CONFIG_MTD_UBI_WL_THRESHOLD=4096
+CONFIG_MUTEX_SPIN_ON_OWNER=y
+CONFIG_NEED_DMA_MAP_STATE=y
+CONFIG_NEED_SG_DMA_LENGTH=y
+CONFIG_NET_AIROHA=y
+CONFIG_NET_AIROHA_FLOW_STATS=y
+CONFIG_NET_DEVLINK=y
+CONFIG_NET_DSA=y
+CONFIG_NET_DSA_MT7530=y
+CONFIG_NET_DSA_MT7530_MDIO=y
+CONFIG_NET_DSA_MT7530_MMIO=y
+CONFIG_NET_DSA_TAG_MTK=y
+CONFIG_NET_FLOW_LIMIT=y
+# CONFIG_NET_MEDIATEK_SOC is not set
+CONFIG_NET_SELFTESTS=y
+# CONFIG_NET_VENDOR_3COM is not set
+CONFIG_NET_VENDOR_AIROHA=y
+# CONFIG_NET_VENDOR_MEDIATEK is not set
+CONFIG_NLS=y
+CONFIG_NO_HZ_COMMON=y
+CONFIG_NO_HZ_IDLE=y
+CONFIG_NR_CPUS=4
+CONFIG_NVMEM=y
+CONFIG_NVMEM_BLOCK=y
+CONFIG_NVMEM_LAYOUTS=y
+CONFIG_NVMEM_LAYOUT_ASCII_ENV=y
+CONFIG_NVMEM_SYSFS=y
+CONFIG_OF=y
+CONFIG_OF_ADDRESS=y
+CONFIG_OF_EARLY_FLATTREE=y
+CONFIG_OF_FLATTREE=y
+CONFIG_OF_GPIO=y
+CONFIG_OF_IRQ=y
+CONFIG_OF_KOBJ=y
+CONFIG_OF_MDIO=y
+CONFIG_PAGE_POOL=y
+CONFIG_PAGE_SIZE_LESS_THAN_256KB=y
+CONFIG_PAGE_SIZE_LESS_THAN_64KB=y
+CONFIG_PARTITION_PERCPU=y
+CONFIG_PCI=y
+CONFIG_PCIEAER=y
+CONFIG_PCIEASPM=y
+# CONFIG_PCIEASPM_DEFAULT is not set
+CONFIG_PCIEASPM_PERFORMANCE=y
+# CONFIG_PCIEASPM_POWERSAVE is not set
+# CONFIG_PCIEASPM_POWER_SUPERSAVE is not set
+CONFIG_PCIEPORTBUS=y
+CONFIG_PCIE_MEDIATEK=y
+CONFIG_PCIE_MEDIATEK_GEN3=y
+CONFIG_PCIE_PME=y
+CONFIG_PCI_DOMAINS=y
+CONFIG_PCI_DOMAINS_GENERIC=y
+CONFIG_PCI_MSI=y
+# CONFIG_PCS_AIROHA_AN7581 is not set
+CONFIG_PCS_AIROHA_AN7583=y
+CONFIG_PERF_EVENTS=y
+CONFIG_PER_VMA_LOCK=y
+CONFIG_PGTABLE_LEVELS=3
+CONFIG_PHYLIB=y
+CONFIG_PHYLIB_LEDS=y
+CONFIG_PHYLINK=y
+CONFIG_PHYS_ADDR_T_64BIT=y
+CONFIG_PHY_AIROHA_PCIE=y
+# CONFIG_PHY_AIROHA_USB is not set
+CONFIG_PINCTRL=y
+CONFIG_PINCTRL_AIROHA=y
+# CONFIG_PINCTRL_MT2712 is not set
+# CONFIG_PINCTRL_MT6765 is not set
+# CONFIG_PINCTRL_MT6795 is not set
+# CONFIG_PINCTRL_MT6797 is not set
+# CONFIG_PINCTRL_MT7622 is not set
+# CONFIG_PINCTRL_MT7981 is not set
+# CONFIG_PINCTRL_MT7986 is not set
+# CONFIG_PINCTRL_MT8173 is not set
+# CONFIG_PINCTRL_MT8183 is not set
+# CONFIG_PINCTRL_MT8186 is not set
+# CONFIG_PINCTRL_MT8188 is not set
+# CONFIG_PINCTRL_MT8516 is not set
+CONFIG_PM=y
+CONFIG_PM_CLK=y
+CONFIG_PM_OPP=y
+CONFIG_POSIX_CPU_TIMERS_TASK_WORK=y
+CONFIG_POWER_RESET=y
+CONFIG_POWER_RESET_SYSCON=y
+CONFIG_POWER_SUPPLY=y
+CONFIG_PTP_1588_CLOCK_OPTIONAL=y
+CONFIG_QUEUED_RWLOCKS=y
+CONFIG_QUEUED_SPINLOCKS=y
+CONFIG_RANDSTRUCT_NONE=y
+CONFIG_RAS=y
+CONFIG_RATIONAL=y
+CONFIG_REGMAP=y
+CONFIG_REGMAP_MMIO=y
+CONFIG_REGULATOR=y
+CONFIG_REGULATOR_FIXED_VOLTAGE=y
+CONFIG_RELOCATABLE=y
+CONFIG_RESET_CONTROLLER=y
+CONFIG_RFS_ACCEL=y
+CONFIG_RODATA_FULL_DEFAULT_ENABLED=y
+CONFIG_RPS=y
+CONFIG_RTL8261N_PHY=y
+CONFIG_RWSEM_SPIN_ON_OWNER=y
+CONFIG_SERIAL_8250_AIROHA=y
+CONFIG_SERIAL_8250_EXTENDED=y
+CONFIG_SERIAL_8250_FSL=y
+CONFIG_SERIAL_8250_NR_UARTS=5
+CONFIG_SERIAL_8250_RUNTIME_UARTS=5
+CONFIG_SERIAL_8250_SHARE_IRQ=y
+CONFIG_SERIAL_MCTRL_GPIO=y
+CONFIG_SERIAL_OF_PLATFORM=y
+CONFIG_SGL_ALLOC=y
+CONFIG_SKB_EXTENSIONS=y
+CONFIG_SMP=y
+CONFIG_SOCK_RX_QUEUE_MAPPING=y
+CONFIG_SOC_BUS=y
+CONFIG_SOFTIRQ_ON_OWN_STACK=y
+CONFIG_SPARSEMEM=y
+CONFIG_SPARSEMEM_EXTREME=y
+CONFIG_SPARSEMEM_VMEMMAP=y
+CONFIG_SPARSEMEM_VMEMMAP_ENABLE=y
+CONFIG_SPARSE_IRQ=y
+CONFIG_SPI=y
+# CONFIG_SPI_AIROHA_EN7523 is not set
+CONFIG_SPI_AIROHA_SNFI=y
+CONFIG_SPI_MASTER=y
+CONFIG_SPI_MEM=y
+CONFIG_SQUASHFS_DECOMP_MULTI_PERCPU=y
+CONFIG_SWIOTLB=y
+CONFIG_SWPHY=y
+CONFIG_SYSCTL_EXCEPTION_TRACE=y
+# CONFIG_TEST_FPU is not set
+CONFIG_THERMAL=y
+CONFIG_THERMAL_DEFAULT_GOV_STEP_WISE=y
+CONFIG_THERMAL_EMERGENCY_POWEROFF_DELAY_MS=0
+CONFIG_THERMAL_GOV_STEP_WISE=y
+CONFIG_THERMAL_OF=y
+CONFIG_THREAD_INFO_IN_TASK=y
+CONFIG_TICK_CPU_ACCOUNTING=y
+CONFIG_TIMER_OF=y
+CONFIG_TIMER_PROBE=y
+CONFIG_TRACE_IRQFLAGS_NMI_SUPPORT=y
+CONFIG_TREE_RCU=y
+CONFIG_TREE_SRCU=y
+CONFIG_UBIFS_FS=y
+# CONFIG_UNMAP_KERNEL_AT_EL0 is not set
+CONFIG_USER_STACKTRACE_SUPPORT=y
+CONFIG_VDSO_GETRANDOM=y
+CONFIG_VMAP_STACK=y
+CONFIG_WATCHDOG_CORE=y
+# CONFIG_WLAN is not set
+# CONFIG_WQ_POWER_EFFICIENT_DEFAULT is not set
+CONFIG_XFRM_AH=y
+CONFIG_XFRM_ALGO=y
+CONFIG_XFRM_ESP=y
+CONFIG_XFRM_IPCOMP=y
+CONFIG_XFRM_MIGRATE=y
+CONFIG_XPS=y
+CONFIG_XXHASH=y
+CONFIG_ZLIB_DEFLATE=y
+CONFIG_ZLIB_INFLATE=y
+CONFIG_ZONE_DMA32=y
+CONFIG_ZSTD_COMMON=y
+CONFIG_ZSTD_COMPRESS=y
+CONFIG_ZSTD_DECOMPRESS=y
--- /dev/null
+ARCH:=aarch64
+SUBTARGET:=an7583
+BOARDNAME:=AN7583
+CPU_TYPE:=cortex-a53
+KERNELNAME:=Image dtbs
+FEATURES+=pwm source-only
+
+define Target/Description
+ Build firmware images for Airoha an7583 ARM based boards.
+endef
+
--- /dev/null
+// SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+/dts-v1/;
+
+#include <dt-bindings/leds/common.h>
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/input/input.h>
+#include "an7583.dtsi"
+
+/ {
+ model = "Airoha AN7583 Evaluation Board";
+ compatible = "airoha,an7583-evb", "airoha,an7583", "airoha,en7583";
+
+ aliases {
+ serial0 = &uart1;
+ };
+
+ chosen {
+ bootargs = "console=ttyS0,115200 earlycon";
+ stdout-path = "serial0:115200n8";
+ };
+
+ memory@80000000 {
+ device_type = "memory";
+ reg = <0x0 0x80000000 0x2 0x00000000>;
+ };
+};
+
+&an7583_pinctrl {
+ gpio-ranges = <&an7583_pinctrl 0 2 53>;
+
+ mdio0_pins: mdio0-pins {
+ conf {
+ pins = "mdio_0";
+ output-high;
+ };
+ };
+
+ pcie0_rst_pins: pcie0-rst-pins {
+ conf {
+ pins = "pcie_reset0";
+ drive-open-drain = <1>;
+ };
+ };
+
+ pcie1_rst_pins: pcie1-rst-pins {
+ conf {
+ pins = "pcie_reset1";
+ drive-open-drain = <1>;
+ };
+ };
+
+ gswp1_led0_pins: gswp1-led0-pins {
+ mux {
+ function = "phy1_led0";
+ pins = "gpio1";
+ };
+ };
+};
+
+&snfi {
+ status = "okay";
+};
+
+
+&spi_nand {
+ partitions {
+ compatible = "fixed-partitions";
+ #address-cells = <1>;
+ #size-cells = <1>;
+
+ bl2@0 {
+ label = "bl2";
+ reg = <0x0 0x20000>;
+ };
+
+ ubi@20000 {
+ label = "ubi";
+ reg = <0x20000 0x0>;
+ };
+ };
+};
+
+&i2c0 {
+ status = "okay";
+};
+
+ð {
+ status = "okay";
+};
+
+&gdm1 {
+ status = "okay";
+};
+
+&switch {
+ status = "okay";
+};
+
+&gsw_phy1 {
+ pinctrl-names = "gbe-led";
+ pinctrl-0 = <&gswp1_led0_pins>;
+ status = "okay";
+};
+
+&gsw_phy1_led0 {
+ status = "okay";
+ active-low;
+};
+
+&gsw_port2 {
+ status = "disabled";
+};
+
+&gsw_port3 {
+ status = "disabled";
+};
+
+&gsw_port4 {
+ status = "disabled";
+};
+
+&gsw_phy2 {
+ status = "disabled";
+};
+
+&gsw_phy3 {
+ status = "disabled";
+};
+
+&gsw_phy4 {
+ status = "disabled";
+};
+
+&mdio_0 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&mdio0_pins>;
+
+ as21xx_0: ethernet-phy@1d {
+ reg = <0x1d>;
+ compatible = "ethernet-phy-ieee802.3-c45";
+
+ firmware-name = "as21x1x_fw.bin";
+
+ reset-deassert-us = <350000>;
+ reset-assert-us = <200000>;
+ reset-gpios = <&an7583_pinctrl 34 GPIO_ACTIVE_LOW>;
+
+ leds {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ led@0 {
+ reg = <0>;
+ color = <LED_COLOR_ID_GREEN>;
+ function = LED_FUNCTION_LAN;
+ function-enumerator = <0>;
+ default-state = "keep";
+ };
+
+ led@1 {
+ reg = <1>;
+ color = <LED_COLOR_ID_GREEN>;
+ function = LED_FUNCTION_LAN;
+ function-enumerator = <1>;
+ default-state = "keep";
+ };
+ };
+ };
+
+ as21xx_1: ethernet-phy@1f {
+ reg = <0x1f>;
+ compatible = "ethernet-phy-ieee802.3-c45";
+
+ firmware-name = "as21x1x_fw.bin";
+
+ reset-deassert-us = <350000>;
+ reset-assert-us = <200000>;
+ reset-gpios = <&an7583_pinctrl 35 GPIO_ACTIVE_LOW>;
+
+ leds {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ led@0 {
+ reg = <0>;
+ color = <LED_COLOR_ID_GREEN>;
+ function = LED_FUNCTION_LAN;
+ function-enumerator = <0>;
+ default-state = "keep";
+ };
+
+ led@1 {
+ reg = <1>;
+ color = <LED_COLOR_ID_GREEN>;
+ function = LED_FUNCTION_LAN;
+ function-enumerator = <1>;
+ default-state = "keep";
+ };
+ };
+ };
+};
+
+&gdm3 {
+ status = "okay";
+
+ phy-handle = <&as21xx_1>;
+ phy-mode = "usxgmii";
+};
+
+&gdm2 {
+ status = "okay";
+
+ phy-handle = <&as21xx_0>;
+ phy-mode = "usxgmii";
+};
--- /dev/null
+// SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+
+#include <dt-bindings/interrupt-controller/irq.h>
+#include <dt-bindings/interrupt-controller/arm-gic.h>
+#include <dt-bindings/clock/en7523-clk.h>
+#include <dt-bindings/phy/phy.h>
+#include <dt-bindings/reset/airoha,an7583-reset.h>
+#include <dt-bindings/leds/common.h>
+#include <dt-bindings/thermal/thermal.h>
+
+/ {
+ interrupt-parent = <&gic>;
+ #address-cells = <2>;
+ #size-cells = <2>;
+
+ reserved-memory {
+ #address-cells = <2>;
+ #size-cells = <2>;
+ ranges;
+
+ atf@80000000 {
+ no-map;
+ reg = <0x0 0x80000000 0x0 0x200000>;
+ };
+
+ npu_binary: npu-binary@84000000 {
+ no-map;
+ reg = <0x0 0x84000000 0x0 0xa00000>;
+ };
+
+ qdma0_buf: qdma0-buf@87000000 {
+ no-map;
+ reg = <0x0 0x87000000 0x0 0x2000000>;
+ };
+
+ qdma1_buf: qdma1-buf@89000000 {
+ no-map;
+ reg = <0x0 0x89000000 0x0 0x1000000>;
+ };
+ };
+
+ psci {
+ compatible = "arm,psci-1.0";
+ method = "smc";
+ };
+
+ cpus {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ cpu-map {
+ cluster0 {
+ core0 {
+ cpu = <&cpu0>;
+ };
+
+ core1 {
+ cpu = <&cpu1>;
+ };
+ };
+ };
+
+ cpu0: cpu@0 {
+ device_type = "cpu";
+ compatible = "arm,cortex-a53";
+ reg = <0x0>;
+ operating-points-v2 = <&cpu_opp_table>;
+ enable-method = "psci";
+ clocks = <&cpufreq>;
+ clock-names = "cpu";
+ power-domains = <&cpufreq>;
+ power-domain-names = "perf";
+ next-level-cache = <&l2>;
+ #cooling-cells = <2>;
+ };
+
+ cpu1: cpu@1 {
+ device_type = "cpu";
+ compatible = "arm,cortex-a53";
+ reg = <0x1>;
+ operating-points-v2 = <&cpu_opp_table>;
+ enable-method = "psci";
+ clocks = <&cpufreq>;
+ clock-names = "cpu";
+ power-domains = <&cpufreq>;
+ power-domain-names = "perf";
+ next-level-cache = <&l2>;
+ #cooling-cells = <2>;
+ };
+
+ l2: l2-cache {
+ compatible = "cache";
+ cache-size = <0x80000>;
+ cache-line-size = <64>;
+ cache-level = <2>;
+ cache-unified;
+ };
+ };
+
+ cpufreq: cpufreq {
+ compatible = "airoha,en7581-cpufreq";
+
+ operating-points-v2 = <&cpu_smcc_opp_table>;
+
+ #power-domain-cells = <0>;
+ #clock-cells = <0>;
+ };
+
+ cpu_opp_table: opp-table {
+ compatible = "operating-points-v2";
+ opp-shared;
+
+ opp-500000000 {
+ opp-hz = /bits/ 64 <500000000>;
+ required-opps = <&smcc_opp0>;
+ };
+
+ opp-550000000 {
+ opp-hz = /bits/ 64 <550000000>;
+ required-opps = <&smcc_opp1>;
+ };
+
+ opp-600000000 {
+ opp-hz = /bits/ 64 <600000000>;
+ required-opps = <&smcc_opp2>;
+ };
+
+ opp-650000000 {
+ opp-hz = /bits/ 64 <650000000>;
+ required-opps = <&smcc_opp3>;
+ };
+
+ opp-7000000000 {
+ opp-hz = /bits/ 64 <700000000>;
+ required-opps = <&smcc_opp4>;
+ };
+
+ opp-7500000000 {
+ opp-hz = /bits/ 64 <750000000>;
+ required-opps = <&smcc_opp5>;
+ };
+
+ opp-8000000000 {
+ opp-hz = /bits/ 64 <800000000>;
+ required-opps = <&smcc_opp6>;
+ };
+
+ opp-8500000000 {
+ opp-hz = /bits/ 64 <850000000>;
+ required-opps = <&smcc_opp7>;
+ };
+
+ opp-9000000000 {
+ opp-hz = /bits/ 64 <900000000>;
+ required-opps = <&smcc_opp8>;
+ };
+
+ opp-9500000000 {
+ opp-hz = /bits/ 64 <950000000>;
+ required-opps = <&smcc_opp9>;
+ };
+
+ opp-10000000000 {
+ opp-hz = /bits/ 64 <1000000000>;
+ required-opps = <&smcc_opp10>;
+ };
+
+ opp-10500000000 {
+ opp-hz = /bits/ 64 <1050000000>;
+ required-opps = <&smcc_opp11>;
+ };
+
+ opp-11000000000 {
+ opp-hz = /bits/ 64 <1100000000>;
+ required-opps = <&smcc_opp12>;
+ };
+
+ opp-11500000000 {
+ opp-hz = /bits/ 64 <1150000000>;
+ required-opps = <&smcc_opp13>;
+ };
+
+ opp-12000000000 {
+ opp-hz = /bits/ 64 <1200000000>;
+ required-opps = <&smcc_opp14>;
+ };
+ };
+
+ cpu_smcc_opp_table: opp-table-cpu-smcc {
+ compatible = "operating-points-v2";
+
+ smcc_opp0: opp0 {
+ opp-level = <0>;
+ };
+
+ smcc_opp1: opp1 {
+ opp-level = <1>;
+ };
+
+ smcc_opp2: opp2 {
+ opp-level = <2>;
+ };
+
+ smcc_opp3: opp3 {
+ opp-level = <3>;
+ };
+
+ smcc_opp4: opp4 {
+ opp-level = <4>;
+ };
+
+ smcc_opp5: opp5 {
+ opp-level = <5>;
+ };
+
+ smcc_opp6: opp6 {
+ opp-level = <6>;
+ };
+
+ smcc_opp7: opp7 {
+ opp-level = <7>;
+ };
+
+ smcc_opp8: opp8 {
+ opp-level = <8>;
+ };
+
+ smcc_opp9: opp9 {
+ opp-level = <9>;
+ };
+
+ smcc_opp10: opp10 {
+ opp-level = <10>;
+ };
+
+ smcc_opp11: opp11 {
+ opp-level = <11>;
+ };
+
+ smcc_opp12: opp12 {
+ opp-level = <12>;
+ };
+
+ smcc_opp13: opp13 {
+ opp-level = <13>;
+ };
+
+ smcc_opp14: opp14 {
+ opp-level = <14>;
+ };
+ };
+
+ timer {
+ compatible = "arm,armv8-timer";
+ interrupt-parent = <&gic>;
+ interrupts = <GIC_PPI 13 IRQ_TYPE_LEVEL_LOW>,
+ <GIC_PPI 14 IRQ_TYPE_LEVEL_LOW>,
+ <GIC_PPI 11 IRQ_TYPE_LEVEL_LOW>,
+ <GIC_PPI 10 IRQ_TYPE_LEVEL_LOW>;
+ };
+
+ thermal-zones {
+ cpu_thermal: cpu-thermal {
+ polling-delay-passive = <10000>;
+ polling-delay = <5000>;
+
+ thermal-sensors = <&thermal 0>;
+
+ trips {
+ cpu_hot: cpu-hot {
+ temperature = <95000>;
+ hysteresis = <1000>;
+ type = "hot";
+ };
+
+ cpu-critical {
+ temperature = <110000>;
+ hysteresis = <1000>;
+ type = "critical";
+ };
+ };
+
+ cooling-maps {
+ map0 {
+ trip = <&cpu_hot>;
+ cooling-device = <&cpu0 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>,
+ <&cpu1 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>;
+ };
+ };
+ };
+ };
+
+ clk25m: oscillator {
+ compatible = "fixed-clock";
+ #clock-cells = <0>;
+ clock-frequency = <25000000>;
+ clock-output-names = "clkxtal";
+ };
+
+ sys_hclk: clk-oscillator-100mhz {
+ compatible = "fixed-clock";
+ #clock-cells = <0>;
+ clock-frequency = <100000000>;
+ clock-output-names = "sys_hclk";
+ };
+
+ vmmc_3v3: regulator-vmmc-3v3 {
+ compatible = "regulator-fixed";
+ regulator-name = "vmmc";
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ regulator-always-on;
+ };
+
+ sfp1: sfp1 {
+ compatible = "sff,sfp";
+ };
+
+ sfp2: sfp2 {
+ compatible = "sff,sfp";
+ };
+
+ soc {
+ compatible = "simple-bus";
+ #address-cells = <2>;
+ #size-cells = <2>;
+ ranges;
+
+ gic: interrupt-controller@9000000 {
+ compatible = "arm,gic-v3";
+ interrupt-controller;
+ #interrupt-cells = <3>;
+ #address-cells = <1>;
+ #size-cells = <1>;
+ reg = <0x0 0x09000000 0x0 0x20000>,
+ <0x0 0x09080000 0x0 0x80000>,
+ <0x0 0x09400000 0x0 0x2000>,
+ <0x0 0x09500000 0x0 0x2000>,
+ <0x0 0x09600000 0x0 0x20000>;
+ interrupts = <GIC_PPI 9 IRQ_TYPE_LEVEL_LOW>;
+ };
+
+ chip_scu: syscon@1fa20000 {
+ compatible = "airoha,en7581-chip-scu", "syscon", "simple-mfd";
+ reg = <0x0 0x1fa20000 0x0 0x388>;
+
+ thermal: thermal {
+ compatible = "airoha,an7583-thermal";
+
+ #thermal-sensor-cells = <0>;
+ };
+ };
+
+ pbus_csr: syscon@1fbe3400 {
+ compatible = "airoha,en7581-pbus-csr", "syscon";
+ reg = <0x0 0x1fbe3400 0x0 0xff>;
+ };
+
+ scuclk: system-controller@1fa20000 {
+ compatible = "airoha,an7583-scu", "syscon";
+ reg = <0x0 0x1fb00000 0x0 0x970>;
+
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ #clock-cells = <1>;
+ #reset-cells = <1>;
+
+ airoha,chip-scu = <&chip_scu>;
+
+ mdio_0: mdio-bus@c8 {
+ compatible = "airoha,an7583-mdio";
+ reg = <0xc8>;
+
+ clocks = <&scuclk AN7583_CLK_MDIO0>;
+ resets = <&scuclk AN7583_MDIO0>;
+ };
+
+ mdio_1: mdio-bus@cc {
+ compatible = "airoha,an7583-mdio";
+ reg = <0xcc>;
+
+ clocks = <&scuclk AN7583_CLK_MDIO1>;
+ resets = <&scuclk AN7583_MDIO1>;
+ };
+ };
+
+ system-controller@1fbf0200 {
+ compatible = "syscon", "simple-mfd";
+ reg = <0x0 0x1fbf0200 0x0 0xc0>;
+
+ an7583_pinctrl: pinctrl {
+ compatible = "airoha,an7583-pinctrl";
+
+ interrupt-parent = <&gic>;
+ interrupts = <GIC_SPI 26 IRQ_TYPE_LEVEL_HIGH>;
+
+ gpio-controller;
+ #gpio-cells = <2>;
+
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ };
+ };
+
+ i2cclock: i2cclock@0 {
+ #clock-cells = <0>;
+ compatible = "fixed-clock";
+
+ /* 20 MHz */
+ clock-frequency = <20000000>;
+ };
+
+ i2c0: i2c0@1fbf8000 {
+ compatible = "airoha,an7581-i2c";
+ reg = <0x0 0x1fbf8000 0x0 0x100>;
+
+ clocks = <&i2cclock>;
+
+ /* 100 kHz */
+ clock-frequency = <100000>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ status = "disable";
+ };
+
+ i2c1: i2c1@1fbf8100 {
+ compatible = "airoha,an7581-i2c";
+ reg = <0x0 0x1fbf8100 0x0 0x100>;
+
+ clocks = <&i2cclock>;
+
+ /* 100 kHz */
+ clock-frequency = <100000>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ status = "disable";
+ };
+
+ mmc0: mmc@1fa0e000 {
+ compatible = "mediatek,mt7622-mmc";
+ reg = <0x0 0x1fa0e000 0x0 0x1000>,
+ <0x0 0x1fa0c000 0x0 0x60>;
+ interrupts = <GIC_SPI 170 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&scuclk EN7581_CLK_EMMC>, <&clk25m>;
+ clock-names = "source", "hclk";
+ bus-width = <4>;
+ max-frequency = <52000000>;
+ vmmc-supply = <&vmmc_3v3>;
+ disable-wp;
+ cap-mmc-highspeed;
+ non-removable;
+
+ status = "disabled";
+ };
+
+ snfi: spi@1fa10000 {
+ compatible = "airoha,en7581-snand";
+ reg = <0x0 0x1fa10000 0x0 0x140>,
+ <0x0 0x1fa11000 0x0 0x160>;
+
+ clocks = <&scuclk EN7523_CLK_SPI>;
+ clock-names = "spi";
+
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ status = "disabled";
+
+ spi_nand: nand@0 {
+ compatible = "spi-nand";
+ reg = <0>;
+ spi-max-frequency = <50000000>;
+ spi-tx-bus-width = <1>;
+ spi-rx-bus-width = <2>;
+ };
+ };
+
+ uart1: serial@1fbf0000 {
+ compatible = "ns16550";
+ reg = <0x0 0x1fbf0000 0x0 0x30>;
+ reg-io-width = <4>;
+ reg-shift = <2>;
+ interrupts = <GIC_SPI 18 IRQ_TYPE_LEVEL_HIGH>;
+ clock-frequency = <1843200>;
+ };
+
+ watchdog@1fbf0100 {
+ compatible = "airoha,en7581-wdt";
+ reg = <0x0 0x1fbf0100 0x0 0x38>;
+
+ clocks = <&sys_hclk>;
+ clock-names = "bus";
+ };
+
+ uart2: serial@1fbf0300 {
+ compatible = "airoha,en7523-uart";
+ reg = <0x0 0x1fbf0300 0x0 0x30>;
+ reg-io-width = <4>;
+ reg-shift = <2>;
+ interrupts = <GIC_SPI 32 IRQ_TYPE_LEVEL_HIGH>;
+ clock-frequency = <7372800>;
+
+ status = "disabled";
+ };
+
+ hsuart3: serial@1fbe1000 {
+ compatible = "airoha,en7523-uart";
+ reg = <0x0 0x1fbe1000 0x0 0x40>;
+ reg-io-width = <4>;
+ reg-shift = <2>;
+ interrupts = <GIC_SPI 54 IRQ_TYPE_LEVEL_HIGH>;
+ clock-frequency = <7372800>;
+
+ status = "disabled";
+ };
+
+ uart4: serial@1fbf0600 {
+ compatible = "airoha,en7523-uart";
+ reg = <0x0 0x1fbf0600 0x0 0x30>;
+ reg-io-width = <4>;
+ reg-shift = <2>;
+ interrupts = <GIC_SPI 61 IRQ_TYPE_LEVEL_HIGH>;
+ clock-frequency = <7372800>;
+
+ status = "disabled";
+ };
+
+ uart5: serial@1fbf0700 {
+ compatible = "airoha,en7523-uart";
+ reg = <0x0 0x1fbf0700 0x0 0x30>;
+ reg-io-width = <4>;
+ reg-shift = <2>;
+ interrupts = <GIC_SPI 18 IRQ_TYPE_LEVEL_HIGH>;
+ clock-frequency = <7372800>;
+
+ status = "disabled";
+ };
+
+ crypto@1e004000 {
+ compatible = "inside-secure,safexcel-eip93ies";
+ reg = <0x0 0x1fb70000 0x0 0x1000>;
+
+ interrupts = <GIC_SPI 44 IRQ_TYPE_LEVEL_HIGH>;
+ };
+
+ pon_pcs: pcs@1fa08000 {
+ compatible = "airoha,an7583-pcs-pon";
+ reg = <0x0 0x1fa08000 0x0 0x1000>,
+ <0x0 0x1fa80000 0x0 0x60>,
+ <0x0 0x1fa80a00 0x0 0x164>,
+ <0x0 0x1fa84000 0x0 0x450>,
+ <0x0 0x1fa85900 0x0 0x338>,
+ <0x0 0x1fa86000 0x0 0x300>,
+ <0x0 0x1fa8f000 0x0 0x1000>,
+ <0x0 0x1fa8e000 0x0 0x1000>;
+ reg-names = "xfi_mac", "hsgmii_an", "hsgmii_pcs",
+ "multi_sgmii", "usxgmii",
+ "hsgmii_rate_adp", "xfi_ana", "xfi_pma";
+
+ resets = <&scuclk AN7583_XPON_MAC_RST>,
+ <&scuclk AN7583_XPON_PHY_RST>,
+ <&scuclk AN7583_XPON_XFI_RST>;
+ reset-names = "mac", "phy", "xfi";
+
+ airoha,scu = <&scuclk>;
+ };
+
+ eth_pcs: pcs@1fa09000 {
+ compatible = "airoha,an7583-pcs-eth";
+ reg = <0x0 0x1fa09000 0x0 0x1000>,
+ <0x0 0x1fa70000 0x0 0x60>,
+ <0x0 0x1fa70a00 0x0 0x164>,
+ <0x0 0x1fa74000 0x0 0x450>,
+ <0x0 0x1fa75900 0x0 0x338>,
+ <0x0 0x1fa76000 0x0 0x300>,
+ <0x0 0x1fa7f000 0x0 0x1000>,
+ <0x0 0x1fa7e000 0x0 0x1000>;
+ reg-names = "xfi_mac", "hsgmii_an", "hsgmii_pcs",
+ "multi_sgmii", "usxgmii",
+ "hsgmii_rate_adp", "xfi_ana", "xfi_pma";
+
+ resets = <&scuclk AN7583_XSI_MAC_RST>,
+ <&scuclk AN7583_XSI_PHY_RST>;
+ reset-names = "mac", "phy";
+
+ airoha,scu = <&scuclk>;
+ };
+
+ eth: ethernet@1fb50000 {
+ compatible = "airoha,an7583-eth";
+ reg = <0 0x1fb50000 0 0x2600>,
+ <0 0x1fb54000 0 0x2000>,
+ <0 0x1fb56000 0 0x2000>;
+ reg-names = "fe", "qdma0", "qdma1";
+
+ resets = <&scuclk AN7583_FE_RST>,
+ <&scuclk AN7583_FE_PDMA_RST>,
+ <&scuclk AN7583_FE_QDMA_RST>,
+ <&scuclk AN7583_DUAL_HSI0_MAC_RST>,
+ <&scuclk AN7583_DUAL_HSI1_MAC_RST>,
+ <&scuclk AN7583_XFP_MAC_RST>;
+ reset-names = "fe", "pdma", "qdma",
+ "hsi0-mac", "hsi1-mac",
+ "xfp-mac";
+
+ interrupts = <GIC_SPI 37 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 55 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 56 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 57 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 38 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 58 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 59 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 60 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 49 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 64 IRQ_TYPE_LEVEL_HIGH>;
+
+ memory-region = <&qdma0_buf>, <&qdma1_buf>;
+ memory-region-names = "qdma0-buf", "qdma1-buf";
+
+ status = "disabled";
+
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ gdm1: ethernet@1 {
+ compatible = "airoha,eth-mac";
+ reg = <1>;
+ phy-mode = "internal";
+ status = "disabled";
+
+ fixed-link {
+ speed = <10000>;
+ full-duplex;
+ pause;
+ };
+ };
+
+ gdm2: ethernet@2 {
+ compatible = "airoha,eth-mac";
+ reg = <2>;
+ pcs = <&pon_pcs>;
+
+ status = "disabled";
+ };
+
+ gdm3: ethernet@3 {
+ compatible = "airoha,eth-mac";
+ reg = <3>;
+ pcs = <ð_pcs>;
+ airoha,gdm-srcport = <0x16>;
+
+ status = "disabled";
+ };
+ };
+
+ switch: switch@1fb58000 {
+ compatible = "airoha,an7583-switch";
+ reg = <0 0x1fb58000 0 0x8000>;
+ resets = <&scuclk AN7583_GSW_RST>;
+
+ interrupt-controller;
+ #interrupt-cells = <1>;
+ interrupt-parent = <&gic>;
+ interrupts = <GIC_SPI 209 IRQ_TYPE_LEVEL_HIGH>;
+
+ status = "disabled";
+
+ #address-cells = <1>;
+ #size-cells = <1>;
+
+ ports {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ gsw_port1: port@1 {
+ reg = <1>;
+ label = "lan1";
+ phy-mode = "internal";
+ phy-handle = <&gsw_phy1>;
+ };
+
+ gsw_port2: port@2 {
+ reg = <2>;
+ label = "lan2";
+ phy-mode = "internal";
+ phy-handle = <&gsw_phy2>;
+ };
+
+ gsw_port3: port@3 {
+ reg = <3>;
+ label = "lan3";
+ phy-mode = "internal";
+ phy-handle = <&gsw_phy3>;
+ };
+
+ gsw_port4: port@4 {
+ reg = <4>;
+ label = "lan4";
+ phy-mode = "internal";
+ phy-handle = <&gsw_phy4>;
+ };
+
+ port@6 {
+ reg = <6>;
+ label = "cpu";
+ ethernet = <&gdm1>;
+ phy-mode = "internal";
+
+ fixed-link {
+ speed = <10000>;
+ full-duplex;
+ pause;
+ };
+ };
+ };
+
+ mdio: mdio {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ gsw_phy1: ethernet-phy@1 {
+ compatible = "ethernet-phy-ieee802.3-c22";
+ reg = <9>;
+ phy-mode = "internal";
+
+ leds {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ gsw_phy1_led0: gsw-phy1-led0@0 {
+ reg = <0>;
+ function = "phy1_led0";
+ status = "disabled";
+ };
+
+ gsw_phy1_led1: gsw-phy1-led1@1 {
+ reg = <1>;
+ function = "phy1_led1";
+ status = "disabled";
+ };
+ };
+ };
+
+ gsw_phy2: ethernet-phy@2 {
+ compatible = "ethernet-phy-ieee802.3-c22";
+ reg = <10>;
+ phy-mode = "internal";
+
+ leds {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ gsw_phy2_led0: gsw-phy2-led0@0 {
+ reg = <0>;
+ function = "phy2_led0";
+ status = "disabled";
+ };
+
+ gsw_phy2_led1: gsw-phy2-led1@1 {
+ reg = <1>;
+ function = "phy1_led1";
+ status = "disabled";
+ };
+ };
+ };
+
+ gsw_phy3: ethernet-phy@3 {
+ compatible = "ethernet-phy-ieee802.3-c22";
+ reg = <11>;
+ phy-mode = "internal";
+
+ leds {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ gsw_phy3_led0: gsw-phy3-led0@0 {
+ reg = <0>;
+ function = LED_FUNCTION_LAN;
+ status = "disabled";
+ };
+
+ gsw_phy3_led1: gsw-phy3-led1@1 {
+ reg = <1>;
+ function = LED_FUNCTION_LAN;
+ status = "disabled";
+ };
+ };
+ };
+
+ gsw_phy4: ethernet-phy@4 {
+ compatible = "ethernet-phy-ieee802.3-c22";
+ reg = <12>;
+ phy-mode = "internal";
+
+ leds {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ gsw_phy4_led0: gsw-phy4-led0@0 {
+ reg = <0>;
+ function = LED_FUNCTION_LAN;
+ status = "disabled";
+ };
+
+ gsw_phy4_led1: gsw-phy4-led1@1 {
+ reg = <1>;
+ function = LED_FUNCTION_LAN;
+ status = "disabled";
+ };
+ };
+ };
+ };
+ };
+ };
+};
--- /dev/null
+define Build/an7583-bl2-bl31-uboot
+ head -c $$((0x800)) /dev/zero > $@
+ cat $(STAGING_DIR_IMAGE)/an7583_$1-bl2.fip >> $@
+ dd if=$(STAGING_DIR_IMAGE)/an7583_$1-bl31-uboot.img of=$@ bs=1 seek=$$((0x20000)) conv=notrunc
+endef
+
+define Build/an7583-emmc-bl2-bl31-uboot
+ head -c $$((0x800)) /dev/zero > $@
+ cat $(STAGING_DIR_IMAGE)/an7583_$1-bl2.fip >> $@
+ dd if=$(STAGING_DIR_IMAGE)/an7583_$1-bl31-u-boot.fip of=$@ bs=1 seek=$$((0x20000)) conv=notrunc
+endef
+
+define Build/an7583-preloader
+ cat $(STAGING_DIR_IMAGE)/an7583_$1-bl2.fip >> $@
+endef
+
+define Build/an7583-bl31-uboot
+ cat $(STAGING_DIR_IMAGE)/an7583_$1-bl31-u-boot.fip >> $@
+endef
+
+define Device/FitImageLzma
+ KERNEL_SUFFIX := -uImage.itb
+ KERNEL = kernel-bin | lzma | fit lzma $$(KDIR)/image-$$(DEVICE_DTS).dtb
+ KERNEL_NAME := Image
+endef
+
+define Device/airoha_an7583-evb
+ $(call Device/FitImageLzma)
+ DEVICE_VENDOR := Airoha
+ DEVICE_MODEL := AN7583 Evaluation Board (SNAND)
+ DEVICE_PACKAGES := kmod-leds-pwm kmod-input-gpio-keys-polled
+ DEVICE_DTS := an7583-evb
+ DEVICE_DTS_DIR := ../dts
+ DEVICE_DTS_CONFIG := config@1
+ KERNEL_LOADADDR := 0x80088000
+ IMAGE/sysupgrade.bin := append-kernel | pad-to 128k | append-rootfs | pad-rootfs | append-metadata
+ ARTIFACT/bl2-bl31-uboot.bin := an7583-bl2-bl31-uboot rfb
+ ARTIFACT/preloader.bin := an7583-preloader rfb
+ ARTIFACT/bl31-uboot.fip := an7583-bl31-uboot rfb
+ ARTIFACTS := bl2-bl31-uboot.bin preloader.bin bl31-uboot.fip
+endef
+TARGET_DEVICES += airoha_an7583-evb
+
+define Device/airoha_an7583-evb-emmc
+ DEVICE_VENDOR := Airoha
+ DEVICE_MODEL := AN7583 Evaluation Board (EMMC)
+ DEVICE_DTS := an7583-evb-emmc
+ DEVICE_DTS_DIR := ../dts
+ DEVICE_PACKAGES := kmod-i2c-an7581
+ ARTIFACT/preloader.bin := an7583-preloader rfb
+ ARTIFACT/bl31-uboot.fip := an7583-bl31-uboot rfb
+ ARTIFACT/bl2-bl31-uboot.bin := an7583-emmc-bl2-bl31-uboot rfb
+ ARTIFACTS := bl2-bl31-uboot.bin preloader.bin bl31-uboot.fip
+endef
+TARGET_DEVICES += airoha_an7583-evb-emmc
--- /dev/null
+From 67e3ba978361cb262f8f8981ab88ccb97f1e2bda Mon Sep 17 00:00:00 2001
+From: Christian Marangi <ansuelsmth@gmail.com>
+Date: Tue, 17 Jun 2025 11:16:53 +0200
+Subject: [PATCH] net: mdio: Add MDIO bus controller for Airoha AN7583
+
+Airoha AN7583 SoC have 2 dedicated MDIO bus controller in the SCU
+register map. To driver register an MDIO controller based on the DT
+reg property and access the register by accessing the parent syscon.
+
+The MDIO bus logic is similar to the MT7530 internal MDIO bus but
+deviates of some setting and some HW bug.
+
+On Airoha AN7583 the MDIO clock is set to 25MHz by default and needs to
+be correctly setup to 2.5MHz to correctly work (by setting the divisor
+to 10x).
+
+There seems to be Hardware bug where AN7583_MII_RWDATA
+is not wiped in the context of unconnected PHY and the
+previous read value is returned.
+
+Example: (only one PHY on the BUS at 0x1f)
+ - read at 0x1f report at 0x2 0x7500
+ - read at 0x0 report 0x7500 on every address
+
+To workaround this, we reset the Mdio BUS at every read
+to have consistent values on read operation.
+
+Signed-off-by: Christian Marangi <ansuelsmth@gmail.com>
+Reviewed-by: Andrew Lunn <andrew@lunn.ch>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+---
+ drivers/net/mdio/Kconfig | 7 +
+ drivers/net/mdio/Makefile | 1 +
+ drivers/net/mdio/mdio-airoha.c | 276 +++++++++++++++++++++++++++++++++
+ 3 files changed, 284 insertions(+)
+ create mode 100644 drivers/net/mdio/mdio-airoha.c
+
+--- a/drivers/net/mdio/Kconfig
++++ b/drivers/net/mdio/Kconfig
+@@ -46,6 +46,13 @@ if MDIO_BUS
+ config MDIO_DEVRES
+ tristate
+
++config MDIO_AIROHA
++ tristate "Airoha AN7583 MDIO bus controller"
++ depends on ARCH_AIROHA || COMPILE_TEST
++ help
++ This module provides a driver for the MDIO busses found in the
++ Airoha AN7583 SoC's.
++
+ config MDIO_SUN4I
+ tristate "Allwinner sun4i MDIO interface support"
+ depends on ARCH_SUNXI || COMPILE_TEST
+--- a/drivers/net/mdio/Makefile
++++ b/drivers/net/mdio/Makefile
+@@ -5,6 +5,7 @@ obj-$(CONFIG_ACPI_MDIO) += acpi_mdio.o
+ obj-$(CONFIG_FWNODE_MDIO) += fwnode_mdio.o
+ obj-$(CONFIG_OF_MDIO) += of_mdio.o
+
++obj-$(CONFIG_MDIO_AIROHA) += mdio-airoha.o
+ obj-$(CONFIG_MDIO_ASPEED) += mdio-aspeed.o
+ obj-$(CONFIG_MDIO_BCM_IPROC) += mdio-bcm-iproc.o
+ obj-$(CONFIG_MDIO_BCM_UNIMAC) += mdio-bcm-unimac.o
+--- /dev/null
++++ b/drivers/net/mdio/mdio-airoha.c
+@@ -0,0 +1,276 @@
++// SPDX-License-Identifier: GPL-2.0
++/* Airoha AN7583 MDIO interface driver
++ *
++ * Copyright (C) 2025 Christian Marangi <ansuelsmth@gmail.com>
++ */
++
++#include <linux/clk.h>
++#include <linux/delay.h>
++#include <linux/kernel.h>
++#include <linux/mfd/syscon.h>
++#include <linux/module.h>
++#include <linux/of_mdio.h>
++#include <linux/of_address.h>
++#include <linux/platform_device.h>
++#include <linux/regmap.h>
++#include <linux/reset.h>
++
++/* MII address register definitions */
++#define AN7583_MII_BUSY BIT(31)
++#define AN7583_MII_RDY BIT(30) /* RO signal BUS is ready */
++#define AN7583_MII_CL22_REG_ADDR GENMASK(29, 25)
++#define AN7583_MII_CL45_DEV_ADDR AN7583_MII_CL22_REG_ADDR
++#define AN7583_MII_PHY_ADDR GENMASK(24, 20)
++#define AN7583_MII_CMD GENMASK(19, 18)
++#define AN7583_MII_CMD_CL22_WRITE FIELD_PREP_CONST(AN7583_MII_CMD, 0x1)
++#define AN7583_MII_CMD_CL22_READ FIELD_PREP_CONST(AN7583_MII_CMD, 0x2)
++#define AN7583_MII_CMD_CL45_ADDR FIELD_PREP_CONST(AN7583_MII_CMD, 0x0)
++#define AN7583_MII_CMD_CL45_WRITE FIELD_PREP_CONST(AN7583_MII_CMD, 0x1)
++#define AN7583_MII_CMD_CL45_POSTREAD_INCADDR FIELD_PREP_CONST(AN7583_MII_CMD, 0x2)
++#define AN7583_MII_CMD_CL45_READ FIELD_PREP_CONST(AN7583_MII_CMD, 0x3)
++#define AN7583_MII_ST GENMASK(17, 16)
++#define AN7583_MII_ST_CL45 FIELD_PREP_CONST(AN7583_MII_ST, 0x0)
++#define AN7583_MII_ST_CL22 FIELD_PREP_CONST(AN7583_MII_ST, 0x1)
++#define AN7583_MII_RWDATA GENMASK(15, 0)
++#define AN7583_MII_CL45_REG_ADDR AN7583_MII_RWDATA
++
++#define AN7583_MII_MDIO_DELAY_USEC 100
++#define AN7583_MII_MDIO_RETRY_MSEC 100
++
++struct airoha_mdio_data {
++ u32 base_addr;
++ struct regmap *regmap;
++ struct clk *clk;
++ struct reset_control *reset;
++};
++
++static int airoha_mdio_wait_busy(struct airoha_mdio_data *priv)
++{
++ u32 busy;
++
++ return regmap_read_poll_timeout(priv->regmap, priv->base_addr, busy,
++ !(busy & AN7583_MII_BUSY),
++ AN7583_MII_MDIO_DELAY_USEC,
++ AN7583_MII_MDIO_RETRY_MSEC * USEC_PER_MSEC);
++}
++
++static void airoha_mdio_reset(struct airoha_mdio_data *priv)
++{
++ /* There seems to be Hardware bug where AN7583_MII_RWDATA
++ * is not wiped in the context of unconnected PHY and the
++ * previous read value is returned.
++ *
++ * Example: (only one PHY on the BUS at 0x1f)
++ * - read at 0x1f report at 0x2 0x7500
++ * - read at 0x0 report 0x7500 on every address
++ *
++ * To workaround this, we reset the Mdio BUS at every read
++ * to have consistent values on read operation.
++ */
++ reset_control_assert(priv->reset);
++ reset_control_deassert(priv->reset);
++}
++
++static int airoha_mdio_read(struct mii_bus *bus, int addr, int regnum)
++{
++ struct airoha_mdio_data *priv = bus->priv;
++ u32 val;
++ int ret;
++
++ airoha_mdio_reset(priv);
++
++ val = AN7583_MII_BUSY | AN7583_MII_ST_CL22 |
++ AN7583_MII_CMD_CL22_READ;
++ val |= FIELD_PREP(AN7583_MII_PHY_ADDR, addr);
++ val |= FIELD_PREP(AN7583_MII_CL22_REG_ADDR, regnum);
++
++ ret = regmap_write(priv->regmap, priv->base_addr, val);
++ if (ret)
++ return ret;
++
++ ret = airoha_mdio_wait_busy(priv);
++ if (ret)
++ return ret;
++
++ ret = regmap_read(priv->regmap, priv->base_addr, &val);
++ if (ret)
++ return ret;
++
++ return FIELD_GET(AN7583_MII_RWDATA, val);
++}
++
++static int airoha_mdio_write(struct mii_bus *bus, int addr, int regnum,
++ u16 value)
++{
++ struct airoha_mdio_data *priv = bus->priv;
++ u32 val;
++ int ret;
++
++ val = AN7583_MII_BUSY | AN7583_MII_ST_CL22 |
++ AN7583_MII_CMD_CL22_WRITE;
++ val |= FIELD_PREP(AN7583_MII_PHY_ADDR, addr);
++ val |= FIELD_PREP(AN7583_MII_CL22_REG_ADDR, regnum);
++ val |= FIELD_PREP(AN7583_MII_RWDATA, value);
++
++ ret = regmap_write(priv->regmap, priv->base_addr, val);
++ if (ret)
++ return ret;
++
++ ret = airoha_mdio_wait_busy(priv);
++
++ return ret;
++}
++
++static int airoha_mdio_cl45_read(struct mii_bus *bus, int addr, int devnum,
++ int regnum)
++{
++ struct airoha_mdio_data *priv = bus->priv;
++ u32 val;
++ int ret;
++
++ airoha_mdio_reset(priv);
++
++ val = AN7583_MII_BUSY | AN7583_MII_ST_CL45 |
++ AN7583_MII_CMD_CL45_ADDR;
++ val |= FIELD_PREP(AN7583_MII_PHY_ADDR, addr);
++ val |= FIELD_PREP(AN7583_MII_CL45_DEV_ADDR, devnum);
++ val |= FIELD_PREP(AN7583_MII_CL45_REG_ADDR, regnum);
++
++ ret = regmap_write(priv->regmap, priv->base_addr, val);
++ if (ret)
++ return ret;
++
++ ret = airoha_mdio_wait_busy(priv);
++ if (ret)
++ return ret;
++
++ val = AN7583_MII_BUSY | AN7583_MII_ST_CL45 |
++ AN7583_MII_CMD_CL45_READ;
++ val |= FIELD_PREP(AN7583_MII_PHY_ADDR, addr);
++ val |= FIELD_PREP(AN7583_MII_CL45_DEV_ADDR, devnum);
++
++ ret = regmap_write(priv->regmap, priv->base_addr, val);
++ if (ret)
++ return ret;
++
++ ret = airoha_mdio_wait_busy(priv);
++ if (ret)
++ return ret;
++
++ ret = regmap_read(priv->regmap, priv->base_addr, &val);
++ if (ret)
++ return ret;
++
++ return FIELD_GET(AN7583_MII_RWDATA, val);
++}
++
++static int airoha_mdio_cl45_write(struct mii_bus *bus, int addr, int devnum,
++ int regnum, u16 value)
++{
++ struct airoha_mdio_data *priv = bus->priv;
++ u32 val;
++ int ret;
++
++ val = AN7583_MII_BUSY | AN7583_MII_ST_CL45 |
++ AN7583_MII_CMD_CL45_ADDR;
++ val |= FIELD_PREP(AN7583_MII_PHY_ADDR, addr);
++ val |= FIELD_PREP(AN7583_MII_CL45_DEV_ADDR, devnum);
++ val |= FIELD_PREP(AN7583_MII_CL45_REG_ADDR, regnum);
++
++ ret = regmap_write(priv->regmap, priv->base_addr, val);
++ if (ret)
++ return ret;
++
++ ret = airoha_mdio_wait_busy(priv);
++ if (ret)
++ return ret;
++
++ val = AN7583_MII_BUSY | AN7583_MII_ST_CL45 |
++ AN7583_MII_CMD_CL45_WRITE;
++ val |= FIELD_PREP(AN7583_MII_PHY_ADDR, addr);
++ val |= FIELD_PREP(AN7583_MII_CL45_DEV_ADDR, devnum);
++ val |= FIELD_PREP(AN7583_MII_RWDATA, value);
++
++ ret = regmap_write(priv->regmap, priv->base_addr, val);
++ if (ret)
++ return ret;
++
++ ret = airoha_mdio_wait_busy(priv);
++
++ return ret;
++}
++
++static int airoha_mdio_probe(struct platform_device *pdev)
++{
++ struct device *dev = &pdev->dev;
++ struct airoha_mdio_data *priv;
++ struct mii_bus *bus;
++ u32 addr, freq;
++ int ret;
++
++ ret = of_property_read_u32(dev->of_node, "reg", &addr);
++ if (ret)
++ return ret;
++
++ bus = devm_mdiobus_alloc_size(dev, sizeof(*priv));
++ if (!bus)
++ return -ENOMEM;
++
++ priv = bus->priv;
++ priv->base_addr = addr;
++ priv->regmap = device_node_to_regmap(dev->parent->of_node);
++
++ priv->clk = devm_clk_get_enabled(dev, NULL);
++ if (IS_ERR(priv->clk))
++ return PTR_ERR(priv->clk);
++
++ priv->reset = devm_reset_control_get_exclusive(dev, NULL);
++ if (IS_ERR(priv->reset))
++ return PTR_ERR(priv->reset);
++
++ reset_control_deassert(priv->reset);
++
++ bus->name = "airoha_mdio_bus";
++ snprintf(bus->id, MII_BUS_ID_SIZE, "%s-mii", dev_name(dev));
++ bus->parent = dev;
++ bus->read = airoha_mdio_read;
++ bus->write = airoha_mdio_write;
++ bus->read_c45 = airoha_mdio_cl45_read;
++ bus->write_c45 = airoha_mdio_cl45_write;
++
++ /* Check if a custom frequency is defined in DT or default to 2.5 MHz */
++ if (of_property_read_u32(dev->of_node, "clock-frequency", &freq))
++ freq = 2500000;
++
++ ret = clk_set_rate(priv->clk, freq);
++ if (ret)
++ return ret;
++
++ ret = devm_of_mdiobus_register(dev, bus, dev->of_node);
++ if (ret) {
++ reset_control_assert(priv->reset);
++ return ret;
++ }
++
++ return 0;
++}
++
++static const struct of_device_id airoha_mdio_dt_ids[] = {
++ { .compatible = "airoha,an7583-mdio" },
++ { }
++};
++MODULE_DEVICE_TABLE(of, airoha_mdio_dt_ids);
++
++static struct platform_driver airoha_mdio_driver = {
++ .probe = airoha_mdio_probe,
++ .driver = {
++ .name = "airoha-mdio",
++ .of_match_table = airoha_mdio_dt_ids,
++ },
++};
++
++module_platform_driver(airoha_mdio_driver);
++
++MODULE_DESCRIPTION("Airoha AN7583 MDIO interface driver");
++MODULE_AUTHOR("Christian Marangi <ansuelsmth@gmail.com>");
++MODULE_LICENSE("GPL");
--- /dev/null
+From e77c958d8eab1c29008ab57a2be82daefe886e0a Mon Sep 17 00:00:00 2001
+From: Christian Marangi <ansuelsmth@gmail.com>
+Date: Sun, 25 May 2025 19:25:20 +0200
+Subject: [PATCH 2/5] pinctrl: mediatek: airoha: generalize
+ pins/group/function/confs handling
+
+In preparation for support of Airoha AN7583, generalize
+pins/group/function/confs handling and move them in match_data.
+Inner function will base the values on the pinctrl priv struct instead of
+relying on hardcoded struct.
+
+This permits to use different PIN data while keeping the same logic.
+
+Signed-off-by: Christian Marangi <ansuelsmth@gmail.com>
+---
+ drivers/pinctrl/mediatek/pinctrl-airoha.c | 569 ++++++++++++----------
+ 1 file changed, 319 insertions(+), 250 deletions(-)
+
+--- a/drivers/pinctrl/mediatek/pinctrl-airoha.c
++++ b/drivers/pinctrl/mediatek/pinctrl-airoha.c
+@@ -30,20 +30,20 @@
+ #include "../pinconf.h"
+ #include "../pinmux.h"
+
+-#define PINCTRL_PIN_GROUP(id) \
+- PINCTRL_PINGROUP(#id, id##_pins, ARRAY_SIZE(id##_pins))
++#define PINCTRL_PIN_GROUP(id, table) \
++ PINCTRL_PINGROUP(id, table##_pins, ARRAY_SIZE(table##_pins))
+
+-#define PINCTRL_FUNC_DESC(id) \
++#define PINCTRL_FUNC_DESC(id, table) \
+ { \
+ .desc = { \
+ .func = { \
+ .name = #id, \
+- .groups = id##_groups, \
+- .ngroups = ARRAY_SIZE(id##_groups), \
++ .groups = table##_groups, \
++ .ngroups = ARRAY_SIZE(table##_groups), \
+ } \
+ }, \
+- .groups = id##_func_group, \
+- .group_size = ARRAY_SIZE(id##_func_group), \
++ .groups = table##_func_group, \
++ .group_size = ARRAY_SIZE(table##_func_group), \
+ }
+
+ #define PINCTRL_CONF_DESC(p, offset, mask) \
+@@ -362,16 +362,46 @@ struct airoha_pinctrl_gpiochip {
+ u32 irq_type[AIROHA_NUM_PINS];
+ };
+
++struct airoha_pinctrl_confs_info {
++ const struct airoha_pinctrl_conf *confs;
++ unsigned int num_confs;
++};
++
++enum airoha_pinctrl_confs_type {
++ AIROHA_PINCTRL_CONFS_PULLUP,
++ AIROHA_PINCTRL_CONFS_PULLDOWN,
++ AIROHA_PINCTRL_CONFS_DRIVE_E2,
++ AIROHA_PINCTRL_CONFS_DRIVE_E4,
++ AIROHA_PINCTRL_CONFS_PCIE_RST_OD,
++
++ AIROHA_PINCTRL_CONFS_MAX,
++};
++
+ struct airoha_pinctrl {
+ struct pinctrl_dev *ctrl;
+
++ struct pinctrl_desc desc;
++ const struct pingroup *grps;
++ const struct airoha_pinctrl_func *funcs;
++ const struct airoha_pinctrl_confs_info *confs_info;
++
+ struct regmap *chip_scu;
+ struct regmap *regmap;
+
+ struct airoha_pinctrl_gpiochip gpiochip;
+ };
+
+-static struct pinctrl_pin_desc airoha_pinctrl_pins[] = {
++struct airoha_pinctrl_match_data {
++ const struct pinctrl_pin_desc *pins;
++ const unsigned int num_pins;
++ const struct pingroup *grps;
++ const unsigned int num_grps;
++ const struct airoha_pinctrl_func *funcs;
++ const unsigned int num_funcs;
++ const struct airoha_pinctrl_confs_info confs_info[AIROHA_PINCTRL_CONFS_MAX];
++};
++
++static struct pinctrl_pin_desc en7581_pinctrl_pins[] = {
+ PINCTRL_PIN(0, "uart1_txd"),
+ PINCTRL_PIN(1, "uart1_rxd"),
+ PINCTRL_PIN(2, "i2c_scl"),
+@@ -432,172 +462,172 @@ static struct pinctrl_pin_desc airoha_pi
+ PINCTRL_PIN(63, "pcie_reset2"),
+ };
+
+-static const int pon_pins[] = { 49, 50, 51, 52, 53, 54 };
+-static const int pon_tod_1pps_pins[] = { 46 };
+-static const int gsw_tod_1pps_pins[] = { 46 };
+-static const int sipo_pins[] = { 16, 17 };
+-static const int sipo_rclk_pins[] = { 16, 17, 43 };
+-static const int mdio_pins[] = { 14, 15 };
+-static const int uart2_pins[] = { 48, 55 };
+-static const int uart2_cts_rts_pins[] = { 46, 47 };
+-static const int hsuart_pins[] = { 28, 29 };
+-static const int hsuart_cts_rts_pins[] = { 26, 27 };
+-static const int uart4_pins[] = { 38, 39 };
+-static const int uart5_pins[] = { 18, 19 };
+-static const int i2c0_pins[] = { 2, 3 };
+-static const int i2c1_pins[] = { 14, 15 };
+-static const int jtag_udi_pins[] = { 16, 17, 18, 19, 20 };
+-static const int jtag_dfd_pins[] = { 16, 17, 18, 19, 20 };
+-static const int i2s_pins[] = { 26, 27, 28, 29 };
+-static const int pcm1_pins[] = { 22, 23, 24, 25 };
+-static const int pcm2_pins[] = { 18, 19, 20, 21 };
+-static const int spi_quad_pins[] = { 32, 33 };
+-static const int spi_pins[] = { 4, 5, 6, 7 };
+-static const int spi_cs1_pins[] = { 34 };
+-static const int pcm_spi_pins[] = { 18, 19, 20, 21, 22, 23, 24, 25 };
+-static const int pcm_spi_int_pins[] = { 14 };
+-static const int pcm_spi_rst_pins[] = { 15 };
+-static const int pcm_spi_cs1_pins[] = { 43 };
+-static const int pcm_spi_cs2_pins[] = { 40 };
+-static const int pcm_spi_cs2_p128_pins[] = { 40 };
+-static const int pcm_spi_cs2_p156_pins[] = { 40 };
+-static const int pcm_spi_cs3_pins[] = { 41 };
+-static const int pcm_spi_cs4_pins[] = { 42 };
+-static const int emmc_pins[] = { 4, 5, 6, 30, 31, 32, 33, 34, 35, 36, 37 };
+-static const int pnand_pins[] = { 4, 5, 6, 7, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42 };
+-static const int gpio0_pins[] = { 13 };
+-static const int gpio1_pins[] = { 14 };
+-static const int gpio2_pins[] = { 15 };
+-static const int gpio3_pins[] = { 16 };
+-static const int gpio4_pins[] = { 17 };
+-static const int gpio5_pins[] = { 18 };
+-static const int gpio6_pins[] = { 19 };
+-static const int gpio7_pins[] = { 20 };
+-static const int gpio8_pins[] = { 21 };
+-static const int gpio9_pins[] = { 22 };
+-static const int gpio10_pins[] = { 23 };
+-static const int gpio11_pins[] = { 24 };
+-static const int gpio12_pins[] = { 25 };
+-static const int gpio13_pins[] = { 26 };
+-static const int gpio14_pins[] = { 27 };
+-static const int gpio15_pins[] = { 28 };
+-static const int gpio16_pins[] = { 29 };
+-static const int gpio17_pins[] = { 30 };
+-static const int gpio18_pins[] = { 31 };
+-static const int gpio19_pins[] = { 32 };
+-static const int gpio20_pins[] = { 33 };
+-static const int gpio21_pins[] = { 34 };
+-static const int gpio22_pins[] = { 35 };
+-static const int gpio23_pins[] = { 36 };
+-static const int gpio24_pins[] = { 37 };
+-static const int gpio25_pins[] = { 38 };
+-static const int gpio26_pins[] = { 39 };
+-static const int gpio27_pins[] = { 40 };
+-static const int gpio28_pins[] = { 41 };
+-static const int gpio29_pins[] = { 42 };
+-static const int gpio30_pins[] = { 43 };
+-static const int gpio31_pins[] = { 44 };
+-static const int gpio33_pins[] = { 46 };
+-static const int gpio34_pins[] = { 47 };
+-static const int gpio35_pins[] = { 48 };
+-static const int gpio36_pins[] = { 49 };
+-static const int gpio37_pins[] = { 50 };
+-static const int gpio38_pins[] = { 51 };
+-static const int gpio39_pins[] = { 52 };
+-static const int gpio40_pins[] = { 53 };
+-static const int gpio41_pins[] = { 54 };
+-static const int gpio42_pins[] = { 55 };
+-static const int gpio43_pins[] = { 56 };
+-static const int gpio44_pins[] = { 57 };
+-static const int gpio45_pins[] = { 58 };
+-static const int gpio46_pins[] = { 59 };
+-static const int pcie_reset0_pins[] = { 61 };
+-static const int pcie_reset1_pins[] = { 62 };
+-static const int pcie_reset2_pins[] = { 63 };
+-
+-static const struct pingroup airoha_pinctrl_groups[] = {
+- PINCTRL_PIN_GROUP(pon),
+- PINCTRL_PIN_GROUP(pon_tod_1pps),
+- PINCTRL_PIN_GROUP(gsw_tod_1pps),
+- PINCTRL_PIN_GROUP(sipo),
+- PINCTRL_PIN_GROUP(sipo_rclk),
+- PINCTRL_PIN_GROUP(mdio),
+- PINCTRL_PIN_GROUP(uart2),
+- PINCTRL_PIN_GROUP(uart2_cts_rts),
+- PINCTRL_PIN_GROUP(hsuart),
+- PINCTRL_PIN_GROUP(hsuart_cts_rts),
+- PINCTRL_PIN_GROUP(uart4),
+- PINCTRL_PIN_GROUP(uart5),
+- PINCTRL_PIN_GROUP(i2c0),
+- PINCTRL_PIN_GROUP(i2c1),
+- PINCTRL_PIN_GROUP(jtag_udi),
+- PINCTRL_PIN_GROUP(jtag_dfd),
+- PINCTRL_PIN_GROUP(i2s),
+- PINCTRL_PIN_GROUP(pcm1),
+- PINCTRL_PIN_GROUP(pcm2),
+- PINCTRL_PIN_GROUP(spi),
+- PINCTRL_PIN_GROUP(spi_quad),
+- PINCTRL_PIN_GROUP(spi_cs1),
+- PINCTRL_PIN_GROUP(pcm_spi),
+- PINCTRL_PIN_GROUP(pcm_spi_int),
+- PINCTRL_PIN_GROUP(pcm_spi_rst),
+- PINCTRL_PIN_GROUP(pcm_spi_cs1),
+- PINCTRL_PIN_GROUP(pcm_spi_cs2_p128),
+- PINCTRL_PIN_GROUP(pcm_spi_cs2_p156),
+- PINCTRL_PIN_GROUP(pcm_spi_cs2),
+- PINCTRL_PIN_GROUP(pcm_spi_cs3),
+- PINCTRL_PIN_GROUP(pcm_spi_cs4),
+- PINCTRL_PIN_GROUP(emmc),
+- PINCTRL_PIN_GROUP(pnand),
+- PINCTRL_PIN_GROUP(gpio0),
+- PINCTRL_PIN_GROUP(gpio1),
+- PINCTRL_PIN_GROUP(gpio2),
+- PINCTRL_PIN_GROUP(gpio3),
+- PINCTRL_PIN_GROUP(gpio4),
+- PINCTRL_PIN_GROUP(gpio5),
+- PINCTRL_PIN_GROUP(gpio6),
+- PINCTRL_PIN_GROUP(gpio7),
+- PINCTRL_PIN_GROUP(gpio8),
+- PINCTRL_PIN_GROUP(gpio9),
+- PINCTRL_PIN_GROUP(gpio10),
+- PINCTRL_PIN_GROUP(gpio11),
+- PINCTRL_PIN_GROUP(gpio12),
+- PINCTRL_PIN_GROUP(gpio13),
+- PINCTRL_PIN_GROUP(gpio14),
+- PINCTRL_PIN_GROUP(gpio15),
+- PINCTRL_PIN_GROUP(gpio16),
+- PINCTRL_PIN_GROUP(gpio17),
+- PINCTRL_PIN_GROUP(gpio18),
+- PINCTRL_PIN_GROUP(gpio19),
+- PINCTRL_PIN_GROUP(gpio20),
+- PINCTRL_PIN_GROUP(gpio21),
+- PINCTRL_PIN_GROUP(gpio22),
+- PINCTRL_PIN_GROUP(gpio23),
+- PINCTRL_PIN_GROUP(gpio24),
+- PINCTRL_PIN_GROUP(gpio25),
+- PINCTRL_PIN_GROUP(gpio26),
+- PINCTRL_PIN_GROUP(gpio27),
+- PINCTRL_PIN_GROUP(gpio28),
+- PINCTRL_PIN_GROUP(gpio29),
+- PINCTRL_PIN_GROUP(gpio30),
+- PINCTRL_PIN_GROUP(gpio31),
+- PINCTRL_PIN_GROUP(gpio33),
+- PINCTRL_PIN_GROUP(gpio34),
+- PINCTRL_PIN_GROUP(gpio35),
+- PINCTRL_PIN_GROUP(gpio36),
+- PINCTRL_PIN_GROUP(gpio37),
+- PINCTRL_PIN_GROUP(gpio38),
+- PINCTRL_PIN_GROUP(gpio39),
+- PINCTRL_PIN_GROUP(gpio40),
+- PINCTRL_PIN_GROUP(gpio41),
+- PINCTRL_PIN_GROUP(gpio42),
+- PINCTRL_PIN_GROUP(gpio43),
+- PINCTRL_PIN_GROUP(gpio44),
+- PINCTRL_PIN_GROUP(gpio45),
+- PINCTRL_PIN_GROUP(gpio46),
+- PINCTRL_PIN_GROUP(pcie_reset0),
+- PINCTRL_PIN_GROUP(pcie_reset1),
+- PINCTRL_PIN_GROUP(pcie_reset2),
++static const int en7581_pon_pins[] = { 49, 50, 51, 52, 53, 54 };
++static const int en7581_pon_tod_1pps_pins[] = { 46 };
++static const int en7581_gsw_tod_1pps_pins[] = { 46 };
++static const int en7581_sipo_pins[] = { 16, 17 };
++static const int en7581_sipo_rclk_pins[] = { 16, 17, 43 };
++static const int en7581_mdio_pins[] = { 14, 15 };
++static const int en7581_uart2_pins[] = { 48, 55 };
++static const int en7581_uart2_cts_rts_pins[] = { 46, 47 };
++static const int en7581_hsuart_pins[] = { 28, 29 };
++static const int en7581_hsuart_cts_rts_pins[] = { 26, 27 };
++static const int en7581_uart4_pins[] = { 38, 39 };
++static const int en7581_uart5_pins[] = { 18, 19 };
++static const int en7581_i2c0_pins[] = { 2, 3 };
++static const int en7581_i2c1_pins[] = { 14, 15 };
++static const int en7581_jtag_udi_pins[] = { 16, 17, 18, 19, 20 };
++static const int en7581_jtag_dfd_pins[] = { 16, 17, 18, 19, 20 };
++static const int en7581_i2s_pins[] = { 26, 27, 28, 29 };
++static const int en7581_pcm1_pins[] = { 22, 23, 24, 25 };
++static const int en7581_pcm2_pins[] = { 18, 19, 20, 21 };
++static const int en7581_spi_quad_pins[] = { 32, 33 };
++static const int en7581_spi_pins[] = { 4, 5, 6, 7 };
++static const int en7581_spi_cs1_pins[] = { 34 };
++static const int en7581_pcm_spi_pins[] = { 18, 19, 20, 21, 22, 23, 24, 25 };
++static const int en7581_pcm_spi_int_pins[] = { 14 };
++static const int en7581_pcm_spi_rst_pins[] = { 15 };
++static const int en7581_pcm_spi_cs1_pins[] = { 43 };
++static const int en7581_pcm_spi_cs2_pins[] = { 40 };
++static const int en7581_pcm_spi_cs2_p128_pins[] = { 40 };
++static const int en7581_pcm_spi_cs2_p156_pins[] = { 40 };
++static const int en7581_pcm_spi_cs3_pins[] = { 41 };
++static const int en7581_pcm_spi_cs4_pins[] = { 42 };
++static const int en7581_emmc_pins[] = { 4, 5, 6, 30, 31, 32, 33, 34, 35, 36, 37 };
++static const int en7581_pnand_pins[] = { 4, 5, 6, 7, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42 };
++static const int en7581_gpio0_pins[] = { 13 };
++static const int en7581_gpio1_pins[] = { 14 };
++static const int en7581_gpio2_pins[] = { 15 };
++static const int en7581_gpio3_pins[] = { 16 };
++static const int en7581_gpio4_pins[] = { 17 };
++static const int en7581_gpio5_pins[] = { 18 };
++static const int en7581_gpio6_pins[] = { 19 };
++static const int en7581_gpio7_pins[] = { 20 };
++static const int en7581_gpio8_pins[] = { 21 };
++static const int en7581_gpio9_pins[] = { 22 };
++static const int en7581_gpio10_pins[] = { 23 };
++static const int en7581_gpio11_pins[] = { 24 };
++static const int en7581_gpio12_pins[] = { 25 };
++static const int en7581_gpio13_pins[] = { 26 };
++static const int en7581_gpio14_pins[] = { 27 };
++static const int en7581_gpio15_pins[] = { 28 };
++static const int en7581_gpio16_pins[] = { 29 };
++static const int en7581_gpio17_pins[] = { 30 };
++static const int en7581_gpio18_pins[] = { 31 };
++static const int en7581_gpio19_pins[] = { 32 };
++static const int en7581_gpio20_pins[] = { 33 };
++static const int en7581_gpio21_pins[] = { 34 };
++static const int en7581_gpio22_pins[] = { 35 };
++static const int en7581_gpio23_pins[] = { 36 };
++static const int en7581_gpio24_pins[] = { 37 };
++static const int en7581_gpio25_pins[] = { 38 };
++static const int en7581_gpio26_pins[] = { 39 };
++static const int en7581_gpio27_pins[] = { 40 };
++static const int en7581_gpio28_pins[] = { 41 };
++static const int en7581_gpio29_pins[] = { 42 };
++static const int en7581_gpio30_pins[] = { 43 };
++static const int en7581_gpio31_pins[] = { 44 };
++static const int en7581_gpio33_pins[] = { 46 };
++static const int en7581_gpio34_pins[] = { 47 };
++static const int en7581_gpio35_pins[] = { 48 };
++static const int en7581_gpio36_pins[] = { 49 };
++static const int en7581_gpio37_pins[] = { 50 };
++static const int en7581_gpio38_pins[] = { 51 };
++static const int en7581_gpio39_pins[] = { 52 };
++static const int en7581_gpio40_pins[] = { 53 };
++static const int en7581_gpio41_pins[] = { 54 };
++static const int en7581_gpio42_pins[] = { 55 };
++static const int en7581_gpio43_pins[] = { 56 };
++static const int en7581_gpio44_pins[] = { 57 };
++static const int en7581_gpio45_pins[] = { 58 };
++static const int en7581_gpio46_pins[] = { 59 };
++static const int en7581_pcie_reset0_pins[] = { 61 };
++static const int en7581_pcie_reset1_pins[] = { 62 };
++static const int en7581_pcie_reset2_pins[] = { 63 };
++
++static const struct pingroup en7581_pinctrl_groups[] = {
++ PINCTRL_PIN_GROUP("pon", en7581_pon),
++ PINCTRL_PIN_GROUP("pon_tod_1pps", en7581_pon_tod_1pps),
++ PINCTRL_PIN_GROUP("gsw_tod_1pps", en7581_gsw_tod_1pps),
++ PINCTRL_PIN_GROUP("sipo", en7581_sipo),
++ PINCTRL_PIN_GROUP("sipo_rclk", en7581_sipo_rclk),
++ PINCTRL_PIN_GROUP("mdio", en7581_mdio),
++ PINCTRL_PIN_GROUP("uart2", en7581_uart2),
++ PINCTRL_PIN_GROUP("uart2_cts_rts", en7581_uart2_cts_rts),
++ PINCTRL_PIN_GROUP("hsuart", en7581_hsuart),
++ PINCTRL_PIN_GROUP("hsuart_cts_rts", en7581_hsuart_cts_rts),
++ PINCTRL_PIN_GROUP("uart4", en7581_uart4),
++ PINCTRL_PIN_GROUP("uart5", en7581_uart5),
++ PINCTRL_PIN_GROUP("i2c0", en7581_i2c0),
++ PINCTRL_PIN_GROUP("i2c1", en7581_i2c1),
++ PINCTRL_PIN_GROUP("jtag_udi", en7581_jtag_udi),
++ PINCTRL_PIN_GROUP("jtag_dfd", en7581_jtag_dfd),
++ PINCTRL_PIN_GROUP("i2s", en7581_i2s),
++ PINCTRL_PIN_GROUP("pcm1", en7581_pcm1),
++ PINCTRL_PIN_GROUP("pcm2", en7581_pcm2),
++ PINCTRL_PIN_GROUP("spi", en7581_spi),
++ PINCTRL_PIN_GROUP("spi_quad", en7581_spi_quad),
++ PINCTRL_PIN_GROUP("spi_cs1", en7581_spi_cs1),
++ PINCTRL_PIN_GROUP("pcm_spi", en7581_pcm_spi),
++ PINCTRL_PIN_GROUP("pcm_spi_int", en7581_pcm_spi_int),
++ PINCTRL_PIN_GROUP("pcm_spi_rst", en7581_pcm_spi_rst),
++ PINCTRL_PIN_GROUP("pcm_spi_cs1", en7581_pcm_spi_cs1),
++ PINCTRL_PIN_GROUP("pcm_spi_cs2_p128", en7581_pcm_spi_cs2_p128),
++ PINCTRL_PIN_GROUP("pcm_spi_cs2_p156", en7581_pcm_spi_cs2_p156),
++ PINCTRL_PIN_GROUP("pcm_spi_cs2", en7581_pcm_spi_cs2),
++ PINCTRL_PIN_GROUP("pcm_spi_cs3", en7581_pcm_spi_cs3),
++ PINCTRL_PIN_GROUP("pcm_spi_cs4", en7581_pcm_spi_cs4),
++ PINCTRL_PIN_GROUP("emmc", en7581_emmc),
++ PINCTRL_PIN_GROUP("pnand", en7581_pnand),
++ PINCTRL_PIN_GROUP("gpio0", en7581_gpio0),
++ PINCTRL_PIN_GROUP("gpio1", en7581_gpio1),
++ PINCTRL_PIN_GROUP("gpio2", en7581_gpio2),
++ PINCTRL_PIN_GROUP("gpio3", en7581_gpio3),
++ PINCTRL_PIN_GROUP("gpio4", en7581_gpio4),
++ PINCTRL_PIN_GROUP("gpio5", en7581_gpio5),
++ PINCTRL_PIN_GROUP("gpio6", en7581_gpio6),
++ PINCTRL_PIN_GROUP("gpio7", en7581_gpio7),
++ PINCTRL_PIN_GROUP("gpio8", en7581_gpio8),
++ PINCTRL_PIN_GROUP("gpio9", en7581_gpio9),
++ PINCTRL_PIN_GROUP("gpio10", en7581_gpio10),
++ PINCTRL_PIN_GROUP("gpio11", en7581_gpio11),
++ PINCTRL_PIN_GROUP("gpio12", en7581_gpio12),
++ PINCTRL_PIN_GROUP("gpio13", en7581_gpio13),
++ PINCTRL_PIN_GROUP("gpio14", en7581_gpio14),
++ PINCTRL_PIN_GROUP("gpio15", en7581_gpio15),
++ PINCTRL_PIN_GROUP("gpio16", en7581_gpio16),
++ PINCTRL_PIN_GROUP("gpio17", en7581_gpio17),
++ PINCTRL_PIN_GROUP("gpio18", en7581_gpio18),
++ PINCTRL_PIN_GROUP("gpio19", en7581_gpio19),
++ PINCTRL_PIN_GROUP("gpio20", en7581_gpio20),
++ PINCTRL_PIN_GROUP("gpio21", en7581_gpio21),
++ PINCTRL_PIN_GROUP("gpio22", en7581_gpio22),
++ PINCTRL_PIN_GROUP("gpio23", en7581_gpio23),
++ PINCTRL_PIN_GROUP("gpio24", en7581_gpio24),
++ PINCTRL_PIN_GROUP("gpio25", en7581_gpio25),
++ PINCTRL_PIN_GROUP("gpio26", en7581_gpio26),
++ PINCTRL_PIN_GROUP("gpio27", en7581_gpio27),
++ PINCTRL_PIN_GROUP("gpio28", en7581_gpio28),
++ PINCTRL_PIN_GROUP("gpio29", en7581_gpio29),
++ PINCTRL_PIN_GROUP("gpio30", en7581_gpio30),
++ PINCTRL_PIN_GROUP("gpio31", en7581_gpio31),
++ PINCTRL_PIN_GROUP("gpio33", en7581_gpio33),
++ PINCTRL_PIN_GROUP("gpio34", en7581_gpio34),
++ PINCTRL_PIN_GROUP("gpio35", en7581_gpio35),
++ PINCTRL_PIN_GROUP("gpio36", en7581_gpio36),
++ PINCTRL_PIN_GROUP("gpio37", en7581_gpio37),
++ PINCTRL_PIN_GROUP("gpio38", en7581_gpio38),
++ PINCTRL_PIN_GROUP("gpio39", en7581_gpio39),
++ PINCTRL_PIN_GROUP("gpio40", en7581_gpio40),
++ PINCTRL_PIN_GROUP("gpio41", en7581_gpio41),
++ PINCTRL_PIN_GROUP("gpio42", en7581_gpio42),
++ PINCTRL_PIN_GROUP("gpio43", en7581_gpio43),
++ PINCTRL_PIN_GROUP("gpio44", en7581_gpio44),
++ PINCTRL_PIN_GROUP("gpio45", en7581_gpio45),
++ PINCTRL_PIN_GROUP("gpio46", en7581_gpio46),
++ PINCTRL_PIN_GROUP("pcie_reset0", en7581_pcie_reset0),
++ PINCTRL_PIN_GROUP("pcie_reset1", en7581_pcie_reset1),
++ PINCTRL_PIN_GROUP("pcie_reset2", en7581_pcie_reset2),
+ };
+
+ static const char *const pon_groups[] = { "pon" };
+@@ -1960,33 +1990,33 @@ static const struct airoha_pinctrl_func_
+ },
+ };
+
+-static const struct airoha_pinctrl_func airoha_pinctrl_funcs[] = {
+- PINCTRL_FUNC_DESC(pon),
+- PINCTRL_FUNC_DESC(tod_1pps),
+- PINCTRL_FUNC_DESC(sipo),
+- PINCTRL_FUNC_DESC(mdio),
+- PINCTRL_FUNC_DESC(uart),
+- PINCTRL_FUNC_DESC(i2c),
+- PINCTRL_FUNC_DESC(jtag),
+- PINCTRL_FUNC_DESC(pcm),
+- PINCTRL_FUNC_DESC(spi),
+- PINCTRL_FUNC_DESC(pcm_spi),
+- PINCTRL_FUNC_DESC(i2s),
+- PINCTRL_FUNC_DESC(emmc),
+- PINCTRL_FUNC_DESC(pnand),
+- PINCTRL_FUNC_DESC(pcie_reset),
+- PINCTRL_FUNC_DESC(pwm),
+- PINCTRL_FUNC_DESC(phy1_led0),
+- PINCTRL_FUNC_DESC(phy2_led0),
+- PINCTRL_FUNC_DESC(phy3_led0),
+- PINCTRL_FUNC_DESC(phy4_led0),
+- PINCTRL_FUNC_DESC(phy1_led1),
+- PINCTRL_FUNC_DESC(phy2_led1),
+- PINCTRL_FUNC_DESC(phy3_led1),
+- PINCTRL_FUNC_DESC(phy4_led1),
++static const struct airoha_pinctrl_func en7581_pinctrl_funcs[] = {
++ PINCTRL_FUNC_DESC("pon", pon),
++ PINCTRL_FUNC_DESC("tod_1pps", tod_1pps),
++ PINCTRL_FUNC_DESC("sipo", sipo),
++ PINCTRL_FUNC_DESC("mdio", mdio),
++ PINCTRL_FUNC_DESC("uart", uart),
++ PINCTRL_FUNC_DESC("i2c", i2c),
++ PINCTRL_FUNC_DESC("jtag", jtag),
++ PINCTRL_FUNC_DESC("pcm", pcm),
++ PINCTRL_FUNC_DESC("spi", spi),
++ PINCTRL_FUNC_DESC("pcm_spi", pcm_spi),
++ PINCTRL_FUNC_DESC("i2s", i2s),
++ PINCTRL_FUNC_DESC("emmc", emmc),
++ PINCTRL_FUNC_DESC("pnand", pnand),
++ PINCTRL_FUNC_DESC("pcie_reset", pcie_reset),
++ PINCTRL_FUNC_DESC("pwm", pwm),
++ PINCTRL_FUNC_DESC("phy1_led0", phy1_led0),
++ PINCTRL_FUNC_DESC("phy2_led0", phy2_led0),
++ PINCTRL_FUNC_DESC("phy3_led0", phy3_led0),
++ PINCTRL_FUNC_DESC("phy4_led0", phy4_led0),
++ PINCTRL_FUNC_DESC("phy1_led1", phy1_led1),
++ PINCTRL_FUNC_DESC("phy2_led1", phy2_led1),
++ PINCTRL_FUNC_DESC("phy3_led1", phy3_led1),
++ PINCTRL_FUNC_DESC("phy4_led1", phy4_led1),
+ };
+
+-static const struct airoha_pinctrl_conf airoha_pinctrl_pullup_conf[] = {
++static const struct airoha_pinctrl_conf en7581_pinctrl_pullup_conf[] = {
+ PINCTRL_CONF_DESC(0, REG_I2C_SDA_PU, UART1_TXD_PU_MASK),
+ PINCTRL_CONF_DESC(1, REG_I2C_SDA_PU, UART1_RXD_PU_MASK),
+ PINCTRL_CONF_DESC(2, REG_I2C_SDA_PU, I2C_SDA_PU_MASK),
+@@ -2047,7 +2077,7 @@ static const struct airoha_pinctrl_conf
+ PINCTRL_CONF_DESC(63, REG_I2C_SDA_PU, PCIE2_RESET_PU_MASK),
+ };
+
+-static const struct airoha_pinctrl_conf airoha_pinctrl_pulldown_conf[] = {
++static const struct airoha_pinctrl_conf en7581_pinctrl_pulldown_conf[] = {
+ PINCTRL_CONF_DESC(0, REG_I2C_SDA_PD, UART1_TXD_PD_MASK),
+ PINCTRL_CONF_DESC(1, REG_I2C_SDA_PD, UART1_RXD_PD_MASK),
+ PINCTRL_CONF_DESC(2, REG_I2C_SDA_PD, I2C_SDA_PD_MASK),
+@@ -2108,7 +2138,7 @@ static const struct airoha_pinctrl_conf
+ PINCTRL_CONF_DESC(63, REG_I2C_SDA_PD, PCIE2_RESET_PD_MASK),
+ };
+
+-static const struct airoha_pinctrl_conf airoha_pinctrl_drive_e2_conf[] = {
++static const struct airoha_pinctrl_conf en7581_pinctrl_drive_e2_conf[] = {
+ PINCTRL_CONF_DESC(0, REG_I2C_SDA_E2, UART1_TXD_E2_MASK),
+ PINCTRL_CONF_DESC(1, REG_I2C_SDA_E2, UART1_RXD_E2_MASK),
+ PINCTRL_CONF_DESC(2, REG_I2C_SDA_E2, I2C_SDA_E2_MASK),
+@@ -2169,7 +2199,7 @@ static const struct airoha_pinctrl_conf
+ PINCTRL_CONF_DESC(63, REG_I2C_SDA_E2, PCIE2_RESET_E2_MASK),
+ };
+
+-static const struct airoha_pinctrl_conf airoha_pinctrl_drive_e4_conf[] = {
++static const struct airoha_pinctrl_conf en7581_pinctrl_drive_e4_conf[] = {
+ PINCTRL_CONF_DESC(0, REG_I2C_SDA_E4, UART1_TXD_E4_MASK),
+ PINCTRL_CONF_DESC(1, REG_I2C_SDA_E4, UART1_RXD_E4_MASK),
+ PINCTRL_CONF_DESC(2, REG_I2C_SDA_E4, I2C_SDA_E4_MASK),
+@@ -2230,7 +2260,7 @@ static const struct airoha_pinctrl_conf
+ PINCTRL_CONF_DESC(63, REG_I2C_SDA_E4, PCIE2_RESET_E4_MASK),
+ };
+
+-static const struct airoha_pinctrl_conf airoha_pinctrl_pcie_rst_od_conf[] = {
++static const struct airoha_pinctrl_conf en7581_pinctrl_pcie_rst_od_conf[] = {
+ PINCTRL_CONF_DESC(61, REG_PCIE_RESET_OD, PCIE0_RESET_OD_MASK),
+ PINCTRL_CONF_DESC(62, REG_PCIE_RESET_OD, PCIE1_RESET_OD_MASK),
+ PINCTRL_CONF_DESC(63, REG_PCIE_RESET_OD, PCIE2_RESET_OD_MASK),
+@@ -2552,12 +2582,17 @@ airoha_pinctrl_get_conf_reg(const struct
+ }
+
+ static int airoha_pinctrl_get_conf(struct airoha_pinctrl *pinctrl,
+- const struct airoha_pinctrl_conf *conf,
+- int conf_size, int pin, u32 *val)
++ enum airoha_pinctrl_confs_type conf_type,
++ int pin, u32 *val)
+ {
++ const struct airoha_pinctrl_confs_info *confs_info;
+ const struct airoha_pinctrl_reg *reg;
+
+- reg = airoha_pinctrl_get_conf_reg(conf, conf_size, pin);
++ confs_info = &pinctrl->confs_info[conf_type];
++
++ reg = airoha_pinctrl_get_conf_reg(confs_info->confs,
++ confs_info->num_confs,
++ pin);
+ if (!reg)
+ return -EINVAL;
+
+@@ -2570,12 +2605,17 @@ static int airoha_pinctrl_get_conf(struc
+ }
+
+ static int airoha_pinctrl_set_conf(struct airoha_pinctrl *pinctrl,
+- const struct airoha_pinctrl_conf *conf,
+- int conf_size, int pin, u32 val)
++ enum airoha_pinctrl_confs_type conf_type,
++ int pin, u32 val)
+ {
++ const struct airoha_pinctrl_confs_info *confs_info;
+ const struct airoha_pinctrl_reg *reg = NULL;
+
+- reg = airoha_pinctrl_get_conf_reg(conf, conf_size, pin);
++ confs_info = &pinctrl->confs_info[conf_type];
++
++ reg = airoha_pinctrl_get_conf_reg(confs_info->confs,
++ confs_info->num_confs,
++ pin);
+ if (!reg)
+ return -EINVAL;
+
+@@ -2588,44 +2628,34 @@ static int airoha_pinctrl_set_conf(struc
+ }
+
+ #define airoha_pinctrl_get_pullup_conf(pinctrl, pin, val) \
+- airoha_pinctrl_get_conf((pinctrl), airoha_pinctrl_pullup_conf, \
+- ARRAY_SIZE(airoha_pinctrl_pullup_conf), \
++ airoha_pinctrl_get_conf((pinctrl), AIROHA_PINCTRL_CONFS_PULLUP, \
+ (pin), (val))
+ #define airoha_pinctrl_get_pulldown_conf(pinctrl, pin, val) \
+- airoha_pinctrl_get_conf((pinctrl), airoha_pinctrl_pulldown_conf, \
+- ARRAY_SIZE(airoha_pinctrl_pulldown_conf), \
++ airoha_pinctrl_get_conf((pinctrl), AIROHA_PINCTRL_CONFS_PULLDOWN, \
+ (pin), (val))
+ #define airoha_pinctrl_get_drive_e2_conf(pinctrl, pin, val) \
+- airoha_pinctrl_get_conf((pinctrl), airoha_pinctrl_drive_e2_conf, \
+- ARRAY_SIZE(airoha_pinctrl_drive_e2_conf), \
++ airoha_pinctrl_get_conf((pinctrl), AIROHA_PINCTRL_CONFS_DRIVE_E2, \
+ (pin), (val))
+ #define airoha_pinctrl_get_drive_e4_conf(pinctrl, pin, val) \
+- airoha_pinctrl_get_conf((pinctrl), airoha_pinctrl_drive_e4_conf, \
+- ARRAY_SIZE(airoha_pinctrl_drive_e4_conf), \
++ airoha_pinctrl_get_conf((pinctrl), AIROHA_PINCTRL_CONFS_DRIVE_E4, \
+ (pin), (val))
+ #define airoha_pinctrl_get_pcie_rst_od_conf(pinctrl, pin, val) \
+- airoha_pinctrl_get_conf((pinctrl), airoha_pinctrl_pcie_rst_od_conf, \
+- ARRAY_SIZE(airoha_pinctrl_pcie_rst_od_conf), \
++ airoha_pinctrl_get_conf((pinctrl), AIROHA_PINCTRL_CONFS_PCIE_RST_OD, \
+ (pin), (val))
+ #define airoha_pinctrl_set_pullup_conf(pinctrl, pin, val) \
+- airoha_pinctrl_set_conf((pinctrl), airoha_pinctrl_pullup_conf, \
+- ARRAY_SIZE(airoha_pinctrl_pullup_conf), \
++ airoha_pinctrl_set_conf((pinctrl), AIROHA_PINCTRL_CONFS_PULLUP, \
+ (pin), (val))
+ #define airoha_pinctrl_set_pulldown_conf(pinctrl, pin, val) \
+- airoha_pinctrl_set_conf((pinctrl), airoha_pinctrl_pulldown_conf, \
+- ARRAY_SIZE(airoha_pinctrl_pulldown_conf), \
++ airoha_pinctrl_set_conf((pinctrl), AIROHA_PINCTRL_CONFS_PULLDOWN, \
+ (pin), (val))
+ #define airoha_pinctrl_set_drive_e2_conf(pinctrl, pin, val) \
+- airoha_pinctrl_set_conf((pinctrl), airoha_pinctrl_drive_e2_conf, \
+- ARRAY_SIZE(airoha_pinctrl_drive_e2_conf), \
++ airoha_pinctrl_set_conf((pinctrl), AIROHA_PINCTRL_CONFS_DRIVE_E2, \
+ (pin), (val))
+ #define airoha_pinctrl_set_drive_e4_conf(pinctrl, pin, val) \
+- airoha_pinctrl_set_conf((pinctrl), airoha_pinctrl_drive_e4_conf, \
+- ARRAY_SIZE(airoha_pinctrl_drive_e4_conf), \
++ airoha_pinctrl_set_conf((pinctrl), AIROHA_PINCTRL_CONFS_DRIVE_E4, \
+ (pin), (val))
+ #define airoha_pinctrl_set_pcie_rst_od_conf(pinctrl, pin, val) \
+- airoha_pinctrl_set_conf((pinctrl), airoha_pinctrl_pcie_rst_od_conf, \
+- ARRAY_SIZE(airoha_pinctrl_pcie_rst_od_conf), \
++ airoha_pinctrl_set_conf((pinctrl), AIROHA_PINCTRL_CONFS_PCIE_RST_OD, \
+ (pin), (val))
+
+ static int airoha_pinconf_get_direction(struct pinctrl_dev *pctrl_dev, u32 p)
+@@ -2804,12 +2834,13 @@ static int airoha_pinconf_set(struct pin
+ static int airoha_pinconf_group_get(struct pinctrl_dev *pctrl_dev,
+ unsigned int group, unsigned long *config)
+ {
++ struct airoha_pinctrl *pinctrl = pinctrl_dev_get_drvdata(pctrl_dev);
+ u32 cur_config = 0;
+ int i;
+
+- for (i = 0; i < airoha_pinctrl_groups[group].npins; i++) {
++ for (i = 0; i < pinctrl->grps[group].npins; i++) {
+ if (airoha_pinconf_get(pctrl_dev,
+- airoha_pinctrl_groups[group].pins[i],
++ pinctrl->grps[group].pins[i],
+ config))
+ return -ENOTSUPP;
+
+@@ -2826,13 +2857,14 @@ static int airoha_pinconf_group_set(stru
+ unsigned int group, unsigned long *configs,
+ unsigned int num_configs)
+ {
++ struct airoha_pinctrl *pinctrl = pinctrl_dev_get_drvdata(pctrl_dev);
+ int i;
+
+- for (i = 0; i < airoha_pinctrl_groups[group].npins; i++) {
++ for (i = 0; i < pinctrl->grps[group].npins; i++) {
+ int err;
+
+ err = airoha_pinconf_set(pctrl_dev,
+- airoha_pinctrl_groups[group].pins[i],
++ pinctrl->grps[group].pins[i],
+ configs, num_configs);
+ if (err)
+ return err;
+@@ -2858,23 +2890,16 @@ static const struct pinctrl_ops airoha_p
+ .dt_free_map = pinconf_generic_dt_free_map,
+ };
+
+-static struct pinctrl_desc airoha_pinctrl_desc = {
+- .name = KBUILD_MODNAME,
+- .owner = THIS_MODULE,
+- .pctlops = &airoha_pctlops,
+- .pmxops = &airoha_pmxops,
+- .confops = &airoha_confops,
+- .pins = airoha_pinctrl_pins,
+- .npins = ARRAY_SIZE(airoha_pinctrl_pins),
+-};
+-
+ static int airoha_pinctrl_probe(struct platform_device *pdev)
+ {
++ const struct airoha_pinctrl_match_data *data;
+ struct device *dev = &pdev->dev;
+ struct airoha_pinctrl *pinctrl;
+ struct regmap *map;
+ int err, i;
+
++ data = device_get_match_data(dev);
++
+ pinctrl = devm_kzalloc(dev, sizeof(*pinctrl), GFP_KERNEL);
+ if (!pinctrl)
+ return -ENOMEM;
+@@ -2889,14 +2914,23 @@ static int airoha_pinctrl_probe(struct p
+
+ pinctrl->chip_scu = map;
+
+- err = devm_pinctrl_register_and_init(dev, &airoha_pinctrl_desc,
++ /* Init pinctrl desc struct */
++ pinctrl->desc.name = KBUILD_MODNAME;
++ pinctrl->desc.owner = THIS_MODULE,
++ pinctrl->desc.pctlops = &airoha_pctlops,
++ pinctrl->desc.pmxops = &airoha_pmxops,
++ pinctrl->desc.confops = &airoha_confops,
++ pinctrl->desc.pins = data->pins,
++ pinctrl->desc.npins = data->num_pins,
++
++ err = devm_pinctrl_register_and_init(dev, &pinctrl->desc,
+ pinctrl, &pinctrl->ctrl);
+ if (err)
+ return err;
+
+ /* build pin groups */
+- for (i = 0; i < ARRAY_SIZE(airoha_pinctrl_groups); i++) {
+- const struct pingroup *grp = &airoha_pinctrl_groups[i];
++ for (i = 0; i < data->num_grps; i++) {
++ const struct pingroup *grp = &data->grps[i];
+
+ err = pinctrl_generic_add_group(pinctrl->ctrl, grp->name,
+ grp->pins, grp->npins,
+@@ -2909,10 +2943,10 @@ static int airoha_pinctrl_probe(struct p
+ }
+
+ /* build functions */
+- for (i = 0; i < ARRAY_SIZE(airoha_pinctrl_funcs); i++) {
++ for (i = 0; i < data->num_funcs; i++) {
+ const struct airoha_pinctrl_func *func;
+
+- func = &airoha_pinctrl_funcs[i];
++ func = &data->funcs[i];
+ err = pinmux_generic_add_function(pinctrl->ctrl,
+ func->desc.func.name,
+ func->desc.func.groups,
+@@ -2925,6 +2959,10 @@ static int airoha_pinctrl_probe(struct p
+ }
+ }
+
++ pinctrl->grps = data->grps;
++ pinctrl->funcs = data->funcs;
++ pinctrl->confs_info = data->confs_info;
++
+ err = pinctrl_enable(pinctrl->ctrl);
+ if (err)
+ return err;
+@@ -2933,8 +2971,39 @@ static int airoha_pinctrl_probe(struct p
+ return airoha_pinctrl_add_gpiochip(pinctrl, pdev);
+ }
+
++static const struct airoha_pinctrl_match_data en7581_pinctrl_match_data = {
++ .pins = en7581_pinctrl_pins,
++ .num_pins = ARRAY_SIZE(en7581_pinctrl_pins),
++ .grps = en7581_pinctrl_groups,
++ .num_grps = ARRAY_SIZE(en7581_pinctrl_groups),
++ .funcs = en7581_pinctrl_funcs,
++ .num_funcs = ARRAY_SIZE(en7581_pinctrl_funcs),
++ .confs_info = {
++ [AIROHA_PINCTRL_CONFS_PULLUP] = {
++ .confs = en7581_pinctrl_pullup_conf,
++ .num_confs = ARRAY_SIZE(en7581_pinctrl_pullup_conf),
++ },
++ [AIROHA_PINCTRL_CONFS_PULLDOWN] = {
++ .confs = en7581_pinctrl_pulldown_conf,
++ .num_confs = ARRAY_SIZE(en7581_pinctrl_pulldown_conf),
++ },
++ [AIROHA_PINCTRL_CONFS_DRIVE_E2] = {
++ .confs = en7581_pinctrl_drive_e2_conf,
++ .num_confs = ARRAY_SIZE(en7581_pinctrl_drive_e2_conf),
++ },
++ [AIROHA_PINCTRL_CONFS_DRIVE_E4] = {
++ .confs = en7581_pinctrl_drive_e4_conf,
++ .num_confs = ARRAY_SIZE(en7581_pinctrl_drive_e4_conf),
++ },
++ [AIROHA_PINCTRL_CONFS_PCIE_RST_OD] = {
++ .confs = en7581_pinctrl_pcie_rst_od_conf,
++ .num_confs = ARRAY_SIZE(en7581_pinctrl_pcie_rst_od_conf),
++ },
++ },
++};
++
+ static const struct of_device_id airoha_pinctrl_of_match[] = {
+- { .compatible = "airoha,en7581-pinctrl" },
++ { .compatible = "airoha,en7581-pinctrl", .data = &en7581_pinctrl_match_data },
+ { /* sentinel */ }
+ };
+ MODULE_DEVICE_TABLE(of, airoha_pinctrl_of_match);
--- /dev/null
+From ee980d96b6ecd385691f101e641f3e15513ce8c3 Mon Sep 17 00:00:00 2001
+From: Christian Marangi <ansuelsmth@gmail.com>
+Date: Sun, 25 May 2025 20:28:34 +0200
+Subject: [PATCH 3/5] pinctrl: airoha: convert PHY LED GPIO to macro
+
+PHY LED GPIO pinctrl struct definition is very similar across the
+different 4 PHY and 2 LED and it can be generelized to a macro.
+
+To reduce code size, convert them to a common macro.
+
+Signed-off-by: Christian Marangi <ansuelsmth@gmail.com>
+---
+ drivers/pinctrl/mediatek/pinctrl-airoha.c | 570 ++++------------------
+ 1 file changed, 82 insertions(+), 488 deletions(-)
+
+--- a/drivers/pinctrl/mediatek/pinctrl-airoha.c
++++ b/drivers/pinctrl/mediatek/pinctrl-airoha.c
+@@ -1478,516 +1478,110 @@ static const struct airoha_pinctrl_func_
+ },
+ };
+
++#define AIROHA_PINCTRL_PHY_LED(gpio, mux_val, map_mask, map_val) \
++ { \
++ .name = (gpio), \
++ .regmap[0] = { \
++ AIROHA_FUNC_MUX, \
++ REG_GPIO_2ND_I2C_MODE, \
++ (mux_val), \
++ (mux_val), \
++ }, \
++ .regmap[1] = { \
++ AIROHA_FUNC_MUX, \
++ REG_LAN_LED0_MAPPING, \
++ (map_mask), \
++ (map_val), \
++ }, \
++ .regmap_size = 2, \
++ }
++
+ static const struct airoha_pinctrl_func_group phy1_led0_func_group[] = {
+- {
+- .name = "gpio33",
+- .regmap[0] = {
+- AIROHA_FUNC_MUX,
+- REG_GPIO_2ND_I2C_MODE,
+- GPIO_LAN0_LED0_MODE_MASK,
+- GPIO_LAN0_LED0_MODE_MASK
+- },
+- .regmap[1] = {
+- AIROHA_FUNC_MUX,
+- REG_LAN_LED0_MAPPING,
+- LAN0_LED_MAPPING_MASK,
+- LAN0_PHY_LED_MAP(0)
+- },
+- .regmap_size = 2,
+- }, {
+- .name = "gpio34",
+- .regmap[0] = {
+- AIROHA_FUNC_MUX,
+- REG_GPIO_2ND_I2C_MODE,
+- GPIO_LAN1_LED0_MODE_MASK,
+- GPIO_LAN1_LED0_MODE_MASK
+- },
+- .regmap[1] = {
+- AIROHA_FUNC_MUX,
+- REG_LAN_LED0_MAPPING,
+- LAN1_LED_MAPPING_MASK,
+- LAN1_PHY_LED_MAP(0)
+- },
+- .regmap_size = 2,
+- }, {
+- .name = "gpio35",
+- .regmap[0] = {
+- AIROHA_FUNC_MUX,
+- REG_GPIO_2ND_I2C_MODE,
+- GPIO_LAN2_LED0_MODE_MASK,
+- GPIO_LAN2_LED0_MODE_MASK
+- },
+- .regmap[1] = {
+- AIROHA_FUNC_MUX,
+- REG_LAN_LED0_MAPPING,
+- LAN2_LED_MAPPING_MASK,
+- LAN2_PHY_LED_MAP(0)
+- },
+- .regmap_size = 2,
+- }, {
+- .name = "gpio42",
+- .regmap[0] = {
+- AIROHA_FUNC_MUX,
+- REG_GPIO_2ND_I2C_MODE,
+- GPIO_LAN3_LED0_MODE_MASK,
+- GPIO_LAN3_LED0_MODE_MASK
+- },
+- .regmap[1] = {
+- AIROHA_FUNC_MUX,
+- REG_LAN_LED0_MAPPING,
+- LAN3_LED_MAPPING_MASK,
+- LAN3_PHY_LED_MAP(0)
+- },
+- .regmap_size = 2,
+- },
++ AIROHA_PINCTRL_PHY_LED("gpio33", GPIO_LAN0_LED0_MODE_MASK,
++ LAN0_LED_MAPPING_MASK, LAN0_PHY_LED_MAP(0)),
++ AIROHA_PINCTRL_PHY_LED("gpio34", GPIO_LAN1_LED0_MODE_MASK,
++ LAN1_LED_MAPPING_MASK, LAN1_PHY_LED_MAP(0)),
++ AIROHA_PINCTRL_PHY_LED("gpio35", GPIO_LAN2_LED0_MODE_MASK,
++ LAN2_LED_MAPPING_MASK, LAN2_PHY_LED_MAP(0)),
++ AIROHA_PINCTRL_PHY_LED("gpio42", GPIO_LAN3_LED0_MODE_MASK,
++ LAN3_LED_MAPPING_MASK, LAN3_PHY_LED_MAP(0)),
+ };
+
+ static const struct airoha_pinctrl_func_group phy2_led0_func_group[] = {
+- {
+- .name = "gpio33",
+- .regmap[0] = {
+- AIROHA_FUNC_MUX,
+- REG_GPIO_2ND_I2C_MODE,
+- GPIO_LAN0_LED0_MODE_MASK,
+- GPIO_LAN0_LED0_MODE_MASK
+- },
+- .regmap[1] = {
+- AIROHA_FUNC_MUX,
+- REG_LAN_LED0_MAPPING,
+- LAN0_LED_MAPPING_MASK,
+- LAN0_PHY_LED_MAP(1)
+- },
+- .regmap_size = 2,
+- }, {
+- .name = "gpio34",
+- .regmap[0] = {
+- AIROHA_FUNC_MUX,
+- REG_GPIO_2ND_I2C_MODE,
+- GPIO_LAN1_LED0_MODE_MASK,
+- GPIO_LAN1_LED0_MODE_MASK
+- },
+- .regmap[1] = {
+- AIROHA_FUNC_MUX,
+- REG_LAN_LED0_MAPPING,
+- LAN1_LED_MAPPING_MASK,
+- LAN1_PHY_LED_MAP(1)
+- },
+- .regmap_size = 2,
+- }, {
+- .name = "gpio35",
+- .regmap[0] = {
+- AIROHA_FUNC_MUX,
+- REG_GPIO_2ND_I2C_MODE,
+- GPIO_LAN2_LED0_MODE_MASK,
+- GPIO_LAN2_LED0_MODE_MASK
+- },
+- .regmap[1] = {
+- AIROHA_FUNC_MUX,
+- REG_LAN_LED0_MAPPING,
+- LAN2_LED_MAPPING_MASK,
+- LAN2_PHY_LED_MAP(1)
+- },
+- .regmap_size = 2,
+- }, {
+- .name = "gpio42",
+- .regmap[0] = {
+- AIROHA_FUNC_MUX,
+- REG_GPIO_2ND_I2C_MODE,
+- GPIO_LAN3_LED0_MODE_MASK,
+- GPIO_LAN3_LED0_MODE_MASK
+- },
+- .regmap[1] = {
+- AIROHA_FUNC_MUX,
+- REG_LAN_LED0_MAPPING,
+- LAN3_LED_MAPPING_MASK,
+- LAN3_PHY_LED_MAP(1)
+- },
+- .regmap_size = 2,
+- },
++ AIROHA_PINCTRL_PHY_LED("gpio33", GPIO_LAN0_LED0_MODE_MASK,
++ LAN0_LED_MAPPING_MASK, LAN0_PHY_LED_MAP(1)),
++ AIROHA_PINCTRL_PHY_LED("gpio34", GPIO_LAN1_LED0_MODE_MASK,
++ LAN1_LED_MAPPING_MASK, LAN1_PHY_LED_MAP(1)),
++ AIROHA_PINCTRL_PHY_LED("gpio35", GPIO_LAN2_LED0_MODE_MASK,
++ LAN2_LED_MAPPING_MASK, LAN2_PHY_LED_MAP(1)),
++ AIROHA_PINCTRL_PHY_LED("gpio42", GPIO_LAN3_LED0_MODE_MASK,
++ LAN3_LED_MAPPING_MASK, LAN3_PHY_LED_MAP(1)),
+ };
+
+ static const struct airoha_pinctrl_func_group phy3_led0_func_group[] = {
+- {
+- .name = "gpio33",
+- .regmap[0] = {
+- AIROHA_FUNC_MUX,
+- REG_GPIO_2ND_I2C_MODE,
+- GPIO_LAN0_LED0_MODE_MASK,
+- GPIO_LAN0_LED0_MODE_MASK
+- },
+- .regmap[1] = {
+- AIROHA_FUNC_MUX,
+- REG_LAN_LED0_MAPPING,
+- LAN0_LED_MAPPING_MASK,
+- LAN0_PHY_LED_MAP(2)
+- },
+- .regmap_size = 2,
+- }, {
+- .name = "gpio34",
+- .regmap[0] = {
+- AIROHA_FUNC_MUX,
+- REG_GPIO_2ND_I2C_MODE,
+- GPIO_LAN1_LED0_MODE_MASK,
+- GPIO_LAN1_LED0_MODE_MASK
+- },
+- .regmap[1] = {
+- AIROHA_FUNC_MUX,
+- REG_LAN_LED0_MAPPING,
+- LAN1_LED_MAPPING_MASK,
+- LAN1_PHY_LED_MAP(2)
+- },
+- .regmap_size = 2,
+- }, {
+- .name = "gpio35",
+- .regmap[0] = {
+- AIROHA_FUNC_MUX,
+- REG_GPIO_2ND_I2C_MODE,
+- GPIO_LAN2_LED0_MODE_MASK,
+- GPIO_LAN2_LED0_MODE_MASK
+- },
+- .regmap[1] = {
+- AIROHA_FUNC_MUX,
+- REG_LAN_LED0_MAPPING,
+- LAN2_LED_MAPPING_MASK,
+- LAN2_PHY_LED_MAP(2)
+- },
+- .regmap_size = 2,
+- }, {
+- .name = "gpio42",
+- .regmap[0] = {
+- AIROHA_FUNC_MUX,
+- REG_GPIO_2ND_I2C_MODE,
+- GPIO_LAN3_LED0_MODE_MASK,
+- GPIO_LAN3_LED0_MODE_MASK
+- },
+- .regmap[1] = {
+- AIROHA_FUNC_MUX,
+- REG_LAN_LED0_MAPPING,
+- LAN3_LED_MAPPING_MASK,
+- LAN3_PHY_LED_MAP(2)
+- },
+- .regmap_size = 2,
+- },
++ AIROHA_PINCTRL_PHY_LED("gpio33", GPIO_LAN0_LED0_MODE_MASK,
++ LAN0_LED_MAPPING_MASK, LAN0_PHY_LED_MAP(2)),
++ AIROHA_PINCTRL_PHY_LED("gpio34", GPIO_LAN1_LED0_MODE_MASK,
++ LAN1_LED_MAPPING_MASK, LAN1_PHY_LED_MAP(2)),
++ AIROHA_PINCTRL_PHY_LED("gpio35", GPIO_LAN2_LED0_MODE_MASK,
++ LAN2_LED_MAPPING_MASK, LAN2_PHY_LED_MAP(2)),
++ AIROHA_PINCTRL_PHY_LED("gpio42", GPIO_LAN3_LED0_MODE_MASK,
++ LAN3_LED_MAPPING_MASK, LAN3_PHY_LED_MAP(2)),
+ };
+
+ static const struct airoha_pinctrl_func_group phy4_led0_func_group[] = {
+- {
+- .name = "gpio33",
+- .regmap[0] = {
+- AIROHA_FUNC_MUX,
+- REG_GPIO_2ND_I2C_MODE,
+- GPIO_LAN0_LED0_MODE_MASK,
+- GPIO_LAN0_LED0_MODE_MASK
+- },
+- .regmap[1] = {
+- AIROHA_FUNC_MUX,
+- REG_LAN_LED0_MAPPING,
+- LAN0_LED_MAPPING_MASK,
+- LAN0_PHY_LED_MAP(3)
+- },
+- .regmap_size = 2,
+- }, {
+- .name = "gpio34",
+- .regmap[0] = {
+- AIROHA_FUNC_MUX,
+- REG_GPIO_2ND_I2C_MODE,
+- GPIO_LAN1_LED0_MODE_MASK,
+- GPIO_LAN1_LED0_MODE_MASK
+- },
+- .regmap[1] = {
+- AIROHA_FUNC_MUX,
+- REG_LAN_LED0_MAPPING,
+- LAN1_LED_MAPPING_MASK,
+- LAN1_PHY_LED_MAP(3)
+- },
+- .regmap_size = 2,
+- }, {
+- .name = "gpio35",
+- .regmap[0] = {
+- AIROHA_FUNC_MUX,
+- REG_GPIO_2ND_I2C_MODE,
+- GPIO_LAN2_LED0_MODE_MASK,
+- GPIO_LAN2_LED0_MODE_MASK
+- },
+- .regmap[1] = {
+- AIROHA_FUNC_MUX,
+- REG_LAN_LED0_MAPPING,
+- LAN2_LED_MAPPING_MASK,
+- LAN2_PHY_LED_MAP(3)
+- },
+- .regmap_size = 2,
+- }, {
+- .name = "gpio42",
+- .regmap[0] = {
+- AIROHA_FUNC_MUX,
+- REG_GPIO_2ND_I2C_MODE,
+- GPIO_LAN3_LED0_MODE_MASK,
+- GPIO_LAN3_LED0_MODE_MASK
+- },
+- .regmap[1] = {
+- AIROHA_FUNC_MUX,
+- REG_LAN_LED0_MAPPING,
+- LAN3_LED_MAPPING_MASK,
+- LAN3_PHY_LED_MAP(3)
+- },
+- .regmap_size = 2,
+- },
++ AIROHA_PINCTRL_PHY_LED("gpio33", GPIO_LAN0_LED0_MODE_MASK,
++ LAN0_LED_MAPPING_MASK, LAN0_PHY_LED_MAP(3)),
++ AIROHA_PINCTRL_PHY_LED("gpio34", GPIO_LAN1_LED0_MODE_MASK,
++ LAN1_LED_MAPPING_MASK, LAN1_PHY_LED_MAP(3)),
++ AIROHA_PINCTRL_PHY_LED("gpio35", GPIO_LAN2_LED0_MODE_MASK,
++ LAN2_LED_MAPPING_MASK, LAN2_PHY_LED_MAP(3)),
++ AIROHA_PINCTRL_PHY_LED("gpio42", GPIO_LAN3_LED0_MODE_MASK,
++ LAN3_LED_MAPPING_MASK, LAN3_PHY_LED_MAP(3)),
+ };
+
+ static const struct airoha_pinctrl_func_group phy1_led1_func_group[] = {
+- {
+- .name = "gpio43",
+- .regmap[0] = {
+- AIROHA_FUNC_MUX,
+- REG_GPIO_2ND_I2C_MODE,
+- GPIO_LAN0_LED1_MODE_MASK,
+- GPIO_LAN0_LED1_MODE_MASK
+- },
+- .regmap[1] = {
+- AIROHA_FUNC_MUX,
+- REG_LAN_LED1_MAPPING,
+- LAN0_LED_MAPPING_MASK,
+- LAN0_PHY_LED_MAP(0)
+- },
+- .regmap_size = 2,
+- }, {
+- .name = "gpio44",
+- .regmap[0] = {
+- AIROHA_FUNC_MUX,
+- REG_GPIO_2ND_I2C_MODE,
+- GPIO_LAN1_LED1_MODE_MASK,
+- GPIO_LAN1_LED1_MODE_MASK
+- },
+- .regmap[1] = {
+- AIROHA_FUNC_MUX,
+- REG_LAN_LED1_MAPPING,
+- LAN1_LED_MAPPING_MASK,
+- LAN1_PHY_LED_MAP(0)
+- },
+- .regmap_size = 2,
+- }, {
+- .name = "gpio45",
+- .regmap[0] = {
+- AIROHA_FUNC_MUX,
+- REG_GPIO_2ND_I2C_MODE,
+- GPIO_LAN2_LED1_MODE_MASK,
+- GPIO_LAN2_LED1_MODE_MASK
+- },
+- .regmap[1] = {
+- AIROHA_FUNC_MUX,
+- REG_LAN_LED1_MAPPING,
+- LAN2_LED_MAPPING_MASK,
+- LAN2_PHY_LED_MAP(0)
+- },
+- .regmap_size = 2,
+- }, {
+- .name = "gpio46",
+- .regmap[0] = {
+- AIROHA_FUNC_MUX,
+- REG_GPIO_2ND_I2C_MODE,
+- GPIO_LAN3_LED1_MODE_MASK,
+- GPIO_LAN3_LED1_MODE_MASK
+- },
+- .regmap[1] = {
+- AIROHA_FUNC_MUX,
+- REG_LAN_LED1_MAPPING,
+- LAN3_LED_MAPPING_MASK,
+- LAN3_PHY_LED_MAP(0)
+- },
+- .regmap_size = 2,
+- },
++ AIROHA_PINCTRL_PHY_LED("gpio33", GPIO_LAN0_LED1_MODE_MASK,
++ LAN0_LED_MAPPING_MASK, LAN0_PHY_LED_MAP(0)),
++ AIROHA_PINCTRL_PHY_LED("gpio34", GPIO_LAN1_LED1_MODE_MASK,
++ LAN1_LED_MAPPING_MASK, LAN1_PHY_LED_MAP(0)),
++ AIROHA_PINCTRL_PHY_LED("gpio35", GPIO_LAN2_LED1_MODE_MASK,
++ LAN2_LED_MAPPING_MASK, LAN2_PHY_LED_MAP(0)),
++ AIROHA_PINCTRL_PHY_LED("gpio42", GPIO_LAN3_LED1_MODE_MASK,
++ LAN3_LED_MAPPING_MASK, LAN3_PHY_LED_MAP(0)),
+ };
+
+ static const struct airoha_pinctrl_func_group phy2_led1_func_group[] = {
+- {
+- .name = "gpio43",
+- .regmap[0] = {
+- AIROHA_FUNC_MUX,
+- REG_GPIO_2ND_I2C_MODE,
+- GPIO_LAN0_LED1_MODE_MASK,
+- GPIO_LAN0_LED1_MODE_MASK
+- },
+- .regmap[1] = {
+- AIROHA_FUNC_MUX,
+- REG_LAN_LED1_MAPPING,
+- LAN0_LED_MAPPING_MASK,
+- LAN0_PHY_LED_MAP(1)
+- },
+- .regmap_size = 2,
+- }, {
+- .name = "gpio44",
+- .regmap[0] = {
+- AIROHA_FUNC_MUX,
+- REG_GPIO_2ND_I2C_MODE,
+- GPIO_LAN1_LED1_MODE_MASK,
+- GPIO_LAN1_LED1_MODE_MASK
+- },
+- .regmap[1] = {
+- AIROHA_FUNC_MUX,
+- REG_LAN_LED1_MAPPING,
+- LAN1_LED_MAPPING_MASK,
+- LAN1_PHY_LED_MAP(1)
+- },
+- .regmap_size = 2,
+- }, {
+- .name = "gpio45",
+- .regmap[0] = {
+- AIROHA_FUNC_MUX,
+- REG_GPIO_2ND_I2C_MODE,
+- GPIO_LAN2_LED1_MODE_MASK,
+- GPIO_LAN2_LED1_MODE_MASK
+- },
+- .regmap[1] = {
+- AIROHA_FUNC_MUX,
+- REG_LAN_LED1_MAPPING,
+- LAN2_LED_MAPPING_MASK,
+- LAN2_PHY_LED_MAP(1)
+- },
+- .regmap_size = 2,
+- }, {
+- .name = "gpio46",
+- .regmap[0] = {
+- AIROHA_FUNC_MUX,
+- REG_GPIO_2ND_I2C_MODE,
+- GPIO_LAN3_LED1_MODE_MASK,
+- GPIO_LAN3_LED1_MODE_MASK
+- },
+- .regmap[1] = {
+- AIROHA_FUNC_MUX,
+- REG_LAN_LED1_MAPPING,
+- LAN3_LED_MAPPING_MASK,
+- LAN3_PHY_LED_MAP(1)
+- },
+- .regmap_size = 2,
+- },
++ AIROHA_PINCTRL_PHY_LED("gpio33", GPIO_LAN0_LED1_MODE_MASK,
++ LAN0_LED_MAPPING_MASK, LAN0_PHY_LED_MAP(1)),
++ AIROHA_PINCTRL_PHY_LED("gpio34", GPIO_LAN1_LED1_MODE_MASK,
++ LAN1_LED_MAPPING_MASK, LAN1_PHY_LED_MAP(1)),
++ AIROHA_PINCTRL_PHY_LED("gpio35", GPIO_LAN2_LED1_MODE_MASK,
++ LAN2_LED_MAPPING_MASK, LAN2_PHY_LED_MAP(1)),
++ AIROHA_PINCTRL_PHY_LED("gpio42", GPIO_LAN3_LED1_MODE_MASK,
++ LAN3_LED_MAPPING_MASK, LAN3_PHY_LED_MAP(1)),
+ };
+
+ static const struct airoha_pinctrl_func_group phy3_led1_func_group[] = {
+- {
+- .name = "gpio43",
+- .regmap[0] = {
+- AIROHA_FUNC_MUX,
+- REG_GPIO_2ND_I2C_MODE,
+- GPIO_LAN0_LED1_MODE_MASK,
+- GPIO_LAN0_LED1_MODE_MASK
+- },
+- .regmap[1] = {
+- AIROHA_FUNC_MUX,
+- REG_LAN_LED1_MAPPING,
+- LAN0_LED_MAPPING_MASK,
+- LAN0_PHY_LED_MAP(2)
+- },
+- .regmap_size = 2,
+- }, {
+- .name = "gpio44",
+- .regmap[0] = {
+- AIROHA_FUNC_MUX,
+- REG_GPIO_2ND_I2C_MODE,
+- GPIO_LAN1_LED1_MODE_MASK,
+- GPIO_LAN1_LED1_MODE_MASK
+- },
+- .regmap[1] = {
+- AIROHA_FUNC_MUX,
+- REG_LAN_LED1_MAPPING,
+- LAN1_LED_MAPPING_MASK,
+- LAN1_PHY_LED_MAP(2)
+- },
+- .regmap_size = 2,
+- }, {
+- .name = "gpio45",
+- .regmap[0] = {
+- AIROHA_FUNC_MUX,
+- REG_GPIO_2ND_I2C_MODE,
+- GPIO_LAN2_LED1_MODE_MASK,
+- GPIO_LAN2_LED1_MODE_MASK
+- },
+- .regmap[1] = {
+- AIROHA_FUNC_MUX,
+- REG_LAN_LED1_MAPPING,
+- LAN2_LED_MAPPING_MASK,
+- LAN2_PHY_LED_MAP(2)
+- },
+- .regmap_size = 2,
+- }, {
+- .name = "gpio46",
+- .regmap[0] = {
+- AIROHA_FUNC_MUX,
+- REG_GPIO_2ND_I2C_MODE,
+- GPIO_LAN3_LED1_MODE_MASK,
+- GPIO_LAN3_LED1_MODE_MASK
+- },
+- .regmap[1] = {
+- AIROHA_FUNC_MUX,
+- REG_LAN_LED1_MAPPING,
+- LAN3_LED_MAPPING_MASK,
+- LAN3_PHY_LED_MAP(2)
+- },
+- .regmap_size = 2,
+- },
++ AIROHA_PINCTRL_PHY_LED("gpio33", GPIO_LAN0_LED1_MODE_MASK,
++ LAN0_LED_MAPPING_MASK, LAN0_PHY_LED_MAP(2)),
++ AIROHA_PINCTRL_PHY_LED("gpio34", GPIO_LAN1_LED1_MODE_MASK,
++ LAN1_LED_MAPPING_MASK, LAN1_PHY_LED_MAP(2)),
++ AIROHA_PINCTRL_PHY_LED("gpio35", GPIO_LAN2_LED1_MODE_MASK,
++ LAN2_LED_MAPPING_MASK, LAN2_PHY_LED_MAP(2)),
++ AIROHA_PINCTRL_PHY_LED("gpio42", GPIO_LAN3_LED1_MODE_MASK,
++ LAN3_LED_MAPPING_MASK, LAN3_PHY_LED_MAP(2)),
+ };
+
+ static const struct airoha_pinctrl_func_group phy4_led1_func_group[] = {
+- {
+- .name = "gpio43",
+- .regmap[0] = {
+- AIROHA_FUNC_MUX,
+- REG_GPIO_2ND_I2C_MODE,
+- GPIO_LAN0_LED1_MODE_MASK,
+- GPIO_LAN0_LED1_MODE_MASK
+- },
+- .regmap[1] = {
+- AIROHA_FUNC_MUX,
+- REG_LAN_LED1_MAPPING,
+- LAN0_LED_MAPPING_MASK,
+- LAN0_PHY_LED_MAP(3)
+- },
+- .regmap_size = 2,
+- }, {
+- .name = "gpio44",
+- .regmap[0] = {
+- AIROHA_FUNC_MUX,
+- REG_GPIO_2ND_I2C_MODE,
+- GPIO_LAN1_LED1_MODE_MASK,
+- GPIO_LAN1_LED1_MODE_MASK
+- },
+- .regmap[1] = {
+- AIROHA_FUNC_MUX,
+- REG_LAN_LED1_MAPPING,
+- LAN1_LED_MAPPING_MASK,
+- LAN1_PHY_LED_MAP(3)
+- },
+- .regmap_size = 2,
+- }, {
+- .name = "gpio45",
+- .regmap[0] = {
+- AIROHA_FUNC_MUX,
+- REG_GPIO_2ND_I2C_MODE,
+- GPIO_LAN2_LED1_MODE_MASK,
+- GPIO_LAN2_LED1_MODE_MASK
+- },
+- .regmap[1] = {
+- AIROHA_FUNC_MUX,
+- REG_LAN_LED1_MAPPING,
+- LAN2_LED_MAPPING_MASK,
+- LAN2_PHY_LED_MAP(3)
+- },
+- .regmap_size = 2,
+- }, {
+- .name = "gpio46",
+- .regmap[0] = {
+- AIROHA_FUNC_MUX,
+- REG_GPIO_2ND_I2C_MODE,
+- GPIO_LAN3_LED1_MODE_MASK,
+- GPIO_LAN3_LED1_MODE_MASK
+- },
+- .regmap[1] = {
+- AIROHA_FUNC_MUX,
+- REG_LAN_LED1_MAPPING,
+- LAN3_LED_MAPPING_MASK,
+- LAN3_PHY_LED_MAP(3)
+- },
+- .regmap_size = 2,
+- },
++ AIROHA_PINCTRL_PHY_LED("gpio33", GPIO_LAN0_LED1_MODE_MASK,
++ LAN0_LED_MAPPING_MASK, LAN0_PHY_LED_MAP(2)),
++ AIROHA_PINCTRL_PHY_LED("gpio34", GPIO_LAN1_LED1_MODE_MASK,
++ LAN1_LED_MAPPING_MASK, LAN1_PHY_LED_MAP(2)),
++ AIROHA_PINCTRL_PHY_LED("gpio35", GPIO_LAN2_LED1_MODE_MASK,
++ LAN2_LED_MAPPING_MASK, LAN2_PHY_LED_MAP(2)),
++ AIROHA_PINCTRL_PHY_LED("gpio42", GPIO_LAN3_LED1_MODE_MASK,
++ LAN3_LED_MAPPING_MASK, LAN3_PHY_LED_MAP(2)),
+ };
+
+ static const struct airoha_pinctrl_func en7581_pinctrl_funcs[] = {
--- /dev/null
+From 83c79d127c610063e1b86c3f7f8d5e0145ffe9c6 Mon Sep 17 00:00:00 2001
+From: Christian Marangi <ansuelsmth@gmail.com>
+Date: Sun, 25 May 2025 20:43:47 +0200
+Subject: [PATCH 4/5] pinctrl: airoha: convert PWM GPIO to macro
+
+The PWM GPIO struct definition follow the same pattern for every GPIO
+pin hence it can be converted to a macro.
+
+Create 2 macro one for normal mux and one for ext mux and convert all
+the entry to these new macro to reduce code size.
+
+Signed-off-by: Christian Marangi <ansuelsmth@gmail.com>
+---
+ drivers/pinctrl/mediatek/pinctrl-airoha.c | 465 ++++------------------
+ 1 file changed, 68 insertions(+), 397 deletions(-)
+
+--- a/drivers/pinctrl/mediatek/pinctrl-airoha.c
++++ b/drivers/pinctrl/mediatek/pinctrl-airoha.c
+@@ -1078,404 +1078,75 @@ static const struct airoha_pinctrl_func_
+ };
+
+ /* PWM */
++#define AIROHA_PINCTRL_PWM(gpio, mux_val) \
++ { \
++ .name = (gpio), \
++ .regmap[0] = { \
++ AIROHA_FUNC_PWM_MUX, \
++ REG_GPIO_FLASH_MODE_CFG, \
++ (mux_val), \
++ (mux_val) \
++ }, \
++ .regmap_size = 1, \
++ } \
++
++#define AIROHA_PINCTRL_PWM_EXT(gpio, mux_val) \
++ { \
++ .name = (gpio), \
++ .regmap[0] = { \
++ AIROHA_FUNC_PWM_EXT_MUX, \
++ REG_GPIO_FLASH_MODE_CFG_EXT, \
++ (mux_val), \
++ (mux_val) \
++ }, \
++ .regmap_size = 1, \
++ } \
++
+ static const struct airoha_pinctrl_func_group pwm_func_group[] = {
+- {
+- .name = "gpio0",
+- .regmap[0] = {
+- AIROHA_FUNC_PWM_MUX,
+- REG_GPIO_FLASH_MODE_CFG,
+- GPIO0_FLASH_MODE_CFG,
+- GPIO0_FLASH_MODE_CFG
+- },
+- .regmap_size = 1,
+- }, {
+- .name = "gpio1",
+- .regmap[0] = {
+- AIROHA_FUNC_PWM_MUX,
+- REG_GPIO_FLASH_MODE_CFG,
+- GPIO1_FLASH_MODE_CFG,
+- GPIO1_FLASH_MODE_CFG
+- },
+- .regmap_size = 1,
+- }, {
+- .name = "gpio2",
+- .regmap[0] = {
+- AIROHA_FUNC_PWM_MUX,
+- REG_GPIO_FLASH_MODE_CFG,
+- GPIO2_FLASH_MODE_CFG,
+- GPIO2_FLASH_MODE_CFG
+- },
+- .regmap_size = 1,
+- }, {
+- .name = "gpio3",
+- .regmap[0] = {
+- AIROHA_FUNC_PWM_MUX,
+- REG_GPIO_FLASH_MODE_CFG,
+- GPIO3_FLASH_MODE_CFG,
+- GPIO3_FLASH_MODE_CFG
+- },
+- .regmap_size = 1,
+- }, {
+- .name = "gpio4",
+- .regmap[0] = {
+- AIROHA_FUNC_PWM_MUX,
+- REG_GPIO_FLASH_MODE_CFG,
+- GPIO4_FLASH_MODE_CFG,
+- GPIO4_FLASH_MODE_CFG
+- },
+- .regmap_size = 1,
+- }, {
+- .name = "gpio5",
+- .regmap[0] = {
+- AIROHA_FUNC_PWM_MUX,
+- REG_GPIO_FLASH_MODE_CFG,
+- GPIO5_FLASH_MODE_CFG,
+- GPIO5_FLASH_MODE_CFG
+- },
+- .regmap_size = 1,
+- }, {
+- .name = "gpio6",
+- .regmap[0] = {
+- AIROHA_FUNC_PWM_MUX,
+- REG_GPIO_FLASH_MODE_CFG,
+- GPIO6_FLASH_MODE_CFG,
+- GPIO6_FLASH_MODE_CFG
+- },
+- .regmap_size = 1,
+- }, {
+- .name = "gpio7",
+- .regmap[0] = {
+- AIROHA_FUNC_PWM_MUX,
+- REG_GPIO_FLASH_MODE_CFG,
+- GPIO7_FLASH_MODE_CFG,
+- GPIO7_FLASH_MODE_CFG
+- },
+- .regmap_size = 1,
+- }, {
+- .name = "gpio8",
+- .regmap[0] = {
+- AIROHA_FUNC_PWM_MUX,
+- REG_GPIO_FLASH_MODE_CFG,
+- GPIO8_FLASH_MODE_CFG,
+- GPIO8_FLASH_MODE_CFG
+- },
+- .regmap_size = 1,
+- }, {
+- .name = "gpio9",
+- .regmap[0] = {
+- AIROHA_FUNC_PWM_MUX,
+- REG_GPIO_FLASH_MODE_CFG,
+- GPIO9_FLASH_MODE_CFG,
+- GPIO9_FLASH_MODE_CFG
+- },
+- .regmap_size = 1,
+- }, {
+- .name = "gpio10",
+- .regmap[0] = {
+- AIROHA_FUNC_PWM_MUX,
+- REG_GPIO_FLASH_MODE_CFG,
+- GPIO10_FLASH_MODE_CFG,
+- GPIO10_FLASH_MODE_CFG
+- },
+- .regmap_size = 1,
+- }, {
+- .name = "gpio11",
+- .regmap[0] = {
+- AIROHA_FUNC_PWM_MUX,
+- REG_GPIO_FLASH_MODE_CFG,
+- GPIO11_FLASH_MODE_CFG,
+- GPIO11_FLASH_MODE_CFG
+- },
+- .regmap_size = 1,
+- }, {
+- .name = "gpio12",
+- .regmap[0] = {
+- AIROHA_FUNC_PWM_MUX,
+- REG_GPIO_FLASH_MODE_CFG,
+- GPIO12_FLASH_MODE_CFG,
+- GPIO12_FLASH_MODE_CFG
+- },
+- .regmap_size = 1,
+- }, {
+- .name = "gpio13",
+- .regmap[0] = {
+- AIROHA_FUNC_PWM_MUX,
+- REG_GPIO_FLASH_MODE_CFG,
+- GPIO13_FLASH_MODE_CFG,
+- GPIO13_FLASH_MODE_CFG
+- },
+- .regmap_size = 1,
+- }, {
+- .name = "gpio14",
+- .regmap[0] = {
+- AIROHA_FUNC_PWM_MUX,
+- REG_GPIO_FLASH_MODE_CFG,
+- GPIO14_FLASH_MODE_CFG,
+- GPIO14_FLASH_MODE_CFG
+- },
+- .regmap_size = 1,
+- }, {
+- .name = "gpio15",
+- .regmap[0] = {
+- AIROHA_FUNC_PWM_MUX,
+- REG_GPIO_FLASH_MODE_CFG,
+- GPIO15_FLASH_MODE_CFG,
+- GPIO15_FLASH_MODE_CFG
+- },
+- .regmap_size = 1,
+- }, {
+- .name = "gpio16",
+- .regmap[0] = {
+- AIROHA_FUNC_PWM_EXT_MUX,
+- REG_GPIO_FLASH_MODE_CFG_EXT,
+- GPIO16_FLASH_MODE_CFG,
+- GPIO16_FLASH_MODE_CFG
+- },
+- .regmap_size = 1,
+- }, {
+- .name = "gpio17",
+- .regmap[0] = {
+- AIROHA_FUNC_PWM_EXT_MUX,
+- REG_GPIO_FLASH_MODE_CFG_EXT,
+- GPIO17_FLASH_MODE_CFG,
+- GPIO17_FLASH_MODE_CFG
+- },
+- .regmap_size = 1,
+- }, {
+- .name = "gpio18",
+- .regmap[0] = {
+- AIROHA_FUNC_PWM_EXT_MUX,
+- REG_GPIO_FLASH_MODE_CFG_EXT,
+- GPIO18_FLASH_MODE_CFG,
+- GPIO18_FLASH_MODE_CFG
+- },
+- .regmap_size = 1,
+- }, {
+- .name = "gpio19",
+- .regmap[0] = {
+- AIROHA_FUNC_PWM_EXT_MUX,
+- REG_GPIO_FLASH_MODE_CFG_EXT,
+- GPIO19_FLASH_MODE_CFG,
+- GPIO19_FLASH_MODE_CFG
+- },
+- .regmap_size = 1,
+- }, {
+- .name = "gpio20",
+- .regmap[0] = {
+- AIROHA_FUNC_PWM_EXT_MUX,
+- REG_GPIO_FLASH_MODE_CFG_EXT,
+- GPIO20_FLASH_MODE_CFG,
+- GPIO20_FLASH_MODE_CFG
+- },
+- .regmap_size = 1,
+- }, {
+- .name = "gpio21",
+- .regmap[0] = {
+- AIROHA_FUNC_PWM_EXT_MUX,
+- REG_GPIO_FLASH_MODE_CFG_EXT,
+- GPIO21_FLASH_MODE_CFG,
+- GPIO21_FLASH_MODE_CFG
+- },
+- .regmap_size = 1,
+- }, {
+- .name = "gpio22",
+- .regmap[0] = {
+- AIROHA_FUNC_PWM_EXT_MUX,
+- REG_GPIO_FLASH_MODE_CFG_EXT,
+- GPIO22_FLASH_MODE_CFG,
+- GPIO22_FLASH_MODE_CFG
+- },
+- .regmap_size = 1,
+- }, {
+- .name = "gpio23",
+- .regmap[0] = {
+- AIROHA_FUNC_PWM_EXT_MUX,
+- REG_GPIO_FLASH_MODE_CFG_EXT,
+- GPIO23_FLASH_MODE_CFG,
+- GPIO23_FLASH_MODE_CFG
+- },
+- .regmap_size = 1,
+- }, {
+- .name = "gpio24",
+- .regmap[0] = {
+- AIROHA_FUNC_PWM_EXT_MUX,
+- REG_GPIO_FLASH_MODE_CFG_EXT,
+- GPIO24_FLASH_MODE_CFG,
+- GPIO24_FLASH_MODE_CFG
+- },
+- .regmap_size = 1,
+- }, {
+- .name = "gpio25",
+- .regmap[0] = {
+- AIROHA_FUNC_PWM_EXT_MUX,
+- REG_GPIO_FLASH_MODE_CFG_EXT,
+- GPIO25_FLASH_MODE_CFG,
+- GPIO25_FLASH_MODE_CFG
+- },
+- .regmap_size = 1,
+- }, {
+- .name = "gpio26",
+- .regmap[0] = {
+- AIROHA_FUNC_PWM_EXT_MUX,
+- REG_GPIO_FLASH_MODE_CFG_EXT,
+- GPIO26_FLASH_MODE_CFG,
+- GPIO26_FLASH_MODE_CFG
+- },
+- .regmap_size = 1,
+- }, {
+- .name = "gpio27",
+- .regmap[0] = {
+- AIROHA_FUNC_PWM_EXT_MUX,
+- REG_GPIO_FLASH_MODE_CFG_EXT,
+- GPIO27_FLASH_MODE_CFG,
+- GPIO27_FLASH_MODE_CFG
+- },
+- .regmap_size = 1,
+- }, {
+- .name = "gpio28",
+- .regmap[0] = {
+- AIROHA_FUNC_PWM_EXT_MUX,
+- REG_GPIO_FLASH_MODE_CFG_EXT,
+- GPIO28_FLASH_MODE_CFG,
+- GPIO28_FLASH_MODE_CFG
+- },
+- .regmap_size = 1,
+- }, {
+- .name = "gpio29",
+- .regmap[0] = {
+- AIROHA_FUNC_PWM_EXT_MUX,
+- REG_GPIO_FLASH_MODE_CFG_EXT,
+- GPIO29_FLASH_MODE_CFG,
+- GPIO29_FLASH_MODE_CFG
+- },
+- .regmap_size = 1,
+- }, {
+- .name = "gpio30",
+- .regmap[0] = {
+- AIROHA_FUNC_PWM_EXT_MUX,
+- REG_GPIO_FLASH_MODE_CFG_EXT,
+- GPIO30_FLASH_MODE_CFG,
+- GPIO30_FLASH_MODE_CFG
+- },
+- .regmap_size = 1,
+- }, {
+- .name = "gpio31",
+- .regmap[0] = {
+- AIROHA_FUNC_PWM_EXT_MUX,
+- REG_GPIO_FLASH_MODE_CFG_EXT,
+- GPIO31_FLASH_MODE_CFG,
+- GPIO31_FLASH_MODE_CFG
+- },
+- .regmap_size = 1,
+- }, {
+- .name = "gpio36",
+- .regmap[0] = {
+- AIROHA_FUNC_PWM_EXT_MUX,
+- REG_GPIO_FLASH_MODE_CFG_EXT,
+- GPIO36_FLASH_MODE_CFG,
+- GPIO36_FLASH_MODE_CFG
+- },
+- .regmap_size = 1,
+- }, {
+- .name = "gpio37",
+- .regmap[0] = {
+- AIROHA_FUNC_PWM_EXT_MUX,
+- REG_GPIO_FLASH_MODE_CFG_EXT,
+- GPIO37_FLASH_MODE_CFG,
+- GPIO37_FLASH_MODE_CFG
+- },
+- .regmap_size = 1,
+- }, {
+- .name = "gpio38",
+- .regmap[0] = {
+- AIROHA_FUNC_PWM_EXT_MUX,
+- REG_GPIO_FLASH_MODE_CFG_EXT,
+- GPIO38_FLASH_MODE_CFG,
+- GPIO38_FLASH_MODE_CFG
+- },
+- .regmap_size = 1,
+- }, {
+- .name = "gpio39",
+- .regmap[0] = {
+- AIROHA_FUNC_PWM_EXT_MUX,
+- REG_GPIO_FLASH_MODE_CFG_EXT,
+- GPIO39_FLASH_MODE_CFG,
+- GPIO39_FLASH_MODE_CFG
+- },
+- .regmap_size = 1,
+- }, {
+- .name = "gpio40",
+- .regmap[0] = {
+- AIROHA_FUNC_PWM_EXT_MUX,
+- REG_GPIO_FLASH_MODE_CFG_EXT,
+- GPIO40_FLASH_MODE_CFG,
+- GPIO40_FLASH_MODE_CFG
+- },
+- .regmap_size = 1,
+- }, {
+- .name = "gpio41",
+- .regmap[0] = {
+- AIROHA_FUNC_PWM_EXT_MUX,
+- REG_GPIO_FLASH_MODE_CFG_EXT,
+- GPIO41_FLASH_MODE_CFG,
+- GPIO41_FLASH_MODE_CFG
+- },
+- .regmap_size = 1,
+- }, {
+- .name = "gpio42",
+- .regmap[0] = {
+- AIROHA_FUNC_PWM_EXT_MUX,
+- REG_GPIO_FLASH_MODE_CFG_EXT,
+- GPIO42_FLASH_MODE_CFG,
+- GPIO42_FLASH_MODE_CFG
+- },
+- .regmap_size = 1,
+- }, {
+- .name = "gpio43",
+- .regmap[0] = {
+- AIROHA_FUNC_PWM_EXT_MUX,
+- REG_GPIO_FLASH_MODE_CFG_EXT,
+- GPIO43_FLASH_MODE_CFG,
+- GPIO43_FLASH_MODE_CFG
+- },
+- .regmap_size = 1,
+- }, {
+- .name = "gpio44",
+- .regmap[0] = {
+- AIROHA_FUNC_PWM_EXT_MUX,
+- REG_GPIO_FLASH_MODE_CFG_EXT,
+- GPIO44_FLASH_MODE_CFG,
+- GPIO44_FLASH_MODE_CFG
+- },
+- .regmap_size = 1,
+- }, {
+- .name = "gpio45",
+- .regmap[0] = {
+- AIROHA_FUNC_PWM_EXT_MUX,
+- REG_GPIO_FLASH_MODE_CFG_EXT,
+- GPIO45_FLASH_MODE_CFG,
+- GPIO45_FLASH_MODE_CFG
+- },
+- .regmap_size = 1,
+- }, {
+- .name = "gpio46",
+- .regmap[0] = {
+- AIROHA_FUNC_PWM_EXT_MUX,
+- REG_GPIO_FLASH_MODE_CFG_EXT,
+- GPIO46_FLASH_MODE_CFG,
+- GPIO46_FLASH_MODE_CFG
+- },
+- .regmap_size = 1,
+- }, {
+- .name = "gpio47",
+- .regmap[0] = {
+- AIROHA_FUNC_PWM_EXT_MUX,
+- REG_GPIO_FLASH_MODE_CFG_EXT,
+- GPIO47_FLASH_MODE_CFG,
+- GPIO47_FLASH_MODE_CFG
+- },
+- .regmap_size = 1,
+- },
++ AIROHA_PINCTRL_PWM("gpio0", GPIO0_FLASH_MODE_CFG),
++ AIROHA_PINCTRL_PWM("gpio1", GPIO1_FLASH_MODE_CFG),
++ AIROHA_PINCTRL_PWM("gpio2", GPIO2_FLASH_MODE_CFG),
++ AIROHA_PINCTRL_PWM("gpio3", GPIO3_FLASH_MODE_CFG),
++ AIROHA_PINCTRL_PWM("gpio4", GPIO4_FLASH_MODE_CFG),
++ AIROHA_PINCTRL_PWM("gpio5", GPIO5_FLASH_MODE_CFG),
++ AIROHA_PINCTRL_PWM("gpio6", GPIO6_FLASH_MODE_CFG),
++ AIROHA_PINCTRL_PWM("gpio7", GPIO7_FLASH_MODE_CFG),
++ AIROHA_PINCTRL_PWM("gpio8", GPIO8_FLASH_MODE_CFG),
++ AIROHA_PINCTRL_PWM("gpio9", GPIO9_FLASH_MODE_CFG),
++ AIROHA_PINCTRL_PWM("gpio10", GPIO10_FLASH_MODE_CFG),
++ AIROHA_PINCTRL_PWM("gpio11", GPIO11_FLASH_MODE_CFG),
++ AIROHA_PINCTRL_PWM("gpio12", GPIO12_FLASH_MODE_CFG),
++ AIROHA_PINCTRL_PWM("gpio13", GPIO13_FLASH_MODE_CFG),
++ AIROHA_PINCTRL_PWM("gpio14", GPIO14_FLASH_MODE_CFG),
++ AIROHA_PINCTRL_PWM("gpio15", GPIO15_FLASH_MODE_CFG),
++ AIROHA_PINCTRL_PWM_EXT("gpio16", GPIO16_FLASH_MODE_CFG),
++ AIROHA_PINCTRL_PWM_EXT("gpio17", GPIO17_FLASH_MODE_CFG),
++ AIROHA_PINCTRL_PWM_EXT("gpio18", GPIO18_FLASH_MODE_CFG),
++ AIROHA_PINCTRL_PWM_EXT("gpio19", GPIO19_FLASH_MODE_CFG),
++ AIROHA_PINCTRL_PWM_EXT("gpio20", GPIO20_FLASH_MODE_CFG),
++ AIROHA_PINCTRL_PWM_EXT("gpio21", GPIO21_FLASH_MODE_CFG),
++ AIROHA_PINCTRL_PWM_EXT("gpio22", GPIO22_FLASH_MODE_CFG),
++ AIROHA_PINCTRL_PWM_EXT("gpio23", GPIO23_FLASH_MODE_CFG),
++ AIROHA_PINCTRL_PWM_EXT("gpio24", GPIO24_FLASH_MODE_CFG),
++ AIROHA_PINCTRL_PWM_EXT("gpio25", GPIO25_FLASH_MODE_CFG),
++ AIROHA_PINCTRL_PWM_EXT("gpio26", GPIO26_FLASH_MODE_CFG),
++ AIROHA_PINCTRL_PWM_EXT("gpio27", GPIO27_FLASH_MODE_CFG),
++ AIROHA_PINCTRL_PWM_EXT("gpio28", GPIO28_FLASH_MODE_CFG),
++ AIROHA_PINCTRL_PWM_EXT("gpio29", GPIO29_FLASH_MODE_CFG),
++ AIROHA_PINCTRL_PWM_EXT("gpio30", GPIO30_FLASH_MODE_CFG),
++ AIROHA_PINCTRL_PWM_EXT("gpio31", GPIO31_FLASH_MODE_CFG),
++ AIROHA_PINCTRL_PWM_EXT("gpio36", GPIO36_FLASH_MODE_CFG),
++ AIROHA_PINCTRL_PWM_EXT("gpio37", GPIO37_FLASH_MODE_CFG),
++ AIROHA_PINCTRL_PWM_EXT("gpio38", GPIO38_FLASH_MODE_CFG),
++ AIROHA_PINCTRL_PWM_EXT("gpio39", GPIO39_FLASH_MODE_CFG),
++ AIROHA_PINCTRL_PWM_EXT("gpio40", GPIO40_FLASH_MODE_CFG),
++ AIROHA_PINCTRL_PWM_EXT("gpio41", GPIO41_FLASH_MODE_CFG),
++ AIROHA_PINCTRL_PWM_EXT("gpio42", GPIO42_FLASH_MODE_CFG),
++ AIROHA_PINCTRL_PWM_EXT("gpio43", GPIO43_FLASH_MODE_CFG),
++ AIROHA_PINCTRL_PWM_EXT("gpio44", GPIO44_FLASH_MODE_CFG),
++ AIROHA_PINCTRL_PWM_EXT("gpio45", GPIO45_FLASH_MODE_CFG),
++ AIROHA_PINCTRL_PWM_EXT("gpio46", GPIO46_FLASH_MODE_CFG),
++ AIROHA_PINCTRL_PWM_EXT("gpio47", GPIO47_FLASH_MODE_CFG),
+ };
+
+ #define AIROHA_PINCTRL_PHY_LED(gpio, mux_val, map_mask, map_val) \
--- /dev/null
+From cc92581b44cc3a6821c540ddbe27d4c009a7d312 Mon Sep 17 00:00:00 2001
+From: Christian Marangi <ansuelsmth@gmail.com>
+Date: Sun, 25 May 2025 21:32:25 +0200
+Subject: [PATCH 5/5] pinctrl: airoha: add support for Airoha AN7583 PINs
+
+Add all the required entry to add suppot for Airoha AN7583 PINs.
+
+Where possible the same function group are used from Airoha EN7581 to
+reduce code duplication.
+
+Signed-off-by: Christian Marangi <ansuelsmth@gmail.com>
+---
+ drivers/pinctrl/mediatek/pinctrl-airoha.c | 733 ++++++++++++++++++++++
+ 1 file changed, 733 insertions(+)
+
+--- a/drivers/pinctrl/mediatek/pinctrl-airoha.c
++++ b/drivers/pinctrl/mediatek/pinctrl-airoha.c
+@@ -75,6 +75,7 @@
+ #define GPIO_PCM_SPI_CS3_MODE_MASK BIT(20)
+ #define GPIO_PCM_SPI_CS2_MODE_P156_MASK BIT(19)
+ #define GPIO_PCM_SPI_CS2_MODE_P128_MASK BIT(18)
++#define AN7583_GPIO_PCM_SPI_CS2_MODE_MASK BIT(18)
+ #define GPIO_PCM_SPI_CS1_MODE_MASK BIT(17)
+ #define GPIO_PCM_SPI_MODE_MASK BIT(16)
+ #define GPIO_PCM2_MODE_MASK BIT(13)
+@@ -132,6 +133,8 @@
+
+ /* CONF */
+ #define REG_I2C_SDA_E2 0x001c
++#define AN7583_I2C1_SCL_E2_MASK BIT(16)
++#define AN7583_I2C1_SDA_E2_MASK BIT(15)
+ #define SPI_MISO_E2_MASK BIT(14)
+ #define SPI_MOSI_E2_MASK BIT(13)
+ #define SPI_CLK_E2_MASK BIT(12)
+@@ -139,12 +142,16 @@
+ #define PCIE2_RESET_E2_MASK BIT(10)
+ #define PCIE1_RESET_E2_MASK BIT(9)
+ #define PCIE0_RESET_E2_MASK BIT(8)
++#define AN7583_MDIO_0_E2_MASK BIT(5)
++#define AN7583_MDC_0_E2_MASK BIT(4)
+ #define UART1_RXD_E2_MASK BIT(3)
+ #define UART1_TXD_E2_MASK BIT(2)
+ #define I2C_SCL_E2_MASK BIT(1)
+ #define I2C_SDA_E2_MASK BIT(0)
+
+ #define REG_I2C_SDA_E4 0x0020
++#define AN7583_I2C1_SCL_E4_MASK BIT(16)
++#define AN7583_I2C1_SDA_E4_MASK BIT(15)
+ #define SPI_MISO_E4_MASK BIT(14)
+ #define SPI_MOSI_E4_MASK BIT(13)
+ #define SPI_CLK_E4_MASK BIT(12)
+@@ -152,6 +159,8 @@
+ #define PCIE2_RESET_E4_MASK BIT(10)
+ #define PCIE1_RESET_E4_MASK BIT(9)
+ #define PCIE0_RESET_E4_MASK BIT(8)
++#define AN7583_MDIO_0_E4_MASK BIT(5)
++#define AN7583_MDC_0_E4_MASK BIT(4)
+ #define UART1_RXD_E4_MASK BIT(3)
+ #define UART1_TXD_E4_MASK BIT(2)
+ #define I2C_SCL_E4_MASK BIT(1)
+@@ -163,6 +172,8 @@
+ #define REG_GPIO_H_E4 0x0030
+
+ #define REG_I2C_SDA_PU 0x0044
++#define AN7583_I2C1_SCL_PU_MASK BIT(16)
++#define AN7583_I2C1_SDA_PU_MASK BIT(15)
+ #define SPI_MISO_PU_MASK BIT(14)
+ #define SPI_MOSI_PU_MASK BIT(13)
+ #define SPI_CLK_PU_MASK BIT(12)
+@@ -170,12 +181,16 @@
+ #define PCIE2_RESET_PU_MASK BIT(10)
+ #define PCIE1_RESET_PU_MASK BIT(9)
+ #define PCIE0_RESET_PU_MASK BIT(8)
++#define AN7583_MDIO_0_PU_MASK BIT(5)
++#define AN7583_MDC_0_PU_MASK BIT(4)
+ #define UART1_RXD_PU_MASK BIT(3)
+ #define UART1_TXD_PU_MASK BIT(2)
+ #define I2C_SCL_PU_MASK BIT(1)
+ #define I2C_SDA_PU_MASK BIT(0)
+
+ #define REG_I2C_SDA_PD 0x0048
++#define AN7583_I2C1_SDA_PD_MASK BIT(16)
++#define AN7583_I2C1_SCL_PD_MASK BIT(15)
+ #define SPI_MISO_PD_MASK BIT(14)
+ #define SPI_MOSI_PD_MASK BIT(13)
+ #define SPI_CLK_PD_MASK BIT(12)
+@@ -183,6 +198,8 @@
+ #define PCIE2_RESET_PD_MASK BIT(10)
+ #define PCIE1_RESET_PD_MASK BIT(9)
+ #define PCIE0_RESET_PD_MASK BIT(8)
++#define AN7583_MDIO_0_PD_MASK BIT(5)
++#define AN7583_MDC_0_PD_MASK BIT(4)
+ #define UART1_RXD_PD_MASK BIT(3)
+ #define UART1_TXD_PD_MASK BIT(2)
+ #define I2C_SCL_PD_MASK BIT(1)
+@@ -630,10 +647,223 @@ static const struct pingroup en7581_pinc
+ PINCTRL_PIN_GROUP("pcie_reset2", en7581_pcie_reset2),
+ };
+
++static struct pinctrl_pin_desc an7583_pinctrl_pins[] = {
++ PINCTRL_PIN(2, "gpio0"),
++ PINCTRL_PIN(3, "gpio1"),
++ PINCTRL_PIN(4, "gpio2"),
++ PINCTRL_PIN(5, "gpio3"),
++ PINCTRL_PIN(6, "gpio4"),
++ PINCTRL_PIN(7, "gpio5"),
++ PINCTRL_PIN(8, "gpio6"),
++ PINCTRL_PIN(9, "gpio7"),
++ PINCTRL_PIN(10, "gpio8"),
++ PINCTRL_PIN(11, "gpio9"),
++ PINCTRL_PIN(12, "gpio10"),
++ PINCTRL_PIN(13, "gpio11"),
++ PINCTRL_PIN(14, "gpio12"),
++ PINCTRL_PIN(15, "gpio13"),
++ PINCTRL_PIN(16, "gpio14"),
++ PINCTRL_PIN(17, "gpio15"),
++ PINCTRL_PIN(18, "gpio16"),
++ PINCTRL_PIN(19, "gpio17"),
++ PINCTRL_PIN(20, "gpio18"),
++ PINCTRL_PIN(21, "gpio19"),
++ PINCTRL_PIN(22, "gpio20"),
++ PINCTRL_PIN(23, "gpio21"),
++ PINCTRL_PIN(24, "gpio22"),
++ PINCTRL_PIN(25, "gpio23"),
++ PINCTRL_PIN(26, "gpio24"),
++ PINCTRL_PIN(27, "gpio25"),
++ PINCTRL_PIN(28, "gpio26"),
++ PINCTRL_PIN(29, "gpio27"),
++ PINCTRL_PIN(30, "gpio28"),
++ PINCTRL_PIN(31, "gpio29"),
++ PINCTRL_PIN(32, "gpio30"),
++ PINCTRL_PIN(33, "gpio31"),
++ PINCTRL_PIN(34, "gpio32"),
++ PINCTRL_PIN(35, "gpio33"),
++ PINCTRL_PIN(36, "gpio34"),
++ PINCTRL_PIN(37, "gpio35"),
++ PINCTRL_PIN(38, "gpio36"),
++ PINCTRL_PIN(39, "gpio37"),
++ PINCTRL_PIN(40, "gpio38"),
++ PINCTRL_PIN(41, "i2c0_scl"),
++ PINCTRL_PIN(42, "i2c0_sda"),
++ PINCTRL_PIN(43, "i2c1_scl"),
++ PINCTRL_PIN(44, "i2c1_sda"),
++ PINCTRL_PIN(45, "spi_clk"),
++ PINCTRL_PIN(46, "spi_cs"),
++ PINCTRL_PIN(47, "spi_mosi"),
++ PINCTRL_PIN(48, "spi_miso"),
++ PINCTRL_PIN(49, "uart_txd"),
++ PINCTRL_PIN(50, "uart_rxd"),
++ PINCTRL_PIN(51, "pcie_reset0"),
++ PINCTRL_PIN(52, "pcie_reset1"),
++ PINCTRL_PIN(53, "mdc_0"),
++ PINCTRL_PIN(54, "mdio_0"),
++};
++
++static const int an7583_pon_pins[] = { 15, 16, 17, 18, 19, 20 };
++static const int an7583_pon_tod_1pps_pins[] = { 32 };
++static const int an7583_gsw_tod_1pps_pins[] = { 32 };
++static const int an7583_sipo_pins[] = { 34, 35 };
++static const int an7583_sipo_rclk_pins[] = { 34, 35, 33 };
++static const int an7583_mdio_pins[] = { 43, 44 };
++static const int an7583_uart2_pins[] = { 34, 35 };
++static const int an7583_uart2_cts_rts_pins[] = { 32, 33 };
++static const int an7583_hsuart_pins[] = { 30, 31 };
++static const int an7583_hsuart_cts_rts_pins[] = { 28, 29 };
++static const int an7583_npu_uart_pins[] = { 7, 8 };
++static const int an7583_uart4_pins[] = { 7, 8 };
++static const int an7583_uart5_pins[] = { 23, 24 };
++static const int an7583_i2c0_pins[] = { 41, 42 };
++static const int an7583_i2c1_pins[] = { 43, 44 };
++static const int an7583_jtag_udi_pins[] = { 23, 24, 22, 25, 26 };
++static const int an7583_jtag_dfd_pins[] = { 23, 24, 22, 25, 26 };
++static const int an7583_pcm1_pins[] = { 10, 11, 12, 13, 14 };
++static const int an7583_pcm2_pins[] = { 28, 29, 30, 31, 24 };
++static const int an7583_spi_pins[] = { 28, 29, 30, 31 };
++static const int an7583_spi_quad_pins[] = { 25, 26 };
++static const int an7583_spi_cs1_pins[] = { 27 };
++static const int an7583_pcm_spi_pins[] = { 28, 29, 30, 31, 10, 11, 12, 13 };
++static const int an7583_pcm_spi_rst_pins[] = { 14 };
++static const int an7583_pcm_spi_cs1_pins[] = { 24 };
++static const int an7583_emmc_pins[] = { 7, 8, 9, 22, 23, 24, 25, 26, 45, 46, 47 };
++static const int an7583_pnand_pins[] = { 7, 8, 9, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 45, 46, 47, 48 };
++static const int an7583_gpio0_pins[] = { 2 };
++static const int an7583_gpio1_pins[] = { 3 };
++static const int an7583_gpio2_pins[] = { 4 };
++static const int an7583_gpio3_pins[] = { 5 };
++static const int an7583_gpio4_pins[] = { 6 };
++static const int an7583_gpio5_pins[] = { 7 };
++static const int an7583_gpio6_pins[] = { 8 };
++static const int an7583_gpio7_pins[] = { 9 };
++static const int an7583_gpio8_pins[] = { 10 };
++static const int an7583_gpio9_pins[] = { 11 };
++static const int an7583_gpio10_pins[] = { 12 };
++static const int an7583_gpio11_pins[] = { 13 };
++static const int an7583_gpio12_pins[] = { 14 };
++static const int an7583_gpio13_pins[] = { 15 };
++static const int an7583_gpio14_pins[] = { 16 };
++static const int an7583_gpio15_pins[] = { 17 };
++static const int an7583_gpio16_pins[] = { 18 };
++static const int an7583_gpio17_pins[] = { 19 };
++static const int an7583_gpio18_pins[] = { 20 };
++static const int an7583_gpio19_pins[] = { 21 };
++static const int an7583_gpio20_pins[] = { 22 };
++static const int an7583_gpio21_pins[] = { 24 };
++static const int an7583_gpio23_pins[] = { 25 };
++static const int an7583_gpio24_pins[] = { 26 };
++static const int an7583_gpio25_pins[] = { 27 };
++static const int an7583_gpio26_pins[] = { 28 };
++static const int an7583_gpio27_pins[] = { 29 };
++static const int an7583_gpio28_pins[] = { 30 };
++static const int an7583_gpio29_pins[] = { 31 };
++static const int an7583_gpio30_pins[] = { 32 };
++static const int an7583_gpio31_pins[] = { 33 };
++static const int an7583_gpio33_pins[] = { 35 };
++static const int an7583_gpio34_pins[] = { 36 };
++static const int an7583_gpio35_pins[] = { 37 };
++static const int an7583_gpio36_pins[] = { 38 };
++static const int an7583_gpio37_pins[] = { 39 };
++static const int an7583_gpio38_pins[] = { 40 };
++static const int an7583_gpio39_pins[] = { 41 };
++static const int an7583_gpio40_pins[] = { 42 };
++static const int an7583_gpio41_pins[] = { 43 };
++static const int an7583_gpio42_pins[] = { 44 };
++static const int an7583_gpio43_pins[] = { 45 };
++static const int an7583_gpio44_pins[] = { 46 };
++static const int an7583_gpio45_pins[] = { 47 };
++static const int an7583_gpio46_pins[] = { 48 };
++static const int an7583_gpio47_pins[] = { 49 };
++static const int an7583_gpio48_pins[] = { 50 };
++static const int an7583_pcie_reset0_pins[] = { 51 };
++static const int an7583_pcie_reset1_pins[] = { 52 };
++
++static const struct pingroup an7583_pinctrl_groups[] = {
++ PINCTRL_PIN_GROUP("pon", an7583_pon),
++ PINCTRL_PIN_GROUP("pon_tod_1pps", an7583_pon_tod_1pps),
++ PINCTRL_PIN_GROUP("gsw_tod_1pps", an7583_gsw_tod_1pps),
++ PINCTRL_PIN_GROUP("sipo", an7583_sipo),
++ PINCTRL_PIN_GROUP("sipo_rclk", an7583_sipo_rclk),
++ PINCTRL_PIN_GROUP("mdio", an7583_mdio),
++ PINCTRL_PIN_GROUP("uart2", an7583_uart2),
++ PINCTRL_PIN_GROUP("uart2_cts_rts", an7583_uart2_cts_rts),
++ PINCTRL_PIN_GROUP("hsuart", an7583_hsuart),
++ PINCTRL_PIN_GROUP("hsuart_cts_rts", an7583_hsuart_cts_rts),
++ PINCTRL_PIN_GROUP("npu_uart", an7583_npu_uart),
++ PINCTRL_PIN_GROUP("uart4", an7583_uart4),
++ PINCTRL_PIN_GROUP("uart5", an7583_uart5),
++ PINCTRL_PIN_GROUP("i2c0", an7583_i2c0),
++ PINCTRL_PIN_GROUP("i2c1", an7583_i2c1),
++ PINCTRL_PIN_GROUP("jtag_udi", an7583_jtag_udi),
++ PINCTRL_PIN_GROUP("jtag_dfd", an7583_jtag_dfd),
++ PINCTRL_PIN_GROUP("pcm1", an7583_pcm1),
++ PINCTRL_PIN_GROUP("pcm2", an7583_pcm2),
++ PINCTRL_PIN_GROUP("spi", an7583_spi),
++ PINCTRL_PIN_GROUP("spi_quad", an7583_spi_quad),
++ PINCTRL_PIN_GROUP("spi_cs1", an7583_spi_cs1),
++ PINCTRL_PIN_GROUP("pcm_spi", an7583_pcm_spi),
++ PINCTRL_PIN_GROUP("pcm_spi_rst", an7583_pcm_spi_rst),
++ PINCTRL_PIN_GROUP("pcm_spi_cs1", an7583_pcm_spi_cs1),
++ PINCTRL_PIN_GROUP("emmc", an7583_emmc),
++ PINCTRL_PIN_GROUP("pnand", an7583_pnand),
++ PINCTRL_PIN_GROUP("gpio0", an7583_gpio0),
++ PINCTRL_PIN_GROUP("gpio1", an7583_gpio1),
++ PINCTRL_PIN_GROUP("gpio2", an7583_gpio2),
++ PINCTRL_PIN_GROUP("gpio3", an7583_gpio3),
++ PINCTRL_PIN_GROUP("gpio4", an7583_gpio4),
++ PINCTRL_PIN_GROUP("gpio5", an7583_gpio5),
++ PINCTRL_PIN_GROUP("gpio6", an7583_gpio6),
++ PINCTRL_PIN_GROUP("gpio7", an7583_gpio7),
++ PINCTRL_PIN_GROUP("gpio8", an7583_gpio8),
++ PINCTRL_PIN_GROUP("gpio9", an7583_gpio9),
++ PINCTRL_PIN_GROUP("gpio10", an7583_gpio10),
++ PINCTRL_PIN_GROUP("gpio11", an7583_gpio11),
++ PINCTRL_PIN_GROUP("gpio12", an7583_gpio12),
++ PINCTRL_PIN_GROUP("gpio13", an7583_gpio13),
++ PINCTRL_PIN_GROUP("gpio14", an7583_gpio14),
++ PINCTRL_PIN_GROUP("gpio15", an7583_gpio15),
++ PINCTRL_PIN_GROUP("gpio16", an7583_gpio16),
++ PINCTRL_PIN_GROUP("gpio17", an7583_gpio17),
++ PINCTRL_PIN_GROUP("gpio18", an7583_gpio18),
++ PINCTRL_PIN_GROUP("gpio19", an7583_gpio19),
++ PINCTRL_PIN_GROUP("gpio20", an7583_gpio20),
++ PINCTRL_PIN_GROUP("gpio21", an7583_gpio21),
++ PINCTRL_PIN_GROUP("gpio23", an7583_gpio23),
++ PINCTRL_PIN_GROUP("gpio24", an7583_gpio24),
++ PINCTRL_PIN_GROUP("gpio25", an7583_gpio25),
++ PINCTRL_PIN_GROUP("gpio26", an7583_gpio26),
++ PINCTRL_PIN_GROUP("gpio27", an7583_gpio27),
++ PINCTRL_PIN_GROUP("gpio28", an7583_gpio28),
++ PINCTRL_PIN_GROUP("gpio29", an7583_gpio29),
++ PINCTRL_PIN_GROUP("gpio30", an7583_gpio30),
++ PINCTRL_PIN_GROUP("gpio31", an7583_gpio31),
++ PINCTRL_PIN_GROUP("gpio33", an7583_gpio33),
++ PINCTRL_PIN_GROUP("gpio34", an7583_gpio34),
++ PINCTRL_PIN_GROUP("gpio35", an7583_gpio35),
++ PINCTRL_PIN_GROUP("gpio36", an7583_gpio36),
++ PINCTRL_PIN_GROUP("gpio37", an7583_gpio37),
++ PINCTRL_PIN_GROUP("gpio38", an7583_gpio38),
++ PINCTRL_PIN_GROUP("gpio39", an7583_gpio39),
++ PINCTRL_PIN_GROUP("gpio40", an7583_gpio40),
++ PINCTRL_PIN_GROUP("gpio41", an7583_gpio41),
++ PINCTRL_PIN_GROUP("gpio42", an7583_gpio42),
++ PINCTRL_PIN_GROUP("gpio43", an7583_gpio43),
++ PINCTRL_PIN_GROUP("gpio44", an7583_gpio44),
++ PINCTRL_PIN_GROUP("gpio45", an7583_gpio45),
++ PINCTRL_PIN_GROUP("gpio46", an7583_gpio46),
++ PINCTRL_PIN_GROUP("gpio47", an7583_gpio47),
++ PINCTRL_PIN_GROUP("gpio48", an7583_gpio48),
++ PINCTRL_PIN_GROUP("pcie_reset0", an7583_pcie_reset0),
++ PINCTRL_PIN_GROUP("pcie_reset1", an7583_pcie_reset1),
++};
++
+ static const char *const pon_groups[] = { "pon" };
+ static const char *const tod_1pps_groups[] = { "pon_tod_1pps", "gsw_tod_1pps" };
+ static const char *const sipo_groups[] = { "sipo", "sipo_rclk" };
+ static const char *const mdio_groups[] = { "mdio" };
++static const char *const an7583_mdio_groups[] = { "mdio" };
+ static const char *const uart_groups[] = { "uart2", "uart2_cts_rts", "hsuart",
+ "hsuart_cts_rts", "uart4",
+ "uart5" };
+@@ -646,11 +876,16 @@ static const char *const pcm_spi_groups[
+ "pcm_spi_cs2_p156",
+ "pcm_spi_cs2_p128",
+ "pcm_spi_cs3", "pcm_spi_cs4" };
++static const char *const an7583_pcm_spi_groups[] = { "pcm_spi", "pcm_spi_int",
++ "pcm_spi_rst", "pcm_spi_cs1",
++ "pcm_spi_cs2", "pcm_spi_cs3",
++ "pcm_spi_cs4" };
+ static const char *const i2s_groups[] = { "i2s" };
+ static const char *const emmc_groups[] = { "emmc" };
+ static const char *const pnand_groups[] = { "pnand" };
+ static const char *const pcie_reset_groups[] = { "pcie_reset0", "pcie_reset1",
+ "pcie_reset2" };
++static const char *const an7583_pcie_reset_groups[] = { "pcie_reset0", "pcie_reset1" };
+ static const char *const pwm_groups[] = { "gpio0", "gpio1",
+ "gpio2", "gpio3",
+ "gpio4", "gpio5",
+@@ -689,6 +924,22 @@ static const char *const phy3_led1_group
+ "gpio45", "gpio46" };
+ static const char *const phy4_led1_groups[] = { "gpio43", "gpio44",
+ "gpio45", "gpio46" };
++static const char *const an7583_phy1_led0_groups[] = { "gpio1", "gpio2",
++ "gpio3", "gpio4" };
++static const char *const an7583_phy2_led0_groups[] = { "gpio1", "gpio2",
++ "gpio3", "gpio4" };
++static const char *const an7583_phy3_led0_groups[] = { "gpio1", "gpio2",
++ "gpio3", "gpio4" };
++static const char *const an7583_phy4_led0_groups[] = { "gpio1", "gpio2",
++ "gpio3", "gpio4" };
++static const char *const an7583_phy1_led1_groups[] = { "gpio8", "gpio9",
++ "gpio10", "gpio11" };
++static const char *const an7583_phy2_led1_groups[] = { "gpio8", "gpio9",
++ "gpio10", "gpio11" };
++static const char *const an7583_phy3_led1_groups[] = { "gpio8", "gpio9",
++ "gpio10", "gpio11" };
++static const char *const an7583_phy4_led1_groups[] = { "gpio8", "gpio9",
++ "gpio10", "gpio11" };
+
+ static const struct airoha_pinctrl_func_group pon_func_group[] = {
+ {
+@@ -766,6 +1017,25 @@ static const struct airoha_pinctrl_func_
+ },
+ };
+
++static const struct airoha_pinctrl_func_group an7583_mdio_func_group[] = {
++ {
++ .name = "mdio",
++ .regmap[0] = {
++ AIROHA_FUNC_MUX,
++ REG_GPIO_PON_MODE,
++ GPIO_SGMII_MDIO_MODE_MASK,
++ GPIO_SGMII_MDIO_MODE_MASK
++ },
++ .regmap[1] = {
++ AIROHA_FUNC_MUX,
++ REG_GPIO_SPI_CS1_MODE,
++ GPIO_MDC_IO_MASTER_MODE_MODE,
++ GPIO_MDC_IO_MASTER_MODE_MODE
++ },
++ .regmap_size = 2,
++ },
++};
++
+ static const struct airoha_pinctrl_func_group uart_func_group[] = {
+ {
+ .name = "uart2",
+@@ -1007,6 +1277,73 @@ static const struct airoha_pinctrl_func_
+ },
+ };
+
++static const struct airoha_pinctrl_func_group an7583_pcm_spi_func_group[] = {
++ {
++ .name = "pcm_spi",
++ .regmap[0] = {
++ AIROHA_FUNC_MUX,
++ REG_GPIO_SPI_CS1_MODE,
++ GPIO_PCM_SPI_MODE_MASK,
++ GPIO_PCM_SPI_MODE_MASK
++ },
++ .regmap_size = 1,
++ }, {
++ .name = "pcm_spi_int",
++ .regmap[0] = {
++ AIROHA_FUNC_MUX,
++ REG_GPIO_SPI_CS1_MODE,
++ GPIO_PCM_INT_MODE_MASK,
++ GPIO_PCM_INT_MODE_MASK
++ },
++ .regmap_size = 1,
++ }, {
++ .name = "pcm_spi_rst",
++ .regmap[0] = {
++ AIROHA_FUNC_MUX,
++ REG_GPIO_SPI_CS1_MODE,
++ GPIO_PCM_RESET_MODE_MASK,
++ GPIO_PCM_RESET_MODE_MASK
++ },
++ .regmap_size = 1,
++ }, {
++ .name = "pcm_spi_cs1",
++ .regmap[0] = {
++ AIROHA_FUNC_MUX,
++ REG_GPIO_SPI_CS1_MODE,
++ GPIO_PCM_SPI_CS1_MODE_MASK,
++ GPIO_PCM_SPI_CS1_MODE_MASK
++ },
++ .regmap_size = 1,
++ }, {
++ .name = "pcm_spi_cs2",
++ .regmap[0] = {
++ AIROHA_FUNC_MUX,
++ REG_GPIO_SPI_CS1_MODE,
++ AN7583_GPIO_PCM_SPI_CS2_MODE_MASK,
++ AN7583_GPIO_PCM_SPI_CS2_MODE_MASK
++ },
++ .regmap_size = 1,
++ }, {
++ .name = "pcm_spi_cs3",
++ .regmap[0] = {
++ AIROHA_FUNC_MUX,
++ REG_GPIO_SPI_CS1_MODE,
++ GPIO_PCM_SPI_CS3_MODE_MASK,
++ GPIO_PCM_SPI_CS3_MODE_MASK
++ },
++ .regmap_size = 1,
++ }, {
++ .name = "pcm_spi_cs4",
++ .regmap[0] = {
++ AIROHA_FUNC_MUX,
++ REG_GPIO_SPI_CS1_MODE,
++ GPIO_PCM_SPI_CS4_MODE_MASK,
++ GPIO_PCM_SPI_CS4_MODE_MASK
++ },
++ .regmap_size = 1,
++ },
++};
++
+ static const struct airoha_pinctrl_func_group i2s_func_group[] = {
+ {
+ .name = "i2s",
+@@ -1077,6 +1414,28 @@ static const struct airoha_pinctrl_func_
+ },
+ };
+
++static const struct airoha_pinctrl_func_group an7583_pcie_reset_func_group[] = {
++ {
++ .name = "pcie_reset0",
++ .regmap[0] = {
++ AIROHA_FUNC_MUX,
++ REG_GPIO_PON_MODE,
++ GPIO_PCIE_RESET0_MASK,
++ GPIO_PCIE_RESET0_MASK
++ },
++ .regmap_size = 1,
++ }, {
++ .name = "pcie_reset1",
++ .regmap[0] = {
++ AIROHA_FUNC_MUX,
++ REG_GPIO_PON_MODE,
++ GPIO_PCIE_RESET1_MASK,
++ GPIO_PCIE_RESET1_MASK
++ },
++ .regmap_size = 1,
++ },
++};
++
+ /* PWM */
+ #define AIROHA_PINCTRL_PWM(gpio, mux_val) \
+ { \
+@@ -1255,6 +1614,94 @@ static const struct airoha_pinctrl_func_
+ LAN3_LED_MAPPING_MASK, LAN3_PHY_LED_MAP(2)),
+ };
+
++static const struct airoha_pinctrl_func_group an7583_phy1_led0_func_group[] = {
++ AIROHA_PINCTRL_PHY_LED("gpio1", GPIO_LAN0_LED0_MODE_MASK,
++ LAN0_LED_MAPPING_MASK, LAN0_PHY_LED_MAP(0)),
++ AIROHA_PINCTRL_PHY_LED("gpio2", GPIO_LAN1_LED0_MODE_MASK,
++ LAN1_LED_MAPPING_MASK, LAN1_PHY_LED_MAP(0)),
++ AIROHA_PINCTRL_PHY_LED("gpio3", GPIO_LAN2_LED0_MODE_MASK,
++ LAN2_LED_MAPPING_MASK, LAN2_PHY_LED_MAP(0)),
++ AIROHA_PINCTRL_PHY_LED("gpio4", GPIO_LAN3_LED0_MODE_MASK,
++ LAN3_LED_MAPPING_MASK, LAN3_PHY_LED_MAP(0)),
++};
++
++static const struct airoha_pinctrl_func_group an7583_phy2_led0_func_group[] = {
++ AIROHA_PINCTRL_PHY_LED("gpio1", GPIO_LAN0_LED0_MODE_MASK,
++ LAN0_LED_MAPPING_MASK, LAN0_PHY_LED_MAP(1)),
++ AIROHA_PINCTRL_PHY_LED("gpio2", GPIO_LAN1_LED0_MODE_MASK,
++ LAN1_LED_MAPPING_MASK, LAN1_PHY_LED_MAP(1)),
++ AIROHA_PINCTRL_PHY_LED("gpio3", GPIO_LAN2_LED0_MODE_MASK,
++ LAN2_LED_MAPPING_MASK, LAN2_PHY_LED_MAP(1)),
++ AIROHA_PINCTRL_PHY_LED("gpio4", GPIO_LAN3_LED0_MODE_MASK,
++ LAN3_LED_MAPPING_MASK, LAN3_PHY_LED_MAP(1)),
++};
++
++static const struct airoha_pinctrl_func_group an7583_phy3_led0_func_group[] = {
++ AIROHA_PINCTRL_PHY_LED("gpio1", GPIO_LAN0_LED0_MODE_MASK,
++ LAN0_LED_MAPPING_MASK, LAN0_PHY_LED_MAP(2)),
++ AIROHA_PINCTRL_PHY_LED("gpio2", GPIO_LAN1_LED0_MODE_MASK,
++ LAN1_LED_MAPPING_MASK, LAN1_PHY_LED_MAP(2)),
++ AIROHA_PINCTRL_PHY_LED("gpio3", GPIO_LAN2_LED0_MODE_MASK,
++ LAN2_LED_MAPPING_MASK, LAN2_PHY_LED_MAP(2)),
++ AIROHA_PINCTRL_PHY_LED("gpio4", GPIO_LAN3_LED0_MODE_MASK,
++ LAN3_LED_MAPPING_MASK, LAN3_PHY_LED_MAP(2)),
++};
++
++static const struct airoha_pinctrl_func_group an7583_phy4_led0_func_group[] = {
++ AIROHA_PINCTRL_PHY_LED("gpio1", GPIO_LAN0_LED0_MODE_MASK,
++ LAN0_LED_MAPPING_MASK, LAN0_PHY_LED_MAP(3)),
++ AIROHA_PINCTRL_PHY_LED("gpio2", GPIO_LAN1_LED0_MODE_MASK,
++ LAN1_LED_MAPPING_MASK, LAN1_PHY_LED_MAP(3)),
++ AIROHA_PINCTRL_PHY_LED("gpio3", GPIO_LAN2_LED0_MODE_MASK,
++ LAN2_LED_MAPPING_MASK, LAN2_PHY_LED_MAP(3)),
++ AIROHA_PINCTRL_PHY_LED("gpio4", GPIO_LAN3_LED0_MODE_MASK,
++ LAN3_LED_MAPPING_MASK, LAN3_PHY_LED_MAP(3)),
++};
++
++static const struct airoha_pinctrl_func_group an7583_phy1_led1_func_group[] = {
++ AIROHA_PINCTRL_PHY_LED("gpio8", GPIO_LAN0_LED1_MODE_MASK,
++ LAN0_LED_MAPPING_MASK, LAN0_PHY_LED_MAP(0)),
++ AIROHA_PINCTRL_PHY_LED("gpio9", GPIO_LAN1_LED1_MODE_MASK,
++ LAN1_LED_MAPPING_MASK, LAN1_PHY_LED_MAP(0)),
++ AIROHA_PINCTRL_PHY_LED("gpio10", GPIO_LAN2_LED1_MODE_MASK,
++ LAN2_LED_MAPPING_MASK, LAN2_PHY_LED_MAP(0)),
++ AIROHA_PINCTRL_PHY_LED("gpio1", GPIO_LAN3_LED1_MODE_MASK,
++ LAN3_LED_MAPPING_MASK, LAN3_PHY_LED_MAP(0)),
++};
++
++static const struct airoha_pinctrl_func_group an7583_phy2_led1_func_group[] = {
++ AIROHA_PINCTRL_PHY_LED("gpio8", GPIO_LAN0_LED1_MODE_MASK,
++ LAN0_LED_MAPPING_MASK, LAN0_PHY_LED_MAP(1)),
++ AIROHA_PINCTRL_PHY_LED("gpio9", GPIO_LAN1_LED1_MODE_MASK,
++ LAN1_LED_MAPPING_MASK, LAN1_PHY_LED_MAP(1)),
++ AIROHA_PINCTRL_PHY_LED("gpio10", GPIO_LAN2_LED1_MODE_MASK,
++ LAN2_LED_MAPPING_MASK, LAN2_PHY_LED_MAP(1)),
++ AIROHA_PINCTRL_PHY_LED("gpio11", GPIO_LAN3_LED1_MODE_MASK,
++ LAN3_LED_MAPPING_MASK, LAN3_PHY_LED_MAP(1)),
++};
++
++static const struct airoha_pinctrl_func_group an7583_phy3_led1_func_group[] = {
++ AIROHA_PINCTRL_PHY_LED("gpio8", GPIO_LAN0_LED1_MODE_MASK,
++ LAN0_LED_MAPPING_MASK, LAN0_PHY_LED_MAP(2)),
++ AIROHA_PINCTRL_PHY_LED("gpio9", GPIO_LAN1_LED1_MODE_MASK,
++ LAN1_LED_MAPPING_MASK, LAN1_PHY_LED_MAP(2)),
++ AIROHA_PINCTRL_PHY_LED("gpio10", GPIO_LAN2_LED1_MODE_MASK,
++ LAN2_LED_MAPPING_MASK, LAN2_PHY_LED_MAP(2)),
++ AIROHA_PINCTRL_PHY_LED("gpio11", GPIO_LAN3_LED1_MODE_MASK,
++ LAN3_LED_MAPPING_MASK, LAN3_PHY_LED_MAP(2)),
++};
++
++static const struct airoha_pinctrl_func_group an7583_phy4_led1_func_group[] = {
++ AIROHA_PINCTRL_PHY_LED("gpio8", GPIO_LAN0_LED1_MODE_MASK,
++ LAN0_LED_MAPPING_MASK, LAN0_PHY_LED_MAP(2)),
++ AIROHA_PINCTRL_PHY_LED("gpio9", GPIO_LAN1_LED1_MODE_MASK,
++ LAN1_LED_MAPPING_MASK, LAN1_PHY_LED_MAP(2)),
++ AIROHA_PINCTRL_PHY_LED("gpio10", GPIO_LAN2_LED1_MODE_MASK,
++ LAN2_LED_MAPPING_MASK, LAN2_PHY_LED_MAP(2)),
++ AIROHA_PINCTRL_PHY_LED("gpio11", GPIO_LAN3_LED1_MODE_MASK,
++ LAN3_LED_MAPPING_MASK, LAN3_PHY_LED_MAP(2)),
++};
++
+ static const struct airoha_pinctrl_func en7581_pinctrl_funcs[] = {
+ PINCTRL_FUNC_DESC("pon", pon),
+ PINCTRL_FUNC_DESC("tod_1pps", tod_1pps),
+@@ -1281,6 +1728,31 @@ static const struct airoha_pinctrl_func
+ PINCTRL_FUNC_DESC("phy4_led1", phy4_led1),
+ };
+
++static const struct airoha_pinctrl_func an7583_pinctrl_funcs[] = {
++ PINCTRL_FUNC_DESC("pon", pon),
++ PINCTRL_FUNC_DESC("tod_1pps", tod_1pps),
++ PINCTRL_FUNC_DESC("sipo", sipo),
++ PINCTRL_FUNC_DESC("mdio", an7583_mdio),
++ PINCTRL_FUNC_DESC("uart", uart),
++ PINCTRL_FUNC_DESC("i2c", i2c),
++ PINCTRL_FUNC_DESC("jtag", jtag),
++ PINCTRL_FUNC_DESC("pcm", pcm),
++ PINCTRL_FUNC_DESC("spi", spi),
++ PINCTRL_FUNC_DESC("pcm_spi", an7583_pcm_spi),
++ PINCTRL_FUNC_DESC("emmc", emmc),
++ PINCTRL_FUNC_DESC("pnand", pnand),
++ PINCTRL_FUNC_DESC("pcie_reset", an7583_pcie_reset),
++ PINCTRL_FUNC_DESC("pwm", pwm),
++ PINCTRL_FUNC_DESC("phy1_led0", an7583_phy1_led0),
++ PINCTRL_FUNC_DESC("phy2_led0", an7583_phy2_led0),
++ PINCTRL_FUNC_DESC("phy3_led0", an7583_phy3_led0),
++ PINCTRL_FUNC_DESC("phy4_led0", an7583_phy4_led0),
++ PINCTRL_FUNC_DESC("phy1_led1", an7583_phy1_led1),
++ PINCTRL_FUNC_DESC("phy2_led1", an7583_phy2_led1),
++ PINCTRL_FUNC_DESC("phy3_led1", an7583_phy3_led1),
++ PINCTRL_FUNC_DESC("phy4_led1", an7583_phy4_led1),
++};
++
+ static const struct airoha_pinctrl_conf en7581_pinctrl_pullup_conf[] = {
+ PINCTRL_CONF_DESC(0, REG_I2C_SDA_PU, UART1_TXD_PU_MASK),
+ PINCTRL_CONF_DESC(1, REG_I2C_SDA_PU, UART1_RXD_PU_MASK),
+@@ -1342,6 +1814,62 @@ static const struct airoha_pinctrl_conf
+ PINCTRL_CONF_DESC(63, REG_I2C_SDA_PU, PCIE2_RESET_PU_MASK),
+ };
+
++static const struct airoha_pinctrl_conf an7583_pinctrl_pullup_conf[] = {
++ PINCTRL_CONF_DESC(2, REG_GPIO_L_PU, BIT(0)),
++ PINCTRL_CONF_DESC(3, REG_GPIO_L_PU, BIT(1)),
++ PINCTRL_CONF_DESC(4, REG_GPIO_L_PU, BIT(2)),
++ PINCTRL_CONF_DESC(5, REG_GPIO_L_PU, BIT(3)),
++ PINCTRL_CONF_DESC(6, REG_GPIO_L_PU, BIT(4)),
++ PINCTRL_CONF_DESC(7, REG_GPIO_L_PU, BIT(5)),
++ PINCTRL_CONF_DESC(8, REG_GPIO_L_PU, BIT(6)),
++ PINCTRL_CONF_DESC(9, REG_GPIO_L_PU, BIT(7)),
++ PINCTRL_CONF_DESC(10, REG_GPIO_L_PU, BIT(8)),
++ PINCTRL_CONF_DESC(11, REG_GPIO_L_PU, BIT(9)),
++ PINCTRL_CONF_DESC(12, REG_GPIO_L_PU, BIT(10)),
++ PINCTRL_CONF_DESC(13, REG_GPIO_L_PU, BIT(11)),
++ PINCTRL_CONF_DESC(14, REG_GPIO_L_PU, BIT(12)),
++ PINCTRL_CONF_DESC(15, REG_GPIO_L_PU, BIT(13)),
++ PINCTRL_CONF_DESC(16, REG_GPIO_L_PU, BIT(14)),
++ PINCTRL_CONF_DESC(17, REG_GPIO_L_PU, BIT(15)),
++ PINCTRL_CONF_DESC(18, REG_GPIO_L_PU, BIT(16)),
++ PINCTRL_CONF_DESC(19, REG_GPIO_L_PU, BIT(17)),
++ PINCTRL_CONF_DESC(20, REG_GPIO_L_PU, BIT(18)),
++ PINCTRL_CONF_DESC(21, REG_GPIO_L_PU, BIT(18)),
++ PINCTRL_CONF_DESC(22, REG_GPIO_L_PU, BIT(20)),
++ PINCTRL_CONF_DESC(23, REG_GPIO_L_PU, BIT(21)),
++ PINCTRL_CONF_DESC(24, REG_GPIO_L_PU, BIT(22)),
++ PINCTRL_CONF_DESC(25, REG_GPIO_L_PU, BIT(23)),
++ PINCTRL_CONF_DESC(26, REG_GPIO_L_PU, BIT(24)),
++ PINCTRL_CONF_DESC(27, REG_GPIO_L_PU, BIT(25)),
++ PINCTRL_CONF_DESC(28, REG_GPIO_L_PU, BIT(26)),
++ PINCTRL_CONF_DESC(29, REG_GPIO_L_PU, BIT(27)),
++ PINCTRL_CONF_DESC(30, REG_GPIO_L_PU, BIT(28)),
++ PINCTRL_CONF_DESC(31, REG_GPIO_L_PU, BIT(29)),
++ PINCTRL_CONF_DESC(32, REG_GPIO_L_PU, BIT(30)),
++ PINCTRL_CONF_DESC(33, REG_GPIO_L_PU, BIT(31)),
++ PINCTRL_CONF_DESC(34, REG_GPIO_H_PU, BIT(0)),
++ PINCTRL_CONF_DESC(35, REG_GPIO_H_PU, BIT(1)),
++ PINCTRL_CONF_DESC(36, REG_GPIO_H_PU, BIT(2)),
++ PINCTRL_CONF_DESC(37, REG_GPIO_H_PU, BIT(3)),
++ PINCTRL_CONF_DESC(38, REG_GPIO_H_PU, BIT(4)),
++ PINCTRL_CONF_DESC(39, REG_GPIO_H_PU, BIT(5)),
++ PINCTRL_CONF_DESC(40, REG_GPIO_H_PU, BIT(6)),
++ PINCTRL_CONF_DESC(41, REG_I2C_SDA_PU, I2C_SCL_PU_MASK),
++ PINCTRL_CONF_DESC(42, REG_I2C_SDA_PU, I2C_SDA_PU_MASK),
++ PINCTRL_CONF_DESC(43, REG_I2C_SDA_PU, AN7583_I2C1_SCL_PU_MASK),
++ PINCTRL_CONF_DESC(44, REG_I2C_SDA_PU, AN7583_I2C1_SDA_PU_MASK),
++ PINCTRL_CONF_DESC(45, REG_I2C_SDA_PU, SPI_CLK_PU_MASK),
++ PINCTRL_CONF_DESC(46, REG_I2C_SDA_PU, SPI_CS0_PU_MASK),
++ PINCTRL_CONF_DESC(47, REG_I2C_SDA_PU, SPI_MOSI_PU_MASK),
++ PINCTRL_CONF_DESC(48, REG_I2C_SDA_PU, SPI_MISO_PU_MASK),
++ PINCTRL_CONF_DESC(49, REG_I2C_SDA_PU, UART1_TXD_PU_MASK),
++ PINCTRL_CONF_DESC(50, REG_I2C_SDA_PU, UART1_RXD_PU_MASK),
++ PINCTRL_CONF_DESC(51, REG_I2C_SDA_PU, PCIE0_RESET_PU_MASK),
++ PINCTRL_CONF_DESC(52, REG_I2C_SDA_PU, PCIE1_RESET_PU_MASK),
++ PINCTRL_CONF_DESC(53, REG_I2C_SDA_PU, AN7583_MDC_0_PU_MASK),
++ PINCTRL_CONF_DESC(54, REG_I2C_SDA_PU, AN7583_MDIO_0_PU_MASK),
++};
++
+ static const struct airoha_pinctrl_conf en7581_pinctrl_pulldown_conf[] = {
+ PINCTRL_CONF_DESC(0, REG_I2C_SDA_PD, UART1_TXD_PD_MASK),
+ PINCTRL_CONF_DESC(1, REG_I2C_SDA_PD, UART1_RXD_PD_MASK),
+@@ -1403,6 +1931,62 @@ static const struct airoha_pinctrl_conf
+ PINCTRL_CONF_DESC(63, REG_I2C_SDA_PD, PCIE2_RESET_PD_MASK),
+ };
+
++static const struct airoha_pinctrl_conf an7583_pinctrl_pulldown_conf[] = {
++ PINCTRL_CONF_DESC(2, REG_GPIO_L_PD, BIT(0)),
++ PINCTRL_CONF_DESC(3, REG_GPIO_L_PD, BIT(1)),
++ PINCTRL_CONF_DESC(4, REG_GPIO_L_PD, BIT(2)),
++ PINCTRL_CONF_DESC(5, REG_GPIO_L_PD, BIT(3)),
++ PINCTRL_CONF_DESC(6, REG_GPIO_L_PD, BIT(4)),
++ PINCTRL_CONF_DESC(7, REG_GPIO_L_PD, BIT(5)),
++ PINCTRL_CONF_DESC(8, REG_GPIO_L_PD, BIT(6)),
++ PINCTRL_CONF_DESC(9, REG_GPIO_L_PD, BIT(7)),
++ PINCTRL_CONF_DESC(10, REG_GPIO_L_PD, BIT(8)),
++ PINCTRL_CONF_DESC(11, REG_GPIO_L_PD, BIT(9)),
++ PINCTRL_CONF_DESC(12, REG_GPIO_L_PD, BIT(10)),
++ PINCTRL_CONF_DESC(13, REG_GPIO_L_PD, BIT(11)),
++ PINCTRL_CONF_DESC(14, REG_GPIO_L_PD, BIT(12)),
++ PINCTRL_CONF_DESC(15, REG_GPIO_L_PD, BIT(13)),
++ PINCTRL_CONF_DESC(16, REG_GPIO_L_PD, BIT(14)),
++ PINCTRL_CONF_DESC(17, REG_GPIO_L_PD, BIT(15)),
++ PINCTRL_CONF_DESC(18, REG_GPIO_L_PD, BIT(16)),
++ PINCTRL_CONF_DESC(19, REG_GPIO_L_PD, BIT(17)),
++ PINCTRL_CONF_DESC(20, REG_GPIO_L_PD, BIT(18)),
++ PINCTRL_CONF_DESC(21, REG_GPIO_L_PD, BIT(18)),
++ PINCTRL_CONF_DESC(22, REG_GPIO_L_PD, BIT(20)),
++ PINCTRL_CONF_DESC(23, REG_GPIO_L_PD, BIT(21)),
++ PINCTRL_CONF_DESC(24, REG_GPIO_L_PD, BIT(22)),
++ PINCTRL_CONF_DESC(25, REG_GPIO_L_PD, BIT(23)),
++ PINCTRL_CONF_DESC(26, REG_GPIO_L_PD, BIT(24)),
++ PINCTRL_CONF_DESC(27, REG_GPIO_L_PD, BIT(25)),
++ PINCTRL_CONF_DESC(28, REG_GPIO_L_PD, BIT(26)),
++ PINCTRL_CONF_DESC(29, REG_GPIO_L_PD, BIT(27)),
++ PINCTRL_CONF_DESC(30, REG_GPIO_L_PD, BIT(28)),
++ PINCTRL_CONF_DESC(31, REG_GPIO_L_PD, BIT(29)),
++ PINCTRL_CONF_DESC(32, REG_GPIO_L_PD, BIT(30)),
++ PINCTRL_CONF_DESC(33, REG_GPIO_L_PD, BIT(31)),
++ PINCTRL_CONF_DESC(34, REG_GPIO_H_PD, BIT(0)),
++ PINCTRL_CONF_DESC(35, REG_GPIO_H_PD, BIT(1)),
++ PINCTRL_CONF_DESC(36, REG_GPIO_H_PD, BIT(2)),
++ PINCTRL_CONF_DESC(37, REG_GPIO_H_PD, BIT(3)),
++ PINCTRL_CONF_DESC(38, REG_GPIO_H_PD, BIT(4)),
++ PINCTRL_CONF_DESC(39, REG_GPIO_H_PD, BIT(5)),
++ PINCTRL_CONF_DESC(40, REG_GPIO_H_PD, BIT(6)),
++ PINCTRL_CONF_DESC(41, REG_I2C_SDA_PD, I2C_SCL_PD_MASK),
++ PINCTRL_CONF_DESC(42, REG_I2C_SDA_PD, I2C_SDA_PD_MASK),
++ PINCTRL_CONF_DESC(43, REG_I2C_SDA_PD, AN7583_I2C1_SCL_PD_MASK),
++ PINCTRL_CONF_DESC(44, REG_I2C_SDA_PD, AN7583_I2C1_SDA_PD_MASK),
++ PINCTRL_CONF_DESC(45, REG_I2C_SDA_PD, SPI_CLK_PD_MASK),
++ PINCTRL_CONF_DESC(46, REG_I2C_SDA_PD, SPI_CS0_PD_MASK),
++ PINCTRL_CONF_DESC(47, REG_I2C_SDA_PD, SPI_MOSI_PD_MASK),
++ PINCTRL_CONF_DESC(48, REG_I2C_SDA_PD, SPI_MISO_PD_MASK),
++ PINCTRL_CONF_DESC(49, REG_I2C_SDA_PD, UART1_TXD_PD_MASK),
++ PINCTRL_CONF_DESC(50, REG_I2C_SDA_PD, UART1_RXD_PD_MASK),
++ PINCTRL_CONF_DESC(51, REG_I2C_SDA_PD, PCIE0_RESET_PD_MASK),
++ PINCTRL_CONF_DESC(52, REG_I2C_SDA_PD, PCIE1_RESET_PD_MASK),
++ PINCTRL_CONF_DESC(53, REG_I2C_SDA_PD, AN7583_MDC_0_PD_MASK),
++ PINCTRL_CONF_DESC(54, REG_I2C_SDA_PD, AN7583_MDIO_0_PD_MASK),
++};
++
+ static const struct airoha_pinctrl_conf en7581_pinctrl_drive_e2_conf[] = {
+ PINCTRL_CONF_DESC(0, REG_I2C_SDA_E2, UART1_TXD_E2_MASK),
+ PINCTRL_CONF_DESC(1, REG_I2C_SDA_E2, UART1_RXD_E2_MASK),
+@@ -1464,6 +2048,62 @@ static const struct airoha_pinctrl_conf
+ PINCTRL_CONF_DESC(63, REG_I2C_SDA_E2, PCIE2_RESET_E2_MASK),
+ };
+
++static const struct airoha_pinctrl_conf an7583_pinctrl_drive_e2_conf[] = {
++ PINCTRL_CONF_DESC(2, REG_GPIO_L_E2, BIT(0)),
++ PINCTRL_CONF_DESC(3, REG_GPIO_L_E2, BIT(1)),
++ PINCTRL_CONF_DESC(4, REG_GPIO_L_E2, BIT(2)),
++ PINCTRL_CONF_DESC(5, REG_GPIO_L_E2, BIT(3)),
++ PINCTRL_CONF_DESC(6, REG_GPIO_L_E2, BIT(4)),
++ PINCTRL_CONF_DESC(7, REG_GPIO_L_E2, BIT(5)),
++ PINCTRL_CONF_DESC(8, REG_GPIO_L_E2, BIT(6)),
++ PINCTRL_CONF_DESC(9, REG_GPIO_L_E2, BIT(7)),
++ PINCTRL_CONF_DESC(10, REG_GPIO_L_E2, BIT(8)),
++ PINCTRL_CONF_DESC(11, REG_GPIO_L_E2, BIT(9)),
++ PINCTRL_CONF_DESC(12, REG_GPIO_L_E2, BIT(10)),
++ PINCTRL_CONF_DESC(13, REG_GPIO_L_E2, BIT(11)),
++ PINCTRL_CONF_DESC(14, REG_GPIO_L_E2, BIT(12)),
++ PINCTRL_CONF_DESC(15, REG_GPIO_L_E2, BIT(13)),
++ PINCTRL_CONF_DESC(16, REG_GPIO_L_E2, BIT(14)),
++ PINCTRL_CONF_DESC(17, REG_GPIO_L_E2, BIT(15)),
++ PINCTRL_CONF_DESC(18, REG_GPIO_L_E2, BIT(16)),
++ PINCTRL_CONF_DESC(19, REG_GPIO_L_E2, BIT(17)),
++ PINCTRL_CONF_DESC(20, REG_GPIO_L_E2, BIT(18)),
++ PINCTRL_CONF_DESC(21, REG_GPIO_L_E2, BIT(18)),
++ PINCTRL_CONF_DESC(22, REG_GPIO_L_E2, BIT(20)),
++ PINCTRL_CONF_DESC(23, REG_GPIO_L_E2, BIT(21)),
++ PINCTRL_CONF_DESC(24, REG_GPIO_L_E2, BIT(22)),
++ PINCTRL_CONF_DESC(25, REG_GPIO_L_E2, BIT(23)),
++ PINCTRL_CONF_DESC(26, REG_GPIO_L_E2, BIT(24)),
++ PINCTRL_CONF_DESC(27, REG_GPIO_L_E2, BIT(25)),
++ PINCTRL_CONF_DESC(28, REG_GPIO_L_E2, BIT(26)),
++ PINCTRL_CONF_DESC(29, REG_GPIO_L_E2, BIT(27)),
++ PINCTRL_CONF_DESC(30, REG_GPIO_L_E2, BIT(28)),
++ PINCTRL_CONF_DESC(31, REG_GPIO_L_E2, BIT(29)),
++ PINCTRL_CONF_DESC(32, REG_GPIO_L_E2, BIT(30)),
++ PINCTRL_CONF_DESC(33, REG_GPIO_L_E2, BIT(31)),
++ PINCTRL_CONF_DESC(34, REG_GPIO_H_E2, BIT(0)),
++ PINCTRL_CONF_DESC(35, REG_GPIO_H_E2, BIT(1)),
++ PINCTRL_CONF_DESC(36, REG_GPIO_H_E2, BIT(2)),
++ PINCTRL_CONF_DESC(37, REG_GPIO_H_E2, BIT(3)),
++ PINCTRL_CONF_DESC(38, REG_GPIO_H_E2, BIT(4)),
++ PINCTRL_CONF_DESC(39, REG_GPIO_H_E2, BIT(5)),
++ PINCTRL_CONF_DESC(40, REG_GPIO_H_E2, BIT(6)),
++ PINCTRL_CONF_DESC(41, REG_I2C_SDA_E2, I2C_SCL_E2_MASK),
++ PINCTRL_CONF_DESC(42, REG_I2C_SDA_E2, I2C_SDA_E2_MASK),
++ PINCTRL_CONF_DESC(43, REG_I2C_SDA_E2, AN7583_I2C1_SCL_E2_MASK),
++ PINCTRL_CONF_DESC(44, REG_I2C_SDA_E2, AN7583_I2C1_SDA_E2_MASK),
++ PINCTRL_CONF_DESC(45, REG_I2C_SDA_E2, SPI_CLK_E2_MASK),
++ PINCTRL_CONF_DESC(46, REG_I2C_SDA_E2, SPI_CS0_E2_MASK),
++ PINCTRL_CONF_DESC(47, REG_I2C_SDA_E2, SPI_MOSI_E2_MASK),
++ PINCTRL_CONF_DESC(48, REG_I2C_SDA_E2, SPI_MISO_E2_MASK),
++ PINCTRL_CONF_DESC(49, REG_I2C_SDA_E2, UART1_TXD_E2_MASK),
++ PINCTRL_CONF_DESC(50, REG_I2C_SDA_E2, UART1_RXD_E2_MASK),
++ PINCTRL_CONF_DESC(51, REG_I2C_SDA_E2, PCIE0_RESET_E2_MASK),
++ PINCTRL_CONF_DESC(52, REG_I2C_SDA_E2, PCIE1_RESET_E2_MASK),
++ PINCTRL_CONF_DESC(53, REG_I2C_SDA_E2, AN7583_MDC_0_E2_MASK),
++ PINCTRL_CONF_DESC(54, REG_I2C_SDA_E2, AN7583_MDIO_0_E2_MASK),
++};
++
+ static const struct airoha_pinctrl_conf en7581_pinctrl_drive_e4_conf[] = {
+ PINCTRL_CONF_DESC(0, REG_I2C_SDA_E4, UART1_TXD_E4_MASK),
+ PINCTRL_CONF_DESC(1, REG_I2C_SDA_E4, UART1_RXD_E4_MASK),
+@@ -1525,12 +2165,73 @@ static const struct airoha_pinctrl_conf
+ PINCTRL_CONF_DESC(63, REG_I2C_SDA_E4, PCIE2_RESET_E4_MASK),
+ };
+
++static const struct airoha_pinctrl_conf an7583_pinctrl_drive_e4_conf[] = {
++ PINCTRL_CONF_DESC(2, REG_GPIO_L_E4, BIT(0)),
++ PINCTRL_CONF_DESC(3, REG_GPIO_L_E4, BIT(1)),
++ PINCTRL_CONF_DESC(4, REG_GPIO_L_E4, BIT(2)),
++ PINCTRL_CONF_DESC(5, REG_GPIO_L_E4, BIT(3)),
++ PINCTRL_CONF_DESC(6, REG_GPIO_L_E4, BIT(4)),
++ PINCTRL_CONF_DESC(7, REG_GPIO_L_E4, BIT(5)),
++ PINCTRL_CONF_DESC(8, REG_GPIO_L_E4, BIT(6)),
++ PINCTRL_CONF_DESC(9, REG_GPIO_L_E4, BIT(7)),
++ PINCTRL_CONF_DESC(10, REG_GPIO_L_E4, BIT(8)),
++ PINCTRL_CONF_DESC(11, REG_GPIO_L_E4, BIT(9)),
++ PINCTRL_CONF_DESC(12, REG_GPIO_L_E4, BIT(10)),
++ PINCTRL_CONF_DESC(13, REG_GPIO_L_E4, BIT(11)),
++ PINCTRL_CONF_DESC(14, REG_GPIO_L_E4, BIT(12)),
++ PINCTRL_CONF_DESC(15, REG_GPIO_L_E4, BIT(13)),
++ PINCTRL_CONF_DESC(16, REG_GPIO_L_E4, BIT(14)),
++ PINCTRL_CONF_DESC(17, REG_GPIO_L_E4, BIT(15)),
++ PINCTRL_CONF_DESC(18, REG_GPIO_L_E4, BIT(16)),
++ PINCTRL_CONF_DESC(19, REG_GPIO_L_E4, BIT(17)),
++ PINCTRL_CONF_DESC(20, REG_GPIO_L_E4, BIT(18)),
++ PINCTRL_CONF_DESC(21, REG_GPIO_L_E4, BIT(18)),
++ PINCTRL_CONF_DESC(22, REG_GPIO_L_E4, BIT(20)),
++ PINCTRL_CONF_DESC(23, REG_GPIO_L_E4, BIT(21)),
++ PINCTRL_CONF_DESC(24, REG_GPIO_L_E4, BIT(22)),
++ PINCTRL_CONF_DESC(25, REG_GPIO_L_E4, BIT(23)),
++ PINCTRL_CONF_DESC(26, REG_GPIO_L_E4, BIT(24)),
++ PINCTRL_CONF_DESC(27, REG_GPIO_L_E4, BIT(25)),
++ PINCTRL_CONF_DESC(28, REG_GPIO_L_E4, BIT(26)),
++ PINCTRL_CONF_DESC(29, REG_GPIO_L_E4, BIT(27)),
++ PINCTRL_CONF_DESC(30, REG_GPIO_L_E4, BIT(28)),
++ PINCTRL_CONF_DESC(31, REG_GPIO_L_E4, BIT(29)),
++ PINCTRL_CONF_DESC(32, REG_GPIO_L_E4, BIT(30)),
++ PINCTRL_CONF_DESC(33, REG_GPIO_L_E4, BIT(31)),
++ PINCTRL_CONF_DESC(34, REG_GPIO_H_E4, BIT(0)),
++ PINCTRL_CONF_DESC(35, REG_GPIO_H_E4, BIT(1)),
++ PINCTRL_CONF_DESC(36, REG_GPIO_H_E4, BIT(2)),
++ PINCTRL_CONF_DESC(37, REG_GPIO_H_E4, BIT(3)),
++ PINCTRL_CONF_DESC(38, REG_GPIO_H_E4, BIT(4)),
++ PINCTRL_CONF_DESC(39, REG_GPIO_H_E4, BIT(5)),
++ PINCTRL_CONF_DESC(40, REG_GPIO_H_E4, BIT(6)),
++ PINCTRL_CONF_DESC(41, REG_I2C_SDA_E4, I2C_SCL_E4_MASK),
++ PINCTRL_CONF_DESC(42, REG_I2C_SDA_E4, I2C_SDA_E4_MASK),
++ PINCTRL_CONF_DESC(43, REG_I2C_SDA_E4, AN7583_I2C1_SCL_E4_MASK),
++ PINCTRL_CONF_DESC(44, REG_I2C_SDA_E4, AN7583_I2C1_SDA_E4_MASK),
++ PINCTRL_CONF_DESC(45, REG_I2C_SDA_E4, SPI_CLK_E4_MASK),
++ PINCTRL_CONF_DESC(46, REG_I2C_SDA_E4, SPI_CS0_E4_MASK),
++ PINCTRL_CONF_DESC(47, REG_I2C_SDA_E4, SPI_MOSI_E4_MASK),
++ PINCTRL_CONF_DESC(48, REG_I2C_SDA_E4, SPI_MISO_E4_MASK),
++ PINCTRL_CONF_DESC(49, REG_I2C_SDA_E4, UART1_TXD_E4_MASK),
++ PINCTRL_CONF_DESC(50, REG_I2C_SDA_E4, UART1_RXD_E4_MASK),
++ PINCTRL_CONF_DESC(51, REG_I2C_SDA_E4, PCIE0_RESET_E4_MASK),
++ PINCTRL_CONF_DESC(52, REG_I2C_SDA_E4, PCIE1_RESET_E4_MASK),
++ PINCTRL_CONF_DESC(53, REG_I2C_SDA_E4, AN7583_MDC_0_E4_MASK),
++ PINCTRL_CONF_DESC(54, REG_I2C_SDA_E4, AN7583_MDIO_0_E4_MASK),
++};
++
+ static const struct airoha_pinctrl_conf en7581_pinctrl_pcie_rst_od_conf[] = {
+ PINCTRL_CONF_DESC(61, REG_PCIE_RESET_OD, PCIE0_RESET_OD_MASK),
+ PINCTRL_CONF_DESC(62, REG_PCIE_RESET_OD, PCIE1_RESET_OD_MASK),
+ PINCTRL_CONF_DESC(63, REG_PCIE_RESET_OD, PCIE2_RESET_OD_MASK),
+ };
+
++static const struct airoha_pinctrl_conf an7583_pinctrl_pcie_rst_od_conf[] = {
++ PINCTRL_CONF_DESC(51, REG_PCIE_RESET_OD, PCIE0_RESET_OD_MASK),
++ PINCTRL_CONF_DESC(52, REG_PCIE_RESET_OD, PCIE1_RESET_OD_MASK),
++};
++
+ static int airoha_convert_pin_to_reg_offset(struct pinctrl_dev *pctrl_dev,
+ struct pinctrl_gpio_range *range,
+ int pin)
+@@ -2267,8 +2968,40 @@ static const struct airoha_pinctrl_match
+ },
+ };
+
++static const struct airoha_pinctrl_match_data an7583_pinctrl_match_data = {
++ .pins = an7583_pinctrl_pins,
++ .num_pins = ARRAY_SIZE(an7583_pinctrl_pins),
++ .grps = an7583_pinctrl_groups,
++ .num_grps = ARRAY_SIZE(an7583_pinctrl_groups),
++ .funcs = an7583_pinctrl_funcs,
++ .num_funcs = ARRAY_SIZE(an7583_pinctrl_funcs),
++ .confs_info = {
++ [AIROHA_PINCTRL_CONFS_PULLUP] = {
++ .confs = an7583_pinctrl_pullup_conf,
++ .num_confs = ARRAY_SIZE(an7583_pinctrl_pullup_conf),
++ },
++ [AIROHA_PINCTRL_CONFS_PULLDOWN] = {
++ .confs = an7583_pinctrl_pulldown_conf,
++ .num_confs = ARRAY_SIZE(an7583_pinctrl_pulldown_conf),
++ },
++ [AIROHA_PINCTRL_CONFS_DRIVE_E2] = {
++ .confs = en7581_pinctrl_drive_e2_conf,
++ .num_confs = ARRAY_SIZE(an7583_pinctrl_drive_e2_conf),
++ },
++ [AIROHA_PINCTRL_CONFS_DRIVE_E4] = {
++ .confs = an7583_pinctrl_drive_e4_conf,
++ .num_confs = ARRAY_SIZE(an7583_pinctrl_drive_e4_conf),
++ },
++ [AIROHA_PINCTRL_CONFS_PCIE_RST_OD] = {
++ .confs = an7583_pinctrl_pcie_rst_od_conf,
++ .num_confs = ARRAY_SIZE(an7583_pinctrl_pcie_rst_od_conf),
++ },
++ },
++};
++
+ static const struct of_device_id airoha_pinctrl_of_match[] = {
+ { .compatible = "airoha,en7581-pinctrl", .data = &en7581_pinctrl_match_data },
++ { .compatible = "airoha,an7583-pinctrl", .data = &an7583_pinctrl_match_data },
+ { /* sentinel */ }
+ };
+ MODULE_DEVICE_TABLE(of, airoha_pinctrl_of_match);
--- /dev/null
+From 7e112e51d48db09739dd73c90411fc8a5635747f Mon Sep 17 00:00:00 2001
+From: Christian Marangi <ansuelsmth@gmail.com>
+Date: Thu, 22 May 2025 15:13:10 +0200
+Subject: [PATCH 2/3] net: dsa: mt7530: Add AN7583 support
+
+Add Airoha AN7583 Switch support. This is based on Airoha EN7581 that is
+based on Mediatek MT7988 Switch.
+
+Airoha AN7583 require additional tweak to the GEPHY_CONN_CFG register to
+make the internal PHY work.
+
+Signed-off-by: Christian Marangi <ansuelsmth@gmail.com>
+---
+ drivers/net/dsa/mt7530-mmio.c | 1 +
+ drivers/net/dsa/mt7530.c | 24 ++++++++++++++++++++++--
+ drivers/net/dsa/mt7530.h | 18 ++++++++++++++----
+ 3 files changed, 37 insertions(+), 6 deletions(-)
+
+--- a/drivers/net/dsa/mt7530-mmio.c
++++ b/drivers/net/dsa/mt7530-mmio.c
+@@ -11,6 +11,7 @@
+ #include "mt7530.h"
+
+ static const struct of_device_id mt7988_of_match[] = {
++ { .compatible = "airoha,an7583-switch", .data = &mt753x_table[ID_AN7583], },
+ { .compatible = "airoha,en7581-switch", .data = &mt753x_table[ID_EN7581], },
+ { .compatible = "mediatek,mt7988-switch", .data = &mt753x_table[ID_MT7988], },
+ { /* sentinel */ },
+--- a/drivers/net/dsa/mt7530.c
++++ b/drivers/net/dsa/mt7530.c
+@@ -1153,7 +1153,7 @@ mt753x_cpu_port_enable(struct dsa_switch
+ * is affine to the inbound user port.
+ */
+ if (priv->id == ID_MT7531 || priv->id == ID_MT7988 ||
+- priv->id == ID_EN7581)
++ priv->id == ID_EN7581 || priv->id == ID_AN7583)
+ mt7530_set(priv, MT7531_CFC, MT7531_CPU_PMAP(BIT(port)));
+
+ /* CPU port gets connected to all user ports of
+@@ -2589,7 +2589,7 @@ mt7531_setup_common(struct dsa_switch *d
+ mt7530_set(priv, MT753X_AGC, LOCAL_EN);
+
+ /* Enable Special Tag for rx frames */
+- if (priv->id == ID_EN7581)
++ if (priv->id == ID_EN7581 || priv->id == ID_AN7583)
+ mt7530_write(priv, MT753X_CPORT_SPTAG_CFG,
+ CPORT_SW2FE_STAG_EN | CPORT_FE2SW_STAG_EN);
+
+@@ -3157,6 +3157,16 @@ static int mt7988_setup(struct dsa_switc
+ reset_control_deassert(priv->rstc);
+ usleep_range(20, 50);
+
++ /* AN7583 require additional tweak to CONN_CFG */
++ if (priv->id == ID_AN7583)
++ mt7530_rmw(priv, AN7583_GEPHY_CONN_CFG,
++ AN7583_CSR_DPHY_CKIN_SEL |
++ AN7583_CSR_PHY_CORE_REG_CLK_SEL |
++ AN7583_CSR_ETHER_AFE_PWD,
++ AN7583_CSR_DPHY_CKIN_SEL |
++ AN7583_CSR_PHY_CORE_REG_CLK_SEL |
++ FIELD_PREP(AN7583_CSR_ETHER_AFE_PWD, 0));
++
+ /* Reset the switch PHYs */
+ mt7530_write(priv, MT7530_SYS_CTRL, SYS_CTRL_PHY_RST);
+
+@@ -3253,6 +3263,16 @@ const struct mt753x_info mt753x_table[]
+ .pcs_ops = &mt7530_pcs_ops,
+ .sw_setup = mt7988_setup,
+ .phy_read_c22 = mt7531_ind_c22_phy_read,
++ .phy_write_c22 = mt7531_ind_c22_phy_write,
++ .phy_read_c45 = mt7531_ind_c45_phy_read,
++ .phy_write_c45 = mt7531_ind_c45_phy_write,
++ .mac_port_get_caps = en7581_mac_port_get_caps,
++ },
++ [ID_AN7583] = {
++ .id = ID_AN7583,
++ .pcs_ops = &mt7530_pcs_ops,
++ .sw_setup = mt7988_setup,
++ .phy_read_c22 = mt7531_ind_c22_phy_read,
+ .phy_write_c22 = mt7531_ind_c22_phy_write,
+ .phy_read_c45 = mt7531_ind_c45_phy_read,
+ .phy_write_c45 = mt7531_ind_c45_phy_write,
+--- a/drivers/net/dsa/mt7530.h
++++ b/drivers/net/dsa/mt7530.h
+@@ -20,6 +20,7 @@ enum mt753x_id {
+ ID_MT7531 = 2,
+ ID_MT7988 = 3,
+ ID_EN7581 = 4,
++ ID_AN7583 = 5,
+ };
+
+ #define NUM_TRGMII_CTRL 5
+@@ -66,7 +67,8 @@ enum mt753x_id {
+
+ #define MT753X_MIRROR_REG(id) ((id == ID_MT7531 || \
+ id == ID_MT7988 || \
+- id == ID_EN7581) ? \
++ id == ID_EN7581 || \
++ id == ID_AN7583) ? \
+ MT7531_CFC : MT753X_MFC)
+
+ #define MT753X_MIRROR_EN(id) ((id == ID_MT7531 || \
+@@ -76,19 +78,22 @@ enum mt753x_id {
+
+ #define MT753X_MIRROR_PORT_MASK(id) ((id == ID_MT7531 || \
+ id == ID_MT7988 || \
+- id == ID_EN7581) ? \
++ id == ID_EN7581 || \
++ id == ID_AN7583) ? \
+ MT7531_MIRROR_PORT_MASK : \
+ MT7530_MIRROR_PORT_MASK)
+
+ #define MT753X_MIRROR_PORT_GET(id, val) ((id == ID_MT7531 || \
+ id == ID_MT7988 || \
+- id == ID_EN7581) ? \
++ id == ID_EN7581 || \
++ id == ID_AN7583) ? \
+ MT7531_MIRROR_PORT_GET(val) : \
+ MT7530_MIRROR_PORT_GET(val))
+
+ #define MT753X_MIRROR_PORT_SET(id, val) ((id == ID_MT7531 || \
+ id == ID_MT7988 || \
+- id == ID_EN7581) ? \
++ id == ID_EN7581 || \
++ id == ID_AN7583) ? \
+ MT7531_MIRROR_PORT_SET(val) : \
+ MT7530_MIRROR_PORT_SET(val))
+
+@@ -619,6 +624,11 @@ enum mt7531_xtal_fsel {
+ #define CPORT_SW2FE_STAG_EN BIT(1)
+ #define CPORT_FE2SW_STAG_EN BIT(0)
+
++#define AN7583_GEPHY_CONN_CFG 0x7c14
++#define AN7583_CSR_DPHY_CKIN_SEL BIT(31)
++#define AN7583_CSR_PHY_CORE_REG_CLK_SEL BIT(30)
++#define AN7583_CSR_ETHER_AFE_PWD GENMASK(28, 24)
++
+ /* Registers for LED GPIO control (MT7530 only)
+ * All registers follow this pattern:
+ * [ 2: 0] port 0
--- /dev/null
+From 7d55e75edc87022a4c1820588f70a80cebb13c5f Mon Sep 17 00:00:00 2001
+From: Christian Marangi <ansuelsmth@gmail.com>
+Date: Fri, 23 May 2025 19:34:54 +0200
+Subject: [PATCH 1/5] thermal: airoha: convert to regmap API
+
+In preparation for support of Airoha AN7583, convert the driver to
+regmap API. This is needed as Airoha AN7583 will be based on syscon
+regmap.
+
+Signed-off-by: Christian Marangi <ansuelsmth@gmail.com>
+---
+ drivers/thermal/airoha_thermal.c | 72 +++++++++++++++++++-------------
+ 1 file changed, 42 insertions(+), 30 deletions(-)
+
+--- a/drivers/thermal/airoha_thermal.c
++++ b/drivers/thermal/airoha_thermal.c
+@@ -194,7 +194,7 @@
+ #define AIROHA_MAX_SAMPLES 6
+
+ struct airoha_thermal_priv {
+- void __iomem *base;
++ struct regmap *map;
+ struct regmap *chip_scu;
+ struct resource scu_adc_res;
+
+@@ -265,8 +265,8 @@ static int airoha_thermal_set_trips(stru
+ RAW_TO_TEMP(priv, FIELD_MAX(EN7581_DOUT_TADC_MASK)));
+
+ /* We offset the high temp of 1°C to trigger correct event */
+- writel(TEMP_TO_RAW(priv, high) >> 4,
+- priv->base + EN7581_TEMPOFFSETH);
++ regmap_write(priv->map, EN7581_TEMPOFFSETH,
++ TEMP_TO_RAW(priv, high) >> 4);
+
+ enable_monitor = true;
+ }
+@@ -277,15 +277,15 @@ static int airoha_thermal_set_trips(stru
+ RAW_TO_TEMP(priv, FIELD_MAX(EN7581_DOUT_TADC_MASK)));
+
+ /* We offset the low temp of 1°C to trigger correct event */
+- writel(TEMP_TO_RAW(priv, low) >> 4,
+- priv->base + EN7581_TEMPOFFSETL);
++ regmap_write(priv->map, EN7581_TEMPOFFSETL,
++ TEMP_TO_RAW(priv, high) >> 4);
+
+ enable_monitor = true;
+ }
+
+ /* Enable sensor 0 monitor after trip are set */
+ if (enable_monitor)
+- writel(EN7581_SENSE0_EN, priv->base + EN7581_TEMPMONCTL0);
++ regmap_write(priv->map, EN7581_TEMPMONCTL0, EN7581_SENSE0_EN);
+
+ return 0;
+ }
+@@ -302,7 +302,7 @@ static irqreturn_t airoha_thermal_irq(in
+ bool update = false;
+ u32 status;
+
+- status = readl(priv->base + EN7581_TEMPMONINTSTS);
++ regmap_read(priv->map, EN7581_TEMPMONINTSTS, &status);
+ switch (status & (EN7581_HOFSINTSTS0 | EN7581_LOFSINTSTS0)) {
+ case EN7581_HOFSINTSTS0:
+ event = THERMAL_TRIP_VIOLATED;
+@@ -318,7 +318,7 @@ static irqreturn_t airoha_thermal_irq(in
+ }
+
+ /* Reset Interrupt */
+- writel(status, priv->base + EN7581_TEMPMONINTSTS);
++ regmap_write(priv->map, EN7581_TEMPMONINTSTS, status);
+
+ if (update)
+ thermal_zone_device_update(priv->tz, event);
+@@ -336,11 +336,11 @@ static void airoha_thermal_setup_adc_val
+ /* sleep 10 ms for ADC to enable */
+ usleep_range(10 * USEC_PER_MSEC, 11 * USEC_PER_MSEC);
+
+- efuse_calib_info = readl(priv->base + EN7581_EFUSE_TEMP_OFFSET_REG);
++ regmap_read(priv->map, EN7581_EFUSE_TEMP_OFFSET_REG, &efuse_calib_info);
+ if (efuse_calib_info) {
+ priv->default_offset = FIELD_GET(EN7581_EFUSE_TEMP_OFFSET, efuse_calib_info);
+ /* Different slope are applied if the sensor is used for CPU or for package */
+- cpu_sensor = readl(priv->base + EN7581_EFUSE_TEMP_CPU_SENSOR_REG);
++ regmap_read(priv->map, EN7581_EFUSE_TEMP_CPU_SENSOR_REG, &cpu_sensor);
+ if (cpu_sensor) {
+ priv->default_slope = EN7581_SLOPE_X100_DIO_DEFAULT;
+ priv->init_temp = EN7581_INIT_TEMP_FTK_X10;
+@@ -359,8 +359,8 @@ static void airoha_thermal_setup_adc_val
+ static void airoha_thermal_setup_monitor(struct airoha_thermal_priv *priv)
+ {
+ /* Set measure mode */
+- writel(FIELD_PREP(EN7581_MSRCTL0, EN7581_MSRCTL_6SAMPLE_MAX_MIX_AVG4),
+- priv->base + EN7581_TEMPMSRCTL0);
++ regmap_write(priv->map, EN7581_TEMPMSRCTL0,
++ FIELD_PREP(EN7581_MSRCTL0, EN7581_MSRCTL_6SAMPLE_MAX_MIX_AVG4));
+
+ /*
+ * Configure ADC valid reading addr
+@@ -375,15 +375,15 @@ static void airoha_thermal_setup_monitor
+ * We set valid instead of volt as we don't enable valid/volt
+ * split reading and AHB read valid addr in such case.
+ */
+- writel(priv->scu_adc_res.start + EN7581_DOUT_TADC,
+- priv->base + EN7581_TEMPADCVALIDADDR);
++ regmap_write(priv->map, EN7581_TEMPADCVALIDADDR,
++ priv->scu_adc_res.start + EN7581_DOUT_TADC);
+
+ /*
+ * Configure valid bit on a fake value of bit 16. The ADC outputs
+ * max of 2 bytes for voltage.
+ */
+- writel(FIELD_PREP(EN7581_ADV_RD_VALID_POS, 16),
+- priv->base + EN7581_TEMPADCVALIDMASK);
++ regmap_write(priv->map, EN7581_TEMPADCVALIDMASK,
++ FIELD_PREP(EN7581_ADV_RD_VALID_POS, 16));
+
+ /*
+ * AHB supports max 12 bytes for ADC voltage. Shift the read
+@@ -391,40 +391,52 @@ static void airoha_thermal_setup_monitor
+ * in the order of half a °C and is acceptable in the context
+ * of triggering interrupt in critical condition.
+ */
+- writel(FIELD_PREP(EN7581_ADC_VOLTAGE_SHIFT, 4),
+- priv->base + EN7581_TEMPADCVOLTAGESHIFT);
++ regmap_write(priv->map, EN7581_TEMPADCVOLTAGESHIFT,
++ FIELD_PREP(EN7581_ADC_VOLTAGE_SHIFT, 4));
+
+ /* BUS clock is 300MHz counting unit is 3 * 68.64 * 256 = 52.715us */
+- writel(FIELD_PREP(EN7581_PERIOD_UNIT, 3),
+- priv->base + EN7581_TEMPMONCTL1);
++ regmap_write(priv->map, EN7581_TEMPMONCTL1,
++ FIELD_PREP(EN7581_PERIOD_UNIT, 3));
+
+ /*
+ * filt interval is 1 * 52.715us = 52.715us,
+ * sen interval is 379 * 52.715us = 19.97ms
+ */
+- writel(FIELD_PREP(EN7581_FILT_INTERVAL, 1) |
+- FIELD_PREP(EN7581_FILT_INTERVAL, 379),
+- priv->base + EN7581_TEMPMONCTL2);
++ regmap_write(priv->map, EN7581_TEMPMONCTL2,
++ FIELD_PREP(EN7581_FILT_INTERVAL, 1) |
++ FIELD_PREP(EN7581_FILT_INTERVAL, 379));
+
+ /* AHB poll is set to 146 * 68.64 = 10.02us */
+- writel(FIELD_PREP(EN7581_ADC_POLL_INTVL, 146),
+- priv->base + EN7581_TEMPAHBPOLL);
++ regmap_write(priv->map, EN7581_TEMPAHBPOLL,
++ FIELD_PREP(EN7581_ADC_POLL_INTVL, 146));
+ }
+
++static const struct regmap_config airoha_thermal_regmap_config = {
++ .reg_bits = 32,
++ .reg_stride = 4,
++ .val_bits = 32,
++};
++
+ static int airoha_thermal_probe(struct platform_device *pdev)
+ {
+ struct airoha_thermal_priv *priv;
+ struct device_node *chip_scu_np;
+ struct device *dev = &pdev->dev;
++ void __iomem *base;
+ int irq, ret;
+
+ priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);
+ if (!priv)
+ return -ENOMEM;
+
+- priv->base = devm_platform_ioremap_resource(pdev, 0);
+- if (IS_ERR(priv->base))
+- return PTR_ERR(priv->base);
++ base = devm_platform_ioremap_resource(pdev, 0);
++ if (IS_ERR(base))
++ return PTR_ERR(base);
++
++ priv->map = devm_regmap_init_mmio(dev, base,
++ &airoha_thermal_regmap_config);
++ if (IS_ERR(priv->map))
++ return PTR_ERR(priv->map);
+
+ chip_scu_np = of_parse_phandle(dev->of_node, "airoha,chip-scu", 0);
+ if (!chip_scu_np)
+@@ -462,8 +474,8 @@ static int airoha_thermal_probe(struct p
+ platform_set_drvdata(pdev, priv);
+
+ /* Enable LOW and HIGH interrupt */
+- writel(EN7581_HOFSINTEN0 | EN7581_LOFSINTEN0,
+- priv->base + EN7581_TEMPMONINT);
++ regmap_write(priv->map, EN7581_TEMPMONINT,
++ EN7581_HOFSINTEN0 | EN7581_LOFSINTEN0);
+
+ return 0;
+ }
--- /dev/null
+From 6c0f01b16687dc582f0470a5d5b20084fb3a290f Mon Sep 17 00:00:00 2001
+From: Christian Marangi <ansuelsmth@gmail.com>
+Date: Fri, 23 May 2025 19:48:32 +0200
+Subject: [PATCH 2/5] thermal/drivers: airoha: Generalize probe function
+
+In preparation for support of Airoha AN7583, generalize the probe
+function to address for the 2 SoC differece.
+
+Implement a match_data struct where it's possible to define a more
+specific probe and post_probe function and specific thermal ops and
+pllrg protect value.
+
+Signed-off-by: Christian Marangi <ansuelsmth@gmail.com>
+---
+ drivers/thermal/airoha_thermal.c | 102 +++++++++++++++++++++++--------
+ 1 file changed, 75 insertions(+), 27 deletions(-)
+
+--- a/drivers/thermal/airoha_thermal.c
++++ b/drivers/thermal/airoha_thermal.c
+@@ -198,12 +198,23 @@ struct airoha_thermal_priv {
+ struct regmap *chip_scu;
+ struct resource scu_adc_res;
+
++ u32 pllrg_protect;
++
+ struct thermal_zone_device *tz;
+ int init_temp;
+ int default_slope;
+ int default_offset;
+ };
+
++struct airoha_thermal_soc_data {
++ u32 pllrg_protect;
++
++ const struct thermal_zone_device_ops *thdev_ops;
++ int (*probe)(struct platform_device *pdev,
++ struct airoha_thermal_priv *priv);
++ int (*post_probe)(struct platform_device *pdev);
++};
++
+ static int airoha_get_thermal_ADC(struct airoha_thermal_priv *priv)
+ {
+ u32 val;
+@@ -220,7 +231,8 @@ static void airoha_init_thermal_ADC_mode
+ regmap_read(priv->chip_scu, EN7581_PLLRG_PROTECT, &pllrg);
+
+ /* Give access to thermal regs */
+- regmap_write(priv->chip_scu, EN7581_PLLRG_PROTECT, EN7581_SCU_THERMAL_PROTECT_KEY);
++ regmap_write(priv->chip_scu, EN7581_PLLRG_PROTECT,
++ priv->pllrg_protect);
+ adc_mux = FIELD_PREP(EN7581_MUX_TADC, EN7581_SCU_THERMAL_MUX_DIODE1);
+ regmap_write(priv->chip_scu, EN7581_PWD_TADC, adc_mux);
+
+@@ -228,7 +240,7 @@ static void airoha_init_thermal_ADC_mode
+ regmap_write(priv->chip_scu, EN7581_PLLRG_PROTECT, pllrg);
+ }
+
+-static int airoha_thermal_get_temp(struct thermal_zone_device *tz, int *temp)
++static int en7581_thermal_get_temp(struct thermal_zone_device *tz, int *temp)
+ {
+ struct airoha_thermal_priv *priv = thermal_zone_device_priv(tz);
+ int min_value, max_value, avg_value, value;
+@@ -253,7 +265,7 @@ static int airoha_thermal_get_temp(struc
+ return 0;
+ }
+
+-static int airoha_thermal_set_trips(struct thermal_zone_device *tz, int low,
++static int en7581_thermal_set_trips(struct thermal_zone_device *tz, int low,
+ int high)
+ {
+ struct airoha_thermal_priv *priv = thermal_zone_device_priv(tz);
+@@ -290,12 +302,12 @@ static int airoha_thermal_set_trips(stru
+ return 0;
+ }
+
+-static const struct thermal_zone_device_ops thdev_ops = {
+- .get_temp = airoha_thermal_get_temp,
+- .set_trips = airoha_thermal_set_trips,
++static const struct thermal_zone_device_ops en7581_thdev_ops = {
++ .get_temp = en7581_thermal_get_temp,
++ .set_trips = en7581_thermal_set_trips,
+ };
+
+-static irqreturn_t airoha_thermal_irq(int irq, void *data)
++static irqreturn_t en7581_thermal_irq(int irq, void *data)
+ {
+ struct airoha_thermal_priv *priv = data;
+ enum thermal_notify_event event;
+@@ -326,7 +338,7 @@ static irqreturn_t airoha_thermal_irq(in
+ return IRQ_HANDLED;
+ }
+
+-static void airoha_thermal_setup_adc_val(struct device *dev,
++static void en7581_thermal_setup_adc_val(struct device *dev,
+ struct airoha_thermal_priv *priv)
+ {
+ u32 efuse_calib_info, cpu_sensor;
+@@ -356,7 +368,7 @@ static void airoha_thermal_setup_adc_val
+ }
+ }
+
+-static void airoha_thermal_setup_monitor(struct airoha_thermal_priv *priv)
++static void en7581_thermal_setup_monitor(struct airoha_thermal_priv *priv)
+ {
+ /* Set measure mode */
+ regmap_write(priv->map, EN7581_TEMPMSRCTL0,
+@@ -411,30 +423,26 @@ static void airoha_thermal_setup_monitor
+ FIELD_PREP(EN7581_ADC_POLL_INTVL, 146));
+ }
+
+-static const struct regmap_config airoha_thermal_regmap_config = {
++static const struct regmap_config en7581_thermal_regmap_config = {
+ .reg_bits = 32,
+ .reg_stride = 4,
+ .val_bits = 32,
+ };
+
+-static int airoha_thermal_probe(struct platform_device *pdev)
++static int en7581_thermal_probe(struct platform_device *pdev,
++ struct airoha_thermal_priv *priv)
+ {
+- struct airoha_thermal_priv *priv;
+ struct device_node *chip_scu_np;
+ struct device *dev = &pdev->dev;
+ void __iomem *base;
+ int irq, ret;
+
+- priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);
+- if (!priv)
+- return -ENOMEM;
+-
+ base = devm_platform_ioremap_resource(pdev, 0);
+ if (IS_ERR(base))
+ return PTR_ERR(base);
+
+ priv->map = devm_regmap_init_mmio(dev, base,
+- &airoha_thermal_regmap_config);
++ &en7581_thermal_regmap_config);
+ if (IS_ERR(priv->map))
+ return PTR_ERR(priv->map);
+
+@@ -454,18 +462,55 @@ static int airoha_thermal_probe(struct p
+ return irq;
+
+ ret = devm_request_threaded_irq(&pdev->dev, irq, NULL,
+- airoha_thermal_irq, IRQF_ONESHOT,
++ en7581_thermal_irq, IRQF_ONESHOT,
+ pdev->name, priv);
+ if (ret) {
+ dev_err(dev, "Can't get interrupt working.\n");
+ return ret;
+ }
+
+- airoha_thermal_setup_monitor(priv);
+- airoha_thermal_setup_adc_val(dev, priv);
++ en7581_thermal_setup_monitor(priv);
++ en7581_thermal_setup_adc_val(dev, priv);
++
++ return 0;
++}
++
++static int en7581_thermal_post_probe(struct platform_device *pdev)
++{
++ struct airoha_thermal_priv *priv = platform_get_drvdata(pdev);
++
++ /* Enable LOW and HIGH interrupt (if supported) */
++ regmap_write(priv->map, EN7581_TEMPMONINT,
++ EN7581_HOFSINTEN0 | EN7581_LOFSINTEN0);
++
++ return 0;
++}
++
++static int airoha_thermal_probe(struct platform_device *pdev)
++{
++ const struct airoha_thermal_soc_data *soc_data;
++ struct airoha_thermal_priv *priv;
++ struct device *dev = &pdev->dev;
++ int ret;
++
++ soc_data = device_get_match_data(dev);
++
++ priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);
++ if (!priv)
++ return -ENOMEM;
++
++ priv->pllrg_protect = soc_data->pllrg_protect;
++
++ if (!soc_data->probe)
++ return -EINVAL;
++
++ ret = soc_data->probe(pdev, priv);
++ if (ret)
++ return ret;
+
+ /* register of thermal sensor and get info from DT */
+- priv->tz = devm_thermal_of_zone_register(dev, 0, priv, &thdev_ops);
++ priv->tz = devm_thermal_of_zone_register(dev, 0, priv,
++ soc_data->thdev_ops);
+ if (IS_ERR(priv->tz)) {
+ dev_err(dev, "register thermal zone sensor failed\n");
+ return PTR_ERR(priv->tz);
+@@ -473,15 +518,18 @@ static int airoha_thermal_probe(struct p
+
+ platform_set_drvdata(pdev, priv);
+
+- /* Enable LOW and HIGH interrupt */
+- regmap_write(priv->map, EN7581_TEMPMONINT,
+- EN7581_HOFSINTEN0 | EN7581_LOFSINTEN0);
+-
+- return 0;
++ return soc_data->post_probe ? soc_data->post_probe(pdev) : 0;
+ }
+
++static const struct airoha_thermal_soc_data en7581_data = {
++ .pllrg_protect = EN7581_SCU_THERMAL_PROTECT_KEY,
++ .thdev_ops = &en7581_thdev_ops,
++ .probe = &en7581_thermal_probe,
++ .post_probe = &en7581_thermal_post_probe,
++};
++
+ static const struct of_device_id airoha_thermal_match[] = {
+- { .compatible = "airoha,en7581-thermal" },
++ { .compatible = "airoha,en7581-thermal", .data = &en7581_data },
+ {},
+ };
+ MODULE_DEVICE_TABLE(of, airoha_thermal_match);
--- /dev/null
+From 1e623852d07759c3c076505193bd7f0bd3486774 Mon Sep 17 00:00:00 2001
+From: Christian Marangi <ansuelsmth@gmail.com>
+Date: Fri, 23 May 2025 19:54:53 +0200
+Subject: [PATCH 3/5] thermal/drivers: airoha: generalize get_thermal_ADC and
+ set_mux function
+
+In preparation for support of Airoha AN7583, generalize
+get_thermal_ADC() and set_thermal_mux() with the use of reg_field API.
+
+This is to account the same logic between the current supported SoC and
+the new one but with different register address.
+
+While at it also further improve some comments and move sleep inside the
+set_thermal_mux function.
+
+Signed-off-by: Christian Marangi <ansuelsmth@gmail.com>
+---
+ drivers/thermal/airoha_thermal.c | 54 +++++++++++++++++++++++++-------
+ 1 file changed, 42 insertions(+), 12 deletions(-)
+
+--- a/drivers/thermal/airoha_thermal.c
++++ b/drivers/thermal/airoha_thermal.c
+@@ -193,9 +193,18 @@
+
+ #define AIROHA_MAX_SAMPLES 6
+
++enum airoha_thermal_chip_scu_field {
++ AIROHA_THERMAL_DOUT_TADC,
++ AIROHA_THERMAL_MUX_TADC,
++
++ /* keep last */
++ AIROHA_THERMAL_FIELD_MAX,
++};
++
+ struct airoha_thermal_priv {
+ struct regmap *map;
+ struct regmap *chip_scu;
++ struct regmap_field *chip_scu_fields[AIROHA_THERMAL_FIELD_MAX];
+ struct resource scu_adc_res;
+
+ u32 pllrg_protect;
+@@ -219,22 +228,29 @@ static int airoha_get_thermal_ADC(struct
+ {
+ u32 val;
+
+- regmap_read(priv->chip_scu, EN7581_DOUT_TADC, &val);
+- return FIELD_GET(EN7581_DOUT_TADC_MASK, val);
++ regmap_field_read(priv->chip_scu_fields[AIROHA_THERMAL_DOUT_TADC],
++ &val);
++ return val;
+ }
+
+-static void airoha_init_thermal_ADC_mode(struct airoha_thermal_priv *priv)
++static void airoha_set_thermal_mux(struct airoha_thermal_priv *priv,
++ int tdac_idx)
+ {
+- u32 adc_mux, pllrg;
++ u32 pllrg;
+
+ /* Save PLLRG current value */
+ regmap_read(priv->chip_scu, EN7581_PLLRG_PROTECT, &pllrg);
+
+- /* Give access to thermal regs */
++ /* Give access to Thermal regs */
+ regmap_write(priv->chip_scu, EN7581_PLLRG_PROTECT,
+ priv->pllrg_protect);
+- adc_mux = FIELD_PREP(EN7581_MUX_TADC, EN7581_SCU_THERMAL_MUX_DIODE1);
+- regmap_write(priv->chip_scu, EN7581_PWD_TADC, adc_mux);
++
++ /* Configure Thermal ADC mux to tdac_idx */
++ regmap_field_write(priv->chip_scu_fields[AIROHA_THERMAL_MUX_TADC],
++ tdac_idx);
++
++ /* Sleep 10 ms for Thermal ADC to enable */
++ usleep_range(10 * USEC_PER_MSEC, 11 * USEC_PER_MSEC);
+
+ /* Restore PLLRG value on exit */
+ regmap_write(priv->chip_scu, EN7581_PLLRG_PROTECT, pllrg);
+@@ -343,10 +359,8 @@ static void en7581_thermal_setup_adc_val
+ {
+ u32 efuse_calib_info, cpu_sensor;
+
+- /* Setup thermal sensor to ADC mode and setup the mux to DIODE1 */
+- airoha_init_thermal_ADC_mode(priv);
+- /* sleep 10 ms for ADC to enable */
+- usleep_range(10 * USEC_PER_MSEC, 11 * USEC_PER_MSEC);
++ /* Setup Thermal Sensor to ADC mode and setup the mux to DIODE1 */
++ airoha_set_thermal_mux(priv, EN7581_SCU_THERMAL_MUX_DIODE1);
+
+ regmap_read(priv->map, EN7581_EFUSE_TEMP_OFFSET_REG, &efuse_calib_info);
+ if (efuse_calib_info) {
+@@ -429,13 +443,18 @@ static const struct regmap_config en7581
+ .val_bits = 32,
+ };
+
++static const struct reg_field en7581_chip_scu_fields[AIROHA_THERMAL_FIELD_MAX] = {
++ [AIROHA_THERMAL_DOUT_TADC] = REG_FIELD(EN7581_DOUT_TADC, 0, 15),
++ [AIROHA_THERMAL_MUX_TADC] = REG_FIELD(EN7581_PWD_TADC, 1, 3),
++};
++
+ static int en7581_thermal_probe(struct platform_device *pdev,
+ struct airoha_thermal_priv *priv)
+ {
+ struct device_node *chip_scu_np;
+ struct device *dev = &pdev->dev;
+ void __iomem *base;
+- int irq, ret;
++ int i, irq, ret;
+
+ base = devm_platform_ioremap_resource(pdev, 0);
+ if (IS_ERR(base))
+@@ -454,6 +473,17 @@ static int en7581_thermal_probe(struct p
+ if (IS_ERR(priv->chip_scu))
+ return PTR_ERR(priv->chip_scu);
+
++ for (i = 0; i < AIROHA_THERMAL_FIELD_MAX; i++) {
++ struct regmap_field *field;
++
++ field = devm_regmap_field_alloc(dev, priv->chip_scu,
++ en7581_chip_scu_fields[i]);
++ if (IS_ERR(field))
++ return PTR_ERR(field);
++
++ priv->chip_scu_fields[i] = field;
++ }
++
+ of_address_to_resource(chip_scu_np, 0, &priv->scu_adc_res);
+ of_node_put(chip_scu_np);
+
--- /dev/null
+From 5891a9e5fbdf9a305b5f81e2625455efb2a886f0 Mon Sep 17 00:00:00 2001
+From: Christian Marangi <ansuelsmth@gmail.com>
+Date: Fri, 23 May 2025 19:59:20 +0200
+Subject: [PATCH 5/5] thermal/drivers: airoha: Add support for AN7583
+
+Add support for Airoha AN7583 Thermal driver. This apply similar logic
+on how to read the temperature but totally drop support for the
+PTP_THERMAL subsystem. PTP_THERMAL subsystem was a way to trigger trip
+point from hardware by configuring how to read the temperature
+internally.
+
+This subsystem has been totally removed from Airoha AN7583 permitting
+only to read the temperature.
+
+The SoC support up to 3 sensor but the original driver always read the
+BGA sensor hence it's currently implemented reading only this specific
+sensor. Reference and values for the other 2 sensor are defined for
+further implementation if confirmed working.
+
+set_thermal_mux() is extended to also address muxing the sensor as
+AN7583 use a different way to read the temperature from 3 different
+diode. The EN7581 code is updated to account for these changes.
+
+Signed-off-by: Christian Marangi <ansuelsmth@gmail.com>
+---
+ drivers/thermal/airoha_thermal.c | 158 ++++++++++++++++++++++++++++++-
+ 1 file changed, 154 insertions(+), 4 deletions(-)
+
+--- a/drivers/thermal/airoha_thermal.c
++++ b/drivers/thermal/airoha_thermal.c
+@@ -18,6 +18,12 @@
+ #define EN7581_DOUT_TADC 0x2f8
+ #define EN7581_DOUT_TADC_MASK GENMASK(15, 0)
+
++#define AN7583_MUX_SENSOR 0x2a0
++#define AN7583_LOAD_ADJ GENMASK(3, 2)
++#define AN7583_MUX_TADC 0x2e4
++#define AN7583_MUX_TADC_MASK GENMASK(3, 1)
++#define AN7583_DOUT_TADC 0x2f0
++
+ /* PTP_THERMAL regs */
+ #define EN7581_TEMPMONCTL0 0x800
+ #define EN7581_SENSE3_EN BIT(3)
+@@ -181,6 +187,11 @@
+ #define EN7581_SCU_THERMAL_PROTECT_KEY 0x12
+ #define EN7581_SCU_THERMAL_MUX_DIODE1 0x7
+
++#define AN7583_SCU_THERMAL_PROTECT_KEY 0x80
++#define AN7583_NUM_SENSOR 3
++
++#define AIROHA_THERMAL_NO_MUX_SENSOR -1
++
+ /* Convert temp to raw value as read from ADC ((((temp / 100) - init) * slope) / 1000) + offset */
+ #define TEMP_TO_RAW(priv, temp) ((((((temp) / 100) - (priv)->init_temp) * \
+ (priv)->default_slope) / 1000) + \
+@@ -193,8 +204,39 @@
+
+ #define AIROHA_MAX_SAMPLES 6
+
++/*
++ * AN7583 supports all these ADC mux but the original driver
++ * always checked temp with the AN7583_BGP_TEMP_SENSOR.
++ * Assume using the other sensor temperature is invalid and
++ * always read from AN7583_BGP_TEMP_SENSOR.
++ *
++ * On top of this it's defined that AN7583 supports 3
++ * sensor: AN7583_BGP_TEMP_SENSOR, AN7583_GBE_TEMP_SENSOR,
++ * AN7583_CPU_TEMP_SENSOR.
++ *
++ * Provide the ADC mux for reference.
++ */
++enum an7583_thermal_adc_mux {
++ AN7583_BGP_TEMP_SENSOR,
++ AN7583_PAD_AVS,
++ AN7583_CORE_POWER,
++ AN7583_AVSDAC_OUT,
++ AN7583_VCM,
++ AN7583_GBE_TEMP_SENSOR,
++ AN7583_CPU_TEMP_SENSOR,
++
++ AN7583_ADC_MUX_MAX,
++};
++
++enum an7583_thermal_diode_mux {
++ AN7583_D0_TADC,
++ AN7583_ZERO_TADC,
++ AN7583_D1_TADC,
++};
++
+ enum airoha_thermal_chip_scu_field {
+ AIROHA_THERMAL_DOUT_TADC,
++ AIROHA_THERMAL_MUX_SENSOR,
+ AIROHA_THERMAL_MUX_TADC,
+
+ /* keep last */
+@@ -208,6 +250,7 @@ struct airoha_thermal_priv {
+ struct resource scu_adc_res;
+
+ u32 pllrg_protect;
++ int current_adc;
+
+ struct thermal_zone_device *tz;
+ int init_temp;
+@@ -224,6 +267,24 @@ struct airoha_thermal_soc_data {
+ int (*post_probe)(struct platform_device *pdev);
+ };
+
++static const unsigned int an7583_thermal_coeff[AN7583_ADC_MUX_MAX] = {
++ [AN7583_BGP_TEMP_SENSOR] = 973,
++ [AN7583_GBE_TEMP_SENSOR] = 995,
++ [AN7583_CPU_TEMP_SENSOR] = 1035,
++};
++
++static const unsigned int an7583_thermal_slope[AN7583_ADC_MUX_MAX] = {
++ [AN7583_BGP_TEMP_SENSOR] = 7440,
++ [AN7583_GBE_TEMP_SENSOR] = 7620,
++ [AN7583_CPU_TEMP_SENSOR] = 8390,
++};
++
++static const unsigned int an7583_thermal_offset[AN7583_ADC_MUX_MAX] = {
++ [AN7583_BGP_TEMP_SENSOR] = 294,
++ [AN7583_GBE_TEMP_SENSOR] = 298,
++ [AN7583_CPU_TEMP_SENSOR] = 344,
++};
++
+ static int airoha_get_thermal_ADC(struct airoha_thermal_priv *priv)
+ {
+ u32 val;
+@@ -234,7 +295,7 @@ static int airoha_get_thermal_ADC(struct
+ }
+
+ static void airoha_set_thermal_mux(struct airoha_thermal_priv *priv,
+- int tdac_idx)
++ int tdac_idx, int sensor_idx)
+ {
+ u32 pllrg;
+
+@@ -245,9 +306,20 @@ static void airoha_set_thermal_mux(struc
+ regmap_write(priv->chip_scu, EN7581_PLLRG_PROTECT,
+ priv->pllrg_protect);
+
++ /*
++ * Configure Thermal Sensor mux to sensor_idx.
++ * (if not supported, sensor_idx is AIROHA_THERMAL_NO_MUX_SENSOR)
++ */
++ if (sensor_idx != AIROHA_THERMAL_NO_MUX_SENSOR)
++ regmap_field_write(priv->chip_scu_fields[AIROHA_THERMAL_MUX_SENSOR],
++ sensor_idx);
++
+ /* Configure Thermal ADC mux to tdac_idx */
+- regmap_field_write(priv->chip_scu_fields[AIROHA_THERMAL_MUX_TADC],
+- tdac_idx);
++ if (priv->current_adc != tdac_idx) {
++ regmap_field_write(priv->chip_scu_fields[AIROHA_THERMAL_MUX_TADC],
++ tdac_idx);
++ priv->current_adc = tdac_idx;
++ }
+
+ /* Sleep 10 ms for Thermal ADC to enable */
+ usleep_range(10 * USEC_PER_MSEC, 11 * USEC_PER_MSEC);
+@@ -360,7 +432,8 @@ static void en7581_thermal_setup_adc_val
+ u32 efuse_calib_info, cpu_sensor;
+
+ /* Setup Thermal Sensor to ADC mode and setup the mux to DIODE1 */
+- airoha_set_thermal_mux(priv, EN7581_SCU_THERMAL_MUX_DIODE1);
++ airoha_set_thermal_mux(priv, EN7581_SCU_THERMAL_MUX_DIODE1,
++ AIROHA_THERMAL_NO_MUX_SENSOR);
+
+ regmap_read(priv->map, EN7581_EFUSE_TEMP_OFFSET_REG, &efuse_calib_info);
+ if (efuse_calib_info) {
+@@ -476,6 +549,10 @@ static int en7581_thermal_probe(struct p
+ for (i = 0; i < AIROHA_THERMAL_FIELD_MAX; i++) {
+ struct regmap_field *field;
+
++ /* Skip registering MUX_SENSOR field as not supported */
++ if (i == AIROHA_THERMAL_MUX_SENSOR)
++ continue;
++
+ field = devm_regmap_field_alloc(dev, priv->chip_scu,
+ en7581_chip_scu_fields[i]);
+ if (IS_ERR(field))
+@@ -516,6 +593,71 @@ static int en7581_thermal_post_probe(str
+ return 0;
+ }
+
++static int an7583_thermal_get_temp(struct thermal_zone_device *tz, int *temp)
++{
++ struct airoha_thermal_priv *priv = thermal_zone_device_priv(tz);
++ int sensor_idx;
++ int delta_diode, delta_gain;
++ int coeff, slope, offset;
++
++ int diode_zero, diode_d0, diode_d1;
++
++ /* Always read sensor AN7583_BGP_TEMP_SENSOR */
++ sensor_idx = AN7583_BGP_TEMP_SENSOR;
++
++ coeff = an7583_thermal_coeff[sensor_idx];
++ slope = an7583_thermal_slope[sensor_idx];
++ offset = an7583_thermal_offset[sensor_idx];
++
++ airoha_set_thermal_mux(priv, sensor_idx, AN7583_ZERO_TADC);
++ diode_zero = airoha_get_thermal_ADC(priv);
++ airoha_set_thermal_mux(priv, sensor_idx, AN7583_D0_TADC);
++ diode_d0 = airoha_get_thermal_ADC(priv);
++ airoha_set_thermal_mux(priv, sensor_idx, AN7583_D1_TADC);
++ diode_d1 = airoha_get_thermal_ADC(priv);
++
++ delta_diode = diode_d1 - diode_d0;
++ delta_gain = (delta_diode * coeff) / 100 + (diode_zero - diode_d1);
++ *temp = (slope * delta_diode * 10) / delta_gain - offset * 10;
++ *temp *= 100;
++
++ return 0;
++}
++
++static const struct thermal_zone_device_ops an7583_tz_ops = {
++ .get_temp = an7583_thermal_get_temp,
++};
++
++static const struct reg_field an7583_chip_scu_fields[AIROHA_THERMAL_FIELD_MAX] = {
++ [AIROHA_THERMAL_DOUT_TADC] = REG_FIELD(AN7583_DOUT_TADC, 0, 31),
++ [AIROHA_THERMAL_MUX_TADC] = REG_FIELD(AN7583_MUX_TADC, 1, 3),
++ [AIROHA_THERMAL_MUX_SENSOR] = REG_FIELD(AN7583_MUX_SENSOR, 2, 3),
++};
++
++static int an7583_thermal_probe(struct platform_device *pdev,
++ struct airoha_thermal_priv *priv)
++{
++ struct device *dev = &pdev->dev;
++ int i;
++
++ priv->chip_scu = device_node_to_regmap(dev->parent->of_node);
++ if (IS_ERR(priv->map))
++ return PTR_ERR(priv->map);
++
++ for (i = 0; i < AIROHA_THERMAL_FIELD_MAX; i++) {
++ struct regmap_field *field;
++
++ field = devm_regmap_field_alloc(dev, priv->chip_scu,
++ an7583_chip_scu_fields[i]);
++ if (IS_ERR(field))
++ return PTR_ERR(field);
++
++ priv->chip_scu_fields[i] = field;
++ }
++
++ return 0;
++}
++
+ static int airoha_thermal_probe(struct platform_device *pdev)
+ {
+ const struct airoha_thermal_soc_data *soc_data;
+@@ -530,6 +672,7 @@ static int airoha_thermal_probe(struct p
+ return -ENOMEM;
+
+ priv->pllrg_protect = soc_data->pllrg_protect;
++ priv->current_adc = -1;
+
+ if (!soc_data->probe)
+ return -EINVAL;
+@@ -558,8 +701,15 @@ static const struct airoha_thermal_soc_d
+ .post_probe = &en7581_thermal_post_probe,
+ };
+
++static const struct airoha_thermal_soc_data an7583_data = {
++ .pllrg_protect = AN7583_SCU_THERMAL_PROTECT_KEY,
++ .thdev_ops = &an7583_tz_ops,
++ .probe = &an7583_thermal_probe,
++};
++
+ static const struct of_device_id airoha_thermal_match[] = {
+ { .compatible = "airoha,en7581-thermal", .data = &en7581_data },
++ { .compatible = "airoha,an7583-thermal", .data = &an7583_data },
+ {},
+ };
+ MODULE_DEVICE_TABLE(of, airoha_thermal_match);
--- /dev/null
+From 8a38220c6bf6d79ecb1c95b083e062bd7221dea9 Mon Sep 17 00:00:00 2001
+From: Christian Marangi <ansuelsmth@gmail.com>
+Date: Sat, 9 Aug 2025 13:24:57 +0200
+Subject: [PATCH] cpufreq: airoha: Add support for AN7583 SoC
+
+New Airoha AN7583 SoC use the same exact logic to control the CPU
+frequency. Add the Device compatible to the block list for
+cpufreq-dt-plat and to the Airoha CPUFreq driver compatible list.
+
+Signed-off-by: Christian Marangi <ansuelsmth@gmail.com>
+---
+ drivers/cpufreq/airoha-cpufreq.c | 1 +
+ drivers/cpufreq/cpufreq-dt-platdev.c | 1 +
+ 2 files changed, 2 insertions(+)
+
+--- a/drivers/cpufreq/airoha-cpufreq.c
++++ b/drivers/cpufreq/airoha-cpufreq.c
+@@ -121,6 +121,7 @@ static struct platform_driver airoha_cpu
+ };
+
+ static const struct of_device_id airoha_cpufreq_match_list[] __initconst = {
++ { .compatible = "airoha,an7583" },
+ { .compatible = "airoha,en7581" },
+ {},
+ };
+--- a/drivers/cpufreq/cpufreq-dt-platdev.c
++++ b/drivers/cpufreq/cpufreq-dt-platdev.c
+@@ -103,6 +103,7 @@ static const struct of_device_id allowli
+ * platforms using "operating-points-v2" property.
+ */
+ static const struct of_device_id blocklist[] __initconst = {
++ { .compatible = "airoha,an7583", },
+ { .compatible = "airoha,en7581", },
+
+ { .compatible = "allwinner,sun50i-h6", },
--- /dev/null
+From 8d5a00b3b83f76d255bcffc91d5263f72b27547a Mon Sep 17 00:00:00 2001
+From: Christian Marangi <ansuelsmth@gmail.com>
+Date: Fri, 7 Feb 2025 23:51:23 +0100
+Subject: [PATCH 01/10] clk: en7523: convert driver to regmap API
+
+Convert driver to regmap API, in preparation for support of Airoha
+AN7523 as the SCU will be an MFD and the regmap will be provided in the
+parent node.
+
+Signed-off-by: Christian Marangi <ansuelsmth@gmail.com>
+---
+ drivers/clk/clk-en7523.c | 137 ++++++++++++++++++++++-----------------
+ 1 file changed, 76 insertions(+), 61 deletions(-)
+
+--- a/drivers/clk/clk-en7523.c
++++ b/drivers/clk/clk-en7523.c
+@@ -1,5 +1,6 @@
+ // SPDX-License-Identifier: GPL-2.0-only
+
++#include <linux/bitfield.h>
+ #include <linux/delay.h>
+ #include <linux/clk-provider.h>
+ #include <linux/io.h>
+@@ -34,6 +35,7 @@
+ #define REG_RESET_CONTROL_PCIE2 BIT(26)
+ /* EN7581 */
+ #define REG_NP_SCU_PCIC 0x88
++#define REG_PCIE_CTRL GENMASK(7, 0)
+ #define REG_NP_SCU_SSTR 0x9c
+ #define REG_PCIE_XSI0_SEL_MASK GENMASK(14, 13)
+ #define REG_PCIE_XSI1_SEL_MASK GENMASK(12, 11)
+@@ -63,14 +65,14 @@ struct en_clk_desc {
+ };
+
+ struct en_clk_gate {
+- void __iomem *base;
++ struct regmap *map;
+ struct clk_hw hw;
+ };
+
+ struct en_rst_data {
+ const u16 *bank_ofs;
+ const u16 *idx_map;
+- void __iomem *base;
++ struct regmap *map;
+ struct reset_controller_dev rcdev;
+ };
+
+@@ -388,44 +390,44 @@ static u32 en7523_get_div(const struct e
+ static int en7523_pci_is_enabled(struct clk_hw *hw)
+ {
+ struct en_clk_gate *cg = container_of(hw, struct en_clk_gate, hw);
++ u32 val;
+
+- return !!(readl(cg->base + REG_PCI_CONTROL) & REG_PCI_CONTROL_REFCLK_EN1);
++ regmap_read(cg->map, REG_PCI_CONTROL, &val);
++ return !!(val & REG_PCI_CONTROL_REFCLK_EN1);
+ }
+
+ static int en7523_pci_prepare(struct clk_hw *hw)
+ {
+ struct en_clk_gate *cg = container_of(hw, struct en_clk_gate, hw);
+- void __iomem *np_base = cg->base;
+- u32 val, mask;
++ struct regmap *map = cg->map;
++ u32 mask;
+
+ /* Need to pull device low before reset */
+- val = readl(np_base + REG_PCI_CONTROL);
+- val &= ~(REG_PCI_CONTROL_PERSTOUT1 | REG_PCI_CONTROL_PERSTOUT);
+- writel(val, np_base + REG_PCI_CONTROL);
++ regmap_clear_bits(map, REG_PCI_CONTROL,
++ REG_PCI_CONTROL_PERSTOUT1 |
++ REG_PCI_CONTROL_PERSTOUT);
+ usleep_range(1000, 2000);
+
+ /* Enable PCIe port 1 */
+- val |= REG_PCI_CONTROL_REFCLK_EN1;
+- writel(val, np_base + REG_PCI_CONTROL);
++ regmap_set_bits(map, REG_PCI_CONTROL,
++ REG_PCI_CONTROL_REFCLK_EN1);
+ usleep_range(1000, 2000);
+
+ /* Reset to default */
+- val = readl(np_base + REG_RESET_CONTROL1);
+ mask = REG_RESET_CONTROL_PCIE1 | REG_RESET_CONTROL_PCIE2 |
+ REG_RESET_CONTROL_PCIEHB;
+- writel(val & ~mask, np_base + REG_RESET_CONTROL1);
++ regmap_clear_bits(map, REG_RESET_CONTROL1, mask);
+ usleep_range(1000, 2000);
+- writel(val | mask, np_base + REG_RESET_CONTROL1);
++ regmap_set_bits(map, REG_RESET_CONTROL1, mask);
+ msleep(100);
+- writel(val & ~mask, np_base + REG_RESET_CONTROL1);
++ regmap_clear_bits(map, REG_RESET_CONTROL1, mask);
+ usleep_range(5000, 10000);
+
+ /* Release device */
+ mask = REG_PCI_CONTROL_PERSTOUT1 | REG_PCI_CONTROL_PERSTOUT;
+- val = readl(np_base + REG_PCI_CONTROL);
+- writel(val & ~mask, np_base + REG_PCI_CONTROL);
++ regmap_clear_bits(map, REG_PCI_CONTROL, mask);
+ usleep_range(1000, 2000);
+- writel(val | mask, np_base + REG_PCI_CONTROL);
++ regmap_set_bits(map, REG_PCI_CONTROL, mask);
+ msleep(250);
+
+ return 0;
+@@ -434,16 +436,13 @@ static int en7523_pci_prepare(struct clk
+ static void en7523_pci_unprepare(struct clk_hw *hw)
+ {
+ struct en_clk_gate *cg = container_of(hw, struct en_clk_gate, hw);
+- void __iomem *np_base = cg->base;
+- u32 val;
++ struct regmap *map = cg->map;
+
+- val = readl(np_base + REG_PCI_CONTROL);
+- val &= ~REG_PCI_CONTROL_REFCLK_EN1;
+- writel(val, np_base + REG_PCI_CONTROL);
++ regmap_clear_bits(map, REG_PCI_CONTROL, REG_PCI_CONTROL_REFCLK_EN1);
+ }
+
+ static struct clk_hw *en7523_register_pcie_clk(struct device *dev,
+- void __iomem *np_base)
++ struct regmap *clk_map)
+ {
+ const struct en_clk_soc_data *soc_data = device_get_match_data(dev);
+ struct clk_init_data init = {
+@@ -456,7 +455,7 @@ static struct clk_hw *en7523_register_pc
+ if (!cg)
+ return NULL;
+
+- cg->base = np_base;
++ cg->map = clk_map;
+ cg->hw.init = &init;
+
+ if (init.ops->unprepare)
+@@ -474,21 +473,20 @@ static int en7581_pci_is_enabled(struct
+ u32 val, mask;
+
+ mask = REG_PCI_CONTROL_REFCLK_EN0 | REG_PCI_CONTROL_REFCLK_EN1;
+- val = readl(cg->base + REG_PCI_CONTROL);
++ regmap_read(cg->map, REG_PCI_CONTROL, &val);
+ return (val & mask) == mask;
+ }
+
+ static int en7581_pci_enable(struct clk_hw *hw)
+ {
+ struct en_clk_gate *cg = container_of(hw, struct en_clk_gate, hw);
+- void __iomem *np_base = cg->base;
+- u32 val, mask;
++ struct regmap *map = cg->map;
++ u32 mask;
+
+ mask = REG_PCI_CONTROL_REFCLK_EN0 | REG_PCI_CONTROL_REFCLK_EN1 |
+ REG_PCI_CONTROL_PERSTOUT1 | REG_PCI_CONTROL_PERSTOUT2 |
+ REG_PCI_CONTROL_PERSTOUT;
+- val = readl(np_base + REG_PCI_CONTROL);
+- writel(val | mask, np_base + REG_PCI_CONTROL);
++ regmap_set_bits(map, REG_PCI_CONTROL, mask);
+
+ return 0;
+ }
+@@ -496,19 +494,18 @@ static int en7581_pci_enable(struct clk_
+ static void en7581_pci_disable(struct clk_hw *hw)
+ {
+ struct en_clk_gate *cg = container_of(hw, struct en_clk_gate, hw);
+- void __iomem *np_base = cg->base;
+- u32 val, mask;
++ struct regmap *map = cg->map;
++ u32 mask;
+
+ mask = REG_PCI_CONTROL_REFCLK_EN0 | REG_PCI_CONTROL_REFCLK_EN1 |
+ REG_PCI_CONTROL_PERSTOUT1 | REG_PCI_CONTROL_PERSTOUT2 |
+ REG_PCI_CONTROL_PERSTOUT;
+- val = readl(np_base + REG_PCI_CONTROL);
+- writel(val & ~mask, np_base + REG_PCI_CONTROL);
++ regmap_clear_bits(map, REG_PCI_CONTROL, mask);
+ usleep_range(1000, 2000);
+ }
+
+ static void en7523_register_clocks(struct device *dev, struct clk_hw_onecell_data *clk_data,
+- void __iomem *base, void __iomem *np_base)
++ struct regmap *map, struct regmap *clk_map)
+ {
+ struct clk_hw *hw;
+ u32 rate;
+@@ -517,10 +514,12 @@ static void en7523_register_clocks(struc
+ for (i = 0; i < ARRAY_SIZE(en7523_base_clks); i++) {
+ const struct en_clk_desc *desc = &en7523_base_clks[i];
+ u32 reg = desc->div_reg ? desc->div_reg : desc->base_reg;
+- u32 val = readl(base + desc->base_reg);
++ u32 val;
++
++ regmap_read(map, desc->base_reg, &val);
+
+ rate = en7523_get_base_rate(desc, val);
+- val = readl(base + reg);
++ regmap_read(map, reg, &val);
+ rate /= en7523_get_div(desc, val);
+
+ hw = clk_hw_register_fixed_rate(dev, desc->name, NULL, 0, rate);
+@@ -533,30 +532,47 @@ static void en7523_register_clocks(struc
+ clk_data->hws[desc->id] = hw;
+ }
+
+- hw = en7523_register_pcie_clk(dev, np_base);
++ hw = en7523_register_pcie_clk(dev, clk_map);
+ clk_data->hws[EN7523_CLK_PCIE] = hw;
+ }
+
++static const struct regmap_config en7523_clk_regmap_config = {
++ .reg_bits = 32,
++ .val_bits = 32,
++ .reg_stride = 4,
++};
++
+ static int en7523_clk_hw_init(struct platform_device *pdev,
+ struct clk_hw_onecell_data *clk_data)
+ {
+ void __iomem *base, *np_base;
++ struct regmap *map, *clk_map;
+
+ base = devm_platform_ioremap_resource(pdev, 0);
+ if (IS_ERR(base))
+ return PTR_ERR(base);
+
++ map = devm_regmap_init_mmio(&pdev->dev, base,
++ &en7523_clk_regmap_config);
++ if (IS_ERR(map))
++ return PTR_ERR(map);
++
+ np_base = devm_platform_ioremap_resource(pdev, 1);
+ if (IS_ERR(np_base))
+ return PTR_ERR(np_base);
+
+- en7523_register_clocks(&pdev->dev, clk_data, base, np_base);
++ clk_map = devm_regmap_init_mmio(&pdev->dev, np_base,
++ &en7523_clk_regmap_config);
++ if (IS_ERR(clk_map))
++ return PTR_ERR(clk_map);
++
++ en7523_register_clocks(&pdev->dev, clk_data, map, clk_map);
+
+ return 0;
+ }
+
+ static void en7581_register_clocks(struct device *dev, struct clk_hw_onecell_data *clk_data,
+- struct regmap *map, void __iomem *base)
++ struct regmap *map, struct regmap *clk_map)
+ {
+ struct clk_hw *hw;
+ u32 rate;
+@@ -593,7 +609,7 @@ static void en7581_register_clocks(struc
+ clk_data->hws[desc->id] = hw;
+ }
+
+- hw = en7523_register_pcie_clk(dev, base);
++ hw = en7523_register_pcie_clk(dev, clk_map);
+ clk_data->hws[EN7523_CLK_PCIE] = hw;
+ }
+
+@@ -601,15 +617,10 @@ static int en7523_reset_update(struct re
+ unsigned long id, bool assert)
+ {
+ struct en_rst_data *rst_data = container_of(rcdev, struct en_rst_data, rcdev);
+- void __iomem *addr = rst_data->base + rst_data->bank_ofs[id / RST_NR_PER_BANK];
+- u32 val;
++ u32 addr = rst_data->bank_ofs[id / RST_NR_PER_BANK];
+
+- val = readl(addr);
+- if (assert)
+- val |= BIT(id % RST_NR_PER_BANK);
+- else
+- val &= ~BIT(id % RST_NR_PER_BANK);
+- writel(val, addr);
++ regmap_update_bits(rst_data->map, addr, BIT(id % RST_NR_PER_BANK),
++ assert ? BIT(id % RST_NR_PER_BANK) : 0);
+
+ return 0;
+ }
+@@ -630,9 +641,11 @@ static int en7523_reset_status(struct re
+ unsigned long id)
+ {
+ struct en_rst_data *rst_data = container_of(rcdev, struct en_rst_data, rcdev);
+- void __iomem *addr = rst_data->base + rst_data->bank_ofs[id / RST_NR_PER_BANK];
++ u32 addr = rst_data->bank_ofs[id / RST_NR_PER_BANK];
++ u32 val;
+
+- return !!(readl(addr) & BIT(id % RST_NR_PER_BANK));
++ regmap_read(rst_data->map, addr, &val);
++ return !!(val & BIT(id % RST_NR_PER_BANK));
+ }
+
+ static int en7523_reset_xlate(struct reset_controller_dev *rcdev,
+@@ -652,7 +665,7 @@ static const struct reset_control_ops en
+ .status = en7523_reset_status,
+ };
+
+-static int en7581_reset_register(struct device *dev, void __iomem *base)
++static int en7581_reset_register(struct device *dev, struct regmap *map)
+ {
+ struct en_rst_data *rst_data;
+
+@@ -662,7 +675,7 @@ static int en7581_reset_register(struct
+
+ rst_data->bank_ofs = en7581_rst_ofs;
+ rst_data->idx_map = en7581_rst_map;
+- rst_data->base = base;
++ rst_data->map = map;
+
+ rst_data->rcdev.nr_resets = ARRAY_SIZE(en7581_rst_map);
+ rst_data->rcdev.of_xlate = en7523_reset_xlate;
+@@ -678,9 +691,8 @@ static int en7581_reset_register(struct
+ static int en7581_clk_hw_init(struct platform_device *pdev,
+ struct clk_hw_onecell_data *clk_data)
+ {
+- struct regmap *map;
++ struct regmap *map, *clk_map;
+ void __iomem *base;
+- u32 val;
+
+ map = syscon_regmap_lookup_by_compatible("airoha,en7581-chip-scu");
+ if (IS_ERR(map))
+@@ -690,15 +702,18 @@ static int en7581_clk_hw_init(struct pla
+ if (IS_ERR(base))
+ return PTR_ERR(base);
+
+- en7581_register_clocks(&pdev->dev, clk_data, map, base);
+-
+- val = readl(base + REG_NP_SCU_SSTR);
+- val &= ~(REG_PCIE_XSI0_SEL_MASK | REG_PCIE_XSI1_SEL_MASK);
+- writel(val, base + REG_NP_SCU_SSTR);
+- val = readl(base + REG_NP_SCU_PCIC);
+- writel(val | 3, base + REG_NP_SCU_PCIC);
++ clk_map = devm_regmap_init_mmio(&pdev->dev, base, &en7523_clk_regmap_config);
++ if (IS_ERR(clk_map))
++ return PTR_ERR(clk_map);
++
++ en7581_register_clocks(&pdev->dev, clk_data, map, clk_map);
++
++ regmap_clear_bits(clk_map, REG_NP_SCU_SSTR,
++ REG_PCIE_XSI0_SEL_MASK | REG_PCIE_XSI1_SEL_MASK);
++ regmap_update_bits(clk_map, REG_NP_SCU_PCIC, REG_PCIE_CTRL,
++ FIELD_PREP(REG_PCIE_CTRL, 3));
+
+- return en7581_reset_register(&pdev->dev, base);
++ return en7581_reset_register(&pdev->dev, clk_map);
+ }
+
+ static int en7523_clk_probe(struct platform_device *pdev)
--- /dev/null
+From 36a3a919391dea2000f355125f0a161c453fcf78 Mon Sep 17 00:00:00 2001
+From: Christian Marangi <ansuelsmth@gmail.com>
+Date: Sat, 8 Feb 2025 00:08:08 +0100
+Subject: [PATCH 02/10] clk: en7523: generalize register clocks function
+
+Generalize register clocks function for Airoha EN7523 and EN7581 clocks
+driver. The same logic is applied for both clock hence code can be
+reduced and simplified by putting the base_clocks struct in the soc_data
+and passing that to a generic register clocks function.
+
+While at it rework some function to return error and use devm variant
+for clk_hw_regiser.
+
+Signed-off-by: Christian Marangi <ansuelsmth@gmail.com>
+---
+ drivers/clk/clk-en7523.c | 148 +++++++++++++++++----------------------
+ 1 file changed, 66 insertions(+), 82 deletions(-)
+
+--- a/drivers/clk/clk-en7523.c
++++ b/drivers/clk/clk-en7523.c
+@@ -78,8 +78,10 @@ struct en_rst_data {
+
+ struct en_clk_soc_data {
+ u32 num_clocks;
++ const struct en_clk_desc *base_clks;
+ const struct clk_ops pcie_ops;
+ int (*hw_init)(struct platform_device *pdev,
++ const struct en_clk_soc_data *soc_data,
+ struct clk_hw_onecell_data *clk_data);
+ };
+
+@@ -450,10 +452,11 @@ static struct clk_hw *en7523_register_pc
+ .ops = &soc_data->pcie_ops,
+ };
+ struct en_clk_gate *cg;
++ int err;
+
+ cg = devm_kzalloc(dev, sizeof(*cg), GFP_KERNEL);
+ if (!cg)
+- return NULL;
++ return ERR_PTR(-ENOMEM);
+
+ cg->map = clk_map;
+ cg->hw.init = &init;
+@@ -461,12 +464,62 @@ static struct clk_hw *en7523_register_pc
+ if (init.ops->unprepare)
+ init.ops->unprepare(&cg->hw);
+
+- if (clk_hw_register(dev, &cg->hw))
+- return NULL;
++ err = devm_clk_hw_register(dev, &cg->hw);
++ if (err)
++ return ERR_PTR(err);
+
+ return &cg->hw;
+ }
+
++static int en75xx_register_clocks(struct device *dev,
++ const struct en_clk_soc_data *soc_data,
++ struct clk_hw_onecell_data *clk_data,
++ struct regmap *map, struct regmap *clk_map)
++{
++ struct clk_hw *hw;
++ u32 rate;
++ int i;
++
++ for (i = 0; i < soc_data->num_clocks - 1; i++) {
++ const struct en_clk_desc *desc = &soc_data->base_clks[i];
++ u32 val, reg = desc->div_reg ? desc->div_reg : desc->base_reg;
++ int err;
++
++ err = regmap_read(map, desc->base_reg, &val);
++ if (err) {
++ pr_err("Failed reading fixed clk rate %s: %d\n",
++ desc->name, err);
++ return err;
++ }
++ rate = en7523_get_base_rate(desc, val);
++
++ err = regmap_read(map, reg, &val);
++ if (err) {
++ pr_err("Failed reading fixed clk div %s: %d\n",
++ desc->name, err);
++ return err;
++ }
++ rate /= en7523_get_div(desc, val);
++
++ hw = clk_hw_register_fixed_rate(dev, desc->name, NULL, 0, rate);
++ if (IS_ERR(hw)) {
++ pr_err("Failed to register clk %s: %ld\n",
++ desc->name, PTR_ERR(hw));
++ return PTR_ERR(hw);
++ }
++
++ clk_data->hws[desc->id] = hw;
++ }
++
++ hw = en7523_register_pcie_clk(dev, clk_map);
++ if (IS_ERR(hw))
++ return PTR_ERR(hw);
++
++ clk_data->hws[EN7523_CLK_PCIE] = hw;
++
++ return 0;
++}
++
+ static int en7581_pci_is_enabled(struct clk_hw *hw)
+ {
+ struct en_clk_gate *cg = container_of(hw, struct en_clk_gate, hw);
+@@ -504,38 +557,6 @@ static void en7581_pci_disable(struct cl
+ usleep_range(1000, 2000);
+ }
+
+-static void en7523_register_clocks(struct device *dev, struct clk_hw_onecell_data *clk_data,
+- struct regmap *map, struct regmap *clk_map)
+-{
+- struct clk_hw *hw;
+- u32 rate;
+- int i;
+-
+- for (i = 0; i < ARRAY_SIZE(en7523_base_clks); i++) {
+- const struct en_clk_desc *desc = &en7523_base_clks[i];
+- u32 reg = desc->div_reg ? desc->div_reg : desc->base_reg;
+- u32 val;
+-
+- regmap_read(map, desc->base_reg, &val);
+-
+- rate = en7523_get_base_rate(desc, val);
+- regmap_read(map, reg, &val);
+- rate /= en7523_get_div(desc, val);
+-
+- hw = clk_hw_register_fixed_rate(dev, desc->name, NULL, 0, rate);
+- if (IS_ERR(hw)) {
+- pr_err("Failed to register clk %s: %ld\n",
+- desc->name, PTR_ERR(hw));
+- continue;
+- }
+-
+- clk_data->hws[desc->id] = hw;
+- }
+-
+- hw = en7523_register_pcie_clk(dev, clk_map);
+- clk_data->hws[EN7523_CLK_PCIE] = hw;
+-}
+-
+ static const struct regmap_config en7523_clk_regmap_config = {
+ .reg_bits = 32,
+ .val_bits = 32,
+@@ -543,6 +564,7 @@ static const struct regmap_config en7523
+ };
+
+ static int en7523_clk_hw_init(struct platform_device *pdev,
++ const struct en_clk_soc_data *soc_data,
+ struct clk_hw_onecell_data *clk_data)
+ {
+ void __iomem *base, *np_base;
+@@ -566,51 +588,7 @@ static int en7523_clk_hw_init(struct pla
+ if (IS_ERR(clk_map))
+ return PTR_ERR(clk_map);
+
+- en7523_register_clocks(&pdev->dev, clk_data, map, clk_map);
+-
+- return 0;
+-}
+-
+-static void en7581_register_clocks(struct device *dev, struct clk_hw_onecell_data *clk_data,
+- struct regmap *map, struct regmap *clk_map)
+-{
+- struct clk_hw *hw;
+- u32 rate;
+- int i;
+-
+- for (i = 0; i < ARRAY_SIZE(en7581_base_clks); i++) {
+- const struct en_clk_desc *desc = &en7581_base_clks[i];
+- u32 val, reg = desc->div_reg ? desc->div_reg : desc->base_reg;
+- int err;
+-
+- err = regmap_read(map, desc->base_reg, &val);
+- if (err) {
+- pr_err("Failed reading fixed clk rate %s: %d\n",
+- desc->name, err);
+- continue;
+- }
+- rate = en7523_get_base_rate(desc, val);
+-
+- err = regmap_read(map, reg, &val);
+- if (err) {
+- pr_err("Failed reading fixed clk div %s: %d\n",
+- desc->name, err);
+- continue;
+- }
+- rate /= en7523_get_div(desc, val);
+-
+- hw = clk_hw_register_fixed_rate(dev, desc->name, NULL, 0, rate);
+- if (IS_ERR(hw)) {
+- pr_err("Failed to register clk %s: %ld\n",
+- desc->name, PTR_ERR(hw));
+- continue;
+- }
+-
+- clk_data->hws[desc->id] = hw;
+- }
+-
+- hw = en7523_register_pcie_clk(dev, clk_map);
+- clk_data->hws[EN7523_CLK_PCIE] = hw;
++ return en75xx_register_clocks(&pdev->dev, soc_data, clk_data, map, clk_map);
+ }
+
+ static int en7523_reset_update(struct reset_controller_dev *rcdev,
+@@ -689,10 +667,12 @@ static int en7581_reset_register(struct
+ }
+
+ static int en7581_clk_hw_init(struct platform_device *pdev,
++ const struct en_clk_soc_data *soc_data,
+ struct clk_hw_onecell_data *clk_data)
+ {
+ struct regmap *map, *clk_map;
+ void __iomem *base;
++ int ret;
+
+ map = syscon_regmap_lookup_by_compatible("airoha,en7581-chip-scu");
+ if (IS_ERR(map))
+@@ -706,7 +686,9 @@ static int en7581_clk_hw_init(struct pla
+ if (IS_ERR(clk_map))
+ return PTR_ERR(clk_map);
+
+- en7581_register_clocks(&pdev->dev, clk_data, map, clk_map);
++ ret = en75xx_register_clocks(&pdev->dev, soc_data, clk_data, map, clk_map);
++ if (ret)
++ return ret;
+
+ regmap_clear_bits(clk_map, REG_NP_SCU_SSTR,
+ REG_PCIE_XSI0_SEL_MASK | REG_PCIE_XSI1_SEL_MASK);
+@@ -732,7 +714,7 @@ static int en7523_clk_probe(struct platf
+ return -ENOMEM;
+
+ clk_data->num = soc_data->num_clocks;
+- r = soc_data->hw_init(pdev, clk_data);
++ r = soc_data->hw_init(pdev, soc_data, clk_data);
+ if (r)
+ return r;
+
+@@ -740,6 +722,7 @@ static int en7523_clk_probe(struct platf
+ }
+
+ static const struct en_clk_soc_data en7523_data = {
++ .base_clks = en7523_base_clks,
+ .num_clocks = ARRAY_SIZE(en7523_base_clks) + 1,
+ .pcie_ops = {
+ .is_enabled = en7523_pci_is_enabled,
+@@ -750,6 +733,7 @@ static const struct en_clk_soc_data en75
+ };
+
+ static const struct en_clk_soc_data en7581_data = {
++ .base_clks = en7581_base_clks,
+ /* We increment num_clocks by 1 to account for additional PCIe clock */
+ .num_clocks = ARRAY_SIZE(en7581_base_clks) + 1,
+ .pcie_ops = {
--- /dev/null
+From 933030fd268ac111eb9db13b5a90b7c66cd9df41 Mon Sep 17 00:00:00 2001
+From: Christian Marangi <ansuelsmth@gmail.com>
+Date: Tue, 17 Jun 2025 11:38:21 +0200
+Subject: [PATCH 03/10] clk: en7523: convert to full clk_hw implementation
+
+In preparation for support of .set_rate, convert the clock register
+logic from fixed clock implementation to full clk_hw implementation with
+dedicated OPs.
+
+This is just a rework and no behaviour change is expected.
+
+Signed-off-by: Christian Marangi <ansuelsmth@gmail.com>
+---
+ drivers/clk/clk-en7523.c | 83 ++++++++++++++++++++++++++++------------
+ 1 file changed, 59 insertions(+), 24 deletions(-)
+
+--- a/drivers/clk/clk-en7523.c
++++ b/drivers/clk/clk-en7523.c
+@@ -69,6 +69,12 @@ struct en_clk_gate {
+ struct clk_hw hw;
+ };
+
++struct en_clk {
++ struct regmap *map;
++ const struct en_clk_desc *desc;
++ struct clk_hw hw;
++};
++
+ struct en_rst_data {
+ const u16 *bank_ofs;
+ const u16 *idx_map;
+@@ -471,44 +477,73 @@ static struct clk_hw *en7523_register_pc
+ return &cg->hw;
+ }
+
++static unsigned long en75xx_recalc_rate(struct clk_hw *hw,
++ unsigned long parent_rate)
++{
++ struct en_clk *c = container_of(hw, struct en_clk, hw);
++ const struct en_clk_desc *desc = c->desc;
++ struct regmap *map = c->map;
++ u32 val, reg;
++ u32 rate;
++ int err;
++
++ err = regmap_read(map, desc->base_reg, &val);
++ if (err) {
++ pr_err("Failed reading fixed clk rate %s: %d\n",
++ desc->name, err);
++ return err;
++ }
++ rate = en7523_get_base_rate(desc, val);
++
++ reg = desc->div_reg ? desc->div_reg : desc->base_reg;
++ err = regmap_read(map, reg, &val);
++ if (err) {
++ pr_err("Failed reading fixed clk div %s: %d\n",
++ desc->name, err);
++ return err;
++ }
++
++ return rate / en7523_get_div(desc, val);
++}
++
++static const struct clk_ops en75xx_clk_ops = {
++ .recalc_rate = en75xx_recalc_rate,
++};
++
+ static int en75xx_register_clocks(struct device *dev,
+ const struct en_clk_soc_data *soc_data,
+ struct clk_hw_onecell_data *clk_data,
+ struct regmap *map, struct regmap *clk_map)
+ {
+ struct clk_hw *hw;
+- u32 rate;
+ int i;
+
+ for (i = 0; i < soc_data->num_clocks - 1; i++) {
+ const struct en_clk_desc *desc = &soc_data->base_clks[i];
+- u32 val, reg = desc->div_reg ? desc->div_reg : desc->base_reg;
++ struct clk_init_data init = {
++ .ops = &en75xx_clk_ops,
++ };
++ struct en_clk *en_clk;
+ int err;
+
+- err = regmap_read(map, desc->base_reg, &val);
+- if (err) {
+- pr_err("Failed reading fixed clk rate %s: %d\n",
+- desc->name, err);
+- return err;
+- }
+- rate = en7523_get_base_rate(desc, val);
++ en_clk = devm_kzalloc(dev, sizeof(*en_clk), GFP_KERNEL);
++ if (!en_clk)
++ return -ENOMEM;
+
+- err = regmap_read(map, reg, &val);
++ init.name = desc->name;
++
++ en_clk->map = map;
++ en_clk->desc = desc;
++ en_clk->hw.init = &init;
++
++ err = devm_clk_hw_register(dev, &en_clk->hw);
+ if (err) {
+- pr_err("Failed reading fixed clk div %s: %d\n",
++ pr_err("Failed to register clk %s: %d\n",
+ desc->name, err);
+ return err;
+ }
+- rate /= en7523_get_div(desc, val);
+-
+- hw = clk_hw_register_fixed_rate(dev, desc->name, NULL, 0, rate);
+- if (IS_ERR(hw)) {
+- pr_err("Failed to register clk %s: %ld\n",
+- desc->name, PTR_ERR(hw));
+- return PTR_ERR(hw);
+- }
+
+- clk_data->hws[desc->id] = hw;
++ clk_data->hws[desc->id] = &en_clk->hw;
+ }
+
+ hw = en7523_register_pcie_clk(dev, clk_map);
+@@ -672,7 +707,7 @@ static int en7581_clk_hw_init(struct pla
+ {
+ struct regmap *map, *clk_map;
+ void __iomem *base;
+- int ret;
++ int err;
+
+ map = syscon_regmap_lookup_by_compatible("airoha,en7581-chip-scu");
+ if (IS_ERR(map))
+@@ -686,9 +721,9 @@ static int en7581_clk_hw_init(struct pla
+ if (IS_ERR(clk_map))
+ return PTR_ERR(clk_map);
+
+- ret = en75xx_register_clocks(&pdev->dev, soc_data, clk_data, map, clk_map);
+- if (ret)
+- return ret;
++ err = en75xx_register_clocks(&pdev->dev, soc_data, clk_data, map, clk_map);
++ if (err)
++ return err;
+
+ regmap_clear_bits(clk_map, REG_NP_SCU_SSTR,
+ REG_PCIE_XSI0_SEL_MASK | REG_PCIE_XSI1_SEL_MASK);
--- /dev/null
+From fe71e8f734a5c9b808a68b8abaa0156de605df4f Mon Sep 17 00:00:00 2001
+From: Christian Marangi <ansuelsmth@gmail.com>
+Date: Tue, 17 Jun 2025 12:28:41 +0200
+Subject: [PATCH 04/10] clk: en7523: add support for .set_rate
+
+Add support for EN7523 driver to configure rate. The SoC expose both
+base clock selector and clock divisor hence it's possible to change the
+rate.
+
+This will be especially needed for new SoC AN7583 that require changes
+for the MDIO and the eMMC.
+
+The clock were assumed correctly configured by the bootloader but this
+goes against the rule of "kernel should not depend on external
+configuration".
+
+Signed-off-by: Christian Marangi <ansuelsmth@gmail.com>
+---
+ drivers/clk/clk-en7523.c | 141 +++++++++++++++++++++++++++++++++++++++
+ 1 file changed, 141 insertions(+)
+
+--- a/drivers/clk/clk-en7523.c
++++ b/drivers/clk/clk-en7523.c
+@@ -506,8 +506,149 @@ static unsigned long en75xx_recalc_rate(
+ return rate / en7523_get_div(desc, val);
+ }
+
++static int en75xx_get_base_val_for_rate(const struct en_clk_desc *desc,
++ int div, unsigned long rate)
++{
++ int i;
++
++ /* Single base rate */
++ if (!desc->base_bits) {
++ if (rate != desc->base_value / div)
++ goto err;
++
++ return 0;
++ }
++
++ /* Check every base rate with provided divisor */
++ for (i = 0; i < desc->n_base_values; i++)
++ if (rate == desc->base_values[i] / div)
++ return i;
++
++err:
++ return -EINVAL;
++}
++
++static int en75xx_get_vals_for_rate(const struct en_clk_desc *desc,
++ unsigned long rate,
++ u32 *base_val, u32 *div_val)
++{
++ int tmp_base_val = 0;
++ int tmp_div_val = 0;
++
++ if (!desc->base_bits && !desc->div_bits)
++ return -EINVAL;
++
++ /* Divisor not supported, just search in base rate */
++ if (!desc->div_bits) {
++ tmp_base_val = en75xx_get_base_val_for_rate(desc, 1, rate);
++ if (tmp_base_val < 0) {
++ pr_err("Invalid rate for clock %s\n",
++ desc->name);
++ return -EINVAL;
++ }
++
++ goto exit;
++ }
++
++ /* Check if div0 satisfy the request */
++ if (desc->div_val0) {
++ tmp_base_val = en75xx_get_base_val_for_rate(desc,
++ desc->div_val0,
++ rate);
++ if (tmp_base_val >= 0)
++ goto exit;
++
++ /* Skip checking first divisor val */
++ tmp_div_val = 1;
++ }
++
++ /* Simulate rate with every divisor supported */
++ for (; tmp_div_val < BIT(desc->div_bits); tmp_div_val++) {
++ int div = (tmp_div_val + desc->div_offset) * desc->div_step;
++
++ tmp_base_val = en75xx_get_base_val_for_rate(desc, div,
++ rate);
++ if (tmp_base_val >= 0)
++ goto exit;
++ }
++
++ if (tmp_div_val == BIT(desc->div_bits)) {
++ pr_err("Invalid rate for clock %s\n",
++ desc->name);
++ return -EINVAL;
++ }
++
++exit:
++ *base_val = tmp_base_val;
++ *div_val = tmp_div_val;
++
++ return 0;
++}
++
++static long en75xx_round_rate(struct clk_hw *hw, unsigned long rate,
++ unsigned long *parent_rate)
++{
++ struct en_clk *en_clk = container_of(hw, struct en_clk, hw);
++ u32 div_val, base_val;
++ int err;
++
++ /* Just check if the rate is possible */
++ err = en75xx_get_vals_for_rate(en_clk->desc, rate,
++ &base_val, &div_val);
++ if (err)
++ return err;
++
++ return rate;
++}
++
++static int en75xx_set_rate(struct clk_hw *hw, unsigned long rate,
++ unsigned long parent_rate)
++{
++ struct en_clk *en_clk = container_of(hw, struct en_clk, hw);
++ const struct en_clk_desc *desc = en_clk->desc;
++ struct regmap *map = en_clk->map;
++ u32 base_val, div_val;
++ u32 reg, val, mask;
++ int err;
++
++ err = en75xx_get_vals_for_rate(en_clk->desc, rate,
++ &base_val, &div_val);
++ if (err)
++ return err;
++
++ if (desc->div_bits) {
++ reg = desc->div_reg ? desc->div_reg : desc->base_reg;
++
++ mask = (BIT(desc->div_bits) - 1) << desc->div_shift;
++ val = div_val << desc->div_shift;
++
++ err = regmap_update_bits(map, reg, mask, val);
++ if (err) {
++ pr_err("Failed to update div reg for clock %s\n",
++ desc->name);
++ return -EINVAL;
++ }
++ }
++
++ if (desc->base_bits) {
++ mask = (BIT(desc->base_bits) - 1) << desc->base_shift;
++ val = base_val << desc->base_shift;
++
++ err = regmap_update_bits(map, desc->base_reg, mask, val);
++ if (err) {
++ pr_err("Failed to update reg for clock %s\n",
++ desc->name);
++ return -EINVAL;
++ }
++ }
++
++ return 0;
++}
++
+ static const struct clk_ops en75xx_clk_ops = {
+ .recalc_rate = en75xx_recalc_rate,
++ .round_rate = en75xx_round_rate,
++ .set_rate = en75xx_set_rate,
+ };
+
+ static int en75xx_register_clocks(struct device *dev,
--- /dev/null
+From 397a132fb8173a9d728bc7c7a31ff5c0590d076f Mon Sep 17 00:00:00 2001
+From: Christian Marangi <ansuelsmth@gmail.com>
+Date: Tue, 17 Jun 2025 12:48:35 +0200
+Subject: [PATCH 05/10] clk: en7523: permit to reference Chip SCU from phandle
+
+In preparation for support of AN7583 and to make Chip SCU reference more
+robust, permit to reference the Chip SCU syscon regmap also with the
+"airoha,chip-scu" property in DT.
+
+Legacy implementation is kept by fallbacking in the absence of
+"airoha,chip-scu" property.
+
+Signed-off-by: Christian Marangi <ansuelsmth@gmail.com>
+---
+ drivers/clk/clk-en7523.c | 7 ++++++-
+ 1 file changed, 6 insertions(+), 1 deletion(-)
+
+--- a/drivers/clk/clk-en7523.c
++++ b/drivers/clk/clk-en7523.c
+@@ -846,11 +846,16 @@ static int en7581_clk_hw_init(struct pla
+ const struct en_clk_soc_data *soc_data,
+ struct clk_hw_onecell_data *clk_data)
+ {
++ struct device *dev = &pdev->dev;
+ struct regmap *map, *clk_map;
+ void __iomem *base;
+ int err;
+
+- map = syscon_regmap_lookup_by_compatible("airoha,en7581-chip-scu");
++ if (of_property_present(dev->of_node, "airoha,chip-scu"))
++ map = syscon_regmap_lookup_by_phandle(dev->of_node,
++ "airoha,chip-scu");
++ else
++ map = syscon_regmap_lookup_by_compatible("airoha,en7581-chip-scu");
+ if (IS_ERR(map))
+ return PTR_ERR(map);
+
--- /dev/null
+From d05fc5c8a9ab7bbda80e4fc728902f8d48d3e8aa Mon Sep 17 00:00:00 2001
+From: Christian Marangi <ansuelsmth@gmail.com>
+Date: Tue, 17 Jun 2025 14:53:56 +0200
+Subject: [PATCH 07/10] clk: en7523: reword and clean clk_probe variables
+
+Rework and clean en7523_clk_probe variables to make them consistent with
+the rest of the source. Also apply some minor cleanup for pdev
+variables.
+
+Signed-off-by: Christian Marangi <ansuelsmth@gmail.com>
+---
+ drivers/clk/clk-en7523.c | 20 +++++++++++---------
+ 1 file changed, 11 insertions(+), 9 deletions(-)
+
+--- a/drivers/clk/clk-en7523.c
++++ b/drivers/clk/clk-en7523.c
+@@ -881,25 +881,27 @@ static int en7581_clk_hw_init(struct pla
+
+ static int en7523_clk_probe(struct platform_device *pdev)
+ {
+- struct device_node *node = pdev->dev.of_node;
+ const struct en_clk_soc_data *soc_data;
+ struct clk_hw_onecell_data *clk_data;
+- int r;
++ struct device *dev = &pdev->dev;
++ int err;
+
+- soc_data = device_get_match_data(&pdev->dev);
++ soc_data = device_get_match_data(dev);
+
+- clk_data = devm_kzalloc(&pdev->dev,
+- struct_size(clk_data, hws, soc_data->num_clocks),
++ clk_data = devm_kzalloc(dev,
++ struct_size(clk_data, hws,
++ soc_data->num_clocks),
+ GFP_KERNEL);
+ if (!clk_data)
+ return -ENOMEM;
+
+ clk_data->num = soc_data->num_clocks;
+- r = soc_data->hw_init(pdev, soc_data, clk_data);
+- if (r)
+- return r;
++ err = soc_data->hw_init(pdev, soc_data, clk_data);
++ if (err)
++ return err;
+
+- return of_clk_add_hw_provider(node, of_clk_hw_onecell_get, clk_data);
++ return of_clk_add_hw_provider(dev->of_node, of_clk_hw_onecell_get,
++ clk_data);
+ }
+
+ static const struct en_clk_soc_data en7523_data = {
--- /dev/null
+From 8f1aea6f4aa61e09eb29b41ff9fffeedd5b2fc0d Mon Sep 17 00:00:00 2001
+From: Christian Marangi <ansuelsmth@gmail.com>
+Date: Tue, 17 Jun 2025 13:15:19 +0200
+Subject: [PATCH 08/10] clk: en7523: add support for probing SCU child
+
+On new Airoha SoC in the SCU register space additional pheriperal might
+be present aside from the clock/reset. The Airoha AN7583 SoC is an
+example of this where 2 MDIO controller are present.
+
+Introduce a bool "probe_child" to trigger probe of child node of the SCU
+node.
+
+Signed-off-by: Christian Marangi <ansuelsmth@gmail.com>
+---
+ drivers/clk/clk-en7523.c | 17 +++++++++++++++--
+ 1 file changed, 15 insertions(+), 2 deletions(-)
+
+--- a/drivers/clk/clk-en7523.c
++++ b/drivers/clk/clk-en7523.c
+@@ -5,6 +5,7 @@
+ #include <linux/clk-provider.h>
+ #include <linux/io.h>
+ #include <linux/mfd/syscon.h>
++#include <linux/of_platform.h>
+ #include <linux/platform_device.h>
+ #include <linux/property.h>
+ #include <linux/regmap.h>
+@@ -83,6 +84,7 @@ struct en_rst_data {
+ };
+
+ struct en_clk_soc_data {
++ bool probe_child;
+ u32 num_clocks;
+ const struct en_clk_desc *base_clks;
+ const struct clk_ops pcie_ops;
+@@ -900,8 +902,19 @@ static int en7523_clk_probe(struct platf
+ if (err)
+ return err;
+
+- return of_clk_add_hw_provider(dev->of_node, of_clk_hw_onecell_get,
+- clk_data);
++ err = of_clk_add_hw_provider(dev->of_node, of_clk_hw_onecell_get,
++ clk_data);
++ if (err)
++ return err;
++
++ if (soc_data->probe_child) {
++ err = of_platform_populate(dev->of_node, NULL, NULL,
++ dev);
++ if (err)
++ return err;
++ }
++
++ return 0;
+ }
+
+ static const struct en_clk_soc_data en7523_data = {
--- /dev/null
+From 12838dd20851a6eae67061c5f195f31981a4d8c1 Mon Sep 17 00:00:00 2001
+From: Christian Marangi <ansuelsmth@gmail.com>
+Date: Wed, 28 May 2025 02:39:35 +0200
+Subject: [PATCH 09/10] dt-bindings: clock: airoha: Document support for AN7583
+ clock
+
+Document support for Airoha AN7583 clock. This is based on the EN7523
+clock schema with the new requirement of the "airoha,chip-scu"
+(previously optional for EN7581).
+
+Add additional binding for additional clock and reset lines.
+
+Signed-off-by: Christian Marangi <ansuelsmth@gmail.com>
+---
+ .../bindings/clock/airoha,en7523-scu.yaml | 9 +++
+ include/dt-bindings/clock/en7523-clk.h | 3 +
+ .../dt-bindings/reset/airoha,an7583-reset.h | 61 +++++++++++++++++++
+ 3 files changed, 73 insertions(+)
+ create mode 100644 include/dt-bindings/reset/airoha,an7583-reset.h
+
+# diff --git a/Documentation/devicetree/bindings/clock/airoha,en7523-scu.yaml b/Documentation/devicetree/bindings/clock/airoha,en7523-scu.yaml
+# index bce77a14c938..be9759b86fdc 100644
+# --- a/Documentation/devicetree/bindings/clock/airoha,en7523-scu.yaml
+# +++ b/Documentation/devicetree/bindings/clock/airoha,en7523-scu.yaml
+# @@ -32,6 +32,7 @@ properties:
+# - enum:
+# - airoha,en7523-scu
+# - airoha,en7581-scu
+# + - airoha,an7583-scu
+
+# reg:
+# items:
+# @@ -82,6 +83,14 @@ allOf:
+# reg:
+# maxItems: 1
+
+# + - if:
+# + properties:
+# + compatible:
+# + const: airoha,an7583-scu
+# + then:
+# + required:
+# + - airoha,chip-scu
+# +
+# additionalProperties: false
+
+# examples:
+--- a/include/dt-bindings/clock/en7523-clk.h
++++ b/include/dt-bindings/clock/en7523-clk.h
+@@ -14,4 +14,7 @@
+
+ #define EN7581_CLK_EMMC 8
+
++#define AN7583_CLK_MDIO0 9
++#define AN7583_CLK_MDIO1 10
++
+ #endif /* _DT_BINDINGS_CLOCK_AIROHA_EN7523_H_ */
+--- /dev/null
++++ b/include/dt-bindings/reset/airoha,an7583-reset.h
+@@ -0,0 +1,62 @@
++/* SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) */
++/*
++ * Copyright (c) 2024 AIROHA Inc
++ * Author: Christian Marangi <ansuelsmth@gmail.com>
++ */
++
++#ifndef __DT_BINDINGS_RESET_CONTROLLER_AIROHA_AN7583_H_
++#define __DT_BINDINGS_RESET_CONTROLLER_AIROHA_AN7583_H_
++
++/* RST_CTRL2 */
++#define AN7583_XPON_PHY_RST 0
++#define AN7583_GPON_OLT_RST 1
++#define AN7583_CPU_TIMER2_RST 2
++#define AN7583_HSUART_RST 3
++#define AN7583_UART4_RST 4
++#define AN7583_UART5_RST 5
++#define AN7583_I2C2_RST 6
++#define AN7583_XSI_MAC_RST 7
++#define AN7583_XSI_PHY_RST 8
++#define AN7583_NPU_RST 9
++#define AN7583_TRNG_MSTART_RST 10
++#define AN7583_DUAL_HSI0_RST 11
++#define AN7583_DUAL_HSI1_RST 12
++#define AN7583_DUAL_HSI0_MAC_RST 13
++#define AN7583_DUAL_HSI1_MAC_RST 14
++#define AN7583_XPON_XFI_RST 15
++#define AN7583_WDMA_RST 16
++#define AN7583_WOE0_RST 17
++#define AN7583_HSDMA_RST 18
++#define AN7583_TDMA_RST 19
++#define AN7583_EMMC_RST 20
++#define AN7583_SOE_RST 21
++#define AN7583_XFP_MAC_RST 22
++#define AN7583_MDIO0 23
++#define AN7583_MDIO1 24
++/* RST_CTRL1 */
++#define AN7583_PCM1_ZSI_ISI_RST 25
++#define AN7583_FE_PDMA_RST 26
++#define AN7583_FE_QDMA_RST 27
++#define AN7583_PCM_SPIWP_RST 28
++#define AN7583_CRYPTO_RST 29
++#define AN7583_TIMER_RST 30
++#define AN7583_PCM1_RST 31
++#define AN7583_UART_RST 32
++#define AN7583_GPIO_RST 33
++#define AN7583_GDMA_RST 34
++#define AN7583_I2C_MASTER_RST 35
++#define AN7583_PCM2_ZSI_ISI_RST 36
++#define AN7583_SFC_RST 37
++#define AN7583_UART2_RST 38
++#define AN7583_GDMP_RST 39
++#define AN7583_FE_RST 40
++#define AN7583_USB_HOST_P0_RST 41
++#define AN7583_GSW_RST 42
++#define AN7583_SFC2_PCM_RST 43
++#define AN7583_PCIE0_RST 44
++#define AN7583_PCIE1_RST 45
++#define AN7583_CPU_TIMER_RST 46
++#define AN7583_PCIE_HB_RST 47
++#define AN7583_XPON_MAC_RST 48
++
++#endif /* __DT_BINDINGS_RESET_CONTROLLER_AIROHA_AN7583_H_ */
--- /dev/null
+From 3c5cd99f894c23650accf19fef18b5b9bbe83941 Mon Sep 17 00:00:00 2001
+From: Christian Marangi <ansuelsmth@gmail.com>
+Date: Sat, 8 Feb 2025 00:43:27 +0100
+Subject: [PATCH 10/10] clk: en7523: add support for Airoha AN7583 clock
+
+Add support for Airoha AN7583 clock and reset.
+
+Airoha AN7583 SoC have the same register address of EN7581 but implement
+different bits and additional base clocks. Also reset are different with
+the introduction of 2 dedicated MDIO line and drop of some reset lines.
+
+Signed-off-by: Christian Marangi <ansuelsmth@gmail.com>
+---
+ drivers/clk/clk-en7523.c | 264 +++++++++++++++++++++++++++++++++++++++
+ 1 file changed, 264 insertions(+)
+
+--- a/drivers/clk/clk-en7523.c
++++ b/drivers/clk/clk-en7523.c
+@@ -12,6 +12,7 @@
+ #include <linux/reset-controller.h>
+ #include <dt-bindings/clock/en7523-clk.h>
+ #include <dt-bindings/reset/airoha,en7581-reset.h>
++#include <dt-bindings/reset/airoha,an7583-reset.h>
+
+ #define RST_NR_PER_BANK 32
+
+@@ -104,6 +105,14 @@ static const u32 bus7581_base[] = { 6000
+ static const u32 npu7581_base[] = { 800000000, 750000000, 720000000, 600000000 };
+ static const u32 crypto_base[] = { 540000000, 480000000 };
+ static const u32 emmc7581_base[] = { 200000000, 150000000 };
++/* AN7583 */
++static const u32 gsw7583_base[] = { 540672000, 270336000, 400000000, 200000000 };
++static const u32 emi7583_base[] = { 540672000, 480000000, 400000000, 300000000 };
++static const u32 bus7583_base[] = { 600000000, 540672000, 480000000, 400000000 };
++static const u32 spi7583_base[] = { 100000000, 12500000 };
++static const u32 npu7583_base[] = { 666000000, 800000000, 720000000, 600000000 };
++static const u32 crypto7583_base[] = { 540672000, 400000000 };
++static const u32 emmc7583_base[] = { 150000000, 200000000 };
+
+ static const struct en_clk_desc en7523_base_clks[] = {
+ {
+@@ -306,6 +315,138 @@ static const struct en_clk_desc en7581_b
+ }
+ };
+
++static const struct en_clk_desc an7583_base_clks[] = {
++ {
++ .id = EN7523_CLK_GSW,
++ .name = "gsw",
++
++ .base_reg = REG_GSW_CLK_DIV_SEL,
++ .base_bits = 2,
++ .base_shift = 8,
++ .base_values = gsw7583_base,
++ .n_base_values = ARRAY_SIZE(gsw7583_base),
++
++ .div_bits = 3,
++ .div_shift = 0,
++ .div_step = 1,
++ .div_offset = 1,
++ }, {
++ .id = EN7523_CLK_EMI,
++ .name = "emi",
++
++ .base_reg = REG_EMI_CLK_DIV_SEL,
++ .base_bits = 2,
++ .base_shift = 8,
++ .base_values = emi7583_base,
++ .n_base_values = ARRAY_SIZE(emi7583_base),
++
++ .div_bits = 3,
++ .div_shift = 0,
++ .div_step = 1,
++ .div_offset = 1,
++ }, {
++ .id = EN7523_CLK_BUS,
++ .name = "bus",
++
++ .base_reg = REG_BUS_CLK_DIV_SEL,
++ .base_bits = 2,
++ .base_shift = 8,
++ .base_values = bus7583_base,
++ .n_base_values = ARRAY_SIZE(bus7583_base),
++
++ .div_bits = 3,
++ .div_shift = 0,
++ .div_step = 1,
++ .div_offset = 1,
++ }, {
++ .id = EN7523_CLK_SLIC,
++ .name = "slic",
++
++ .base_reg = REG_SPI_CLK_FREQ_SEL,
++ .base_bits = 1,
++ .base_shift = 0,
++ .base_values = slic_base,
++ .n_base_values = ARRAY_SIZE(slic_base),
++
++ .div_reg = REG_SPI_CLK_DIV_SEL,
++ .div_bits = 5,
++ .div_shift = 24,
++ .div_val0 = 20,
++ .div_step = 2,
++ }, {
++ .id = EN7523_CLK_SPI,
++ .name = "spi",
++
++ .base_reg = REG_SPI_CLK_FREQ_SEL,
++ .base_bits = 1,
++ .base_shift = 1,
++ .base_values = spi7583_base,
++ .n_base_values = ARRAY_SIZE(spi7583_base),
++
++ .div_reg = REG_SPI_CLK_DIV_SEL,
++ .div_bits = 5,
++ .div_shift = 8,
++ .div_val0 = 40,
++ .div_step = 2,
++ }, {
++ .id = EN7523_CLK_NPU,
++ .name = "npu",
++
++ .base_reg = REG_NPU_CLK_DIV_SEL,
++ .base_bits = 2,
++ .base_shift = 9,
++ .base_values = npu7583_base,
++ .n_base_values = ARRAY_SIZE(npu7583_base),
++
++ .div_bits = 3,
++ .div_shift = 0,
++ .div_step = 1,
++ .div_offset = 1,
++ }, {
++ .id = EN7523_CLK_CRYPTO,
++ .name = "crypto",
++
++ .base_reg = REG_CRYPTO_CLKSRC2,
++ .base_bits = 1,
++ .base_shift = 0,
++ .base_values = crypto7583_base,
++ .n_base_values = ARRAY_SIZE(crypto7583_base),
++ }, {
++ .id = EN7581_CLK_EMMC,
++ .name = "emmc",
++
++ .base_reg = REG_CRYPTO_CLKSRC2,
++ .base_bits = 1,
++ .base_shift = 13,
++ .base_values = emmc7583_base,
++ .n_base_values = ARRAY_SIZE(emmc7583_base),
++ }, {
++ .id = AN7583_CLK_MDIO0,
++ .name = "mdio0",
++
++ .base_reg = REG_CRYPTO_CLKSRC2,
++
++ .base_value = 25000000,
++
++ .div_bits = 4,
++ .div_shift = 15,
++ .div_step = 1,
++ .div_offset = 1,
++ }, {
++ .id = AN7583_CLK_MDIO1,
++ .name = "mdio1",
++
++ .base_reg = REG_CRYPTO_CLKSRC2,
++
++ .base_value = 25000000,
++
++ .div_bits = 4,
++ .div_shift = 19,
++ .div_step = 1,
++ .div_offset = 1,
++ }
++};
++
+ static const u16 en7581_rst_ofs[] = {
+ REG_RST_CTRL2,
+ REG_RST_CTRL1,
+@@ -369,6 +510,60 @@ static const u16 en7581_rst_map[] = {
+ [EN7581_XPON_MAC_RST] = RST_NR_PER_BANK + 31,
+ };
+
++static const u16 an7583_rst_map[] = {
++ /* RST_CTRL2 */
++ [AN7583_XPON_PHY_RST] = 0,
++ [AN7583_GPON_OLT_RST] = 1,
++ [AN7583_CPU_TIMER2_RST] = 2,
++ [AN7583_HSUART_RST] = 3,
++ [AN7583_UART4_RST] = 4,
++ [AN7583_UART5_RST] = 5,
++ [AN7583_I2C2_RST] = 6,
++ [AN7583_XSI_MAC_RST] = 7,
++ [AN7583_XSI_PHY_RST] = 8,
++ [AN7583_NPU_RST] = 9,
++ [AN7583_TRNG_MSTART_RST] = 12,
++ [AN7583_DUAL_HSI0_RST] = 13,
++ [AN7583_DUAL_HSI1_RST] = 14,
++ [AN7583_DUAL_HSI0_MAC_RST] = 16,
++ [AN7583_DUAL_HSI1_MAC_RST] = 17,
++ [AN7583_XPON_XFI_RST] = 18,
++ [AN7583_WDMA_RST] = 19,
++ [AN7583_WOE0_RST] = 20,
++ [AN7583_HSDMA_RST] = 22,
++ [AN7583_TDMA_RST] = 24,
++ [AN7583_EMMC_RST] = 25,
++ [AN7583_SOE_RST] = 26,
++ [AN7583_XFP_MAC_RST] = 28,
++ [AN7583_MDIO0] = 30,
++ [AN7583_MDIO1] = 31,
++ /* RST_CTRL1 */
++ [AN7583_PCM1_ZSI_ISI_RST] = RST_NR_PER_BANK + 0,
++ [AN7583_FE_PDMA_RST] = RST_NR_PER_BANK + 1,
++ [AN7583_FE_QDMA_RST] = RST_NR_PER_BANK + 2,
++ [AN7583_PCM_SPIWP_RST] = RST_NR_PER_BANK + 4,
++ [AN7583_CRYPTO_RST] = RST_NR_PER_BANK + 6,
++ [AN7583_TIMER_RST] = RST_NR_PER_BANK + 8,
++ [AN7583_PCM1_RST] = RST_NR_PER_BANK + 11,
++ [AN7583_UART_RST] = RST_NR_PER_BANK + 12,
++ [AN7583_GPIO_RST] = RST_NR_PER_BANK + 13,
++ [AN7583_GDMA_RST] = RST_NR_PER_BANK + 14,
++ [AN7583_I2C_MASTER_RST] = RST_NR_PER_BANK + 16,
++ [AN7583_PCM2_ZSI_ISI_RST] = RST_NR_PER_BANK + 17,
++ [AN7583_SFC_RST] = RST_NR_PER_BANK + 18,
++ [AN7583_UART2_RST] = RST_NR_PER_BANK + 19,
++ [AN7583_GDMP_RST] = RST_NR_PER_BANK + 20,
++ [AN7583_FE_RST] = RST_NR_PER_BANK + 21,
++ [AN7583_USB_HOST_P0_RST] = RST_NR_PER_BANK + 22,
++ [AN7583_GSW_RST] = RST_NR_PER_BANK + 23,
++ [AN7583_SFC2_PCM_RST] = RST_NR_PER_BANK + 25,
++ [AN7583_PCIE0_RST] = RST_NR_PER_BANK + 26,
++ [AN7583_PCIE1_RST] = RST_NR_PER_BANK + 27,
++ [AN7583_CPU_TIMER_RST] = RST_NR_PER_BANK + 28,
++ [AN7583_PCIE_HB_RST] = RST_NR_PER_BANK + 29,
++ [AN7583_XPON_MAC_RST] = RST_NR_PER_BANK + 31,
++};
++
+ static u32 en7523_get_base_rate(const struct en_clk_desc *desc, u32 val)
+ {
+ if (!desc->base_bits)
+@@ -881,6 +1076,62 @@ static int en7581_clk_hw_init(struct pla
+ return en7581_reset_register(&pdev->dev, clk_map);
+ }
+
++static int an7583_reset_register(struct device *dev, struct regmap *map)
++{
++ struct en_rst_data *rst_data;
++
++ rst_data = devm_kzalloc(dev, sizeof(*rst_data), GFP_KERNEL);
++ if (!rst_data)
++ return -ENOMEM;
++
++ rst_data->bank_ofs = en7581_rst_ofs;
++ rst_data->idx_map = an7583_rst_map;
++ rst_data->map = map;
++
++ rst_data->rcdev.nr_resets = ARRAY_SIZE(an7583_rst_map);
++ rst_data->rcdev.of_xlate = en7523_reset_xlate;
++ rst_data->rcdev.ops = &en7581_reset_ops;
++ rst_data->rcdev.of_node = dev->of_node;
++ rst_data->rcdev.of_reset_n_cells = 1;
++ rst_data->rcdev.owner = THIS_MODULE;
++ rst_data->rcdev.dev = dev;
++
++ return devm_reset_controller_register(dev, &rst_data->rcdev);
++}
++
++static int an7583_clk_hw_init(struct platform_device *pdev,
++ const struct en_clk_soc_data *soc_data,
++ struct clk_hw_onecell_data *clk_data)
++{
++ struct device *dev = &pdev->dev;
++ struct regmap *map, *clk_map;
++ void __iomem *base;
++ int err;
++
++ map = syscon_regmap_lookup_by_phandle(dev->of_node, "airoha,chip-scu");
++ if (IS_ERR(map))
++ return PTR_ERR(map);
++
++ base = devm_platform_ioremap_resource(pdev, 0);
++ if (IS_ERR(base))
++ return PTR_ERR(base);
++
++ clk_map = devm_regmap_init_mmio(&pdev->dev, base, &en7523_clk_regmap_config);
++ if (IS_ERR(clk_map))
++ return PTR_ERR(clk_map);
++
++ err = en75xx_register_clocks(dev, soc_data, clk_data, map, clk_map);
++ if (err)
++ return err;
++
++ regmap_clear_bits(clk_map, REG_NP_SCU_SSTR,
++ REG_PCIE_XSI0_SEL_MASK | REG_PCIE_XSI1_SEL_MASK);
++ regmap_update_bits(clk_map, REG_NP_SCU_PCIC, REG_PCIE_CTRL,
++ FIELD_PREP(REG_PCIE_CTRL, 3));
++
++ return an7583_reset_register(dev, clk_map);
++}
++
+ static int en7523_clk_probe(struct platform_device *pdev)
+ {
+ const struct en_clk_soc_data *soc_data;
+@@ -940,9 +1191,23 @@ static const struct en_clk_soc_data en75
+ .hw_init = en7581_clk_hw_init,
+ };
+
++static const struct en_clk_soc_data an7583_data = {
++ .probe_child = true,
++ .base_clks = an7583_base_clks,
++ /* We increment num_clocks by 1 to account for additional PCIe clock */
++ .num_clocks = ARRAY_SIZE(an7583_base_clks) + 1,
++ .pcie_ops = {
++ .is_enabled = en7581_pci_is_enabled,
++ .enable = en7581_pci_enable,
++ .disable = en7581_pci_disable,
++ },
++ .hw_init = an7583_clk_hw_init,
++};
++
+ static const struct of_device_id of_match_clk_en7523[] = {
+ { .compatible = "airoha,en7523-scu", .data = &en7523_data },
+ { .compatible = "airoha,en7581-scu", .data = &en7581_data },
++ { .compatible = "airoha,an7583-scu", .data = &an7583_data },
+ { /* sentinel */ }
+ };
+
--- /dev/null
+From 500f525a21bfc18605b23e7b39fc1d8f74393b30 Mon Sep 17 00:00:00 2001
+From: Christian Marangi <ansuelsmth@gmail.com>
+Date: Wed, 25 Jun 2025 00:00:59 +0200
+Subject: [PATCH 6/8] net: pcs: airoha: add support for Airoha AN7583 SoC
+
+Add support for Airoha AN7583 PCS. This use a new analog PHY
+implementation that doesn't require manual calibration but makes use of
+internal algo to lock to the center of the band EYE.
+
+Signed-off-by: Christian Marangi <ansuelsmth@gmail.com>
+---
+ drivers/net/pcs/airoha/Kconfig | 7 +
+ drivers/net/pcs/airoha/Makefile | 3 +
+ drivers/net/pcs/airoha/pcs-airoha-common.c | 50 +-
+ drivers/net/pcs/airoha/pcs-airoha.h | 430 ++++
+ drivers/net/pcs/airoha/pcs-an7583.c | 2199 ++++++++++++++++++++
+ 5 files changed, 2686 insertions(+), 3 deletions(-)
+ create mode 100644 drivers/net/pcs/airoha/pcs-an7583.c
+
+--- a/drivers/net/pcs/airoha/Kconfig
++++ b/drivers/net/pcs/airoha/Kconfig
+@@ -9,3 +9,10 @@ config PCS_AIROHA_AN7581
+ help
+ This module provides helper to phylink for managing the Airoha
+ AN7581 PCS for SoC Ethernet and PON SERDES.
++
++config PCS_AIROHA_AN7583
++ tristate "Airoha AN7583 PCS driver"
++ select PCS_AIROHA
++ help
++ This module provides helper to phylink for managing the Airoha
++ AN7583 PCS for SoC Ethernet and PON SERDES.
+--- a/drivers/net/pcs/airoha/Makefile
++++ b/drivers/net/pcs/airoha/Makefile
+@@ -5,3 +5,6 @@ pcs-airoha-objs := pcs-airoha-common.o
+ ifdef CONFIG_PCS_AIROHA_AN7581
+ pcs-airoha-objs += pcs-an7581.o
+ endif
++ifdef CONFIG_PCS_AIROHA_AN7583
++pcs-airoha-objs += pcs-an7583.o
++endif
+--- a/drivers/net/pcs/airoha/pcs-airoha-common.c
++++ b/drivers/net/pcs/airoha/pcs-airoha-common.c
+@@ -19,6 +19,7 @@
+ static void airoha_pcs_setup_scu_eth(struct airoha_pcs_priv *priv,
+ phy_interface_t interface)
+ {
++ struct device *dev = priv->dev;
+ u32 xsi_sel;
+
+ switch (interface) {
+@@ -36,6 +37,12 @@ static void airoha_pcs_setup_scu_eth(str
+ regmap_update_bits(priv->scu, AIROHA_SCU_SSR3,
+ AIROHA_SCU_ETH_XSI_SEL,
+ xsi_sel);
++
++ /* AN7583 require additional setting */
++ if (device_is_compatible(dev, "airoha,an7583-pcs-eth"))
++ regmap_update_bits(priv->scu, AIROHA_SCU_WAN_CONF,
++ AIROHA_SCU_ETH_MAC_SEL,
++ AIROHA_SCU_ETH_MAC_SEL_XFI);
+ }
+
+ static void airoha_pcs_setup_scu_pon(struct airoha_pcs_priv *priv,
+@@ -100,16 +107,24 @@ static int airoha_pcs_setup_scu(struct a
+
+ static void airoha_pcs_init_usxgmii(struct airoha_pcs_priv *priv)
+ {
++ const struct airoha_pcs_match_data *data = priv->data;
++
+ regmap_set_bits(priv->multi_sgmii, AIROHA_PCS_MULTI_SGMII_MSG_RX_CTRL_0,
+ AIROHA_PCS_HSGMII_XFI_SEL);
+
+ /* Disable Hibernation */
+- regmap_clear_bits(priv->usxgmii_pcs, AIROHA_PCS_USXGMII_PCS_CTROL_1,
+- AIROHA_PCS_USXGMII_SPEED_SEL_H);
++ if (data->hibernation_workaround)
++ regmap_clear_bits(priv->usxgmii_pcs, AIROHA_PCS_USXGMII_PCS_CTROL_1,
++ AIROHA_PCS_USXGMII_SPEED_SEL_H);
+
+ /* FIXME: wait Airoha */
+ /* Avoid PCS sending garbage to MAC in some HW revision (E0) */
+- regmap_write(priv->usxgmii_pcs, AIROHA_PCS_USGMII_VENDOR_DEFINE_116, 0);
++ if (data->usxgmii_ber_time_fixup)
++ regmap_write(priv->usxgmii_pcs, AIROHA_PCS_USGMII_VENDOR_DEFINE_116, 0);
++
++ if (data->usxgmii_rx_gb_out_vld_tweak)
++ regmap_clear_bits(priv->usxgmii_pcs, AN7583_PCS_USXGMII_RTL_MODIFIED,
++ AIROHA_PCS_USXGMII_MODIFIED_RX_GB_OUT_VLD);
+ }
+
+ static void airoha_pcs_init_hsgmii(struct airoha_pcs_priv *priv)
+@@ -434,6 +449,13 @@ static int airoha_pcs_config(struct phyl
+ regmap_clear_bits(priv->usxgmii_pcs,
+ AIROHA_PCS_USXGMII_PCS_AN_CONTROL_0,
+ AIROHA_PCS_USXGMII_AN_ENABLE);
++
++ if (data->usxgmii_xfi_mode_sel &&
++ neg_mode == PHYLINK_PCS_NEG_INBAND_ENABLED)
++ regmap_set_bits(priv->usxgmii_pcs,
++ AIROHA_PCS_USXGMII_PCS_AN_CONTROL_7,
++ AIROHA_PCS_USXGMII_XFI_MODE_TX_SEL |
++ AIROHA_PCS_USXGMII_XFI_MODE_RX_SEL);
+ }
+
+ /* Clear any force bit that my be set by bootloader */
+@@ -985,7 +1007,8 @@ static int airoha_pcs_probe(struct platf
+ * manual rx calibration is needed. This is only limited to
+ * any SoC revision before E2.
+ */
+- if (data->port_type == AIROHA_PCS_ETH) {
++ if (device_is_compatible(dev, "airoha,an7581-pcs-eth") &&
++ data->port_type == AIROHA_PCS_ETH) {
+ u32 val;
+
+ ret = regmap_read(priv->scu, AIROHA_SCU_PDIDR, &val);
+@@ -1003,6 +1026,8 @@ static int airoha_pcs_probe(struct platf
+
+ static const struct airoha_pcs_match_data an7581_pcs_eth = {
+ .port_type = AIROHA_PCS_ETH,
++ .hibernation_workaround = true,
++ .usxgmii_ber_time_fixup = true,
+ .bringup = an7581_pcs_bringup,
+ .link_up = an7581_pcs_phya_link_up,
+ .rxlock_workaround = an7581_pcs_rxlock_workaround,
+@@ -1010,13 +1035,33 @@ static const struct airoha_pcs_match_dat
+
+ static const struct airoha_pcs_match_data an7581_pcs_pon = {
+ .port_type = AIROHA_PCS_PON,
++ .hibernation_workaround = true,
++ .usxgmii_ber_time_fixup = true,
+ .bringup = an7581_pcs_bringup,
+ .link_up = an7581_pcs_phya_link_up,
+ };
+
++static const struct airoha_pcs_match_data an7583_pcs_eth = {
++ .port_type = AIROHA_PCS_ETH,
++ .usxgmii_rx_gb_out_vld_tweak = true,
++ .usxgmii_xfi_mode_sel = true,
++ .bringup = an7583_pcs_common_phya_bringup,
++ .link_up = an7583_pcs_common_phya_link_up,
++};
++
++static const struct airoha_pcs_match_data an7583_pcs_pon = {
++ .port_type = AIROHA_PCS_PON,
++ .usxgmii_rx_gb_out_vld_tweak = true,
++ .usxgmii_xfi_mode_sel = true,
++ .bringup = an7583_pcs_common_phya_bringup,
++ .link_up = an7583_pcs_common_phya_link_up,
++};
++
+ 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,an7583-pcs-eth", .data = &an7583_pcs_eth },
++ { .compatible = "airoha,an7583-pcs-pon", .data = &an7583_pcs_pon },
+ { /* sentinel */ },
+ };
+ MODULE_DEVICE_TABLE(of, airoha_pcs_of_table);
+--- a/drivers/net/pcs/airoha/pcs-airoha.h
++++ b/drivers/net/pcs/airoha/pcs-airoha.h
+@@ -14,6 +14,9 @@
+ #define AIROHA_SCU_PDIDR 0x5c
+ #define AIROHA_SCU_PRODUCT_ID GENMASK(15, 0)
+ #define AIROHA_SCU_WAN_CONF 0x70
++#define AIROHA_SCU_ETH_MAC_SEL BIT(24)
++#define AIROHA_SCU_ETH_MAC_SEL_XFI FIELD_PREP_CONST(AIROHA_SCU_ETH_MAC_SEL, 0x0)
++#define AIROHA_SCU_ETH_MAC_SEL_PON FIELD_PREP_CONST(AIROHA_SCU_ETH_MAC_SEL, 0x1)
+ #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)
+@@ -244,6 +247,8 @@
+ #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_XFI_MODE_TX_SEL BIT(20)
++#define AIROHA_PCS_USXGMII_XFI_MODE_RX_SEL BIT(16)
+ #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)
+@@ -251,9 +256,27 @@
+ #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)
++#define AN7583_PCS_USXGMII_RTL_MODIFIED 0x334
++#define AIROHA_PCS_USXGMII_MODIFIED_RX_GB_OUT_VLD BIT(25)
+
+ /* PMA_PHYA */
+ #define AIROHA_PCS_ANA_PXP_CMN_EN 0x0
++#define AIROHA_PCS_ANA_CMN_VREFSEL GENMASK(18, 16)
++#define AIROHA_PCS_ANA_CMN_VREFSEL_8V FIELD_PREP_CONST(AIROHA_PCS_ANA_CMN_VREFSEL, 0x0)
++#define AIROHA_PCS_ANA_CMN_VREFSEL_8_25V FIELD_PREP_CONST(AIROHA_PCS_ANA_CMN_VREFSEL, 0x1)
++#define AIROHA_PCS_ANA_CMN_VREFSEL_8_5V FIELD_PREP_CONST(AIROHA_PCS_ANA_CMN_VREFSEL, 0x2)
++#define AIROHA_PCS_ANA_CMN_VREFSEL_8_75V FIELD_PREP_CONST(AIROHA_PCS_ANA_CMN_VREFSEL, 0x3)
++#define AIROHA_PCS_ANA_CMN_VREFSEL_9V FIELD_PREP_CONST(AIROHA_PCS_ANA_CMN_VREFSEL, 0x4)
++#define AIROHA_PCS_ANA_CMN_VREFSEL_9_25V FIELD_PREP_CONST(AIROHA_PCS_ANA_CMN_VREFSEL, 0x5)
++#define AIROHA_PCS_ANA_CMN_VREFSEL_9_5V FIELD_PREP_CONST(AIROHA_PCS_ANA_CMN_VREFSEL, 0x6)
++#define AIROHA_PCS_ANA_CMN_VREFSEL_9_75V FIELD_PREP_CONST(AIROHA_PCS_ANA_CMN_VREFSEL, 0x7)
++#define AIROHA_PCS_ANA_CMN_VREFSEL GENMASK(18, 16)
++/* GENMASK(2, 0) input selection from 0 to 7
++ * BIT(3) OPAMP and path EN
++ * BIT(4) Current path measurement
++ * BIT(5) voltage/current path to PAD
++ */
++#define AIROHA_PCS_ANA_CMN_MPXSELTOP_DC GENMASK(13, 8)
+ #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)
+@@ -347,6 +370,8 @@
+ #define AIROHA_PCS_ANA_JCPLL_TCL_KBAND_VREF GENMASK(20, 16)
+ #define AIROHA_PCS_ANA_JCPLL_SPARE_L GENMASK(15, 8)
+ #define AIROHA_PCS_ANA_JCPLL_SPARE_L_LDO FIELD_PREP_CONST(AIROHA_PCS_ANA_JCPLL_SPARE_L, BIT(5))
++#define AIROHA_PCS_ANA_PXP_JCPLL_FREQ_MEAS_EN 0x4c
++#define AIROHA_PCS_ANA_TXPLL_IB_EXT_EN BIT(24)
+ #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)
+@@ -370,6 +395,9 @@
+ #define AIROHA_PCS_ANA_TXPLL_MMD_PREDIV_MODE_1 FIELD_PREP_CONST(AIROHA_PCS_ANA_TXPLL_MMD_PREDIV_MODE, 0x3)
+ #define AIROHA_PCS_ANA_TXPLL_POSTDIV_EN BIT(8)
+ #define AIROHA_PCS_ANA_TXPLL_KBAND_KS GENMASK(1, 0)
++#define AIROHA_PCS_ANA_PXP_TXPLL_PHY_CK1_EN 0x60
++#define AIROHA_PCS_ANA_TXPLL_PHY_CK2_EN BIT(8)
++#define AIROHA_PCS_ANA_TXPLL_PHY_CK1_EN BIT(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)
+@@ -435,16 +463,41 @@
+ #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_VTP_EN 0x88
++#define AIROHA_PCS_ANA_TXPLL_VTP GENMASK(10, 8)
++#define AIROHA_PCS_ANA_TXPLL_VTP_EN BIT(0)
+ #define AIROHA_PCS_ANA_PXP_TXPLL_TCL_KBAND_VREF 0x94
++#define AIROHA_PCS_ANA_TXPLL_POSTDIV_D256_EN BIT(25) /* 0: 128 1: 256 */
++#define AIROHA_PCS_ANA_TXPLL_VCO_KBAND_MEAS_EN BIT(24)
++#define AIROHA_PCS_ANA_TXPLL_FREQ_MEAS_EN BIT(16)
++#define AIROHA_PCS_ANA_TXPLL_VREF_SEL BIT(8)
++#define AIROHA_PCS_ANA_TXPLL_VREF_SEL_VBG FIELD_PREP_CONST(AIROHA_PCS_ANA_TXPLL_VREF_SEL, 0x0)
++#define AIROHA_PCS_ANA_TXPLL_VREF_SEL_AVDD FIELD_PREP_CONST(AIROHA_PCS_ANA_TXPLL_VREF_SEL, 0x1)
+ #define AIROHA_PCS_ANA_TXPLL_TCL_KBAND_VREF GENMASK(4, 0)
++#define AN7583_PCS_ANA_PXP_TXPLL_CHP_DOUBLE_EN 0x98
++#define AIROHA_PCS_ANA_TXPLL_SPARE_L BIT(0) /* ICHP_DOUBLE */
++#define AIROHA_PCS_ANA_PXP_PLL_MONCLK_SEL 0xa0
++#define AIROHA_PCS_ANA_TDC_AUTOEN BIT(24)
++#define AIROHA_PCS_ANA_PXP_TDC_SYNC_CK_SEL 0xa8
++#define AIROHA_PCS_ANA_PLL_LDO_CKDRV_VSEL GENMASK(17, 16)
++#define AIROHA_PCS_ANA_PLL_LDO_CKDRV_EN BIT(8)
++#define AIROHA_PCS_ANA_PXP_TX_TXLBRC_EN 0xc0
++#define AIROHA_PCS_ANA_TX_TERMCAL_VREF_L GENMASK(26, 24)
++#define AIROHA_PCS_ANA_TX_TERMCAL_VREF_H GENMASK(18, 16)
+ #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_TX_TERMCAL_SELPN 0xc8
++#define AIROHA_PCS_ANA_TX_TDC_CK_SEL GENMASK(17, 16)
+ #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 FIELD_PREP_CONST(AIROHA_PCS_ANA_RX_PHY_CK_SEL, 0x0)
+ #define AIROHA_PCS_ANA_RX_PHY_CK_SEL_FROM_DES FIELD_PREP_CONST(AIROHA_PCS_ANA_RX_PHY_CK_SEL, 0x1)
++#define AIROHA_PCS_ANA_RX_BUSBIT_SEL_FORCE BIT(8)
++#define AIROHA_PCS_ANA_RX_BUSBIT_SEL BIT(0)
++#define AIROHA_PCS_ANA_RX_BUSBIT_SEL_8BIT FIELD_PREP_CONST(AIROHA_PCS_ANA_RX_BUSBIT_SEL, 0x0)
++#define AIROHA_PCS_ANA_RX_BUSBIT_SEL_16BIT FIELD_PREP_CONST(AIROHA_PCS_ANA_RX_BUSBIT_SEL, 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)
+@@ -452,6 +505,16 @@
+ #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_RX_REV_0 GENMASK(15, 0)
++#define AIROHA_PCS_ANA_REV_0_FE_BUF2_BIAS_TYPE GENMASK(13, 12)
++#define AIROHA_PCS_ANA_REV_0_OSCAL_FE_MODE_SET_SEL BIT(11)
++#define AIROHA_PCS_ANA_REV_0_FE_EQ_GAIN_MODE_TRAINING BIT(10)
++#define AIROHA_PCS_ANA_REV_0_FE_BUF_GAIN_MODE_TRAINING GENMASK(9, 8)
++#define AIROHA_PCS_ANA_REV_0_FE_EQ_GAIN_MODE_NORMAL BIT(6)
++#define AIROHA_PCS_ANA_REV_0_FE_BUF_GAIN_MODE_NORMAL GENMASK(5, 4)
++#define AIROHA_PCS_ANA_REV_0_VOS_PNINV GENMASK(3, 2)
++#define AIROHA_PCS_ANA_REV_0_PLEYEBD4 BIT(1)
++#define AIROHA_PCS_ANA_REV_0_PLEYE_XOR_MON_EN BIT(0)
+ #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)
+@@ -460,6 +523,8 @@
+ #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_BOT_LIM 0xe0
++#define AIROHA_PCS_ANA_CDR_LPF_BOT_LIM GENMASK(18, 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)
+@@ -475,6 +540,19 @@
+ #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_CKREF_DIV 0x100
++#define AIROHA_PCS_ANA_CDR_PR_RSTB_BYPASS BIT(16)
++#define AIROHA_PCS_ANA_CDR_PR_CKREF_DIV GENMASK(1, 0)
++#define AIROHA_PCS_ANA_CDR_PR_CKREF_DIV_1 FIELD_PREP_CONST(AIROHA_PCS_ANA_CDR_PR_CKREF_DIV, 0x0)
++#define AIROHA_PCS_ANA_CDR_PR_CKREF_DIV_2 FIELD_PREP_CONST(AIROHA_PCS_ANA_CDR_PR_CKREF_DIV, 0x1)
++#define AIROHA_PCS_ANA_CDR_PR_CKREF_DIV_4 FIELD_PREP_CONST(AIROHA_PCS_ANA_CDR_PR_CKREF_DIV, 0x2)
++#define AIROHA_PCS_ANA_CDR_PR_CKREF_DIV_X FIELD_PREP_CONST(AIROHA_PCS_ANA_CDR_PR_CKREF_DIV, 0x3)
++#define AIROHA_PCS_ANA_PXP_CDR_PR_TDC_REF_SEL 0x108
++#define AIROHA_PCS_ANA_CDR_PR_CKREF_DIV1 GENMASK(25, 24)
++#define AIROHA_PCS_ANA_CDR_PR_CKREF_DIV1_1 FIELD_PREP_CONST(AIROHA_PCS_ANA_CDR_PR_CKREF_DIV1, 0x0)
++#define AIROHA_PCS_ANA_CDR_PR_CKREF_DIV1_2 FIELD_PREP_CONST(AIROHA_PCS_ANA_CDR_PR_CKREF_DIV1, 0x1)
++#define AIROHA_PCS_ANA_CDR_PR_CKREF_DIV1_4 FIELD_PREP_CONST(AIROHA_PCS_ANA_CDR_PR_CKREF_DIV1, 0x2)
++#define AIROHA_PCS_ANA_CDR_PR_CKREF_DIV1_X FIELD_PREP_CONST(AIROHA_PCS_ANA_CDR_PR_CKREF_DIV1, 0x3)
+ #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)
+@@ -484,6 +562,7 @@
+ #define AIROHA_PCS_ANA_CDR_PR_MONDPR_EN BIT(0)
+ #define AIROHA_PCS_ANA_PXP_RX_DAC_RANGE 0x110
+ #define AIROHA_PCS_ANA_RX_SIGDET_LPF_CTRL GENMASK(25, 24)
++#define AIROHA_PCS_ANA_RX_DAC_RANGE_EYE GENMASK(9, 8)
+ #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)
+@@ -532,7 +611,70 @@
+ #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_CK_STB_TIMER GENMASK(31, 24)
++#define AIROHA_PCS_PMA_LCPLL_PCW_MAN_LOAD_TIMER GENMASK(23, 16)
++#define AIROHA_PCS_PMA_LCPLL_EN_TIMER GENMASK(15, 8)
+ #define AIROHA_PCS_PMA_LCPLL_MAN_PWDB BIT(0)
++#define AIROHA_PCS_PMA_LCPLL_TDC_PW_0 0x10
++#define AIROHA_PCS_PMA_LCPLL_TDC_DIG_PWDB BIT(0)
++#define AIROHA_PCS_PMA_LCPLL_TDC_PW_5 0x24
++#define AIROHA_PCS_PMA_LCPLL_TDC_SYNC_IN_MODE BIT(24)
++#define AIROHA_PCS_PMA_LCPLL_AUTOK_TDC BIT(16)
++#define AIROHA_PCS_PMA_LCPLL_TDC_FLT_0 0x28
++#define AIROHA_PCS_PMA_LCPLL_KI GENMASK(10, 8)
++#define AIROHA_PCS_PMA_LCPLL_PON_RX_CDR_DIVTDC GENMASK(1, 0)
++#define AIROHA_PCS_PMA_LCPLL_PON_RX_CDR_DIVTDC_32 FIELD_PREP_CONST(AIROHA_PCS_PMA_LCPLL_PON_RX_CDR_DIVTDC, 0x0)
++#define AIROHA_PCS_PMA_LCPLL_PON_RX_CDR_DIVTDC_16 FIELD_PREP_CONST(AIROHA_PCS_PMA_LCPLL_PON_RX_CDR_DIVTDC, 0x1)
++#define AIROHA_PCS_PMA_LCPLL_PON_RX_CDR_DIVTDC_8 FIELD_PREP_CONST(AIROHA_PCS_PMA_LCPLL_PON_RX_CDR_DIVTDC, 0x2)
++#define AIROHA_PCS_PMA_LCPLL_PON_RX_CDR_DIVTDC_4 FIELD_PREP_CONST(AIROHA_PCS_PMA_LCPLL_PON_RX_CDR_DIVTDC, 0x3)
++#define AIROHA_PCS_PMA_LCPLL_TDC_FLT_1 0x2c
++#define AIROHA_PCS_PMA_LCPLL_A_TDC GENMASK(11, 8)
++#define AIROHA_PCS_PMA_LCPLL_GPON_SEL BIT(0)
++#define AIROHA_PCS_PMA_LCPLL_GPON_SEL_FROM_EPON FIELD_PREP_CONST(AIROHA_PCS_PMA_LCPLL_GPON_SEL, 0x0)
++#define AIROHA_PCS_PMA_LCPLL_GPON_SEL_FROM_GPON FIELD_PREP_CONST(AIROHA_PCS_PMA_LCPLL_GPON_SEL, 0x1)
++#define AIROHA_PCS_PMA_LCPLL_TDC_FLT_3 0x34
++#define AIROHA_PCS_PMA_LCPLL_NCPO_LOAD BIT(8)
++#define AIROHA_PCS_PMA_LCPLL_NCPO_SHIFT GENMASK(1, 0)
++#define AIROHA_PCS_PMA_LCPLL_TDC_FLT_5 0x3c
++#define AIROHA_PCS_PMA_LCPLL_TDC_AUTOPW_NCPO BIT(16)
++#define AIROHA_PCS_PMA_LCPLL_TDC_FLT_6 0x40
++#define AIROHA_PCS_PMA_LCPLL_NCPO_CHG_DELAY GENMASK(9, 8)
++#define AIROHA_PCS_PMA_LCPLL_NCPO_CHG_DELAY_SEL FIELD_PREP_CONST(AIROHA_PCS_PMA_LCPLL_NCPO_CHG_DELAY, 0x0)
++#define AIROHA_PCS_PMA_LCPLL_NCPO_CHG_DELAY_SEL_D1 FIELD_PREP_CONST(AIROHA_PCS_PMA_LCPLL_NCPO_CHG_DELAY, 0x1)
++#define AIROHA_PCS_PMA_LCPLL_NCPO_CHG_DELAY_SEL_D2 FIELD_PREP_CONST(AIROHA_PCS_PMA_LCPLL_NCPO_CHG_DELAY, 0x2)
++#define AIROHA_PCS_PMA_LCPLL_NCPO_CHG_DELAY_SEL_D3 FIELD_PREP_CONST(AIROHA_PCS_PMA_LCPLL_NCPO_CHG_DELAY, 0x3)
++#define AIROHA_PCS_PMA_LCPLL_TDC_PCW_1 0x48
++#define AIROHA_PCS_PMA_LCPLL_PON_HRDDS_PCW_NCPO_GPON GENMASK(30, 0)
++#define AIROHA_PCS_PMA_LCPLL_TDC_PCW_2 0x4c
++#define AIROHA_PCS_PMA_LCPLL_PON_HRDDS_PCW_NCPO_EPON GENMASK(30, 0)
++#define AIROHA_PCS_PMA_RX_EYE_TOP_EYEINDEX_CTRL_0 0x68
++#define AIROHA_PCS_PMA_X_MAX GENMASK(26, 16)
++#define AIROHA_PCS_PMA_X_MIN GENMASK(10, 0)
++#define AIROHA_PCS_PMA_RX_EYE_TOP_EYEINDEX_CTRL_1 0x6c
++#define AIROHA_PCS_PMA_INDEX_MODE BIT(16)
++#define AIROHA_PCS_PMA_Y_MAX GENMASK(14, 8)
++#define AIROHA_PCS_PMA_Y_MIN GENMASK(6, 0)
++#define AIROHA_PCS_PMA_RX_EYE_TOP_EYEINDEX_CTRL_2 0x70
++#define AIROHA_PCS_PMA_EYEDUR GENMASK(19, 0)
++#define AIROHA_PCS_PMA_RX_EYE_TOP_EYEINDEX_CTRL_3 0x74
++#define AIROHA_PCS_PMA_EYE_NEXTPTS BIT(16)
++#define AIROHA_PCS_PMA_EYE_NEXTPTS_TOGGLE BIT(8)
++#define AIROHA_PCS_PMA_EYE_NEXTPTS_SEL BIT(0)
++#define AIROHA_PCS_PMA_RX_EYE_TOP_EYEOPENING_CTRL_0 0x78
++#define AIROHA_PCS_PMA_EYECNT_VTH GENMASK(15, 8)
++#define AIROHA_PCS_PMA_EYECNT_HTH GENMASK(7, 0)
++#define AIROHA_PCS_PMA_RX_EYE_TOP_EYEOPENING_CTRL_1 0x7c
++#define AIROHA_PCS_PMA_EO_VTH GENMASK(23, 16)
++#define AIROHA_PCS_PMA_EO_HTH GENMASK(10, 0)
++#define AIROHA_PCS_PMA_RX_EYE_TOP_EYECNT_CTRL_0 0x80
++#define AIROHA_PCS_PMA_EYE_MASK GENMASK(31, 24)
++#define AIROHA_PCS_PMA_CNTFOREVER BIT(16)
++#define AIROHA_PCS_PMA_CNTLEN GENMASK(9, 0)
++#define AIROHA_PCS_PMA_RX_EYE_TOP_EYECNT_CTRL_1 0x84
++#define AIROHA_PCS_PMA_FORCE_EYEDUR_INIT_B BIT(24)
++#define AIROHA_PCS_PMA_FORCE_EYEDUR_EN BIT(16)
++#define AIROHA_PCS_PMA_DISB_EYEDUR_INIT_B BIT(8)
++#define AIROHA_PCS_PMA_DISB_EYEDUR_EN 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)
+@@ -564,14 +706,49 @@
+ #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_0 0x108
++#define AIROHA_PCS_PMA_DISB_RX_FEOS_EN BIT(24)
++#define AIROHA_PCS_PMA_DISB_RX_PDOS_EN BIT(16)
++#define AIROHA_PCS_PMA_DISB_RX_PICAL_EN BIT(8)
++#define AIROHA_PCS_PMA_DISB_RX_OS_EN BIT(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_DISB_RX_BLWC_EN BIT(16)
++#define AIROHA_PCS_PMA_DISB_RX_OS_RDY BIT(8)
++#define AIROHA_PCS_PMA_DISB_RX_SDCAL_EN BIT(0)
++#define AIROHA_PCS_PMA_RX_CTRL_SEQUENCE_FORCE_CTRL_0 0x110
++#define AIROHA_PCS_PMA_FORCE_RX_FEOS_EN BIT(24)
++#define AIROHA_PCS_PMA_FORCE_RX_PDOS_EN BIT(16)
++#define AIROHA_PCS_PMA_FORCE_RX_PICAL_EN BIT(8)
++#define AIROHA_PCS_PMA_FORCE_RX_OS_EN BIT(0)
+ #define AIROHA_PCS_PMA_RX_CTRL_SEQUENCE_FORCE_CTRL_1 0x114
+ #define AIROHA_PCS_PMA_FORCE_RX_RDY BIT(24)
++#define AIROHA_PCS_PMA_FORCE_RX_BLWC_EN BIT(16)
++#define AIROHA_PCS_PMA_FORCE_RX_OS_RDY BIT(8)
++#define AIROHA_PCS_PMA_FORCE_RX_SDCAL_EN BIT(0)
++#define AIROHA_PCS_PMA_PHY_EQ_CTRL_0 0x118
++#define AIROHA_PCS_PMA_VEO_MASK GENMASK(31, 24)
++#define AIROHA_PCS_PMA_HEO_MASK GENMASK(18, 8)
++#define AIROHA_PCS_PMA_EQ_EN_DELAY GENMASK(7, 0)
++#define AIROHA_PCS_PMA_PHY_EQ_CTRL_1 0x11c
++#define AIROHA_PCS_PMA_B_ZERO_SEL BIT(24)
++#define AIROHA_PCS_PMA_HEO_EMPHASIS BIT(16)
++#define AIROHA_PCS_PMA_A_MGAIN BIT(8)
++#define AIROHA_PCS_PMA_A_LGAIN BIT(0)
+ #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_FEOS 0x144
++#define AIROHA_PCS_PMA_EQ_FORCE_BLWC_FREEZE BIT(8)
++#define AIROHA_PCS_PMA_LFSEL GENMASK(7, 0)
++#define AIROHA_PCS_PMA_SS_RX_BLWC 0x148
++#define AIROHA_PCS_PMA_EQ_BLWC_CNT_BOT_LIM GENMASK(29, 23)
++#define AIROHA_PCS_PMA_EQ_BLWC_CNT_TOP_LIM GENMASK(22, 16)
++#define AIROHA_PCS_PMA_EQ_BLWC_GAIN GENMASK(11, 8)
++#define AIROHA_PCS_PMA_EQ_BLWC_POL BIT(0)
++#define AIROHA_PCS_PMA_EQ_BLWC_POL_NORMAL FIELD_PREP_CONST(AIROHA_PCS_PMA_EQ_BLWC_POL, 0x0)
++#define AIROHA_PCS_PMA_EQ_BLWC_POL_INVERSION FIELD_PREP_CONST(AIROHA_PCS_PMA_EQ_BLWC_POL, 0x1)
+ #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)
+@@ -590,31 +767,182 @@
+ #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_RX_PI_CAL 0x15c
++#define AIROHA_PCS_PMA_KPGAIN GENMASK(10, 8)
++#define AIROHA_PCS_PMA_RX_CAL1 0x160
++#define AIROHA_PCS_PMA_CAL_CYC GENMASK(25, 24)
++#define AIROHA_PCS_PMA_CAL_CYC_63 FIELD_PREP_CONST(AIROHA_PCS_PMA_CAL_CYC, 0x0)
++#define AIROHA_PCS_PMA_CAL_CYC_15 FIELD_PREP_CONST(AIROHA_PCS_PMA_CAL_CYC, 0x1)
++#define AIROHA_PCS_PMA_CAL_CYC_31 FIELD_PREP_CONST(AIROHA_PCS_PMA_CAL_CYC, 0x2)
++#define AIROHA_PCS_PMA_CAL_CYC_127 FIELD_PREP_CONST(AIROHA_PCS_PMA_CAL_CYC, 0x3)
++#define AIROHA_PCS_PMA_CAL_STB GENMASK(17, 16)
++#define AIROHA_PCS_PMA_CAL_STB_5US FIELD_PREP_CONST(AIROHA_PCS_PMA_CAL_STB, 0x0)
++#define AIROHA_PCS_PMA_CAL_STB_8US FIELD_PREP_CONST(AIROHA_PCS_PMA_CAL_STB, 0x1)
++#define AIROHA_PCS_PMA_CAL_STB_16US FIELD_PREP_CONST(AIROHA_PCS_PMA_CAL_STB, 0x2)
++#define AIROHA_PCS_PMA_CAL_STB_32US FIELD_PREP_CONST(AIROHA_PCS_PMA_CAL_STB, 0x3)
++#define AIROHA_PCS_PMA_CAL_1US_SET GENMASK(15, 8)
++#define AIROHA_PCS_PMA_SIM_FAST_EN BIT(0)
++#define AIROHA_PCS_PMA_RX_CAL2 0x164
++#define AIROHA_PCS_PMA_CAL_CYC_TIME GENMASK(17, 16)
++#define AIROHA_PCS_PMA_CAL_OUT_OS GENMASK(11, 8)
++#define AIROHA_PCS_PMA_CAL_OS_PULSE BIT(0)
+ #define AIROHA_PCS_PMA_SS_RX_SIGDET_1 0x16c
+ #define AIROHA_PCS_PMA_SIGDET_EN BIT(0)
++#define AIROHA_PCS_PMA_RX_FLL_0 0x170
++#define AIROHA_PCS_PMA_KBAND_KFC GENMASK(25, 24)
++#define AIROHA_PCS_PMA_KBAND_KFC_8 FIELD_PREP_CONST(AIROHA_PCS_PMA_KBAND_KFC, 0x0)
++#define AIROHA_PCS_PMA_KBAND_KFC_16 FIELD_PREP_CONST(AIROHA_PCS_PMA_KBAND_KFC, 0x1)
++#define AIROHA_PCS_PMA_KBAND_KFC_32 FIELD_PREP_CONST(AIROHA_PCS_PMA_KBAND_KFC, 0x2)
++#define AIROHA_PCS_PMA_KBAND_KFC_64 FIELD_PREP_CONST(AIROHA_PCS_PMA_KBAND_KFC, 0x3)
++#define AIROHA_PCS_PMA_FPKDIV GENMASK(18, 8)
++#define AIROHA_PCS_PMA_KBAND_PREDIV GENMASK(2, 0)
++#define AIROHA_PCS_PMA_KBAND_PREDIV_1 FIELD_PREP_CONST(AIROHA_PCS_PMA_KBAND_PREDIV, 0x0)
++#define AIROHA_PCS_PMA_KBAND_PREDIV_2 FIELD_PREP_CONST(AIROHA_PCS_PMA_KBAND_PREDIV, 0x1)
++#define AIROHA_PCS_PMA_KBAND_PREDIV_4 FIELD_PREP_CONST(AIROHA_PCS_PMA_KBAND_PREDIV, 0x2)
++#define AIROHA_PCS_PMA_KBAND_PREDIV_8 FIELD_PREP_CONST(AIROHA_PCS_PMA_KBAND_PREDIV, 0x3)
+ #define AIROHA_PCS_PMA_RX_FLL_1 0x174
++#define AIROHA_PCS_PMA_SYMBOL_WD GENMASK(26, 24)
++#define AIROHA_PCS_PMA_SETTLE_TIME_SEL GENMASK(18, 16)
+ #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_AMP GENMASK(10, 8)
++#define AIROHA_PCS_PMA_PRBS_SEL GENMASK(2, 0)
+ #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_6 0x188
++#define AIROHA_PCS_PMA_LNX_SW_FLL_4_LATCH_EN BIT(24)
++#define AIROHA_PCS_PMA_LNX_SW_FLL_3_LATCH_EN BIT(16)
++#define AIROHA_PCS_PMA_LNX_SW_FLL_2_LATCH_EN BIT(8)
++#define AIROHA_PCS_PMA_LNX_SW_FLL_1_LATCH_EN BIT(0)
+ #define AIROHA_PCS_PMA_RX_FLL_B 0x19c
+ #define AIROHA_PCS_PMA_LOAD_EN BIT(0)
++#define AIROHA_PCS_PMA_RX_PDOS_CTRL_0 0x200
++#define AIROHA_PCS_PMA_SAP_SEL GENMASK(18, 16)
++#define AIROHA_PCS_PMA_SAP_SEL_SHIFT_6 FIELD_PREP_CONST(AIROHA_PCS_PMA_SAP_SEL, 0x0)
++#define AIROHA_PCS_PMA_SAP_SEL_SHIFT_7 FIELD_PREP_CONST(AIROHA_PCS_PMA_SAP_SEL, 0x1)
++#define AIROHA_PCS_PMA_SAP_SEL_SHIFT_8 FIELD_PREP_CONST(AIROHA_PCS_PMA_SAP_SEL, 0x2)
++#define AIROHA_PCS_PMA_SAP_SEL_SHIFT_9 FIELD_PREP_CONST(AIROHA_PCS_PMA_SAP_SEL, 0x3)
++#define AIROHA_PCS_PMA_SAP_SEL_SHIFT_10 FIELD_PREP_CONST(AIROHA_PCS_PMA_SAP_SEL, 0x4)
++#define AIROHA_PCS_PMA_EYE_BLWC_ADD BIT(8)
++#define AIROHA_PCS_PMA_DATA_BLWC_ADD BIT(0)
++#define AIROHA_PCS_PMA_RX_RESET_0 0x204
++#define AIROHA_PCS_PMA_CAL_RST_B BIT(24)
++#define AIROHA_PCS_PMA_EQ_PI_CAL_RST_B BIT(16)
++#define AIROHA_PCS_PMA_FEOS_RST_B BIT(8)
+ #define AIROHA_PCS_PMA_RX_RESET_1 0x208
+ #define AIROHA_PCS_PMA_SIGDET_RST_B BIT(8)
++#define AIROHA_PCS_PMA_PDOS_RST_B BIT(0)
++#define AIROHA_PCS_PMA_RX_DEBUG_0 0x20c
++#define AIROHA_PCS_PMA_RO_TOGGLE BIT(24)
++#define AIROHA_PCS_PMA_BISTCTL_CONTROL 0x210
++#define AIROHA_PCS_PMA_BISTCTL_PAT_SEL GENMASK(4, 0)
++/* AIROHA_PCS_PMA_BISTCTL_PAT_SEL_ALL_0 FIELD_PREP_CONST(AIROHA_PCS_PMA_BISTCTL_PAT_SEL, 0x0) */
++#define AIROHA_PCS_PMA_BISTCTL_PAT_SEL_PRBS7 FIELD_PREP_CONST(AIROHA_PCS_PMA_BISTCTL_PAT_SEL, 0x1)
++#define AIROHA_PCS_PMA_BISTCTL_PAT_SEL_PRBS9 FIELD_PREP_CONST(AIROHA_PCS_PMA_BISTCTL_PAT_SEL, 0x2)
++#define AIROHA_PCS_PMA_BISTCTL_PAT_SEL_PRBS15 FIELD_PREP_CONST(AIROHA_PCS_PMA_BISTCTL_PAT_SEL, 0x3)
++#define AIROHA_PCS_PMA_BISTCTL_PAT_SEL_PRBS23 FIELD_PREP_CONST(AIROHA_PCS_PMA_BISTCTL_PAT_SEL, 0x4)
++#define AIROHA_PCS_PMA_BISTCTL_PAT_SEL_PRBS31 FIELD_PREP_CONST(AIROHA_PCS_PMA_BISTCTL_PAT_SEL, 0x5)
++#define AIROHA_PCS_PMA_BISTCTL_PAT_SEL_HFTP FIELD_PREP_CONST(AIROHA_PCS_PMA_BISTCTL_PAT_SEL, 0x6)
++#define AIROHA_PCS_PMA_BISTCTL_PAT_SEL_MFTP FIELD_PREP_CONST(AIROHA_PCS_PMA_BISTCTL_PAT_SEL, 0x7)
++#define AIROHA_PCS_PMA_BISTCTL_PAT_SEL_SQUARE_4 FIELD_PREP_CONST(AIROHA_PCS_PMA_BISTCTL_PAT_SEL, 0x8)
++#define AIROHA_PCS_PMA_BISTCTL_PAT_SEL_SQUARE_5_LFTP FIELD_PREP_CONST(AIROHA_PCS_PMA_BISTCTL_PAT_SEL, 0x9)
++#define AIROHA_PCS_PMA_BISTCTL_PAT_SEL_SQUARE_6 FIELD_PREP_CONST(AIROHA_PCS_PMA_BISTCTL_PAT_SEL, 0xa)
++#define AIROHA_PCS_PMA_BISTCTL_PAT_SEL_SQUARE_7 FIELD_PREP_CONST(AIROHA_PCS_PMA_BISTCTL_PAT_SEL, 0xb)
++#define AIROHA_PCS_PMA_BISTCTL_PAT_SEL_SQUARE_8_LFTP FIELD_PREP_CONST(AIROHA_PCS_PMA_BISTCTL_PAT_SEL, 0xc)
++#define AIROHA_PCS_PMA_BISTCTL_PAT_SEL_SQUARE_9 FIELD_PREP_CONST(AIROHA_PCS_PMA_BISTCTL_PAT_SEL, 0xd)
++#define AIROHA_PCS_PMA_BISTCTL_PAT_SEL_SQUARE_10 FIELD_PREP_CONST(AIROHA_PCS_PMA_BISTCTL_PAT_SEL, 0xe)
++#define AIROHA_PCS_PMA_BISTCTL_PAT_SEL_SQUARE_11 FIELD_PREP_CONST(AIROHA_PCS_PMA_BISTCTL_PAT_SEL, 0xf)
++#define AIROHA_PCS_PMA_BISTCTL_PAT_SEL_PROG_80 FIELD_PREP_CONST(AIROHA_PCS_PMA_BISTCTL_PAT_SEL, 0x10)
++#define AIROHA_PCS_PMA_BISTCTL_PAT_SEL_ALL_1 FIELD_PREP_CONST(AIROHA_PCS_PMA_BISTCTL_PAT_SEL, 0x11)
++#define AIROHA_PCS_PMA_BISTCTL_PAT_SEL_ALL_0 FIELD_PREP_CONST(AIROHA_PCS_PMA_BISTCTL_PAT_SEL, 0x12)
++#define AIROHA_PCS_PMA_BISTCTL_PAT_SEL_PRBS11 FIELD_PREP_CONST(AIROHA_PCS_PMA_BISTCTL_PAT_SEL, 0x13)
++#define AIROHA_PCS_PMA_BISTCTL_ALIGN_PAT 0x214
++#define AIROHA_PCS_PMA_BISTCTL_POLLUTION 0x220
++#define AIROHA_PCS_PMA_BIST_TX_DATA_POLLUTION_LATCH BIT(16)
++#define AIROHA_PCS_PMA_BISTCTL_PRBS_INITIAL_SEED 0x224
++#define AIROHA_PCS_PMA_BISTCTL_PRBS_FAIL_THRESHOLD 0x230
++#define AIROHA_PCS_PMA_BISTCTL_PRBS_FAIL_THRESHOLD_MASK GENMASK(15, 0)
++#define AIROHA_PCS_PMA_RX_TORGS_DEBUG_2 0x23c
++#define AIROHA_PCS_PMA_PI_CAL_DATA_OUT GENMASK(22, 16)
++#define AIROHA_PCS_PMA_RX_TORGS_DEBUG_5 0x248
++#define AIROHA_PCS_PMA_VEO_RDY BIT(24)
++#define AIROHA_PCS_PMA_HEO_RDY BIT(16)
++#define AIROHA_PCS_PMA_RX_TORGS_DEBUG_9 0x258
++#define AIROHA_PCS_PMA_EO_Y_DONE BIT(24)
++#define AIROHA_PCS_PMA_EO_X_DONE BIT(16)
++#define AIROHA_PCS_PMA_RX_TORGS_DEBUG_10 0x25c
++#define AIROHA_PCS_PMA_EYE_EL GENMASK(26, 16)
++#define AIROHA_PCS_PMA_EYE_ER GENMASK(10, 0)
+ #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_TX_CALIB_0 0x264
++#define AIROHA_PCS_PMA_TXCALIB_FORCE_TERMP_SEL GENMASK(25, 24)
++#define AIROHA_PCS_PMA_TXCALIB_FORCE_TERMP_SEL_EN BIT(16)
++#define AIROHA_PCS_PMA_RX_TORGS_DEBUG_11 0x290
++#define AIROHA_PCS_PMA_EYE_EB GENMASK(14, 8)
++#define AIROHA_PCS_PMA_EYE_EU GENMASK(6, 0)
++#define AIROHA_PCS_PMA_RX_FORCE_MODE_0 0x294
++#define AIROHA_PCS_PMA_FORCE_DA_XPON_CDR_LPF_RSTB BIT(24)
++#define AIROHA_PCS_PMA_FORCE_DA_XPON_RX_FE_GAIN_CTRL GENMASK(1, 0)
++#define AIROHA_PCS_PMA_RX_DISB_MODE_0 0x300
++#define AIROHA_PCS_PMA_DISB_DA_XPON_CDR_LPF_RSTB BIT(24)
++#define AIROHA_PCS_PMA_DISB_DA_XPON_RX_FE_GAIN_CTRL BIT(0)
++#define AIROHA_PCS_PMA_RX_DISB_MODE_1 0x304
++#define AIROHA_PCS_PMA_DISB_DA_XPON_RX_DAC_E0 BIT(24)
++#define AIROHA_PCS_PMA_DISB_DA_XPON_RX_DAC_D1 BIT(16)
++#define AIROHA_PCS_PMA_DISB_DA_XPON_RX_DAC_D0 BIT(8)
++#define AIROHA_PCS_PMA_RX_DISB_MODE_2 0x308
++#define AIROHA_PCS_PMA_DISB_DA_XPON_CDR_PR_PIEYE BIT(24)
++#define AIROHA_PCS_PMA_DISB_DA_XPON_RX_FE_VOS BIT(16)
++#define AIROHA_PCS_PMA_DISB_DA_XPON_RX_DAC_EYE BIT(8)
++#define AIROHA_PCS_PMA_DISB_DA_XPON_RX_DAC_E1 BIT(0)
++#define AIROHA_PCS_PMA_RX_FORCE_MODE_3 0x30c
++#define AIROHA_PCS_PMA_FORCE_EQ_PI_CAL_RDY BIT(0)
++#define AIROHA_PCS_PMA_RX_FORCE_MODE_6 0x318
++#define AIROHA_PCS_PMA_FORCE_RX_OR_PICAL_EN BIT(8)
++#define AIROHA_PCS_PMA_FORCE_EYECNT_RDY BIT(0)
++#define AIROHA_PCS_PMA_RX_DISB_MODE_3 0x31c
++#define AIROHA_PCS_PMA_DISB_RQ_PI_CAL_RDY 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_DISB_MODE_5 0x324
++#define AIROHA_PCS_PMA_DISB_RX_OR_PICAL_EN BIT(24)
++#define AIROHA_PCS_PMA_DISB_EYECNT_RDY BIT(16)
++#define AIROHA_PCS_PMA_RX_FORCE_MODE_7 0x328
++#define AIROHA_PCS_PMA_FORCE_PDOS_RX_RST_B BIT(16)
++#define AIROHA_PCS_PMA_FORCE_RX_AND_PICAL_RSTB BIT(8)
++#define AIROHA_PCS_PMA_FORCE_REF_AND_PICAL_RSTB BIT(0)
++#define AIROHA_PCS_PMA_RX_FORCE_MODE_8 0x32c
++#define AIROHA_PCS_PMA_FORCE_EYECNT_RX_RST_B BIT(24)
++#define AIROHA_PCS_PMA_FORCE_FEOS_RX_RST_B BIT(16)
++#define AIROHA_PCS_PMA_FORCE_SDCAL_REF_RST_B BIT(8)
++#define AIROHA_PCS_PMA_FORCE_BLWC_RX_RST_B BIT(0)
+ #define AIROHA_PCS_PMA_RX_FORCE_MODE_9 0x330
++#define AIROHA_PCS_PMA_FORCE_EYE_TOP_EN BIT(16)
++#define AIROHA_PCS_PMA_FORCE_EYE_RESET_PLU_O BIT(8)
+ #define AIROHA_PCS_PMA_FORCE_FBCK_LOCK BIT(0)
++#define AIROHA_PCS_PMA_RX_DISB_MODE_6 0x334
++#define AIROHA_PCS_PMA_DISB_PDOS_RX_RST_B BIT(16)
++#define AIROHA_PCS_PMA_DISB_RX_AND_PICAL_RSTB BIT(8)
++#define AIROHA_PCS_PMA_DISB_REF_AND_PICAL_RSTB BIT(0)
++#define AIROHA_PCS_PMA_RX_DISB_MODE_7 0x338
++#define AIROHA_PCS_PMA_DISB_EYECNT_RX_RST_B BIT(24)
++#define AIROHA_PCS_PMA_DISB_FEOS_RX_RST_B BIT(16)
++#define AIROHA_PCS_PMA_DISB_SDCAL_REF_RST_B BIT(8)
++#define AIROHA_PCS_PMA_DISB_BLWC_RX_RST_B BIT(0)
+ #define AIROHA_PCS_PMA_RX_DISB_MODE_8 0x33c
++#define AIROHA_PCS_PMA_DISB_EYE_TOP_EN BIT(16)
++#define AIROHA_PCS_PMA_DISB_EYE_RESET_PLU_O BIT(8)
+ #define AIROHA_PCS_PMA_DISB_FBCK_LOCK BIT(0)
++#define AIROHA_PCS_PMA_SS_BIST_1 0x344
++#define AIROHA_PCS_PMA_LNX_BISTCTL_BIT_ERROR_RST_SEL BIT(24)
++#define AIROHA_PCS_PMA_ANLT_PX_LNX_LT_LOS 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)
+@@ -637,7 +965,32 @@
+ #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_CLKPATH_RST_0 0x410
++#define AIROHA_PCS_PMA_CLKPATH_RSTB_CK BIT(8)
++#define AIROHA_PCS_PMA_CLKPATH_RST_EN BIT(0)
++#define AIROHA_PCS_PMA_ADD_XPON_MODE_1 0x414
++#define AIROHA_PCS_PMA_TX_BIST_GEN_EN BIT(16)
++#define AIROHA_PCS_PMA_R2T_MODE BIT(8)
++#define AIROHA_PCS_PMA_ADD_RX2ANA_1 0x424
++#define AIROHA_PCS_PMA_RX_DAC_E0 GENMASK(30, 24)
++#define AIROHA_PCS_PMA_RX_DAC_D1 GENMASK(22, 16)
++#define AIROHA_PCS_PMA_RX_DAC_D0 GENMASK(14, 8)
++#define AIROHA_PCS_PMA_RX_DAC_EYE GENMASK(6, 0)
++#define AIROHA_PCS_PMA_ADD_RX2ANA_2 0x428
++#define AIROHA_PCS_PMA_RX_FEOS_OUT GENMASK(13, 8)
++#define AIROHA_PCS_PMA_RX_DAC_E1 GENMASK(6, 0)
++#define AIROHA_PCS_PMA_PON_TX_COUNTER_0 0x440
++#define AIROHA_PCS_PMA_TXCALIB_5US GENMASK(31, 16)
++#define AIROHA_PCS_PMA_TXCALIB_50US GENMASK(15, 0)
++#define AIROHA_PCS_PMA_PON_TX_COUNTER_1 0x444
++#define AIROHA_PCS_PMA_TX_HSDATA_EN_WAIT GENMASK(31, 16)
++#define AIROHA_PCS_PMA_TX_CK_EN_WAIT GENMASK(15, 0)
++#define AIROHA_PCS_PMA_PON_TX_COUNTER_2 0x448
++#define AIROHA_PCS_PMA_TX_SERDES_RDY_WAIT GENMASK(31, 16)
++#define AIROHA_PCS_PMA_TX_POWER_ON_WAIT GENMASK(15, 0)
+ #define AIROHA_PCS_PMA_SW_RST_SET 0x460
++#define AIROHA_PCS_PMA_SW_XFI_RXMAC_RST_N BIT(17)
++#define AIROHA_PCS_PMA_SW_XFI_TXMAC_RST_N BIT(16)
+ #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)
+@@ -650,17 +1003,32 @@
+ #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_TX_DLY_CTRL 0x468
++#define AIROHA_PCS_PMA_OUTBEN_DATA_MODE GENMASK(30, 28)
++#define AIROHA_PCS_PMA_TX_BEN_EXTEN_FTUNE GENMASK(23, 16)
++#define AIROHA_PCS_PMA_TX_DLY_BEN_FTUNE GENMASK(14, 8)
++#define AIROHA_PCS_PMA_TX_DLY_DATA_FTUNE GENMASK(6, 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
++/* 4ref_ck step:
++ * - 0x1 4ref_ck
++ * - 0x2 8ref_ck
++ * - 0x3 12ref_ck
++ * ...
++ */
++#define AIROHA_PCS_PMA_L2D_TRIG_EQ_EN_TIME GENMASK(15, 8)
++#define AIROHA_PCS_PMA_OS_RDY_LATCH BIT(1)
+ #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_MD32_MEM_CLK_CTRL 0x60c
++#define AIROHA_PCS_PMA_MD32PM_CK_SEL GENMASK(31, 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)
+@@ -683,8 +1051,13 @@
+ #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_CDR_PR_PIEYE BIT(24)
++#define AIROHA_PCS_PMA_FORCE_DA_CDR_PR_PIEYE GENMASK(22, 16)
+ #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_FLL_COR 0x790
++#define AIROHA_PCS_PMA_FORCE_SEL_DA_RX_DAC_EYE BIT(24)
++#define AIROHA_PCS_PMA_FORCE_DA_RX_DAC_EYE GENMASK(22, 16)
+ #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)
+@@ -729,6 +1102,14 @@
+ #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_JCPLL_SDM_SCAN_RSTB 0x83c
++#define AIROHA_PCS_PMA_FORCE_SEL_DA_RX_OSCAL_CKON BIT(24)
++#define AIROHA_PCS_PMA_FORCE_DA_RX_OSCAL_CKON BIT(16)
++#define AIROHA_PCS_PMA_PXP_RX_OSCAL_EN 0x840
++#define AIROHA_PCS_PMA_FORCE_SEL_DA_RX_OSCAL_RSTB BIT(24)
++#define AIROHA_PCS_PMA_FORCE_DA_RX_OSCAL_RSTB BIT(16)
++#define AIROHA_PCS_PMA_FORCE_SEL_DA_RX_OSCAL_EN BIT(8)
++#define AIROHA_PCS_PMA_FORCE_DA_RX_OSCAL_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)
+@@ -739,6 +1120,12 @@
+ #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_TXPLL_KBAND_LOAD_EN 0x858
++#define AIROHA_PCS_PMA_FORCE_SEL_DA_TXPLL_KBAND_LOAD_EN BIT(8)
++#define AIROHA_PCS_PMA_FORCE_DA_TXPLL_KBAND_LOAD_EN BIT(0)
++#define AIROHA_PCS_PMA_PXP_TXPLL_SDM_PCW_CHG 0x864
++#define AIROHA_PCS_PMA_FORCE_SEL_DA_TXPLL_SDM_PCW_CHG BIT(8)
++#define AIROHA_PCS_PMA_FORCE_DA_TXPLL_SDM_PCW_CHG 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)
+@@ -750,10 +1137,31 @@
+ #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_PXP_RX_SIGDET_CAL_EN 0x898
++#define AIROHA_PCS_PMA_FORCE_SEL_DA_RX_SIGDET_CAL_EN BIT(8)
++#define AIROHA_PCS_PMA_FORCE_DA_RX_SIGDET_CAL_EN BIT(0)
++#define AIROHA_PCS_PMA_DIG_RESERVE_12 0x8b8
++#define AIROHA_PCS_PMA_RESERVE_12_FEOS_0 BIT(0)
++#define AIROHA_PCS_PMA_DIG_RESERVE_24 0x8fc
++#define AIROHA_PCS_PMA_FORCE_RX_GEARBOX BIT(12)
++#define AIROHA_PCS_PMA_FORCE_SEL_RX_GEARBOX BIT(8)
+
+ #define AIROHA_PCS_MAX_CALIBRATION_TRY 50
+ #define AIROHA_PCS_MAX_NUM_RSTS 2
+
++enum pon_eo_buf_vals {
++ EYE_EU,
++ EYE_EB,
++ DAC_D0,
++ DAC_D1,
++ DAC_E0,
++ DAC_E1,
++ DAC_EYE,
++ FEOS,
++
++ EO_BUF_MAX,
++};
++
+ enum xfi_port_type {
+ AIROHA_PCS_ETH,
+ AIROHA_PCS_PON,
+@@ -790,6 +1198,11 @@ struct airoha_pcs_port {
+ struct airoha_pcs_match_data {
+ enum xfi_port_type port_type;
+
++ bool hibernation_workaround;
++ bool usxgmii_ber_time_fixup;
++ bool usxgmii_rx_gb_out_vld_tweak;
++ bool usxgmii_xfi_mode_sel;
++
+ int (*bringup)(struct airoha_pcs_priv *priv,
+ phy_interface_t interface);
+ void (*link_up)(struct airoha_pcs_priv *priv);
+@@ -820,3 +1233,20 @@ static inline int an7581_pcs_rxlock_work
+ return 0;
+ }
+ #endif
++
++#ifdef CONFIG_PCS_AIROHA_AN7583
++int an7583_pcs_common_phya_bringup(struct airoha_pcs_priv *priv,
++ phy_interface_t interface);
++
++void an7583_pcs_common_phya_link_up(struct airoha_pcs_priv *priv);
++#else
++static inline int an7583_pcs_common_phya_bringup(struct airoha_pcs_priv *priv,
++ phy_interface_t interface)
++{
++ return -EOPNOTSUPP;
++}
++
++static inline void an7583_pcs_common_phya_link_up(struct airoha_pcs_priv *priv)
++{
++}
++#endif
+--- /dev/null
++++ b/drivers/net/pcs/airoha/pcs-an7583.c
+@@ -0,0 +1,2199 @@
++// SPDX-License-Identifier: GPL-2.0
++/*
++ * Copyright (c) 2024 AIROHA Inc
++ * Author: Christian Marangi <ansuelsmth@gmail.com>
++ */
++#include <linux/phylink.h>
++#include <linux/regmap.h>
++
++#include "pcs-airoha.h"
++
++static void an7583_pcs_dig_reset_hold(struct airoha_pcs_priv *priv)
++{
++ regmap_clear_bits(priv->xfi_pma, AIROHA_PCS_PMA_SW_RST_SET,
++ AIROHA_PCS_PMA_SW_RX_FIFO_RST_N |
++ AIROHA_PCS_PMA_SW_TX_FIFO_RST_N);
++
++ regmap_clear_bits(priv->xfi_pma, AIROHA_PCS_PMA_SW_RST_SET,
++ AIROHA_PCS_PMA_SW_REF_RST_N);
++
++ regmap_clear_bits(priv->xfi_pma, AIROHA_PCS_PMA_SW_RST_SET,
++ AIROHA_PCS_PMA_SW_ALLPCS_RST_N);
++
++ regmap_clear_bits(priv->xfi_pma, AIROHA_PCS_PMA_SW_RST_SET,
++ AIROHA_PCS_PMA_SW_TX_RST_N |
++ AIROHA_PCS_PMA_SW_RX_RST_N);
++
++ regmap_clear_bits(priv->xfi_pma, AIROHA_PCS_PMA_SW_RST_SET,
++ AIROHA_PCS_PMA_SW_PMA_RST_N);
++
++ usleep_range(50, 100);
++}
++
++static void an7583_pcs_dig_reset_release(struct airoha_pcs_priv *priv)
++{
++ regmap_set_bits(priv->xfi_pma, AIROHA_PCS_PMA_SW_RST_SET,
++ AIROHA_PCS_PMA_SW_REF_RST_N);
++
++ regmap_set_bits(priv->xfi_pma, AIROHA_PCS_PMA_SW_RST_SET,
++ AIROHA_PCS_PMA_SW_TX_RST_N |
++ AIROHA_PCS_PMA_SW_RX_RST_N);
++
++ regmap_set_bits(priv->xfi_pma, AIROHA_PCS_PMA_SW_RST_SET,
++ AIROHA_PCS_PMA_SW_PMA_RST_N);
++
++ regmap_set_bits(priv->xfi_pma, AIROHA_PCS_PMA_SW_RST_SET,
++ AIROHA_PCS_PMA_SW_RX_FIFO_RST_N |
++ AIROHA_PCS_PMA_SW_TX_FIFO_RST_N);
++
++ regmap_set_bits(priv->xfi_pma, AIROHA_PCS_PMA_SW_RST_SET,
++ AIROHA_PCS_PMA_SW_ALLPCS_RST_N);
++
++ usleep_range(100, 200);
++}
++
++static void an7583_pcs_common_phya_txpll(struct airoha_pcs_priv *priv,
++ phy_interface_t interface)
++{
++ u32 pcw, tdc_pcw;
++
++ switch (interface) {
++ case PHY_INTERFACE_MODE_SGMII: /* DS(RX)_1.25G / US(TX)_1.25G*/
++ case PHY_INTERFACE_MODE_1000BASEX:
++ pcw = 0x32000000;
++ tdc_pcw = 0x64000000;
++ break;
++ case PHY_INTERFACE_MODE_2500BASEX: /* DS(RX)_3.125G / US(TX)_3.125G */
++ pcw = 0x3e800000;
++ tdc_pcw = 0x7d000000;
++ break;
++ case PHY_INTERFACE_MODE_5GBASER: /* DS(RX)_5.15625G / US(TX)_5.15625G */
++ case PHY_INTERFACE_MODE_USXGMII: /* DS(RX)_10.31252G / US(TX)_10.3125G */
++ case PHY_INTERFACE_MODE_10GBASER:
++ pcw = 0x33900000;
++ tdc_pcw = 0x67200000;
++ break;
++ default:
++ return;
++ }
++
++ regmap_set_bits(priv->xfi_pma, AIROHA_PCS_PMA_PXP_CDR_PR_IDAC,
++ AIROHA_PCS_PMA_FORCE_SEL_DA_TXPLL_SDM_PCW);
++
++ regmap_set_bits(priv->xfi_pma, AIROHA_PCS_PMA_LCPLL_TDC_FLT_3,
++ AIROHA_PCS_PMA_LCPLL_NCPO_LOAD);
++
++ regmap_update_bits(priv->xfi_pma, AIROHA_PCS_PMA_PXP_TXPLL_SDM_PCW,
++ AIROHA_PCS_PMA_FORCE_DA_TXPLL_SDM_PCW,
++ FIELD_PREP(AIROHA_PCS_PMA_FORCE_DA_TXPLL_SDM_PCW, pcw));
++
++ regmap_update_bits(priv->xfi_pma, AIROHA_PCS_PMA_LCPLL_TDC_PCW_1,
++ AIROHA_PCS_PMA_LCPLL_PON_HRDDS_PCW_NCPO_GPON,
++ FIELD_PREP(AIROHA_PCS_PMA_LCPLL_PON_HRDDS_PCW_NCPO_GPON,
++ tdc_pcw));
++
++ regmap_update_bits(priv->xfi_pma, AIROHA_PCS_PMA_LCPLL_TDC_PCW_2,
++ AIROHA_PCS_PMA_LCPLL_PON_HRDDS_PCW_NCPO_EPON,
++ FIELD_PREP(AIROHA_PCS_PMA_LCPLL_PON_HRDDS_PCW_NCPO_EPON,
++ tdc_pcw));
++}
++
++static void an7583_pcs_common_phya_tx(struct airoha_pcs_priv *priv,
++ phy_interface_t interface)
++{
++ const struct airoha_pcs_match_data *data = priv->data;
++ u32 tx_rate_ctrl;
++ u32 ckin_divisor;
++ u32 fir_cn1, fir_c0b, fir_c1, fir_c2;
++ u32 tx_ben_exten_ftune;
++ u32 tx_dly_ben_ftune;
++ u32 tx_dly_data_ftune;
++
++ if (data->port_type == AIROHA_PCS_ETH)
++ tx_ben_exten_ftune = 0x2;
++
++ 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 = 8;
++ fir_c1 = 0;
++ fir_c2 = 0;
++
++ if (data->port_type == AIROHA_PCS_PON) {
++ tx_ben_exten_ftune = 0x7;
++ tx_dly_ben_ftune = 0x2;
++ tx_dly_data_ftune = 0x6;
++ }
++ break;
++ case PHY_INTERFACE_MODE_2500BASEX:
++ ckin_divisor = BIT(2);
++ tx_rate_ctrl = BIT(0);
++ fir_cn1 = 0;
++ fir_c0b = 8;
++ fir_c1 = 1;
++ fir_c2 = 0;
++ if (data->port_type == AIROHA_PCS_PON)
++ tx_ben_exten_ftune = 0x2;
++ break;
++ case PHY_INTERFACE_MODE_5GBASER:
++ ckin_divisor = BIT(2);
++ tx_rate_ctrl = BIT(1);
++ fir_cn1 = 0;
++ fir_c0b = 14;
++ fir_c1 = 4;
++ fir_c2 = 0;
++ if (data->port_type == AIROHA_PCS_PON)
++ tx_ben_exten_ftune = 0x2;
++ break;
++ case PHY_INTERFACE_MODE_USXGMII:
++ case PHY_INTERFACE_MODE_10GBASER:
++ ckin_divisor = BIT(2) | BIT(0);
++ tx_rate_ctrl = BIT(1);
++ fir_cn1 = 0;
++ fir_c0b = 14;
++ fir_c1 = 4;
++ fir_c2 = 0;
++
++ if (data->port_type == AIROHA_PCS_PON) {
++ tx_ben_exten_ftune = 0x16;
++ tx_dly_ben_ftune = 0xd;
++ tx_dly_data_ftune = 0x30;
++ }
++
++ break;
++ default:
++ return;
++ }
++
++ regmap_set_bits(priv->xfi_ana, AIROHA_PCS_ANA_PXP_TX_CKLDO_EN,
++ AIROHA_PCS_ANA_TX_DMEDGEGEN_EN |
++ AIROHA_PCS_ANA_TX_CKLDO_EN);
++
++ regmap_update_bits(priv->xfi_ana, AIROHA_PCS_ANA_PXP_CMN_EN,
++ AIROHA_PCS_ANA_CMN_VREFSEL |
++ AIROHA_PCS_ANA_CMN_MPXSELTOP_DC |
++ AIROHA_PCS_ANA_CMN_EN,
++ AIROHA_PCS_ANA_CMN_VREFSEL_9V |
++ FIELD_PREP(AIROHA_PCS_ANA_CMN_MPXSELTOP_DC, 0x1) |
++ AIROHA_PCS_ANA_CMN_EN);
++
++ regmap_set_bits(priv->xfi_pma, AIROHA_PCS_PMA_PXP_TX_ACJTAG_EN,
++ AIROHA_PCS_PMA_FORCE_SEL_DA_TX_CKIN_SEL |
++ AIROHA_PCS_PMA_FORCE_DA_TX_CKIN_SEL);
++
++ regmap_update_bits(priv->xfi_pma, AIROHA_PCS_PMA_PXP_TX_FIR_C0B,
++ AIROHA_PCS_PMA_FORCE_SEL_DA_TX_FIR_CN1 |
++ AIROHA_PCS_PMA_FORCE_DA_TX_FIR_CN1 |
++ AIROHA_PCS_PMA_FORCE_SEL_DA_TX_FIR_C0B |
++ AIROHA_PCS_PMA_FORCE_DA_TX_FIR_C0B,
++ AIROHA_PCS_PMA_FORCE_SEL_DA_TX_FIR_CN1 |
++ FIELD_PREP(AIROHA_PCS_PMA_FORCE_DA_TX_FIR_CN1, fir_cn1) |
++ AIROHA_PCS_PMA_FORCE_SEL_DA_TX_FIR_C0B |
++ FIELD_PREP(AIROHA_PCS_PMA_FORCE_DA_TX_FIR_C0B, fir_c0b));
++
++ regmap_update_bits(priv->xfi_pma, AIROHA_PCS_PMA_PXP_TX_FIR_C1,
++ AIROHA_PCS_PMA_FORCE_SEL_DA_TX_FIR_C2 |
++ AIROHA_PCS_PMA_FORCE_DA_TX_FIR_C2 |
++ AIROHA_PCS_PMA_FORCE_SEL_DA_TX_FIR_C1 |
++ AIROHA_PCS_PMA_FORCE_DA_TX_FIR_C1,
++ AIROHA_PCS_PMA_FORCE_SEL_DA_TX_FIR_C2 |
++ FIELD_PREP(AIROHA_PCS_PMA_FORCE_DA_TX_FIR_C2, fir_c2) |
++ AIROHA_PCS_PMA_FORCE_SEL_DA_TX_FIR_C1 |
++ FIELD_PREP(AIROHA_PCS_PMA_FORCE_DA_TX_FIR_C1, fir_c1));
++
++ regmap_update_bits(priv->xfi_pma, AIROHA_PCS_PMA_PXP_TX_TERM_SEL,
++ AIROHA_PCS_PMA_FORCE_SEL_DA_TX_CKIN_DIVISOR |
++ AIROHA_PCS_PMA_FORCE_DA_TX_CKIN_DIVISOR,
++ AIROHA_PCS_PMA_FORCE_SEL_DA_TX_CKIN_DIVISOR |
++ FIELD_PREP(AIROHA_PCS_PMA_FORCE_DA_TX_CKIN_DIVISOR,
++ ckin_divisor));
++
++ regmap_update_bits(priv->xfi_pma, AIROHA_PCS_PMA_PXP_TX_RATE_CTRL,
++ AIROHA_PCS_PMA_FORCE_SEL_DA_TX_RATE_CTRL |
++ AIROHA_PCS_PMA_FORCE_DA_TX_RATE_CTRL,
++ AIROHA_PCS_PMA_FORCE_SEL_DA_TX_RATE_CTRL |
++ FIELD_PREP(AIROHA_PCS_PMA_FORCE_DA_TX_RATE_CTRL,
++ tx_rate_ctrl));
++
++ regmap_update_bits(priv->xfi_pma, AIROHA_PCS_PMA_XPON_TX_RATE_CTRL,
++ AIROHA_PCS_PMA_PON_TX_RATE_CTRL,
++ FIELD_PREP(AIROHA_PCS_PMA_PON_TX_RATE_CTRL,
++ tx_rate_ctrl));
++
++ regmap_update_bits(priv->xfi_pma, AIROHA_PCS_PMA_TX_DLY_CTRL,
++ AIROHA_PCS_PMA_TX_BEN_EXTEN_FTUNE,
++ FIELD_PREP(AIROHA_PCS_PMA_TX_BEN_EXTEN_FTUNE, tx_ben_exten_ftune));
++
++ if (data->port_type == AIROHA_PCS_PON) {
++ if (interface == PHY_INTERFACE_MODE_SGMII || interface == PHY_INTERFACE_MODE_1000BASEX ||
++ interface == PHY_INTERFACE_MODE_USXGMII || interface == PHY_INTERFACE_MODE_10GBASER)
++ regmap_update_bits(priv->xfi_pma, AIROHA_PCS_PMA_TX_DLY_CTRL,
++ AIROHA_PCS_PMA_TX_DLY_BEN_FTUNE |
++ AIROHA_PCS_PMA_TX_DLY_DATA_FTUNE,
++ FIELD_PREP(AIROHA_PCS_PMA_TX_DLY_BEN_FTUNE, tx_dly_ben_ftune) |
++ FIELD_PREP(AIROHA_PCS_PMA_TX_DLY_DATA_FTUNE, tx_dly_data_ftune));
++
++ regmap_update_bits(priv->xfi_pma, AIROHA_PCS_PMA_MD32_MEM_CLK_CTRL,
++ AIROHA_PCS_PMA_MD32PM_CK_SEL,
++ FIELD_PREP(AIROHA_PCS_PMA_MD32PM_CK_SEL, 0x3));
++
++ regmap_update_bits(priv->xfi_pma, AIROHA_PCS_PMA_TX_DLY_CTRL,
++ AIROHA_PCS_PMA_OUTBEN_DATA_MODE,
++ FIELD_PREP(AIROHA_PCS_PMA_OUTBEN_DATA_MODE, 0x1));
++ }
++}
++
++static void an7583_pcs_common_phya_rx(struct airoha_pcs_priv *priv,
++ phy_interface_t interface)
++{
++ const struct airoha_pcs_match_data *data = priv->data;
++
++ u32 rx_rev0;
++ u32 fe_gain_ctrl;
++ u32 dig_reserve_0;
++ u32 rx_force_mode_0;
++ u32 cdr_pr_beta_dac;
++ u32 phyck_sel;
++ u32 phyck_div;
++ u32 lpf_ratio;
++ u32 busbit_sel;
++ u32 rx_rate_ctrl;
++ u32 osr;
++
++ switch (interface) {
++ case PHY_INTERFACE_MODE_SGMII:
++ case PHY_INTERFACE_MODE_1000BASEX:
++ dig_reserve_0 = 0x300;
++ cdr_pr_beta_dac = 0x8;
++ phyck_sel = 0x1;
++ phyck_div = 0x29;
++ lpf_ratio = 0x3;
++ osr = 0x3;
++ rx_rate_ctrl = 0x0;
++ break;
++ case PHY_INTERFACE_MODE_2500BASEX:
++ dig_reserve_0 = 0x300;
++ cdr_pr_beta_dac = 0x6;
++ phyck_sel = 0x1;
++ phyck_div = 0xb;
++ lpf_ratio = 0x1;
++ osr = 0x1;
++ rx_rate_ctrl = 0x0;
++ break;
++ case PHY_INTERFACE_MODE_5GBASER:
++ dig_reserve_0 = 0x400;
++ cdr_pr_beta_dac = 0x8;
++ phyck_sel = 0x2;
++ phyck_div = 0x42;
++ lpf_ratio = 0x1;
++ osr = 0x1;
++ rx_rate_ctrl = 0x2;
++ break;
++ case PHY_INTERFACE_MODE_USXGMII:
++ case PHY_INTERFACE_MODE_10GBASER:
++ dig_reserve_0 = 0x100;
++ cdr_pr_beta_dac = 0x8;
++ phyck_sel = 0x2;
++ phyck_div = 0x42;
++ lpf_ratio = 0x0;
++ osr = 0x0;
++ rx_rate_ctrl = 0x2;
++ break;
++ default:
++ return;
++ }
++ regmap_update_bits(priv->xfi_ana, AIROHA_PCS_ANA_PXP_RX_REV_0,
++ AIROHA_PCS_ANA_REV_1_FE_BUF1_BIAS_CTRL |
++ AIROHA_PCS_ANA_REV_1_FE_BUF2_BIAS_CTRL |
++ AIROHA_PCS_ANA_REV_1_SIGDET_ILEAK,
++ FIELD_PREP(AIROHA_PCS_ANA_REV_1_FE_BUF1_BIAS_CTRL, BIT(2)) |
++ FIELD_PREP(AIROHA_PCS_ANA_REV_1_FE_BUF2_BIAS_CTRL, BIT(2)) |
++ FIELD_PREP(AIROHA_PCS_ANA_REV_1_SIGDET_ILEAK, 0x0));
++
++ regmap_update_bits(priv->xfi_ana, AIROHA_PCS_ANA_PXP_RX_OSCAL_WATCH_WNDW,
++ AIROHA_PCS_ANA_RX_OSCAL_FORCE,
++ AIROHA_PCS_ANA_RX_OSCAL_FORCE_VGA2VOS |
++ AIROHA_PCS_ANA_RX_OSCAL_FORCE_VGA2IOS |
++ AIROHA_PCS_ANA_RX_OSCAL_FORCE_VGA1VOS |
++ AIROHA_PCS_ANA_RX_OSCAL_FORCE_VGA1IOS |
++ AIROHA_PCS_ANA_RX_OSCAL_FORCE_CTLE2VOS |
++ AIROHA_PCS_ANA_RX_OSCAL_FORCE_CTLE2IOS |
++ AIROHA_PCS_ANA_RX_OSCAL_FORCE_CTLE1VOS |
++ AIROHA_PCS_ANA_RX_OSCAL_FORCE_CTLE1IOS |
++ AIROHA_PCS_ANA_RX_OSCAL_FORCE_LVSH |
++ AIROHA_PCS_ANA_RX_OSCAL_FORCE_COMPOS);
++
++ regmap_clear_bits(priv->xfi_ana, AIROHA_PCS_ANA_PXP_CDR_PD_PICAL_CKD8_INV,
++ AIROHA_PCS_ANA_CDR_PD_EDGE_DIS |
++ AIROHA_PCS_ANA_CDR_PD_PICAL_CKD8_INV);
++
++ regmap_set_bits(priv->xfi_pma, AIROHA_PCS_PMA_PXP_AEQ_RSTB,
++ AIROHA_PCS_PMA_FORCE_SEL_DA_CDR_INJCK_SEL |
++ AIROHA_PCS_PMA_FORCE_DA_CDR_INJCK_SEL);
++
++ regmap_set_bits(priv->xfi_pma, AIROHA_PCS_PMA_PXP_FE_GAIN_CTRL,
++ AIROHA_PCS_PMA_FORCE_SEL_DA_RX_FE_GAIN_CTRL);
++
++ regmap_set_bits(priv->xfi_pma, AIROHA_PCS_PMA_DIG_RESERVE_12,
++ AIROHA_PCS_PMA_RESERVE_12_FEOS_0);
++
++ if (interface == PHY_INTERFACE_MODE_USXGMII ||
++ interface == PHY_INTERFACE_MODE_10GBASER) {
++ rx_rev0 = FIELD_PREP(AIROHA_PCS_ANA_REV_0_FE_BUF2_BIAS_TYPE, 0x1) |
++ FIELD_PREP(AIROHA_PCS_ANA_REV_0_FE_BUF_GAIN_MODE_NORMAL, 0x3);
++ fe_gain_ctrl = 0x1;
++ rx_force_mode_0 = 0x1;
++ } else {
++ rx_rev0 = FIELD_PREP(AIROHA_PCS_ANA_REV_0_FE_BUF2_BIAS_TYPE, 0x1) |
++ AIROHA_PCS_ANA_REV_0_OSCAL_FE_MODE_SET_SEL |
++ BIT(7) | /* FIXME: Missing documentation for this BIT */
++ FIELD_PREP(AIROHA_PCS_ANA_REV_0_FE_BUF_GAIN_MODE_NORMAL, 0x3);
++ fe_gain_ctrl = 0x3;
++ rx_force_mode_0 = 0x3;
++ }
++
++ regmap_update_bits(priv->xfi_ana, AIROHA_PCS_ANA_PXP_RX_REV_0,
++ AIROHA_PCS_ANA_RX_REV_0, rx_rev0);
++
++ regmap_update_bits(priv->xfi_pma, AIROHA_PCS_PMA_PXP_FE_GAIN_CTRL,
++ AIROHA_PCS_PMA_FORCE_DA_RX_FE_GAIN_CTRL,
++ FIELD_PREP(AIROHA_PCS_PMA_FORCE_DA_RX_FE_GAIN_CTRL,
++ fe_gain_ctrl));
++
++ regmap_write(priv->xfi_pma, AIROHA_PCS_PMA_DIG_RESERVE_0,
++ dig_reserve_0);
++
++ regmap_update_bits(priv->xfi_pma, AIROHA_PCS_PMA_RX_FORCE_MODE_0,
++ AIROHA_PCS_PMA_FORCE_DA_XPON_RX_FE_GAIN_CTRL,
++ FIELD_PREP(AIROHA_PCS_PMA_FORCE_DA_XPON_RX_FE_GAIN_CTRL,
++ rx_force_mode_0));
++
++ regmap_clear_bits(priv->xfi_pma, AIROHA_PCS_PMA_RX_DISB_MODE_0,
++ AIROHA_PCS_PMA_DISB_DA_XPON_RX_FE_GAIN_CTRL);
++
++ regmap_update_bits(priv->xfi_ana, AIROHA_PCS_ANA_PXP_CDR_PR_BETA_DAC,
++ AIROHA_PCS_ANA_CDR_PR_BETA_DAC,
++ FIELD_PREP(AIROHA_PCS_ANA_CDR_PR_BETA_DAC,
++ cdr_pr_beta_dac));
++
++ if (data->port_type == AIROHA_PCS_ETH &&
++ interface == PHY_INTERFACE_MODE_2500BASEX)
++ regmap_update_bits(priv->xfi_ana,
++ AIROHA_PCS_ANA_PXP_CDR_PR_VREG_IBAND_VAL,
++ AIROHA_PCS_ANA_CDR_PR_DAC_BAND,
++ FIELD_PREP(AIROHA_PCS_ANA_CDR_PR_DAC_BAND,
++ 0x6));
++
++ regmap_update_bits(priv->xfi_ana, AIROHA_PCS_ANA_PXP_RX_PHYCK_DIV,
++ AIROHA_PCS_ANA_RX_PHYCK_SEL,
++ FIELD_PREP(AIROHA_PCS_ANA_RX_PHYCK_SEL, phyck_sel));
++
++ regmap_set_bits(priv->xfi_ana, AIROHA_PCS_ANA_PXP_CDR_PR_MONPR_EN,
++ AIROHA_PCS_ANA_CDR_PR_XFICK_EN);
++
++ regmap_update_bits(priv->xfi_ana, AIROHA_PCS_ANA_PXP_RX_BUSBIT_SEL,
++ AIROHA_PCS_ANA_RX_PHY_CK_SEL_FORCE |
++ AIROHA_PCS_ANA_RX_PHY_CK_SEL,
++ AIROHA_PCS_ANA_RX_PHY_CK_SEL_FORCE);
++
++ regmap_update_bits(priv->xfi_ana, AIROHA_PCS_ANA_PXP_RX_PHYCK_DIV,
++ AIROHA_PCS_ANA_RX_PHYCK_RSTB |
++ AIROHA_PCS_ANA_RX_PHYCK_DIV,
++ AIROHA_PCS_ANA_RX_PHYCK_RSTB |
++ FIELD_PREP(AIROHA_PCS_ANA_RX_PHYCK_DIV, phyck_div));
++
++ regmap_update_bits(priv->xfi_ana, AIROHA_PCS_ANA_PXP_CDR_LPF_RATIO,
++ AIROHA_PCS_ANA_CDR_LPF_RATIO,
++ FIELD_PREP(AIROHA_PCS_ANA_CDR_LPF_RATIO,
++ lpf_ratio));
++
++ if (interface == PHY_INTERFACE_MODE_5GBASER)
++ busbit_sel = AIROHA_PCS_ANA_RX_BUSBIT_SEL_FORCE |
++ AIROHA_PCS_ANA_RX_BUSBIT_SEL_16BIT;
++ else
++ busbit_sel = 0;
++
++ regmap_update_bits(priv->xfi_ana, AIROHA_PCS_ANA_PXP_RX_BUSBIT_SEL,
++ AIROHA_PCS_ANA_RX_BUSBIT_SEL_FORCE |
++ AIROHA_PCS_ANA_RX_BUSBIT_SEL,
++ busbit_sel);
++
++ regmap_update_bits(priv->xfi_pma, AIROHA_PCS_PMA_PXP_AEQ_SPEED,
++ AIROHA_PCS_PMA_FORCE_SEL_DA_OSR_SEL |
++ AIROHA_PCS_PMA_FORCE_DA_OSR_SEL,
++ AIROHA_PCS_PMA_FORCE_SEL_DA_OSR_SEL |
++ FIELD_PREP(AIROHA_PCS_PMA_FORCE_DA_OSR_SEL, osr));
++
++ regmap_update_bits(priv->xfi_pma, AIROHA_PCS_PMA_XPON_RX_RESERVED_1,
++ AIROHA_PCS_PMA_XPON_RX_RATE_CTRL,
++ FIELD_PREP(AIROHA_PCS_PMA_XPON_RX_RATE_CTRL, rx_rate_ctrl));
++}
++
++static void an7583_pcs_common_phya_ana(struct airoha_pcs_priv *priv,
++ phy_interface_t interface)
++{
++ const struct airoha_pcs_match_data *data = priv->data;
++ u32 txpll_chp_br, txpll_chp_ibias;
++ u32 lpf_bwr;
++ u32 vco_cfix;
++ u32 tcl_amp_vref;
++ bool sdm_ifm;
++ bool sdm_di;
++ bool sdm_hren;
++ bool vcodiv;
++ bool chp_double_en;
++
++ switch (interface) {
++ case PHY_INTERFACE_MODE_SGMII:
++ case PHY_INTERFACE_MODE_1000BASEX:
++ if (data->port_type == AIROHA_PCS_PON) {
++ txpll_chp_br = 0xa;
++ txpll_chp_ibias = 0x18;
++ lpf_bwr = 0x16;
++ } else {
++ txpll_chp_br = 0x5;
++ txpll_chp_ibias = 0x31;
++ lpf_bwr = 0xb;
++ }
++ vco_cfix = 0x3;
++ tcl_amp_vref = 0xb;
++ vcodiv = false;
++ sdm_hren = data->port_type == AIROHA_PCS_PON;
++ sdm_ifm = data->port_type == AIROHA_PCS_PON;
++ sdm_di = data->port_type == AIROHA_PCS_PON;
++ chp_double_en = false;
++ break;
++ case PHY_INTERFACE_MODE_2500BASEX:
++ txpll_chp_br = 0x5;
++ txpll_chp_ibias = 0x1e;
++ lpf_bwr = 0xb;
++ vco_cfix = 0x0;
++ tcl_amp_vref = 0xe;
++ vcodiv = true;
++ sdm_hren = false;
++ sdm_ifm = false;
++ sdm_di = false;
++ chp_double_en = data->port_type == AIROHA_PCS_PON;
++ break;
++ case PHY_INTERFACE_MODE_5GBASER:
++ case PHY_INTERFACE_MODE_10GBASER:
++ case PHY_INTERFACE_MODE_USXGMII:
++ txpll_chp_br = 0xa;
++ txpll_chp_ibias = 0x18;
++ lpf_bwr = 0x16;
++ sdm_hren = true;
++ vco_cfix = 0x2;
++ tcl_amp_vref = 0xb;
++ vcodiv = false;
++ sdm_ifm = true;
++ sdm_di = true;
++ chp_double_en = false;
++ break;
++ default:
++ return;
++ }
++
++ if (data->port_type == AIROHA_PCS_PON)
++ /* XPON TDC */
++ regmap_set_bits(priv->xfi_ana, AIROHA_PCS_ANA_PXP_PLL_MONCLK_SEL,
++ AIROHA_PCS_ANA_TDC_AUTOEN);
++
++ /* TXPLL VCO LDO Out */
++ regmap_update_bits(priv->xfi_ana, AIROHA_PCS_ANA_PXP_TXPLL_SSC_PERIOD,
++ AIROHA_PCS_ANA_TXPLL_LDO_VCO_OUT |
++ AIROHA_PCS_ANA_TXPLL_LDO_OUT,
++ FIELD_PREP(AIROHA_PCS_ANA_TXPLL_LDO_VCO_OUT, 0x1) |
++ FIELD_PREP(AIROHA_PCS_ANA_TXPLL_LDO_OUT, 0x1));
++
++ regmap_update_bits(priv->xfi_ana, AIROHA_PCS_ANA_PXP_TXPLL_VTP_EN,
++ AIROHA_PCS_ANA_TXPLL_VTP |
++ AIROHA_PCS_ANA_TXPLL_VTP_EN,
++ FIELD_PREP(AIROHA_PCS_ANA_TXPLL_VTP, 0x0) |
++ AIROHA_PCS_ANA_TXPLL_VTP_EN);
++
++ regmap_update_bits(priv->xfi_ana, AIROHA_PCS_ANA_PXP_TDC_SYNC_CK_SEL,
++ AIROHA_PCS_ANA_PLL_LDO_CKDRV_VSEL |
++ AIROHA_PCS_ANA_PLL_LDO_CKDRV_EN,
++ FIELD_PREP(AIROHA_PCS_ANA_PLL_LDO_CKDRV_VSEL, 0x1) |
++ AIROHA_PCS_ANA_PLL_LDO_CKDRV_EN);
++
++ /* Setup RSTB */
++ /* FIXME: different order */
++ regmap_update_bits(priv->xfi_ana, AIROHA_PCS_ANA_PXP_TXPLL_REFIN_INTERNAL,
++ AIROHA_PCS_ANA_TXPLL_PLL_RSTB |
++ AIROHA_PCS_ANA_TXPLL_RST_DLY |
++ AIROHA_PCS_ANA_TXPLL_REFIN_DIV |
++ AIROHA_PCS_ANA_TXPLL_REFIN_INTERNAL,
++ AIROHA_PCS_ANA_TXPLL_PLL_RSTB |
++ FIELD_PREP(AIROHA_PCS_ANA_TXPLL_RST_DLY, 0x4) |
++ AIROHA_PCS_ANA_TXPLL_REFIN_DIV_1);
++
++ /* Setup SDM */
++ regmap_update_bits(priv->xfi_ana, AIROHA_PCS_ANA_PXP_TXPLL_SDM_DI_EN,
++ AIROHA_PCS_ANA_TXPLL_SDM_MODE |
++ AIROHA_PCS_ANA_TXPLL_SDM_IFM |
++ AIROHA_PCS_ANA_TXPLL_SDM_DI_LS |
++ AIROHA_PCS_ANA_TXPLL_SDM_DI_EN,
++ FIELD_PREP(AIROHA_PCS_ANA_TXPLL_SDM_MODE, 0) |
++ (sdm_ifm ? AIROHA_PCS_ANA_TXPLL_SDM_IFM : 0) |
++ AIROHA_PCS_ANA_TXPLL_SDM_DI_LS_2_23 |
++ (sdm_di ? AIROHA_PCS_ANA_TXPLL_SDM_DI_EN : 0));
++
++ regmap_update_bits(priv->xfi_ana, AIROHA_PCS_ANA_PXP_TXPLL_SDM_ORD,
++ AIROHA_PCS_ANA_TXPLL_SDM_HREN |
++ AIROHA_PCS_ANA_TXPLL_SDM_OUT |
++ AIROHA_PCS_ANA_TXPLL_SDM_ORD,
++ (sdm_hren ? AIROHA_PCS_ANA_TXPLL_SDM_HREN : 0) |
++ AIROHA_PCS_ANA_TXPLL_SDM_ORD_3SDM);
++
++ /* Setup SSC */
++ regmap_update_bits(priv->xfi_ana, AIROHA_PCS_ANA_PXP_TXPLL_SSC_DELTA1,
++ AIROHA_PCS_ANA_TXPLL_SSC_DELTA |
++ AIROHA_PCS_ANA_TXPLL_SSC_DELTA1,
++ FIELD_PREP(AIROHA_PCS_ANA_TXPLL_SSC_DELTA, 0x0) |
++ FIELD_PREP(AIROHA_PCS_ANA_TXPLL_SSC_DELTA1, 0x0));
++
++ regmap_clear_bits(priv->xfi_ana, AIROHA_PCS_ANA_PXP_TXPLL_SSC_EN,
++ AIROHA_PCS_ANA_TXPLL_SSC_TRI_EN |
++ AIROHA_PCS_ANA_TXPLL_SSC_PHASE_INI |
++ AIROHA_PCS_ANA_TXPLL_SSC_EN);
++
++ regmap_update_bits(priv->xfi_ana, AIROHA_PCS_ANA_PXP_TXPLL_SSC_PERIOD,
++ AIROHA_PCS_ANA_TXPLL_SSC_PERIOD,
++ FIELD_PREP(AIROHA_PCS_ANA_TXPLL_SSC_PERIOD, 0x0));
++
++ regmap_update_bits(priv->xfi_ana, AN7583_PCS_ANA_PXP_TXPLL_CHP_DOUBLE_EN,
++ AIROHA_PCS_ANA_TXPLL_SPARE_L,
++ chp_double_en ? AIROHA_PCS_ANA_TXPLL_SPARE_L : 0);
++
++ /* Setup LPF */
++ regmap_update_bits(priv->xfi_ana, AIROHA_PCS_ANA_PXP_TXPLL_CHP_IBIAS,
++ AIROHA_PCS_ANA_TXPLL_LPF_BC |
++ AIROHA_PCS_ANA_TXPLL_LPF_BR |
++ AIROHA_PCS_ANA_TXPLL_CHP_IOFST |
++ AIROHA_PCS_ANA_TXPLL_CHP_IBIAS,
++ FIELD_PREP(AIROHA_PCS_ANA_TXPLL_LPF_BC, 0x1f) |
++ FIELD_PREP(AIROHA_PCS_ANA_TXPLL_LPF_BR, txpll_chp_br) |
++ FIELD_PREP(AIROHA_PCS_ANA_TXPLL_CHP_IOFST, 0x0) |
++ FIELD_PREP(AIROHA_PCS_ANA_TXPLL_CHP_IBIAS, txpll_chp_ibias));
++
++ regmap_update_bits(priv->xfi_ana, AIROHA_PCS_ANA_PXP_TXPLL_LPF_BP,
++ AIROHA_PCS_ANA_TXPLL_LPF_BWC |
++ AIROHA_PCS_ANA_TXPLL_LPF_BWR |
++ AIROHA_PCS_ANA_TXPLL_LPF_BP,
++ FIELD_PREP(AIROHA_PCS_ANA_TXPLL_LPF_BWC, 0x18) |
++ FIELD_PREP(AIROHA_PCS_ANA_TXPLL_LPF_BWR, lpf_bwr) |
++ FIELD_PREP(AIROHA_PCS_ANA_TXPLL_LPF_BP, 0x2));
++
++ /* Setup VCO */
++ regmap_update_bits(priv->xfi_ana, AIROHA_PCS_ANA_PXP_TXPLL_TCL_LPF_EN,
++ AIROHA_PCS_ANA_TXPLL_VCO_CFIX,
++ FIELD_PREP(AIROHA_PCS_ANA_TXPLL_VCO_CFIX, vco_cfix));
++
++ regmap_update_bits(priv->xfi_ana, AIROHA_PCS_ANA_PXP_TXPLL_VCO_HALFLSB_EN,
++ AIROHA_PCS_ANA_TXPLL_VCO_VCOVAR_BIAS_L |
++ AIROHA_PCS_ANA_TXPLL_VCO_VCOVAR_BIAS_H |
++ AIROHA_PCS_ANA_TXPLL_VCO_TCLVAR |
++ AIROHA_PCS_ANA_TXPLL_VCO_SCAPWR |
++ AIROHA_PCS_ANA_TXPLL_VCO_HALFLSB_EN,
++ FIELD_PREP(AIROHA_PCS_ANA_TXPLL_VCO_VCOVAR_BIAS_L, 0x0) |
++ FIELD_PREP(AIROHA_PCS_ANA_TXPLL_VCO_VCOVAR_BIAS_H, 0x4) |
++ FIELD_PREP(AIROHA_PCS_ANA_TXPLL_VCO_TCLVAR, 0x4) |
++ FIELD_PREP(AIROHA_PCS_ANA_TXPLL_VCO_SCAPWR, 0x7) |
++ AIROHA_PCS_ANA_TXPLL_VCO_HALFLSB_EN);
++
++ /* Setup KBand */
++ regmap_update_bits(priv->xfi_ana, AIROHA_PCS_ANA_PXP_TXPLL_KBAND_CODE,
++ AIROHA_PCS_ANA_TXPLL_KBAND_KF |
++ AIROHA_PCS_ANA_TXPLL_KBAND_KFC |
++ AIROHA_PCS_ANA_TXPLL_KBAND_DIV |
++ AIROHA_PCS_ANA_TXPLL_KBAND_CODE,
++ FIELD_PREP(AIROHA_PCS_ANA_TXPLL_KBAND_KF, 0x3) |
++ FIELD_PREP(AIROHA_PCS_ANA_TXPLL_KBAND_KFC, 0x0) |
++ FIELD_PREP(AIROHA_PCS_ANA_TXPLL_KBAND_DIV, 0x2) |
++ FIELD_PREP(AIROHA_PCS_ANA_TXPLL_KBAND_CODE, 0xe4));
++
++ regmap_update_bits(priv->xfi_ana, AIROHA_PCS_ANA_PXP_TXPLL_KBAND_KS,
++ AIROHA_PCS_ANA_TXPLL_KBAND_KS,
++ FIELD_PREP(AIROHA_PCS_ANA_TXPLL_KBAND_KS, 0x1));
++
++ regmap_clear_bits(priv->xfi_ana, AIROHA_PCS_ANA_PXP_TXPLL_LPF_BP,
++ AIROHA_PCS_ANA_TXPLL_KBAND_OPTION);
++
++ regmap_clear_bits(priv->xfi_ana, AIROHA_PCS_ANA_PXP_TXPLL_TCL_KBAND_VREF,
++ AIROHA_PCS_ANA_TXPLL_VCO_KBAND_MEAS_EN);
++
++ regmap_update_bits(priv->xfi_pma, AIROHA_PCS_PMA_PXP_TXPLL_KBAND_LOAD_EN,
++ AIROHA_PCS_PMA_FORCE_SEL_DA_TXPLL_KBAND_LOAD_EN |
++ AIROHA_PCS_PMA_FORCE_DA_TXPLL_KBAND_LOAD_EN,
++ AIROHA_PCS_PMA_FORCE_SEL_DA_TXPLL_KBAND_LOAD_EN);
++
++ regmap_update_bits(priv->xfi_ana, AIROHA_PCS_ANA_PXP_TXPLL_KBAND_KS,
++ AIROHA_PCS_ANA_TXPLL_MMD_PREDIV_MODE |
++ AIROHA_PCS_ANA_TXPLL_POSTDIV_EN,
++ AIROHA_PCS_ANA_TXPLL_MMD_PREDIV_MODE_2 |
++ AIROHA_PCS_ANA_TXPLL_POSTDIV_EN);
++
++ regmap_update_bits(priv->xfi_ana, AIROHA_PCS_ANA_PXP_TXPLL_TCL_AMP_GAIN,
++ AIROHA_PCS_ANA_TXPLL_TCL_AMP_VREF |
++ AIROHA_PCS_ANA_TXPLL_TCL_AMP_GAIN,
++ FIELD_PREP(AIROHA_PCS_ANA_TXPLL_TCL_AMP_VREF, tcl_amp_vref) |
++ AIROHA_PCS_ANA_TXPLL_TCL_AMP_GAIN_4);
++
++ if (interface == PHY_INTERFACE_MODE_2500BASEX)
++ regmap_set_bits(priv->xfi_ana, AIROHA_PCS_ANA_PXP_TXPLL_TCL_KBAND_VREF,
++ AIROHA_PCS_ANA_TXPLL_POSTDIV_D256_EN);
++
++ regmap_update_bits(priv->xfi_ana, AIROHA_PCS_ANA_PXP_TXPLL_TCL_LPF_EN,
++ AIROHA_PCS_ANA_TXPLL_VCODIV,
++ vcodiv ? AIROHA_PCS_ANA_TXPLL_VCODIV_2 :
++ AIROHA_PCS_ANA_TXPLL_VCODIV_1);
++
++ regmap_update_bits(priv->xfi_ana, AIROHA_PCS_ANA_PXP_TXPLL_TCL_KBAND_VREF,
++ AIROHA_PCS_ANA_TXPLL_TCL_KBAND_VREF,
++ FIELD_PREP(AIROHA_PCS_ANA_TXPLL_TCL_KBAND_VREF, 0xf));
++
++ regmap_update_bits(priv->xfi_ana, AIROHA_PCS_ANA_PXP_TXPLL_TCL_LPF_EN,
++ AIROHA_PCS_ANA_TXPLL_TCL_LPF_BW |
++ AIROHA_PCS_ANA_TXPLL_TCL_LPF_EN,
++ AIROHA_PCS_ANA_TXPLL_TCL_LPF_BW_0_5 |
++ AIROHA_PCS_ANA_TXPLL_TCL_LPF_EN);
++
++ regmap_set_bits(priv->xfi_ana, AIROHA_PCS_ANA_PXP_TXPLL_SDM_ORD,
++ AIROHA_PCS_ANA_TXPLL_TCL_AMP_EN);
++
++ /* Setup TX TermCal */
++ regmap_update_bits(priv->xfi_ana, AIROHA_PCS_ANA_PXP_TX_TXLBRC_EN,
++ AIROHA_PCS_ANA_TX_TERMCAL_VREF_L |
++ AIROHA_PCS_ANA_TX_TERMCAL_VREF_H,
++ FIELD_PREP(AIROHA_PCS_ANA_TX_TERMCAL_VREF_L, 0x2) |
++ FIELD_PREP(AIROHA_PCS_ANA_TX_TERMCAL_VREF_H, 0x2));
++
++ /* Setup XPON RX */
++ regmap_update_bits(priv->xfi_ana, AIROHA_PCS_ANA_PXP_RX_FE_EQ_HZEN,
++ AIROHA_PCS_ANA_RX_FE_VB_EQ3_EN |
++ AIROHA_PCS_ANA_RX_FE_VB_EQ2_EN |
++ AIROHA_PCS_ANA_RX_FE_VB_EQ1_EN |
++ AIROHA_PCS_ANA_RX_FE_EQ_HZEN,
++ AIROHA_PCS_ANA_RX_FE_VB_EQ3_EN |
++ AIROHA_PCS_ANA_RX_FE_VB_EQ2_EN |
++ AIROHA_PCS_ANA_RX_FE_VB_EQ1_EN);
++
++ regmap_set_bits(priv->xfi_ana, AIROHA_PCS_ANA_PXP_RX_FE_VCM_GEN_PWDB,
++ AIROHA_PCS_ANA_FE_VCM_GEN_PWDB);
++
++ regmap_update_bits(priv->xfi_ana, AIROHA_PCS_ANA_PXP_CDR_LPF_RATIO,
++ AIROHA_PCS_ANA_CDR_LPF_TOP_LIM,
++ FIELD_PREP(AIROHA_PCS_ANA_CDR_LPF_TOP_LIM, 0x8000));
++
++ regmap_update_bits(priv->xfi_ana, AIROHA_PCS_ANA_PXP_CDR_LPF_BOT_LIM,
++ AIROHA_PCS_ANA_CDR_LPF_BOT_LIM,
++ FIELD_PREP(AIROHA_PCS_ANA_CDR_LPF_BOT_LIM, 0x78000));
++
++ regmap_clear_bits(priv->xfi_ana, AIROHA_PCS_ANA_PXP_CDR_PR_CKREF_DIV,
++ AIROHA_PCS_ANA_CDR_PR_RSTB_BYPASS);
++
++ regmap_update_bits(priv->xfi_ana, AIROHA_PCS_ANA_PXP_RX_DAC_RANGE,
++ AIROHA_PCS_ANA_RX_DAC_RANGE_EYE,
++ FIELD_PREP(AIROHA_PCS_ANA_RX_DAC_RANGE_EYE, 0x2));
++}
++
++static void an7583_pcs_cfg_phy_type(struct airoha_pcs_priv *priv,
++ phy_interface_t interface)
++{
++ const struct airoha_pcs_match_data *data = priv->data;
++
++ /* Enable PLL force selection and Force Disable */
++ regmap_update_bits(priv->xfi_pma, AIROHA_PCS_PMA_PXP_TXPLL_CKOUT_EN,
++ AIROHA_PCS_PMA_FORCE_SEL_DA_TXPLL_EN |
++ AIROHA_PCS_PMA_FORCE_DA_TXPLL_EN,
++ AIROHA_PCS_PMA_FORCE_SEL_DA_TXPLL_EN);
++
++ if (data->port_type == AIROHA_PCS_PON) {
++ /* TDC */
++ regmap_update_bits(priv->xfi_pma, AIROHA_PCS_PMA_LCPLL_TDC_FLT_3,
++ AIROHA_PCS_PMA_LCPLL_NCPO_SHIFT,
++ FIELD_PREP(AIROHA_PCS_PMA_LCPLL_NCPO_SHIFT, 0x1));
++ regmap_update_bits(priv->xfi_pma, AIROHA_PCS_PMA_LCPLL_TDC_FLT_1,
++ AIROHA_PCS_PMA_LCPLL_A_TDC,
++ FIELD_PREP(AIROHA_PCS_PMA_LCPLL_A_TDC, 0x5));
++ regmap_update_bits(priv->xfi_ana, AIROHA_PCS_ANA_PXP_TX_TERMCAL_SELPN,
++ AIROHA_PCS_ANA_TX_TDC_CK_SEL,
++ FIELD_PREP(AIROHA_PCS_ANA_TX_TDC_CK_SEL, 0x0));
++ regmap_set_bits(priv->xfi_ana, AIROHA_PCS_ANA_PXP_RX_PHYCK_DIV,
++ AIROHA_PCS_ANA_RX_TDC_CK_SEL);
++ }
++
++ /* PLL EN HW Mode */
++ regmap_update_bits(priv->xfi_pma, AIROHA_PCS_PMA_SS_LCPLL_PWCTL_SETTING_1,
++ AIROHA_PCS_PMA_LCPLL_CK_STB_TIMER |
++ AIROHA_PCS_PMA_LCPLL_PCW_MAN_LOAD_TIMER |
++ AIROHA_PCS_PMA_LCPLL_EN_TIMER |
++ AIROHA_PCS_PMA_LCPLL_MAN_PWDB,
++ FIELD_PREP(AIROHA_PCS_PMA_LCPLL_CK_STB_TIMER, 0x1) |
++ FIELD_PREP(AIROHA_PCS_PMA_LCPLL_PCW_MAN_LOAD_TIMER, 0x10) |
++ FIELD_PREP(AIROHA_PCS_PMA_LCPLL_EN_TIMER, 0xa) |
++ AIROHA_PCS_PMA_LCPLL_MAN_PWDB);
++
++ regmap_update_bits(priv->xfi_pma, AIROHA_PCS_PMA_PON_TX_COUNTER_1,
++ AIROHA_PCS_PMA_TX_HSDATA_EN_WAIT |
++ AIROHA_PCS_PMA_TX_CK_EN_WAIT,
++ FIELD_PREP(AIROHA_PCS_PMA_TX_HSDATA_EN_WAIT, 0x113) |
++ FIELD_PREP(AIROHA_PCS_PMA_TX_CK_EN_WAIT, 0xfa));
++
++ regmap_update_bits(priv->xfi_pma, AIROHA_PCS_PMA_PON_TX_COUNTER_2,
++ AIROHA_PCS_PMA_TX_SERDES_RDY_WAIT |
++ AIROHA_PCS_PMA_TX_POWER_ON_WAIT,
++ FIELD_PREP(AIROHA_PCS_PMA_TX_SERDES_RDY_WAIT, 0x9b) |
++ FIELD_PREP(AIROHA_PCS_PMA_TX_POWER_ON_WAIT, 0x210));
++
++ regmap_update_bits(priv->xfi_pma, AIROHA_PCS_PMA_PON_TX_COUNTER_0,
++ AIROHA_PCS_PMA_TXCALIB_5US |
++ AIROHA_PCS_PMA_TXCALIB_50US,
++ FIELD_PREP(AIROHA_PCS_PMA_TXCALIB_5US, 0x4) |
++ FIELD_PREP(AIROHA_PCS_PMA_TXCALIB_50US, 0x26));
++
++ regmap_update_bits(priv->xfi_pma, AIROHA_PCS_PMA_LCPLL_TDC_FLT_0,
++ AIROHA_PCS_PMA_LCPLL_KI,
++ FIELD_PREP(AIROHA_PCS_PMA_LCPLL_KI, 0x3));
++
++ regmap_clear_bits(priv->xfi_pma, AIROHA_PCS_PMA_LCPLL_TDC_PW_5,
++ AIROHA_PCS_PMA_LCPLL_TDC_SYNC_IN_MODE);
++
++ an7583_pcs_common_phya_txpll(priv, interface);
++ an7583_pcs_common_phya_tx(priv, interface);
++
++ /* RX HW mode counter */
++ regmap_update_bits(priv->xfi_pma, AIROHA_PCS_PMA_RX_CTRL_SEQUENCE_CTRL_0,
++ AIROHA_PCS_PMA_RX_OS_START,
++ FIELD_PREP(AIROHA_PCS_PMA_RX_OS_START, 0x1));
++
++ regmap_update_bits(priv->xfi_pma, AIROHA_PCS_PMA_RX_CTRL_SEQUENCE_CTRL_6,
++ AIROHA_PCS_PMA_RX_OS_END,
++ FIELD_PREP(AIROHA_PCS_PMA_RX_OS_END, 0x2));
++
++ regmap_update_bits(priv->xfi_pma, AIROHA_PCS_PMA_RX_CTRL_SEQUENCE_CTRL_0,
++ AIROHA_PCS_PMA_OSC_SPEED_OPT,
++ AIROHA_PCS_PMA_OSC_SPEED_OPT_0_1);
++
++ regmap_update_bits(priv->xfi_pma, AIROHA_PCS_PMA_RX_CTRL_SEQUENCE_CTRL_1,
++ AIROHA_PCS_PMA_RX_PICAL_END |
++ AIROHA_PCS_PMA_RX_PICAL_START,
++ FIELD_PREP(AIROHA_PCS_PMA_RX_PICAL_END, 0x3e8) |
++ FIELD_PREP(AIROHA_PCS_PMA_RX_PICAL_START, 0x2));
++
++ regmap_update_bits(priv->xfi_pma, AIROHA_PCS_PMA_RX_CTRL_SEQUENCE_CTRL_4,
++ AIROHA_PCS_PMA_RX_SDCAL_END |
++ AIROHA_PCS_PMA_RX_SDCAL_START,
++ FIELD_PREP(AIROHA_PCS_PMA_RX_SDCAL_END, 0x3e8) |
++ FIELD_PREP(AIROHA_PCS_PMA_RX_SDCAL_START, 0x2));
++
++ regmap_update_bits(priv->xfi_pma, AIROHA_PCS_PMA_RX_CTRL_SEQUENCE_CTRL_2,
++ AIROHA_PCS_PMA_RX_PDOS_END |
++ AIROHA_PCS_PMA_RX_PDOS_START,
++ FIELD_PREP(AIROHA_PCS_PMA_RX_PDOS_END, 0x3e8) |
++ FIELD_PREP(AIROHA_PCS_PMA_RX_PDOS_START, 0x2));
++
++ regmap_update_bits(priv->xfi_pma, AIROHA_PCS_PMA_RX_CTRL_SEQUENCE_CTRL_3,
++ AIROHA_PCS_PMA_RX_FEOS_END |
++ AIROHA_PCS_PMA_RX_FEOS_START,
++ FIELD_PREP(AIROHA_PCS_PMA_RX_FEOS_END, 0x3e8) |
++ FIELD_PREP(AIROHA_PCS_PMA_RX_FEOS_START, 0x2));
++
++ /* RX Settings */
++ regmap_update_bits(priv->xfi_pma, AIROHA_PCS_PMA_PHY_EQ_CTRL_2,
++ AIROHA_PCS_PMA_FOM_NUM_ORDER |
++ AIROHA_PCS_PMA_A_SEL,
++ FIELD_PREP(AIROHA_PCS_PMA_FOM_NUM_ORDER, 0x1) |
++ FIELD_PREP(AIROHA_PCS_PMA_A_SEL, 0x3));
++
++ regmap_update_bits(priv->xfi_pma, AIROHA_PCS_PMA_RX_EYE_TOP_EYEINDEX_CTRL_0,
++ AIROHA_PCS_PMA_X_MAX | AIROHA_PCS_PMA_X_MIN,
++ FIELD_PREP(AIROHA_PCS_PMA_X_MAX, 0x240) |
++ FIELD_PREP(AIROHA_PCS_PMA_X_MIN, 0x1c0));
++
++ regmap_clear_bits(priv->xfi_pma, AIROHA_PCS_PMA_RX_EYE_TOP_EYECNT_CTRL_2,
++ AIROHA_PCS_PMA_DATA_SHIFT);
++
++ an7583_pcs_common_phya_rx(priv, interface);
++ an7583_pcs_common_phya_ana(priv, interface);
++
++ /* Setup EYE */
++ regmap_set_bits(priv->xfi_pma, AIROHA_PCS_PMA_RX_EYE_TOP_EYECNT_CTRL_2,
++ AIROHA_PCS_PMA_EYECNT_FAST);
++ regmap_set_bits(priv->xfi_pma, AIROHA_PCS_PMA_RX_EYE_TOP_EYEINDEX_CTRL_3,
++ AIROHA_PCS_PMA_EYE_NEXTPTS);
++
++ regmap_update_bits(priv->xfi_pma, AIROHA_PCS_PMA_RX_EYE_TOP_EYEOPENING_CTRL_0,
++ AIROHA_PCS_PMA_EYECNT_VTH |
++ AIROHA_PCS_PMA_EYECNT_HTH,
++ FIELD_PREP(AIROHA_PCS_PMA_EYECNT_VTH, 0x4) |
++ FIELD_PREP(AIROHA_PCS_PMA_EYECNT_HTH, 0x4));
++
++ regmap_update_bits(priv->xfi_pma, AIROHA_PCS_PMA_RX_EYE_TOP_EYEOPENING_CTRL_1,
++ AIROHA_PCS_PMA_EO_VTH |
++ AIROHA_PCS_PMA_EO_HTH,
++ FIELD_PREP(AIROHA_PCS_PMA_EO_VTH, 0x4) |
++ FIELD_PREP(AIROHA_PCS_PMA_EO_HTH, 0x4));
++
++ regmap_update_bits(priv->xfi_pma, AIROHA_PCS_PMA_RX_EYE_TOP_EYECNT_CTRL_0,
++ AIROHA_PCS_PMA_EYE_MASK |
++ AIROHA_PCS_PMA_CNTLEN,
++ FIELD_PREP(AIROHA_PCS_PMA_EYE_MASK, 0xff) |
++ FIELD_PREP(AIROHA_PCS_PMA_CNTLEN, 0xd0));
++
++ regmap_update_bits(priv->xfi_pma, AIROHA_PCS_PMA_PHY_EQ_CTRL_0,
++ AIROHA_PCS_PMA_VEO_MASK |
++ AIROHA_PCS_PMA_HEO_MASK |
++ AIROHA_PCS_PMA_EQ_EN_DELAY,
++ FIELD_PREP(AIROHA_PCS_PMA_VEO_MASK, 0x0) |
++ FIELD_PREP(AIROHA_PCS_PMA_HEO_MASK, 0x0) |
++ FIELD_PREP(AIROHA_PCS_PMA_EQ_EN_DELAY, 0x1));
++
++ regmap_set_bits(priv->xfi_pma, AIROHA_PCS_PMA_PHY_EQ_CTRL_1,
++ AIROHA_PCS_PMA_A_LGAIN);
++
++ regmap_update_bits(priv->xfi_pma, AIROHA_PCS_PMA_RX_CAL1,
++ AIROHA_PCS_PMA_CAL_CYC |
++ AIROHA_PCS_PMA_CAL_STB |
++ AIROHA_PCS_PMA_CAL_1US_SET |
++ AIROHA_PCS_PMA_SIM_FAST_EN,
++ AIROHA_PCS_PMA_CAL_CYC_15 |
++ AIROHA_PCS_PMA_CAL_STB_8US |
++ FIELD_PREP(AIROHA_PCS_PMA_CAL_1US_SET, 0x2e) |
++ AIROHA_PCS_PMA_SIM_FAST_EN);
++
++ regmap_update_bits(priv->xfi_pma, AIROHA_PCS_PMA_RX_CAL2,
++ AIROHA_PCS_PMA_CAL_CYC_TIME |
++ AIROHA_PCS_PMA_CAL_OUT_OS |
++ AIROHA_PCS_PMA_CAL_OS_PULSE,
++ FIELD_PREP(AIROHA_PCS_PMA_CAL_CYC_TIME, 0x0) |
++ FIELD_PREP(AIROHA_PCS_PMA_CAL_OUT_OS, 0x0));
++
++ regmap_update_bits(priv->xfi_pma, AIROHA_PCS_PMA_RX_CTRL_SEQUENCE_CTRL_5,
++ AIROHA_PCS_PMA_RX_RDY |
++ AIROHA_PCS_PMA_RX_BLWC_RDY_EN,
++ FIELD_PREP(AIROHA_PCS_PMA_RX_RDY, 0xa) |
++ FIELD_PREP(AIROHA_PCS_PMA_RX_BLWC_RDY_EN, 0x5));
++
++ regmap_update_bits(priv->xfi_pma, AIROHA_PCS_PMA_SS_RX_FEOS,
++ AIROHA_PCS_PMA_EQ_FORCE_BLWC_FREEZE |
++ AIROHA_PCS_PMA_LFSEL,
++ FIELD_PREP(AIROHA_PCS_PMA_EQ_FORCE_BLWC_FREEZE, 0x0));
++
++ regmap_update_bits(priv->xfi_pma, AIROHA_PCS_PMA_RX_EYE_TOP_EYEINDEX_CTRL_1,
++ AIROHA_PCS_PMA_INDEX_MODE |
++ AIROHA_PCS_PMA_Y_MAX |
++ AIROHA_PCS_PMA_Y_MIN,
++ AIROHA_PCS_PMA_INDEX_MODE |
++ FIELD_PREP(AIROHA_PCS_PMA_Y_MAX, 0x3f) |
++ FIELD_PREP(AIROHA_PCS_PMA_Y_MIN, 0x40));
++
++ regmap_update_bits(priv->xfi_pma, AIROHA_PCS_PMA_RX_EYE_TOP_EYEINDEX_CTRL_2,
++ AIROHA_PCS_PMA_EYEDUR,
++ FIELD_PREP(AIROHA_PCS_PMA_EYEDUR, 0x18));
++
++ regmap_update_bits(priv->xfi_pma, AIROHA_PCS_PMA_RX_EXTRAL_CTRL,
++ AIROHA_PCS_PMA_L2D_TRIG_EQ_EN_TIME |
++ AIROHA_PCS_PMA_OS_RDY_LATCH |
++ AIROHA_PCS_PMA_DISB_LEQ,
++ FIELD_PREP(AIROHA_PCS_PMA_L2D_TRIG_EQ_EN_TIME, 0x2) |
++ AIROHA_PCS_PMA_OS_RDY_LATCH);
++
++ regmap_update_bits(priv->xfi_pma, AIROHA_PCS_PMA_RX_FLL_0,
++ AIROHA_PCS_PMA_KBAND_KFC |
++ AIROHA_PCS_PMA_FPKDIV |
++ AIROHA_PCS_PMA_KBAND_PREDIV,
++ AIROHA_PCS_PMA_KBAND_KFC_8 |
++ FIELD_PREP(AIROHA_PCS_PMA_FPKDIV, 0xa5) |
++ AIROHA_PCS_PMA_KBAND_PREDIV_4);
++
++ regmap_update_bits(priv->xfi_pma, AIROHA_PCS_PMA_RX_FLL_1,
++ AIROHA_PCS_PMA_SYMBOL_WD |
++ AIROHA_PCS_PMA_SETTLE_TIME_SEL,
++ FIELD_PREP(AIROHA_PCS_PMA_SYMBOL_WD, 0x4) |
++ FIELD_PREP(AIROHA_PCS_PMA_SETTLE_TIME_SEL, 0x1));
++
++ regmap_update_bits(priv->xfi_pma, AIROHA_PCS_PMA_RX_FLL_5,
++ AIROHA_PCS_PMA_FLL_IDAC_MIN |
++ AIROHA_PCS_PMA_FLL_IDAC_MAX,
++ FIELD_PREP(AIROHA_PCS_PMA_FLL_IDAC_MIN, 0x400) |
++ FIELD_PREP(AIROHA_PCS_PMA_FLL_IDAC_MAX, 0x1ff));
++
++ regmap_update_bits(priv->xfi_pma, AIROHA_PCS_PMA_RX_FLL_2,
++ AIROHA_PCS_PMA_AMP |
++ AIROHA_PCS_PMA_PRBS_SEL,
++ FIELD_PREP(AIROHA_PCS_PMA_AMP, 0x4) |
++ FIELD_PREP(AIROHA_PCS_PMA_PRBS_SEL, 0x3));
++
++ regmap_clear_bits(priv->xfi_pma, AIROHA_PCS_PMA_RX_DISB_MODE_4,
++ AIROHA_PCS_PMA_DISB_BLWC_OFFSET);
++
++ regmap_update_bits(priv->xfi_pma, AIROHA_PCS_PMA_RX_PDOS_CTRL_0,
++ AIROHA_PCS_PMA_EYE_BLWC_ADD |
++ AIROHA_PCS_PMA_DATA_BLWC_ADD,
++ AIROHA_PCS_PMA_DATA_BLWC_ADD);
++
++ regmap_update_bits(priv->xfi_pma, AIROHA_PCS_PMA_SS_RX_BLWC,
++ AIROHA_PCS_PMA_EQ_BLWC_CNT_BOT_LIM |
++ AIROHA_PCS_PMA_EQ_BLWC_CNT_TOP_LIM |
++ AIROHA_PCS_PMA_EQ_BLWC_GAIN |
++ AIROHA_PCS_PMA_EQ_BLWC_POL,
++ FIELD_PREP(AIROHA_PCS_PMA_EQ_BLWC_CNT_BOT_LIM, 0x10) |
++ FIELD_PREP(AIROHA_PCS_PMA_EQ_BLWC_CNT_TOP_LIM, 0x70) |
++ FIELD_PREP(AIROHA_PCS_PMA_EQ_BLWC_GAIN, 0xa) |
++ AIROHA_PCS_PMA_EQ_BLWC_POL_INVERSION);
++}
++
++static void an7583_pcs_common_phya_txpll_on(struct airoha_pcs_priv *priv)
++{
++ regmap_set_bits(priv->xfi_pma, AIROHA_PCS_PMA_PXP_TXPLL_CKOUT_EN,
++ AIROHA_PCS_PMA_FORCE_SEL_DA_TXPLL_CKOUT_EN |
++ AIROHA_PCS_PMA_FORCE_DA_TXPLL_CKOUT_EN);
++
++ regmap_set_bits(priv->xfi_pma, AIROHA_PCS_PMA_SS_LCPLL_PWCTL_SETTING_0,
++ AIROHA_PCS_PMA_SW_LCPLL_EN);
++
++ udelay(6);
++
++ regmap_set_bits(priv->xfi_pma, AIROHA_PCS_PMA_PXP_TXPLL_CKOUT_EN,
++ AIROHA_PCS_PMA_FORCE_SEL_DA_TXPLL_EN |
++ AIROHA_PCS_PMA_FORCE_DA_TXPLL_EN);
++
++ regmap_update_bits(priv->xfi_ana, AIROHA_PCS_ANA_PXP_TXPLL_TCL_KBAND_VREF,
++ AIROHA_PCS_ANA_TXPLL_FREQ_MEAS_EN |
++ AIROHA_PCS_ANA_TXPLL_VREF_SEL,
++ AIROHA_PCS_ANA_TXPLL_FREQ_MEAS_EN |
++ AIROHA_PCS_ANA_TXPLL_VREF_SEL_VBG);
++
++ regmap_set_bits(priv->xfi_ana, AIROHA_PCS_ANA_PXP_TXPLL_PHY_CK1_EN,
++ AIROHA_PCS_ANA_TXPLL_PHY_CK2_EN |
++ AIROHA_PCS_ANA_TXPLL_PHY_CK1_EN);
++
++ regmap_clear_bits(priv->xfi_ana, AIROHA_PCS_ANA_PXP_TXPLL_TCL_KBAND_VREF,
++ AIROHA_PCS_ANA_TXPLL_FREQ_MEAS_EN);
++
++ regmap_clear_bits(priv->xfi_ana, AIROHA_PCS_ANA_PXP_JCPLL_FREQ_MEAS_EN,
++ AIROHA_PCS_ANA_TXPLL_IB_EXT_EN);
++
++ usleep_range(500, 1000);
++}
++
++static void an7583_pcs_common_phya_tx_on(struct airoha_pcs_priv *priv)
++{
++ u32 xfi_tx_term_sel = 0x1;
++ // int efuse_valid;
++
++ regmap_set_bits(priv->xfi_pma, AIROHA_PCS_PMA_TX_RST_B,
++ AIROHA_PCS_PMA_TX_TOP_RST_B);
++
++ regmap_set_bits(priv->xfi_pma, AIROHA_PCS_PMA_ADD_CLKPATH_RST_0,
++ AIROHA_PCS_PMA_CLKPATH_RSTB_CK |
++ AIROHA_PCS_PMA_CLKPATH_RST_EN);
++
++ regmap_set_bits(priv->xfi_pma, AIROHA_PCS_PMA_TX_RST_B,
++ AIROHA_PCS_PMA_TXCALIB_RST_B |
++ AIROHA_PCS_PMA_TX_TOP_RST_B);
++
++ usleep_range(100, 200);
++
++ /* TODO handle efuse */
++ regmap_update_bits(priv->xfi_pma, AIROHA_PCS_PMA_TX_CALIB_0,
++ AIROHA_PCS_PMA_TXCALIB_FORCE_TERMP_SEL |
++ AIROHA_PCS_PMA_TXCALIB_FORCE_TERMP_SEL_EN,
++ FIELD_PREP(AIROHA_PCS_PMA_TXCALIB_FORCE_TERMP_SEL,
++ xfi_tx_term_sel) |
++ AIROHA_PCS_PMA_TXCALIB_FORCE_TERMP_SEL_EN);
++}
++
++static void an7583_pcs_common_phya_rx_preset(struct airoha_pcs_priv *priv,
++ phy_interface_t interface)
++{
++ u32 cdr_pr_buf_in_sr;
++ bool cdr_pr_cap_en;
++
++ switch (interface) {
++ case PHY_INTERFACE_MODE_2500BASEX:
++ cdr_pr_cap_en = true;
++ cdr_pr_buf_in_sr = 0x6;
++ break;
++ case PHY_INTERFACE_MODE_SGMII:
++ case PHY_INTERFACE_MODE_1000BASEX:
++ case PHY_INTERFACE_MODE_5GBASER:
++ case PHY_INTERFACE_MODE_10GBASER:
++ case PHY_INTERFACE_MODE_USXGMII:
++ cdr_pr_cap_en = false;
++ cdr_pr_buf_in_sr = 0x7;
++ break;
++ default:
++ return;
++ }
++
++ /* Setup RX Precondition */
++ regmap_update_bits(priv->xfi_ana, AIROHA_PCS_ANA_PXP_RX_SIGDET_NOVTH,
++ AIROHA_PCS_ANA_RX_SIGDET_VTH_SEL |
++ AIROHA_PCS_ANA_RX_SIGDET_PEAK,
++ FIELD_PREP(AIROHA_PCS_ANA_RX_SIGDET_VTH_SEL, 0x2) |
++ FIELD_PREP(AIROHA_PCS_ANA_RX_SIGDET_PEAK, 0x2));
++
++ regmap_update_bits(priv->xfi_ana, AIROHA_PCS_ANA_PXP_RX_DAC_RANGE,
++ AIROHA_PCS_ANA_RX_SIGDET_LPF_CTRL,
++ FIELD_PREP(AIROHA_PCS_ANA_RX_SIGDET_LPF_CTRL, 0x3));
++
++ regmap_update_bits(priv->xfi_ana, AIROHA_PCS_ANA_PXP_CDR_PR_MONPR_EN,
++ AIROHA_PCS_ANA_CDR_PR_CAP_EN |
++ AIROHA_PCS_ANA_CDR_BUF_IN_SR,
++ (cdr_pr_cap_en ? AIROHA_PCS_ANA_CDR_PR_CAP_EN : 0) |
++ FIELD_PREP(AIROHA_PCS_ANA_CDR_BUF_IN_SR, cdr_pr_buf_in_sr));
++
++ regmap_clear_bits(priv->xfi_pma, AIROHA_PCS_PMA_RX_CTRL_SEQUENCE_FORCE_CTRL_1,
++ AIROHA_PCS_PMA_FORCE_RX_OS_RDY);
++
++ regmap_clear_bits(priv->xfi_pma, AIROHA_PCS_PMA_RX_CTRL_SEQUENCE_DISB_CTRL_1,
++ AIROHA_PCS_PMA_DISB_RX_OS_RDY);
++
++ /* Setup L2R */
++ regmap_update_bits(priv->xfi_pma, AIROHA_PCS_PMA_PXP_CDR_LPF_LCK_2DATA,
++ AIROHA_PCS_PMA_FORCE_SEL_DA_CDR_LPF_LCK2DATA |
++ AIROHA_PCS_PMA_FORCE_DA_CDR_LPF_LCK2DATA,
++ AIROHA_PCS_PMA_FORCE_SEL_DA_CDR_LPF_LCK2DATA);
++
++ /* Setup LEQ setting */
++ regmap_update_bits(priv->xfi_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,
++ AIROHA_PCS_PMA_FORCE_SEL_DA_RX_FE_PEAKING_CTRL |
++ FIELD_PREP(AIROHA_PCS_PMA_FORCE_DA_RX_FE_PEAKING_CTRL, 0x0));
++
++ /* Keep EYE reset */
++ regmap_set_bits(priv->xfi_pma, AIROHA_PCS_PMA_RX_FORCE_MODE_9,
++ AIROHA_PCS_PMA_FORCE_EYE_RESET_PLU_O);
++
++ regmap_clear_bits(priv->xfi_pma, AIROHA_PCS_PMA_RX_DISB_MODE_8,
++ AIROHA_PCS_PMA_DISB_EYE_RESET_PLU_O);
++
++ regmap_clear_bits(priv->xfi_pma, AIROHA_PCS_PMA_RX_FORCE_MODE_9,
++ AIROHA_PCS_PMA_FORCE_EYE_TOP_EN);
++
++ regmap_clear_bits(priv->xfi_pma, AIROHA_PCS_PMA_RX_DISB_MODE_8,
++ AIROHA_PCS_PMA_DISB_EYE_TOP_EN);
++
++ /* Kepp BLWC reset */
++ regmap_clear_bits(priv->xfi_pma, AIROHA_PCS_PMA_RX_DISB_MODE_7,
++ AIROHA_PCS_PMA_DISB_BLWC_RX_RST_B);
++
++ regmap_clear_bits(priv->xfi_pma, AIROHA_PCS_PMA_RX_FORCE_MODE_8,
++ AIROHA_PCS_PMA_FORCE_BLWC_RX_RST_B);
++
++ regmap_set_bits(priv->xfi_pma, AIROHA_PCS_PMA_RX_CTRL_SEQUENCE_DISB_CTRL_1,
++ AIROHA_PCS_PMA_DISB_RX_BLWC_EN);
++
++ regmap_set_bits(priv->xfi_pma, AIROHA_PCS_PMA_RX_CTRL_SEQUENCE_FORCE_CTRL_1,
++ AIROHA_PCS_PMA_FORCE_RX_BLWC_EN);
++}
++
++static void an7583_pcs_common_phya_rx_on(struct airoha_pcs_priv *priv)
++{
++ regmap_set_bits(priv->xfi_pma, AIROHA_PCS_PMA_PXP_CDR_PR_PIEYE_PWDB,
++ AIROHA_PCS_PMA_FORCE_SEL_DA_CDR_PR_PWDB |
++ AIROHA_PCS_PMA_FORCE_DA_CDR_PR_PWDB);
++
++ regmap_set_bits(priv->xfi_pma, AIROHA_PCS_PMA_PXP_CDR_PR_PIEYE_PWDB,
++ AIROHA_PCS_PMA_FORCE_SEL_DA_CDR_PR_PIEYE_PWDB |
++ AIROHA_PCS_PMA_FORCE_DA_CDR_PR_PIEYE_PWDB);
++
++ regmap_clear_bits(priv->xfi_pma, AIROHA_PCS_PMA_PXP_CDR_PD_PWDB,
++ AIROHA_PCS_PMA_FORCE_SEL_DA_CDR_PR_KBAND_RSTB |
++ AIROHA_PCS_PMA_FORCE_DA_CDR_PR_KBAND_RSTB);
++
++ regmap_set_bits(priv->xfi_pma, AIROHA_PCS_PMA_PXP_CDR_PD_PWDB,
++ AIROHA_PCS_PMA_FORCE_SEL_DA_CDR_PD_PWDB |
++ AIROHA_PCS_PMA_FORCE_DA_CDR_PR_PD_PWDB);
++
++ regmap_set_bits(priv->xfi_pma, AIROHA_PCS_PMA_PXP_RX_FE_PWDB,
++ AIROHA_PCS_PMA_FORCE_SEL_DA_RX_FE_PWDB |
++ AIROHA_PCS_PMA_FORCE_DA_RX_FE_PWDB);
++
++ /* RX SigDet Pwdb */
++ regmap_set_bits(priv->xfi_pma, AIROHA_PCS_PMA_PXP_RX_SCAN_RST_B,
++ AIROHA_PCS_PMA_FORCE_SEL_DA_RX_SIGDET_PWDB |
++ AIROHA_PCS_PMA_FORCE_DA_RX_SIGDET_PWDB);
++
++ regmap_clear_bits(priv->xfi_pma, AIROHA_PCS_PMA_PXP_RX_SCAN_RST_B,
++ AIROHA_PCS_PMA_FORCE_SEL_DA_RX_SCAN_RST_B |
++ AIROHA_PCS_PMA_FORCE_DA_RX_SCAN_RST_B);
++
++ regmap_set_bits(priv->xfi_pma, AIROHA_PCS_PMA_PXP_CDR_LPF_LCK_2DATA,
++ AIROHA_PCS_PMA_FORCE_SEL_DA_CDR_LPF_LCK2DATA |
++ AIROHA_PCS_PMA_FORCE_DA_CDR_LPF_LCK2DATA);
++
++ regmap_set_bits(priv->xfi_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);
++
++ regmap_set_bits(priv->xfi_pma, AIROHA_PCS_PMA_SS_DA_XPON_PWDB_1,
++ AIROHA_PCS_PMA_RX_SIDGET_PWDB);
++
++ regmap_update_bits(priv->xfi_pma, AIROHA_PCS_PMA_RX_SYS_EN_SEL_0,
++ AIROHA_PCS_PMA_RX_SYS_EN_SEL,
++ FIELD_PREP(AIROHA_PCS_PMA_RX_SYS_EN_SEL, 0x1));
++
++ regmap_update_bits(priv->xfi_ana, AIROHA_PCS_ANA_PXP_CDR_PR_VREG_IBAND_VAL,
++ AIROHA_PCS_ANA_CDR_PR_FBKSEL |
++ AIROHA_PCS_ANA_CDR_PR_VREG_CKBUF_VAL |
++ AIROHA_PCS_ANA_CDR_PR_VREG_IBAND_VAL,
++ FIELD_PREP(AIROHA_PCS_ANA_CDR_PR_FBKSEL, 0x0) |
++ FIELD_PREP(AIROHA_PCS_ANA_CDR_PR_VREG_CKBUF_VAL, 0x5) |
++ FIELD_PREP(AIROHA_PCS_ANA_CDR_PR_VREG_IBAND_VAL, 0x5));
++
++ regmap_clear_bits(priv->xfi_pma, AIROHA_PCS_PMA_RX_CTRL_SEQUENCE_DISB_CTRL_0,
++ AIROHA_PCS_PMA_DISB_RX_PICAL_EN);
++
++ regmap_clear_bits(priv->xfi_pma, AIROHA_PCS_PMA_RX_CTRL_SEQUENCE_DISB_CTRL_0,
++ AIROHA_PCS_PMA_DISB_RX_PDOS_EN);
++
++ regmap_clear_bits(priv->xfi_pma, AIROHA_PCS_PMA_RX_CTRL_SEQUENCE_DISB_CTRL_0,
++ AIROHA_PCS_PMA_DISB_RX_FEOS_EN);
++
++ regmap_clear_bits(priv->xfi_pma, AIROHA_PCS_PMA_RX_CTRL_SEQUENCE_DISB_CTRL_1,
++ AIROHA_PCS_PMA_DISB_RX_SDCAL_EN);
++
++ regmap_clear_bits(priv->xfi_pma, AIROHA_PCS_PMA_RX_CTRL_SEQUENCE_DISB_CTRL_0,
++ AIROHA_PCS_PMA_DISB_RX_OS_EN);
++
++ regmap_clear_bits(priv->xfi_pma, AIROHA_PCS_PMA_RX_CTRL_SEQUENCE_DISB_CTRL_1,
++ AIROHA_PCS_PMA_DISB_RX_BLWC_EN);
++
++ regmap_update_bits(priv->xfi_ana, AIROHA_PCS_ANA_PXP_CDR_PR_CKREF_DIV,
++ AIROHA_PCS_ANA_CDR_PR_CKREF_DIV,
++ AIROHA_PCS_ANA_CDR_PR_CKREF_DIV_1);
++
++ regmap_update_bits(priv->xfi_ana, AIROHA_PCS_ANA_PXP_CDR_PR_TDC_REF_SEL,
++ AIROHA_PCS_ANA_CDR_PR_CKREF_DIV1,
++ AIROHA_PCS_ANA_CDR_PR_CKREF_DIV1_1);
++
++ regmap_set_bits(priv->xfi_pma, AIROHA_PCS_PMA_SW_RST_SET,
++ AIROHA_PCS_PMA_SW_RX_RST_N);
++
++ regmap_set_bits(priv->xfi_pma, AIROHA_PCS_PMA_SW_RST_SET,
++ AIROHA_PCS_PMA_SW_REF_RST_N);
++
++ regmap_set_bits(priv->xfi_pma, AIROHA_PCS_PMA_PXP_CDR_LPF_LCK_2DATA,
++ AIROHA_PCS_PMA_FORCE_DA_CDR_LPF_RSTB);
++
++ usleep_range(100, 200);
++
++ regmap_clear_bits(priv->xfi_pma, AIROHA_PCS_PMA_PXP_CDR_LPF_LCK_2DATA,
++ AIROHA_PCS_PMA_FORCE_DA_CDR_LPF_RSTB);
++}
++
++static void an7583_pcs_common_phya_l2d(struct airoha_pcs_priv *priv)
++{
++ /* Setup LPF L2D force and disable */
++ regmap_update_bits(priv->xfi_pma, AIROHA_PCS_PMA_PXP_CDR_LPF_LCK_2DATA,
++ AIROHA_PCS_PMA_FORCE_SEL_DA_CDR_LPF_LCK2DATA |
++ AIROHA_PCS_PMA_FORCE_DA_CDR_LPF_LCK2DATA,
++ AIROHA_PCS_PMA_FORCE_SEL_DA_CDR_LPF_LCK2DATA);
++
++ usleep_range(200, 300);
++
++ regmap_update_bits(priv->xfi_pma, AIROHA_PCS_PMA_PXP_CDR_LPF_LCK_2DATA,
++ AIROHA_PCS_PMA_FORCE_SEL_DA_CDR_LPF_RSTB |
++ AIROHA_PCS_PMA_FORCE_DA_CDR_LPF_RSTB,
++ AIROHA_PCS_PMA_FORCE_SEL_DA_CDR_LPF_RSTB);
++
++ regmap_set_bits(priv->xfi_pma, AIROHA_PCS_PMA_PXP_CDR_LPF_LCK_2DATA,
++ AIROHA_PCS_PMA_FORCE_DA_CDR_LPF_RSTB);
++}
++
++static void an7583_pcs_common_phya_tdc_off(struct airoha_pcs_priv *priv)
++{
++ regmap_set_bits(priv->xfi_pma, AIROHA_PCS_PMA_PXP_CDR_PR_IDAC,
++ AIROHA_PCS_PMA_FORCE_SEL_DA_TXPLL_SDM_PCW);
++
++ regmap_set_bits(priv->xfi_pma, AIROHA_PCS_PMA_LCPLL_TDC_FLT_3,
++ AIROHA_PCS_PMA_LCPLL_NCPO_LOAD);
++
++ regmap_set_bits(priv->xfi_pma, AIROHA_PCS_PMA_PXP_TXPLL_SDM_PCW_CHG,
++ AIROHA_PCS_PMA_FORCE_SEL_DA_TXPLL_SDM_PCW_CHG);
++
++ regmap_clear_bits(priv->xfi_pma, AIROHA_PCS_PMA_PXP_TXPLL_SDM_PCW_CHG,
++ AIROHA_PCS_PMA_FORCE_DA_TXPLL_SDM_PCW_CHG);
++
++ regmap_set_bits(priv->xfi_pma, AIROHA_PCS_PMA_PXP_TXPLL_SDM_PCW_CHG,
++ AIROHA_PCS_PMA_FORCE_DA_TXPLL_SDM_PCW_CHG);
++
++ regmap_update_bits(priv->xfi_pma, AIROHA_PCS_PMA_LCPLL_TDC_FLT_1,
++ AIROHA_PCS_PMA_LCPLL_GPON_SEL,
++ AIROHA_PCS_PMA_LCPLL_GPON_SEL_FROM_EPON);
++
++ regmap_clear_bits(priv->xfi_pma, AIROHA_PCS_PMA_LCPLL_TDC_PW_0,
++ AIROHA_PCS_PMA_LCPLL_TDC_DIG_PWDB);
++
++ usleep_range(100, 200);
++}
++
++static void an7583_pcs_common_phya_rx_oscal(struct airoha_pcs_priv *priv)
++{
++ regmap_clear_bits(priv->xfi_pma, AIROHA_PCS_PMA_RX_DISB_MODE_8,
++ AIROHA_PCS_PMA_DISB_FBCK_LOCK);
++
++ regmap_set_bits(priv->xfi_pma, AIROHA_PCS_PMA_RX_FORCE_MODE_9,
++ AIROHA_PCS_PMA_FORCE_FBCK_LOCK);
++
++ regmap_set_bits(priv->xfi_pma, AIROHA_PCS_PMA_PXP_JCPLL_SDM_SCAN_RSTB,
++ AIROHA_PCS_PMA_FORCE_SEL_DA_RX_OSCAL_CKON |
++ AIROHA_PCS_PMA_FORCE_DA_RX_OSCAL_CKON);
++
++ regmap_set_bits(priv->xfi_pma, AIROHA_PCS_PMA_PXP_RX_OSCAL_EN,
++ AIROHA_PCS_PMA_FORCE_SEL_DA_RX_OSCAL_RSTB |
++ AIROHA_PCS_PMA_FORCE_DA_RX_OSCAL_RSTB);
++
++ regmap_set_bits(priv->xfi_pma, AIROHA_PCS_PMA_PXP_RX_OSCAL_EN,
++ AIROHA_PCS_PMA_FORCE_SEL_DA_RX_OSCAL_EN |
++ AIROHA_PCS_PMA_FORCE_DA_RX_OSCAL_EN);
++
++ usleep_range(200, 300);
++
++ /* Set normal of force mode */
++ regmap_clear_bits(priv->xfi_pma, AIROHA_PCS_PMA_RX_CTRL_SEQUENCE_DISB_CTRL_0,
++ AIROHA_PCS_PMA_DISB_RX_OS_EN);
++
++ regmap_clear_bits(priv->xfi_pma, AIROHA_PCS_PMA_RX_CTRL_SEQUENCE_DISB_CTRL_1,
++ AIROHA_PCS_PMA_DISB_RX_OS_RDY);
++
++ /* Disable force mode signal */
++ regmap_clear_bits(priv->xfi_pma, AIROHA_PCS_PMA_RX_CTRL_SEQUENCE_FORCE_CTRL_0,
++ AIROHA_PCS_PMA_FORCE_RX_OS_EN);
++
++ regmap_clear_bits(priv->xfi_pma, AIROHA_PCS_PMA_RX_CTRL_SEQUENCE_FORCE_CTRL_1,
++ AIROHA_PCS_PMA_FORCE_RX_OS_RDY);
++
++ /* Release reset enable */
++ regmap_set_bits(priv->xfi_pma, AIROHA_PCS_PMA_RX_CTRL_SEQUENCE_FORCE_CTRL_0,
++ AIROHA_PCS_PMA_FORCE_RX_OS_EN);
++}
++
++static void an7583_pcs_common_phya_pical(struct airoha_pcs_priv *priv)
++{
++ /* Pre Condition */
++ regmap_set_bits(priv->xfi_pma, AIROHA_PCS_PMA_RX_DISB_MODE_2,
++ AIROHA_PCS_PMA_DISB_DA_XPON_CDR_PR_PIEYE);
++
++ regmap_update_bits(priv->xfi_pma, AIROHA_PCS_PMA_RX_PI_CAL,
++ AIROHA_PCS_PMA_KPGAIN,
++ FIELD_PREP(AIROHA_PCS_PMA_KPGAIN, 0x4));
++
++ regmap_update_bits(priv->xfi_pma, AIROHA_PCS_PMA_PHY_EQ_CTRL_0,
++ AIROHA_PCS_PMA_EQ_EN_DELAY,
++ FIELD_PREP(AIROHA_PCS_PMA_EQ_EN_DELAY, 0x8));
++
++ /* Reset Block */
++ regmap_clear_bits(priv->xfi_pma, AIROHA_PCS_PMA_RX_RESET_0,
++ AIROHA_PCS_PMA_EQ_PI_CAL_RST_B);
++
++ regmap_clear_bits(priv->xfi_pma, AIROHA_PCS_PMA_RX_FORCE_MODE_7,
++ AIROHA_PCS_PMA_FORCE_RX_AND_PICAL_RSTB);
++
++ regmap_clear_bits(priv->xfi_pma, AIROHA_PCS_PMA_RX_DISB_MODE_6,
++ AIROHA_PCS_PMA_DISB_RX_AND_PICAL_RSTB);
++
++ regmap_clear_bits(priv->xfi_pma, AIROHA_PCS_PMA_RX_FORCE_MODE_7,
++ AIROHA_PCS_PMA_FORCE_REF_AND_PICAL_RSTB);
++
++ regmap_clear_bits(priv->xfi_pma, AIROHA_PCS_PMA_RX_DISB_MODE_6,
++ AIROHA_PCS_PMA_DISB_REF_AND_PICAL_RSTB);
++
++ regmap_clear_bits(priv->xfi_pma, AIROHA_PCS_PMA_RX_DISB_MODE_3,
++ AIROHA_PCS_PMA_DISB_RQ_PI_CAL_RDY);
++
++ /* Enable */
++ regmap_clear_bits(priv->xfi_pma, AIROHA_PCS_PMA_RX_FORCE_MODE_6,
++ AIROHA_PCS_PMA_FORCE_RX_OR_PICAL_EN);
++
++ regmap_clear_bits(priv->xfi_pma, AIROHA_PCS_PMA_RX_DISB_MODE_5,
++ AIROHA_PCS_PMA_DISB_RX_OR_PICAL_EN);
++
++ regmap_clear_bits(priv->xfi_pma, AIROHA_PCS_PMA_RX_CTRL_SEQUENCE_FORCE_CTRL_0,
++ AIROHA_PCS_PMA_FORCE_RX_PICAL_EN);
++
++ regmap_clear_bits(priv->xfi_pma, AIROHA_PCS_PMA_RX_CTRL_SEQUENCE_DISB_CTRL_0,
++ AIROHA_PCS_PMA_DISB_RX_PICAL_EN);
++
++ regmap_clear_bits(priv->xfi_pma, AIROHA_PCS_PMA_RX_FORCE_MODE_3,
++ AIROHA_PCS_PMA_FORCE_EQ_PI_CAL_RDY);
++
++ /* Release Reset and Enable */
++ regmap_set_bits(priv->xfi_pma, AIROHA_PCS_PMA_RX_RESET_0,
++ AIROHA_PCS_PMA_EQ_PI_CAL_RST_B);
++
++ regmap_set_bits(priv->xfi_pma, AIROHA_PCS_PMA_RX_FORCE_MODE_7,
++ AIROHA_PCS_PMA_FORCE_RX_AND_PICAL_RSTB);
++
++ regmap_set_bits(priv->xfi_pma, AIROHA_PCS_PMA_RX_FORCE_MODE_7,
++ AIROHA_PCS_PMA_FORCE_REF_AND_PICAL_RSTB);
++
++ regmap_set_bits(priv->xfi_pma, AIROHA_PCS_PMA_RX_FORCE_MODE_6,
++ AIROHA_PCS_PMA_FORCE_RX_OR_PICAL_EN);
++
++ regmap_set_bits(priv->xfi_pma, AIROHA_PCS_PMA_RX_CTRL_SEQUENCE_FORCE_CTRL_0,
++ AIROHA_PCS_PMA_FORCE_RX_PICAL_EN);
++
++ usleep_range(200, 300);
++
++ regmap_clear_bits(priv->xfi_pma, AIROHA_PCS_PMA_RX_CTRL_SEQUENCE_FORCE_CTRL_0,
++ AIROHA_PCS_PMA_FORCE_RX_PICAL_EN);
++
++ regmap_clear_bits(priv->xfi_pma, AIROHA_PCS_PMA_RX_FORCE_MODE_6,
++ AIROHA_PCS_PMA_FORCE_RX_OR_PICAL_EN);
++
++ regmap_set_bits(priv->xfi_pma, AIROHA_PCS_PMA_RX_FORCE_MODE_3,
++ AIROHA_PCS_PMA_FORCE_EQ_PI_CAL_RDY);
++}
++
++static void an7583_pcs_common_phya_pdos(struct airoha_pcs_priv *priv)
++{
++ regmap_set_bits(priv->xfi_pma, AIROHA_PCS_PMA_PXP_RX_FE_PWDB,
++ AIROHA_PCS_PMA_FORCE_SEL_DA_RX_PDOSCAL_EN |
++ AIROHA_PCS_PMA_FORCE_DA_RX_PDOSCAL_EN);
++
++ /* Pre Condition */
++ regmap_clear_bits(priv->xfi_pma, AIROHA_PCS_PMA_RX_CTRL_SEQUENCE_FORCE_CTRL_1,
++ AIROHA_PCS_PMA_FORCE_RX_OS_RDY);
++
++ regmap_clear_bits(priv->xfi_pma, AIROHA_PCS_PMA_RX_CTRL_SEQUENCE_DISB_CTRL_1,
++ AIROHA_PCS_PMA_DISB_RX_OS_RDY);
++
++ regmap_set_bits(priv->xfi_pma, AIROHA_PCS_PMA_RX_DISB_MODE_1,
++ AIROHA_PCS_PMA_DISB_DA_XPON_RX_DAC_E0);
++
++ regmap_set_bits(priv->xfi_pma, AIROHA_PCS_PMA_RX_DISB_MODE_1,
++ AIROHA_PCS_PMA_DISB_DA_XPON_RX_DAC_D1);
++
++ regmap_set_bits(priv->xfi_pma, AIROHA_PCS_PMA_RX_DISB_MODE_1,
++ AIROHA_PCS_PMA_DISB_DA_XPON_RX_DAC_D0);
++
++ regmap_set_bits(priv->xfi_pma, AIROHA_PCS_PMA_RX_DISB_MODE_2,
++ AIROHA_PCS_PMA_DISB_DA_XPON_RX_DAC_E1);
++
++ regmap_set_bits(priv->xfi_pma, AIROHA_PCS_PMA_RX_DISB_MODE_2,
++ AIROHA_PCS_PMA_DISB_DA_XPON_RX_DAC_EYE);
++
++ regmap_clear_bits(priv->xfi_pma, AIROHA_PCS_PMA_RX_FORCE_MODE_8,
++ AIROHA_PCS_PMA_FORCE_BLWC_RX_RST_B);
++
++ regmap_clear_bits(priv->xfi_pma, AIROHA_PCS_PMA_RX_DISB_MODE_7,
++ AIROHA_PCS_PMA_DISB_BLWC_RX_RST_B);
++
++ regmap_clear_bits(priv->xfi_pma, AIROHA_PCS_PMA_RX_EYE_TOP_EYECNT_CTRL_1,
++ AIROHA_PCS_PMA_FORCE_EYEDUR_INIT_B);
++
++ regmap_clear_bits(priv->xfi_pma, AIROHA_PCS_PMA_RX_EYE_TOP_EYECNT_CTRL_1,
++ AIROHA_PCS_PMA_DISB_EYEDUR_INIT_B);
++
++ regmap_clear_bits(priv->xfi_pma, AIROHA_PCS_PMA_RX_FORCE_MODE_8,
++ AIROHA_PCS_PMA_FORCE_EYECNT_RX_RST_B);
++
++ regmap_clear_bits(priv->xfi_pma, AIROHA_PCS_PMA_RX_DISB_MODE_7,
++ AIROHA_PCS_PMA_DISB_EYECNT_RX_RST_B);
++
++ regmap_clear_bits(priv->xfi_pma, AIROHA_PCS_PMA_RX_EYE_TOP_EYECNT_CTRL_1,
++ AIROHA_PCS_PMA_FORCE_EYEDUR_EN);
++
++ regmap_clear_bits(priv->xfi_pma, AIROHA_PCS_PMA_RX_EYE_TOP_EYECNT_CTRL_1,
++ AIROHA_PCS_PMA_DISB_EYEDUR_EN);
++
++ regmap_update_bits(priv->xfi_pma, AIROHA_PCS_PMA_RX_PDOS_CTRL_0,
++ AIROHA_PCS_PMA_SAP_SEL,
++ AIROHA_PCS_PMA_SAP_SEL_SHIFT_8);
++
++ /* Reset Block */
++ regmap_clear_bits(priv->xfi_pma, AIROHA_PCS_PMA_RX_FORCE_MODE_7,
++ AIROHA_PCS_PMA_FORCE_PDOS_RX_RST_B);
++
++ regmap_clear_bits(priv->xfi_pma, AIROHA_PCS_PMA_RX_DISB_MODE_6,
++ AIROHA_PCS_PMA_DISB_PDOS_RX_RST_B);
++
++ regmap_clear_bits(priv->xfi_pma, AIROHA_PCS_PMA_RX_RESET_1,
++ AIROHA_PCS_PMA_PDOS_RST_B);
++
++ /* Disable */
++ regmap_clear_bits(priv->xfi_pma, AIROHA_PCS_PMA_RX_CTRL_SEQUENCE_FORCE_CTRL_0,
++ AIROHA_PCS_PMA_FORCE_RX_PDOS_EN);
++
++ regmap_clear_bits(priv->xfi_pma, AIROHA_PCS_PMA_RX_CTRL_SEQUENCE_DISB_CTRL_0,
++ AIROHA_PCS_PMA_DISB_RX_PDOS_EN);
++
++ /* Release Reset and Enable */
++ regmap_clear_bits(priv->xfi_pma, AIROHA_PCS_PMA_RX_CTRL_SEQUENCE_FORCE_CTRL_0,
++ AIROHA_PCS_PMA_FORCE_RX_OS_EN);
++
++ regmap_clear_bits(priv->xfi_pma, AIROHA_PCS_PMA_RX_CTRL_SEQUENCE_DISB_CTRL_0,
++ AIROHA_PCS_PMA_DISB_RX_OS_EN);
++
++ regmap_set_bits(priv->xfi_pma, AIROHA_PCS_PMA_RX_FORCE_MODE_7,
++ AIROHA_PCS_PMA_FORCE_PDOS_RX_RST_B);
++
++ regmap_set_bits(priv->xfi_pma, AIROHA_PCS_PMA_RX_RESET_1,
++ AIROHA_PCS_PMA_PDOS_RST_B);
++
++ regmap_set_bits(priv->xfi_pma, AIROHA_PCS_PMA_RX_CTRL_SEQUENCE_FORCE_CTRL_0,
++ AIROHA_PCS_PMA_FORCE_RX_PDOS_EN);
++
++ usleep_range(200, 300);
++
++ /* Disable (again) */
++ regmap_clear_bits(priv->xfi_pma, AIROHA_PCS_PMA_RX_CTRL_SEQUENCE_FORCE_CTRL_0,
++ AIROHA_PCS_PMA_FORCE_RX_PDOS_EN);
++
++ regmap_clear_bits(priv->xfi_pma, AIROHA_PCS_PMA_RX_CTRL_SEQUENCE_FORCE_CTRL_0,
++ AIROHA_PCS_PMA_FORCE_RX_OS_EN);
++
++ /* Release EYE related */
++ regmap_clear_bits(priv->xfi_pma, AIROHA_PCS_PMA_RX_EYE_TOP_EYECNT_CTRL_1,
++ AIROHA_PCS_PMA_FORCE_EYEDUR_INIT_B);
++
++ regmap_set_bits(priv->xfi_pma, AIROHA_PCS_PMA_RX_EYE_TOP_EYECNT_CTRL_1,
++ AIROHA_PCS_PMA_DISB_EYEDUR_INIT_B);
++
++ regmap_clear_bits(priv->xfi_pma, AIROHA_PCS_PMA_RX_FORCE_MODE_8,
++ AIROHA_PCS_PMA_FORCE_EYECNT_RX_RST_B);
++
++ regmap_set_bits(priv->xfi_pma, AIROHA_PCS_PMA_RX_DISB_MODE_7,
++ AIROHA_PCS_PMA_DISB_EYECNT_RX_RST_B);
++
++ regmap_clear_bits(priv->xfi_pma, AIROHA_PCS_PMA_RX_EYE_TOP_EYECNT_CTRL_1,
++ AIROHA_PCS_PMA_FORCE_EYEDUR_EN);
++
++ regmap_set_bits(priv->xfi_pma, AIROHA_PCS_PMA_RX_EYE_TOP_EYECNT_CTRL_1,
++ AIROHA_PCS_PMA_DISB_EYEDUR_EN);
++
++ /* Disable PDOS */
++ regmap_update_bits(priv->xfi_pma, AIROHA_PCS_PMA_PXP_RX_FE_PWDB,
++ AIROHA_PCS_PMA_FORCE_SEL_DA_RX_PDOSCAL_EN |
++ AIROHA_PCS_PMA_FORCE_DA_RX_PDOSCAL_EN,
++ AIROHA_PCS_PMA_FORCE_SEL_DA_RX_PDOSCAL_EN);
++}
++
++static void an7583_pcs_common_phya_feos(struct airoha_pcs_priv *priv)
++{
++ /* Pre Condition */
++ regmap_clear_bits(priv->xfi_pma, AIROHA_PCS_PMA_RX_CTRL_SEQUENCE_FORCE_CTRL_1,
++ AIROHA_PCS_PMA_FORCE_RX_OS_RDY);
++
++ regmap_clear_bits(priv->xfi_pma, AIROHA_PCS_PMA_RX_CTRL_SEQUENCE_DISB_CTRL_1,
++ AIROHA_PCS_PMA_DISB_RX_OS_RDY);
++
++ regmap_set_bits(priv->xfi_pma, AIROHA_PCS_PMA_RX_DISB_MODE_2,
++ AIROHA_PCS_PMA_DISB_DA_XPON_RX_FE_VOS);
++
++ regmap_clear_bits(priv->xfi_pma, AIROHA_PCS_PMA_RX_FORCE_MODE_8,
++ AIROHA_PCS_PMA_FORCE_BLWC_RX_RST_B);
++
++ regmap_clear_bits(priv->xfi_pma, AIROHA_PCS_PMA_RX_DISB_MODE_7,
++ AIROHA_PCS_PMA_DISB_BLWC_RX_RST_B);
++
++ /* Setting */
++ regmap_update_bits(priv->xfi_pma, AIROHA_PCS_PMA_SS_RX_FEOS,
++ AIROHA_PCS_PMA_LFSEL,
++ FIELD_PREP(AIROHA_PCS_PMA_LFSEL, 0x30));
++
++ /* Reset */
++ regmap_clear_bits(priv->xfi_pma, AIROHA_PCS_PMA_RX_FORCE_MODE_8,
++ AIROHA_PCS_PMA_FORCE_FEOS_RX_RST_B);
++
++ regmap_clear_bits(priv->xfi_pma, AIROHA_PCS_PMA_RX_DISB_MODE_7,
++ AIROHA_PCS_PMA_DISB_FEOS_RX_RST_B);
++
++ regmap_clear_bits(priv->xfi_pma, AIROHA_PCS_PMA_RX_RESET_0,
++ AIROHA_PCS_PMA_FEOS_RST_B);
++
++ /* Disable */
++ regmap_clear_bits(priv->xfi_pma, AIROHA_PCS_PMA_RX_CTRL_SEQUENCE_FORCE_CTRL_0,
++ AIROHA_PCS_PMA_FORCE_RX_FEOS_EN);
++
++ regmap_clear_bits(priv->xfi_pma, AIROHA_PCS_PMA_RX_CTRL_SEQUENCE_DISB_CTRL_0,
++ AIROHA_PCS_PMA_DISB_RX_FEOS_EN);
++
++ /* Release Reset and Enable */
++ regmap_set_bits(priv->xfi_pma, AIROHA_PCS_PMA_RX_CTRL_SEQUENCE_FORCE_CTRL_0,
++ AIROHA_PCS_PMA_FORCE_RX_OS_EN);
++
++ regmap_clear_bits(priv->xfi_pma, AIROHA_PCS_PMA_RX_CTRL_SEQUENCE_DISB_CTRL_0,
++ AIROHA_PCS_PMA_DISB_RX_OS_EN);
++
++ regmap_set_bits(priv->xfi_pma, AIROHA_PCS_PMA_RX_FORCE_MODE_8,
++ AIROHA_PCS_PMA_FORCE_FEOS_RX_RST_B);
++
++ regmap_set_bits(priv->xfi_pma, AIROHA_PCS_PMA_RX_RESET_0,
++ AIROHA_PCS_PMA_FEOS_RST_B);
++
++ regmap_set_bits(priv->xfi_pma, AIROHA_PCS_PMA_RX_CTRL_SEQUENCE_FORCE_CTRL_0,
++ AIROHA_PCS_PMA_FORCE_RX_FEOS_EN);
++
++ usleep_range(1000, 1500);
++
++ /* Disable */
++ regmap_clear_bits(priv->xfi_pma, AIROHA_PCS_PMA_RX_CTRL_SEQUENCE_FORCE_CTRL_0,
++ AIROHA_PCS_PMA_FORCE_RX_FEOS_EN);
++
++ regmap_clear_bits(priv->xfi_pma, AIROHA_PCS_PMA_RX_CTRL_SEQUENCE_FORCE_CTRL_0,
++ AIROHA_PCS_PMA_FORCE_RX_OS_EN);
++}
++
++static void an7583_pcs_common_phya_sdcal(struct airoha_pcs_priv *priv)
++{
++ /* Pre Condition */
++ regmap_set_bits(priv->xfi_pma, AIROHA_PCS_PMA_PXP_RX_SIGDET_CAL_EN,
++ AIROHA_PCS_PMA_FORCE_SEL_DA_RX_SIGDET_CAL_EN |
++ AIROHA_PCS_PMA_FORCE_DA_RX_SIGDET_CAL_EN);
++
++ regmap_set_bits(priv->xfi_pma, AIROHA_PCS_PMA_PXP_RX_OSCAL_EN,
++ AIROHA_PCS_PMA_FORCE_SEL_DA_RX_OSCAL_EN |
++ AIROHA_PCS_PMA_FORCE_DA_RX_OSCAL_EN);
++
++ /* Reset */
++ regmap_clear_bits(priv->xfi_pma, AIROHA_PCS_PMA_RX_RESET_0,
++ AIROHA_PCS_PMA_CAL_RST_B);
++
++ regmap_clear_bits(priv->xfi_pma, AIROHA_PCS_PMA_RX_FORCE_MODE_8,
++ AIROHA_PCS_PMA_FORCE_SDCAL_REF_RST_B);
++
++ regmap_clear_bits(priv->xfi_pma, AIROHA_PCS_PMA_RX_CTRL_SEQUENCE_DISB_CTRL_1,
++ AIROHA_PCS_PMA_DISB_RX_SDCAL_EN);
++
++ regmap_clear_bits(priv->xfi_pma, AIROHA_PCS_PMA_RX_DISB_MODE_7,
++ AIROHA_PCS_PMA_DISB_SDCAL_REF_RST_B);
++
++ regmap_clear_bits(priv->xfi_pma, AIROHA_PCS_PMA_RX_CTRL_SEQUENCE_FORCE_CTRL_1,
++ AIROHA_PCS_PMA_FORCE_RX_SDCAL_EN);
++
++ /* Release Reset and Enable */
++ regmap_set_bits(priv->xfi_pma, AIROHA_PCS_PMA_RX_RESET_0,
++ AIROHA_PCS_PMA_CAL_RST_B);
++
++ regmap_set_bits(priv->xfi_pma, AIROHA_PCS_PMA_RX_FORCE_MODE_8,
++ AIROHA_PCS_PMA_FORCE_SDCAL_REF_RST_B);
++
++ regmap_set_bits(priv->xfi_pma, AIROHA_PCS_PMA_RX_CTRL_SEQUENCE_FORCE_CTRL_1,
++ AIROHA_PCS_PMA_FORCE_RX_SDCAL_EN);
++
++ usleep_range(200, 300);
++
++ regmap_clear_bits(priv->xfi_pma, AIROHA_PCS_PMA_RX_CTRL_SEQUENCE_FORCE_CTRL_1,
++ AIROHA_PCS_PMA_FORCE_RX_SDCAL_EN);
++
++ /* SigDet Cal Disable */
++ regmap_update_bits(priv->xfi_pma, AIROHA_PCS_PMA_PXP_RX_SIGDET_CAL_EN,
++ AIROHA_PCS_PMA_FORCE_SEL_DA_RX_SIGDET_CAL_EN |
++ AIROHA_PCS_PMA_FORCE_DA_RX_SIGDET_CAL_EN,
++ AIROHA_PCS_PMA_FORCE_SEL_DA_RX_SIGDET_CAL_EN);
++
++ regmap_update_bits(priv->xfi_pma, AIROHA_PCS_PMA_PXP_JCPLL_SDM_SCAN_RSTB,
++ AIROHA_PCS_PMA_FORCE_SEL_DA_RX_OSCAL_CKON |
++ AIROHA_PCS_PMA_FORCE_DA_RX_OSCAL_CKON,
++ AIROHA_PCS_PMA_FORCE_SEL_DA_RX_OSCAL_CKON);
++
++ regmap_update_bits(priv->xfi_pma, AIROHA_PCS_PMA_PXP_RX_OSCAL_EN,
++ AIROHA_PCS_PMA_FORCE_SEL_DA_RX_OSCAL_RSTB |
++ AIROHA_PCS_PMA_FORCE_DA_RX_OSCAL_RSTB,
++ AIROHA_PCS_PMA_FORCE_SEL_DA_RX_OSCAL_RSTB);
++
++ regmap_update_bits(priv->xfi_pma, AIROHA_PCS_PMA_PXP_RX_OSCAL_EN,
++ AIROHA_PCS_PMA_FORCE_SEL_DA_RX_OSCAL_EN |
++ AIROHA_PCS_PMA_FORCE_DA_RX_OSCAL_EN,
++ AIROHA_PCS_PMA_FORCE_SEL_DA_RX_OSCAL_EN);
++}
++
++static void an7583_pcs_common_phya_phy_status(struct airoha_pcs_priv *priv)
++{
++ regmap_set_bits(priv->xfi_pma, AIROHA_PCS_PMA_RX_CTRL_SEQUENCE_FORCE_CTRL_1,
++ AIROHA_PCS_PMA_FORCE_RX_OS_RDY);
++ regmap_clear_bits(priv->xfi_pma, AIROHA_PCS_PMA_RX_CTRL_SEQUENCE_DISB_CTRL_1,
++ AIROHA_PCS_PMA_DISB_RX_OS_RDY);
++ udelay(1);
++}
++
++static void an7583_pcs_common_phya_eye_setting(struct airoha_pcs_priv *priv,
++ phy_interface_t interface)
++{
++ u32 x_min, x_max;
++ u32 cdr_lpf_ratio;
++
++ switch (interface) {
++ case PHY_INTERFACE_MODE_SGMII:
++ case PHY_INTERFACE_MODE_1000BASEX:
++ x_min = 0x0;
++ x_max = 0x400;
++ cdr_lpf_ratio = 0x3;
++ break;
++ case PHY_INTERFACE_MODE_2500BASEX:
++ x_min = 0x140;
++ x_max = 0x2c0;
++ cdr_lpf_ratio = 0x0;
++ break;
++ case PHY_INTERFACE_MODE_5GBASER:
++ x_min = 0x180;
++ x_max = 0x280;
++ cdr_lpf_ratio = 0x1;
++ break;
++ case PHY_INTERFACE_MODE_10GBASER:
++ case PHY_INTERFACE_MODE_USXGMII:
++ x_min = 0x1c0;
++ x_max = 0x234;
++ cdr_lpf_ratio = 0x0;
++ break;
++ default:
++ return;
++ }
++
++ regmap_update_bits(priv->xfi_ana, AIROHA_PCS_ANA_PXP_CDR_LPF_RATIO,
++ AIROHA_PCS_ANA_CDR_LPF_RATIO,
++ FIELD_PREP(AIROHA_PCS_ANA_CDR_LPF_RATIO,
++ cdr_lpf_ratio));
++
++ regmap_update_bits(priv->xfi_pma, AIROHA_PCS_PMA_RX_EYE_TOP_EYECNT_CTRL_0,
++ AIROHA_PCS_PMA_EYE_MASK,
++ FIELD_PREP(AIROHA_PCS_PMA_EYE_MASK, 0xff));
++
++ regmap_update_bits(priv->xfi_pma, AIROHA_PCS_PMA_RX_EYE_TOP_EYEINDEX_CTRL_0,
++ AIROHA_PCS_PMA_X_MAX | AIROHA_PCS_PMA_X_MIN,
++ FIELD_PREP(AIROHA_PCS_PMA_X_MAX, x_max) |
++ FIELD_PREP(AIROHA_PCS_PMA_X_MIN, x_min));
++
++ regmap_update_bits(priv->xfi_pma, AIROHA_PCS_PMA_RX_EYE_TOP_EYECNT_CTRL_0,
++ AIROHA_PCS_PMA_CNTLEN,
++ FIELD_PREP(AIROHA_PCS_PMA_CNTLEN, 0xf8));
++
++ regmap_clear_bits(priv->xfi_ana, AIROHA_PCS_PMA_RX_EYE_TOP_EYECNT_CTRL_0,
++ AIROHA_PCS_PMA_CNTFOREVER);
++
++ regmap_clear_bits(priv->xfi_pma, AIROHA_PCS_PMA_RX_EYE_TOP_EYECNT_CTRL_2,
++ AIROHA_PCS_PMA_DATA_SHIFT);
++
++ regmap_clear_bits(priv->xfi_pma, AIROHA_PCS_PMA_RX_EYE_TOP_EYEINDEX_CTRL_1,
++ AIROHA_PCS_PMA_INDEX_MODE);
++
++ regmap_update_bits(priv->xfi_pma, AIROHA_PCS_PMA_RX_EYE_TOP_EYEINDEX_CTRL_2,
++ AIROHA_PCS_PMA_EYEDUR,
++ FIELD_PREP(AIROHA_PCS_PMA_EYEDUR, 0x44c));
++
++ regmap_update_bits(priv->xfi_pma, AIROHA_PCS_PMA_RX_EYE_TOP_EYEINDEX_CTRL_3,
++ AIROHA_PCS_PMA_EYE_NEXTPTS |
++ AIROHA_PCS_PMA_EYE_NEXTPTS_TOGGLE |
++ AIROHA_PCS_PMA_EYE_NEXTPTS_SEL,
++ AIROHA_PCS_PMA_EYE_NEXTPTS);
++
++ regmap_update_bits(priv->xfi_pma, AIROHA_PCS_PMA_RX_EYE_TOP_EYEOPENING_CTRL_0,
++ AIROHA_PCS_PMA_EYECNT_VTH |
++ AIROHA_PCS_PMA_EYECNT_HTH,
++ FIELD_PREP(AIROHA_PCS_PMA_EYECNT_VTH, 0x4) |
++ FIELD_PREP(AIROHA_PCS_PMA_EYECNT_HTH, 0x4));
++
++ regmap_update_bits(priv->xfi_pma, AIROHA_PCS_PMA_RX_EYE_TOP_EYEOPENING_CTRL_1,
++ AIROHA_PCS_PMA_EO_VTH |
++ AIROHA_PCS_PMA_EO_HTH,
++ FIELD_PREP(AIROHA_PCS_PMA_EO_VTH, 0x4) |
++ FIELD_PREP(AIROHA_PCS_PMA_EO_HTH, 0x4));
++
++ regmap_clear_bits(priv->xfi_pma, AIROHA_PCS_PMA_PHY_EQ_CTRL_1,
++ AIROHA_PCS_PMA_B_ZERO_SEL |
++ AIROHA_PCS_PMA_HEO_EMPHASIS |
++ AIROHA_PCS_PMA_A_MGAIN |
++ AIROHA_PCS_PMA_A_LGAIN);
++
++ regmap_update_bits(priv->xfi_pma, AIROHA_PCS_PMA_PHY_EQ_CTRL_2,
++ AIROHA_PCS_PMA_A_SEL,
++ FIELD_PREP(AIROHA_PCS_PMA_A_SEL, 0x1));
++}
++
++static void an7583_pcs_common_phya_eye_cal(struct airoha_pcs_priv *priv)
++{
++ regmap_update_bits(priv->xfi_pma, AIROHA_PCS_PMA_PXP_TX_RATE_CTRL,
++ AIROHA_PCS_PMA_FORCE_SEL_DA_CDR_PR_PIEYE |
++ AIROHA_PCS_PMA_FORCE_DA_CDR_PR_PIEYE,
++ FIELD_PREP(AIROHA_PCS_PMA_FORCE_DA_CDR_PR_PIEYE, 0x0));
++
++ regmap_update_bits(priv->xfi_pma, AIROHA_PCS_PMA_PXP_CDR_PR_FLL_COR,
++ AIROHA_PCS_PMA_FORCE_SEL_DA_RX_DAC_EYE |
++ AIROHA_PCS_PMA_FORCE_DA_RX_DAC_EYE,
++ FIELD_PREP(AIROHA_PCS_PMA_FORCE_DA_RX_DAC_EYE, 0x0));
++
++ /* Redo PICal and reset Block */
++ regmap_update_bits(priv->xfi_pma, AIROHA_PCS_PMA_PHY_EQ_CTRL_0,
++ AIROHA_PCS_PMA_EQ_EN_DELAY,
++ FIELD_PREP(AIROHA_PCS_PMA_EQ_EN_DELAY, 0x80));
++
++ regmap_update_bits(priv->xfi_pma, AIROHA_PCS_PMA_RX_PI_CAL,
++ AIROHA_PCS_PMA_KPGAIN,
++ FIELD_PREP(AIROHA_PCS_PMA_KPGAIN, 0x1));
++
++ regmap_clear_bits(priv->xfi_pma, AIROHA_PCS_PMA_RX_RESET_0,
++ AIROHA_PCS_PMA_EQ_PI_CAL_RST_B);
++
++ regmap_clear_bits(priv->xfi_pma, AIROHA_PCS_PMA_RX_FORCE_MODE_7,
++ AIROHA_PCS_PMA_FORCE_RX_AND_PICAL_RSTB);
++
++ regmap_clear_bits(priv->xfi_pma, AIROHA_PCS_PMA_RX_DISB_MODE_6,
++ AIROHA_PCS_PMA_DISB_RX_AND_PICAL_RSTB);
++
++ regmap_clear_bits(priv->xfi_pma, AIROHA_PCS_PMA_RX_FORCE_MODE_7,
++ AIROHA_PCS_PMA_FORCE_REF_AND_PICAL_RSTB);
++
++ regmap_clear_bits(priv->xfi_pma, AIROHA_PCS_PMA_RX_DISB_MODE_6,
++ AIROHA_PCS_PMA_DISB_REF_AND_PICAL_RSTB);
++
++ /* Enable PICal */
++ regmap_clear_bits(priv->xfi_pma, AIROHA_PCS_PMA_RX_DISB_MODE_5,
++ AIROHA_PCS_PMA_DISB_RX_OR_PICAL_EN);
++
++ regmap_clear_bits(priv->xfi_pma, AIROHA_PCS_PMA_RX_FORCE_MODE_6,
++ AIROHA_PCS_PMA_FORCE_RX_OR_PICAL_EN);
++
++ regmap_clear_bits(priv->xfi_pma, AIROHA_PCS_PMA_RX_CTRL_SEQUENCE_DISB_CTRL_0,
++ AIROHA_PCS_PMA_DISB_RX_PICAL_EN);
++
++ regmap_clear_bits(priv->xfi_pma, AIROHA_PCS_PMA_RX_CTRL_SEQUENCE_FORCE_CTRL_0,
++ AIROHA_PCS_PMA_FORCE_RX_PICAL_EN);
++
++ /* Release Reset */
++ regmap_set_bits(priv->xfi_pma, AIROHA_PCS_PMA_RX_RESET_0,
++ AIROHA_PCS_PMA_EQ_PI_CAL_RST_B);
++
++ regmap_set_bits(priv->xfi_pma, AIROHA_PCS_PMA_RX_FORCE_MODE_7,
++ AIROHA_PCS_PMA_FORCE_RX_AND_PICAL_RSTB);
++
++ regmap_set_bits(priv->xfi_pma, AIROHA_PCS_PMA_RX_FORCE_MODE_7,
++ AIROHA_PCS_PMA_FORCE_REF_AND_PICAL_RSTB);
++
++ regmap_set_bits(priv->xfi_pma, AIROHA_PCS_PMA_RX_FORCE_MODE_6,
++ AIROHA_PCS_PMA_FORCE_RX_OR_PICAL_EN);
++
++ usleep_range(1000, 1500);
++
++ regmap_clear_bits(priv->xfi_pma, AIROHA_PCS_PMA_RX_FORCE_MODE_6,
++ AIROHA_PCS_PMA_FORCE_RX_OR_PICAL_EN);
++
++ regmap_clear_bits(priv->xfi_pma, AIROHA_PCS_PMA_RX_DISB_MODE_3,
++ AIROHA_PCS_PMA_DISB_RQ_PI_CAL_RDY);
++
++ regmap_set_bits(priv->xfi_pma, AIROHA_PCS_PMA_RX_FORCE_MODE_3,
++ AIROHA_PCS_PMA_FORCE_EQ_PI_CAL_RDY);
++
++ regmap_clear_bits(priv->xfi_pma, AIROHA_PCS_PMA_RX_DISB_MODE_5,
++ AIROHA_PCS_PMA_DISB_EYECNT_RDY);
++
++ regmap_set_bits(priv->xfi_pma, AIROHA_PCS_PMA_RX_FORCE_MODE_6,
++ AIROHA_PCS_PMA_FORCE_EYECNT_RDY);
++
++ usleep_range(1000, 1500);
++}
++
++static void an7583_pcs_common_phya_eye_eo_read(struct airoha_pcs_priv *priv,
++ u32 *heo, u32 *veo)
++{
++ u32 eo_buf[EO_BUF_MAX];
++ u32 eye_el, eye_er;
++ u32 feos;
++ u32 val;
++ int i;
++
++ regmap_set_bits(priv->xfi_pma, AIROHA_PCS_PMA_RX_FLL_6,
++ AIROHA_PCS_PMA_LNX_SW_FLL_4_LATCH_EN |
++ AIROHA_PCS_PMA_LNX_SW_FLL_3_LATCH_EN |
++ AIROHA_PCS_PMA_LNX_SW_FLL_2_LATCH_EN |
++ AIROHA_PCS_PMA_LNX_SW_FLL_1_LATCH_EN);
++
++ usleep_range(50, 100);
++
++ regmap_clear_bits(priv->xfi_pma, AIROHA_PCS_PMA_RX_FLL_6,
++ AIROHA_PCS_PMA_LNX_SW_FLL_4_LATCH_EN |
++ AIROHA_PCS_PMA_LNX_SW_FLL_3_LATCH_EN |
++ AIROHA_PCS_PMA_LNX_SW_FLL_2_LATCH_EN |
++ AIROHA_PCS_PMA_LNX_SW_FLL_1_LATCH_EN);
++
++ regmap_clear_bits(priv->xfi_pma, AIROHA_PCS_PMA_RX_DEBUG_0,
++ AIROHA_PCS_PMA_RO_TOGGLE);
++
++ usleep_range(100, 200);
++
++ regmap_set_bits(priv->xfi_pma, AIROHA_PCS_PMA_RX_DEBUG_0,
++ AIROHA_PCS_PMA_RO_TOGGLE);
++
++ regmap_read(priv->xfi_pma, AIROHA_PCS_PMA_RX_TORGS_DEBUG_10, &val);
++ eye_el = FIELD_GET(AIROHA_PCS_PMA_EYE_EL, val);
++ eye_er = FIELD_GET(AIROHA_PCS_PMA_EYE_ER, val);
++
++ regmap_read(priv->xfi_pma, AIROHA_PCS_PMA_RX_TORGS_DEBUG_11, &val);
++ eo_buf[EYE_EU] = FIELD_GET(AIROHA_PCS_PMA_EYE_EU, val);
++ eo_buf[EYE_EB] = FIELD_GET(AIROHA_PCS_PMA_EYE_EB, val);
++
++ regmap_read(priv->xfi_pma, AIROHA_PCS_PMA_ADD_RX2ANA_1, &val);
++ eo_buf[DAC_EYE] = FIELD_GET(AIROHA_PCS_PMA_RX_DAC_EYE, val);
++ eo_buf[DAC_D0] = FIELD_GET(AIROHA_PCS_PMA_RX_DAC_D0, val);
++ eo_buf[DAC_D1] = FIELD_GET(AIROHA_PCS_PMA_RX_DAC_D1, val);
++ eo_buf[DAC_E0] = FIELD_GET(AIROHA_PCS_PMA_RX_DAC_E0, val);
++
++ regmap_read(priv->xfi_pma, AIROHA_PCS_PMA_ADD_RX2ANA_2, &val);
++ eo_buf[FEOS] = FIELD_GET(AIROHA_PCS_PMA_RX_FEOS_OUT, val);
++ eo_buf[DAC_E1] = FIELD_GET(AIROHA_PCS_PMA_RX_DAC_E1, val);
++
++ feos = eo_buf[FEOS];
++
++ for (i = 0; i < ARRAY_SIZE(eo_buf); i++) {
++ if ((eo_buf[i] == feos) && (eo_buf[i] >= 32))
++ eo_buf[i] = eo_buf[i] - 64;
++ else if (eo_buf[i] >= 64)
++ eo_buf[i] = eo_buf[i] - 128;
++ }
++
++ /* Check if CLK unlocking happens (E0 result validity) */
++ regmap_read(priv->xfi_pma, AIROHA_PCS_PMA_RX_TORGS_DEBUG_5, &val);
++ if (!FIELD_GET(AIROHA_PCS_PMA_HEO_RDY, val)) {
++ regmap_clear_bits(priv->xfi_pma, AIROHA_PCS_PMA_RX_DISB_MODE_0,
++ AIROHA_PCS_PMA_DISB_DA_XPON_CDR_LPF_RSTB);
++
++ regmap_clear_bits(priv->xfi_pma, AIROHA_PCS_PMA_RX_FORCE_MODE_0,
++ AIROHA_PCS_PMA_FORCE_DA_XPON_CDR_LPF_RSTB);
++
++ usleep_range(500, 700);
++
++ regmap_set_bits(priv->xfi_pma, AIROHA_PCS_PMA_RX_FORCE_MODE_0,
++ AIROHA_PCS_PMA_FORCE_DA_XPON_CDR_LPF_RSTB);
++
++ usleep_range(500, 700);
++ }
++
++ *heo = abs(eye_er - eye_el);
++ *veo = abs(eo_buf[EYE_EU] - eo_buf[EYE_EB]);
++}
++
++static void an7583_pcs_common_phya_eye_eo(struct airoha_pcs_priv *priv,
++ phy_interface_t interface,
++ u32 *heo, u32 *veo)
++{
++ regmap_clear_bits(priv->xfi_pma, AIROHA_PCS_PMA_RX_DISB_MODE_8,
++ AIROHA_PCS_PMA_DISB_EYE_RESET_PLU_O);
++
++ regmap_set_bits(priv->xfi_pma, AIROHA_PCS_PMA_RX_FORCE_MODE_9,
++ AIROHA_PCS_PMA_FORCE_EYE_RESET_PLU_O);
++
++ regmap_clear_bits(priv->xfi_pma, AIROHA_PCS_PMA_RX_FORCE_MODE_9,
++ AIROHA_PCS_PMA_FORCE_EYE_RESET_PLU_O);
++
++ regmap_clear_bits(priv->xfi_pma, AIROHA_PCS_PMA_RX_DISB_MODE_8,
++ AIROHA_PCS_PMA_DISB_EYE_TOP_EN);
++
++ regmap_clear_bits(priv->xfi_pma, AIROHA_PCS_PMA_RX_FORCE_MODE_9,
++ AIROHA_PCS_PMA_FORCE_EYE_TOP_EN);
++
++ regmap_set_bits(priv->xfi_pma, AIROHA_PCS_PMA_RX_FORCE_MODE_9,
++ AIROHA_PCS_PMA_FORCE_EYE_TOP_EN);
++
++ if (interface == PHY_INTERFACE_MODE_10GBASER ||
++ interface == PHY_INTERFACE_MODE_USXGMII)
++ usleep_range(5500, 6000);
++ else
++ msleep(55);
++
++ regmap_set_bits(priv->xfi_pma, AIROHA_PCS_PMA_RX_DISB_MODE_2,
++ AIROHA_PCS_PMA_DISB_DA_XPON_CDR_PR_PIEYE |
++ AIROHA_PCS_PMA_DISB_DA_XPON_RX_DAC_EYE);
++
++ regmap_set_bits(priv->xfi_pma, AIROHA_PCS_PMA_RX_EYE_TOP_EYECNT_CTRL_1,
++ AIROHA_PCS_PMA_DISB_EYEDUR_INIT_B);
++
++ regmap_set_bits(priv->xfi_pma, AIROHA_PCS_PMA_RX_DISB_MODE_7,
++ AIROHA_PCS_PMA_DISB_EYECNT_RX_RST_B);
++
++ regmap_set_bits(priv->xfi_pma, AIROHA_PCS_PMA_RX_EYE_TOP_EYECNT_CTRL_1,
++ AIROHA_PCS_PMA_DISB_EYEDUR_EN);
++
++ an7583_pcs_common_phya_eye_eo_read(priv, heo, veo);
++
++ /* Clear Eye SW value */
++ regmap_set_bits(priv->xfi_pma, AIROHA_PCS_PMA_RX_FORCE_MODE_9,
++ AIROHA_PCS_PMA_FORCE_EYE_RESET_PLU_O);
++
++ regmap_clear_bits(priv->xfi_pma, AIROHA_PCS_PMA_RX_DISB_MODE_8,
++ AIROHA_PCS_PMA_DISB_EYE_TOP_EN);
++
++ regmap_clear_bits(priv->xfi_pma, AIROHA_PCS_PMA_RX_FORCE_MODE_9,
++ AIROHA_PCS_PMA_FORCE_EYE_TOP_EN);
++
++ /* Reset PICal Rdy */
++ regmap_clear_bits(priv->xfi_pma, AIROHA_PCS_PMA_RX_DISB_MODE_3,
++ AIROHA_PCS_PMA_DISB_RQ_PI_CAL_RDY);
++
++ regmap_clear_bits(priv->xfi_pma, AIROHA_PCS_PMA_RX_FORCE_MODE_3,
++ AIROHA_PCS_PMA_FORCE_EQ_PI_CAL_RDY);
++
++ /* Reset Eyecnt Rdy */
++ regmap_clear_bits(priv->xfi_pma, AIROHA_PCS_PMA_RX_DISB_MODE_5,
++ AIROHA_PCS_PMA_DISB_EYECNT_RDY);
++
++ regmap_clear_bits(priv->xfi_pma, AIROHA_PCS_PMA_RX_FORCE_MODE_6,
++ AIROHA_PCS_PMA_FORCE_EYECNT_RDY);
++}
++
++static void an7583_pcs_common_phya_eo_scan(struct airoha_pcs_priv *priv,
++ phy_interface_t interface)
++{
++
++ u32 best_heo = 0, best_veo = 0;
++ u32 leq_gain, best_leq_gain;
++ u32 best_leq_peacking = 0;
++
++ switch (interface) {
++ case PHY_INTERFACE_MODE_SGMII:
++ case PHY_INTERFACE_MODE_1000BASEX:
++ case PHY_INTERFACE_MODE_2500BASEX:
++ case PHY_INTERFACE_MODE_5GBASER:
++ leq_gain = 3;
++ break;
++ case PHY_INTERFACE_MODE_10GBASER:
++ case PHY_INTERFACE_MODE_USXGMII:
++ leq_gain = 1;
++ break;
++ default:
++ return;
++ }
++
++ best_leq_gain = leq_gain;
++
++ regmap_set_bits(priv->xfi_pma, AIROHA_PCS_PMA_PXP_CDR_PR_PIEYE_PWDB,
++ AIROHA_PCS_PMA_FORCE_SEL_DA_CDR_PR_PIEYE_PWDB |
++ AIROHA_PCS_PMA_FORCE_DA_CDR_PR_PIEYE_PWDB);
++
++ an7583_pcs_common_phya_eye_setting(priv, interface);
++
++ /* EYE Open */
++ regmap_update_bits(priv->xfi_pma, AIROHA_PCS_PMA_PHY_EQ_CTRL_0,
++ AIROHA_PCS_PMA_EQ_EN_DELAY,
++ FIELD_PREP(AIROHA_PCS_PMA_EQ_EN_DELAY, 0x80));
++
++ regmap_update_bits(priv->xfi_pma, AIROHA_PCS_PMA_RX_PI_CAL,
++ AIROHA_PCS_PMA_KPGAIN,
++ FIELD_PREP(AIROHA_PCS_PMA_KPGAIN, 0x4));
++
++ for (; leq_gain <= FIELD_MAX(AIROHA_PCS_PMA_FORCE_DA_RX_FE_GAIN_CTRL); leq_gain++) {
++ u32 leq_peaking;
++ u32 heo, veo;
++
++ regmap_update_bits(priv->xfi_pma, AIROHA_PCS_PMA_PXP_FE_GAIN_CTRL,
++ AIROHA_PCS_PMA_FORCE_SEL_DA_RX_FE_GAIN_CTRL |
++ AIROHA_PCS_PMA_FORCE_DA_RX_FE_GAIN_CTRL,
++ AIROHA_PCS_PMA_FORCE_SEL_DA_RX_FE_GAIN_CTRL |
++ FIELD_PREP(AIROHA_PCS_PMA_FORCE_DA_RX_FE_GAIN_CTRL, leq_gain));
++
++ for (leq_peaking = 0; leq_peaking <= FIELD_MAX(AIROHA_PCS_PMA_FORCE_DA_RX_FE_PEAKING_CTRL); leq_peaking++) {
++ regmap_update_bits(priv->xfi_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,
++ AIROHA_PCS_PMA_FORCE_SEL_DA_RX_FE_PEAKING_CTRL |
++ FIELD_PREP(AIROHA_PCS_PMA_FORCE_DA_RX_FE_PEAKING_CTRL, leq_peaking));
++
++ usleep_range(500, 700);
++
++ an7583_pcs_common_phya_eye_cal(priv);
++ an7583_pcs_common_phya_eye_eo(priv, interface, &heo, &veo);
++
++ if (veo > 53 && best_veo > 53) {
++ if (heo > best_heo) {
++ best_heo = heo;
++ best_veo = veo;
++ best_leq_peacking = leq_peaking;
++ best_leq_gain = leq_gain;
++ } else if (heo == best_heo && veo > best_veo) {
++ best_heo = heo;
++ best_veo = veo;
++ best_leq_peacking = leq_peaking;
++ best_leq_gain = leq_gain;
++ }
++ } else {
++ if (veo > best_veo) {
++ best_heo = heo;
++ best_veo = veo;
++ best_leq_peacking = leq_peaking;
++ best_leq_gain = leq_gain;
++ }
++ }
++ }
++ }
++
++ regmap_update_bits(priv->xfi_pma, AIROHA_PCS_PMA_PXP_FE_GAIN_CTRL,
++ AIROHA_PCS_PMA_FORCE_DA_RX_FE_GAIN_CTRL,
++ FIELD_PREP(AIROHA_PCS_PMA_FORCE_DA_RX_FE_GAIN_CTRL, best_leq_gain));
++
++ regmap_update_bits(priv->xfi_pma, AIROHA_PCS_PMA_PXP_JCPLL_SDM_SCAN,
++ AIROHA_PCS_PMA_FORCE_DA_RX_FE_PEAKING_CTRL,
++ FIELD_PREP(AIROHA_PCS_PMA_FORCE_DA_RX_FE_PEAKING_CTRL, best_leq_peacking));
++}
++
++static void an7583_pcs_common_phya_rxrdy(struct airoha_pcs_priv *priv)
++{
++ u32 xfi_rx_term_sel = 0x1;
++ // int efuse_valid;
++
++ regmap_set_bits(priv->xfi_pma, AIROHA_PCS_PMA_RX_CTRL_SEQUENCE_FORCE_CTRL_1,
++ AIROHA_PCS_PMA_FORCE_RX_RDY);
++ regmap_clear_bits(priv->xfi_pma, AIROHA_PCS_PMA_RX_CTRL_SEQUENCE_DISB_CTRL_1,
++ AIROHA_PCS_PMA_DISB_RX_RDY);
++
++ regmap_clear_bits(priv->xfi_pma, AIROHA_PCS_PMA_SW_RST_SET,
++ AIROHA_PCS_PMA_SW_RX_FIFO_RST_N);
++ regmap_set_bits(priv->xfi_pma, AIROHA_PCS_PMA_SW_RST_SET,
++ AIROHA_PCS_PMA_SW_RX_FIFO_RST_N);
++
++ /* TODO HANDLE EFUSE */
++ regmap_update_bits(priv->xfi_ana, AIROHA_PCS_ANA_PXP_RX_SIGDET_NOVTH,
++ AIROHA_PCS_ANA_RX_FE_50OHMS_SEL,
++ FIELD_PREP(AIROHA_PCS_ANA_RX_FE_50OHMS_SEL,
++ xfi_rx_term_sel));
++}
++
++static void an7583_pcs_common_phya_bist_setting(struct airoha_pcs_priv *priv)
++{
++ regmap_write(priv->xfi_pma, AIROHA_PCS_PMA_BISTCTL_ALIGN_PAT,
++ 0x8ff1fd53);
++ regmap_write(priv->xfi_pma, AIROHA_PCS_PMA_BISTCTL_PRBS_INITIAL_SEED,
++ 0xFF1FD53);
++ regmap_update_bits(priv->xfi_pma, AIROHA_PCS_PMA_BISTCTL_PRBS_FAIL_THRESHOLD,
++ AIROHA_PCS_PMA_BISTCTL_PRBS_FAIL_THRESHOLD_MASK,
++ FIELD_PREP(AIROHA_PCS_PMA_BISTCTL_PRBS_FAIL_THRESHOLD_MASK, 0x1));
++
++ regmap_update_bits(priv->xfi_pma, AIROHA_PCS_PMA_BISTCTL_CONTROL,
++ AIROHA_PCS_PMA_BISTCTL_PAT_SEL,
++ AIROHA_PCS_PMA_BISTCTL_PAT_SEL_PRBS31);
++
++ regmap_set_bits(priv->xfi_pma, AIROHA_PCS_PMA_BISTCTL_POLLUTION,
++ AIROHA_PCS_PMA_BIST_TX_DATA_POLLUTION_LATCH);
++
++ regmap_clear_bits(priv->xfi_pma, AIROHA_PCS_PMA_SS_BIST_1,
++ AIROHA_PCS_PMA_LNX_BISTCTL_BIT_ERROR_RST_SEL |
++ AIROHA_PCS_PMA_ANLT_PX_LNX_LT_LOS);
++}
++
++static void an7583_pcs_first_plug_in(struct airoha_pcs_priv *priv,
++ phy_interface_t interface)
++{
++ const struct airoha_pcs_match_data *data = priv->data;
++
++ an7583_pcs_common_phya_rx_preset(priv, interface);
++ if (data->port_type == AIROHA_PCS_PON)
++ an7583_pcs_common_phya_tdc_off(priv);
++ an7583_pcs_common_phya_rx_on(priv);
++ an7583_pcs_common_phya_l2d(priv);
++
++ regmap_set_bits(priv->xfi_pma, AIROHA_PCS_PMA_SW_RST_SET,
++ AIROHA_PCS_PMA_SW_REF_RST_N);
++
++ an7583_pcs_common_phya_rx_oscal(priv);
++ an7583_pcs_common_phya_pical(priv);
++ an7583_pcs_common_phya_pdos(priv);
++ an7583_pcs_common_phya_feos(priv);
++ an7583_pcs_common_phya_sdcal(priv);
++ an7583_pcs_common_phya_phy_status(priv);
++
++ an7583_pcs_dig_reset_release(priv);
++
++ an7583_pcs_common_phya_l2d(priv);
++
++ if (data->port_type == AIROHA_PCS_PON)
++ an7583_pcs_common_phya_eo_scan(priv, interface);
++ an7583_pcs_common_phya_rxrdy(priv);
++ if (data->port_type == AIROHA_PCS_PON)
++ an7583_pcs_common_phya_bist_setting(priv);
++
++ regmap_clear_bits(priv->xfi_pma, AIROHA_PCS_PMA_ADD_XPON_MODE_1,
++ AIROHA_PCS_PMA_TX_BIST_GEN_EN |
++ AIROHA_PCS_PMA_R2T_MODE);
++}
++
++static void an7583_pcs_ana_reset_release(struct airoha_pcs_priv *priv)
++{
++ regmap_set_bits(priv->xfi_pma, AIROHA_PCS_PMA_SW_RST_SET,
++ AIROHA_PCS_PMA_SW_XFI_RXPCS_RST_N |
++ AIROHA_PCS_PMA_SW_XFI_TXPCS_RST_N);
++
++ regmap_set_bits(priv->xfi_pma, AIROHA_PCS_PMA_SW_RST_SET,
++ AIROHA_PCS_PMA_SW_XFI_RXPCS_BIST_RST_N);
++
++ regmap_set_bits(priv->xfi_pma, AIROHA_PCS_PMA_SW_RST_SET,
++ AIROHA_PCS_PMA_SW_HSG_RXPCS_RST_N |
++ AIROHA_PCS_PMA_SW_HSG_TXPCS_RST_N);
++
++ regmap_set_bits(priv->xfi_pma, AIROHA_PCS_PMA_SW_RST_SET,
++ AIROHA_PCS_PMA_SW_XFI_RXMAC_RST_N |
++ AIROHA_PCS_PMA_SW_XFI_TXMAC_RST_N);
++}
++
++int an7583_pcs_common_phya_bringup(struct airoha_pcs_priv *priv,
++ phy_interface_t interface)
++{
++ an7583_pcs_dig_reset_hold(priv);
++
++ an7583_pcs_cfg_phy_type(priv, interface);
++
++ an7583_pcs_common_phya_txpll_on(priv);
++
++ an7583_pcs_common_phya_tx_on(priv);
++
++ an7583_pcs_first_plug_in(priv, interface);
++
++ an7583_pcs_ana_reset_release(priv);
++
++ return 0;
++}
++
++void an7583_pcs_common_phya_link_up(struct airoha_pcs_priv *priv)
++{
++ /* First CDR reset */
++ regmap_update_bits(priv->xfi_pma, AIROHA_PCS_PMA_PXP_CDR_LPF_LCK_2DATA,
++ AIROHA_PCS_PMA_FORCE_SEL_DA_CDR_LPF_LCK2DATA |
++ AIROHA_PCS_PMA_FORCE_DA_CDR_LPF_LCK2DATA,
++ AIROHA_PCS_PMA_FORCE_SEL_DA_CDR_LPF_LCK2DATA);
++
++ regmap_update_bits(priv->xfi_pma, AIROHA_PCS_PMA_PXP_CDR_LPF_LCK_2DATA,
++ AIROHA_PCS_PMA_FORCE_SEL_DA_CDR_LPF_RSTB |
++ AIROHA_PCS_PMA_FORCE_DA_CDR_LPF_RSTB,
++ AIROHA_PCS_PMA_FORCE_SEL_DA_CDR_LPF_RSTB);
++
++ usleep_range(700, 1000);
++
++ regmap_update_bits(priv->xfi_pma, AIROHA_PCS_PMA_PXP_CDR_LPF_LCK_2DATA,
++ AIROHA_PCS_PMA_FORCE_SEL_DA_CDR_LPF_RSTB |
++ AIROHA_PCS_PMA_FORCE_DA_CDR_LPF_RSTB,
++ AIROHA_PCS_PMA_FORCE_SEL_DA_CDR_LPF_RSTB |
++ AIROHA_PCS_PMA_FORCE_DA_CDR_LPF_RSTB);
++
++ usleep_range(100, 200);
++
++ regmap_update_bits(priv->xfi_pma, AIROHA_PCS_PMA_PXP_CDR_LPF_LCK_2DATA,
++ AIROHA_PCS_PMA_FORCE_SEL_DA_CDR_LPF_LCK2DATA |
++ AIROHA_PCS_PMA_FORCE_DA_CDR_LPF_LCK2DATA,
++ AIROHA_PCS_PMA_FORCE_SEL_DA_CDR_LPF_LCK2DATA |
++ AIROHA_PCS_PMA_FORCE_DA_CDR_LPF_LCK2DATA);
++
++ regmap_update_bits(priv->xfi_pma, AIROHA_PCS_PMA_PXP_CDR_LPF_LCK_2DATA,
++ AIROHA_PCS_PMA_FORCE_SEL_DA_CDR_LPF_RSTB |
++ AIROHA_PCS_PMA_FORCE_DA_CDR_LPF_RSTB,
++ AIROHA_PCS_PMA_FORCE_DA_CDR_LPF_RSTB);
++
++ regmap_update_bits(priv->xfi_pma, AIROHA_PCS_PMA_PXP_CDR_LPF_LCK_2DATA,
++ AIROHA_PCS_PMA_FORCE_SEL_DA_CDR_LPF_LCK2DATA |
++ AIROHA_PCS_PMA_FORCE_DA_CDR_LPF_LCK2DATA,
++ AIROHA_PCS_PMA_FORCE_DA_CDR_LPF_LCK2DATA);
++
++ /* Then RX Rdy reset */
++ regmap_set_bits(priv->xfi_pma, AIROHA_PCS_PMA_RX_CTRL_SEQUENCE_DISB_CTRL_1,
++ AIROHA_PCS_PMA_DISB_RX_RDY);
++
++ regmap_clear_bits(priv->xfi_pma, AIROHA_PCS_PMA_RX_CTRL_SEQUENCE_FORCE_CTRL_1,
++ AIROHA_PCS_PMA_DISB_RX_RDY);
++}
--- /dev/null
+From 6548e580509397a622b7c504a79de93414771459 Mon Sep 17 00:00:00 2001
+From: Christian Marangi <ansuelsmth@gmail.com>
+Date: Wed, 25 Jun 2025 00:04:36 +0200
+Subject: [PATCH 6/6] net: ethernet: airoha: define sport value for GDM3
+
+On Airoha AN7583, the Serdes Ethernet goes through the GDM3 port.
+To correctly receive packet for QDMA, add the sport value to identify
+packet from GDM3 port.
+
+Signed-off-by: Christian Marangi <ansuelsmth@gmail.com>
+---
+ drivers/net/ethernet/airoha/airoha_eth.c | 3 +++
+ 1 file changed, 3 insertions(+)
+
+--- a/drivers/net/ethernet/airoha/airoha_eth.c
++++ b/drivers/net/ethernet/airoha/airoha_eth.c
+@@ -616,6 +616,9 @@ static int airoha_qdma_get_gdm_port(stru
+ case 0x18:
+ port = 3; /* GDM4 */
+ break;
++ case 0x16:
++ port = 2; /* GDM3 */
++ break;
+ case 0x10 ... 0x14:
+ port = 0; /* GDM1 */
+ break;
--- /dev/null
+From 961800f3badd72e4efda39f219ac4cbec5791433 Mon Sep 17 00:00:00 2001
+From: Christian Marangi <ansuelsmth@gmail.com>
+Date: Sat, 26 Jul 2025 22:58:10 +0200
+Subject: [PATCH 7/8] net: pcs: airoha: add support for optional xfi reset line
+
+On Airoha AN7583 there is a dedicated reset line for the PON XFI Serdes.
+This is needed to permit changing the WAN sel register or the system
+will stall on accessing the XFI register.
+
+Add support for this optional dedicated reset to permit correct
+configuration of the PON Serdes.
+
+Signed-off-by: Christian Marangi <ansuelsmth@gmail.com>
+---
+ drivers/net/pcs/airoha/pcs-airoha-common.c | 12 ++++++++++++
+ drivers/net/pcs/airoha/pcs-airoha.h | 1 +
+ 2 files changed, 13 insertions(+)
+
+--- a/drivers/net/pcs/airoha/pcs-airoha-common.c
++++ b/drivers/net/pcs/airoha/pcs-airoha-common.c
+@@ -82,6 +82,10 @@ static int airoha_pcs_setup_scu(struct a
+ const struct airoha_pcs_match_data *data = priv->data;
+ int ret;
+
++ ret = reset_control_assert(priv->xfi_rst);
++ if (ret)
++ return ret;
++
+ switch (data->port_type) {
+ case AIROHA_PCS_ETH:
+ airoha_pcs_setup_scu_eth(priv, interface);
+@@ -91,6 +95,10 @@ static int airoha_pcs_setup_scu(struct a
+ break;
+ }
+
++ ret = reset_control_deassert(priv->xfi_rst);
++ if (ret)
++ return ret;
++
+ /* TODO better handle reset from MAC */
+ ret = reset_control_bulk_assert(ARRAY_SIZE(priv->rsts),
+ priv->rsts);
+@@ -1003,6 +1011,10 @@ static int airoha_pcs_probe(struct platf
+ if (ret)
+ return dev_err_probe(dev, ret, "failed to get bulk reset lines\n");
+
++ priv->xfi_rst = devm_reset_control_get_optional_exclusive(dev, "xfi");
++ if (IS_ERR(priv->xfi_rst))
++ return dev_err_probe(dev, PTR_ERR(priv->xfi_rst), "failed to get xfi 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.
+--- a/drivers/net/pcs/airoha/pcs-airoha.h
++++ b/drivers/net/pcs/airoha/pcs-airoha.h
+@@ -1184,6 +1184,7 @@ struct airoha_pcs_priv {
+ struct regmap *xfi_pma;
+ struct regmap *xfi_ana;
+
++ struct reset_control *xfi_rst;
+ struct reset_control_bulk_data rsts[AIROHA_PCS_MAX_NUM_RSTS];
+
+ bool manual_rx_calib;