[openwrt/openwrt] ramips: PCIe driver improvements for mt7620 and mt7628

LEDE Commits lede-commits at lists.infradead.org
Wed Jun 18 11:36:35 PDT 2025


hauke pushed a commit to openwrt/openwrt.git, branch main:
https://git.openwrt.org/9b777547beefa491319498208310f0758b49c45d

commit 9b777547beefa491319498208310f0758b49c45d
Author: Shiji Yang <yangshiji66 at qq.com>
AuthorDate: Tue Mar 18 00:42:19 2025 +0800

    ramips: PCIe driver improvements for mt7620 and mt7628
    
    This patchset fixes some PCIe bridge register access issues and
    reworks the initialization procedure. It may bring some stability
    improvements. To match the driver changes, the memory remap range
    was extended and a PCIe reset pinctrl was added to mt7628an.dtsi.
    
    Link: https://lore.kernel.org/all/OSBPR01MB1670555F549B69B9A5E7F133BC72A@OSBPR01MB1670.jpnprd01.prod.outlook.com/
    Signed-off-by: Shiji Yang <yangshiji66 at qq.com>
    Link: https://github.com/openwrt/openwrt/pull/18299
    Signed-off-by: Hauke Mehrtens <hauke at hauke-m.de>
---
 target/linux/ramips/dts/mt7628an.dtsi              |  12 +-
 ...ips-pci-mt7620-fix-bridge-register-access.patch |  59 +++++++++
 ...-pci-mt7620-add-more-register-init-values.patch | 132 +++++++++++++++++++++
 ...ci-mt7620-rework-initialization-procedure.patch |  95 +++++++++++++++
 ...ips-pci-mt7620-fix-bridge-register-access.patch |  59 +++++++++
 ...-pci-mt7620-add-more-register-init-values.patch | 132 +++++++++++++++++++++
 ...ci-mt7620-rework-initialization-procedure.patch |  95 +++++++++++++++
 7 files changed, 583 insertions(+), 1 deletion(-)

diff --git a/target/linux/ramips/dts/mt7628an.dtsi b/target/linux/ramips/dts/mt7628an.dtsi
index 47dd4df276..34d68ff9b1 100644
--- a/target/linux/ramips/dts/mt7628an.dtsi
+++ b/target/linux/ramips/dts/mt7628an.dtsi
@@ -352,6 +352,13 @@
 			};
 		};
 
+		pcie_pins: pcie {
+			pcie_reset {
+				groups = "perst";
+				function = "perst";
+			};
+		};
+
 		refclk_pins: refclk {
 			refclk {
 				groups = "refclk";
@@ -464,7 +471,7 @@
 	pcie: pcie at 10140000 {
 		compatible = "mediatek,mt7620-pci";
 		reg = <0x10140000 0x100
-			0x10142000 0x100>;
+		       0x10142000 0x8000>;
 
 		#address-cells = <3>;
 		#size-cells = <2>;
@@ -472,6 +479,9 @@
 		interrupt-parent = <&cpuintc>;
 		interrupts = <4>;
 
+		pinctrl-names = "default";
+		pinctrl-0 = <&pcie_pins>;
+
 		resets = <&sysc 26>;
 		reset-names = "pcie0";
 
diff --git a/target/linux/ramips/patches-6.12/120-1-mips-pci-mt7620-fix-bridge-register-access.patch b/target/linux/ramips/patches-6.12/120-1-mips-pci-mt7620-fix-bridge-register-access.patch
new file mode 100644
index 0000000000..742e6b8cd5
--- /dev/null
+++ b/target/linux/ramips/patches-6.12/120-1-mips-pci-mt7620-fix-bridge-register-access.patch
@@ -0,0 +1,59 @@
+From: Shiji Yang <yangshiji66 at outlook.com>
+Date: Mon, 17 Mar 2025 20:35:44 +0800
+Subject: [PATCH 1/3] mips: pci-mt7620: fix bridge register access
+
+Host bridge registers and PCI RC control registers have different
+memory base. pcie_m32() is used to write the RC control registers
+instead of bridge registers. This patch introduces bridge_m32()
+and use it to operate bridge registers to fix the access issue.
+
+Signed-off-by: Shiji Yang <yangshiji66 at outlook.com>
+---
+ arch/mips/pci/pci-mt7620.c | 15 ++++++++++++---
+ 1 file changed, 12 insertions(+), 3 deletions(-)
+
+--- a/arch/mips/pci/pci-mt7620.c
++++ b/arch/mips/pci/pci-mt7620.c
+@@ -87,6 +87,15 @@ static inline u32 bridge_r32(unsigned re
+ 	return ioread32(bridge_base + reg);
+ }
+ 
++static inline void bridge_m32(u32 clr, u32 set, unsigned reg)
++{
++	u32 val = bridge_r32(reg);
++
++	val &= ~clr;
++	val |= set;
++	bridge_w32(val, reg);
++}
++
+ static inline void pcie_w32(u32 val, unsigned reg)
+ {
+ 	iowrite32(val, pcie_base + reg);
+@@ -228,7 +237,7 @@ static int mt7620_pci_hw_init(struct pla
+ 	pcie_phy(0x68, 0xB4);
+ 
+ 	/* put core into reset */
+-	pcie_m32(0, PCIRST, RALINK_PCI_PCICFG_ADDR);
++	bridge_m32(PCIRST, PCIRST, RALINK_PCI_PCICFG_ADDR);
+ 	reset_control_assert(rstpcie0);
+ 
+ 	/* disable power and all clocks */
+@@ -318,7 +327,7 @@ static int mt7620_pci_probe(struct platf
+ 	mdelay(50);
+ 
+ 	/* enable write access */
+-	pcie_m32(PCIRST, 0, RALINK_PCI_PCICFG_ADDR);
++	bridge_m32(PCIRST, 0, RALINK_PCI_PCICFG_ADDR);
+ 	mdelay(100);
+ 
+ 	/* check if there is a card present */
+@@ -340,7 +349,7 @@ static int mt7620_pci_probe(struct platf
+ 	pcie_w32(0x06040001, RALINK_PCI0_CLASS);
+ 
+ 	/* enable interrupts */
+-	pcie_m32(0, PCIINT2, RALINK_PCI_PCIENA);
++	bridge_m32(PCIINT2, PCIINT2, RALINK_PCI_PCIENA);
+ 
+ 	/* voodoo from the SDK driver */
+ 	pci_config_read(NULL, 0, 4, 4, &val);
diff --git a/target/linux/ramips/patches-6.12/120-2-mips-pci-mt7620-add-more-register-init-values.patch b/target/linux/ramips/patches-6.12/120-2-mips-pci-mt7620-add-more-register-init-values.patch
new file mode 100644
index 0000000000..52e389dc1e
--- /dev/null
+++ b/target/linux/ramips/patches-6.12/120-2-mips-pci-mt7620-add-more-register-init-values.patch
@@ -0,0 +1,132 @@
+From: Shiji Yang <yangshiji66 at outlook.com>
+Date: Mon, 17 Mar 2025 20:54:24 +0800
+Subject: [PATCH 2/3] mips: pci-mt7620: add more register init values
+
+These missing register init values are ported from the vendor SDK.
+It should have some stability enhancements. Tested on both MT7620
+and MT7628.
+
+Signed-off-by: Shiji Yang <yangshiji66 at outlook.com>
+---
+ arch/mips/pci/pci-mt7620.c | 59 +++++++++++++++++++++++++++++---------
+ 1 file changed, 46 insertions(+), 13 deletions(-)
+
+--- a/arch/mips/pci/pci-mt7620.c
++++ b/arch/mips/pci/pci-mt7620.c
+@@ -26,6 +26,8 @@
+ 
+ #define RALINK_INT_PCIE0		4
+ 
++#define RALINK_SYSCFG0			0x10
++#define RALINK_SYSCFG0_XTAL40		BIT(6)
+ #define RALINK_CLKCFG1			0x30
+ #define RALINK_GPIOMODE			0x60
+ 
+@@ -62,7 +64,7 @@
+ 
+ #define PCIEPHY0_CFG			0x90
+ 
+-#define RALINK_PCIEPHY_P0_CTL_OFFSET	0x7498
++#define RALINK_PCIEPHY_P0_CTL_OFFSET	0x7000
+ #define RALINK_PCIE0_CLK_EN		BIT(26)
+ 
+ #define BUSY				0x80000000
+@@ -115,6 +117,14 @@ static inline void pcie_m32(u32 clr, u32
+ 	pcie_w32(val, reg);
+ }
+ 
++static inline void
++pcie_phyctrl_set(unsigned offset, u32 b_start, u32 bits, u32 val)
++{
++	pcie_m32(GENMASK(b_start + bits - 1, b_start),
++		 val << b_start,
++		 RALINK_PCIEPHY_P0_CTL_OFFSET + offset);
++}
++
+ static int wait_pciephy_busy(void)
+ {
+ 	unsigned long reg_value = 0x0, retry = 0;
+@@ -263,10 +273,8 @@ static int mt7620_pci_hw_init(struct pla
+ 	return 0;
+ }
+ 
+-static int mt7628_pci_hw_init(struct platform_device *pdev)
++static void mt7628_pci_hw_init(struct platform_device *pdev)
+ {
+-	u32 val = 0;
+-
+ 	/* bring the core out of reset */
+ 	rt_sysc_m32(BIT(16), 0, RALINK_GPIOMODE);
+ 	reset_control_deassert(rstpcie0);
+@@ -276,14 +284,33 @@ static int mt7628_pci_hw_init(struct pla
+ 	mdelay(100);
+ 
+ 	/* voodoo from the SDK driver */
+-	pcie_m32(~0xff, 0x5, RALINK_PCIEPHY_P0_CTL_OFFSET);
+-
+-	pci_config_read(NULL, 0, 0x70c, 4, &val);
+-	val &= ~(0xff) << 8;
+-	val |= 0x50 << 8;
+-	pci_config_write(NULL, 0, 0x70c, 4, val);
++	pcie_phyctrl_set(0x400, 8, 1, 0x1);
++	pcie_phyctrl_set(0x400, 9, 2, 0x0);
++	pcie_phyctrl_set(0x000, 4, 1, 0x1);
++	pcie_phyctrl_set(0x000, 5, 1, 0x0);
++	pcie_phyctrl_set(0x4ac, 16, 3, 0x3);
++
++	if (rt_sysc_r32(RALINK_SYSCFG0) & RALINK_SYSCFG0_XTAL40) {
++		pcie_phyctrl_set(0x4bc, 24,  8, 0x7d);
++		pcie_phyctrl_set(0x490, 12,  4, 0x08);
++		pcie_phyctrl_set(0x490,  6,  2, 0x01);
++		pcie_phyctrl_set(0x4c0,  0, 32, 0x1f400000);
++		pcie_phyctrl_set(0x4a4,  0, 16, 0x013d);
++		pcie_phyctrl_set(0x4a8, 16, 16, 0x74);
++		pcie_phyctrl_set(0x4a8,  0, 16, 0x74);
++	} else {
++		pcie_phyctrl_set(0x4bc, 24,  8, 0x64);
++		pcie_phyctrl_set(0x490, 12,  4, 0x0a);
++		pcie_phyctrl_set(0x490,  6,  2, 0x00);
++		pcie_phyctrl_set(0x4c0,  0, 32, 0x19000000);
++		pcie_phyctrl_set(0x4a4,  0, 16, 0x018d);
++		pcie_phyctrl_set(0x4a8, 16, 16, 0x4a);
++		pcie_phyctrl_set(0x4a8,  0, 16, 0x4a);
++	}
+ 
+-	return 0;
++	pcie_phyctrl_set(0x498, 0, 8, 0x5);
++	pcie_phyctrl_set(0x000, 5, 1, 0x1);
++	pcie_phyctrl_set(0x000, 4, 1, 0x0);
+ }
+ 
+ static int mt7620_pci_probe(struct platform_device *pdev)
+@@ -316,8 +343,7 @@ static int mt7620_pci_probe(struct platf
+ 
+ 	case MT762X_SOC_MT7628AN:
+ 	case MT762X_SOC_MT7688:
+-		if (mt7628_pci_hw_init(pdev))
+-			return -1;
++		mt7628_pci_hw_init(pdev);
+ 		break;
+ 
+ 	default:
+@@ -336,6 +362,8 @@ static int mt7620_pci_probe(struct platf
+ 		rt_sysc_m32(RALINK_PCIE0_CLK_EN, 0, RALINK_CLKCFG1);
+ 		if (ralink_soc == MT762X_SOC_MT7620A)
+ 			rt_sysc_m32(LC_CKDRVPD, PDRV_SW_SET, PPLL_DRV);
++		else
++			pcie_phyctrl_set(0x000, 0, 32, 0x10);
+ 		dev_info(&pdev->dev, "PCIE0 no card, disable it(RST&CLK)\n");
+ 		return -1;
+ 	}
+@@ -355,6 +383,11 @@ static int mt7620_pci_probe(struct platf
+ 	pci_config_read(NULL, 0, 4, 4, &val);
+ 	pci_config_write(NULL, 0, 4, 4, val | 0x7);
+ 
++	pci_config_read(NULL, 0, 0x70c, 4, &val);
++	val &= ~(0xff) << 8;
++	val |= 0x50 << 8;
++	pci_config_write(NULL, 0, 0x70c, 4, val);
++
+ 	pci_load_of_ranges(&mt7620_controller, pdev->dev.of_node);
+ 	register_pci_controller(&mt7620_controller);
+ 
diff --git a/target/linux/ramips/patches-6.12/120-3-mips-pci-mt7620-rework-initialization-procedure.patch b/target/linux/ramips/patches-6.12/120-3-mips-pci-mt7620-rework-initialization-procedure.patch
new file mode 100644
index 0000000000..c262d0031b
--- /dev/null
+++ b/target/linux/ramips/patches-6.12/120-3-mips-pci-mt7620-rework-initialization-procedure.patch
@@ -0,0 +1,95 @@
+From: Shiji Yang <yangshiji66 at outlook.com>
+Date: Mon, 17 Mar 2025 23:55:24 +0800
+Subject: [PATCH 3/3] mips: pci-mt7620: rework initialization procedure
+
+Move the reset operation to the common part to reduce the code
+redundancy. They are actually the same and needed for all SoCs.
+Disabling power and clock are unnecessary for MT7620 and will be
+removed. In vendor SDK, it's used to save the power when the PCI
+driver is not selected. The MT7628 GPIO pinctrl has been removed
+because this should be done in device-tree. Some delay intervals
+have also been increased to follow the recommendations of the SoC
+SDK and datasheet. Tested on both MT7620 and MT7628.
+
+Signed-off-by: Shiji Yang <yangshiji66 at outlook.com>
+---
+ arch/mips/pci/pci-mt7620.c | 38 +++++++++++++-------------------------
+ 1 file changed, 13 insertions(+), 25 deletions(-)
+
+--- a/arch/mips/pci/pci-mt7620.c
++++ b/arch/mips/pci/pci-mt7620.c
+@@ -29,7 +29,6 @@
+ #define RALINK_SYSCFG0			0x10
+ #define RALINK_SYSCFG0_XTAL40		BIT(6)
+ #define RALINK_CLKCFG1			0x30
+-#define RALINK_GPIOMODE			0x60
+ 
+ #define PPLL_CFG1			0x9c
+ #define PPLL_LD				BIT(23)
+@@ -246,19 +245,6 @@ static int mt7620_pci_hw_init(struct pla
+ 	/* Elastic buffer control */
+ 	pcie_phy(0x68, 0xB4);
+ 
+-	/* put core into reset */
+-	bridge_m32(PCIRST, PCIRST, RALINK_PCI_PCICFG_ADDR);
+-	reset_control_assert(rstpcie0);
+-
+-	/* disable power and all clocks */
+-	rt_sysc_m32(RALINK_PCIE0_CLK_EN, 0, RALINK_CLKCFG1);
+-	rt_sysc_m32(LC_CKDRVPD, PDRV_SW_SET, PPLL_DRV);
+-
+-	/* bring core out of reset */
+-	reset_control_deassert(rstpcie0);
+-	rt_sysc_m32(0, RALINK_PCIE0_CLK_EN, RALINK_CLKCFG1);
+-	mdelay(100);
+-
+ 	if (!(rt_sysc_r32(PPLL_CFG1) & PPLL_LD)) {
+ 		dev_err(&pdev->dev, "pcie PLL not locked, aborting init\n");
+ 		reset_control_assert(rstpcie0);
+@@ -275,14 +261,6 @@ static int mt7620_pci_hw_init(struct pla
+ 
+ static void mt7628_pci_hw_init(struct platform_device *pdev)
+ {
+-	/* bring the core out of reset */
+-	rt_sysc_m32(BIT(16), 0, RALINK_GPIOMODE);
+-	reset_control_deassert(rstpcie0);
+-
+-	/* enable the pci clk */
+-	rt_sysc_m32(0, RALINK_PCIE0_CLK_EN, RALINK_CLKCFG1);
+-	mdelay(100);
+-
+ 	/* voodoo from the SDK driver */
+ 	pcie_phyctrl_set(0x400, 8, 1, 0x1);
+ 	pcie_phyctrl_set(0x400, 9, 2, 0x0);
+@@ -334,6 +312,16 @@ static int mt7620_pci_probe(struct platf
+ 	ioport_resource.start = 0;
+ 	ioport_resource.end = ~0;
+ 
++	/* reset PCIe controller */
++	reset_control_assert(rstpcie0);
++	msleep(100);
++	reset_control_deassert(rstpcie0);
++	rt_sysc_m32(0, RALINK_PCIE0_CLK_EN, RALINK_CLKCFG1);
++	msleep(100);
++
++	/* assert PERST_N pin */
++	bridge_m32(PCIRST, PCIRST, RALINK_PCI_PCICFG_ADDR);
++
+ 	/* bring up the pci core */
+ 	switch (ralink_soc) {
+ 	case MT762X_SOC_MT7620A:
+@@ -350,11 +338,11 @@ static int mt7620_pci_probe(struct platf
+ 		dev_err(&pdev->dev, "pcie is not supported on this hardware\n");
+ 		return -1;
+ 	}
+-	mdelay(50);
++	msleep(500);
+ 
+-	/* enable write access */
++	/* deassert PERST_N pin and wait PCIe peripheral init */
+ 	bridge_m32(PCIRST, 0, RALINK_PCI_PCICFG_ADDR);
+-	mdelay(100);
++	msleep(1000);
+ 
+ 	/* check if there is a card present */
+ 	if ((pcie_r32(RALINK_PCI0_STATUS) & PCIE_LINK_UP_ST) == 0) {
diff --git a/target/linux/ramips/patches-6.6/120-1-mips-pci-mt7620-fix-bridge-register-access.patch b/target/linux/ramips/patches-6.6/120-1-mips-pci-mt7620-fix-bridge-register-access.patch
new file mode 100644
index 0000000000..742e6b8cd5
--- /dev/null
+++ b/target/linux/ramips/patches-6.6/120-1-mips-pci-mt7620-fix-bridge-register-access.patch
@@ -0,0 +1,59 @@
+From: Shiji Yang <yangshiji66 at outlook.com>
+Date: Mon, 17 Mar 2025 20:35:44 +0800
+Subject: [PATCH 1/3] mips: pci-mt7620: fix bridge register access
+
+Host bridge registers and PCI RC control registers have different
+memory base. pcie_m32() is used to write the RC control registers
+instead of bridge registers. This patch introduces bridge_m32()
+and use it to operate bridge registers to fix the access issue.
+
+Signed-off-by: Shiji Yang <yangshiji66 at outlook.com>
+---
+ arch/mips/pci/pci-mt7620.c | 15 ++++++++++++---
+ 1 file changed, 12 insertions(+), 3 deletions(-)
+
+--- a/arch/mips/pci/pci-mt7620.c
++++ b/arch/mips/pci/pci-mt7620.c
+@@ -87,6 +87,15 @@ static inline u32 bridge_r32(unsigned re
+ 	return ioread32(bridge_base + reg);
+ }
+ 
++static inline void bridge_m32(u32 clr, u32 set, unsigned reg)
++{
++	u32 val = bridge_r32(reg);
++
++	val &= ~clr;
++	val |= set;
++	bridge_w32(val, reg);
++}
++
+ static inline void pcie_w32(u32 val, unsigned reg)
+ {
+ 	iowrite32(val, pcie_base + reg);
+@@ -228,7 +237,7 @@ static int mt7620_pci_hw_init(struct pla
+ 	pcie_phy(0x68, 0xB4);
+ 
+ 	/* put core into reset */
+-	pcie_m32(0, PCIRST, RALINK_PCI_PCICFG_ADDR);
++	bridge_m32(PCIRST, PCIRST, RALINK_PCI_PCICFG_ADDR);
+ 	reset_control_assert(rstpcie0);
+ 
+ 	/* disable power and all clocks */
+@@ -318,7 +327,7 @@ static int mt7620_pci_probe(struct platf
+ 	mdelay(50);
+ 
+ 	/* enable write access */
+-	pcie_m32(PCIRST, 0, RALINK_PCI_PCICFG_ADDR);
++	bridge_m32(PCIRST, 0, RALINK_PCI_PCICFG_ADDR);
+ 	mdelay(100);
+ 
+ 	/* check if there is a card present */
+@@ -340,7 +349,7 @@ static int mt7620_pci_probe(struct platf
+ 	pcie_w32(0x06040001, RALINK_PCI0_CLASS);
+ 
+ 	/* enable interrupts */
+-	pcie_m32(0, PCIINT2, RALINK_PCI_PCIENA);
++	bridge_m32(PCIINT2, PCIINT2, RALINK_PCI_PCIENA);
+ 
+ 	/* voodoo from the SDK driver */
+ 	pci_config_read(NULL, 0, 4, 4, &val);
diff --git a/target/linux/ramips/patches-6.6/120-2-mips-pci-mt7620-add-more-register-init-values.patch b/target/linux/ramips/patches-6.6/120-2-mips-pci-mt7620-add-more-register-init-values.patch
new file mode 100644
index 0000000000..52e389dc1e
--- /dev/null
+++ b/target/linux/ramips/patches-6.6/120-2-mips-pci-mt7620-add-more-register-init-values.patch
@@ -0,0 +1,132 @@
+From: Shiji Yang <yangshiji66 at outlook.com>
+Date: Mon, 17 Mar 2025 20:54:24 +0800
+Subject: [PATCH 2/3] mips: pci-mt7620: add more register init values
+
+These missing register init values are ported from the vendor SDK.
+It should have some stability enhancements. Tested on both MT7620
+and MT7628.
+
+Signed-off-by: Shiji Yang <yangshiji66 at outlook.com>
+---
+ arch/mips/pci/pci-mt7620.c | 59 +++++++++++++++++++++++++++++---------
+ 1 file changed, 46 insertions(+), 13 deletions(-)
+
+--- a/arch/mips/pci/pci-mt7620.c
++++ b/arch/mips/pci/pci-mt7620.c
+@@ -26,6 +26,8 @@
+ 
+ #define RALINK_INT_PCIE0		4
+ 
++#define RALINK_SYSCFG0			0x10
++#define RALINK_SYSCFG0_XTAL40		BIT(6)
+ #define RALINK_CLKCFG1			0x30
+ #define RALINK_GPIOMODE			0x60
+ 
+@@ -62,7 +64,7 @@
+ 
+ #define PCIEPHY0_CFG			0x90
+ 
+-#define RALINK_PCIEPHY_P0_CTL_OFFSET	0x7498
++#define RALINK_PCIEPHY_P0_CTL_OFFSET	0x7000
+ #define RALINK_PCIE0_CLK_EN		BIT(26)
+ 
+ #define BUSY				0x80000000
+@@ -115,6 +117,14 @@ static inline void pcie_m32(u32 clr, u32
+ 	pcie_w32(val, reg);
+ }
+ 
++static inline void
++pcie_phyctrl_set(unsigned offset, u32 b_start, u32 bits, u32 val)
++{
++	pcie_m32(GENMASK(b_start + bits - 1, b_start),
++		 val << b_start,
++		 RALINK_PCIEPHY_P0_CTL_OFFSET + offset);
++}
++
+ static int wait_pciephy_busy(void)
+ {
+ 	unsigned long reg_value = 0x0, retry = 0;
+@@ -263,10 +273,8 @@ static int mt7620_pci_hw_init(struct pla
+ 	return 0;
+ }
+ 
+-static int mt7628_pci_hw_init(struct platform_device *pdev)
++static void mt7628_pci_hw_init(struct platform_device *pdev)
+ {
+-	u32 val = 0;
+-
+ 	/* bring the core out of reset */
+ 	rt_sysc_m32(BIT(16), 0, RALINK_GPIOMODE);
+ 	reset_control_deassert(rstpcie0);
+@@ -276,14 +284,33 @@ static int mt7628_pci_hw_init(struct pla
+ 	mdelay(100);
+ 
+ 	/* voodoo from the SDK driver */
+-	pcie_m32(~0xff, 0x5, RALINK_PCIEPHY_P0_CTL_OFFSET);
+-
+-	pci_config_read(NULL, 0, 0x70c, 4, &val);
+-	val &= ~(0xff) << 8;
+-	val |= 0x50 << 8;
+-	pci_config_write(NULL, 0, 0x70c, 4, val);
++	pcie_phyctrl_set(0x400, 8, 1, 0x1);
++	pcie_phyctrl_set(0x400, 9, 2, 0x0);
++	pcie_phyctrl_set(0x000, 4, 1, 0x1);
++	pcie_phyctrl_set(0x000, 5, 1, 0x0);
++	pcie_phyctrl_set(0x4ac, 16, 3, 0x3);
++
++	if (rt_sysc_r32(RALINK_SYSCFG0) & RALINK_SYSCFG0_XTAL40) {
++		pcie_phyctrl_set(0x4bc, 24,  8, 0x7d);
++		pcie_phyctrl_set(0x490, 12,  4, 0x08);
++		pcie_phyctrl_set(0x490,  6,  2, 0x01);
++		pcie_phyctrl_set(0x4c0,  0, 32, 0x1f400000);
++		pcie_phyctrl_set(0x4a4,  0, 16, 0x013d);
++		pcie_phyctrl_set(0x4a8, 16, 16, 0x74);
++		pcie_phyctrl_set(0x4a8,  0, 16, 0x74);
++	} else {
++		pcie_phyctrl_set(0x4bc, 24,  8, 0x64);
++		pcie_phyctrl_set(0x490, 12,  4, 0x0a);
++		pcie_phyctrl_set(0x490,  6,  2, 0x00);
++		pcie_phyctrl_set(0x4c0,  0, 32, 0x19000000);
++		pcie_phyctrl_set(0x4a4,  0, 16, 0x018d);
++		pcie_phyctrl_set(0x4a8, 16, 16, 0x4a);
++		pcie_phyctrl_set(0x4a8,  0, 16, 0x4a);
++	}
+ 
+-	return 0;
++	pcie_phyctrl_set(0x498, 0, 8, 0x5);
++	pcie_phyctrl_set(0x000, 5, 1, 0x1);
++	pcie_phyctrl_set(0x000, 4, 1, 0x0);
+ }
+ 
+ static int mt7620_pci_probe(struct platform_device *pdev)
+@@ -316,8 +343,7 @@ static int mt7620_pci_probe(struct platf
+ 
+ 	case MT762X_SOC_MT7628AN:
+ 	case MT762X_SOC_MT7688:
+-		if (mt7628_pci_hw_init(pdev))
+-			return -1;
++		mt7628_pci_hw_init(pdev);
+ 		break;
+ 
+ 	default:
+@@ -336,6 +362,8 @@ static int mt7620_pci_probe(struct platf
+ 		rt_sysc_m32(RALINK_PCIE0_CLK_EN, 0, RALINK_CLKCFG1);
+ 		if (ralink_soc == MT762X_SOC_MT7620A)
+ 			rt_sysc_m32(LC_CKDRVPD, PDRV_SW_SET, PPLL_DRV);
++		else
++			pcie_phyctrl_set(0x000, 0, 32, 0x10);
+ 		dev_info(&pdev->dev, "PCIE0 no card, disable it(RST&CLK)\n");
+ 		return -1;
+ 	}
+@@ -355,6 +383,11 @@ static int mt7620_pci_probe(struct platf
+ 	pci_config_read(NULL, 0, 4, 4, &val);
+ 	pci_config_write(NULL, 0, 4, 4, val | 0x7);
+ 
++	pci_config_read(NULL, 0, 0x70c, 4, &val);
++	val &= ~(0xff) << 8;
++	val |= 0x50 << 8;
++	pci_config_write(NULL, 0, 0x70c, 4, val);
++
+ 	pci_load_of_ranges(&mt7620_controller, pdev->dev.of_node);
+ 	register_pci_controller(&mt7620_controller);
+ 
diff --git a/target/linux/ramips/patches-6.6/120-3-mips-pci-mt7620-rework-initialization-procedure.patch b/target/linux/ramips/patches-6.6/120-3-mips-pci-mt7620-rework-initialization-procedure.patch
new file mode 100644
index 0000000000..c262d0031b
--- /dev/null
+++ b/target/linux/ramips/patches-6.6/120-3-mips-pci-mt7620-rework-initialization-procedure.patch
@@ -0,0 +1,95 @@
+From: Shiji Yang <yangshiji66 at outlook.com>
+Date: Mon, 17 Mar 2025 23:55:24 +0800
+Subject: [PATCH 3/3] mips: pci-mt7620: rework initialization procedure
+
+Move the reset operation to the common part to reduce the code
+redundancy. They are actually the same and needed for all SoCs.
+Disabling power and clock are unnecessary for MT7620 and will be
+removed. In vendor SDK, it's used to save the power when the PCI
+driver is not selected. The MT7628 GPIO pinctrl has been removed
+because this should be done in device-tree. Some delay intervals
+have also been increased to follow the recommendations of the SoC
+SDK and datasheet. Tested on both MT7620 and MT7628.
+
+Signed-off-by: Shiji Yang <yangshiji66 at outlook.com>
+---
+ arch/mips/pci/pci-mt7620.c | 38 +++++++++++++-------------------------
+ 1 file changed, 13 insertions(+), 25 deletions(-)
+
+--- a/arch/mips/pci/pci-mt7620.c
++++ b/arch/mips/pci/pci-mt7620.c
+@@ -29,7 +29,6 @@
+ #define RALINK_SYSCFG0			0x10
+ #define RALINK_SYSCFG0_XTAL40		BIT(6)
+ #define RALINK_CLKCFG1			0x30
+-#define RALINK_GPIOMODE			0x60
+ 
+ #define PPLL_CFG1			0x9c
+ #define PPLL_LD				BIT(23)
+@@ -246,19 +245,6 @@ static int mt7620_pci_hw_init(struct pla
+ 	/* Elastic buffer control */
+ 	pcie_phy(0x68, 0xB4);
+ 
+-	/* put core into reset */
+-	bridge_m32(PCIRST, PCIRST, RALINK_PCI_PCICFG_ADDR);
+-	reset_control_assert(rstpcie0);
+-
+-	/* disable power and all clocks */
+-	rt_sysc_m32(RALINK_PCIE0_CLK_EN, 0, RALINK_CLKCFG1);
+-	rt_sysc_m32(LC_CKDRVPD, PDRV_SW_SET, PPLL_DRV);
+-
+-	/* bring core out of reset */
+-	reset_control_deassert(rstpcie0);
+-	rt_sysc_m32(0, RALINK_PCIE0_CLK_EN, RALINK_CLKCFG1);
+-	mdelay(100);
+-
+ 	if (!(rt_sysc_r32(PPLL_CFG1) & PPLL_LD)) {
+ 		dev_err(&pdev->dev, "pcie PLL not locked, aborting init\n");
+ 		reset_control_assert(rstpcie0);
+@@ -275,14 +261,6 @@ static int mt7620_pci_hw_init(struct pla
+ 
+ static void mt7628_pci_hw_init(struct platform_device *pdev)
+ {
+-	/* bring the core out of reset */
+-	rt_sysc_m32(BIT(16), 0, RALINK_GPIOMODE);
+-	reset_control_deassert(rstpcie0);
+-
+-	/* enable the pci clk */
+-	rt_sysc_m32(0, RALINK_PCIE0_CLK_EN, RALINK_CLKCFG1);
+-	mdelay(100);
+-
+ 	/* voodoo from the SDK driver */
+ 	pcie_phyctrl_set(0x400, 8, 1, 0x1);
+ 	pcie_phyctrl_set(0x400, 9, 2, 0x0);
+@@ -334,6 +312,16 @@ static int mt7620_pci_probe(struct platf
+ 	ioport_resource.start = 0;
+ 	ioport_resource.end = ~0;
+ 
++	/* reset PCIe controller */
++	reset_control_assert(rstpcie0);
++	msleep(100);
++	reset_control_deassert(rstpcie0);
++	rt_sysc_m32(0, RALINK_PCIE0_CLK_EN, RALINK_CLKCFG1);
++	msleep(100);
++
++	/* assert PERST_N pin */
++	bridge_m32(PCIRST, PCIRST, RALINK_PCI_PCICFG_ADDR);
++
+ 	/* bring up the pci core */
+ 	switch (ralink_soc) {
+ 	case MT762X_SOC_MT7620A:
+@@ -350,11 +338,11 @@ static int mt7620_pci_probe(struct platf
+ 		dev_err(&pdev->dev, "pcie is not supported on this hardware\n");
+ 		return -1;
+ 	}
+-	mdelay(50);
++	msleep(500);
+ 
+-	/* enable write access */
++	/* deassert PERST_N pin and wait PCIe peripheral init */
+ 	bridge_m32(PCIRST, 0, RALINK_PCI_PCICFG_ADDR);
+-	mdelay(100);
++	msleep(1000);
+ 
+ 	/* check if there is a card present */
+ 	if ((pcie_r32(RALINK_PCI0_STATUS) & PCIE_LINK_UP_ST) == 0) {




More information about the lede-commits mailing list