]> git.ipfire.org Git - thirdparty/openwrt.git/commitdiff
econet: add PCIe driver for EN751221 and enable wifi 22208/head
authorCaleb James DeLisle <cjd@cjdns.fr>
Fri, 27 Feb 2026 15:40:03 +0000 (15:40 +0000)
committerHauke Mehrtens <hauke@hauke-m.de>
Thu, 14 May 2026 18:34:20 +0000 (20:34 +0200)
Extend the EN7528 PCIe driver to EN751221 with a specific PHY
tuning ritual. Also enable wifi drivers on SmartFiber XP8421-B,
TpLink Archer VR1200V v2 and Zyxel PMG5617GA.

Signed-off-by: Caleb James DeLisle <cjd@cjdns.fr>
Link: https://github.com/openwrt/openwrt/pull/22208
Signed-off-by: Hauke Mehrtens <hauke@hauke-m.de>
target/linux/econet/dts/en751221.dtsi
target/linux/econet/dts/en751221_smartfiber_xp8421-b.dts
target/linux/econet/dts/en751221_tplink_archer-vr1200v-v2.dts
target/linux/econet/dts/en751221_zyxel_pmg5617ga.dts
target/linux/econet/en751221/config-6.12
target/linux/econet/image/en751221.mk
target/linux/econet/patches-6.12/912-pcie-add-en7528-pcie-and-phy-support.patch

index de1a2287cfddde97a13ea453fefb1b3c2ad62af0..7b749f88af08c42919f49f643f71ff2685c57ec7 100644 (file)
@@ -1,6 +1,7 @@
 // SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
 
 #include <dt-bindings/reset/econet,en751221-scu.h>
+#include <dt-bindings/clock/econet,en751221-scu.h>
 
 /dts-v1/;
 
                reg = <0x1fa20000 0x388>;
        };
 
+       pcie_phy1: pcie-phy@1fac0000 {
+               compatible = "econet,en751221-pcie-phy1";
+               reg = <0x1fac0000 0x1000>;
+               #phy-cells = <0>;
+       };
+
+       pcie_phy0: pcie-phy@1faf2000 {
+               compatible = "econet,en751221-pcie-phy0";
+               reg = <0x1faf2000 0x1000>;
+               #phy-cells = <0>;
+       };
+
        intc: interrupt-controller@1fb40000 {
                compatible = "econet,en751221-intc";
                reg = <0x1fb40000 0x100>;
                };
        };
 
+       pciecfg: pciecfg@1fb80000 {
+               compatible = "mediatek,generic-pciecfg", "syscon";
+               reg = <0x1fb80000 0x1000>;
+       };
+
+       pcie0: pcie@1fb81000 {
+               compatible = "econet,en7528-pcie";
+               device_type = "pci";
+               reg = <0x1fb81000 0x1000>;
+               reg-names = "port0";
+               linux,pci-domain = <0>;
+               #address-cells = <3>;
+               #size-cells = <2>;
+               interrupt-parent = <&intc>;
+               interrupts = <23>;
+               interrupt-names = "pcie_irq";
+               clocks = <&scuclk EN751221_CLK_PCIE>;
+               clock-names = "sys_ck0";
+               phys = <&pcie_phy0>;
+               phy-names = "pcie-phy0";
+               bus-range = <0x00 0xff>;
+               ranges = <0x01000000 0 0x00000000 0x1f600000 0 0x00008000>,
+                        <0x82000000 0 0x20000000 0x20000000 0 0x08000000>;
+               status = "disabled";
+
+               #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>;
+
+               pcie_intc0: interrupt-controller {
+                       interrupt-controller;
+                       #address-cells = <0>;
+                       #interrupt-cells = <1>;
+               };
+
+               slot0: pcie@0,0 {
+                       reg = <0x0000 0 0 0 0>;
+                       device_type = "pci";
+                       #address-cells = <3>;
+                       #size-cells = <2>;
+                       ranges;
+               };
+       };
+
+       pcie1: pcie@1fb83000 {
+               compatible = "econet,en7528-pcie";
+               device_type = "pci";
+               reg = <0x1fb83000 0x1000>;
+               reg-names = "port1";
+               linux,pci-domain = <1>;
+               #address-cells = <3>;
+               #size-cells = <2>;
+               interrupt-parent = <&intc>;
+               interrupts = <24>;
+               interrupt-names = "pcie_irq";
+               clocks = <&scuclk EN751221_CLK_PCIE>;
+               clock-names = "sys_ck1";
+               phys = <&pcie_phy1>;
+               phy-names = "pcie-phy1";
+               bus-range = <0x00 0xff>;
+               ranges = <0x81000000 0 0x00000000 0x1f608000 0 0x00008000>,
+                        <0x82000000 0 0x28000000 0x28000000 0 0x08000000>;
+               status = "disabled";
+
+               #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>;
+
+               pcie_intc1: interrupt-controller {
+                       interrupt-controller;
+                       #address-cells = <0>;
+                       #interrupt-cells = <1>;
+               };
+
+               slot1: pcie@1,0 {
+                       reg = <0x0800 0 0 0 0>;
+                       #address-cells = <3>;
+                       #size-cells = <2>;
+                       ranges;
+               };
+       };
+
     usb: usb@1fb90000 {
             compatible = "mediatek,mt8173-xhci", "mediatek,mtk-xhci";
             reg = <0x1fb90000 0x4000>,
index 4599d3405355e22272ac8604d59cc7667c2c24b3..5f35f2189f34d7901165b9dd17f29f8b1e57646e 100644 (file)
        nvmem-cells = <&macaddr_bootloader_ff48 0>;
        nvmem-cell-names = "mac-address";
 };
+
+&pcie0 {
+       status = "okay";
+};
+&slot0 {
+       wifi@0,0 {
+               /* MT7612E */
+               compatible = "mediatek,mt76";
+               reg = <0x0000 0 0 0 0>;
+               nvmem-cells = <&eeprom_reserve_180040>, <&macaddr_bootloader_ff48 1>;
+               nvmem-cell-names = "eeprom", "mac-address";
+       };
+};
+&pcie1 {
+       status = "okay";
+};
+&slot1 {
+       wifi@0,0 {
+               /* MT7592 */
+               compatible = "mediatek,mt76";
+               reg = <0x0000 0 0 0 0>;
+               nvmem-cells = <&eeprom_reserve_140000>, <&macaddr_bootloader_ff48 2>;
+               nvmem-cell-names = "eeprom", "mac-address";
+       };
+};
index 2bc44d11cd5caf00ed487bbef205036174a292c3..6aa6aa115c10a56e20ddae5ccf0425cc36a21cc0 100644 (file)
        nvmem-cells = <&macaddr_misc_8f100 0>;
        nvmem-cell-names = "mac-address";
 };
+
+&pcie0 {
+       status = "okay";
+};
+&slot0 {
+       wifi@0,0 {
+               /* MT7592 */
+               compatible = "mediatek,mt76";
+               reg = <0x0000 0 0 0 0>;
+               nvmem-cells = <&eeprom_misc_80000>, <&macaddr_misc_8f100 1>;
+               nvmem-cell-names = "eeprom", "mac-address";
+       };
+};
+&pcie1 {
+       status = "okay";
+};
+&slot1 {
+       wifi@0,0 {
+               /* MT7613BE */
+               compatible = "mediatek,mt76";
+               reg = <0x0000 0 0 0 0>;
+               nvmem-cells = <&eeprom_misc_a0000>, <&macaddr_misc_8f100 2>;
+               nvmem-cell-names = "eeprom", "mac-address";
+       };
+};
index b6a95801bec646b233df22d9da3152869cc71f7b..73f9af674e8a5c5056217496d402b44285898978 100644 (file)
                partition@7540000 {
                        label = "reservearea";
                        reg = <0x007540000 0x000080000>;
+                       nvmem-layout {
+                                       compatible = "fixed-layout";
+                                       #address-cells = <1>;
+                                       #size-cells = <1>;
+
+                                       eeprom_reserve_60000: eeprom@60000 {
+                                                       /* MT7592 */
+                                                       /* This overlaps the MT7612E EEPROM, but MT7603E demands
+                                                        * 1024 bytes of EEPROM even though only 512 bytes are used.
+                                                        */
+                                                       reg = <0x60000 0x400>;
+                                       };
+
+                                       eeprom_reserve_60200: eeprom@60200 {
+                                                       /* MT7612E */
+                                                       reg = <0x60200 0x200>;
+                                       };
+                       };
                };
        };
 };
+
+&pcie0 {
+       status = "okay";
+};
+&slot0 {
+       wifi@0,0 {
+               /* MT7592 */
+               compatible = "mediatek,mt76";
+               reg = <0x0000 0 0 0 0>;
+               nvmem-cells = <&eeprom_reserve_60000>;
+               nvmem-cell-names = "eeprom";
+       };
+};
+&pcie1 {
+       status = "okay";
+};
+&slot1 {
+       wifi@0,0 {
+               /* MT7612E */
+               compatible = "mediatek,mt76";
+               reg = <0x0000 0 0 0 0>;
+               nvmem-cells = <&eeprom_reserve_60200>;
+               nvmem-cell-names = "eeprom";
+       };
+};
index 5357f6f9883ab659fa3f1d1190974d05447de478..d68d0ca44d17af338056bcc42ff5df92f83fa242 100644 (file)
@@ -2,6 +2,7 @@ CONFIG_ARCH_32BIT_OFF_T=y
 CONFIG_ARCH_KEEP_MEMBLOCK=y
 CONFIG_ARCH_MMAP_RND_BITS_MAX=15
 CONFIG_ARCH_MMAP_RND_COMPAT_BITS_MAX=15
+CONFIG_BLK_MQ_PCI=y
 CONFIG_CLKSRC_MMIO=y
 CONFIG_CLONE_BACKWARDS=y
 CONFIG_COMMON_CLK=y
@@ -69,7 +70,9 @@ CONFIG_GENERIC_LIB_ASHRDI3=y
 CONFIG_GENERIC_LIB_CMPDI2=y
 CONFIG_GENERIC_LIB_LSHRDI3=y
 CONFIG_GENERIC_LIB_UCMPDI2=y
+CONFIG_GENERIC_MSI_IRQ=y
 CONFIG_GENERIC_PCI_IOMAP=y
+CONFIG_GENERIC_PHY=y
 CONFIG_GENERIC_SCHED_CLOCK=y
 CONFIG_GENERIC_SMP_IDLE_THREAD=y
 CONFIG_GENERIC_TIME_VSYSCALL=y
@@ -84,6 +87,7 @@ CONFIG_HZ_PERIODIC=y
 CONFIG_INITRAMFS_SOURCE=""
 CONFIG_IRQCHIP=y
 CONFIG_IRQ_DOMAIN=y
+CONFIG_IRQ_DOMAIN_HIERARCHY=y
 CONFIG_IRQ_FORCED_THREADING=y
 CONFIG_IRQ_MIPS_CPU=y
 CONFIG_IRQ_WORK=y
@@ -119,7 +123,6 @@ CONFIG_NET_EGRESS=y
 CONFIG_NET_FLOW_LIMIT=y
 CONFIG_NET_INGRESS=y
 CONFIG_NET_XGRESS=y
-CONFIG_NO_GENERIC_PCI_IOPORT_MAP=y
 CONFIG_NR_CPUS=2
 CONFIG_NVMEM=y
 CONFIG_NVMEM_LAYOUTS=y
@@ -135,15 +138,27 @@ CONFIG_PADATA=y
 CONFIG_PAGE_POOL=y
 CONFIG_PAGE_SIZE_LESS_THAN_256KB=y
 CONFIG_PAGE_SIZE_LESS_THAN_64KB=y
-CONFIG_PCI_DRIVERS_LEGACY=y
+CONFIG_PCI=y
+CONFIG_PCIEAER=y
+CONFIG_PCIEPORTBUS=y
+CONFIG_PCIE_MEDIATEK=y
+CONFIG_PCI_DISABLE_COMMON_QUIRKS=y
+CONFIG_PCI_DOMAINS=y
+CONFIG_PCI_DOMAINS_GENERIC=y
+CONFIG_PCI_DRIVERS_GENERIC=y
+CONFIG_PCI_MSI=y
+CONFIG_PCI_MSI_ARCH_FALLBACKS=y
 CONFIG_PERF_USE_VMALLOC=y
 CONFIG_PGTABLE_LEVELS=2
-# CONFIG_PHY_EN7528_PCIE is not set
+CONFIG_PHY_EN7528_PCIE=y
 CONFIG_PTP_1588_CLOCK_OPTIONAL=y
 CONFIG_QUEUED_RWLOCKS=y
 CONFIG_QUEUED_SPINLOCKS=y
 CONFIG_RANDSTRUCT_NONE=y
+CONFIG_RAS=y
 CONFIG_RATIONAL=y
+CONFIG_REGMAP=y
+CONFIG_REGMAP_MMIO=y
 CONFIG_RESET_CONTROLLER=y
 CONFIG_RFS_ACCEL=y
 CONFIG_RPS=y
index 126288bfecb2110834713ef01e1596260920a141..89fc0bdee2a865c19b5665afab3912a03fd7b393 100644 (file)
@@ -25,7 +25,7 @@ define Device/smartfiber_xp8421-b
   DEVICE_DTS := en751221_smartfiber_xp8421-b
   IMAGES := tclinux.trx
   IMAGE/tclinux.trx := append-kernel | lzma | tclinux-trx
-  DEVICE_PACKAGES := kmod-usb3
+  DEVICE_PACKAGES := kmod-usb3 kmod-mt7603 kmod-mt76x2
 endef
 TARGET_DEVICES += smartfiber_xp8421-b
 
@@ -41,6 +41,7 @@ define Device/tplink_archer-vr1200v-v2
   TPLINK_HWREVADD := 0x0
   TPLINK_HVERSION := 3
   DEVICE_DTS := en751221_tplink_archer-vr1200v-v2
+  DEVICE_PACKAGES := kmod-mt7603 kmod-mt7615e kmod-mt7663-firmware-ap
   IMAGES := sysupgrade.bin
   IMAGE/sysupgrade.bin := append-kernel | lzma | pad-to 4193792 | append-rootfs | \
     tplink-v2-header -R 0x400000
@@ -53,6 +54,6 @@ define Device/zyxel_pmg5617ga
   DEVICE_DTS := en751221_zyxel_pmg5617ga
   IMAGES := tclinux.trx
   IMAGE/tclinux.trx := append-kernel | lzma | tclinux-trx
-  DEVICE_PACKAGES := kmod-usb3
+  DEVICE_PACKAGES := kmod-usb3 kmod-mt7603 kmod-mt76x2
 endef
 TARGET_DEVICES += zyxel_pmg5617ga
index 917bd8a4808ba369b3770e7ac44c5f2ed91ae04a..ee8d1bdab9d36d45f4bb114fd8cedc8c6b86ad13 100644 (file)
        help
 --- a/arch/mips/econet/Kconfig
 +++ b/arch/mips/econet/Kconfig
-@@ -28,9 +28,11 @@ choice
+@@ -14,7 +14,9 @@ choice
+               select COMMON_CLK
+               select CPU_BIG_ENDIAN
+               select ECONET_EN751221_INTC
++              select HAVE_PCI
+               select IRQ_MIPS_CPU
++              select PCI_DRIVERS_GENERIC
+               select SMP
+               select SMP_UP
+               select SYS_SUPPORTS_SMP
+@@ -28,9 +30,11 @@ choice
                bool "EN7528 family"
                select COMMON_CLK
                select CPU_LITTLE_ENDIAN
                                           broadcom/    \
 --- /dev/null
 +++ b/drivers/phy/phy-en7528-pcie.c
-@@ -0,0 +1,119 @@
+@@ -0,0 +1,155 @@
 +// SPDX-License-Identifier: GPL-2.0+
 +/*
 + * Copyright (C) 2026 Ahmed Naseef <naseefkm@gmail.com>
 +#include <linux/platform_device.h>
 +#include <linux/regmap.h>
 +
-+struct en7528_pcie_phy_data {
++struct en7528_pcie_phy_op {
 +      u32 reg;
 +      u32 mask;
 +      u32 val;
-+      u32 max_reg;
 +};
 +
 +struct en7528_pcie_phy {
 +      struct regmap *regmap;
-+      const struct en7528_pcie_phy_data *data;
++      const struct en7528_pcie_phy_op *data;
 +};
 +
 +/* Port 0 PHY: set LCDDS_CLK_PH_INV for PLL operation */
-+static const struct en7528_pcie_phy_data en7528_phy_port0 = {
-+      .reg = 0x4a0,
-+      .mask = BIT(5),
-+      .val = BIT(5),
-+      .max_reg = 0x4a0,
++static const struct en7528_pcie_phy_op en7528_phy_port0[] = {
++      {
++              .reg = 0x4a0,
++              .mask = BIT(5),
++              .val = BIT(5),
++      },
++      { /* sentinel */ }
 +};
 +
 +/* Port 1 PHY: Rx impedance tuning, target R -5 Ohm */
-+static const struct en7528_pcie_phy_data en7528_phy_port1 = {
-+      .reg = 0xb2c,
-+      .mask = GENMASK(13, 12),
-+      .val = BIT(12),
-+      .max_reg = 0xb2c,
++static const struct en7528_pcie_phy_op en7528_phy_port1[] = {
++      {
++              .reg = 0xb2c,
++              .mask = GENMASK(13, 12),
++              .val = BIT(12),
++      },
++      { /* sentinel */ }
++};
++
++/* EN751221 Port 1 PHY */
++static const struct en7528_pcie_phy_op en751221_phy_port1[] = {
++      /* Rx Detection Timing for 7512 E1, 16*8 clock cycles  */
++      {
++              .reg = 0xa28,
++              .mask = GENMASK(17, 9),
++              .val = 16 << 9,
++      },
++      /* Same for different power mode */
++        {
++              .reg = 0xa2c,
++              .mask = GENMASK(8, 0),
++              .val = 16,
++      },
++      { /* sentinel */ }
 +};
 +
 +static int en7528_pcie_phy_init(struct phy *phy)
 +{
 +      struct en7528_pcie_phy *ephy = phy_get_drvdata(phy);
-+      const struct en7528_pcie_phy_data *data = ephy->data;
++      const struct en7528_pcie_phy_op *data = ephy->data;
++      int i, ret;
 +
-+      return regmap_update_bits(ephy->regmap, data->reg,
-+                                data->mask, data->val);
++      for (i = 0; data[i].mask || data[i].val; i++) {
++              if (i)
++                      usleep_range(1000, 2000);
++
++              ret = regmap_update_bits(ephy->regmap, data[i].reg,
++                                       data[i].mask, data[i].val);
++              if (ret)
++                      return ret;
++      }
++
++      return 0;
 +}
 +
 +static const struct phy_ops en7528_pcie_phy_ops = {
 +static int en7528_pcie_phy_probe(struct platform_device *pdev)
 +{
 +      struct device *dev = &pdev->dev;
-+      const struct en7528_pcie_phy_data *data;
++      const struct en7528_pcie_phy_op *data;
 +      struct regmap_config regmap_config = {
 +              .reg_bits = 32,
 +              .val_bits = 32,
 +      struct en7528_pcie_phy *ephy;
 +      void __iomem *base;
 +      struct phy *phy;
++      int i;
 +
 +      data = of_device_get_match_data(dev);
 +      if (!data)
 +      if (IS_ERR(base))
 +              return PTR_ERR(base);
 +
-+      regmap_config.max_register = data->max_reg;
++      for (i = 0; data[i].mask || data[i].val; i++)
++              if (data[i].reg > regmap_config.max_register)
++                      regmap_config.max_register = data[i].reg;
++
 +      ephy->regmap = devm_regmap_init_mmio(dev, base, &regmap_config);
 +      if (IS_ERR(ephy->regmap))
 +              return PTR_ERR(ephy->regmap);
 +}
 +
 +static const struct of_device_id en7528_pcie_phy_ids[] = {
-+      { .compatible = "econet,en7528-pcie-phy0", .data = &en7528_phy_port0 },
-+      { .compatible = "econet,en7528-pcie-phy1", .data = &en7528_phy_port1 },
++      { .compatible = "econet,en7528-pcie-phy0", .data = en7528_phy_port0 },
++      { .compatible = "econet,en7528-pcie-phy1", .data = en7528_phy_port1 },
++      { .compatible = "econet,en751221-pcie-phy0", .data = en7528_phy_port0 },
++      { .compatible = "econet,en751221-pcie-phy1", .data = en751221_phy_port1 },
 +      { /* sentinel */ }
 +};
 +MODULE_DEVICE_TABLE(of, en7528_pcie_phy_ids);