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