[PATCH 10/18] wifi: mt76: mt7925: enable MT7927 runtime power management
From: Javier Tia <hidden>
Date: 2026-03-07 00:33:59
Also in:
linux-mediatek, linux-wireless, lkml
Subsystem:
mediatek mt76 wireless lan driver, the rest · Maintainers:
Felix Fietkau, Lorenzo Bianconi, Ryder Lee, Linus Torvalds
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 <redacted>
Tested-by: Cristian-Florin Radoi <redacted>
Tested-by: George Salukvadze <redacted>
Tested-by: Evgeny Kapusta <redacted>
Tested-by: Samu Toljamo <redacted>
Tested-by: Ariel Rosenfeld <redacted>
Tested-by: Chapuis Dario <redacted>
Tested-by: Thibaut François <redacted>
Tested-by: 张旭涵 <redacted>
Signed-off-by: Javier Tia <redacted>
---
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