Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
torvalds
GitHub Repository: torvalds/linux
Path: blob/master/drivers/accel/qaic/mhi_controller.c
26428 views
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
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
818
static void mhi_write_reg(struct mhi_controller *mhi_cntrl, void __iomem *addr, u32 val)
819
{
820
writel_relaxed(val, addr);
821
}
822
823
static int mhi_runtime_get(struct mhi_controller *mhi_cntrl)
824
{
825
return 0;
826
}
827
828
static void mhi_runtime_put(struct mhi_controller *mhi_cntrl)
829
{
830
}
831
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
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
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
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
963
void qaic_mhi_start_reset(struct mhi_controller *mhi_cntrl)
964
{
965
mhi_power_down(mhi_cntrl, true);
966
}
967
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
978