diff --git a/target/linux/airoha/Makefile b/target/linux/airoha/Makefile index 7e64485ae1..970a3398f9 100644 --- a/target/linux/airoha/Makefile +++ b/target/linux/airoha/Makefile @@ -3,7 +3,7 @@ include $(TOPDIR)/rules.mk ARCH:=arm BOARD:=airoha BOARDNAME:=Airoha ARM -SUBTARGETS:=en7523 an7581 +SUBTARGETS:=en7523 an7581 an7583 FEATURES:=dt squashfs nand ramdisk gpio KERNEL_PATCHVER:=6.12 diff --git a/target/linux/airoha/an7581/config-6.12 b/target/linux/airoha/an7581/config-6.12 index 6899f3251a..e5b9281145 100644 --- a/target/linux/airoha/an7581/config-6.12 +++ b/target/linux/airoha/an7581/config-6.12 @@ -213,6 +213,7 @@ CONFIG_LZO_COMPRESS=y 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 @@ -289,6 +290,7 @@ CONFIG_PCI_DOMAINS=y 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 diff --git a/target/linux/airoha/an7583/base-files/etc/board.d/02_network b/target/linux/airoha/an7583/base-files/etc/board.d/02_network new file mode 100644 index 0000000000..077d193ed5 --- /dev/null +++ b/target/linux/airoha/an7583/base-files/etc/board.d/02_network @@ -0,0 +1,28 @@ +# +# 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 diff --git a/target/linux/airoha/an7583/config-6.12 b/target/linux/airoha/an7583/config-6.12 new file mode 100644 index 0000000000..b95bfa67c6 --- /dev/null +++ b/target/linux/airoha/an7583/config-6.12 @@ -0,0 +1,402 @@ +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 diff --git a/target/linux/airoha/an7583/target.mk b/target/linux/airoha/an7583/target.mk new file mode 100644 index 0000000000..dacbe0928e --- /dev/null +++ b/target/linux/airoha/an7583/target.mk @@ -0,0 +1,11 @@ +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 + diff --git a/target/linux/airoha/dts/an7583-evb.dts b/target/linux/airoha/dts/an7583-evb.dts new file mode 100644 index 0000000000..fdd5b2aa92 --- /dev/null +++ b/target/linux/airoha/dts/an7583-evb.dts @@ -0,0 +1,215 @@ +// SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) +/dts-v1/; + +#include +#include +#include +#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 = ; + function = LED_FUNCTION_LAN; + function-enumerator = <0>; + default-state = "keep"; + }; + + led@1 { + reg = <1>; + color = ; + 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 = ; + function = LED_FUNCTION_LAN; + function-enumerator = <0>; + default-state = "keep"; + }; + + led@1 { + reg = <1>; + color = ; + 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"; +}; diff --git a/target/linux/airoha/dts/an7583.dtsi b/target/linux/airoha/dts/an7583.dtsi new file mode 100644 index 0000000000..43e60ebf66 --- /dev/null +++ b/target/linux/airoha/dts/an7583.dtsi @@ -0,0 +1,818 @@ +// SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) + +#include +#include +#include +#include +#include +#include +#include + +/ { + 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 = , + , + , + ; + }; + + 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 = ; + }; + + 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 = ; + + 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 = ; + 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 = ; + 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 = ; + 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 = ; + 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 = ; + 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 = ; + clock-frequency = <7372800>; + + status = "disabled"; + }; + + crypto@1e004000 { + compatible = "inside-secure,safexcel-eip93ies"; + reg = <0x0 0x1fb70000 0x0 0x1000>; + + interrupts = ; + }; + + 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 = , + , + , + , + , + , + , + , + , + ; + + 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 = ; + + 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"; + }; + }; + }; + }; + }; + }; +}; diff --git a/target/linux/airoha/image/an7583.mk b/target/linux/airoha/image/an7583.mk new file mode 100644 index 0000000000..6ebec7af1b --- /dev/null +++ b/target/linux/airoha/image/an7583.mk @@ -0,0 +1,55 @@ +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 diff --git a/target/linux/airoha/patches-6.12/090-v6.17-net-mdio-Add-MDIO-bus-controller-for-Airoha-AN7583.patch b/target/linux/airoha/patches-6.12/090-v6.17-net-mdio-Add-MDIO-bus-controller-for-Airoha-AN7583.patch new file mode 100644 index 0000000000..37b0ed5c78 --- /dev/null +++ b/target/linux/airoha/patches-6.12/090-v6.17-net-mdio-Add-MDIO-bus-controller-for-Airoha-AN7583.patch @@ -0,0 +1,342 @@ +From 67e3ba978361cb262f8f8981ab88ccb97f1e2bda Mon Sep 17 00:00:00 2001 +From: Christian Marangi +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 +Reviewed-by: Andrew Lunn +Signed-off-by: David S. Miller +--- + 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 ++ */ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++/* 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 "); ++MODULE_LICENSE("GPL"); diff --git a/target/linux/airoha/patches-6.12/120-02-pinctrl-mediatek-airoha-generalize-pins-group-functi.patch b/target/linux/airoha/patches-6.12/120-02-pinctrl-mediatek-airoha-generalize-pins-group-functi.patch new file mode 100644 index 0000000000..61989bc00b --- /dev/null +++ b/target/linux/airoha/patches-6.12/120-02-pinctrl-mediatek-airoha-generalize-pins-group-functi.patch @@ -0,0 +1,779 @@ +From e77c958d8eab1c29008ab57a2be82daefe886e0a Mon Sep 17 00:00:00 2001 +From: Christian Marangi +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 +--- + 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); diff --git a/target/linux/airoha/patches-6.12/120-03-pinctrl-airoha-convert-PHY-LED-GPIO-to-macro.patch b/target/linux/airoha/patches-6.12/120-03-pinctrl-airoha-convert-PHY-LED-GPIO-to-macro.patch new file mode 100644 index 0000000000..df1d96699e --- /dev/null +++ b/target/linux/airoha/patches-6.12/120-03-pinctrl-airoha-convert-PHY-LED-GPIO-to-macro.patch @@ -0,0 +1,616 @@ +From ee980d96b6ecd385691f101e641f3e15513ce8c3 Mon Sep 17 00:00:00 2001 +From: Christian Marangi +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 +--- + 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[] = { diff --git a/target/linux/airoha/patches-6.12/120-04-pinctrl-airoha-convert-PWM-GPIO-to-macro.patch b/target/linux/airoha/patches-6.12/120-04-pinctrl-airoha-convert-PWM-GPIO-to-macro.patch new file mode 100644 index 0000000000..e541cdd610 --- /dev/null +++ b/target/linux/airoha/patches-6.12/120-04-pinctrl-airoha-convert-PWM-GPIO-to-macro.patch @@ -0,0 +1,491 @@ +From 83c79d127c610063e1b86c3f7f8d5e0145ffe9c6 Mon Sep 17 00:00:00 2001 +From: Christian Marangi +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 +--- + 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) \ diff --git a/target/linux/airoha/patches-6.12/120-05-pinctrl-airoha-add-support-for-Airoha-AN7583-PINs.patch b/target/linux/airoha/patches-6.12/120-05-pinctrl-airoha-add-support-for-Airoha-AN7583-PINs.patch new file mode 100644 index 0000000000..37d3b29f2d --- /dev/null +++ b/target/linux/airoha/patches-6.12/120-05-pinctrl-airoha-add-support-for-Airoha-AN7583-PINs.patch @@ -0,0 +1,919 @@ +From cc92581b44cc3a6821c540ddbe27d4c009a7d312 Mon Sep 17 00:00:00 2001 +From: Christian Marangi +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 +--- + 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); diff --git a/target/linux/airoha/patches-6.12/401-02-net-dsa-mt7530-Add-AN7583-support.patch b/target/linux/airoha/patches-6.12/401-02-net-dsa-mt7530-Add-AN7583-support.patch new file mode 100644 index 0000000000..0d72a59ad9 --- /dev/null +++ b/target/linux/airoha/patches-6.12/401-02-net-dsa-mt7530-Add-AN7583-support.patch @@ -0,0 +1,140 @@ +From 7e112e51d48db09739dd73c90411fc8a5635747f Mon Sep 17 00:00:00 2001 +From: Christian Marangi +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 +--- + 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 diff --git a/target/linux/airoha/patches-6.12/402-01-thermal-airoha-convert-to-regmap-API.patch b/target/linux/airoha/patches-6.12/402-01-thermal-airoha-convert-to-regmap-API.patch new file mode 100644 index 0000000000..9414bef9cb --- /dev/null +++ b/target/linux/airoha/patches-6.12/402-01-thermal-airoha-convert-to-regmap-API.patch @@ -0,0 +1,194 @@ +From 7d55e75edc87022a4c1820588f70a80cebb13c5f Mon Sep 17 00:00:00 2001 +From: Christian Marangi +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 +--- + 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; + } diff --git a/target/linux/airoha/patches-6.12/402-02-thermal-drivers-airoha-Generalize-probe-function.patch b/target/linux/airoha/patches-6.12/402-02-thermal-drivers-airoha-Generalize-probe-function.patch new file mode 100644 index 0000000000..b306b2308b --- /dev/null +++ b/target/linux/airoha/patches-6.12/402-02-thermal-drivers-airoha-Generalize-probe-function.patch @@ -0,0 +1,226 @@ +From 6c0f01b16687dc582f0470a5d5b20084fb3a290f Mon Sep 17 00:00:00 2001 +From: Christian Marangi +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 +--- + 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); diff --git a/target/linux/airoha/patches-6.12/402-03-thermal-drivers-airoha-generalize-get_thermal_ADC-an.patch b/target/linux/airoha/patches-6.12/402-03-thermal-drivers-airoha-generalize-get_thermal_ADC-an.patch new file mode 100644 index 0000000000..5f6ae2c08a --- /dev/null +++ b/target/linux/airoha/patches-6.12/402-03-thermal-drivers-airoha-generalize-get_thermal_ADC-an.patch @@ -0,0 +1,129 @@ +From 1e623852d07759c3c076505193bd7f0bd3486774 Mon Sep 17 00:00:00 2001 +From: Christian Marangi +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 +--- + 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); + diff --git a/target/linux/airoha/patches-6.12/402-05-thermal-drivers-airoha-Add-support-for-AN7583.patch b/target/linux/airoha/patches-6.12/402-05-thermal-drivers-airoha-Add-support-for-AN7583.patch new file mode 100644 index 0000000000..51332350ef --- /dev/null +++ b/target/linux/airoha/patches-6.12/402-05-thermal-drivers-airoha-Add-support-for-AN7583.patch @@ -0,0 +1,277 @@ +From 5891a9e5fbdf9a305b5f81e2625455efb2a886f0 Mon Sep 17 00:00:00 2001 +From: Christian Marangi +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 +--- + 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); diff --git a/target/linux/airoha/patches-6.12/403-cpufreq-airoha-Add-support-for-AN7583-SoC.patch b/target/linux/airoha/patches-6.12/403-cpufreq-airoha-Add-support-for-AN7583-SoC.patch new file mode 100644 index 0000000000..3c076b4173 --- /dev/null +++ b/target/linux/airoha/patches-6.12/403-cpufreq-airoha-Add-support-for-AN7583-SoC.patch @@ -0,0 +1,35 @@ +From 8a38220c6bf6d79ecb1c95b083e062bd7221dea9 Mon Sep 17 00:00:00 2001 +From: Christian Marangi +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 +--- + 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", }, diff --git a/target/linux/airoha/patches-6.12/600-01-clk-en7523-convert-driver-to-regmap-API.patch b/target/linux/airoha/patches-6.12/600-01-clk-en7523-convert-driver-to-regmap-API.patch new file mode 100644 index 0000000000..85bd2c214e --- /dev/null +++ b/target/linux/airoha/patches-6.12/600-01-clk-en7523-convert-driver-to-regmap-API.patch @@ -0,0 +1,351 @@ +From 8d5a00b3b83f76d255bcffc91d5263f72b27547a Mon Sep 17 00:00:00 2001 +From: Christian Marangi +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 +--- + 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 + #include + #include + #include +@@ -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) diff --git a/target/linux/airoha/patches-6.12/600-02-clk-en7523-generalize-register-clocks-function.patch b/target/linux/airoha/patches-6.12/600-02-clk-en7523-generalize-register-clocks-function.patch new file mode 100644 index 0000000000..b8d892ffb4 --- /dev/null +++ b/target/linux/airoha/patches-6.12/600-02-clk-en7523-generalize-register-clocks-function.patch @@ -0,0 +1,258 @@ +From 36a3a919391dea2000f355125f0a161c453fcf78 Mon Sep 17 00:00:00 2001 +From: Christian Marangi +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 +--- + 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 = { diff --git a/target/linux/airoha/patches-6.12/600-03-clk-en7523-convert-to-full-clk_hw-implementation.patch b/target/linux/airoha/patches-6.12/600-03-clk-en7523-convert-to-full-clk_hw-implementation.patch new file mode 100644 index 0000000000..31b5bce636 --- /dev/null +++ b/target/linux/airoha/patches-6.12/600-03-clk-en7523-convert-to-full-clk_hw-implementation.patch @@ -0,0 +1,147 @@ +From 933030fd268ac111eb9db13b5a90b7c66cd9df41 Mon Sep 17 00:00:00 2001 +From: Christian Marangi +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 +--- + 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); diff --git a/target/linux/airoha/patches-6.12/600-04-clk-en7523-add-support-for-.set_rate.patch b/target/linux/airoha/patches-6.12/600-04-clk-en7523-add-support-for-.set_rate.patch new file mode 100644 index 0000000000..fc2656aeb7 --- /dev/null +++ b/target/linux/airoha/patches-6.12/600-04-clk-en7523-add-support-for-.set_rate.patch @@ -0,0 +1,173 @@ +From fe71e8f734a5c9b808a68b8abaa0156de605df4f Mon Sep 17 00:00:00 2001 +From: Christian Marangi +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 +--- + 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, diff --git a/target/linux/airoha/patches-6.12/600-05-clk-en7523-permit-to-reference-Chip-SCU-from-phandle.patch b/target/linux/airoha/patches-6.12/600-05-clk-en7523-permit-to-reference-Chip-SCU-from-phandle.patch new file mode 100644 index 0000000000..059d8083cf --- /dev/null +++ b/target/linux/airoha/patches-6.12/600-05-clk-en7523-permit-to-reference-Chip-SCU-from-phandle.patch @@ -0,0 +1,37 @@ +From 397a132fb8173a9d728bc7c7a31ff5c0590d076f Mon Sep 17 00:00:00 2001 +From: Christian Marangi +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 +--- + 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); + diff --git a/target/linux/airoha/patches-6.12/600-07-clk-en7523-reword-and-clean-clk_probe-variables.patch b/target/linux/airoha/patches-6.12/600-07-clk-en7523-reword-and-clean-clk_probe-variables.patch new file mode 100644 index 0000000000..5de1768f1d --- /dev/null +++ b/target/linux/airoha/patches-6.12/600-07-clk-en7523-reword-and-clean-clk_probe-variables.patch @@ -0,0 +1,53 @@ +From d05fc5c8a9ab7bbda80e4fc728902f8d48d3e8aa Mon Sep 17 00:00:00 2001 +From: Christian Marangi +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 +--- + 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 = { diff --git a/target/linux/airoha/patches-6.12/600-08-clk-en7523-add-support-for-probing-SCU-child.patch b/target/linux/airoha/patches-6.12/600-08-clk-en7523-add-support-for-probing-SCU-child.patch new file mode 100644 index 0000000000..4d57996a07 --- /dev/null +++ b/target/linux/airoha/patches-6.12/600-08-clk-en7523-add-support-for-probing-SCU-child.patch @@ -0,0 +1,57 @@ +From 8f1aea6f4aa61e09eb29b41ff9fffeedd5b2fc0d Mon Sep 17 00:00:00 2001 +From: Christian Marangi +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 +--- + 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 + #include + #include ++#include + #include + #include + #include +@@ -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 = { diff --git a/target/linux/airoha/patches-6.12/600-09-dt-bindings-clock-airoha-Document-support-for-AN7583.patch b/target/linux/airoha/patches-6.12/600-09-dt-bindings-clock-airoha-Document-support-for-AN7583.patch new file mode 100644 index 0000000000..7c3430bb95 --- /dev/null +++ b/target/linux/airoha/patches-6.12/600-09-dt-bindings-clock-airoha-Document-support-for-AN7583.patch @@ -0,0 +1,122 @@ +From 12838dd20851a6eae67061c5f195f31981a4d8c1 Mon Sep 17 00:00:00 2001 +From: Christian Marangi +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 +--- + .../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 ++ */ ++ ++#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_ */ diff --git a/target/linux/airoha/patches-6.12/600-10-clk-en7523-add-support-for-Airoha-AN7583-clock.patch b/target/linux/airoha/patches-6.12/600-10-clk-en7523-add-support-for-Airoha-AN7583-clock.patch new file mode 100644 index 0000000000..0a57e8a9fb --- /dev/null +++ b/target/linux/airoha/patches-6.12/600-10-clk-en7523-add-support-for-Airoha-AN7583-clock.patch @@ -0,0 +1,328 @@ +From 3c5cd99f894c23650accf19fef18b5b9bbe83941 Mon Sep 17 00:00:00 2001 +From: Christian Marangi +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 +--- + 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 + #include + #include ++#include + + #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 */ } + }; + diff --git a/target/linux/airoha/patches-6.12/604-01-net-pcs-airoha-add-support-for-AN7583.patch b/target/linux/airoha/patches-6.12/604-01-net-pcs-airoha-add-support-for-AN7583.patch new file mode 100644 index 0000000000..6f0b3c9622 --- /dev/null +++ b/target/linux/airoha/patches-6.12/604-01-net-pcs-airoha-add-support-for-AN7583.patch @@ -0,0 +1,3002 @@ +From 500f525a21bfc18605b23e7b39fc1d8f74393b30 Mon Sep 17 00:00:00 2001 +From: Christian Marangi +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 +--- + 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 ++ */ ++#include ++#include ++ ++#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); ++} diff --git a/target/linux/airoha/patches-6.12/604-02-net-ethernet-airoha-define-sport-value-for-GDM3.patch b/target/linux/airoha/patches-6.12/604-02-net-ethernet-airoha-define-sport-value-for-GDM3.patch new file mode 100644 index 0000000000..0fa14de3ee --- /dev/null +++ b/target/linux/airoha/patches-6.12/604-02-net-ethernet-airoha-define-sport-value-for-GDM3.patch @@ -0,0 +1,26 @@ +From 6548e580509397a622b7c504a79de93414771459 Mon Sep 17 00:00:00 2001 +From: Christian Marangi +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 +--- + 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; diff --git a/target/linux/airoha/patches-6.12/605-net-pcs-airoha-add-support-for-optional-xfi-reset-li.patch b/target/linux/airoha/patches-6.12/605-net-pcs-airoha-add-support-for-optional-xfi-reset-li.patch new file mode 100644 index 0000000000..5f48c34753 --- /dev/null +++ b/target/linux/airoha/patches-6.12/605-net-pcs-airoha-add-support-for-optional-xfi-reset-li.patch @@ -0,0 +1,63 @@ +From 961800f3badd72e4efda39f219ac4cbec5791433 Mon Sep 17 00:00:00 2001 +From: Christian Marangi +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 +--- + 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;