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 struct mhi_channel_config aic100_channels[] = {
24 {
25 .name = "QAIC_LOOPBACK",
26 .num = 0,
27 .num_elements = 32,
28 .local_elements = 0,
29 .event_ring = 0,
30 .dir = DMA_TO_DEVICE,
31 .ee_mask = MHI_CH_EE_AMSS,
32 .pollcfg = 0,
33 .doorbell = MHI_DB_BRST_DISABLE,
34 .lpm_notify = false,
35 .offload_channel = false,
36 .doorbell_mode_switch = false,
37 .auto_queue = false,
38 .wake_capable = false,
39 },
40 {
41 .name = "QAIC_LOOPBACK",
42 .num = 1,
43 .num_elements = 32,
44 .local_elements = 0,
45 .event_ring = 0,
46 .dir = DMA_FROM_DEVICE,
47 .ee_mask = MHI_CH_EE_AMSS,
48 .pollcfg = 0,
49 .doorbell = MHI_DB_BRST_DISABLE,
50 .lpm_notify = false,
51 .offload_channel = false,
52 .doorbell_mode_switch = false,
53 .auto_queue = false,
54 .wake_capable = false,
55 },
56 {
57 .name = "QAIC_SAHARA",
58 .num = 2,
59 .num_elements = 32,
60 .local_elements = 0,
61 .event_ring = 0,
62 .dir = DMA_TO_DEVICE,
63 .ee_mask = MHI_CH_EE_SBL,
64 .pollcfg = 0,
65 .doorbell = MHI_DB_BRST_DISABLE,
66 .lpm_notify = false,
67 .offload_channel = false,
68 .doorbell_mode_switch = false,
69 .auto_queue = false,
70 .wake_capable = false,
71 },
72 {
73 .name = "QAIC_SAHARA",
74 .num = 3,
75 .num_elements = 32,
76 .local_elements = 0,
77 .event_ring = 0,
78 .dir = DMA_FROM_DEVICE,
79 .ee_mask = MHI_CH_EE_SBL,
80 .pollcfg = 0,
81 .doorbell = MHI_DB_BRST_DISABLE,
82 .lpm_notify = false,
83 .offload_channel = false,
84 .doorbell_mode_switch = false,
85 .auto_queue = false,
86 .wake_capable = false,
87 },
88 {
89 .name = "QAIC_DIAG",
90 .num = 4,
91 .num_elements = 32,
92 .local_elements = 0,
93 .event_ring = 0,
94 .dir = DMA_TO_DEVICE,
95 .ee_mask = MHI_CH_EE_AMSS,
96 .pollcfg = 0,
97 .doorbell = MHI_DB_BRST_DISABLE,
98 .lpm_notify = false,
99 .offload_channel = false,
100 .doorbell_mode_switch = false,
101 .auto_queue = 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 .auto_queue = false,
118 .wake_capable = false,
119 },
120 {
121 .name = "QAIC_SSR",
122 .num = 6,
123 .num_elements = 32,
124 .local_elements = 0,
125 .event_ring = 0,
126 .dir = DMA_TO_DEVICE,
127 .ee_mask = MHI_CH_EE_AMSS,
128 .pollcfg = 0,
129 .doorbell = MHI_DB_BRST_DISABLE,
130 .lpm_notify = false,
131 .offload_channel = false,
132 .doorbell_mode_switch = false,
133 .auto_queue = false,
134 .wake_capable = false,
135 },
136 {
137 .name = "QAIC_SSR",
138 .num = 7,
139 .num_elements = 32,
140 .local_elements = 0,
141 .event_ring = 0,
142 .dir = DMA_FROM_DEVICE,
143 .ee_mask = MHI_CH_EE_AMSS,
144 .pollcfg = 0,
145 .doorbell = MHI_DB_BRST_DISABLE,
146 .lpm_notify = false,
147 .offload_channel = false,
148 .doorbell_mode_switch = false,
149 .auto_queue = false,
150 .wake_capable = false,
151 },
152 {
153 .name = "QAIC_QDSS",
154 .num = 8,
155 .num_elements = 32,
156 .local_elements = 0,
157 .event_ring = 0,
158 .dir = DMA_TO_DEVICE,
159 .ee_mask = MHI_CH_EE_AMSS,
160 .pollcfg = 0,
161 .doorbell = MHI_DB_BRST_DISABLE,
162 .lpm_notify = false,
163 .offload_channel = false,
164 .doorbell_mode_switch = false,
165 .auto_queue = false,
166 .wake_capable = false,
167 },
168 {
169 .name = "QAIC_QDSS",
170 .num = 9,
171 .num_elements = 32,
172 .local_elements = 0,
173 .event_ring = 0,
174 .dir = DMA_FROM_DEVICE,
175 .ee_mask = MHI_CH_EE_AMSS,
176 .pollcfg = 0,
177 .doorbell = MHI_DB_BRST_DISABLE,
178 .lpm_notify = false,
179 .offload_channel = false,
180 .doorbell_mode_switch = false,
181 .auto_queue = false,
182 .wake_capable = false,
183 },
184 {
185 .name = "QAIC_CONTROL",
186 .num = 10,
187 .num_elements = 128,
188 .local_elements = 0,
189 .event_ring = 0,
190 .dir = DMA_TO_DEVICE,
191 .ee_mask = MHI_CH_EE_AMSS,
192 .pollcfg = 0,
193 .doorbell = MHI_DB_BRST_DISABLE,
194 .lpm_notify = false,
195 .offload_channel = false,
196 .doorbell_mode_switch = false,
197 .auto_queue = false,
198 .wake_capable = false,
199 },
200 {
201 .name = "QAIC_CONTROL",
202 .num = 11,
203 .num_elements = 128,
204 .local_elements = 0,
205 .event_ring = 0,
206 .dir = DMA_FROM_DEVICE,
207 .ee_mask = MHI_CH_EE_AMSS,
208 .pollcfg = 0,
209 .doorbell = MHI_DB_BRST_DISABLE,
210 .lpm_notify = false,
211 .offload_channel = false,
212 .doorbell_mode_switch = false,
213 .auto_queue = false,
214 .wake_capable = false,
215 },
216 {
217 .name = "QAIC_LOGGING",
218 .num = 12,
219 .num_elements = 32,
220 .local_elements = 0,
221 .event_ring = 0,
222 .dir = DMA_TO_DEVICE,
223 .ee_mask = MHI_CH_EE_SBL,
224 .pollcfg = 0,
225 .doorbell = MHI_DB_BRST_DISABLE,
226 .lpm_notify = false,
227 .offload_channel = false,
228 .doorbell_mode_switch = false,
229 .auto_queue = false,
230 .wake_capable = false,
231 },
232 {
233 .name = "QAIC_LOGGING",
234 .num = 13,
235 .num_elements = 32,
236 .local_elements = 0,
237 .event_ring = 0,
238 .dir = DMA_FROM_DEVICE,
239 .ee_mask = MHI_CH_EE_SBL,
240 .pollcfg = 0,
241 .doorbell = MHI_DB_BRST_DISABLE,
242 .lpm_notify = false,
243 .offload_channel = false,
244 .doorbell_mode_switch = false,
245 .auto_queue = false,
246 .wake_capable = false,
247 },
248 {
249 .name = "QAIC_STATUS",
250 .num = 14,
251 .num_elements = 32,
252 .local_elements = 0,
253 .event_ring = 0,
254 .dir = DMA_TO_DEVICE,
255 .ee_mask = MHI_CH_EE_AMSS,
256 .pollcfg = 0,
257 .doorbell = MHI_DB_BRST_DISABLE,
258 .lpm_notify = false,
259 .offload_channel = false,
260 .doorbell_mode_switch = false,
261 .auto_queue = false,
262 .wake_capable = false,
263 },
264 {
265 .name = "QAIC_STATUS",
266 .num = 15,
267 .num_elements = 32,
268 .local_elements = 0,
269 .event_ring = 0,
270 .dir = DMA_FROM_DEVICE,
271 .ee_mask = MHI_CH_EE_AMSS,
272 .pollcfg = 0,
273 .doorbell = MHI_DB_BRST_DISABLE,
274 .lpm_notify = false,
275 .offload_channel = false,
276 .doorbell_mode_switch = false,
277 .auto_queue = false,
278 .wake_capable = false,
279 },
280 {
281 .name = "QAIC_TELEMETRY",
282 .num = 16,
283 .num_elements = 32,
284 .local_elements = 0,
285 .event_ring = 0,
286 .dir = DMA_TO_DEVICE,
287 .ee_mask = MHI_CH_EE_AMSS,
288 .pollcfg = 0,
289 .doorbell = MHI_DB_BRST_DISABLE,
290 .lpm_notify = false,
291 .offload_channel = false,
292 .doorbell_mode_switch = false,
293 .auto_queue = false,
294 .wake_capable = false,
295 },
296 {
297 .name = "QAIC_TELEMETRY",
298 .num = 17,
299 .num_elements = 32,
300 .local_elements = 0,
301 .event_ring = 0,
302 .dir = DMA_FROM_DEVICE,
303 .ee_mask = MHI_CH_EE_AMSS,
304 .pollcfg = 0,
305 .doorbell = MHI_DB_BRST_DISABLE,
306 .lpm_notify = false,
307 .offload_channel = false,
308 .doorbell_mode_switch = false,
309 .auto_queue = false,
310 .wake_capable = false,
311 },
312 {
313 .name = "QAIC_DEBUG",
314 .num = 18,
315 .num_elements = 32,
316 .local_elements = 0,
317 .event_ring = 0,
318 .dir = DMA_TO_DEVICE,
319 .ee_mask = MHI_CH_EE_AMSS,
320 .pollcfg = 0,
321 .doorbell = MHI_DB_BRST_DISABLE,
322 .lpm_notify = false,
323 .offload_channel = false,
324 .doorbell_mode_switch = false,
325 .auto_queue = false,
326 .wake_capable = false,
327 },
328 {
329 .name = "QAIC_DEBUG",
330 .num = 19,
331 .num_elements = 32,
332 .local_elements = 0,
333 .event_ring = 0,
334 .dir = DMA_FROM_DEVICE,
335 .ee_mask = MHI_CH_EE_AMSS,
336 .pollcfg = 0,
337 .doorbell = MHI_DB_BRST_DISABLE,
338 .lpm_notify = false,
339 .offload_channel = false,
340 .doorbell_mode_switch = false,
341 .auto_queue = false,
342 .wake_capable = false,
343 },
344 {
345 .name = "QAIC_TIMESYNC",
346 .num = 20,
347 .num_elements = 32,
348 .local_elements = 0,
349 .event_ring = 0,
350 .dir = DMA_TO_DEVICE,
351 .ee_mask = MHI_CH_EE_SBL | MHI_CH_EE_AMSS,
352 .pollcfg = 0,
353 .doorbell = MHI_DB_BRST_DISABLE,
354 .lpm_notify = false,
355 .offload_channel = false,
356 .doorbell_mode_switch = false,
357 .auto_queue = false,
358 .wake_capable = false,
359 },
360 {
361 .num = 21,
362 .name = "QAIC_TIMESYNC",
363 .num_elements = 32,
364 .local_elements = 0,
365 .event_ring = 0,
366 .dir = DMA_FROM_DEVICE,
367 .ee_mask = MHI_CH_EE_SBL | MHI_CH_EE_AMSS,
368 .pollcfg = 0,
369 .doorbell = MHI_DB_BRST_DISABLE,
370 .lpm_notify = false,
371 .offload_channel = false,
372 .doorbell_mode_switch = false,
373 .auto_queue = false,
374 .wake_capable = false,
375 },
376 };
377
378 static struct mhi_event_config aic100_events[] = {
379 {
380 .num_elements = 32,
381 .irq_moderation_ms = 0,
382 .irq = 0,
383 .channel = U32_MAX,
384 .priority = 1,
385 .mode = MHI_DB_BRST_DISABLE,
386 .data_type = MHI_ER_CTRL,
387 .hardware_event = false,
388 .client_managed = false,
389 .offload_channel = false,
390 },
391 };
392
393 static struct mhi_controller_config aic100_config = {
394 .max_channels = 128,
395 .timeout_ms = 0, /* controlled by mhi_timeout */
396 .buf_len = 0,
397 .num_channels = ARRAY_SIZE(aic100_channels),
398 .ch_cfg = aic100_channels,
399 .num_events = ARRAY_SIZE(aic100_events),
400 .event_cfg = aic100_events,
401 .use_bounce_buf = false,
402 .m2_no_db = false,
403 };
404
mhi_read_reg(struct mhi_controller * mhi_cntrl,void __iomem * addr,u32 * out)405 static int mhi_read_reg(struct mhi_controller *mhi_cntrl, void __iomem *addr, u32 *out)
406 {
407 u32 tmp;
408
409 /*
410 * SOC_HW_VERSION quirk
411 * The SOC_HW_VERSION register (offset 0x224) is not reliable and
412 * may contain uninitialized values, including 0xFFFFFFFF. This could
413 * cause a false positive link down error. Instead, intercept any
414 * reads and provide the correct value of the register.
415 */
416 if (addr - mhi_cntrl->regs == 0x224) {
417 *out = 0x60110200;
418 return 0;
419 }
420
421 tmp = readl_relaxed(addr);
422 if (tmp == U32_MAX)
423 return -EIO;
424
425 *out = tmp;
426
427 return 0;
428 }
429
mhi_write_reg(struct mhi_controller * mhi_cntrl,void __iomem * addr,u32 val)430 static void mhi_write_reg(struct mhi_controller *mhi_cntrl, void __iomem *addr, u32 val)
431 {
432 writel_relaxed(val, addr);
433 }
434
mhi_runtime_get(struct mhi_controller * mhi_cntrl)435 static int mhi_runtime_get(struct mhi_controller *mhi_cntrl)
436 {
437 return 0;
438 }
439
mhi_runtime_put(struct mhi_controller * mhi_cntrl)440 static void mhi_runtime_put(struct mhi_controller *mhi_cntrl)
441 {
442 }
443
mhi_status_cb(struct mhi_controller * mhi_cntrl,enum mhi_callback reason)444 static void mhi_status_cb(struct mhi_controller *mhi_cntrl, enum mhi_callback reason)
445 {
446 struct qaic_device *qdev = pci_get_drvdata(to_pci_dev(mhi_cntrl->cntrl_dev));
447
448 /* this event occurs in atomic context */
449 if (reason == MHI_CB_FATAL_ERROR)
450 pci_err(qdev->pdev, "Fatal error received from device. Attempting to recover\n");
451 /* this event occurs in non-atomic context */
452 if (reason == MHI_CB_SYS_ERROR)
453 qaic_dev_reset_clean_local_state(qdev, true);
454 }
455
mhi_reset_and_async_power_up(struct mhi_controller * mhi_cntrl)456 static int mhi_reset_and_async_power_up(struct mhi_controller *mhi_cntrl)
457 {
458 u8 time_sec = 1;
459 int current_ee;
460 int ret;
461
462 /* Reset the device to bring the device in PBL EE */
463 mhi_soc_reset(mhi_cntrl);
464
465 /*
466 * Keep checking the execution environment(EE) after every 1 second
467 * interval.
468 */
469 do {
470 msleep(1000);
471 current_ee = mhi_get_exec_env(mhi_cntrl);
472 } while (current_ee != MHI_EE_PBL && time_sec++ <= MAX_RESET_TIME_SEC);
473
474 /* If the device is in PBL EE retry power up */
475 if (current_ee == MHI_EE_PBL)
476 ret = mhi_async_power_up(mhi_cntrl);
477 else
478 ret = -EIO;
479
480 return ret;
481 }
482
qaic_mhi_register_controller(struct pci_dev * pci_dev,void __iomem * mhi_bar,int mhi_irq)483 struct mhi_controller *qaic_mhi_register_controller(struct pci_dev *pci_dev, void __iomem *mhi_bar,
484 int mhi_irq)
485 {
486 struct mhi_controller *mhi_cntrl;
487 int ret;
488
489 mhi_cntrl = devm_kzalloc(&pci_dev->dev, sizeof(*mhi_cntrl), GFP_KERNEL);
490 if (!mhi_cntrl)
491 return ERR_PTR(-ENOMEM);
492
493 mhi_cntrl->cntrl_dev = &pci_dev->dev;
494
495 /*
496 * Covers the entire possible physical ram region. Remote side is
497 * going to calculate a size of this range, so subtract 1 to prevent
498 * rollover.
499 */
500 mhi_cntrl->iova_start = 0;
501 mhi_cntrl->iova_stop = PHYS_ADDR_MAX - 1;
502 mhi_cntrl->status_cb = mhi_status_cb;
503 mhi_cntrl->runtime_get = mhi_runtime_get;
504 mhi_cntrl->runtime_put = mhi_runtime_put;
505 mhi_cntrl->read_reg = mhi_read_reg;
506 mhi_cntrl->write_reg = mhi_write_reg;
507 mhi_cntrl->regs = mhi_bar;
508 mhi_cntrl->reg_len = SZ_4K;
509 mhi_cntrl->nr_irqs = 1;
510 mhi_cntrl->irq = devm_kmalloc(&pci_dev->dev, sizeof(*mhi_cntrl->irq), GFP_KERNEL);
511
512 if (!mhi_cntrl->irq)
513 return ERR_PTR(-ENOMEM);
514
515 mhi_cntrl->irq[0] = mhi_irq;
516 mhi_cntrl->fw_image = "qcom/aic100/sbl.bin";
517
518 /* use latest configured timeout */
519 aic100_config.timeout_ms = mhi_timeout_ms;
520 ret = mhi_register_controller(mhi_cntrl, &aic100_config);
521 if (ret) {
522 pci_err(pci_dev, "mhi_register_controller failed %d\n", ret);
523 return ERR_PTR(ret);
524 }
525
526 ret = mhi_prepare_for_power_up(mhi_cntrl);
527 if (ret) {
528 pci_err(pci_dev, "mhi_prepare_for_power_up failed %d\n", ret);
529 goto prepare_power_up_fail;
530 }
531
532 ret = mhi_async_power_up(mhi_cntrl);
533 /*
534 * If EIO is returned it is possible that device is in SBL EE, which is
535 * undesired. SOC reset the device and try to power up again.
536 */
537 if (ret == -EIO && MHI_EE_SBL == mhi_get_exec_env(mhi_cntrl)) {
538 pci_err(pci_dev, "Found device in SBL at MHI init. Attempting a reset.\n");
539 ret = mhi_reset_and_async_power_up(mhi_cntrl);
540 }
541
542 if (ret) {
543 pci_err(pci_dev, "mhi_async_power_up failed %d\n", ret);
544 goto power_up_fail;
545 }
546
547 return mhi_cntrl;
548
549 power_up_fail:
550 mhi_unprepare_after_power_down(mhi_cntrl);
551 prepare_power_up_fail:
552 mhi_unregister_controller(mhi_cntrl);
553 return ERR_PTR(ret);
554 }
555
qaic_mhi_free_controller(struct mhi_controller * mhi_cntrl,bool link_up)556 void qaic_mhi_free_controller(struct mhi_controller *mhi_cntrl, bool link_up)
557 {
558 mhi_power_down(mhi_cntrl, link_up);
559 mhi_unprepare_after_power_down(mhi_cntrl);
560 mhi_unregister_controller(mhi_cntrl);
561 }
562
qaic_mhi_start_reset(struct mhi_controller * mhi_cntrl)563 void qaic_mhi_start_reset(struct mhi_controller *mhi_cntrl)
564 {
565 mhi_power_down(mhi_cntrl, true);
566 }
567
qaic_mhi_reset_done(struct mhi_controller * mhi_cntrl)568 void qaic_mhi_reset_done(struct mhi_controller *mhi_cntrl)
569 {
570 struct pci_dev *pci_dev = container_of(mhi_cntrl->cntrl_dev, struct pci_dev, dev);
571 int ret;
572
573 ret = mhi_async_power_up(mhi_cntrl);
574 if (ret)
575 pci_err(pci_dev, "mhi_async_power_up failed after reset %d\n", ret);
576 }
577