snoc.c (188de5dd80b2b7986e75821374efb67081049b6e) snoc.c (ba94c753ccb471bafe8bd824b744fda6fee0001e)
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

--- 53 unchanged lines hidden (view full) ---

62static void ath10k_snoc_htc_rx_cb(struct ath10k_ce_pipe *ce_state);
63static void ath10k_snoc_htt_rx_cb(struct ath10k_ce_pipe *ce_state);
64static void ath10k_snoc_htt_htc_rx_cb(struct ath10k_ce_pipe *ce_state);
65static void ath10k_snoc_pktlog_rx_cb(struct ath10k_ce_pipe *ce_state);
66
67static const struct ath10k_snoc_drv_priv drv_priv = {
68 .hw_rev = ATH10K_HW_WCN3990,
69 .dma_mask = DMA_BIT_MASK(37),
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

--- 53 unchanged lines hidden (view full) ---

62static void ath10k_snoc_htc_rx_cb(struct ath10k_ce_pipe *ce_state);
63static void ath10k_snoc_htt_rx_cb(struct ath10k_ce_pipe *ce_state);
64static void ath10k_snoc_htt_htc_rx_cb(struct ath10k_ce_pipe *ce_state);
65static void ath10k_snoc_pktlog_rx_cb(struct ath10k_ce_pipe *ce_state);
66
67static const struct ath10k_snoc_drv_priv drv_priv = {
68 .hw_rev = ATH10K_HW_WCN3990,
69 .dma_mask = DMA_BIT_MASK(37),
70 .msa_size = 0x100000,
70};
71
71};
72
73#define WCN3990_SRC_WR_IDX_OFFSET 0x3C
74#define WCN3990_DST_WR_IDX_OFFSET 0x40
75
76static struct ath10k_shadow_reg_cfg target_shadow_reg_cfg_map[] = {
77 {
78 .ce_id = __cpu_to_le16(0),
79 .reg_offset = __cpu_to_le16(WCN3990_SRC_WR_IDX_OFFSET),
80 },
81
82 {
83 .ce_id = __cpu_to_le16(3),
84 .reg_offset = __cpu_to_le16(WCN3990_SRC_WR_IDX_OFFSET),
85 },
86
87 {
88 .ce_id = __cpu_to_le16(4),
89 .reg_offset = __cpu_to_le16(WCN3990_SRC_WR_IDX_OFFSET),
90 },
91
92 {
93 .ce_id = __cpu_to_le16(5),
94 .reg_offset = __cpu_to_le16(WCN3990_SRC_WR_IDX_OFFSET),
95 },
96
97 {
98 .ce_id = __cpu_to_le16(7),
99 .reg_offset = __cpu_to_le16(WCN3990_SRC_WR_IDX_OFFSET),
100 },
101
102 {
103 .ce_id = __cpu_to_le16(1),
104 .reg_offset = __cpu_to_le16(WCN3990_DST_WR_IDX_OFFSET),
105 },
106
107 {
108 .ce_id = __cpu_to_le16(2),
109 .reg_offset = __cpu_to_le16(WCN3990_DST_WR_IDX_OFFSET),
110 },
111
112 {
113 .ce_id = __cpu_to_le16(7),
114 .reg_offset = __cpu_to_le16(WCN3990_DST_WR_IDX_OFFSET),
115 },
116
117 {
118 .ce_id = __cpu_to_le16(8),
119 .reg_offset = __cpu_to_le16(WCN3990_DST_WR_IDX_OFFSET),
120 },
121
122 {
123 .ce_id = __cpu_to_le16(9),
124 .reg_offset = __cpu_to_le16(WCN3990_DST_WR_IDX_OFFSET),
125 },
126
127 {
128 .ce_id = __cpu_to_le16(10),
129 .reg_offset = __cpu_to_le16(WCN3990_DST_WR_IDX_OFFSET),
130 },
131
132 {
133 .ce_id = __cpu_to_le16(11),
134 .reg_offset = __cpu_to_le16(WCN3990_DST_WR_IDX_OFFSET),
135 },
136};
137
72static 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,

--- 91 unchanged lines hidden (view full) ---

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
138static struct ce_attr host_ce_config_wlan[] = {
139 /* CE0: host->target HTC control streams */
140 {
141 .flags = CE_ATTR_FLAGS,
142 .src_nentries = 16,
143 .src_sz_max = 2048,
144 .dest_nentries = 0,
145 .send_cb = ath10k_snoc_htc_tx_cb,

--- 91 unchanged lines hidden (view full) ---

237 .flags = CE_ATTR_FLAGS,
238 .src_nentries = 0,
239 .src_sz_max = 2048,
240 .dest_nentries = 512,
241 .recv_cb = ath10k_snoc_pktlog_rx_cb,
242 },
243};
244
245static struct ce_pipe_config target_ce_config_wlan[] = {
246 /* CE0: host->target HTC control and raw streams */
247 {
248 .pipenum = __cpu_to_le32(0),
249 .pipedir = __cpu_to_le32(PIPEDIR_OUT),
250 .nentries = __cpu_to_le32(32),
251 .nbytes_max = __cpu_to_le32(2048),
252 .flags = __cpu_to_le32(CE_ATTR_FLAGS),
253 .reserved = __cpu_to_le32(0),
254 },
255
256 /* CE1: target->host HTT + HTC control */
257 {
258 .pipenum = __cpu_to_le32(1),
259 .pipedir = __cpu_to_le32(PIPEDIR_IN),
260 .nentries = __cpu_to_le32(32),
261 .nbytes_max = __cpu_to_le32(2048),
262 .flags = __cpu_to_le32(CE_ATTR_FLAGS),
263 .reserved = __cpu_to_le32(0),
264 },
265
266 /* CE2: target->host WMI */
267 {
268 .pipenum = __cpu_to_le32(2),
269 .pipedir = __cpu_to_le32(PIPEDIR_IN),
270 .nentries = __cpu_to_le32(64),
271 .nbytes_max = __cpu_to_le32(2048),
272 .flags = __cpu_to_le32(CE_ATTR_FLAGS),
273 .reserved = __cpu_to_le32(0),
274 },
275
276 /* CE3: host->target WMI */
277 {
278 .pipenum = __cpu_to_le32(3),
279 .pipedir = __cpu_to_le32(PIPEDIR_OUT),
280 .nentries = __cpu_to_le32(32),
281 .nbytes_max = __cpu_to_le32(2048),
282 .flags = __cpu_to_le32(CE_ATTR_FLAGS),
283 .reserved = __cpu_to_le32(0),
284 },
285
286 /* CE4: host->target HTT */
287 {
288 .pipenum = __cpu_to_le32(4),
289 .pipedir = __cpu_to_le32(PIPEDIR_OUT),
290 .nentries = __cpu_to_le32(256),
291 .nbytes_max = __cpu_to_le32(256),
292 .flags = __cpu_to_le32(CE_ATTR_FLAGS | CE_ATTR_DIS_INTR),
293 .reserved = __cpu_to_le32(0),
294 },
295
296 /* CE5: target->host HTT (HIF->HTT) */
297 {
298 .pipenum = __cpu_to_le32(5),
299 .pipedir = __cpu_to_le32(PIPEDIR_OUT),
300 .nentries = __cpu_to_le32(1024),
301 .nbytes_max = __cpu_to_le32(64),
302 .flags = __cpu_to_le32(CE_ATTR_FLAGS | CE_ATTR_DIS_INTR),
303 .reserved = __cpu_to_le32(0),
304 },
305
306 /* CE6: Reserved for target autonomous hif_memcpy */
307 {
308 .pipenum = __cpu_to_le32(6),
309 .pipedir = __cpu_to_le32(PIPEDIR_INOUT),
310 .nentries = __cpu_to_le32(32),
311 .nbytes_max = __cpu_to_le32(16384),
312 .flags = __cpu_to_le32(CE_ATTR_FLAGS),
313 .reserved = __cpu_to_le32(0),
314 },
315
316 /* CE7 used only by Host */
317 {
318 .pipenum = __cpu_to_le32(7),
319 .pipedir = __cpu_to_le32(4),
320 .nentries = __cpu_to_le32(0),
321 .nbytes_max = __cpu_to_le32(0),
322 .flags = __cpu_to_le32(CE_ATTR_FLAGS | CE_ATTR_DIS_INTR),
323 .reserved = __cpu_to_le32(0),
324 },
325
326 /* CE8 Target to uMC */
327 {
328 .pipenum = __cpu_to_le32(8),
329 .pipedir = __cpu_to_le32(PIPEDIR_IN),
330 .nentries = __cpu_to_le32(32),
331 .nbytes_max = __cpu_to_le32(2048),
332 .flags = __cpu_to_le32(0),
333 .reserved = __cpu_to_le32(0),
334 },
335
336 /* CE9 target->host HTT */
337 {
338 .pipenum = __cpu_to_le32(9),
339 .pipedir = __cpu_to_le32(PIPEDIR_IN),
340 .nentries = __cpu_to_le32(32),
341 .nbytes_max = __cpu_to_le32(2048),
342 .flags = __cpu_to_le32(CE_ATTR_FLAGS),
343 .reserved = __cpu_to_le32(0),
344 },
345
346 /* CE10 target->host HTT */
347 {
348 .pipenum = __cpu_to_le32(10),
349 .pipedir = __cpu_to_le32(PIPEDIR_IN),
350 .nentries = __cpu_to_le32(32),
351 .nbytes_max = __cpu_to_le32(2048),
352 .flags = __cpu_to_le32(CE_ATTR_FLAGS),
353 .reserved = __cpu_to_le32(0),
354 },
355
356 /* CE11 target autonomous qcache memcpy */
357 {
358 .pipenum = __cpu_to_le32(11),
359 .pipedir = __cpu_to_le32(PIPEDIR_IN),
360 .nentries = __cpu_to_le32(32),
361 .nbytes_max = __cpu_to_le32(2048),
362 .flags = __cpu_to_le32(CE_ATTR_FLAGS),
363 .reserved = __cpu_to_le32(0),
364 },
365};
366
179static 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),

--- 574 unchanged lines hidden (view full) ---

761 }
762 }
763
764 return 0;
765}
766
767static int ath10k_snoc_wlan_enable(struct ath10k *ar)
768{
367static struct service_to_pipe target_service_to_ce_map_wlan[] = {
368 {
369 __cpu_to_le32(ATH10K_HTC_SVC_ID_WMI_DATA_VO),
370 __cpu_to_le32(PIPEDIR_OUT), /* out = UL = host -> target */
371 __cpu_to_le32(3),
372 },
373 {
374 __cpu_to_le32(ATH10K_HTC_SVC_ID_WMI_DATA_VO),

--- 574 unchanged lines hidden (view full) ---

949 }
950 }
951
952 return 0;
953}
954
955static int ath10k_snoc_wlan_enable(struct ath10k *ar)
956{
769 return 0;
957 struct ath10k_tgt_pipe_cfg tgt_cfg[CE_COUNT_MAX];
958 struct ath10k_qmi_wlan_enable_cfg cfg;
959 enum wlfw_driver_mode_enum_v01 mode;
960 int pipe_num;
961
962 for (pipe_num = 0; pipe_num < CE_COUNT_MAX; pipe_num++) {
963 tgt_cfg[pipe_num].pipe_num =
964 target_ce_config_wlan[pipe_num].pipenum;
965 tgt_cfg[pipe_num].pipe_dir =
966 target_ce_config_wlan[pipe_num].pipedir;
967 tgt_cfg[pipe_num].nentries =
968 target_ce_config_wlan[pipe_num].nentries;
969 tgt_cfg[pipe_num].nbytes_max =
970 target_ce_config_wlan[pipe_num].nbytes_max;
971 tgt_cfg[pipe_num].flags =
972 target_ce_config_wlan[pipe_num].flags;
973 tgt_cfg[pipe_num].reserved = 0;
974 }
975
976 cfg.num_ce_tgt_cfg = sizeof(target_ce_config_wlan) /
977 sizeof(struct ath10k_tgt_pipe_cfg);
978 cfg.ce_tgt_cfg = (struct ath10k_tgt_pipe_cfg *)
979 &tgt_cfg;
980 cfg.num_ce_svc_pipe_cfg = sizeof(target_service_to_ce_map_wlan) /
981 sizeof(struct ath10k_svc_pipe_cfg);
982 cfg.ce_svc_cfg = (struct ath10k_svc_pipe_cfg *)
983 &target_service_to_ce_map_wlan;
984 cfg.num_shadow_reg_cfg = sizeof(target_shadow_reg_cfg_map) /
985 sizeof(struct ath10k_shadow_reg_cfg);
986 cfg.shadow_reg_cfg = (struct ath10k_shadow_reg_cfg *)
987 &target_shadow_reg_cfg_map;
988
989 mode = QMI_WLFW_MISSION_V01;
990
991 return ath10k_qmi_wlan_enable(ar, &cfg, mode,
992 NULL);
770}
771
772static void ath10k_snoc_wlan_disable(struct ath10k *ar)
773{
993}
994
995static void ath10k_snoc_wlan_disable(struct ath10k *ar)
996{
997 ath10k_qmi_wlan_disable(ar);
774}
775
776static 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);

--- 170 unchanged lines hidden (view full) ---

952 }
953 ar_snoc->ce_irqs[i].irq_line = res->start;
954 }
955
956out:
957 return ret;
958}
959
998}
999
1000static void ath10k_snoc_hif_power_down(struct ath10k *ar)
1001{
1002 ath10k_dbg(ar, ATH10K_DBG_BOOT, "boot hif power down\n");
1003
1004 ath10k_snoc_wlan_disable(ar);
1005 ath10k_ce_free_rri(ar);

--- 170 unchanged lines hidden (view full) ---

1176 }
1177 ar_snoc->ce_irqs[i].irq_line = res->start;
1178 }
1179
1180out:
1181 return ret;
1182}
1183
1184int ath10k_snoc_fw_indication(struct ath10k *ar, u64 type)
1185{
1186 struct ath10k_snoc *ar_snoc = ath10k_snoc_priv(ar);
1187 struct ath10k_bus_params bus_params;
1188 int ret;
1189
1190 switch (type) {
1191 case ATH10K_QMI_EVENT_FW_READY_IND:
1192 bus_params.dev_type = ATH10K_DEV_TYPE_LL;
1193 bus_params.chip_id = ar_snoc->target_info.soc_version;
1194 ret = ath10k_core_register(ar, &bus_params);
1195 if (ret) {
1196 ath10k_err(ar, "failed to register driver core: %d\n",
1197 ret);
1198 }
1199 break;
1200 case ATH10K_QMI_EVENT_FW_DOWN_IND:
1201 break;
1202 default:
1203 ath10k_err(ar, "invalid fw indication: %llx\n", type);
1204 return -EINVAL;
1205 }
1206
1207 return 0;
1208}
1209
960static 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);

--- 308 unchanged lines hidden (view full) ---

1276
1277static 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;
1210static int ath10k_snoc_setup_resource(struct ath10k *ar)
1211{
1212 struct ath10k_snoc *ar_snoc = ath10k_snoc_priv(ar);
1213 struct ath10k_ce *ce = ath10k_ce_priv(ar);
1214 struct ath10k_snoc_pipe *pipe;
1215 int i, ret;
1216
1217 timer_setup(&ar_snoc->rx_post_retry, ath10k_snoc_rx_replenish_retry, 0);

--- 308 unchanged lines hidden (view full) ---

1526
1527static int ath10k_snoc_probe(struct platform_device *pdev)
1528{
1529 const struct ath10k_snoc_drv_priv *drv_data;
1530 const struct of_device_id *of_id;
1531 struct ath10k_snoc *ar_snoc;
1532 struct device *dev;
1533 struct ath10k *ar;
1534 u32 msa_size;
1284 int ret;
1285 u32 i;
1535 int ret;
1536 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;

--- 13 unchanged lines hidden (view full) ---

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;
1537
1538 of_id = of_match_device(ath10k_snoc_dt_match, &pdev->dev);
1539 if (!of_id) {
1540 dev_err(&pdev->dev, "failed to find matching device tree id\n");
1541 return -EINVAL;
1542 }
1543
1544 drv_data = of_id->data;

--- 13 unchanged lines hidden (view full) ---

1558 }
1559
1560 ar_snoc = ath10k_snoc_priv(ar);
1561 ar_snoc->dev = pdev;
1562 platform_set_drvdata(pdev, ar);
1563 ar_snoc->ar = ar;
1564 ar_snoc->ce.bus_ops = &ath10k_snoc_bus_ops;
1565 ar->ce_priv = &ar_snoc->ce;
1566 msa_size = drv_data->msa_size;
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);

--- 22 unchanged lines hidden (view full) ---

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
1567
1568 ret = ath10k_snoc_resource_init(ar);
1569 if (ret) {
1570 ath10k_warn(ar, "failed to initialize resource: %d\n", ret);
1571 goto err_core_destroy;
1572 }
1573
1574 ret = ath10k_snoc_setup_resource(ar);

--- 22 unchanged lines hidden (view full) ---

1597 }
1598
1599 ret = ath10k_hw_power_on(ar);
1600 if (ret) {
1601 ath10k_err(ar, "failed to power on device: %d\n", ret);
1602 goto err_free_irq;
1603 }
1604
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);
1605 ret = ath10k_qmi_init(ar, msa_size);
1357 if (ret) {
1606 if (ret) {
1358 ath10k_err(ar, "failed to register driver core: %d\n", ret);
1359 goto err_hw_power_off;
1607 ath10k_warn(ar, "failed to register wlfw qmi client: %d\n", ret);
1608 goto err_core_destroy;
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
1609 }
1610
1611 ath10k_dbg(ar, ATH10K_DBG_SNOC, "snoc probe\n");
1612 ath10k_warn(ar, "Warning: SNOC support is still work-in-progress, it will not work properly!");
1613
1614 return 0;
1615
1367err_hw_power_off:
1368 ath10k_hw_power_off(ar);
1369
1370err_free_irq:
1371 ath10k_snoc_free_irq(ar);
1372
1373err_release_resource:
1374 ath10k_snoc_release_resource(ar);
1375
1376err_core_destroy:
1377 ath10k_core_destroy(ar);

--- 5 unchanged lines hidden (view full) ---

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);
1616err_free_irq:
1617 ath10k_snoc_free_irq(ar);
1618
1619err_release_resource:
1620 ath10k_snoc_release_resource(ar);
1621
1622err_core_destroy:
1623 ath10k_core_destroy(ar);

--- 5 unchanged lines hidden (view full) ---

1629{
1630 struct ath10k *ar = platform_get_drvdata(pdev);
1631
1632 ath10k_dbg(ar, ATH10K_DBG_SNOC, "snoc remove\n");
1633 ath10k_core_unregister(ar);
1634 ath10k_hw_power_off(ar);
1635 ath10k_snoc_free_irq(ar);
1636 ath10k_snoc_release_resource(ar);
1637 ath10k_qmi_deinit(ar);
1391 ath10k_core_destroy(ar);
1392
1393 return 0;
1394}
1395
1396static 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};
1404module_platform_driver(ath10k_snoc_driver);
1405
1406MODULE_AUTHOR("Qualcomm");
1407MODULE_LICENSE("Dual BSD/GPL");
1408MODULE_DESCRIPTION("Driver support for Atheros WCN3990 SNOC devices");
1638 ath10k_core_destroy(ar);
1639
1640 return 0;
1641}
1642
1643static struct platform_driver ath10k_snoc_driver = {
1644 .probe = ath10k_snoc_probe,
1645 .remove = ath10k_snoc_remove,
1646 .driver = {
1647 .name = "ath10k_snoc",
1648 .of_match_table = ath10k_snoc_dt_match,
1649 },
1650};
1651module_platform_driver(ath10k_snoc_driver);
1652
1653MODULE_AUTHOR("Qualcomm");
1654MODULE_LICENSE("Dual BSD/GPL");
1655MODULE_DESCRIPTION("Driver support for Atheros WCN3990 SNOC devices");