1 // SPDX-License-Identifier: GPL-2.0-only
2
3 /* Copyright (c) 2019-2021, The Linux Foundation. All rights reserved. */
4 /* Copyright (c) 2021-2023 Qualcomm Innovation Center, Inc. All rights reserved. */
5
6 #include <linux/delay.h>
7 #include <linux/err.h>
8 #include <linux/memblock.h>
9 #include <linux/mhi.h>
10 #include <linux/moduleparam.h>
11 #include <linux/pci.h>
12 #include <linux/sizes.h>
13
14 #include "mhi_controller.h"
15 #include "qaic.h"
16
17 #define MAX_RESET_TIME_SEC 25
18
19 static unsigned int mhi_timeout_ms = 2000; /* 2 sec default */
20 module_param(mhi_timeout_ms, uint, 0600);
21 MODULE_PARM_DESC(mhi_timeout_ms, "MHI controller timeout value");
22
23 static const char *fw_image_paths[FAMILY_MAX] = {
24 [FAMILY_AIC100] = "qcom/aic100/sbl.bin",
25 [FAMILY_AIC200] = "qcom/aic200/sbl.bin",
26 };
27
28 static const struct mhi_channel_config aic100_channels[] = {
29 {
30 .name = "QAIC_LOOPBACK",
31 .num = 0,
32 .num_elements = 32,
33 .local_elements = 0,
34 .event_ring = 0,
35 .dir = DMA_TO_DEVICE,
36 .ee_mask = MHI_CH_EE_AMSS,
37 .pollcfg = 0,
38 .doorbell = MHI_DB_BRST_DISABLE,
39 .lpm_notify = false,
40 .offload_channel = false,
41 .doorbell_mode_switch = false,
42 .auto_queue = false,
43 .wake_capable = false,
44 },
45 {
46 .name = "QAIC_LOOPBACK",
47 .num = 1,
48 .num_elements = 32,
49 .local_elements = 0,
50 .event_ring = 0,
51 .dir = DMA_FROM_DEVICE,
52 .ee_mask = MHI_CH_EE_AMSS,
53 .pollcfg = 0,
54 .doorbell = MHI_DB_BRST_DISABLE,
55 .lpm_notify = false,
56 .offload_channel = false,
57 .doorbell_mode_switch = false,
58 .auto_queue = false,
59 .wake_capable = false,
60 },
61 {
62 .name = "QAIC_SAHARA",
63 .num = 2,
64 .num_elements = 32,
65 .local_elements = 0,
66 .event_ring = 0,
67 .dir = DMA_TO_DEVICE,
68 .ee_mask = MHI_CH_EE_SBL,
69 .pollcfg = 0,
70 .doorbell = MHI_DB_BRST_DISABLE,
71 .lpm_notify = false,
72 .offload_channel = false,
73 .doorbell_mode_switch = false,
74 .auto_queue = false,
75 .wake_capable = false,
76 },
77 {
78 .name = "QAIC_SAHARA",
79 .num = 3,
80 .num_elements = 32,
81 .local_elements = 0,
82 .event_ring = 0,
83 .dir = DMA_FROM_DEVICE,
84 .ee_mask = MHI_CH_EE_SBL,
85 .pollcfg = 0,
86 .doorbell = MHI_DB_BRST_DISABLE,
87 .lpm_notify = false,
88 .offload_channel = false,
89 .doorbell_mode_switch = false,
90 .auto_queue = false,
91 .wake_capable = false,
92 },
93 {
94 .name = "QAIC_DIAG",
95 .num = 4,
96 .num_elements = 32,
97 .local_elements = 0,
98 .event_ring = 0,
99 .dir = DMA_TO_DEVICE,
100 .ee_mask = MHI_CH_EE_AMSS,
101 .pollcfg = 0,
102 .doorbell = MHI_DB_BRST_DISABLE,
103 .lpm_notify = false,
104 .offload_channel = false,
105 .doorbell_mode_switch = false,
106 .auto_queue = false,
107 .wake_capable = false,
108 },
109 {
110 .name = "QAIC_DIAG",
111 .num = 5,
112 .num_elements = 32,
113 .local_elements = 0,
114 .event_ring = 0,
115 .dir = DMA_FROM_DEVICE,
116 .ee_mask = MHI_CH_EE_AMSS,
117 .pollcfg = 0,
118 .doorbell = MHI_DB_BRST_DISABLE,
119 .lpm_notify = false,
120 .offload_channel = false,
121 .doorbell_mode_switch = false,
122 .auto_queue = false,
123 .wake_capable = false,
124 },
125 {
126 .name = "QAIC_SSR",
127 .num = 6,
128 .num_elements = 32,
129 .local_elements = 0,
130 .event_ring = 0,
131 .dir = DMA_TO_DEVICE,
132 .ee_mask = MHI_CH_EE_AMSS,
133 .pollcfg = 0,
134 .doorbell = MHI_DB_BRST_DISABLE,
135 .lpm_notify = false,
136 .offload_channel = false,
137 .doorbell_mode_switch = false,
138 .auto_queue = false,
139 .wake_capable = false,
140 },
141 {
142 .name = "QAIC_SSR",
143 .num = 7,
144 .num_elements = 32,
145 .local_elements = 0,
146 .event_ring = 0,
147 .dir = DMA_FROM_DEVICE,
148 .ee_mask = MHI_CH_EE_AMSS,
149 .pollcfg = 0,
150 .doorbell = MHI_DB_BRST_DISABLE,
151 .lpm_notify = false,
152 .offload_channel = false,
153 .doorbell_mode_switch = false,
154 .auto_queue = false,
155 .wake_capable = false,
156 },
157 {
158 .name = "QAIC_QDSS",
159 .num = 8,
160 .num_elements = 32,
161 .local_elements = 0,
162 .event_ring = 0,
163 .dir = DMA_TO_DEVICE,
164 .ee_mask = MHI_CH_EE_AMSS,
165 .pollcfg = 0,
166 .doorbell = MHI_DB_BRST_DISABLE,
167 .lpm_notify = false,
168 .offload_channel = false,
169 .doorbell_mode_switch = false,
170 .auto_queue = false,
171 .wake_capable = false,
172 },
173 {
174 .name = "QAIC_QDSS",
175 .num = 9,
176 .num_elements = 32,
177 .local_elements = 0,
178 .event_ring = 0,
179 .dir = DMA_FROM_DEVICE,
180 .ee_mask = MHI_CH_EE_AMSS,
181 .pollcfg = 0,
182 .doorbell = MHI_DB_BRST_DISABLE,
183 .lpm_notify = false,
184 .offload_channel = false,
185 .doorbell_mode_switch = false,
186 .auto_queue = false,
187 .wake_capable = false,
188 },
189 {
190 .name = "QAIC_CONTROL",
191 .num = 10,
192 .num_elements = 128,
193 .local_elements = 0,
194 .event_ring = 0,
195 .dir = DMA_TO_DEVICE,
196 .ee_mask = MHI_CH_EE_AMSS,
197 .pollcfg = 0,
198 .doorbell = MHI_DB_BRST_DISABLE,
199 .lpm_notify = false,
200 .offload_channel = false,
201 .doorbell_mode_switch = false,
202 .auto_queue = false,
203 .wake_capable = false,
204 },
205 {
206 .name = "QAIC_CONTROL",
207 .num = 11,
208 .num_elements = 128,
209 .local_elements = 0,
210 .event_ring = 0,
211 .dir = DMA_FROM_DEVICE,
212 .ee_mask = MHI_CH_EE_AMSS,
213 .pollcfg = 0,
214 .doorbell = MHI_DB_BRST_DISABLE,
215 .lpm_notify = false,
216 .offload_channel = false,
217 .doorbell_mode_switch = false,
218 .auto_queue = false,
219 .wake_capable = false,
220 },
221 {
222 .name = "QAIC_LOGGING",
223 .num = 12,
224 .num_elements = 32,
225 .local_elements = 0,
226 .event_ring = 0,
227 .dir = DMA_TO_DEVICE,
228 .ee_mask = MHI_CH_EE_SBL,
229 .pollcfg = 0,
230 .doorbell = MHI_DB_BRST_DISABLE,
231 .lpm_notify = false,
232 .offload_channel = false,
233 .doorbell_mode_switch = false,
234 .auto_queue = false,
235 .wake_capable = false,
236 },
237 {
238 .name = "QAIC_LOGGING",
239 .num = 13,
240 .num_elements = 32,
241 .local_elements = 0,
242 .event_ring = 0,
243 .dir = DMA_FROM_DEVICE,
244 .ee_mask = MHI_CH_EE_SBL,
245 .pollcfg = 0,
246 .doorbell = MHI_DB_BRST_DISABLE,
247 .lpm_notify = false,
248 .offload_channel = false,
249 .doorbell_mode_switch = false,
250 .auto_queue = false,
251 .wake_capable = false,
252 },
253 {
254 .name = "QAIC_STATUS",
255 .num = 14,
256 .num_elements = 32,
257 .local_elements = 0,
258 .event_ring = 0,
259 .dir = DMA_TO_DEVICE,
260 .ee_mask = MHI_CH_EE_AMSS,
261 .pollcfg = 0,
262 .doorbell = MHI_DB_BRST_DISABLE,
263 .lpm_notify = false,
264 .offload_channel = false,
265 .doorbell_mode_switch = false,
266 .auto_queue = false,
267 .wake_capable = false,
268 },
269 {
270 .name = "QAIC_STATUS",
271 .num = 15,
272 .num_elements = 32,
273 .local_elements = 0,
274 .event_ring = 0,
275 .dir = DMA_FROM_DEVICE,
276 .ee_mask = MHI_CH_EE_AMSS,
277 .pollcfg = 0,
278 .doorbell = MHI_DB_BRST_DISABLE,
279 .lpm_notify = false,
280 .offload_channel = false,
281 .doorbell_mode_switch = false,
282 .auto_queue = false,
283 .wake_capable = false,
284 },
285 {
286 .name = "QAIC_TELEMETRY",
287 .num = 16,
288 .num_elements = 32,
289 .local_elements = 0,
290 .event_ring = 0,
291 .dir = DMA_TO_DEVICE,
292 .ee_mask = MHI_CH_EE_AMSS,
293 .pollcfg = 0,
294 .doorbell = MHI_DB_BRST_DISABLE,
295 .lpm_notify = false,
296 .offload_channel = false,
297 .doorbell_mode_switch = false,
298 .auto_queue = false,
299 .wake_capable = false,
300 },
301 {
302 .name = "QAIC_TELEMETRY",
303 .num = 17,
304 .num_elements = 32,
305 .local_elements = 0,
306 .event_ring = 0,
307 .dir = DMA_FROM_DEVICE,
308 .ee_mask = MHI_CH_EE_AMSS,
309 .pollcfg = 0,
310 .doorbell = MHI_DB_BRST_DISABLE,
311 .lpm_notify = false,
312 .offload_channel = false,
313 .doorbell_mode_switch = false,
314 .auto_queue = false,
315 .wake_capable = false,
316 },
317 {
318 .name = "QAIC_DEBUG",
319 .num = 18,
320 .num_elements = 32,
321 .local_elements = 0,
322 .event_ring = 0,
323 .dir = DMA_TO_DEVICE,
324 .ee_mask = MHI_CH_EE_AMSS,
325 .pollcfg = 0,
326 .doorbell = MHI_DB_BRST_DISABLE,
327 .lpm_notify = false,
328 .offload_channel = false,
329 .doorbell_mode_switch = false,
330 .auto_queue = false,
331 .wake_capable = false,
332 },
333 {
334 .name = "QAIC_DEBUG",
335 .num = 19,
336 .num_elements = 32,
337 .local_elements = 0,
338 .event_ring = 0,
339 .dir = DMA_FROM_DEVICE,
340 .ee_mask = MHI_CH_EE_AMSS,
341 .pollcfg = 0,
342 .doorbell = MHI_DB_BRST_DISABLE,
343 .lpm_notify = false,
344 .offload_channel = false,
345 .doorbell_mode_switch = false,
346 .auto_queue = false,
347 .wake_capable = false,
348 },
349 {
350 .name = "QAIC_TIMESYNC",
351 .num = 20,
352 .num_elements = 32,
353 .local_elements = 0,
354 .event_ring = 0,
355 .dir = DMA_TO_DEVICE,
356 .ee_mask = MHI_CH_EE_SBL,
357 .pollcfg = 0,
358 .doorbell = MHI_DB_BRST_DISABLE,
359 .lpm_notify = false,
360 .offload_channel = false,
361 .doorbell_mode_switch = false,
362 .auto_queue = false,
363 .wake_capable = false,
364 },
365 {
366 .name = "QAIC_TIMESYNC",
367 .num = 21,
368 .num_elements = 32,
369 .local_elements = 0,
370 .event_ring = 0,
371 .dir = DMA_FROM_DEVICE,
372 .ee_mask = MHI_CH_EE_SBL,
373 .pollcfg = 0,
374 .doorbell = MHI_DB_BRST_DISABLE,
375 .lpm_notify = false,
376 .offload_channel = false,
377 .doorbell_mode_switch = false,
378 .auto_queue = false,
379 .wake_capable = false,
380 },
381 {
382 .name = "QAIC_TIMESYNC_PERIODIC",
383 .num = 22,
384 .num_elements = 32,
385 .local_elements = 0,
386 .event_ring = 0,
387 .dir = DMA_TO_DEVICE,
388 .ee_mask = MHI_CH_EE_AMSS,
389 .pollcfg = 0,
390 .doorbell = MHI_DB_BRST_DISABLE,
391 .lpm_notify = false,
392 .offload_channel = false,
393 .doorbell_mode_switch = false,
394 .auto_queue = false,
395 .wake_capable = false,
396 },
397 {
398 .name = "QAIC_TIMESYNC_PERIODIC",
399 .num = 23,
400 .num_elements = 32,
401 .local_elements = 0,
402 .event_ring = 0,
403 .dir = DMA_FROM_DEVICE,
404 .ee_mask = MHI_CH_EE_AMSS,
405 .pollcfg = 0,
406 .doorbell = MHI_DB_BRST_DISABLE,
407 .lpm_notify = false,
408 .offload_channel = false,
409 .doorbell_mode_switch = false,
410 .auto_queue = false,
411 .wake_capable = false,
412 },
413 {
414 .name = "IPCR",
415 .num = 24,
416 .num_elements = 32,
417 .local_elements = 0,
418 .event_ring = 0,
419 .dir = DMA_TO_DEVICE,
420 .ee_mask = MHI_CH_EE_AMSS,
421 .pollcfg = 0,
422 .doorbell = MHI_DB_BRST_DISABLE,
423 .lpm_notify = false,
424 .offload_channel = false,
425 .doorbell_mode_switch = false,
426 .auto_queue = false,
427 .wake_capable = false,
428 },
429 {
430 .name = "IPCR",
431 .num = 25,
432 .num_elements = 32,
433 .local_elements = 0,
434 .event_ring = 0,
435 .dir = DMA_FROM_DEVICE,
436 .ee_mask = MHI_CH_EE_AMSS,
437 .pollcfg = 0,
438 .doorbell = MHI_DB_BRST_DISABLE,
439 .lpm_notify = false,
440 .offload_channel = false,
441 .doorbell_mode_switch = false,
442 .auto_queue = true,
443 .wake_capable = false,
444 },
445 };
446
447 static const struct mhi_channel_config aic200_channels[] = {
448 {
449 .name = "QAIC_LOOPBACK",
450 .num = 0,
451 .num_elements = 32,
452 .local_elements = 0,
453 .event_ring = 0,
454 .dir = DMA_TO_DEVICE,
455 .ee_mask = MHI_CH_EE_AMSS,
456 .pollcfg = 0,
457 .doorbell = MHI_DB_BRST_DISABLE,
458 .lpm_notify = false,
459 .offload_channel = false,
460 .doorbell_mode_switch = false,
461 .auto_queue = false,
462 .wake_capable = false,
463 },
464 {
465 .name = "QAIC_LOOPBACK",
466 .num = 1,
467 .num_elements = 32,
468 .local_elements = 0,
469 .event_ring = 0,
470 .dir = DMA_FROM_DEVICE,
471 .ee_mask = MHI_CH_EE_AMSS,
472 .pollcfg = 0,
473 .doorbell = MHI_DB_BRST_DISABLE,
474 .lpm_notify = false,
475 .offload_channel = false,
476 .doorbell_mode_switch = false,
477 .auto_queue = false,
478 .wake_capable = false,
479 },
480 {
481 .name = "QAIC_SAHARA",
482 .num = 2,
483 .num_elements = 32,
484 .local_elements = 0,
485 .event_ring = 0,
486 .dir = DMA_TO_DEVICE,
487 .ee_mask = MHI_CH_EE_SBL,
488 .pollcfg = 0,
489 .doorbell = MHI_DB_BRST_DISABLE,
490 .lpm_notify = false,
491 .offload_channel = false,
492 .doorbell_mode_switch = false,
493 .auto_queue = false,
494 .wake_capable = false,
495 },
496 {
497 .name = "QAIC_SAHARA",
498 .num = 3,
499 .num_elements = 32,
500 .local_elements = 0,
501 .event_ring = 0,
502 .dir = DMA_FROM_DEVICE,
503 .ee_mask = MHI_CH_EE_SBL,
504 .pollcfg = 0,
505 .doorbell = MHI_DB_BRST_DISABLE,
506 .lpm_notify = false,
507 .offload_channel = false,
508 .doorbell_mode_switch = false,
509 .auto_queue = false,
510 .wake_capable = false,
511 },
512 {
513 .name = "QAIC_SSR",
514 .num = 6,
515 .num_elements = 32,
516 .local_elements = 0,
517 .event_ring = 0,
518 .dir = DMA_TO_DEVICE,
519 .ee_mask = MHI_CH_EE_AMSS,
520 .pollcfg = 0,
521 .doorbell = MHI_DB_BRST_DISABLE,
522 .lpm_notify = false,
523 .offload_channel = false,
524 .doorbell_mode_switch = false,
525 .auto_queue = false,
526 .wake_capable = false,
527 },
528 {
529 .name = "QAIC_SSR",
530 .num = 7,
531 .num_elements = 32,
532 .local_elements = 0,
533 .event_ring = 0,
534 .dir = DMA_FROM_DEVICE,
535 .ee_mask = MHI_CH_EE_AMSS,
536 .pollcfg = 0,
537 .doorbell = MHI_DB_BRST_DISABLE,
538 .lpm_notify = false,
539 .offload_channel = false,
540 .doorbell_mode_switch = false,
541 .auto_queue = false,
542 .wake_capable = false,
543 },
544 {
545 .name = "QAIC_CONTROL",
546 .num = 10,
547 .num_elements = 128,
548 .local_elements = 0,
549 .event_ring = 0,
550 .dir = DMA_TO_DEVICE,
551 .ee_mask = MHI_CH_EE_AMSS,
552 .pollcfg = 0,
553 .doorbell = MHI_DB_BRST_DISABLE,
554 .lpm_notify = false,
555 .offload_channel = false,
556 .doorbell_mode_switch = false,
557 .auto_queue = false,
558 .wake_capable = false,
559 },
560 {
561 .name = "QAIC_CONTROL",
562 .num = 11,
563 .num_elements = 128,
564 .local_elements = 0,
565 .event_ring = 0,
566 .dir = DMA_FROM_DEVICE,
567 .ee_mask = MHI_CH_EE_AMSS,
568 .pollcfg = 0,
569 .doorbell = MHI_DB_BRST_DISABLE,
570 .lpm_notify = false,
571 .offload_channel = false,
572 .doorbell_mode_switch = false,
573 .auto_queue = false,
574 .wake_capable = false,
575 },
576 {
577 .name = "QAIC_LOGGING",
578 .num = 12,
579 .num_elements = 32,
580 .local_elements = 0,
581 .event_ring = 0,
582 .dir = DMA_TO_DEVICE,
583 .ee_mask = MHI_CH_EE_SBL,
584 .pollcfg = 0,
585 .doorbell = MHI_DB_BRST_DISABLE,
586 .lpm_notify = false,
587 .offload_channel = false,
588 .doorbell_mode_switch = false,
589 .auto_queue = false,
590 .wake_capable = false,
591 },
592 {
593 .name = "QAIC_LOGGING",
594 .num = 13,
595 .num_elements = 32,
596 .local_elements = 0,
597 .event_ring = 0,
598 .dir = DMA_FROM_DEVICE,
599 .ee_mask = MHI_CH_EE_SBL,
600 .pollcfg = 0,
601 .doorbell = MHI_DB_BRST_DISABLE,
602 .lpm_notify = false,
603 .offload_channel = false,
604 .doorbell_mode_switch = false,
605 .auto_queue = false,
606 .wake_capable = false,
607 },
608 {
609 .name = "QAIC_STATUS",
610 .num = 14,
611 .num_elements = 32,
612 .local_elements = 0,
613 .event_ring = 0,
614 .dir = DMA_TO_DEVICE,
615 .ee_mask = MHI_CH_EE_AMSS,
616 .pollcfg = 0,
617 .doorbell = MHI_DB_BRST_DISABLE,
618 .lpm_notify = false,
619 .offload_channel = false,
620 .doorbell_mode_switch = false,
621 .auto_queue = false,
622 .wake_capable = false,
623 },
624 {
625 .name = "QAIC_STATUS",
626 .num = 15,
627 .num_elements = 32,
628 .local_elements = 0,
629 .event_ring = 0,
630 .dir = DMA_FROM_DEVICE,
631 .ee_mask = MHI_CH_EE_AMSS,
632 .pollcfg = 0,
633 .doorbell = MHI_DB_BRST_DISABLE,
634 .lpm_notify = false,
635 .offload_channel = false,
636 .doorbell_mode_switch = false,
637 .auto_queue = false,
638 .wake_capable = false,
639 },
640 {
641 .name = "QAIC_TELEMETRY",
642 .num = 16,
643 .num_elements = 32,
644 .local_elements = 0,
645 .event_ring = 0,
646 .dir = DMA_TO_DEVICE,
647 .ee_mask = MHI_CH_EE_AMSS,
648 .pollcfg = 0,
649 .doorbell = MHI_DB_BRST_DISABLE,
650 .lpm_notify = false,
651 .offload_channel = false,
652 .doorbell_mode_switch = false,
653 .auto_queue = false,
654 .wake_capable = false,
655 },
656 {
657 .name = "QAIC_TELEMETRY",
658 .num = 17,
659 .num_elements = 32,
660 .local_elements = 0,
661 .event_ring = 0,
662 .dir = DMA_FROM_DEVICE,
663 .ee_mask = MHI_CH_EE_AMSS,
664 .pollcfg = 0,
665 .doorbell = MHI_DB_BRST_DISABLE,
666 .lpm_notify = false,
667 .offload_channel = false,
668 .doorbell_mode_switch = false,
669 .auto_queue = false,
670 .wake_capable = false,
671 },
672 {
673 .name = "QAIC_TIMESYNC_PERIODIC",
674 .num = 22,
675 .num_elements = 32,
676 .local_elements = 0,
677 .event_ring = 0,
678 .dir = DMA_TO_DEVICE,
679 .ee_mask = MHI_CH_EE_AMSS,
680 .pollcfg = 0,
681 .doorbell = MHI_DB_BRST_DISABLE,
682 .lpm_notify = false,
683 .offload_channel = false,
684 .doorbell_mode_switch = false,
685 .auto_queue = false,
686 .wake_capable = false,
687 },
688 {
689 .name = "QAIC_TIMESYNC_PERIODIC",
690 .num = 23,
691 .num_elements = 32,
692 .local_elements = 0,
693 .event_ring = 0,
694 .dir = DMA_FROM_DEVICE,
695 .ee_mask = MHI_CH_EE_AMSS,
696 .pollcfg = 0,
697 .doorbell = MHI_DB_BRST_DISABLE,
698 .lpm_notify = false,
699 .offload_channel = false,
700 .doorbell_mode_switch = false,
701 .auto_queue = false,
702 .wake_capable = false,
703 },
704 {
705 .name = "IPCR",
706 .num = 24,
707 .num_elements = 32,
708 .local_elements = 0,
709 .event_ring = 0,
710 .dir = DMA_TO_DEVICE,
711 .ee_mask = MHI_CH_EE_AMSS,
712 .pollcfg = 0,
713 .doorbell = MHI_DB_BRST_DISABLE,
714 .lpm_notify = false,
715 .offload_channel = false,
716 .doorbell_mode_switch = false,
717 .auto_queue = false,
718 .wake_capable = false,
719 },
720 {
721 .name = "IPCR",
722 .num = 25,
723 .num_elements = 32,
724 .local_elements = 0,
725 .event_ring = 0,
726 .dir = DMA_FROM_DEVICE,
727 .ee_mask = MHI_CH_EE_AMSS,
728 .pollcfg = 0,
729 .doorbell = MHI_DB_BRST_DISABLE,
730 .lpm_notify = false,
731 .offload_channel = false,
732 .doorbell_mode_switch = false,
733 .auto_queue = true,
734 .wake_capable = false,
735 },
736 };
737
738 static struct mhi_event_config aic100_events[] = {
739 {
740 .num_elements = 32,
741 .irq_moderation_ms = 0,
742 .irq = 0,
743 .channel = U32_MAX,
744 .priority = 1,
745 .mode = MHI_DB_BRST_DISABLE,
746 .data_type = MHI_ER_CTRL,
747 .hardware_event = false,
748 .client_managed = false,
749 .offload_channel = false,
750 },
751 };
752
753 static struct mhi_event_config aic200_events[] = {
754 {
755 .num_elements = 32,
756 .irq_moderation_ms = 0,
757 .irq = 0,
758 .channel = U32_MAX,
759 .priority = 1,
760 .mode = MHI_DB_BRST_DISABLE,
761 .data_type = MHI_ER_CTRL,
762 .hardware_event = false,
763 .client_managed = false,
764 .offload_channel = false,
765 },
766 };
767
768 static struct mhi_controller_config mhi_cntrl_configs[] = {
769 [FAMILY_AIC100] = {
770 .max_channels = 128,
771 .timeout_ms = 0, /* controlled by mhi_timeout */
772 .buf_len = 0,
773 .num_channels = ARRAY_SIZE(aic100_channels),
774 .ch_cfg = aic100_channels,
775 .num_events = ARRAY_SIZE(aic100_events),
776 .event_cfg = aic100_events,
777 .use_bounce_buf = false,
778 .m2_no_db = false,
779 },
780 [FAMILY_AIC200] = {
781 .max_channels = 128,
782 .timeout_ms = 0, /* controlled by mhi_timeout */
783 .buf_len = 0,
784 .num_channels = ARRAY_SIZE(aic200_channels),
785 .ch_cfg = aic200_channels,
786 .num_events = ARRAY_SIZE(aic200_events),
787 .event_cfg = aic200_events,
788 .use_bounce_buf = false,
789 .m2_no_db = false,
790 },
791 };
792
mhi_read_reg(struct mhi_controller * mhi_cntrl,void __iomem * addr,u32 * out)793 static int mhi_read_reg(struct mhi_controller *mhi_cntrl, void __iomem *addr, u32 *out)
794 {
795 u32 tmp;
796
797 /*
798 * SOC_HW_VERSION quirk
799 * The SOC_HW_VERSION register (offset 0x224) is not reliable and
800 * may contain uninitialized values, including 0xFFFFFFFF. This could
801 * cause a false positive link down error. Instead, intercept any
802 * reads and provide the correct value of the register.
803 */
804 if (addr - mhi_cntrl->regs == 0x224) {
805 *out = 0x60110200;
806 return 0;
807 }
808
809 tmp = readl_relaxed(addr);
810 if (tmp == U32_MAX)
811 return -EIO;
812
813 *out = tmp;
814
815 return 0;
816 }
817
mhi_write_reg(struct mhi_controller * mhi_cntrl,void __iomem * addr,u32 val)818 static void mhi_write_reg(struct mhi_controller *mhi_cntrl, void __iomem *addr, u32 val)
819 {
820 writel_relaxed(val, addr);
821 }
822
mhi_runtime_get(struct mhi_controller * mhi_cntrl)823 static int mhi_runtime_get(struct mhi_controller *mhi_cntrl)
824 {
825 return 0;
826 }
827
mhi_runtime_put(struct mhi_controller * mhi_cntrl)828 static void mhi_runtime_put(struct mhi_controller *mhi_cntrl)
829 {
830 }
831
mhi_status_cb(struct mhi_controller * mhi_cntrl,enum mhi_callback reason)832 static void mhi_status_cb(struct mhi_controller *mhi_cntrl, enum mhi_callback reason)
833 {
834 struct qaic_device *qdev = pci_get_drvdata(to_pci_dev(mhi_cntrl->cntrl_dev));
835
836 /* this event occurs in atomic context */
837 if (reason == MHI_CB_FATAL_ERROR)
838 pci_err(qdev->pdev, "Fatal error received from device. Attempting to recover\n");
839 /* this event occurs in non-atomic context */
840 if (reason == MHI_CB_SYS_ERROR)
841 qaic_dev_reset_clean_local_state(qdev);
842 }
843
mhi_reset_and_async_power_up(struct mhi_controller * mhi_cntrl)844 static int mhi_reset_and_async_power_up(struct mhi_controller *mhi_cntrl)
845 {
846 u8 time_sec = 1;
847 int current_ee;
848 int ret;
849
850 /* Reset the device to bring the device in PBL EE */
851 mhi_soc_reset(mhi_cntrl);
852
853 /*
854 * Keep checking the execution environment(EE) after every 1 second
855 * interval.
856 */
857 do {
858 msleep(1000);
859 current_ee = mhi_get_exec_env(mhi_cntrl);
860 } while (current_ee != MHI_EE_PBL && time_sec++ <= MAX_RESET_TIME_SEC);
861
862 /* If the device is in PBL EE retry power up */
863 if (current_ee == MHI_EE_PBL)
864 ret = mhi_async_power_up(mhi_cntrl);
865 else
866 ret = -EIO;
867
868 return ret;
869 }
870
qaic_mhi_register_controller(struct pci_dev * pci_dev,void __iomem * mhi_bar,int mhi_irq,bool shared_msi,int family)871 struct mhi_controller *qaic_mhi_register_controller(struct pci_dev *pci_dev, void __iomem *mhi_bar,
872 int mhi_irq, bool shared_msi, int family)
873 {
874 struct mhi_controller_config mhi_config = mhi_cntrl_configs[family];
875 struct mhi_controller *mhi_cntrl;
876 int ret;
877
878 mhi_cntrl = devm_kzalloc(&pci_dev->dev, sizeof(*mhi_cntrl), GFP_KERNEL);
879 if (!mhi_cntrl)
880 return ERR_PTR(-ENOMEM);
881
882 mhi_cntrl->cntrl_dev = &pci_dev->dev;
883
884 /*
885 * Covers the entire possible physical ram region. Remote side is
886 * going to calculate a size of this range, so subtract 1 to prevent
887 * rollover.
888 */
889 mhi_cntrl->iova_start = 0;
890 mhi_cntrl->iova_stop = PHYS_ADDR_MAX - 1;
891 mhi_cntrl->status_cb = mhi_status_cb;
892 mhi_cntrl->runtime_get = mhi_runtime_get;
893 mhi_cntrl->runtime_put = mhi_runtime_put;
894 mhi_cntrl->read_reg = mhi_read_reg;
895 mhi_cntrl->write_reg = mhi_write_reg;
896 mhi_cntrl->regs = mhi_bar;
897 mhi_cntrl->reg_len = SZ_4K;
898 mhi_cntrl->nr_irqs = 1;
899 mhi_cntrl->irq = devm_kmalloc(&pci_dev->dev, sizeof(*mhi_cntrl->irq), GFP_KERNEL);
900
901 if (!mhi_cntrl->irq)
902 return ERR_PTR(-ENOMEM);
903
904 mhi_cntrl->irq[0] = mhi_irq;
905
906 if (shared_msi) /* MSI shared with data path, no IRQF_NO_SUSPEND */
907 mhi_cntrl->irq_flags = IRQF_SHARED;
908
909 mhi_cntrl->fw_image = fw_image_paths[family];
910
911 if (family == FAMILY_AIC200) {
912 mhi_cntrl->name = "AIC200";
913 mhi_cntrl->seg_len = SZ_512K;
914 } else {
915 mhi_cntrl->name = "AIC100";
916 }
917
918 /* use latest configured timeout */
919 mhi_config.timeout_ms = mhi_timeout_ms;
920 ret = mhi_register_controller(mhi_cntrl, &mhi_config);
921 if (ret) {
922 pci_err(pci_dev, "mhi_register_controller failed %d\n", ret);
923 return ERR_PTR(ret);
924 }
925
926 ret = mhi_prepare_for_power_up(mhi_cntrl);
927 if (ret) {
928 pci_err(pci_dev, "mhi_prepare_for_power_up failed %d\n", ret);
929 goto prepare_power_up_fail;
930 }
931
932 ret = mhi_async_power_up(mhi_cntrl);
933 /*
934 * If EIO is returned it is possible that device is in SBL EE, which is
935 * undesired. SOC reset the device and try to power up again.
936 */
937 if (ret == -EIO && MHI_EE_SBL == mhi_get_exec_env(mhi_cntrl)) {
938 pci_err(pci_dev, "Found device in SBL at MHI init. Attempting a reset.\n");
939 ret = mhi_reset_and_async_power_up(mhi_cntrl);
940 }
941
942 if (ret) {
943 pci_err(pci_dev, "mhi_async_power_up failed %d\n", ret);
944 goto power_up_fail;
945 }
946
947 return mhi_cntrl;
948
949 power_up_fail:
950 mhi_unprepare_after_power_down(mhi_cntrl);
951 prepare_power_up_fail:
952 mhi_unregister_controller(mhi_cntrl);
953 return ERR_PTR(ret);
954 }
955
qaic_mhi_free_controller(struct mhi_controller * mhi_cntrl,bool link_up)956 void qaic_mhi_free_controller(struct mhi_controller *mhi_cntrl, bool link_up)
957 {
958 mhi_power_down(mhi_cntrl, link_up);
959 mhi_unprepare_after_power_down(mhi_cntrl);
960 mhi_unregister_controller(mhi_cntrl);
961 }
962
qaic_mhi_start_reset(struct mhi_controller * mhi_cntrl)963 void qaic_mhi_start_reset(struct mhi_controller *mhi_cntrl)
964 {
965 mhi_power_down(mhi_cntrl, true);
966 }
967
qaic_mhi_reset_done(struct mhi_controller * mhi_cntrl)968 void qaic_mhi_reset_done(struct mhi_controller *mhi_cntrl)
969 {
970 struct pci_dev *pci_dev = container_of(mhi_cntrl->cntrl_dev, struct pci_dev, dev);
971 int ret;
972
973 ret = mhi_async_power_up(mhi_cntrl);
974 if (ret)
975 pci_err(pci_dev, "mhi_async_power_up failed after reset %d\n", ret);
976 }
977