xref: /linux/drivers/net/wireless/ath/ath10k/snoc.c (revision b7d3826c2ed6c3e626e7ae796c5df2c0d2551c6a)
1 /*
2  * Copyright (c) 2018 The Linux Foundation. All rights reserved.
3  *
4  * Permission to use, copy, modify, and/or distribute this software for any
5  * purpose with or without fee is hereby granted, provided that the above
6  * copyright notice and this permission notice appear in all copies.
7  *
8  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
9  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
10  * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
11  * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
12  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
13  * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
14  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
15  */
16 
17 #include <linux/clk.h>
18 #include <linux/kernel.h>
19 #include <linux/module.h>
20 #include <linux/of.h>
21 #include <linux/of_device.h>
22 #include <linux/platform_device.h>
23 #include <linux/regulator/consumer.h>
24 
25 #include "ce.h"
26 #include "debug.h"
27 #include "hif.h"
28 #include "htc.h"
29 #include "snoc.h"
30 
31 #define ATH10K_SNOC_RX_POST_RETRY_MS 50
32 #define CE_POLL_PIPE 4
33 
34 static char *const ce_name[] = {
35 	"WLAN_CE_0",
36 	"WLAN_CE_1",
37 	"WLAN_CE_2",
38 	"WLAN_CE_3",
39 	"WLAN_CE_4",
40 	"WLAN_CE_5",
41 	"WLAN_CE_6",
42 	"WLAN_CE_7",
43 	"WLAN_CE_8",
44 	"WLAN_CE_9",
45 	"WLAN_CE_10",
46 	"WLAN_CE_11",
47 };
48 
49 static struct ath10k_wcn3990_vreg_info vreg_cfg[] = {
50 	{NULL, "vdd-0.8-cx-mx", 800000, 800000, 0, 0, false},
51 	{NULL, "vdd-1.8-xo", 1800000, 1800000, 0, 0, false},
52 	{NULL, "vdd-1.3-rfa", 1304000, 1304000, 0, 0, false},
53 	{NULL, "vdd-3.3-ch0", 3312000, 3312000, 0, 0, false},
54 };
55 
56 static struct ath10k_wcn3990_clk_info clk_cfg[] = {
57 	{NULL, "cxo_ref_clk_pin", 0, false},
58 };
59 
60 static void ath10k_snoc_htc_tx_cb(struct ath10k_ce_pipe *ce_state);
61 static void ath10k_snoc_htt_tx_cb(struct ath10k_ce_pipe *ce_state);
62 static void ath10k_snoc_htc_rx_cb(struct ath10k_ce_pipe *ce_state);
63 static void ath10k_snoc_htt_rx_cb(struct ath10k_ce_pipe *ce_state);
64 static void ath10k_snoc_htt_htc_rx_cb(struct ath10k_ce_pipe *ce_state);
65 static void ath10k_snoc_pktlog_rx_cb(struct ath10k_ce_pipe *ce_state);
66 
67 static const struct ath10k_snoc_drv_priv drv_priv = {
68 	.hw_rev = ATH10K_HW_WCN3990,
69 	.dma_mask = DMA_BIT_MASK(37),
70 };
71 
72 static struct ce_attr host_ce_config_wlan[] = {
73 	/* CE0: host->target HTC control streams */
74 	{
75 		.flags = CE_ATTR_FLAGS,
76 		.src_nentries = 16,
77 		.src_sz_max = 2048,
78 		.dest_nentries = 0,
79 		.send_cb = ath10k_snoc_htc_tx_cb,
80 	},
81 
82 	/* CE1: target->host HTT + HTC control */
83 	{
84 		.flags = CE_ATTR_FLAGS,
85 		.src_nentries = 0,
86 		.src_sz_max = 2048,
87 		.dest_nentries = 512,
88 		.recv_cb = ath10k_snoc_htt_htc_rx_cb,
89 	},
90 
91 	/* CE2: target->host WMI */
92 	{
93 		.flags = CE_ATTR_FLAGS,
94 		.src_nentries = 0,
95 		.src_sz_max = 2048,
96 		.dest_nentries = 64,
97 		.recv_cb = ath10k_snoc_htc_rx_cb,
98 	},
99 
100 	/* CE3: host->target WMI */
101 	{
102 		.flags = CE_ATTR_FLAGS,
103 		.src_nentries = 32,
104 		.src_sz_max = 2048,
105 		.dest_nentries = 0,
106 		.send_cb = ath10k_snoc_htc_tx_cb,
107 	},
108 
109 	/* CE4: host->target HTT */
110 	{
111 		.flags = CE_ATTR_FLAGS | CE_ATTR_DIS_INTR,
112 		.src_nentries = 256,
113 		.src_sz_max = 256,
114 		.dest_nentries = 0,
115 		.send_cb = ath10k_snoc_htt_tx_cb,
116 	},
117 
118 	/* CE5: target->host HTT (ipa_uc->target ) */
119 	{
120 		.flags = CE_ATTR_FLAGS,
121 		.src_nentries = 0,
122 		.src_sz_max = 512,
123 		.dest_nentries = 512,
124 		.recv_cb = ath10k_snoc_htt_rx_cb,
125 	},
126 
127 	/* CE6: target autonomous hif_memcpy */
128 	{
129 		.flags = CE_ATTR_FLAGS,
130 		.src_nentries = 0,
131 		.src_sz_max = 0,
132 		.dest_nentries = 0,
133 	},
134 
135 	/* CE7: ce_diag, the Diagnostic Window */
136 	{
137 		.flags = CE_ATTR_FLAGS,
138 		.src_nentries = 2,
139 		.src_sz_max = 2048,
140 		.dest_nentries = 2,
141 	},
142 
143 	/* CE8: Target to uMC */
144 	{
145 		.flags = CE_ATTR_FLAGS,
146 		.src_nentries = 0,
147 		.src_sz_max = 2048,
148 		.dest_nentries = 128,
149 	},
150 
151 	/* CE9 target->host HTT */
152 	{
153 		.flags = CE_ATTR_FLAGS,
154 		.src_nentries = 0,
155 		.src_sz_max = 2048,
156 		.dest_nentries = 512,
157 		.recv_cb = ath10k_snoc_htt_htc_rx_cb,
158 	},
159 
160 	/* CE10: target->host HTT */
161 	{
162 		.flags = CE_ATTR_FLAGS,
163 		.src_nentries = 0,
164 		.src_sz_max = 2048,
165 		.dest_nentries = 512,
166 		.recv_cb = ath10k_snoc_htt_htc_rx_cb,
167 	},
168 
169 	/* CE11: target -> host PKTLOG */
170 	{
171 		.flags = CE_ATTR_FLAGS,
172 		.src_nentries = 0,
173 		.src_sz_max = 2048,
174 		.dest_nentries = 512,
175 		.recv_cb = ath10k_snoc_pktlog_rx_cb,
176 	},
177 };
178 
179 static struct service_to_pipe target_service_to_ce_map_wlan[] = {
180 	{
181 		__cpu_to_le32(ATH10K_HTC_SVC_ID_WMI_DATA_VO),
182 		__cpu_to_le32(PIPEDIR_OUT),	/* out = UL = host -> target */
183 		__cpu_to_le32(3),
184 	},
185 	{
186 		__cpu_to_le32(ATH10K_HTC_SVC_ID_WMI_DATA_VO),
187 		__cpu_to_le32(PIPEDIR_IN),	/* in = DL = target -> host */
188 		__cpu_to_le32(2),
189 	},
190 	{
191 		__cpu_to_le32(ATH10K_HTC_SVC_ID_WMI_DATA_BK),
192 		__cpu_to_le32(PIPEDIR_OUT),	/* out = UL = host -> target */
193 		__cpu_to_le32(3),
194 	},
195 	{
196 		__cpu_to_le32(ATH10K_HTC_SVC_ID_WMI_DATA_BK),
197 		__cpu_to_le32(PIPEDIR_IN),	/* in = DL = target -> host */
198 		__cpu_to_le32(2),
199 	},
200 	{
201 		__cpu_to_le32(ATH10K_HTC_SVC_ID_WMI_DATA_BE),
202 		__cpu_to_le32(PIPEDIR_OUT),	/* out = UL = host -> target */
203 		__cpu_to_le32(3),
204 	},
205 	{
206 		__cpu_to_le32(ATH10K_HTC_SVC_ID_WMI_DATA_BE),
207 		__cpu_to_le32(PIPEDIR_IN),	/* in = DL = target -> host */
208 		__cpu_to_le32(2),
209 	},
210 	{
211 		__cpu_to_le32(ATH10K_HTC_SVC_ID_WMI_DATA_VI),
212 		__cpu_to_le32(PIPEDIR_OUT),	/* out = UL = host -> target */
213 		__cpu_to_le32(3),
214 	},
215 	{
216 		__cpu_to_le32(ATH10K_HTC_SVC_ID_WMI_DATA_VI),
217 		__cpu_to_le32(PIPEDIR_IN),	/* in = DL = target -> host */
218 		__cpu_to_le32(2),
219 	},
220 	{
221 		__cpu_to_le32(ATH10K_HTC_SVC_ID_WMI_CONTROL),
222 		__cpu_to_le32(PIPEDIR_OUT),	/* out = UL = host -> target */
223 		__cpu_to_le32(3),
224 	},
225 	{
226 		__cpu_to_le32(ATH10K_HTC_SVC_ID_WMI_CONTROL),
227 		__cpu_to_le32(PIPEDIR_IN),	/* in = DL = target -> host */
228 		__cpu_to_le32(2),
229 	},
230 	{
231 		__cpu_to_le32(ATH10K_HTC_SVC_ID_RSVD_CTRL),
232 		__cpu_to_le32(PIPEDIR_OUT),	/* out = UL = host -> target */
233 		__cpu_to_le32(0),
234 	},
235 	{
236 		__cpu_to_le32(ATH10K_HTC_SVC_ID_RSVD_CTRL),
237 		__cpu_to_le32(PIPEDIR_IN),	/* in = DL = target -> host */
238 		__cpu_to_le32(2),
239 	},
240 	{ /* not used */
241 		__cpu_to_le32(ATH10K_HTC_SVC_ID_TEST_RAW_STREAMS),
242 		__cpu_to_le32(PIPEDIR_OUT),	/* out = UL = host -> target */
243 		__cpu_to_le32(0),
244 	},
245 	{ /* not used */
246 		__cpu_to_le32(ATH10K_HTC_SVC_ID_TEST_RAW_STREAMS),
247 		__cpu_to_le32(PIPEDIR_IN),	/* in = DL = target -> host */
248 		__cpu_to_le32(2),
249 	},
250 	{
251 		__cpu_to_le32(ATH10K_HTC_SVC_ID_HTT_DATA_MSG),
252 		__cpu_to_le32(PIPEDIR_OUT),	/* out = UL = host -> target */
253 		__cpu_to_le32(4),
254 	},
255 	{
256 		__cpu_to_le32(ATH10K_HTC_SVC_ID_HTT_DATA_MSG),
257 		__cpu_to_le32(PIPEDIR_IN),	/* in = DL = target -> host */
258 		__cpu_to_le32(1),
259 	},
260 	{ /* not used */
261 		__cpu_to_le32(ATH10K_HTC_SVC_ID_TEST_RAW_STREAMS),
262 		__cpu_to_le32(PIPEDIR_OUT),
263 		__cpu_to_le32(5),
264 	},
265 	{ /* in = DL = target -> host */
266 		__cpu_to_le32(ATH10K_HTC_SVC_ID_HTT_DATA2_MSG),
267 		__cpu_to_le32(PIPEDIR_IN),	/* in = DL = target -> host */
268 		__cpu_to_le32(9),
269 	},
270 	{ /* in = DL = target -> host */
271 		__cpu_to_le32(ATH10K_HTC_SVC_ID_HTT_DATA3_MSG),
272 		__cpu_to_le32(PIPEDIR_IN),	/* in = DL = target -> host */
273 		__cpu_to_le32(10),
274 	},
275 	{ /* in = DL = target -> host pktlog */
276 		__cpu_to_le32(ATH10K_HTC_SVC_ID_HTT_LOG_MSG),
277 		__cpu_to_le32(PIPEDIR_IN),	/* in = DL = target -> host */
278 		__cpu_to_le32(11),
279 	},
280 	/* (Additions here) */
281 
282 	{ /* must be last */
283 		__cpu_to_le32(0),
284 		__cpu_to_le32(0),
285 		__cpu_to_le32(0),
286 	},
287 };
288 
289 void ath10k_snoc_write32(struct ath10k *ar, u32 offset, u32 value)
290 {
291 	struct ath10k_snoc *ar_snoc = ath10k_snoc_priv(ar);
292 
293 	iowrite32(value, ar_snoc->mem + offset);
294 }
295 
296 u32 ath10k_snoc_read32(struct ath10k *ar, u32 offset)
297 {
298 	struct ath10k_snoc *ar_snoc = ath10k_snoc_priv(ar);
299 	u32 val;
300 
301 	val = ioread32(ar_snoc->mem + offset);
302 
303 	return val;
304 }
305 
306 static int __ath10k_snoc_rx_post_buf(struct ath10k_snoc_pipe *pipe)
307 {
308 	struct ath10k_ce_pipe *ce_pipe = pipe->ce_hdl;
309 	struct ath10k *ar = pipe->hif_ce_state;
310 	struct ath10k_ce *ce = ath10k_ce_priv(ar);
311 	struct sk_buff *skb;
312 	dma_addr_t paddr;
313 	int ret;
314 
315 	skb = dev_alloc_skb(pipe->buf_sz);
316 	if (!skb)
317 		return -ENOMEM;
318 
319 	WARN_ONCE((unsigned long)skb->data & 3, "unaligned skb");
320 
321 	paddr = dma_map_single(ar->dev, skb->data,
322 			       skb->len + skb_tailroom(skb),
323 			       DMA_FROM_DEVICE);
324 	if (unlikely(dma_mapping_error(ar->dev, paddr))) {
325 		ath10k_warn(ar, "failed to dma map snoc rx buf\n");
326 		dev_kfree_skb_any(skb);
327 		return -EIO;
328 	}
329 
330 	ATH10K_SKB_RXCB(skb)->paddr = paddr;
331 
332 	spin_lock_bh(&ce->ce_lock);
333 	ret = ce_pipe->ops->ce_rx_post_buf(ce_pipe, skb, paddr);
334 	spin_unlock_bh(&ce->ce_lock);
335 	if (ret) {
336 		dma_unmap_single(ar->dev, paddr, skb->len + skb_tailroom(skb),
337 				 DMA_FROM_DEVICE);
338 		dev_kfree_skb_any(skb);
339 		return ret;
340 	}
341 
342 	return 0;
343 }
344 
345 static void ath10k_snoc_rx_post_pipe(struct ath10k_snoc_pipe *pipe)
346 {
347 	struct ath10k *ar = pipe->hif_ce_state;
348 	struct ath10k_ce *ce = ath10k_ce_priv(ar);
349 	struct ath10k_snoc *ar_snoc = ath10k_snoc_priv(ar);
350 	struct ath10k_ce_pipe *ce_pipe = pipe->ce_hdl;
351 	int ret, num;
352 
353 	if (pipe->buf_sz == 0)
354 		return;
355 
356 	if (!ce_pipe->dest_ring)
357 		return;
358 
359 	spin_lock_bh(&ce->ce_lock);
360 	num = __ath10k_ce_rx_num_free_bufs(ce_pipe);
361 	spin_unlock_bh(&ce->ce_lock);
362 	while (num--) {
363 		ret = __ath10k_snoc_rx_post_buf(pipe);
364 		if (ret) {
365 			if (ret == -ENOSPC)
366 				break;
367 			ath10k_warn(ar, "failed to post rx buf: %d\n", ret);
368 			mod_timer(&ar_snoc->rx_post_retry, jiffies +
369 				  ATH10K_SNOC_RX_POST_RETRY_MS);
370 			break;
371 		}
372 	}
373 }
374 
375 static void ath10k_snoc_rx_post(struct ath10k *ar)
376 {
377 	struct ath10k_snoc *ar_snoc = ath10k_snoc_priv(ar);
378 	int i;
379 
380 	for (i = 0; i < CE_COUNT; i++)
381 		ath10k_snoc_rx_post_pipe(&ar_snoc->pipe_info[i]);
382 }
383 
384 static void ath10k_snoc_process_rx_cb(struct ath10k_ce_pipe *ce_state,
385 				      void (*callback)(struct ath10k *ar,
386 						       struct sk_buff *skb))
387 {
388 	struct ath10k *ar = ce_state->ar;
389 	struct ath10k_snoc *ar_snoc = ath10k_snoc_priv(ar);
390 	struct ath10k_snoc_pipe *pipe_info =  &ar_snoc->pipe_info[ce_state->id];
391 	struct sk_buff *skb;
392 	struct sk_buff_head list;
393 	void *transfer_context;
394 	unsigned int nbytes, max_nbytes;
395 
396 	__skb_queue_head_init(&list);
397 	while (ath10k_ce_completed_recv_next(ce_state, &transfer_context,
398 					     &nbytes) == 0) {
399 		skb = transfer_context;
400 		max_nbytes = skb->len + skb_tailroom(skb);
401 		dma_unmap_single(ar->dev, ATH10K_SKB_RXCB(skb)->paddr,
402 				 max_nbytes, DMA_FROM_DEVICE);
403 
404 		if (unlikely(max_nbytes < nbytes)) {
405 			ath10k_warn(ar, "rxed more than expected (nbytes %d, max %d)",
406 				    nbytes, max_nbytes);
407 			dev_kfree_skb_any(skb);
408 			continue;
409 		}
410 
411 		skb_put(skb, nbytes);
412 		__skb_queue_tail(&list, skb);
413 	}
414 
415 	while ((skb = __skb_dequeue(&list))) {
416 		ath10k_dbg(ar, ATH10K_DBG_SNOC, "snoc rx ce pipe %d len %d\n",
417 			   ce_state->id, skb->len);
418 
419 		callback(ar, skb);
420 	}
421 
422 	ath10k_snoc_rx_post_pipe(pipe_info);
423 }
424 
425 static void ath10k_snoc_htc_rx_cb(struct ath10k_ce_pipe *ce_state)
426 {
427 	ath10k_snoc_process_rx_cb(ce_state, ath10k_htc_rx_completion_handler);
428 }
429 
430 static void ath10k_snoc_htt_htc_rx_cb(struct ath10k_ce_pipe *ce_state)
431 {
432 	/* CE4 polling needs to be done whenever CE pipe which transports
433 	 * HTT Rx (target->host) is processed.
434 	 */
435 	ath10k_ce_per_engine_service(ce_state->ar, CE_POLL_PIPE);
436 
437 	ath10k_snoc_process_rx_cb(ce_state, ath10k_htc_rx_completion_handler);
438 }
439 
440 /* Called by lower (CE) layer when data is received from the Target.
441  * WCN3990 firmware uses separate CE(CE11) to transfer pktlog data.
442  */
443 static void ath10k_snoc_pktlog_rx_cb(struct ath10k_ce_pipe *ce_state)
444 {
445 	ath10k_snoc_process_rx_cb(ce_state, ath10k_htc_rx_completion_handler);
446 }
447 
448 static void ath10k_snoc_htt_rx_deliver(struct ath10k *ar, struct sk_buff *skb)
449 {
450 	skb_pull(skb, sizeof(struct ath10k_htc_hdr));
451 	ath10k_htt_t2h_msg_handler(ar, skb);
452 }
453 
454 static void ath10k_snoc_htt_rx_cb(struct ath10k_ce_pipe *ce_state)
455 {
456 	ath10k_ce_per_engine_service(ce_state->ar, CE_POLL_PIPE);
457 	ath10k_snoc_process_rx_cb(ce_state, ath10k_snoc_htt_rx_deliver);
458 }
459 
460 static void ath10k_snoc_rx_replenish_retry(struct timer_list *t)
461 {
462 	struct ath10k_snoc *ar_snoc = from_timer(ar_snoc, t, rx_post_retry);
463 	struct ath10k *ar = ar_snoc->ar;
464 
465 	ath10k_snoc_rx_post(ar);
466 }
467 
468 static void ath10k_snoc_htc_tx_cb(struct ath10k_ce_pipe *ce_state)
469 {
470 	struct ath10k *ar = ce_state->ar;
471 	struct sk_buff_head list;
472 	struct sk_buff *skb;
473 
474 	__skb_queue_head_init(&list);
475 	while (ath10k_ce_completed_send_next(ce_state, (void **)&skb) == 0) {
476 		if (!skb)
477 			continue;
478 
479 		__skb_queue_tail(&list, skb);
480 	}
481 
482 	while ((skb = __skb_dequeue(&list)))
483 		ath10k_htc_tx_completion_handler(ar, skb);
484 }
485 
486 static void ath10k_snoc_htt_tx_cb(struct ath10k_ce_pipe *ce_state)
487 {
488 	struct ath10k *ar = ce_state->ar;
489 	struct sk_buff *skb;
490 
491 	while (ath10k_ce_completed_send_next(ce_state, (void **)&skb) == 0) {
492 		if (!skb)
493 			continue;
494 
495 		dma_unmap_single(ar->dev, ATH10K_SKB_CB(skb)->paddr,
496 				 skb->len, DMA_TO_DEVICE);
497 		ath10k_htt_hif_tx_complete(ar, skb);
498 	}
499 }
500 
501 static int ath10k_snoc_hif_tx_sg(struct ath10k *ar, u8 pipe_id,
502 				 struct ath10k_hif_sg_item *items, int n_items)
503 {
504 	struct ath10k_snoc *ar_snoc = ath10k_snoc_priv(ar);
505 	struct ath10k_ce *ce = ath10k_ce_priv(ar);
506 	struct ath10k_snoc_pipe *snoc_pipe;
507 	struct ath10k_ce_pipe *ce_pipe;
508 	int err, i = 0;
509 
510 	snoc_pipe = &ar_snoc->pipe_info[pipe_id];
511 	ce_pipe = snoc_pipe->ce_hdl;
512 	spin_lock_bh(&ce->ce_lock);
513 
514 	for (i = 0; i < n_items - 1; i++) {
515 		ath10k_dbg(ar, ATH10K_DBG_SNOC,
516 			   "snoc tx item %d paddr %pad len %d n_items %d\n",
517 			   i, &items[i].paddr, items[i].len, n_items);
518 
519 		err = ath10k_ce_send_nolock(ce_pipe,
520 					    items[i].transfer_context,
521 					    items[i].paddr,
522 					    items[i].len,
523 					    items[i].transfer_id,
524 					    CE_SEND_FLAG_GATHER);
525 		if (err)
526 			goto err;
527 	}
528 
529 	ath10k_dbg(ar, ATH10K_DBG_SNOC,
530 		   "snoc tx item %d paddr %pad len %d n_items %d\n",
531 		   i, &items[i].paddr, items[i].len, n_items);
532 
533 	err = ath10k_ce_send_nolock(ce_pipe,
534 				    items[i].transfer_context,
535 				    items[i].paddr,
536 				    items[i].len,
537 				    items[i].transfer_id,
538 				    0);
539 	if (err)
540 		goto err;
541 
542 	spin_unlock_bh(&ce->ce_lock);
543 
544 	return 0;
545 
546 err:
547 	for (; i > 0; i--)
548 		__ath10k_ce_send_revert(ce_pipe);
549 
550 	spin_unlock_bh(&ce->ce_lock);
551 	return err;
552 }
553 
554 static int ath10k_snoc_hif_get_target_info(struct ath10k *ar,
555 					   struct bmi_target_info *target_info)
556 {
557 	target_info->version = ATH10K_HW_WCN3990;
558 	target_info->type = ATH10K_HW_WCN3990;
559 
560 	return 0;
561 }
562 
563 static u16 ath10k_snoc_hif_get_free_queue_number(struct ath10k *ar, u8 pipe)
564 {
565 	struct ath10k_snoc *ar_snoc = ath10k_snoc_priv(ar);
566 
567 	ath10k_dbg(ar, ATH10K_DBG_SNOC, "hif get free queue number\n");
568 
569 	return ath10k_ce_num_free_src_entries(ar_snoc->pipe_info[pipe].ce_hdl);
570 }
571 
572 static void ath10k_snoc_hif_send_complete_check(struct ath10k *ar, u8 pipe,
573 						int force)
574 {
575 	int resources;
576 
577 	ath10k_dbg(ar, ATH10K_DBG_SNOC, "snoc hif send complete check\n");
578 
579 	if (!force) {
580 		resources = ath10k_snoc_hif_get_free_queue_number(ar, pipe);
581 
582 		if (resources > (host_ce_config_wlan[pipe].src_nentries >> 1))
583 			return;
584 	}
585 	ath10k_ce_per_engine_service(ar, pipe);
586 }
587 
588 static int ath10k_snoc_hif_map_service_to_pipe(struct ath10k *ar,
589 					       u16 service_id,
590 					       u8 *ul_pipe, u8 *dl_pipe)
591 {
592 	const struct service_to_pipe *entry;
593 	bool ul_set = false, dl_set = false;
594 	int i;
595 
596 	ath10k_dbg(ar, ATH10K_DBG_SNOC, "snoc hif map service\n");
597 
598 	for (i = 0; i < ARRAY_SIZE(target_service_to_ce_map_wlan); i++) {
599 		entry = &target_service_to_ce_map_wlan[i];
600 
601 		if (__le32_to_cpu(entry->service_id) != service_id)
602 			continue;
603 
604 		switch (__le32_to_cpu(entry->pipedir)) {
605 		case PIPEDIR_NONE:
606 			break;
607 		case PIPEDIR_IN:
608 			WARN_ON(dl_set);
609 			*dl_pipe = __le32_to_cpu(entry->pipenum);
610 			dl_set = true;
611 			break;
612 		case PIPEDIR_OUT:
613 			WARN_ON(ul_set);
614 			*ul_pipe = __le32_to_cpu(entry->pipenum);
615 			ul_set = true;
616 			break;
617 		case PIPEDIR_INOUT:
618 			WARN_ON(dl_set);
619 			WARN_ON(ul_set);
620 			*dl_pipe = __le32_to_cpu(entry->pipenum);
621 			*ul_pipe = __le32_to_cpu(entry->pipenum);
622 			dl_set = true;
623 			ul_set = true;
624 			break;
625 		}
626 	}
627 
628 	if (!ul_set || !dl_set)
629 		return -ENOENT;
630 
631 	return 0;
632 }
633 
634 static void ath10k_snoc_hif_get_default_pipe(struct ath10k *ar,
635 					     u8 *ul_pipe, u8 *dl_pipe)
636 {
637 	ath10k_dbg(ar, ATH10K_DBG_SNOC, "snoc hif get default pipe\n");
638 
639 	(void)ath10k_snoc_hif_map_service_to_pipe(ar,
640 						 ATH10K_HTC_SVC_ID_RSVD_CTRL,
641 						 ul_pipe, dl_pipe);
642 }
643 
644 static inline void ath10k_snoc_irq_disable(struct ath10k *ar)
645 {
646 	ath10k_ce_disable_interrupts(ar);
647 }
648 
649 static inline void ath10k_snoc_irq_enable(struct ath10k *ar)
650 {
651 	ath10k_ce_enable_interrupts(ar);
652 }
653 
654 static void ath10k_snoc_rx_pipe_cleanup(struct ath10k_snoc_pipe *snoc_pipe)
655 {
656 	struct ath10k_ce_pipe *ce_pipe;
657 	struct ath10k_ce_ring *ce_ring;
658 	struct sk_buff *skb;
659 	struct ath10k *ar;
660 	int i;
661 
662 	ar = snoc_pipe->hif_ce_state;
663 	ce_pipe = snoc_pipe->ce_hdl;
664 	ce_ring = ce_pipe->dest_ring;
665 
666 	if (!ce_ring)
667 		return;
668 
669 	if (!snoc_pipe->buf_sz)
670 		return;
671 
672 	for (i = 0; i < ce_ring->nentries; i++) {
673 		skb = ce_ring->per_transfer_context[i];
674 		if (!skb)
675 			continue;
676 
677 		ce_ring->per_transfer_context[i] = NULL;
678 
679 		dma_unmap_single(ar->dev, ATH10K_SKB_RXCB(skb)->paddr,
680 				 skb->len + skb_tailroom(skb),
681 				 DMA_FROM_DEVICE);
682 		dev_kfree_skb_any(skb);
683 	}
684 }
685 
686 static void ath10k_snoc_tx_pipe_cleanup(struct ath10k_snoc_pipe *snoc_pipe)
687 {
688 	struct ath10k_ce_pipe *ce_pipe;
689 	struct ath10k_ce_ring *ce_ring;
690 	struct ath10k_snoc *ar_snoc;
691 	struct sk_buff *skb;
692 	struct ath10k *ar;
693 	int i;
694 
695 	ar = snoc_pipe->hif_ce_state;
696 	ar_snoc = ath10k_snoc_priv(ar);
697 	ce_pipe = snoc_pipe->ce_hdl;
698 	ce_ring = ce_pipe->src_ring;
699 
700 	if (!ce_ring)
701 		return;
702 
703 	if (!snoc_pipe->buf_sz)
704 		return;
705 
706 	for (i = 0; i < ce_ring->nentries; i++) {
707 		skb = ce_ring->per_transfer_context[i];
708 		if (!skb)
709 			continue;
710 
711 		ce_ring->per_transfer_context[i] = NULL;
712 
713 		ath10k_htc_tx_completion_handler(ar, skb);
714 	}
715 }
716 
717 static void ath10k_snoc_buffer_cleanup(struct ath10k *ar)
718 {
719 	struct ath10k_snoc *ar_snoc = ath10k_snoc_priv(ar);
720 	struct ath10k_snoc_pipe *pipe_info;
721 	int pipe_num;
722 
723 	del_timer_sync(&ar_snoc->rx_post_retry);
724 	for (pipe_num = 0; pipe_num < CE_COUNT; pipe_num++) {
725 		pipe_info = &ar_snoc->pipe_info[pipe_num];
726 		ath10k_snoc_rx_pipe_cleanup(pipe_info);
727 		ath10k_snoc_tx_pipe_cleanup(pipe_info);
728 	}
729 }
730 
731 static void ath10k_snoc_hif_stop(struct ath10k *ar)
732 {
733 	ath10k_snoc_irq_disable(ar);
734 	napi_synchronize(&ar->napi);
735 	napi_disable(&ar->napi);
736 	ath10k_snoc_buffer_cleanup(ar);
737 	ath10k_dbg(ar, ATH10K_DBG_BOOT, "boot hif stop\n");
738 }
739 
740 static int ath10k_snoc_hif_start(struct ath10k *ar)
741 {
742 	napi_enable(&ar->napi);
743 	ath10k_snoc_irq_enable(ar);
744 	ath10k_snoc_rx_post(ar);
745 
746 	ath10k_dbg(ar, ATH10K_DBG_BOOT, "boot hif start\n");
747 
748 	return 0;
749 }
750 
751 static int ath10k_snoc_init_pipes(struct ath10k *ar)
752 {
753 	int i, ret;
754 
755 	for (i = 0; i < CE_COUNT; i++) {
756 		ret = ath10k_ce_init_pipe(ar, i, &host_ce_config_wlan[i]);
757 		if (ret) {
758 			ath10k_err(ar, "failed to initialize copy engine pipe %d: %d\n",
759 				   i, ret);
760 			return ret;
761 		}
762 	}
763 
764 	return 0;
765 }
766 
767 static int ath10k_snoc_wlan_enable(struct ath10k *ar)
768 {
769 	return 0;
770 }
771 
772 static void ath10k_snoc_wlan_disable(struct ath10k *ar)
773 {
774 }
775 
776 static void ath10k_snoc_hif_power_down(struct ath10k *ar)
777 {
778 	ath10k_dbg(ar, ATH10K_DBG_BOOT, "boot hif power down\n");
779 
780 	ath10k_snoc_wlan_disable(ar);
781 	ath10k_ce_free_rri(ar);
782 }
783 
784 static int ath10k_snoc_hif_power_up(struct ath10k *ar)
785 {
786 	int ret;
787 
788 	ath10k_dbg(ar, ATH10K_DBG_SNOC, "%s:WCN3990 driver state = %d\n",
789 		   __func__, ar->state);
790 
791 	ret = ath10k_snoc_wlan_enable(ar);
792 	if (ret) {
793 		ath10k_err(ar, "failed to enable wcn3990: %d\n", ret);
794 		return ret;
795 	}
796 
797 	ath10k_ce_alloc_rri(ar);
798 
799 	ret = ath10k_snoc_init_pipes(ar);
800 	if (ret) {
801 		ath10k_err(ar, "failed to initialize CE: %d\n", ret);
802 		goto err_wlan_enable;
803 	}
804 
805 	return 0;
806 
807 err_wlan_enable:
808 	ath10k_snoc_wlan_disable(ar);
809 
810 	return ret;
811 }
812 
813 static const struct ath10k_hif_ops ath10k_snoc_hif_ops = {
814 	.read32		= ath10k_snoc_read32,
815 	.write32	= ath10k_snoc_write32,
816 	.start		= ath10k_snoc_hif_start,
817 	.stop		= ath10k_snoc_hif_stop,
818 	.map_service_to_pipe	= ath10k_snoc_hif_map_service_to_pipe,
819 	.get_default_pipe	= ath10k_snoc_hif_get_default_pipe,
820 	.power_up		= ath10k_snoc_hif_power_up,
821 	.power_down		= ath10k_snoc_hif_power_down,
822 	.tx_sg			= ath10k_snoc_hif_tx_sg,
823 	.send_complete_check	= ath10k_snoc_hif_send_complete_check,
824 	.get_free_queue_number	= ath10k_snoc_hif_get_free_queue_number,
825 	.get_target_info	= ath10k_snoc_hif_get_target_info,
826 };
827 
828 static const struct ath10k_bus_ops ath10k_snoc_bus_ops = {
829 	.read32		= ath10k_snoc_read32,
830 	.write32	= ath10k_snoc_write32,
831 };
832 
833 static int ath10k_snoc_get_ce_id_from_irq(struct ath10k *ar, int irq)
834 {
835 	struct ath10k_snoc *ar_snoc = ath10k_snoc_priv(ar);
836 	int i;
837 
838 	for (i = 0; i < CE_COUNT_MAX; i++) {
839 		if (ar_snoc->ce_irqs[i].irq_line == irq)
840 			return i;
841 	}
842 	ath10k_err(ar, "No matching CE id for irq %d\n", irq);
843 
844 	return -EINVAL;
845 }
846 
847 static irqreturn_t ath10k_snoc_per_engine_handler(int irq, void *arg)
848 {
849 	struct ath10k *ar = arg;
850 	struct ath10k_snoc *ar_snoc = ath10k_snoc_priv(ar);
851 	int ce_id = ath10k_snoc_get_ce_id_from_irq(ar, irq);
852 
853 	if (ce_id < 0 || ce_id >= ARRAY_SIZE(ar_snoc->pipe_info)) {
854 		ath10k_warn(ar, "unexpected/invalid irq %d ce_id %d\n", irq,
855 			    ce_id);
856 		return IRQ_HANDLED;
857 	}
858 
859 	ath10k_snoc_irq_disable(ar);
860 	napi_schedule(&ar->napi);
861 
862 	return IRQ_HANDLED;
863 }
864 
865 static int ath10k_snoc_napi_poll(struct napi_struct *ctx, int budget)
866 {
867 	struct ath10k *ar = container_of(ctx, struct ath10k, napi);
868 	int done = 0;
869 
870 	ath10k_ce_per_engine_service_any(ar);
871 	done = ath10k_htt_txrx_compl_task(ar, budget);
872 
873 	if (done < budget) {
874 		napi_complete(ctx);
875 		ath10k_snoc_irq_enable(ar);
876 	}
877 
878 	return done;
879 }
880 
881 static void ath10k_snoc_init_napi(struct ath10k *ar)
882 {
883 	netif_napi_add(&ar->napi_dev, &ar->napi, ath10k_snoc_napi_poll,
884 		       ATH10K_NAPI_BUDGET);
885 }
886 
887 static int ath10k_snoc_request_irq(struct ath10k *ar)
888 {
889 	struct ath10k_snoc *ar_snoc = ath10k_snoc_priv(ar);
890 	int irqflags = IRQF_TRIGGER_RISING;
891 	int ret, id;
892 
893 	for (id = 0; id < CE_COUNT_MAX; id++) {
894 		ret = request_irq(ar_snoc->ce_irqs[id].irq_line,
895 				  ath10k_snoc_per_engine_handler,
896 				  irqflags, ce_name[id], ar);
897 		if (ret) {
898 			ath10k_err(ar,
899 				   "failed to register IRQ handler for CE %d: %d",
900 				   id, ret);
901 			goto err_irq;
902 		}
903 	}
904 
905 	return 0;
906 
907 err_irq:
908 	for (id -= 1; id >= 0; id--)
909 		free_irq(ar_snoc->ce_irqs[id].irq_line, ar);
910 
911 	return ret;
912 }
913 
914 static void ath10k_snoc_free_irq(struct ath10k *ar)
915 {
916 	struct ath10k_snoc *ar_snoc = ath10k_snoc_priv(ar);
917 	int id;
918 
919 	for (id = 0; id < CE_COUNT_MAX; id++)
920 		free_irq(ar_snoc->ce_irqs[id].irq_line, ar);
921 }
922 
923 static int ath10k_snoc_resource_init(struct ath10k *ar)
924 {
925 	struct ath10k_snoc *ar_snoc = ath10k_snoc_priv(ar);
926 	struct platform_device *pdev;
927 	struct resource *res;
928 	int i, ret = 0;
929 
930 	pdev = ar_snoc->dev;
931 	res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "membase");
932 	if (!res) {
933 		ath10k_err(ar, "Memory base not found in DT\n");
934 		return -EINVAL;
935 	}
936 
937 	ar_snoc->mem_pa = res->start;
938 	ar_snoc->mem = devm_ioremap(&pdev->dev, ar_snoc->mem_pa,
939 				    resource_size(res));
940 	if (!ar_snoc->mem) {
941 		ath10k_err(ar, "Memory base ioremap failed with physical address %pa\n",
942 			   &ar_snoc->mem_pa);
943 		return -EINVAL;
944 	}
945 
946 	for (i = 0; i < CE_COUNT; i++) {
947 		res = platform_get_resource(ar_snoc->dev, IORESOURCE_IRQ, i);
948 		if (!res) {
949 			ath10k_err(ar, "failed to get IRQ%d\n", i);
950 			ret = -ENODEV;
951 			goto out;
952 		}
953 		ar_snoc->ce_irqs[i].irq_line = res->start;
954 	}
955 
956 out:
957 	return ret;
958 }
959 
960 static int ath10k_snoc_setup_resource(struct ath10k *ar)
961 {
962 	struct ath10k_snoc *ar_snoc = ath10k_snoc_priv(ar);
963 	struct ath10k_ce *ce = ath10k_ce_priv(ar);
964 	struct ath10k_snoc_pipe *pipe;
965 	int i, ret;
966 
967 	timer_setup(&ar_snoc->rx_post_retry, ath10k_snoc_rx_replenish_retry, 0);
968 	spin_lock_init(&ce->ce_lock);
969 	for (i = 0; i < CE_COUNT; i++) {
970 		pipe = &ar_snoc->pipe_info[i];
971 		pipe->ce_hdl = &ce->ce_states[i];
972 		pipe->pipe_num = i;
973 		pipe->hif_ce_state = ar;
974 
975 		ret = ath10k_ce_alloc_pipe(ar, i, &host_ce_config_wlan[i]);
976 		if (ret) {
977 			ath10k_err(ar, "failed to allocate copy engine pipe %d: %d\n",
978 				   i, ret);
979 			return ret;
980 		}
981 
982 		pipe->buf_sz = host_ce_config_wlan[i].src_sz_max;
983 	}
984 	ath10k_snoc_init_napi(ar);
985 
986 	return 0;
987 }
988 
989 static void ath10k_snoc_release_resource(struct ath10k *ar)
990 {
991 	int i;
992 
993 	netif_napi_del(&ar->napi);
994 	for (i = 0; i < CE_COUNT; i++)
995 		ath10k_ce_free_pipe(ar, i);
996 }
997 
998 static int ath10k_get_vreg_info(struct ath10k *ar, struct device *dev,
999 				struct ath10k_wcn3990_vreg_info *vreg_info)
1000 {
1001 	struct regulator *reg;
1002 	int ret = 0;
1003 
1004 	reg = devm_regulator_get_optional(dev, vreg_info->name);
1005 
1006 	if (IS_ERR(reg)) {
1007 		ret = PTR_ERR(reg);
1008 
1009 		if (ret  == -EPROBE_DEFER) {
1010 			ath10k_err(ar, "EPROBE_DEFER for regulator: %s\n",
1011 				   vreg_info->name);
1012 			return ret;
1013 		}
1014 		if (vreg_info->required) {
1015 			ath10k_err(ar, "Regulator %s doesn't exist: %d\n",
1016 				   vreg_info->name, ret);
1017 			return ret;
1018 		}
1019 		ath10k_dbg(ar, ATH10K_DBG_SNOC,
1020 			   "Optional regulator %s doesn't exist: %d\n",
1021 			   vreg_info->name, ret);
1022 		goto done;
1023 	}
1024 
1025 	vreg_info->reg = reg;
1026 
1027 done:
1028 	ath10k_dbg(ar, ATH10K_DBG_SNOC,
1029 		   "snog vreg %s min_v %u max_v %u load_ua %u settle_delay %lu\n",
1030 		   vreg_info->name, vreg_info->min_v, vreg_info->max_v,
1031 		   vreg_info->load_ua, vreg_info->settle_delay);
1032 
1033 	return 0;
1034 }
1035 
1036 static int ath10k_get_clk_info(struct ath10k *ar, struct device *dev,
1037 			       struct ath10k_wcn3990_clk_info *clk_info)
1038 {
1039 	struct clk *handle;
1040 	int ret = 0;
1041 
1042 	handle = devm_clk_get(dev, clk_info->name);
1043 	if (IS_ERR(handle)) {
1044 		ret = PTR_ERR(handle);
1045 		if (clk_info->required) {
1046 			ath10k_err(ar, "snoc clock %s isn't available: %d\n",
1047 				   clk_info->name, ret);
1048 			return ret;
1049 		}
1050 		ath10k_dbg(ar, ATH10K_DBG_SNOC, "snoc ignoring clock %s: %d\n",
1051 			   clk_info->name,
1052 			   ret);
1053 		return 0;
1054 	}
1055 
1056 	ath10k_dbg(ar, ATH10K_DBG_SNOC, "snoc clock %s freq %u\n",
1057 		   clk_info->name, clk_info->freq);
1058 
1059 	clk_info->handle = handle;
1060 
1061 	return ret;
1062 }
1063 
1064 static int ath10k_wcn3990_vreg_on(struct ath10k *ar)
1065 {
1066 	struct ath10k_snoc *ar_snoc = ath10k_snoc_priv(ar);
1067 	struct ath10k_wcn3990_vreg_info *vreg_info;
1068 	int ret = 0;
1069 	int i;
1070 
1071 	for (i = 0; i < ARRAY_SIZE(vreg_cfg); i++) {
1072 		vreg_info = &ar_snoc->vreg[i];
1073 
1074 		if (!vreg_info->reg)
1075 			continue;
1076 
1077 		ath10k_dbg(ar, ATH10K_DBG_SNOC, "snoc regulator %s being enabled\n",
1078 			   vreg_info->name);
1079 
1080 		ret = regulator_set_voltage(vreg_info->reg, vreg_info->min_v,
1081 					    vreg_info->max_v);
1082 		if (ret) {
1083 			ath10k_err(ar,
1084 				   "failed to set regulator %s voltage-min: %d voltage-max: %d\n",
1085 				   vreg_info->name, vreg_info->min_v, vreg_info->max_v);
1086 			goto err_reg_config;
1087 		}
1088 
1089 		if (vreg_info->load_ua) {
1090 			ret = regulator_set_load(vreg_info->reg,
1091 						 vreg_info->load_ua);
1092 			if (ret < 0) {
1093 				ath10k_err(ar,
1094 					   "failed to set regulator %s load: %d\n",
1095 					   vreg_info->name,
1096 					   vreg_info->load_ua);
1097 				goto err_reg_config;
1098 			}
1099 		}
1100 
1101 		ret = regulator_enable(vreg_info->reg);
1102 		if (ret) {
1103 			ath10k_err(ar, "failed to enable regulator %s\n",
1104 				   vreg_info->name);
1105 			goto err_reg_config;
1106 		}
1107 
1108 		if (vreg_info->settle_delay)
1109 			udelay(vreg_info->settle_delay);
1110 	}
1111 
1112 	return 0;
1113 
1114 err_reg_config:
1115 	for (; i >= 0; i--) {
1116 		vreg_info = &ar_snoc->vreg[i];
1117 
1118 		if (!vreg_info->reg)
1119 			continue;
1120 
1121 		regulator_disable(vreg_info->reg);
1122 		regulator_set_load(vreg_info->reg, 0);
1123 		regulator_set_voltage(vreg_info->reg, 0, vreg_info->max_v);
1124 	}
1125 
1126 	return ret;
1127 }
1128 
1129 static int ath10k_wcn3990_vreg_off(struct ath10k *ar)
1130 {
1131 	struct ath10k_snoc *ar_snoc = ath10k_snoc_priv(ar);
1132 	struct ath10k_wcn3990_vreg_info *vreg_info;
1133 	int ret = 0;
1134 	int i;
1135 
1136 	for (i = ARRAY_SIZE(vreg_cfg) - 1; i >= 0; i--) {
1137 		vreg_info = &ar_snoc->vreg[i];
1138 
1139 		if (!vreg_info->reg)
1140 			continue;
1141 
1142 		ath10k_dbg(ar, ATH10K_DBG_SNOC, "snoc regulator %s being disabled\n",
1143 			   vreg_info->name);
1144 
1145 		ret = regulator_disable(vreg_info->reg);
1146 		if (ret)
1147 			ath10k_err(ar, "failed to disable regulator %s\n",
1148 				   vreg_info->name);
1149 
1150 		ret = regulator_set_load(vreg_info->reg, 0);
1151 		if (ret < 0)
1152 			ath10k_err(ar, "failed to set load %s\n",
1153 				   vreg_info->name);
1154 
1155 		ret = regulator_set_voltage(vreg_info->reg, 0,
1156 					    vreg_info->max_v);
1157 		if (ret)
1158 			ath10k_err(ar, "failed to set voltage %s\n",
1159 				   vreg_info->name);
1160 	}
1161 
1162 	return ret;
1163 }
1164 
1165 static int ath10k_wcn3990_clk_init(struct ath10k *ar)
1166 {
1167 	struct ath10k_snoc *ar_snoc = ath10k_snoc_priv(ar);
1168 	struct ath10k_wcn3990_clk_info *clk_info;
1169 	int ret = 0;
1170 	int i;
1171 
1172 	for (i = 0; i < ARRAY_SIZE(clk_cfg); i++) {
1173 		clk_info = &ar_snoc->clk[i];
1174 
1175 		if (!clk_info->handle)
1176 			continue;
1177 
1178 		ath10k_dbg(ar, ATH10K_DBG_SNOC, "snoc clock %s being enabled\n",
1179 			   clk_info->name);
1180 
1181 		if (clk_info->freq) {
1182 			ret = clk_set_rate(clk_info->handle, clk_info->freq);
1183 
1184 			if (ret) {
1185 				ath10k_err(ar, "failed to set clock %s freq %u\n",
1186 					   clk_info->name, clk_info->freq);
1187 				goto err_clock_config;
1188 			}
1189 		}
1190 
1191 		ret = clk_prepare_enable(clk_info->handle);
1192 		if (ret) {
1193 			ath10k_err(ar, "failed to enable clock %s\n",
1194 				   clk_info->name);
1195 			goto err_clock_config;
1196 		}
1197 	}
1198 
1199 	return 0;
1200 
1201 err_clock_config:
1202 	for (; i >= 0; i--) {
1203 		clk_info = &ar_snoc->clk[i];
1204 
1205 		if (!clk_info->handle)
1206 			continue;
1207 
1208 		clk_disable_unprepare(clk_info->handle);
1209 	}
1210 
1211 	return ret;
1212 }
1213 
1214 static int ath10k_wcn3990_clk_deinit(struct ath10k *ar)
1215 {
1216 	struct ath10k_snoc *ar_snoc = ath10k_snoc_priv(ar);
1217 	struct ath10k_wcn3990_clk_info *clk_info;
1218 	int i;
1219 
1220 	for (i = 0; i < ARRAY_SIZE(clk_cfg); i++) {
1221 		clk_info = &ar_snoc->clk[i];
1222 
1223 		if (!clk_info->handle)
1224 			continue;
1225 
1226 		ath10k_dbg(ar, ATH10K_DBG_SNOC, "snoc clock %s being disabled\n",
1227 			   clk_info->name);
1228 
1229 		clk_disable_unprepare(clk_info->handle);
1230 	}
1231 
1232 	return 0;
1233 }
1234 
1235 static int ath10k_hw_power_on(struct ath10k *ar)
1236 {
1237 	int ret;
1238 
1239 	ath10k_dbg(ar, ATH10K_DBG_SNOC, "soc power on\n");
1240 
1241 	ret = ath10k_wcn3990_vreg_on(ar);
1242 	if (ret)
1243 		return ret;
1244 
1245 	ret = ath10k_wcn3990_clk_init(ar);
1246 	if (ret)
1247 		goto vreg_off;
1248 
1249 	return ret;
1250 
1251 vreg_off:
1252 	ath10k_wcn3990_vreg_off(ar);
1253 	return ret;
1254 }
1255 
1256 static int ath10k_hw_power_off(struct ath10k *ar)
1257 {
1258 	int ret;
1259 
1260 	ath10k_dbg(ar, ATH10K_DBG_SNOC, "soc power off\n");
1261 
1262 	ath10k_wcn3990_clk_deinit(ar);
1263 
1264 	ret = ath10k_wcn3990_vreg_off(ar);
1265 
1266 	return ret;
1267 }
1268 
1269 static const struct of_device_id ath10k_snoc_dt_match[] = {
1270 	{ .compatible = "qcom,wcn3990-wifi",
1271 	 .data = &drv_priv,
1272 	},
1273 	{ }
1274 };
1275 MODULE_DEVICE_TABLE(of, ath10k_snoc_dt_match);
1276 
1277 static int ath10k_snoc_probe(struct platform_device *pdev)
1278 {
1279 	const struct ath10k_snoc_drv_priv *drv_data;
1280 	const struct of_device_id *of_id;
1281 	struct ath10k_snoc *ar_snoc;
1282 	struct device *dev;
1283 	struct ath10k *ar;
1284 	int ret;
1285 	u32 i;
1286 	struct ath10k_bus_params bus_params;
1287 
1288 	of_id = of_match_device(ath10k_snoc_dt_match, &pdev->dev);
1289 	if (!of_id) {
1290 		dev_err(&pdev->dev, "failed to find matching device tree id\n");
1291 		return -EINVAL;
1292 	}
1293 
1294 	drv_data = of_id->data;
1295 	dev = &pdev->dev;
1296 
1297 	ret = dma_set_mask_and_coherent(dev, drv_data->dma_mask);
1298 	if (ret) {
1299 		dev_err(dev, "failed to set dma mask: %d", ret);
1300 		return ret;
1301 	}
1302 
1303 	ar = ath10k_core_create(sizeof(*ar_snoc), dev, ATH10K_BUS_SNOC,
1304 				drv_data->hw_rev, &ath10k_snoc_hif_ops);
1305 	if (!ar) {
1306 		dev_err(dev, "failed to allocate core\n");
1307 		return -ENOMEM;
1308 	}
1309 
1310 	ar_snoc = ath10k_snoc_priv(ar);
1311 	ar_snoc->dev = pdev;
1312 	platform_set_drvdata(pdev, ar);
1313 	ar_snoc->ar = ar;
1314 	ar_snoc->ce.bus_ops = &ath10k_snoc_bus_ops;
1315 	ar->ce_priv = &ar_snoc->ce;
1316 
1317 	ret = ath10k_snoc_resource_init(ar);
1318 	if (ret) {
1319 		ath10k_warn(ar, "failed to initialize resource: %d\n", ret);
1320 		goto err_core_destroy;
1321 	}
1322 
1323 	ret = ath10k_snoc_setup_resource(ar);
1324 	if (ret) {
1325 		ath10k_warn(ar, "failed to setup resource: %d\n", ret);
1326 		goto err_core_destroy;
1327 	}
1328 	ret = ath10k_snoc_request_irq(ar);
1329 	if (ret) {
1330 		ath10k_warn(ar, "failed to request irqs: %d\n", ret);
1331 		goto err_release_resource;
1332 	}
1333 
1334 	ar_snoc->vreg = vreg_cfg;
1335 	for (i = 0; i < ARRAY_SIZE(vreg_cfg); i++) {
1336 		ret = ath10k_get_vreg_info(ar, dev, &ar_snoc->vreg[i]);
1337 		if (ret)
1338 			goto err_free_irq;
1339 	}
1340 
1341 	ar_snoc->clk = clk_cfg;
1342 	for (i = 0; i < ARRAY_SIZE(clk_cfg); i++) {
1343 		ret = ath10k_get_clk_info(ar, dev, &ar_snoc->clk[i]);
1344 		if (ret)
1345 			goto err_free_irq;
1346 	}
1347 
1348 	ret = ath10k_hw_power_on(ar);
1349 	if (ret) {
1350 		ath10k_err(ar, "failed to power on device: %d\n", ret);
1351 		goto err_free_irq;
1352 	}
1353 
1354 	bus_params.dev_type = ATH10K_DEV_TYPE_LL;
1355 	bus_params.chip_id = drv_data->hw_rev;
1356 	ret = ath10k_core_register(ar, &bus_params);
1357 	if (ret) {
1358 		ath10k_err(ar, "failed to register driver core: %d\n", ret);
1359 		goto err_hw_power_off;
1360 	}
1361 
1362 	ath10k_dbg(ar, ATH10K_DBG_SNOC, "snoc probe\n");
1363 	ath10k_warn(ar, "Warning: SNOC support is still work-in-progress, it will not work properly!");
1364 
1365 	return 0;
1366 
1367 err_hw_power_off:
1368 	ath10k_hw_power_off(ar);
1369 
1370 err_free_irq:
1371 	ath10k_snoc_free_irq(ar);
1372 
1373 err_release_resource:
1374 	ath10k_snoc_release_resource(ar);
1375 
1376 err_core_destroy:
1377 	ath10k_core_destroy(ar);
1378 
1379 	return ret;
1380 }
1381 
1382 static int ath10k_snoc_remove(struct platform_device *pdev)
1383 {
1384 	struct ath10k *ar = platform_get_drvdata(pdev);
1385 
1386 	ath10k_dbg(ar, ATH10K_DBG_SNOC, "snoc remove\n");
1387 	ath10k_core_unregister(ar);
1388 	ath10k_hw_power_off(ar);
1389 	ath10k_snoc_free_irq(ar);
1390 	ath10k_snoc_release_resource(ar);
1391 	ath10k_core_destroy(ar);
1392 
1393 	return 0;
1394 }
1395 
1396 static struct platform_driver ath10k_snoc_driver = {
1397 		.probe  = ath10k_snoc_probe,
1398 		.remove = ath10k_snoc_remove,
1399 		.driver = {
1400 			.name   = "ath10k_snoc",
1401 			.of_match_table = ath10k_snoc_dt_match,
1402 		},
1403 };
1404 module_platform_driver(ath10k_snoc_driver);
1405 
1406 MODULE_AUTHOR("Qualcomm");
1407 MODULE_LICENSE("Dual BSD/GPL");
1408 MODULE_DESCRIPTION("Driver support for Atheros WCN3990 SNOC devices");
1409