include $(TOPDIR)/rules.mk
include $(INCLUDE_DIR)/kernel.mk
-PKG_VERSION:=2026.01
-PKG_HASH:=b60d5865cefdbc75da8da4156c56c458e00de75a49b80c1a2e58a96e30ad0d54
+PKG_VERSION:=2026.07
+PKG_HASH:=78e8bfc382fe388f9b55aa1daf8c563522a037779b5d4c349d1415e381f1243e
PKG_BUILD_DEPENDS:=arm-trusted-firmware-tools/host
UBOOT_USE_INTREE_DTC:=1
--- /dev/null
+From abfc83fc16f570d25212c0a8a5e2694dd2383b9d Mon Sep 17 00:00:00 2001
+From: Mikhail Kshevetskiy <mikhail.kshevetskiy@iopsys.eu>
+Date: Sat, 9 May 2026 11:24:10 +0300
+Subject: [PATCH 01/29] bitops: import BITS_PER_TYPE() macro from linux
+
+This macro will be used by include/linux/bitfield.h header.
+
+Signed-off-by: Mikhail Kshevetskiy <mikhail.kshevetskiy@iopsys.eu>
+Reviewed-by: David Lechner <dlechner@baylibre.com>
+Reviewed-by: Simon Glass <sjg@chromium.org>
+---
+ include/linux/bitops.h | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/include/linux/bitops.h b/include/linux/bitops.h
+index 29e0da48de8..52eea4f8380 100644
+--- a/include/linux/bitops.h
++++ b/include/linux/bitops.h
+@@ -15,6 +15,7 @@
+ #define BIT_ULL_MASK(nr) (1ULL << ((nr) % BITS_PER_LONG_LONG))
+ #define BIT_ULL_WORD(nr) ((nr) / BITS_PER_LONG_LONG)
+ #define BITS_PER_BYTE 8
++#define BITS_PER_TYPE(type) (sizeof(type) * BITS_PER_BYTE)
+ #define BITS_TO_LONGS(nr) DIV_ROUND_UP(nr, BITS_PER_BYTE * sizeof(long))
+ #endif
+
+--
+2.53.0
+
--- /dev/null
+From fd4dadc9d17bfd624bef9f1292d31e56e99f5344 Mon Sep 17 00:00:00 2001
+From: Geert Uytterhoeven <geert+renesas@glider.be>
+Date: Thu, 6 Nov 2025 14:34:00 +0100
+Subject: [PATCH 02/29] bitfield: Add less-checking __FIELD_{GET,PREP}()
+
+The BUILD_BUG_ON_MSG() check against "~0ull" works only with "unsigned
+(long) long" _mask types. For constant masks, that condition is usually
+met, as GENMASK() yields an UL value. The few places where the
+constant mask is stored in an intermediate variable were fixed by
+changing the variable type to u64.
+
+However, for non-constant masks, smaller unsigned types should be valid,
+too, but currently lead to "result of comparison of constant
+18446744073709551615 with expression of type ... is always
+false"-warnings with clang and W=1.
+
+Hence refactor the __BF_FIELD_CHECK() helper, and factor out
+__FIELD_{GET,PREP}(). The later lack the single problematic check, but
+are otherwise identical to FIELD_{GET,PREP}(), and are intended to be
+used in the fully non-const variants later.
+
+Signed-off-by: Geert Uytterhoeven <geert+renesas@glider.be>
+Signed-off-by: Yury Norov (NVIDIA) <yury.norov@gmail.com>
+[Linux commit: 2a6c045640c38a407a39cd40c3c4d8dd2fd89aa8]
+Signed-off-by: Mikhail Kshevetskiy <mikhail.kshevetskiy@iopsys.eu>
+Reviewed-by: David Lechner <dlechner@baylibre.com>
+Reviewed-by: Simon Glass <sjg@chromium.org>
+---
+ include/linux/bitfield.h | 36 ++++++++++++++++++++++++++++--------
+ 1 file changed, 28 insertions(+), 8 deletions(-)
+
+diff --git a/include/linux/bitfield.h b/include/linux/bitfield.h
+index 63928f17322..ef81901bc41 100644
+--- a/include/linux/bitfield.h
++++ b/include/linux/bitfield.h
+@@ -60,7 +60,7 @@
+
+ #define __bf_cast_unsigned(type, x) ((__unsigned_scalar_typeof(type))(x))
+
+-#define __BF_FIELD_CHECK(_mask, _reg, _val, _pfx) \
++#define __BF_FIELD_CHECK_MASK(_mask, _val, _pfx) \
+ ({ \
+ BUILD_BUG_ON_MSG(!__builtin_constant_p(_mask), \
+ _pfx "mask is not constant"); \
+@@ -69,13 +69,33 @@
+ ~((_mask) >> __bf_shf(_mask)) & \
+ (0 + (_val)) : 0, \
+ _pfx "value too large for the field"); \
+- BUILD_BUG_ON_MSG(__bf_cast_unsigned(_mask, _mask) > \
+- __bf_cast_unsigned(_reg, ~0ull), \
+- _pfx "type of reg too small for mask"); \
+ __BUILD_BUG_ON_NOT_POWER_OF_2((_mask) + \
+ (1ULL << __bf_shf(_mask))); \
+ })
+
++#define __BF_FIELD_CHECK_REG(mask, reg, pfx) \
++ BUILD_BUG_ON_MSG(__bf_cast_unsigned(mask, mask) > \
++ __bf_cast_unsigned(reg, ~0ull), \
++ pfx "type of reg too small for mask")
++
++#define __BF_FIELD_CHECK(mask, reg, val, pfx) \
++ ({ \
++ __BF_FIELD_CHECK_MASK(mask, val, pfx); \
++ __BF_FIELD_CHECK_REG(mask, reg, pfx); \
++ })
++
++#define __FIELD_PREP(mask, val, pfx) \
++ ({ \
++ __BF_FIELD_CHECK_MASK(mask, val, pfx); \
++ ((typeof(mask))(val) << __bf_shf(mask)) & (mask); \
++ })
++
++#define __FIELD_GET(mask, reg, pfx) \
++ ({ \
++ __BF_FIELD_CHECK_MASK(mask, 0U, pfx); \
++ (typeof(mask))(((reg) & (mask)) >> __bf_shf(mask)); \
++ })
++
+ /**
+ * FIELD_MAX() - produce the maximum value representable by a field
+ * @_mask: shifted mask defining the field's length and position
+@@ -112,8 +132,8 @@
+ */
+ #define FIELD_PREP(_mask, _val) \
+ ({ \
+- __BF_FIELD_CHECK(_mask, 0ULL, _val, "FIELD_PREP: "); \
+- ((typeof(_mask))(_val) << __bf_shf(_mask)) & (_mask); \
++ __BF_FIELD_CHECK_REG(_mask, 0ULL, "FIELD_PREP: "); \
++ __FIELD_PREP(_mask, _val, "FIELD_PREP: "); \
+ })
+
+ #define __BF_CHECK_POW2(n) BUILD_BUG_ON_ZERO(((n) & ((n) - 1)) != 0)
+@@ -152,8 +172,8 @@
+ */
+ #define FIELD_GET(_mask, _reg) \
+ ({ \
+- __BF_FIELD_CHECK(_mask, _reg, 0U, "FIELD_GET: "); \
+- (typeof(_mask))(((_reg) & (_mask)) >> __bf_shf(_mask)); \
++ __BF_FIELD_CHECK_REG(_mask, _reg, "FIELD_GET: "); \
++ __FIELD_GET(_mask, _reg, "FIELD_GET: "); \
+ })
+
+ extern void __compiletime_error("value doesn't fit into mask")
+--
+2.53.0
+
--- /dev/null
+From bb8df4be357e61cd8e97d2109395e6dd4d7c51ab Mon Sep 17 00:00:00 2001
+From: Geert Uytterhoeven <geert+renesas@glider.be>
+Date: Thu, 6 Nov 2025 14:34:01 +0100
+Subject: [PATCH 03/29] bitfield: Add non-constant field_{prep,get}() helpers
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+The existing FIELD_{GET,PREP}() macros are limited to compile-time
+constants. However, it is very common to prepare or extract bitfield
+elements where the bitfield mask is not a compile-time constant.
+
+To avoid this limitation, the AT91 clock driver and several other
+drivers already have their own non-const field_{prep,get}() macros.
+Make them available for general use by adding them to
+<linux/bitfield.h>, and improve them slightly:
+ 1. Avoid evaluating macro parameters more than once,
+ 2. Replace "ffs() - 1" by "__ffs()",
+ 3. Support 64-bit use on 32-bit architectures,
+ 4. Wire field_{get,prep}() to FIELD_{GET,PREP}() when mask is
+ actually constant.
+
+This is deliberately not merged into the existing FIELD_{GET,PREP}()
+macros, as people expressed the desire to keep stricter variants for
+increased safety, or for performance critical paths.
+
+Yury: use __mask within new macros.
+
+Signed-off-by: Geert Uytterhoeven <geert+renesas@glider.be>
+Acked-by: Alexandre Belloni <alexandre.belloni@bootlin.com>
+Acked-by: Jonathan Cameron <Jonathan.Cameron@huawei.com>
+Acked-by: Crt Mori <cmo@melexis.com>
+Acked-by: Nuno Sá <nuno.sa@analog.com>
+Acked-by: Richard Genoud <richard.genoud@bootlin.com>
+Reviewed-by: Andy Shevchenko <andriy.shevchenko@intel.com>
+Reviewed-by: Yury Norov (NVIDIA) <yury.norov@gmail.com>
+Signed-off-by: Yury Norov (NVIDIA) <yury.norov@gmail.com>
+[Linux commit c1c6ab80b25c8db1e2ef5ae3ac8075d2c242ae13]
+Signed-off-by: Mikhail Kshevetskiy <mikhail.kshevetskiy@iopsys.eu>
+Reviewed-by: David Lechner <dlechner@baylibre.com>
+Reviewed-by: Simon Glass <sjg@chromium.org>
+---
+ include/linux/bitfield.h | 59 ++++++++++++++++++++++++++++++++++++++++
+ 1 file changed, 59 insertions(+)
+
+diff --git a/include/linux/bitfield.h b/include/linux/bitfield.h
+index ef81901bc41..18cf57aeb2c 100644
+--- a/include/linux/bitfield.h
++++ b/include/linux/bitfield.h
+@@ -16,6 +16,7 @@
+ * FIELD_{GET,PREP} macros take as first parameter shifted mask
+ * from which they extract the base mask and shift amount.
+ * Mask must be a compilation time constant.
++ * field_{get,prep} are variants that take a non-const mask.
+ *
+ * Example:
+ *
+@@ -223,4 +224,62 @@ __MAKE_OP(64)
+ #undef __MAKE_OP
+ #undef ____MAKE_OP
+
++#define __field_prep(mask, val) \
++ ({ \
++ __auto_type __mask = (mask); \
++ typeof(__mask) __val = (val); \
++ unsigned int __shift = BITS_PER_TYPE(__mask) <= 32 ? \
++ __ffs(__mask) : __ffs64(__mask); \
++ (__val << __shift) & __mask; \
++ })
++
++#define __field_get(mask, reg) \
++ ({ \
++ __auto_type __mask = (mask); \
++ typeof(__mask) __reg = (reg); \
++ unsigned int __shift = BITS_PER_TYPE(__mask) <= 32 ? \
++ __ffs(__mask) : __ffs64(__mask); \
++ (__reg & __mask) >> __shift; \
++ })
++
++/**
++ * field_prep() - prepare a bitfield element
++ * @mask: shifted mask defining the field's length and position, must be
++ * non-zero
++ * @val: value to put in the field
++ *
++ * Return: field value masked and shifted to its final destination
++ *
++ * field_prep() masks and shifts up the value. The result should be
++ * combined with other fields of the bitfield using logical OR.
++ * Unlike FIELD_PREP(), @mask is not limited to a compile-time constant.
++ * Typical usage patterns are a value stored in a table, or calculated by
++ * shifting a constant by a variable number of bits.
++ * If you want to ensure that @mask is a compile-time constant, please use
++ * FIELD_PREP() directly instead.
++ */
++#define field_prep(mask, val) \
++ (__builtin_constant_p(mask) ? __FIELD_PREP(mask, val, "field_prep: ") \
++ : __field_prep(mask, val))
++
++/**
++ * field_get() - extract a bitfield element
++ * @mask: shifted mask defining the field's length and position, must be
++ * non-zero
++ * @reg: value of entire bitfield
++ *
++ * Return: extracted field value
++ *
++ * field_get() extracts the field specified by @mask from the
++ * bitfield passed in as @reg by masking and shifting it down.
++ * Unlike FIELD_GET(), @mask is not limited to a compile-time constant.
++ * Typical usage patterns are a value stored in a table, or calculated by
++ * shifting a constant by a variable number of bits.
++ * If you want to ensure that @mask is a compile-time constant, please use
++ * FIELD_GET() directly instead.
++ */
++#define field_get(mask, reg) \
++ (__builtin_constant_p(mask) ? __FIELD_GET(mask, reg, "field_get: ") \
++ : __field_get(mask, reg))
++
+ #endif
+--
+2.53.0
+
--- /dev/null
+From 7fd55b7f471fc5b87a1cb3bf347d7e95b776dfc8 Mon Sep 17 00:00:00 2001
+From: Mikhail Kshevetskiy <mikhail.kshevetskiy@iopsys.eu>
+Date: Sun, 26 Apr 2026 23:18:25 +0300
+Subject: [PATCH 04/29] pinctrl: add more pinconf/pinctrl definitions
+
+These pinconf/pinctrl definitions will be used by the next patches.
+
+The definitions was taken from public headers of linux-7.0. It's used
+by several linux pinctrl drivers, so it might be helpful for U-Boot as
+well.
+
+Pinconf definitions are placed near the corresponding U-Boot definitions
+in file include/dm/pinctrl.h. Pin/group/function definitions stored within
+the same path as in linux (include/linux/pinctrl/pinctrl.h).
+
+Signed-off-by: Mikhail Kshevetskiy <mikhail.kshevetskiy@iopsys.eu>
+Reviewed-by: David Lechner <dlechner@baylibre.com>
+---
+ include/dm/pinctrl.h | 28 +++++++++++++
+ include/linux/pinctrl/pinctrl.h | 74 +++++++++++++++++++++++++++++++++
+ 2 files changed, 102 insertions(+)
+ create mode 100644 include/linux/pinctrl/pinctrl.h
+
+diff --git a/include/dm/pinctrl.h b/include/dm/pinctrl.h
+index e41baea6200..36db47802c7 100644
+--- a/include/dm/pinctrl.h
++++ b/include/dm/pinctrl.h
+@@ -481,6 +481,34 @@ enum pin_config_param {
+ PIN_CONFIG_MAX = 255, /* 0xFF */
+ };
+
++/*
++ * Helpful configuration macro to be used in tables etc.
++ */
++#define PIN_CONF_PACKED(p, a) ((a << 8) | ((unsigned long) p & 0xffUL))
++
++/*
++ * The following inlines stuffs a configuration parameter and data value
++ * into and out of an unsigned long argument, as used by the generic pin config
++ * system. We put the parameter in the lower 8 bits and the argument in the
++ * upper 24 bits.
++ */
++
++static inline enum pin_config_param pinconf_to_config_param(unsigned long config)
++{
++ return (enum pin_config_param) (config & 0xffUL);
++}
++
++static inline u32 pinconf_to_config_argument(unsigned long config)
++{
++ return (u32) ((config >> 8) & 0xffffffUL);
++}
++
++static inline unsigned long pinconf_to_config_packed(enum pin_config_param param,
++ u32 argument)
++{
++ return PIN_CONF_PACKED(param, argument);
++}
++
+ #if CONFIG_IS_ENABLED(PINCTRL_GENERIC)
+ /**
+ * pinctrl_generic_set_state() - Generic set_state operation
+diff --git a/include/linux/pinctrl/pinctrl.h b/include/linux/pinctrl/pinctrl.h
+new file mode 100644
+index 00000000000..32b56e0ab18
+--- /dev/null
++++ b/include/linux/pinctrl/pinctrl.h
+@@ -0,0 +1,74 @@
++/* SPDX-License-Identifier: GPL-2.0-only */
++
++#ifndef __LINUX_PINCTRL_PINCTRL_H
++#define __LINUX_PINCTRL_PINCTRL_H
++
++#include <linux/types.h>
++
++/**
++ * struct pingroup - provides information on pingroup
++ * @name: a name for pingroup
++ * @pins: an array of pins in the pingroup
++ * @npins: number of pins in the pingroup
++ */
++struct pingroup {
++ const char *name;
++ const unsigned int *pins;
++ size_t npins;
++};
++
++/* Convenience macro to define a single named or anonymous pingroup */
++#define PINCTRL_PINGROUP(_name, _pins, _npins) \
++(struct pingroup) { \
++ .name = _name, \
++ .pins = _pins, \
++ .npins = _npins, \
++}
++
++/**
++ * struct pinctrl_pin_desc - boards/machines provide information on their
++ * pins, pads or other muxable units in this struct
++ * @number: unique pin number from the global pin number space
++ * @name: a name for this pin
++ * @drv_data: driver-defined per-pin data. pinctrl core does not touch this
++ */
++struct pinctrl_pin_desc {
++ unsigned int number;
++ const char *name;
++ void *drv_data;
++};
++
++/* Convenience macro to define a single named or anonymous pin descriptor */
++#define PINCTRL_PIN(_number, _name) \
++(struct pinctrl_pin_desc) { \
++ .number = _number, \
++ .name = _name, \
++}
++
++#define PINCTRL_PIN_ANON(_number) \
++(struct pinctrl_pin_desc) { \
++ .number = _number, \
++}
++
++/**
++ * struct pinfunction - Description about a function
++ * @name: Name of the function
++ * @groups: An array of groups for this function
++ * @ngroups: Number of groups in @groups
++ * @flags: Additional pin function flags
++ */
++struct pinfunction {
++ const char *name;
++ const char * const *groups;
++ size_t ngroups;
++};
++
++/* Convenience macro to define a single named pinfunction */
++#define PINCTRL_PINFUNCTION(_name, _groups, _ngroups) \
++(struct pinfunction) { \
++ .name = (_name), \
++ .groups = (_groups), \
++ .ngroups = (_ngroups), \
++}
++
++#endif /* __LINUX_PINCTRL_PINCTRL_H */
+--
+2.53.0
+
--- /dev/null
+From be94e08b804ecf0e1b4d97de9faf4d6699f62ea7 Mon Sep 17 00:00:00 2001
+From: Mikhail Kshevetskiy <mikhail.kshevetskiy@iopsys.eu>
+Date: Sun, 26 Apr 2026 23:22:20 +0300
+Subject: [PATCH 05/29] pinctrl: airoha: add shared pinctrl code
+
+This patch introduce shared Airoha pinctrl code.
+Also it sorts contents of pinctrl makefile.
+
+Signed-off-by: Mikhail Kshevetskiy <mikhail.kshevetskiy@iopsys.eu>
+Reviewed-by: David Lechner <dlechner@baylibre.com>
+---
+ drivers/pinctrl/Kconfig | 1 +
+ drivers/pinctrl/Makefile | 1 +
+ drivers/pinctrl/airoha/Kconfig | 11 +
+ drivers/pinctrl/airoha/Makefile | 3 +
+ drivers/pinctrl/airoha/airoha-common.h | 144 ++++
+ drivers/pinctrl/airoha/pinctrl-airoha.c | 958 ++++++++++++++++++++++++
+ 6 files changed, 1118 insertions(+)
+ create mode 100644 drivers/pinctrl/airoha/Kconfig
+ create mode 100644 drivers/pinctrl/airoha/Makefile
+ create mode 100644 drivers/pinctrl/airoha/airoha-common.h
+ create mode 100644 drivers/pinctrl/airoha/pinctrl-airoha.c
+
+diff --git a/drivers/pinctrl/Kconfig b/drivers/pinctrl/Kconfig
+index 578edbf8168..46a95a1ab6b 100644
+--- a/drivers/pinctrl/Kconfig
++++ b/drivers/pinctrl/Kconfig
+@@ -405,6 +405,7 @@ config SPL_PINCTRL_ZYNQMP
+
+ endif
+
++source "drivers/pinctrl/airoha/Kconfig"
+ source "drivers/pinctrl/broadcom/Kconfig"
+ source "drivers/pinctrl/exynos/Kconfig"
+ source "drivers/pinctrl/intel/Kconfig"
+diff --git a/drivers/pinctrl/Makefile b/drivers/pinctrl/Makefile
+index 29fb9b484d0..22f7e841285 100644
+--- a/drivers/pinctrl/Makefile
++++ b/drivers/pinctrl/Makefile
+@@ -4,6 +4,7 @@ obj-y += pinctrl-uclass.o
+ obj-$(CONFIG_$(PHASE_)PINCTRL_GENERIC) += pinctrl-generic.o
+
+ obj-$(CONFIG_PINCTRL_ADI) += pinctrl-adi-adsp.o
++obj-$(CONFIG_PINCTRL_AIROHA) += airoha/
+ obj-$(CONFIG_PINCTRL_APPLE) += pinctrl-apple.o
+ obj-$(CONFIG_PINCTRL_AT91) += pinctrl-at91.o
+ obj-$(CONFIG_PINCTRL_AT91PIO4) += pinctrl-at91-pio4.o
+diff --git a/drivers/pinctrl/airoha/Kconfig b/drivers/pinctrl/airoha/Kconfig
+new file mode 100644
+index 00000000000..eb87afbb374
+--- /dev/null
++++ b/drivers/pinctrl/airoha/Kconfig
+@@ -0,0 +1,11 @@
++# SPDX-License-Identifier: GPL-2.0-only
++
++config PINCTRL_AIROHA
++ depends on ARCH_AIROHA
++ select PINCTRL_FULL
++ select PINCTRL_GENERIC
++ select PINMUX
++ select PINCONF
++ select REGMAP
++ select SYSCON
++ bool
+diff --git a/drivers/pinctrl/airoha/Makefile b/drivers/pinctrl/airoha/Makefile
+new file mode 100644
+index 00000000000..a25b744dd7a
+--- /dev/null
++++ b/drivers/pinctrl/airoha/Makefile
+@@ -0,0 +1,3 @@
++# SPDX-License-Identifier: GPL-2.0
++
++obj-$(CONFIG_PINCTRL_AIROHA) += pinctrl-airoha.o
+diff --git a/drivers/pinctrl/airoha/airoha-common.h b/drivers/pinctrl/airoha/airoha-common.h
+new file mode 100644
+index 00000000000..4354b0eb6b4
+--- /dev/null
++++ b/drivers/pinctrl/airoha/airoha-common.h
+@@ -0,0 +1,144 @@
++/* SPDX-License-Identifier: GPL-2.0-only */
++#ifndef __AIROHA_COMMON_HEADER__
++#define __AIROHA_COMMON_HEADER__
++
++#include <linux/types.h>
++#include <linux/bitops.h>
++#include <linux/bitfield.h>
++#include <linux/pinctrl/pinctrl.h>
++
++#include <dm/device.h>
++#include <dm/pinctrl.h>
++
++/* GPIOs */
++#define REG_GPIO_CTRL 0x0000
++#define REG_GPIO_DATA 0x0004
++#define REG_GPIO_INT 0x0008
++#define REG_GPIO_INT_EDGE 0x000c
++#define REG_GPIO_INT_LEVEL 0x0010
++#define REG_GPIO_OE 0x0014
++#define REG_GPIO_CTRL1 0x0020
++#define REG_GPIO_CTRL2 0x0060
++#define REG_GPIO_CTRL3 0x0064
++#define REG_GPIO_DATA1 0x0070
++#define REG_GPIO_OE1 0x0078
++#define REG_GPIO_INT1 0x007c
++#define REG_GPIO_INT_EDGE1 0x0080
++#define REG_GPIO_INT_EDGE2 0x0084
++#define REG_GPIO_INT_EDGE3 0x0088
++#define REG_GPIO_INT_LEVEL1 0x008c
++#define REG_GPIO_INT_LEVEL2 0x0090
++#define REG_GPIO_INT_LEVEL3 0x0094
++
++#define AIROHA_NUM_PINS 64
++#define AIROHA_PIN_BANK_SIZE (AIROHA_NUM_PINS / 2)
++#define AIROHA_REG_GPIOCTRL_NUM_PIN (AIROHA_NUM_PINS / 4)
++
++#define PINCTRL_PIN_GROUP(id, table) \
++ PINCTRL_PINGROUP(id, table##_pins, ARRAY_SIZE(table##_pins))
++
++#define PINCTRL_FUNC_DESC(id, table) \
++ { \
++ .desc = PINCTRL_PINFUNCTION(id, table##_groups, \
++ ARRAY_SIZE(table##_groups)),\
++ .groups = table##_func_group, \
++ .group_size = ARRAY_SIZE(table##_func_group), \
++ }
++
++#define PINCTRL_CONF_DESC(p, offset, mask) \
++ { \
++ .pin = p, \
++ .reg = { offset, mask }, \
++ }
++
++struct airoha_pinctrl_reg {
++ u32 offset;
++ u32 mask;
++};
++
++enum airoha_pinctrl_mux_func {
++ AIROHA_FUNC_MUX,
++ AIROHA_FUNC_PWM_MUX,
++ AIROHA_FUNC_PWM_EXT_MUX,
++};
++
++struct airoha_pinctrl_func_group {
++ const char *name;
++ struct {
++ enum airoha_pinctrl_mux_func mux;
++ u32 offset;
++ u32 mask;
++ u32 val;
++ } regmap[2];
++ int regmap_size;
++};
++
++struct airoha_pinctrl_func {
++ const struct pinfunction desc;
++ const struct airoha_pinctrl_func_group *groups;
++ u8 group_size;
++};
++
++struct airoha_pinctrl_conf {
++ u32 pin;
++ struct airoha_pinctrl_reg reg;
++};
++
++struct airoha_pinctrl_gpiochip {
++ /* gpio */
++ const u32 *data;
++ const u32 *dir;
++ const u32 *out;
++ /* irq */
++ const u32 *status;
++ const u32 *level;
++ const u32 *edge;
++
++ 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 udevice *dev;
++
++ struct regmap *chip_scu;
++ struct regmap *regmap;
++
++ struct airoha_pinctrl_match_data *data;
++
++ struct airoha_pinctrl_gpiochip gpiochip;
++};
++
++struct airoha_pinctrl_match_data {
++ const int gpio_offs;
++ const int gpio_pin_cnt;
++ const char *chip_scu_compatible;
++ 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];
++};
++
++extern const struct pinctrl_ops airoha_pinctrl_ops;
++
++int airoha_pinctrl_probe(struct udevice *dev);
++int airoha_pinctrl_bind(struct udevice *dev);
++
++#endif
+diff --git a/drivers/pinctrl/airoha/pinctrl-airoha.c b/drivers/pinctrl/airoha/pinctrl-airoha.c
+new file mode 100644
+index 00000000000..60c48c0960c
+--- /dev/null
++++ b/drivers/pinctrl/airoha/pinctrl-airoha.c
+@@ -0,0 +1,958 @@
++// SPDX-License-Identifier: GPL-2.0-only
++/*
++ * Author: Lorenzo Bianconi <lorenzo@kernel.org>
++ * Author: Benjamin Larsson <benjamin.larsson@genexis.eu>
++ * Author: Markus Gothe <markus.gothe@genexis.eu>
++ * Author: Mikhail Kshevetskiy <mikhail.kshevetskiy@iopsys.eu>
++ */
++#include <dm.h>
++#include <dm/device_compat.h>
++#include <dm/device-internal.h>
++#include <dm/lists.h>
++#include <dm/ofnode.h>
++#include <asm-generic/gpio.h>
++#include <asm/arch/scu-regmap.h>
++#include <dt-bindings/pinctrl/mt65xx.h>
++#include <regmap.h>
++#include <syscon.h>
++
++#include "airoha-common.h"
++
++#define airoha_pinctrl_get_pullup_conf(pinctrl, pin, val) \
++ 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_CONFS_PULLDOWN, \
++ (pin), (val))
++#define airoha_pinctrl_get_drive_e2_conf(pinctrl, pin, val) \
++ 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_CONFS_DRIVE_E4, \
++ (pin), (val))
++#define airoha_pinctrl_get_pcie_rst_od_conf(pinctrl, pin, val) \
++ 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_CONFS_PULLUP, \
++ (pin), (val))
++#define airoha_pinctrl_set_pulldown_conf(pinctrl, pin, val) \
++ 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_CONFS_DRIVE_E2, \
++ (pin), (val))
++#define airoha_pinctrl_set_drive_e4_conf(pinctrl, pin, val) \
++ 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_CONFS_PCIE_RST_OD, \
++ (pin), (val))
++
++static const u32 gpio_data_regs[] = {
++ REG_GPIO_DATA,
++ REG_GPIO_DATA1
++};
++
++static const u32 gpio_out_regs[] = {
++ REG_GPIO_OE,
++ REG_GPIO_OE1
++};
++
++static const u32 gpio_dir_regs[] = {
++ REG_GPIO_CTRL,
++ REG_GPIO_CTRL1,
++ REG_GPIO_CTRL2,
++ REG_GPIO_CTRL3
++};
++
++static const u32 irq_status_regs[] = {
++ REG_GPIO_INT,
++ REG_GPIO_INT1
++};
++
++static const u32 irq_level_regs[] = {
++ REG_GPIO_INT_LEVEL,
++ REG_GPIO_INT_LEVEL1,
++ REG_GPIO_INT_LEVEL2,
++ REG_GPIO_INT_LEVEL3
++};
++
++static const u32 irq_edge_regs[] = {
++ REG_GPIO_INT_EDGE,
++ REG_GPIO_INT_EDGE1,
++ REG_GPIO_INT_EDGE2,
++ REG_GPIO_INT_EDGE3
++};
++
++static int pin_in_group(unsigned int pin, const struct pingroup *grp)
++{
++ for (int i = 0; i < grp->npins; i++) {
++ if (grp->pins[i] == pin)
++ return 1;
++ }
++
++ return 0;
++}
++
++static int pin_to_gpio(struct airoha_pinctrl *pinctrl, unsigned int pin)
++{
++ struct airoha_pinctrl_match_data *data = pinctrl->data;
++
++ if (pin < data->gpio_offs ||
++ pin >= data->gpio_offs + data->gpio_pin_cnt)
++ return -EINVAL;
++
++ return pin - data->gpio_offs;
++}
++
++/* gpio callbacks */
++static int airoha_gpio_set(struct airoha_pinctrl *pinctrl, unsigned int gpio,
++ int value)
++{
++ u32 offset = gpio % AIROHA_PIN_BANK_SIZE;
++ u8 index = gpio / AIROHA_PIN_BANK_SIZE;
++
++ return regmap_update_bits(pinctrl->regmap,
++ pinctrl->gpiochip.data[index],
++ BIT(offset), value ? BIT(offset) : 0);
++}
++
++static int airoha_gpio_get(struct airoha_pinctrl *pinctrl, unsigned int gpio)
++{
++ u32 val, pin = gpio % AIROHA_PIN_BANK_SIZE;
++ u8 index = gpio / AIROHA_PIN_BANK_SIZE;
++ int err;
++
++ err = regmap_read(pinctrl->regmap,
++ pinctrl->gpiochip.data[index], &val);
++
++ return err ? err : !!(val & BIT(pin));
++}
++
++static int airoha_gpio_get_direction(struct airoha_pinctrl *pinctrl, unsigned int gpio)
++{
++ u32 mask, index, val;
++ int err, field_shift;
++
++ field_shift = 2 * (gpio % AIROHA_REG_GPIOCTRL_NUM_PIN);
++ mask = GENMASK(field_shift + 1, field_shift);
++ index = gpio / AIROHA_REG_GPIOCTRL_NUM_PIN;
++
++ err = regmap_read(pinctrl->regmap,
++ pinctrl->gpiochip.dir[index], &val);
++ if (err)
++ return err;
++
++ if ((val & mask) > BIT(field_shift))
++ return -EINVAL;
++
++ return (val & mask) ? GPIOF_OUTPUT : GPIOF_INPUT;
++}
++
++static int airoha_gpio_set_direction(struct airoha_pinctrl *pinctrl,
++ unsigned int gpio, bool input)
++{
++ u32 mask, index;
++ int err, field_shift;
++
++ /* set output enable */
++ mask = BIT(gpio % AIROHA_PIN_BANK_SIZE);
++ index = gpio / AIROHA_PIN_BANK_SIZE;
++ err = regmap_update_bits(pinctrl->regmap, pinctrl->gpiochip.out[index],
++ mask, !input ? mask : 0);
++ if (err)
++ return err;
++
++ /* set direction */
++ field_shift = 2 * (gpio % AIROHA_REG_GPIOCTRL_NUM_PIN);
++ mask = GENMASK(field_shift + 1, field_shift);
++ index = gpio / AIROHA_REG_GPIOCTRL_NUM_PIN;
++
++ return regmap_update_bits(pinctrl->regmap,
++ pinctrl->gpiochip.dir[index],
++ mask, !input ? BIT(field_shift) : 0);
++}
++
++/* pinmux callbacks */
++static int airoha_pinmux_set_mux(struct airoha_pinctrl *pinctrl,
++ unsigned int func_selector,
++ unsigned int group_selector)
++{
++ const struct airoha_pinctrl_func *func;
++ const struct pingroup *grp;
++ int i;
++
++ func = &pinctrl->data->funcs[func_selector];
++ grp = &pinctrl->data->grps[group_selector];
++
++ dev_dbg(pinctrl->dev, "enable function %s group %s\n",
++ func->desc.name, grp->name);
++
++ for (i = 0; i < func->group_size; i++) {
++ const struct airoha_pinctrl_func_group *group;
++ int j;
++
++ group = &func->groups[i];
++ if (strcmp(group->name, grp->name))
++ continue;
++
++ for (j = 0; j < group->regmap_size; j++) {
++ switch (group->regmap[j].mux) {
++ case AIROHA_FUNC_PWM_EXT_MUX:
++ case AIROHA_FUNC_PWM_MUX:
++ regmap_update_bits(pinctrl->regmap,
++ group->regmap[j].offset,
++ group->regmap[j].mask,
++ group->regmap[j].val);
++ break;
++ default:
++ regmap_update_bits(pinctrl->chip_scu,
++ group->regmap[j].offset,
++ group->regmap[j].mask,
++ group->regmap[j].val);
++ break;
++ }
++ }
++ return 0;
++ }
++
++ return -EINVAL;
++}
++
++static int airoha_pinmux_set_direction(struct airoha_pinctrl *pinctrl,
++ unsigned int p, bool input)
++{
++ int gpio;
++
++ gpio = pin_to_gpio(pinctrl, p);
++ if (gpio < 0)
++ return gpio;
++
++ return airoha_gpio_set_direction(pinctrl, gpio, input);
++}
++
++/* pinconf callbacks */
++static const struct airoha_pinctrl_reg *
++airoha_pinctrl_get_conf_reg(const struct airoha_pinctrl_conf *conf,
++ int conf_size, int pin)
++{
++ int i;
++
++ for (i = 0; i < conf_size; i++) {
++ if (conf[i].pin == pin)
++ return &conf[i].reg;
++ }
++
++ return NULL;
++}
++
++static int airoha_pinctrl_get_conf(struct airoha_pinctrl *pinctrl,
++ 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;
++
++ confs_info = &pinctrl->data->confs_info[conf_type];
++
++ reg = airoha_pinctrl_get_conf_reg(confs_info->confs,
++ confs_info->num_confs,
++ pin);
++ if (!reg)
++ return -EINVAL;
++
++ if (regmap_read(pinctrl->chip_scu, reg->offset, val))
++ return -EINVAL;
++
++ *val = field_get(reg->mask, *val);
++
++ return 0;
++}
++
++static int airoha_pinctrl_set_conf(struct airoha_pinctrl *pinctrl,
++ 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;
++
++ confs_info = &pinctrl->data->confs_info[conf_type];
++
++ reg = airoha_pinctrl_get_conf_reg(confs_info->confs,
++ confs_info->num_confs,
++ pin);
++ if (!reg)
++ return -EINVAL;
++
++ if (regmap_update_bits(pinctrl->chip_scu, reg->offset, reg->mask,
++ field_prep(reg->mask, val)))
++ return -EINVAL;
++
++ return 0;
++}
++
++static int airoha_pinconf_get_direction(struct airoha_pinctrl *pinctrl, u32 p)
++{
++ int gpio;
++
++ gpio = pin_to_gpio(pinctrl, p);
++ if (gpio < 0)
++ return gpio;
++
++ return airoha_gpio_get_direction(pinctrl, gpio);
++}
++
++static int airoha_pinconf_get(struct airoha_pinctrl *pinctrl,
++ unsigned int pin, unsigned long *config)
++{
++ enum pin_config_param param = pinconf_to_config_param(*config);
++ u32 arg;
++
++ switch (param) {
++ case PIN_CONFIG_BIAS_PULL_DOWN:
++ case PIN_CONFIG_BIAS_DISABLE:
++ case PIN_CONFIG_BIAS_PULL_UP: {
++ u32 pull_up, pull_down;
++
++ if (airoha_pinctrl_get_pullup_conf(pinctrl, pin, &pull_up) ||
++ airoha_pinctrl_get_pulldown_conf(pinctrl, pin, &pull_down))
++ return -EINVAL;
++
++ if (param == PIN_CONFIG_BIAS_PULL_UP &&
++ !(pull_up && !pull_down))
++ return -EINVAL;
++ else if (param == PIN_CONFIG_BIAS_PULL_DOWN &&
++ !(pull_down && !pull_up))
++ return -EINVAL;
++ else if (pull_up || pull_down)
++ return -EINVAL;
++
++ arg = 1;
++ break;
++ }
++ case PIN_CONFIG_DRIVE_STRENGTH: {
++ u32 e2, e4;
++
++ if (airoha_pinctrl_get_drive_e2_conf(pinctrl, pin, &e2) ||
++ airoha_pinctrl_get_drive_e4_conf(pinctrl, pin, &e4))
++ return -EINVAL;
++
++ arg = e4 << 1 | e2;
++ break;
++ }
++ case PIN_CONFIG_DRIVE_OPEN_DRAIN:
++ if (airoha_pinctrl_get_pcie_rst_od_conf(pinctrl, pin, &arg))
++ return -EINVAL;
++ break;
++ case PIN_CONFIG_OUTPUT_ENABLE:
++ case PIN_CONFIG_INPUT_ENABLE:
++ arg = airoha_pinconf_get_direction(pinctrl, pin);
++ if ((param != PIN_CONFIG_OUTPUT_ENABLE || arg != GPIOF_OUTPUT) &&
++ (param != PIN_CONFIG_INPUT_ENABLE || arg != GPIOF_INPUT))
++ return -EINVAL;
++
++ arg = 1;
++ break;
++ default:
++ return -EOPNOTSUPP;
++ }
++
++ *config = pinconf_to_config_packed(param, arg);
++
++ return 0;
++}
++
++static int airoha_pinconf_set_pin_value(struct airoha_pinctrl *pinctrl,
++ unsigned int p, bool value)
++{
++ int gpio;
++
++ gpio = pin_to_gpio(pinctrl, p);
++ if (gpio < 0)
++ return gpio;
++
++ return airoha_gpio_set(pinctrl, gpio, value);
++}
++
++static int airoha_pinconf_set(struct airoha_pinctrl *pinctrl,
++ unsigned int pin, unsigned long *configs,
++ unsigned int num_configs)
++{
++ int i, err;
++
++ for (i = 0; i < num_configs; i++) {
++ u32 param = pinconf_to_config_param(configs[i]);
++ u32 arg = pinconf_to_config_argument(configs[i]);
++
++ switch (param) {
++ case PIN_CONFIG_BIAS_DISABLE:
++ err = airoha_pinctrl_set_pulldown_conf(pinctrl, pin, 0);
++ if (err)
++ return err;
++
++ err = airoha_pinctrl_set_pullup_conf(pinctrl, pin, 0);
++ if (err)
++ return err;
++
++ break;
++
++ case PIN_CONFIG_BIAS_PULL_UP:
++ err = airoha_pinctrl_set_pulldown_conf(pinctrl, pin, 0);
++ if (err)
++ return err;
++
++ err = airoha_pinctrl_set_pullup_conf(pinctrl, pin, 1);
++ if (err)
++ return err;
++
++ break;
++
++ case PIN_CONFIG_BIAS_PULL_DOWN:
++ err = airoha_pinctrl_set_pulldown_conf(pinctrl, pin, 1);
++ if (err)
++ return err;
++
++ err = airoha_pinctrl_set_pullup_conf(pinctrl, pin, 0);
++ if (err)
++ return err;
++
++ break;
++
++ case PIN_CONFIG_DRIVE_STRENGTH: {
++ u32 e2 = 0, e4 = 0;
++
++ switch (arg) {
++ case MTK_DRIVE_2mA:
++ break;
++ case MTK_DRIVE_4mA:
++ e2 = 1;
++ break;
++ case MTK_DRIVE_6mA:
++ e4 = 1;
++ break;
++ case MTK_DRIVE_8mA:
++ e2 = 1;
++ e4 = 1;
++ break;
++ default:
++ return -EINVAL;
++ }
++
++ err = airoha_pinctrl_set_drive_e2_conf(pinctrl, pin, e2);
++ if (err)
++ return err;
++
++ err = airoha_pinctrl_set_drive_e4_conf(pinctrl, pin, e4);
++ if (err)
++ return err;
++
++ break;
++ }
++ case PIN_CONFIG_DRIVE_OPEN_DRAIN:
++ err = airoha_pinctrl_set_pcie_rst_od_conf(pinctrl, pin, !!arg);
++ if (err)
++ return err;
++
++ break;
++
++ case PIN_CONFIG_OUTPUT_ENABLE:
++ case PIN_CONFIG_INPUT_ENABLE:
++ case PIN_CONFIG_OUTPUT: {
++ bool input = param == PIN_CONFIG_INPUT_ENABLE;
++
++ err = airoha_pinmux_set_direction(pinctrl, pin, input);
++ if (err)
++ return err;
++
++ if (param == PIN_CONFIG_OUTPUT) {
++ err = airoha_pinconf_set_pin_value(pinctrl,
++ pin, !!arg);
++ if (err)
++ return err;
++ }
++
++ break;
++ }
++ default:
++ return -EOPNOTSUPP;
++ }
++ }
++
++ return 0;
++}
++
++static int airoha_pinconf_group_set(struct airoha_pinctrl *pinctrl,
++ unsigned int group, unsigned long *configs,
++ unsigned int num_configs)
++{
++ int i;
++
++ for (i = 0; i < pinctrl->data->grps[group].npins; i++) {
++ int err;
++
++ err = airoha_pinconf_set(pinctrl,
++ pinctrl->data->grps[group].pins[i],
++ configs, num_configs);
++ if (err)
++ return err;
++ }
++
++ return 0;
++}
++
++static int func_grp_active(struct airoha_pinctrl *pinctrl,
++ const struct airoha_pinctrl_func *func,
++ const char *grp_name)
++{
++ const struct airoha_pinctrl_func_group *func_grp;
++ u32 val, match;
++ int ret;
++
++ for (int i = 0; i < func->group_size; i++) {
++ if (strcmp(func->groups[i].name, grp_name))
++ continue;
++
++ match = 0;
++ func_grp = &func->groups[i];
++ for (int j = 0; j < func_grp->regmap_size; j++) {
++ switch (func_grp->regmap[j].mux) {
++ case AIROHA_FUNC_PWM_EXT_MUX:
++ case AIROHA_FUNC_PWM_MUX:
++ ret = regmap_read(pinctrl->regmap,
++ func_grp->regmap[j].offset,
++ &val);
++ break;
++ default:
++ ret = regmap_read(pinctrl->chip_scu,
++ func_grp->regmap[j].offset,
++ &val);
++ break;
++ }
++
++ if (ret)
++ break;
++
++ if ((val & func_grp->regmap[j].mask) !=
++ func_grp->regmap[j].val)
++ break;
++
++ match++;
++ }
++
++ return match == func->groups[i].regmap_size;
++ }
++
++ return 0;
++}
++
++/***********************
++ * gpio driver interface
++ ***********************/
++static int airoha_pinctrl_gpio_set(struct udevice *dev, unsigned int gpio,
++ int value)
++{
++ return airoha_gpio_set(dev_get_priv(dev->parent), gpio, value);
++}
++
++static int airoha_pinctrl_gpio_get(struct udevice *dev, unsigned int gpio)
++{
++ return airoha_gpio_get(dev_get_priv(dev->parent), gpio);
++}
++
++static int airoha_pinctrl_gpio_get_direction(struct udevice *dev,
++ unsigned int gpio)
++{
++ return airoha_gpio_get_direction(dev_get_priv(dev->parent), gpio);
++}
++
++static int airoha_pinctrl_gpio_direction_input(struct udevice *dev,
++ unsigned int gpio)
++{
++ return airoha_gpio_set_direction(dev_get_priv(dev->parent),
++ gpio, true);
++}
++
++static int airoha_pinctrl_gpio_direction_output(struct udevice *dev,
++ unsigned int gpio, int val)
++{
++ struct airoha_pinctrl *pinctrl = dev_get_priv(dev->parent);
++ int err;
++
++ err = airoha_gpio_set_direction(pinctrl, gpio, false);
++ if (err)
++ return err;
++
++ return airoha_gpio_set(pinctrl, gpio, val);
++}
++
++static int airoha_pinctrl_gpio_probe(struct udevice *dev)
++{
++ struct airoha_pinctrl *pinctrl = dev_get_priv(dev->parent);
++ struct gpio_dev_priv *uc_priv;
++
++ uc_priv = dev_get_uclass_priv(dev);
++ uc_priv->bank_name = "airoha";
++ uc_priv->gpio_count = pinctrl->data->gpio_pin_cnt;
++
++ return 0;
++}
++
++static int airoha_pinctrl_gpio_bind(struct udevice *dev)
++{
++ dev_or_flags(dev, DM_FLAG_PROBE_AFTER_BIND);
++
++ return 0;
++}
++
++static const struct dm_gpio_ops airoha_pinctrl_gpio_ops = {
++ .set_value = airoha_pinctrl_gpio_set,
++ .get_value = airoha_pinctrl_gpio_get,
++ .get_function = airoha_pinctrl_gpio_get_direction,
++ .direction_input = airoha_pinctrl_gpio_direction_input,
++ .direction_output = airoha_pinctrl_gpio_direction_output,
++};
++
++static struct driver airoha_pinctrl_gpio_driver = {
++ .name = "airoha_pinctrl_gpio",
++ .id = UCLASS_GPIO,
++ .probe = airoha_pinctrl_gpio_probe,
++ .bind = airoha_pinctrl_gpio_bind,
++ .ops = &airoha_pinctrl_gpio_ops,
++};
++
++static int airoha_pinctrl_gpio_register(struct udevice *parent)
++{
++ struct uclass_driver *drv;
++ ofnode node;
++ int ret;
++
++ drv = lists_uclass_lookup(UCLASS_GPIO);
++ if (!drv)
++ return -ENOENT;
++
++ /*
++ * Support upstream linux DTSI that define gpio-controller
++ * in the root node (instead of a dedicated subnode)
++ */
++ if (dev_read_bool(parent, "gpio-controller")) {
++ /* upstream DTSI, use current node */
++ node = dev_ofnode(parent);
++ } else {
++ /* legacy DTSI, search for gpio-controller subnode */
++ ret = -ENOENT;
++ dev_for_each_subnode(node, parent)
++ if (ofnode_read_bool(node, "gpio-controller")) {
++ ret = 0;
++ break;
++ }
++
++ if (ret)
++ return ret;
++ }
++
++ return device_bind_with_driver_data(parent,
++ &airoha_pinctrl_gpio_driver,
++ "airoha_pinctrl_gpio",
++ 0, node, NULL);
++}
++
++/**************************
++ * pinctrl driver interface
++ **************************/
++static int airoha_get_pins_count(struct udevice *dev)
++{
++ struct airoha_pinctrl *pinctrl = dev_get_priv(dev);
++
++ return pinctrl->data->num_pins;
++}
++
++static const char *airoha_get_pin_name(struct udevice *dev,
++ unsigned int selector)
++{
++ struct airoha_pinctrl *pinctrl = dev_get_priv(dev);
++
++ return pinctrl->data->pins[selector].name;
++}
++
++static int airoha_get_groups_count(struct udevice *dev)
++{
++ struct airoha_pinctrl *pinctrl = dev_get_priv(dev);
++
++ return pinctrl->data->num_grps;
++}
++
++static const char *airoha_get_group_name(struct udevice *dev,
++ unsigned int selector)
++{
++ struct airoha_pinctrl *pinctrl = dev_get_priv(dev);
++
++ return pinctrl->data->grps[selector].name;
++}
++
++static int airoha_get_funcs_count(struct udevice *dev)
++{
++ struct airoha_pinctrl *pinctrl = dev_get_priv(dev);
++
++ return pinctrl->data->num_funcs;
++}
++
++static const char *airoha_get_func_name(struct udevice *dev,
++ unsigned int selector)
++{
++ struct airoha_pinctrl *pinctrl = dev_get_priv(dev);
++
++ return pinctrl->data->funcs[selector].desc.name;
++}
++
++static int airoha_pinmux_group_set(struct udevice *dev,
++ unsigned int group_selector,
++ unsigned int func_selector)
++{
++ struct airoha_pinctrl *pinctrl = dev_get_priv(dev);
++
++ dev_dbg(dev, "enabling %s function for pin group %s\n",
++ airoha_get_func_name(dev, func_selector),
++ airoha_get_group_name(dev, group_selector));
++
++ return airoha_pinmux_set_mux(pinctrl, func_selector, group_selector);
++}
++
++static int airoha_pinmux_set(struct udevice *dev,
++ unsigned int pin_selector,
++ unsigned int func_selector)
++{
++ struct airoha_pinctrl *pinctrl = dev_get_priv(dev);
++ const struct airoha_pinctrl_match_data *data = pinctrl->data;
++ const char *pin_name;
++ unsigned int selector;
++
++ pin_name = data->pins[pin_selector].name;
++
++ /* find group matching the pin_name */
++ for (selector = 0; selector < data->num_grps; selector++) {
++ if (!strcmp(pin_name, data->grps[selector].name))
++ return airoha_pinmux_group_set(dev, selector,
++ func_selector);
++ }
++
++ return -ENOENT;
++}
++
++static const struct pinconf_param airoha_pinconf_params[] = {
++ { "bias-disable", PIN_CONFIG_BIAS_DISABLE, 0 },
++ { "bias-pull-up", PIN_CONFIG_BIAS_PULL_UP, 1 },
++ { "bias-pull-down", PIN_CONFIG_BIAS_PULL_DOWN, 1 },
++ { "drive-strength", PIN_CONFIG_DRIVE_STRENGTH, 0 },
++ { "drive-open-drain", PIN_CONFIG_DRIVE_OPEN_DRAIN, 0 },
++ { "output-enable", PIN_CONFIG_OUTPUT_ENABLE, 1 },
++ { "input-enable", PIN_CONFIG_INPUT_ENABLE, 1 },
++};
++
++static const char *airoha_pinconf_param_name(unsigned int param)
++{
++ for (int i = 0; i < ARRAY_SIZE(airoha_pinconf_params); i++) {
++ if (airoha_pinconf_params[i].param == param)
++ return airoha_pinconf_params[i].property;
++ }
++
++ return NULL;
++}
++
++static int airoha_pinconf_set_handler(struct udevice *dev,
++ unsigned pin_selector,
++ unsigned int param,
++ unsigned int argument)
++{
++ struct airoha_pinctrl *pinctrl = dev_get_priv(dev);
++ unsigned long configs[1] = { pinconf_to_config_packed(param, argument) };
++ unsigned int pin = pinctrl->data->pins[pin_selector].number;
++
++ dev_dbg(dev, "enabling %s=%d property for pin %s\n",
++ airoha_pinconf_param_name(param), argument,
++ airoha_get_pin_name(dev, pin_selector));
++
++ return airoha_pinconf_set(pinctrl, pin, configs,
++ ARRAY_SIZE(configs));
++}
++
++static int airoha_pinconf_group_set_handler(struct udevice *dev,
++ unsigned int group_selector,
++ unsigned int param,
++ unsigned int argument)
++{
++ struct airoha_pinctrl *pinctrl = dev_get_priv(dev);
++ unsigned long configs[1] = { pinconf_to_config_packed(param, argument) };
++
++ dev_dbg(dev, "enabling %s=%d property for pin group %s\n",
++ airoha_pinconf_param_name(param), argument,
++ airoha_get_group_name(dev, group_selector));
++
++ return airoha_pinconf_group_set(pinctrl, group_selector,
++ configs, ARRAY_SIZE(configs));
++}
++
++static int airoha_get_pin_muxing(struct udevice *dev, unsigned int selector,
++ char *buf, int size)
++{
++ struct airoha_pinctrl *pinctrl = dev_get_priv(dev);
++ struct airoha_pinctrl_match_data *data = pinctrl->data;
++ const char *name, *type;
++ int ret, gpio, found = 0;
++ unsigned long config;
++ unsigned int param, pin;
++ u32 val;
++
++ pin = data->pins[selector].number;
++ for (int i = 0; i < data->num_grps; i++) {
++ if (!pin_in_group(pin, &data->grps[i]))
++ continue;
++
++ name = data->grps[i].name;
++ for (int j = 0; j < data->num_funcs; j++) {
++ if (!func_grp_active(pinctrl, &data->funcs[j], name))
++ continue;
++
++ ret = scnprintf(buf, size, "%s(%s)",
++ data->funcs[j].desc.name, name);
++ if (ret < 0)
++ return -ENOSPC;
++
++ found = 1;
++ buf += ret;
++ size -= ret;
++ break;
++ }
++
++ if (found)
++ break;
++ }
++
++ if (!found) {
++ gpio = pin_to_gpio(pinctrl, pin);
++ if (gpio < 0) {
++ /*
++ * WARNING: non-gpio pin with unknown function.
++ *
++ * This should not have happened, the function group
++ * tables are incomplete. Please fix ASAP.
++ */
++ ret = scnprintf(buf, size, "default");
++ } else {
++ /* assume gpio */
++ val = airoha_gpio_get(pinctrl, gpio);
++ switch (airoha_gpio_get_direction(pinctrl, gpio)) {
++ case GPIOF_INPUT:
++ type = "input";
++ break;
++ case GPIOF_OUTPUT:
++ type = "output";
++ break;
++ default:
++ type = "unknown";
++ break;
++ };
++ ret = scnprintf(buf, size, "gpio%d, %s(%d)",
++ gpio, type, val);
++ }
++
++ if (ret < 0)
++ return -ENOSPC;
++
++ buf += ret;
++ size -= ret;
++ }
++
++ for (int i = 0; i < ARRAY_SIZE(airoha_pinconf_params); i++) {
++ param = airoha_pinconf_params[i].param;
++ config = pinconf_to_config_packed(param, 0);
++ ret = airoha_pinconf_get(pinctrl, pin, &config);
++ if (ret < 0)
++ continue;
++
++ name = airoha_pinconf_params[i].property;
++ switch (param) {
++ case PIN_CONFIG_BIAS_DISABLE:
++ case PIN_CONFIG_BIAS_PULL_UP:
++ case PIN_CONFIG_BIAS_PULL_DOWN:
++ ret = scnprintf(buf, size, ", %s", name);
++ break;
++
++ case PIN_CONFIG_DRIVE_STRENGTH:
++ case PIN_CONFIG_DRIVE_OPEN_DRAIN:
++ val = pinconf_to_config_argument(config);
++ ret = scnprintf(buf, size, ", %s(%d)", name, val);
++ break;
++
++ default:
++ break;
++ }
++
++ if (ret < 0)
++ return -ENOSPC;
++
++ buf += ret;
++ size -= ret;
++ }
++
++ return 0;
++}
++
++const struct pinctrl_ops airoha_pinctrl_ops = {
++ .get_pins_count = airoha_get_pins_count,
++ .get_pin_name = airoha_get_pin_name,
++ .get_groups_count = airoha_get_groups_count,
++ .get_group_name = airoha_get_group_name,
++ .get_functions_count = airoha_get_funcs_count,
++ .get_function_name = airoha_get_func_name,
++ .pinmux_set = airoha_pinmux_set,
++ .pinmux_group_set = airoha_pinmux_group_set,
++
++ .pinconf_num_params = ARRAY_SIZE(airoha_pinconf_params),
++ .pinconf_params = airoha_pinconf_params,
++ .pinconf_set = airoha_pinconf_set_handler,
++ .pinconf_group_set = airoha_pinconf_group_set_handler,
++
++ .set_state = pinctrl_generic_set_state,
++ .get_pin_muxing = airoha_get_pin_muxing,
++};
++
++int airoha_pinctrl_probe(struct udevice *dev)
++{
++ struct airoha_pinctrl *pinctrl = dev_get_priv(dev);
++
++ pinctrl->dev = dev;
++ pinctrl->data = (struct airoha_pinctrl_match_data *)dev_get_driver_data(dev);
++
++ pinctrl->regmap = syscon_node_to_regmap(dev_ofnode(dev->parent));
++ if (IS_ERR(pinctrl->regmap))
++ return PTR_ERR(pinctrl->regmap);
++
++ pinctrl->chip_scu = airoha_get_chip_scu_regmap();
++ if (IS_ERR(pinctrl->chip_scu))
++ return PTR_ERR(pinctrl->chip_scu);
++
++ pinctrl->gpiochip.data = gpio_data_regs;
++ pinctrl->gpiochip.dir = gpio_dir_regs;
++ pinctrl->gpiochip.out = gpio_out_regs;
++ pinctrl->gpiochip.status = irq_status_regs;
++ pinctrl->gpiochip.level = irq_level_regs;
++ pinctrl->gpiochip.edge = irq_edge_regs;
++
++ return 0;
++}
++
++int airoha_pinctrl_bind(struct udevice *dev)
++{
++ if (airoha_pinctrl_gpio_register(dev))
++ debug("Warning: can't bind gpio driver with device node\n");
++
++ /*
++ * Make sure that the pinctrl driver gets probed after binding,
++ * otherwise GPIO interface driver will not be probed as well.
++ * GPIOs of non-probed driver can't be used.
++ */
++ dev_or_flags(dev, DM_FLAG_PROBE_AFTER_BIND);
++
++ return 0;
++}
+--
+2.53.0
+
--- /dev/null
+From 4c711536c4d5489de846a7bd73a8cf3563722c76 Mon Sep 17 00:00:00 2001
+From: Mikhail Kshevetskiy <mikhail.kshevetskiy@iopsys.eu>
+Date: Sun, 26 Apr 2026 23:22:20 +0300
+Subject: [PATCH 06/29] pinctrl: airoha: add pin controller and gpio driver for
+ AN7581 SoC
+
+This patch adds U-Boot pin controller and gpio driver for Airoha AN7581 SoC.
+
+Signed-off-by: Mikhail Kshevetskiy <mikhail.kshevetskiy@iopsys.eu>
+Reviewed-by: David Lechner <dlechner@baylibre.com>
+---
+ drivers/pinctrl/airoha/Kconfig | 5 +
+ drivers/pinctrl/airoha/Makefile | 2 +
+ drivers/pinctrl/airoha/pinctrl-an7581.c | 1484 +++++++++++++++++++++++
+ 3 files changed, 1491 insertions(+)
+ create mode 100644 drivers/pinctrl/airoha/pinctrl-an7581.c
+
+diff --git a/drivers/pinctrl/airoha/Kconfig b/drivers/pinctrl/airoha/Kconfig
+index eb87afbb374..ae387f70b22 100644
+--- a/drivers/pinctrl/airoha/Kconfig
++++ b/drivers/pinctrl/airoha/Kconfig
+@@ -9,3 +9,8 @@ config PINCTRL_AIROHA
+ select REGMAP
+ select SYSCON
+ bool
++
++config PINCTRL_AIROHA_AN7581
++ bool "Airoha AN7581 pin controller and gpio driver"
++ depends on TARGET_AN7581
++ select PINCTRL_AIROHA
+diff --git a/drivers/pinctrl/airoha/Makefile b/drivers/pinctrl/airoha/Makefile
+index a25b744dd7a..909bd9a04d9 100644
+--- a/drivers/pinctrl/airoha/Makefile
++++ b/drivers/pinctrl/airoha/Makefile
+@@ -1,3 +1,5 @@
+ # SPDX-License-Identifier: GPL-2.0
+
+ obj-$(CONFIG_PINCTRL_AIROHA) += pinctrl-airoha.o
++
++obj-$(CONFIG_PINCTRL_AIROHA_AN7581) += pinctrl-an7581.o
+diff --git a/drivers/pinctrl/airoha/pinctrl-an7581.c b/drivers/pinctrl/airoha/pinctrl-an7581.c
+new file mode 100644
+index 00000000000..4f7da74a1cf
+--- /dev/null
++++ b/drivers/pinctrl/airoha/pinctrl-an7581.c
+@@ -0,0 +1,1484 @@
++// SPDX-License-Identifier: GPL-2.0-only
++/*
++ * Author: Lorenzo Bianconi <lorenzo@kernel.org>
++ * Author: Benjamin Larsson <benjamin.larsson@genexis.eu>
++ * Author: Markus Gothe <markus.gothe@genexis.eu>
++ */
++
++#include "airoha-common.h"
++
++/* MUX */
++#define REG_GPIO_2ND_I2C_MODE 0x0214
++#define GPIO_MDC_IO_MASTER_MODE_MASK BIT(14)
++#define GPIO_I2C_MASTER_MODE_MODE BIT(13)
++#define GPIO_I2S_MODE_MASK BIT(12)
++#define GPIO_I2C_SLAVE_MODE_MODE BIT(11)
++#define GPIO_LAN3_LED1_MODE_MASK BIT(10)
++#define GPIO_LAN3_LED0_MODE_MASK BIT(9)
++#define GPIO_LAN2_LED1_MODE_MASK BIT(8)
++#define GPIO_LAN2_LED0_MODE_MASK BIT(7)
++#define GPIO_LAN1_LED1_MODE_MASK BIT(6)
++#define GPIO_LAN1_LED0_MODE_MASK BIT(5)
++#define GPIO_LAN0_LED1_MODE_MASK BIT(4)
++#define GPIO_LAN0_LED0_MODE_MASK BIT(3)
++#define PON_TOD_1PPS_MODE_MASK BIT(2)
++#define GSW_TOD_1PPS_MODE_MASK BIT(1)
++#define GPIO_2ND_I2C_MODE_MASK BIT(0)
++
++#define REG_GPIO_SPI_CS1_MODE 0x0218
++#define GPIO_PCM_SPI_CS4_MODE_MASK BIT(21)
++#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 GPIO_PCM_SPI_CS1_MODE_MASK BIT(17)
++#define GPIO_PCM_SPI_MODE_MASK BIT(16)
++#define GPIO_PCM2_MODE_MASK BIT(13)
++#define GPIO_PCM1_MODE_MASK BIT(12)
++#define GPIO_PCM_INT_MODE_MASK BIT(9)
++#define GPIO_PCM_RESET_MODE_MASK BIT(8)
++#define GPIO_SPI_QUAD_MODE_MASK BIT(4)
++#define GPIO_SPI_CS4_MODE_MASK BIT(3)
++#define GPIO_SPI_CS3_MODE_MASK BIT(2)
++#define GPIO_SPI_CS2_MODE_MASK BIT(1)
++#define GPIO_SPI_CS1_MODE_MASK BIT(0)
++
++#define REG_GPIO_PON_MODE 0x021c
++#define GPIO_PARALLEL_NAND_MODE_MASK BIT(14)
++#define GPIO_SGMII_MDIO_MODE_MASK BIT(13)
++#define GPIO_PCIE_RESET2_MASK BIT(12)
++#define SIPO_RCLK_MODE_MASK BIT(11)
++#define GPIO_PCIE_RESET1_MASK BIT(10)
++#define GPIO_PCIE_RESET0_MASK BIT(9)
++#define GPIO_UART5_MODE_MASK BIT(8)
++#define GPIO_UART4_MODE_MASK BIT(7)
++#define GPIO_HSUART_CTS_RTS_MODE_MASK BIT(6)
++#define GPIO_HSUART_MODE_MASK BIT(5)
++#define GPIO_UART2_CTS_RTS_MODE_MASK BIT(4)
++#define GPIO_UART2_MODE_MASK BIT(3)
++#define GPIO_SIPO_MODE_MASK BIT(2)
++#define GPIO_EMMC_MODE_MASK BIT(1)
++#define GPIO_PON_MODE_MASK BIT(0)
++
++#define REG_NPU_UART_EN 0x0224
++#define JTAG_UDI_EN_MASK BIT(4)
++#define JTAG_DFD_EN_MASK BIT(3)
++
++#define REG_FORCE_GPIO_EN 0x0228
++#define FORCE_GPIO_EN(n) BIT(n)
++
++/* LED MAP */
++#define REG_LAN_LED0_MAPPING 0x027c
++#define REG_LAN_LED1_MAPPING 0x0280
++
++#define LAN4_LED_MAPPING_MASK GENMASK(18, 16)
++#define LAN4_PHY_LED_MAP(_n) FIELD_PREP_CONST(LAN4_LED_MAPPING_MASK, (_n))
++
++#define LAN3_LED_MAPPING_MASK GENMASK(14, 12)
++#define LAN3_PHY_LED_MAP(_n) FIELD_PREP_CONST(LAN3_LED_MAPPING_MASK, (_n))
++
++#define LAN2_LED_MAPPING_MASK GENMASK(10, 8)
++#define LAN2_PHY_LED_MAP(_n) FIELD_PREP_CONST(LAN2_LED_MAPPING_MASK, (_n))
++
++#define LAN1_LED_MAPPING_MASK GENMASK(6, 4)
++#define LAN1_PHY_LED_MAP(_n) FIELD_PREP_CONST(LAN1_LED_MAPPING_MASK, (_n))
++
++#define LAN0_LED_MAPPING_MASK GENMASK(2, 0)
++#define LAN0_PHY_LED_MAP(_n) FIELD_PREP_CONST(LAN0_LED_MAPPING_MASK, (_n))
++
++/* CONF */
++#define REG_I2C_SDA_E2 0x001c
++#define SPI_MISO_E2_MASK BIT(14)
++#define SPI_MOSI_E2_MASK BIT(13)
++#define SPI_CLK_E2_MASK BIT(12)
++#define SPI_CS0_E2_MASK BIT(11)
++#define PCIE2_RESET_E2_MASK BIT(10)
++#define PCIE1_RESET_E2_MASK BIT(9)
++#define PCIE0_RESET_E2_MASK BIT(8)
++#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 SPI_MISO_E4_MASK BIT(14)
++#define SPI_MOSI_E4_MASK BIT(13)
++#define SPI_CLK_E4_MASK BIT(12)
++#define SPI_CS0_E4_MASK BIT(11)
++#define PCIE2_RESET_E4_MASK BIT(10)
++#define PCIE1_RESET_E4_MASK BIT(9)
++#define PCIE0_RESET_E4_MASK BIT(8)
++#define UART1_RXD_E4_MASK BIT(3)
++#define UART1_TXD_E4_MASK BIT(2)
++#define I2C_SCL_E4_MASK BIT(1)
++#define I2C_SDA_E4_MASK BIT(0)
++
++#define REG_GPIO_L_E2 0x0024
++#define REG_GPIO_L_E4 0x0028
++#define REG_GPIO_H_E2 0x002c
++#define REG_GPIO_H_E4 0x0030
++
++#define REG_I2C_SDA_PU 0x0044
++#define SPI_MISO_PU_MASK BIT(14)
++#define SPI_MOSI_PU_MASK BIT(13)
++#define SPI_CLK_PU_MASK BIT(12)
++#define SPI_CS0_PU_MASK BIT(11)
++#define PCIE2_RESET_PU_MASK BIT(10)
++#define PCIE1_RESET_PU_MASK BIT(9)
++#define PCIE0_RESET_PU_MASK BIT(8)
++#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 SPI_MISO_PD_MASK BIT(14)
++#define SPI_MOSI_PD_MASK BIT(13)
++#define SPI_CLK_PD_MASK BIT(12)
++#define SPI_CS0_PD_MASK BIT(11)
++#define PCIE2_RESET_PD_MASK BIT(10)
++#define PCIE1_RESET_PD_MASK BIT(9)
++#define PCIE0_RESET_PD_MASK BIT(8)
++#define UART1_RXD_PD_MASK BIT(3)
++#define UART1_TXD_PD_MASK BIT(2)
++#define I2C_SCL_PD_MASK BIT(1)
++#define I2C_SDA_PD_MASK BIT(0)
++
++#define REG_GPIO_L_PU 0x004c
++#define REG_GPIO_L_PD 0x0050
++#define REG_GPIO_H_PU 0x0054
++#define REG_GPIO_H_PD 0x0058
++
++#define REG_PCIE_RESET_OD 0x018c
++#define PCIE2_RESET_OD_MASK BIT(2)
++#define PCIE1_RESET_OD_MASK BIT(1)
++#define PCIE0_RESET_OD_MASK BIT(0)
++
++/* PWM MODE CONF */
++#define REG_GPIO_FLASH_MODE_CFG 0x0034
++#define GPIO15_FLASH_MODE_CFG BIT(15)
++#define GPIO14_FLASH_MODE_CFG BIT(14)
++#define GPIO13_FLASH_MODE_CFG BIT(13)
++#define GPIO12_FLASH_MODE_CFG BIT(12)
++#define GPIO11_FLASH_MODE_CFG BIT(11)
++#define GPIO10_FLASH_MODE_CFG BIT(10)
++#define GPIO9_FLASH_MODE_CFG BIT(9)
++#define GPIO8_FLASH_MODE_CFG BIT(8)
++#define GPIO7_FLASH_MODE_CFG BIT(7)
++#define GPIO6_FLASH_MODE_CFG BIT(6)
++#define GPIO5_FLASH_MODE_CFG BIT(5)
++#define GPIO4_FLASH_MODE_CFG BIT(4)
++#define GPIO3_FLASH_MODE_CFG BIT(3)
++#define GPIO2_FLASH_MODE_CFG BIT(2)
++#define GPIO1_FLASH_MODE_CFG BIT(1)
++#define GPIO0_FLASH_MODE_CFG BIT(0)
++
++/* PWM MODE CONF EXT */
++#define REG_GPIO_FLASH_MODE_CFG_EXT 0x0068
++#define GPIO51_FLASH_MODE_CFG BIT(31)
++#define GPIO50_FLASH_MODE_CFG BIT(30)
++#define GPIO49_FLASH_MODE_CFG BIT(29)
++#define GPIO48_FLASH_MODE_CFG BIT(28)
++#define GPIO47_FLASH_MODE_CFG BIT(27)
++#define GPIO46_FLASH_MODE_CFG BIT(26)
++#define GPIO45_FLASH_MODE_CFG BIT(25)
++#define GPIO44_FLASH_MODE_CFG BIT(24)
++#define GPIO43_FLASH_MODE_CFG BIT(23)
++#define GPIO42_FLASH_MODE_CFG BIT(22)
++#define GPIO41_FLASH_MODE_CFG BIT(21)
++#define GPIO40_FLASH_MODE_CFG BIT(20)
++#define GPIO39_FLASH_MODE_CFG BIT(19)
++#define GPIO38_FLASH_MODE_CFG BIT(18)
++#define GPIO37_FLASH_MODE_CFG BIT(17)
++#define GPIO36_FLASH_MODE_CFG BIT(16)
++#define GPIO31_FLASH_MODE_CFG BIT(15)
++#define GPIO30_FLASH_MODE_CFG BIT(14)
++#define GPIO29_FLASH_MODE_CFG BIT(13)
++#define GPIO28_FLASH_MODE_CFG BIT(12)
++#define GPIO27_FLASH_MODE_CFG BIT(11)
++#define GPIO26_FLASH_MODE_CFG BIT(10)
++#define GPIO25_FLASH_MODE_CFG BIT(9)
++#define GPIO24_FLASH_MODE_CFG BIT(8)
++#define GPIO23_FLASH_MODE_CFG BIT(7)
++#define GPIO22_FLASH_MODE_CFG BIT(6)
++#define GPIO21_FLASH_MODE_CFG BIT(5)
++#define GPIO20_FLASH_MODE_CFG BIT(4)
++#define GPIO19_FLASH_MODE_CFG BIT(3)
++#define GPIO18_FLASH_MODE_CFG BIT(2)
++#define GPIO17_FLASH_MODE_CFG BIT(1)
++#define GPIO16_FLASH_MODE_CFG BIT(0)
++
++#define AIROHA_PINCTRL_GPIO(gpio, mux_val) \
++ { \
++ .name = (gpio), \
++ .regmap[0] = { \
++ AIROHA_FUNC_MUX, \
++ REG_GPIO_PON_MODE, \
++ (mux_val), \
++ (mux_val) \
++ }, \
++ .regmap_size = 1, \
++ }
++
++#define AIROHA_PINCTRL_GPIO_EXT(gpio, mux_val, smux_val) \
++ { \
++ .name = (gpio), \
++ .regmap[0] = { \
++ AIROHA_FUNC_PWM_EXT_MUX, \
++ REG_GPIO_FLASH_MODE_CFG_EXT, \
++ (mux_val), \
++ 0 \
++ }, \
++ .regmap[1] = { \
++ AIROHA_FUNC_MUX, \
++ REG_GPIO_PON_MODE, \
++ (smux_val), \
++ (smux_val) \
++ }, \
++ .regmap_size = 2, \
++ }
++
++/* 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, \
++ }
++
++#define AIROHA_PINCTRL_PWM_EXT_SEC(gpio, mux_val, smux_val) \
++ { \
++ .name = (gpio), \
++ .regmap[0] = { \
++ AIROHA_FUNC_PWM_EXT_MUX, \
++ REG_GPIO_FLASH_MODE_CFG_EXT, \
++ (mux_val), \
++ (mux_val) \
++ }, \
++ .regmap[1] = { \
++ AIROHA_FUNC_MUX, \
++ REG_GPIO_PON_MODE, \
++ (smux_val), \
++ (smux_val) \
++ }, \
++ .regmap_size = 2, \
++ }
++
++#define AIROHA_PINCTRL_PHY_LED0(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, \
++ }
++
++#define AIROHA_PINCTRL_PHY_LED1(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_LED1_MAPPING, \
++ (map_mask), \
++ (map_val), \
++ }, \
++ .regmap_size = 2, \
++ }
++
++static struct pinctrl_pin_desc pinctrl_pins[] = {
++ PINCTRL_PIN(0, "uart1_txd"),
++ PINCTRL_PIN(1, "uart1_rxd"),
++ PINCTRL_PIN(2, "i2c_scl"),
++ PINCTRL_PIN(3, "i2c_sda"),
++ PINCTRL_PIN(4, "spi_cs0"),
++ PINCTRL_PIN(5, "spi_clk"),
++ PINCTRL_PIN(6, "spi_mosi"),
++ PINCTRL_PIN(7, "spi_miso"),
++ PINCTRL_PIN(13, "gpio0"),
++ PINCTRL_PIN(14, "gpio1"),
++ PINCTRL_PIN(15, "gpio2"),
++ PINCTRL_PIN(16, "gpio3"),
++ PINCTRL_PIN(17, "gpio4"),
++ PINCTRL_PIN(18, "gpio5"),
++ PINCTRL_PIN(19, "gpio6"),
++ PINCTRL_PIN(20, "gpio7"),
++ PINCTRL_PIN(21, "gpio8"),
++ PINCTRL_PIN(22, "gpio9"),
++ PINCTRL_PIN(23, "gpio10"),
++ PINCTRL_PIN(24, "gpio11"),
++ PINCTRL_PIN(25, "gpio12"),
++ PINCTRL_PIN(26, "gpio13"),
++ PINCTRL_PIN(27, "gpio14"),
++ PINCTRL_PIN(28, "gpio15"),
++ PINCTRL_PIN(29, "gpio16"),
++ PINCTRL_PIN(30, "gpio17"),
++ PINCTRL_PIN(31, "gpio18"),
++ PINCTRL_PIN(32, "gpio19"),
++ PINCTRL_PIN(33, "gpio20"),
++ PINCTRL_PIN(34, "gpio21"),
++ PINCTRL_PIN(35, "gpio22"),
++ PINCTRL_PIN(36, "gpio23"),
++ PINCTRL_PIN(37, "gpio24"),
++ PINCTRL_PIN(38, "gpio25"),
++ PINCTRL_PIN(39, "gpio26"),
++ PINCTRL_PIN(40, "gpio27"),
++ PINCTRL_PIN(41, "gpio28"),
++ PINCTRL_PIN(42, "gpio29"),
++ PINCTRL_PIN(43, "gpio30"),
++ PINCTRL_PIN(44, "gpio31"),
++ PINCTRL_PIN(45, "gpio32"),
++ PINCTRL_PIN(46, "gpio33"),
++ PINCTRL_PIN(47, "gpio34"),
++ PINCTRL_PIN(48, "gpio35"),
++ PINCTRL_PIN(49, "gpio36"),
++ PINCTRL_PIN(50, "gpio37"),
++ PINCTRL_PIN(51, "gpio38"),
++ PINCTRL_PIN(52, "gpio39"),
++ PINCTRL_PIN(53, "gpio40"),
++ PINCTRL_PIN(54, "gpio41"),
++ PINCTRL_PIN(55, "gpio42"),
++ PINCTRL_PIN(56, "gpio43"),
++ PINCTRL_PIN(57, "gpio44"),
++ PINCTRL_PIN(58, "gpio45"),
++ PINCTRL_PIN(59, "gpio46"),
++ PINCTRL_PIN(60, "pcie_reset0"),
++ PINCTRL_PIN(61, "pcie_reset1"),
++ PINCTRL_PIN(62, "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 gpio32_pins[] = { 45 };
++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 gpio47_pins[] = { 60 };
++static const int gpio48_pins[] = { 61 };
++static const int gpio49_pins[] = { 62 };
++static const int pcie_reset0_pins[] = { 60 };
++static const int pcie_reset1_pins[] = { 61 };
++static const int pcie_reset2_pins[] = { 62 };
++
++static const struct pingroup pinctrl_groups[] = {
++ PINCTRL_PIN_GROUP("pon", pon),
++ PINCTRL_PIN_GROUP("pon_tod_1pps", pon_tod_1pps),
++ PINCTRL_PIN_GROUP("gsw_tod_1pps", gsw_tod_1pps),
++ PINCTRL_PIN_GROUP("sipo", sipo),
++ PINCTRL_PIN_GROUP("sipo_rclk", sipo_rclk),
++ PINCTRL_PIN_GROUP("mdio", mdio),
++ PINCTRL_PIN_GROUP("uart2", uart2),
++ PINCTRL_PIN_GROUP("uart2_cts_rts", uart2_cts_rts),
++ PINCTRL_PIN_GROUP("hsuart", hsuart),
++ PINCTRL_PIN_GROUP("hsuart_cts_rts", hsuart_cts_rts),
++ PINCTRL_PIN_GROUP("uart4", uart4),
++ PINCTRL_PIN_GROUP("uart5", uart5),
++ PINCTRL_PIN_GROUP("i2c0", i2c0),
++ PINCTRL_PIN_GROUP("i2c1", i2c1),
++ PINCTRL_PIN_GROUP("jtag_udi", jtag_udi),
++ PINCTRL_PIN_GROUP("jtag_dfd", jtag_dfd),
++ PINCTRL_PIN_GROUP("i2s", i2s),
++ PINCTRL_PIN_GROUP("pcm1", pcm1),
++ PINCTRL_PIN_GROUP("pcm2", pcm2),
++ PINCTRL_PIN_GROUP("spi", spi),
++ PINCTRL_PIN_GROUP("spi_quad", spi_quad),
++ PINCTRL_PIN_GROUP("spi_cs1", spi_cs1),
++ PINCTRL_PIN_GROUP("pcm_spi", pcm_spi),
++ PINCTRL_PIN_GROUP("pcm_spi_int", pcm_spi_int),
++ PINCTRL_PIN_GROUP("pcm_spi_rst", pcm_spi_rst),
++ PINCTRL_PIN_GROUP("pcm_spi_cs1", pcm_spi_cs1),
++ PINCTRL_PIN_GROUP("pcm_spi_cs2_p128", pcm_spi_cs2_p128),
++ PINCTRL_PIN_GROUP("pcm_spi_cs2_p156", pcm_spi_cs2_p156),
++ PINCTRL_PIN_GROUP("pcm_spi_cs2", pcm_spi_cs2),
++ PINCTRL_PIN_GROUP("pcm_spi_cs3", pcm_spi_cs3),
++ PINCTRL_PIN_GROUP("pcm_spi_cs4", pcm_spi_cs4),
++ PINCTRL_PIN_GROUP("emmc", emmc),
++ PINCTRL_PIN_GROUP("pnand", pnand),
++ PINCTRL_PIN_GROUP("gpio0", gpio0),
++ PINCTRL_PIN_GROUP("gpio1", gpio1),
++ PINCTRL_PIN_GROUP("gpio2", gpio2),
++ PINCTRL_PIN_GROUP("gpio3", gpio3),
++ PINCTRL_PIN_GROUP("gpio4", gpio4),
++ PINCTRL_PIN_GROUP("gpio5", gpio5),
++ PINCTRL_PIN_GROUP("gpio6", gpio6),
++ PINCTRL_PIN_GROUP("gpio7", gpio7),
++ PINCTRL_PIN_GROUP("gpio8", gpio8),
++ PINCTRL_PIN_GROUP("gpio9", gpio9),
++ PINCTRL_PIN_GROUP("gpio10", gpio10),
++ PINCTRL_PIN_GROUP("gpio11", gpio11),
++ PINCTRL_PIN_GROUP("gpio12", gpio12),
++ PINCTRL_PIN_GROUP("gpio13", gpio13),
++ PINCTRL_PIN_GROUP("gpio14", gpio14),
++ PINCTRL_PIN_GROUP("gpio15", gpio15),
++ PINCTRL_PIN_GROUP("gpio16", gpio16),
++ PINCTRL_PIN_GROUP("gpio17", gpio17),
++ PINCTRL_PIN_GROUP("gpio18", gpio18),
++ PINCTRL_PIN_GROUP("gpio19", gpio19),
++ PINCTRL_PIN_GROUP("gpio20", gpio20),
++ PINCTRL_PIN_GROUP("gpio21", gpio21),
++ PINCTRL_PIN_GROUP("gpio22", gpio22),
++ PINCTRL_PIN_GROUP("gpio23", gpio23),
++ PINCTRL_PIN_GROUP("gpio24", gpio24),
++ PINCTRL_PIN_GROUP("gpio25", gpio25),
++ PINCTRL_PIN_GROUP("gpio26", gpio26),
++ PINCTRL_PIN_GROUP("gpio27", gpio27),
++ PINCTRL_PIN_GROUP("gpio28", gpio28),
++ PINCTRL_PIN_GROUP("gpio29", gpio29),
++ PINCTRL_PIN_GROUP("gpio30", gpio30),
++ PINCTRL_PIN_GROUP("gpio31", gpio31),
++ PINCTRL_PIN_GROUP("gpio32", gpio32),
++ PINCTRL_PIN_GROUP("gpio33", gpio33),
++ PINCTRL_PIN_GROUP("gpio34", gpio34),
++ PINCTRL_PIN_GROUP("gpio35", gpio35),
++ PINCTRL_PIN_GROUP("gpio36", gpio36),
++ PINCTRL_PIN_GROUP("gpio37", gpio37),
++ PINCTRL_PIN_GROUP("gpio38", gpio38),
++ PINCTRL_PIN_GROUP("gpio39", gpio39),
++ PINCTRL_PIN_GROUP("gpio40", gpio40),
++ PINCTRL_PIN_GROUP("gpio41", gpio41),
++ PINCTRL_PIN_GROUP("gpio42", gpio42),
++ PINCTRL_PIN_GROUP("gpio43", gpio43),
++ PINCTRL_PIN_GROUP("gpio44", gpio44),
++ PINCTRL_PIN_GROUP("gpio45", gpio45),
++ PINCTRL_PIN_GROUP("gpio46", gpio46),
++ PINCTRL_PIN_GROUP("gpio47", gpio47),
++ PINCTRL_PIN_GROUP("gpio48", gpio48),
++ PINCTRL_PIN_GROUP("gpio49", gpio49),
++ PINCTRL_PIN_GROUP("pcie_reset0", pcie_reset0),
++ PINCTRL_PIN_GROUP("pcie_reset1", pcie_reset1),
++ PINCTRL_PIN_GROUP("pcie_reset2", pcie_reset2),
++};
++
++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 uart_groups[] = {
++ "uart2", "uart2_cts_rts", "hsuart", "hsuart_cts_rts",
++ "uart4", "uart5"
++};
++static const char *const i2c_groups[] = { "i2c1" };
++static const char *const jtag_groups[] = { "jtag_udi", "jtag_dfd" };
++static const char *const pcm_groups[] = { "pcm1", "pcm2" };
++static const char *const spi_groups[] = { "spi_quad", "spi_cs1" };
++static const char *const pcm_spi_groups[] = {
++ "pcm_spi", "pcm_spi_int", "pcm_spi_rst", "pcm_spi_cs1",
++ "pcm_spi_cs2_p156", "pcm_spi_cs2_p128", "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 gpio_groups[] = { "gpio47", "gpio48", "gpio49" };
++static const char *const pcie_reset_groups[] = {
++ "pcie_reset0", "pcie_reset1", "pcie_reset2"
++};
++static const char *const pwm_groups[] = {
++ "gpio0", "gpio1", "gpio2", "gpio3", "gpio4", "gpio5",
++ "gpio6", "gpio7", "gpio8", "gpio9", "gpio10", "gpio11",
++ "gpio12", "gpio13", "gpio14", "gpio15", "gpio16", "gpio17",
++ "gpio18", "gpio19", "gpio20", "gpio21", "gpio22", "gpio23",
++ "gpio24", "gpio25", "gpio26", "gpio27", "gpio28", "gpio29",
++ "gpio30", "gpio31", "gpio36", "gpio37", "gpio38", "gpio39",
++ "gpio40", "gpio41", "gpio42", "gpio43", "gpio44", "gpio45",
++ "gpio46", "gpio47", "gpio48", "gpio49"
++};
++static const char *const phy1_led0_groups[] = {
++ "gpio33", "gpio34", "gpio35", "gpio42"
++};
++static const char *const phy2_led0_groups[] = {
++ "gpio33", "gpio34", "gpio35", "gpio42"
++};
++static const char *const phy3_led0_groups[] = {
++ "gpio33", "gpio34", "gpio35", "gpio42"
++};
++static const char *const phy4_led0_groups[] = {
++ "gpio33", "gpio34", "gpio35", "gpio42"
++};
++static const char *const phy1_led1_groups[] = {
++ "gpio43", "gpio44", "gpio45", "gpio46"
++};
++static const char *const phy2_led1_groups[] = {
++ "gpio43", "gpio44", "gpio45", "gpio46"
++};
++static const char *const phy3_led1_groups[] = {
++ "gpio43", "gpio44", "gpio45", "gpio46"
++};
++static const char *const phy4_led1_groups[] = {
++ "gpio43", "gpio44", "gpio45", "gpio46"
++};
++
++static const struct airoha_pinctrl_func_group pon_func_group[] = {
++ {
++ .name = "pon",
++ .regmap[0] = {
++ AIROHA_FUNC_MUX,
++ REG_GPIO_PON_MODE,
++ GPIO_PON_MODE_MASK,
++ GPIO_PON_MODE_MASK
++ },
++ .regmap_size = 1,
++ },
++};
++
++static const struct airoha_pinctrl_func_group tod_1pps_func_group[] = {
++ {
++ .name = "pon_tod_1pps",
++ .regmap[0] = {
++ AIROHA_FUNC_MUX,
++ REG_GPIO_2ND_I2C_MODE,
++ PON_TOD_1PPS_MODE_MASK,
++ PON_TOD_1PPS_MODE_MASK
++ },
++ .regmap_size = 1,
++ }, {
++ .name = "gsw_tod_1pps",
++ .regmap[0] = {
++ AIROHA_FUNC_MUX,
++ REG_GPIO_2ND_I2C_MODE,
++ GSW_TOD_1PPS_MODE_MASK,
++ GSW_TOD_1PPS_MODE_MASK
++ },
++ .regmap_size = 1,
++ },
++};
++
++static const struct airoha_pinctrl_func_group sipo_func_group[] = {
++ {
++ .name = "sipo",
++ .regmap[0] = {
++ AIROHA_FUNC_MUX,
++ REG_GPIO_PON_MODE,
++ GPIO_SIPO_MODE_MASK | SIPO_RCLK_MODE_MASK,
++ GPIO_SIPO_MODE_MASK
++ },
++ .regmap_size = 1,
++ }, {
++ .name = "sipo_rclk",
++ .regmap[0] = {
++ AIROHA_FUNC_MUX,
++ REG_GPIO_PON_MODE,
++ GPIO_SIPO_MODE_MASK | SIPO_RCLK_MODE_MASK,
++ GPIO_SIPO_MODE_MASK | SIPO_RCLK_MODE_MASK
++ },
++ .regmap_size = 1,
++ },
++};
++
++static const struct airoha_pinctrl_func_group mdio_func_group[] = {
++ {
++ .name = "mdio",
++ .regmap[0] = {
++ AIROHA_FUNC_MUX,
++ REG_GPIO_2ND_I2C_MODE,
++ GPIO_MDC_IO_MASTER_MODE_MASK,
++ GPIO_MDC_IO_MASTER_MODE_MASK
++ },
++ .regmap[1] = {
++ AIROHA_FUNC_MUX,
++ REG_FORCE_GPIO_EN,
++ FORCE_GPIO_EN(1) | FORCE_GPIO_EN(2),
++ FORCE_GPIO_EN(1) | FORCE_GPIO_EN(2)
++ },
++ .regmap_size = 2,
++ },
++};
++
++static const struct airoha_pinctrl_func_group uart_func_group[] = {
++ {
++ .name = "uart2",
++ .regmap[0] = {
++ AIROHA_FUNC_MUX,
++ REG_GPIO_PON_MODE,
++ GPIO_UART2_MODE_MASK,
++ GPIO_UART2_MODE_MASK
++ },
++ .regmap_size = 1,
++ }, {
++ .name = "uart2_cts_rts",
++ .regmap[0] = {
++ AIROHA_FUNC_MUX,
++ REG_GPIO_PON_MODE,
++ GPIO_UART2_MODE_MASK | GPIO_UART2_CTS_RTS_MODE_MASK,
++ GPIO_UART2_MODE_MASK | GPIO_UART2_CTS_RTS_MODE_MASK
++ },
++ .regmap_size = 1,
++ }, {
++ .name = "hsuart",
++ .regmap[0] = {
++ AIROHA_FUNC_MUX,
++ REG_GPIO_PON_MODE,
++ GPIO_HSUART_MODE_MASK | GPIO_HSUART_CTS_RTS_MODE_MASK,
++ GPIO_HSUART_MODE_MASK
++ },
++ .regmap_size = 1,
++ },
++ {
++ .name = "hsuart_cts_rts",
++ .regmap[0] = {
++ AIROHA_FUNC_MUX,
++ REG_GPIO_PON_MODE,
++ GPIO_HSUART_MODE_MASK | GPIO_HSUART_CTS_RTS_MODE_MASK,
++ GPIO_HSUART_MODE_MASK | GPIO_HSUART_CTS_RTS_MODE_MASK
++ },
++ .regmap_size = 1,
++ }, {
++ .name = "uart4",
++ .regmap[0] = {
++ AIROHA_FUNC_MUX,
++ REG_GPIO_PON_MODE,
++ GPIO_UART4_MODE_MASK,
++ GPIO_UART4_MODE_MASK
++ },
++ .regmap_size = 1,
++ }, {
++ .name = "uart5",
++ .regmap[0] = {
++ AIROHA_FUNC_MUX,
++ REG_GPIO_PON_MODE,
++ GPIO_UART5_MODE_MASK,
++ GPIO_UART5_MODE_MASK
++ },
++ .regmap_size = 1,
++ },
++};
++
++static const struct airoha_pinctrl_func_group i2c_func_group[] = {
++ {
++ .name = "i2c1",
++ .regmap[0] = {
++ AIROHA_FUNC_MUX,
++ REG_GPIO_2ND_I2C_MODE,
++ GPIO_2ND_I2C_MODE_MASK,
++ GPIO_2ND_I2C_MODE_MASK
++ },
++ .regmap_size = 1,
++ },
++};
++
++static const struct airoha_pinctrl_func_group jtag_func_group[] = {
++ {
++ .name = "jtag_udi",
++ .regmap[0] = {
++ AIROHA_FUNC_MUX,
++ REG_NPU_UART_EN,
++ JTAG_UDI_EN_MASK,
++ JTAG_UDI_EN_MASK
++ },
++ .regmap_size = 1,
++ }, {
++ .name = "jtag_dfd",
++ .regmap[0] = {
++ AIROHA_FUNC_MUX,
++ REG_NPU_UART_EN,
++ JTAG_DFD_EN_MASK,
++ JTAG_DFD_EN_MASK
++ },
++ .regmap_size = 1,
++ },
++};
++
++static const struct airoha_pinctrl_func_group pcm_func_group[] = {
++ {
++ .name = "pcm1",
++ .regmap[0] = {
++ AIROHA_FUNC_MUX,
++ REG_GPIO_SPI_CS1_MODE,
++ GPIO_PCM1_MODE_MASK,
++ GPIO_PCM1_MODE_MASK
++ },
++ .regmap_size = 1,
++ }, {
++ .name = "pcm2",
++ .regmap[0] = {
++ AIROHA_FUNC_MUX,
++ REG_GPIO_SPI_CS1_MODE,
++ GPIO_PCM2_MODE_MASK,
++ GPIO_PCM2_MODE_MASK
++ },
++ .regmap_size = 1,
++ },
++};
++
++static const struct airoha_pinctrl_func_group spi_func_group[] = {
++ {
++ .name = "spi_quad",
++ .regmap[0] = {
++ AIROHA_FUNC_MUX,
++ REG_GPIO_SPI_CS1_MODE,
++ GPIO_SPI_QUAD_MODE_MASK,
++ GPIO_SPI_QUAD_MODE_MASK
++ },
++ .regmap_size = 1,
++ }, {
++ .name = "spi_cs1",
++ .regmap[0] = {
++ AIROHA_FUNC_MUX,
++ REG_GPIO_SPI_CS1_MODE,
++ GPIO_SPI_CS1_MODE_MASK,
++ GPIO_SPI_CS1_MODE_MASK
++ },
++ .regmap_size = 1,
++ }, {
++ .name = "spi_cs2",
++ .regmap[0] = {
++ AIROHA_FUNC_MUX,
++ REG_GPIO_SPI_CS1_MODE,
++ GPIO_SPI_CS2_MODE_MASK,
++ GPIO_SPI_CS2_MODE_MASK
++ },
++ .regmap_size = 1,
++ }, {
++ .name = "spi_cs3",
++ .regmap[0] = {
++ AIROHA_FUNC_MUX,
++ REG_GPIO_SPI_CS1_MODE,
++ GPIO_SPI_CS3_MODE_MASK,
++ GPIO_SPI_CS3_MODE_MASK
++ },
++ .regmap_size = 1,
++ }, {
++ .name = "spi_cs4",
++ .regmap[0] = {
++ AIROHA_FUNC_MUX,
++ REG_GPIO_SPI_CS1_MODE,
++ GPIO_SPI_CS4_MODE_MASK,
++ GPIO_SPI_CS4_MODE_MASK
++ },
++ .regmap_size = 1,
++ },
++};
++
++static const struct airoha_pinctrl_func_group 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_p128",
++ .regmap[0] = {
++ AIROHA_FUNC_MUX,
++ REG_GPIO_SPI_CS1_MODE,
++ GPIO_PCM_SPI_CS2_MODE_P128_MASK,
++ GPIO_PCM_SPI_CS2_MODE_P128_MASK
++ },
++ .regmap_size = 1,
++ }, {
++ .name = "pcm_spi_cs2_p156",
++ .regmap[0] = {
++ AIROHA_FUNC_MUX,
++ REG_GPIO_SPI_CS1_MODE,
++ GPIO_PCM_SPI_CS2_MODE_P156_MASK,
++ GPIO_PCM_SPI_CS2_MODE_P156_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",
++ .regmap[0] = {
++ AIROHA_FUNC_MUX,
++ REG_GPIO_2ND_I2C_MODE,
++ GPIO_I2S_MODE_MASK,
++ GPIO_I2S_MODE_MASK
++ },
++ .regmap_size = 1,
++ },
++};
++
++static const struct airoha_pinctrl_func_group emmc_func_group[] = {
++ {
++ .name = "emmc",
++ .regmap[0] = {
++ AIROHA_FUNC_MUX,
++ REG_GPIO_PON_MODE,
++ GPIO_EMMC_MODE_MASK,
++ GPIO_EMMC_MODE_MASK
++ },
++ .regmap_size = 1,
++ },
++};
++
++static const struct airoha_pinctrl_func_group pnand_func_group[] = {
++ {
++ .name = "pnand",
++ .regmap[0] = {
++ AIROHA_FUNC_MUX,
++ REG_GPIO_PON_MODE,
++ GPIO_PARALLEL_NAND_MODE_MASK,
++ GPIO_PARALLEL_NAND_MODE_MASK
++ },
++ .regmap_size = 1,
++ },
++};
++
++static const struct airoha_pinctrl_func_group gpio_func_group[] = {
++ AIROHA_PINCTRL_GPIO_EXT("gpio47", GPIO47_FLASH_MODE_CFG,
++ GPIO_PCIE_RESET0_MASK),
++ AIROHA_PINCTRL_GPIO_EXT("gpio48", GPIO48_FLASH_MODE_CFG,
++ GPIO_PCIE_RESET1_MASK),
++ AIROHA_PINCTRL_GPIO_EXT("gpio49", GPIO49_FLASH_MODE_CFG,
++ GPIO_PCIE_RESET2_MASK),
++};
++
++static const struct airoha_pinctrl_func_group pcie_reset_func_group[] = {
++ {
++ .name = "pcie_reset0",
++ .regmap[0] = {
++ AIROHA_FUNC_MUX,
++ REG_GPIO_PON_MODE,
++ GPIO_PCIE_RESET0_MASK,
++ 0
++ },
++ .regmap_size = 1,
++ }, {
++ .name = "pcie_reset1",
++ .regmap[0] = {
++ AIROHA_FUNC_MUX,
++ REG_GPIO_PON_MODE,
++ GPIO_PCIE_RESET1_MASK,
++ 0
++ },
++ .regmap_size = 1,
++ }, {
++ .name = "pcie_reset2",
++ .regmap[0] = {
++ AIROHA_FUNC_MUX,
++ REG_GPIO_PON_MODE,
++ GPIO_PCIE_RESET2_MASK,
++ 0
++ },
++ .regmap_size = 1,
++ },
++};
++
++static const struct airoha_pinctrl_func_group pwm_func_group[] = {
++ 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_SEC("gpio47", GPIO47_FLASH_MODE_CFG,
++ GPIO_PCIE_RESET0_MASK),
++ AIROHA_PINCTRL_PWM_EXT_SEC("gpio48", GPIO48_FLASH_MODE_CFG,
++ GPIO_PCIE_RESET1_MASK),
++ AIROHA_PINCTRL_PWM_EXT_SEC("gpio49", GPIO49_FLASH_MODE_CFG,
++ GPIO_PCIE_RESET2_MASK),
++};
++
++static const struct airoha_pinctrl_func_group phy1_led0_func_group[] = {
++ AIROHA_PINCTRL_PHY_LED0("gpio33", GPIO_LAN0_LED0_MODE_MASK,
++ LAN0_LED_MAPPING_MASK, LAN0_PHY_LED_MAP(0)),
++ AIROHA_PINCTRL_PHY_LED0("gpio34", GPIO_LAN1_LED0_MODE_MASK,
++ LAN1_LED_MAPPING_MASK, LAN1_PHY_LED_MAP(0)),
++ AIROHA_PINCTRL_PHY_LED0("gpio35", GPIO_LAN2_LED0_MODE_MASK,
++ LAN2_LED_MAPPING_MASK, LAN2_PHY_LED_MAP(0)),
++ AIROHA_PINCTRL_PHY_LED0("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[] = {
++ AIROHA_PINCTRL_PHY_LED0("gpio33", GPIO_LAN0_LED0_MODE_MASK,
++ LAN0_LED_MAPPING_MASK, LAN0_PHY_LED_MAP(1)),
++ AIROHA_PINCTRL_PHY_LED0("gpio34", GPIO_LAN1_LED0_MODE_MASK,
++ LAN1_LED_MAPPING_MASK, LAN1_PHY_LED_MAP(1)),
++ AIROHA_PINCTRL_PHY_LED0("gpio35", GPIO_LAN2_LED0_MODE_MASK,
++ LAN2_LED_MAPPING_MASK, LAN2_PHY_LED_MAP(1)),
++ AIROHA_PINCTRL_PHY_LED0("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[] = {
++ AIROHA_PINCTRL_PHY_LED0("gpio33", GPIO_LAN0_LED0_MODE_MASK,
++ LAN0_LED_MAPPING_MASK, LAN0_PHY_LED_MAP(2)),
++ AIROHA_PINCTRL_PHY_LED0("gpio34", GPIO_LAN1_LED0_MODE_MASK,
++ LAN1_LED_MAPPING_MASK, LAN1_PHY_LED_MAP(2)),
++ AIROHA_PINCTRL_PHY_LED0("gpio35", GPIO_LAN2_LED0_MODE_MASK,
++ LAN2_LED_MAPPING_MASK, LAN2_PHY_LED_MAP(2)),
++ AIROHA_PINCTRL_PHY_LED0("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[] = {
++ AIROHA_PINCTRL_PHY_LED0("gpio33", GPIO_LAN0_LED0_MODE_MASK,
++ LAN0_LED_MAPPING_MASK, LAN0_PHY_LED_MAP(3)),
++ AIROHA_PINCTRL_PHY_LED0("gpio34", GPIO_LAN1_LED0_MODE_MASK,
++ LAN1_LED_MAPPING_MASK, LAN1_PHY_LED_MAP(3)),
++ AIROHA_PINCTRL_PHY_LED0("gpio35", GPIO_LAN2_LED0_MODE_MASK,
++ LAN2_LED_MAPPING_MASK, LAN2_PHY_LED_MAP(3)),
++ AIROHA_PINCTRL_PHY_LED0("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[] = {
++ AIROHA_PINCTRL_PHY_LED1("gpio43", GPIO_LAN0_LED1_MODE_MASK,
++ LAN0_LED_MAPPING_MASK, LAN0_PHY_LED_MAP(0)),
++ AIROHA_PINCTRL_PHY_LED1("gpio44", GPIO_LAN1_LED1_MODE_MASK,
++ LAN1_LED_MAPPING_MASK, LAN1_PHY_LED_MAP(0)),
++ AIROHA_PINCTRL_PHY_LED1("gpio45", GPIO_LAN2_LED1_MODE_MASK,
++ LAN2_LED_MAPPING_MASK, LAN2_PHY_LED_MAP(0)),
++ AIROHA_PINCTRL_PHY_LED1("gpio46", 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[] = {
++ AIROHA_PINCTRL_PHY_LED1("gpio43", GPIO_LAN0_LED1_MODE_MASK,
++ LAN0_LED_MAPPING_MASK, LAN0_PHY_LED_MAP(1)),
++ AIROHA_PINCTRL_PHY_LED1("gpio44", GPIO_LAN1_LED1_MODE_MASK,
++ LAN1_LED_MAPPING_MASK, LAN1_PHY_LED_MAP(1)),
++ AIROHA_PINCTRL_PHY_LED1("gpio45", GPIO_LAN2_LED1_MODE_MASK,
++ LAN2_LED_MAPPING_MASK, LAN2_PHY_LED_MAP(1)),
++ AIROHA_PINCTRL_PHY_LED1("gpio46", 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[] = {
++ AIROHA_PINCTRL_PHY_LED1("gpio43", GPIO_LAN0_LED1_MODE_MASK,
++ LAN0_LED_MAPPING_MASK, LAN0_PHY_LED_MAP(2)),
++ AIROHA_PINCTRL_PHY_LED1("gpio44", GPIO_LAN1_LED1_MODE_MASK,
++ LAN1_LED_MAPPING_MASK, LAN1_PHY_LED_MAP(2)),
++ AIROHA_PINCTRL_PHY_LED1("gpio45", GPIO_LAN2_LED1_MODE_MASK,
++ LAN2_LED_MAPPING_MASK, LAN2_PHY_LED_MAP(2)),
++ AIROHA_PINCTRL_PHY_LED1("gpio46", 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[] = {
++ AIROHA_PINCTRL_PHY_LED1("gpio43", GPIO_LAN0_LED1_MODE_MASK,
++ LAN0_LED_MAPPING_MASK, LAN0_PHY_LED_MAP(3)),
++ AIROHA_PINCTRL_PHY_LED1("gpio44", GPIO_LAN1_LED1_MODE_MASK,
++ LAN1_LED_MAPPING_MASK, LAN1_PHY_LED_MAP(3)),
++ AIROHA_PINCTRL_PHY_LED1("gpio45", GPIO_LAN2_LED1_MODE_MASK,
++ LAN2_LED_MAPPING_MASK, LAN2_PHY_LED_MAP(3)),
++ AIROHA_PINCTRL_PHY_LED1("gpio46", GPIO_LAN3_LED1_MODE_MASK,
++ LAN3_LED_MAPPING_MASK, LAN3_PHY_LED_MAP(3)),
++};
++
++static const struct airoha_pinctrl_func 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("gpio", gpio),
++ 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 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),
++ PINCTRL_CONF_DESC(3, REG_I2C_SDA_PU, I2C_SCL_PU_MASK),
++ PINCTRL_CONF_DESC(4, REG_I2C_SDA_PU, SPI_CS0_PU_MASK),
++ PINCTRL_CONF_DESC(5, REG_I2C_SDA_PU, SPI_CLK_PU_MASK),
++ PINCTRL_CONF_DESC(6, REG_I2C_SDA_PU, SPI_MOSI_PU_MASK),
++ PINCTRL_CONF_DESC(7, REG_I2C_SDA_PU, SPI_MISO_PU_MASK),
++ PINCTRL_CONF_DESC(13, REG_GPIO_L_PU, BIT(0)),
++ PINCTRL_CONF_DESC(14, REG_GPIO_L_PU, BIT(1)),
++ PINCTRL_CONF_DESC(15, REG_GPIO_L_PU, BIT(2)),
++ PINCTRL_CONF_DESC(16, REG_GPIO_L_PU, BIT(3)),
++ PINCTRL_CONF_DESC(17, REG_GPIO_L_PU, BIT(4)),
++ PINCTRL_CONF_DESC(18, REG_GPIO_L_PU, BIT(5)),
++ PINCTRL_CONF_DESC(19, REG_GPIO_L_PU, BIT(6)),
++ PINCTRL_CONF_DESC(20, REG_GPIO_L_PU, BIT(7)),
++ PINCTRL_CONF_DESC(21, REG_GPIO_L_PU, BIT(8)),
++ PINCTRL_CONF_DESC(22, REG_GPIO_L_PU, BIT(9)),
++ PINCTRL_CONF_DESC(23, REG_GPIO_L_PU, BIT(10)),
++ PINCTRL_CONF_DESC(24, REG_GPIO_L_PU, BIT(11)),
++ PINCTRL_CONF_DESC(25, REG_GPIO_L_PU, BIT(12)),
++ PINCTRL_CONF_DESC(26, REG_GPIO_L_PU, BIT(13)),
++ PINCTRL_CONF_DESC(27, REG_GPIO_L_PU, BIT(14)),
++ PINCTRL_CONF_DESC(28, REG_GPIO_L_PU, BIT(15)),
++ PINCTRL_CONF_DESC(29, REG_GPIO_L_PU, BIT(16)),
++ PINCTRL_CONF_DESC(30, REG_GPIO_L_PU, BIT(17)),
++ PINCTRL_CONF_DESC(31, REG_GPIO_L_PU, BIT(18)),
++ PINCTRL_CONF_DESC(32, REG_GPIO_L_PU, BIT(19)),
++ PINCTRL_CONF_DESC(33, REG_GPIO_L_PU, BIT(20)),
++ PINCTRL_CONF_DESC(34, REG_GPIO_L_PU, BIT(21)),
++ PINCTRL_CONF_DESC(35, REG_GPIO_L_PU, BIT(22)),
++ PINCTRL_CONF_DESC(36, REG_GPIO_L_PU, BIT(23)),
++ PINCTRL_CONF_DESC(37, REG_GPIO_L_PU, BIT(24)),
++ PINCTRL_CONF_DESC(38, REG_GPIO_L_PU, BIT(25)),
++ PINCTRL_CONF_DESC(39, REG_GPIO_L_PU, BIT(26)),
++ PINCTRL_CONF_DESC(40, REG_GPIO_L_PU, BIT(27)),
++ PINCTRL_CONF_DESC(41, REG_GPIO_L_PU, BIT(28)),
++ PINCTRL_CONF_DESC(42, REG_GPIO_L_PU, BIT(29)),
++ PINCTRL_CONF_DESC(43, REG_GPIO_L_PU, BIT(30)),
++ PINCTRL_CONF_DESC(44, REG_GPIO_L_PU, BIT(31)),
++ PINCTRL_CONF_DESC(45, REG_GPIO_H_PU, BIT(0)),
++ PINCTRL_CONF_DESC(46, REG_GPIO_H_PU, BIT(1)),
++ PINCTRL_CONF_DESC(47, REG_GPIO_H_PU, BIT(2)),
++ PINCTRL_CONF_DESC(48, REG_GPIO_H_PU, BIT(3)),
++ PINCTRL_CONF_DESC(49, REG_GPIO_H_PU, BIT(4)),
++ PINCTRL_CONF_DESC(50, REG_GPIO_H_PU, BIT(5)),
++ PINCTRL_CONF_DESC(51, REG_GPIO_H_PU, BIT(6)),
++ PINCTRL_CONF_DESC(52, REG_GPIO_H_PU, BIT(7)),
++ PINCTRL_CONF_DESC(53, REG_GPIO_H_PU, BIT(8)),
++ PINCTRL_CONF_DESC(54, REG_GPIO_H_PU, BIT(9)),
++ PINCTRL_CONF_DESC(55, REG_GPIO_H_PU, BIT(10)),
++ PINCTRL_CONF_DESC(56, REG_GPIO_H_PU, BIT(11)),
++ PINCTRL_CONF_DESC(57, REG_GPIO_H_PU, BIT(12)),
++ PINCTRL_CONF_DESC(58, REG_GPIO_H_PU, BIT(13)),
++ PINCTRL_CONF_DESC(59, REG_GPIO_H_PU, BIT(14)),
++ PINCTRL_CONF_DESC(60, REG_I2C_SDA_PU, PCIE0_RESET_PU_MASK),
++ PINCTRL_CONF_DESC(61, REG_I2C_SDA_PU, PCIE1_RESET_PU_MASK),
++ PINCTRL_CONF_DESC(62, REG_I2C_SDA_PU, PCIE2_RESET_PU_MASK),
++};
++
++static const struct airoha_pinctrl_conf 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),
++ PINCTRL_CONF_DESC(3, REG_I2C_SDA_PD, I2C_SCL_PD_MASK),
++ PINCTRL_CONF_DESC(4, REG_I2C_SDA_PD, SPI_CS0_PD_MASK),
++ PINCTRL_CONF_DESC(5, REG_I2C_SDA_PD, SPI_CLK_PD_MASK),
++ PINCTRL_CONF_DESC(6, REG_I2C_SDA_PD, SPI_MOSI_PD_MASK),
++ PINCTRL_CONF_DESC(7, REG_I2C_SDA_PD, SPI_MISO_PD_MASK),
++ PINCTRL_CONF_DESC(13, REG_GPIO_L_PD, BIT(0)),
++ PINCTRL_CONF_DESC(14, REG_GPIO_L_PD, BIT(1)),
++ PINCTRL_CONF_DESC(15, REG_GPIO_L_PD, BIT(2)),
++ PINCTRL_CONF_DESC(16, REG_GPIO_L_PD, BIT(3)),
++ PINCTRL_CONF_DESC(17, REG_GPIO_L_PD, BIT(4)),
++ PINCTRL_CONF_DESC(18, REG_GPIO_L_PD, BIT(5)),
++ PINCTRL_CONF_DESC(19, REG_GPIO_L_PD, BIT(6)),
++ PINCTRL_CONF_DESC(20, REG_GPIO_L_PD, BIT(7)),
++ PINCTRL_CONF_DESC(21, REG_GPIO_L_PD, BIT(8)),
++ PINCTRL_CONF_DESC(22, REG_GPIO_L_PD, BIT(9)),
++ PINCTRL_CONF_DESC(23, REG_GPIO_L_PD, BIT(10)),
++ PINCTRL_CONF_DESC(24, REG_GPIO_L_PD, BIT(11)),
++ PINCTRL_CONF_DESC(25, REG_GPIO_L_PD, BIT(12)),
++ PINCTRL_CONF_DESC(26, REG_GPIO_L_PD, BIT(13)),
++ PINCTRL_CONF_DESC(27, REG_GPIO_L_PD, BIT(14)),
++ PINCTRL_CONF_DESC(28, REG_GPIO_L_PD, BIT(15)),
++ PINCTRL_CONF_DESC(29, REG_GPIO_L_PD, BIT(16)),
++ PINCTRL_CONF_DESC(30, REG_GPIO_L_PD, BIT(17)),
++ PINCTRL_CONF_DESC(31, REG_GPIO_L_PD, BIT(18)),
++ PINCTRL_CONF_DESC(32, REG_GPIO_L_PD, BIT(19)),
++ PINCTRL_CONF_DESC(33, REG_GPIO_L_PD, BIT(20)),
++ PINCTRL_CONF_DESC(34, REG_GPIO_L_PD, BIT(21)),
++ PINCTRL_CONF_DESC(35, REG_GPIO_L_PD, BIT(22)),
++ PINCTRL_CONF_DESC(36, REG_GPIO_L_PD, BIT(23)),
++ PINCTRL_CONF_DESC(37, REG_GPIO_L_PD, BIT(24)),
++ PINCTRL_CONF_DESC(38, REG_GPIO_L_PD, BIT(25)),
++ PINCTRL_CONF_DESC(39, REG_GPIO_L_PD, BIT(26)),
++ PINCTRL_CONF_DESC(40, REG_GPIO_L_PD, BIT(27)),
++ PINCTRL_CONF_DESC(41, REG_GPIO_L_PD, BIT(28)),
++ PINCTRL_CONF_DESC(42, REG_GPIO_L_PD, BIT(29)),
++ PINCTRL_CONF_DESC(43, REG_GPIO_L_PD, BIT(30)),
++ PINCTRL_CONF_DESC(44, REG_GPIO_L_PD, BIT(31)),
++ PINCTRL_CONF_DESC(45, REG_GPIO_H_PD, BIT(0)),
++ PINCTRL_CONF_DESC(46, REG_GPIO_H_PD, BIT(1)),
++ PINCTRL_CONF_DESC(47, REG_GPIO_H_PD, BIT(2)),
++ PINCTRL_CONF_DESC(48, REG_GPIO_H_PD, BIT(3)),
++ PINCTRL_CONF_DESC(49, REG_GPIO_H_PD, BIT(4)),
++ PINCTRL_CONF_DESC(50, REG_GPIO_H_PD, BIT(5)),
++ PINCTRL_CONF_DESC(51, REG_GPIO_H_PD, BIT(6)),
++ PINCTRL_CONF_DESC(52, REG_GPIO_H_PD, BIT(7)),
++ PINCTRL_CONF_DESC(53, REG_GPIO_H_PD, BIT(8)),
++ PINCTRL_CONF_DESC(54, REG_GPIO_H_PD, BIT(9)),
++ PINCTRL_CONF_DESC(55, REG_GPIO_H_PD, BIT(10)),
++ PINCTRL_CONF_DESC(56, REG_GPIO_H_PD, BIT(11)),
++ PINCTRL_CONF_DESC(57, REG_GPIO_H_PD, BIT(12)),
++ PINCTRL_CONF_DESC(58, REG_GPIO_H_PD, BIT(13)),
++ PINCTRL_CONF_DESC(59, REG_GPIO_H_PD, BIT(14)),
++ PINCTRL_CONF_DESC(60, REG_I2C_SDA_PD, PCIE0_RESET_PD_MASK),
++ PINCTRL_CONF_DESC(61, REG_I2C_SDA_PD, PCIE1_RESET_PD_MASK),
++ PINCTRL_CONF_DESC(62, REG_I2C_SDA_PD, PCIE2_RESET_PD_MASK),
++};
++
++static const struct airoha_pinctrl_conf 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),
++ PINCTRL_CONF_DESC(3, REG_I2C_SDA_E2, I2C_SCL_E2_MASK),
++ PINCTRL_CONF_DESC(4, REG_I2C_SDA_E2, SPI_CS0_E2_MASK),
++ PINCTRL_CONF_DESC(5, REG_I2C_SDA_E2, SPI_CLK_E2_MASK),
++ PINCTRL_CONF_DESC(6, REG_I2C_SDA_E2, SPI_MOSI_E2_MASK),
++ PINCTRL_CONF_DESC(7, REG_I2C_SDA_E2, SPI_MISO_E2_MASK),
++ PINCTRL_CONF_DESC(13, REG_GPIO_L_E2, BIT(0)),
++ PINCTRL_CONF_DESC(14, REG_GPIO_L_E2, BIT(1)),
++ PINCTRL_CONF_DESC(15, REG_GPIO_L_E2, BIT(2)),
++ PINCTRL_CONF_DESC(16, REG_GPIO_L_E2, BIT(3)),
++ PINCTRL_CONF_DESC(17, REG_GPIO_L_E2, BIT(4)),
++ PINCTRL_CONF_DESC(18, REG_GPIO_L_E2, BIT(5)),
++ PINCTRL_CONF_DESC(19, REG_GPIO_L_E2, BIT(6)),
++ PINCTRL_CONF_DESC(20, REG_GPIO_L_E2, BIT(7)),
++ PINCTRL_CONF_DESC(21, REG_GPIO_L_E2, BIT(8)),
++ PINCTRL_CONF_DESC(22, REG_GPIO_L_E2, BIT(9)),
++ PINCTRL_CONF_DESC(23, REG_GPIO_L_E2, BIT(10)),
++ PINCTRL_CONF_DESC(24, REG_GPIO_L_E2, BIT(11)),
++ PINCTRL_CONF_DESC(25, REG_GPIO_L_E2, BIT(12)),
++ PINCTRL_CONF_DESC(26, REG_GPIO_L_E2, BIT(13)),
++ PINCTRL_CONF_DESC(27, REG_GPIO_L_E2, BIT(14)),
++ PINCTRL_CONF_DESC(28, REG_GPIO_L_E2, BIT(15)),
++ PINCTRL_CONF_DESC(29, REG_GPIO_L_E2, BIT(16)),
++ PINCTRL_CONF_DESC(30, REG_GPIO_L_E2, BIT(17)),
++ PINCTRL_CONF_DESC(31, REG_GPIO_L_E2, BIT(18)),
++ PINCTRL_CONF_DESC(32, REG_GPIO_L_E2, BIT(19)),
++ PINCTRL_CONF_DESC(33, REG_GPIO_L_E2, BIT(20)),
++ PINCTRL_CONF_DESC(34, REG_GPIO_L_E2, BIT(21)),
++ PINCTRL_CONF_DESC(35, REG_GPIO_L_E2, BIT(22)),
++ PINCTRL_CONF_DESC(36, REG_GPIO_L_E2, BIT(23)),
++ PINCTRL_CONF_DESC(37, REG_GPIO_L_E2, BIT(24)),
++ PINCTRL_CONF_DESC(38, REG_GPIO_L_E2, BIT(25)),
++ PINCTRL_CONF_DESC(39, REG_GPIO_L_E2, BIT(26)),
++ PINCTRL_CONF_DESC(40, REG_GPIO_L_E2, BIT(27)),
++ PINCTRL_CONF_DESC(41, REG_GPIO_L_E2, BIT(28)),
++ PINCTRL_CONF_DESC(42, REG_GPIO_L_E2, BIT(29)),
++ PINCTRL_CONF_DESC(43, REG_GPIO_L_E2, BIT(30)),
++ PINCTRL_CONF_DESC(44, REG_GPIO_L_E2, BIT(31)),
++ PINCTRL_CONF_DESC(45, REG_GPIO_H_E2, BIT(0)),
++ PINCTRL_CONF_DESC(46, REG_GPIO_H_E2, BIT(1)),
++ PINCTRL_CONF_DESC(47, REG_GPIO_H_E2, BIT(2)),
++ PINCTRL_CONF_DESC(48, REG_GPIO_H_E2, BIT(3)),
++ PINCTRL_CONF_DESC(49, REG_GPIO_H_E2, BIT(4)),
++ PINCTRL_CONF_DESC(50, REG_GPIO_H_E2, BIT(5)),
++ PINCTRL_CONF_DESC(51, REG_GPIO_H_E2, BIT(6)),
++ PINCTRL_CONF_DESC(52, REG_GPIO_H_E2, BIT(7)),
++ PINCTRL_CONF_DESC(53, REG_GPIO_H_E2, BIT(8)),
++ PINCTRL_CONF_DESC(54, REG_GPIO_H_E2, BIT(9)),
++ PINCTRL_CONF_DESC(55, REG_GPIO_H_E2, BIT(10)),
++ PINCTRL_CONF_DESC(56, REG_GPIO_H_E2, BIT(11)),
++ PINCTRL_CONF_DESC(57, REG_GPIO_H_E2, BIT(12)),
++ PINCTRL_CONF_DESC(58, REG_GPIO_H_E2, BIT(13)),
++ PINCTRL_CONF_DESC(59, REG_GPIO_H_E2, BIT(14)),
++ PINCTRL_CONF_DESC(60, REG_I2C_SDA_E2, PCIE0_RESET_E2_MASK),
++ PINCTRL_CONF_DESC(61, REG_I2C_SDA_E2, PCIE1_RESET_E2_MASK),
++ PINCTRL_CONF_DESC(62, REG_I2C_SDA_E2, PCIE2_RESET_E2_MASK),
++};
++
++static const struct airoha_pinctrl_conf 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),
++ PINCTRL_CONF_DESC(3, REG_I2C_SDA_E4, I2C_SCL_E4_MASK),
++ PINCTRL_CONF_DESC(4, REG_I2C_SDA_E4, SPI_CS0_E4_MASK),
++ PINCTRL_CONF_DESC(5, REG_I2C_SDA_E4, SPI_CLK_E4_MASK),
++ PINCTRL_CONF_DESC(6, REG_I2C_SDA_E4, SPI_MOSI_E4_MASK),
++ PINCTRL_CONF_DESC(7, REG_I2C_SDA_E4, SPI_MISO_E4_MASK),
++ PINCTRL_CONF_DESC(13, REG_GPIO_L_E4, BIT(0)),
++ PINCTRL_CONF_DESC(14, REG_GPIO_L_E4, BIT(1)),
++ PINCTRL_CONF_DESC(15, REG_GPIO_L_E4, BIT(2)),
++ PINCTRL_CONF_DESC(16, REG_GPIO_L_E4, BIT(3)),
++ PINCTRL_CONF_DESC(17, REG_GPIO_L_E4, BIT(4)),
++ PINCTRL_CONF_DESC(18, REG_GPIO_L_E4, BIT(5)),
++ PINCTRL_CONF_DESC(19, REG_GPIO_L_E4, BIT(6)),
++ PINCTRL_CONF_DESC(20, REG_GPIO_L_E4, BIT(7)),
++ PINCTRL_CONF_DESC(21, REG_GPIO_L_E4, BIT(8)),
++ PINCTRL_CONF_DESC(22, REG_GPIO_L_E4, BIT(9)),
++ PINCTRL_CONF_DESC(23, REG_GPIO_L_E4, BIT(10)),
++ PINCTRL_CONF_DESC(24, REG_GPIO_L_E4, BIT(11)),
++ PINCTRL_CONF_DESC(25, REG_GPIO_L_E4, BIT(12)),
++ PINCTRL_CONF_DESC(26, REG_GPIO_L_E4, BIT(13)),
++ PINCTRL_CONF_DESC(27, REG_GPIO_L_E4, BIT(14)),
++ PINCTRL_CONF_DESC(28, REG_GPIO_L_E4, BIT(15)),
++ PINCTRL_CONF_DESC(29, REG_GPIO_L_E4, BIT(16)),
++ PINCTRL_CONF_DESC(30, REG_GPIO_L_E4, BIT(17)),
++ PINCTRL_CONF_DESC(31, REG_GPIO_L_E4, BIT(18)),
++ PINCTRL_CONF_DESC(32, REG_GPIO_L_E4, BIT(19)),
++ PINCTRL_CONF_DESC(33, REG_GPIO_L_E4, BIT(20)),
++ PINCTRL_CONF_DESC(34, REG_GPIO_L_E4, BIT(21)),
++ PINCTRL_CONF_DESC(35, REG_GPIO_L_E4, BIT(22)),
++ PINCTRL_CONF_DESC(36, REG_GPIO_L_E4, BIT(23)),
++ PINCTRL_CONF_DESC(37, REG_GPIO_L_E4, BIT(24)),
++ PINCTRL_CONF_DESC(38, REG_GPIO_L_E4, BIT(25)),
++ PINCTRL_CONF_DESC(39, REG_GPIO_L_E4, BIT(26)),
++ PINCTRL_CONF_DESC(40, REG_GPIO_L_E4, BIT(27)),
++ PINCTRL_CONF_DESC(41, REG_GPIO_L_E4, BIT(28)),
++ PINCTRL_CONF_DESC(42, REG_GPIO_L_E4, BIT(29)),
++ PINCTRL_CONF_DESC(43, REG_GPIO_L_E4, BIT(30)),
++ PINCTRL_CONF_DESC(44, REG_GPIO_L_E4, BIT(31)),
++ PINCTRL_CONF_DESC(45, REG_GPIO_H_E4, BIT(0)),
++ PINCTRL_CONF_DESC(46, REG_GPIO_H_E4, BIT(1)),
++ PINCTRL_CONF_DESC(47, REG_GPIO_H_E4, BIT(2)),
++ PINCTRL_CONF_DESC(48, REG_GPIO_H_E4, BIT(3)),
++ PINCTRL_CONF_DESC(49, REG_GPIO_H_E4, BIT(4)),
++ PINCTRL_CONF_DESC(50, REG_GPIO_H_E4, BIT(5)),
++ PINCTRL_CONF_DESC(51, REG_GPIO_H_E4, BIT(6)),
++ PINCTRL_CONF_DESC(52, REG_GPIO_H_E4, BIT(7)),
++ PINCTRL_CONF_DESC(53, REG_GPIO_H_E4, BIT(8)),
++ PINCTRL_CONF_DESC(54, REG_GPIO_H_E4, BIT(9)),
++ PINCTRL_CONF_DESC(55, REG_GPIO_H_E4, BIT(10)),
++ PINCTRL_CONF_DESC(56, REG_GPIO_H_E4, BIT(11)),
++ PINCTRL_CONF_DESC(57, REG_GPIO_H_E4, BIT(12)),
++ PINCTRL_CONF_DESC(58, REG_GPIO_H_E4, BIT(13)),
++ PINCTRL_CONF_DESC(59, REG_GPIO_H_E4, BIT(14)),
++ PINCTRL_CONF_DESC(60, REG_I2C_SDA_E4, PCIE0_RESET_E4_MASK),
++ PINCTRL_CONF_DESC(61, REG_I2C_SDA_E4, PCIE1_RESET_E4_MASK),
++ PINCTRL_CONF_DESC(62, REG_I2C_SDA_E4, PCIE2_RESET_E4_MASK),
++};
++
++static const struct airoha_pinctrl_conf pinctrl_pcie_rst_od_conf[] = {
++ PINCTRL_CONF_DESC(60, REG_PCIE_RESET_OD, PCIE0_RESET_OD_MASK),
++ PINCTRL_CONF_DESC(61, REG_PCIE_RESET_OD, PCIE1_RESET_OD_MASK),
++ PINCTRL_CONF_DESC(62, REG_PCIE_RESET_OD, PCIE2_RESET_OD_MASK),
++};
++
++static const struct airoha_pinctrl_match_data pinctrl_match_data = {
++ .gpio_offs = 13,
++ .gpio_pin_cnt = 50,
++ .chip_scu_compatible = "airoha,en7581-chip-scu",
++ .pins = pinctrl_pins,
++ .num_pins = ARRAY_SIZE(pinctrl_pins),
++ .grps = pinctrl_groups,
++ .num_grps = ARRAY_SIZE(pinctrl_groups),
++ .funcs = pinctrl_funcs,
++ .num_funcs = ARRAY_SIZE(pinctrl_funcs),
++ .confs_info = {
++ [AIROHA_PINCTRL_CONFS_PULLUP] = {
++ .confs = pinctrl_pullup_conf,
++ .num_confs = ARRAY_SIZE(pinctrl_pullup_conf),
++ },
++ [AIROHA_PINCTRL_CONFS_PULLDOWN] = {
++ .confs = pinctrl_pulldown_conf,
++ .num_confs = ARRAY_SIZE(pinctrl_pulldown_conf),
++ },
++ [AIROHA_PINCTRL_CONFS_DRIVE_E2] = {
++ .confs = pinctrl_drive_e2_conf,
++ .num_confs = ARRAY_SIZE(pinctrl_drive_e2_conf),
++ },
++ [AIROHA_PINCTRL_CONFS_DRIVE_E4] = {
++ .confs = pinctrl_drive_e4_conf,
++ .num_confs = ARRAY_SIZE(pinctrl_drive_e4_conf),
++ },
++ [AIROHA_PINCTRL_CONFS_PCIE_RST_OD] = {
++ .confs = pinctrl_pcie_rst_od_conf,
++ .num_confs = ARRAY_SIZE(pinctrl_pcie_rst_od_conf),
++ },
++ },
++};
++
++static const struct udevice_id pinctrl_of_match[] = {
++ { .compatible = "airoha,en7581-pinctrl",
++ .data = (uintptr_t)&pinctrl_match_data },
++ { .compatible = "airoha,an7581-pinctrl",
++ .data = (uintptr_t)&pinctrl_match_data },
++ { /* sentinel */ }
++};
++
++U_BOOT_DRIVER(airoha_an7581_pinctrl) = {
++ .name = "airoha-an7581-pinctrl",
++ .id = UCLASS_PINCTRL,
++ .of_match = of_match_ptr(pinctrl_of_match),
++ .probe = airoha_pinctrl_probe,
++ .bind = airoha_pinctrl_bind,
++ .priv_auto = sizeof(struct airoha_pinctrl),
++ .ops = &airoha_pinctrl_ops,
++};
+--
+2.53.0
+
--- /dev/null
+From a53ca68fcb463b9beaedb0bf0aa9eaf4f199d2c3 Mon Sep 17 00:00:00 2001
+From: Mikhail Kshevetskiy <mikhail.kshevetskiy@iopsys.eu>
+Date: Sun, 26 Apr 2026 23:59:04 +0300
+Subject: [PATCH 07/29] pinctrl: airoha: add pin controller and gpio driver for
+ AN7583 SoC
+
+This patch adds U-Boot pin controller and gpio driver for Airoha AN7583 SoC.
+
+Signed-off-by: Mikhail Kshevetskiy <mikhail.kshevetskiy@iopsys.eu>
+Reviewed-by: David Lechner <dlechner@baylibre.com>
+---
+ drivers/pinctrl/airoha/Kconfig | 5 +
+ drivers/pinctrl/airoha/Makefile | 1 +
+ drivers/pinctrl/airoha/pinctrl-an7583.c | 1492 +++++++++++++++++++++++
+ 3 files changed, 1498 insertions(+)
+ create mode 100644 drivers/pinctrl/airoha/pinctrl-an7583.c
+
+diff --git a/drivers/pinctrl/airoha/Kconfig b/drivers/pinctrl/airoha/Kconfig
+index ae387f70b22..5d3e29c8fd6 100644
+--- a/drivers/pinctrl/airoha/Kconfig
++++ b/drivers/pinctrl/airoha/Kconfig
+@@ -14,3 +14,8 @@ config PINCTRL_AIROHA_AN7581
+ bool "Airoha AN7581 pin controller and gpio driver"
+ depends on TARGET_AN7581
+ select PINCTRL_AIROHA
++
++config PINCTRL_AIROHA_AN7583
++ bool "Airoha AN7583 pin controller and gpio driver"
++ depends on TARGET_AN7583
++ select PINCTRL_AIROHA
+diff --git a/drivers/pinctrl/airoha/Makefile b/drivers/pinctrl/airoha/Makefile
+index 909bd9a04d9..c8c99dd22f8 100644
+--- a/drivers/pinctrl/airoha/Makefile
++++ b/drivers/pinctrl/airoha/Makefile
+@@ -3,3 +3,4 @@
+ obj-$(CONFIG_PINCTRL_AIROHA) += pinctrl-airoha.o
+
+ obj-$(CONFIG_PINCTRL_AIROHA_AN7581) += pinctrl-an7581.o
++obj-$(CONFIG_PINCTRL_AIROHA_AN7583) += pinctrl-an7583.o
+diff --git a/drivers/pinctrl/airoha/pinctrl-an7583.c b/drivers/pinctrl/airoha/pinctrl-an7583.c
+new file mode 100644
+index 00000000000..2f6f3651ec8
+--- /dev/null
++++ b/drivers/pinctrl/airoha/pinctrl-an7583.c
+@@ -0,0 +1,1492 @@
++// SPDX-License-Identifier: GPL-2.0-only
++/*
++ * Author: Lorenzo Bianconi <lorenzo@kernel.org>
++ * Author: Benjamin Larsson <benjamin.larsson@genexis.eu>
++ * Author: Markus Gothe <markus.gothe@genexis.eu>
++ */
++
++#include "airoha-common.h"
++
++/* MUX */
++#define REG_SW_TOD_1PPS_MODE 0x0214
++#define GPIO_LAN3_LED1_MODE_MASK BIT(10)
++#define GPIO_LAN3_LED0_MODE_MASK BIT(9)
++#define GPIO_LAN2_LED1_MODE_MASK BIT(8)
++#define GPIO_LAN2_LED0_MODE_MASK BIT(7)
++#define GPIO_LAN1_LED1_MODE_MASK BIT(6)
++#define GPIO_LAN1_LED0_MODE_MASK BIT(5)
++#define GPIO_LAN0_LED1_MODE_MASK BIT(4)
++#define GPIO_LAN0_LED0_MODE_MASK BIT(3)
++#define PON_TOD_1PPS_MODE_MASK BIT(2)
++#define GSW_TOD_1PPS_MODE_MASK BIT(1)
++
++#define REG_GPIO_SPI_CS1_MODE 0x0218
++#define GPIO_MDC_IO_MASTER_MODE_MASK BIT(22)
++#define GPIO_PCM_SPI_CS4_MODE_MASK BIT(21)
++#define GPIO_PCM_SPI_CS3_MODE_MASK BIT(20)
++#define 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)
++#define GPIO_PCM1_MODE_MASK BIT(12)
++#define GPIO_PCM_INT_MODE_MASK BIT(9)
++#define GPIO_PCM_RESET_MODE_MASK BIT(8)
++#define GPIO_SPI_QUAD_MODE_MASK BIT(4)
++#define GPIO_SPI_CS4_MODE_MASK BIT(3)
++#define GPIO_SPI_CS3_MODE_MASK BIT(2)
++#define GPIO_SPI_CS2_MODE_MASK BIT(1)
++#define GPIO_SPI_CS1_MODE_MASK BIT(0)
++
++#define REG_GPIO_PON_MODE 0x021c
++#define GPIO_PON_ALT_MODE_MASK BIT(27)
++#define MDIO_0_GPIO_MODE_MASK BIT(26)
++#define MDC_0_GPIO_MODE_MASK BIT(25)
++#define UART_RXD_GPIO_MODE_MASK BIT(24)
++#define UART_TXD_GPIO_MODE_MASK BIT(23)
++#define SPI_MISO_GPIO_MODE_MASK BIT(22)
++#define SPI_MOSI_GPIO_MODE_MASK BIT(21)
++#define SPI_CS_GPIO_MODE_MASK BIT(20)
++#define SPI_CLK_GPIO_MODE_MASK BIT(19)
++#define I2C1_SDA_GPIO_MODE_MASK BIT(18)
++#define I2C1_SCL_GPIO_MODE_MASK BIT(17)
++#define I2C0_SDA_GPIO_MODE_MASK BIT(16)
++#define I2C0_SCL_GPIO_MODE_MASK BIT(15)
++#define GPIO_PARALLEL_NAND_MODE_MASK BIT(14)
++#define GPIO_SGMII_MDIO_MODE_MASK BIT(13)
++#define GPIO_OLT_MODE_MASK BIT(12)
++#define SIPO_RCLK_MODE_MASK BIT(11)
++#define GPIO_PCIE_RESET1_MASK BIT(10)
++#define GPIO_PCIE_RESET0_MASK BIT(9)
++#define GPIO_UART5_MODE_MASK BIT(8)
++#define GPIO_UART4_MODE_MASK BIT(7)
++#define GPIO_HSUART_CTS_RTS_MODE_MASK BIT(6)
++#define GPIO_HSUART_MODE_MASK BIT(5)
++#define GPIO_UART2_CTS_RTS_MODE_MASK BIT(4)
++#define GPIO_UART2_MODE_MASK BIT(3)
++#define GPIO_SIPO_MODE_MASK BIT(2)
++#define GPIO_EMMC_MODE_MASK BIT(1)
++#define GPIO_PON_MODE_MASK BIT(0)
++
++#define REG_NPU_UART_EN 0x0224
++#define JTAG_UDI_EN_MASK BIT(4)
++#define JTAG_DFD_EN_MASK BIT(3)
++#define NPU_UART_EN_MASK BIT(2)
++
++#define REG_FORCE_GPIO_EN 0x0228
++#define FORCE_GPIO_EN(n) BIT(n)
++
++/* LED MAP */
++#define REG_LAN_LED0_MAPPING 0x027c
++#define REG_LAN_LED1_MAPPING 0x0280
++
++#define LAN4_LED_MAPPING_MASK GENMASK(18, 16)
++#define LAN4_PHY_LED_MAP(_n) FIELD_PREP_CONST(LAN4_LED_MAPPING_MASK, (_n))
++
++#define LAN3_LED_MAPPING_MASK GENMASK(14, 12)
++#define LAN3_PHY_LED_MAP(_n) FIELD_PREP_CONST(LAN3_LED_MAPPING_MASK, (_n))
++
++#define LAN2_LED_MAPPING_MASK GENMASK(10, 8)
++#define LAN2_PHY_LED_MAP(_n) FIELD_PREP_CONST(LAN2_LED_MAPPING_MASK, (_n))
++
++#define LAN1_LED_MAPPING_MASK GENMASK(6, 4)
++#define LAN1_PHY_LED_MAP(_n) FIELD_PREP_CONST(LAN1_LED_MAPPING_MASK, (_n))
++
++#define LAN0_LED_MAPPING_MASK GENMASK(2, 0)
++#define LAN0_PHY_LED_MAP(_n) FIELD_PREP_CONST(LAN0_LED_MAPPING_MASK, (_n))
++
++/* CONF */
++#define REG_I2C_SDA_E2 0x001c
++#define I2C1_SCL_E2_MASK BIT(16)
++#define 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)
++#define SPI_CS0_E2_MASK BIT(11)
++#define PCIE1_RESET_E2_MASK BIT(9)
++#define PCIE0_RESET_E2_MASK BIT(8)
++#define MDIO_0_E2_MASK BIT(5)
++#define 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 I2C1_SCL_E4_MASK BIT(16)
++#define 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)
++#define SPI_CS0_E4_MASK BIT(11)
++#define PCIE1_RESET_E4_MASK BIT(9)
++#define PCIE0_RESET_E4_MASK BIT(8)
++#define MDIO_0_E4_MASK BIT(5)
++#define 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)
++#define I2C_SDA_E4_MASK BIT(0)
++
++#define REG_GPIO_L_E2 0x0024
++#define REG_GPIO_L_E4 0x0028
++#define REG_GPIO_H_E2 0x002c
++#define REG_GPIO_H_E4 0x0030
++
++#define REG_I2C_SDA_PU 0x0044
++#define I2C1_SCL_PU_MASK BIT(16)
++#define 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)
++#define SPI_CS0_PU_MASK BIT(11)
++#define PCIE1_RESET_PU_MASK BIT(9)
++#define PCIE0_RESET_PU_MASK BIT(8)
++#define MDIO_0_PU_MASK BIT(5)
++#define 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 I2C1_SCL_PD_MASK BIT(16)
++#define I2C1_SDA_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)
++#define SPI_CS0_PD_MASK BIT(11)
++#define PCIE1_RESET_PD_MASK BIT(9)
++#define PCIE0_RESET_PD_MASK BIT(8)
++#define MDIO_0_PD_MASK BIT(5)
++#define 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)
++#define I2C_SDA_PD_MASK BIT(0)
++
++#define REG_GPIO_L_PU 0x004c
++#define REG_GPIO_L_PD 0x0050
++#define REG_GPIO_H_PU 0x0054
++#define REG_GPIO_H_PD 0x0058
++
++#define REG_PCIE_RESET_OD 0x018c
++#define PCIE1_RESET_OD_MASK BIT(1)
++#define PCIE0_RESET_OD_MASK BIT(0)
++
++/* PWM MODE CONF */
++#define REG_GPIO_FLASH_MODE_CFG 0x0034
++#define GPIO15_FLASH_MODE_CFG BIT(15)
++#define GPIO14_FLASH_MODE_CFG BIT(14)
++#define GPIO13_FLASH_MODE_CFG BIT(13)
++#define GPIO12_FLASH_MODE_CFG BIT(12)
++#define GPIO11_FLASH_MODE_CFG BIT(11)
++#define GPIO10_FLASH_MODE_CFG BIT(10)
++#define GPIO9_FLASH_MODE_CFG BIT(9)
++#define GPIO8_FLASH_MODE_CFG BIT(8)
++#define GPIO7_FLASH_MODE_CFG BIT(7)
++#define GPIO6_FLASH_MODE_CFG BIT(6)
++#define GPIO5_FLASH_MODE_CFG BIT(5)
++#define GPIO4_FLASH_MODE_CFG BIT(4)
++#define GPIO3_FLASH_MODE_CFG BIT(3)
++#define GPIO2_FLASH_MODE_CFG BIT(2)
++#define GPIO1_FLASH_MODE_CFG BIT(1)
++#define GPIO0_FLASH_MODE_CFG BIT(0)
++
++/* PWM MODE CONF EXT */
++#define REG_GPIO_FLASH_MODE_CFG_EXT 0x0068
++#define GPIO51_FLASH_MODE_CFG BIT(31)
++#define GPIO50_FLASH_MODE_CFG BIT(30)
++#define GPIO49_FLASH_MODE_CFG BIT(29)
++#define GPIO48_FLASH_MODE_CFG BIT(28)
++#define GPIO47_FLASH_MODE_CFG BIT(27)
++#define GPIO46_FLASH_MODE_CFG BIT(26)
++#define GPIO45_FLASH_MODE_CFG BIT(25)
++#define GPIO44_FLASH_MODE_CFG BIT(24)
++#define GPIO43_FLASH_MODE_CFG BIT(23)
++#define GPIO42_FLASH_MODE_CFG BIT(22)
++#define GPIO41_FLASH_MODE_CFG BIT(21)
++#define GPIO40_FLASH_MODE_CFG BIT(20)
++#define GPIO39_FLASH_MODE_CFG BIT(19)
++#define GPIO38_FLASH_MODE_CFG BIT(18)
++#define GPIO37_FLASH_MODE_CFG BIT(17)
++#define GPIO36_FLASH_MODE_CFG BIT(16)
++#define GPIO31_FLASH_MODE_CFG BIT(15)
++#define GPIO30_FLASH_MODE_CFG BIT(14)
++#define GPIO29_FLASH_MODE_CFG BIT(13)
++#define GPIO28_FLASH_MODE_CFG BIT(12)
++#define GPIO27_FLASH_MODE_CFG BIT(11)
++#define GPIO26_FLASH_MODE_CFG BIT(10)
++#define GPIO25_FLASH_MODE_CFG BIT(9)
++#define GPIO24_FLASH_MODE_CFG BIT(8)
++#define GPIO23_FLASH_MODE_CFG BIT(7)
++#define GPIO22_FLASH_MODE_CFG BIT(6)
++#define GPIO21_FLASH_MODE_CFG BIT(5)
++#define GPIO20_FLASH_MODE_CFG BIT(4)
++#define GPIO19_FLASH_MODE_CFG BIT(3)
++#define GPIO18_FLASH_MODE_CFG BIT(2)
++#define GPIO17_FLASH_MODE_CFG BIT(1)
++#define GPIO16_FLASH_MODE_CFG BIT(0)
++
++#define AIROHA_PINCTRL_GPIO(gpio, mux_val) \
++ { \
++ .name = (gpio), \
++ .regmap[0] = { \
++ AIROHA_FUNC_MUX, \
++ REG_GPIO_PON_MODE, \
++ (mux_val), \
++ (mux_val) \
++ }, \
++ .regmap_size = 1, \
++ }
++
++#define AIROHA_PINCTRL_GPIO_EXT(gpio, mux_val, smux_val) \
++ { \
++ .name = (gpio), \
++ .regmap[0] = { \
++ AIROHA_FUNC_PWM_EXT_MUX, \
++ REG_GPIO_FLASH_MODE_CFG_EXT, \
++ (mux_val), \
++ 0 \
++ }, \
++ .regmap[1] = { \
++ AIROHA_FUNC_MUX, \
++ REG_GPIO_PON_MODE, \
++ (smux_val), \
++ (smux_val) \
++ }, \
++ .regmap_size = 2, \
++ }
++
++/* 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, \
++ }
++
++#define AIROHA_PINCTRL_PWM_EXT_SEC(gpio, mux_val, smux_val) \
++ { \
++ .name = (gpio), \
++ .regmap[0] = { \
++ AIROHA_FUNC_PWM_EXT_MUX, \
++ REG_GPIO_FLASH_MODE_CFG_EXT, \
++ (mux_val), \
++ (mux_val) \
++ }, \
++ .regmap[1] = { \
++ AIROHA_FUNC_MUX, \
++ REG_GPIO_PON_MODE, \
++ (smux_val), \
++ (smux_val) \
++ }, \
++ .regmap_size = 2, \
++ }
++
++#define AIROHA_PINCTRL_PHY_LED0(gpio, mux_val, map_mask, map_val) \
++ { \
++ .name = (gpio), \
++ .regmap[0] = { \
++ AIROHA_FUNC_MUX, \
++ REG_SW_TOD_1PPS_MODE, \
++ (mux_val), \
++ (mux_val), \
++ }, \
++ .regmap[1] = { \
++ AIROHA_FUNC_MUX, \
++ REG_LAN_LED0_MAPPING, \
++ (map_mask), \
++ (map_val), \
++ }, \
++ .regmap_size = 2, \
++ }
++
++#define AIROHA_PINCTRL_PHY_LED1(gpio, mux_val, map_mask, map_val) \
++ { \
++ .name = (gpio), \
++ .regmap[0] = { \
++ AIROHA_FUNC_MUX, \
++ REG_SW_TOD_1PPS_MODE, \
++ (mux_val), \
++ (mux_val), \
++ }, \
++ .regmap[1] = { \
++ AIROHA_FUNC_MUX, \
++ REG_LAN_LED1_MAPPING, \
++ (map_mask), \
++ (map_val), \
++ }, \
++ .regmap_size = 2, \
++ }
++
++static struct pinctrl_pin_desc 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 pon_pins[] = { 15, 16, 17, 18, 19, 20 };
++static const int pon_alt_pins[] = { 36, 37, 38, 39, 40 };
++static const int olt_pins[] = { 36, 37, 38, 39, 40 };
++static const int pon_tod_1pps_pins[] = { 32 };
++static const int gsw_tod_1pps_pins[] = { 32 };
++static const int sipo_pins[] = { 34, 35 };
++static const int sipo_rclk_pins[] = { 34, 35, 33 };
++static const int mdio_pins[] = { 43, 44 };
++static const int uart2_pins[] = { 34, 35 };
++static const int uart2_cts_rts_pins[] = { 32, 33 };
++static const int hsuart_pins[] = { 30, 31 };
++static const int hsuart_cts_rts_pins[] = { 28, 29 };
++static const int npu_uart_pins[] = { 7, 8 };
++static const int uart4_pins[] = { 7, 8 };
++static const int uart5_pins[] = { 23, 24 };
++static const int i2c0_pins[] = { 41, 42 };
++static const int i2c1_pins[] = { 43, 44 };
++static const int jtag_udi_pins[] = { 23, 24, 22, 25, 26 };
++static const int jtag_dfd_pins[] = { 23, 24, 22, 25, 26 };
++static const int pcm1_pins[] = { 10, 11, 12, 13, 14 };
++static const int pcm2_pins[] = { 28, 29, 30, 31, 24 };
++static const int spi_pins[] = { 28, 29, 30, 31 };
++static const int spi_quad_pins[] = { 25, 26 };
++static const int spi_cs1_pins[] = { 27 };
++static const int pcm_spi_pins[] = { 28, 29, 30, 31, 10, 11, 12, 13 };
++static const int pcm_spi_rst_pins[] = { 14 };
++static const int pcm_spi_cs1_pins[] = { 24 };
++static const int emmc_pins[] = {
++ 7, 8, 9, 22, 23, 24, 25, 26, 45, 46, 47
++};
++static const int pnand_pins[] = {
++ 7, 8, 9, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 45, 46, 47, 48
++};
++static const int gpio0_pins[] = { 2 };
++static const int gpio1_pins[] = { 3 };
++static const int gpio2_pins[] = { 4 };
++static const int gpio3_pins[] = { 5 };
++static const int gpio4_pins[] = { 6 };
++static const int gpio5_pins[] = { 7 };
++static const int gpio6_pins[] = { 8 };
++static const int gpio7_pins[] = { 9 };
++static const int gpio8_pins[] = { 10 };
++static const int gpio9_pins[] = { 11 };
++static const int gpio10_pins[] = { 12 };
++static const int gpio11_pins[] = { 13 };
++static const int gpio12_pins[] = { 14 };
++static const int gpio13_pins[] = { 15 };
++static const int gpio14_pins[] = { 16 };
++static const int gpio15_pins[] = { 17 };
++static const int gpio16_pins[] = { 18 };
++static const int gpio17_pins[] = { 19 };
++static const int gpio18_pins[] = { 20 };
++static const int gpio19_pins[] = { 21 };
++static const int gpio20_pins[] = { 22 };
++static const int gpio21_pins[] = { 23 };
++static const int gpio22_pins[] = { 24 };
++static const int gpio23_pins[] = { 25 };
++static const int gpio24_pins[] = { 26 };
++static const int gpio25_pins[] = { 27 };
++static const int gpio26_pins[] = { 28 };
++static const int gpio27_pins[] = { 29 };
++static const int gpio28_pins[] = { 30 };
++static const int gpio29_pins[] = { 31 };
++static const int gpio30_pins[] = { 32 };
++static const int gpio31_pins[] = { 33 };
++static const int gpio32_pins[] = { 34 };
++static const int gpio33_pins[] = { 35 };
++static const int gpio34_pins[] = { 36 };
++static const int gpio35_pins[] = { 37 };
++static const int gpio36_pins[] = { 38 };
++static const int gpio37_pins[] = { 39 };
++static const int gpio38_pins[] = { 40 };
++static const int gpio39_pins[] = { 41 };
++static const int gpio40_pins[] = { 42 };
++static const int gpio41_pins[] = { 43 };
++static const int gpio42_pins[] = { 44 };
++static const int gpio43_pins[] = { 45 };
++static const int gpio44_pins[] = { 46 };
++static const int gpio45_pins[] = { 47 };
++static const int gpio46_pins[] = { 48 };
++static const int gpio47_pins[] = { 49 };
++static const int gpio48_pins[] = { 50 };
++static const int gpio49_pins[] = { 51 };
++static const int gpio50_pins[] = { 52 };
++static const int gpio51_pins[] = { 53 };
++static const int gpio52_pins[] = { 54 };
++static const int pcie_reset0_pins[] = { 51 };
++static const int pcie_reset1_pins[] = { 52 };
++
++static const struct pingroup pinctrl_groups[] = {
++ PINCTRL_PIN_GROUP("pon", pon),
++ PINCTRL_PIN_GROUP("pon_alt", pon_alt),
++ PINCTRL_PIN_GROUP("olt", olt),
++ PINCTRL_PIN_GROUP("pon_tod_1pps", pon_tod_1pps),
++ PINCTRL_PIN_GROUP("gsw_tod_1pps", gsw_tod_1pps),
++ PINCTRL_PIN_GROUP("sipo", sipo),
++ PINCTRL_PIN_GROUP("sipo_rclk", sipo_rclk),
++ PINCTRL_PIN_GROUP("mdio", mdio),
++ PINCTRL_PIN_GROUP("uart2", uart2),
++ PINCTRL_PIN_GROUP("uart2_cts_rts", uart2_cts_rts),
++ PINCTRL_PIN_GROUP("hsuart", hsuart),
++ PINCTRL_PIN_GROUP("hsuart_cts_rts", hsuart_cts_rts),
++ PINCTRL_PIN_GROUP("npu_uart", npu_uart),
++ PINCTRL_PIN_GROUP("uart4", uart4),
++ PINCTRL_PIN_GROUP("uart5", uart5),
++ PINCTRL_PIN_GROUP("i2c0", i2c0),
++ PINCTRL_PIN_GROUP("i2c1", i2c1),
++ PINCTRL_PIN_GROUP("jtag_udi", jtag_udi),
++ PINCTRL_PIN_GROUP("jtag_dfd", jtag_dfd),
++ PINCTRL_PIN_GROUP("pcm1", pcm1),
++ PINCTRL_PIN_GROUP("pcm2", pcm2),
++ PINCTRL_PIN_GROUP("spi", spi),
++ PINCTRL_PIN_GROUP("spi_quad", spi_quad),
++ PINCTRL_PIN_GROUP("spi_cs1", spi_cs1),
++ PINCTRL_PIN_GROUP("pcm_spi", pcm_spi),
++ PINCTRL_PIN_GROUP("pcm_spi_rst", pcm_spi_rst),
++ PINCTRL_PIN_GROUP("pcm_spi_cs1", pcm_spi_cs1),
++ PINCTRL_PIN_GROUP("emmc", emmc),
++ PINCTRL_PIN_GROUP("pnand", pnand),
++ PINCTRL_PIN_GROUP("gpio0", gpio0),
++ PINCTRL_PIN_GROUP("gpio1", gpio1),
++ PINCTRL_PIN_GROUP("gpio2", gpio2),
++ PINCTRL_PIN_GROUP("gpio3", gpio3),
++ PINCTRL_PIN_GROUP("gpio4", gpio4),
++ PINCTRL_PIN_GROUP("gpio5", gpio5),
++ PINCTRL_PIN_GROUP("gpio6", gpio6),
++ PINCTRL_PIN_GROUP("gpio7", gpio7),
++ PINCTRL_PIN_GROUP("gpio8", gpio8),
++ PINCTRL_PIN_GROUP("gpio9", gpio9),
++ PINCTRL_PIN_GROUP("gpio10", gpio10),
++ PINCTRL_PIN_GROUP("gpio11", gpio11),
++ PINCTRL_PIN_GROUP("gpio12", gpio12),
++ PINCTRL_PIN_GROUP("gpio13", gpio13),
++ PINCTRL_PIN_GROUP("gpio14", gpio14),
++ PINCTRL_PIN_GROUP("gpio15", gpio15),
++ PINCTRL_PIN_GROUP("gpio16", gpio16),
++ PINCTRL_PIN_GROUP("gpio17", gpio17),
++ PINCTRL_PIN_GROUP("gpio18", gpio18),
++ PINCTRL_PIN_GROUP("gpio19", gpio19),
++ PINCTRL_PIN_GROUP("gpio20", gpio20),
++ PINCTRL_PIN_GROUP("gpio21", gpio21),
++ PINCTRL_PIN_GROUP("gpio22", gpio22),
++ PINCTRL_PIN_GROUP("gpio23", gpio23),
++ PINCTRL_PIN_GROUP("gpio24", gpio24),
++ PINCTRL_PIN_GROUP("gpio25", gpio25),
++ PINCTRL_PIN_GROUP("gpio26", gpio26),
++ PINCTRL_PIN_GROUP("gpio27", gpio27),
++ PINCTRL_PIN_GROUP("gpio28", gpio28),
++ PINCTRL_PIN_GROUP("gpio29", gpio29),
++ PINCTRL_PIN_GROUP("gpio30", gpio30),
++ PINCTRL_PIN_GROUP("gpio31", gpio31),
++ PINCTRL_PIN_GROUP("gpio32", gpio32),
++ PINCTRL_PIN_GROUP("gpio33", gpio33),
++ PINCTRL_PIN_GROUP("gpio34", gpio34),
++ PINCTRL_PIN_GROUP("gpio35", gpio35),
++ PINCTRL_PIN_GROUP("gpio36", gpio36),
++ PINCTRL_PIN_GROUP("gpio37", gpio37),
++ PINCTRL_PIN_GROUP("gpio38", gpio38),
++ PINCTRL_PIN_GROUP("gpio39", gpio39),
++ PINCTRL_PIN_GROUP("gpio40", gpio40),
++ PINCTRL_PIN_GROUP("gpio41", gpio41),
++ PINCTRL_PIN_GROUP("gpio42", gpio42),
++ PINCTRL_PIN_GROUP("gpio43", gpio43),
++ PINCTRL_PIN_GROUP("gpio44", gpio44),
++ PINCTRL_PIN_GROUP("gpio45", gpio45),
++ PINCTRL_PIN_GROUP("gpio46", gpio46),
++ PINCTRL_PIN_GROUP("gpio47", gpio47),
++ PINCTRL_PIN_GROUP("gpio48", gpio48),
++ PINCTRL_PIN_GROUP("gpio49", gpio49),
++ PINCTRL_PIN_GROUP("gpio50", gpio50),
++ PINCTRL_PIN_GROUP("gpio51", gpio51),
++ PINCTRL_PIN_GROUP("gpio52", gpio52),
++ PINCTRL_PIN_GROUP("pcie_reset0", pcie_reset0),
++ PINCTRL_PIN_GROUP("pcie_reset1", pcie_reset1),
++};
++
++static const char *const pon_groups[] = { "pon", "pon_alt" };
++static const char *const olt_groups[] = { "olt" };
++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 uart_groups[] = {
++ "uart2", "uart2_cts_rts", "hsuart", "hsuart_cts_rts",
++ "uart4", "uart5", "npu_uart"
++};
++static const char *const jtag_groups[] = { "jtag_udi", "jtag_dfd" };
++static const char *const pcm_groups[] = { "pcm1", "pcm2" };
++static const char *const spi_groups[] = { "spi_quad", "spi_cs1" };
++static const char *const pcm_spi_groups[] = {
++ "pcm_spi", "pcm_spi_rst", "pcm_spi_cs1"
++};
++static const char *const emmc_groups[] = { "emmc" };
++static const char *const pnand_groups[] = { "pnand" };
++static const char *const gpio_groups[] = {
++ "gpio39", "gpio40", "gpio41", "gpio42", "gpio43",
++ "gpio44", "gpio45", "gpio46", "gpio47", "gpio48",
++ "gpio49", "gpio50", "gpio51", "gpio52"
++};
++static const char *const pcie_reset_groups[] = {
++ "pcie_reset0", "pcie_reset1"
++};
++static const char *const pwm_groups[] = {
++ "gpio0", "gpio1", "gpio2", "gpio3", "gpio4", "gpio5",
++ "gpio6", "gpio7", "gpio8", "gpio9", "gpio10", "gpio11",
++ "gpio12", "gpio13", "gpio14", "gpio15", "gpio16", "gpio17",
++ "gpio18", "gpio19", "gpio20", "gpio21", "gpio22", "gpio23",
++ "gpio24", "gpio25", "gpio26", "gpio27", "gpio28", "gpio29",
++ "gpio30", "gpio31", "gpio36", "gpio37", "gpio38", "gpio39",
++ "gpio40", "gpio41", "gpio42", "gpio43", "gpio44", "gpio45",
++ "gpio46", "gpio47", "gpio48", "gpio49", "gpio50", "gpio51"
++};
++static const char *const phy1_led0_groups[] = {
++ "gpio1", "gpio2", "gpio3", "gpio4"
++};
++static const char *const phy2_led0_groups[] = {
++ "gpio1", "gpio2", "gpio3", "gpio4"
++};
++static const char *const phy3_led0_groups[] = {
++ "gpio1", "gpio2", "gpio3", "gpio4"
++};
++static const char *const phy4_led0_groups[] = {
++ "gpio1", "gpio2", "gpio3", "gpio4"
++};
++static const char *const phy1_led1_groups[] = {
++ "gpio8", "gpio9", "gpio10", "gpio11"
++};
++static const char *const phy2_led1_groups[] = {
++ "gpio8", "gpio9", "gpio10", "gpio11"
++};
++static const char *const phy3_led1_groups[] = {
++ "gpio8", "gpio9", "gpio10", "gpio11"
++};
++static const char *const phy4_led1_groups[] = {
++ "gpio8", "gpio9", "gpio10", "gpio11"
++};
++
++static const struct airoha_pinctrl_func_group pon_func_group[] = {
++ {
++ .name = "pon",
++ .regmap[0] = {
++ AIROHA_FUNC_MUX,
++ REG_GPIO_PON_MODE,
++ GPIO_PON_MODE_MASK | GPIO_PON_ALT_MODE_MASK,
++ GPIO_PON_MODE_MASK
++ },
++ .regmap_size = 1,
++ }, {
++ .name = "pon_alt",
++ .regmap[0] = {
++ AIROHA_FUNC_MUX,
++ REG_GPIO_PON_MODE,
++ GPIO_PON_MODE_MASK | GPIO_PON_ALT_MODE_MASK,
++ GPIO_PON_ALT_MODE_MASK
++ },
++ .regmap_size = 1,
++ },
++};
++
++static const struct airoha_pinctrl_func_group olt_func_group[] = {
++ {
++ .name = "olt",
++ .regmap[0] = {
++ AIROHA_FUNC_MUX,
++ REG_GPIO_PON_MODE,
++ GPIO_OLT_MODE_MASK,
++ GPIO_OLT_MODE_MASK
++ },
++ .regmap_size = 1,
++ },
++};
++
++static const struct airoha_pinctrl_func_group tod_1pps_func_group[] = {
++ {
++ .name = "pon_tod_1pps",
++ .regmap[0] = {
++ AIROHA_FUNC_MUX,
++ REG_SW_TOD_1PPS_MODE,
++ PON_TOD_1PPS_MODE_MASK,
++ PON_TOD_1PPS_MODE_MASK
++ },
++ .regmap_size = 1,
++ }, {
++ .name = "gsw_tod_1pps",
++ .regmap[0] = {
++ AIROHA_FUNC_MUX,
++ REG_SW_TOD_1PPS_MODE,
++ GSW_TOD_1PPS_MODE_MASK,
++ GSW_TOD_1PPS_MODE_MASK
++ },
++ .regmap_size = 1,
++ },
++};
++
++static const struct airoha_pinctrl_func_group sipo_func_group[] = {
++ {
++ .name = "sipo",
++ .regmap[0] = {
++ AIROHA_FUNC_MUX,
++ REG_GPIO_PON_MODE,
++ GPIO_SIPO_MODE_MASK | SIPO_RCLK_MODE_MASK,
++ GPIO_SIPO_MODE_MASK
++ },
++ .regmap_size = 1,
++ }, {
++ .name = "sipo_rclk",
++ .regmap[0] = {
++ AIROHA_FUNC_MUX,
++ REG_GPIO_PON_MODE,
++ GPIO_SIPO_MODE_MASK | SIPO_RCLK_MODE_MASK,
++ GPIO_SIPO_MODE_MASK | SIPO_RCLK_MODE_MASK
++ },
++ .regmap_size = 1,
++ },
++};
++
++static const struct airoha_pinctrl_func_group 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_MASK,
++ GPIO_MDC_IO_MASTER_MODE_MASK
++ },
++ .regmap_size = 2,
++ },
++};
++
++static const struct airoha_pinctrl_func_group uart_func_group[] = {
++ {
++ .name = "uart2",
++ .regmap[0] = {
++ AIROHA_FUNC_MUX,
++ REG_GPIO_PON_MODE,
++ GPIO_UART2_MODE_MASK,
++ GPIO_UART2_MODE_MASK
++ },
++ .regmap_size = 1,
++ }, {
++ .name = "uart2_cts_rts",
++ .regmap[0] = {
++ AIROHA_FUNC_MUX,
++ REG_GPIO_PON_MODE,
++ GPIO_UART2_MODE_MASK | GPIO_UART2_CTS_RTS_MODE_MASK,
++ GPIO_UART2_MODE_MASK | GPIO_UART2_CTS_RTS_MODE_MASK
++ },
++ .regmap_size = 1,
++ }, {
++ .name = "hsuart",
++ .regmap[0] = {
++ AIROHA_FUNC_MUX,
++ REG_GPIO_PON_MODE,
++ GPIO_HSUART_MODE_MASK | GPIO_HSUART_CTS_RTS_MODE_MASK,
++ GPIO_HSUART_MODE_MASK
++ },
++ .regmap_size = 1,
++ },
++ {
++ .name = "hsuart_cts_rts",
++ .regmap[0] = {
++ AIROHA_FUNC_MUX,
++ REG_GPIO_PON_MODE,
++ GPIO_HSUART_MODE_MASK | GPIO_HSUART_CTS_RTS_MODE_MASK,
++ GPIO_HSUART_MODE_MASK | GPIO_HSUART_CTS_RTS_MODE_MASK
++ },
++ .regmap_size = 1,
++ }, {
++ .name = "uart4",
++ .regmap[0] = {
++ AIROHA_FUNC_MUX,
++ REG_GPIO_PON_MODE,
++ GPIO_UART4_MODE_MASK,
++ GPIO_UART4_MODE_MASK
++ },
++ .regmap_size = 1,
++ }, {
++ .name = "uart5",
++ .regmap[0] = {
++ AIROHA_FUNC_MUX,
++ REG_GPIO_PON_MODE,
++ GPIO_UART5_MODE_MASK,
++ GPIO_UART5_MODE_MASK
++ },
++ .regmap_size = 1,
++ }, {
++ .name = "npu_uart",
++ .regmap[0] = {
++ AIROHA_FUNC_MUX,
++ REG_NPU_UART_EN,
++ NPU_UART_EN_MASK,
++ NPU_UART_EN_MASK
++ },
++ .regmap_size = 1,
++ },
++};
++
++static const struct airoha_pinctrl_func_group jtag_func_group[] = {
++ {
++ .name = "jtag_udi",
++ .regmap[0] = {
++ AIROHA_FUNC_MUX,
++ REG_NPU_UART_EN,
++ JTAG_UDI_EN_MASK,
++ JTAG_UDI_EN_MASK
++ },
++ .regmap_size = 1,
++ }, {
++ .name = "jtag_dfd",
++ .regmap[0] = {
++ AIROHA_FUNC_MUX,
++ REG_NPU_UART_EN,
++ JTAG_DFD_EN_MASK,
++ JTAG_DFD_EN_MASK
++ },
++ .regmap_size = 1,
++ },
++};
++
++static const struct airoha_pinctrl_func_group pcm_func_group[] = {
++ {
++ .name = "pcm1",
++ .regmap[0] = {
++ AIROHA_FUNC_MUX,
++ REG_GPIO_SPI_CS1_MODE,
++ GPIO_PCM1_MODE_MASK,
++ GPIO_PCM1_MODE_MASK
++ },
++ .regmap_size = 1,
++ }, {
++ .name = "pcm2",
++ .regmap[0] = {
++ AIROHA_FUNC_MUX,
++ REG_GPIO_SPI_CS1_MODE,
++ GPIO_PCM2_MODE_MASK,
++ GPIO_PCM2_MODE_MASK
++ },
++ .regmap_size = 1,
++ },
++};
++
++static const struct airoha_pinctrl_func_group spi_func_group[] = {
++ {
++ .name = "spi_quad",
++ .regmap[0] = {
++ AIROHA_FUNC_MUX,
++ REG_GPIO_SPI_CS1_MODE,
++ GPIO_SPI_QUAD_MODE_MASK,
++ GPIO_SPI_QUAD_MODE_MASK
++ },
++ .regmap_size = 1,
++ }, {
++ .name = "spi_cs1",
++ .regmap[0] = {
++ AIROHA_FUNC_MUX,
++ REG_GPIO_SPI_CS1_MODE,
++ GPIO_SPI_CS1_MODE_MASK,
++ GPIO_SPI_CS1_MODE_MASK
++ },
++ .regmap_size = 1,
++ }, {
++ .name = "spi_cs2",
++ .regmap[0] = {
++ AIROHA_FUNC_MUX,
++ REG_GPIO_SPI_CS1_MODE,
++ GPIO_SPI_CS2_MODE_MASK,
++ GPIO_SPI_CS2_MODE_MASK
++ },
++ .regmap_size = 1,
++ }, {
++ .name = "spi_cs3",
++ .regmap[0] = {
++ AIROHA_FUNC_MUX,
++ REG_GPIO_SPI_CS1_MODE,
++ GPIO_SPI_CS3_MODE_MASK,
++ GPIO_SPI_CS3_MODE_MASK
++ },
++ .regmap_size = 1,
++ }, {
++ .name = "spi_cs4",
++ .regmap[0] = {
++ AIROHA_FUNC_MUX,
++ REG_GPIO_SPI_CS1_MODE,
++ GPIO_SPI_CS4_MODE_MASK,
++ GPIO_SPI_CS4_MODE_MASK
++ },
++ .regmap_size = 1,
++ },
++};
++
++static const struct airoha_pinctrl_func_group 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,
++ GPIO_PCM_SPI_CS2_MODE_MASK,
++ 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 emmc_func_group[] = {
++ {
++ .name = "emmc",
++ .regmap[0] = {
++ AIROHA_FUNC_MUX,
++ REG_GPIO_PON_MODE,
++ GPIO_EMMC_MODE_MASK,
++ GPIO_EMMC_MODE_MASK
++ },
++ .regmap_size = 1,
++ },
++};
++
++static const struct airoha_pinctrl_func_group pnand_func_group[] = {
++ {
++ .name = "pnand",
++ .regmap[0] = {
++ AIROHA_FUNC_MUX,
++ REG_GPIO_PON_MODE,
++ GPIO_PARALLEL_NAND_MODE_MASK,
++ GPIO_PARALLEL_NAND_MODE_MASK
++ },
++ .regmap_size = 1,
++ },
++};
++
++static const struct airoha_pinctrl_func_group gpio_func_group[] = {
++ AIROHA_PINCTRL_GPIO_EXT("gpio39", GPIO39_FLASH_MODE_CFG,
++ I2C0_SCL_GPIO_MODE_MASK),
++ AIROHA_PINCTRL_GPIO_EXT("gpio40", GPIO40_FLASH_MODE_CFG,
++ I2C0_SDA_GPIO_MODE_MASK),
++ AIROHA_PINCTRL_GPIO_EXT("gpio41", GPIO41_FLASH_MODE_CFG,
++ I2C1_SCL_GPIO_MODE_MASK),
++ AIROHA_PINCTRL_GPIO_EXT("gpio42", GPIO42_FLASH_MODE_CFG,
++ I2C1_SDA_GPIO_MODE_MASK),
++ AIROHA_PINCTRL_GPIO_EXT("gpio43", GPIO43_FLASH_MODE_CFG,
++ SPI_CLK_GPIO_MODE_MASK),
++ AIROHA_PINCTRL_GPIO_EXT("gpio44", GPIO44_FLASH_MODE_CFG,
++ SPI_CS_GPIO_MODE_MASK),
++ AIROHA_PINCTRL_GPIO_EXT("gpio45", GPIO45_FLASH_MODE_CFG,
++ SPI_MOSI_GPIO_MODE_MASK),
++ AIROHA_PINCTRL_GPIO_EXT("gpio46", GPIO46_FLASH_MODE_CFG,
++ SPI_MISO_GPIO_MODE_MASK),
++ AIROHA_PINCTRL_GPIO_EXT("gpio47", GPIO47_FLASH_MODE_CFG,
++ UART_TXD_GPIO_MODE_MASK),
++ AIROHA_PINCTRL_GPIO_EXT("gpio48", GPIO48_FLASH_MODE_CFG,
++ UART_RXD_GPIO_MODE_MASK),
++ AIROHA_PINCTRL_GPIO_EXT("gpio49", GPIO49_FLASH_MODE_CFG,
++ GPIO_PCIE_RESET0_MASK),
++ AIROHA_PINCTRL_GPIO_EXT("gpio50", GPIO50_FLASH_MODE_CFG,
++ GPIO_PCIE_RESET1_MASK),
++ AIROHA_PINCTRL_GPIO_EXT("gpio51", GPIO51_FLASH_MODE_CFG,
++ MDC_0_GPIO_MODE_MASK),
++ AIROHA_PINCTRL_GPIO("gpio52", MDIO_0_GPIO_MODE_MASK),
++};
++
++static const struct airoha_pinctrl_func_group pcie_reset_func_group[] = {
++ {
++ .name = "pcie_reset0",
++ .regmap[0] = {
++ AIROHA_FUNC_MUX,
++ REG_GPIO_PON_MODE,
++ GPIO_PCIE_RESET0_MASK,
++ 0
++ },
++ .regmap_size = 1,
++ }, {
++ .name = "pcie_reset1",
++ .regmap[0] = {
++ AIROHA_FUNC_MUX,
++ REG_GPIO_PON_MODE,
++ GPIO_PCIE_RESET1_MASK,
++ 0
++ },
++ .regmap_size = 1,
++ },
++};
++
++static const struct airoha_pinctrl_func_group pwm_func_group[] = {
++ 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_SEC("gpio39", GPIO39_FLASH_MODE_CFG,
++ I2C0_SCL_GPIO_MODE_MASK),
++ AIROHA_PINCTRL_PWM_EXT_SEC("gpio40", GPIO40_FLASH_MODE_CFG,
++ I2C0_SDA_GPIO_MODE_MASK),
++ AIROHA_PINCTRL_PWM_EXT_SEC("gpio41", GPIO41_FLASH_MODE_CFG,
++ I2C1_SCL_GPIO_MODE_MASK),
++ AIROHA_PINCTRL_PWM_EXT_SEC("gpio42", GPIO42_FLASH_MODE_CFG,
++ I2C1_SDA_GPIO_MODE_MASK),
++ AIROHA_PINCTRL_PWM_EXT_SEC("gpio43", GPIO43_FLASH_MODE_CFG,
++ SPI_CLK_GPIO_MODE_MASK),
++ AIROHA_PINCTRL_PWM_EXT_SEC("gpio44", GPIO44_FLASH_MODE_CFG,
++ SPI_CS_GPIO_MODE_MASK),
++ AIROHA_PINCTRL_PWM_EXT_SEC("gpio45", GPIO45_FLASH_MODE_CFG,
++ SPI_MOSI_GPIO_MODE_MASK),
++ AIROHA_PINCTRL_PWM_EXT_SEC("gpio46", GPIO46_FLASH_MODE_CFG,
++ SPI_MISO_GPIO_MODE_MASK),
++ AIROHA_PINCTRL_PWM_EXT_SEC("gpio47", GPIO47_FLASH_MODE_CFG,
++ UART_TXD_GPIO_MODE_MASK),
++ AIROHA_PINCTRL_PWM_EXT_SEC("gpio48", GPIO48_FLASH_MODE_CFG,
++ UART_RXD_GPIO_MODE_MASK),
++ AIROHA_PINCTRL_PWM_EXT_SEC("gpio49", GPIO49_FLASH_MODE_CFG,
++ GPIO_PCIE_RESET0_MASK),
++ AIROHA_PINCTRL_PWM_EXT_SEC("gpio50", GPIO50_FLASH_MODE_CFG,
++ GPIO_PCIE_RESET1_MASK),
++ AIROHA_PINCTRL_PWM_EXT_SEC("gpio51", GPIO51_FLASH_MODE_CFG,
++ MDC_0_GPIO_MODE_MASK),
++};
++
++static const struct airoha_pinctrl_func_group phy1_led0_func_group[] = {
++ AIROHA_PINCTRL_PHY_LED0("gpio1", GPIO_LAN0_LED0_MODE_MASK,
++ LAN0_LED_MAPPING_MASK, LAN0_PHY_LED_MAP(0)),
++ AIROHA_PINCTRL_PHY_LED0("gpio2", GPIO_LAN1_LED0_MODE_MASK,
++ LAN1_LED_MAPPING_MASK, LAN1_PHY_LED_MAP(0)),
++ AIROHA_PINCTRL_PHY_LED0("gpio3", GPIO_LAN2_LED0_MODE_MASK,
++ LAN2_LED_MAPPING_MASK, LAN2_PHY_LED_MAP(0)),
++ AIROHA_PINCTRL_PHY_LED0("gpio4", 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[] = {
++ AIROHA_PINCTRL_PHY_LED0("gpio1", GPIO_LAN0_LED0_MODE_MASK,
++ LAN0_LED_MAPPING_MASK, LAN0_PHY_LED_MAP(1)),
++ AIROHA_PINCTRL_PHY_LED0("gpio2", GPIO_LAN1_LED0_MODE_MASK,
++ LAN1_LED_MAPPING_MASK, LAN1_PHY_LED_MAP(1)),
++ AIROHA_PINCTRL_PHY_LED0("gpio3", GPIO_LAN2_LED0_MODE_MASK,
++ LAN2_LED_MAPPING_MASK, LAN2_PHY_LED_MAP(1)),
++ AIROHA_PINCTRL_PHY_LED0("gpio4", 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[] = {
++ AIROHA_PINCTRL_PHY_LED0("gpio1", GPIO_LAN0_LED0_MODE_MASK,
++ LAN0_LED_MAPPING_MASK, LAN0_PHY_LED_MAP(2)),
++ AIROHA_PINCTRL_PHY_LED0("gpio2", GPIO_LAN1_LED0_MODE_MASK,
++ LAN1_LED_MAPPING_MASK, LAN1_PHY_LED_MAP(2)),
++ AIROHA_PINCTRL_PHY_LED0("gpio3", GPIO_LAN2_LED0_MODE_MASK,
++ LAN2_LED_MAPPING_MASK, LAN2_PHY_LED_MAP(2)),
++ AIROHA_PINCTRL_PHY_LED0("gpio4", 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[] = {
++ AIROHA_PINCTRL_PHY_LED0("gpio1", GPIO_LAN0_LED0_MODE_MASK,
++ LAN0_LED_MAPPING_MASK, LAN0_PHY_LED_MAP(3)),
++ AIROHA_PINCTRL_PHY_LED0("gpio2", GPIO_LAN1_LED0_MODE_MASK,
++ LAN1_LED_MAPPING_MASK, LAN1_PHY_LED_MAP(3)),
++ AIROHA_PINCTRL_PHY_LED0("gpio3", GPIO_LAN2_LED0_MODE_MASK,
++ LAN2_LED_MAPPING_MASK, LAN2_PHY_LED_MAP(3)),
++ AIROHA_PINCTRL_PHY_LED0("gpio4", 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[] = {
++ AIROHA_PINCTRL_PHY_LED1("gpio8", GPIO_LAN0_LED1_MODE_MASK,
++ LAN0_LED_MAPPING_MASK, LAN0_PHY_LED_MAP(0)),
++ AIROHA_PINCTRL_PHY_LED1("gpio9", GPIO_LAN1_LED1_MODE_MASK,
++ LAN1_LED_MAPPING_MASK, LAN1_PHY_LED_MAP(0)),
++ AIROHA_PINCTRL_PHY_LED1("gpio10", GPIO_LAN2_LED1_MODE_MASK,
++ LAN2_LED_MAPPING_MASK, LAN2_PHY_LED_MAP(0)),
++ AIROHA_PINCTRL_PHY_LED1("gpio11", 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[] = {
++ AIROHA_PINCTRL_PHY_LED1("gpio8", GPIO_LAN0_LED1_MODE_MASK,
++ LAN0_LED_MAPPING_MASK, LAN0_PHY_LED_MAP(1)),
++ AIROHA_PINCTRL_PHY_LED1("gpio9", GPIO_LAN1_LED1_MODE_MASK,
++ LAN1_LED_MAPPING_MASK, LAN1_PHY_LED_MAP(1)),
++ AIROHA_PINCTRL_PHY_LED1("gpio10", GPIO_LAN2_LED1_MODE_MASK,
++ LAN2_LED_MAPPING_MASK, LAN2_PHY_LED_MAP(1)),
++ AIROHA_PINCTRL_PHY_LED1("gpio11", 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[] = {
++ AIROHA_PINCTRL_PHY_LED1("gpio8", GPIO_LAN0_LED1_MODE_MASK,
++ LAN0_LED_MAPPING_MASK, LAN0_PHY_LED_MAP(2)),
++ AIROHA_PINCTRL_PHY_LED1("gpio9", GPIO_LAN1_LED1_MODE_MASK,
++ LAN1_LED_MAPPING_MASK, LAN1_PHY_LED_MAP(2)),
++ AIROHA_PINCTRL_PHY_LED1("gpio10", GPIO_LAN2_LED1_MODE_MASK,
++ LAN2_LED_MAPPING_MASK, LAN2_PHY_LED_MAP(2)),
++ AIROHA_PINCTRL_PHY_LED1("gpio11", 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[] = {
++ AIROHA_PINCTRL_PHY_LED1("gpio8", GPIO_LAN0_LED1_MODE_MASK,
++ LAN0_LED_MAPPING_MASK, LAN0_PHY_LED_MAP(3)),
++ AIROHA_PINCTRL_PHY_LED1("gpio9", GPIO_LAN1_LED1_MODE_MASK,
++ LAN1_LED_MAPPING_MASK, LAN1_PHY_LED_MAP(3)),
++ AIROHA_PINCTRL_PHY_LED1("gpio10", GPIO_LAN2_LED1_MODE_MASK,
++ LAN2_LED_MAPPING_MASK, LAN2_PHY_LED_MAP(3)),
++ AIROHA_PINCTRL_PHY_LED1("gpio11", GPIO_LAN3_LED1_MODE_MASK,
++ LAN3_LED_MAPPING_MASK, LAN3_PHY_LED_MAP(3)),
++};
++
++static const struct airoha_pinctrl_func pinctrl_funcs[] = {
++ PINCTRL_FUNC_DESC("pon", pon),
++ PINCTRL_FUNC_DESC("olt", olt),
++ 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("jtag", jtag),
++ PINCTRL_FUNC_DESC("pcm", pcm),
++ PINCTRL_FUNC_DESC("spi", spi),
++ PINCTRL_FUNC_DESC("pcm_spi", pcm_spi),
++ PINCTRL_FUNC_DESC("emmc", emmc),
++ PINCTRL_FUNC_DESC("pnand", pnand),
++ PINCTRL_FUNC_DESC("gpio", gpio),
++ 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 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(19)),
++ 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, I2C1_SCL_PU_MASK),
++ PINCTRL_CONF_DESC(44, REG_I2C_SDA_PU, 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, MDC_0_PU_MASK),
++ PINCTRL_CONF_DESC(54, REG_I2C_SDA_PU, MDIO_0_PU_MASK),
++};
++
++static const struct airoha_pinctrl_conf 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(19)),
++ 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, I2C1_SCL_PD_MASK),
++ PINCTRL_CONF_DESC(44, REG_I2C_SDA_PD, 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, MDC_0_PD_MASK),
++ PINCTRL_CONF_DESC(54, REG_I2C_SDA_PD, MDIO_0_PD_MASK),
++};
++
++static const struct airoha_pinctrl_conf 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(19)),
++ 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, I2C1_SCL_E2_MASK),
++ PINCTRL_CONF_DESC(44, REG_I2C_SDA_E2, 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, MDC_0_E2_MASK),
++ PINCTRL_CONF_DESC(54, REG_I2C_SDA_E2, MDIO_0_E2_MASK),
++};
++
++static const struct airoha_pinctrl_conf 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(19)),
++ 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, I2C1_SCL_E4_MASK),
++ PINCTRL_CONF_DESC(44, REG_I2C_SDA_E4, 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, MDC_0_E4_MASK),
++ PINCTRL_CONF_DESC(54, REG_I2C_SDA_E4, MDIO_0_E4_MASK),
++};
++
++static const struct airoha_pinctrl_conf 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 const struct airoha_pinctrl_match_data pinctrl_match_data = {
++ .gpio_offs = 2,
++ .gpio_pin_cnt = 53,
++ .chip_scu_compatible = "airoha,en7581-chip-scu",
++ .pins = pinctrl_pins,
++ .num_pins = ARRAY_SIZE(pinctrl_pins),
++ .grps = pinctrl_groups,
++ .num_grps = ARRAY_SIZE(pinctrl_groups),
++ .funcs = pinctrl_funcs,
++ .num_funcs = ARRAY_SIZE(pinctrl_funcs),
++ .confs_info = {
++ [AIROHA_PINCTRL_CONFS_PULLUP] = {
++ .confs = pinctrl_pullup_conf,
++ .num_confs = ARRAY_SIZE(pinctrl_pullup_conf),
++ },
++ [AIROHA_PINCTRL_CONFS_PULLDOWN] = {
++ .confs = pinctrl_pulldown_conf,
++ .num_confs = ARRAY_SIZE(pinctrl_pulldown_conf),
++ },
++ [AIROHA_PINCTRL_CONFS_DRIVE_E2] = {
++ .confs = pinctrl_drive_e2_conf,
++ .num_confs = ARRAY_SIZE(pinctrl_drive_e2_conf),
++ },
++ [AIROHA_PINCTRL_CONFS_DRIVE_E4] = {
++ .confs = pinctrl_drive_e4_conf,
++ .num_confs = ARRAY_SIZE(pinctrl_drive_e4_conf),
++ },
++ [AIROHA_PINCTRL_CONFS_PCIE_RST_OD] = {
++ .confs = pinctrl_pcie_rst_od_conf,
++ .num_confs = ARRAY_SIZE(pinctrl_pcie_rst_od_conf),
++ },
++ },
++};
++
++static const struct udevice_id pinctrl_of_match[] = {
++ { .compatible = "airoha,an7583-pinctrl",
++ .data = (uintptr_t)&pinctrl_match_data },
++ { /* sentinel */ }
++};
++
++U_BOOT_DRIVER(airoha_an7583_pinctrl) = {
++ .name = "airoha-an7583-pinctrl",
++ .id = UCLASS_PINCTRL,
++ .of_match = of_match_ptr(pinctrl_of_match),
++ .probe = airoha_pinctrl_probe,
++ .bind = airoha_pinctrl_bind,
++ .priv_auto = sizeof(struct airoha_pinctrl),
++ .ops = &airoha_pinctrl_ops,
++};
+--
+2.53.0
+
--- /dev/null
+From 1d10d403ccb92066454419903b43fdafd71795b6 Mon Sep 17 00:00:00 2001
+From: Mikhail Kshevetskiy <mikhail.kshevetskiy@iopsys.eu>
+Date: Mon, 27 Apr 2026 00:02:04 +0300
+Subject: [PATCH 08/29] pinctrl: airoha: add pin controller and gpio driver for
+ EN7523 SoC
+
+This patch adds U-Boot pin controller and gpio driver for Airoha EN7523 SoC.
+
+Signed-off-by: Mikhail Kshevetskiy <mikhail.kshevetskiy@iopsys.eu>
+Reviewed-by: David Lechner <dlechner@baylibre.com>
+---
+ drivers/pinctrl/airoha/Kconfig | 5 +
+ drivers/pinctrl/airoha/Makefile | 1 +
+ drivers/pinctrl/airoha/pinctrl-en7523.c | 1118 +++++++++++++++++++++++
+ 3 files changed, 1124 insertions(+)
+ create mode 100644 drivers/pinctrl/airoha/pinctrl-en7523.c
+
+diff --git a/drivers/pinctrl/airoha/Kconfig b/drivers/pinctrl/airoha/Kconfig
+index 5d3e29c8fd6..f5d948b27eb 100644
+--- a/drivers/pinctrl/airoha/Kconfig
++++ b/drivers/pinctrl/airoha/Kconfig
+@@ -10,6 +10,11 @@ config PINCTRL_AIROHA
+ select SYSCON
+ bool
+
++config PINCTRL_AIROHA_EN7523
++ bool "Airoha EN7523 pin controller and gpio driver"
++ depends on TARGET_EN7523
++ select PINCTRL_AIROHA
++
+ config PINCTRL_AIROHA_AN7581
+ bool "Airoha AN7581 pin controller and gpio driver"
+ depends on TARGET_AN7581
+diff --git a/drivers/pinctrl/airoha/Makefile b/drivers/pinctrl/airoha/Makefile
+index c8c99dd22f8..b90bd180591 100644
+--- a/drivers/pinctrl/airoha/Makefile
++++ b/drivers/pinctrl/airoha/Makefile
+@@ -2,5 +2,6 @@
+
+ obj-$(CONFIG_PINCTRL_AIROHA) += pinctrl-airoha.o
+
++obj-$(CONFIG_PINCTRL_AIROHA_EN7523) += pinctrl-en7523.o
+ obj-$(CONFIG_PINCTRL_AIROHA_AN7581) += pinctrl-an7581.o
+ obj-$(CONFIG_PINCTRL_AIROHA_AN7583) += pinctrl-an7583.o
+diff --git a/drivers/pinctrl/airoha/pinctrl-en7523.c b/drivers/pinctrl/airoha/pinctrl-en7523.c
+new file mode 100644
+index 00000000000..958fcc8418f
+--- /dev/null
++++ b/drivers/pinctrl/airoha/pinctrl-en7523.c
+@@ -0,0 +1,1118 @@
++// SPDX-License-Identifier: GPL-2.0-only
++/*
++ * Author: Lorenzo Bianconi <lorenzo@kernel.org>
++ * Author: Benjamin Larsson <benjamin.larsson@genexis.eu>
++ * Author: Markus Gothe <markus.gothe@genexis.eu>
++ * Author: Matheus Sampaio Queiroga <srherobrine20@gmail.com>
++ * Author: Mikhail Kshevetskiy <mikhail.kshevetskiy@iopsys.eu>
++ */
++#include "airoha-common.h"
++
++/* MUX */
++#define REG_GPIO_2ND_I2C_MODE 0x0210
++#define GPIO_I2S_MODE_MASK BIT(12)
++#define GPIO_I2C_SLAVE_MODE_MODE BIT(11)
++#define GPIO_LAN3_LED1_MODE_MASK BIT(10)
++#define GPIO_LAN3_LED0_MODE_MASK BIT(9)
++#define GPIO_LAN2_LED1_MODE_MASK BIT(8)
++#define GPIO_LAN2_LED0_MODE_MASK BIT(7)
++#define GPIO_LAN1_LED1_MODE_MASK BIT(6)
++#define GPIO_LAN1_LED0_MODE_MASK BIT(5)
++#define GPIO_LAN0_LED1_MODE_MASK BIT(4)
++#define GPIO_LAN0_LED0_MODE_MASK BIT(3)
++#define PON_TOD_1PPS_MODE_MASK BIT(2)
++#define GSW_TOD_1PPS_MODE_MASK BIT(1)
++#define GPIO_2ND_I2C_MODE_MASK BIT(0)
++
++#define REG_GPIO_SPI_CS1_MODE 0x0214
++#define GPIO_PCM_SPI_CS4_MODE_MASK BIT(21)
++#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 GPIO_PCM_SPI_CS1_MODE_MASK BIT(17)
++#define GPIO_PCM_SPI_MODE_MASK BIT(16)
++#define GPIO_PCM2_MODE_MASK BIT(13)
++#define GPIO_PCM1_MODE_MASK BIT(12)
++#define GPIO_PCM_INT_MODE_MASK BIT(9)
++#define GPIO_PCM_RESET_MODE_MASK BIT(8)
++#define GPIO_SPI_QUAD_MODE_MASK BIT(4)
++#define GPIO_SPI_CS1_MODE_MASK BIT(0)
++
++#define REG_GPIO_PON_MODE 0x0218
++#define GPIO_SGMII_MDIO_MODE_MASK BIT(13)
++#define SIPO_RCLK_MODE_MASK BIT(11)
++#define GPIO_PCIE_RESET1_MASK BIT(10)
++#define GPIO_PCIE_RESET0_MASK BIT(9)
++#define GPIO_UART2_MODE_MASK BIT(3)
++#define GPIO_SIPO_MODE_MASK BIT(2)
++#define GPIO_PON_MODE_MASK BIT(0)
++
++#define REG_NPU_UART_EN 0x0220
++#define JTAG_UDI_EN_MASK BIT(4)
++#define JTAG_DFD_EN_MASK BIT(3)
++#define NPU_UART_EN_MASK BIT(2)
++
++#define REG_FORCE_GPIO_EN 0x0224
++#define FORCE_GPIO_EN(n) BIT(n)
++
++/* LED MAP */
++#define REG_LAN_LED0_MAPPING 0x0278
++#define REG_LAN_LED1_MAPPING 0x027c
++
++#define LAN3_LED_MAPPING_MASK GENMASK(14, 12)
++#define LAN3_PHY_LED_MAP(_n) FIELD_PREP_CONST(LAN3_LED_MAPPING_MASK, (_n))
++
++#define LAN2_LED_MAPPING_MASK GENMASK(10, 8)
++#define LAN2_PHY_LED_MAP(_n) FIELD_PREP_CONST(LAN2_LED_MAPPING_MASK, (_n))
++
++#define LAN1_LED_MAPPING_MASK GENMASK(6, 4)
++#define LAN1_PHY_LED_MAP(_n) FIELD_PREP_CONST(LAN1_LED_MAPPING_MASK, (_n))
++
++#define LAN0_LED_MAPPING_MASK GENMASK(2, 0)
++#define LAN0_PHY_LED_MAP(_n) FIELD_PREP_CONST(LAN0_LED_MAPPING_MASK, (_n))
++
++/* CONF */
++#define REG_I2C_SDA_E2 0x001c
++#define SPI_MISO_E2_MASK BIT(13)
++#define SPI_MOSI_E2_MASK BIT(12)
++#define SPI_CLK_E2_MASK BIT(11)
++#define SPI_CS0_E2_MASK BIT(10)
++#define PCIE1_RESET_E2_MASK BIT(9)
++#define PCIE0_RESET_E2_MASK BIT(8)
++#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 SPI_MISO_E4_MASK BIT(13)
++#define SPI_MOSI_E4_MASK BIT(12)
++#define SPI_CLK_E4_MASK BIT(11)
++#define SPI_CS0_E4_MASK BIT(10)
++#define PCIE1_RESET_E4_MASK BIT(9)
++#define PCIE0_RESET_E4_MASK BIT(8)
++#define UART1_RXD_E4_MASK BIT(3)
++#define UART1_TXD_E4_MASK BIT(2)
++#define I2C_SCL_E4_MASK BIT(1)
++#define I2C_SDA_E4_MASK BIT(0)
++
++#define REG_GPIO_L_E2 0x0024
++#define REG_GPIO_L_E4 0x0028
++
++#define REG_I2C_SDA_PU 0x0044
++#define SPI_MISO_PU_MASK BIT(13)
++#define SPI_MOSI_PU_MASK BIT(12)
++#define SPI_CLK_PU_MASK BIT(11)
++#define SPI_CS0_PU_MASK BIT(10)
++#define PCIE1_RESET_PU_MASK BIT(9)
++#define PCIE0_RESET_PU_MASK BIT(8)
++#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 SPI_MISO_PD_MASK BIT(13)
++#define SPI_MOSI_PD_MASK BIT(12)
++#define SPI_CLK_PD_MASK BIT(11)
++#define SPI_CS0_PD_MASK BIT(10)
++#define PCIE1_RESET_PD_MASK BIT(9)
++#define PCIE0_RESET_PD_MASK BIT(8)
++#define UART1_RXD_PD_MASK BIT(3)
++#define UART1_TXD_PD_MASK BIT(2)
++#define I2C_SCL_PD_MASK BIT(1)
++#define I2C_SDA_PD_MASK BIT(0)
++
++#define REG_GPIO_L_PU 0x004c
++#define REG_GPIO_L_PD 0x0050
++
++/* PWM MODE CONF */
++#define REG_GPIO_FLASH_MODE_CFG 0x0034
++#define GPIO15_FLASH_MODE_CFG BIT(15)
++#define GPIO14_FLASH_MODE_CFG BIT(14)
++#define GPIO13_FLASH_MODE_CFG BIT(13)
++#define GPIO12_FLASH_MODE_CFG BIT(12)
++#define GPIO11_FLASH_MODE_CFG BIT(11)
++#define GPIO10_FLASH_MODE_CFG BIT(10)
++#define GPIO9_FLASH_MODE_CFG BIT(9)
++#define GPIO8_FLASH_MODE_CFG BIT(8)
++#define GPIO7_FLASH_MODE_CFG BIT(7)
++#define GPIO6_FLASH_MODE_CFG BIT(6)
++#define GPIO5_FLASH_MODE_CFG BIT(5)
++#define GPIO4_FLASH_MODE_CFG BIT(4)
++#define GPIO3_FLASH_MODE_CFG BIT(3)
++#define GPIO2_FLASH_MODE_CFG BIT(2)
++#define GPIO1_FLASH_MODE_CFG BIT(1)
++#define GPIO0_FLASH_MODE_CFG BIT(0)
++
++/* PWM MODE CONF EXT */
++#define REG_GPIO_FLASH_MODE_CFG_EXT 0x0068
++#define GPIO51_FLASH_MODE_CFG BIT(31)
++#define GPIO50_FLASH_MODE_CFG BIT(30)
++#define GPIO49_FLASH_MODE_CFG BIT(29)
++#define GPIO48_FLASH_MODE_CFG BIT(28)
++#define GPIO47_FLASH_MODE_CFG BIT(27)
++#define GPIO46_FLASH_MODE_CFG BIT(26)
++#define GPIO45_FLASH_MODE_CFG BIT(25)
++#define GPIO44_FLASH_MODE_CFG BIT(24)
++#define GPIO43_FLASH_MODE_CFG BIT(23)
++#define GPIO42_FLASH_MODE_CFG BIT(22)
++#define GPIO41_FLASH_MODE_CFG BIT(21)
++#define GPIO40_FLASH_MODE_CFG BIT(20)
++#define GPIO39_FLASH_MODE_CFG BIT(19)
++#define GPIO38_FLASH_MODE_CFG BIT(18)
++#define GPIO37_FLASH_MODE_CFG BIT(17)
++#define GPIO36_FLASH_MODE_CFG BIT(16)
++#define GPIO31_FLASH_MODE_CFG BIT(15)
++#define GPIO30_FLASH_MODE_CFG BIT(14)
++#define GPIO29_FLASH_MODE_CFG BIT(13)
++#define GPIO28_FLASH_MODE_CFG BIT(12)
++#define GPIO27_FLASH_MODE_CFG BIT(11)
++#define GPIO26_FLASH_MODE_CFG BIT(10)
++#define GPIO25_FLASH_MODE_CFG BIT(9)
++#define GPIO24_FLASH_MODE_CFG BIT(8)
++#define GPIO23_FLASH_MODE_CFG BIT(7)
++#define GPIO22_FLASH_MODE_CFG BIT(6)
++#define GPIO21_FLASH_MODE_CFG BIT(5)
++#define GPIO20_FLASH_MODE_CFG BIT(4)
++#define GPIO19_FLASH_MODE_CFG BIT(3)
++#define GPIO18_FLASH_MODE_CFG BIT(2)
++#define GPIO17_FLASH_MODE_CFG BIT(1)
++#define GPIO16_FLASH_MODE_CFG BIT(0)
++
++#define AIROHA_PINCTRL_GPIO(gpio, mux_val) \
++ { \
++ .name = (gpio), \
++ .regmap[0] = { \
++ AIROHA_FUNC_MUX, \
++ REG_GPIO_PON_MODE, \
++ (mux_val), \
++ (mux_val) \
++ }, \
++ .regmap_size = 1, \
++ }
++
++#define AIROHA_PINCTRL_GPIO_EXT(gpio, mux_val, smux_val) \
++ { \
++ .name = (gpio), \
++ .regmap[0] = { \
++ AIROHA_FUNC_PWM_EXT_MUX, \
++ REG_GPIO_FLASH_MODE_CFG_EXT, \
++ (mux_val), \
++ 0 \
++ }, \
++ .regmap[1] = { \
++ AIROHA_FUNC_MUX, \
++ REG_GPIO_PON_MODE, \
++ (smux_val), \
++ (smux_val) \
++ }, \
++ .regmap_size = 2, \
++ }
++
++/* 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, \
++ }
++
++#define AIROHA_PINCTRL_PWM_EXT_SEC(gpio, mux_val, smux_val) \
++ { \
++ .name = (gpio), \
++ .regmap[0] = { \
++ AIROHA_FUNC_PWM_EXT_MUX, \
++ REG_GPIO_FLASH_MODE_CFG_EXT, \
++ (mux_val), \
++ (mux_val) \
++ }, \
++ .regmap[1] = { \
++ AIROHA_FUNC_MUX, \
++ REG_GPIO_PON_MODE, \
++ (smux_val), \
++ (smux_val) \
++ }, \
++ .regmap_size = 2, \
++ }
++
++#define AIROHA_PINCTRL_PHY_LED0(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, \
++ }
++
++#define AIROHA_PINCTRL_PHY_LED1(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_LED1_MAPPING, \
++ (map_mask), \
++ (map_val), \
++ }, \
++ .regmap_size = 2, \
++ }
++
++static struct pinctrl_pin_desc pinctrl_pins[] = {
++ PINCTRL_PIN(2, "i2c_sda"),
++ PINCTRL_PIN(3, "i2c_scl"),
++ PINCTRL_PIN(4, "spi_cs0"),
++ PINCTRL_PIN(5, "spi_clk"),
++ PINCTRL_PIN(6, "spi_mosi"),
++ PINCTRL_PIN(7, "spi_miso"),
++ PINCTRL_PIN(8, "uart1_txd"),
++ PINCTRL_PIN(9, "uart1_rxd"),
++ PINCTRL_PIN(12, "gpio0"),
++ PINCTRL_PIN(13, "gpio1"),
++ PINCTRL_PIN(14, "gpio2"),
++ PINCTRL_PIN(15, "gpio3"),
++ PINCTRL_PIN(16, "gpio4"),
++ PINCTRL_PIN(17, "gpio5"),
++ PINCTRL_PIN(18, "gpio6"),
++ PINCTRL_PIN(19, "gpio7"),
++ PINCTRL_PIN(20, "gpio8"),
++ PINCTRL_PIN(21, "gpio9"),
++ PINCTRL_PIN(22, "gpio10"),
++ PINCTRL_PIN(23, "gpio11"),
++ PINCTRL_PIN(24, "gpio12"),
++ PINCTRL_PIN(25, "gpio13"),
++ PINCTRL_PIN(26, "gpio14"),
++ PINCTRL_PIN(27, "gpio15"),
++ PINCTRL_PIN(28, "gpio16"),
++ PINCTRL_PIN(29, "gpio17"),
++ PINCTRL_PIN(30, "gpio18"),
++ PINCTRL_PIN(31, "gpio19"),
++ PINCTRL_PIN(32, "gpio20"),
++ PINCTRL_PIN(33, "gpio21"),
++ PINCTRL_PIN(34, "gpio22"),
++ PINCTRL_PIN(35, "gpio23"),
++ PINCTRL_PIN(36, "gpio24"),
++ PINCTRL_PIN(37, "gpio25"),
++ PINCTRL_PIN(38, "gpio26"),
++ PINCTRL_PIN(39, "gpio27"),
++ PINCTRL_PIN(40, "pcie_reset0"),
++ PINCTRL_PIN(41, "pcie_reset1"),
++};
++
++static const int pon_pins[] = { 28, 29, 30, 31, 32, 33 };
++static const int pon_tod_1pps_pins[] = { 21 };
++static const int gsw_tod_1pps_pins[] = { 21 };
++static const int sipo_pins[] = { 13, 38 };
++static const int sipo_rclk_pins[] = { 13, 30, 38 };
++static const int mdio_pins[] = { 20, 21 };
++static const int uart2_pins[] = { 20, 21 };
++static const int npu_uart_pins[] = { 13, 38 };
++static const int i2c0_pins[] = { 2, 3 };
++static const int i2c1_pins[] = { 14, 15 };
++static const int jtag_udi_pins[] = { 34, 35, 36, 37, 38 };
++static const int jtag_dfd_pins[] = { 34, 35, 36, 37, 38 };
++static const int i2s_pins[] = { 16, 17, 18, 19 };
++static const int pcm1_pins[] = { 24, 25, 26, 27 };
++static const int pcm2_pins[] = { 16, 17, 18, 19 };
++static const int spi_pins[] = { 4, 5, 6, 7 };
++static const int spi_quad_pins[] = { 14, 15 };
++static const int spi_cs1_pins[] = { 21 };
++static const int pcm_spi_pins[] = { 16, 17, 18, 19, 24, 25, 26, 27 };
++static const int pcm_spi_int_pins[] = { 15 };
++static const int pcm_spi_rst_pins[] = { 14 };
++static const int pcm_spi_cs1_pins[] = { 22 };
++static const int pcm_spi_cs2_p128_pins[] = { 39 };
++static const int pcm_spi_cs2_p156_pins[] = { 39 };
++static const int pcm_spi_cs3_pins[] = { 20 };
++static const int pcm_spi_cs4_pins[] = { 23 };
++static const int gpio0_pins[] = { 12 };
++static const int gpio1_pins[] = { 13 };
++static const int gpio2_pins[] = { 14 };
++static const int gpio3_pins[] = { 15 };
++static const int gpio4_pins[] = { 16 };
++static const int gpio5_pins[] = { 17 };
++static const int gpio6_pins[] = { 18 };
++static const int gpio7_pins[] = { 19 };
++static const int gpio8_pins[] = { 20 };
++static const int gpio9_pins[] = { 21 };
++static const int gpio10_pins[] = { 22 };
++static const int gpio11_pins[] = { 23 };
++static const int gpio12_pins[] = { 24 };
++static const int gpio13_pins[] = { 25 };
++static const int gpio14_pins[] = { 26 };
++static const int gpio15_pins[] = { 27 };
++static const int gpio16_pins[] = { 28 };
++static const int gpio17_pins[] = { 29 };
++static const int gpio18_pins[] = { 30 };
++static const int gpio19_pins[] = { 31 };
++static const int gpio20_pins[] = { 32 };
++static const int gpio21_pins[] = { 33 };
++static const int gpio22_pins[] = { 34 };
++static const int gpio23_pins[] = { 35 };
++static const int gpio24_pins[] = { 36 };
++static const int gpio25_pins[] = { 37 };
++static const int gpio26_pins[] = { 38 };
++static const int gpio27_pins[] = { 39 };
++static const int gpio28_pins[] = { 40 };
++static const int gpio29_pins[] = { 41 };
++static const int pcie_reset0_pins[] = { 40 };
++static const int pcie_reset1_pins[] = { 41 };
++
++static const struct pingroup pinctrl_groups[] = {
++ PINCTRL_PIN_GROUP("pon", pon),
++ PINCTRL_PIN_GROUP("pon_tod_1pps", pon_tod_1pps),
++ PINCTRL_PIN_GROUP("gsw_tod_1pps", gsw_tod_1pps),
++ PINCTRL_PIN_GROUP("sipo", sipo),
++ PINCTRL_PIN_GROUP("sipo_rclk", sipo_rclk),
++ PINCTRL_PIN_GROUP("mdio", mdio),
++ PINCTRL_PIN_GROUP("uart2", uart2),
++ PINCTRL_PIN_GROUP("npu_uart", npu_uart),
++ PINCTRL_PIN_GROUP("i2c0", i2c0),
++ PINCTRL_PIN_GROUP("i2c1", i2c1),
++ PINCTRL_PIN_GROUP("jtag_udi", jtag_udi),
++ PINCTRL_PIN_GROUP("jtag_dfd", jtag_dfd),
++ PINCTRL_PIN_GROUP("i2s", i2s),
++ PINCTRL_PIN_GROUP("pcm1", pcm1),
++ PINCTRL_PIN_GROUP("pcm2", pcm2),
++ PINCTRL_PIN_GROUP("spi", spi),
++ PINCTRL_PIN_GROUP("spi_quad", spi_quad),
++ PINCTRL_PIN_GROUP("spi_cs1", spi_cs1),
++ PINCTRL_PIN_GROUP("pcm_spi", pcm_spi),
++ PINCTRL_PIN_GROUP("pcm_spi_int", pcm_spi_int),
++ PINCTRL_PIN_GROUP("pcm_spi_rst", pcm_spi_rst),
++ PINCTRL_PIN_GROUP("pcm_spi_cs1", pcm_spi_cs1),
++ PINCTRL_PIN_GROUP("pcm_spi_cs2_p128", pcm_spi_cs2_p128),
++ PINCTRL_PIN_GROUP("pcm_spi_cs2_p156", pcm_spi_cs2_p156),
++ PINCTRL_PIN_GROUP("pcm_spi_cs3", pcm_spi_cs3),
++ PINCTRL_PIN_GROUP("pcm_spi_cs4", pcm_spi_cs4),
++ PINCTRL_PIN_GROUP("gpio0", gpio0),
++ PINCTRL_PIN_GROUP("gpio1", gpio1),
++ PINCTRL_PIN_GROUP("gpio2", gpio2),
++ PINCTRL_PIN_GROUP("gpio3", gpio3),
++ PINCTRL_PIN_GROUP("gpio4", gpio4),
++ PINCTRL_PIN_GROUP("gpio5", gpio5),
++ PINCTRL_PIN_GROUP("gpio6", gpio6),
++ PINCTRL_PIN_GROUP("gpio7", gpio7),
++ PINCTRL_PIN_GROUP("gpio8", gpio8),
++ PINCTRL_PIN_GROUP("gpio9", gpio9),
++ PINCTRL_PIN_GROUP("gpio10", gpio10),
++ PINCTRL_PIN_GROUP("gpio11", gpio11),
++ PINCTRL_PIN_GROUP("gpio12", gpio12),
++ PINCTRL_PIN_GROUP("gpio13", gpio13),
++ PINCTRL_PIN_GROUP("gpio14", gpio14),
++ PINCTRL_PIN_GROUP("gpio15", gpio15),
++ PINCTRL_PIN_GROUP("gpio16", gpio16),
++ PINCTRL_PIN_GROUP("gpio17", gpio17),
++ PINCTRL_PIN_GROUP("gpio18", gpio18),
++ PINCTRL_PIN_GROUP("gpio19", gpio19),
++ PINCTRL_PIN_GROUP("gpio20", gpio20),
++ PINCTRL_PIN_GROUP("gpio21", gpio21),
++ PINCTRL_PIN_GROUP("gpio22", gpio22),
++ PINCTRL_PIN_GROUP("gpio23", gpio23),
++ PINCTRL_PIN_GROUP("gpio24", gpio24),
++ PINCTRL_PIN_GROUP("gpio25", gpio25),
++ PINCTRL_PIN_GROUP("gpio26", gpio26),
++ PINCTRL_PIN_GROUP("gpio27", gpio27),
++ PINCTRL_PIN_GROUP("gpio28", gpio28),
++ PINCTRL_PIN_GROUP("gpio29", gpio29),
++ PINCTRL_PIN_GROUP("pcie_reset0", pcie_reset0),
++ PINCTRL_PIN_GROUP("pcie_reset1", 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 uart_groups[] = { "uart2", "npu_uart" };
++static const char *const i2c_groups[] = { "i2c1" };
++static const char *const jtag_groups[] = { "jtag_udi", "jtag_dfd" };
++static const char *const pcm_groups[] = { "pcm1", "pcm2" };
++static const char *const spi_groups[] = { "spi_quad", "spi_cs1" };
++static const char *const pcm_spi_groups[] = {
++ "pcm_spi", "pcm_spi_int", "pcm_spi_rst", "pcm_spi_cs1",
++ "pcm_spi_cs2_p156", "pcm_spi_cs2_p128", "pcm_spi_cs3", "pcm_spi_cs4"
++};
++static const char *const i2s_groups[] = { "i2s" };
++static const char *const gpio_groups[] = { "gpio28", "gpio29" };
++static const char *const pcie_reset_groups[] = {
++ "pcie_reset0", "pcie_reset1"
++};
++static const char *const pwm_groups[] = {
++ "gpio0", "gpio1", "gpio2", "gpio3", "gpio4", "gpio5",
++ "gpio6", "gpio7", "gpio8", "gpio9", "gpio10", "gpio11",
++ "gpio12", "gpio13", "gpio14", "gpio15", "gpio16", "gpio17",
++ "gpio18", "gpio19", "gpio20", "gpio21", "gpio22", "gpio23",
++ "gpio24", "gpio25", "gpio26", "gpio27", "gpio28", "gpio29"
++};
++static const char *const phy1_led0_groups[] = {
++ "gpio22", "gpio23", "gpio24", "gpio25"
++};
++static const char *const phy2_led0_groups[] = {
++ "gpio22", "gpio23", "gpio24", "gpio25"
++};
++static const char *const phy3_led0_groups[] = {
++ "gpio22", "gpio23", "gpio24", "gpio25"
++};
++static const char *const phy4_led0_groups[] = {
++ "gpio22", "gpio23", "gpio24", "gpio25"
++};
++static const char *const phy1_led1_groups[] = {
++ "gpio7", "gpio6", "gpio5", "gpio4"
++};
++static const char *const phy2_led1_groups[] = {
++ "gpio7", "gpio6", "gpio5", "gpio4"
++};
++static const char *const phy3_led1_groups[] = {
++ "gpio7", "gpio6", "gpio5", "gpio4"
++};
++static const char *const phy4_led1_groups[] = {
++ "gpio7", "gpio6", "gpio5", "gpio4"
++};
++
++static const struct airoha_pinctrl_func_group pon_func_group[] = {
++ {
++ .name = "pon",
++ .regmap[0] = {
++ AIROHA_FUNC_MUX,
++ REG_GPIO_PON_MODE,
++ GPIO_PON_MODE_MASK,
++ GPIO_PON_MODE_MASK
++ },
++ .regmap_size = 1,
++ },
++};
++
++static const struct airoha_pinctrl_func_group tod_1pps_func_group[] = {
++ {
++ .name = "pon_tod_1pps",
++ .regmap[0] = {
++ AIROHA_FUNC_MUX,
++ REG_GPIO_2ND_I2C_MODE,
++ PON_TOD_1PPS_MODE_MASK,
++ PON_TOD_1PPS_MODE_MASK
++ },
++ .regmap_size = 1,
++ }, {
++ .name = "gsw_tod_1pps",
++ .regmap[0] = {
++ AIROHA_FUNC_MUX,
++ REG_GPIO_2ND_I2C_MODE,
++ GSW_TOD_1PPS_MODE_MASK,
++ GSW_TOD_1PPS_MODE_MASK
++ },
++ .regmap_size = 1,
++ },
++};
++
++static const struct airoha_pinctrl_func_group sipo_func_group[] = {
++ {
++ .name = "sipo",
++ .regmap[0] = {
++ AIROHA_FUNC_MUX,
++ REG_GPIO_PON_MODE,
++ GPIO_SIPO_MODE_MASK | SIPO_RCLK_MODE_MASK,
++ GPIO_SIPO_MODE_MASK
++ },
++ .regmap_size = 1,
++ }, {
++ .name = "sipo_rclk",
++ .regmap[0] = {
++ AIROHA_FUNC_MUX,
++ REG_GPIO_PON_MODE,
++ GPIO_SIPO_MODE_MASK | SIPO_RCLK_MODE_MASK,
++ GPIO_SIPO_MODE_MASK | SIPO_RCLK_MODE_MASK
++ },
++ .regmap_size = 1,
++ },
++};
++
++static const struct airoha_pinctrl_func_group 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_size = 1,
++ },
++};
++
++static const struct airoha_pinctrl_func_group uart_func_group[] = {
++ {
++ .name = "uart2",
++ .regmap[0] = {
++ AIROHA_FUNC_MUX,
++ REG_GPIO_PON_MODE,
++ GPIO_UART2_MODE_MASK,
++ GPIO_UART2_MODE_MASK
++ },
++ .regmap_size = 1,
++ }, {
++ .name = "npu_uart",
++ .regmap[0] = {
++ AIROHA_FUNC_MUX,
++ REG_NPU_UART_EN,
++ NPU_UART_EN_MASK,
++ NPU_UART_EN_MASK
++ },
++ .regmap_size = 1,
++ }
++};
++
++static const struct airoha_pinctrl_func_group i2c_func_group[] = {
++ {
++ .name = "i2c1",
++ .regmap[0] = {
++ AIROHA_FUNC_MUX,
++ REG_GPIO_2ND_I2C_MODE,
++ GPIO_2ND_I2C_MODE_MASK,
++ GPIO_2ND_I2C_MODE_MASK
++ },
++ .regmap_size = 1,
++ },
++};
++
++static const struct airoha_pinctrl_func_group jtag_func_group[] = {
++ {
++ .name = "jtag_udi",
++ .regmap[0] = {
++ AIROHA_FUNC_MUX,
++ REG_NPU_UART_EN,
++ JTAG_UDI_EN_MASK,
++ JTAG_UDI_EN_MASK
++ },
++ .regmap_size = 1,
++ }, {
++ .name = "jtag_dfd",
++ .regmap[0] = {
++ AIROHA_FUNC_MUX,
++ REG_NPU_UART_EN,
++ JTAG_DFD_EN_MASK,
++ JTAG_DFD_EN_MASK
++ },
++ .regmap_size = 1,
++ },
++};
++
++static const struct airoha_pinctrl_func_group pcm_func_group[] = {
++ {
++ .name = "pcm1",
++ .regmap[0] = {
++ AIROHA_FUNC_MUX,
++ REG_GPIO_SPI_CS1_MODE,
++ GPIO_PCM1_MODE_MASK,
++ GPIO_PCM1_MODE_MASK
++ },
++ .regmap_size = 1,
++ }, {
++ .name = "pcm2",
++ .regmap[0] = {
++ AIROHA_FUNC_MUX,
++ REG_GPIO_SPI_CS1_MODE,
++ GPIO_PCM2_MODE_MASK,
++ GPIO_PCM2_MODE_MASK
++ },
++ .regmap_size = 1,
++ },
++};
++
++static const struct airoha_pinctrl_func_group spi_func_group[] = {
++ {
++ .name = "spi_quad",
++ .regmap[0] = {
++ AIROHA_FUNC_MUX,
++ REG_GPIO_SPI_CS1_MODE,
++ GPIO_SPI_QUAD_MODE_MASK,
++ GPIO_SPI_QUAD_MODE_MASK
++ },
++ .regmap_size = 1,
++ }, {
++ .name = "spi_cs1",
++ .regmap[0] = {
++ AIROHA_FUNC_MUX,
++ REG_GPIO_SPI_CS1_MODE,
++ GPIO_SPI_CS1_MODE_MASK,
++ GPIO_SPI_CS1_MODE_MASK
++ },
++ .regmap_size = 1,
++ },
++};
++
++static const struct airoha_pinctrl_func_group 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_p128",
++ .regmap[0] = {
++ AIROHA_FUNC_MUX,
++ REG_GPIO_SPI_CS1_MODE,
++ GPIO_PCM_SPI_CS2_MODE_P128_MASK,
++ GPIO_PCM_SPI_CS2_MODE_P128_MASK
++ },
++ .regmap_size = 1,
++ }, {
++ .name = "pcm_spi_cs2_p156",
++ .regmap[0] = {
++ AIROHA_FUNC_MUX,
++ REG_GPIO_SPI_CS1_MODE,
++ GPIO_PCM_SPI_CS2_MODE_P156_MASK,
++ GPIO_PCM_SPI_CS2_MODE_P156_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",
++ .regmap[0] = {
++ AIROHA_FUNC_MUX,
++ REG_GPIO_2ND_I2C_MODE,
++ GPIO_I2S_MODE_MASK,
++ GPIO_I2S_MODE_MASK
++ },
++ .regmap_size = 1,
++ },
++};
++
++static const struct airoha_pinctrl_func_group gpio_func_group[] = {
++ AIROHA_PINCTRL_GPIO_EXT("gpio28", GPIO28_FLASH_MODE_CFG,
++ GPIO_PCIE_RESET0_MASK),
++ AIROHA_PINCTRL_GPIO_EXT("gpio29", GPIO29_FLASH_MODE_CFG,
++ GPIO_PCIE_RESET1_MASK),
++};
++
++static const struct airoha_pinctrl_func_group pcie_reset_func_group[] = {
++ {
++ .name = "pcie_reset0",
++ .regmap[0] = {
++ AIROHA_FUNC_MUX,
++ REG_GPIO_PON_MODE,
++ GPIO_PCIE_RESET0_MASK,
++ 0
++ },
++ .regmap_size = 1,
++ }, {
++ .name = "pcie_reset1",
++ .regmap[0] = {
++ AIROHA_FUNC_MUX,
++ REG_GPIO_PON_MODE,
++ GPIO_PCIE_RESET1_MASK,
++ 0
++ },
++ .regmap_size = 1,
++ },
++};
++
++static const struct airoha_pinctrl_func_group pwm_func_group[] = {
++ 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_SEC("gpio28", GPIO28_FLASH_MODE_CFG,
++ GPIO_PCIE_RESET0_MASK),
++ AIROHA_PINCTRL_PWM_EXT_SEC("gpio29", GPIO29_FLASH_MODE_CFG,
++ GPIO_PCIE_RESET1_MASK),
++};
++
++static const struct airoha_pinctrl_func_group phy1_led0_func_group[] = {
++ AIROHA_PINCTRL_PHY_LED0("gpio22", GPIO_LAN0_LED0_MODE_MASK,
++ LAN0_LED_MAPPING_MASK, LAN0_PHY_LED_MAP(0)),
++ AIROHA_PINCTRL_PHY_LED0("gpio23", GPIO_LAN1_LED0_MODE_MASK,
++ LAN1_LED_MAPPING_MASK, LAN1_PHY_LED_MAP(0)),
++ AIROHA_PINCTRL_PHY_LED0("gpio24", GPIO_LAN2_LED0_MODE_MASK,
++ LAN2_LED_MAPPING_MASK, LAN2_PHY_LED_MAP(0)),
++ AIROHA_PINCTRL_PHY_LED0("gpio25", 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[] = {
++ AIROHA_PINCTRL_PHY_LED0("gpio22", GPIO_LAN0_LED0_MODE_MASK,
++ LAN0_LED_MAPPING_MASK, LAN0_PHY_LED_MAP(1)),
++ AIROHA_PINCTRL_PHY_LED0("gpio23", GPIO_LAN1_LED0_MODE_MASK,
++ LAN1_LED_MAPPING_MASK, LAN1_PHY_LED_MAP(1)),
++ AIROHA_PINCTRL_PHY_LED0("gpio24", GPIO_LAN2_LED0_MODE_MASK,
++ LAN2_LED_MAPPING_MASK, LAN2_PHY_LED_MAP(1)),
++ AIROHA_PINCTRL_PHY_LED0("gpio25", 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[] = {
++ AIROHA_PINCTRL_PHY_LED0("gpio22", GPIO_LAN0_LED0_MODE_MASK,
++ LAN0_LED_MAPPING_MASK, LAN0_PHY_LED_MAP(2)),
++ AIROHA_PINCTRL_PHY_LED0("gpio23", GPIO_LAN1_LED0_MODE_MASK,
++ LAN1_LED_MAPPING_MASK, LAN1_PHY_LED_MAP(2)),
++ AIROHA_PINCTRL_PHY_LED0("gpio24", GPIO_LAN2_LED0_MODE_MASK,
++ LAN2_LED_MAPPING_MASK, LAN2_PHY_LED_MAP(2)),
++ AIROHA_PINCTRL_PHY_LED0("gpio25", 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[] = {
++ AIROHA_PINCTRL_PHY_LED0("gpio22", GPIO_LAN0_LED0_MODE_MASK,
++ LAN0_LED_MAPPING_MASK, LAN0_PHY_LED_MAP(3)),
++ AIROHA_PINCTRL_PHY_LED0("gpio23", GPIO_LAN1_LED0_MODE_MASK,
++ LAN1_LED_MAPPING_MASK, LAN1_PHY_LED_MAP(3)),
++ AIROHA_PINCTRL_PHY_LED0("gpio24", GPIO_LAN2_LED0_MODE_MASK,
++ LAN2_LED_MAPPING_MASK, LAN2_PHY_LED_MAP(3)),
++ AIROHA_PINCTRL_PHY_LED0("gpio25", 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[] = {
++ AIROHA_PINCTRL_PHY_LED1("gpio7", GPIO_LAN0_LED1_MODE_MASK,
++ LAN0_LED_MAPPING_MASK, LAN0_PHY_LED_MAP(0)),
++ AIROHA_PINCTRL_PHY_LED1("gpio6", GPIO_LAN1_LED1_MODE_MASK,
++ LAN1_LED_MAPPING_MASK, LAN1_PHY_LED_MAP(0)),
++ AIROHA_PINCTRL_PHY_LED1("gpio5", GPIO_LAN2_LED1_MODE_MASK,
++ LAN2_LED_MAPPING_MASK, LAN2_PHY_LED_MAP(0)),
++ AIROHA_PINCTRL_PHY_LED1("gpio4", 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[] = {
++ AIROHA_PINCTRL_PHY_LED1("gpio7", GPIO_LAN0_LED1_MODE_MASK,
++ LAN0_LED_MAPPING_MASK, LAN0_PHY_LED_MAP(1)),
++ AIROHA_PINCTRL_PHY_LED1("gpio6", GPIO_LAN1_LED1_MODE_MASK,
++ LAN1_LED_MAPPING_MASK, LAN1_PHY_LED_MAP(1)),
++ AIROHA_PINCTRL_PHY_LED1("gpio5", GPIO_LAN2_LED1_MODE_MASK,
++ LAN2_LED_MAPPING_MASK, LAN2_PHY_LED_MAP(1)),
++ AIROHA_PINCTRL_PHY_LED1("gpio4", 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[] = {
++ AIROHA_PINCTRL_PHY_LED1("gpio7", GPIO_LAN0_LED1_MODE_MASK,
++ LAN0_LED_MAPPING_MASK, LAN0_PHY_LED_MAP(2)),
++ AIROHA_PINCTRL_PHY_LED1("gpio6", GPIO_LAN1_LED1_MODE_MASK,
++ LAN1_LED_MAPPING_MASK, LAN1_PHY_LED_MAP(2)),
++ AIROHA_PINCTRL_PHY_LED1("gpio5", GPIO_LAN2_LED1_MODE_MASK,
++ LAN2_LED_MAPPING_MASK, LAN2_PHY_LED_MAP(2)),
++ AIROHA_PINCTRL_PHY_LED1("gpio4", 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[] = {
++ AIROHA_PINCTRL_PHY_LED1("gpio7", GPIO_LAN0_LED1_MODE_MASK,
++ LAN0_LED_MAPPING_MASK, LAN0_PHY_LED_MAP(3)),
++ AIROHA_PINCTRL_PHY_LED1("gpio6", GPIO_LAN1_LED1_MODE_MASK,
++ LAN1_LED_MAPPING_MASK, LAN1_PHY_LED_MAP(3)),
++ AIROHA_PINCTRL_PHY_LED1("gpio5", GPIO_LAN2_LED1_MODE_MASK,
++ LAN2_LED_MAPPING_MASK, LAN2_PHY_LED_MAP(3)),
++ AIROHA_PINCTRL_PHY_LED1("gpio4", GPIO_LAN3_LED1_MODE_MASK,
++ LAN3_LED_MAPPING_MASK, LAN3_PHY_LED_MAP(3)),
++};
++
++static const struct airoha_pinctrl_func 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("gpio", gpio),
++ 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 pinctrl_pullup_conf[] = {
++ PINCTRL_CONF_DESC(12, REG_GPIO_L_PU, BIT(0)),
++ PINCTRL_CONF_DESC(13, REG_GPIO_L_PU, BIT(1)),
++ PINCTRL_CONF_DESC(14, REG_GPIO_L_PU, BIT(2)),
++ PINCTRL_CONF_DESC(15, REG_GPIO_L_PU, BIT(3)),
++ PINCTRL_CONF_DESC(16, REG_GPIO_L_PU, BIT(4)),
++ PINCTRL_CONF_DESC(17, REG_GPIO_L_PU, BIT(5)),
++ PINCTRL_CONF_DESC(18, REG_GPIO_L_PU, BIT(6)),
++ PINCTRL_CONF_DESC(19, REG_GPIO_L_PU, BIT(7)),
++ PINCTRL_CONF_DESC(20, REG_GPIO_L_PU, BIT(8)),
++ PINCTRL_CONF_DESC(21, REG_GPIO_L_PU, BIT(9)),
++ PINCTRL_CONF_DESC(22, REG_GPIO_L_PU, BIT(10)),
++ PINCTRL_CONF_DESC(23, REG_GPIO_L_PU, BIT(11)),
++ PINCTRL_CONF_DESC(24, REG_GPIO_L_PU, BIT(12)),
++ PINCTRL_CONF_DESC(25, REG_GPIO_L_PU, BIT(13)),
++ PINCTRL_CONF_DESC(26, REG_GPIO_L_PU, BIT(14)),
++ PINCTRL_CONF_DESC(27, REG_GPIO_L_PU, BIT(15)),
++ PINCTRL_CONF_DESC(28, REG_GPIO_L_PU, BIT(16)),
++ PINCTRL_CONF_DESC(29, REG_GPIO_L_PU, BIT(17)),
++ PINCTRL_CONF_DESC(30, REG_GPIO_L_PU, BIT(18)),
++ PINCTRL_CONF_DESC(31, REG_GPIO_L_PU, BIT(19)),
++ PINCTRL_CONF_DESC(32, REG_GPIO_L_PU, BIT(20)),
++ PINCTRL_CONF_DESC(33, REG_GPIO_L_PU, BIT(21)),
++ PINCTRL_CONF_DESC(34, REG_GPIO_L_PU, BIT(22)),
++ PINCTRL_CONF_DESC(35, REG_GPIO_L_PU, BIT(23)),
++ PINCTRL_CONF_DESC(36, REG_GPIO_L_PU, BIT(24)),
++ PINCTRL_CONF_DESC(37, REG_GPIO_L_PU, BIT(25)),
++ PINCTRL_CONF_DESC(38, REG_GPIO_L_PU, BIT(26)),
++ PINCTRL_CONF_DESC(39, REG_GPIO_L_PU, BIT(27)),
++ PINCTRL_CONF_DESC(40, REG_GPIO_L_PU, BIT(28)),
++ PINCTRL_CONF_DESC(41, REG_GPIO_L_PU, BIT(29)),
++};
++
++static const struct airoha_pinctrl_conf pinctrl_pulldown_conf[] = {
++ PINCTRL_CONF_DESC(12, REG_GPIO_L_PD, BIT(0)),
++ PINCTRL_CONF_DESC(13, REG_GPIO_L_PD, BIT(1)),
++ PINCTRL_CONF_DESC(14, REG_GPIO_L_PD, BIT(2)),
++ PINCTRL_CONF_DESC(15, REG_GPIO_L_PD, BIT(3)),
++ PINCTRL_CONF_DESC(16, REG_GPIO_L_PD, BIT(4)),
++ PINCTRL_CONF_DESC(17, REG_GPIO_L_PD, BIT(5)),
++ PINCTRL_CONF_DESC(18, REG_GPIO_L_PD, BIT(6)),
++ PINCTRL_CONF_DESC(19, REG_GPIO_L_PD, BIT(7)),
++ PINCTRL_CONF_DESC(20, REG_GPIO_L_PD, BIT(8)),
++ PINCTRL_CONF_DESC(21, REG_GPIO_L_PD, BIT(9)),
++ PINCTRL_CONF_DESC(22, REG_GPIO_L_PD, BIT(10)),
++ PINCTRL_CONF_DESC(23, REG_GPIO_L_PD, BIT(11)),
++ PINCTRL_CONF_DESC(24, REG_GPIO_L_PD, BIT(12)),
++ PINCTRL_CONF_DESC(25, REG_GPIO_L_PD, BIT(13)),
++ PINCTRL_CONF_DESC(26, REG_GPIO_L_PD, BIT(14)),
++ PINCTRL_CONF_DESC(27, REG_GPIO_L_PD, BIT(15)),
++ PINCTRL_CONF_DESC(28, REG_GPIO_L_PD, BIT(16)),
++ PINCTRL_CONF_DESC(29, REG_GPIO_L_PD, BIT(17)),
++ PINCTRL_CONF_DESC(30, REG_GPIO_L_PD, BIT(18)),
++ PINCTRL_CONF_DESC(31, REG_GPIO_L_PD, BIT(19)),
++ PINCTRL_CONF_DESC(32, REG_GPIO_L_PD, BIT(20)),
++ PINCTRL_CONF_DESC(33, REG_GPIO_L_PD, BIT(21)),
++ PINCTRL_CONF_DESC(34, REG_GPIO_L_PD, BIT(22)),
++ PINCTRL_CONF_DESC(35, REG_GPIO_L_PD, BIT(23)),
++ PINCTRL_CONF_DESC(36, REG_GPIO_L_PD, BIT(24)),
++ PINCTRL_CONF_DESC(37, REG_GPIO_L_PD, BIT(25)),
++ PINCTRL_CONF_DESC(38, REG_GPIO_L_PD, BIT(26)),
++ PINCTRL_CONF_DESC(39, REG_GPIO_L_PD, BIT(27)),
++ PINCTRL_CONF_DESC(40, REG_GPIO_L_PD, BIT(28)),
++ PINCTRL_CONF_DESC(41, REG_GPIO_L_PD, BIT(29)),
++};
++
++static const struct airoha_pinctrl_conf pinctrl_drive_e2_conf[] = {
++ PINCTRL_CONF_DESC(12, REG_GPIO_L_E2, BIT(0)),
++ PINCTRL_CONF_DESC(13, REG_GPIO_L_E2, BIT(1)),
++ PINCTRL_CONF_DESC(14, REG_GPIO_L_E2, BIT(2)),
++ PINCTRL_CONF_DESC(15, REG_GPIO_L_E2, BIT(3)),
++ PINCTRL_CONF_DESC(16, REG_GPIO_L_E2, BIT(4)),
++ PINCTRL_CONF_DESC(17, REG_GPIO_L_E2, BIT(5)),
++ PINCTRL_CONF_DESC(18, REG_GPIO_L_E2, BIT(6)),
++ PINCTRL_CONF_DESC(19, REG_GPIO_L_E2, BIT(7)),
++ PINCTRL_CONF_DESC(20, REG_GPIO_L_E2, BIT(8)),
++ PINCTRL_CONF_DESC(21, REG_GPIO_L_E2, BIT(9)),
++ PINCTRL_CONF_DESC(22, REG_GPIO_L_E2, BIT(10)),
++ PINCTRL_CONF_DESC(23, REG_GPIO_L_E2, BIT(11)),
++ PINCTRL_CONF_DESC(24, REG_GPIO_L_E2, BIT(12)),
++ PINCTRL_CONF_DESC(25, REG_GPIO_L_E2, BIT(13)),
++ PINCTRL_CONF_DESC(26, REG_GPIO_L_E2, BIT(14)),
++ PINCTRL_CONF_DESC(27, REG_GPIO_L_E2, BIT(15)),
++ PINCTRL_CONF_DESC(28, REG_GPIO_L_E2, BIT(16)),
++ PINCTRL_CONF_DESC(29, REG_GPIO_L_E2, BIT(17)),
++ PINCTRL_CONF_DESC(30, REG_GPIO_L_E2, BIT(18)),
++ PINCTRL_CONF_DESC(31, REG_GPIO_L_E2, BIT(19)),
++ PINCTRL_CONF_DESC(32, REG_GPIO_L_E2, BIT(20)),
++ PINCTRL_CONF_DESC(33, REG_GPIO_L_E2, BIT(21)),
++ PINCTRL_CONF_DESC(34, REG_GPIO_L_E2, BIT(22)),
++ PINCTRL_CONF_DESC(35, REG_GPIO_L_E2, BIT(23)),
++ PINCTRL_CONF_DESC(36, REG_GPIO_L_E2, BIT(24)),
++ PINCTRL_CONF_DESC(37, REG_GPIO_L_E2, BIT(25)),
++ PINCTRL_CONF_DESC(38, REG_GPIO_L_E2, BIT(26)),
++ PINCTRL_CONF_DESC(39, REG_GPIO_L_E2, BIT(27)),
++ PINCTRL_CONF_DESC(40, REG_GPIO_L_E2, BIT(28)),
++ PINCTRL_CONF_DESC(41, REG_GPIO_L_E2, BIT(29)),
++};
++
++static const struct airoha_pinctrl_conf pinctrl_drive_e4_conf[] = {
++ PINCTRL_CONF_DESC(12, REG_GPIO_L_E4, BIT(0)),
++ PINCTRL_CONF_DESC(13, REG_GPIO_L_E4, BIT(1)),
++ PINCTRL_CONF_DESC(14, REG_GPIO_L_E4, BIT(2)),
++ PINCTRL_CONF_DESC(15, REG_GPIO_L_E4, BIT(3)),
++ PINCTRL_CONF_DESC(16, REG_GPIO_L_E4, BIT(4)),
++ PINCTRL_CONF_DESC(17, REG_GPIO_L_E4, BIT(5)),
++ PINCTRL_CONF_DESC(18, REG_GPIO_L_E4, BIT(6)),
++ PINCTRL_CONF_DESC(19, REG_GPIO_L_E4, BIT(7)),
++ PINCTRL_CONF_DESC(20, REG_GPIO_L_E4, BIT(8)),
++ PINCTRL_CONF_DESC(21, REG_GPIO_L_E4, BIT(9)),
++ PINCTRL_CONF_DESC(22, REG_GPIO_L_E4, BIT(10)),
++ PINCTRL_CONF_DESC(23, REG_GPIO_L_E4, BIT(11)),
++ PINCTRL_CONF_DESC(24, REG_GPIO_L_E4, BIT(12)),
++ PINCTRL_CONF_DESC(25, REG_GPIO_L_E4, BIT(13)),
++ PINCTRL_CONF_DESC(26, REG_GPIO_L_E4, BIT(14)),
++ PINCTRL_CONF_DESC(27, REG_GPIO_L_E4, BIT(15)),
++ PINCTRL_CONF_DESC(28, REG_GPIO_L_E4, BIT(16)),
++ PINCTRL_CONF_DESC(29, REG_GPIO_L_E4, BIT(17)),
++ PINCTRL_CONF_DESC(30, REG_GPIO_L_E4, BIT(18)),
++ PINCTRL_CONF_DESC(31, REG_GPIO_L_E4, BIT(19)),
++ PINCTRL_CONF_DESC(32, REG_GPIO_L_E4, BIT(20)),
++ PINCTRL_CONF_DESC(33, REG_GPIO_L_E4, BIT(21)),
++ PINCTRL_CONF_DESC(34, REG_GPIO_L_E4, BIT(22)),
++ PINCTRL_CONF_DESC(35, REG_GPIO_L_E4, BIT(23)),
++ PINCTRL_CONF_DESC(36, REG_GPIO_L_E4, BIT(24)),
++ PINCTRL_CONF_DESC(37, REG_GPIO_L_E4, BIT(25)),
++ PINCTRL_CONF_DESC(38, REG_GPIO_L_E4, BIT(26)),
++ PINCTRL_CONF_DESC(39, REG_GPIO_L_E4, BIT(27)),
++ PINCTRL_CONF_DESC(40, REG_GPIO_L_E4, BIT(28)),
++ PINCTRL_CONF_DESC(41, REG_GPIO_L_E4, BIT(29)),
++};
++
++static const struct airoha_pinctrl_match_data pinctrl_match_data = {
++ .gpio_offs = 12,
++ .gpio_pin_cnt = 30,
++ .chip_scu_compatible = "airoha,en7523-chip-scu",
++ .pins = pinctrl_pins,
++ .num_pins = ARRAY_SIZE(pinctrl_pins),
++ .grps = pinctrl_groups,
++ .num_grps = ARRAY_SIZE(pinctrl_groups),
++ .funcs = pinctrl_funcs,
++ .num_funcs = ARRAY_SIZE(pinctrl_funcs),
++ .confs_info = {
++ [AIROHA_PINCTRL_CONFS_PULLUP] = {
++ .confs = pinctrl_pullup_conf,
++ .num_confs = ARRAY_SIZE(pinctrl_pullup_conf),
++ },
++ [AIROHA_PINCTRL_CONFS_PULLDOWN] = {
++ .confs = pinctrl_pulldown_conf,
++ .num_confs = ARRAY_SIZE(pinctrl_pulldown_conf),
++ },
++ [AIROHA_PINCTRL_CONFS_DRIVE_E2] = {
++ .confs = pinctrl_drive_e2_conf,
++ .num_confs = ARRAY_SIZE(pinctrl_drive_e2_conf),
++ },
++ [AIROHA_PINCTRL_CONFS_DRIVE_E4] = {
++ .confs = pinctrl_drive_e4_conf,
++ .num_confs = ARRAY_SIZE(pinctrl_drive_e4_conf),
++ },
++ },
++};
++
++static const struct udevice_id pinctrl_of_match[] = {
++ { .compatible = "airoha,en7523-pinctrl",
++ .data = (uintptr_t)&pinctrl_match_data },
++ { /* sentinel */ }
++};
++
++U_BOOT_DRIVER(airoha_en7523_pinctrl) = {
++ .name = "airoha-en7523-pinctrl",
++ .id = UCLASS_PINCTRL,
++ .of_match = of_match_ptr(pinctrl_of_match),
++ .probe = airoha_pinctrl_probe,
++ .bind = airoha_pinctrl_bind,
++ .priv_auto = sizeof(struct airoha_pinctrl),
++ .ops = &airoha_pinctrl_ops,
++};
+--
+2.53.0
+
--- /dev/null
+From c721a0c1076d30958ab96f3dd209f7d92c10f750 Mon Sep 17 00:00:00 2001
+From: Mikhail Kshevetskiy <mikhail.kshevetskiy@iopsys.eu>
+Date: Mon, 27 Apr 2026 15:30:41 +0300
+Subject: [PATCH 09/29] configs: airoha: an7581: enable pinctrl/gpio support
+
+This enables AN7581 pin controller and gpio driver.
+Defconfig was minimized with 'make savedefconfig'.
+
+Signed-off-by: Mikhail Kshevetskiy <mikhail.kshevetskiy@iopsys.eu>
+Reviewed-by: David Lechner <dlechner@baylibre.com>
+---
+ configs/an7581_evb_defconfig | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/configs/an7581_evb_defconfig b/configs/an7581_evb_defconfig
+index 07569fa0a4e..a615994cc76 100644
+--- a/configs/an7581_evb_defconfig
++++ b/configs/an7581_evb_defconfig
+@@ -72,7 +72,7 @@ CONFIG_PCS_AIROHA_AN7581=y
+ CONFIG_AIROHA_ETH=y
+ CONFIG_PHY=y
+ CONFIG_PINCTRL=y
+-CONFIG_PINCONF=y
++CONFIG_PINCTRL_AIROHA_AN7581=y
+ CONFIG_POWER_DOMAIN=y
+ CONFIG_DM_REGULATOR=y
+ CONFIG_DM_REGULATOR_FIXED=y
+--
+2.53.0
+
--- /dev/null
+From 2fe4ab7941f5213304c2fdcda022dd013ea81f4c Mon Sep 17 00:00:00 2001
+From: Mikhail Kshevetskiy <mikhail.kshevetskiy@iopsys.eu>
+Date: Mon, 27 Apr 2026 16:01:13 +0300
+Subject: [PATCH 10/29] configs: airoha: en7523: enable pinctrl/gpio support
+
+This enables EN7523 pin controller and gpio driver.
+Defconfig was minimized with 'make savedefconfig'.
+
+Signed-off-by: Mikhail Kshevetskiy <mikhail.kshevetskiy@iopsys.eu>
+Reviewed-by: David Lechner <dlechner@baylibre.com>
+---
+ configs/en7523_evb_defconfig | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/configs/en7523_evb_defconfig b/configs/en7523_evb_defconfig
+index d3137a0ae44..8b1f3c71e9b 100644
+--- a/configs/en7523_evb_defconfig
++++ b/configs/en7523_evb_defconfig
+@@ -54,7 +54,7 @@ CONFIG_DM_MDIO=y
+ CONFIG_AIROHA_ETH=y
+ CONFIG_PHY=y
+ CONFIG_PINCTRL=y
+-CONFIG_PINCONF=y
++CONFIG_PINCTRL_AIROHA_EN7523=y
+ CONFIG_RAM=y
+ CONFIG_DM_SERIAL=y
+ CONFIG_SYS_NS16550=y
+--
+2.53.0
+
--- /dev/null
+From 683bc456ef47c0d63686a60bc496ab2a1122d550 Mon Sep 17 00:00:00 2001
+From: Mikhail Kshevetskiy <mikhail.kshevetskiy@iopsys.eu>
+Date: Mon, 27 Apr 2026 16:01:13 +0300
+Subject: [PATCH 11/29] arm: dts: en7523: add pinctrl/gpio support, drop legacy
+ gpio support
+
+This patch adds pinctrl/gpio dts nodes for airoha pinctrl driver.
+It also removes legacy gpio nodes.
+
+It should not be very dangerous, because:
+ * No official EN7523 gpio support present in U-Boot
+ * The same driver is planned for upstream linux/openwrt
+
+Signed-off-by: Mikhail Kshevetskiy <mikhail.kshevetskiy@iopsys.eu>
+Reviewed-by: David Lechner <dlechner@baylibre.com>
+---
+ arch/arm/dts/en7523-u-boot.dtsi | 23 +++++++++++++++++++++++
+ 1 file changed, 23 insertions(+)
+
+diff --git a/arch/arm/dts/en7523-u-boot.dtsi b/arch/arm/dts/en7523-u-boot.dtsi
+index 62d1a724678..7866a3552e6 100644
+--- a/arch/arm/dts/en7523-u-boot.dtsi
++++ b/arch/arm/dts/en7523-u-boot.dtsi
+@@ -2,6 +2,9 @@
+
+ #include <dt-bindings/reset/airoha,en7523-reset.h>
+
++/delete-node/ &gpio0;
++/delete-node/ &gpio1;
++
+ / {
+ reserved-memory {
+ #address-cells = <1>;
+@@ -22,6 +25,26 @@
+ #reset-cells = <1>;
+ };
+
++ system-controller@1fbf0200 {
++ compatible = "syscon", "simple-mfd";
++ reg = <0x1fbf0200 0xc0>;
++
++ en7523_pinctrl: pinctrl {
++ compatible = "airoha,en7523-pinctrl";
++
++ interrupt-parent = <&gic>;
++ interrupts = <GIC_SPI 26 IRQ_TYPE_LEVEL_HIGH>;
++
++ gpio-controller;
++ #gpio-cells = <2>;
++
++ interrupt-controller;
++ #interrupt-cells = <2>;
++
++ gpio-ranges = <&en7523_pinctrl 0 12 30>;
++ };
++ };
++
+ eth: ethernet@1fb50000 {
+ compatible = "airoha,en7523-eth";
+ reg = <0x1fb50000 0x2600>,
+--
+2.53.0
+
-From 4791e708e2976c3e8bf4e69c92ccd6f1103e8f1f Mon Sep 17 00:00:00 2001
+From 8f8f6a330755301d247768af13cb53c5c325579c Mon Sep 17 00:00:00 2001
From: Christian Marangi <ansuelsmth@gmail.com>
Date: Tue, 29 Apr 2025 13:06:59 +0200
-Subject: [PATCH 01/24] airoha: add support for Airoha AN7583 SoC
+Subject: [PATCH 12/29] airoha: add support for Airoha AN7583 SoC
Add support for Airoha AN7583 SoC. This adds the Kconfig and Makefile
entry for the SoC, DTSI and initial config for it. Also add the code for
board/airoha/an7583/MAINTAINERS | 5 +
board/airoha/an7583/Makefile | 3 +
board/airoha/an7583/an7583_rfb.c | 16 ++
- configs/an7583_evb_defconfig | 80 ++++++
+ configs/an7583_evb_defconfig | 79 ++++++
include/configs/an7583.h | 19 ++
- 11 files changed, 642 insertions(+)
+ 11 files changed, 641 insertions(+)
create mode 100644 arch/arm/dts/an7583-evb.dts
create mode 100644 arch/arm/dts/an7583.dtsi
create mode 100644 arch/arm/mach-airoha/an7583/Makefile
+ };
+};
diff --git a/arch/arm/mach-airoha/Kconfig b/arch/arm/mach-airoha/Kconfig
-index b9cd0a413e1..2d74e3ce902 100644
+index 4b0374001d0..72cd1454208 100644
--- a/arch/arm/mach-airoha/Kconfig
+++ b/arch/arm/mach-airoha/Kconfig
-@@ -28,19 +28,33 @@ config TARGET_AN7581
+@@ -29,19 +29,33 @@ config TARGET_AN7581
Peripherals include Gigabit Ethernet, switch, USB3.0 and OTG, PCIe,
I2S, PCM, S/PDIF, UART, SPI, I2C, IR TX/RX, and PWM.
+}
diff --git a/configs/an7583_evb_defconfig b/configs/an7583_evb_defconfig
new file mode 100644
-index 00000000000..d1893fff398
+index 00000000000..16466be51b2
--- /dev/null
+++ b/configs/an7583_evb_defconfig
-@@ -0,0 +1,80 @@
+@@ -0,0 +1,79 @@
+CONFIG_ARM=y
+CONFIG_ARCH_AIROHA=y
+CONFIG_TARGET_AN7583=y
+CONFIG_ENV_VARS_UBOOT_RUNTIME_CONFIG=y
+CONFIG_NET_RANDOM_ETHADDR=y
+CONFIG_SYS_RX_ETH_BUFFER=8
-+CONFIG_REGMAP=y
+CONFIG_SYSCON=y
+CONFIG_CLK=y
+CONFIG_DMA=y
+CONFIG_AIROHA_ETH=y
+CONFIG_PHY=y
+CONFIG_PINCTRL=y
-+CONFIG_PINCONF=y
++CONFIG_PINCTRL_AIROHA_AN7583=y
+CONFIG_POWER_DOMAIN=y
+CONFIG_DM_REGULATOR=y
+CONFIG_DM_REGULATOR_FIXED=y
+
+#endif
--
-2.51.0
+2.53.0
-From 2ed022130bb42e3c419a4943115144259fa3b4b6 Mon Sep 17 00:00:00 2001
+From c1a853581a4045c0ce9c51d038981c459e02a32d Mon Sep 17 00:00:00 2001
From: Mikhail Kshevetskiy <mikhail.kshevetskiy@iopsys.eu>
Date: Fri, 17 Oct 2025 02:53:28 +0300
-Subject: [PATCH 02/24] arm/an7583: sync init code with an7581
+Subject: [PATCH 13/29] arm/an7583: sync init code with an7581
Signed-off-by: Mikhail Kshevetskiy <mikhail.kshevetskiy@iopsys.eu>
---
};
struct mm_region *mem_map = an7583_mem_map;
--
-2.51.0
+2.53.0
-From 59e3fa0d74fd36ba61a2b4e63eb6faf31b4e2396 Mon Sep 17 00:00:00 2001
+From a4e98508a271287ca3b9425916ad0aa92896bc66 Mon Sep 17 00:00:00 2001
From: Mikhail Kshevetskiy <mikhail.kshevetskiy@iopsys.eu>
Date: Fri, 31 Oct 2025 00:42:08 +0300
-Subject: [PATCH 03/24] arm: airoha: introduce AN7583 helpers to get SCU and
+Subject: [PATCH 14/29] arm: airoha: introduce AN7583 helpers to get SCU and
CHIP_SCU regmaps
We need access SCU and CHIP_SCU regmaps in several places (clk-airoha,
+ return syscon_node_to_regmap(node);
+}
--
-2.51.0
+2.53.0
-From 0faf0f239a145129063a1a2c798fc97c362cc98d Mon Sep 17 00:00:00 2001
+From 42ffd5ad8caf672035084c054a707fff9fbc83cd Mon Sep 17 00:00:00 2001
From: Christian Marangi <ansuelsmth@gmail.com>
Date: Tue, 30 Sep 2025 22:15:15 +0200
-Subject: [PATCH 04/24] dt-bindings: clock: airoha: Document support for AN7583
+Subject: [PATCH 15/29] dt-bindings: clock: airoha: Document support for AN7583
clock
Document support for Airoha AN7583 clock. This is based on the EN7523
+
#endif /* _DT_BINDINGS_CLOCK_AIROHA_EN7523_H_ */
--
-2.51.0
+2.53.0
-From c2bc25eaebdaf865c52418ff89ece3eb6aded616 Mon Sep 17 00:00:00 2001
+From 01976be0b8fb4fd5d5f2bb28ef20f6cebded1772 Mon Sep 17 00:00:00 2001
From: Christian Marangi <ansuelsmth@gmail.com>
Date: Tue, 29 Apr 2025 13:19:11 +0200
-Subject: [PATCH 05/24] clk: airoha: add support for Airoha AN7583 SoC clock
+Subject: [PATCH 16/29] clk: airoha: add support for Airoha AN7583 SoC clock
Add support for Airoha AN7583 SoC clock that implement more base values
for clocks compared to AN7581.
1 file changed, 158 insertions(+)
diff --git a/drivers/clk/airoha/clk-airoha.c b/drivers/clk/airoha/clk-airoha.c
-index 49dbca82135..68dca6ab202 100644
+index 49dbca82135..f5c2d9f1461 100644
--- a/drivers/clk/airoha/clk-airoha.c
+++ b/drivers/clk/airoha/clk-airoha.c
@@ -36,6 +36,7 @@
};
--
-2.51.0
+2.53.0
-From 6b54d65d6b247d06d94c28c6df92ed5b45d7468a Mon Sep 17 00:00:00 2001
+From 62c3c0d6f4094768089a3bb50351fd0576a0c51f Mon Sep 17 00:00:00 2001
From: Christian Marangi <ansuelsmth@gmail.com>
Date: Tue, 29 Apr 2025 13:33:35 +0200
-Subject: [PATCH 06/24] reset: airoha: Add support for Airoha AN7583 reset
+Subject: [PATCH 17/29] reset: airoha: Add support for Airoha AN7583 reset
Adapt the Airoha reset driver to support Airoha AN7583 node structure.
In AN7583 the register is exposed by the parent syscon hence a different
+
+#endif /* __DT_BINDINGS_RESET_CONTROLLER_AIROHA_AN7583_H_ */
--
-2.51.0
+2.53.0
-From fca7240fd0ea0b30d8b6eda68eec67d84d48f15d Mon Sep 17 00:00:00 2001
+From 8e7a468d4e3e55d64cbfe5576092f7ecb3eaa0f1 Mon Sep 17 00:00:00 2001
From: Christian Marangi <ansuelsmth@gmail.com>
Date: Mon, 19 May 2025 14:29:53 +0200
-Subject: [PATCH 07/24] net: airoha: add support for Airoha AN7583
+Subject: [PATCH 18/29] net: airoha: add support for Airoha AN7583
Add support for Ethernet controller present in Airoha AN7583. This
follow the same implementation of Airoha AN7581 with the only difference
1 file changed, 91 insertions(+)
diff --git a/drivers/net/airoha_eth.c b/drivers/net/airoha_eth.c
-index 3234d875887..75af93f182d 100644
+index e5d39b95cc5..863c35647b6 100644
--- a/drivers/net/airoha_eth.c
+++ b/drivers/net/airoha_eth.c
-@@ -20,6 +20,7 @@
- #include <linux/dma-mapping.h>
+@@ -24,6 +24,7 @@
+ #include <linux/ethtool.h>
#include <linux/io.h>
#include <linux/iopoll.h>
+#include <linux/mii.h>
#include <linux/time.h>
#include <asm/arch/scu-regmap.h>
-@@ -28,6 +29,11 @@
+@@ -34,6 +35,11 @@
#define AIROHA_MAX_NUM_RSTS 3
#define AIROHA_MAX_NUM_XSI_RSTS 4
#define AIROHA_MAX_PACKET_SIZE 2048
#define AIROHA_NUM_TX_RING 1
#define AIROHA_NUM_RX_RING 1
-@@ -78,6 +84,19 @@
+@@ -86,6 +92,19 @@
#define SWITCH_PHY_PRE_EN BIT(15)
#define SWITCH_PHY_END_ADDR GENMASK(12, 8)
#define SWITCH_PHY_ST_ADDR GENMASK(4, 0)
/* FE */
#define PSE_BASE 0x0100
-@@ -332,6 +351,12 @@ static const char * const en7581_xsi_rsts_names[] = {
+@@ -365,6 +384,12 @@ static const char * const en7581_xsi_rsts_names[] = {
"xfp-mac",
};
static u32 airoha_rr(void __iomem *base, u32 offset)
{
return readl(base + offset);
-@@ -372,8 +397,12 @@ static u32 airoha_rmw(void __iomem *base, u32 offset, u32 mask, u32 val)
+@@ -405,8 +430,12 @@ static u32 airoha_rmw(void __iomem *base, u32 offset, u32 mask, u32 val)
#define airoha_qdma_clear(qdma, offset, val) \
airoha_rmw((qdma)->regs, (offset), (val), 0)
static inline dma_addr_t dma_map_unaligned(void *vaddr, size_t len,
enum dma_data_direction dir)
-@@ -735,6 +764,59 @@ static int airoha_switch_init(struct udevice *dev, struct airoha_eth *eth)
+@@ -809,6 +838,59 @@ static int airoha_switch_init(struct udevice *dev, struct airoha_eth *eth)
FIELD_PREP(SWITCH_PHY_END_ADDR, 0xc) |
FIELD_PREP(SWITCH_PHY_ST_ADDR, 0x8));
return 0;
}
-@@ -994,6 +1076,12 @@ static const struct airoha_eth_soc_data en7581_data = {
+@@ -1269,6 +1351,12 @@ static const struct airoha_eth_soc_data en7581_data = {
.switch_compatible = "airoha,en7581-switch",
};
static const struct udevice_id airoha_eth_ids[] = {
{ .compatible = "airoha,en7523-eth",
.data = (ulong)&en7523_data,
-@@ -1001,6 +1089,9 @@ static const struct udevice_id airoha_eth_ids[] = {
+@@ -1276,6 +1364,9 @@ static const struct udevice_id airoha_eth_ids[] = {
{ .compatible = "airoha,en7581-eth",
.data = (ulong)&en7581_data,
},
};
--
-2.51.0
+2.53.0
-From e3acb9cf6e3e08e72e3549788a4cb35eb88ce206 Mon Sep 17 00:00:00 2001
+From e4ebf563b9917884af3b708a6a06bf2de0134273 Mon Sep 17 00:00:00 2001
From: Christian Marangi <ansuelsmth@gmail.com>
Date: Mon, 19 May 2025 14:31:59 +0200
-Subject: [PATCH 08/24] airoha: add Ethernet node in AN7583 dtsi
+Subject: [PATCH 19/29] airoha: add Ethernet node in AN7583 dtsi
Add Ethernet node in AN7583 dtsi to add support for the integrated
Ethernet Controller.
compatible = "airoha,en7581-pbus-csr", "syscon";
reg = <0x0 0x1fbe3400 0x0 0xff>;
--
-2.51.0
+2.53.0
-From a982b2b81c8c73213915ff7ff655461fe2fe0cef Mon Sep 17 00:00:00 2001
+From 9acf80067946f14d21238fb614cee3eb20bfa664 Mon Sep 17 00:00:00 2001
From: Christian Marangi <ansuelsmth@gmail.com>
Date: Mon, 19 May 2025 14:52:26 +0200
-Subject: [PATCH 09/24] airoha: add MMC node for Airoha AN7583
+Subject: [PATCH 20/29] airoha: add MMC node for Airoha AN7583
Add MMC node for Airoha AN7583. These follow the same node of Airoha
AN7581.
compatible = "ns16550";
reg = <0x0 0x1fbf0000 0x0 0x30>;
--
-2.51.0
+2.53.0
+++ /dev/null
-From 1357636b826cadf15e410b64f1c98bde930dfb4e Mon Sep 17 00:00:00 2001
-From: Christian Marangi <ansuelsmth@gmail.com>
-Date: Thu, 23 Oct 2025 19:07:45 +0200
-Subject: [PATCH 10/24] net: airoha: bind MDIO controller on Ethernet load
-
-Bind MDIO controller on Ethernet Controller load. The Airoha AN7581 SoC
-have an integrated Switch based on MT7531 (or more saying MT7988).
-
-Attach it to the mdio node in the switch node to support scanning for
-MDIO devices on the BUS with DM API.
-
-Signed-off-by: Christian Marangi <ansuelsmth@gmail.com>
----
- drivers/net/Kconfig | 1 +
- drivers/net/airoha_eth.c | 32 ++++++++++++++++++++++++++++++++
- 2 files changed, 33 insertions(+)
-
-diff --git a/drivers/net/Kconfig b/drivers/net/Kconfig
-index 544e302d600..f382a7752d5 100644
---- a/drivers/net/Kconfig
-+++ b/drivers/net/Kconfig
-@@ -126,6 +126,7 @@ config AIROHA_ETH
- depends on ARCH_AIROHA
- select PHYLIB
- select DM_RESET
-+ select MDIO_MT7531
- help
- This Driver support Airoha Ethernet QDMA Driver
- Say Y to enable support for the Airoha Ethernet QDMA.
-diff --git a/drivers/net/airoha_eth.c b/drivers/net/airoha_eth.c
-index 75af93f182d..661b6ac19f0 100644
---- a/drivers/net/airoha_eth.c
-+++ b/drivers/net/airoha_eth.c
-@@ -10,6 +10,7 @@
-
- #include <dm.h>
- #include <dm/devres.h>
-+#include <dm/lists.h>
- #include <mapmem.h>
- #include <net.h>
- #include <regmap.h>
-@@ -1064,6 +1065,36 @@ static int arht_eth_write_hwaddr(struct udevice *dev)
- return 0;
- }
-
-+static int airoha_eth_bind(struct udevice *dev)
-+{
-+ ofnode switch_node, mdio_node;
-+ struct udevice *mdio_dev;
-+ int ret = 0;
-+
-+ if (!CONFIG_IS_ENABLED(MDIO_MT7531))
-+ return 0;
-+
-+ switch_node = ofnode_by_compatible(ofnode_null(),
-+ "airoha,en7581-switch");
-+ if (!ofnode_valid(switch_node)) {
-+ debug("Warning: missing switch node\n");
-+ return 0;
-+ }
-+
-+ mdio_node = ofnode_find_subnode(switch_node, "mdio");
-+ if (!ofnode_valid(mdio_node)) {
-+ debug("Warning: missing mdio node\n");
-+ return 0;
-+ }
-+
-+ ret = device_bind_driver_to_node(dev, "mt7531-mdio", "mdio",
-+ mdio_node, &mdio_dev);
-+ if (ret)
-+ debug("Warning: failed to bind mdio controller\n");
-+
-+ return 0;
-+}
-+
- static const struct airoha_eth_soc_data en7523_data = {
- .xsi_rsts_names = en7523_xsi_rsts_names,
- .num_xsi_rsts = ARRAY_SIZE(en7523_xsi_rsts_names),
-@@ -1109,6 +1140,7 @@ U_BOOT_DRIVER(airoha_eth) = {
- .id = UCLASS_ETH,
- .of_match = airoha_eth_ids,
- .probe = airoha_eth_probe,
-+ .bind = airoha_eth_bind,
- .ops = &airoha_eth_ops,
- .priv_auto = sizeof(struct airoha_eth),
- .plat_auto = sizeof(struct eth_pdata),
---
-2.51.0
-
+++ /dev/null
-From 967084a19cf6aef3a5f2a43d758e93ae1fadebbf Mon Sep 17 00:00:00 2001
-From: Mikhail Kshevetskiy <mikhail.kshevetskiy@iopsys.eu>
-Date: Sat, 31 Jan 2026 01:06:23 +0300
-Subject: [PATCH 11/24] net: airoha_eth: fix mdio binding to switch device
-
-Commit d2145a89bcf6 ("net: airoha: bind MDIO controller on Ethernet load")
-refers to non-present CONFIG_MDIO_MT7531 and non-present "mt7531-mdio"
-driver. It should use CONFIG_MDIO_MT7531_MMIO and "mt7531-mdio-mmio"
-instead.
-
-Fixes: d2145a89bcf6 ("net: airoha: bind MDIO controller on Ethernet load")
-Signed-off-by: Mikhail Kshevetskiy <mikhail.kshevetskiy@iopsys.eu>
----
- drivers/net/Kconfig | 2 +-
- drivers/net/airoha_eth.c | 4 ++--
- 2 files changed, 3 insertions(+), 3 deletions(-)
-
-diff --git a/drivers/net/Kconfig b/drivers/net/Kconfig
-index f382a7752d5..51663580bdc 100644
---- a/drivers/net/Kconfig
-+++ b/drivers/net/Kconfig
-@@ -126,7 +126,7 @@ config AIROHA_ETH
- depends on ARCH_AIROHA
- select PHYLIB
- select DM_RESET
-- select MDIO_MT7531
-+ select MDIO_MT7531_MMIO
- help
- This Driver support Airoha Ethernet QDMA Driver
- Say Y to enable support for the Airoha Ethernet QDMA.
-diff --git a/drivers/net/airoha_eth.c b/drivers/net/airoha_eth.c
-index 661b6ac19f0..7be4f3c074f 100644
---- a/drivers/net/airoha_eth.c
-+++ b/drivers/net/airoha_eth.c
-@@ -1071,7 +1071,7 @@ static int airoha_eth_bind(struct udevice *dev)
- struct udevice *mdio_dev;
- int ret = 0;
-
-- if (!CONFIG_IS_ENABLED(MDIO_MT7531))
-+ if (!CONFIG_IS_ENABLED(MDIO_MT7531_MMIO))
- return 0;
-
- switch_node = ofnode_by_compatible(ofnode_null(),
-@@ -1087,7 +1087,7 @@ static int airoha_eth_bind(struct udevice *dev)
- return 0;
- }
-
-- ret = device_bind_driver_to_node(dev, "mt7531-mdio", "mdio",
-+ ret = device_bind_driver_to_node(dev, "mt7531-mdio-mmio", "mdio",
- mdio_node, &mdio_dev);
- if (ret)
- debug("Warning: failed to bind mdio controller\n");
---
-2.51.0
-
+++ /dev/null
-From 54e56dd99f1c00eae7be5ca8c37149b8671f25d8 Mon Sep 17 00:00:00 2001
-From: Mikhail Kshevetskiy <mikhail.kshevetskiy@iopsys.eu>
-Date: Sat, 31 Jan 2026 01:06:24 +0300
-Subject: [PATCH 12/24] net: airoha_eth: use proper switch node for en7523 case
-
-Commit d2145a89bcf6 ("net: airoha: bind MDIO controller on Ethernet load")
-uses "airoha,en7581-switch" dts node for finding MDIO childs. This is wrong
-for EN7523 SoC. The correct node name should be used instead.
-
-Fixes: d2145a89bcf6 ("net: airoha: bind MDIO controller on Ethernet load")
-Signed-off-by: Mikhail Kshevetskiy <mikhail.kshevetskiy@iopsys.eu>
----
- drivers/net/airoha_eth.c | 3 ++-
- 1 file changed, 2 insertions(+), 1 deletion(-)
-
-diff --git a/drivers/net/airoha_eth.c b/drivers/net/airoha_eth.c
-index 7be4f3c074f..f8d7235146d 100644
---- a/drivers/net/airoha_eth.c
-+++ b/drivers/net/airoha_eth.c
-@@ -1067,6 +1067,7 @@ static int arht_eth_write_hwaddr(struct udevice *dev)
-
- static int airoha_eth_bind(struct udevice *dev)
- {
-+ struct airoha_eth_soc_data *data = (void *)dev_get_driver_data(dev);
- ofnode switch_node, mdio_node;
- struct udevice *mdio_dev;
- int ret = 0;
-@@ -1075,7 +1076,7 @@ static int airoha_eth_bind(struct udevice *dev)
- return 0;
-
- switch_node = ofnode_by_compatible(ofnode_null(),
-- "airoha,en7581-switch");
-+ data->switch_compatible);
- if (!ofnode_valid(switch_node)) {
- debug("Warning: missing switch node\n");
- return 0;
---
-2.51.0
-
+++ /dev/null
-From 9317668aa6e37152d799d7cbaf8b3ce7926b526a Mon Sep 17 00:00:00 2001
-From: Mikhail Kshevetskiy <mikhail.kshevetskiy@iopsys.eu>
-Date: Sat, 31 Jan 2026 01:06:25 +0300
-Subject: [PATCH 13/24] net: mdio-mt7531-mmio: fix switch regs initialization
-
-mdio is a child node of the switch, so to get switch base address
-we need to lookup for a parent node
-
-Signed-off-by: Mikhail Kshevetskiy <mikhail.kshevetskiy@iopsys.eu>
----
- drivers/net/mdio-mt7531-mmio.c | 7 ++++++-
- 1 file changed, 6 insertions(+), 1 deletion(-)
-
-diff --git a/drivers/net/mdio-mt7531-mmio.c b/drivers/net/mdio-mt7531-mmio.c
-index 3e325ca58da..5a0725010f2 100644
---- a/drivers/net/mdio-mt7531-mmio.c
-+++ b/drivers/net/mdio-mt7531-mmio.c
-@@ -151,8 +151,13 @@ static const struct mdio_ops mt7531_mdio_ops = {
- static int mt7531_mdio_probe(struct udevice *dev)
- {
- struct mt7531_mdio_priv *priv = dev_get_priv(dev);
-+ ofnode switch_node;
-
-- priv->switch_regs = dev_read_addr(dev);
-+ switch_node = ofnode_get_parent(dev_ofnode(dev));
-+ if (!ofnode_valid(switch_node))
-+ return -EINVAL;
-+
-+ priv->switch_regs = ofnode_get_addr(switch_node);
- if (priv->switch_regs == FDT_ADDR_T_NONE)
- return -EINVAL;
-
---
-2.51.0
-
+++ /dev/null
-From 1a853053a3e44cae45f16b1b30da70da2629c590 Mon Sep 17 00:00:00 2001
-From: Christian Marangi <ansuelsmth@gmail.com>
-Date: Mon, 9 Feb 2026 12:20:33 +0100
-Subject: [PATCH 14/24] net: mdio-mt7531-mmio: use common header priv struct
-
-Instead of having duplicate priv struct for mdio-mt7531-mmio driver in
-both driver and header, use the one exposed by the header directly.
-
-This make sure we have consistent priv struct if the driver will be
-updated in the future.
-
-Signed-off-by: Christian Marangi <ansuelsmth@gmail.com>
----
- drivers/net/mdio-mt7531-mmio.c | 24 +++++++++++-------------
- 1 file changed, 11 insertions(+), 13 deletions(-)
-
-diff --git a/drivers/net/mdio-mt7531-mmio.c b/drivers/net/mdio-mt7531-mmio.c
-index 5a0725010f2..930454a9b0e 100644
---- a/drivers/net/mdio-mt7531-mmio.c
-+++ b/drivers/net/mdio-mt7531-mmio.c
-@@ -6,6 +6,8 @@
- #include <linux/iopoll.h>
- #include <miiphy.h>
-
-+#include "mdio-mt7531-mmio.h"
-+
- #define MT7531_PHY_IAC 0x701c
- #define MT7531_PHY_ACS_ST BIT(31)
- #define MT7531_MDIO_REG_ADDR_CL22 GENMASK(29, 25)
-@@ -25,11 +27,7 @@
- #define MT7531_MDIO_TIMEOUT 100000
- #define MT7531_MDIO_SLEEP 20
-
--struct mt7531_mdio_priv {
-- phys_addr_t switch_regs;
--};
--
--static int mt7531_mdio_wait_busy(struct mt7531_mdio_priv *priv)
-+static int mt7531_mdio_wait_busy(struct mt7531_mdio_mmio_priv *priv)
- {
- unsigned int busy;
-
-@@ -38,7 +36,7 @@ static int mt7531_mdio_wait_busy(struct mt7531_mdio_priv *priv)
- MT7531_MDIO_SLEEP, MT7531_MDIO_TIMEOUT);
- }
-
--static int mt7531_mdio_read(struct mt7531_mdio_priv *priv, int addr, int devad, int reg)
-+static int mt7531_mdio_read(struct mt7531_mdio_mmio_priv *priv, int addr, int devad, int reg)
- {
- u32 val;
-
-@@ -75,7 +73,7 @@ static int mt7531_mdio_read(struct mt7531_mdio_priv *priv, int addr, int devad,
- return val & MT7531_MDIO_RW_DATA;
- }
-
--static int mt7531_mdio_write(struct mt7531_mdio_priv *priv, int addr, int devad,
-+static int mt7531_mdio_write(struct mt7531_mdio_mmio_priv *priv, int addr, int devad,
- int reg, u16 value)
- {
- u32 val;
-@@ -115,7 +113,7 @@ static int mt7531_mdio_write(struct mt7531_mdio_priv *priv, int addr, int devad,
-
- int mt7531_mdio_mmio_read(struct mii_dev *bus, int addr, int devad, int reg)
- {
-- struct mt7531_mdio_priv *priv = bus->priv;
-+ struct mt7531_mdio_mmio_priv *priv = bus->priv;
-
- return mt7531_mdio_read(priv, addr, devad, reg);
- }
-@@ -123,14 +121,14 @@ int mt7531_mdio_mmio_read(struct mii_dev *bus, int addr, int devad, int reg)
- int mt7531_mdio_mmio_write(struct mii_dev *bus, int addr, int devad,
- int reg, u16 value)
- {
-- struct mt7531_mdio_priv *priv = bus->priv;
-+ struct mt7531_mdio_mmio_priv *priv = bus->priv;
-
- return mt7531_mdio_write(priv, addr, devad, reg, value);
- }
-
- static int dm_mt7531_mdio_read(struct udevice *dev, int addr, int devad, int reg)
- {
-- struct mt7531_mdio_priv *priv = dev_get_priv(dev);
-+ struct mt7531_mdio_mmio_priv *priv = dev_get_priv(dev);
-
- return mt7531_mdio_read(priv, addr, devad, reg);
- }
-@@ -138,7 +136,7 @@ static int dm_mt7531_mdio_read(struct udevice *dev, int addr, int devad, int reg
- static int dm_mt7531_mdio_write(struct udevice *dev, int addr, int devad,
- int reg, u16 value)
- {
-- struct mt7531_mdio_priv *priv = dev_get_priv(dev);
-+ struct mt7531_mdio_mmio_priv *priv = dev_get_priv(dev);
-
- return mt7531_mdio_write(priv, addr, devad, reg, value);
- }
-@@ -150,7 +148,7 @@ static const struct mdio_ops mt7531_mdio_ops = {
-
- static int mt7531_mdio_probe(struct udevice *dev)
- {
-- struct mt7531_mdio_priv *priv = dev_get_priv(dev);
-+ struct mt7531_mdio_mmio_priv *priv = dev_get_priv(dev);
- ofnode switch_node;
-
- switch_node = ofnode_get_parent(dev_ofnode(dev));
-@@ -169,5 +167,5 @@ U_BOOT_DRIVER(mt7531_mdio) = {
- .id = UCLASS_MDIO,
- .probe = mt7531_mdio_probe,
- .ops = &mt7531_mdio_ops,
-- .priv_auto = sizeof(struct mt7531_mdio_priv),
-+ .priv_auto = sizeof(struct mt7531_mdio_mmio_priv),
- };
---
-2.51.0
-
+++ /dev/null
-From 25125e98275aa43023c1d311433e0dca1c12e069 Mon Sep 17 00:00:00 2001
-From: Mikhail Kshevetskiy <mikhail.kshevetskiy@iopsys.eu>
-Date: Sat, 31 Jan 2026 01:06:26 +0300
-Subject: [PATCH 15/24] configs: an7581: add mii/mdio support
-
-This enables mdio/mii command support.
-
-Signed-off-by: Mikhail Kshevetskiy <mikhail.kshevetskiy@iopsys.eu>
----
- configs/an7581_evb_defconfig | 3 +++
- 1 file changed, 3 insertions(+)
-
-diff --git a/configs/an7581_evb_defconfig b/configs/an7581_evb_defconfig
-index 73af30cd693..8e2c694dbbb 100644
---- a/configs/an7581_evb_defconfig
-+++ b/configs/an7581_evb_defconfig
-@@ -66,6 +66,9 @@ CONFIG_SPI_FLASH_STMICRO=y
- CONFIG_SPI_FLASH_WINBOND=y
- CONFIG_SPI_FLASH_MTD=y
- CONFIG_AIROHA_ETH=y
-+CONFIG_DM_MDIO=y
-+CONFIG_CMD_MII=y
-+CONFIG_CMD_MDIO=y
- CONFIG_PHY=y
- CONFIG_PINCTRL=y
- CONFIG_PINCONF=y
---
-2.51.0
-
+++ /dev/null
-From 3236c124261ca9da41632762c36b86aface13b05 Mon Sep 17 00:00:00 2001
-From: Mikhail Kshevetskiy <mikhail.kshevetskiy@iopsys.eu>
-Date: Sat, 31 Jan 2026 01:06:27 +0300
-Subject: [PATCH 16/24] arm: dts: an7581: add mdio child node to switch node
-
-add mdio node to be able see switch port states
-
-Signed-off-by: Mikhail Kshevetskiy <mikhail.kshevetskiy@iopsys.eu>
----
- arch/arm/dts/an7581-u-boot.dtsi | 5 +++++
- 1 file changed, 5 insertions(+)
-
-diff --git a/arch/arm/dts/an7581-u-boot.dtsi b/arch/arm/dts/an7581-u-boot.dtsi
-index a9297ca6503..c5e24c76457 100644
---- a/arch/arm/dts/an7581-u-boot.dtsi
-+++ b/arch/arm/dts/an7581-u-boot.dtsi
-@@ -57,6 +57,11 @@
- switch: switch@1fb58000 {
- compatible = "airoha,en7581-switch";
- reg = <0 0x1fb58000 0 0x8000>;
-+
-+ mdio: mdio {
-+ #address-cells = <1>;
-+ #size-cells = <0>;
-+ };
- };
-
- snfi: spi@1fa10000 {
---
-2.51.0
-
+++ /dev/null
-From 6efbdacd79d253507e62ae93358953fff6fb3173 Mon Sep 17 00:00:00 2001
-From: Mikhail Kshevetskiy <mikhail.kshevetskiy@iopsys.eu>
-Date: Sat, 31 Jan 2026 01:06:28 +0300
-Subject: [PATCH 17/24] configs: en7523: add mii/mdio support
-
-This enables mdio/mii command support.
-
-Signed-off-by: Mikhail Kshevetskiy <mikhail.kshevetskiy@iopsys.eu>
----
- configs/en7523_evb_defconfig | 3 +++
- 1 file changed, 3 insertions(+)
-
-diff --git a/configs/en7523_evb_defconfig b/configs/en7523_evb_defconfig
-index 113ddb46a7f..ebd99d133c9 100644
---- a/configs/en7523_evb_defconfig
-+++ b/configs/en7523_evb_defconfig
-@@ -51,6 +51,9 @@ CONFIG_MTD=y
- CONFIG_DM_MTD=y
- CONFIG_MTD_SPI_NAND=y
- CONFIG_AIROHA_ETH=y
-+CONFIG_DM_MDIO=y
-+CONFIG_CMD_MII=y
-+CONFIG_CMD_MDIO=y
- CONFIG_PHY=y
- CONFIG_PINCTRL=y
- CONFIG_PINCONF=y
---
-2.51.0
-
+++ /dev/null
-From 3ad8d165ce15559d5cab0df0cad9559e81c995f4 Mon Sep 17 00:00:00 2001
-From: Mikhail Kshevetskiy <mikhail.kshevetskiy@iopsys.eu>
-Date: Sat, 31 Jan 2026 01:06:29 +0300
-Subject: [PATCH 18/24] arm: dts: en7523: add mdio child node to switch node
-
-add mdio node to be able see switch port states
-
-Signed-off-by: Mikhail Kshevetskiy <mikhail.kshevetskiy@iopsys.eu>
----
- arch/arm/dts/en7523-u-boot.dtsi | 5 +++++
- 1 file changed, 5 insertions(+)
-
-diff --git a/arch/arm/dts/en7523-u-boot.dtsi b/arch/arm/dts/en7523-u-boot.dtsi
-index f031f81515a..9eadaccc500 100644
---- a/arch/arm/dts/en7523-u-boot.dtsi
-+++ b/arch/arm/dts/en7523-u-boot.dtsi
-@@ -42,6 +42,11 @@
- switch: switch@1fb58000 {
- compatible = "airoha,en7523-switch";
- reg = <0x1fb58000 0x8000>;
-+
-+ mdio: mdio {
-+ #address-cells = <1>;
-+ #size-cells = <0>;
-+ };
- };
-
- snfi: spi@1fa10000 {
---
-2.51.0
-
-From c8d2c4c3beb5fd27a041744f0f9a6b6d5c4e1ebe Mon Sep 17 00:00:00 2001
+From 71d25a3ea404f14405df175da6e4ba257f1ad289 Mon Sep 17 00:00:00 2001
From: Mikhail Kshevetskiy <mikhail.kshevetskiy@iopsys.eu>
Date: Wed, 11 Feb 2026 03:26:13 +0300
-Subject: [PATCH 19/24] configs: an7583: add mii/mdio support
+Subject: [PATCH 21/29] configs: an7583: add mii/mdio support
This enables mdio/mii command support.
Signed-off-by: Mikhail Kshevetskiy <mikhail.kshevetskiy@iopsys.eu
---
- configs/an7583_evb_defconfig | 3 +++
- 1 file changed, 3 insertions(+)
+ configs/an7583_evb_defconfig | 2 ++
+ 1 file changed, 2 insertions(+)
diff --git a/configs/an7583_evb_defconfig b/configs/an7583_evb_defconfig
-index d1893fff398..41d98bab5de 100644
+index 16466be51b2..7178f45e3f8 100644
--- a/configs/an7583_evb_defconfig
+++ b/configs/an7583_evb_defconfig
-@@ -65,6 +65,9 @@ CONFIG_SPI_FLASH_STMICRO=y
+@@ -32,6 +32,7 @@ CONFIG_CMD_MTD=y
+ CONFIG_CMD_SF_TEST=y
+ CONFIG_CMD_SPI=y
+ # CONFIG_CMD_SETEXPR is not set
++CONFIG_CMD_MII=y
+ CONFIG_CMD_PING=y
+ CONFIG_CMD_EXT4=y
+ CONFIG_CMD_FAT=y
+@@ -63,6 +64,7 @@ CONFIG_SPI_FLASH_SPANSION=y
+ CONFIG_SPI_FLASH_STMICRO=y
CONFIG_SPI_FLASH_WINBOND=y
CONFIG_SPI_FLASH_MTD=y
- CONFIG_AIROHA_ETH=y
+CONFIG_DM_MDIO=y
-+CONFIG_CMD_MII=y
-+CONFIG_CMD_MDIO=y
+ CONFIG_AIROHA_ETH=y
CONFIG_PHY=y
CONFIG_PINCTRL=y
- CONFIG_PINCONF=y
--
-2.51.0
+2.53.0
-From 7f9bbd9ed8d2e3b7dae0fbc7d2bd2b0c08a115d0 Mon Sep 17 00:00:00 2001
+From da94257c7177f860bd70c39f1c2e3a51fb391068 Mon Sep 17 00:00:00 2001
From: Mikhail Kshevetskiy <mikhail.kshevetskiy@iopsys.eu>
Date: Wed, 11 Feb 2026 03:29:23 +0300
-Subject: [PATCH 20/24] arm: dts: an7583: add mdio child node to switch node
+Subject: [PATCH 22/29] arm: dts: an7583: add mdio child node to switch node
add mdio node to be able see switch port states
syscon@1fbe3400 {
--
-2.51.0
+2.53.0
--- /dev/null
+From 900bbfbb0abbe89abf156dc4b48dc19b929c8a13 Mon Sep 17 00:00:00 2001
+From: Christian Marangi <ansuelsmth@gmail.com>
+Date: Tue, 30 Sep 2025 22:56:29 +0200
+Subject: [PATCH 27/38] net: airoha: add support for Airoha AN7583 PCS driver
+
+Add support for the PCS interface on Airoha AN7583 SoC. This is based on
+the AN7581 SoC with difference in the calibration and Analog PHY
+handling.
+
+Signed-off-by: Christian Marangi <ansuelsmth@gmail.com>
+---
+ drivers/net/airoha/Kconfig | 8 +
+ drivers/net/airoha/Makefile | 1 +
+ drivers/net/airoha/pcs-airoha-common.c | 27 +
+ drivers/net/airoha/pcs-airoha.h | 17 +
+ drivers/net/airoha/pcs-an7583.c | 2200 ++++++++++++++++++++++++
+ 5 files changed, 2253 insertions(+)
+ create mode 100644 drivers/net/airoha/pcs-an7583.c
+
+diff --git a/drivers/net/airoha/Kconfig b/drivers/net/airoha/Kconfig
+index d0c007ced80..5f660bb280f 100644
+--- a/drivers/net/airoha/Kconfig
++++ b/drivers/net/airoha/Kconfig
+@@ -11,3 +11,11 @@ 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
++ bool "Airoha AN7583 PCS driver"
++ depends on ARCH_AIROHA
++ select PCS_AIROHA
++ help
++ This module provides helper to phylink for managing the Airoha
++ AN7583 PCS for SoC Ethernet and PON SERDES.
+diff --git a/drivers/net/airoha/Makefile b/drivers/net/airoha/Makefile
+index 81fd26cf813..a3b84518129 100644
+--- a/drivers/net/airoha/Makefile
++++ b/drivers/net/airoha/Makefile
+@@ -2,3 +2,4 @@
+
+ obj-$(CONFIG_PCS_AIROHA) += pcs-airoha-common.o
+ obj-$(CONFIG_PCS_AIROHA_AN7581) += pcs-an7581.o
++obj-$(CONFIG_PCS_AIROHA_AN7583) += pcs-an7583.o
+diff --git a/drivers/net/airoha/pcs-airoha-common.c b/drivers/net/airoha/pcs-airoha-common.c
+index 1263092fcdd..bc64263fad9 100644
+--- a/drivers/net/airoha/pcs-airoha-common.c
++++ b/drivers/net/airoha/pcs-airoha-common.c
+@@ -17,6 +17,7 @@
+ static void airoha_pcs_setup_scu_eth(struct airoha_pcs_priv *priv,
+ phy_interface_t interface)
+ {
++ struct udevice *dev = priv->dev;
+ u32 xsi_sel;
+
+ switch (interface) {
+@@ -34,6 +35,12 @@ static void airoha_pcs_setup_scu_eth(struct airoha_pcs_priv *priv,
+ 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,
+@@ -810,11 +817,31 @@ static const struct airoha_pcs_match_data an7581_pcs_pon = {
+ .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 udevice_id airoha_pcs_of_table[] = {
+ { .compatible = "airoha,an7581-pcs-eth",
+ .data = (ulong)&an7581_pcs_eth },
+ { .compatible = "airoha,an7581-pcs-pon",
+ .data = (ulong)&an7581_pcs_pon },
++ { .compatible = "airoha,an7583-pcs-eth",
++ .data = (ulong)&an7583_pcs_eth },
++ { .compatible = "airoha,an7583-pcs-pon",
++ .data = (ulong)&an7583_pcs_pon },
+ { },
+ };
+
+diff --git a/drivers/net/airoha/pcs-airoha.h b/drivers/net/airoha/pcs-airoha.h
+index 714d2ebe520..fddeda5ca36 100644
+--- a/drivers/net/airoha/pcs-airoha.h
++++ b/drivers/net/airoha/pcs-airoha.h
+@@ -1218,3 +1218,20 @@ static inline void an7581_pcs_phya_link_up(struct airoha_pcs_priv *priv)
+ {
+ }
+ #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
+diff --git a/drivers/net/airoha/pcs-an7583.c b/drivers/net/airoha/pcs-an7583.c
+new file mode 100644
+index 00000000000..0a5b936cd93
+--- /dev/null
++++ b/drivers/net/airoha/pcs-an7583.c
+@@ -0,0 +1,2200 @@
++// SPDX-License-Identifier: GPL-2.0
++/*
++ * Copyright (c) 2024 AIROHA Inc
++ * Author: Christian Marangi <ansuelsmth@gmail.com>
++ */
++#include <dm.h>
++#include <dm/device_compat.h>
++#include <regmap.h>
++
++#include "pcs-airoha.h"
++
++static void an7583_pcs_dig_reset_hold(struct airoha_pcs_priv *priv)
++{
++ regmap_clear_bits(priv->xfi_pma, AIROHA_PCS_PMA_SW_RST_SET,
++ AIROHA_PCS_PMA_SW_RX_FIFO_RST_N |
++ AIROHA_PCS_PMA_SW_TX_FIFO_RST_N);
++
++ regmap_clear_bits(priv->xfi_pma, AIROHA_PCS_PMA_SW_RST_SET,
++ AIROHA_PCS_PMA_SW_REF_RST_N);
++
++ regmap_clear_bits(priv->xfi_pma, AIROHA_PCS_PMA_SW_RST_SET,
++ AIROHA_PCS_PMA_SW_ALLPCS_RST_N);
++
++ regmap_clear_bits(priv->xfi_pma, AIROHA_PCS_PMA_SW_RST_SET,
++ AIROHA_PCS_PMA_SW_TX_RST_N |
++ AIROHA_PCS_PMA_SW_RX_RST_N);
++
++ regmap_clear_bits(priv->xfi_pma, AIROHA_PCS_PMA_SW_RST_SET,
++ AIROHA_PCS_PMA_SW_PMA_RST_N);
++
++ udelay(50);
++}
++
++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);
++
++ udelay(100);
++}
++
++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);
++
++ udelay(500);
++}
++
++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);
++
++ udelay(100);
++
++ /* 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);
++
++ udelay(100);
++
++ 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);
++
++ udelay(200);
++
++ 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);
++
++ udelay(100);
++}
++
++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);
++
++ udelay(200);
++
++ /* 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);
++
++ udelay(200);
++
++ 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);
++
++ udelay(200);
++
++ /* 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);
++
++ udelay(1000);
++
++ /* 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);
++
++ udelay(200);
++
++ 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);
++
++ udelay(1000);
++
++ 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);
++
++ udelay(1000);
++}
++
++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);
++
++ udelay(50);
++
++ 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);
++
++ udelay(100);
++
++ 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);
++
++ udelay(500);
++
++ regmap_set_bits(priv->xfi_pma, AIROHA_PCS_PMA_RX_FORCE_MODE_0,
++ AIROHA_PCS_PMA_FORCE_DA_XPON_CDR_LPF_RSTB);
++
++ udelay(500);
++ }
++
++ *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)
++ udelay(5500);
++ else
++ udelay(55 * 1000);
++
++ 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));
++
++ udelay(500);
++
++ 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);
++
++ udelay(700);
++
++ 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);
++
++ udelay(100);
++
++ 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);
++}
+--
+2.53.0
+
--- /dev/null
+From 010279f19e681753494fc156031aed7bd663bd6a Mon Sep 17 00:00:00 2001
+From: Christian Marangi <ansuelsmth@gmail.com>
+Date: Tue, 30 Sep 2025 23:00:29 +0200
+Subject: [PATCH 28/38] airoha: add PCS node for AN7583
+
+Add PCS node for Airoha AN7583 SoC to enable support for Serdes Ethernet
+and PON port.
+
+Signed-off-by: Christian Marangi <ansuelsmth@gmail.com>
+---
+ arch/arm/dts/an7583-evb.dts | 18 ++++++++++
+ arch/arm/dts/an7583.dtsi | 72 +++++++++++++++++++++++++++++++++++++
+ 2 files changed, 90 insertions(+)
+
+diff --git a/arch/arm/dts/an7583-evb.dts b/arch/arm/dts/an7583-evb.dts
+index d02cd194e8a..714c90eadfe 100644
+--- a/arch/arm/dts/an7583-evb.dts
++++ b/arch/arm/dts/an7583-evb.dts
+@@ -65,3 +65,21 @@
+ &snfi {
+ status = "okay";
+ };
++
++&gdm1 {
++ status = "okay";
++};
++
++&gdm2 {
++ status = "okay";
++
++ managed = "in-band-status";
++ phy-mode = "usxgmii";
++};
++
++&gdm3 {
++ status = "okay";
++
++ managed = "in-band-status";
++ phy-mode = "2500base-x";
++};
+diff --git a/arch/arm/dts/an7583.dtsi b/arch/arm/dts/an7583.dtsi
+index d84ccf27f2c..c6c5083ee7c 100644
+--- a/arch/arm/dts/an7583.dtsi
++++ b/arch/arm/dts/an7583.dtsi
+@@ -145,6 +145,49 @@
+ reg = <0x0 0x1fa20000 0x0 0x388>;
+ };
+
++ 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>,
+@@ -161,6 +204,35 @@
+ reset-names = "fe", "pdma", "qdma",
+ "hsi0-mac", "hsi1-mac",
+ "xfp-mac";
++
++ 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>;
++
++ status = "disabled";
++ };
+ };
+
+ switch: switch@1fb58000 {
+--
+2.53.0
+
--- /dev/null
+From 9382e01855870a8b54a22539b26095b54c3a9b7d Mon Sep 17 00:00:00 2001
+From: Christian Marangi <ansuelsmth@gmail.com>
+Date: Tue, 30 Sep 2025 23:04:15 +0200
+Subject: [PATCH 29/38] configs: enable PCS for Airoha AN7583
+
+Enable PCS config for Airoha AN7583 SoC by default to enable
+support fo External PHY.
+
+Signed-off-by: Christian Marangi <ansuelsmth@gmail.com>
+---
+ configs/an7583_evb_defconfig | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/configs/an7583_evb_defconfig b/configs/an7583_evb_defconfig
+index 7178f45e3f8..8b076c1cfe5 100644
+--- a/configs/an7583_evb_defconfig
++++ b/configs/an7583_evb_defconfig
+@@ -65,6 +65,7 @@ CONFIG_SPI_FLASH_STMICRO=y
+ CONFIG_SPI_FLASH_WINBOND=y
+ CONFIG_SPI_FLASH_MTD=y
+ CONFIG_DM_MDIO=y
++CONFIG_PCS_AIROHA_AN7583=y
+ CONFIG_AIROHA_ETH=y
+ CONFIG_PHY=y
+ CONFIG_PINCTRL=y
+--
+2.53.0
+
--- /dev/null
+From deef0e91119270603748690416f1977a8b4cc035 Mon Sep 17 00:00:00 2001
+From: Christian Marangi <ansuelsmth@gmail.com>
+Date: Tue, 30 Sep 2025 22:20:13 +0200
+Subject: [PATCH 30/38] net: Add support for Airoha AN7583 MDIO Controller
+
+The Airoha AN7583 SoC have 2 dedicated MDIO controller in the SCU
+register map. Add a dedicated driver for it ported from linux kernel.
+
+Signed-off-by: Christian Marangi <ansuelsmth@gmail.com>
+---
+ drivers/net/Kconfig | 7 ++
+ drivers/net/Makefile | 1 +
+ drivers/net/mdio-airoha.c | 221 ++++++++++++++++++++++++++++++++++++++
+ 3 files changed, 229 insertions(+)
+ create mode 100644 drivers/net/mdio-airoha.c
+
+diff --git a/drivers/net/Kconfig b/drivers/net/Kconfig
+index 666618681df..40b1e74a30f 100644
+--- a/drivers/net/Kconfig
++++ b/drivers/net/Kconfig
+@@ -118,6 +118,13 @@ config AG7XXX
+ This driver supports the Atheros AG7xxx Ethernet MAC. This MAC is
+ present in the Atheros AR7xxx, AR9xxx and QCA9xxx MIPS chips.
+
++config MDIO_AIROHA
++ bool "Airoha AN7583 MDIO interface support"
++ depends on DM_MDIO
++ help
++ This driver supports the MDIO interface found in Airoha
++ AN7583 SoC.
++
+ source "drivers/net/airoha/Kconfig"
+
+ config AIROHA_ETH
+diff --git a/drivers/net/Makefile b/drivers/net/Makefile
+index 5e90183d090..b9dfadaf2e9 100644
+--- a/drivers/net/Makefile
++++ b/drivers/net/Makefile
+@@ -62,6 +62,7 @@ obj-$(CONFIG_KSZ9477) += ksz9477.o
+ obj-$(CONFIG_LITEETH) += liteeth.o
+ obj-$(CONFIG_MACB) += macb.o
+ obj-$(CONFIG_MCFFEC) += mcffec.o mcfmii.o
++obj-$(CONFIG_MDIO_AIROHA) += mdio-airoha.o
+ obj-$(CONFIG_MDIO_IPQ4019) += mdio-ipq4019.o
+ obj-$(CONFIG_MDIO_MSCC_MIIM) += mdio-mscc-miim.o
+ obj-$(CONFIG_MDIO_GPIO_BITBANG) += mdio_gpio.o
+diff --git a/drivers/net/mdio-airoha.c b/drivers/net/mdio-airoha.c
+new file mode 100644
+index 00000000000..ac1fb13622e
+--- /dev/null
++++ b/drivers/net/mdio-airoha.c
+@@ -0,0 +1,221 @@
++// SPDX-License-Identifier: GPL-2.0
++/* Airoha AN7583 MDIO interface driver
++ *
++ * Copyright (C) 2025 Christian Marangi <ansuelsmth@gmail.com>
++ */
++
++#include <clk.h>
++#include <dm.h>
++#include <dm/ofnode.h>
++#include <linux/delay.h>
++#include <linux/bitfield.h>
++#include <linux/time.h>
++#include <miiphy.h>
++#include <syscon.h>
++#include <regmap.h>
++#include <reset.h>
++
++/* MII address register definitions */
++#define AN7583_MII_BUSY BIT(31)
++#define AN7583_MII_RDY BIT(30) /* RO signal BUS is ready */
++#define AN7583_MII_CL22_REG_ADDR GENMASK(29, 25)
++#define AN7583_MII_CL45_DEV_ADDR AN7583_MII_CL22_REG_ADDR
++#define AN7583_MII_PHY_ADDR GENMASK(24, 20)
++#define AN7583_MII_CMD GENMASK(19, 18)
++#define AN7583_MII_CMD_CL22_WRITE FIELD_PREP_CONST(AN7583_MII_CMD, 0x1)
++#define AN7583_MII_CMD_CL22_READ FIELD_PREP_CONST(AN7583_MII_CMD, 0x2)
++#define AN7583_MII_CMD_CL45_ADDR FIELD_PREP_CONST(AN7583_MII_CMD, 0x0)
++#define AN7583_MII_CMD_CL45_WRITE FIELD_PREP_CONST(AN7583_MII_CMD, 0x1)
++#define AN7583_MII_CMD_CL45_POSTREAD_INCADDR FIELD_PREP_CONST(AN7583_MII_CMD, 0x2)
++#define AN7583_MII_CMD_CL45_READ FIELD_PREP_CONST(AN7583_MII_CMD, 0x3)
++#define AN7583_MII_ST GENMASK(17, 16)
++#define AN7583_MII_ST_CL45 FIELD_PREP_CONST(AN7583_MII_ST, 0x0)
++#define AN7583_MII_ST_CL22 FIELD_PREP_CONST(AN7583_MII_ST, 0x1)
++#define AN7583_MII_RWDATA GENMASK(15, 0)
++#define AN7583_MII_CL45_REG_ADDR AN7583_MII_RWDATA
++
++#define AN7583_MII_MDIO_DELAY_USEC 100
++#define AN7583_MII_MDIO_RETRY_MSEC 100
++
++struct airoha_mdio_data {
++ u32 base_addr;
++ struct regmap *regmap;
++ struct clk *clk;
++ struct reset_ctl *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_assert(priv->reset);
++ reset_deassert(priv->reset);
++}
++
++static int airoha_mdio_read(struct udevice *dev, int addr, int devnum,
++ int regnum)
++{
++ struct airoha_mdio_data *priv = dev_get_priv(dev);
++ u32 val;
++ int ret;
++
++ airoha_mdio_reset(priv);
++
++ if (devnum != MDIO_DEVAD_NONE) {
++ 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 | FIELD_PREP(AN7583_MII_PHY_ADDR, addr);
++ if (devnum != MDIO_DEVAD_NONE) {
++ val |= AN7583_MII_ST_CL45 | AN7583_MII_CMD_CL45_READ;
++ val |= FIELD_PREP(AN7583_MII_CL45_DEV_ADDR, devnum);
++ } else {
++ val |= AN7583_MII_ST_CL22 | AN7583_MII_CMD_CL22_READ;
++ 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 udevice *dev, int addr, int devnum,
++ int regnum, u16 value)
++{
++ struct airoha_mdio_data *priv = dev_get_priv(dev);
++ u32 val;
++ int ret;
++
++ if (devnum != MDIO_DEVAD_NONE) {
++ 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 | FIELD_PREP(AN7583_MII_PHY_ADDR, addr) |
++ FIELD_PREP(AN7583_MII_RWDATA, value);
++ if (devnum != MDIO_DEVAD_NONE) {
++ val |= AN7583_MII_ST_CL45 | AN7583_MII_CMD_CL45_WRITE;
++ val |= FIELD_PREP(AN7583_MII_CL45_DEV_ADDR, devnum);
++ } else {
++ val |= AN7583_MII_ST_CL22 | AN7583_MII_CMD_CL22_WRITE;
++ 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);
++
++ return ret;
++}
++
++static const struct mdio_ops airoha_mdio_ops = {
++ .read = airoha_mdio_read,
++ .write = airoha_mdio_write,
++};
++
++static int airoha_mdio_probe(struct udevice *dev)
++{
++ struct airoha_mdio_data *priv = dev_get_priv(dev);
++ ofnode ofnode = dev_ofnode(dev);
++ u32 addr, freq;
++ int ret;
++
++ ret = dev_read_u32(dev, "reg", &addr);
++ if (ret)
++ return ret;
++
++ priv->base_addr = addr;
++ priv->regmap = syscon_node_to_regmap(ofnode_get_parent(ofnode));
++
++ priv->clk = devm_clk_get(dev, NULL);
++ if (IS_ERR(priv->clk))
++ return PTR_ERR(priv->clk);
++
++ priv->reset = devm_reset_control_get(dev, NULL);
++ if (IS_ERR(priv->reset))
++ return PTR_ERR(priv->reset);
++
++ reset_deassert(priv->reset);
++
++ /* Check if a custom frequency is defined in DT or default to 2.5 MHz */
++ if (dev_read_u32(dev, "clock-frequency", &freq))
++ freq = 2500000;
++
++ ret = clk_enable(priv->clk);
++ if (ret)
++ return ret;
++
++ ret = clk_set_rate(priv->clk, freq);
++ if (ret < 0)
++ return ret;
++
++ return 0;
++}
++
++static const struct udevice_id airoha_mdio_dt_ids[] = {
++ { .compatible = "airoha,an7583-mdio" },
++ { }
++};
++
++U_BOOT_DRIVER(airoha_mdio) = {
++ .name = "airoha-mdio",
++ .id = UCLASS_MDIO,
++ .of_match = airoha_mdio_dt_ids,
++ .probe = airoha_mdio_probe,
++ .ops = &airoha_mdio_ops,
++ .priv_auto = sizeof(struct airoha_mdio_data),
++};
+--
+2.53.0
+
--- /dev/null
+From e4faff574f7652c1508d788d9a3fb6f6d3d07321 Mon Sep 17 00:00:00 2001
+From: Mikhail Kshevetskiy <mikhail.kshevetskiy@iopsys.eu>
+Date: Sat, 14 Feb 2026 02:55:19 +0300
+Subject: [PATCH 31/38] an7583: fix system controller mdio nodes
+
+The properties 'reg' and 'clocks' should exist for the proper driver initialization.
+This patch adds missed properties and renames a bit mdio bus nodes.
+
+Signed-off-by: Mikhail Kshevetskiy <mikhail.kshevetskiy@iopsys.eu>
+---
+ arch/arm/dts/an7583.dtsi | 14 ++++++++------
+ 1 file changed, 8 insertions(+), 6 deletions(-)
+
+diff --git a/arch/arm/dts/an7583.dtsi b/arch/arm/dts/an7583.dtsi
+index c6c5083ee7c..2229d48ef9c 100644
+--- a/arch/arm/dts/an7583.dtsi
++++ b/arch/arm/dts/an7583.dtsi
+@@ -260,18 +260,20 @@
+ #reset-cells = <1>;
+ };
+
+- mdio_0: mdio-0 {
++ mdio_0: mdio-bus@c8 {
+ compatible = "airoha,an7583-mdio";
+- resets = <&scuclk AN7583_MDIO0>;
++ reg = <0xc8>;
+
+- airoha,bus-id = <0>;
++ clocks = <&scuclk AN7583_CLK_MDIO0>;
++ resets = <&scuclk AN7583_MDIO0>;
+ };
+
+- mdio_1: mdio-1 {
++ mdio_1: mdio-bus@cc {
+ compatible = "airoha,an7583-mdio";
+- resets = <&scuclk AN7583_MDIO1>;
++ reg = <0xcc>;
+
+- airoha,bus-id = <1>;
++ clocks = <&scuclk AN7583_CLK_MDIO1>;
++ resets = <&scuclk AN7583_MDIO1>;
+ };
+ };
+
+--
+2.53.0
+
--- /dev/null
+From b1a6af17ceb35295cf96e512407aacdf3daccf92 Mon Sep 17 00:00:00 2001
+From: Christian Marangi <ansuelsmth@gmail.com>
+Date: Fri, 22 Aug 2025 15:43:56 +0200
+Subject: [PATCH 32/38] an7583: enable MDIO_AIROHA by default
+
+Enable MDIO_AIROHA in the default config.
+
+Signed-off-by: Christian Marangi <ansuelsmth@gmail.com>
+---
+ configs/an7583_evb_defconfig | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/configs/an7583_evb_defconfig b/configs/an7583_evb_defconfig
+index 8b076c1cfe5..08bcbd52c99 100644
+--- a/configs/an7583_evb_defconfig
++++ b/configs/an7583_evb_defconfig
+@@ -65,6 +65,7 @@ CONFIG_SPI_FLASH_STMICRO=y
+ CONFIG_SPI_FLASH_WINBOND=y
+ CONFIG_SPI_FLASH_MTD=y
+ CONFIG_DM_MDIO=y
++CONFIG_MDIO_AIROHA=y
+ CONFIG_PCS_AIROHA_AN7583=y
+ CONFIG_AIROHA_ETH=y
+ CONFIG_PHY=y
+--
+2.53.0
+
-From 06a44c562647bedd0705cac8bec862877371ff1f Mon Sep 17 00:00:00 2001
+From 54483fd54b42ee7ddb23e0d69f5b59fcaec74dee Mon Sep 17 00:00:00 2001
From: Christian Marangi <ansuelsmth@gmail.com>
Date: Wed, 28 May 2025 03:10:53 +0200
-Subject: [PATCH 21/24] airoha: enable UBI support and define default partition
+Subject: [PATCH 23/29] airoha: enable UBI support and define default partition
Signed-off-by: Christian Marangi <ansuelsmth@gmail.com>
---
arch/arm/dts/an7583-evb.dts | 22 ++++++++++++++++++++++
arch/arm/dts/en7523-evb-u-boot.dtsi | 22 ++++++++++++++++++++++
arch/arm/dts/en7581-evb-u-boot.dtsi | 22 ++++++++++++++++++++++
- configs/an7581_evb_defconfig | 17 +++++++++++++++++
- configs/an7583_evb_defconfig | 17 +++++++++++++++++
- configs/en7523_evb_defconfig | 20 ++++++++++++++++++--
- 6 files changed, 118 insertions(+), 2 deletions(-)
+ configs/an7581_evb_defconfig | 8 ++++++++
+ configs/an7583_evb_defconfig | 8 ++++++++
+ configs/en7523_evb_defconfig | 8 ++++++++
+ 6 files changed, 90 insertions(+)
diff --git a/arch/arm/dts/an7583-evb.dts b/arch/arm/dts/an7583-evb.dts
index d02cd194e8a..b3045e6e7d0 100644
pinctrl-names = "default";
pinctrl-0 = <&pcie0_rst_pins>;
diff --git a/arch/arm/dts/en7523-evb-u-boot.dtsi b/arch/arm/dts/en7523-evb-u-boot.dtsi
-index c109d6794fb..b74bfe2d707 100644
+index d6ab621d590..7c688b1fd97 100644
--- a/arch/arm/dts/en7523-evb-u-boot.dtsi
+++ b/arch/arm/dts/en7523-evb-u-boot.dtsi
-@@ -9,3 +9,25 @@
+@@ -13,3 +13,25 @@
+ &gdm1 {
+ status = "okay";
};
-
- #include "en7523-u-boot.dtsi"
+
+&snfi {
+ status = "okay";
+ };
+};
diff --git a/arch/arm/dts/en7581-evb-u-boot.dtsi b/arch/arm/dts/en7581-evb-u-boot.dtsi
-index ebd3b8b4958..b9a9382e254 100644
+index 9a02122fbfa..23331b7703d 100644
--- a/arch/arm/dts/en7581-evb-u-boot.dtsi
+++ b/arch/arm/dts/en7581-evb-u-boot.dtsi
-@@ -9,3 +9,25 @@
+@@ -27,3 +27,25 @@
+ managed = "in-band-status";
+ phy-mode = "usxgmii";
};
-
- #include "an7581-u-boot.dtsi"
+
+&snfi {
+ status = "okay";
+ };
+};
diff --git a/configs/an7581_evb_defconfig b/configs/an7581_evb_defconfig
-index 8e2c694dbbb..05e37d04681 100644
+index a615994cc76..bd7440ddc76 100644
--- a/configs/an7581_evb_defconfig
+++ b/configs/an7581_evb_defconfig
-@@ -81,4 +81,21 @@ CONFIG_SYS_NS16550=y
- CONFIG_SPI=y
- CONFIG_DM_SPI=y
- CONFIG_AIROHA_SNFI_SPI=y
+@@ -40,10 +40,16 @@ CONFIG_CMD_FAT=y
+ CONFIG_CMD_FS_GENERIC=y
+ CONFIG_CMD_MTDPARTS=y
+ CONFIG_CMD_LOG=y
+CONFIG_CMD_UBI=y
-+# CONFIG_CMD_UBI_RENAME is not set
-+CONFIG_CMD_UBIFS=y
+ CONFIG_OF_UPSTREAM=y
+ CONFIG_ENV_OVERWRITE=y
+ CONFIG_ENV_IS_IN_MMC=y
+ # CONFIG_ENV_IS_IN_MTD is not set
+CONFIG_ENV_IS_IN_UBI=y
+CONFIG_ENV_REDUNDANT=y
+CONFIG_ENV_UBI_PART="ubi"
+CONFIG_ENV_UBI_VOLUME="ubootenv"
+CONFIG_ENV_UBI_VOLUME_REDUND="ubootenv2"
-+CONFIG_ENV_UBI_VID_OFFSET=0
-+CONFIG_MTD_UBI=y
-+CONFIG_MTD_UBI_MODULE=y
-+CONFIG_MTD_UBI_WL_THRESHOLD=4096
-+CONFIG_MTD_UBI_BEB_LIMIT=20
-+# CONFIG_MTD_UBI_FASTMAP is not set
+ CONFIG_ENV_RELOC_GD_ENV_ADDR=y
+ CONFIG_ENV_VARS_UBOOT_RUNTIME_CONFIG=y
+ CONFIG_NET_RANDOM_ETHADDR=y
+@@ -67,6 +73,7 @@ CONFIG_SPI_FLASH_SPANSION=y
+ CONFIG_SPI_FLASH_STMICRO=y
+ CONFIG_SPI_FLASH_WINBOND=y
+ CONFIG_SPI_FLASH_MTD=y
+CONFIG_UBI_BLOCK=y
+ CONFIG_DM_MDIO=y
+ CONFIG_PCS_AIROHA_AN7581=y
+ CONFIG_AIROHA_ETH=y
+@@ -82,4 +89,5 @@ CONFIG_SYS_NS16550=y
+ CONFIG_SPI=y
+ CONFIG_DM_SPI=y
+ CONFIG_AIROHA_SNFI_SPI=y
+# CONFIG_UBIFS_SILENCE_MSG is not set
-+# CONFIG_UBIFS_SILENCE_DEBUG_DUMP is not set
CONFIG_SHA512=y
diff --git a/configs/an7583_evb_defconfig b/configs/an7583_evb_defconfig
-index 41d98bab5de..663d1ec52ae 100644
+index 7178f45e3f8..7517b1a6fb3 100644
--- a/configs/an7583_evb_defconfig
+++ b/configs/an7583_evb_defconfig
-@@ -80,4 +80,21 @@ CONFIG_SYS_NS16550=y
- CONFIG_SPI=y
- CONFIG_DM_SPI=y
- CONFIG_AIROHA_SNFI_SPI=y
+@@ -39,8 +39,14 @@ CONFIG_CMD_FAT=y
+ CONFIG_CMD_FS_GENERIC=y
+ CONFIG_CMD_MTDPARTS=y
+ CONFIG_CMD_LOG=y
+CONFIG_CMD_UBI=y
-+# CONFIG_CMD_UBI_RENAME is not set
-+CONFIG_CMD_UBIFS=y
+ CONFIG_ENV_OVERWRITE=y
+ CONFIG_ENV_IS_IN_MMC=y
+CONFIG_ENV_IS_IN_UBI=y
+CONFIG_ENV_REDUNDANT=y
+CONFIG_ENV_UBI_PART="ubi"
+CONFIG_ENV_UBI_VOLUME="ubootenv"
+CONFIG_ENV_UBI_VOLUME_REDUND="ubootenv2"
-+CONFIG_ENV_UBI_VID_OFFSET=0
-+CONFIG_MTD_UBI=y
-+CONFIG_MTD_UBI_MODULE=y
-+CONFIG_MTD_UBI_WL_THRESHOLD=4096
-+CONFIG_MTD_UBI_BEB_LIMIT=20
-+# CONFIG_MTD_UBI_FASTMAP is not set
+ CONFIG_ENV_RELOC_GD_ENV_ADDR=y
+ CONFIG_ENV_VARS_UBOOT_RUNTIME_CONFIG=y
+ CONFIG_NET_RANDOM_ETHADDR=y
+@@ -64,6 +70,7 @@ CONFIG_SPI_FLASH_SPANSION=y
+ CONFIG_SPI_FLASH_STMICRO=y
+ CONFIG_SPI_FLASH_WINBOND=y
+ CONFIG_SPI_FLASH_MTD=y
+CONFIG_UBI_BLOCK=y
+ CONFIG_DM_MDIO=y
+ CONFIG_AIROHA_ETH=y
+ CONFIG_PHY=y
+@@ -78,4 +85,5 @@ CONFIG_SYS_NS16550=y
+ CONFIG_SPI=y
+ CONFIG_DM_SPI=y
+ CONFIG_AIROHA_SNFI_SPI=y
+# CONFIG_UBIFS_SILENCE_MSG is not set
-+# CONFIG_UBIFS_SILENCE_DEBUG_DUMP is not set
CONFIG_SHA512=y
diff --git a/configs/en7523_evb_defconfig b/configs/en7523_evb_defconfig
-index ebd99d133c9..4d01e3f54fe 100644
+index 8b1f3c71e9b..7f05cb63a28 100644
--- a/configs/en7523_evb_defconfig
+++ b/configs/en7523_evb_defconfig
-@@ -5,7 +5,6 @@ CONFIG_TEXT_BASE=0x81E00000
- CONFIG_SYS_MALLOC_F_LEN=0x4000
- CONFIG_NR_DRAM_BANKS=1
- CONFIG_ENV_SIZE=0x4000
--CONFIG_ENV_OFFSET=0x7c000
- CONFIG_DM_GPIO=y
- CONFIG_DEFAULT_DEVICE_TREE="airoha/en7523-evb"
- CONFIG_SYS_LOAD_ADDR=0x81800000
-@@ -36,8 +35,8 @@ CONFIG_CMD_MTDPARTS=y
+@@ -35,8 +35,14 @@ CONFIG_CMD_FAT=y
+ CONFIG_CMD_FS_GENERIC=y
+ CONFIG_CMD_MTDPARTS=y
CONFIG_CMD_LOG=y
++CONFIG_CMD_UBI=y
CONFIG_OF_UPSTREAM=y
CONFIG_ENV_OVERWRITE=y
-+# CONFIG_ENV_IS_IN_MTD is not set
- CONFIG_ENV_RELOC_GD_ENV_ADDR=y
--CONFIG_ENV_MTD_DEV="spi-nand0"
- CONFIG_ENV_VARS_UBOOT_RUNTIME_CONFIG=y
- CONFIG_NET_RANDOM_ETHADDR=y
- CONFIG_SYS_RX_ETH_BUFFER=8
-@@ -63,4 +62,21 @@ CONFIG_SYS_NS16550=y
- CONFIG_SPI=y
- CONFIG_DM_SPI=y
- CONFIG_AIROHA_SNFI_SPI=y
-+CONFIG_CMD_UBI=y
-+# CONFIG_CMD_UBI_RENAME is not set
-+CONFIG_CMD_UBIFS=y
+CONFIG_ENV_IS_IN_UBI=y
+CONFIG_ENV_REDUNDANT=y
+CONFIG_ENV_UBI_PART="ubi"
+CONFIG_ENV_UBI_VOLUME="ubootenv"
+CONFIG_ENV_UBI_VOLUME_REDUND="ubootenv2"
-+CONFIG_ENV_UBI_VID_OFFSET=0
-+CONFIG_MTD_UBI=y
-+CONFIG_MTD_UBI_MODULE=y
-+CONFIG_MTD_UBI_WL_THRESHOLD=4096
-+CONFIG_MTD_UBI_BEB_LIMIT=20
-+# CONFIG_MTD_UBI_FASTMAP is not set
+ CONFIG_ENV_RELOC_GD_ENV_ADDR=y
+ CONFIG_ENV_MTD_DEV="spi-nand0"
+ CONFIG_ENV_VARS_UBOOT_RUNTIME_CONFIG=y
+@@ -50,6 +56,7 @@ CONFIG_LED_GPIO=y
+ CONFIG_MTD=y
+ CONFIG_DM_MTD=y
+ CONFIG_MTD_SPI_NAND=y
+CONFIG_UBI_BLOCK=y
+ CONFIG_DM_MDIO=y
+ CONFIG_AIROHA_ETH=y
+ CONFIG_PHY=y
+@@ -61,4 +68,5 @@ CONFIG_SYS_NS16550=y
+ CONFIG_SPI=y
+ CONFIG_DM_SPI=y
+ CONFIG_AIROHA_SNFI_SPI=y
+# CONFIG_UBIFS_SILENCE_MSG is not set
-+# CONFIG_UBIFS_SILENCE_DEBUG_DUMP is not set
CONFIG_SHA512=y
--
-2.51.0
+2.53.0
-From 2bd435e8b2da2047ea0c5bb9b9af96bc6af2f8cd Mon Sep 17 00:00:00 2001
+From 7c6978fa5518ee3709afcee10183ae2771ad255d Mon Sep 17 00:00:00 2001
From: Christian Marangi <ansuelsmth@gmail.com>
Date: Wed, 28 May 2025 03:18:32 +0200
-Subject: [PATCH 22/24] airoha: add default configuration
+Subject: [PATCH 24/29] airoha: add default configuration
Signed-off-by: Christian Marangi <ansuelsmth@gmail.com>
---
create mode 100644 defenvs/en7523_rfb_env
diff --git a/configs/an7581_evb_defconfig b/configs/an7581_evb_defconfig
-index 05e37d04681..7633cb7ac96 100644
+index bd7440ddc76..b39ebac8f40 100644
--- a/configs/an7581_evb_defconfig
+++ b/configs/an7581_evb_defconfig
-@@ -98,4 +98,6 @@ CONFIG_MTD_UBI_BEB_LIMIT=20
- CONFIG_UBI_BLOCK=y
- # CONFIG_UBIFS_SILENCE_MSG is not set
- # CONFIG_UBIFS_SILENCE_DEBUG_DUMP is not set
+@@ -51,6 +51,8 @@ CONFIG_ENV_UBI_PART="ubi"
+ CONFIG_ENV_UBI_VOLUME="ubootenv"
+ CONFIG_ENV_UBI_VOLUME_REDUND="ubootenv2"
+ CONFIG_ENV_RELOC_GD_ENV_ADDR=y
+CONFIG_ENV_USE_DEFAULT_ENV_TEXT_FILE=y
+CONFIG_ENV_DEFAULT_ENV_TEXT_FILE="defenvs/an7581_rfb_env"
- CONFIG_SHA512=y
+ CONFIG_ENV_VARS_UBOOT_RUNTIME_CONFIG=y
+ CONFIG_NET_RANDOM_ETHADDR=y
+ CONFIG_SYS_RX_ETH_BUFFER=8
diff --git a/configs/an7583_evb_defconfig b/configs/an7583_evb_defconfig
-index 663d1ec52ae..c69cf353ffa 100644
+index 7517b1a6fb3..e1d3c3b428a 100644
--- a/configs/an7583_evb_defconfig
+++ b/configs/an7583_evb_defconfig
-@@ -97,4 +97,6 @@ CONFIG_MTD_UBI_BEB_LIMIT=20
- CONFIG_UBI_BLOCK=y
- # CONFIG_UBIFS_SILENCE_MSG is not set
- # CONFIG_UBIFS_SILENCE_DEBUG_DUMP is not set
+@@ -48,6 +48,8 @@ CONFIG_ENV_UBI_PART="ubi"
+ CONFIG_ENV_UBI_VOLUME="ubootenv"
+ CONFIG_ENV_UBI_VOLUME_REDUND="ubootenv2"
+ CONFIG_ENV_RELOC_GD_ENV_ADDR=y
+CONFIG_ENV_USE_DEFAULT_ENV_TEXT_FILE=y
+CONFIG_ENV_DEFAULT_ENV_TEXT_FILE="defenvs/an7583_rfb_env"
- CONFIG_SHA512=y
+ CONFIG_ENV_VARS_UBOOT_RUNTIME_CONFIG=y
+ CONFIG_NET_RANDOM_ETHADDR=y
+ CONFIG_SYS_RX_ETH_BUFFER=8
diff --git a/configs/en7523_evb_defconfig b/configs/en7523_evb_defconfig
-index 4d01e3f54fe..8febb6cabdd 100644
+index 7f05cb63a28..dd809c5f949 100644
--- a/configs/en7523_evb_defconfig
+++ b/configs/en7523_evb_defconfig
-@@ -79,4 +79,6 @@ CONFIG_MTD_UBI_BEB_LIMIT=20
- CONFIG_UBI_BLOCK=y
- # CONFIG_UBIFS_SILENCE_MSG is not set
- # CONFIG_UBIFS_SILENCE_DEBUG_DUMP is not set
+@@ -45,6 +45,8 @@ CONFIG_ENV_UBI_VOLUME="ubootenv"
+ CONFIG_ENV_UBI_VOLUME_REDUND="ubootenv2"
+ CONFIG_ENV_RELOC_GD_ENV_ADDR=y
+ CONFIG_ENV_MTD_DEV="spi-nand0"
+CONFIG_ENV_USE_DEFAULT_ENV_TEXT_FILE=y
+CONFIG_ENV_DEFAULT_ENV_TEXT_FILE="defenvs/en7523_rfb_env"
- CONFIG_SHA512=y
+ CONFIG_ENV_VARS_UBOOT_RUNTIME_CONFIG=y
+ CONFIG_NET_RANDOM_ETHADDR=y
+ CONFIG_SYS_RX_ETH_BUFFER=8
diff --git a/defenvs/an7581_rfb_env b/defenvs/an7581_rfb_env
new file mode 100644
index 00000000000..716ddc321e2
+serverip=192.168.1.10
+bootargs=ubi.mtd=ubi root=/dev/ubiblock0_5 rootwait
--
-2.51.0
+2.53.0
+++ /dev/null
-From c89b8f1baa9bf4e32b9f146f5fece6f2151e2dd0 Mon Sep 17 00:00:00 2001
-From: Mikhail Kshevetskiy <mikhail.kshevetskiy@iopsys.eu>
-Date: Mon, 13 Oct 2025 20:48:00 +0300
-Subject: [PATCH 23/24] arm: airoha: disable environment inside mtd partition
-
-When booting on en7581_evb board equipped with spinand flash, a u-boot
-panic occurs. The panic is caused by the absence any available mtd
-partition.
-
-Disable CONFIG_ENV_IS_IN_MTD to avoid an issue. The environment will
-be stored in the EMMC or in UBI, so actually CONFIG_ENV_IS_IN_MTD is
-not needed.
-
-Signed-off-by: Mikhail Kshevetskiy <mikhail.kshevetskiy@iopsys.eu>
----
- configs/an7581_evb_defconfig | 1 +
- configs/an7583_evb_defconfig | 1 +
- 2 files changed, 2 insertions(+)
-
-diff --git a/configs/an7581_evb_defconfig b/configs/an7581_evb_defconfig
-index 7633cb7ac96..afdb0cd8586 100644
---- a/configs/an7581_evb_defconfig
-+++ b/configs/an7581_evb_defconfig
-@@ -41,6 +41,7 @@ CONFIG_CMD_LOG=y
- CONFIG_OF_UPSTREAM=y
- CONFIG_ENV_OVERWRITE=y
- CONFIG_ENV_IS_IN_MMC=y
-+# CONFIG_ENV_IS_IN_MTD is not set
- CONFIG_ENV_RELOC_GD_ENV_ADDR=y
- CONFIG_ENV_VARS_UBOOT_RUNTIME_CONFIG=y
- CONFIG_NET_RANDOM_ETHADDR=y
-diff --git a/configs/an7583_evb_defconfig b/configs/an7583_evb_defconfig
-index c69cf353ffa..c3d47c411ba 100644
---- a/configs/an7583_evb_defconfig
-+++ b/configs/an7583_evb_defconfig
-@@ -40,6 +40,7 @@ CONFIG_CMD_MTDPARTS=y
- CONFIG_CMD_LOG=y
- CONFIG_ENV_OVERWRITE=y
- CONFIG_ENV_IS_IN_MMC=y
-+# CONFIG_ENV_IS_IN_MTD is not set
- CONFIG_ENV_RELOC_GD_ENV_ADDR=y
- CONFIG_ENV_VARS_UBOOT_RUNTIME_CONFIG=y
- CONFIG_NET_RANDOM_ETHADDR=y
---
-2.51.0
-
--- /dev/null
+From b90921faa3ba5ef8608667c3afb61fdbd21a2fe4 Mon Sep 17 00:00:00 2001
+From: Mikhail Kshevetskiy <mikhail.kshevetskiy@iopsys.eu>
+Date: Mon, 27 Apr 2026 15:20:15 +0300
+Subject: [PATCH 25/29] configs: airoha: disable ENV_IS_IN_MTD to avoid boot panic
+
+Booting image generated with
+
+ make an7581_evb_defconfig
+
+will results in
+
+ U-Boot 2026.04-00924-gfb815bd8793b (Apr 27 2026 - 15:08:30 +0300)
+
+ CPU: Airoha AN7581
+ DRAM: 512 MiB
+ Core: 35 devices, 19 uclasses, devicetree: separate
+ MMC: mmc@1fa0e000: 0
+ Loading Environment from MMC... *** Warning - No block device, using default environment
+
+ Loading Environment from MTD... *** Warning - get_mtd_device_nm() failed, using default environment
+
+ BUG at drivers/mtd/mtdcore.c:898/__put_mtd_device()!
+ BUG!
+ resetting ...
+
+This happens because no any mtd partition defined in dts/mtdparts.
+Disabling of ENV_IS_IN_MTD fixes an issue.
+
+Fix the same for en7523 & an7583 as well.
+
+Signed-off-by: Mikhail Kshevetskiy <mikhail.kshevetskiy@iopsys.eu>
+---
+ configs/an7583_evb_defconfig | 1 +
+ configs/en7523_evb_defconfig | 3 +--
+ 2 files changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/configs/an7583_evb_defconfig b/configs/an7583_evb_defconfig
+index e1d3c3b428a..ca0422abcdb 100644
+--- a/configs/an7583_evb_defconfig
++++ b/configs/an7583_evb_defconfig
+@@ -42,6 +42,7 @@ CONFIG_CMD_LOG=y
+ CONFIG_CMD_UBI=y
+ CONFIG_ENV_OVERWRITE=y
+ CONFIG_ENV_IS_IN_MMC=y
++# CONFIG_ENV_IS_IN_MTD is not set
+ CONFIG_ENV_IS_IN_UBI=y
+ CONFIG_ENV_REDUNDANT=y
+ CONFIG_ENV_UBI_PART="ubi"
+diff --git a/configs/en7523_evb_defconfig b/configs/en7523_evb_defconfig
+index dd809c5f949..c539ba71994 100644
+--- a/configs/en7523_evb_defconfig
++++ b/configs/en7523_evb_defconfig
+@@ -5,7 +5,6 @@ CONFIG_TEXT_BASE=0x81E00000
+ CONFIG_SYS_MALLOC_F_LEN=0x4000
+ CONFIG_NR_DRAM_BANKS=1
+ CONFIG_ENV_SIZE=0x4000
+-CONFIG_ENV_OFFSET=0x7c000
+ CONFIG_DM_GPIO=y
+ CONFIG_DEFAULT_DEVICE_TREE="airoha/en7523-evb"
+ CONFIG_SYS_LOAD_ADDR=0x81800000
+@@ -38,13 +37,13 @@ CONFIG_CMD_LOG=y
+ CONFIG_CMD_UBI=y
+ CONFIG_OF_UPSTREAM=y
+ CONFIG_ENV_OVERWRITE=y
++# CONFIG_ENV_IS_IN_MTD is not set
+ CONFIG_ENV_IS_IN_UBI=y
+ CONFIG_ENV_REDUNDANT=y
+ CONFIG_ENV_UBI_PART="ubi"
+ CONFIG_ENV_UBI_VOLUME="ubootenv"
+ CONFIG_ENV_UBI_VOLUME_REDUND="ubootenv2"
+ CONFIG_ENV_RELOC_GD_ENV_ADDR=y
+-CONFIG_ENV_MTD_DEV="spi-nand0"
+ CONFIG_ENV_USE_DEFAULT_ENV_TEXT_FILE=y
+ CONFIG_ENV_DEFAULT_ENV_TEXT_FILE="defenvs/en7523_rfb_env"
+ CONFIG_ENV_VARS_UBOOT_RUNTIME_CONFIG=y
+--
+2.53.0
+
+++ /dev/null
-From 78a01bfa242139ae6b7ac487c0e857457d8ff416 Mon Sep 17 00:00:00 2001
-From: Mikhail Kshevetskiy <mikhail.kshevetskiy@iopsys.eu>
-Date: Mon, 13 Oct 2025 20:56:31 +0300
-Subject: [PATCH 24/24] arm: airoha: enable position independent code
-
-This slightly increase the code, but makes debugging a bit easy
-
-Signed-off-by: Mikhail Kshevetskiy <mikhail.kshevetskiy@iopsys.eu>
----
- configs/an7581_evb_defconfig | 1 +
- configs/an7583_evb_defconfig | 1 +
- configs/en7523_evb_defconfig | 1 +
- 3 files changed, 3 insertions(+)
-
-diff --git a/configs/an7581_evb_defconfig b/configs/an7581_evb_defconfig
-index afdb0cd8586..be076ec7723 100644
---- a/configs/an7581_evb_defconfig
-+++ b/configs/an7581_evb_defconfig
-@@ -1,5 +1,6 @@
- CONFIG_ARM=y
- CONFIG_ARCH_AIROHA=y
-+CONFIG_POSITION_INDEPENDENT=y
- CONFIG_TARGET_AN7581=y
- CONFIG_TEXT_BASE=0x81E00000
- CONFIG_SYS_MALLOC_F_LEN=0x4000
-diff --git a/configs/an7583_evb_defconfig b/configs/an7583_evb_defconfig
-index c3d47c411ba..7ef2d6feeba 100644
---- a/configs/an7583_evb_defconfig
-+++ b/configs/an7583_evb_defconfig
-@@ -1,5 +1,6 @@
- CONFIG_ARM=y
- CONFIG_ARCH_AIROHA=y
-+CONFIG_POSITION_INDEPENDENT=y
- CONFIG_TARGET_AN7583=y
- CONFIG_TEXT_BASE=0x81E00000
- CONFIG_SYS_MALLOC_F_LEN=0x4000
-diff --git a/configs/en7523_evb_defconfig b/configs/en7523_evb_defconfig
-index 8febb6cabdd..53011e47f55 100644
---- a/configs/en7523_evb_defconfig
-+++ b/configs/en7523_evb_defconfig
-@@ -1,6 +1,7 @@
- CONFIG_ARM=y
- CONFIG_SYS_ARCH_TIMER=y
- CONFIG_ARCH_AIROHA=y
-+CONFIG_POSITION_INDEPENDENT=y
- CONFIG_TEXT_BASE=0x81E00000
- CONFIG_SYS_MALLOC_F_LEN=0x4000
- CONFIG_NR_DRAM_BANKS=1
---
-2.51.0
-
--- /dev/null
+From 12fa74667740e51317366c4c86b78ccf215d3421 Mon Sep 17 00:00:00 2001
+From: Mikhail Kshevetskiy <mikhail.kshevetskiy@iopsys.eu>
+Date: Mon, 27 Apr 2026 15:18:48 +0300
+Subject: [PATCH 26/29] configs: airoha: enable position independent code
+
+This enables U-Boot loading from any 4K aligned address.
+It makes U-Boot debugging a bit simpler.
+
+Signed-off-by: Mikhail Kshevetskiy <mikhail.kshevetskiy@iopsys.eu>
+---
+ configs/an7583_evb_defconfig | 1 +
+ configs/en7523_evb_defconfig | 1 +
+ 2 files changed, 2 insertions(+)
+
+diff --git a/configs/an7583_evb_defconfig b/configs/an7583_evb_defconfig
+index ca0422abcdb..1c4739d0d39 100644
+--- a/configs/an7583_evb_defconfig
++++ b/configs/an7583_evb_defconfig
+@@ -1,4 +1,5 @@
+ CONFIG_ARM=y
++CONFIG_POSITION_INDEPENDENT=y
+ CONFIG_ARCH_AIROHA=y
+ CONFIG_TARGET_AN7583=y
+ CONFIG_TEXT_BASE=0x81E00000
+diff --git a/configs/en7523_evb_defconfig b/configs/en7523_evb_defconfig
+index c539ba71994..c85c12d438d 100644
+--- a/configs/en7523_evb_defconfig
++++ b/configs/en7523_evb_defconfig
+@@ -1,4 +1,5 @@
+ CONFIG_ARM=y
++CONFIG_POSITION_INDEPENDENT=y
+ CONFIG_SYS_ARCH_TIMER=y
+ CONFIG_ARCH_AIROHA=y
+ CONFIG_TEXT_BASE=0x81E00000
+--
+2.53.0
+