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