blob: 795b9059085e64bc228796bec5d10450321d6448 [file] [log] [blame]
Yue Ma4dac45d2018-02-23 11:49:25 -08001/* Copyright (c) 2016-2018, The Linux Foundation. All rights reserved.
Yue Ma0317e4a2018-01-10 11:48:32 -08002 *
3 * This program is free software; you can redistribute it and/or modify
4 * it under the terms of the GNU General Public License version 2 and
5 * only version 2 as published by the Free Software Foundation.
6 *
7 * This program is distributed in the hope that it will be useful,
8 * but WITHOUT ANY WARRANTY; without even the implied warranty of
9 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10 * GNU General Public License for more details.
11 */
12
13#include <linux/firmware.h>
14#include <linux/irq.h>
15#include <linux/module.h>
16#include <linux/msi.h>
17#include <linux/of.h>
18#include <linux/pm_runtime.h>
19
20#include "main.h"
21#include "debug.h"
22#include "pci.h"
23
24#define PCI_LINK_UP 1
25#define PCI_LINK_DOWN 0
26
27#define SAVE_PCI_CONFIG_SPACE 1
28#define RESTORE_PCI_CONFIG_SPACE 0
29
30#define PM_OPTIONS_DEFAULT 0
31#define PM_OPTIONS_LINK_DOWN \
32 (MSM_PCIE_CONFIG_NO_CFG_RESTORE | MSM_PCIE_CONFIG_LINKDOWN)
33
34#define PCI_BAR_NUM 0
35
36#ifdef CONFIG_ARM_LPAE
37#define PCI_DMA_MASK 64
38#else
39#define PCI_DMA_MASK 32
40#endif
41
42#define MHI_NODE_NAME "qcom,mhi"
43
44#define MAX_M3_FILE_NAME_LENGTH 13
45#define DEFAULT_M3_FILE_NAME "m3.bin"
46
47static DEFINE_SPINLOCK(pci_link_down_lock);
48
49static unsigned int pci_link_down_panic;
50module_param(pci_link_down_panic, uint, 0600);
51MODULE_PARM_DESC(pci_link_down_panic,
52 "Trigger kernel panic when PCI link down is detected");
53
54static bool fbc_bypass;
55#ifdef CONFIG_CNSS2_DEBUG
56module_param(fbc_bypass, bool, 0600);
57MODULE_PARM_DESC(fbc_bypass,
58 "Bypass firmware download when loading WLAN driver");
59#endif
60
61static int cnss_set_pci_config_space(struct cnss_pci_data *pci_priv, bool save)
62{
63 struct pci_dev *pci_dev = pci_priv->pci_dev;
64 struct cnss_plat_data *plat_priv = pci_priv->plat_priv;
65 bool link_down_or_recovery;
66
67 if (!plat_priv)
68 return -ENODEV;
69
70 link_down_or_recovery = pci_priv->pci_link_down_ind ||
71 (test_bit(CNSS_DRIVER_RECOVERY, &plat_priv->driver_state));
72
73 if (save) {
74 if (link_down_or_recovery) {
75 pci_priv->saved_state = NULL;
76 } else {
77 pci_save_state(pci_dev);
78 pci_priv->saved_state = pci_store_saved_state(pci_dev);
79 }
80 } else {
81 if (link_down_or_recovery) {
82 pci_load_saved_state(pci_dev, pci_priv->default_state);
83 pci_restore_state(pci_dev);
84 } else if (pci_priv->saved_state) {
85 pci_load_and_free_saved_state(pci_dev,
86 &pci_priv->saved_state);
87 pci_restore_state(pci_dev);
88 }
89 }
90
91 return 0;
92}
93
94static int cnss_set_pci_link(struct cnss_pci_data *pci_priv, bool link_up)
95{
96 int ret = 0;
97 struct pci_dev *pci_dev = pci_priv->pci_dev;
98
99 ret = msm_pcie_pm_control(link_up ? MSM_PCIE_RESUME :
100 MSM_PCIE_SUSPEND,
101 pci_dev->bus->number,
102 pci_dev, NULL,
103 PM_OPTIONS_DEFAULT);
104 if (ret) {
105 cnss_pr_err("Failed to %s PCI link with default option, err = %d\n",
106 link_up ? "resume" : "suspend", ret);
107 return ret;
108 }
109
110 return 0;
111}
112
113int cnss_suspend_pci_link(struct cnss_pci_data *pci_priv)
114{
115 int ret = 0;
116
117 if (!pci_priv)
118 return -ENODEV;
119
120 cnss_pr_dbg("Suspending PCI link\n");
121 if (!pci_priv->pci_link_state) {
122 cnss_pr_info("PCI link is already suspended!\n");
123 goto out;
124 }
125
126 ret = cnss_set_pci_config_space(pci_priv, SAVE_PCI_CONFIG_SPACE);
127 if (ret)
128 goto out;
129
130 pci_disable_device(pci_priv->pci_dev);
131
132 if (pci_priv->pci_dev->device != QCA6174_DEVICE_ID) {
133 if (pci_set_power_state(pci_priv->pci_dev, PCI_D3hot))
134 cnss_pr_err("Failed to set D3Hot, err = %d\n", ret);
135 }
136
137 ret = cnss_set_pci_link(pci_priv, PCI_LINK_DOWN);
138 if (ret)
139 goto out;
140
141 pci_priv->pci_link_state = PCI_LINK_DOWN;
142
143 return 0;
144out:
145 return ret;
146}
147
148int cnss_resume_pci_link(struct cnss_pci_data *pci_priv)
149{
150 int ret = 0;
151
152 if (!pci_priv)
153 return -ENODEV;
154
155 cnss_pr_dbg("Resuming PCI link\n");
156 if (pci_priv->pci_link_state) {
157 cnss_pr_info("PCI link is already resumed!\n");
158 goto out;
159 }
160
161 ret = cnss_set_pci_link(pci_priv, PCI_LINK_UP);
162 if (ret)
163 goto out;
164
165 pci_priv->pci_link_state = PCI_LINK_UP;
166
167 ret = cnss_set_pci_config_space(pci_priv, RESTORE_PCI_CONFIG_SPACE);
168 if (ret)
169 goto out;
170
171 ret = pci_enable_device(pci_priv->pci_dev);
172 if (ret) {
173 cnss_pr_err("Failed to enable PCI device, err = %d\n", ret);
174 goto out;
175 }
176
177 pci_set_master(pci_priv->pci_dev);
178
179 if (pci_priv->pci_link_down_ind)
180 pci_priv->pci_link_down_ind = false;
181
182 return 0;
183out:
184 return ret;
185}
186
187int cnss_pci_link_down(struct device *dev)
188{
189 unsigned long flags;
190 struct pci_dev *pci_dev = to_pci_dev(dev);
191 struct cnss_pci_data *pci_priv = cnss_get_pci_priv(pci_dev);
192
193 if (!pci_priv) {
194 cnss_pr_err("pci_priv is NULL!\n");
195 return -EINVAL;
196 }
197
198 if (pci_link_down_panic)
199 panic("cnss: PCI link is down!\n");
200
201 spin_lock_irqsave(&pci_link_down_lock, flags);
202 if (pci_priv->pci_link_down_ind) {
203 cnss_pr_dbg("PCI link down recovery is in progress, ignore!\n");
204 spin_unlock_irqrestore(&pci_link_down_lock, flags);
205 return -EINVAL;
206 }
207 pci_priv->pci_link_down_ind = true;
208 spin_unlock_irqrestore(&pci_link_down_lock, flags);
209
210 cnss_pr_err("PCI link down is detected by host driver, schedule recovery!\n");
211
212 cnss_pci_set_mhi_state(pci_priv, CNSS_MHI_NOTIFY_LINK_ERROR);
213 cnss_schedule_recovery(dev, CNSS_REASON_LINK_DOWN);
214
215 return 0;
216}
217EXPORT_SYMBOL(cnss_pci_link_down);
218
219static int cnss_pci_init_smmu(struct cnss_pci_data *pci_priv)
220{
221 int ret = 0;
222 struct device *dev;
223 struct dma_iommu_mapping *mapping;
224 int atomic_ctx = 1;
225 int s1_bypass = 1;
Yue Ma4dac45d2018-02-23 11:49:25 -0800226 int fast = 1;
227
228 cnss_pr_dbg("Initializing SMMU\n");
Yue Ma0317e4a2018-01-10 11:48:32 -0800229
230 dev = &pci_priv->pci_dev->dev;
231
Yue Ma4dac45d2018-02-23 11:49:25 -0800232 mapping = arm_iommu_create_mapping(dev->bus,
Yue Ma0317e4a2018-01-10 11:48:32 -0800233 pci_priv->smmu_iova_start,
234 pci_priv->smmu_iova_len);
235 if (IS_ERR(mapping)) {
236 ret = PTR_ERR(mapping);
237 cnss_pr_err("Failed to create SMMU mapping, err = %d\n", ret);
238 goto out;
239 }
240
Yue Ma4dac45d2018-02-23 11:49:25 -0800241 if (pci_priv->smmu_s1_enable) {
242 cnss_pr_dbg("Enabling SMMU S1 stage\n");
Yue Ma0317e4a2018-01-10 11:48:32 -0800243
Yue Ma4dac45d2018-02-23 11:49:25 -0800244 ret = iommu_domain_set_attr(mapping->domain,
245 DOMAIN_ATTR_ATOMIC,
246 &atomic_ctx);
247 if (ret) {
248 pr_err("Failed to set SMMU atomic_ctx attribute, err = %d\n",
249 ret);
250 goto release_mapping;
251 }
252
253 ret = iommu_domain_set_attr(mapping->domain,
254 DOMAIN_ATTR_FAST,
255 &fast);
256 if (ret) {
257 pr_err("Failed to set SMMU fast attribute, err = %d\n",
258 ret);
259 goto release_mapping;
260 }
261 } else {
262 ret = iommu_domain_set_attr(mapping->domain,
263 DOMAIN_ATTR_S1_BYPASS,
264 &s1_bypass);
265 if (ret) {
266 pr_err("Failed to set SMMU s1_bypass attribute, err = %d\n",
267 ret);
268 goto release_mapping;
269 }
Yue Ma0317e4a2018-01-10 11:48:32 -0800270 }
271
272 ret = arm_iommu_attach_device(dev, mapping);
273 if (ret) {
274 pr_err("Failed to attach SMMU device, err = %d\n", ret);
275 goto release_mapping;
276 }
277
278 pci_priv->smmu_mapping = mapping;
279
280 return ret;
281release_mapping:
282 arm_iommu_release_mapping(mapping);
283out:
284 return ret;
285}
286
287static void cnss_pci_deinit_smmu(struct cnss_pci_data *pci_priv)
288{
289 arm_iommu_detach_device(&pci_priv->pci_dev->dev);
290 arm_iommu_release_mapping(pci_priv->smmu_mapping);
291
292 pci_priv->smmu_mapping = NULL;
293}
294
295static void cnss_pci_event_cb(struct msm_pcie_notify *notify)
296{
297 unsigned long flags;
298 struct pci_dev *pci_dev;
299 struct cnss_pci_data *pci_priv;
300
301 if (!notify)
302 return;
303
304 pci_dev = notify->user;
305 if (!pci_dev)
306 return;
307
308 pci_priv = cnss_get_pci_priv(pci_dev);
309 if (!pci_priv)
310 return;
311
312 switch (notify->event) {
313 case MSM_PCIE_EVENT_LINKDOWN:
314 if (pci_link_down_panic)
315 panic("cnss: PCI link is down!\n");
316
317 spin_lock_irqsave(&pci_link_down_lock, flags);
318 if (pci_priv->pci_link_down_ind) {
319 cnss_pr_dbg("PCI link down recovery is in progress, ignore!\n");
320 spin_unlock_irqrestore(&pci_link_down_lock, flags);
321 return;
322 }
323 pci_priv->pci_link_down_ind = true;
324 spin_unlock_irqrestore(&pci_link_down_lock, flags);
325
326 cnss_pr_err("PCI link down, schedule recovery!\n");
327 cnss_pci_set_mhi_state(pci_priv, CNSS_MHI_NOTIFY_LINK_ERROR);
328 if (pci_dev->device == QCA6174_DEVICE_ID)
329 disable_irq(pci_dev->irq);
330 cnss_schedule_recovery(&pci_dev->dev, CNSS_REASON_LINK_DOWN);
331 break;
332 case MSM_PCIE_EVENT_WAKEUP:
333 if (cnss_pci_get_monitor_wake_intr(pci_priv) &&
334 cnss_pci_get_auto_suspended(pci_priv)) {
335 cnss_pci_set_monitor_wake_intr(pci_priv, false);
336 pm_request_resume(&pci_dev->dev);
337 }
338 break;
339 default:
340 cnss_pr_err("Received invalid PCI event: %d\n", notify->event);
341 }
342}
343
344static int cnss_reg_pci_event(struct cnss_pci_data *pci_priv)
345{
346 int ret = 0;
347 struct msm_pcie_register_event *pci_event;
348
349 pci_event = &pci_priv->msm_pci_event;
350 pci_event->events = MSM_PCIE_EVENT_LINKDOWN |
351 MSM_PCIE_EVENT_WAKEUP;
352 pci_event->user = pci_priv->pci_dev;
353 pci_event->mode = MSM_PCIE_TRIGGER_CALLBACK;
354 pci_event->callback = cnss_pci_event_cb;
355 pci_event->options = MSM_PCIE_CONFIG_NO_RECOVERY;
356
357 ret = msm_pcie_register_event(pci_event);
358 if (ret)
359 cnss_pr_err("Failed to register MSM PCI event, err = %d\n",
360 ret);
361
362 return ret;
363}
364
365static void cnss_dereg_pci_event(struct cnss_pci_data *pci_priv)
366{
367 msm_pcie_deregister_event(&pci_priv->msm_pci_event);
368}
369
370static int cnss_pci_suspend(struct device *dev)
371{
372 int ret = 0;
373 struct pci_dev *pci_dev = to_pci_dev(dev);
374 struct cnss_pci_data *pci_priv = cnss_get_pci_priv(pci_dev);
375 struct cnss_plat_data *plat_priv;
376 struct cnss_wlan_driver *driver_ops;
377
378 pm_message_t state = { .event = PM_EVENT_SUSPEND };
379
380 if (!pci_priv)
381 goto out;
382
383 plat_priv = pci_priv->plat_priv;
384 if (!plat_priv)
385 goto out;
386
387 driver_ops = plat_priv->driver_ops;
388 if (driver_ops && driver_ops->suspend) {
389 ret = driver_ops->suspend(pci_dev, state);
390 if (ret) {
391 cnss_pr_err("Failed to suspend host driver, err = %d\n",
392 ret);
393 ret = -EAGAIN;
394 goto out;
395 }
396 }
397
398 if (pci_priv->pci_link_state) {
399 ret = cnss_pci_set_mhi_state(pci_priv, CNSS_MHI_SUSPEND);
400 if (ret) {
401 if (driver_ops && driver_ops->resume)
402 driver_ops->resume(pci_dev);
403 ret = -EAGAIN;
404 goto out;
405 }
406
407 cnss_set_pci_config_space(pci_priv,
408 SAVE_PCI_CONFIG_SPACE);
409 pci_disable_device(pci_dev);
410
411 ret = pci_set_power_state(pci_dev, PCI_D3hot);
412 if (ret)
413 cnss_pr_err("Failed to set D3Hot, err = %d\n",
414 ret);
415 }
416
417 cnss_pci_set_monitor_wake_intr(pci_priv, false);
418
419 return 0;
420
421out:
422 return ret;
423}
424
425static int cnss_pci_resume(struct device *dev)
426{
427 int ret = 0;
428 struct pci_dev *pci_dev = to_pci_dev(dev);
429 struct cnss_pci_data *pci_priv = cnss_get_pci_priv(pci_dev);
430 struct cnss_plat_data *plat_priv;
431 struct cnss_wlan_driver *driver_ops;
432
433 if (!pci_priv)
434 goto out;
435
436 plat_priv = pci_priv->plat_priv;
437 if (!plat_priv)
438 goto out;
439
440 if (pci_priv->pci_link_down_ind)
441 goto out;
442
443 ret = pci_enable_device(pci_dev);
444 if (ret)
445 cnss_pr_err("Failed to enable PCI device, err = %d\n", ret);
446
447 if (pci_priv->saved_state)
448 cnss_set_pci_config_space(pci_priv,
449 RESTORE_PCI_CONFIG_SPACE);
450
451 pci_set_master(pci_dev);
452 cnss_pci_set_mhi_state(pci_priv, CNSS_MHI_RESUME);
453
454 driver_ops = plat_priv->driver_ops;
455 if (driver_ops && driver_ops->resume) {
456 ret = driver_ops->resume(pci_dev);
457 if (ret)
458 cnss_pr_err("Failed to resume host driver, err = %d\n",
459 ret);
460 }
461
462 return 0;
463
464out:
465 return ret;
466}
467
468static int cnss_pci_suspend_noirq(struct device *dev)
469{
470 int ret = 0;
471 struct pci_dev *pci_dev = to_pci_dev(dev);
472 struct cnss_pci_data *pci_priv = cnss_get_pci_priv(pci_dev);
473 struct cnss_plat_data *plat_priv;
474 struct cnss_wlan_driver *driver_ops;
475
476 if (!pci_priv)
477 goto out;
478
479 plat_priv = pci_priv->plat_priv;
480 if (!plat_priv)
481 goto out;
482
483 driver_ops = plat_priv->driver_ops;
484 if (driver_ops && driver_ops->suspend_noirq)
485 ret = driver_ops->suspend_noirq(pci_dev);
486
487out:
488 return ret;
489}
490
491static int cnss_pci_resume_noirq(struct device *dev)
492{
493 int ret = 0;
494 struct pci_dev *pci_dev = to_pci_dev(dev);
495 struct cnss_pci_data *pci_priv = cnss_get_pci_priv(pci_dev);
496 struct cnss_plat_data *plat_priv;
497 struct cnss_wlan_driver *driver_ops;
498
499 if (!pci_priv)
500 goto out;
501
502 plat_priv = pci_priv->plat_priv;
503 if (!plat_priv)
504 goto out;
505
506 driver_ops = plat_priv->driver_ops;
507 if (driver_ops && driver_ops->resume_noirq &&
508 !pci_priv->pci_link_down_ind)
509 ret = driver_ops->resume_noirq(pci_dev);
510
511out:
512 return ret;
513}
514
515static int cnss_pci_runtime_suspend(struct device *dev)
516{
517 int ret = 0;
518 struct pci_dev *pci_dev = to_pci_dev(dev);
519 struct cnss_pci_data *pci_priv = cnss_get_pci_priv(pci_dev);
520 struct cnss_plat_data *plat_priv;
521 struct cnss_wlan_driver *driver_ops;
522
523 if (!pci_priv)
524 return -EAGAIN;
525
526 plat_priv = pci_priv->plat_priv;
527 if (!plat_priv)
528 return -EAGAIN;
529
530 if (pci_priv->pci_link_down_ind) {
531 cnss_pr_dbg("PCI link down recovery is in progress!\n");
532 return -EAGAIN;
533 }
534
535 cnss_pr_dbg("Runtime suspend start\n");
536
537 driver_ops = plat_priv->driver_ops;
538 if (driver_ops && driver_ops->runtime_ops &&
539 driver_ops->runtime_ops->runtime_suspend)
540 ret = driver_ops->runtime_ops->runtime_suspend(pci_dev);
541
542 cnss_pr_info("Runtime suspend status: %d\n", ret);
543
544 return ret;
545}
546
547static int cnss_pci_runtime_resume(struct device *dev)
548{
549 int ret = 0;
550 struct pci_dev *pci_dev = to_pci_dev(dev);
551 struct cnss_pci_data *pci_priv = cnss_get_pci_priv(pci_dev);
552 struct cnss_plat_data *plat_priv;
553 struct cnss_wlan_driver *driver_ops;
554
555 if (!pci_priv)
556 return -EAGAIN;
557
558 plat_priv = pci_priv->plat_priv;
559 if (!plat_priv)
560 return -EAGAIN;
561
562 if (pci_priv->pci_link_down_ind) {
563 cnss_pr_dbg("PCI link down recovery is in progress!\n");
564 return -EAGAIN;
565 }
566
567 cnss_pr_dbg("Runtime resume start\n");
568
569 driver_ops = plat_priv->driver_ops;
570 if (driver_ops && driver_ops->runtime_ops &&
571 driver_ops->runtime_ops->runtime_resume)
572 ret = driver_ops->runtime_ops->runtime_resume(pci_dev);
573
574 cnss_pr_info("Runtime resume status: %d\n", ret);
575
576 return ret;
577}
578
579static int cnss_pci_runtime_idle(struct device *dev)
580{
581 cnss_pr_dbg("Runtime idle\n");
582
583 pm_request_autosuspend(dev);
584
585 return -EBUSY;
586}
587
588int cnss_wlan_pm_control(struct device *dev, bool vote)
589{
590 struct cnss_plat_data *plat_priv = cnss_bus_dev_to_plat_priv(dev);
591 struct cnss_pci_data *pci_priv;
592 struct pci_dev *pci_dev;
593
594 if (!plat_priv)
595 return -ENODEV;
596
597 pci_priv = plat_priv->bus_priv;
598 if (!pci_priv)
599 return -ENODEV;
600
601 pci_dev = pci_priv->pci_dev;
602
603 return msm_pcie_pm_control(vote ? MSM_PCIE_DISABLE_PC :
604 MSM_PCIE_ENABLE_PC,
605 pci_dev->bus->number, pci_dev,
606 NULL, PM_OPTIONS_DEFAULT);
607}
608EXPORT_SYMBOL(cnss_wlan_pm_control);
609
610int cnss_auto_suspend(struct device *dev)
611{
612 int ret = 0;
613 struct cnss_plat_data *plat_priv = cnss_bus_dev_to_plat_priv(dev);
614 struct pci_dev *pci_dev;
615 struct cnss_pci_data *pci_priv;
616 struct cnss_bus_bw_info *bus_bw_info;
617
618 if (!plat_priv)
619 return -ENODEV;
620
621 pci_priv = plat_priv->bus_priv;
622 if (!pci_priv)
623 return -ENODEV;
624
625 pci_dev = pci_priv->pci_dev;
626
627 if (pci_priv->pci_link_state) {
628 if (cnss_pci_set_mhi_state(pci_priv, CNSS_MHI_SUSPEND)) {
629 ret = -EAGAIN;
630 goto out;
631 }
632
633 cnss_set_pci_config_space(pci_priv, SAVE_PCI_CONFIG_SPACE);
634 pci_disable_device(pci_dev);
635
636 ret = pci_set_power_state(pci_dev, PCI_D3hot);
637 if (ret)
638 cnss_pr_err("Failed to set D3Hot, err = %d\n", ret);
639
640 cnss_pr_dbg("Suspending PCI link\n");
641 if (cnss_set_pci_link(pci_priv, PCI_LINK_DOWN)) {
642 cnss_pr_err("Failed to suspend PCI link!\n");
643 ret = -EAGAIN;
644 goto resume_mhi;
645 }
646
647 pci_priv->pci_link_state = PCI_LINK_DOWN;
648 }
649
650 cnss_pci_set_auto_suspended(pci_priv, 1);
651 cnss_pci_set_monitor_wake_intr(pci_priv, true);
652
653 bus_bw_info = &plat_priv->bus_bw_info;
654 msm_bus_scale_client_update_request(bus_bw_info->bus_client,
655 CNSS_BUS_WIDTH_NONE);
656
657 return 0;
658
659resume_mhi:
660 if (pci_enable_device(pci_dev))
661 cnss_pr_err("Failed to enable PCI device!\n");
662 cnss_pci_set_mhi_state(pci_priv, CNSS_MHI_RESUME);
663out:
664 return ret;
665}
666EXPORT_SYMBOL(cnss_auto_suspend);
667
668int cnss_auto_resume(struct device *dev)
669{
670 int ret = 0;
671 struct cnss_plat_data *plat_priv = cnss_bus_dev_to_plat_priv(dev);
672 struct pci_dev *pci_dev;
673 struct cnss_pci_data *pci_priv;
674 struct cnss_bus_bw_info *bus_bw_info;
675
676 if (!plat_priv)
677 return -ENODEV;
678
679 pci_priv = plat_priv->bus_priv;
680 if (!pci_priv)
681 return -ENODEV;
682
683 pci_dev = pci_priv->pci_dev;
684 if (!pci_priv->pci_link_state) {
685 cnss_pr_dbg("Resuming PCI link\n");
686 if (cnss_set_pci_link(pci_priv, PCI_LINK_UP)) {
687 cnss_pr_err("Failed to resume PCI link!\n");
688 ret = -EAGAIN;
689 goto out;
690 }
691 pci_priv->pci_link_state = PCI_LINK_UP;
692
693 ret = pci_enable_device(pci_dev);
694 if (ret)
695 cnss_pr_err("Failed to enable PCI device, err = %d\n",
696 ret);
697
698 cnss_set_pci_config_space(pci_priv, RESTORE_PCI_CONFIG_SPACE);
699 pci_set_master(pci_dev);
700 cnss_pci_set_mhi_state(pci_priv, CNSS_MHI_RESUME);
701 }
702
703 cnss_pci_set_auto_suspended(pci_priv, 0);
704
705 bus_bw_info = &plat_priv->bus_bw_info;
706 msm_bus_scale_client_update_request(bus_bw_info->bus_client,
707 bus_bw_info->current_bw_vote);
708out:
709 return ret;
710}
711EXPORT_SYMBOL(cnss_auto_resume);
712
713int cnss_pm_request_resume(struct cnss_pci_data *pci_priv)
714{
715 struct pci_dev *pci_dev;
716
717 if (!pci_priv)
718 return -ENODEV;
719
720 pci_dev = pci_priv->pci_dev;
721 if (!pci_dev)
722 return -ENODEV;
723
724 return pm_request_resume(&pci_dev->dev);
725}
726
727int cnss_pci_alloc_fw_mem(struct cnss_pci_data *pci_priv)
728{
729 struct cnss_plat_data *plat_priv = pci_priv->plat_priv;
730 struct cnss_fw_mem *fw_mem = &plat_priv->fw_mem;
731
732 if (!fw_mem->va && fw_mem->size) {
733 fw_mem->va = dma_alloc_coherent(&pci_priv->pci_dev->dev,
734 fw_mem->size, &fw_mem->pa,
735 GFP_KERNEL);
736 if (!fw_mem->va) {
737 cnss_pr_err("Failed to allocate memory for FW, size: 0x%zx\n",
738 fw_mem->size);
739 fw_mem->size = 0;
740
741 return -ENOMEM;
742 }
743 }
744
745 return 0;
746}
747
748static void cnss_pci_free_fw_mem(struct cnss_pci_data *pci_priv)
749{
750 struct cnss_plat_data *plat_priv = pci_priv->plat_priv;
751 struct cnss_fw_mem *fw_mem = &plat_priv->fw_mem;
752
753 if (fw_mem->va && fw_mem->size) {
754 cnss_pr_dbg("Freeing memory for FW, va: 0x%pK, pa: %pa, size: 0x%zx\n",
755 fw_mem->va, &fw_mem->pa, fw_mem->size);
756 dma_free_coherent(&pci_priv->pci_dev->dev, fw_mem->size,
757 fw_mem->va, fw_mem->pa);
758 fw_mem->va = NULL;
759 fw_mem->pa = 0;
760 fw_mem->size = 0;
761 }
762}
763
764int cnss_pci_load_m3(struct cnss_pci_data *pci_priv)
765{
766 struct cnss_plat_data *plat_priv = pci_priv->plat_priv;
767 struct cnss_fw_mem *m3_mem = &plat_priv->m3_mem;
768 char filename[MAX_M3_FILE_NAME_LENGTH];
769 const struct firmware *fw_entry;
770 int ret = 0;
771
772 if (!m3_mem->va && !m3_mem->size) {
773 snprintf(filename, sizeof(filename), DEFAULT_M3_FILE_NAME);
774
775 ret = request_firmware(&fw_entry, filename,
776 &pci_priv->pci_dev->dev);
777 if (ret) {
778 cnss_pr_err("Failed to load M3 image: %s\n", filename);
779 return ret;
780 }
781
782 m3_mem->va = dma_alloc_coherent(&pci_priv->pci_dev->dev,
783 fw_entry->size, &m3_mem->pa,
784 GFP_KERNEL);
785 if (!m3_mem->va) {
786 cnss_pr_err("Failed to allocate memory for M3, size: 0x%zx\n",
787 fw_entry->size);
788 release_firmware(fw_entry);
789 return -ENOMEM;
790 }
791
792 memcpy(m3_mem->va, fw_entry->data, fw_entry->size);
793 m3_mem->size = fw_entry->size;
794 release_firmware(fw_entry);
795 }
796
797 return 0;
798}
799
800static void cnss_pci_free_m3_mem(struct cnss_pci_data *pci_priv)
801{
802 struct cnss_plat_data *plat_priv = pci_priv->plat_priv;
803 struct cnss_fw_mem *m3_mem = &plat_priv->m3_mem;
804
805 if (m3_mem->va && m3_mem->size) {
806 cnss_pr_dbg("Freeing memory for M3, va: 0x%pK, pa: %pa, size: 0x%zx\n",
807 m3_mem->va, &m3_mem->pa, m3_mem->size);
808 dma_free_coherent(&pci_priv->pci_dev->dev, m3_mem->size,
809 m3_mem->va, m3_mem->pa);
810 }
811
812 m3_mem->va = NULL;
813 m3_mem->pa = 0;
814 m3_mem->size = 0;
815}
816
817int cnss_pci_get_bar_info(struct cnss_pci_data *pci_priv, void __iomem **va,
818 phys_addr_t *pa)
819{
820 if (!pci_priv)
821 return -ENODEV;
822
823 *va = pci_priv->bar;
824 *pa = pci_resource_start(pci_priv->pci_dev, PCI_BAR_NUM);
825
826 return 0;
827}
828
829static struct cnss_msi_config msi_config = {
830 .total_vectors = 32,
831 .total_users = 4,
832 .users = (struct cnss_msi_user[]) {
833 { .name = "MHI", .num_vectors = 2, .base_vector = 0 },
834 { .name = "CE", .num_vectors = 11, .base_vector = 2 },
835 { .name = "WAKE", .num_vectors = 1, .base_vector = 13 },
836 { .name = "DP", .num_vectors = 18, .base_vector = 14 },
837 },
838};
839
840static int cnss_pci_get_msi_assignment(struct cnss_pci_data *pci_priv)
841{
842 pci_priv->msi_config = &msi_config;
843
844 return 0;
845}
846
847static int cnss_pci_enable_msi(struct cnss_pci_data *pci_priv)
848{
849 int ret = 0;
850 struct pci_dev *pci_dev = pci_priv->pci_dev;
851 int num_vectors;
852 struct cnss_msi_config *msi_config;
853 struct msi_desc *msi_desc;
854
855 ret = cnss_pci_get_msi_assignment(pci_priv);
856 if (ret) {
857 cnss_pr_err("Failed to get MSI assignment, err = %d\n", ret);
858 goto out;
859 }
860
861 msi_config = pci_priv->msi_config;
862 if (!msi_config) {
863 cnss_pr_err("msi_config is NULL!\n");
864 ret = -EINVAL;
865 goto out;
866 }
867
Yue Ma46c7d762018-03-21 16:11:49 -0700868 num_vectors = pci_alloc_irq_vectors(pci_dev,
869 msi_config->total_vectors,
870 msi_config->total_vectors,
871 PCI_IRQ_MSI);
Yue Ma0317e4a2018-01-10 11:48:32 -0800872 if (num_vectors != msi_config->total_vectors) {
873 cnss_pr_err("Failed to get enough MSI vectors (%d), available vectors = %d",
874 msi_config->total_vectors, num_vectors);
Yue Ma46c7d762018-03-21 16:11:49 -0700875 if (num_vectors >= 0)
876 ret = -EINVAL;
Yue Ma0317e4a2018-01-10 11:48:32 -0800877 goto reset_msi_config;
878 }
879
880 msi_desc = irq_get_msi_desc(pci_dev->irq);
881 if (!msi_desc) {
882 cnss_pr_err("msi_desc is NULL!\n");
883 ret = -EINVAL;
Yue Ma46c7d762018-03-21 16:11:49 -0700884 goto free_msi_vector;
Yue Ma0317e4a2018-01-10 11:48:32 -0800885 }
886
887 pci_priv->msi_ep_base_data = msi_desc->msg.data;
888 if (!pci_priv->msi_ep_base_data) {
889 cnss_pr_err("Got 0 MSI base data!\n");
890 CNSS_ASSERT(0);
891 }
892
893 cnss_pr_dbg("MSI base data is %d\n", pci_priv->msi_ep_base_data);
894
895 return 0;
896
Yue Ma46c7d762018-03-21 16:11:49 -0700897free_msi_vector:
898 pci_free_irq_vectors(pci_priv->pci_dev);
Yue Ma0317e4a2018-01-10 11:48:32 -0800899reset_msi_config:
900 pci_priv->msi_config = NULL;
901out:
902 return ret;
903}
904
905static void cnss_pci_disable_msi(struct cnss_pci_data *pci_priv)
906{
Yue Ma46c7d762018-03-21 16:11:49 -0700907 pci_free_irq_vectors(pci_priv->pci_dev);
Yue Ma0317e4a2018-01-10 11:48:32 -0800908}
909
910int cnss_get_user_msi_assignment(struct device *dev, char *user_name,
911 int *num_vectors, u32 *user_base_data,
912 u32 *base_vector)
913{
914 struct cnss_pci_data *pci_priv = dev_get_drvdata(dev);
915 struct cnss_msi_config *msi_config;
916 int idx;
917
918 if (!pci_priv)
919 return -ENODEV;
920
921 msi_config = pci_priv->msi_config;
922 if (!msi_config) {
923 cnss_pr_err("MSI is not supported.\n");
924 return -EINVAL;
925 }
926
927 for (idx = 0; idx < msi_config->total_users; idx++) {
928 if (strcmp(user_name, msi_config->users[idx].name) == 0) {
929 *num_vectors = msi_config->users[idx].num_vectors;
930 *user_base_data = msi_config->users[idx].base_vector
931 + pci_priv->msi_ep_base_data;
932 *base_vector = msi_config->users[idx].base_vector;
933
934 cnss_pr_dbg("Assign MSI to user: %s, num_vectors: %d, user_base_data: %u, base_vector: %u\n",
935 user_name, *num_vectors, *user_base_data,
936 *base_vector);
937
938 return 0;
939 }
940 }
941
942 cnss_pr_err("Failed to find MSI assignment for %s!\n", user_name);
943
944 return -EINVAL;
945}
946EXPORT_SYMBOL(cnss_get_user_msi_assignment);
947
948int cnss_get_msi_irq(struct device *dev, unsigned int vector)
949{
950 struct pci_dev *pci_dev = to_pci_dev(dev);
Yue Ma46c7d762018-03-21 16:11:49 -0700951 int irq_num;
Yue Ma0317e4a2018-01-10 11:48:32 -0800952
Yue Ma46c7d762018-03-21 16:11:49 -0700953 irq_num = pci_irq_vector(pci_dev, vector);
954 cnss_pr_dbg("Get IRQ number %d for vector index %d\n", irq_num, vector);
955
956 return irq_num;
Yue Ma0317e4a2018-01-10 11:48:32 -0800957}
958EXPORT_SYMBOL(cnss_get_msi_irq);
959
960void cnss_get_msi_address(struct device *dev, u32 *msi_addr_low,
961 u32 *msi_addr_high)
962{
963 struct pci_dev *pci_dev = to_pci_dev(dev);
964
965 pci_read_config_dword(pci_dev, pci_dev->msi_cap + PCI_MSI_ADDRESS_LO,
966 msi_addr_low);
967
968 pci_read_config_dword(pci_dev, pci_dev->msi_cap + PCI_MSI_ADDRESS_HI,
969 msi_addr_high);
970}
971EXPORT_SYMBOL(cnss_get_msi_address);
972
973static int cnss_pci_enable_bus(struct cnss_pci_data *pci_priv)
974{
975 int ret = 0;
976 struct pci_dev *pci_dev = pci_priv->pci_dev;
977 u16 device_id;
978
979 pci_read_config_word(pci_dev, PCI_DEVICE_ID, &device_id);
980 if (device_id != pci_priv->pci_device_id->device) {
981 cnss_pr_err("PCI device ID mismatch, config ID: 0x%x, probe ID: 0x%x\n",
982 device_id, pci_priv->pci_device_id->device);
983 ret = -EIO;
984 goto out;
985 }
986
987 ret = pci_assign_resource(pci_dev, PCI_BAR_NUM);
988 if (ret) {
989 pr_err("Failed to assign PCI resource, err = %d\n", ret);
990 goto out;
991 }
992
993 ret = pci_enable_device(pci_dev);
994 if (ret) {
995 cnss_pr_err("Failed to enable PCI device, err = %d\n", ret);
996 goto out;
997 }
998
999 ret = pci_request_region(pci_dev, PCI_BAR_NUM, "cnss");
1000 if (ret) {
1001 cnss_pr_err("Failed to request PCI region, err = %d\n", ret);
1002 goto disable_device;
1003 }
1004
1005 ret = pci_set_dma_mask(pci_dev, DMA_BIT_MASK(PCI_DMA_MASK));
1006 if (ret) {
1007 cnss_pr_err("Failed to set PCI DMA mask (%d), err = %d\n",
1008 ret, PCI_DMA_MASK);
1009 goto release_region;
1010 }
1011
1012 ret = pci_set_consistent_dma_mask(pci_dev, DMA_BIT_MASK(PCI_DMA_MASK));
1013 if (ret) {
1014 cnss_pr_err("Failed to set PCI consistent DMA mask (%d), err = %d\n",
1015 ret, PCI_DMA_MASK);
1016 goto release_region;
1017 }
1018
1019 pci_set_master(pci_dev);
1020
1021 pci_priv->bar = pci_iomap(pci_dev, PCI_BAR_NUM, 0);
1022 if (!pci_priv->bar) {
1023 cnss_pr_err("Failed to do PCI IO map!\n");
1024 ret = -EIO;
1025 goto clear_master;
1026 }
1027 return 0;
1028
1029clear_master:
1030 pci_clear_master(pci_dev);
1031release_region:
1032 pci_release_region(pci_dev, PCI_BAR_NUM);
1033disable_device:
1034 pci_disable_device(pci_dev);
1035out:
1036 return ret;
1037}
1038
1039static void cnss_pci_disable_bus(struct cnss_pci_data *pci_priv)
1040{
1041 struct pci_dev *pci_dev = pci_priv->pci_dev;
1042
1043 if (pci_priv->bar) {
1044 pci_iounmap(pci_dev, pci_priv->bar);
1045 pci_priv->bar = NULL;
1046 }
1047
1048 pci_clear_master(pci_dev);
1049 pci_release_region(pci_dev, PCI_BAR_NUM);
1050 pci_disable_device(pci_dev);
1051}
1052
1053static int cnss_mhi_pm_runtime_get(struct pci_dev *pci_dev)
1054{
1055 return pm_runtime_get(&pci_dev->dev);
1056}
1057
1058static void cnss_mhi_pm_runtime_put_noidle(struct pci_dev *pci_dev)
1059{
1060 pm_runtime_put_noidle(&pci_dev->dev);
1061}
1062
1063static char *cnss_mhi_state_to_str(enum cnss_mhi_state mhi_state)
1064{
1065 switch (mhi_state) {
1066 case CNSS_MHI_INIT:
1067 return "INIT";
1068 case CNSS_MHI_DEINIT:
1069 return "DEINIT";
1070 case CNSS_MHI_POWER_ON:
1071 return "POWER_ON";
1072 case CNSS_MHI_POWER_OFF:
1073 return "POWER_OFF";
1074 case CNSS_MHI_SUSPEND:
1075 return "SUSPEND";
1076 case CNSS_MHI_RESUME:
1077 return "RESUME";
1078 case CNSS_MHI_TRIGGER_RDDM:
1079 return "TRIGGER_RDDM";
1080 case CNSS_MHI_RDDM:
1081 return "RDDM";
1082 case CNSS_MHI_RDDM_KERNEL_PANIC:
1083 return "RDDM_KERNEL_PANIC";
1084 case CNSS_MHI_NOTIFY_LINK_ERROR:
1085 return "NOTIFY_LINK_ERROR";
1086 default:
1087 return "UNKNOWN";
1088 }
1089};
1090
1091static void *cnss_pci_collect_dump_seg(struct cnss_pci_data *pci_priv,
1092 enum mhi_rddm_segment type,
1093 void *start_addr)
1094{
1095 int count;
1096 struct scatterlist *sg_list, *s;
1097 unsigned int i;
1098 struct cnss_plat_data *plat_priv = pci_priv->plat_priv;
1099 struct cnss_dump_data *dump_data =
1100 &plat_priv->ramdump_info_v2.dump_data;
1101 struct cnss_dump_seg *dump_seg = start_addr;
1102
1103 count = mhi_xfer_rddm(&pci_priv->mhi_dev, type, &sg_list);
1104 if (count <= 0 || !sg_list) {
1105 cnss_pr_err("Invalid dump_seg for type %u, count %u, sg_list %pK\n",
1106 type, count, sg_list);
1107 return start_addr;
1108 }
1109
1110 cnss_pr_dbg("Collect dump seg: type %u, nentries %d\n", type, count);
1111
1112 for_each_sg(sg_list, s, count, i) {
1113 dump_seg->address = sg_dma_address(s);
1114 dump_seg->v_address = sg_virt(s);
1115 dump_seg->size = s->length;
1116 dump_seg->type = type;
1117 cnss_pr_dbg("seg-%d: address 0x%lx, v_address %pK, size 0x%lx\n",
1118 i, dump_seg->address,
1119 dump_seg->v_address, dump_seg->size);
1120 dump_seg++;
1121 }
1122
1123 dump_data->nentries += count;
1124
1125 return dump_seg;
1126}
1127
1128void cnss_pci_collect_dump_info(struct cnss_pci_data *pci_priv)
1129{
1130 struct cnss_plat_data *plat_priv = pci_priv->plat_priv;
1131 struct cnss_dump_data *dump_data =
1132 &plat_priv->ramdump_info_v2.dump_data;
1133 void *start_addr, *end_addr;
1134
1135 dump_data->nentries = 0;
1136
1137 start_addr = plat_priv->ramdump_info_v2.dump_data_vaddr;
1138 end_addr = cnss_pci_collect_dump_seg(pci_priv,
1139 MHI_RDDM_FW_SEGMENT, start_addr);
1140
1141 start_addr = end_addr;
1142 end_addr = cnss_pci_collect_dump_seg(pci_priv,
1143 MHI_RDDM_RD_SEGMENT, start_addr);
1144
1145 if (dump_data->nentries > 0)
1146 plat_priv->ramdump_info_v2.dump_data_valid = true;
1147}
1148
1149void cnss_pci_clear_dump_info(struct cnss_pci_data *pci_priv)
1150{
1151 struct cnss_plat_data *plat_priv = pci_priv->plat_priv;
1152
1153 plat_priv->ramdump_info_v2.dump_data.nentries = 0;
1154 plat_priv->ramdump_info_v2.dump_data_valid = false;
1155}
1156
1157static void cnss_mhi_notify_status(enum MHI_CB_REASON reason, void *priv)
1158{
1159 struct cnss_pci_data *pci_priv = priv;
1160 struct cnss_plat_data *plat_priv = pci_priv->plat_priv;
1161 enum cnss_recovery_reason cnss_reason = CNSS_REASON_RDDM;
1162
1163 if (!pci_priv)
1164 return;
1165
1166 cnss_pr_dbg("MHI status cb is called with reason %d\n", reason);
1167
1168 set_bit(CNSS_DEV_ERR_NOTIFY, &plat_priv->driver_state);
1169 del_timer(&plat_priv->fw_boot_timer);
1170
1171 if (reason == MHI_CB_SYS_ERROR)
1172 cnss_reason = CNSS_REASON_TIMEOUT;
1173
1174 cnss_schedule_recovery(&pci_priv->pci_dev->dev,
1175 cnss_reason);
1176}
1177
1178static int cnss_pci_register_mhi(struct cnss_pci_data *pci_priv)
1179{
1180 int ret = 0;
1181 struct pci_dev *pci_dev = pci_priv->pci_dev;
1182 struct mhi_device *mhi_dev = &pci_priv->mhi_dev;
1183
1184 mhi_dev->dev = &pci_priv->plat_priv->plat_dev->dev;
1185 mhi_dev->pci_dev = pci_dev;
1186
1187 mhi_dev->resources[0].start = (resource_size_t)pci_priv->bar;
1188 mhi_dev->resources[0].end = (resource_size_t)pci_priv->bar +
1189 pci_resource_len(pci_dev, PCI_BAR_NUM);
1190 mhi_dev->resources[0].flags =
1191 pci_resource_flags(pci_dev, PCI_BAR_NUM);
1192 mhi_dev->resources[0].name = "BAR";
1193 cnss_pr_dbg("BAR start is %pa, BAR end is %pa\n",
1194 &mhi_dev->resources[0].start, &mhi_dev->resources[0].end);
1195
1196 if (!mhi_dev->resources[1].start) {
1197 mhi_dev->resources[1].start = pci_dev->irq;
1198 mhi_dev->resources[1].end = pci_dev->irq + 1;
1199 mhi_dev->resources[1].flags = IORESOURCE_IRQ;
1200 mhi_dev->resources[1].name = "IRQ";
1201 }
1202 cnss_pr_dbg("IRQ start is %pa, IRQ end is %pa\n",
1203 &mhi_dev->resources[1].start, &mhi_dev->resources[1].end);
1204
1205 mhi_dev->pm_runtime_get = cnss_mhi_pm_runtime_get;
1206 mhi_dev->pm_runtime_put_noidle = cnss_mhi_pm_runtime_put_noidle;
1207
1208 mhi_dev->support_rddm = true;
1209 mhi_dev->rddm_size = pci_priv->plat_priv->ramdump_info_v2.ramdump_size;
1210 mhi_dev->status_cb = cnss_mhi_notify_status;
1211
1212 ret = mhi_register_device(mhi_dev, MHI_NODE_NAME, pci_priv);
1213 if (ret) {
1214 cnss_pr_err("Failed to register as MHI device, err = %d\n",
1215 ret);
1216 return ret;
1217 }
1218
1219 return 0;
1220}
1221
1222static void cnss_pci_unregister_mhi(struct cnss_pci_data *pci_priv)
1223{
1224}
1225
1226static enum mhi_dev_ctrl cnss_to_mhi_dev_state(enum cnss_mhi_state state)
1227{
1228 switch (state) {
1229 case CNSS_MHI_INIT:
1230 return MHI_DEV_CTRL_INIT;
1231 case CNSS_MHI_DEINIT:
1232 return MHI_DEV_CTRL_DE_INIT;
1233 case CNSS_MHI_POWER_ON:
1234 return MHI_DEV_CTRL_POWER_ON;
1235 case CNSS_MHI_POWER_OFF:
1236 return MHI_DEV_CTRL_POWER_OFF;
1237 case CNSS_MHI_SUSPEND:
1238 return MHI_DEV_CTRL_SUSPEND;
1239 case CNSS_MHI_RESUME:
1240 return MHI_DEV_CTRL_RESUME;
1241 case CNSS_MHI_TRIGGER_RDDM:
1242 return MHI_DEV_CTRL_TRIGGER_RDDM;
1243 case CNSS_MHI_RDDM:
1244 return MHI_DEV_CTRL_RDDM;
1245 case CNSS_MHI_RDDM_KERNEL_PANIC:
1246 return MHI_DEV_CTRL_RDDM_KERNEL_PANIC;
1247 case CNSS_MHI_NOTIFY_LINK_ERROR:
1248 return MHI_DEV_CTRL_NOTIFY_LINK_ERROR;
1249 default:
1250 cnss_pr_err("Unknown CNSS MHI state (%d)\n", state);
1251 return -EINVAL;
1252 }
1253}
1254
1255static int cnss_pci_check_mhi_state_bit(struct cnss_pci_data *pci_priv,
1256 enum cnss_mhi_state mhi_state)
1257{
1258 switch (mhi_state) {
1259 case CNSS_MHI_INIT:
1260 if (!test_bit(CNSS_MHI_INIT, &pci_priv->mhi_state))
1261 return 0;
1262 break;
1263 case CNSS_MHI_DEINIT:
1264 case CNSS_MHI_POWER_ON:
1265 if (test_bit(CNSS_MHI_INIT, &pci_priv->mhi_state) &&
1266 !test_bit(CNSS_MHI_POWER_ON, &pci_priv->mhi_state))
1267 return 0;
1268 break;
1269 case CNSS_MHI_POWER_OFF:
1270 case CNSS_MHI_SUSPEND:
1271 if (test_bit(CNSS_MHI_POWER_ON, &pci_priv->mhi_state) &&
1272 !test_bit(CNSS_MHI_SUSPEND, &pci_priv->mhi_state))
1273 return 0;
1274 break;
1275 case CNSS_MHI_RESUME:
1276 if (test_bit(CNSS_MHI_SUSPEND, &pci_priv->mhi_state))
1277 return 0;
1278 break;
1279 case CNSS_MHI_TRIGGER_RDDM:
1280 case CNSS_MHI_RDDM:
1281 case CNSS_MHI_RDDM_KERNEL_PANIC:
1282 case CNSS_MHI_NOTIFY_LINK_ERROR:
1283 return 0;
1284 default:
1285 cnss_pr_err("Unhandled MHI state: %s(%d)\n",
1286 cnss_mhi_state_to_str(mhi_state), mhi_state);
1287 }
1288
1289 cnss_pr_err("Cannot set MHI state %s(%d) in current MHI state (0x%lx)\n",
1290 cnss_mhi_state_to_str(mhi_state), mhi_state,
1291 pci_priv->mhi_state);
1292
1293 return -EINVAL;
1294}
1295
1296static void cnss_pci_set_mhi_state_bit(struct cnss_pci_data *pci_priv,
1297 enum cnss_mhi_state mhi_state)
1298{
1299 switch (mhi_state) {
1300 case CNSS_MHI_INIT:
1301 set_bit(CNSS_MHI_INIT, &pci_priv->mhi_state);
1302 break;
1303 case CNSS_MHI_DEINIT:
1304 clear_bit(CNSS_MHI_INIT, &pci_priv->mhi_state);
1305 break;
1306 case CNSS_MHI_POWER_ON:
1307 set_bit(CNSS_MHI_POWER_ON, &pci_priv->mhi_state);
1308 break;
1309 case CNSS_MHI_POWER_OFF:
1310 clear_bit(CNSS_MHI_POWER_ON, &pci_priv->mhi_state);
1311 break;
1312 case CNSS_MHI_SUSPEND:
1313 set_bit(CNSS_MHI_SUSPEND, &pci_priv->mhi_state);
1314 break;
1315 case CNSS_MHI_RESUME:
1316 clear_bit(CNSS_MHI_SUSPEND, &pci_priv->mhi_state);
1317 break;
1318 case CNSS_MHI_TRIGGER_RDDM:
1319 case CNSS_MHI_RDDM:
1320 case CNSS_MHI_RDDM_KERNEL_PANIC:
1321 case CNSS_MHI_NOTIFY_LINK_ERROR:
1322 break;
1323 default:
1324 cnss_pr_err("Unhandled MHI state (%d)\n", mhi_state);
1325 }
1326}
1327
1328int cnss_pci_set_mhi_state(struct cnss_pci_data *pci_priv,
1329 enum cnss_mhi_state mhi_state)
1330{
1331 int ret = 0;
1332 enum mhi_dev_ctrl mhi_dev_state = cnss_to_mhi_dev_state(mhi_state);
1333
1334 if (!pci_priv) {
1335 cnss_pr_err("pci_priv is NULL!\n");
1336 return -ENODEV;
1337 }
1338
1339 if (pci_priv->device_id == QCA6174_DEVICE_ID)
1340 return 0;
1341
1342 if (mhi_dev_state < 0) {
1343 cnss_pr_err("Invalid MHI DEV state (%d)\n", mhi_dev_state);
1344 return -EINVAL;
1345 }
1346
1347 ret = cnss_pci_check_mhi_state_bit(pci_priv, mhi_state);
1348 if (ret)
1349 goto out;
1350
1351 cnss_pr_dbg("Setting MHI state: %s(%d)\n",
1352 cnss_mhi_state_to_str(mhi_state), mhi_state);
1353 ret = mhi_pm_control_device(&pci_priv->mhi_dev, mhi_dev_state);
1354 if (ret) {
1355 cnss_pr_err("Failed to set MHI state: %s(%d)\n",
1356 cnss_mhi_state_to_str(mhi_state), mhi_state);
1357 goto out;
1358 }
1359
1360 cnss_pci_set_mhi_state_bit(pci_priv, mhi_state);
1361
1362out:
1363 return ret;
1364}
1365
1366int cnss_pci_start_mhi(struct cnss_pci_data *pci_priv)
1367{
1368 int ret = 0;
1369
1370 if (!pci_priv) {
1371 cnss_pr_err("pci_priv is NULL!\n");
1372 return -ENODEV;
1373 }
1374
1375 if (fbc_bypass)
1376 return 0;
1377
1378 ret = cnss_pci_set_mhi_state(pci_priv, CNSS_MHI_INIT);
1379 if (ret)
1380 goto out;
1381
1382 ret = cnss_pci_set_mhi_state(pci_priv, CNSS_MHI_POWER_ON);
1383 if (ret)
1384 goto out;
1385
1386 return 0;
1387
1388out:
1389 return ret;
1390}
1391
1392void cnss_pci_stop_mhi(struct cnss_pci_data *pci_priv)
1393{
1394 struct cnss_plat_data *plat_priv;
1395
1396 if (!pci_priv) {
1397 cnss_pr_err("pci_priv is NULL!\n");
1398 return;
1399 }
1400
1401 if (fbc_bypass)
1402 return;
1403
1404 plat_priv = pci_priv->plat_priv;
1405
1406 cnss_pci_set_mhi_state_bit(pci_priv, CNSS_MHI_RESUME);
1407 cnss_pci_set_mhi_state(pci_priv, CNSS_MHI_POWER_OFF);
1408
1409 if (plat_priv->ramdump_info_v2.dump_data_valid ||
1410 test_bit(CNSS_DRIVER_RECOVERY, &plat_priv->driver_state))
1411 return;
1412
1413 cnss_pci_set_mhi_state(pci_priv, CNSS_MHI_DEINIT);
1414}
1415
1416static int cnss_pci_probe(struct pci_dev *pci_dev,
1417 const struct pci_device_id *id)
1418{
1419 int ret = 0;
1420 struct cnss_pci_data *pci_priv;
1421 struct cnss_plat_data *plat_priv = cnss_bus_dev_to_plat_priv(NULL);
1422 struct resource *res;
1423
1424 cnss_pr_dbg("PCI is probing, vendor ID: 0x%x, device ID: 0x%x\n",
1425 id->vendor, pci_dev->device);
1426
1427 switch (pci_dev->device) {
1428 case QCA6290_EMULATION_DEVICE_ID:
1429 case QCA6290_DEVICE_ID:
1430 if (!mhi_is_device_ready(&plat_priv->plat_dev->dev,
1431 MHI_NODE_NAME)) {
1432 cnss_pr_err("MHI driver is not ready, defer PCI probe!\n");
1433 ret = -EPROBE_DEFER;
1434 goto out;
1435 }
1436 break;
1437 default:
1438 break;
1439 }
1440
1441 pci_priv = devm_kzalloc(&pci_dev->dev, sizeof(*pci_priv),
1442 GFP_KERNEL);
1443 if (!pci_priv) {
1444 ret = -ENOMEM;
1445 goto out;
1446 }
1447
1448 pci_priv->pci_link_state = PCI_LINK_UP;
1449 pci_priv->plat_priv = plat_priv;
1450 pci_priv->pci_dev = pci_dev;
1451 pci_priv->pci_device_id = id;
1452 pci_priv->device_id = pci_dev->device;
1453 cnss_set_pci_priv(pci_dev, pci_priv);
1454 plat_priv->device_id = pci_dev->device;
1455 plat_priv->bus_priv = pci_priv;
1456
1457 ret = cnss_register_subsys(plat_priv);
1458 if (ret)
1459 goto reset_ctx;
1460
1461 ret = cnss_register_ramdump(plat_priv);
1462 if (ret)
1463 goto unregister_subsys;
1464
1465 res = platform_get_resource_byname(plat_priv->plat_dev, IORESOURCE_MEM,
1466 "smmu_iova_base");
1467 if (res) {
Yue Ma4dac45d2018-02-23 11:49:25 -08001468 if (of_property_read_bool(plat_priv->plat_dev->dev.of_node,
1469 "qcom,smmu-s1-enable"))
1470 pci_priv->smmu_s1_enable = true;
1471
Yue Ma0317e4a2018-01-10 11:48:32 -08001472 pci_priv->smmu_iova_start = res->start;
1473 pci_priv->smmu_iova_len = resource_size(res);
1474 cnss_pr_dbg("smmu_iova_start: %pa, smmu_iova_len: %zu\n",
1475 &pci_priv->smmu_iova_start,
1476 pci_priv->smmu_iova_len);
1477
1478 ret = cnss_pci_init_smmu(pci_priv);
1479 if (ret) {
1480 cnss_pr_err("Failed to init SMMU, err = %d\n", ret);
1481 goto unregister_ramdump;
1482 }
1483 }
1484
1485 ret = cnss_reg_pci_event(pci_priv);
1486 if (ret) {
1487 cnss_pr_err("Failed to register PCI event, err = %d\n", ret);
1488 goto deinit_smmu;
1489 }
1490
1491 ret = cnss_pci_enable_bus(pci_priv);
1492 if (ret)
1493 goto dereg_pci_event;
1494
1495 pci_save_state(pci_dev);
1496 pci_priv->default_state = pci_store_saved_state(pci_dev);
1497
1498 switch (pci_dev->device) {
1499 case QCA6174_DEVICE_ID:
1500 pci_read_config_word(pci_dev, QCA6174_REV_ID_OFFSET,
1501 &pci_priv->revision_id);
1502 ret = cnss_suspend_pci_link(pci_priv);
1503 if (ret)
1504 cnss_pr_err("Failed to suspend PCI link, err = %d\n",
1505 ret);
1506 cnss_power_off_device(plat_priv);
1507 break;
1508 case QCA6290_EMULATION_DEVICE_ID:
1509 case QCA6290_DEVICE_ID:
1510 ret = cnss_pci_enable_msi(pci_priv);
1511 if (ret)
1512 goto disable_bus;
1513 ret = cnss_pci_register_mhi(pci_priv);
1514 if (ret) {
1515 cnss_pci_disable_msi(pci_priv);
1516 goto disable_bus;
1517 }
1518 ret = cnss_suspend_pci_link(pci_priv);
1519 if (ret)
1520 cnss_pr_err("Failed to suspend PCI link, err = %d\n",
1521 ret);
1522 cnss_power_off_device(plat_priv);
1523 break;
1524 default:
1525 cnss_pr_err("Unknown PCI device found: 0x%x\n",
1526 pci_dev->device);
1527 ret = -ENODEV;
1528 goto disable_bus;
1529 }
1530
1531 return 0;
1532
1533disable_bus:
1534 cnss_pci_disable_bus(pci_priv);
1535dereg_pci_event:
1536 cnss_dereg_pci_event(pci_priv);
1537deinit_smmu:
1538 if (pci_priv->smmu_mapping)
1539 cnss_pci_deinit_smmu(pci_priv);
1540unregister_ramdump:
1541 cnss_unregister_ramdump(plat_priv);
1542unregister_subsys:
1543 cnss_unregister_subsys(plat_priv);
1544reset_ctx:
1545 plat_priv->bus_priv = NULL;
1546out:
1547 return ret;
1548}
1549
1550static void cnss_pci_remove(struct pci_dev *pci_dev)
1551{
1552 struct cnss_pci_data *pci_priv = cnss_get_pci_priv(pci_dev);
1553 struct cnss_plat_data *plat_priv =
1554 cnss_bus_dev_to_plat_priv(&pci_dev->dev);
1555
1556 cnss_pci_free_m3_mem(pci_priv);
1557 cnss_pci_free_fw_mem(pci_priv);
1558
1559 switch (pci_dev->device) {
1560 case QCA6290_EMULATION_DEVICE_ID:
1561 case QCA6290_DEVICE_ID:
1562 cnss_pci_unregister_mhi(pci_priv);
1563 cnss_pci_disable_msi(pci_priv);
1564 break;
1565 default:
1566 break;
1567 }
1568
1569 pci_load_and_free_saved_state(pci_dev, &pci_priv->saved_state);
1570
1571 cnss_pci_disable_bus(pci_priv);
1572 cnss_dereg_pci_event(pci_priv);
1573 if (pci_priv->smmu_mapping)
1574 cnss_pci_deinit_smmu(pci_priv);
1575 cnss_unregister_ramdump(plat_priv);
1576 cnss_unregister_subsys(plat_priv);
1577 plat_priv->bus_priv = NULL;
1578}
1579
1580static const struct pci_device_id cnss_pci_id_table[] = {
1581 { QCA6174_VENDOR_ID, QCA6174_DEVICE_ID, PCI_ANY_ID, PCI_ANY_ID },
1582 { QCA6290_EMULATION_VENDOR_ID, QCA6290_EMULATION_DEVICE_ID,
1583 PCI_ANY_ID, PCI_ANY_ID },
1584 { QCA6290_VENDOR_ID, QCA6290_DEVICE_ID, PCI_ANY_ID, PCI_ANY_ID },
1585 { 0 }
1586};
1587MODULE_DEVICE_TABLE(pci, cnss_pci_id_table);
1588
1589static const struct dev_pm_ops cnss_pm_ops = {
1590 SET_SYSTEM_SLEEP_PM_OPS(cnss_pci_suspend, cnss_pci_resume)
1591 SET_NOIRQ_SYSTEM_SLEEP_PM_OPS(cnss_pci_suspend_noirq,
1592 cnss_pci_resume_noirq)
1593 SET_RUNTIME_PM_OPS(cnss_pci_runtime_suspend, cnss_pci_runtime_resume,
1594 cnss_pci_runtime_idle)
1595};
1596
1597struct pci_driver cnss_pci_driver = {
1598 .name = "cnss_pci",
1599 .id_table = cnss_pci_id_table,
1600 .probe = cnss_pci_probe,
1601 .remove = cnss_pci_remove,
1602 .driver = {
1603 .pm = &cnss_pm_ops,
1604 },
1605};
1606
1607int cnss_pci_init(struct cnss_plat_data *plat_priv)
1608{
1609 int ret = 0;
1610 struct device *dev = &plat_priv->plat_dev->dev;
1611 u32 rc_num;
1612
1613 ret = of_property_read_u32(dev->of_node, "qcom,wlan-rc-num", &rc_num);
1614 if (ret) {
1615 cnss_pr_err("Failed to find PCIe RC number, err = %d\n", ret);
1616 goto out;
1617 }
1618
1619 ret = msm_pcie_enumerate(rc_num);
1620 if (ret) {
1621 cnss_pr_err("Failed to enable PCIe RC%x, err = %d\n",
1622 rc_num, ret);
1623 goto out;
1624 }
1625
1626 ret = pci_register_driver(&cnss_pci_driver);
1627 if (ret) {
1628 cnss_pr_err("Failed to register to PCI framework, err = %d\n",
1629 ret);
1630 goto out;
1631 }
1632
1633 return 0;
1634out:
1635 return ret;
1636}
1637
1638void cnss_pci_deinit(struct cnss_plat_data *plat_priv)
1639{
1640 pci_unregister_driver(&cnss_pci_driver);
1641}