[PATCH 10/18] wifi: mt76: mt7925: enable MT7927 runtime power management

Javier Tia floss at jetm.me
Fri Mar 6 16:33:29 PST 2026


Add MT7927-specific GLO_CFG register programming to mt792x_dma_enable()
so that ADDR_EXT_EN and CSR_LBK_RX_Q_SEL_EN are correctly configured
after every WPDMA reinitialization triggered by CLR_OWN during power
management transitions.

On MT7927, every CLR_OWN causes the ROM to reinitialize WFDMA, which
resets the DMA configuration. The PM wake path already handles ring
reprogramming (mt76_queue_reset restores ring base addresses from
stored desc_dma) and prefetch configuration (mt792x_dma_prefetch has
an is_mt7927 branch), but two GLO_CFG bits were missing from
mt792x_dma_enable:

  - BIT(26) ADDR_EXT_EN: extended DMA addressing, required for
    MT7927's host memory access
  - BIT(20) CSR_LBK_RX_Q_SEL_EN: loopback RX queue select, must
    be cleared for normal DMA operation

Also define proper macros for these bits and use them in
mt7927_dma_init() to replace bare BIT() values.

With the DMA recovery path now fully MT7927-aware, remove the
is_mt7927() guard that disabled runtime PM and deep sleep. Let the
standard mt792x power management work for MT7927 hardware.

Tested-by: Marcin FM <marcin at lgic.pl>
Tested-by: Cristian-Florin Radoi <radoi.chris at gmail.com>
Tested-by: George Salukvadze <giosal90 at gmail.com>
Tested-by: Evgeny Kapusta <3193631 at gmail.com>
Tested-by: Samu Toljamo <samu.toljamo at gmail.com>
Tested-by: Ariel Rosenfeld <ariel.rosenfeld.750 at gmail.com>
Tested-by: Chapuis Dario <chapuisdario4 at gmail.com>
Tested-by: Thibaut François <tibo at humeurlibre.fr>
Tested-by: 张旭涵 <Loong.0x00 at gmail.com>
Signed-off-by: Javier Tia <floss at jetm.me>
---
 drivers/net/wireless/mediatek/mt76/mt7925/init.c | 5 +----
 drivers/net/wireless/mediatek/mt76/mt7925/pci.c  | 4 ++--
 drivers/net/wireless/mediatek/mt76/mt792x_dma.c  | 7 +++++++
 drivers/net/wireless/mediatek/mt76/mt792x_regs.h | 2 ++
 4 files changed, 12 insertions(+), 6 deletions(-)

diff --git a/drivers/net/wireless/mediatek/mt76/mt7925/init.c b/drivers/net/wireless/mediatek/mt76/mt7925/init.c
index 1e9eadca3988..84af52a0176d 100644
--- a/drivers/net/wireless/mediatek/mt76/mt7925/init.c
+++ b/drivers/net/wireless/mediatek/mt76/mt7925/init.c
@@ -242,10 +242,7 @@ int mt7925_register_device(struct mt792x_dev *dev)
 	dev->pm.idle_timeout = MT792x_PM_TIMEOUT;
 	dev->pm.stats.last_wake_event = jiffies;
 	dev->pm.stats.last_doze_event = jiffies;
-	/* MT7927: disable power management. Every CLR_OWN triggers the
-	 * ROM to reinitialize WFDMA, destroying DMA ring configuration.
-	 * Keep the device awake until the PM wake path handles MT7927. */
-	if (!mt76_is_usb(&dev->mt76) && !is_mt7927(&dev->mt76)) {
+	if (!mt76_is_usb(&dev->mt76)) {
 		dev->pm.enable_user = true;
 		dev->pm.enable = true;
 		dev->pm.ds_enable_user = true;
diff --git a/drivers/net/wireless/mediatek/mt76/mt7925/pci.c b/drivers/net/wireless/mediatek/mt76/mt7925/pci.c
index 0dec25b320f8..0f76d9197230 100644
--- a/drivers/net/wireless/mediatek/mt76/mt7925/pci.c
+++ b/drivers/net/wireless/mediatek/mt76/mt7925/pci.c
@@ -416,8 +416,8 @@ static int mt7927_dma_init(struct mt792x_dev *dev)
 	napi_enable(&dev->mt76.tx_napi);
 
 	/* MT7927-specific GLO_CFG bits before DMA enable */
-	mt76_set(dev, MT_WFDMA0_GLO_CFG, BIT(26));   /* ADDR_EXT_EN */
-	mt76_clear(dev, MT_WFDMA0_GLO_CFG, BIT(20)); /* CSR_LBK_RX_Q_SEL_EN */
+	mt76_set(dev, MT_WFDMA0_GLO_CFG, MT_WFDMA0_GLO_CFG_ADDR_EXT_EN);
+	mt76_clear(dev, MT_WFDMA0_GLO_CFG, MT_WFDMA0_GLO_CFG_CSR_LBK_RX_Q_SEL_EN);
 	mt76_set(dev, MT_WFDMA0_GLO_CFG_EXT1, BIT(28));
 	mt76_set(dev, MT_WFDMA0_GLO_CFG,
 		 MT_WFDMA0_GLO_CFG_FW_DWLD_BYPASS_DMASHDL);
diff --git a/drivers/net/wireless/mediatek/mt76/mt792x_dma.c b/drivers/net/wireless/mediatek/mt76/mt792x_dma.c
index 3177c6cc6eb5..32364f19007d 100644
--- a/drivers/net/wireless/mediatek/mt76/mt792x_dma.c
+++ b/drivers/net/wireless/mediatek/mt76/mt792x_dma.c
@@ -166,6 +166,13 @@ int mt792x_dma_enable(struct mt792x_dev *dev)
 	mt76_set(dev, MT_WFDMA0_GLO_CFG,
 		 MT_WFDMA0_GLO_CFG_TX_DMA_EN | MT_WFDMA0_GLO_CFG_RX_DMA_EN);
 
+	if (is_mt7927(&dev->mt76)) {
+		mt76_set(dev, MT_WFDMA0_GLO_CFG,
+			 MT_WFDMA0_GLO_CFG_ADDR_EXT_EN);
+		mt76_clear(dev, MT_WFDMA0_GLO_CFG,
+			   MT_WFDMA0_GLO_CFG_CSR_LBK_RX_Q_SEL_EN);
+	}
+
 	if (is_mt7925(&dev->mt76)) {
 		mt76_rmw(dev, MT_UWFDMA0_GLO_CFG_EXT1, BIT(28), BIT(28));
 		mt76_set(dev, MT_WFDMA0_INT_RX_PRI, 0x0F00);
diff --git a/drivers/net/wireless/mediatek/mt76/mt792x_regs.h b/drivers/net/wireless/mediatek/mt76/mt792x_regs.h
index 5497cfaab8d7..b364d0038653 100644
--- a/drivers/net/wireless/mediatek/mt76/mt792x_regs.h
+++ b/drivers/net/wireless/mediatek/mt76/mt792x_regs.h
@@ -299,7 +299,9 @@
 #define MT_WFDMA0_GLO_CFG_FIFO_LITTLE_ENDIAN	BIT(12)
 #define MT_WFDMA0_GLO_CFG_RX_WB_DDONE	BIT(13)
 #define MT_WFDMA0_GLO_CFG_CSR_DISP_BASE_PTR_CHAIN_EN BIT(15)
+#define MT_WFDMA0_GLO_CFG_CSR_LBK_RX_Q_SEL_EN	BIT(20)
 #define MT_WFDMA0_GLO_CFG_OMIT_RX_INFO_PFET2	BIT(21)
+#define MT_WFDMA0_GLO_CFG_ADDR_EXT_EN		BIT(26)
 #define MT_WFDMA0_GLO_CFG_OMIT_RX_INFO	BIT(27)
 #define MT_WFDMA0_GLO_CFG_OMIT_TX_INFO	BIT(28)
 #define MT_WFDMA0_GLO_CFG_CLK_GAT_DIS	BIT(30)

-- 
2.53.0




More information about the Linux-mediatek mailing list