forked from ~ljy/RK356X_SDK_RELEASE

hc
2023-12-11 6778948f9de86c3cfaf36725a7c87dcff9ba247f
kernel/drivers/net/wireless/ath/ath10k/snoc.c
....@@ -1,28 +1,22 @@
1
+// SPDX-License-Identifier: ISC
12 /*
23 * 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.
154 */
165
6
+#include <linux/bits.h>
177 #include <linux/clk.h>
188 #include <linux/kernel.h>
199 #include <linux/module.h>
2010 #include <linux/of.h>
2111 #include <linux/of_device.h>
2212 #include <linux/platform_device.h>
13
+#include <linux/property.h>
2314 #include <linux/regulator/consumer.h>
15
+#include <linux/of_address.h>
16
+#include <linux/iommu.h>
2417
2518 #include "ce.h"
19
+#include "coredump.h"
2620 #include "debug.h"
2721 #include "hif.h"
2822 #include "htc.h"
....@@ -30,6 +24,7 @@
3024
3125 #define ATH10K_SNOC_RX_POST_RETRY_MS 50
3226 #define CE_POLL_PIPE 4
27
+#define ATH10K_SNOC_WAKE_IRQ 2
3328
3429 static char *const ce_name[] = {
3530 "WLAN_CE_0",
....@@ -46,15 +41,16 @@
4641 "WLAN_CE_11",
4742 };
4843
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},
44
+static const char * const ath10k_regulators[] = {
45
+ "vdd-0.8-cx-mx",
46
+ "vdd-1.8-xo",
47
+ "vdd-1.3-rfa",
48
+ "vdd-3.3-ch0",
49
+ "vdd-3.3-ch1",
5450 };
5551
56
-static struct ath10k_wcn3990_clk_info clk_cfg[] = {
57
- {NULL, "cxo_ref_clk_pin", 0, false},
52
+static const char * const ath10k_clocks[] = {
53
+ "cxo_ref_clk_pin", "qdss",
5854 };
5955
6056 static void ath10k_snoc_htc_tx_cb(struct ath10k_ce_pipe *ce_state);
....@@ -62,10 +58,77 @@
6258 static void ath10k_snoc_htc_rx_cb(struct ath10k_ce_pipe *ce_state);
6359 static void ath10k_snoc_htt_rx_cb(struct ath10k_ce_pipe *ce_state);
6460 static void ath10k_snoc_htt_htc_rx_cb(struct ath10k_ce_pipe *ce_state);
61
+static void ath10k_snoc_pktlog_rx_cb(struct ath10k_ce_pipe *ce_state);
6562
6663 static const struct ath10k_snoc_drv_priv drv_priv = {
6764 .hw_rev = ATH10K_HW_WCN3990,
68
- .dma_mask = DMA_BIT_MASK(37),
65
+ .dma_mask = DMA_BIT_MASK(35),
66
+ .msa_size = 0x100000,
67
+};
68
+
69
+#define WCN3990_SRC_WR_IDX_OFFSET 0x3C
70
+#define WCN3990_DST_WR_IDX_OFFSET 0x40
71
+
72
+static struct ath10k_shadow_reg_cfg target_shadow_reg_cfg_map[] = {
73
+ {
74
+ .ce_id = __cpu_to_le16(0),
75
+ .reg_offset = __cpu_to_le16(WCN3990_SRC_WR_IDX_OFFSET),
76
+ },
77
+
78
+ {
79
+ .ce_id = __cpu_to_le16(3),
80
+ .reg_offset = __cpu_to_le16(WCN3990_SRC_WR_IDX_OFFSET),
81
+ },
82
+
83
+ {
84
+ .ce_id = __cpu_to_le16(4),
85
+ .reg_offset = __cpu_to_le16(WCN3990_SRC_WR_IDX_OFFSET),
86
+ },
87
+
88
+ {
89
+ .ce_id = __cpu_to_le16(5),
90
+ .reg_offset = __cpu_to_le16(WCN3990_SRC_WR_IDX_OFFSET),
91
+ },
92
+
93
+ {
94
+ .ce_id = __cpu_to_le16(7),
95
+ .reg_offset = __cpu_to_le16(WCN3990_SRC_WR_IDX_OFFSET),
96
+ },
97
+
98
+ {
99
+ .ce_id = __cpu_to_le16(1),
100
+ .reg_offset = __cpu_to_le16(WCN3990_DST_WR_IDX_OFFSET),
101
+ },
102
+
103
+ {
104
+ .ce_id = __cpu_to_le16(2),
105
+ .reg_offset = __cpu_to_le16(WCN3990_DST_WR_IDX_OFFSET),
106
+ },
107
+
108
+ {
109
+ .ce_id = __cpu_to_le16(7),
110
+ .reg_offset = __cpu_to_le16(WCN3990_DST_WR_IDX_OFFSET),
111
+ },
112
+
113
+ {
114
+ .ce_id = __cpu_to_le16(8),
115
+ .reg_offset = __cpu_to_le16(WCN3990_DST_WR_IDX_OFFSET),
116
+ },
117
+
118
+ {
119
+ .ce_id = __cpu_to_le16(9),
120
+ .reg_offset = __cpu_to_le16(WCN3990_DST_WR_IDX_OFFSET),
121
+ },
122
+
123
+ {
124
+ .ce_id = __cpu_to_le16(10),
125
+ .reg_offset = __cpu_to_le16(WCN3990_DST_WR_IDX_OFFSET),
126
+ },
127
+
128
+ {
129
+ .ce_id = __cpu_to_le16(11),
130
+ .reg_offset = __cpu_to_le16(WCN3990_DST_WR_IDX_OFFSET),
131
+ },
69132 };
70133
71134 static struct ce_attr host_ce_config_wlan[] = {
....@@ -108,7 +171,7 @@
108171 /* CE4: host->target HTT */
109172 {
110173 .flags = CE_ATTR_FLAGS | CE_ATTR_DIS_INTR,
111
- .src_nentries = 256,
174
+ .src_nentries = 2048,
112175 .src_sz_max = 256,
113176 .dest_nentries = 0,
114177 .send_cb = ath10k_snoc_htt_tx_cb,
....@@ -171,11 +234,133 @@
171234 .src_nentries = 0,
172235 .src_sz_max = 2048,
173236 .dest_nentries = 512,
174
- .recv_cb = ath10k_snoc_htt_htc_rx_cb,
237
+ .recv_cb = ath10k_snoc_pktlog_rx_cb,
175238 },
176239 };
177240
178
-static struct service_to_pipe target_service_to_ce_map_wlan[] = {
241
+static struct ce_pipe_config target_ce_config_wlan[] = {
242
+ /* CE0: host->target HTC control and raw streams */
243
+ {
244
+ .pipenum = __cpu_to_le32(0),
245
+ .pipedir = __cpu_to_le32(PIPEDIR_OUT),
246
+ .nentries = __cpu_to_le32(32),
247
+ .nbytes_max = __cpu_to_le32(2048),
248
+ .flags = __cpu_to_le32(CE_ATTR_FLAGS),
249
+ .reserved = __cpu_to_le32(0),
250
+ },
251
+
252
+ /* CE1: target->host HTT + HTC control */
253
+ {
254
+ .pipenum = __cpu_to_le32(1),
255
+ .pipedir = __cpu_to_le32(PIPEDIR_IN),
256
+ .nentries = __cpu_to_le32(32),
257
+ .nbytes_max = __cpu_to_le32(2048),
258
+ .flags = __cpu_to_le32(CE_ATTR_FLAGS),
259
+ .reserved = __cpu_to_le32(0),
260
+ },
261
+
262
+ /* CE2: target->host WMI */
263
+ {
264
+ .pipenum = __cpu_to_le32(2),
265
+ .pipedir = __cpu_to_le32(PIPEDIR_IN),
266
+ .nentries = __cpu_to_le32(64),
267
+ .nbytes_max = __cpu_to_le32(2048),
268
+ .flags = __cpu_to_le32(CE_ATTR_FLAGS),
269
+ .reserved = __cpu_to_le32(0),
270
+ },
271
+
272
+ /* CE3: host->target WMI */
273
+ {
274
+ .pipenum = __cpu_to_le32(3),
275
+ .pipedir = __cpu_to_le32(PIPEDIR_OUT),
276
+ .nentries = __cpu_to_le32(32),
277
+ .nbytes_max = __cpu_to_le32(2048),
278
+ .flags = __cpu_to_le32(CE_ATTR_FLAGS),
279
+ .reserved = __cpu_to_le32(0),
280
+ },
281
+
282
+ /* CE4: host->target HTT */
283
+ {
284
+ .pipenum = __cpu_to_le32(4),
285
+ .pipedir = __cpu_to_le32(PIPEDIR_OUT),
286
+ .nentries = __cpu_to_le32(256),
287
+ .nbytes_max = __cpu_to_le32(256),
288
+ .flags = __cpu_to_le32(CE_ATTR_FLAGS | CE_ATTR_DIS_INTR),
289
+ .reserved = __cpu_to_le32(0),
290
+ },
291
+
292
+ /* CE5: target->host HTT (HIF->HTT) */
293
+ {
294
+ .pipenum = __cpu_to_le32(5),
295
+ .pipedir = __cpu_to_le32(PIPEDIR_OUT),
296
+ .nentries = __cpu_to_le32(1024),
297
+ .nbytes_max = __cpu_to_le32(64),
298
+ .flags = __cpu_to_le32(CE_ATTR_FLAGS | CE_ATTR_DIS_INTR),
299
+ .reserved = __cpu_to_le32(0),
300
+ },
301
+
302
+ /* CE6: Reserved for target autonomous hif_memcpy */
303
+ {
304
+ .pipenum = __cpu_to_le32(6),
305
+ .pipedir = __cpu_to_le32(PIPEDIR_INOUT),
306
+ .nentries = __cpu_to_le32(32),
307
+ .nbytes_max = __cpu_to_le32(16384),
308
+ .flags = __cpu_to_le32(CE_ATTR_FLAGS),
309
+ .reserved = __cpu_to_le32(0),
310
+ },
311
+
312
+ /* CE7 used only by Host */
313
+ {
314
+ .pipenum = __cpu_to_le32(7),
315
+ .pipedir = __cpu_to_le32(4),
316
+ .nentries = __cpu_to_le32(0),
317
+ .nbytes_max = __cpu_to_le32(0),
318
+ .flags = __cpu_to_le32(CE_ATTR_FLAGS | CE_ATTR_DIS_INTR),
319
+ .reserved = __cpu_to_le32(0),
320
+ },
321
+
322
+ /* CE8 Target to uMC */
323
+ {
324
+ .pipenum = __cpu_to_le32(8),
325
+ .pipedir = __cpu_to_le32(PIPEDIR_IN),
326
+ .nentries = __cpu_to_le32(32),
327
+ .nbytes_max = __cpu_to_le32(2048),
328
+ .flags = __cpu_to_le32(0),
329
+ .reserved = __cpu_to_le32(0),
330
+ },
331
+
332
+ /* CE9 target->host HTT */
333
+ {
334
+ .pipenum = __cpu_to_le32(9),
335
+ .pipedir = __cpu_to_le32(PIPEDIR_IN),
336
+ .nentries = __cpu_to_le32(32),
337
+ .nbytes_max = __cpu_to_le32(2048),
338
+ .flags = __cpu_to_le32(CE_ATTR_FLAGS),
339
+ .reserved = __cpu_to_le32(0),
340
+ },
341
+
342
+ /* CE10 target->host HTT */
343
+ {
344
+ .pipenum = __cpu_to_le32(10),
345
+ .pipedir = __cpu_to_le32(PIPEDIR_IN),
346
+ .nentries = __cpu_to_le32(32),
347
+ .nbytes_max = __cpu_to_le32(2048),
348
+ .flags = __cpu_to_le32(CE_ATTR_FLAGS),
349
+ .reserved = __cpu_to_le32(0),
350
+ },
351
+
352
+ /* CE11 target autonomous qcache memcpy */
353
+ {
354
+ .pipenum = __cpu_to_le32(11),
355
+ .pipedir = __cpu_to_le32(PIPEDIR_IN),
356
+ .nentries = __cpu_to_le32(32),
357
+ .nbytes_max = __cpu_to_le32(2048),
358
+ .flags = __cpu_to_le32(CE_ATTR_FLAGS),
359
+ .reserved = __cpu_to_le32(0),
360
+ },
361
+};
362
+
363
+static struct ce_service_to_pipe target_service_to_ce_map_wlan[] = {
179364 {
180365 __cpu_to_le32(ATH10K_HTC_SVC_ID_WMI_DATA_VO),
181366 __cpu_to_le32(PIPEDIR_OUT), /* out = UL = host -> target */
....@@ -285,14 +470,14 @@
285470 },
286471 };
287472
288
-void ath10k_snoc_write32(struct ath10k *ar, u32 offset, u32 value)
473
+static void ath10k_snoc_write32(struct ath10k *ar, u32 offset, u32 value)
289474 {
290475 struct ath10k_snoc *ar_snoc = ath10k_snoc_priv(ar);
291476
292477 iowrite32(value, ar_snoc->mem + offset);
293478 }
294479
295
-u32 ath10k_snoc_read32(struct ath10k *ar, u32 offset)
480
+static u32 ath10k_snoc_read32(struct ath10k *ar, u32 offset)
296481 {
297482 struct ath10k_snoc *ar_snoc = ath10k_snoc_priv(ar);
298483 u32 val;
....@@ -401,7 +586,7 @@
401586 max_nbytes, DMA_FROM_DEVICE);
402587
403588 if (unlikely(max_nbytes < nbytes)) {
404
- ath10k_warn(ar, "rxed more than expected (nbytes %d, max %d)",
589
+ ath10k_warn(ar, "rxed more than expected (nbytes %d, max %d)\n",
405590 nbytes, max_nbytes);
406591 dev_kfree_skb_any(skb);
407592 continue;
....@@ -433,6 +618,14 @@
433618 */
434619 ath10k_ce_per_engine_service(ce_state->ar, CE_POLL_PIPE);
435620
621
+ ath10k_snoc_process_rx_cb(ce_state, ath10k_htc_rx_completion_handler);
622
+}
623
+
624
+/* Called by lower (CE) layer when data is received from the Target.
625
+ * WCN3990 firmware uses separate CE(CE11) to transfer pktlog data.
626
+ */
627
+static void ath10k_snoc_pktlog_rx_cb(struct ath10k_ce_pipe *ce_state)
628
+{
436629 ath10k_snoc_process_rx_cb(ce_state, ath10k_htc_rx_completion_handler);
437630 }
438631
....@@ -580,7 +773,7 @@
580773 u16 service_id,
581774 u8 *ul_pipe, u8 *dl_pipe)
582775 {
583
- const struct service_to_pipe *entry;
776
+ const struct ce_service_to_pipe *entry;
584777 bool ul_set = false, dl_set = false;
585778 int i;
586779
....@@ -616,7 +809,7 @@
616809 }
617810 }
618811
619
- if (WARN_ON(!ul_set || !dl_set))
812
+ if (!ul_set || !dl_set)
620813 return -ENOENT;
621814
622815 return 0;
....@@ -678,13 +871,11 @@
678871 {
679872 struct ath10k_ce_pipe *ce_pipe;
680873 struct ath10k_ce_ring *ce_ring;
681
- struct ath10k_snoc *ar_snoc;
682874 struct sk_buff *skb;
683875 struct ath10k *ar;
684876 int i;
685877
686878 ar = snoc_pipe->hif_ce_state;
687
- ar_snoc = ath10k_snoc_priv(ar);
688879 ce_pipe = snoc_pipe->ce_hdl;
689880 ce_ring = ce_pipe->src_ring;
690881
....@@ -721,17 +912,25 @@
721912
722913 static void ath10k_snoc_hif_stop(struct ath10k *ar)
723914 {
724
- ath10k_snoc_irq_disable(ar);
725
- ath10k_snoc_buffer_cleanup(ar);
915
+ if (!test_bit(ATH10K_FLAG_CRASH_FLUSH, &ar->dev_flags))
916
+ ath10k_snoc_irq_disable(ar);
917
+
726918 napi_synchronize(&ar->napi);
727919 napi_disable(&ar->napi);
920
+ ath10k_snoc_buffer_cleanup(ar);
728921 ath10k_dbg(ar, ATH10K_DBG_BOOT, "boot hif stop\n");
729922 }
730923
731924 static int ath10k_snoc_hif_start(struct ath10k *ar)
732925 {
926
+ struct ath10k_snoc *ar_snoc = ath10k_snoc_priv(ar);
927
+
928
+ bitmap_clear(ar_snoc->pending_ce_irqs, 0, CE_COUNT_MAX);
929
+ napi_enable(&ar->napi);
733930 ath10k_snoc_irq_enable(ar);
734931 ath10k_snoc_rx_post(ar);
932
+
933
+ clear_bit(ATH10K_SNOC_FLAG_RECOVERY, &ar_snoc->flags);
735934
736935 ath10k_dbg(ar, ATH10K_DBG_BOOT, "boot hif start\n");
737936
....@@ -754,13 +953,69 @@
754953 return 0;
755954 }
756955
757
-static int ath10k_snoc_wlan_enable(struct ath10k *ar)
956
+static int ath10k_snoc_wlan_enable(struct ath10k *ar,
957
+ enum ath10k_firmware_mode fw_mode)
758958 {
759
- return 0;
959
+ struct ath10k_tgt_pipe_cfg tgt_cfg[CE_COUNT_MAX];
960
+ struct ath10k_qmi_wlan_enable_cfg cfg;
961
+ enum wlfw_driver_mode_enum_v01 mode;
962
+ int pipe_num;
963
+
964
+ for (pipe_num = 0; pipe_num < CE_COUNT_MAX; pipe_num++) {
965
+ tgt_cfg[pipe_num].pipe_num =
966
+ target_ce_config_wlan[pipe_num].pipenum;
967
+ tgt_cfg[pipe_num].pipe_dir =
968
+ target_ce_config_wlan[pipe_num].pipedir;
969
+ tgt_cfg[pipe_num].nentries =
970
+ target_ce_config_wlan[pipe_num].nentries;
971
+ tgt_cfg[pipe_num].nbytes_max =
972
+ target_ce_config_wlan[pipe_num].nbytes_max;
973
+ tgt_cfg[pipe_num].flags =
974
+ target_ce_config_wlan[pipe_num].flags;
975
+ tgt_cfg[pipe_num].reserved = 0;
976
+ }
977
+
978
+ cfg.num_ce_tgt_cfg = sizeof(target_ce_config_wlan) /
979
+ sizeof(struct ath10k_tgt_pipe_cfg);
980
+ cfg.ce_tgt_cfg = (struct ath10k_tgt_pipe_cfg *)
981
+ &tgt_cfg;
982
+ cfg.num_ce_svc_pipe_cfg = sizeof(target_service_to_ce_map_wlan) /
983
+ sizeof(struct ath10k_svc_pipe_cfg);
984
+ cfg.ce_svc_cfg = (struct ath10k_svc_pipe_cfg *)
985
+ &target_service_to_ce_map_wlan;
986
+ cfg.num_shadow_reg_cfg = ARRAY_SIZE(target_shadow_reg_cfg_map);
987
+ cfg.shadow_reg_cfg = (struct ath10k_shadow_reg_cfg *)
988
+ &target_shadow_reg_cfg_map;
989
+
990
+ switch (fw_mode) {
991
+ case ATH10K_FIRMWARE_MODE_NORMAL:
992
+ mode = QMI_WLFW_MISSION_V01;
993
+ break;
994
+ case ATH10K_FIRMWARE_MODE_UTF:
995
+ mode = QMI_WLFW_FTM_V01;
996
+ break;
997
+ default:
998
+ ath10k_err(ar, "invalid firmware mode %d\n", fw_mode);
999
+ return -EINVAL;
1000
+ }
1001
+
1002
+ return ath10k_qmi_wlan_enable(ar, &cfg, mode,
1003
+ NULL);
7601004 }
7611005
7621006 static void ath10k_snoc_wlan_disable(struct ath10k *ar)
7631007 {
1008
+ struct ath10k_snoc *ar_snoc = ath10k_snoc_priv(ar);
1009
+
1010
+ /* If both ATH10K_FLAG_CRASH_FLUSH and ATH10K_SNOC_FLAG_RECOVERY
1011
+ * flags are not set, it means that the driver has restarted
1012
+ * due to a crash inject via debugfs. In this case, the driver
1013
+ * needs to restart the firmware and hence send qmi wlan disable,
1014
+ * during the driver restart sequence.
1015
+ */
1016
+ if (!test_bit(ATH10K_FLAG_CRASH_FLUSH, &ar->dev_flags) ||
1017
+ !test_bit(ATH10K_SNOC_FLAG_RECOVERY, &ar_snoc->flags))
1018
+ ath10k_qmi_wlan_disable(ar);
7641019 }
7651020
7661021 static void ath10k_snoc_hif_power_down(struct ath10k *ar)
....@@ -771,14 +1026,15 @@
7711026 ath10k_ce_free_rri(ar);
7721027 }
7731028
774
-static int ath10k_snoc_hif_power_up(struct ath10k *ar)
1029
+static int ath10k_snoc_hif_power_up(struct ath10k *ar,
1030
+ enum ath10k_firmware_mode fw_mode)
7751031 {
7761032 int ret;
7771033
7781034 ath10k_dbg(ar, ATH10K_DBG_SNOC, "%s:WCN3990 driver state = %d\n",
7791035 __func__, ar->state);
7801036
781
- ret = ath10k_snoc_wlan_enable(ar);
1037
+ ret = ath10k_snoc_wlan_enable(ar, fw_mode);
7821038 if (ret) {
7831039 ath10k_err(ar, "failed to enable wcn3990: %d\n", ret);
7841040 return ret;
....@@ -792,7 +1048,6 @@
7921048 goto err_free_rri;
7931049 }
7941050
795
- napi_enable(&ar->napi);
7961051 return 0;
7971052
7981053 err_free_rri:
....@@ -801,6 +1056,59 @@
8011056
8021057 return ret;
8031058 }
1059
+
1060
+static int ath10k_snoc_hif_set_target_log_mode(struct ath10k *ar,
1061
+ u8 fw_log_mode)
1062
+{
1063
+ u8 fw_dbg_mode;
1064
+
1065
+ if (fw_log_mode)
1066
+ fw_dbg_mode = ATH10K_ENABLE_FW_LOG_CE;
1067
+ else
1068
+ fw_dbg_mode = ATH10K_ENABLE_FW_LOG_DIAG;
1069
+
1070
+ return ath10k_qmi_set_fw_log_mode(ar, fw_dbg_mode);
1071
+}
1072
+
1073
+#ifdef CONFIG_PM
1074
+static int ath10k_snoc_hif_suspend(struct ath10k *ar)
1075
+{
1076
+ struct ath10k_snoc *ar_snoc = ath10k_snoc_priv(ar);
1077
+ int ret;
1078
+
1079
+ if (!device_may_wakeup(ar->dev))
1080
+ return -EPERM;
1081
+
1082
+ ret = enable_irq_wake(ar_snoc->ce_irqs[ATH10K_SNOC_WAKE_IRQ].irq_line);
1083
+ if (ret) {
1084
+ ath10k_err(ar, "failed to enable wakeup irq :%d\n", ret);
1085
+ return ret;
1086
+ }
1087
+
1088
+ ath10k_dbg(ar, ATH10K_DBG_SNOC, "snoc device suspended\n");
1089
+
1090
+ return ret;
1091
+}
1092
+
1093
+static int ath10k_snoc_hif_resume(struct ath10k *ar)
1094
+{
1095
+ struct ath10k_snoc *ar_snoc = ath10k_snoc_priv(ar);
1096
+ int ret;
1097
+
1098
+ if (!device_may_wakeup(ar->dev))
1099
+ return -EPERM;
1100
+
1101
+ ret = disable_irq_wake(ar_snoc->ce_irqs[ATH10K_SNOC_WAKE_IRQ].irq_line);
1102
+ if (ret) {
1103
+ ath10k_err(ar, "failed to disable wakeup irq: %d\n", ret);
1104
+ return ret;
1105
+ }
1106
+
1107
+ ath10k_dbg(ar, ATH10K_DBG_SNOC, "snoc device resumed\n");
1108
+
1109
+ return ret;
1110
+}
1111
+#endif
8041112
8051113 static const struct ath10k_hif_ops ath10k_snoc_hif_ops = {
8061114 .read32 = ath10k_snoc_read32,
....@@ -815,6 +1123,12 @@
8151123 .send_complete_check = ath10k_snoc_hif_send_complete_check,
8161124 .get_free_queue_number = ath10k_snoc_hif_get_free_queue_number,
8171125 .get_target_info = ath10k_snoc_hif_get_target_info,
1126
+ .set_target_log_mode = ath10k_snoc_hif_set_target_log_mode,
1127
+
1128
+#ifdef CONFIG_PM
1129
+ .suspend = ath10k_snoc_hif_suspend,
1130
+ .resume = ath10k_snoc_hif_resume,
1131
+#endif
8181132 };
8191133
8201134 static const struct ath10k_bus_ops ath10k_snoc_bus_ops = {
....@@ -848,7 +1162,9 @@
8481162 return IRQ_HANDLED;
8491163 }
8501164
851
- ath10k_snoc_irq_disable(ar);
1165
+ ath10k_ce_disable_interrupt(ar, ce_id);
1166
+ set_bit(ce_id, ar_snoc->pending_ce_irqs);
1167
+
8521168 napi_schedule(&ar->napi);
8531169
8541170 return IRQ_HANDLED;
....@@ -857,15 +1173,25 @@
8571173 static int ath10k_snoc_napi_poll(struct napi_struct *ctx, int budget)
8581174 {
8591175 struct ath10k *ar = container_of(ctx, struct ath10k, napi);
1176
+ struct ath10k_snoc *ar_snoc = ath10k_snoc_priv(ar);
8601177 int done = 0;
1178
+ int ce_id;
8611179
862
- ath10k_ce_per_engine_service_any(ar);
1180
+ if (test_bit(ATH10K_FLAG_CRASH_FLUSH, &ar->dev_flags)) {
1181
+ napi_complete(ctx);
1182
+ return done;
1183
+ }
1184
+
1185
+ for (ce_id = 0; ce_id < CE_COUNT; ce_id++)
1186
+ if (test_and_clear_bit(ce_id, ar_snoc->pending_ce_irqs)) {
1187
+ ath10k_ce_per_engine_service(ar, ce_id);
1188
+ ath10k_ce_enable_interrupt(ar, ce_id);
1189
+ }
1190
+
8631191 done = ath10k_htt_txrx_compl_task(ar, budget);
8641192
865
- if (done < budget) {
1193
+ if (done < budget)
8661194 napi_complete(ctx);
867
- ath10k_snoc_irq_enable(ar);
868
- }
8691195
8701196 return done;
8711197 }
....@@ -879,16 +1205,15 @@
8791205 static int ath10k_snoc_request_irq(struct ath10k *ar)
8801206 {
8811207 struct ath10k_snoc *ar_snoc = ath10k_snoc_priv(ar);
882
- int irqflags = IRQF_TRIGGER_RISING;
8831208 int ret, id;
8841209
8851210 for (id = 0; id < CE_COUNT_MAX; id++) {
8861211 ret = request_irq(ar_snoc->ce_irqs[id].irq_line,
887
- ath10k_snoc_per_engine_handler,
888
- irqflags, ce_name[id], ar);
1212
+ ath10k_snoc_per_engine_handler, 0,
1213
+ ce_name[id], ar);
8891214 if (ret) {
8901215 ath10k_err(ar,
891
- "failed to register IRQ handler for CE %d: %d",
1216
+ "failed to register IRQ handler for CE %d: %d\n",
8921217 id, ret);
8931218 goto err_irq;
8941219 }
....@@ -945,8 +1270,65 @@
9451270 ar_snoc->ce_irqs[i].irq_line = res->start;
9461271 }
9471272
1273
+ ret = device_property_read_u32(&pdev->dev, "qcom,xo-cal-data",
1274
+ &ar_snoc->xo_cal_data);
1275
+ ath10k_dbg(ar, ATH10K_DBG_SNOC, "snoc xo-cal-data return %d\n", ret);
1276
+ if (ret == 0) {
1277
+ ar_snoc->xo_cal_supported = true;
1278
+ ath10k_dbg(ar, ATH10K_DBG_SNOC, "xo cal data %x\n",
1279
+ ar_snoc->xo_cal_data);
1280
+ }
1281
+ ret = 0;
1282
+
9481283 out:
9491284 return ret;
1285
+}
1286
+
1287
+static void ath10k_snoc_quirks_init(struct ath10k *ar)
1288
+{
1289
+ struct ath10k_snoc *ar_snoc = ath10k_snoc_priv(ar);
1290
+ struct device *dev = &ar_snoc->dev->dev;
1291
+
1292
+ if (of_property_read_bool(dev->of_node, "qcom,snoc-host-cap-8bit-quirk"))
1293
+ set_bit(ATH10K_SNOC_FLAG_8BIT_HOST_CAP_QUIRK, &ar_snoc->flags);
1294
+}
1295
+
1296
+int ath10k_snoc_fw_indication(struct ath10k *ar, u64 type)
1297
+{
1298
+ struct ath10k_snoc *ar_snoc = ath10k_snoc_priv(ar);
1299
+ struct ath10k_bus_params bus_params = {};
1300
+ int ret;
1301
+
1302
+ if (test_bit(ATH10K_SNOC_FLAG_UNREGISTERING, &ar_snoc->flags))
1303
+ return 0;
1304
+
1305
+ switch (type) {
1306
+ case ATH10K_QMI_EVENT_FW_READY_IND:
1307
+ if (test_bit(ATH10K_SNOC_FLAG_REGISTERED, &ar_snoc->flags)) {
1308
+ queue_work(ar->workqueue, &ar->restart_work);
1309
+ break;
1310
+ }
1311
+
1312
+ bus_params.dev_type = ATH10K_DEV_TYPE_LL;
1313
+ bus_params.chip_id = ar_snoc->target_info.soc_version;
1314
+ ret = ath10k_core_register(ar, &bus_params);
1315
+ if (ret) {
1316
+ ath10k_err(ar, "Failed to register driver core: %d\n",
1317
+ ret);
1318
+ return ret;
1319
+ }
1320
+ set_bit(ATH10K_SNOC_FLAG_REGISTERED, &ar_snoc->flags);
1321
+ break;
1322
+ case ATH10K_QMI_EVENT_FW_DOWN_IND:
1323
+ set_bit(ATH10K_SNOC_FLAG_RECOVERY, &ar_snoc->flags);
1324
+ set_bit(ATH10K_FLAG_CRASH_FLUSH, &ar->dev_flags);
1325
+ break;
1326
+ default:
1327
+ ath10k_err(ar, "invalid fw indication: %llx\n", type);
1328
+ return -EINVAL;
1329
+ }
1330
+
1331
+ return 0;
9501332 }
9511333
9521334 static int ath10k_snoc_setup_resource(struct ath10k *ar)
....@@ -987,275 +1369,250 @@
9871369 ath10k_ce_free_pipe(ar, i);
9881370 }
9891371
990
-static int ath10k_get_vreg_info(struct ath10k *ar, struct device *dev,
991
- struct ath10k_wcn3990_vreg_info *vreg_info)
992
-{
993
- struct regulator *reg;
994
- int ret = 0;
995
-
996
- reg = devm_regulator_get_optional(dev, vreg_info->name);
997
-
998
- if (IS_ERR(reg)) {
999
- ret = PTR_ERR(reg);
1000
-
1001
- if (ret == -EPROBE_DEFER) {
1002
- ath10k_err(ar, "EPROBE_DEFER for regulator: %s\n",
1003
- vreg_info->name);
1004
- return ret;
1005
- }
1006
- if (vreg_info->required) {
1007
- ath10k_err(ar, "Regulator %s doesn't exist: %d\n",
1008
- vreg_info->name, ret);
1009
- return ret;
1010
- }
1011
- ath10k_dbg(ar, ATH10K_DBG_SNOC,
1012
- "Optional regulator %s doesn't exist: %d\n",
1013
- vreg_info->name, ret);
1014
- goto done;
1015
- }
1016
-
1017
- vreg_info->reg = reg;
1018
-
1019
-done:
1020
- ath10k_dbg(ar, ATH10K_DBG_SNOC,
1021
- "snog vreg %s min_v %u max_v %u load_ua %u settle_delay %lu\n",
1022
- vreg_info->name, vreg_info->min_v, vreg_info->max_v,
1023
- vreg_info->load_ua, vreg_info->settle_delay);
1024
-
1025
- return 0;
1026
-}
1027
-
1028
-static int ath10k_get_clk_info(struct ath10k *ar, struct device *dev,
1029
- struct ath10k_wcn3990_clk_info *clk_info)
1030
-{
1031
- struct clk *handle;
1032
- int ret = 0;
1033
-
1034
- handle = devm_clk_get(dev, clk_info->name);
1035
- if (IS_ERR(handle)) {
1036
- ret = PTR_ERR(handle);
1037
- if (clk_info->required) {
1038
- ath10k_err(ar, "snoc clock %s isn't available: %d\n",
1039
- clk_info->name, ret);
1040
- return ret;
1041
- }
1042
- ath10k_dbg(ar, ATH10K_DBG_SNOC, "snoc ignoring clock %s: %d\n",
1043
- clk_info->name,
1044
- ret);
1045
- return 0;
1046
- }
1047
-
1048
- ath10k_dbg(ar, ATH10K_DBG_SNOC, "snoc clock %s freq %u\n",
1049
- clk_info->name, clk_info->freq);
1050
-
1051
- clk_info->handle = handle;
1052
-
1053
- return ret;
1054
-}
1055
-
1056
-static int ath10k_wcn3990_vreg_on(struct ath10k *ar)
1057
-{
1058
- struct ath10k_snoc *ar_snoc = ath10k_snoc_priv(ar);
1059
- struct ath10k_wcn3990_vreg_info *vreg_info;
1060
- int ret = 0;
1061
- int i;
1062
-
1063
- for (i = 0; i < ARRAY_SIZE(vreg_cfg); i++) {
1064
- vreg_info = &ar_snoc->vreg[i];
1065
-
1066
- if (!vreg_info->reg)
1067
- continue;
1068
-
1069
- ath10k_dbg(ar, ATH10K_DBG_SNOC, "snoc regulator %s being enabled\n",
1070
- vreg_info->name);
1071
-
1072
- ret = regulator_set_voltage(vreg_info->reg, vreg_info->min_v,
1073
- vreg_info->max_v);
1074
- if (ret) {
1075
- ath10k_err(ar,
1076
- "failed to set regulator %s voltage-min: %d voltage-max: %d\n",
1077
- vreg_info->name, vreg_info->min_v, vreg_info->max_v);
1078
- goto err_reg_config;
1079
- }
1080
-
1081
- if (vreg_info->load_ua) {
1082
- ret = regulator_set_load(vreg_info->reg,
1083
- vreg_info->load_ua);
1084
- if (ret < 0) {
1085
- ath10k_err(ar,
1086
- "failed to set regulator %s load: %d\n",
1087
- vreg_info->name,
1088
- vreg_info->load_ua);
1089
- goto err_reg_config;
1090
- }
1091
- }
1092
-
1093
- ret = regulator_enable(vreg_info->reg);
1094
- if (ret) {
1095
- ath10k_err(ar, "failed to enable regulator %s\n",
1096
- vreg_info->name);
1097
- goto err_reg_config;
1098
- }
1099
-
1100
- if (vreg_info->settle_delay)
1101
- udelay(vreg_info->settle_delay);
1102
- }
1103
-
1104
- return 0;
1105
-
1106
-err_reg_config:
1107
- for (; i >= 0; i--) {
1108
- vreg_info = &ar_snoc->vreg[i];
1109
-
1110
- if (!vreg_info->reg)
1111
- continue;
1112
-
1113
- regulator_disable(vreg_info->reg);
1114
- regulator_set_load(vreg_info->reg, 0);
1115
- regulator_set_voltage(vreg_info->reg, 0, vreg_info->max_v);
1116
- }
1117
-
1118
- return ret;
1119
-}
1120
-
1121
-static int ath10k_wcn3990_vreg_off(struct ath10k *ar)
1122
-{
1123
- struct ath10k_snoc *ar_snoc = ath10k_snoc_priv(ar);
1124
- struct ath10k_wcn3990_vreg_info *vreg_info;
1125
- int ret = 0;
1126
- int i;
1127
-
1128
- for (i = ARRAY_SIZE(vreg_cfg) - 1; i >= 0; i--) {
1129
- vreg_info = &ar_snoc->vreg[i];
1130
-
1131
- if (!vreg_info->reg)
1132
- continue;
1133
-
1134
- ath10k_dbg(ar, ATH10K_DBG_SNOC, "snoc regulator %s being disabled\n",
1135
- vreg_info->name);
1136
-
1137
- ret = regulator_disable(vreg_info->reg);
1138
- if (ret)
1139
- ath10k_err(ar, "failed to disable regulator %s\n",
1140
- vreg_info->name);
1141
-
1142
- ret = regulator_set_load(vreg_info->reg, 0);
1143
- if (ret < 0)
1144
- ath10k_err(ar, "failed to set load %s\n",
1145
- vreg_info->name);
1146
-
1147
- ret = regulator_set_voltage(vreg_info->reg, 0,
1148
- vreg_info->max_v);
1149
- if (ret)
1150
- ath10k_err(ar, "failed to set voltage %s\n",
1151
- vreg_info->name);
1152
- }
1153
-
1154
- return ret;
1155
-}
1156
-
1157
-static int ath10k_wcn3990_clk_init(struct ath10k *ar)
1158
-{
1159
- struct ath10k_snoc *ar_snoc = ath10k_snoc_priv(ar);
1160
- struct ath10k_wcn3990_clk_info *clk_info;
1161
- int ret = 0;
1162
- int i;
1163
-
1164
- for (i = 0; i < ARRAY_SIZE(clk_cfg); i++) {
1165
- clk_info = &ar_snoc->clk[i];
1166
-
1167
- if (!clk_info->handle)
1168
- continue;
1169
-
1170
- ath10k_dbg(ar, ATH10K_DBG_SNOC, "snoc clock %s being enabled\n",
1171
- clk_info->name);
1172
-
1173
- if (clk_info->freq) {
1174
- ret = clk_set_rate(clk_info->handle, clk_info->freq);
1175
-
1176
- if (ret) {
1177
- ath10k_err(ar, "failed to set clock %s freq %u\n",
1178
- clk_info->name, clk_info->freq);
1179
- goto err_clock_config;
1180
- }
1181
- }
1182
-
1183
- ret = clk_prepare_enable(clk_info->handle);
1184
- if (ret) {
1185
- ath10k_err(ar, "failed to enable clock %s\n",
1186
- clk_info->name);
1187
- goto err_clock_config;
1188
- }
1189
- }
1190
-
1191
- return 0;
1192
-
1193
-err_clock_config:
1194
- for (i = i - 1; i >= 0; i--) {
1195
- clk_info = &ar_snoc->clk[i];
1196
-
1197
- if (!clk_info->handle)
1198
- continue;
1199
-
1200
- clk_disable_unprepare(clk_info->handle);
1201
- }
1202
-
1203
- return ret;
1204
-}
1205
-
1206
-static int ath10k_wcn3990_clk_deinit(struct ath10k *ar)
1207
-{
1208
- struct ath10k_snoc *ar_snoc = ath10k_snoc_priv(ar);
1209
- struct ath10k_wcn3990_clk_info *clk_info;
1210
- int i;
1211
-
1212
- for (i = 0; i < ARRAY_SIZE(clk_cfg); i++) {
1213
- clk_info = &ar_snoc->clk[i];
1214
-
1215
- if (!clk_info->handle)
1216
- continue;
1217
-
1218
- ath10k_dbg(ar, ATH10K_DBG_SNOC, "snoc clock %s being disabled\n",
1219
- clk_info->name);
1220
-
1221
- clk_disable_unprepare(clk_info->handle);
1222
- }
1223
-
1224
- return 0;
1225
-}
1226
-
12271372 static int ath10k_hw_power_on(struct ath10k *ar)
12281373 {
1374
+ struct ath10k_snoc *ar_snoc = ath10k_snoc_priv(ar);
12291375 int ret;
12301376
12311377 ath10k_dbg(ar, ATH10K_DBG_SNOC, "soc power on\n");
12321378
1233
- ret = ath10k_wcn3990_vreg_on(ar);
1379
+ ret = regulator_bulk_enable(ar_snoc->num_vregs, ar_snoc->vregs);
12341380 if (ret)
12351381 return ret;
12361382
1237
- ret = ath10k_wcn3990_clk_init(ar);
1383
+ ret = clk_bulk_prepare_enable(ar_snoc->num_clks, ar_snoc->clks);
12381384 if (ret)
12391385 goto vreg_off;
12401386
12411387 return ret;
12421388
12431389 vreg_off:
1244
- ath10k_wcn3990_vreg_off(ar);
1390
+ regulator_bulk_disable(ar_snoc->num_vregs, ar_snoc->vregs);
12451391 return ret;
12461392 }
12471393
12481394 static int ath10k_hw_power_off(struct ath10k *ar)
12491395 {
1250
- int ret;
1396
+ struct ath10k_snoc *ar_snoc = ath10k_snoc_priv(ar);
12511397
12521398 ath10k_dbg(ar, ATH10K_DBG_SNOC, "soc power off\n");
12531399
1254
- ath10k_wcn3990_clk_deinit(ar);
1400
+ clk_bulk_disable_unprepare(ar_snoc->num_clks, ar_snoc->clks);
12551401
1256
- ret = ath10k_wcn3990_vreg_off(ar);
1402
+ return regulator_bulk_disable(ar_snoc->num_vregs, ar_snoc->vregs);
1403
+}
1404
+
1405
+static void ath10k_msa_dump_memory(struct ath10k *ar,
1406
+ struct ath10k_fw_crash_data *crash_data)
1407
+{
1408
+ const struct ath10k_hw_mem_layout *mem_layout;
1409
+ const struct ath10k_mem_region *current_region;
1410
+ struct ath10k_dump_ram_data_hdr *hdr;
1411
+ size_t buf_len;
1412
+ u8 *buf;
1413
+
1414
+ if (!crash_data || !crash_data->ramdump_buf)
1415
+ return;
1416
+
1417
+ mem_layout = ath10k_coredump_get_mem_layout(ar);
1418
+ if (!mem_layout)
1419
+ return;
1420
+
1421
+ current_region = &mem_layout->region_table.regions[0];
1422
+
1423
+ buf = crash_data->ramdump_buf;
1424
+ buf_len = crash_data->ramdump_buf_len;
1425
+ memset(buf, 0, buf_len);
1426
+
1427
+ /* Reserve space for the header. */
1428
+ hdr = (void *)buf;
1429
+ buf += sizeof(*hdr);
1430
+ buf_len -= sizeof(*hdr);
1431
+
1432
+ hdr->region_type = cpu_to_le32(current_region->type);
1433
+ hdr->start = cpu_to_le32((unsigned long)ar->msa.vaddr);
1434
+ hdr->length = cpu_to_le32(ar->msa.mem_size);
1435
+
1436
+ if (current_region->len < ar->msa.mem_size) {
1437
+ memcpy(buf, ar->msa.vaddr, current_region->len);
1438
+ ath10k_warn(ar, "msa dump length is less than msa size %x, %x\n",
1439
+ current_region->len, ar->msa.mem_size);
1440
+ } else {
1441
+ memcpy(buf, ar->msa.vaddr, ar->msa.mem_size);
1442
+ }
1443
+}
1444
+
1445
+void ath10k_snoc_fw_crashed_dump(struct ath10k *ar)
1446
+{
1447
+ struct ath10k_fw_crash_data *crash_data;
1448
+ char guid[UUID_STRING_LEN + 1];
1449
+
1450
+ mutex_lock(&ar->dump_mutex);
1451
+
1452
+ spin_lock_bh(&ar->data_lock);
1453
+ ar->stats.fw_crash_counter++;
1454
+ spin_unlock_bh(&ar->data_lock);
1455
+
1456
+ crash_data = ath10k_coredump_new(ar);
1457
+
1458
+ if (crash_data)
1459
+ scnprintf(guid, sizeof(guid), "%pUl", &crash_data->guid);
1460
+ else
1461
+ scnprintf(guid, sizeof(guid), "n/a");
1462
+
1463
+ ath10k_err(ar, "firmware crashed! (guid %s)\n", guid);
1464
+ ath10k_print_driver_info(ar);
1465
+ ath10k_msa_dump_memory(ar, crash_data);
1466
+ mutex_unlock(&ar->dump_mutex);
1467
+}
1468
+
1469
+static int ath10k_setup_msa_resources(struct ath10k *ar, u32 msa_size)
1470
+{
1471
+ struct device *dev = ar->dev;
1472
+ struct device_node *node;
1473
+ struct resource r;
1474
+ int ret;
1475
+
1476
+ node = of_parse_phandle(dev->of_node, "memory-region", 0);
1477
+ if (node) {
1478
+ ret = of_address_to_resource(node, 0, &r);
1479
+ of_node_put(node);
1480
+ if (ret) {
1481
+ dev_err(dev, "failed to resolve msa fixed region\n");
1482
+ return ret;
1483
+ }
1484
+
1485
+ ar->msa.paddr = r.start;
1486
+ ar->msa.mem_size = resource_size(&r);
1487
+ ar->msa.vaddr = devm_memremap(dev, ar->msa.paddr,
1488
+ ar->msa.mem_size,
1489
+ MEMREMAP_WT);
1490
+ if (IS_ERR(ar->msa.vaddr)) {
1491
+ dev_err(dev, "failed to map memory region: %pa\n",
1492
+ &r.start);
1493
+ return PTR_ERR(ar->msa.vaddr);
1494
+ }
1495
+ } else {
1496
+ ar->msa.vaddr = dmam_alloc_coherent(dev, msa_size,
1497
+ &ar->msa.paddr,
1498
+ GFP_KERNEL);
1499
+ if (!ar->msa.vaddr) {
1500
+ ath10k_err(ar, "failed to allocate dma memory for msa region\n");
1501
+ return -ENOMEM;
1502
+ }
1503
+ ar->msa.mem_size = msa_size;
1504
+ }
1505
+
1506
+ ath10k_dbg(ar, ATH10K_DBG_QMI, "qmi msa.paddr: %pad , msa.vaddr: 0x%p\n",
1507
+ &ar->msa.paddr,
1508
+ ar->msa.vaddr);
1509
+
1510
+ return 0;
1511
+}
1512
+
1513
+static int ath10k_fw_init(struct ath10k *ar)
1514
+{
1515
+ struct ath10k_snoc *ar_snoc = ath10k_snoc_priv(ar);
1516
+ struct device *host_dev = &ar_snoc->dev->dev;
1517
+ struct platform_device_info info;
1518
+ struct iommu_domain *iommu_dom;
1519
+ struct platform_device *pdev;
1520
+ struct device_node *node;
1521
+ int ret;
1522
+
1523
+ node = of_get_child_by_name(host_dev->of_node, "wifi-firmware");
1524
+ if (!node) {
1525
+ ar_snoc->use_tz = true;
1526
+ return 0;
1527
+ }
1528
+
1529
+ memset(&info, 0, sizeof(info));
1530
+ info.fwnode = &node->fwnode;
1531
+ info.parent = host_dev;
1532
+ info.name = node->name;
1533
+ info.dma_mask = DMA_BIT_MASK(32);
1534
+
1535
+ pdev = platform_device_register_full(&info);
1536
+ if (IS_ERR(pdev)) {
1537
+ of_node_put(node);
1538
+ return PTR_ERR(pdev);
1539
+ }
1540
+
1541
+ pdev->dev.of_node = node;
1542
+
1543
+ ret = of_dma_configure(&pdev->dev, node, true);
1544
+ if (ret) {
1545
+ ath10k_err(ar, "dma configure fail: %d\n", ret);
1546
+ goto err_unregister;
1547
+ }
1548
+
1549
+ ar_snoc->fw.dev = &pdev->dev;
1550
+
1551
+ iommu_dom = iommu_domain_alloc(&platform_bus_type);
1552
+ if (!iommu_dom) {
1553
+ ath10k_err(ar, "failed to allocate iommu domain\n");
1554
+ ret = -ENOMEM;
1555
+ goto err_unregister;
1556
+ }
1557
+
1558
+ ret = iommu_attach_device(iommu_dom, ar_snoc->fw.dev);
1559
+ if (ret) {
1560
+ ath10k_err(ar, "could not attach device: %d\n", ret);
1561
+ goto err_iommu_free;
1562
+ }
1563
+
1564
+ ar_snoc->fw.iommu_domain = iommu_dom;
1565
+ ar_snoc->fw.fw_start_addr = ar->msa.paddr;
1566
+
1567
+ ret = iommu_map(iommu_dom, ar_snoc->fw.fw_start_addr,
1568
+ ar->msa.paddr, ar->msa.mem_size,
1569
+ IOMMU_READ | IOMMU_WRITE);
1570
+ if (ret) {
1571
+ ath10k_err(ar, "failed to map firmware region: %d\n", ret);
1572
+ goto err_iommu_detach;
1573
+ }
1574
+
1575
+ of_node_put(node);
1576
+
1577
+ return 0;
1578
+
1579
+err_iommu_detach:
1580
+ iommu_detach_device(iommu_dom, ar_snoc->fw.dev);
1581
+
1582
+err_iommu_free:
1583
+ iommu_domain_free(iommu_dom);
1584
+
1585
+err_unregister:
1586
+ platform_device_unregister(pdev);
1587
+ of_node_put(node);
12571588
12581589 return ret;
1590
+}
1591
+
1592
+static int ath10k_fw_deinit(struct ath10k *ar)
1593
+{
1594
+ struct ath10k_snoc *ar_snoc = ath10k_snoc_priv(ar);
1595
+ const size_t mapped_size = ar_snoc->fw.mapped_mem_size;
1596
+ struct iommu_domain *iommu;
1597
+ size_t unmapped_size;
1598
+
1599
+ if (ar_snoc->use_tz)
1600
+ return 0;
1601
+
1602
+ iommu = ar_snoc->fw.iommu_domain;
1603
+
1604
+ unmapped_size = iommu_unmap(iommu, ar_snoc->fw.fw_start_addr,
1605
+ mapped_size);
1606
+ if (unmapped_size != mapped_size)
1607
+ ath10k_err(ar, "failed to unmap firmware: %zu\n",
1608
+ unmapped_size);
1609
+
1610
+ iommu_detach_device(iommu, ar_snoc->fw.dev);
1611
+ iommu_domain_free(iommu);
1612
+
1613
+ platform_device_unregister(to_platform_device(ar_snoc->fw.dev));
1614
+
1615
+ return 0;
12591616 }
12601617
12611618 static const struct of_device_id ath10k_snoc_dt_match[] = {
....@@ -1269,25 +1626,23 @@
12691626 static int ath10k_snoc_probe(struct platform_device *pdev)
12701627 {
12711628 const struct ath10k_snoc_drv_priv *drv_data;
1272
- const struct of_device_id *of_id;
12731629 struct ath10k_snoc *ar_snoc;
12741630 struct device *dev;
12751631 struct ath10k *ar;
1632
+ u32 msa_size;
12761633 int ret;
12771634 u32 i;
12781635
1279
- of_id = of_match_device(ath10k_snoc_dt_match, &pdev->dev);
1280
- if (!of_id) {
1281
- dev_err(&pdev->dev, "failed to find matching device tree id\n");
1636
+ dev = &pdev->dev;
1637
+ drv_data = device_get_match_data(dev);
1638
+ if (!drv_data) {
1639
+ dev_err(dev, "failed to find matching device tree id\n");
12821640 return -EINVAL;
12831641 }
12841642
1285
- drv_data = of_id->data;
1286
- dev = &pdev->dev;
1287
-
12881643 ret = dma_set_mask_and_coherent(dev, drv_data->dma_mask);
12891644 if (ret) {
1290
- dev_err(dev, "failed to set dma mask: %d", ret);
1645
+ dev_err(dev, "failed to set dma mask: %d\n", ret);
12911646 return ret;
12921647 }
12931648
....@@ -1304,6 +1659,9 @@
13041659 ar_snoc->ar = ar;
13051660 ar_snoc->ce.bus_ops = &ath10k_snoc_bus_ops;
13061661 ar->ce_priv = &ar_snoc->ce;
1662
+ msa_size = drv_data->msa_size;
1663
+
1664
+ ath10k_snoc_quirks_init(ar);
13071665
13081666 ret = ath10k_snoc_resource_init(ar);
13091667 if (ret) {
....@@ -1322,19 +1680,36 @@
13221680 goto err_release_resource;
13231681 }
13241682
1325
- ar_snoc->vreg = vreg_cfg;
1326
- for (i = 0; i < ARRAY_SIZE(vreg_cfg); i++) {
1327
- ret = ath10k_get_vreg_info(ar, dev, &ar_snoc->vreg[i]);
1328
- if (ret)
1329
- goto err_free_irq;
1683
+ ar_snoc->num_vregs = ARRAY_SIZE(ath10k_regulators);
1684
+ ar_snoc->vregs = devm_kcalloc(&pdev->dev, ar_snoc->num_vregs,
1685
+ sizeof(*ar_snoc->vregs), GFP_KERNEL);
1686
+ if (!ar_snoc->vregs) {
1687
+ ret = -ENOMEM;
1688
+ goto err_free_irq;
1689
+ }
1690
+ for (i = 0; i < ar_snoc->num_vregs; i++)
1691
+ ar_snoc->vregs[i].supply = ath10k_regulators[i];
1692
+
1693
+ ret = devm_regulator_bulk_get(&pdev->dev, ar_snoc->num_vregs,
1694
+ ar_snoc->vregs);
1695
+ if (ret < 0)
1696
+ goto err_free_irq;
1697
+
1698
+ ar_snoc->num_clks = ARRAY_SIZE(ath10k_clocks);
1699
+ ar_snoc->clks = devm_kcalloc(&pdev->dev, ar_snoc->num_clks,
1700
+ sizeof(*ar_snoc->clks), GFP_KERNEL);
1701
+ if (!ar_snoc->clks) {
1702
+ ret = -ENOMEM;
1703
+ goto err_free_irq;
13301704 }
13311705
1332
- ar_snoc->clk = clk_cfg;
1333
- for (i = 0; i < ARRAY_SIZE(clk_cfg); i++) {
1334
- ret = ath10k_get_clk_info(ar, dev, &ar_snoc->clk[i]);
1335
- if (ret)
1336
- goto err_free_irq;
1337
- }
1706
+ for (i = 0; i < ar_snoc->num_clks; i++)
1707
+ ar_snoc->clks[i].id = ath10k_clocks[i];
1708
+
1709
+ ret = devm_clk_bulk_get_optional(&pdev->dev, ar_snoc->num_clks,
1710
+ ar_snoc->clks);
1711
+ if (ret)
1712
+ goto err_free_irq;
13381713
13391714 ret = ath10k_hw_power_on(ar);
13401715 if (ret) {
....@@ -1342,18 +1717,32 @@
13421717 goto err_free_irq;
13431718 }
13441719
1345
- ret = ath10k_core_register(ar, drv_data->hw_rev);
1720
+ ret = ath10k_setup_msa_resources(ar, msa_size);
13461721 if (ret) {
1347
- ath10k_err(ar, "failed to register driver core: %d\n", ret);
1348
- goto err_hw_power_off;
1722
+ ath10k_warn(ar, "failed to setup msa resources: %d\n", ret);
1723
+ goto err_power_off;
1724
+ }
1725
+
1726
+ ret = ath10k_fw_init(ar);
1727
+ if (ret) {
1728
+ ath10k_err(ar, "failed to initialize firmware: %d\n", ret);
1729
+ goto err_power_off;
1730
+ }
1731
+
1732
+ ret = ath10k_qmi_init(ar, msa_size);
1733
+ if (ret) {
1734
+ ath10k_warn(ar, "failed to register wlfw qmi client: %d\n", ret);
1735
+ goto err_fw_deinit;
13491736 }
13501737
13511738 ath10k_dbg(ar, ATH10K_DBG_SNOC, "snoc probe\n");
1352
- ath10k_warn(ar, "Warning: SNOC support is still work-in-progress, it will not work properly!");
13531739
13541740 return 0;
13551741
1356
-err_hw_power_off:
1742
+err_fw_deinit:
1743
+ ath10k_fw_deinit(ar);
1744
+
1745
+err_power_off:
13571746 ath10k_hw_power_off(ar);
13581747
13591748 err_free_irq:
....@@ -1371,24 +1760,44 @@
13711760 static int ath10k_snoc_remove(struct platform_device *pdev)
13721761 {
13731762 struct ath10k *ar = platform_get_drvdata(pdev);
1763
+ struct ath10k_snoc *ar_snoc = ath10k_snoc_priv(ar);
13741764
13751765 ath10k_dbg(ar, ATH10K_DBG_SNOC, "snoc remove\n");
1766
+
1767
+ reinit_completion(&ar->driver_recovery);
1768
+
1769
+ if (test_bit(ATH10K_SNOC_FLAG_RECOVERY, &ar_snoc->flags))
1770
+ wait_for_completion_timeout(&ar->driver_recovery, 3 * HZ);
1771
+
1772
+ set_bit(ATH10K_SNOC_FLAG_UNREGISTERING, &ar_snoc->flags);
1773
+
13761774 ath10k_core_unregister(ar);
13771775 ath10k_hw_power_off(ar);
1776
+ ath10k_fw_deinit(ar);
13781777 ath10k_snoc_free_irq(ar);
13791778 ath10k_snoc_release_resource(ar);
1779
+ ath10k_qmi_deinit(ar);
13801780 ath10k_core_destroy(ar);
13811781
13821782 return 0;
13831783 }
13841784
1785
+static void ath10k_snoc_shutdown(struct platform_device *pdev)
1786
+{
1787
+ struct ath10k *ar = platform_get_drvdata(pdev);
1788
+
1789
+ ath10k_dbg(ar, ATH10K_DBG_SNOC, "snoc shutdown\n");
1790
+ ath10k_snoc_remove(pdev);
1791
+}
1792
+
13851793 static struct platform_driver ath10k_snoc_driver = {
1386
- .probe = ath10k_snoc_probe,
1387
- .remove = ath10k_snoc_remove,
1388
- .driver = {
1389
- .name = "ath10k_snoc",
1390
- .of_match_table = ath10k_snoc_dt_match,
1391
- },
1794
+ .probe = ath10k_snoc_probe,
1795
+ .remove = ath10k_snoc_remove,
1796
+ .shutdown = ath10k_snoc_shutdown,
1797
+ .driver = {
1798
+ .name = "ath10k_snoc",
1799
+ .of_match_table = ath10k_snoc_dt_match,
1800
+ },
13921801 };
13931802 module_platform_driver(ath10k_snoc_driver);
13941803