linux-wireless.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH 0/6] enable deep sleep mode when mt7921e suspends
@ 2021-04-18 16:36 sean.wang
  2021-04-18 16:36 ` [PATCH 1/6] mt76: mt7921: move mt7921_dma_reset in dma.c sean.wang
                   ` (5 more replies)
  0 siblings, 6 replies; 9+ messages in thread
From: sean.wang @ 2021-04-18 16:36 UTC (permalink / raw)
  To: nbd, lorenzo.bianconi
  Cc: sean.wang, Soul.Huang, YN.Chen, Leon.Yen, Deren.Wu, km.lin,
	robin.chiu, ch.yeh, posh.sun, Eric.Liang, Stella.Chang,
	linux-wireless, linux-mediatek

From: Sean Wang <sean.wang@mediatek.com>

Enable the deep sleep mode in suspend handler which is able to reduce the
power consumption further.

Lorenzo Bianconi (3):
  mt76: mt7921: move mt7921_dma_reset in dma.c
  mt76: mt7921: introduce mt7921_wpdma_reset utility routine
  mt76: mt7921: introduce mt7921_dma_{enable,disable} utilities

Sean Wang (3):
  mt76: mt7921: introduce mt7921_wpdma_reinit_cond utility routine
  mt76: connac: introduce mt76_connac_mcu_set_deep_sleep utility
  mt76: mt7921: enable deep sleep when the device suspends

 .../net/wireless/mediatek/mt76/mt76_connac.h  |   4 +
 .../wireless/mediatek/mt76/mt76_connac_mcu.c  |  22 +-
 .../wireless/mediatek/mt76/mt76_connac_mcu.h  |  10 +
 .../wireless/mediatek/mt76/mt7921/debugfs.c   |  13 ++
 .../net/wireless/mediatek/mt76/mt7921/dma.c   | 204 +++++++++++++-----
 .../net/wireless/mediatek/mt76/mt7921/mac.c   |  93 +-------
 .../wireless/mediatek/mt76/mt7921/mt7921.h    |   8 +-
 .../net/wireless/mediatek/mt76/mt7921/pci.c   |  12 ++
 8 files changed, 215 insertions(+), 151 deletions(-)

--
2.25.1


^ permalink raw reply	[flat|nested] 9+ messages in thread

* [PATCH 1/6] mt76: mt7921: move mt7921_dma_reset in dma.c
  2021-04-18 16:36 [PATCH 0/6] enable deep sleep mode when mt7921e suspends sean.wang
@ 2021-04-18 16:36 ` sean.wang
  2021-04-18 16:47   ` Lorenzo Bianconi
  2021-04-18 16:36 ` [PATCH 2/6] mt76: mt7921: introduce mt7921_wpdma_reset utility routine sean.wang
                   ` (4 subsequent siblings)
  5 siblings, 1 reply; 9+ messages in thread
From: sean.wang @ 2021-04-18 16:36 UTC (permalink / raw)
  To: nbd, lorenzo.bianconi
  Cc: sean.wang, Soul.Huang, YN.Chen, Leon.Yen, Deren.Wu, km.lin,
	robin.chiu, ch.yeh, posh.sun, Eric.Liang, Stella.Chang,
	linux-wireless, linux-mediatek, Lorenzo Bianconi

From: Lorenzo Bianconi <lorenzo@kernel.org>

Move mt7921_dma_reset routine in dma.c and make mt7921_dma_prefetch
static. Moreover add force parameter to mt7921_dma_reset signature.
This is a preliminary patch to reset dma mt7921_mcu_drv_pmctrl.

Signed-off-by: Sean Wang <sean.wang@mediatek.com>
Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
---
 .../net/wireless/mediatek/mt76/mt7921/dma.c   | 71 +++++++++++++++++++
 .../net/wireless/mediatek/mt76/mt7921/mac.c   | 66 +----------------
 .../wireless/mediatek/mt76/mt7921/mt7921.h    |  2 +-
 3 files changed, 73 insertions(+), 66 deletions(-)

diff --git a/drivers/net/wireless/mediatek/mt76/mt7921/dma.c b/drivers/net/wireless/mediatek/mt76/mt7921/dma.c
index 992faf82ad09..f8815aa247eb 100644
--- a/drivers/net/wireless/mediatek/mt76/mt7921/dma.c
+++ b/drivers/net/wireless/mediatek/mt76/mt7921/dma.c
@@ -206,6 +206,77 @@ static int mt7921_dmashdl_disabled(struct mt7921_dev *dev)
 	return 0;
 }
 
+int mt7921_dma_reset(struct mt7921_dev *dev, bool force)
+{
+	int i;
+
+	if (force) {
+		/* reset */
+		mt76_clear(dev, MT_WFDMA0_RST,
+			   MT_WFDMA0_RST_DMASHDL_ALL_RST |
+			   MT_WFDMA0_RST_LOGIC_RST);
+
+		mt76_set(dev, MT_WFDMA0_RST,
+			 MT_WFDMA0_RST_DMASHDL_ALL_RST |
+			 MT_WFDMA0_RST_LOGIC_RST);
+	}
+
+	/* disable WFDMA0 */
+	mt76_clear(dev, MT_WFDMA0_GLO_CFG,
+		   MT_WFDMA0_GLO_CFG_TX_DMA_EN | MT_WFDMA0_GLO_CFG_RX_DMA_EN |
+		   MT_WFDMA0_GLO_CFG_CSR_DISP_BASE_PTR_CHAIN_EN |
+		   MT_WFDMA0_GLO_CFG_OMIT_TX_INFO |
+		   MT_WFDMA0_GLO_CFG_OMIT_RX_INFO |
+		   MT_WFDMA0_GLO_CFG_OMIT_RX_INFO_PFET2);
+
+	if (!mt76_poll(dev, MT_WFDMA0_GLO_CFG,
+		       MT_WFDMA0_GLO_CFG_TX_DMA_BUSY |
+		       MT_WFDMA0_GLO_CFG_RX_DMA_BUSY, 0, 1000))
+		return -ETIMEDOUT;
+
+	/* reset hw queues */
+	for (i = 0; i < __MT_TXQ_MAX; i++)
+		mt76_queue_reset(dev, dev->mphy.q_tx[i]);
+
+	for (i = 0; i < __MT_MCUQ_MAX; i++)
+		mt76_queue_reset(dev, dev->mt76.q_mcu[i]);
+
+	mt76_for_each_q_rx(&dev->mt76, i)
+		mt76_queue_reset(dev, &dev->mt76.q_rx[i]);
+
+	mt76_tx_status_check(&dev->mt76, NULL, true);
+
+	/* configure perfetch settings */
+	mt7921_dma_prefetch(dev);
+
+	/* reset dma idx */
+	mt76_wr(dev, MT_WFDMA0_RST_DTX_PTR, ~0);
+
+	/* configure delay interrupt */
+	mt76_wr(dev, MT_WFDMA0_PRI_DLY_INT_CFG0, 0);
+
+	mt76_set(dev, MT_WFDMA0_GLO_CFG,
+		 MT_WFDMA0_GLO_CFG_TX_WB_DDONE |
+		 MT_WFDMA0_GLO_CFG_FIFO_LITTLE_ENDIAN |
+		 MT_WFDMA0_GLO_CFG_CLK_GAT_DIS |
+		 MT_WFDMA0_GLO_CFG_OMIT_TX_INFO |
+		 MT_WFDMA0_GLO_CFG_CSR_DISP_BASE_PTR_CHAIN_EN |
+		 MT_WFDMA0_GLO_CFG_OMIT_RX_INFO_PFET2);
+
+	mt76_set(dev, MT_WFDMA0_GLO_CFG,
+		 MT_WFDMA0_GLO_CFG_TX_DMA_EN | MT_WFDMA0_GLO_CFG_RX_DMA_EN);
+
+	mt76_set(dev, MT_WFDMA_DUMMY_CR, MT_WFDMA_NEED_REINIT);
+
+	/* enable interrupts for TX/RX rings */
+	mt7921_irq_enable(dev,
+			  MT_INT_RX_DONE_ALL | MT_INT_TX_DONE_ALL |
+			  MT_INT_MCU_CMD);
+	mt76_set(dev, MT_MCU2HOST_SW_INT_ENA, MT_MCU_CMD_WAKE_RX_PCIE);
+
+	return 0;
+}
+
 int mt7921_dma_init(struct mt7921_dev *dev)
 {
 	/* Increase buffer size to receive large VHT/HE MPDUs */
diff --git a/drivers/net/wireless/mediatek/mt76/mt7921/mac.c b/drivers/net/wireless/mediatek/mt76/mt7921/mac.c
index 3145880df6e7..4e319f1521a6 100644
--- a/drivers/net/wireless/mediatek/mt76/mt7921/mac.c
+++ b/drivers/net/wireless/mediatek/mt76/mt7921/mac.c
@@ -1220,70 +1220,6 @@ int mt7921_wfsys_reset(struct mt7921_dev *dev)
 				WFSYS_SW_INIT_DONE, WFSYS_SW_INIT_DONE, 500);
 }
 
-static void
-mt7921_dma_reset(struct mt7921_dev *dev)
-{
-	int i;
-
-	/* reset */
-	mt76_clear(dev, MT_WFDMA0_RST,
-		   MT_WFDMA0_RST_DMASHDL_ALL_RST | MT_WFDMA0_RST_LOGIC_RST);
-
-	mt76_set(dev, MT_WFDMA0_RST,
-		 MT_WFDMA0_RST_DMASHDL_ALL_RST | MT_WFDMA0_RST_LOGIC_RST);
-
-	/* disable WFDMA0 */
-	mt76_clear(dev, MT_WFDMA0_GLO_CFG,
-		   MT_WFDMA0_GLO_CFG_TX_DMA_EN | MT_WFDMA0_GLO_CFG_RX_DMA_EN |
-		   MT_WFDMA0_GLO_CFG_CSR_DISP_BASE_PTR_CHAIN_EN |
-		   MT_WFDMA0_GLO_CFG_OMIT_TX_INFO |
-		   MT_WFDMA0_GLO_CFG_OMIT_RX_INFO |
-		   MT_WFDMA0_GLO_CFG_OMIT_RX_INFO_PFET2);
-
-	mt76_poll(dev, MT_WFDMA0_GLO_CFG,
-		  MT_WFDMA0_GLO_CFG_TX_DMA_BUSY |
-		  MT_WFDMA0_GLO_CFG_RX_DMA_BUSY, 0, 1000);
-
-	/* reset hw queues */
-	for (i = 0; i < __MT_TXQ_MAX; i++)
-		mt76_queue_reset(dev, dev->mphy.q_tx[i]);
-
-	for (i = 0; i < __MT_MCUQ_MAX; i++)
-		mt76_queue_reset(dev, dev->mt76.q_mcu[i]);
-
-	mt76_for_each_q_rx(&dev->mt76, i)
-		mt76_queue_reset(dev, &dev->mt76.q_rx[i]);
-
-	mt76_tx_status_check(&dev->mt76, NULL, true);
-
-	/* configure perfetch settings */
-	mt7921_dma_prefetch(dev);
-
-	/* reset dma idx */
-	mt76_wr(dev, MT_WFDMA0_RST_DTX_PTR, ~0);
-
-	/* configure delay interrupt */
-	mt76_wr(dev, MT_WFDMA0_PRI_DLY_INT_CFG0, 0);
-
-	mt76_set(dev, MT_WFDMA0_GLO_CFG,
-		 MT_WFDMA0_GLO_CFG_TX_WB_DDONE |
-		 MT_WFDMA0_GLO_CFG_FIFO_LITTLE_ENDIAN |
-		 MT_WFDMA0_GLO_CFG_CLK_GAT_DIS |
-		 MT_WFDMA0_GLO_CFG_OMIT_TX_INFO |
-		 MT_WFDMA0_GLO_CFG_CSR_DISP_BASE_PTR_CHAIN_EN |
-		 MT_WFDMA0_GLO_CFG_OMIT_RX_INFO_PFET2);
-
-	mt76_set(dev, MT_WFDMA0_GLO_CFG,
-		 MT_WFDMA0_GLO_CFG_TX_DMA_EN | MT_WFDMA0_GLO_CFG_RX_DMA_EN);
-
-	mt76_set(dev, MT_WFDMA_DUMMY_CR, MT_WFDMA_NEED_REINIT);
-
-	/* enable interrupts for TX/RX rings */
-	mt7921_irq_enable(dev,
-			  MT_INT_RX_DONE_ALL | MT_INT_TX_DONE_ALL |
-			  MT_INT_MCU_CMD);
-}
-
 void mt7921_tx_token_put(struct mt7921_dev *dev)
 {
 	struct mt76_txwi_cache *txwi;
@@ -1354,7 +1290,7 @@ mt7921_mac_reset(struct mt7921_dev *dev)
 		mt76_queue_rx_cleanup(dev, &dev->mt76.q_rx[i]);
 
 	mt7921_wfsys_reset(dev);
-	mt7921_dma_reset(dev);
+	mt7921_dma_reset(dev, true);
 
 	mt76_for_each_q_rx(&dev->mt76, i) {
 		mt76_queue_rx_reset(dev, i);
diff --git a/drivers/net/wireless/mediatek/mt76/mt7921/mt7921.h b/drivers/net/wireless/mediatek/mt76/mt7921/mt7921.h
index c34cf3e3a26b..9b476641616d 100644
--- a/drivers/net/wireless/mediatek/mt76/mt7921/mt7921.h
+++ b/drivers/net/wireless/mediatek/mt76/mt7921/mt7921.h
@@ -253,7 +253,7 @@ int mt7921_eeprom_get_target_power(struct mt7921_dev *dev,
 				   u8 chain_idx);
 void mt7921_eeprom_init_sku(struct mt7921_dev *dev);
 int mt7921_dma_init(struct mt7921_dev *dev);
-void mt7921_dma_prefetch(struct mt7921_dev *dev);
+int mt7921_dma_reset(struct mt7921_dev *dev, bool force);
 void mt7921_dma_cleanup(struct mt7921_dev *dev);
 int mt7921_run_firmware(struct mt7921_dev *dev);
 int mt7921_mcu_init(struct mt7921_dev *dev);
-- 
2.25.1


^ permalink raw reply related	[flat|nested] 9+ messages in thread

* [PATCH 2/6] mt76: mt7921: introduce mt7921_wpdma_reset utility routine
  2021-04-18 16:36 [PATCH 0/6] enable deep sleep mode when mt7921e suspends sean.wang
  2021-04-18 16:36 ` [PATCH 1/6] mt76: mt7921: move mt7921_dma_reset in dma.c sean.wang
@ 2021-04-18 16:36 ` sean.wang
  2021-04-18 16:36 ` [PATCH 3/6] mt76: mt7921: introduce mt7921_dma_{enable,disable} utilities sean.wang
                   ` (3 subsequent siblings)
  5 siblings, 0 replies; 9+ messages in thread
From: sean.wang @ 2021-04-18 16:36 UTC (permalink / raw)
  To: nbd, lorenzo.bianconi
  Cc: sean.wang, Soul.Huang, YN.Chen, Leon.Yen, Deren.Wu, km.lin,
	robin.chiu, ch.yeh, posh.sun, Eric.Liang, Stella.Chang,
	linux-wireless, linux-mediatek, Lorenzo Bianconi

From: Lorenzo Bianconi <lorenzo@kernel.org>

Introduce mt7921_wpdma_reset routine to reset wpdma during chip reset
or driver_own request.

Signed-off-by: Sean Wang <sean.wang@mediatek.com>
Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
---
 .../net/wireless/mediatek/mt76/mt7921/dma.c   | 44 ++++++++++++++++++-
 .../net/wireless/mediatek/mt76/mt7921/mac.c   | 29 ++----------
 .../wireless/mediatek/mt76/mt7921/mt7921.h    |  2 +-
 3 files changed, 47 insertions(+), 28 deletions(-)

diff --git a/drivers/net/wireless/mediatek/mt76/mt7921/dma.c b/drivers/net/wireless/mediatek/mt76/mt7921/dma.c
index f8815aa247eb..4aad355f8394 100644
--- a/drivers/net/wireless/mediatek/mt76/mt7921/dma.c
+++ b/drivers/net/wireless/mediatek/mt76/mt7921/dma.c
@@ -206,7 +206,7 @@ static int mt7921_dmashdl_disabled(struct mt7921_dev *dev)
 	return 0;
 }
 
-int mt7921_dma_reset(struct mt7921_dev *dev, bool force)
+static int mt7921_dma_reset(struct mt7921_dev *dev, bool force)
 {
 	int i;
 
@@ -277,6 +277,48 @@ int mt7921_dma_reset(struct mt7921_dev *dev, bool force)
 	return 0;
 }
 
+int mt7921_wfsys_reset(struct mt7921_dev *dev)
+{
+	mt76_set(dev, 0x70002600, BIT(0));
+	msleep(200);
+	mt76_clear(dev, 0x70002600, BIT(0));
+
+	if (!__mt76_poll_msec(&dev->mt76, MT_WFSYS_SW_RST_B,
+			      WFSYS_SW_INIT_DONE, WFSYS_SW_INIT_DONE, 500))
+		return -ETIMEDOUT;
+
+	return 0;
+}
+
+int mt7921_wpdma_reset(struct mt7921_dev *dev, bool force)
+{
+	int i, err;
+
+	/* clean up hw queues */
+	for (i = 0; i < ARRAY_SIZE(dev->mt76.phy.q_tx); i++)
+		mt76_queue_tx_cleanup(dev, dev->mphy.q_tx[i], true);
+
+	for (i = 0; i < ARRAY_SIZE(dev->mt76.q_mcu); i++)
+		mt76_queue_tx_cleanup(dev, dev->mt76.q_mcu[i], true);
+
+	mt76_for_each_q_rx(&dev->mt76, i)
+		mt76_queue_rx_cleanup(dev, &dev->mt76.q_rx[i]);
+
+	if (force) {
+		err = mt7921_wfsys_reset(dev);
+		if (err)
+			return err;
+	}
+	err = mt7921_dma_reset(dev, force);
+	if (err)
+		return err;
+
+	mt76_for_each_q_rx(&dev->mt76, i)
+		mt76_queue_rx_reset(dev, i);
+
+	return 0;
+}
+
 int mt7921_dma_init(struct mt7921_dev *dev)
 {
 	/* Increase buffer size to receive large VHT/HE MPDUs */
diff --git a/drivers/net/wireless/mediatek/mt76/mt7921/mac.c b/drivers/net/wireless/mediatek/mt76/mt7921/mac.c
index 4e319f1521a6..6e89cd41641e 100644
--- a/drivers/net/wireless/mediatek/mt76/mt7921/mac.c
+++ b/drivers/net/wireless/mediatek/mt76/mt7921/mac.c
@@ -1210,16 +1210,6 @@ void mt7921_update_channel(struct mt76_dev *mdev)
 	mt76_connac_power_save_sched(&dev->mphy, &dev->pm);
 }
 
-int mt7921_wfsys_reset(struct mt7921_dev *dev)
-{
-	mt76_set(dev, 0x70002600, BIT(0));
-	msleep(200);
-	mt76_clear(dev, 0x70002600, BIT(0));
-
-	return __mt76_poll_msec(&dev->mt76, MT_WFSYS_SW_RST_B,
-				WFSYS_SW_INIT_DONE, WFSYS_SW_INIT_DONE, 500);
-}
-
 void mt7921_tx_token_put(struct mt7921_dev *dev)
 {
 	struct mt76_txwi_cache *txwi;
@@ -1279,21 +1269,11 @@ mt7921_mac_reset(struct mt7921_dev *dev)
 	mt7921_tx_token_put(dev);
 	idr_init(&dev->token);
 
-	/* clean up hw queues */
-	for (i = 0; i < ARRAY_SIZE(dev->mt76.phy.q_tx); i++)
-		mt76_queue_tx_cleanup(dev, dev->mphy.q_tx[i], true);
-
-	for (i = 0; i < ARRAY_SIZE(dev->mt76.q_mcu); i++)
-		mt76_queue_tx_cleanup(dev, dev->mt76.q_mcu[i], true);
-
-	mt76_for_each_q_rx(&dev->mt76, i)
-		mt76_queue_rx_cleanup(dev, &dev->mt76.q_rx[i]);
-
-	mt7921_wfsys_reset(dev);
-	mt7921_dma_reset(dev, true);
+	err = mt7921_wpdma_reset(dev, true);
+	if (err)
+		return err;
 
 	mt76_for_each_q_rx(&dev->mt76, i) {
-		mt76_queue_rx_reset(dev, i);
 		napi_enable(&dev->mt76.napi[i]);
 		napi_schedule(&dev->mt76.napi[i]);
 	}
@@ -1306,9 +1286,6 @@ mt7921_mac_reset(struct mt7921_dev *dev)
 
 	mt76_wr(dev, MT_WFDMA0_HOST_INT_ENA, 0);
 	mt76_wr(dev, MT_PCIE_MAC_INT_ENABLE, 0xff);
-	mt7921_irq_enable(dev,
-			  MT_INT_RX_DONE_ALL | MT_INT_TX_DONE_ALL |
-			  MT_INT_MCU_CMD);
 
 	err = mt7921_run_firmware(dev);
 	if (err)
diff --git a/drivers/net/wireless/mediatek/mt76/mt7921/mt7921.h b/drivers/net/wireless/mediatek/mt76/mt7921/mt7921.h
index 9b476641616d..06a85d2d1c6f 100644
--- a/drivers/net/wireless/mediatek/mt76/mt7921/mt7921.h
+++ b/drivers/net/wireless/mediatek/mt76/mt7921/mt7921.h
@@ -253,7 +253,7 @@ int mt7921_eeprom_get_target_power(struct mt7921_dev *dev,
 				   u8 chain_idx);
 void mt7921_eeprom_init_sku(struct mt7921_dev *dev);
 int mt7921_dma_init(struct mt7921_dev *dev);
-int mt7921_dma_reset(struct mt7921_dev *dev, bool force);
+int mt7921_wpdma_reset(struct mt7921_dev *dev, bool force);
 void mt7921_dma_cleanup(struct mt7921_dev *dev);
 int mt7921_run_firmware(struct mt7921_dev *dev);
 int mt7921_mcu_init(struct mt7921_dev *dev);
-- 
2.25.1


^ permalink raw reply related	[flat|nested] 9+ messages in thread

* [PATCH 3/6] mt76: mt7921: introduce mt7921_dma_{enable,disable} utilities
  2021-04-18 16:36 [PATCH 0/6] enable deep sleep mode when mt7921e suspends sean.wang
  2021-04-18 16:36 ` [PATCH 1/6] mt76: mt7921: move mt7921_dma_reset in dma.c sean.wang
  2021-04-18 16:36 ` [PATCH 2/6] mt76: mt7921: introduce mt7921_wpdma_reset utility routine sean.wang
@ 2021-04-18 16:36 ` sean.wang
  2021-04-18 16:36 ` [PATCH 4/6] mt76: mt7921: introduce mt7921_wpdma_reinit_cond utility routine sean.wang
                   ` (2 subsequent siblings)
  5 siblings, 0 replies; 9+ messages in thread
From: sean.wang @ 2021-04-18 16:36 UTC (permalink / raw)
  To: nbd, lorenzo.bianconi
  Cc: sean.wang, Soul.Huang, YN.Chen, Leon.Yen, Deren.Wu, km.lin,
	robin.chiu, ch.yeh, posh.sun, Eric.Liang, Stella.Chang,
	linux-wireless, linux-mediatek, Lorenzo Bianconi

From: Lorenzo Bianconi <lorenzo@kernel.org>

Introduce mt7921_dma_enable and mt7921_dma_disable utilities routine in
order for code reusing between mt7921_dma_reset and mt7921_dma_init.
This is a preliminary patch to reset dma during device driver_own
request.

Signed-off-by: Sean Wang <sean.wang@mediatek.com>
Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
---
 .../net/wireless/mediatek/mt76/mt7921/dma.c   | 108 ++++++------------
 1 file changed, 35 insertions(+), 73 deletions(-)

diff --git a/drivers/net/wireless/mediatek/mt76/mt7921/dma.c b/drivers/net/wireless/mediatek/mt76/mt7921/dma.c
index 4aad355f8394..8c556ff3ae93 100644
--- a/drivers/net/wireless/mediatek/mt76/mt7921/dma.c
+++ b/drivers/net/wireless/mediatek/mt76/mt7921/dma.c
@@ -198,18 +198,8 @@ static u32 mt7921_rmw(struct mt76_dev *mdev, u32 offset, u32 mask, u32 val)
 	return dev->bus_ops->rmw(mdev, addr, mask, val);
 }
 
-static int mt7921_dmashdl_disabled(struct mt7921_dev *dev)
+static int mt7921_dma_disable(struct mt7921_dev *dev, bool force)
 {
-	mt76_clear(dev, MT_WFDMA0_GLO_CFG_EXT0, MT_WFDMA0_CSR_TX_DMASHDL_ENABLE);
-	mt76_set(dev, MT_DMASHDL_SW_CONTROL, MT_DMASHDL_DMASHDL_BYPASS);
-
-	return 0;
-}
-
-static int mt7921_dma_reset(struct mt7921_dev *dev, bool force)
-{
-	int i;
-
 	if (force) {
 		/* reset */
 		mt76_clear(dev, MT_WFDMA0_RST,
@@ -221,6 +211,11 @@ static int mt7921_dma_reset(struct mt7921_dev *dev, bool force)
 			 MT_WFDMA0_RST_LOGIC_RST);
 	}
 
+	/* disable dmashdl */
+	mt76_clear(dev, MT_WFDMA0_GLO_CFG_EXT0,
+		   MT_WFDMA0_CSR_TX_DMASHDL_ENABLE);
+	mt76_set(dev, MT_DMASHDL_SW_CONTROL, MT_DMASHDL_DMASHDL_BYPASS);
+
 	/* disable WFDMA0 */
 	mt76_clear(dev, MT_WFDMA0_GLO_CFG,
 		   MT_WFDMA0_GLO_CFG_TX_DMA_EN | MT_WFDMA0_GLO_CFG_RX_DMA_EN |
@@ -234,18 +229,11 @@ static int mt7921_dma_reset(struct mt7921_dev *dev, bool force)
 		       MT_WFDMA0_GLO_CFG_RX_DMA_BUSY, 0, 1000))
 		return -ETIMEDOUT;
 
-	/* reset hw queues */
-	for (i = 0; i < __MT_TXQ_MAX; i++)
-		mt76_queue_reset(dev, dev->mphy.q_tx[i]);
-
-	for (i = 0; i < __MT_MCUQ_MAX; i++)
-		mt76_queue_reset(dev, dev->mt76.q_mcu[i]);
-
-	mt76_for_each_q_rx(&dev->mt76, i)
-		mt76_queue_reset(dev, &dev->mt76.q_rx[i]);
-
-	mt76_tx_status_check(&dev->mt76, NULL, true);
+	return 0;
+}
 
+static int mt7921_dma_enable(struct mt7921_dev *dev)
+{
 	/* configure perfetch settings */
 	mt7921_dma_prefetch(dev);
 
@@ -272,11 +260,33 @@ static int mt7921_dma_reset(struct mt7921_dev *dev, bool force)
 	mt7921_irq_enable(dev,
 			  MT_INT_RX_DONE_ALL | MT_INT_TX_DONE_ALL |
 			  MT_INT_MCU_CMD);
-	mt76_set(dev, MT_MCU2HOST_SW_INT_ENA, MT_MCU_CMD_WAKE_RX_PCIE);
 
 	return 0;
 }
 
+static int mt7921_dma_reset(struct mt7921_dev *dev, bool force)
+{
+	int i, err;
+
+	err = mt7921_dma_disable(dev, force);
+	if (err)
+		return err;
+
+	/* reset hw queues */
+	for (i = 0; i < __MT_TXQ_MAX; i++)
+		mt76_queue_reset(dev, dev->mphy.q_tx[i]);
+
+	for (i = 0; i < __MT_MCUQ_MAX; i++)
+		mt76_queue_reset(dev, dev->mt76.q_mcu[i]);
+
+	mt76_for_each_q_rx(&dev->mt76, i)
+		mt76_queue_reset(dev, &dev->mt76.q_rx[i]);
+
+	mt76_tx_status_check(&dev->mt76, NULL, true);
+
+	return mt7921_dma_enable(dev);
+}
+
 int mt7921_wfsys_reset(struct mt7921_dev *dev)
 {
 	mt76_set(dev, 0x70002600, BIT(0));
@@ -339,32 +349,10 @@ int mt7921_dma_init(struct mt7921_dev *dev)
 
 	mt76_dma_attach(&dev->mt76);
 
-	/* reset */
-	mt76_clear(dev, MT_WFDMA0_RST,
-		   MT_WFDMA0_RST_DMASHDL_ALL_RST |
-		   MT_WFDMA0_RST_LOGIC_RST);
-
-	mt76_set(dev, MT_WFDMA0_RST,
-		 MT_WFDMA0_RST_DMASHDL_ALL_RST |
-		 MT_WFDMA0_RST_LOGIC_RST);
-
-	ret = mt7921_dmashdl_disabled(dev);
+	ret = mt7921_dma_disable(dev, true);
 	if (ret)
 		return ret;
 
-	/* disable WFDMA0 */
-	mt76_clear(dev, MT_WFDMA0_GLO_CFG,
-		   MT_WFDMA0_GLO_CFG_TX_DMA_EN |
-		   MT_WFDMA0_GLO_CFG_RX_DMA_EN |
-		   MT_WFDMA0_GLO_CFG_CSR_DISP_BASE_PTR_CHAIN_EN |
-		   MT_WFDMA0_GLO_CFG_OMIT_TX_INFO |
-		   MT_WFDMA0_GLO_CFG_OMIT_RX_INFO |
-		   MT_WFDMA0_GLO_CFG_OMIT_RX_INFO_PFET2);
-
-	mt76_poll(dev, MT_WFDMA0_GLO_CFG,
-		  MT_WFDMA0_GLO_CFG_TX_DMA_BUSY |
-		  MT_WFDMA0_GLO_CFG_RX_DMA_BUSY, 0, 1000);
-
 	/* init tx queue */
 	ret = mt7921_init_tx_queues(&dev->phy, MT7921_TXQ_BAND0,
 				    MT7921_TX_RING_SIZE);
@@ -416,33 +404,7 @@ int mt7921_dma_init(struct mt7921_dev *dev)
 			  mt7921_poll_tx, NAPI_POLL_WEIGHT);
 	napi_enable(&dev->mt76.tx_napi);
 
-	/* configure perfetch settings */
-	mt7921_dma_prefetch(dev);
-
-	/* reset dma idx */
-	mt76_wr(dev, MT_WFDMA0_RST_DTX_PTR, ~0);
-
-	/* configure delay interrupt */
-	mt76_wr(dev, MT_WFDMA0_PRI_DLY_INT_CFG0, 0);
-
-	mt76_set(dev, MT_WFDMA0_GLO_CFG,
-		 MT_WFDMA0_GLO_CFG_TX_WB_DDONE |
-		 MT_WFDMA0_GLO_CFG_FIFO_LITTLE_ENDIAN |
-		 MT_WFDMA0_GLO_CFG_CLK_GAT_DIS |
-		 MT_WFDMA0_GLO_CFG_OMIT_TX_INFO |
-		 MT_WFDMA0_GLO_CFG_CSR_DISP_BASE_PTR_CHAIN_EN |
-		 MT_WFDMA0_GLO_CFG_OMIT_RX_INFO_PFET2);
-
-	mt76_set(dev, MT_WFDMA0_GLO_CFG,
-		 MT_WFDMA0_GLO_CFG_TX_DMA_EN | MT_WFDMA0_GLO_CFG_RX_DMA_EN);
-
-	mt76_set(dev, MT_WFDMA_DUMMY_CR, MT_WFDMA_NEED_REINIT);
-
-	/* enable interrupts for TX/RX rings */
-	mt7921_irq_enable(dev, MT_INT_RX_DONE_ALL | MT_INT_TX_DONE_ALL |
-			  MT_INT_MCU_CMD);
-
-	return 0;
+	return mt7921_dma_enable(dev);
 }
 
 void mt7921_dma_cleanup(struct mt7921_dev *dev)
-- 
2.25.1


^ permalink raw reply related	[flat|nested] 9+ messages in thread

* [PATCH 4/6] mt76: mt7921: introduce mt7921_wpdma_reinit_cond utility routine
  2021-04-18 16:36 [PATCH 0/6] enable deep sleep mode when mt7921e suspends sean.wang
                   ` (2 preceding siblings ...)
  2021-04-18 16:36 ` [PATCH 3/6] mt76: mt7921: introduce mt7921_dma_{enable,disable} utilities sean.wang
@ 2021-04-18 16:36 ` sean.wang
  2021-04-18 16:48   ` Lorenzo Bianconi
  2021-04-18 16:36 ` [PATCH 5/6] mt76: connac: introduce mt76_connac_mcu_set_deep_sleep utility sean.wang
  2021-04-18 16:36 ` [PATCH 6/6] mt76: mt7921: enable deep sleep when the device suspends sean.wang
  5 siblings, 1 reply; 9+ messages in thread
From: sean.wang @ 2021-04-18 16:36 UTC (permalink / raw)
  To: nbd, lorenzo.bianconi
  Cc: sean.wang, Soul.Huang, YN.Chen, Leon.Yen, Deren.Wu, km.lin,
	robin.chiu, ch.yeh, posh.sun, Eric.Liang, Stella.Chang,
	linux-wireless, linux-mediatek, Leon Yen, Lorenzo Bianconi

From: Sean Wang <sean.wang@mediatek.com>

Add mt7921_wpdma_reinit_cond to check dummy reg if driver needs to
reinitialized WPDMA after driver_own operation

Co-developed-by: Leon Yen <leon.yen@mediatek.com>
Signed-off-by: Leon Yen <leon.yen@mediatek.com>
Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
Signed-off-by: Sean Wang <sean.wang@mediatek.com>
---
 .../net/wireless/mediatek/mt76/mt76_connac.h  |  4 +++
 .../wireless/mediatek/mt76/mt7921/debugfs.c   | 13 ++++++++++
 .../net/wireless/mediatek/mt76/mt7921/dma.c   | 25 +++++++++++++++++++
 .../wireless/mediatek/mt76/mt7921/mt7921.h    |  6 +++++
 4 files changed, 48 insertions(+)

diff --git a/drivers/net/wireless/mediatek/mt76/mt76_connac.h b/drivers/net/wireless/mediatek/mt76/mt76_connac.h
index b811f3c410a1..3b5bff80a462 100644
--- a/drivers/net/wireless/mediatek/mt76/mt76_connac.h
+++ b/drivers/net/wireless/mediatek/mt76/mt76_connac.h
@@ -58,6 +58,10 @@ struct mt76_connac_pm {
 	struct delayed_work ps_work;
 	unsigned long last_activity;
 	unsigned long idle_timeout;
+
+	struct {
+		unsigned int lp_wake;
+	} stats;
 };
 
 struct mt76_connac_coredump {
diff --git a/drivers/net/wireless/mediatek/mt76/mt7921/debugfs.c b/drivers/net/wireless/mediatek/mt76/mt7921/debugfs.c
index 5a54cd8d2ce4..bd2aca654767 100644
--- a/drivers/net/wireless/mediatek/mt76/mt7921/debugfs.c
+++ b/drivers/net/wireless/mediatek/mt76/mt7921/debugfs.c
@@ -256,6 +256,17 @@ mt7921_pm_get(void *data, u64 *val)
 
 DEFINE_DEBUGFS_ATTRIBUTE(fops_pm, mt7921_pm_get, mt7921_pm_set, "%lld\n");
 
+static int
+mt7921_pm_stats(struct seq_file *s, void *data)
+{
+	struct mt7921_dev *dev = dev_get_drvdata(s->private);
+	struct mt76_connac_pm *pm = &dev->pm;
+
+	seq_printf(s, "low power wakes: %9d\n", pm->stats.lp_wake);
+
+	return 0;
+}
+
 static int
 mt7921_pm_idle_timeout_set(void *data, u64 val)
 {
@@ -322,6 +333,8 @@ int mt7921_init_debugfs(struct mt7921_dev *dev)
 	debugfs_create_file("idle-timeout", 0600, dir, dev,
 			    &fops_pm_idle_timeout);
 	debugfs_create_file("chip_reset", 0600, dir, dev, &fops_reset);
+	debugfs_create_devm_seqfile(dev->mt76.dev, "runtime_pm_stats", dir,
+				    mt7921_pm_stats);
 
 	return 0;
 }
diff --git a/drivers/net/wireless/mediatek/mt76/mt7921/dma.c b/drivers/net/wireless/mediatek/mt76/mt7921/dma.c
index 8c556ff3ae93..72f5704f8f11 100644
--- a/drivers/net/wireless/mediatek/mt76/mt7921/dma.c
+++ b/drivers/net/wireless/mediatek/mt76/mt7921/dma.c
@@ -329,6 +329,31 @@ int mt7921_wpdma_reset(struct mt7921_dev *dev, bool force)
 	return 0;
 }
 
+int mt7921_wpdma_reinit_cond(struct mt7921_dev *dev)
+{
+	struct mt76_connac_pm *pm = &dev->pm;
+	int err;
+
+	/* check if the wpdma must be reinitialized */
+	if (mt7921_dma_need_reinit(dev)) {
+		/* disable interrutpts */
+		mt76_wr(dev, MT_WFDMA0_HOST_INT_ENA, 0);
+		mt76_wr(dev, MT_PCIE_MAC_INT_ENABLE, 0x0);
+
+		err = mt7921_wpdma_reset(dev, false);
+		if (err) {
+			dev_err(dev->mt76.dev, "wpdma reset failed\n");
+			return err;
+		}
+
+		/* enable interrutpts */
+		mt76_wr(dev, MT_PCIE_MAC_INT_ENABLE, 0xff);
+		pm->stats.lp_wake++;
+	}
+
+	return 0;
+}
+
 int mt7921_dma_init(struct mt7921_dev *dev)
 {
 	/* Increase buffer size to receive large VHT/HE MPDUs */
diff --git a/drivers/net/wireless/mediatek/mt76/mt7921/mt7921.h b/drivers/net/wireless/mediatek/mt76/mt7921/mt7921.h
index 06a85d2d1c6f..bb4961d3969a 100644
--- a/drivers/net/wireless/mediatek/mt76/mt7921/mt7921.h
+++ b/drivers/net/wireless/mediatek/mt76/mt7921/mt7921.h
@@ -254,6 +254,7 @@ int mt7921_eeprom_get_target_power(struct mt7921_dev *dev,
 void mt7921_eeprom_init_sku(struct mt7921_dev *dev);
 int mt7921_dma_init(struct mt7921_dev *dev);
 int mt7921_wpdma_reset(struct mt7921_dev *dev, bool force);
+int mt7921_wpdma_reinit_cond(struct mt7921_dev *dev);
 void mt7921_dma_cleanup(struct mt7921_dev *dev);
 int mt7921_run_firmware(struct mt7921_dev *dev);
 int mt7921_mcu_init(struct mt7921_dev *dev);
@@ -317,6 +318,11 @@ mt7921_l1_rmw(struct mt7921_dev *dev, u32 addr, u32 mask, u32 val)
 #define mt7921_l1_set(dev, addr, val)	mt7921_l1_rmw(dev, addr, 0, val)
 #define mt7921_l1_clear(dev, addr, val)	mt7921_l1_rmw(dev, addr, val, 0)
 
+static inline bool mt7921_dma_need_reinit(struct mt7921_dev *dev)
+{
+	return !mt76_get_field(dev, MT_WFDMA_DUMMY_CR, MT_WFDMA_NEED_REINIT);
+}
+
 void mt7921_mac_init(struct mt7921_dev *dev);
 bool mt7921_mac_wtbl_update(struct mt7921_dev *dev, int idx, u32 mask);
 void mt7921_mac_reset_counters(struct mt7921_phy *phy);
-- 
2.25.1


^ permalink raw reply related	[flat|nested] 9+ messages in thread

* [PATCH 5/6] mt76: connac: introduce mt76_connac_mcu_set_deep_sleep utility
  2021-04-18 16:36 [PATCH 0/6] enable deep sleep mode when mt7921e suspends sean.wang
                   ` (3 preceding siblings ...)
  2021-04-18 16:36 ` [PATCH 4/6] mt76: mt7921: introduce mt7921_wpdma_reinit_cond utility routine sean.wang
@ 2021-04-18 16:36 ` sean.wang
  2021-04-18 16:36 ` [PATCH 6/6] mt76: mt7921: enable deep sleep when the device suspends sean.wang
  5 siblings, 0 replies; 9+ messages in thread
From: sean.wang @ 2021-04-18 16:36 UTC (permalink / raw)
  To: nbd, lorenzo.bianconi
  Cc: sean.wang, Soul.Huang, YN.Chen, Leon.Yen, Deren.Wu, km.lin,
	robin.chiu, ch.yeh, posh.sun, Eric.Liang, Stella.Chang,
	linux-wireless, linux-mediatek, Leon Yen, Lorenzo Bianconi

From: Sean Wang <sean.wang@mediatek.com>

Introduce mt76_connac_mcu_set_deep_sleep to enable deep sleep mode
and will be activated immediately when the host returns the ownership
to the device.

Co-developed-by: Leon Yen <leon.yen@mediatek.com>
Signed-off-by: Leon Yen <leon.yen@mediatek.com>
Co-developed-by: YN Chen <YN.Chen@mediatek.com>
Signed-off-by: YN Chen <YN.Chen@mediatek.com>
Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
Signed-off-by: Sean Wang <sean.wang@mediatek.com>
---
 .../wireless/mediatek/mt76/mt76_connac_mcu.c  | 22 ++++++++++++-------
 .../wireless/mediatek/mt76/mt76_connac_mcu.h  | 10 +++++++++
 2 files changed, 24 insertions(+), 8 deletions(-)

diff --git a/drivers/net/wireless/mediatek/mt76/mt76_connac_mcu.c b/drivers/net/wireless/mediatek/mt76/mt76_connac_mcu.c
index 860406a53cb6..7578855099e6 100644
--- a/drivers/net/wireless/mediatek/mt76/mt76_connac_mcu.c
+++ b/drivers/net/wireless/mediatek/mt76/mt76_connac_mcu.c
@@ -1528,14 +1528,7 @@ EXPORT_SYMBOL_GPL(mt76_connac_mcu_sched_scan_enable);
 
 int mt76_connac_mcu_chip_config(struct mt76_dev *dev)
 {
-	struct {
-		__le16 id;
-		u8 type;
-		u8 resp_type;
-		__le16 data_size;
-		__le16 resv;
-		u8 data[320];
-	} req = {
+	struct mt76_connac_config req = {
 		.resp_type = 0,
 	};
 
@@ -1546,6 +1539,19 @@ int mt76_connac_mcu_chip_config(struct mt76_dev *dev)
 }
 EXPORT_SYMBOL_GPL(mt76_connac_mcu_chip_config);
 
+int mt76_connac_mcu_set_deep_sleep(struct mt76_dev *dev, bool enable)
+{
+	struct mt76_connac_config req = {
+		.resp_type = 0,
+	};
+
+	snprintf(req.data, sizeof(req.data), "KeepFullPwr %d", !enable);
+
+	return mt76_mcu_send_msg(dev, MCU_CMD_CHIP_CONFIG, &req, sizeof(req),
+				 false);
+}
+EXPORT_SYMBOL_GPL(mt76_connac_mcu_set_deep_sleep);
+
 void mt76_connac_mcu_coredump_event(struct mt76_dev *dev, struct sk_buff *skb,
 				    struct mt76_connac_coredump *coredump)
 {
diff --git a/drivers/net/wireless/mediatek/mt76/mt76_connac_mcu.h b/drivers/net/wireless/mediatek/mt76/mt76_connac_mcu.h
index ff9fca52f344..e943b89fda75 100644
--- a/drivers/net/wireless/mediatek/mt76/mt76_connac_mcu.h
+++ b/drivers/net/wireless/mediatek/mt76/mt76_connac_mcu.h
@@ -918,6 +918,15 @@ struct mt76_connac_tx_power_limit_tlv {
 	u8 pad2[32];
 } __packed;
 
+struct mt76_connac_config {
+	__le16 id;
+	u8 type;
+	u8 resp_type;
+	__le16 data_size;
+	__le16 resv;
+	u8 data[320];
+} __packed;
+
 #define to_wcid_lo(id)		FIELD_GET(GENMASK(7, 0), (u16)id)
 #define to_wcid_hi(id)		FIELD_GET(GENMASK(9, 8), (u16)id)
 
@@ -1017,6 +1026,7 @@ int mt76_connac_mcu_set_hif_suspend(struct mt76_dev *dev, bool suspend);
 void mt76_connac_mcu_set_suspend_iter(void *priv, u8 *mac,
 				      struct ieee80211_vif *vif);
 int mt76_connac_mcu_chip_config(struct mt76_dev *dev);
+int mt76_connac_mcu_set_deep_sleep(struct mt76_dev *dev, bool enable);
 void mt76_connac_mcu_coredump_event(struct mt76_dev *dev, struct sk_buff *skb,
 				    struct mt76_connac_coredump *coredump);
 int mt76_connac_mcu_set_rate_txpower(struct mt76_phy *phy);
-- 
2.25.1


^ permalink raw reply related	[flat|nested] 9+ messages in thread

* [PATCH 6/6] mt76: mt7921: enable deep sleep when the device suspends
  2021-04-18 16:36 [PATCH 0/6] enable deep sleep mode when mt7921e suspends sean.wang
                   ` (4 preceding siblings ...)
  2021-04-18 16:36 ` [PATCH 5/6] mt76: connac: introduce mt76_connac_mcu_set_deep_sleep utility sean.wang
@ 2021-04-18 16:36 ` sean.wang
  5 siblings, 0 replies; 9+ messages in thread
From: sean.wang @ 2021-04-18 16:36 UTC (permalink / raw)
  To: nbd, lorenzo.bianconi
  Cc: sean.wang, Soul.Huang, YN.Chen, Leon.Yen, Deren.Wu, km.lin,
	robin.chiu, ch.yeh, posh.sun, Eric.Liang, Stella.Chang,
	linux-wireless, linux-mediatek

From: Sean Wang <sean.wang@mediatek.com>

Enable the deep sleep mode in suspend handler to reduce the power
consumption further.

Signed-off-by: Sean Wang <sean.wang@mediatek.com>
---
 drivers/net/wireless/mediatek/mt76/mt7921/pci.c | 12 ++++++++++++
 1 file changed, 12 insertions(+)

diff --git a/drivers/net/wireless/mediatek/mt76/mt7921/pci.c b/drivers/net/wireless/mediatek/mt76/mt7921/pci.c
index 40e2086d075c..277960b680bc 100644
--- a/drivers/net/wireless/mediatek/mt76/mt7921/pci.c
+++ b/drivers/net/wireless/mediatek/mt76/mt7921/pci.c
@@ -189,6 +189,9 @@ static int mt7921_pci_suspend(struct pci_dev *pdev, pm_message_t state)
 			return err;
 	}
 
+	if (!dev->pm.enable)
+		mt76_connac_mcu_set_deep_sleep(&dev->mt76, true);
+
 	napi_disable(&mdev->tx_napi);
 	mt76_worker_disable(&mdev->tx_worker);
 
@@ -227,6 +230,10 @@ static int mt7921_pci_suspend(struct pci_dev *pdev, pm_message_t state)
 		napi_enable(&mdev->napi[i]);
 	}
 	napi_enable(&mdev->tx_napi);
+
+	if (!dev->pm.enable)
+		mt76_connac_mcu_set_deep_sleep(&dev->mt76, false);
+
 	if (hif_suspend)
 		mt76_connac_mcu_set_hif_suspend(mdev, false);
 
@@ -249,6 +256,8 @@ static int mt7921_pci_resume(struct pci_dev *pdev)
 	if (err < 0)
 		return err;
 
+	mt7921_wpdma_reinit_cond(dev);
+
 	/* enable interrupt */
 	mt76_wr(dev, MT_PCIE_MAC_INT_ENABLE, 0xff);
 	mt7921_irq_enable(dev, MT_INT_RX_DONE_ALL | MT_INT_TX_DONE_ALL |
@@ -266,6 +275,9 @@ static int mt7921_pci_resume(struct pci_dev *pdev)
 	napi_enable(&mdev->tx_napi);
 	napi_schedule(&mdev->tx_napi);
 
+	if (!dev->pm.enable)
+		mt76_connac_mcu_set_deep_sleep(&dev->mt76, false);
+
 	if (!test_bit(MT76_STATE_SUSPEND, &dev->mphy.state))
 		err = mt76_connac_mcu_set_hif_suspend(mdev, false);
 
-- 
2.25.1


^ permalink raw reply related	[flat|nested] 9+ messages in thread

* Re: [PATCH 1/6] mt76: mt7921: move mt7921_dma_reset in dma.c
  2021-04-18 16:36 ` [PATCH 1/6] mt76: mt7921: move mt7921_dma_reset in dma.c sean.wang
@ 2021-04-18 16:47   ` Lorenzo Bianconi
  0 siblings, 0 replies; 9+ messages in thread
From: Lorenzo Bianconi @ 2021-04-18 16:47 UTC (permalink / raw)
  To: sean.wang
  Cc: nbd, lorenzo.bianconi, Soul.Huang, YN.Chen, Leon.Yen, Deren.Wu,
	km.lin, robin.chiu, ch.yeh, posh.sun, Eric.Liang, Stella.Chang,
	linux-wireless, linux-mediatek

[-- Attachment #1: Type: text/plain, Size: 7217 bytes --]

> From: Lorenzo Bianconi <lorenzo@kernel.org>
> 
> Move mt7921_dma_reset routine in dma.c and make mt7921_dma_prefetch
> static. Moreover add force parameter to mt7921_dma_reset signature.
> This is a preliminary patch to reset dma mt7921_mcu_drv_pmctrl.
> 
> Signed-off-by: Sean Wang <sean.wang@mediatek.com>
> Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
> ---
>  .../net/wireless/mediatek/mt76/mt7921/dma.c   | 71 +++++++++++++++++++
>  .../net/wireless/mediatek/mt76/mt7921/mac.c   | 66 +----------------
>  .../wireless/mediatek/mt76/mt7921/mt7921.h    |  2 +-
>  3 files changed, 73 insertions(+), 66 deletions(-)

Hi Sean,

I have just posted a preliminary series mandatory to enable deep sleep on mt7921.
I can post my patches of this seires (the one you posted) on top of it,
or if you prefer, can you please repost on top of my new series?

Regards,
Lorenzo

> 
> diff --git a/drivers/net/wireless/mediatek/mt76/mt7921/dma.c b/drivers/net/wireless/mediatek/mt76/mt7921/dma.c
> index 992faf82ad09..f8815aa247eb 100644
> --- a/drivers/net/wireless/mediatek/mt76/mt7921/dma.c
> +++ b/drivers/net/wireless/mediatek/mt76/mt7921/dma.c
> @@ -206,6 +206,77 @@ static int mt7921_dmashdl_disabled(struct mt7921_dev *dev)
>  	return 0;
>  }
>  
> +int mt7921_dma_reset(struct mt7921_dev *dev, bool force)
> +{
> +	int i;
> +
> +	if (force) {
> +		/* reset */
> +		mt76_clear(dev, MT_WFDMA0_RST,
> +			   MT_WFDMA0_RST_DMASHDL_ALL_RST |
> +			   MT_WFDMA0_RST_LOGIC_RST);
> +
> +		mt76_set(dev, MT_WFDMA0_RST,
> +			 MT_WFDMA0_RST_DMASHDL_ALL_RST |
> +			 MT_WFDMA0_RST_LOGIC_RST);
> +	}
> +
> +	/* disable WFDMA0 */
> +	mt76_clear(dev, MT_WFDMA0_GLO_CFG,
> +		   MT_WFDMA0_GLO_CFG_TX_DMA_EN | MT_WFDMA0_GLO_CFG_RX_DMA_EN |
> +		   MT_WFDMA0_GLO_CFG_CSR_DISP_BASE_PTR_CHAIN_EN |
> +		   MT_WFDMA0_GLO_CFG_OMIT_TX_INFO |
> +		   MT_WFDMA0_GLO_CFG_OMIT_RX_INFO |
> +		   MT_WFDMA0_GLO_CFG_OMIT_RX_INFO_PFET2);
> +
> +	if (!mt76_poll(dev, MT_WFDMA0_GLO_CFG,
> +		       MT_WFDMA0_GLO_CFG_TX_DMA_BUSY |
> +		       MT_WFDMA0_GLO_CFG_RX_DMA_BUSY, 0, 1000))
> +		return -ETIMEDOUT;
> +
> +	/* reset hw queues */
> +	for (i = 0; i < __MT_TXQ_MAX; i++)
> +		mt76_queue_reset(dev, dev->mphy.q_tx[i]);
> +
> +	for (i = 0; i < __MT_MCUQ_MAX; i++)
> +		mt76_queue_reset(dev, dev->mt76.q_mcu[i]);
> +
> +	mt76_for_each_q_rx(&dev->mt76, i)
> +		mt76_queue_reset(dev, &dev->mt76.q_rx[i]);
> +
> +	mt76_tx_status_check(&dev->mt76, NULL, true);
> +
> +	/* configure perfetch settings */
> +	mt7921_dma_prefetch(dev);
> +
> +	/* reset dma idx */
> +	mt76_wr(dev, MT_WFDMA0_RST_DTX_PTR, ~0);
> +
> +	/* configure delay interrupt */
> +	mt76_wr(dev, MT_WFDMA0_PRI_DLY_INT_CFG0, 0);
> +
> +	mt76_set(dev, MT_WFDMA0_GLO_CFG,
> +		 MT_WFDMA0_GLO_CFG_TX_WB_DDONE |
> +		 MT_WFDMA0_GLO_CFG_FIFO_LITTLE_ENDIAN |
> +		 MT_WFDMA0_GLO_CFG_CLK_GAT_DIS |
> +		 MT_WFDMA0_GLO_CFG_OMIT_TX_INFO |
> +		 MT_WFDMA0_GLO_CFG_CSR_DISP_BASE_PTR_CHAIN_EN |
> +		 MT_WFDMA0_GLO_CFG_OMIT_RX_INFO_PFET2);
> +
> +	mt76_set(dev, MT_WFDMA0_GLO_CFG,
> +		 MT_WFDMA0_GLO_CFG_TX_DMA_EN | MT_WFDMA0_GLO_CFG_RX_DMA_EN);
> +
> +	mt76_set(dev, MT_WFDMA_DUMMY_CR, MT_WFDMA_NEED_REINIT);
> +
> +	/* enable interrupts for TX/RX rings */
> +	mt7921_irq_enable(dev,
> +			  MT_INT_RX_DONE_ALL | MT_INT_TX_DONE_ALL |
> +			  MT_INT_MCU_CMD);
> +	mt76_set(dev, MT_MCU2HOST_SW_INT_ENA, MT_MCU_CMD_WAKE_RX_PCIE);
> +
> +	return 0;
> +}
> +
>  int mt7921_dma_init(struct mt7921_dev *dev)
>  {
>  	/* Increase buffer size to receive large VHT/HE MPDUs */
> diff --git a/drivers/net/wireless/mediatek/mt76/mt7921/mac.c b/drivers/net/wireless/mediatek/mt76/mt7921/mac.c
> index 3145880df6e7..4e319f1521a6 100644
> --- a/drivers/net/wireless/mediatek/mt76/mt7921/mac.c
> +++ b/drivers/net/wireless/mediatek/mt76/mt7921/mac.c
> @@ -1220,70 +1220,6 @@ int mt7921_wfsys_reset(struct mt7921_dev *dev)
>  				WFSYS_SW_INIT_DONE, WFSYS_SW_INIT_DONE, 500);
>  }
>  
> -static void
> -mt7921_dma_reset(struct mt7921_dev *dev)
> -{
> -	int i;
> -
> -	/* reset */
> -	mt76_clear(dev, MT_WFDMA0_RST,
> -		   MT_WFDMA0_RST_DMASHDL_ALL_RST | MT_WFDMA0_RST_LOGIC_RST);
> -
> -	mt76_set(dev, MT_WFDMA0_RST,
> -		 MT_WFDMA0_RST_DMASHDL_ALL_RST | MT_WFDMA0_RST_LOGIC_RST);
> -
> -	/* disable WFDMA0 */
> -	mt76_clear(dev, MT_WFDMA0_GLO_CFG,
> -		   MT_WFDMA0_GLO_CFG_TX_DMA_EN | MT_WFDMA0_GLO_CFG_RX_DMA_EN |
> -		   MT_WFDMA0_GLO_CFG_CSR_DISP_BASE_PTR_CHAIN_EN |
> -		   MT_WFDMA0_GLO_CFG_OMIT_TX_INFO |
> -		   MT_WFDMA0_GLO_CFG_OMIT_RX_INFO |
> -		   MT_WFDMA0_GLO_CFG_OMIT_RX_INFO_PFET2);
> -
> -	mt76_poll(dev, MT_WFDMA0_GLO_CFG,
> -		  MT_WFDMA0_GLO_CFG_TX_DMA_BUSY |
> -		  MT_WFDMA0_GLO_CFG_RX_DMA_BUSY, 0, 1000);
> -
> -	/* reset hw queues */
> -	for (i = 0; i < __MT_TXQ_MAX; i++)
> -		mt76_queue_reset(dev, dev->mphy.q_tx[i]);
> -
> -	for (i = 0; i < __MT_MCUQ_MAX; i++)
> -		mt76_queue_reset(dev, dev->mt76.q_mcu[i]);
> -
> -	mt76_for_each_q_rx(&dev->mt76, i)
> -		mt76_queue_reset(dev, &dev->mt76.q_rx[i]);
> -
> -	mt76_tx_status_check(&dev->mt76, NULL, true);
> -
> -	/* configure perfetch settings */
> -	mt7921_dma_prefetch(dev);
> -
> -	/* reset dma idx */
> -	mt76_wr(dev, MT_WFDMA0_RST_DTX_PTR, ~0);
> -
> -	/* configure delay interrupt */
> -	mt76_wr(dev, MT_WFDMA0_PRI_DLY_INT_CFG0, 0);
> -
> -	mt76_set(dev, MT_WFDMA0_GLO_CFG,
> -		 MT_WFDMA0_GLO_CFG_TX_WB_DDONE |
> -		 MT_WFDMA0_GLO_CFG_FIFO_LITTLE_ENDIAN |
> -		 MT_WFDMA0_GLO_CFG_CLK_GAT_DIS |
> -		 MT_WFDMA0_GLO_CFG_OMIT_TX_INFO |
> -		 MT_WFDMA0_GLO_CFG_CSR_DISP_BASE_PTR_CHAIN_EN |
> -		 MT_WFDMA0_GLO_CFG_OMIT_RX_INFO_PFET2);
> -
> -	mt76_set(dev, MT_WFDMA0_GLO_CFG,
> -		 MT_WFDMA0_GLO_CFG_TX_DMA_EN | MT_WFDMA0_GLO_CFG_RX_DMA_EN);
> -
> -	mt76_set(dev, MT_WFDMA_DUMMY_CR, MT_WFDMA_NEED_REINIT);
> -
> -	/* enable interrupts for TX/RX rings */
> -	mt7921_irq_enable(dev,
> -			  MT_INT_RX_DONE_ALL | MT_INT_TX_DONE_ALL |
> -			  MT_INT_MCU_CMD);
> -}
> -
>  void mt7921_tx_token_put(struct mt7921_dev *dev)
>  {
>  	struct mt76_txwi_cache *txwi;
> @@ -1354,7 +1290,7 @@ mt7921_mac_reset(struct mt7921_dev *dev)
>  		mt76_queue_rx_cleanup(dev, &dev->mt76.q_rx[i]);
>  
>  	mt7921_wfsys_reset(dev);
> -	mt7921_dma_reset(dev);
> +	mt7921_dma_reset(dev, true);
>  
>  	mt76_for_each_q_rx(&dev->mt76, i) {
>  		mt76_queue_rx_reset(dev, i);
> diff --git a/drivers/net/wireless/mediatek/mt76/mt7921/mt7921.h b/drivers/net/wireless/mediatek/mt76/mt7921/mt7921.h
> index c34cf3e3a26b..9b476641616d 100644
> --- a/drivers/net/wireless/mediatek/mt76/mt7921/mt7921.h
> +++ b/drivers/net/wireless/mediatek/mt76/mt7921/mt7921.h
> @@ -253,7 +253,7 @@ int mt7921_eeprom_get_target_power(struct mt7921_dev *dev,
>  				   u8 chain_idx);
>  void mt7921_eeprom_init_sku(struct mt7921_dev *dev);
>  int mt7921_dma_init(struct mt7921_dev *dev);
> -void mt7921_dma_prefetch(struct mt7921_dev *dev);
> +int mt7921_dma_reset(struct mt7921_dev *dev, bool force);
>  void mt7921_dma_cleanup(struct mt7921_dev *dev);
>  int mt7921_run_firmware(struct mt7921_dev *dev);
>  int mt7921_mcu_init(struct mt7921_dev *dev);
> -- 
> 2.25.1
> 

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 228 bytes --]

^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: [PATCH 4/6] mt76: mt7921: introduce mt7921_wpdma_reinit_cond utility routine
  2021-04-18 16:36 ` [PATCH 4/6] mt76: mt7921: introduce mt7921_wpdma_reinit_cond utility routine sean.wang
@ 2021-04-18 16:48   ` Lorenzo Bianconi
  0 siblings, 0 replies; 9+ messages in thread
From: Lorenzo Bianconi @ 2021-04-18 16:48 UTC (permalink / raw)
  To: sean.wang
  Cc: nbd, lorenzo.bianconi, Soul.Huang, YN.Chen, Leon.Yen, Deren.Wu,
	km.lin, robin.chiu, ch.yeh, posh.sun, Eric.Liang, Stella.Chang,
	linux-wireless, linux-mediatek

[-- Attachment #1: Type: text/plain, Size: 4942 bytes --]

> From: Sean Wang <sean.wang@mediatek.com>

I guess here we should use my 'From' tag

Regards,
Lorenzo

> 
> Add mt7921_wpdma_reinit_cond to check dummy reg if driver needs to
> reinitialized WPDMA after driver_own operation
> 
> Co-developed-by: Leon Yen <leon.yen@mediatek.com>
> Signed-off-by: Leon Yen <leon.yen@mediatek.com>
> Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
> Signed-off-by: Sean Wang <sean.wang@mediatek.com>
> ---
>  .../net/wireless/mediatek/mt76/mt76_connac.h  |  4 +++
>  .../wireless/mediatek/mt76/mt7921/debugfs.c   | 13 ++++++++++
>  .../net/wireless/mediatek/mt76/mt7921/dma.c   | 25 +++++++++++++++++++
>  .../wireless/mediatek/mt76/mt7921/mt7921.h    |  6 +++++
>  4 files changed, 48 insertions(+)
> 
> diff --git a/drivers/net/wireless/mediatek/mt76/mt76_connac.h b/drivers/net/wireless/mediatek/mt76/mt76_connac.h
> index b811f3c410a1..3b5bff80a462 100644
> --- a/drivers/net/wireless/mediatek/mt76/mt76_connac.h
> +++ b/drivers/net/wireless/mediatek/mt76/mt76_connac.h
> @@ -58,6 +58,10 @@ struct mt76_connac_pm {
>  	struct delayed_work ps_work;
>  	unsigned long last_activity;
>  	unsigned long idle_timeout;
> +
> +	struct {
> +		unsigned int lp_wake;
> +	} stats;
>  };
>  
>  struct mt76_connac_coredump {
> diff --git a/drivers/net/wireless/mediatek/mt76/mt7921/debugfs.c b/drivers/net/wireless/mediatek/mt76/mt7921/debugfs.c
> index 5a54cd8d2ce4..bd2aca654767 100644
> --- a/drivers/net/wireless/mediatek/mt76/mt7921/debugfs.c
> +++ b/drivers/net/wireless/mediatek/mt76/mt7921/debugfs.c
> @@ -256,6 +256,17 @@ mt7921_pm_get(void *data, u64 *val)
>  
>  DEFINE_DEBUGFS_ATTRIBUTE(fops_pm, mt7921_pm_get, mt7921_pm_set, "%lld\n");
>  
> +static int
> +mt7921_pm_stats(struct seq_file *s, void *data)
> +{
> +	struct mt7921_dev *dev = dev_get_drvdata(s->private);
> +	struct mt76_connac_pm *pm = &dev->pm;
> +
> +	seq_printf(s, "low power wakes: %9d\n", pm->stats.lp_wake);
> +
> +	return 0;
> +}
> +
>  static int
>  mt7921_pm_idle_timeout_set(void *data, u64 val)
>  {
> @@ -322,6 +333,8 @@ int mt7921_init_debugfs(struct mt7921_dev *dev)
>  	debugfs_create_file("idle-timeout", 0600, dir, dev,
>  			    &fops_pm_idle_timeout);
>  	debugfs_create_file("chip_reset", 0600, dir, dev, &fops_reset);
> +	debugfs_create_devm_seqfile(dev->mt76.dev, "runtime_pm_stats", dir,
> +				    mt7921_pm_stats);
>  
>  	return 0;
>  }
> diff --git a/drivers/net/wireless/mediatek/mt76/mt7921/dma.c b/drivers/net/wireless/mediatek/mt76/mt7921/dma.c
> index 8c556ff3ae93..72f5704f8f11 100644
> --- a/drivers/net/wireless/mediatek/mt76/mt7921/dma.c
> +++ b/drivers/net/wireless/mediatek/mt76/mt7921/dma.c
> @@ -329,6 +329,31 @@ int mt7921_wpdma_reset(struct mt7921_dev *dev, bool force)
>  	return 0;
>  }
>  
> +int mt7921_wpdma_reinit_cond(struct mt7921_dev *dev)
> +{
> +	struct mt76_connac_pm *pm = &dev->pm;
> +	int err;
> +
> +	/* check if the wpdma must be reinitialized */
> +	if (mt7921_dma_need_reinit(dev)) {
> +		/* disable interrutpts */
> +		mt76_wr(dev, MT_WFDMA0_HOST_INT_ENA, 0);
> +		mt76_wr(dev, MT_PCIE_MAC_INT_ENABLE, 0x0);
> +
> +		err = mt7921_wpdma_reset(dev, false);
> +		if (err) {
> +			dev_err(dev->mt76.dev, "wpdma reset failed\n");
> +			return err;
> +		}
> +
> +		/* enable interrutpts */
> +		mt76_wr(dev, MT_PCIE_MAC_INT_ENABLE, 0xff);
> +		pm->stats.lp_wake++;
> +	}
> +
> +	return 0;
> +}
> +
>  int mt7921_dma_init(struct mt7921_dev *dev)
>  {
>  	/* Increase buffer size to receive large VHT/HE MPDUs */
> diff --git a/drivers/net/wireless/mediatek/mt76/mt7921/mt7921.h b/drivers/net/wireless/mediatek/mt76/mt7921/mt7921.h
> index 06a85d2d1c6f..bb4961d3969a 100644
> --- a/drivers/net/wireless/mediatek/mt76/mt7921/mt7921.h
> +++ b/drivers/net/wireless/mediatek/mt76/mt7921/mt7921.h
> @@ -254,6 +254,7 @@ int mt7921_eeprom_get_target_power(struct mt7921_dev *dev,
>  void mt7921_eeprom_init_sku(struct mt7921_dev *dev);
>  int mt7921_dma_init(struct mt7921_dev *dev);
>  int mt7921_wpdma_reset(struct mt7921_dev *dev, bool force);
> +int mt7921_wpdma_reinit_cond(struct mt7921_dev *dev);
>  void mt7921_dma_cleanup(struct mt7921_dev *dev);
>  int mt7921_run_firmware(struct mt7921_dev *dev);
>  int mt7921_mcu_init(struct mt7921_dev *dev);
> @@ -317,6 +318,11 @@ mt7921_l1_rmw(struct mt7921_dev *dev, u32 addr, u32 mask, u32 val)
>  #define mt7921_l1_set(dev, addr, val)	mt7921_l1_rmw(dev, addr, 0, val)
>  #define mt7921_l1_clear(dev, addr, val)	mt7921_l1_rmw(dev, addr, val, 0)
>  
> +static inline bool mt7921_dma_need_reinit(struct mt7921_dev *dev)
> +{
> +	return !mt76_get_field(dev, MT_WFDMA_DUMMY_CR, MT_WFDMA_NEED_REINIT);
> +}
> +
>  void mt7921_mac_init(struct mt7921_dev *dev);
>  bool mt7921_mac_wtbl_update(struct mt7921_dev *dev, int idx, u32 mask);
>  void mt7921_mac_reset_counters(struct mt7921_phy *phy);
> -- 
> 2.25.1
> 

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 228 bytes --]

^ permalink raw reply	[flat|nested] 9+ messages in thread

end of thread, other threads:[~2021-04-18 16:48 UTC | newest]

Thread overview: 9+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2021-04-18 16:36 [PATCH 0/6] enable deep sleep mode when mt7921e suspends sean.wang
2021-04-18 16:36 ` [PATCH 1/6] mt76: mt7921: move mt7921_dma_reset in dma.c sean.wang
2021-04-18 16:47   ` Lorenzo Bianconi
2021-04-18 16:36 ` [PATCH 2/6] mt76: mt7921: introduce mt7921_wpdma_reset utility routine sean.wang
2021-04-18 16:36 ` [PATCH 3/6] mt76: mt7921: introduce mt7921_dma_{enable,disable} utilities sean.wang
2021-04-18 16:36 ` [PATCH 4/6] mt76: mt7921: introduce mt7921_wpdma_reinit_cond utility routine sean.wang
2021-04-18 16:48   ` Lorenzo Bianconi
2021-04-18 16:36 ` [PATCH 5/6] mt76: connac: introduce mt76_connac_mcu_set_deep_sleep utility sean.wang
2021-04-18 16:36 ` [PATCH 6/6] mt76: mt7921: enable deep sleep when the device suspends sean.wang

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).