diff --git a/package/boot/uboot-airoha/Makefile b/package/boot/uboot-airoha/Makefile new file mode 100644 index 0000000000..f3ba478fee --- /dev/null +++ b/package/boot/uboot-airoha/Makefile @@ -0,0 +1,95 @@ +include $(TOPDIR)/rules.mk +include $(INCLUDE_DIR)/kernel.mk + +PKG_VERSION:=2025.07 +PKG_HASH:=0f933f6c5a426895bf306e93e6ac53c60870e4b54cda56d95211bec99e63bec7 +PKG_BUILD_DEPENDS:=arm-trusted-firmware-tools/host + +UBOOT_USE_INTREE_DTC:=1 + +include $(INCLUDE_DIR)/u-boot.mk +include $(INCLUDE_DIR)/package.mk +include $(INCLUDE_DIR)/host-build.mk + +define U-Boot/Default + BUILD_TARGET:=airoha + HIDDEN:=1 + FIP_COMPRESS:=1 +endef + +define U-Boot/an7581_rfb + NAME:=AN7581 Reference Board + UBOOT_CONFIG:=an7581_evb + BUILD_DEVICES:=airoha_an7581-evb + BUILD_SUBTARGET:=an7581 + UBOOT_IMAGE:=u-boot.fip + BL2_IMAGE:=an7581-bl2.bin + BL31_IMAGE:=an7581-bl31.bin +endef + +define U-Boot/an7583_rfb + NAME:=AN7583 Reference Board + UBOOT_CONFIG:=an7583_evb + BUILD_DEVICES:=airoha_an7583-evb + BUILD_SUBTARGET:=an7583 + UBOOT_IMAGE:=u-boot.fip + BL2_IMAGE:=an7583-bl2.bin + BL31_IMAGE:=an7583-bl31.bin +endef + +UBOOT_TARGETS := \ + an7581_rfb \ + an7583_rfb + +UBOOT_CUSTOMIZE_CONFIG := \ + --disable TOOLS_KWBIMAGE \ + --disable TOOLS_LIBCRYPTO \ + --disable TOOLS_MKEFICAPSULE \ + --enable SERIAL_RX_BUFFER \ + --set-val SERIAL_RX_BUFFER_SIZE 256 + +define Build/fip-image-bl2 + $(STAGING_DIR_HOST)/bin/fiptool create \ + --tb-fw files/$(BL2_IMAGE) \ + $(PKG_BUILD_DIR)/bl2.fip +endef + +define Build/fip-image + $(if $(FIP_COMPRESS), $(STAGING_DIR_HOST)/bin/lzma e \ + $(PKG_BUILD_DIR)/u-boot.bin \ + $(PKG_BUILD_DIR)/u-boot.bin.lzma) + $(if $(FIP_COMPRESS), $(STAGING_DIR_HOST)/bin/lzma e \ + files/$(BL31_IMAGE) \ + $(PKG_BUILD_DIR)/bl31.bin.lzma) + $(STAGING_DIR_HOST)/bin/fiptool create \ + --soc-fw $(PKG_BUILD_DIR)/bl31.bin$(if $(FIP_COMPRESS),.lzma) \ + --nt-fw $(PKG_BUILD_DIR)/u-boot.bin$(if $(FIP_COMPRESS),.lzma) \ + $(PKG_BUILD_DIR)/u-boot.fip +endef + +define Build/Configure + $(call Build/Configure/U-Boot) + sed -i 's/CONFIG_TOOLS_LIBCRYPTO=y/# CONFIG_TOOLS_LIBCRYPTO is not set/' $(PKG_BUILD_DIR)/.config +endef + +define Build/Compile + $(call Build/Compile/U-Boot) +ifeq ($(UBOOT_IMAGE),u-boot.fip) + $(call Build/fip-image-bl2) + $(call Build/fip-image) +endif +endef + +# don't stage files to bindir, let target/linux/airoha/image/*.mk do that +define Package/u-boot/install +endef + +define Build/InstallDev + $(INSTALL_DIR) $(STAGING_DIR_IMAGE) +ifeq ($(UBOOT_IMAGE),u-boot.fip) + $(INSTALL_DATA) $(PKG_BUILD_DIR)/bl2.fip $(STAGING_DIR_IMAGE)/$(BUILD_VARIANT)-bl2.fip + $(INSTALL_DATA) $(PKG_BUILD_DIR)/u-boot.fip $(STAGING_DIR_IMAGE)/$(BUILD_VARIANT)-bl31-u-boot.fip +endif +endef + +$(eval $(call BuildPackage/U-Boot)) diff --git a/package/boot/uboot-airoha/files/an7581-bl2.bin b/package/boot/uboot-airoha/files/an7581-bl2.bin new file mode 100644 index 0000000000..a500445bfe Binary files /dev/null and b/package/boot/uboot-airoha/files/an7581-bl2.bin differ diff --git a/package/boot/uboot-airoha/files/an7581-bl31.bin b/package/boot/uboot-airoha/files/an7581-bl31.bin new file mode 100644 index 0000000000..f57a37717c Binary files /dev/null and b/package/boot/uboot-airoha/files/an7581-bl31.bin differ diff --git a/package/boot/uboot-airoha/files/an7583-bl2.bin b/package/boot/uboot-airoha/files/an7583-bl2.bin new file mode 100644 index 0000000000..b7c3604e0c Binary files /dev/null and b/package/boot/uboot-airoha/files/an7583-bl2.bin differ diff --git a/package/boot/uboot-airoha/files/an7583-bl31.bin b/package/boot/uboot-airoha/files/an7583-bl31.bin new file mode 100644 index 0000000000..016a2382f9 Binary files /dev/null and b/package/boot/uboot-airoha/files/an7583-bl31.bin differ diff --git a/package/boot/uboot-airoha/patches/200-linux-bitfield.h-import-FIELD_PREP_CONST-macro-from-.patch b/package/boot/uboot-airoha/patches/200-linux-bitfield.h-import-FIELD_PREP_CONST-macro-from-.patch new file mode 100644 index 0000000000..6eca59fcc4 --- /dev/null +++ b/package/boot/uboot-airoha/patches/200-linux-bitfield.h-import-FIELD_PREP_CONST-macro-from-.patch @@ -0,0 +1,55 @@ +From 4f1fcf5281ee4e22b1e89a62bd0417878bcbeca5 Mon Sep 17 00:00:00 2001 +From: Christian Marangi +Date: Tue, 3 Jun 2025 10:41:18 +0200 +Subject: [PATCH 1/2] linux/bitfield.h: import FIELD_PREP_CONST macro from + Linux Kernel + +Import FIELD_PREP_CONST macro from Linux Kernel to permit usage of +FIELD_PREP with scenario where a constant value is needed. + +Refer to commit e2192de59e45 ("bitfield: add FIELD_PREP_CONST()") in +Linux kernel for extensive explaination of why this is useful. + +This is also to better align with the Linux Kernel for easier porting of +driver. + +Signed-off-by: Christian Marangi +--- + include/linux/bitfield.h | 26 ++++++++++++++++++++++++++ + 1 file changed, 26 insertions(+) + +--- a/include/linux/bitfield.h ++++ b/include/linux/bitfield.h +@@ -90,6 +90,32 @@ + ((typeof(_mask))(_val) << __bf_shf(_mask)) & (_mask); \ + }) + ++#define __BF_CHECK_POW2(n) BUILD_BUG_ON_ZERO(((n) & ((n) - 1)) != 0) ++ ++/** ++ * FIELD_PREP_CONST() - prepare a constant bitfield element ++ * @_mask: shifted mask defining the field's length and position ++ * @_val: value to put in the field ++ * ++ * FIELD_PREP_CONST() masks and shifts up the value. The result should ++ * be combined with other fields of the bitfield using logical OR. ++ * ++ * Unlike FIELD_PREP() this is a constant expression and can therefore ++ * be used in initializers. Error checking is less comfortable for this ++ * version, and non-constant masks cannot be used. ++ */ ++#define FIELD_PREP_CONST(_mask, _val) \ ++ ( \ ++ /* mask must be non-zero */ \ ++ BUILD_BUG_ON_ZERO((_mask) == 0) + \ ++ /* check if value fits */ \ ++ BUILD_BUG_ON_ZERO(~((_mask) >> __bf_shf(_mask)) & (_val)) + \ ++ /* check if mask is contiguous */ \ ++ __BF_CHECK_POW2((_mask) + (1ULL << __bf_shf(_mask))) + \ ++ /* and create the value */ \ ++ (((typeof(_mask))(_val) << __bf_shf(_mask)) & (_mask)) \ ++ ) ++ + /** + * FIELD_GET() - extract a bitfield element + * @_mask: shifted mask defining the field's length and position diff --git a/package/boot/uboot-airoha/patches/201-mtd-spinand-winbond-add-Winbond-W25N04KV-flash-suppo.patch b/package/boot/uboot-airoha/patches/201-mtd-spinand-winbond-add-Winbond-W25N04KV-flash-suppo.patch new file mode 100644 index 0000000000..17acda68a2 --- /dev/null +++ b/package/boot/uboot-airoha/patches/201-mtd-spinand-winbond-add-Winbond-W25N04KV-flash-suppo.patch @@ -0,0 +1,56 @@ +From 00e8038b8be74d599f7bc8078731cc2505832f57 Mon Sep 17 00:00:00 2001 +From: Christian Marangi +Date: Tue, 3 Jun 2025 10:47:15 +0200 +Subject: [PATCH 2/2] mtd: spinand: winbond: add Winbond W25N04KV flash support + +Add Winbond W25N04KV flash support that use a different value to detect +ECC bitflip. + +Signed-off-by: Christian Marangi +--- + drivers/mtd/nand/spi/winbond.c | 13 +++++++++++++ + 1 file changed, 13 insertions(+) + +--- a/drivers/mtd/nand/spi/winbond.c ++++ b/drivers/mtd/nand/spi/winbond.c +@@ -11,6 +11,7 @@ + #include + #include + #endif ++#include + #include + #include + +@@ -18,6 +19,8 @@ + + #define WINBOND_CFG_BUF_READ BIT(3) + ++#define W25N04KV_STATUS_ECC_5_8_BITFLIPS FIELD_PREP_CONST(STATUS_ECC_MASK, 0x3) ++ + static SPINAND_OP_VARIANTS(read_cache_variants, + SPINAND_PAGE_READ_FROM_CACHE_QUADIO_OP(0, 2, NULL, 0), + SPINAND_PAGE_READ_FROM_CACHE_X4_OP(0, 1, NULL, 0), +@@ -121,6 +124,7 @@ static int w25n02kv_ecc_get_status(struc + return -EBADMSG; + + case STATUS_ECC_HAS_BITFLIPS: ++ case W25N04KV_STATUS_ECC_5_8_BITFLIPS: + /* + * Let's try to retrieve the real maximum number of bitflips + * in order to avoid forcing the wear-leveling layer to move +@@ -169,6 +173,15 @@ static const struct spinand_info winbond + NAND_ECCREQ(8, 512), + SPINAND_INFO_OP_VARIANTS(&read_cache_variants, + &write_cache_variants, ++ &update_cache_variants), ++ 0, ++ SPINAND_ECCINFO(&w25n02kv_ooblayout, w25n02kv_ecc_get_status)), ++ SPINAND_INFO("W25N04KV", ++ SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0xaa, 0x23), ++ NAND_MEMORG(1, 2048, 128, 64, 4096, 40, 2, 1, 1), ++ NAND_ECCREQ(8, 512), ++ SPINAND_INFO_OP_VARIANTS(&read_cache_variants, ++ &write_cache_variants, + &update_cache_variants), + 0, + SPINAND_ECCINFO(&w25n02kv_ooblayout, w25n02kv_ecc_get_status)), diff --git a/package/boot/uboot-airoha/patches/300-airoha-add-support-for-Airoha-AN7583-SoC.patch b/package/boot/uboot-airoha/patches/300-airoha-add-support-for-Airoha-AN7583-SoC.patch new file mode 100644 index 0000000000..8c7b6a22dd --- /dev/null +++ b/package/boot/uboot-airoha/patches/300-airoha-add-support-for-Airoha-AN7583-SoC.patch @@ -0,0 +1,729 @@ +From 0ee8053a17e6f4d6dbde0828e775309cba38c171 Mon Sep 17 00:00:00 2001 +From: Christian Marangi +Date: Tue, 29 Apr 2025 13:06:59 +0200 +Subject: [PATCH 1/3] airoha: add support for Airoha AN7583 SoC + +Add support for Airoha AN7583 SoC. This adds the Kconfig and Makefile +entry for the SoC, DTSI and initial config for it. Also add the code for +CPU and RAM initialization. Everything is mostly based on AN7581 that +share lots of common piece. + +Signed-off-by: Christian Marangi +--- + 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 | 47 ++++ + board/airoha/an7583/MAINTAINERS | 5 + + board/airoha/an7583/Makefile | 3 + + board/airoha/an7583/an7583_rfb.c | 16 ++ + configs/an7583_evb_defconfig | 83 ++++++ + include/configs/an7583.h | 19 ++ + 11 files changed, 645 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 + +--- /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 ++#include ++#include ++#include "an7583.dtsi" ++ ++/ { ++ model = "Airoha AN7583 Evaluation Board"; ++ compatible = "airoha,an7583-evb", "airoha,an7583", "airoha,en7583"; ++ ++ aliases { ++ serial0 = &uart1; ++ }; ++ ++ chosen { ++ bootargs = "console=ttyS0,115200 earlycon"; ++ stdout-path = "serial0:115200n8"; ++ 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"; ++}; +--- /dev/null ++++ b/arch/arm/dts/an7583.dtsi +@@ -0,0 +1,387 @@ ++// SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) ++ ++#include ++#include ++#include ++#include ++#include ++#include ++ ++/ { ++ interrupt-parent = <&gic>; ++ #address-cells = <2>; ++ #size-cells = <2>; ++ ++ reserved-memory { ++ #address-cells = <2>; ++ #size-cells = <2>; ++ ranges; ++ ++ atf-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 = , ++ , ++ , ++ ; ++ }; ++ ++ soc { ++ compatible = "simple-bus"; ++ #address-cells = <2>; ++ #size-cells = <2>; ++ ranges; ++ ++ gic: interrupt-controller@9000000 { ++ compatible = "arm,gic-v3"; ++ interrupt-controller; ++ #interrupt-cells = <3>; ++ #address-cells = <1>; ++ #size-cells = <1>; ++ reg = <0x0 0x09000000 0x0 0x20000>, ++ <0x0 0x09080000 0x0 0x80000>, ++ <0x0 0x09400000 0x0 0x2000>, ++ <0x0 0x09500000 0x0 0x2000>, ++ <0x0 0x09600000 0x0 0x20000>; ++ interrupts = ; ++ }; ++ ++ chip_scu: syscon@1fa20000 { ++ compatible = "airoha,en7581-chip-scu", "syscon"; ++ reg = <0x0 0x1fa20000 0x0 0x388>; ++ }; ++ ++ syscon@1fbe3400 { ++ compatible = "airoha,en7581-pbus-csr", "syscon"; ++ reg = <0x0 0x1fbe3400 0x0 0xff>; ++ }; ++ ++ system-controller@1fa20000 { ++ 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,en7583-pinctrl"; ++ ++ interrupt-parent = <&gic>; ++ interrupts = ; ++ ++ gpio-controller; ++ #gpio-cells = <2>; ++ ++ interrupt-controller; ++ #interrupt-cells = <2>; ++ }; ++ }; ++ ++ i2cclock: i2cclock@0 { ++ #clock-cells = <0>; ++ compatible = "fixed-clock"; ++ ++ /* 20 MHz */ ++ clock-frequency = <20000000>; ++ }; ++ ++ i2c0: i2c0@1fbf8000 { ++ compatible = "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 = ; ++ 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 = ; ++ clock-frequency = <7372800>; ++ ++ status = "disabled"; ++ }; ++ ++ hsuart3: serial@1fbe1000 { ++ compatible = "airoha,en7523-uart"; ++ reg = <0x0 0x1fbe1000 0x0 0x40>; ++ reg-io-width = <4>; ++ reg-shift = <2>; ++ interrupts = ; ++ clock-frequency = <7372800>; ++ ++ status = "disabled"; ++ }; ++ ++ uart4: serial@1fbf0600 { ++ compatible = "airoha,en7523-uart"; ++ reg = <0x0 0x1fbf0600 0x0 0x30>; ++ reg-io-width = <4>; ++ reg-shift = <2>; ++ interrupts = ; ++ clock-frequency = <7372800>; ++ ++ status = "disabled"; ++ }; ++ ++ uart5: serial@1fbf0700 { ++ compatible = "airoha,en7523-uart"; ++ reg = <0x0 0x1fbf0700 0x0 0x30>; ++ reg-io-width = <4>; ++ reg-shift = <2>; ++ interrupts = ; ++ clock-frequency = <7372800>; ++ ++ status = "disabled"; ++ }; ++ ++ 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 = ; ++ 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 = ; ++ 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>; ++ }; ++ }; ++ }; ++}; +--- a/arch/arm/mach-airoha/Kconfig ++++ b/arch/arm/mach-airoha/Kconfig +@@ -17,16 +17,30 @@ 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 "an7581" if TARGET_AN7581 ++ default "an7583" if TARGET_AN7583 + + config SYS_BOARD + default "an7581" if TARGET_AN7581 ++ default "an7583" if TARGET_AN7583 + + config SYS_CONFIG_NAME + default "an7581" if TARGET_AN7581 ++ default "an7583" if TARGET_AN7583 + + endif + +--- a/arch/arm/mach-airoha/Makefile ++++ b/arch/arm/mach-airoha/Makefile +@@ -3,3 +3,4 @@ + obj-y += cpu.o + + obj-$(CONFIG_TARGET_AN7581) += an7581/ ++obj-$(CONFIG_TARGET_AN7583) += an7583/ +--- /dev/null ++++ b/arch/arm/mach-airoha/an7583/Makefile +@@ -0,0 +1,3 @@ ++# SPDX-License-Identifier: GPL-2.0 ++ ++obj-y += init.o +--- /dev/null ++++ b/arch/arm/mach-airoha/an7583/init.c +@@ -0,0 +1,47 @@ ++// SPDX-License-Identifier: GPL-2.0 ++ ++#include ++#include ++#include ++#include ++ ++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) ++{ ++ return fdtdec_setup_memory_banksize(); ++} ++ ++void reset_cpu(ulong addr) ++{ ++ psci_system_reset(); ++} ++ ++static struct mm_region an7583_mem_map[] = { ++ { ++ /* DDR */ ++ .virt = 0x80000000UL, ++ .phys = 0x80000000UL, ++ .size = 0x80000000UL, ++ .attrs = PTE_BLOCK_MEMTYPE(MT_NORMAL) | PTE_BLOCK_OUTER_SHARE, ++ }, { ++ .virt = 0x00000000UL, ++ .phys = 0x00000000UL, ++ .size = 0x20000000UL, ++ .attrs = PTE_BLOCK_MEMTYPE(MT_DEVICE_NGNRNE) | ++ PTE_BLOCK_NON_SHARE | ++ PTE_BLOCK_PXN | PTE_BLOCK_UXN ++ }, { ++ 0, ++ } ++}; ++struct mm_region *mem_map = an7583_mem_map; +--- /dev/null ++++ b/board/airoha/an7583/MAINTAINERS +@@ -0,0 +1,5 @@ ++AN7581 ++M: Christian Marangi ++S: Maintained ++N: airoha ++N: an7583 +--- /dev/null ++++ b/board/airoha/an7583/Makefile +@@ -0,0 +1,3 @@ ++# SPDX-License-Identifier: GPL-2.0 ++ ++obj-y += an7583_rfb.o +--- /dev/null ++++ b/board/airoha/an7583/an7583_rfb.c +@@ -0,0 +1,16 @@ ++// SPDX-License-Identifier: GPL-2.0 ++/* ++ * Author: Christian Marangi ++ */ ++ ++#include ++ ++DECLARE_GLOBAL_DATA_PTR; ++ ++int board_init(void) ++{ ++ /* address of boot parameters */ ++ gd->bd->bi_boot_params = CFG_SYS_SDRAM_BASE + 0x100; ++ ++ return 0; ++} +--- /dev/null ++++ b/configs/an7583_evb_defconfig +@@ -0,0 +1,81 @@ ++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_DM_RESET=y ++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_SYS_RELOC_GD_ENV_ADDR=y ++CONFIG_ENV_VARS_UBOOT_RUNTIME_CONFIG=y ++CONFIG_NET_RANDOM_ETHADDR=y ++CONFIG_REGMAP=y ++CONFIG_SYSCON=y ++CONFIG_CLK=y ++CONFIG_DMA=y ++CONFIG_LED=y ++CONFIG_LED_GPIO=y ++CONFIG_MMC_HS200_SUPPORT=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_PHYLIB=y ++CONFIG_PHY=y ++CONFIG_PINCTRL=y ++CONFIG_PINCONF=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_SHA512=y ++CONFIG_AIROHA_ETH=y ++CONFIG_MMC_MTK=y ++CONFIG_AIROHA_SNFI_SPI=y +--- /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 ++ ++#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 diff --git a/package/boot/uboot-airoha/patches/301-clk-airoha-add-support-for-Airoha-AN7583-SoC-clock.patch b/package/boot/uboot-airoha/patches/301-clk-airoha-add-support-for-Airoha-AN7583-SoC-clock.patch new file mode 100644 index 0000000000..fcbc13366b --- /dev/null +++ b/package/boot/uboot-airoha/patches/301-clk-airoha-add-support-for-Airoha-AN7583-SoC-clock.patch @@ -0,0 +1,171 @@ +From 62ab067847b30d73d4f661bdc99e9f32ff03f338 Mon Sep 17 00:00:00 2001 +From: Christian Marangi +Date: Tue, 29 Apr 2025 13:19:11 +0200 +Subject: [PATCH] clk: airoha: add support for Airoha AN7583 SoC clock + +Add support for Airoha AN7583 SoC clock that implement more base values +for clocks compared to AN7581. + +Signed-off-by: Christian Marangi +--- + drivers/clk/airoha/clk-airoha.c | 131 ++++++++++++++++++++++++++++++++ + 1 file changed, 131 insertions(+) + +--- a/drivers/clk/airoha/clk-airoha.c ++++ b/drivers/clk/airoha/clk-airoha.c +@@ -73,6 +73,14 @@ static const u32 bus7581_base[] = { 6000 + static const u32 npu7581_base[] = { 800000000, 750000000, 720000000, 600000000 }; + static const u32 crypto_base[] = { 540000000, 480000000 }; + static const u32 emmc7581_base[] = { 200000000, 150000000 }; ++/* AN7583 */ ++static const u32 gsw7583_base[] = { 540672000, 270336000, 400000000, 200000000 }; ++static const u32 emi7583_base[] = { 540672000, 480000000, 400000000, 300000000 }; ++static const u32 bus7583_base[] = { 600000000, 540672000, 480000000, 400000000 }; ++static const u32 spi7583_base[] = { 100000000, 12500000 }; ++static const u32 npu7583_base[] = { 666000000, 800000000, 720000000, 600000000 }; ++static const u32 crypto7583_base[] = { 540672000, 400000000 }; ++static const u32 emmc7583_base[] = { 150000000, 200000000 }; + + static const struct airoha_clk_desc en7581_base_clks[EN7581_MAX_CLKS] = { + [EN7523_CLK_GSW] = { +@@ -186,6 +194,121 @@ static const struct airoha_clk_desc en75 + } + }; + ++static const struct airoha_clk_desc an7583_base_clks[EN7581_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 = 0, ++ .base_values = slic_base, ++ .n_base_values = ARRAY_SIZE(slic_base), ++ ++ .div_reg = REG_SPI_CLK_DIV_SEL, ++ .div_bits = 5, ++ .div_shift = 24, ++ .div_val0 = 20, ++ .div_step = 2, ++ }, ++ [EN7523_CLK_SPI] = { ++ .id = EN7523_CLK_SPI, ++ .name = "spi", ++ ++ .base_reg = REG_SPI_CLK_FREQ_SEL, ++ .base_bits = 1, ++ .base_shift = 1, ++ .base_values = spi7583_base, ++ .n_base_values = ARRAY_SIZE(spi7583_base), ++ ++ .div_reg = REG_SPI_CLK_DIV_SEL, ++ .div_bits = 5, ++ .div_shift = 8, ++ .div_val0 = 40, ++ .div_step = 2, ++ }, ++ [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), ++ } ++}; ++ + static u32 airoha_clk_get_base_rate(const struct airoha_clk_desc *desc, u32 val) + { + if (!desc->base_bits) +@@ -436,10 +559,18 @@ static const struct airoha_clk_soc_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,en7581-scu", + .data = (ulong)&en7581_data, + }, ++ { .compatible = "airoha,an7583-scu", ++ .data = (ulong)&an7583_data, ++ }, + { } + }; + diff --git a/package/boot/uboot-airoha/patches/302-reset-airoha-convert-to-regmap-API.patch b/package/boot/uboot-airoha/patches/302-reset-airoha-convert-to-regmap-API.patch new file mode 100644 index 0000000000..fd0c4d173d --- /dev/null +++ b/package/boot/uboot-airoha/patches/302-reset-airoha-convert-to-regmap-API.patch @@ -0,0 +1,90 @@ +From 7daf0565460e548eb766a0bcc171c34e02dd6eba Mon Sep 17 00:00:00 2001 +From: Christian Marangi +Date: Mon, 19 May 2025 14:22:55 +0200 +Subject: [PATCH 3/6] reset: airoha: convert to regmap API + +In preparation for support for Airoha AN7583, convert the driver to +regmap API. This is needed as Airoha AN7583 will use syscon to access +reset registers. + +Signed-off-by: Christian Marangi +--- + drivers/reset/reset-airoha.c | 35 ++++++++++++++++++----------------- + 1 file changed, 18 insertions(+), 17 deletions(-) + +--- a/drivers/reset/reset-airoha.c ++++ b/drivers/reset/reset-airoha.c +@@ -10,6 +10,7 @@ + #include + #include + #include ++#include + + #include + +@@ -21,7 +22,7 @@ + struct airoha_reset_priv { + const u16 *bank_ofs; + const u16 *idx_map; +- void __iomem *base; ++ struct regmap *map; + }; + + static const u16 en7581_rst_ofs[] = { +@@ -90,17 +91,11 @@ static const u16 en7581_rst_map[] = { + static int airoha_reset_update(struct airoha_reset_priv *priv, + unsigned long id, bool assert) + { +- void __iomem *addr = priv->base + priv->bank_ofs[id / RST_NR_PER_BANK]; +- u32 val; +- +- val = readl(addr); +- if (assert) +- val |= BIT(id % RST_NR_PER_BANK); +- else +- val &= ~BIT(id % RST_NR_PER_BANK); +- writel(val, addr); ++ u16 offset = priv->bank_ofs[id / RST_NR_PER_BANK]; + +- return 0; ++ return regmap_update_bits(priv->map, offset, ++ BIT(id % RST_NR_PER_BANK), ++ assert ? BIT(id % RST_NR_PER_BANK) : 0); + } + + static int airoha_reset_assert(struct reset_ctl *reset_ctl) +@@ -123,11 +118,16 @@ static int airoha_reset_status(struct re + { + struct airoha_reset_priv *priv = dev_get_priv(reset_ctl->dev); + int id = reset_ctl->id; +- void __iomem *addr; ++ u16 offset; ++ u32 val; ++ int ret; + +- addr = priv->base + priv->bank_ofs[id / RST_NR_PER_BANK]; ++ offset = priv->bank_ofs[id / RST_NR_PER_BANK]; ++ ret = regmap_read(priv->map, offset, &val); ++ if (ret) ++ return ret; + +- return !!(readl(addr) & BIT(id % RST_NR_PER_BANK)); ++ return !!(val & BIT(id % RST_NR_PER_BANK)); + } + + static int airoha_reset_xlate(struct reset_ctl *reset_ctl, +@@ -153,10 +153,11 @@ static struct reset_ops airoha_reset_ops + static int airoha_reset_probe(struct udevice *dev) + { + struct airoha_reset_priv *priv = dev_get_priv(dev); ++ int ret; + +- priv->base = dev_remap_addr(dev); +- if (!priv->base) +- return -ENOMEM; ++ ret = regmap_init_mem(dev_ofnode(dev), &priv->map); ++ if (ret) ++ return ret; + + priv->bank_ofs = en7581_rst_ofs; + priv->idx_map = en7581_rst_map; diff --git a/package/boot/uboot-airoha/patches/303-reset-airoha-Add-support-for-Airoha-AN7583-reset.patch b/package/boot/uboot-airoha/patches/303-reset-airoha-Add-support-for-Airoha-AN7583-reset.patch new file mode 100644 index 0000000000..033814f539 --- /dev/null +++ b/package/boot/uboot-airoha/patches/303-reset-airoha-Add-support-for-Airoha-AN7583-reset.patch @@ -0,0 +1,225 @@ +From 23031ad51d55361be507b83307f55995e0204188 Mon Sep 17 00:00:00 2001 +From: Christian Marangi +Date: Tue, 29 Apr 2025 13:33:35 +0200 +Subject: [PATCH 4/6] reset: airoha: Add support for Airoha AN7583 reset + +Adapt the Airoha reset driver to support Airoha AN7583 node structure. +In AN7583 the register is exposed by the parent syscon hence a different +logic needs to be applied. Also the reset line differ from AN7581 hence +a dedicated table is needed. + +Signed-off-by: Christian Marangi +--- + drivers/reset/reset-airoha.c | 94 ++++++++++++++++++- + .../dt-bindings/reset/airoha,an7583-reset.h | 61 ++++++++++++ + 2 files changed, 153 insertions(+), 2 deletions(-) + create mode 100644 include/dt-bindings/reset/airoha,an7583-reset.h + +--- a/drivers/reset/reset-airoha.c ++++ b/drivers/reset/reset-airoha.c +@@ -11,8 +11,10 @@ + #include + #include + #include ++#include + + #include ++#include + + #define RST_NR_PER_BANK 32 + +@@ -22,6 +24,7 @@ + struct airoha_reset_priv { + const u16 *bank_ofs; + const u16 *idx_map; ++ int num_rsts; + struct regmap *map; + }; + +@@ -88,6 +91,59 @@ 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_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) + { +@@ -135,7 +191,7 @@ static int airoha_reset_xlate(struct res + { + struct airoha_reset_priv *priv = dev_get_priv(reset_ctl->dev); + +- if (args->args[0] >= ARRAY_SIZE(en7581_rst_map)) ++ if (args->args[0] >= priv->num_rsts) + return -EINVAL; + + reset_ctl->id = priv->idx_map[args->args[0]]; +@@ -150,7 +206,7 @@ static struct reset_ops airoha_reset_ops + .rst_status = airoha_reset_status, + }; + +-static int airoha_reset_probe(struct udevice *dev) ++static int an7581_reset_probe(struct udevice *dev) + { + struct airoha_reset_priv *priv = dev_get_priv(dev); + int ret; +@@ -161,10 +217,44 @@ static int airoha_reset_probe(struct ude + + priv->bank_ofs = en7581_rst_ofs; + priv->idx_map = en7581_rst_map; ++ priv->num_rsts = ARRAY_SIZE(en7581_rst_map); + + return 0; + } + ++static int an7583_reset_probe(struct udevice *dev) ++{ ++ struct airoha_reset_priv *priv = dev_get_priv(dev); ++ ofnode pnode, scu_node = dev_ofnode(dev); ++ ++ pnode = ofnode_get_parent(scu_node); ++ if (!ofnode_valid(pnode)) ++ return -EINVAL; ++ ++ priv->map = syscon_node_to_regmap(pnode); ++ if (IS_ERR(priv->map)) ++ return PTR_ERR(priv->map); ++ ++ priv->bank_ofs = en7581_rst_ofs; ++ priv->idx_map = an7583_rst_map; ++ priv->num_rsts = ARRAY_SIZE(an7583_rst_map); ++ ++ return 0; ++} ++ ++static int airoha_reset_probe(struct udevice *dev) ++{ ++ if (ofnode_device_is_compatible(dev_ofnode(dev), ++ "airoha,en7581-scu")) ++ return an7581_reset_probe(dev); ++ ++ if (ofnode_device_is_compatible(dev_ofnode(dev), ++ "airoha,an7583-scu")) ++ return an7583_reset_probe(dev); ++ ++ return -ENODEV; ++} ++ + U_BOOT_DRIVER(airoha_reset) = { + .name = "airoha-reset", + .id = UCLASS_RESET, +--- /dev/null ++++ b/include/dt-bindings/reset/airoha,an7583-reset.h +@@ -0,0 +1,61 @@ ++// SPDX-License-Identifier: GPL-2.0-only ++/* ++ * Copyright (c) 2024 AIROHA Inc ++ * Author: Christian Marangi ++ */ ++ ++#ifndef __DT_BINDINGS_RESET_CONTROLLER_AIROHA_AN7583_H_ ++#define __DT_BINDINGS_RESET_CONTROLLER_AIROHA_AN7583_H_ ++ ++/* RST_CTRL2 */ ++#define AN7583_XPON_PHY_RST 0 ++#define AN7583_GPON_OLT_RST 1 ++#define AN7583_CPU_TIMER2_RST 2 ++#define AN7583_HSUART_RST 3 ++#define AN7583_UART4_RST 4 ++#define AN7583_UART5_RST 5 ++#define AN7583_I2C2_RST 6 ++#define AN7583_XSI_MAC_RST 7 ++#define AN7583_XSI_PHY_RST 8 ++#define AN7583_NPU_RST 9 ++#define AN7583_TRNG_MSTART_RST 10 ++#define AN7583_DUAL_HSI0_RST 11 ++#define AN7583_DUAL_HSI1_RST 12 ++#define AN7583_DUAL_HSI0_MAC_RST 13 ++#define AN7583_DUAL_HSI1_MAC_RST 14 ++#define AN7583_WDMA_RST 15 ++#define AN7583_WOE0_RST 16 ++#define AN7583_HSDMA_RST 17 ++#define AN7583_TDMA_RST 18 ++#define AN7583_EMMC_RST 19 ++#define AN7583_SOE_RST 20 ++#define AN7583_XFP_MAC_RST 21 ++#define AN7583_MDIO0 22 ++#define AN7583_MDIO1 23 ++/* RST_CTRL1 */ ++#define AN7583_PCM1_ZSI_ISI_RST 24 ++#define AN7583_FE_PDMA_RST 25 ++#define AN7583_FE_QDMA_RST 26 ++#define AN7583_PCM_SPIWP_RST 27 ++#define AN7583_CRYPTO_RST 28 ++#define AN7583_TIMER_RST 29 ++#define AN7583_PCM1_RST 30 ++#define AN7583_UART_RST 31 ++#define AN7583_GPIO_RST 32 ++#define AN7583_GDMA_RST 33 ++#define AN7583_I2C_MASTER_RST 34 ++#define AN7583_PCM2_ZSI_ISI_RST 35 ++#define AN7583_SFC_RST 36 ++#define AN7583_UART2_RST 37 ++#define AN7583_GDMP_RST 38 ++#define AN7583_FE_RST 39 ++#define AN7583_USB_HOST_P0_RST 40 ++#define AN7583_GSW_RST 41 ++#define AN7583_SFC2_PCM_RST 42 ++#define AN7583_PCIE0_RST 43 ++#define AN7583_PCIE1_RST 44 ++#define AN7583_CPU_TIMER_RST 45 ++#define AN7583_PCIE_HB_RST 46 ++#define AN7583_XPON_MAC_RST 47 ++ ++#endif /* __DT_BINDINGS_RESET_CONTROLLER_AIROHA_AN7583_H_ */ diff --git a/package/boot/uboot-airoha/patches/304-net-airoha-add-support-for-Airoha-AN7583.patch b/package/boot/uboot-airoha/patches/304-net-airoha-add-support-for-Airoha-AN7583.patch new file mode 100644 index 0000000000..bc9eb3c610 --- /dev/null +++ b/package/boot/uboot-airoha/patches/304-net-airoha-add-support-for-Airoha-AN7583.patch @@ -0,0 +1,279 @@ +From 289503869e5580658035e82d91b02a43c775f1a1 Mon Sep 17 00:00:00 2001 +From: Christian Marangi +Date: Mon, 19 May 2025 14:29:53 +0200 +Subject: [PATCH 1/4] net: airoha: add support for Airoha AN7583 + +Add support for Ethernet controller present in Airoha AN7583. This +follow the same implementation of Airoha AN7581 with the only difference +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 +--- + drivers/net/airoha_eth.c | 168 ++++++++++++++++++++++++++++++++++----- + 1 file changed, 147 insertions(+), 21 deletions(-) + +--- a/drivers/net/airoha_eth.c ++++ b/drivers/net/airoha_eth.c +@@ -20,6 +20,7 @@ + #include + #include + #include ++#include + #include + + #define AIROHA_MAX_NUM_GDM_PORTS 1 +@@ -27,6 +28,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 +@@ -77,6 +83,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 +@@ -311,6 +330,26 @@ struct airoha_eth { + struct airoha_gdm_port *ports[AIROHA_MAX_NUM_GDM_PORTS]; + }; + ++struct airoha_eth_soc_data { ++ int num_xsi_rsts; ++ const char * const *xsi_rsts_names; ++ ofnode (*get_scu_node)(struct udevice *dev); ++ const char *switch_compatible; ++}; ++ ++static const char * const en7581_xsi_rsts_names[] = { ++ "hsi0-mac", ++ "hsi1-mac", ++ "hsi-mac", ++ "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); +@@ -351,8 +390,12 @@ static u32 airoha_rmw(void __iomem *base + #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 void airoha_fe_maccr_init(struct airoha_eth *eth) + { +@@ -652,10 +695,12 @@ static int airoha_hw_init(struct udevice + + static int airoha_switch_init(struct udevice *dev, struct airoha_eth *eth) + { ++ struct airoha_eth_soc_data *data = (void *)dev_get_driver_data(dev); + ofnode switch_node; + fdt_addr_t addr; + +- switch_node = ofnode_by_compatible(ofnode_null(), "airoha,en7581-switch"); ++ switch_node = ofnode_by_compatible(ofnode_null(), ++ data->switch_compatible); + if (!ofnode_valid(switch_node)) + return -EINVAL; + +@@ -687,17 +732,71 @@ static int airoha_switch_init(struct ude + 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; + } + + static int airoha_eth_probe(struct udevice *dev) + { ++ struct airoha_eth_soc_data *data = (void *)dev_get_driver_data(dev); + struct airoha_eth *eth = dev_get_priv(dev); + struct regmap *scu_regmap; + ofnode scu_node; +- int ret; ++ int i, ret; + +- scu_node = ofnode_by_compatible(ofnode_null(), "airoha,en7581-scu"); ++ scu_node = data->get_scu_node(dev); + if (!ofnode_valid(scu_node)) + return -EINVAL; + +@@ -721,11 +820,11 @@ static int airoha_eth_probe(struct udevi + return -ENOMEM; + eth->rsts.count = AIROHA_MAX_NUM_RSTS; + +- eth->xsi_rsts.resets = devm_kcalloc(dev, AIROHA_MAX_NUM_XSI_RSTS, ++ eth->xsi_rsts.resets = devm_kcalloc(dev, data->num_xsi_rsts, + sizeof(struct reset_ctl), GFP_KERNEL); + if (!eth->xsi_rsts.resets) + return -ENOMEM; +- eth->xsi_rsts.count = AIROHA_MAX_NUM_XSI_RSTS; ++ eth->xsi_rsts.count = data->num_xsi_rsts; + + ret = reset_get_by_name(dev, "fe", ð->rsts.resets[0]); + if (ret) +@@ -739,21 +838,12 @@ static int airoha_eth_probe(struct udevi + if (ret) + return ret; + +- ret = reset_get_by_name(dev, "hsi0-mac", ð->xsi_rsts.resets[0]); +- if (ret) +- return ret; +- +- ret = reset_get_by_name(dev, "hsi1-mac", ð->xsi_rsts.resets[1]); +- if (ret) +- return ret; +- +- ret = reset_get_by_name(dev, "hsi-mac", ð->xsi_rsts.resets[2]); +- if (ret) +- return ret; +- +- ret = reset_get_by_name(dev, "xfp-mac", ð->xsi_rsts.resets[3]); +- if (ret) +- return ret; ++ for (i = 0; i < data->num_xsi_rsts; i++) { ++ ret = reset_get_by_name(dev, data->xsi_rsts_names[i], ++ ð->xsi_rsts.resets[i]); ++ if (ret) ++ return ret; ++ } + + ret = airoha_hw_init(dev, eth); + if (ret) +@@ -924,8 +1014,44 @@ static int arht_eth_write_hwaddr(struct + return 0; + } + ++ ++static ofnode en7581_get_scu_node(struct udevice *dev) ++{ ++ return ofnode_by_compatible(ofnode_null(), "airoha,en7581-scu"); ++} ++ ++static ofnode an7583_get_scu_node(struct udevice *dev) ++{ ++ ofnode scu_node; ++ ++ scu_node = ofnode_by_compatible(ofnode_null(), "airoha,an7583-scu"); ++ if (!ofnode_valid(scu_node)) ++ return scu_node; ++ ++ return ofnode_get_parent(scu_node); ++} ++ ++static const struct airoha_eth_soc_data en7581_data = { ++ .xsi_rsts_names = en7581_xsi_rsts_names, ++ .num_xsi_rsts = ARRAY_SIZE(en7581_xsi_rsts_names), ++ .get_scu_node = en7581_get_scu_node, ++ .switch_compatible = "airoha,en7581-switch", ++}; ++ ++static const struct airoha_eth_soc_data an7583_data = { ++ .xsi_rsts_names = an7583_xsi_rsts_names, ++ .num_xsi_rsts = ARRAY_SIZE(an7583_xsi_rsts_names), ++ .get_scu_node = an7583_get_scu_node, ++ .switch_compatible = "airoha,an7583-switch", ++}; ++ + static const struct udevice_id airoha_eth_ids[] = { +- { .compatible = "airoha,en7581-eth" }, ++ { .compatible = "airoha,en7581-eth", ++ .data = (ulong)&en7581_data, ++ }, ++ { .compatible = "airoha,an7583-eth", ++ .data = (ulong)&an7583_data, ++ }, + }; + + static const struct eth_ops airoha_eth_ops = { diff --git a/package/boot/uboot-airoha/patches/305-airoha-add-Ethernet-node-in-AN7583-dtsi.patch b/package/boot/uboot-airoha/patches/305-airoha-add-Ethernet-node-in-AN7583-dtsi.patch new file mode 100644 index 0000000000..8873af7c53 --- /dev/null +++ b/package/boot/uboot-airoha/patches/305-airoha-add-Ethernet-node-in-AN7583-dtsi.patch @@ -0,0 +1,45 @@ +From 613d695d0939cbbe6b66933267e3a4be263e1c7b Mon Sep 17 00:00:00 2001 +From: Christian Marangi +Date: Mon, 19 May 2025 14:31:59 +0200 +Subject: [PATCH 2/4] airoha: add Ethernet node in AN7583 dtsi + +Add Ethernet node in AN7583 dtsi to add support for the integrated +Ethernet Controller. + +Signed-off-by: Christian Marangi +--- + arch/arm/dts/an7583.dtsi | 23 +++++++++++++++++++++++ + 1 file changed, 23 insertions(+) + +--- 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>; diff --git a/package/boot/uboot-airoha/patches/306-airoha-add-MMC-node-for-Airoha-AN7583.patch b/package/boot/uboot-airoha/patches/306-airoha-add-MMC-node-for-Airoha-AN7583.patch new file mode 100644 index 0000000000..ecd225df1a --- /dev/null +++ b/package/boot/uboot-airoha/patches/306-airoha-add-MMC-node-for-Airoha-AN7583.patch @@ -0,0 +1,65 @@ +From 1a3039c1e3a194b3f1e72b4506f8bdcd5b10fbbf Mon Sep 17 00:00:00 2001 +From: Christian Marangi +Date: Mon, 19 May 2025 14:52:26 +0200 +Subject: [PATCH] airoha: add MMC node for Airoha AN7583 + +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 +--- + arch/arm/dts/an7583.dtsi | 33 +++++++++++++++++++++++++++++++++ + 1 file changed, 33 insertions(+) + +--- a/arch/arm/dts/an7583.dtsi ++++ b/arch/arm/dts/an7583.dtsi +@@ -105,6 +105,21 @@ + ; + }; + ++ 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 = ; ++ 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>; diff --git a/package/boot/uboot-airoha/patches/500-net-airoha-Fix-spurious-Airoha-Ethernet-stall.patch b/package/boot/uboot-airoha/patches/500-net-airoha-Fix-spurious-Airoha-Ethernet-stall.patch new file mode 100644 index 0000000000..7931c58067 --- /dev/null +++ b/package/boot/uboot-airoha/patches/500-net-airoha-Fix-spurious-Airoha-Ethernet-stall.patch @@ -0,0 +1,133 @@ +From 0343b5c2a754ca20f5155a8f3c6d58e887b9dd4f Mon Sep 17 00:00:00 2001 +From: Christian Marangi +Date: Tue, 20 May 2025 16:32:31 +0200 +Subject: [PATCH] net: airoha: Fix spurious Airoha Ethernet stall + +It was reported that sometimes the Airoha Ethernet driver stall and a +reset is needed to actually receive packet. + +This seems to be related in the logic with how the CPU and DMA counter +are handled for the RX path. The problem seems to be more evident when +multiple device are connected to the Ethernet port. + +To handle this, drop local tracking of the current CPU/DMA counter and +base everything on the current register by reading them and using the +descriptor directly. + +Fixes: ee0f4afa982e ("net: airoha: Add Airoha Ethernet driver") +Signed-off-by: Christian Marangi +--- + drivers/net/airoha_eth.c | 32 +++++++++++++++++--------------- + 1 file changed, 17 insertions(+), 15 deletions(-) + +--- a/drivers/net/airoha_eth.c ++++ b/drivers/net/airoha_eth.c +@@ -286,7 +286,6 @@ struct airoha_qdma_fwd_desc { + + struct airoha_queue { + struct airoha_qdma_desc *desc; +- u16 head; + + int ndesc; + }; +@@ -452,7 +451,6 @@ static int airoha_qdma_init_rx_queue(str + unsigned long dma_addr; + + q->ndesc = ndesc; +- q->head = 0; + + q->desc = dma_alloc_coherent(q->ndesc * sizeof(*q->desc), &dma_addr); + if (!q->desc) +@@ -471,7 +469,7 @@ static int airoha_qdma_init_rx_queue(str + airoha_qdma_rmw(qdma, REG_RX_CPU_IDX(qid), RX_RING_CPU_IDX_MASK, + FIELD_PREP(RX_RING_CPU_IDX_MASK, q->ndesc - 1)); + airoha_qdma_rmw(qdma, REG_RX_DMA_IDX(qid), RX_RING_DMA_IDX_MASK, +- FIELD_PREP(RX_RING_DMA_IDX_MASK, q->head)); ++ FIELD_PREP(RX_RING_DMA_IDX_MASK, 0)); + + return 0; + } +@@ -499,7 +497,6 @@ static int airoha_qdma_init_tx_queue(str + unsigned long dma_addr; + + q->ndesc = size; +- q->head = 0; + + q->desc = dma_alloc_coherent(q->ndesc * sizeof(*q->desc), &dma_addr); + if (!q->desc) +@@ -510,9 +507,9 @@ static int airoha_qdma_init_tx_queue(str + + airoha_qdma_wr(qdma, REG_TX_RING_BASE(qid), dma_addr); + airoha_qdma_rmw(qdma, REG_TX_CPU_IDX(qid), TX_RING_CPU_IDX_MASK, +- FIELD_PREP(TX_RING_CPU_IDX_MASK, q->head)); ++ FIELD_PREP(TX_RING_CPU_IDX_MASK, 0)); + airoha_qdma_rmw(qdma, REG_TX_DMA_IDX(qid), TX_RING_DMA_IDX_MASK, +- FIELD_PREP(TX_RING_DMA_IDX_MASK, q->head)); ++ FIELD_PREP(TX_RING_DMA_IDX_MASK, 0)); + + return 0; + } +@@ -898,8 +895,10 @@ static int airoha_eth_send(struct udevic + + qid = 0; + q = &qdma->q_tx[qid]; +- desc = &q->desc[q->head]; +- index = (q->head + 1) % q->ndesc; ++ ++ index = airoha_qdma_rr(qdma, REG_TX_CPU_IDX(qid)); ++ desc = &q->desc[index]; ++ index = (index + 1) % q->ndesc; + + fport = 1; + +@@ -934,7 +933,6 @@ static int airoha_eth_send(struct udevic + if (!(desc->ctrl & QDMA_DESC_DONE_MASK)) + return -EAGAIN; + +- q->head = index; + airoha_qdma_rmw(qdma, REG_IRQ_CLEAR_LEN(0), + IRQ_CLEAR_LEN_MASK, 1); + +@@ -947,12 +945,15 @@ static int airoha_eth_recv(struct udevic + struct airoha_qdma *qdma = ð->qdma[0]; + struct airoha_qdma_desc *desc; + struct airoha_queue *q; ++ int qid, index; + u16 length; +- int qid; + + qid = 0; + q = &qdma->q_rx[qid]; +- desc = &q->desc[q->head]; ++ ++ index = airoha_qdma_rr(qdma, REG_RX_CPU_IDX(qid)); ++ index = (index + 1) % q->ndesc; ++ desc = &q->desc[index]; + + dma_unmap_single(virt_to_phys(desc), sizeof(*desc), + DMA_FROM_DEVICE); +@@ -974,7 +975,7 @@ static int arht_eth_free_pkt(struct udev + struct airoha_eth *eth = dev_get_priv(dev); + struct airoha_qdma *qdma = ð->qdma[0]; + struct airoha_queue *q; +- int qid; ++ int qid, index; + + if (!packet) + return 0; +@@ -984,11 +985,12 @@ static int arht_eth_free_pkt(struct udev + + dma_map_single(packet, length, DMA_TO_DEVICE); + +- airoha_qdma_reset_rx_desc(q, q->head, packet); ++ index = airoha_qdma_rr(qdma, REG_RX_DMA_IDX(qid)); ++ airoha_qdma_reset_rx_desc(q, index, packet); + ++ index = (index + 1) % q->ndesc; + airoha_qdma_rmw(qdma, REG_RX_CPU_IDX(qid), RX_RING_CPU_IDX_MASK, +- FIELD_PREP(RX_RING_CPU_IDX_MASK, q->head)); +- q->head = (q->head + 1) % q->ndesc; ++ FIELD_PREP(RX_RING_CPU_IDX_MASK, index)); + + return 0; + } diff --git a/package/boot/uboot-airoha/patches/900-airoha-enable-UBI-support-and-define-default-partiti.patch b/package/boot/uboot-airoha/patches/900-airoha-enable-UBI-support-and-define-default-partiti.patch new file mode 100644 index 0000000000..e758d310e5 --- /dev/null +++ b/package/boot/uboot-airoha/patches/900-airoha-enable-UBI-support-and-define-default-partiti.patch @@ -0,0 +1,113 @@ +From 28a72d957b897e7f7212c11f99052a32b0f6abc4 Mon Sep 17 00:00:00 2001 +From: Christian Marangi +Date: Wed, 28 May 2025 03:10:53 +0200 +Subject: [PATCH 1/2] airoha: enable UBI support and define default partition + +Signed-off-by: Christian Marangi +--- + arch/arm/dts/an7581-u-boot.dtsi | 16 ++++++++++++++++ + arch/arm/dts/an7583-evb.dts | 22 ++++++++++++++++++++++ + configs/an7581_evb_defconfig | 16 ++++++++++++++++ + configs/an7583_evb_defconfig | 16 ++++++++++++++++ + 4 files changed, 70 insertions(+) + +--- a/arch/arm/dts/an7581-u-boot.dtsi ++++ b/arch/arm/dts/an7581-u-boot.dtsi +@@ -76,6 +76,22 @@ + spi-max-frequency = <50000000>; + spi-tx-bus-width = <1>; + spi-rx-bus-width = <2>; ++ ++ partitions { ++ compatible = "fixed-partitions"; ++ #address-cells = <1>; ++ #size-cells = <1>; ++ ++ bl2@0 { ++ label = "bl2"; ++ reg = <0x0 0x20000>; ++ }; ++ ++ ubi@20000 { ++ label = "ubi"; ++ reg = <0x20000 0x0>; ++ }; ++ }; + }; + }; + +--- a/arch/arm/dts/an7583-evb.dts ++++ b/arch/arm/dts/an7583-evb.dts +@@ -46,6 +46,28 @@ + }; + }; + ++&snfi { ++ status = "okay"; ++}; ++ ++&spi_nand { ++ partitions { ++ compatible = "fixed-partitions"; ++ #address-cells = <1>; ++ #size-cells = <1>; ++ ++ bl2@0 { ++ label = "bl2"; ++ reg = <0x0 0x20000>; ++ }; ++ ++ ubi@20000 { ++ label = "ubi"; ++ reg = <0x20000 0x0>; ++ }; ++ }; ++}; ++ + &pcie0 { + pinctrl-names = "default"; + pinctrl-0 = <&pcie0_rst_pins>; +--- a/configs/an7581_evb_defconfig ++++ b/configs/an7581_evb_defconfig +@@ -77,3 +77,19 @@ CONFIG_SPI=y + CONFIG_DM_SPI=y + CONFIG_AIROHA_SNFI_SPI=y + CONFIG_SHA512=y ++CONFIG_CMD_UBI=y ++# CONFIG_CMD_UBI_RENAME is not set ++CONFIG_CMD_UBIFS=y ++CONFIG_ENV_IS_IN_UBI=y ++CONFIG_ENV_UBI_PART="ubi" ++CONFIG_ENV_UBI_VOLUME="ubootenv" ++CONFIG_ENV_UBI_VOLUME_REDUND="ubootenv2" ++CONFIG_ENV_UBI_VID_OFFSET=0 ++CONFIG_MTD_UBI=y ++CONFIG_MTD_UBI_MODULE=y ++CONFIG_MTD_UBI_WL_THRESHOLD=4096 ++CONFIG_MTD_UBI_BEB_LIMIT=20 ++# CONFIG_MTD_UBI_FASTMAP is not set ++CONFIG_UBI_BLOCK=y ++# CONFIG_UBIFS_SILENCE_MSG is not set ++# CONFIG_UBIFS_SILENCE_DEBUG_DUMP is not set +--- a/configs/an7583_evb_defconfig ++++ b/configs/an7583_evb_defconfig +@@ -79,3 +79,19 @@ CONFIG_SHA512=y + CONFIG_AIROHA_ETH=y + CONFIG_MMC_MTK=y + CONFIG_AIROHA_SNFI_SPI=y ++CONFIG_CMD_UBI=y ++# CONFIG_CMD_UBI_RENAME is not set ++CONFIG_CMD_UBIFS=y ++CONFIG_ENV_IS_IN_UBI=y ++CONFIG_ENV_UBI_PART="ubi" ++CONFIG_ENV_UBI_VOLUME="ubootenv" ++CONFIG_ENV_UBI_VOLUME_REDUND="ubootenv2" ++CONFIG_ENV_UBI_VID_OFFSET=0 ++CONFIG_MTD_UBI=y ++CONFIG_MTD_UBI_MODULE=y ++CONFIG_MTD_UBI_WL_THRESHOLD=4096 ++CONFIG_MTD_UBI_BEB_LIMIT=20 ++# CONFIG_MTD_UBI_FASTMAP is not set ++CONFIG_UBI_BLOCK=y ++# CONFIG_UBIFS_SILENCE_MSG is not set ++# CONFIG_UBIFS_SILENCE_DEBUG_DUMP is not set diff --git a/package/boot/uboot-airoha/patches/901-airoha-add-default-configuration.patch b/package/boot/uboot-airoha/patches/901-airoha-add-default-configuration.patch new file mode 100644 index 0000000000..595848c731 --- /dev/null +++ b/package/boot/uboot-airoha/patches/901-airoha-add-default-configuration.patch @@ -0,0 +1,45 @@ +From f85e675d7be222d88246bfdb42a1faac92f1eb63 Mon Sep 17 00:00:00 2001 +From: Christian Marangi +Date: Wed, 28 May 2025 03:18:32 +0200 +Subject: [PATCH 2/2] airoha: add default configuration + +Signed-off-by: Christian Marangi +--- + configs/an7581_evb_defconfig | 2 ++ + configs/an7583_evb_defconfig | 2 ++ + defenvs/an7581_rfb_env | 3 +++ + defenvs/an7583_rfb_env | 3 +++ + 4 files changed, 10 insertions(+) + create mode 100644 defenvs/an7581_rfb_env + create mode 100644 defenvs/an7583_rfb_env + +--- a/configs/an7581_evb_defconfig ++++ b/configs/an7581_evb_defconfig +@@ -93,3 +93,5 @@ CONFIG_MTD_UBI_BEB_LIMIT=20 + CONFIG_UBI_BLOCK=y + # CONFIG_UBIFS_SILENCE_MSG is not set + # CONFIG_UBIFS_SILENCE_DEBUG_DUMP is not set ++CONFIG_USE_DEFAULT_ENV_FILE=y ++CONFIG_DEFAULT_ENV_FILE="defenvs/an7581_rfb_env" +--- a/configs/an7583_evb_defconfig ++++ b/configs/an7583_evb_defconfig +@@ -95,3 +95,5 @@ CONFIG_MTD_UBI_BEB_LIMIT=20 + CONFIG_UBI_BLOCK=y + # CONFIG_UBIFS_SILENCE_MSG is not set + # CONFIG_UBIFS_SILENCE_DEBUG_DUMP is not set ++CONFIG_USE_DEFAULT_ENV_FILE=y ++CONFIG_DEFAULT_ENV_FILE="defenvs/an7583_rfb_env" +--- /dev/null ++++ b/defenvs/an7581_rfb_env +@@ -0,0 +1,4 @@ ++loadaddr=0x81800000 ++ipaddr=192.168.1.1 ++serverip=192.168.1.10 ++bootargs=ubi.mtd=ubi root=/dev/ubiblock0_5 rootwait +--- /dev/null ++++ b/defenvs/an7583_rfb_env +@@ -0,0 +1,4 @@ ++loadaddr=0x81800000 ++ipaddr=192.168.1.1 ++serverip=192.168.1.10 ++bootargs=ubi.mtd=ubi root=/dev/ubiblock0_5 rootwait