* [PATCH v2 00/16] arm: airoha: add AN7583 SoC support
@ 2026-09-02 8:52 Mikhail Kshevetskiy
2026-09-02 8:52 ` [PATCH v2 01/16] airoha: add support for Airoha AN7583 SoC Mikhail Kshevetskiy
` (15 more replies)
0 siblings, 16 replies; 20+ messages in thread
From: Mikhail Kshevetskiy @ 2026-09-02 8:52 UTC (permalink / raw)
To: Tom Rini, Ilias Apalodimas, Christian Marangi, Lukasz Majewski,
Jerome Forissier, Sumit Garg, Simon Glass, Wayen Yan,
Quentin Schulz, Johan Jonker, Julien Stephan, u-boot
Cc: Mikhail Kshevetskiy
This patch series adds AN7583 SoC support. It is based on u-boot patches
of Christian Marangi airoha openwrt branch
https://github.com/Ansuel/openwrt/commits/main-airoha-6.12/
AN7583 is not included to upstream linux, but actively supported by
upstream openwrt. The patches were adapted for latest U-Boot.
Tom Rini, could you use this patch series instead of
https://lore.kernel.org/u-boot/20260821070345.138264-1-ansuelsmth@gmail.com/
It have the same commit as a base, but provides much more complete an7583
support. Changes from above patch:
* fixed arch/arm/mach-airoha/an7583/init.c compilation issue
* added an7583 specific helper needed for clk-airoha
* patches for proper support of clk, reset, network
Christian Marangi (12):
airoha: add support for Airoha AN7583 SoC
dt-bindings: clock: airoha: Document support for AN7583 clock
clk: airoha: add support for Airoha AN7583 SoC clock
reset: airoha: Add support for Airoha AN7583 reset
net: airoha: add support for Airoha AN7583
airoha: add Ethernet node in AN7583 dtsi
airoha: add MMC node for Airoha AN7583
net: airoha: add support for Airoha AN7583 PCS driver
airoha: add PCS node for AN7583
configs: enable PCS for Airoha AN7583
net: Add support for Airoha AN7583 MDIO Controller
an7583: enable MDIO_AIROHA by default
Mikhail Kshevetskiy (4):
arm: airoha: introduce AN7583 helpers to get SCU and CHIP_SCU regmaps
configs: an7583: add mii/mdio support
arm: dts: an7583: add mdio child node to switch node
an7583: fix system controller mdio nodes
arch/arm/dts/an7583-evb.dts | 85 +
arch/arm/dts/an7583.dtsi | 522 ++++
arch/arm/include/asm/arch-an7583 | 1 +
arch/arm/mach-airoha/Kconfig | 14 +
arch/arm/mach-airoha/Makefile | 1 +
arch/arm/mach-airoha/an7583/Makefile | 4 +
arch/arm/mach-airoha/an7583/init.c | 66 +
arch/arm/mach-airoha/an7583/scu-regmap.c | 34 +
board/airoha/an7583/MAINTAINERS | 5 +
board/airoha/an7583/Makefile | 3 +
board/airoha/an7583/an7583_rfb.c | 16 +
configs/an7583_evb_defconfig | 83 +
drivers/clk/airoha/clk-airoha.c | 158 ++
drivers/net/Kconfig | 7 +
drivers/net/Makefile | 1 +
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 | 2202 +++++++++++++++++
drivers/net/airoha_eth.c | 94 +
drivers/net/mdio-airoha.c | 221 ++
drivers/reset/reset-airoha.c | 60 +
.../include/dt-bindings/clock/en7523-clk.h | 3 +
include/configs/an7583.h | 19 +
.../dt-bindings/reset/airoha,an7583-reset.h | 62 +
26 files changed, 3714 insertions(+)
create mode 100644 arch/arm/dts/an7583-evb.dts
create mode 100644 arch/arm/dts/an7583.dtsi
create mode 120000 arch/arm/include/asm/arch-an7583
create mode 100644 arch/arm/mach-airoha/an7583/Makefile
create mode 100644 arch/arm/mach-airoha/an7583/init.c
create mode 100644 arch/arm/mach-airoha/an7583/scu-regmap.c
create mode 100644 board/airoha/an7583/MAINTAINERS
create mode 100644 board/airoha/an7583/Makefile
create mode 100644 board/airoha/an7583/an7583_rfb.c
create mode 100644 configs/an7583_evb_defconfig
create mode 100644 drivers/net/airoha/pcs-an7583.c
create mode 100644 drivers/net/mdio-airoha.c
create mode 100644 include/configs/an7583.h
create mode 100644 include/dt-bindings/reset/airoha,an7583-reset.h
--
2.53.0
^ permalink raw reply [flat|nested] 20+ messages in thread
* [PATCH v2 01/16] airoha: add support for Airoha AN7583 SoC
2026-09-02 8:52 [PATCH v2 00/16] arm: airoha: add AN7583 SoC support Mikhail Kshevetskiy
@ 2026-09-02 8:52 ` Mikhail Kshevetskiy
2026-09-02 16:24 ` Tom Rini
2026-09-02 8:52 ` [PATCH v2 02/16] arm: airoha: introduce AN7583 helpers to get SCU and CHIP_SCU regmaps Mikhail Kshevetskiy
` (14 subsequent siblings)
15 siblings, 1 reply; 20+ messages in thread
From: Mikhail Kshevetskiy @ 2026-09-02 8:52 UTC (permalink / raw)
To: Tom Rini, Ilias Apalodimas, Christian Marangi, Lukasz Majewski,
Jerome Forissier, Sumit Garg, Simon Glass, Wayen Yan,
Quentin Schulz, Johan Jonker, Julien Stephan, u-boot
Cc: Mikhail Kshevetskiy
From: Christian Marangi <ansuelsmth@gmail.com>
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
CPU and RAM initialization. Everything is mostly based on AN7581 that
share lots of common piece.
Acked-by: Mikhail Kshevetskiy <mikhail.kshevetskiy@iopsys.eu>
Signed-off-by: Christian Marangi <ansuelsmth@gmail.com>
---
arch/arm/dts/an7583-evb.dts | 67 +++++
arch/arm/dts/an7583.dtsi | 387 +++++++++++++++++++++++++++
arch/arm/mach-airoha/Kconfig | 14 +
arch/arm/mach-airoha/Makefile | 1 +
arch/arm/mach-airoha/an7583/Makefile | 3 +
arch/arm/mach-airoha/an7583/init.c | 66 +++++
board/airoha/an7583/MAINTAINERS | 5 +
board/airoha/an7583/Makefile | 3 +
board/airoha/an7583/an7583_rfb.c | 16 ++
configs/an7583_evb_defconfig | 79 ++++++
include/configs/an7583.h | 19 ++
11 files changed, 660 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
create mode 100644 arch/arm/mach-airoha/an7583/init.c
create mode 100644 board/airoha/an7583/MAINTAINERS
create mode 100644 board/airoha/an7583/Makefile
create mode 100644 board/airoha/an7583/an7583_rfb.c
create mode 100644 configs/an7583_evb_defconfig
create mode 100644 include/configs/an7583.h
diff --git a/arch/arm/dts/an7583-evb.dts b/arch/arm/dts/an7583-evb.dts
new file mode 100644
index 00000000000..d02cd194e8a
--- /dev/null
+++ b/arch/arm/dts/an7583-evb.dts
@@ -0,0 +1,67 @@
+// SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+/dts-v1/;
+
+/* Bootloader installs ATF here */
+/memreserve/ 0x80000000 0x200000;
+
+#include <dt-bindings/leds/common.h>
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/input/input.h>
+#include "an7583.dtsi"
+
+/ {
+ model = "Airoha AN7583 Evaluation Board";
+ compatible = "airoha,an7583-evb", "airoha,an7583", "airoha,en7583";
+
+ aliases {
+ serial0 = &uart1;
+ };
+
+ chosen {
+ bootargs = "console=ttyS0,115200 earlycon";
+ stdout-path = "serial0:115200n8";
+ linux,usable-memory-range = <0x0 0x80200000 0x0 0x1fe00000>;
+ };
+
+ /* When running as a first-stage bootloader this isn't filled in automatically */
+ memory@80000000 {
+ device_type = "memory";
+ reg = <0x0 0x80000000 0x0 0x20000000>;
+ };
+};
+
+&an7583_pinctrl {
+ pcie0_rst_pins: pcie0-rst-pins {
+ conf {
+ pins = "pcie_reset0";
+ drive-open-drain = <1>;
+ };
+ };
+
+ pcie1_rst_pins: pcie1-rst-pins {
+ conf {
+ pins = "pcie_reset1";
+ drive-open-drain = <1>;
+ };
+ };
+};
+
+&pcie0 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pcie0_rst_pins>;
+ status = "okay";
+};
+
+&pcie1 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pcie1_rst_pins>;
+ status = "okay";
+};
+
+&i2c0 {
+ status = "okay";
+};
+
+&snfi {
+ status = "okay";
+};
diff --git a/arch/arm/dts/an7583.dtsi b/arch/arm/dts/an7583.dtsi
new file mode 100644
index 00000000000..9362d2fbedf
--- /dev/null
+++ b/arch/arm/dts/an7583.dtsi
@@ -0,0 +1,387 @@
+// SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+
+#include <dt-bindings/interrupt-controller/irq.h>
+#include <dt-bindings/interrupt-controller/arm-gic.h>
+#include <dt-bindings/clock/en7523-clk.h>
+#include <dt-bindings/reset/airoha,an7583-reset.h>
+#include <dt-bindings/leds/common.h>
+#include <dt-bindings/thermal/thermal.h>
+
+/ {
+ interrupt-parent = <&gic>;
+ #address-cells = <2>;
+ #size-cells = <2>;
+
+ reserved-memory {
+ #address-cells = <2>;
+ #size-cells = <2>;
+ ranges;
+
+ atf-reserved-memory@80000000 {
+ no-map;
+ reg = <0x0 0x80000000 0x0 0x40000>;
+ };
+
+ npu-binary@84000000 {
+ no-map;
+ reg = <0x0 0x84000000 0x0 0xa00000>;
+ };
+
+ npu-flag@84b0000 {
+ no-map;
+ reg = <0x0 0x84b00000 0x0 0x100000>;
+ };
+
+ npu-pkt@85000000 {
+ no-map;
+ reg = <0x0 0x85000000 0x0 0x1a00000>;
+ };
+
+ npu-phyaddr@86b00000 {
+ no-map;
+ reg = <0x0 0x86b00000 0x0 0x100000>;
+ };
+
+ npu-rxdesc@86d00000 {
+ no-map;
+ reg = <0x0 0x86d00000 0x0 0x100000>;
+ };
+ };
+
+ psci {
+ compatible = "arm,psci-1.0";
+ method = "smc";
+ };
+
+ cpus {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ cpu-map {
+ cluster0 {
+ core0 {
+ cpu = <&cpu0>;
+ };
+
+ core1 {
+ cpu = <&cpu1>;
+ };
+ };
+ };
+
+ cpu0: cpu@0 {
+ device_type = "cpu";
+ compatible = "arm,cortex-a53";
+ reg = <0x0>;
+ enable-method = "psci";
+ next-level-cache = <&l2>;
+ #cooling-cells = <2>;
+ };
+
+ cpu1: cpu@1 {
+ device_type = "cpu";
+ compatible = "arm,cortex-a53";
+ reg = <0x1>;
+ enable-method = "psci";
+ next-level-cache = <&l2>;
+ #cooling-cells = <2>;
+ };
+
+ l2: l2-cache {
+ compatible = "cache";
+ cache-size = <0x80000>;
+ cache-line-size = <64>;
+ cache-level = <2>;
+ cache-unified;
+ };
+ };
+
+ timer {
+ compatible = "arm,armv8-timer";
+ interrupt-parent = <&gic>;
+ interrupts = <GIC_PPI 13 IRQ_TYPE_LEVEL_LOW>,
+ <GIC_PPI 14 IRQ_TYPE_LEVEL_LOW>,
+ <GIC_PPI 11 IRQ_TYPE_LEVEL_LOW>,
+ <GIC_PPI 10 IRQ_TYPE_LEVEL_LOW>;
+ };
+
+ soc {
+ compatible = "simple-bus";
+ #address-cells = <2>;
+ #size-cells = <2>;
+ ranges;
+
+ gic: interrupt-controller@9000000 {
+ compatible = "arm,gic-v3";
+ interrupt-controller;
+ #interrupt-cells = <3>;
+ #address-cells = <1>;
+ #size-cells = <1>;
+ reg = <0x0 0x09000000 0x0 0x20000>,
+ <0x0 0x09080000 0x0 0x80000>,
+ <0x0 0x09400000 0x0 0x2000>,
+ <0x0 0x09500000 0x0 0x2000>,
+ <0x0 0x09600000 0x0 0x20000>;
+ interrupts = <GIC_PPI 9 IRQ_TYPE_LEVEL_LOW>;
+ };
+
+ chip_scu: syscon@1fa20000 {
+ compatible = "airoha,en7581-chip-scu", "syscon";
+ reg = <0x0 0x1fa20000 0x0 0x388>;
+ };
+
+ syscon@1fbe3400 {
+ compatible = "airoha,en7581-pbus-csr", "syscon";
+ reg = <0x0 0x1fbe3400 0x0 0xff>;
+ };
+
+ system-controller@1fb00000 {
+ compatible = "syscon", "simple-mfd";
+ reg = <0x0 0x1fb00000 0x0 0x970>;
+
+ scuclk: scuclk {
+ compatible = "airoha,an7583-scu";
+ #clock-cells = <1>;
+ #reset-cells = <1>;
+ };
+
+ mdio_0: mdio-0 {
+ compatible = "airoha,an7583-mdio";
+ resets = <&scuclk AN7583_MDIO0>;
+
+ airoha,bus-id = <0>;
+ };
+
+ mdio_1: mdio-1 {
+ compatible = "airoha,an7583-mdio";
+ resets = <&scuclk AN7583_MDIO1>;
+
+ airoha,bus-id = <1>;
+ };
+ };
+
+ system-controller@1fbf0200 {
+ compatible = "syscon", "simple-mfd";
+ reg = <0x0 0x1fbf0200 0x0 0xc0>;
+
+ an7583_pinctrl: pinctrl {
+ compatible = "airoha,an7583-pinctrl";
+
+ interrupt-parent = <&gic>;
+ interrupts = <GIC_SPI 26 IRQ_TYPE_LEVEL_HIGH>;
+
+ gpio-controller;
+ #gpio-cells = <2>;
+
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ };
+ };
+
+ i2cclock: i2cclock@0 {
+ #clock-cells = <0>;
+ compatible = "fixed-clock";
+
+ /* 20 MHz */
+ clock-frequency = <20000000>;
+ };
+
+ i2c0: i2c0@1fbf8000 {
+ compatible = "mediatek,mt7621-i2c";
+ reg = <0x0 0x1fbf8000 0x0 0x100>;
+
+ clocks = <&i2cclock>;
+
+ /* 100 kHz */
+ clock-frequency = <100000>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ status = "disable";
+ };
+
+ i2c1: i2c1@1fbf8100 {
+ compatible = "mediatek,mt7621-i2c";
+ reg = <0x0 0x1fbf8100 0x0 0x100>;
+
+ clocks = <&i2cclock>;
+
+ /* 100 kHz */
+ clock-frequency = <100000>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ status = "disable";
+ };
+
+ snfi: spi@1fa10000 {
+ compatible = "airoha,en7581-snand";
+ reg = <0x0 0x1fa10000 0x0 0x140>,
+ <0x0 0x1fa11000 0x0 0x600>;
+
+ clocks = <&scuclk EN7523_CLK_SPI>;
+ clock-names = "spi";
+
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ status = "disabled";
+
+ spi_nand: nand@0 {
+ compatible = "spi-nand";
+ reg = <0>;
+ spi-max-frequency = <50000000>;
+ spi-tx-bus-width = <1>;
+ spi-rx-bus-width = <2>;
+ };
+ };
+
+ uart1: serial@1fbf0000 {
+ compatible = "ns16550";
+ reg = <0x0 0x1fbf0000 0x0 0x30>;
+ reg-io-width = <4>;
+ reg-shift = <2>;
+ interrupts = <GIC_SPI 18 IRQ_TYPE_LEVEL_HIGH>;
+ clock-frequency = <1843200>;
+ bootph-all;
+ };
+
+ uart2: serial@1fbf0300 {
+ compatible = "airoha,en7523-uart";
+ reg = <0x0 0x1fbf0300 0x0 0x30>;
+ reg-io-width = <4>;
+ reg-shift = <2>;
+ interrupts = <GIC_SPI 32 IRQ_TYPE_LEVEL_HIGH>;
+ clock-frequency = <7372800>;
+
+ status = "disabled";
+ };
+
+ hsuart3: serial@1fbe1000 {
+ compatible = "airoha,en7523-uart";
+ reg = <0x0 0x1fbe1000 0x0 0x40>;
+ reg-io-width = <4>;
+ reg-shift = <2>;
+ interrupts = <GIC_SPI 54 IRQ_TYPE_LEVEL_HIGH>;
+ clock-frequency = <7372800>;
+
+ status = "disabled";
+ };
+
+ uart4: serial@1fbf0600 {
+ compatible = "airoha,en7523-uart";
+ reg = <0x0 0x1fbf0600 0x0 0x30>;
+ reg-io-width = <4>;
+ reg-shift = <2>;
+ interrupts = <GIC_SPI 61 IRQ_TYPE_LEVEL_HIGH>;
+ clock-frequency = <7372800>;
+
+ status = "disabled";
+ };
+
+ uart5: serial@1fbf0700 {
+ compatible = "airoha,en7523-uart";
+ reg = <0x0 0x1fbf0700 0x0 0x30>;
+ reg-io-width = <4>;
+ reg-shift = <2>;
+ interrupts = <GIC_SPI 18 IRQ_TYPE_LEVEL_HIGH>;
+ clock-frequency = <7372800>;
+
+ status = "disabled";
+ };
+
+ pciephy: phy@1fa5a000 {
+ compatible = "airoha,en7581-pcie-phy";
+ reg = <0x0 0x1fa5a000 0x0 0xfff>,
+ <0x0 0x1fa5b000 0x0 0xfff>,
+ <0x0 0x1fa5c000 0x0 0xfff>,
+ <0x0 0x1fc10044 0x0 0x4>,
+ <0x0 0x1fc30044 0x0 0x4>,
+ <0x0 0x1fc15030 0x0 0x104>;
+ reg-names = "csr-2l", "pma0", "pma1",
+ "p0-xr-dtime", "p1-xr-dtime",
+ "rx-aeq";
+ #phy-cells = <0>;
+ };
+
+ pcie0: pcie@1fc00000 {
+ compatible = "airoha,an7583-pcie";
+ device_type = "pci";
+ linux,pci-domain = <0>;
+ #address-cells = <3>;
+ #size-cells = <2>;
+
+ reg = <0x0 0x1fc20000 0x0 0x1670>;
+ reg-names = "pcie-mac";
+
+ clocks = <&scuclk EN7523_CLK_PCIE>;
+ clock-names = "sys-ck";
+
+ phys = <&pciephy>;
+ phy-names = "pcie-phy";
+
+ ranges = <0x02000000 0 0x20000000 0x0 0x20000000 0 0x4000000>;
+
+ resets = <&scuclk AN7583_PCIE0_RST>,
+ <&scuclk AN7583_PCIE1_RST>;
+ reset-names = "phy-lane0", "phy-lane1";
+
+ interrupts = <GIC_SPI 39 IRQ_TYPE_LEVEL_HIGH>;
+ bus-range = <0x00 0xff>;
+ #interrupt-cells = <1>;
+ interrupt-map-mask = <0 0 0 7>;
+ interrupt-map = <0 0 0 1 &pcie_intc0 0>,
+ <0 0 0 2 &pcie_intc0 1>,
+ <0 0 0 3 &pcie_intc0 2>,
+ <0 0 0 4 &pcie_intc0 3>;
+
+ status = "disabled";
+
+ pcie_intc0: interrupt-controller {
+ interrupt-controller;
+ #address-cells = <0>;
+ #interrupt-cells = <1>;
+ };
+ };
+
+ pcie1: pcie@1fc20000 {
+ compatible = "airoha,an7583-pcie";
+ device_type = "pci";
+ linux,pci-domain = <1>;
+ #address-cells = <3>;
+ #size-cells = <2>;
+
+ reg = <0x0 0x1fa92000 0x0 0x1670>;
+ reg-names = "pcie-mac";
+
+ clocks = <&scuclk EN7523_CLK_PCIE>;
+ clock-names = "sys-ck";
+
+ phys = <&pciephy>;
+ phy-names = "pcie-phy";
+
+ ranges = <0x02000000 0 0x24000000 0x0 0x24000000 0 0x4000000>;
+
+ resets = <&scuclk AN7583_PCIE0_RST>,
+ <&scuclk AN7583_PCIE1_RST>;
+ reset-names = "phy-lane0", "phy-lane1";
+
+ interrupts = <GIC_SPI 40 IRQ_TYPE_LEVEL_HIGH>;
+ bus-range = <0x00 0xff>;
+ #interrupt-cells = <1>;
+ interrupt-map-mask = <0 0 0 7>;
+ interrupt-map = <0 0 0 1 &pcie_intc1 0>,
+ <0 0 0 2 &pcie_intc1 1>,
+ <0 0 0 3 &pcie_intc1 2>,
+ <0 0 0 4 &pcie_intc1 3>;
+
+ status = "disabled";
+
+ pcie_intc1: interrupt-controller {
+ interrupt-controller;
+ #address-cells = <0>;
+ #interrupt-cells = <1>;
+ };
+ };
+ };
+};
diff --git a/arch/arm/mach-airoha/Kconfig b/arch/arm/mach-airoha/Kconfig
index 4b0374001d0..72cd1454208 100644
--- a/arch/arm/mach-airoha/Kconfig
+++ b/arch/arm/mach-airoha/Kconfig
@@ -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.
+config TARGET_AN7583
+ bool "Airoha AN7583 SoC"
+ select ARM64
+ help
+ The Airoha AN7583 is a ARM-based SoC with a quad-core Cortex-A7
+ including NEON and GPU, Mali-450 graphics, several DDR3 options,
+ crypto engine, built-in Wi-Fi / Bluetooth combo chip, JPEG decoder,
+ video interfaces supporting HDMI and MIPI, and video codec support.
+ Peripherals include Gigabit Ethernet, switch, USB3.0 and OTG, PCIe,
+ I2S, PCM, S/PDIF, UART, SPI, I2C, IR TX/RX, and PWM.
+
endchoice
config SYS_SOC
default "en7523" if TARGET_EN7523
default "an7581" if TARGET_AN7581
+ default "an7583" if TARGET_AN7583
config SYS_BOARD
default "en7523" if TARGET_EN7523
default "an7581" if TARGET_AN7581
+ default "an7583" if TARGET_AN7583
config SYS_CONFIG_NAME
default "en7523" if TARGET_EN7523
default "an7581" if TARGET_AN7581
+ default "an7583" if TARGET_AN7583
endif
diff --git a/arch/arm/mach-airoha/Makefile b/arch/arm/mach-airoha/Makefile
index 91395b8a850..51d82ea3e21 100644
--- a/arch/arm/mach-airoha/Makefile
+++ b/arch/arm/mach-airoha/Makefile
@@ -4,3 +4,4 @@ obj-y += cpu.o
obj-$(CONFIG_TARGET_EN7523) += en7523/
obj-$(CONFIG_TARGET_AN7581) += an7581/
+obj-$(CONFIG_TARGET_AN7583) += an7583/
diff --git a/arch/arm/mach-airoha/an7583/Makefile b/arch/arm/mach-airoha/an7583/Makefile
new file mode 100644
index 00000000000..886ab7e4eb9
--- /dev/null
+++ b/arch/arm/mach-airoha/an7583/Makefile
@@ -0,0 +1,3 @@
+# SPDX-License-Identifier: GPL-2.0
+
+obj-y += init.o
diff --git a/arch/arm/mach-airoha/an7583/init.c b/arch/arm/mach-airoha/an7583/init.c
new file mode 100644
index 00000000000..18c5e101367
--- /dev/null
+++ b/arch/arm/mach-airoha/an7583/init.c
@@ -0,0 +1,66 @@
+// SPDX-License-Identifier: GPL-2.0
+
+#include <fdtdec.h>
+#include <init.h>
+#include <linux/sizes.h>
+#include <sysreset.h>
+#include <asm/armv8/mmu.h>
+#include <asm/global_data.h>
+#include <asm/system.h>
+
+DECLARE_GLOBAL_DATA_PTR;
+
+int print_cpuinfo(void)
+{
+ printf("CPU: Airoha AN7583\n");
+ return 0;
+}
+
+int dram_init(void)
+{
+ return fdtdec_setup_mem_size_base();
+}
+
+int dram_init_banksize(void)
+{
+ gd->dram[0].start = gd->ram_base;
+ gd->dram[0].size = get_effective_memsize();
+
+ if (gd->ram_size > SZ_2G) {
+ gd->dram[1].start = gd->ram_base + SZ_2G;
+ gd->dram[1].size = gd->ram_size - SZ_2G;
+ }
+
+ return 0;
+}
+
+void reset_cpu(void)
+{
+ psci_system_reset();
+}
+
+static struct mm_region an7583_mem_map[] = {
+ {
+ /* DDR, 32-bit area */
+ .virt = 0x80000000UL,
+ .phys = 0x80000000UL,
+ .size = SZ_2G,
+ .attrs = PTE_BLOCK_MEMTYPE(MT_NORMAL) | PTE_BLOCK_OUTER_SHARE,
+ }, {
+ /* DDR, 64-bit area */
+ .virt = 0x100000000UL,
+ .phys = 0x100000000UL,
+ .size = SZ_4G + SZ_2G,
+ .attrs = PTE_BLOCK_MEMTYPE(MT_NORMAL) | PTE_BLOCK_OUTER_SHARE,
+ }, {
+ .virt = 0x00000000UL,
+ .phys = 0x00000000UL,
+ .size = 0x40000000UL,
+ .attrs = PTE_BLOCK_MEMTYPE(MT_DEVICE_NGNRNE) |
+ PTE_BLOCK_NON_SHARE |
+ PTE_BLOCK_PXN | PTE_BLOCK_UXN
+ }, {
+ /* List terminator */
+ }
+};
+struct mm_region *mem_map = an7583_mem_map;
diff --git a/board/airoha/an7583/MAINTAINERS b/board/airoha/an7583/MAINTAINERS
new file mode 100644
index 00000000000..71ee542a8bc
--- /dev/null
+++ b/board/airoha/an7583/MAINTAINERS
@@ -0,0 +1,5 @@
+AN7581
+M: Christian Marangi <ansuelsmth@gmail.com>
+S: Maintained
+N: airoha
+N: an7583
diff --git a/board/airoha/an7583/Makefile b/board/airoha/an7583/Makefile
new file mode 100644
index 00000000000..d582684d1f7
--- /dev/null
+++ b/board/airoha/an7583/Makefile
@@ -0,0 +1,3 @@
+# SPDX-License-Identifier: GPL-2.0
+
+obj-y += an7583_rfb.o
diff --git a/board/airoha/an7583/an7583_rfb.c b/board/airoha/an7583/an7583_rfb.c
new file mode 100644
index 00000000000..aa73679d929
--- /dev/null
+++ b/board/airoha/an7583/an7583_rfb.c
@@ -0,0 +1,16 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Author: Christian Marangi <ansuelsmth@gmail.com>
+ */
+
+#include <asm/global_data.h>
+
+DECLARE_GLOBAL_DATA_PTR;
+
+int board_init(void)
+{
+ /* address of boot parameters */
+ gd->bd->bi_boot_params = CFG_SYS_SDRAM_BASE + 0x100;
+
+ return 0;
+}
diff --git a/configs/an7583_evb_defconfig b/configs/an7583_evb_defconfig
new file mode 100644
index 00000000000..16466be51b2
--- /dev/null
+++ b/configs/an7583_evb_defconfig
@@ -0,0 +1,79 @@
+CONFIG_ARM=y
+CONFIG_ARCH_AIROHA=y
+CONFIG_TARGET_AN7583=y
+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="an7583-evb"
+CONFIG_SYS_LOAD_ADDR=0x81800000
+CONFIG_BUILD_TARGET="u-boot.bin"
+# CONFIG_EFI_LOADER is not set
+CONFIG_FIT=y
+CONFIG_FIT_VERBOSE=y
+CONFIG_BOOTDELAY=3
+CONFIG_DEFAULT_FDT_FILE="an7583-evb"
+CONFIG_SYS_PBSIZE=1049
+CONFIG_SYS_CONSOLE_IS_IN_ENV=y
+# CONFIG_DISPLAY_BOARDINFO is not set
+CONFIG_HUSH_PARSER=y
+CONFIG_SYS_PROMPT="U-Boot> "
+CONFIG_SYS_MAXARGS=8
+CONFIG_CMD_BOOTZ=y
+CONFIG_CMD_BOOTMENU=y
+# CONFIG_CMD_ELF is not set
+# CONFIG_CMD_XIMG is not set
+CONFIG_CMD_BIND=y
+CONFIG_CMD_GPIO=y
+CONFIG_CMD_MMC=y
+CONFIG_CMD_MTD=y
+CONFIG_CMD_SF_TEST=y
+CONFIG_CMD_SPI=y
+# CONFIG_CMD_SETEXPR is not set
+CONFIG_CMD_PING=y
+CONFIG_CMD_EXT4=y
+CONFIG_CMD_FAT=y
+CONFIG_CMD_FS_GENERIC=y
+CONFIG_CMD_MTDPARTS=y
+CONFIG_CMD_LOG=y
+CONFIG_ENV_OVERWRITE=y
+CONFIG_ENV_IS_IN_MMC=y
+CONFIG_ENV_RELOC_GD_ENV_ADDR=y
+CONFIG_ENV_VARS_UBOOT_RUNTIME_CONFIG=y
+CONFIG_NET_RANDOM_ETHADDR=y
+CONFIG_SYS_RX_ETH_BUFFER=8
+CONFIG_SYSCON=y
+CONFIG_CLK=y
+CONFIG_DMA=y
+CONFIG_LED=y
+CONFIG_LED_GPIO=y
+CONFIG_MMC_HS200_SUPPORT=y
+CONFIG_MMC_MTK=y
+CONFIG_MTD=y
+CONFIG_DM_MTD=y
+CONFIG_MTD_SPI_NAND=y
+CONFIG_DM_SPI_FLASH=y
+CONFIG_SPI_FLASH_EON=y
+CONFIG_SPI_FLASH_GIGADEVICE=y
+CONFIG_SPI_FLASH_ISSI=y
+CONFIG_SPI_FLASH_MACRONIX=y
+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_PHY=y
+CONFIG_PINCTRL=y
+CONFIG_PINCTRL_AIROHA_AN7583=y
+CONFIG_POWER_DOMAIN=y
+CONFIG_DM_REGULATOR=y
+CONFIG_DM_REGULATOR_FIXED=y
+CONFIG_RAM=y
+CONFIG_DM_SERIAL=y
+CONFIG_SYS_NS16550=y
+CONFIG_SPI=y
+CONFIG_DM_SPI=y
+CONFIG_AIROHA_SNFI_SPI=y
+CONFIG_SHA512=y
diff --git a/include/configs/an7583.h b/include/configs/an7583.h
new file mode 100644
index 00000000000..c865afea1a2
--- /dev/null
+++ b/include/configs/an7583.h
@@ -0,0 +1,19 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Configuration for Airoha AN7583
+ */
+
+#ifndef __AN7583_H
+#define __AN7583_H
+
+#include <linux/sizes.h>
+
+#define CFG_SYS_UBOOT_BASE CONFIG_TEXT_BASE
+
+#define CFG_SYS_INIT_RAM_ADDR CONFIG_TEXT_BASE
+#define CFG_SYS_INIT_RAM_SIZE SZ_2M
+
+/* DRAM */
+#define CFG_SYS_SDRAM_BASE 0x80000000
+
+#endif
--
2.53.0
^ permalink raw reply related [flat|nested] 20+ messages in thread
* [PATCH v2 02/16] arm: airoha: introduce AN7583 helpers to get SCU and CHIP_SCU regmaps
2026-09-02 8:52 [PATCH v2 00/16] arm: airoha: add AN7583 SoC support Mikhail Kshevetskiy
2026-09-02 8:52 ` [PATCH v2 01/16] airoha: add support for Airoha AN7583 SoC Mikhail Kshevetskiy
@ 2026-09-02 8:52 ` Mikhail Kshevetskiy
2026-09-02 8:52 ` [PATCH v2 03/16] dt-bindings: clock: airoha: Document support for AN7583 clock Mikhail Kshevetskiy
` (13 subsequent siblings)
15 siblings, 0 replies; 20+ messages in thread
From: Mikhail Kshevetskiy @ 2026-09-02 8:52 UTC (permalink / raw)
To: Tom Rini, Ilias Apalodimas, Christian Marangi, Lukasz Majewski,
Jerome Forissier, Sumit Garg, Simon Glass, Wayen Yan,
Quentin Schulz, Johan Jonker, Julien Stephan, u-boot
Cc: Mikhail Kshevetskiy
We need access SCU and CHIP_SCU regmaps in several places (clk-airoha,
reset-airoha, airoha_eth). Unfortunately these regmaps can't be easily
retrieved with a common code, because of different Airoha SoCs uses
a different dts structure.
To make life easy we can write a commonly named SoC specific helpers
for these tasks. This patch implements helpers for Airoha AN7583 SoC.
Signed-off-by: Mikhail Kshevetskiy <mikhail.kshevetskiy@iopsys.eu>
---
arch/arm/include/asm/arch-an7583 | 1 +
arch/arm/mach-airoha/an7583/Makefile | 1 +
arch/arm/mach-airoha/an7583/scu-regmap.c | 34 ++++++++++++++++++++++++
3 files changed, 36 insertions(+)
create mode 120000 arch/arm/include/asm/arch-an7583
create mode 100644 arch/arm/mach-airoha/an7583/scu-regmap.c
diff --git a/arch/arm/include/asm/arch-an7583 b/arch/arm/include/asm/arch-an7583
new file mode 120000
index 00000000000..d2317ed3bc3
--- /dev/null
+++ b/arch/arm/include/asm/arch-an7583
@@ -0,0 +1 @@
+arch-airoha
\ No newline at end of file
diff --git a/arch/arm/mach-airoha/an7583/Makefile b/arch/arm/mach-airoha/an7583/Makefile
index 886ab7e4eb9..51f978aa101 100644
--- a/arch/arm/mach-airoha/an7583/Makefile
+++ b/arch/arm/mach-airoha/an7583/Makefile
@@ -1,3 +1,4 @@
# SPDX-License-Identifier: GPL-2.0
obj-y += init.o
+obj-y += scu-regmap.o
diff --git a/arch/arm/mach-airoha/an7583/scu-regmap.c b/arch/arm/mach-airoha/an7583/scu-regmap.c
new file mode 100644
index 00000000000..96f3564eec0
--- /dev/null
+++ b/arch/arm/mach-airoha/an7583/scu-regmap.c
@@ -0,0 +1,34 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Author: Mikhail Kshevetskiy <mikhail.kshevetskiy@iopsys.eu>
+ */
+
+#include <syscon.h>
+#include <linux/err.h>
+#include <asm/arch/scu-regmap.h>
+
+struct regmap *airoha_get_scu_regmap(void)
+{
+ ofnode node;
+
+ node = ofnode_by_compatible(ofnode_null(), "airoha,an7583-scu");
+ if (!ofnode_valid(node))
+ return ERR_PTR(-EINVAL);
+
+ node = ofnode_get_parent(node);
+ if (!ofnode_valid(node))
+ return ERR_PTR(-EINVAL);
+
+ return syscon_node_to_regmap(node);
+}
+
+struct regmap *airoha_get_chip_scu_regmap(void)
+{
+ ofnode node;
+
+ node = ofnode_by_compatible(ofnode_null(), "airoha,en7581-chip-scu");
+ if (!ofnode_valid(node))
+ return ERR_PTR(-EINVAL);
+
+ return syscon_node_to_regmap(node);
+}
--
2.53.0
^ permalink raw reply related [flat|nested] 20+ messages in thread
* [PATCH v2 03/16] dt-bindings: clock: airoha: Document support for AN7583 clock
2026-09-02 8:52 [PATCH v2 00/16] arm: airoha: add AN7583 SoC support Mikhail Kshevetskiy
2026-09-02 8:52 ` [PATCH v2 01/16] airoha: add support for Airoha AN7583 SoC Mikhail Kshevetskiy
2026-09-02 8:52 ` [PATCH v2 02/16] arm: airoha: introduce AN7583 helpers to get SCU and CHIP_SCU regmaps Mikhail Kshevetskiy
@ 2026-09-02 8:52 ` Mikhail Kshevetskiy
2026-09-02 16:22 ` Tom Rini
2026-09-02 8:52 ` [PATCH v2 04/16] clk: airoha: add support for Airoha AN7583 SoC clock Mikhail Kshevetskiy
` (12 subsequent siblings)
15 siblings, 1 reply; 20+ messages in thread
From: Mikhail Kshevetskiy @ 2026-09-02 8:52 UTC (permalink / raw)
To: Tom Rini, Ilias Apalodimas, Christian Marangi, Lukasz Majewski,
Jerome Forissier, Sumit Garg, Simon Glass, Wayen Yan,
Quentin Schulz, Johan Jonker, Julien Stephan, u-boot
Cc: Mikhail Kshevetskiy
From: Christian Marangi <ansuelsmth@gmail.com>
Document support for Airoha AN7583 clock. This is based on the EN7523
clock schema with the new requirement of the "airoha,chip-scu"
(previously optional for EN7581).
Add additional binding for additional clock and reset lines.
Signed-off-by: Christian Marangi <ansuelsmth@gmail.com>
---
dts/upstream/include/dt-bindings/clock/en7523-clk.h | 3 +++
1 file changed, 3 insertions(+)
diff --git a/dts/upstream/include/dt-bindings/clock/en7523-clk.h b/dts/upstream/include/dt-bindings/clock/en7523-clk.h
index edfa64045f5..0fbbcb7b1b2 100644
--- a/dts/upstream/include/dt-bindings/clock/en7523-clk.h
+++ b/dts/upstream/include/dt-bindings/clock/en7523-clk.h
@@ -14,4 +14,7 @@
#define EN7581_CLK_EMMC 8
+#define AN7583_CLK_MDIO0 9
+#define AN7583_CLK_MDIO1 10
+
#endif /* _DT_BINDINGS_CLOCK_AIROHA_EN7523_H_ */
--
2.53.0
^ permalink raw reply related [flat|nested] 20+ messages in thread
* [PATCH v2 04/16] clk: airoha: add support for Airoha AN7583 SoC clock
2026-09-02 8:52 [PATCH v2 00/16] arm: airoha: add AN7583 SoC support Mikhail Kshevetskiy
` (2 preceding siblings ...)
2026-09-02 8:52 ` [PATCH v2 03/16] dt-bindings: clock: airoha: Document support for AN7583 clock Mikhail Kshevetskiy
@ 2026-09-02 8:52 ` Mikhail Kshevetskiy
2026-09-02 8:53 ` [PATCH v2 05/16] reset: airoha: Add support for Airoha AN7583 reset Mikhail Kshevetskiy
` (11 subsequent siblings)
15 siblings, 0 replies; 20+ messages in thread
From: Mikhail Kshevetskiy @ 2026-09-02 8:52 UTC (permalink / raw)
To: Tom Rini, Ilias Apalodimas, Christian Marangi, Lukasz Majewski,
Jerome Forissier, Sumit Garg, Simon Glass, Wayen Yan,
Quentin Schulz, Johan Jonker, Julien Stephan, u-boot
Cc: Mikhail Kshevetskiy
From: Christian Marangi <ansuelsmth@gmail.com>
Add support for Airoha AN7583 SoC clock that implement more base values
for clocks compared to AN7581.
Signed-off-by: Christian Marangi <ansuelsmth@gmail.com>
---
drivers/clk/airoha/clk-airoha.c | 158 ++++++++++++++++++++++++++++++++
1 file changed, 158 insertions(+)
diff --git a/drivers/clk/airoha/clk-airoha.c b/drivers/clk/airoha/clk-airoha.c
index 89a8b4cb1cf..23cb04aa5ef 100644
--- a/drivers/clk/airoha/clk-airoha.c
+++ b/drivers/clk/airoha/clk-airoha.c
@@ -36,6 +36,7 @@
#define EN7523_MAX_CLKS 8
#define EN7581_MAX_CLKS 9
+#define EN7583_MAX_CLKS 11
struct airoha_clk_desc {
int id;
@@ -78,6 +79,14 @@ static const u32 bus7581_base[] = { 600000000, 540000000 };
static const u32 npu7581_base[] = { 800000000, 750000000, 720000000, 600000000 };
static const u32 crypto_base[] = { 540000000, 480000000 };
static const u32 emmc7581_base[] = { 200000000, 150000000 };
+/* AN7583 */
+static const u32 gsw7583_base[] = { 540672000, 270336000, 400000000, 200000000 };
+static const u32 emi7583_base[] = { 540672000, 480000000, 400000000, 300000000 };
+static const u32 bus7583_base[] = { 600000000, 540672000, 480000000, 400000000 };
+static const u32 spi7583_base[] = { 400000000, 12500000 };
+static const u32 npu7583_base[] = { 666000000, 800000000, 720000000, 600000000 };
+static const u32 crypto7583_base[] = { 540672000, 400000000 };
+static const u32 emmc7583_base[] = { 150000000, 200000000 };
static const struct airoha_clk_desc en7523_base_clks[EN7523_MAX_CLKS] = {
[EN7523_CLK_GSW] = {
@@ -293,6 +302,147 @@ static const struct airoha_clk_desc en7581_base_clks[EN7581_MAX_CLKS] = {
}
};
+static const struct airoha_clk_desc an7583_base_clks[EN7583_MAX_CLKS] = {
+ [EN7523_CLK_GSW] = {
+ .id = EN7523_CLK_GSW,
+ .name = "gsw",
+
+ .base_reg = REG_GSW_CLK_DIV_SEL,
+ .base_bits = 2,
+ .base_shift = 8,
+ .base_values = gsw7583_base,
+ .n_base_values = ARRAY_SIZE(gsw7583_base),
+
+ .div_bits = 3,
+ .div_shift = 0,
+ .div_step = 1,
+ .div_offset = 1,
+ },
+ [EN7523_CLK_EMI] = {
+ .id = EN7523_CLK_EMI,
+ .name = "emi",
+
+ .base_reg = REG_EMI_CLK_DIV_SEL,
+ .base_bits = 2,
+ .base_shift = 8,
+ .base_values = emi7583_base,
+ .n_base_values = ARRAY_SIZE(emi7583_base),
+
+ .div_bits = 3,
+ .div_shift = 0,
+ .div_step = 1,
+ .div_offset = 1,
+ },
+ [EN7523_CLK_BUS] = {
+ .id = EN7523_CLK_BUS,
+ .name = "bus",
+
+ .base_reg = REG_BUS_CLK_DIV_SEL,
+ .base_bits = 2,
+ .base_shift = 8,
+ .base_values = bus7583_base,
+ .n_base_values = ARRAY_SIZE(bus7583_base),
+
+ .div_bits = 3,
+ .div_shift = 0,
+ .div_step = 1,
+ .div_offset = 1,
+ },
+ [EN7523_CLK_SLIC] = {
+ .id = EN7523_CLK_SLIC,
+ .name = "slic",
+
+ .base_reg = REG_SPI_CLK_FREQ_SEL,
+ .base_bits = 1,
+ .base_shift = 1,
+ .base_values = slic_base,
+ .n_base_values = ARRAY_SIZE(slic_base),
+
+ .div_reg = REG_SPI_CLK_DIV_SEL,
+ .div_bits = 5,
+ .div_shift = 24,
+ .div_val0 = 20,
+ .div_step = 2,
+ },
+ [EN7523_CLK_SPI] = {
+ .id = EN7523_CLK_SPI,
+ .name = "spi",
+
+ .base_reg = REG_SPI_CLK_FREQ_SEL,
+ .base_bits = 1,
+ .base_shift = 0,
+ .base_values = spi7583_base,
+ .n_base_values = ARRAY_SIZE(spi7583_base),
+
+ .div_reg = REG_SPI_CLK_DIV_SEL,
+ .div_bits = 5,
+ .div_shift = 8,
+ .div_val0 = 40,
+ .div_step = 2,
+ },
+ [EN7523_CLK_NPU] = {
+ .id = EN7523_CLK_NPU,
+ .name = "npu",
+
+ .base_reg = REG_NPU_CLK_DIV_SEL,
+ .base_bits = 2,
+ .base_shift = 9,
+ .base_values = npu7583_base,
+ .n_base_values = ARRAY_SIZE(npu7583_base),
+
+ .div_bits = 3,
+ .div_shift = 0,
+ .div_step = 1,
+ .div_offset = 1,
+ },
+ [EN7523_CLK_CRYPTO] = {
+ .id = EN7523_CLK_CRYPTO,
+ .name = "crypto",
+
+ .base_reg = REG_CRYPTO_CLKSRC2,
+ .base_bits = 1,
+ .base_shift = 0,
+ .base_values = crypto7583_base,
+ .n_base_values = ARRAY_SIZE(crypto7583_base),
+ },
+ [EN7581_CLK_EMMC] = {
+ .id = EN7581_CLK_EMMC,
+ .name = "emmc",
+
+ .base_reg = REG_CRYPTO_CLKSRC2,
+ .base_bits = 1,
+ .base_shift = 13,
+ .base_values = emmc7583_base,
+ .n_base_values = ARRAY_SIZE(emmc7583_base),
+ },
+ [AN7583_CLK_MDIO0] = {
+ .id = AN7583_CLK_MDIO0,
+ .name = "mdio0",
+
+ .base_reg = REG_CRYPTO_CLKSRC2,
+
+ .base_value = 25000000,
+
+ .div_bits = 4,
+ .div_shift = 15,
+ .div_step = 1,
+ .div_offset = 1,
+ },
+ [AN7583_CLK_MDIO1] = {
+ .id = AN7583_CLK_MDIO1,
+ .name = "mdio1",
+
+ .base_reg = REG_CRYPTO_CLKSRC2,
+
+ .base_value = 25000000,
+
+ .div_bits = 4,
+ .div_shift = 19,
+ .div_step = 1,
+ .div_offset = 1,
+ }
+};
+
static u32 airoha_clk_get_base_rate(const struct airoha_clk_desc *desc, u32 val)
{
if (!desc->base_bits)
@@ -542,6 +692,11 @@ static const struct airoha_clk_soc_data en7581_data = {
.descs = en7581_base_clks,
};
+static const struct airoha_clk_soc_data an7583_data = {
+ .num_clocks = ARRAY_SIZE(an7583_base_clks),
+ .descs = an7583_base_clks,
+};
+
static const struct udevice_id airoha_clk_ids[] = {
{ .compatible = "airoha,en7523-scu",
.data = (ulong)&en7523_data,
@@ -549,6 +704,9 @@ static const struct udevice_id airoha_clk_ids[] = {
{ .compatible = "airoha,en7581-scu",
.data = (ulong)&en7581_data,
},
+ { .compatible = "airoha,an7583-scu",
+ .data = (ulong)&an7583_data,
+ },
{ }
};
--
2.53.0
^ permalink raw reply related [flat|nested] 20+ messages in thread
* [PATCH v2 05/16] reset: airoha: Add support for Airoha AN7583 reset
2026-09-02 8:52 [PATCH v2 00/16] arm: airoha: add AN7583 SoC support Mikhail Kshevetskiy
` (3 preceding siblings ...)
2026-09-02 8:52 ` [PATCH v2 04/16] clk: airoha: add support for Airoha AN7583 SoC clock Mikhail Kshevetskiy
@ 2026-09-02 8:53 ` Mikhail Kshevetskiy
2026-09-02 16:24 ` Tom Rini
2026-09-02 8:53 ` [PATCH v2 06/16] net: airoha: add support for Airoha AN7583 Mikhail Kshevetskiy
` (10 subsequent siblings)
15 siblings, 1 reply; 20+ messages in thread
From: Mikhail Kshevetskiy @ 2026-09-02 8:53 UTC (permalink / raw)
To: Tom Rini, Ilias Apalodimas, Christian Marangi, Lukasz Majewski,
Jerome Forissier, Sumit Garg, Simon Glass, Wayen Yan,
Quentin Schulz, Johan Jonker, Julien Stephan, u-boot
Cc: Mikhail Kshevetskiy
From: Christian Marangi <ansuelsmth@gmail.com>
Adapt the Airoha reset driver to support Airoha AN7583 node structure.
In AN7583 the register is exposed by the parent syscon hence a different
logic needs to be applied. Also the reset line differ from AN7581 hence
a dedicated table is needed.
Signed-off-by: Christian Marangi <ansuelsmth@gmail.com>
---
drivers/reset/reset-airoha.c | 60 ++++++++++++++++++
.../dt-bindings/reset/airoha,an7583-reset.h | 62 +++++++++++++++++++
2 files changed, 122 insertions(+)
create mode 100644 include/dt-bindings/reset/airoha,an7583-reset.h
diff --git a/drivers/reset/reset-airoha.c b/drivers/reset/reset-airoha.c
index ef8c47a067b..071f29b6f22 100644
--- a/drivers/reset/reset-airoha.c
+++ b/drivers/reset/reset-airoha.c
@@ -15,6 +15,7 @@
#include <dt-bindings/reset/airoha,en7523-reset.h>
#include <dt-bindings/reset/airoha,en7581-reset.h>
+#include <dt-bindings/reset/airoha,an7583-reset.h>
#define RST_NR_PER_BANK 32
@@ -138,6 +139,60 @@ static const u16 en7581_rst_map[] = {
[EN7581_XPON_MAC_RST] = RST_NR_PER_BANK + 31,
};
+static const u16 an7583_rst_map[] = {
+ /* RST_CTRL2 */
+ [AN7583_XPON_PHY_RST] = 0,
+ [AN7583_GPON_OLT_RST] = 1,
+ [AN7583_CPU_TIMER2_RST] = 2,
+ [AN7583_HSUART_RST] = 3,
+ [AN7583_UART4_RST] = 4,
+ [AN7583_UART5_RST] = 5,
+ [AN7583_I2C2_RST] = 6,
+ [AN7583_XSI_MAC_RST] = 7,
+ [AN7583_XSI_PHY_RST] = 8,
+ [AN7583_NPU_RST] = 9,
+ [AN7583_TRNG_MSTART_RST] = 12,
+ [AN7583_DUAL_HSI0_RST] = 13,
+ [AN7583_DUAL_HSI1_RST] = 14,
+ [AN7583_DUAL_HSI0_MAC_RST] = 16,
+ [AN7583_DUAL_HSI1_MAC_RST] = 17,
+ [AN7583_XPON_XFI_RST] = 18,
+ [AN7583_WDMA_RST] = 19,
+ [AN7583_WOE0_RST] = 20,
+ [AN7583_HSDMA_RST] = 22,
+ [AN7583_TDMA_RST] = 24,
+ [AN7583_EMMC_RST] = 25,
+ [AN7583_SOE_RST] = 26,
+ [AN7583_XFP_MAC_RST] = 28,
+ [AN7583_MDIO0] = 30,
+ [AN7583_MDIO1] = 31,
+ /* RST_CTRL1 */
+ [AN7583_PCM1_ZSI_ISI_RST] = RST_NR_PER_BANK + 0,
+ [AN7583_FE_PDMA_RST] = RST_NR_PER_BANK + 1,
+ [AN7583_FE_QDMA_RST] = RST_NR_PER_BANK + 2,
+ [AN7583_PCM_SPIWP_RST] = RST_NR_PER_BANK + 4,
+ [AN7583_CRYPTO_RST] = RST_NR_PER_BANK + 6,
+ [AN7583_TIMER_RST] = RST_NR_PER_BANK + 8,
+ [AN7583_PCM1_RST] = RST_NR_PER_BANK + 11,
+ [AN7583_UART_RST] = RST_NR_PER_BANK + 12,
+ [AN7583_GPIO_RST] = RST_NR_PER_BANK + 13,
+ [AN7583_GDMA_RST] = RST_NR_PER_BANK + 14,
+ [AN7583_I2C_MASTER_RST] = RST_NR_PER_BANK + 16,
+ [AN7583_PCM2_ZSI_ISI_RST] = RST_NR_PER_BANK + 17,
+ [AN7583_SFC_RST] = RST_NR_PER_BANK + 18,
+ [AN7583_UART2_RST] = RST_NR_PER_BANK + 19,
+ [AN7583_GDMP_RST] = RST_NR_PER_BANK + 20,
+ [AN7583_FE_RST] = RST_NR_PER_BANK + 21,
+ [AN7583_USB_HOST_P0_RST] = RST_NR_PER_BANK + 22,
+ [AN7583_GSW_RST] = RST_NR_PER_BANK + 23,
+ [AN7583_SFC2_PCM_RST] = RST_NR_PER_BANK + 25,
+ [AN7583_PCIE0_RST] = RST_NR_PER_BANK + 26,
+ [AN7583_PCIE1_RST] = RST_NR_PER_BANK + 27,
+ [AN7583_CPU_TIMER_RST] = RST_NR_PER_BANK + 28,
+ [AN7583_PCIE_HB_RST] = RST_NR_PER_BANK + 29,
+ [AN7583_XPON_MAC_RST] = RST_NR_PER_BANK + 31,
+};
+
static int airoha_reset_update(struct airoha_reset_priv *priv,
unsigned long id, bool assert)
{
@@ -227,6 +282,11 @@ static int airoha_reset_probe(struct udevice *dev)
return reset_init(dev, en7581_rst_map,
ARRAY_SIZE(en7581_rst_map));
+ if (ofnode_device_is_compatible(dev_ofnode(dev),
+ "airoha,an7583-scu"))
+ return reset_init(dev, an7583_rst_map,
+ ARRAY_SIZE(an7583_rst_map));
+
return -ENODEV;
}
diff --git a/include/dt-bindings/reset/airoha,an7583-reset.h b/include/dt-bindings/reset/airoha,an7583-reset.h
new file mode 100644
index 00000000000..be80d0e0bf5
--- /dev/null
+++ b/include/dt-bindings/reset/airoha,an7583-reset.h
@@ -0,0 +1,62 @@
+/* SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) */
+/*
+ * Copyright (c) 2024 AIROHA Inc
+ * Author: Christian Marangi <ansuelsmth@gmail.com>
+ */
+
+#ifndef __DT_BINDINGS_RESET_CONTROLLER_AIROHA_AN7583_H_
+#define __DT_BINDINGS_RESET_CONTROLLER_AIROHA_AN7583_H_
+
+/* RST_CTRL2 */
+#define AN7583_XPON_PHY_RST 0
+#define AN7583_GPON_OLT_RST 1
+#define AN7583_CPU_TIMER2_RST 2
+#define AN7583_HSUART_RST 3
+#define AN7583_UART4_RST 4
+#define AN7583_UART5_RST 5
+#define AN7583_I2C2_RST 6
+#define AN7583_XSI_MAC_RST 7
+#define AN7583_XSI_PHY_RST 8
+#define AN7583_NPU_RST 9
+#define AN7583_TRNG_MSTART_RST 10
+#define AN7583_DUAL_HSI0_RST 11
+#define AN7583_DUAL_HSI1_RST 12
+#define AN7583_DUAL_HSI0_MAC_RST 13
+#define AN7583_DUAL_HSI1_MAC_RST 14
+#define AN7583_XPON_XFI_RST 15
+#define AN7583_WDMA_RST 16
+#define AN7583_WOE0_RST 17
+#define AN7583_HSDMA_RST 18
+#define AN7583_TDMA_RST 19
+#define AN7583_EMMC_RST 20
+#define AN7583_SOE_RST 21
+#define AN7583_XFP_MAC_RST 22
+#define AN7583_MDIO0 23
+#define AN7583_MDIO1 24
+/* RST_CTRL1 */
+#define AN7583_PCM1_ZSI_ISI_RST 25
+#define AN7583_FE_PDMA_RST 26
+#define AN7583_FE_QDMA_RST 27
+#define AN7583_PCM_SPIWP_RST 28
+#define AN7583_CRYPTO_RST 29
+#define AN7583_TIMER_RST 30
+#define AN7583_PCM1_RST 31
+#define AN7583_UART_RST 32
+#define AN7583_GPIO_RST 33
+#define AN7583_GDMA_RST 34
+#define AN7583_I2C_MASTER_RST 35
+#define AN7583_PCM2_ZSI_ISI_RST 36
+#define AN7583_SFC_RST 37
+#define AN7583_UART2_RST 38
+#define AN7583_GDMP_RST 39
+#define AN7583_FE_RST 40
+#define AN7583_USB_HOST_P0_RST 41
+#define AN7583_GSW_RST 42
+#define AN7583_SFC2_PCM_RST 43
+#define AN7583_PCIE0_RST 44
+#define AN7583_PCIE1_RST 45
+#define AN7583_CPU_TIMER_RST 46
+#define AN7583_PCIE_HB_RST 47
+#define AN7583_XPON_MAC_RST 48
+
+#endif /* __DT_BINDINGS_RESET_CONTROLLER_AIROHA_AN7583_H_ */
--
2.53.0
^ permalink raw reply related [flat|nested] 20+ messages in thread
* [PATCH v2 06/16] net: airoha: add support for Airoha AN7583
2026-09-02 8:52 [PATCH v2 00/16] arm: airoha: add AN7583 SoC support Mikhail Kshevetskiy
` (4 preceding siblings ...)
2026-09-02 8:53 ` [PATCH v2 05/16] reset: airoha: Add support for Airoha AN7583 reset Mikhail Kshevetskiy
@ 2026-09-02 8:53 ` Mikhail Kshevetskiy
2026-09-02 8:53 ` [PATCH v2 07/16] airoha: add Ethernet node in AN7583 dtsi Mikhail Kshevetskiy
` (9 subsequent siblings)
15 siblings, 0 replies; 20+ messages in thread
From: Mikhail Kshevetskiy @ 2026-09-02 8:53 UTC (permalink / raw)
To: Tom Rini, Ilias Apalodimas, Christian Marangi, Lukasz Majewski,
Jerome Forissier, Sumit Garg, Simon Glass, Wayen Yan,
Quentin Schulz, Johan Jonker, Julien Stephan, u-boot
Cc: Mikhail Kshevetskiy
From: Christian Marangi <ansuelsmth@gmail.com>
Add support for Ethernet controller present in Airoha AN7583. This
follow the same implementation of Airoha AN7581 with the only difference
of having a different reset number and a different logic to reach the
SCU node.
Generalize the driver for these 2 part to account for these minor
difference.
The switch init part also required some care as the Switch Internal PHY
enable BMCR_PDOWN by default and tweak to GEPHY_CONN_CFG is also needed.
Signed-off-by: Christian Marangi <ansuelsmth@gmail.com>
---
drivers/net/airoha_eth.c | 94 ++++++++++++++++++++++++++++++++++++++++
1 file changed, 94 insertions(+)
diff --git a/drivers/net/airoha_eth.c b/drivers/net/airoha_eth.c
index e5d39b95cc5..d552b9e9de9 100644
--- a/drivers/net/airoha_eth.c
+++ b/drivers/net/airoha_eth.c
@@ -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>
@@ -34,6 +35,11 @@
#define AIROHA_MAX_NUM_RSTS 3
#define AIROHA_MAX_NUM_XSI_RSTS 4
+#define AIROHA_MAX_NUM_SWITCH_PORT 4
+#define AIROHA_MAX_PBUS_TRY 10
+#define AIROHA_PBUS_SLEEP 100
+#define AIROHA_PBUS_C22_MASK 0x800000
+
#define AIROHA_MAX_PACKET_SIZE 2048
#define AIROHA_NUM_TX_RING 1
#define AIROHA_NUM_RX_RING 1
@@ -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)
+#define SWITCH_GEPHY_CONN_CFG 0x7c14
+#define SWITCH_DPHY_CKIN_SEL BIT(31)
+#define SWITCH_PHY_CORE_REG_CLK_SEL BIT(30)
+#define SWITCH_ETHER_AFE_PWD GENMASK(28, 24)
+#define SWITCH_PBUS_PHY_IAC 0x7c20
+#define SWITCH_PBUS_PHY_START BIT(31)
+#define SWITCH_PBUS_PHY_CMD BIT(30)
+#define SWITCH_PBUS_PHY_CMD_READ FIELD_PREP(SWITCH_PBUS_PHY_CMD, 0x0)
+#define SWITCH_PBUS_PHY_CMD_WRITE FIELD_PREP(SWITCH_PBUS_PHY_CMD, 0x1)
+#define SWITCH_PBUS_PHY_PORTADDR GENMASK(28, 24)
+#define SWITCH_PBUS_PHY_REGADDR GENMASK(23, 0)
+#define SWITCH_PBUS_PHY_IAWD 0x7c24
+#define SWITCH_PBUS_PHY_IARD 0x7c28
/* FE */
#define PSE_BASE 0x0100
@@ -365,6 +384,12 @@ static const char * const en7581_xsi_rsts_names[] = {
"xfp-mac",
};
+static const char * const an7583_xsi_rsts_names[] = {
+ "hsi0-mac",
+ "hsi1-mac",
+ "xfp-mac",
+};
+
static u32 airoha_rr(void __iomem *base, u32 offset)
{
return readl(base + offset);
@@ -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)
+#define airoha_switch_rr(eth, offset) \
+ airoha_rr((eth)->switch_regs, (offset))
#define airoha_switch_wr(eth, offset, val) \
airoha_wr((eth)->switch_regs, (offset), (val))
+#define airoha_switch_rmw(eth, offset, mask, val) \
+ airoha_rmw((eth)->switch_regs, (offset), (mask), (val))
static inline dma_addr_t dma_map_unaligned(void *vaddr, size_t len,
enum dma_data_direction dir)
@@ -438,6 +467,8 @@ static int airoha_get_fe_port(struct airoha_gdm_port *port)
case 0x7523:
/* FIXME: GDM1 is the only supported port */
return FE_PSE_PORT_GDM1;
+ case 0x7583:
+ return port->id == 3 ? FE_PSE_PORT_GDM3 : port->id;
case 0x7581:
default:
return port->id == 4 ? FE_PSE_PORT_GDM4 : port->id;
@@ -809,6 +840,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));
+ /* AN7583 require tweak to GEPHY_CONN_CFG and clear PHY BMCR_PDOWN */
+ if (!strcmp(data->switch_compatible, "airoha,an7583-switch")) {
+ int i;
+
+ airoha_switch_rmw(eth, SWITCH_GEPHY_CONN_CFG,
+ SWITCH_DPHY_CKIN_SEL |
+ SWITCH_PHY_CORE_REG_CLK_SEL |
+ SWITCH_ETHER_AFE_PWD,
+ SWITCH_DPHY_CKIN_SEL |
+ SWITCH_PHY_CORE_REG_CLK_SEL |
+ FIELD_PREP(SWITCH_ETHER_AFE_PWD, 0));
+
+ /* Disable BMCR_PDOWN for every PHY */
+ for (i = 0; i < AIROHA_MAX_NUM_SWITCH_PORT; i++) {
+ int try;
+ u32 val;
+
+ airoha_switch_wr(eth, SWITCH_PBUS_PHY_IAC,
+ SWITCH_PBUS_PHY_START |
+ SWITCH_PBUS_PHY_CMD_READ |
+ FIELD_PREP(SWITCH_PBUS_PHY_PORTADDR, i) |
+ FIELD_PREP(SWITCH_PBUS_PHY_REGADDR,
+ AIROHA_PBUS_C22_MASK | MII_BMCR));
+
+ for (try = 0; try < AIROHA_MAX_PBUS_TRY; try++) {
+ val = airoha_switch_rr(eth, SWITCH_PBUS_PHY_IAC);
+ if (!(val & SWITCH_PBUS_PHY_START))
+ break;
+
+ udelay(AIROHA_PBUS_SLEEP);
+ }
+
+ val = airoha_switch_rr(eth, SWITCH_PBUS_PHY_IARD);
+ val &= ~BMCR_PDOWN;
+
+ airoha_switch_wr(eth, SWITCH_PBUS_PHY_IAWD, val);
+ airoha_switch_wr(eth, SWITCH_PBUS_PHY_IAC,
+ SWITCH_PBUS_PHY_START |
+ SWITCH_PBUS_PHY_CMD_WRITE |
+ FIELD_PREP(SWITCH_PBUS_PHY_PORTADDR, i) |
+ FIELD_PREP(SWITCH_PBUS_PHY_REGADDR,
+ AIROHA_PBUS_C22_MASK | MII_BMCR));
+
+ for (try = 0; try < AIROHA_MAX_PBUS_TRY; try++) {
+ val = airoha_switch_rr(eth, SWITCH_PBUS_PHY_IAC);
+ if (!(val & SWITCH_PBUS_PHY_START))
+ break;
+
+ udelay(AIROHA_PBUS_SLEEP);
+ }
+ }
+ }
+
return 0;
}
@@ -1269,6 +1353,13 @@ static const struct airoha_eth_soc_data en7581_data = {
.switch_compatible = "airoha,en7581-switch",
};
+static const struct airoha_eth_soc_data an7583_data = {
+ .version = 0x7583,
+ .xsi_rsts_names = an7583_xsi_rsts_names,
+ .num_xsi_rsts = ARRAY_SIZE(an7583_xsi_rsts_names),
+ .switch_compatible = "airoha,an7583-switch",
+};
+
static const struct udevice_id airoha_eth_ids[] = {
{ .compatible = "airoha,en7523-eth",
.data = (ulong)&en7523_data,
@@ -1276,6 +1367,9 @@ static const struct udevice_id airoha_eth_ids[] = {
{ .compatible = "airoha,en7581-eth",
.data = (ulong)&en7581_data,
},
+ { .compatible = "airoha,an7583-eth",
+ .data = (ulong)&an7583_data,
+ },
{ }
};
--
2.53.0
^ permalink raw reply related [flat|nested] 20+ messages in thread
* [PATCH v2 07/16] airoha: add Ethernet node in AN7583 dtsi
2026-09-02 8:52 [PATCH v2 00/16] arm: airoha: add AN7583 SoC support Mikhail Kshevetskiy
` (5 preceding siblings ...)
2026-09-02 8:53 ` [PATCH v2 06/16] net: airoha: add support for Airoha AN7583 Mikhail Kshevetskiy
@ 2026-09-02 8:53 ` Mikhail Kshevetskiy
2026-09-02 8:53 ` [PATCH v2 08/16] airoha: add MMC node for Airoha AN7583 Mikhail Kshevetskiy
` (8 subsequent siblings)
15 siblings, 0 replies; 20+ messages in thread
From: Mikhail Kshevetskiy @ 2026-09-02 8:53 UTC (permalink / raw)
To: Tom Rini, Ilias Apalodimas, Christian Marangi, Lukasz Majewski,
Jerome Forissier, Sumit Garg, Simon Glass, Wayen Yan,
Quentin Schulz, Johan Jonker, Julien Stephan, u-boot
Cc: Mikhail Kshevetskiy
From: Christian Marangi <ansuelsmth@gmail.com>
Add Ethernet node in AN7583 dtsi to add support for the integrated
Ethernet Controller.
Signed-off-by: Christian Marangi <ansuelsmth@gmail.com>
---
arch/arm/dts/an7583.dtsi | 23 +++++++++++++++++++++++
1 file changed, 23 insertions(+)
diff --git a/arch/arm/dts/an7583.dtsi b/arch/arm/dts/an7583.dtsi
index 9362d2fbedf..d67b7459870 100644
--- a/arch/arm/dts/an7583.dtsi
+++ b/arch/arm/dts/an7583.dtsi
@@ -130,6 +130,29 @@
reg = <0x0 0x1fa20000 0x0 0x388>;
};
+ eth: ethernet@1fb50000 {
+ compatible = "airoha,an7583-eth";
+ reg = <0 0x1fb50000 0 0x2600>,
+ <0 0x1fb54000 0 0x2000>,
+ <0 0x1fb56000 0 0x2000>;
+ reg-names = "fe", "qdma0", "qdma1";
+
+ resets = <&scuclk AN7583_FE_RST>,
+ <&scuclk AN7583_FE_PDMA_RST>,
+ <&scuclk AN7583_FE_QDMA_RST>,
+ <&scuclk AN7583_DUAL_HSI0_MAC_RST>,
+ <&scuclk AN7583_DUAL_HSI1_MAC_RST>,
+ <&scuclk AN7583_XFP_MAC_RST>;
+ reset-names = "fe", "pdma", "qdma",
+ "hsi0-mac", "hsi1-mac",
+ "xfp-mac";
+ };
+
+ switch: switch@1fb58000 {
+ compatible = "airoha,an7583-switch";
+ reg = <0 0x1fb58000 0 0x8000>;
+ };
+
syscon@1fbe3400 {
compatible = "airoha,en7581-pbus-csr", "syscon";
reg = <0x0 0x1fbe3400 0x0 0xff>;
--
2.53.0
^ permalink raw reply related [flat|nested] 20+ messages in thread
* [PATCH v2 08/16] airoha: add MMC node for Airoha AN7583
2026-09-02 8:52 [PATCH v2 00/16] arm: airoha: add AN7583 SoC support Mikhail Kshevetskiy
` (6 preceding siblings ...)
2026-09-02 8:53 ` [PATCH v2 07/16] airoha: add Ethernet node in AN7583 dtsi Mikhail Kshevetskiy
@ 2026-09-02 8:53 ` Mikhail Kshevetskiy
2026-09-02 8:53 ` [PATCH v2 09/16] configs: an7583: add mii/mdio support Mikhail Kshevetskiy
` (7 subsequent siblings)
15 siblings, 0 replies; 20+ messages in thread
From: Mikhail Kshevetskiy @ 2026-09-02 8:53 UTC (permalink / raw)
To: Tom Rini, Ilias Apalodimas, Christian Marangi, Lukasz Majewski,
Jerome Forissier, Sumit Garg, Simon Glass, Wayen Yan,
Quentin Schulz, Johan Jonker, Julien Stephan, u-boot
Cc: Mikhail Kshevetskiy
From: Christian Marangi <ansuelsmth@gmail.com>
Add MMC node for Airoha AN7583. These follow the same node of Airoha
AN7581.
Similar to Airoha AN7581, add the fixed regulator and fixed clock for
MMC.
Signed-off-by: Christian Marangi <ansuelsmth@gmail.com>
---
arch/arm/dts/an7583.dtsi | 33 +++++++++++++++++++++++++++++++++
1 file changed, 33 insertions(+)
diff --git a/arch/arm/dts/an7583.dtsi b/arch/arm/dts/an7583.dtsi
index d67b7459870..1a64f48e5f1 100644
--- a/arch/arm/dts/an7583.dtsi
+++ b/arch/arm/dts/an7583.dtsi
@@ -105,6 +105,21 @@
<GIC_PPI 10 IRQ_TYPE_LEVEL_LOW>;
};
+ clk25m: oscillator {
+ compatible = "fixed-clock";
+ #clock-cells = <0>;
+ clock-frequency = <25000000>;
+ clock-output-names = "clkxtal";
+ };
+
+ vmmc_3v3: regulator-vmmc-3v3 {
+ compatible = "regulator-fixed";
+ regulator-name = "vmmc";
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ regulator-always-on;
+ };
+
soc {
compatible = "simple-bus";
#address-cells = <2>;
@@ -259,6 +274,24 @@
};
};
+ mmc0: mmc@1fa0e000 {
+ compatible = "mediatek,mt7622-mmc";
+ reg = <0x0 0x1fa0e000 0x0 0x1000>,
+ <0x0 0x1fa0c000 0x0 0x60>;
+ interrupts = <GIC_SPI 170 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&scuclk EN7581_CLK_EMMC>, <&clk25m>;
+ clock-names = "source", "hclk";
+ bus-width = <4>;
+ max-frequency = <52000000>;
+ vmmc-supply = <&vmmc_3v3>;
+ disable-wp;
+ cap-mmc-highspeed;
+ non-removable;
+
+ assigned-clocks = <&scuclk EN7581_CLK_EMMC>;
+ assigned-clock-rates = <200000000>;
+ };
+
uart1: serial@1fbf0000 {
compatible = "ns16550";
reg = <0x0 0x1fbf0000 0x0 0x30>;
--
2.53.0
^ permalink raw reply related [flat|nested] 20+ messages in thread
* [PATCH v2 09/16] configs: an7583: add mii/mdio support
2026-09-02 8:52 [PATCH v2 00/16] arm: airoha: add AN7583 SoC support Mikhail Kshevetskiy
` (7 preceding siblings ...)
2026-09-02 8:53 ` [PATCH v2 08/16] airoha: add MMC node for Airoha AN7583 Mikhail Kshevetskiy
@ 2026-09-02 8:53 ` Mikhail Kshevetskiy
2026-09-02 8:53 ` [PATCH v2 10/16] arm: dts: an7583: add mdio child node to switch node Mikhail Kshevetskiy
` (6 subsequent siblings)
15 siblings, 0 replies; 20+ messages in thread
From: Mikhail Kshevetskiy @ 2026-09-02 8:53 UTC (permalink / raw)
To: Tom Rini, Ilias Apalodimas, Christian Marangi, Lukasz Majewski,
Jerome Forissier, Sumit Garg, Simon Glass, Wayen Yan,
Quentin Schulz, Johan Jonker, Julien Stephan, u-boot
Cc: Mikhail Kshevetskiy
This enables mdio/mii command support.
Signed-off-by: Mikhail Kshevetskiy <mikhail.kshevetskiy@iopsys.eu
---
configs/an7583_evb_defconfig | 2 ++
1 file changed, 2 insertions(+)
diff --git a/configs/an7583_evb_defconfig b/configs/an7583_evb_defconfig
index 16466be51b2..7178f45e3f8 100644
--- a/configs/an7583_evb_defconfig
+++ b/configs/an7583_evb_defconfig
@@ -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_DM_MDIO=y
CONFIG_AIROHA_ETH=y
CONFIG_PHY=y
CONFIG_PINCTRL=y
--
2.53.0
^ permalink raw reply related [flat|nested] 20+ messages in thread
* [PATCH v2 10/16] arm: dts: an7583: add mdio child node to switch node
2026-09-02 8:52 [PATCH v2 00/16] arm: airoha: add AN7583 SoC support Mikhail Kshevetskiy
` (8 preceding siblings ...)
2026-09-02 8:53 ` [PATCH v2 09/16] configs: an7583: add mii/mdio support Mikhail Kshevetskiy
@ 2026-09-02 8:53 ` Mikhail Kshevetskiy
2026-09-02 8:53 ` [PATCH v2 11/16] net: airoha: add support for Airoha AN7583 PCS driver Mikhail Kshevetskiy
` (5 subsequent siblings)
15 siblings, 0 replies; 20+ messages in thread
From: Mikhail Kshevetskiy @ 2026-09-02 8:53 UTC (permalink / raw)
To: Tom Rini, Ilias Apalodimas, Christian Marangi, Lukasz Majewski,
Jerome Forissier, Sumit Garg, Simon Glass, Wayen Yan,
Quentin Schulz, Johan Jonker, Julien Stephan, u-boot
Cc: Mikhail Kshevetskiy
add mdio node to be able see switch port states
Signed-off-by: Mikhail Kshevetskiy <mikhail.kshevetskiy@iopsys.eu>
---
arch/arm/dts/an7583.dtsi | 5 +++++
1 file changed, 5 insertions(+)
diff --git a/arch/arm/dts/an7583.dtsi b/arch/arm/dts/an7583.dtsi
index 1a64f48e5f1..ec6eab327db 100644
--- a/arch/arm/dts/an7583.dtsi
+++ b/arch/arm/dts/an7583.dtsi
@@ -166,6 +166,11 @@
switch: switch@1fb58000 {
compatible = "airoha,an7583-switch";
reg = <0 0x1fb58000 0 0x8000>;
+
+ mdio: mdio {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ };
};
syscon@1fbe3400 {
--
2.53.0
^ permalink raw reply related [flat|nested] 20+ messages in thread
* [PATCH v2 11/16] net: airoha: add support for Airoha AN7583 PCS driver
2026-09-02 8:52 [PATCH v2 00/16] arm: airoha: add AN7583 SoC support Mikhail Kshevetskiy
` (9 preceding siblings ...)
2026-09-02 8:53 ` [PATCH v2 10/16] arm: dts: an7583: add mdio child node to switch node Mikhail Kshevetskiy
@ 2026-09-02 8:53 ` Mikhail Kshevetskiy
2026-09-02 8:53 ` [PATCH v2 12/16] airoha: add PCS node for AN7583 Mikhail Kshevetskiy
` (4 subsequent siblings)
15 siblings, 0 replies; 20+ messages in thread
From: Mikhail Kshevetskiy @ 2026-09-02 8:53 UTC (permalink / raw)
To: Tom Rini, Ilias Apalodimas, Christian Marangi, Lukasz Majewski,
Jerome Forissier, Sumit Garg, Simon Glass, Wayen Yan,
Quentin Schulz, Johan Jonker, Julien Stephan, u-boot
Cc: Mikhail Kshevetskiy
From: Christian Marangi <ansuelsmth@gmail.com>
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 | 2202 ++++++++++++++++++++++++
5 files changed, 2255 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..4bdda3066ed
--- /dev/null
+++ b/drivers/net/airoha/pcs-an7583.c
@@ -0,0 +1,2202 @@
+// 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;
+
+ 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
^ permalink raw reply related [flat|nested] 20+ messages in thread
* [PATCH v2 12/16] airoha: add PCS node for AN7583
2026-09-02 8:52 [PATCH v2 00/16] arm: airoha: add AN7583 SoC support Mikhail Kshevetskiy
` (10 preceding siblings ...)
2026-09-02 8:53 ` [PATCH v2 11/16] net: airoha: add support for Airoha AN7583 PCS driver Mikhail Kshevetskiy
@ 2026-09-02 8:53 ` Mikhail Kshevetskiy
2026-09-02 8:53 ` [PATCH v2 13/16] configs: enable PCS for Airoha AN7583 Mikhail Kshevetskiy
` (3 subsequent siblings)
15 siblings, 0 replies; 20+ messages in thread
From: Mikhail Kshevetskiy @ 2026-09-02 8:53 UTC (permalink / raw)
To: Tom Rini, Ilias Apalodimas, Christian Marangi, Lukasz Majewski,
Jerome Forissier, Sumit Garg, Simon Glass, Wayen Yan,
Quentin Schulz, Johan Jonker, Julien Stephan, u-boot
Cc: Mikhail Kshevetskiy
From: Christian Marangi <ansuelsmth@gmail.com>
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 ec6eab327db..c8f445b2c41 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
^ permalink raw reply related [flat|nested] 20+ messages in thread
* [PATCH v2 13/16] configs: enable PCS for Airoha AN7583
2026-09-02 8:52 [PATCH v2 00/16] arm: airoha: add AN7583 SoC support Mikhail Kshevetskiy
` (11 preceding siblings ...)
2026-09-02 8:53 ` [PATCH v2 12/16] airoha: add PCS node for AN7583 Mikhail Kshevetskiy
@ 2026-09-02 8:53 ` Mikhail Kshevetskiy
2026-09-02 8:53 ` [PATCH v2 14/16] net: Add support for Airoha AN7583 MDIO Controller Mikhail Kshevetskiy
` (2 subsequent siblings)
15 siblings, 0 replies; 20+ messages in thread
From: Mikhail Kshevetskiy @ 2026-09-02 8:53 UTC (permalink / raw)
To: Tom Rini, Ilias Apalodimas, Christian Marangi, Lukasz Majewski,
Jerome Forissier, Sumit Garg, Simon Glass, Wayen Yan,
Quentin Schulz, Johan Jonker, Julien Stephan, u-boot
Cc: Mikhail Kshevetskiy
From: Christian Marangi <ansuelsmth@gmail.com>
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
^ permalink raw reply related [flat|nested] 20+ messages in thread
* [PATCH v2 14/16] net: Add support for Airoha AN7583 MDIO Controller
2026-09-02 8:52 [PATCH v2 00/16] arm: airoha: add AN7583 SoC support Mikhail Kshevetskiy
` (12 preceding siblings ...)
2026-09-02 8:53 ` [PATCH v2 13/16] configs: enable PCS for Airoha AN7583 Mikhail Kshevetskiy
@ 2026-09-02 8:53 ` Mikhail Kshevetskiy
2026-09-02 8:53 ` [PATCH v2 15/16] an7583: fix system controller mdio nodes Mikhail Kshevetskiy
2026-09-02 8:53 ` [PATCH v2 16/16] an7583: enable MDIO_AIROHA by default Mikhail Kshevetskiy
15 siblings, 0 replies; 20+ messages in thread
From: Mikhail Kshevetskiy @ 2026-09-02 8:53 UTC (permalink / raw)
To: Tom Rini, Ilias Apalodimas, Christian Marangi, Lukasz Majewski,
Jerome Forissier, Sumit Garg, Simon Glass, Wayen Yan,
Quentin Schulz, Johan Jonker, Julien Stephan, u-boot
Cc: Mikhail Kshevetskiy
From: Christian Marangi <ansuelsmth@gmail.com>
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 faa08e9ebba..d2515a98ebf 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 4c1f4094ab2..ad5f6dbd434 100644
--- a/drivers/net/Makefile
+++ b/drivers/net/Makefile
@@ -63,6 +63,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_GPIO_BITBANG) += mdio_gpio.o
obj-$(CONFIG_MDIO_IPQ4019) += mdio-ipq4019.o
obj-$(CONFIG_MDIO_MSCC_MIIM) += mdio-mscc-miim.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
^ permalink raw reply related [flat|nested] 20+ messages in thread
* [PATCH v2 15/16] an7583: fix system controller mdio nodes
2026-09-02 8:52 [PATCH v2 00/16] arm: airoha: add AN7583 SoC support Mikhail Kshevetskiy
` (13 preceding siblings ...)
2026-09-02 8:53 ` [PATCH v2 14/16] net: Add support for Airoha AN7583 MDIO Controller Mikhail Kshevetskiy
@ 2026-09-02 8:53 ` Mikhail Kshevetskiy
2026-09-02 8:53 ` [PATCH v2 16/16] an7583: enable MDIO_AIROHA by default Mikhail Kshevetskiy
15 siblings, 0 replies; 20+ messages in thread
From: Mikhail Kshevetskiy @ 2026-09-02 8:53 UTC (permalink / raw)
To: Tom Rini, Ilias Apalodimas, Christian Marangi, Lukasz Majewski,
Jerome Forissier, Sumit Garg, Simon Glass, Wayen Yan,
Quentin Schulz, Johan Jonker, Julien Stephan, u-boot
Cc: Mikhail Kshevetskiy
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 c8f445b2c41..cbb2a96a1aa 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
^ permalink raw reply related [flat|nested] 20+ messages in thread
* [PATCH v2 16/16] an7583: enable MDIO_AIROHA by default
2026-09-02 8:52 [PATCH v2 00/16] arm: airoha: add AN7583 SoC support Mikhail Kshevetskiy
` (14 preceding siblings ...)
2026-09-02 8:53 ` [PATCH v2 15/16] an7583: fix system controller mdio nodes Mikhail Kshevetskiy
@ 2026-09-02 8:53 ` Mikhail Kshevetskiy
15 siblings, 0 replies; 20+ messages in thread
From: Mikhail Kshevetskiy @ 2026-09-02 8:53 UTC (permalink / raw)
To: Tom Rini, Ilias Apalodimas, Christian Marangi, Lukasz Majewski,
Jerome Forissier, Sumit Garg, Simon Glass, Wayen Yan,
Quentin Schulz, Johan Jonker, Julien Stephan, u-boot
Cc: Mikhail Kshevetskiy
From: Christian Marangi <ansuelsmth@gmail.com>
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
^ permalink raw reply related [flat|nested] 20+ messages in thread
* Re: [PATCH v2 03/16] dt-bindings: clock: airoha: Document support for AN7583 clock
2026-09-02 8:52 ` [PATCH v2 03/16] dt-bindings: clock: airoha: Document support for AN7583 clock Mikhail Kshevetskiy
@ 2026-09-02 16:22 ` Tom Rini
0 siblings, 0 replies; 20+ messages in thread
From: Tom Rini @ 2026-09-02 16:22 UTC (permalink / raw)
To: Mikhail Kshevetskiy
Cc: Ilias Apalodimas, Christian Marangi, Lukasz Majewski,
Jerome Forissier, Sumit Garg, Simon Glass, Wayen Yan,
Quentin Schulz, Johan Jonker, Julien Stephan, u-boot
[-- Attachment #1: Type: text/plain, Size: 784 bytes --]
On Wed, Sep 02, 2026 at 11:52:58AM +0300, Mikhail Kshevetskiy wrote:
> From: Christian Marangi <ansuelsmth@gmail.com>
>
> Document support for Airoha AN7583 clock. This is based on the EN7523
> clock schema with the new requirement of the "airoha,chip-scu"
> (previously optional for EN7581).
>
> Add additional binding for additional clock and reset lines.
>
> Signed-off-by: Christian Marangi <ansuelsmth@gmail.com>
> ---
> dts/upstream/include/dt-bindings/clock/en7523-clk.h | 3 +++
> 1 file changed, 3 insertions(+)
This does not follow the format of a tools/update-subtree.sh done
cherry-pick from upstream, which is the only way we allow changes to
dts/upstream/ to happen. Please re-do this and any other changes to
dts/upstream/, thanks.
--
Tom
[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 228 bytes --]
^ permalink raw reply [flat|nested] 20+ messages in thread
* Re: [PATCH v2 01/16] airoha: add support for Airoha AN7583 SoC
2026-09-02 8:52 ` [PATCH v2 01/16] airoha: add support for Airoha AN7583 SoC Mikhail Kshevetskiy
@ 2026-09-02 16:24 ` Tom Rini
0 siblings, 0 replies; 20+ messages in thread
From: Tom Rini @ 2026-09-02 16:24 UTC (permalink / raw)
To: Mikhail Kshevetskiy
Cc: Ilias Apalodimas, Christian Marangi, Lukasz Majewski,
Jerome Forissier, Sumit Garg, Simon Glass, Wayen Yan,
Quentin Schulz, Johan Jonker, Julien Stephan, u-boot
[-- Attachment #1: Type: text/plain, Size: 933 bytes --]
On Wed, Sep 02, 2026 at 11:52:56AM +0300, Mikhail Kshevetskiy wrote:
> From: Christian Marangi <ansuelsmth@gmail.com>
>
> 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
> CPU and RAM initialization. Everything is mostly based on AN7581 that
> share lots of common piece.
>
> Acked-by: Mikhail Kshevetskiy <mikhail.kshevetskiy@iopsys.eu>
> Signed-off-by: Christian Marangi <ansuelsmth@gmail.com>
[snip]
> diff --git a/board/airoha/an7583/MAINTAINERS b/board/airoha/an7583/MAINTAINERS
> new file mode 100644
> index 00000000000..71ee542a8bc
> --- /dev/null
> +++ b/board/airoha/an7583/MAINTAINERS
> @@ -0,0 +1,5 @@
> +AN7581
> +M: Christian Marangi <ansuelsmth@gmail.com>
> +S: Maintained
> +N: airoha
> +N: an7583
Since I'm already requesting changes, this should be <tab> throughout.
--
Tom
[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 228 bytes --]
^ permalink raw reply [flat|nested] 20+ messages in thread
* Re: [PATCH v2 05/16] reset: airoha: Add support for Airoha AN7583 reset
2026-09-02 8:53 ` [PATCH v2 05/16] reset: airoha: Add support for Airoha AN7583 reset Mikhail Kshevetskiy
@ 2026-09-02 16:24 ` Tom Rini
0 siblings, 0 replies; 20+ messages in thread
From: Tom Rini @ 2026-09-02 16:24 UTC (permalink / raw)
To: Mikhail Kshevetskiy
Cc: Ilias Apalodimas, Christian Marangi, Lukasz Majewski,
Jerome Forissier, Sumit Garg, Simon Glass, Wayen Yan,
Quentin Schulz, Johan Jonker, Julien Stephan, u-boot
[-- Attachment #1: Type: text/plain, Size: 688 bytes --]
On Wed, Sep 02, 2026 at 11:53:00AM +0300, Mikhail Kshevetskiy wrote:
> From: Christian Marangi <ansuelsmth@gmail.com>
>
> Adapt the Airoha reset driver to support Airoha AN7583 node structure.
> In AN7583 the register is exposed by the parent syscon hence a different
> logic needs to be applied. Also the reset line differ from AN7581 hence
> a dedicated table is needed.
>
> Signed-off-by: Christian Marangi <ansuelsmth@gmail.com>
> ---
> drivers/reset/reset-airoha.c | 60 ++++++++++++++++++
> .../dt-bindings/reset/airoha,an7583-reset.h | 62 +++++++++++++++++++
Since this binding isn't touching dts/upstream, has it been submitted?
--
Tom
[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 228 bytes --]
^ permalink raw reply [flat|nested] 20+ messages in thread
end of thread, other threads:[~2026-09-02 16:25 UTC | newest]
Thread overview: 20+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-09-02 8:52 [PATCH v2 00/16] arm: airoha: add AN7583 SoC support Mikhail Kshevetskiy
2026-09-02 8:52 ` [PATCH v2 01/16] airoha: add support for Airoha AN7583 SoC Mikhail Kshevetskiy
2026-09-02 16:24 ` Tom Rini
2026-09-02 8:52 ` [PATCH v2 02/16] arm: airoha: introduce AN7583 helpers to get SCU and CHIP_SCU regmaps Mikhail Kshevetskiy
2026-09-02 8:52 ` [PATCH v2 03/16] dt-bindings: clock: airoha: Document support for AN7583 clock Mikhail Kshevetskiy
2026-09-02 16:22 ` Tom Rini
2026-09-02 8:52 ` [PATCH v2 04/16] clk: airoha: add support for Airoha AN7583 SoC clock Mikhail Kshevetskiy
2026-09-02 8:53 ` [PATCH v2 05/16] reset: airoha: Add support for Airoha AN7583 reset Mikhail Kshevetskiy
2026-09-02 16:24 ` Tom Rini
2026-09-02 8:53 ` [PATCH v2 06/16] net: airoha: add support for Airoha AN7583 Mikhail Kshevetskiy
2026-09-02 8:53 ` [PATCH v2 07/16] airoha: add Ethernet node in AN7583 dtsi Mikhail Kshevetskiy
2026-09-02 8:53 ` [PATCH v2 08/16] airoha: add MMC node for Airoha AN7583 Mikhail Kshevetskiy
2026-09-02 8:53 ` [PATCH v2 09/16] configs: an7583: add mii/mdio support Mikhail Kshevetskiy
2026-09-02 8:53 ` [PATCH v2 10/16] arm: dts: an7583: add mdio child node to switch node Mikhail Kshevetskiy
2026-09-02 8:53 ` [PATCH v2 11/16] net: airoha: add support for Airoha AN7583 PCS driver Mikhail Kshevetskiy
2026-09-02 8:53 ` [PATCH v2 12/16] airoha: add PCS node for AN7583 Mikhail Kshevetskiy
2026-09-02 8:53 ` [PATCH v2 13/16] configs: enable PCS for Airoha AN7583 Mikhail Kshevetskiy
2026-09-02 8:53 ` [PATCH v2 14/16] net: Add support for Airoha AN7583 MDIO Controller Mikhail Kshevetskiy
2026-09-02 8:53 ` [PATCH v2 15/16] an7583: fix system controller mdio nodes Mikhail Kshevetskiy
2026-09-02 8:53 ` [PATCH v2 16/16] an7583: enable MDIO_AIROHA by default Mikhail Kshevetskiy
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.