xref: /freebsd/sys/contrib/dev/mediatek/mt76/mt792x_dma.c (revision 2008043f386721d58158e37e0d7e50df8095942d)
1 // SPDX-License-Identifier: ISC
2 /* Copyright (C) 2023 MediaTek Inc. */
3 
4 #include <linux/module.h>
5 #include <linux/firmware.h>
6 #if defined(__FreeBSD__)
7 #include <linux/delay.h>
8 #endif
9 
10 #include "mt792x.h"
11 #include "dma.h"
12 #include "trace.h"
13 
14 irqreturn_t mt792x_irq_handler(int irq, void *dev_instance)
15 {
16 	struct mt792x_dev *dev = dev_instance;
17 
18 	mt76_wr(dev, dev->irq_map->host_irq_enable, 0);
19 
20 	if (!test_bit(MT76_STATE_INITIALIZED, &dev->mphy.state))
21 		return IRQ_NONE;
22 
23 	tasklet_schedule(&dev->mt76.irq_tasklet);
24 
25 	return IRQ_HANDLED;
26 }
27 EXPORT_SYMBOL_GPL(mt792x_irq_handler);
28 
29 void mt792x_irq_tasklet(unsigned long data)
30 {
31 	struct mt792x_dev *dev = (struct mt792x_dev *)data;
32 	const struct mt792x_irq_map *irq_map = dev->irq_map;
33 	u32 intr, mask = 0;
34 
35 	mt76_wr(dev, irq_map->host_irq_enable, 0);
36 
37 	intr = mt76_rr(dev, MT_WFDMA0_HOST_INT_STA);
38 	intr &= dev->mt76.mmio.irqmask;
39 	mt76_wr(dev, MT_WFDMA0_HOST_INT_STA, intr);
40 
41 	trace_dev_irq(&dev->mt76, intr, dev->mt76.mmio.irqmask);
42 
43 	mask |= intr & (irq_map->rx.data_complete_mask |
44 			irq_map->rx.wm_complete_mask |
45 			irq_map->rx.wm2_complete_mask);
46 	if (intr & dev->irq_map->tx.mcu_complete_mask)
47 		mask |= dev->irq_map->tx.mcu_complete_mask;
48 
49 	if (intr & MT_INT_MCU_CMD) {
50 		u32 intr_sw;
51 
52 		intr_sw = mt76_rr(dev, MT_MCU_CMD);
53 		/* ack MCU2HOST_SW_INT_STA */
54 		mt76_wr(dev, MT_MCU_CMD, intr_sw);
55 		if (intr_sw & MT_MCU_CMD_WAKE_RX_PCIE) {
56 			mask |= irq_map->rx.data_complete_mask;
57 			intr |= irq_map->rx.data_complete_mask;
58 		}
59 	}
60 
61 	mt76_set_irq_mask(&dev->mt76, irq_map->host_irq_enable, mask, 0);
62 
63 	if (intr & dev->irq_map->tx.all_complete_mask)
64 		napi_schedule(&dev->mt76.tx_napi);
65 
66 	if (intr & irq_map->rx.wm_complete_mask)
67 		napi_schedule(&dev->mt76.napi[MT_RXQ_MCU]);
68 
69 	if (intr & irq_map->rx.wm2_complete_mask)
70 		napi_schedule(&dev->mt76.napi[MT_RXQ_MCU_WA]);
71 
72 	if (intr & irq_map->rx.data_complete_mask)
73 		napi_schedule(&dev->mt76.napi[MT_RXQ_MAIN]);
74 }
75 EXPORT_SYMBOL_GPL(mt792x_irq_tasklet);
76 
77 void mt792x_rx_poll_complete(struct mt76_dev *mdev, enum mt76_rxq_id q)
78 {
79 	struct mt792x_dev *dev = container_of(mdev, struct mt792x_dev, mt76);
80 	const struct mt792x_irq_map *irq_map = dev->irq_map;
81 
82 	if (q == MT_RXQ_MAIN)
83 		mt76_connac_irq_enable(mdev, irq_map->rx.data_complete_mask);
84 	else if (q == MT_RXQ_MCU_WA)
85 		mt76_connac_irq_enable(mdev, irq_map->rx.wm2_complete_mask);
86 	else
87 		mt76_connac_irq_enable(mdev, irq_map->rx.wm_complete_mask);
88 }
89 EXPORT_SYMBOL_GPL(mt792x_rx_poll_complete);
90 
91 #define PREFETCH(base, depth)	((base) << 16 | (depth))
92 static void mt792x_dma_prefetch(struct mt792x_dev *dev)
93 {
94 	mt76_wr(dev, MT_WFDMA0_RX_RING0_EXT_CTRL, PREFETCH(0x0, 0x4));
95 	mt76_wr(dev, MT_WFDMA0_RX_RING2_EXT_CTRL, PREFETCH(0x40, 0x4));
96 	mt76_wr(dev, MT_WFDMA0_RX_RING3_EXT_CTRL, PREFETCH(0x80, 0x4));
97 	mt76_wr(dev, MT_WFDMA0_RX_RING4_EXT_CTRL, PREFETCH(0xc0, 0x4));
98 	mt76_wr(dev, MT_WFDMA0_RX_RING5_EXT_CTRL, PREFETCH(0x100, 0x4));
99 
100 	mt76_wr(dev, MT_WFDMA0_TX_RING0_EXT_CTRL, PREFETCH(0x140, 0x4));
101 	mt76_wr(dev, MT_WFDMA0_TX_RING1_EXT_CTRL, PREFETCH(0x180, 0x4));
102 	mt76_wr(dev, MT_WFDMA0_TX_RING2_EXT_CTRL, PREFETCH(0x1c0, 0x4));
103 	mt76_wr(dev, MT_WFDMA0_TX_RING3_EXT_CTRL, PREFETCH(0x200, 0x4));
104 	mt76_wr(dev, MT_WFDMA0_TX_RING4_EXT_CTRL, PREFETCH(0x240, 0x4));
105 	mt76_wr(dev, MT_WFDMA0_TX_RING5_EXT_CTRL, PREFETCH(0x280, 0x4));
106 	mt76_wr(dev, MT_WFDMA0_TX_RING6_EXT_CTRL, PREFETCH(0x2c0, 0x4));
107 	mt76_wr(dev, MT_WFDMA0_TX_RING16_EXT_CTRL, PREFETCH(0x340, 0x4));
108 	mt76_wr(dev, MT_WFDMA0_TX_RING17_EXT_CTRL, PREFETCH(0x380, 0x4));
109 }
110 
111 int mt792x_dma_enable(struct mt792x_dev *dev)
112 {
113 	/* configure perfetch settings */
114 	mt792x_dma_prefetch(dev);
115 
116 	/* reset dma idx */
117 	mt76_wr(dev, MT_WFDMA0_RST_DTX_PTR, ~0);
118 
119 	/* configure delay interrupt */
120 	mt76_wr(dev, MT_WFDMA0_PRI_DLY_INT_CFG0, 0);
121 
122 	mt76_set(dev, MT_WFDMA0_GLO_CFG,
123 		 MT_WFDMA0_GLO_CFG_TX_WB_DDONE |
124 		 MT_WFDMA0_GLO_CFG_FIFO_LITTLE_ENDIAN |
125 		 MT_WFDMA0_GLO_CFG_CLK_GAT_DIS |
126 		 MT_WFDMA0_GLO_CFG_OMIT_TX_INFO |
127 		 MT_WFDMA0_GLO_CFG_CSR_DISP_BASE_PTR_CHAIN_EN |
128 		 MT_WFDMA0_GLO_CFG_OMIT_RX_INFO_PFET2);
129 
130 	mt76_set(dev, MT_WFDMA0_GLO_CFG,
131 		 MT_WFDMA0_GLO_CFG_TX_DMA_EN | MT_WFDMA0_GLO_CFG_RX_DMA_EN);
132 
133 	mt76_set(dev, MT_WFDMA_DUMMY_CR, MT_WFDMA_NEED_REINIT);
134 
135 	/* enable interrupts for TX/RX rings */
136 	mt76_connac_irq_enable(&dev->mt76,
137 			       dev->irq_map->tx.all_complete_mask |
138 			       dev->irq_map->rx.data_complete_mask |
139 			       dev->irq_map->rx.wm2_complete_mask |
140 			       dev->irq_map->rx.wm_complete_mask |
141 			       MT_INT_MCU_CMD);
142 	mt76_set(dev, MT_MCU2HOST_SW_INT_ENA, MT_MCU_CMD_WAKE_RX_PCIE);
143 
144 	return 0;
145 }
146 EXPORT_SYMBOL_GPL(mt792x_dma_enable);
147 
148 static int
149 mt792x_dma_reset(struct mt792x_dev *dev, bool force)
150 {
151 	int i, err;
152 
153 	err = mt792x_dma_disable(dev, force);
154 	if (err)
155 		return err;
156 
157 	/* reset hw queues */
158 	for (i = 0; i < __MT_TXQ_MAX; i++)
159 		mt76_queue_reset(dev, dev->mphy.q_tx[i]);
160 
161 	for (i = 0; i < __MT_MCUQ_MAX; i++)
162 		mt76_queue_reset(dev, dev->mt76.q_mcu[i]);
163 
164 	mt76_for_each_q_rx(&dev->mt76, i)
165 		mt76_queue_reset(dev, &dev->mt76.q_rx[i]);
166 
167 	mt76_tx_status_check(&dev->mt76, true);
168 
169 	return mt792x_dma_enable(dev);
170 }
171 
172 int mt792x_wpdma_reset(struct mt792x_dev *dev, bool force)
173 {
174 	int i, err;
175 
176 	/* clean up hw queues */
177 	for (i = 0; i < ARRAY_SIZE(dev->mt76.phy.q_tx); i++)
178 		mt76_queue_tx_cleanup(dev, dev->mphy.q_tx[i], true);
179 
180 	for (i = 0; i < ARRAY_SIZE(dev->mt76.q_mcu); i++)
181 		mt76_queue_tx_cleanup(dev, dev->mt76.q_mcu[i], true);
182 
183 	mt76_for_each_q_rx(&dev->mt76, i)
184 		mt76_queue_rx_cleanup(dev, &dev->mt76.q_rx[i]);
185 
186 	if (force) {
187 		err = mt792x_wfsys_reset(dev);
188 		if (err)
189 			return err;
190 	}
191 	err = mt792x_dma_reset(dev, force);
192 	if (err)
193 		return err;
194 
195 	mt76_for_each_q_rx(&dev->mt76, i)
196 		mt76_queue_rx_reset(dev, i);
197 
198 	return 0;
199 }
200 EXPORT_SYMBOL_GPL(mt792x_wpdma_reset);
201 
202 int mt792x_wpdma_reinit_cond(struct mt792x_dev *dev)
203 {
204 	struct mt76_connac_pm *pm = &dev->pm;
205 	int err;
206 
207 	/* check if the wpdma must be reinitialized */
208 	if (mt792x_dma_need_reinit(dev)) {
209 		/* disable interrutpts */
210 		mt76_wr(dev, dev->irq_map->host_irq_enable, 0);
211 		mt76_wr(dev, MT_PCIE_MAC_INT_ENABLE, 0x0);
212 
213 		err = mt792x_wpdma_reset(dev, false);
214 		if (err) {
215 			dev_err(dev->mt76.dev, "wpdma reset failed\n");
216 			return err;
217 		}
218 
219 		/* enable interrutpts */
220 		mt76_wr(dev, MT_PCIE_MAC_INT_ENABLE, 0xff);
221 		pm->stats.lp_wake++;
222 	}
223 
224 	return 0;
225 }
226 EXPORT_SYMBOL_GPL(mt792x_wpdma_reinit_cond);
227 
228 int mt792x_dma_disable(struct mt792x_dev *dev, bool force)
229 {
230 	/* disable WFDMA0 */
231 	mt76_clear(dev, MT_WFDMA0_GLO_CFG,
232 		   MT_WFDMA0_GLO_CFG_TX_DMA_EN | MT_WFDMA0_GLO_CFG_RX_DMA_EN |
233 		   MT_WFDMA0_GLO_CFG_CSR_DISP_BASE_PTR_CHAIN_EN |
234 		   MT_WFDMA0_GLO_CFG_OMIT_TX_INFO |
235 		   MT_WFDMA0_GLO_CFG_OMIT_RX_INFO |
236 		   MT_WFDMA0_GLO_CFG_OMIT_RX_INFO_PFET2);
237 
238 	if (!mt76_poll_msec_tick(dev, MT_WFDMA0_GLO_CFG,
239 				 MT_WFDMA0_GLO_CFG_TX_DMA_BUSY |
240 				 MT_WFDMA0_GLO_CFG_RX_DMA_BUSY, 0, 100, 1))
241 		return -ETIMEDOUT;
242 
243 	/* disable dmashdl */
244 	mt76_clear(dev, MT_WFDMA0_GLO_CFG_EXT0,
245 		   MT_WFDMA0_CSR_TX_DMASHDL_ENABLE);
246 	mt76_set(dev, MT_DMASHDL_SW_CONTROL, MT_DMASHDL_DMASHDL_BYPASS);
247 
248 	if (force) {
249 		/* reset */
250 		mt76_clear(dev, MT_WFDMA0_RST,
251 			   MT_WFDMA0_RST_DMASHDL_ALL_RST |
252 			   MT_WFDMA0_RST_LOGIC_RST);
253 
254 		mt76_set(dev, MT_WFDMA0_RST,
255 			 MT_WFDMA0_RST_DMASHDL_ALL_RST |
256 			 MT_WFDMA0_RST_LOGIC_RST);
257 	}
258 
259 	return 0;
260 }
261 EXPORT_SYMBOL_GPL(mt792x_dma_disable);
262 
263 void mt792x_dma_cleanup(struct mt792x_dev *dev)
264 {
265 	/* disable */
266 	mt76_clear(dev, MT_WFDMA0_GLO_CFG,
267 		   MT_WFDMA0_GLO_CFG_TX_DMA_EN |
268 		   MT_WFDMA0_GLO_CFG_RX_DMA_EN |
269 		   MT_WFDMA0_GLO_CFG_CSR_DISP_BASE_PTR_CHAIN_EN |
270 		   MT_WFDMA0_GLO_CFG_OMIT_TX_INFO |
271 		   MT_WFDMA0_GLO_CFG_OMIT_RX_INFO |
272 		   MT_WFDMA0_GLO_CFG_OMIT_RX_INFO_PFET2);
273 
274 	mt76_poll_msec_tick(dev, MT_WFDMA0_GLO_CFG,
275 			    MT_WFDMA0_GLO_CFG_TX_DMA_BUSY |
276 			    MT_WFDMA0_GLO_CFG_RX_DMA_BUSY, 0, 100, 1);
277 
278 	/* reset */
279 	mt76_clear(dev, MT_WFDMA0_RST,
280 		   MT_WFDMA0_RST_DMASHDL_ALL_RST |
281 		   MT_WFDMA0_RST_LOGIC_RST);
282 
283 	mt76_set(dev, MT_WFDMA0_RST,
284 		 MT_WFDMA0_RST_DMASHDL_ALL_RST |
285 		 MT_WFDMA0_RST_LOGIC_RST);
286 
287 	mt76_dma_cleanup(&dev->mt76);
288 }
289 EXPORT_SYMBOL_GPL(mt792x_dma_cleanup);
290 
291 int mt792x_poll_tx(struct napi_struct *napi, int budget)
292 {
293 	struct mt792x_dev *dev;
294 
295 	dev = container_of(napi, struct mt792x_dev, mt76.tx_napi);
296 
297 	if (!mt76_connac_pm_ref(&dev->mphy, &dev->pm)) {
298 		napi_complete(napi);
299 		queue_work(dev->mt76.wq, &dev->pm.wake_work);
300 		return 0;
301 	}
302 
303 	mt76_connac_tx_cleanup(&dev->mt76);
304 	if (napi_complete(napi))
305 		mt76_connac_irq_enable(&dev->mt76,
306 				       dev->irq_map->tx.all_complete_mask);
307 	mt76_connac_pm_unref(&dev->mphy, &dev->pm);
308 
309 	return 0;
310 }
311 EXPORT_SYMBOL_GPL(mt792x_poll_tx);
312 
313 int mt792x_poll_rx(struct napi_struct *napi, int budget)
314 {
315 	struct mt792x_dev *dev;
316 	int done;
317 
318 	dev = container_of(napi->dev, struct mt792x_dev, mt76.napi_dev);
319 
320 	if (!mt76_connac_pm_ref(&dev->mphy, &dev->pm)) {
321 		napi_complete(napi);
322 		queue_work(dev->mt76.wq, &dev->pm.wake_work);
323 		return 0;
324 	}
325 	done = mt76_dma_rx_poll(napi, budget);
326 	mt76_connac_pm_unref(&dev->mphy, &dev->pm);
327 
328 	return done;
329 }
330 EXPORT_SYMBOL_GPL(mt792x_poll_rx);
331 
332 int mt792x_wfsys_reset(struct mt792x_dev *dev)
333 {
334 	u32 addr = is_mt7921(&dev->mt76) ? 0x18000140 : 0x7c000140;
335 
336 	mt76_clear(dev, addr, WFSYS_SW_RST_B);
337 	msleep(50);
338 	mt76_set(dev, addr, WFSYS_SW_RST_B);
339 
340 	if (!__mt76_poll_msec(&dev->mt76, addr, WFSYS_SW_INIT_DONE,
341 			      WFSYS_SW_INIT_DONE, 500))
342 		return -ETIMEDOUT;
343 
344 	return 0;
345 }
346 EXPORT_SYMBOL_GPL(mt792x_wfsys_reset);
347 
348