* [PATCH 1/3] mips: pci-mt7620: fix bridge register access
@ 2025-06-18 3:42 Shiji Yang
2025-06-18 3:42 ` [PATCH 2/3] mips: pci-mt7620: add more register init values Shiji Yang
` (2 more replies)
0 siblings, 3 replies; 6+ messages in thread
From: Shiji Yang @ 2025-06-18 3:42 UTC (permalink / raw)
To: linux-mips
Cc: Thomas Bogendoerfer, Matthias Brugger, AngeloGioacchino Del Regno,
Philipp Zabel, linux-kernel, linux-arm-kernel, linux-mediatek,
Shiji Yang
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@outlook.com>
---
arch/mips/pci/pci-mt7620.c | 15 ++++++++++++---
1 file changed, 12 insertions(+), 3 deletions(-)
diff --git a/arch/mips/pci/pci-mt7620.c b/arch/mips/pci/pci-mt7620.c
index 5c4bdf691..94b3c96a1 100644
--- a/arch/mips/pci/pci-mt7620.c
+++ b/arch/mips/pci/pci-mt7620.c
@@ -87,6 +87,15 @@ static inline u32 bridge_r32(unsigned reg)
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 platform_device *pdev)
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 platform_device *pdev)
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 platform_device *pdev)
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);
--
2.39.5
^ permalink raw reply related [flat|nested] 6+ messages in thread
* [PATCH 2/3] mips: pci-mt7620: add more register init values
2025-06-18 3:42 [PATCH 1/3] mips: pci-mt7620: fix bridge register access Shiji Yang
@ 2025-06-18 3:42 ` Shiji Yang
2026-04-06 12:29 ` Thomas Bogendoerfer
2025-06-18 3:42 ` [PATCH 3/3] mips: pci-mt7620: rework initialization procedure Shiji Yang
2026-04-06 12:28 ` [PATCH 1/3] mips: pci-mt7620: fix bridge register access Thomas Bogendoerfer
2 siblings, 1 reply; 6+ messages in thread
From: Shiji Yang @ 2025-06-18 3:42 UTC (permalink / raw)
To: linux-mips
Cc: Thomas Bogendoerfer, Matthias Brugger, AngeloGioacchino Del Regno,
Philipp Zabel, linux-kernel, linux-arm-kernel, linux-mediatek,
Shiji Yang
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@outlook.com>
---
arch/mips/pci/pci-mt7620.c | 59 +++++++++++++++++++++++++++++---------
1 file changed, 46 insertions(+), 13 deletions(-)
diff --git a/arch/mips/pci/pci-mt7620.c b/arch/mips/pci/pci-mt7620.c
index 94b3c96a1..81a49b05f 100644
--- 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 set, unsigned reg)
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 platform_device *pdev)
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 platform_device *pdev)
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 platform_device *pdev)
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 platform_device *pdev)
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 platform_device *pdev)
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);
--
2.39.5
^ permalink raw reply related [flat|nested] 6+ messages in thread
* [PATCH 3/3] mips: pci-mt7620: rework initialization procedure
2025-06-18 3:42 [PATCH 1/3] mips: pci-mt7620: fix bridge register access Shiji Yang
2025-06-18 3:42 ` [PATCH 2/3] mips: pci-mt7620: add more register init values Shiji Yang
@ 2025-06-18 3:42 ` Shiji Yang
2026-04-06 12:29 ` Thomas Bogendoerfer
2026-04-06 12:28 ` [PATCH 1/3] mips: pci-mt7620: fix bridge register access Thomas Bogendoerfer
2 siblings, 1 reply; 6+ messages in thread
From: Shiji Yang @ 2025-06-18 3:42 UTC (permalink / raw)
To: linux-mips
Cc: Thomas Bogendoerfer, Matthias Brugger, AngeloGioacchino Del Regno,
Philipp Zabel, linux-kernel, linux-arm-kernel, linux-mediatek,
Shiji Yang
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@outlook.com>
---
arch/mips/pci/pci-mt7620.c | 38 +++++++++++++-------------------------
1 file changed, 13 insertions(+), 25 deletions(-)
diff --git a/arch/mips/pci/pci-mt7620.c b/arch/mips/pci/pci-mt7620.c
index 81a49b05f..aae844f27 100644
--- 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 platform_device *pdev)
/* 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 platform_device *pdev)
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 platform_device *pdev)
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 platform_device *pdev)
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) {
--
2.39.5
^ permalink raw reply related [flat|nested] 6+ messages in thread
* Re: [PATCH 1/3] mips: pci-mt7620: fix bridge register access
2025-06-18 3:42 [PATCH 1/3] mips: pci-mt7620: fix bridge register access Shiji Yang
2025-06-18 3:42 ` [PATCH 2/3] mips: pci-mt7620: add more register init values Shiji Yang
2025-06-18 3:42 ` [PATCH 3/3] mips: pci-mt7620: rework initialization procedure Shiji Yang
@ 2026-04-06 12:28 ` Thomas Bogendoerfer
2 siblings, 0 replies; 6+ messages in thread
From: Thomas Bogendoerfer @ 2026-04-06 12:28 UTC (permalink / raw)
To: Shiji Yang
Cc: linux-mips, Matthias Brugger, AngeloGioacchino Del Regno,
Philipp Zabel, linux-kernel, linux-arm-kernel, linux-mediatek
On Wed, Jun 18, 2025 at 11:42:05AM +0800, Shiji Yang wrote:
> 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@outlook.com>
> ---
> arch/mips/pci/pci-mt7620.c | 15 ++++++++++++---
> 1 file changed, 12 insertions(+), 3 deletions(-)
applied to mips-next
Thomas.
--
Crap can work. Given enough thrust pigs will fly, but it's not necessarily a
good idea. [ RFC1925, 2.3 ]
^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: [PATCH 2/3] mips: pci-mt7620: add more register init values
2025-06-18 3:42 ` [PATCH 2/3] mips: pci-mt7620: add more register init values Shiji Yang
@ 2026-04-06 12:29 ` Thomas Bogendoerfer
0 siblings, 0 replies; 6+ messages in thread
From: Thomas Bogendoerfer @ 2026-04-06 12:29 UTC (permalink / raw)
To: Shiji Yang
Cc: linux-mips, Matthias Brugger, AngeloGioacchino Del Regno,
Philipp Zabel, linux-kernel, linux-arm-kernel, linux-mediatek
On Wed, Jun 18, 2025 at 11:42:06AM +0800, Shiji Yang wrote:
> 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@outlook.com>
> ---
> arch/mips/pci/pci-mt7620.c | 59 +++++++++++++++++++++++++++++---------
> 1 file changed, 46 insertions(+), 13 deletions(-)
applied to mips-next
Thomas.
--
Crap can work. Given enough thrust pigs will fly, but it's not necessarily a
good idea. [ RFC1925, 2.3 ]
^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: [PATCH 3/3] mips: pci-mt7620: rework initialization procedure
2025-06-18 3:42 ` [PATCH 3/3] mips: pci-mt7620: rework initialization procedure Shiji Yang
@ 2026-04-06 12:29 ` Thomas Bogendoerfer
0 siblings, 0 replies; 6+ messages in thread
From: Thomas Bogendoerfer @ 2026-04-06 12:29 UTC (permalink / raw)
To: Shiji Yang
Cc: linux-mips, Matthias Brugger, AngeloGioacchino Del Regno,
Philipp Zabel, linux-kernel, linux-arm-kernel, linux-mediatek
On Wed, Jun 18, 2025 at 11:42:07AM +0800, Shiji Yang wrote:
> 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@outlook.com>
> ---
> arch/mips/pci/pci-mt7620.c | 38 +++++++++++++-------------------------
> 1 file changed, 13 insertions(+), 25 deletions(-)
applied to mips-next
Thomas.
--
Crap can work. Given enough thrust pigs will fly, but it's not necessarily a
good idea. [ RFC1925, 2.3 ]
^ permalink raw reply [flat|nested] 6+ messages in thread
end of thread, other threads:[~2026-04-06 12:35 UTC | newest]
Thread overview: 6+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2025-06-18 3:42 [PATCH 1/3] mips: pci-mt7620: fix bridge register access Shiji Yang
2025-06-18 3:42 ` [PATCH 2/3] mips: pci-mt7620: add more register init values Shiji Yang
2026-04-06 12:29 ` Thomas Bogendoerfer
2025-06-18 3:42 ` [PATCH 3/3] mips: pci-mt7620: rework initialization procedure Shiji Yang
2026-04-06 12:29 ` Thomas Bogendoerfer
2026-04-06 12:28 ` [PATCH 1/3] mips: pci-mt7620: fix bridge register access Thomas Bogendoerfer
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox