1 // SPDX-License-Identifier: GPL-2.0-only
2 /*
3 * Qualcomm Peripheral Authentication Service remoteproc driver
4 *
5 * Copyright (C) 2016 Linaro Ltd
6 * Copyright (C) 2014 Sony Mobile Communications AB
7 * Copyright (c) 2012-2013, The Linux Foundation. All rights reserved.
8 */
9
10 #include <linux/clk.h>
11 #include <linux/delay.h>
12 #include <linux/firmware.h>
13 #include <linux/interrupt.h>
14 #include <linux/kernel.h>
15 #include <linux/module.h>
16 #include <linux/of.h>
17 #include <linux/of_address.h>
18 #include <linux/of_reserved_mem.h>
19 #include <linux/platform_device.h>
20 #include <linux/pm_domain.h>
21 #include <linux/pm_runtime.h>
22 #include <linux/firmware/qcom/qcom_scm.h>
23 #include <linux/regulator/consumer.h>
24 #include <linux/remoteproc.h>
25 #include <linux/soc/qcom/mdt_loader.h>
26 #include <linux/soc/qcom/smem.h>
27 #include <linux/soc/qcom/smem_state.h>
28
29 #include "qcom_common.h"
30 #include "qcom_pil_info.h"
31 #include "qcom_q6v5.h"
32 #include "remoteproc_internal.h"
33
34 #define QCOM_PAS_DECRYPT_SHUTDOWN_DELAY_MS 100
35
36 #define MAX_ASSIGN_COUNT 3
37
38 struct qcom_pas_data {
39 int crash_reason_smem;
40 const char *firmware_name;
41 const char *dtb_firmware_name;
42 int pas_id;
43 int dtb_pas_id;
44 int lite_pas_id;
45 unsigned int minidump_id;
46 bool auto_boot;
47 bool decrypt_shutdown;
48
49 char **proxy_pd_names;
50
51 const char *load_state;
52 const char *ssr_name;
53 const char *sysmon_name;
54 int ssctl_id;
55 unsigned int smem_host_id;
56
57 int region_assign_idx;
58 int region_assign_count;
59 bool region_assign_shared;
60 int region_assign_vmid;
61 };
62
63 struct qcom_pas {
64 struct device *dev;
65 struct rproc *rproc;
66
67 struct qcom_q6v5 q6v5;
68
69 struct clk *xo;
70 struct clk *aggre2_clk;
71
72 struct regulator *cx_supply;
73 struct regulator *px_supply;
74
75 struct device *proxy_pds[3];
76
77 int proxy_pd_count;
78
79 const char *dtb_firmware_name;
80 int pas_id;
81 int dtb_pas_id;
82 int lite_pas_id;
83 unsigned int minidump_id;
84 int crash_reason_smem;
85 unsigned int smem_host_id;
86 bool decrypt_shutdown;
87 const char *info_name;
88
89 const struct firmware *firmware;
90 const struct firmware *dtb_firmware;
91
92 struct completion start_done;
93 struct completion stop_done;
94
95 phys_addr_t mem_phys;
96 phys_addr_t dtb_mem_phys;
97 phys_addr_t mem_reloc;
98 phys_addr_t dtb_mem_reloc;
99 phys_addr_t region_assign_phys[MAX_ASSIGN_COUNT];
100 void *mem_region;
101 void *dtb_mem_region;
102 size_t mem_size;
103 size_t dtb_mem_size;
104 size_t region_assign_size[MAX_ASSIGN_COUNT];
105
106 int region_assign_idx;
107 int region_assign_count;
108 bool region_assign_shared;
109 int region_assign_vmid;
110 u64 region_assign_owners[MAX_ASSIGN_COUNT];
111
112 struct qcom_rproc_glink glink_subdev;
113 struct qcom_rproc_subdev smd_subdev;
114 struct qcom_rproc_pdm pdm_subdev;
115 struct qcom_rproc_ssr ssr_subdev;
116 struct qcom_sysmon *sysmon;
117
118 struct qcom_scm_pas_metadata pas_metadata;
119 struct qcom_scm_pas_metadata dtb_pas_metadata;
120 };
121
qcom_pas_segment_dump(struct rproc * rproc,struct rproc_dump_segment * segment,void * dest,size_t offset,size_t size)122 static void qcom_pas_segment_dump(struct rproc *rproc,
123 struct rproc_dump_segment *segment,
124 void *dest, size_t offset, size_t size)
125 {
126 struct qcom_pas *pas = rproc->priv;
127 int total_offset;
128
129 total_offset = segment->da + segment->offset + offset - pas->mem_phys;
130 if (total_offset < 0 || total_offset + size > pas->mem_size) {
131 dev_err(pas->dev,
132 "invalid copy request for segment %pad with offset %zu and size %zu)\n",
133 &segment->da, offset, size);
134 memset(dest, 0xff, size);
135 return;
136 }
137
138 memcpy_fromio(dest, pas->mem_region + total_offset, size);
139 }
140
qcom_pas_minidump(struct rproc * rproc)141 static void qcom_pas_minidump(struct rproc *rproc)
142 {
143 struct qcom_pas *pas = rproc->priv;
144
145 if (rproc->dump_conf == RPROC_COREDUMP_DISABLED)
146 return;
147
148 qcom_minidump(rproc, pas->minidump_id, qcom_pas_segment_dump);
149 }
150
qcom_pas_pds_enable(struct qcom_pas * pas,struct device ** pds,size_t pd_count)151 static int qcom_pas_pds_enable(struct qcom_pas *pas, struct device **pds,
152 size_t pd_count)
153 {
154 int ret;
155 int i;
156
157 for (i = 0; i < pd_count; i++) {
158 dev_pm_genpd_set_performance_state(pds[i], INT_MAX);
159 ret = pm_runtime_get_sync(pds[i]);
160 if (ret < 0) {
161 pm_runtime_put_noidle(pds[i]);
162 dev_pm_genpd_set_performance_state(pds[i], 0);
163 goto unroll_pd_votes;
164 }
165 }
166
167 return 0;
168
169 unroll_pd_votes:
170 for (i--; i >= 0; i--) {
171 dev_pm_genpd_set_performance_state(pds[i], 0);
172 pm_runtime_put(pds[i]);
173 }
174
175 return ret;
176 };
177
qcom_pas_pds_disable(struct qcom_pas * pas,struct device ** pds,size_t pd_count)178 static void qcom_pas_pds_disable(struct qcom_pas *pas, struct device **pds,
179 size_t pd_count)
180 {
181 int i;
182
183 for (i = 0; i < pd_count; i++) {
184 dev_pm_genpd_set_performance_state(pds[i], 0);
185 pm_runtime_put(pds[i]);
186 }
187 }
188
qcom_pas_shutdown_poll_decrypt(struct qcom_pas * pas)189 static int qcom_pas_shutdown_poll_decrypt(struct qcom_pas *pas)
190 {
191 unsigned int retry_num = 50;
192 int ret;
193
194 do {
195 msleep(QCOM_PAS_DECRYPT_SHUTDOWN_DELAY_MS);
196 ret = qcom_scm_pas_shutdown(pas->pas_id);
197 } while (ret == -EINVAL && --retry_num);
198
199 return ret;
200 }
201
qcom_pas_unprepare(struct rproc * rproc)202 static int qcom_pas_unprepare(struct rproc *rproc)
203 {
204 struct qcom_pas *pas = rproc->priv;
205
206 /*
207 * qcom_pas_load() did pass pas_metadata to the SCM driver for storing
208 * metadata context. It might have been released already if
209 * auth_and_reset() was successful, but in other cases clean it up
210 * here.
211 */
212 qcom_scm_pas_metadata_release(&pas->pas_metadata);
213 if (pas->dtb_pas_id)
214 qcom_scm_pas_metadata_release(&pas->dtb_pas_metadata);
215
216 return 0;
217 }
218
qcom_pas_load(struct rproc * rproc,const struct firmware * fw)219 static int qcom_pas_load(struct rproc *rproc, const struct firmware *fw)
220 {
221 struct qcom_pas *pas = rproc->priv;
222 int ret;
223
224 /* Store firmware handle to be used in qcom_pas_start() */
225 pas->firmware = fw;
226
227 if (pas->lite_pas_id)
228 ret = qcom_scm_pas_shutdown(pas->lite_pas_id);
229
230 if (pas->dtb_pas_id) {
231 ret = request_firmware(&pas->dtb_firmware, pas->dtb_firmware_name, pas->dev);
232 if (ret) {
233 dev_err(pas->dev, "request_firmware failed for %s: %d\n",
234 pas->dtb_firmware_name, ret);
235 return ret;
236 }
237
238 ret = qcom_mdt_pas_init(pas->dev, pas->dtb_firmware, pas->dtb_firmware_name,
239 pas->dtb_pas_id, pas->dtb_mem_phys,
240 &pas->dtb_pas_metadata);
241 if (ret)
242 goto release_dtb_firmware;
243
244 ret = qcom_mdt_load_no_init(pas->dev, pas->dtb_firmware, pas->dtb_firmware_name,
245 pas->dtb_pas_id, pas->dtb_mem_region,
246 pas->dtb_mem_phys, pas->dtb_mem_size,
247 &pas->dtb_mem_reloc);
248 if (ret)
249 goto release_dtb_metadata;
250 }
251
252 return 0;
253
254 release_dtb_metadata:
255 qcom_scm_pas_metadata_release(&pas->dtb_pas_metadata);
256
257 release_dtb_firmware:
258 release_firmware(pas->dtb_firmware);
259
260 return ret;
261 }
262
qcom_pas_start(struct rproc * rproc)263 static int qcom_pas_start(struct rproc *rproc)
264 {
265 struct qcom_pas *pas = rproc->priv;
266 int ret;
267
268 ret = qcom_q6v5_prepare(&pas->q6v5);
269 if (ret)
270 return ret;
271
272 ret = qcom_pas_pds_enable(pas, pas->proxy_pds, pas->proxy_pd_count);
273 if (ret < 0)
274 goto disable_irqs;
275
276 ret = clk_prepare_enable(pas->xo);
277 if (ret)
278 goto disable_proxy_pds;
279
280 ret = clk_prepare_enable(pas->aggre2_clk);
281 if (ret)
282 goto disable_xo_clk;
283
284 if (pas->cx_supply) {
285 ret = regulator_enable(pas->cx_supply);
286 if (ret)
287 goto disable_aggre2_clk;
288 }
289
290 if (pas->px_supply) {
291 ret = regulator_enable(pas->px_supply);
292 if (ret)
293 goto disable_cx_supply;
294 }
295
296 if (pas->dtb_pas_id) {
297 ret = qcom_scm_pas_auth_and_reset(pas->dtb_pas_id);
298 if (ret) {
299 dev_err(pas->dev,
300 "failed to authenticate dtb image and release reset\n");
301 goto disable_px_supply;
302 }
303 }
304
305 ret = qcom_mdt_pas_init(pas->dev, pas->firmware, rproc->firmware, pas->pas_id,
306 pas->mem_phys, &pas->pas_metadata);
307 if (ret)
308 goto disable_px_supply;
309
310 ret = qcom_mdt_load_no_init(pas->dev, pas->firmware, rproc->firmware, pas->pas_id,
311 pas->mem_region, pas->mem_phys, pas->mem_size,
312 &pas->mem_reloc);
313 if (ret)
314 goto release_pas_metadata;
315
316 qcom_pil_info_store(pas->info_name, pas->mem_phys, pas->mem_size);
317
318 ret = qcom_scm_pas_auth_and_reset(pas->pas_id);
319 if (ret) {
320 dev_err(pas->dev,
321 "failed to authenticate image and release reset\n");
322 goto release_pas_metadata;
323 }
324
325 ret = qcom_q6v5_wait_for_start(&pas->q6v5, msecs_to_jiffies(5000));
326 if (ret == -ETIMEDOUT) {
327 dev_err(pas->dev, "start timed out\n");
328 qcom_scm_pas_shutdown(pas->pas_id);
329 goto release_pas_metadata;
330 }
331
332 qcom_scm_pas_metadata_release(&pas->pas_metadata);
333 if (pas->dtb_pas_id)
334 qcom_scm_pas_metadata_release(&pas->dtb_pas_metadata);
335
336 /* firmware is used to pass reference from qcom_pas_start(), drop it now */
337 pas->firmware = NULL;
338
339 return 0;
340
341 release_pas_metadata:
342 qcom_scm_pas_metadata_release(&pas->pas_metadata);
343 if (pas->dtb_pas_id)
344 qcom_scm_pas_metadata_release(&pas->dtb_pas_metadata);
345 disable_px_supply:
346 if (pas->px_supply)
347 regulator_disable(pas->px_supply);
348 disable_cx_supply:
349 if (pas->cx_supply)
350 regulator_disable(pas->cx_supply);
351 disable_aggre2_clk:
352 clk_disable_unprepare(pas->aggre2_clk);
353 disable_xo_clk:
354 clk_disable_unprepare(pas->xo);
355 disable_proxy_pds:
356 qcom_pas_pds_disable(pas, pas->proxy_pds, pas->proxy_pd_count);
357 disable_irqs:
358 qcom_q6v5_unprepare(&pas->q6v5);
359
360 /* firmware is used to pass reference from qcom_pas_start(), drop it now */
361 pas->firmware = NULL;
362
363 return ret;
364 }
365
qcom_pas_handover(struct qcom_q6v5 * q6v5)366 static void qcom_pas_handover(struct qcom_q6v5 *q6v5)
367 {
368 struct qcom_pas *pas = container_of(q6v5, struct qcom_pas, q6v5);
369
370 if (pas->px_supply)
371 regulator_disable(pas->px_supply);
372 if (pas->cx_supply)
373 regulator_disable(pas->cx_supply);
374 clk_disable_unprepare(pas->aggre2_clk);
375 clk_disable_unprepare(pas->xo);
376 qcom_pas_pds_disable(pas, pas->proxy_pds, pas->proxy_pd_count);
377 }
378
qcom_pas_stop(struct rproc * rproc)379 static int qcom_pas_stop(struct rproc *rproc)
380 {
381 struct qcom_pas *pas = rproc->priv;
382 int handover;
383 int ret;
384
385 ret = qcom_q6v5_request_stop(&pas->q6v5, pas->sysmon);
386 if (ret == -ETIMEDOUT)
387 dev_err(pas->dev, "timed out on wait\n");
388
389 ret = qcom_scm_pas_shutdown(pas->pas_id);
390 if (ret && pas->decrypt_shutdown)
391 ret = qcom_pas_shutdown_poll_decrypt(pas);
392
393 if (ret)
394 dev_err(pas->dev, "failed to shutdown: %d\n", ret);
395
396 if (pas->dtb_pas_id) {
397 ret = qcom_scm_pas_shutdown(pas->dtb_pas_id);
398 if (ret)
399 dev_err(pas->dev, "failed to shutdown dtb: %d\n", ret);
400 }
401
402 handover = qcom_q6v5_unprepare(&pas->q6v5);
403 if (handover)
404 qcom_pas_handover(&pas->q6v5);
405
406 if (pas->smem_host_id)
407 ret = qcom_smem_bust_hwspin_lock_by_host(pas->smem_host_id);
408
409 return ret;
410 }
411
qcom_pas_da_to_va(struct rproc * rproc,u64 da,size_t len,bool * is_iomem)412 static void *qcom_pas_da_to_va(struct rproc *rproc, u64 da, size_t len, bool *is_iomem)
413 {
414 struct qcom_pas *pas = rproc->priv;
415 int offset;
416
417 offset = da - pas->mem_reloc;
418 if (offset < 0 || offset + len > pas->mem_size)
419 return NULL;
420
421 if (is_iomem)
422 *is_iomem = true;
423
424 return pas->mem_region + offset;
425 }
426
qcom_pas_panic(struct rproc * rproc)427 static unsigned long qcom_pas_panic(struct rproc *rproc)
428 {
429 struct qcom_pas *pas = rproc->priv;
430
431 return qcom_q6v5_panic(&pas->q6v5);
432 }
433
434 static const struct rproc_ops qcom_pas_ops = {
435 .unprepare = qcom_pas_unprepare,
436 .start = qcom_pas_start,
437 .stop = qcom_pas_stop,
438 .da_to_va = qcom_pas_da_to_va,
439 .parse_fw = qcom_register_dump_segments,
440 .load = qcom_pas_load,
441 .panic = qcom_pas_panic,
442 };
443
444 static const struct rproc_ops qcom_pas_minidump_ops = {
445 .unprepare = qcom_pas_unprepare,
446 .start = qcom_pas_start,
447 .stop = qcom_pas_stop,
448 .da_to_va = qcom_pas_da_to_va,
449 .parse_fw = qcom_register_dump_segments,
450 .load = qcom_pas_load,
451 .panic = qcom_pas_panic,
452 .coredump = qcom_pas_minidump,
453 };
454
qcom_pas_init_clock(struct qcom_pas * pas)455 static int qcom_pas_init_clock(struct qcom_pas *pas)
456 {
457 pas->xo = devm_clk_get(pas->dev, "xo");
458 if (IS_ERR(pas->xo))
459 return dev_err_probe(pas->dev, PTR_ERR(pas->xo),
460 "failed to get xo clock");
461
462 pas->aggre2_clk = devm_clk_get_optional(pas->dev, "aggre2");
463 if (IS_ERR(pas->aggre2_clk))
464 return dev_err_probe(pas->dev, PTR_ERR(pas->aggre2_clk),
465 "failed to get aggre2 clock");
466
467 return 0;
468 }
469
qcom_pas_init_regulator(struct qcom_pas * pas)470 static int qcom_pas_init_regulator(struct qcom_pas *pas)
471 {
472 pas->cx_supply = devm_regulator_get_optional(pas->dev, "cx");
473 if (IS_ERR(pas->cx_supply)) {
474 if (PTR_ERR(pas->cx_supply) == -ENODEV)
475 pas->cx_supply = NULL;
476 else
477 return PTR_ERR(pas->cx_supply);
478 }
479
480 if (pas->cx_supply)
481 regulator_set_load(pas->cx_supply, 100000);
482
483 pas->px_supply = devm_regulator_get_optional(pas->dev, "px");
484 if (IS_ERR(pas->px_supply)) {
485 if (PTR_ERR(pas->px_supply) == -ENODEV)
486 pas->px_supply = NULL;
487 else
488 return PTR_ERR(pas->px_supply);
489 }
490
491 return 0;
492 }
493
qcom_pas_pds_attach(struct device * dev,struct device ** devs,char ** pd_names)494 static int qcom_pas_pds_attach(struct device *dev, struct device **devs, char **pd_names)
495 {
496 size_t num_pds = 0;
497 int ret;
498 int i;
499
500 if (!pd_names)
501 return 0;
502
503 while (pd_names[num_pds])
504 num_pds++;
505
506 /* Handle single power domain */
507 if (num_pds == 1 && dev->pm_domain) {
508 devs[0] = dev;
509 pm_runtime_enable(dev);
510 return 1;
511 }
512
513 for (i = 0; i < num_pds; i++) {
514 devs[i] = dev_pm_domain_attach_by_name(dev, pd_names[i]);
515 if (IS_ERR_OR_NULL(devs[i])) {
516 ret = PTR_ERR(devs[i]) ? : -ENODATA;
517 goto unroll_attach;
518 }
519 }
520
521 return num_pds;
522
523 unroll_attach:
524 for (i--; i >= 0; i--)
525 dev_pm_domain_detach(devs[i], false);
526
527 return ret;
528 };
529
qcom_pas_pds_detach(struct qcom_pas * pas,struct device ** pds,size_t pd_count)530 static void qcom_pas_pds_detach(struct qcom_pas *pas, struct device **pds, size_t pd_count)
531 {
532 struct device *dev = pas->dev;
533 int i;
534
535 /* Handle single power domain */
536 if (pd_count == 1 && dev->pm_domain) {
537 pm_runtime_disable(dev);
538 return;
539 }
540
541 for (i = 0; i < pd_count; i++)
542 dev_pm_domain_detach(pds[i], false);
543 }
544
qcom_pas_alloc_memory_region(struct qcom_pas * pas)545 static int qcom_pas_alloc_memory_region(struct qcom_pas *pas)
546 {
547 struct reserved_mem *rmem;
548 struct device_node *node;
549
550 node = of_parse_phandle(pas->dev->of_node, "memory-region", 0);
551 if (!node) {
552 dev_err(pas->dev, "no memory-region specified\n");
553 return -EINVAL;
554 }
555
556 rmem = of_reserved_mem_lookup(node);
557 of_node_put(node);
558 if (!rmem) {
559 dev_err(pas->dev, "unable to resolve memory-region\n");
560 return -EINVAL;
561 }
562
563 pas->mem_phys = pas->mem_reloc = rmem->base;
564 pas->mem_size = rmem->size;
565 pas->mem_region = devm_ioremap_wc(pas->dev, pas->mem_phys, pas->mem_size);
566 if (!pas->mem_region) {
567 dev_err(pas->dev, "unable to map memory region: %pa+%zx\n",
568 &rmem->base, pas->mem_size);
569 return -EBUSY;
570 }
571
572 if (!pas->dtb_pas_id)
573 return 0;
574
575 node = of_parse_phandle(pas->dev->of_node, "memory-region", 1);
576 if (!node) {
577 dev_err(pas->dev, "no dtb memory-region specified\n");
578 return -EINVAL;
579 }
580
581 rmem = of_reserved_mem_lookup(node);
582 of_node_put(node);
583 if (!rmem) {
584 dev_err(pas->dev, "unable to resolve dtb memory-region\n");
585 return -EINVAL;
586 }
587
588 pas->dtb_mem_phys = pas->dtb_mem_reloc = rmem->base;
589 pas->dtb_mem_size = rmem->size;
590 pas->dtb_mem_region = devm_ioremap_wc(pas->dev, pas->dtb_mem_phys, pas->dtb_mem_size);
591 if (!pas->dtb_mem_region) {
592 dev_err(pas->dev, "unable to map dtb memory region: %pa+%zx\n",
593 &rmem->base, pas->dtb_mem_size);
594 return -EBUSY;
595 }
596
597 return 0;
598 }
599
qcom_pas_assign_memory_region(struct qcom_pas * pas)600 static int qcom_pas_assign_memory_region(struct qcom_pas *pas)
601 {
602 struct qcom_scm_vmperm perm[MAX_ASSIGN_COUNT];
603 struct device_node *node;
604 unsigned int perm_size;
605 int offset;
606 int ret;
607
608 if (!pas->region_assign_idx)
609 return 0;
610
611 for (offset = 0; offset < pas->region_assign_count; ++offset) {
612 struct reserved_mem *rmem = NULL;
613
614 node = of_parse_phandle(pas->dev->of_node, "memory-region",
615 pas->region_assign_idx + offset);
616 if (node)
617 rmem = of_reserved_mem_lookup(node);
618 of_node_put(node);
619 if (!rmem) {
620 dev_err(pas->dev, "unable to resolve shareable memory-region index %d\n",
621 offset);
622 return -EINVAL;
623 }
624
625 if (pas->region_assign_shared) {
626 perm[0].vmid = QCOM_SCM_VMID_HLOS;
627 perm[0].perm = QCOM_SCM_PERM_RW;
628 perm[1].vmid = pas->region_assign_vmid;
629 perm[1].perm = QCOM_SCM_PERM_RW;
630 perm_size = 2;
631 } else {
632 perm[0].vmid = pas->region_assign_vmid;
633 perm[0].perm = QCOM_SCM_PERM_RW;
634 perm_size = 1;
635 }
636
637 pas->region_assign_phys[offset] = rmem->base;
638 pas->region_assign_size[offset] = rmem->size;
639 pas->region_assign_owners[offset] = BIT(QCOM_SCM_VMID_HLOS);
640
641 ret = qcom_scm_assign_mem(pas->region_assign_phys[offset],
642 pas->region_assign_size[offset],
643 &pas->region_assign_owners[offset],
644 perm, perm_size);
645 if (ret < 0) {
646 dev_err(pas->dev, "assign memory %d failed\n", offset);
647 return ret;
648 }
649 }
650
651 return 0;
652 }
653
qcom_pas_unassign_memory_region(struct qcom_pas * pas)654 static void qcom_pas_unassign_memory_region(struct qcom_pas *pas)
655 {
656 struct qcom_scm_vmperm perm;
657 int offset;
658 int ret;
659
660 if (!pas->region_assign_idx || pas->region_assign_shared)
661 return;
662
663 for (offset = 0; offset < pas->region_assign_count; ++offset) {
664 perm.vmid = QCOM_SCM_VMID_HLOS;
665 perm.perm = QCOM_SCM_PERM_RW;
666
667 ret = qcom_scm_assign_mem(pas->region_assign_phys[offset],
668 pas->region_assign_size[offset],
669 &pas->region_assign_owners[offset],
670 &perm, 1);
671 if (ret < 0)
672 dev_err(pas->dev, "unassign memory %d failed\n", offset);
673 }
674 }
675
qcom_pas_probe(struct platform_device * pdev)676 static int qcom_pas_probe(struct platform_device *pdev)
677 {
678 const struct qcom_pas_data *desc;
679 struct qcom_pas *pas;
680 struct rproc *rproc;
681 const char *fw_name, *dtb_fw_name = NULL;
682 const struct rproc_ops *ops = &qcom_pas_ops;
683 int ret;
684
685 desc = of_device_get_match_data(&pdev->dev);
686 if (!desc)
687 return -EINVAL;
688
689 if (!qcom_scm_is_available())
690 return -EPROBE_DEFER;
691
692 fw_name = desc->firmware_name;
693 ret = of_property_read_string(pdev->dev.of_node, "firmware-name",
694 &fw_name);
695 if (ret < 0 && ret != -EINVAL)
696 return ret;
697
698 if (desc->dtb_firmware_name) {
699 dtb_fw_name = desc->dtb_firmware_name;
700 ret = of_property_read_string_index(pdev->dev.of_node, "firmware-name", 1,
701 &dtb_fw_name);
702 if (ret < 0 && ret != -EINVAL)
703 return ret;
704 }
705
706 if (desc->minidump_id)
707 ops = &qcom_pas_minidump_ops;
708
709 rproc = devm_rproc_alloc(&pdev->dev, desc->sysmon_name, ops, fw_name, sizeof(*pas));
710
711 if (!rproc) {
712 dev_err(&pdev->dev, "unable to allocate remoteproc\n");
713 return -ENOMEM;
714 }
715
716 rproc->auto_boot = desc->auto_boot;
717 rproc_coredump_set_elf_info(rproc, ELFCLASS32, EM_NONE);
718
719 pas = rproc->priv;
720 pas->dev = &pdev->dev;
721 pas->rproc = rproc;
722 pas->minidump_id = desc->minidump_id;
723 pas->pas_id = desc->pas_id;
724 pas->lite_pas_id = desc->lite_pas_id;
725 pas->info_name = desc->sysmon_name;
726 pas->smem_host_id = desc->smem_host_id;
727 pas->decrypt_shutdown = desc->decrypt_shutdown;
728 pas->region_assign_idx = desc->region_assign_idx;
729 pas->region_assign_count = min_t(int, MAX_ASSIGN_COUNT, desc->region_assign_count);
730 pas->region_assign_vmid = desc->region_assign_vmid;
731 pas->region_assign_shared = desc->region_assign_shared;
732 if (dtb_fw_name) {
733 pas->dtb_firmware_name = dtb_fw_name;
734 pas->dtb_pas_id = desc->dtb_pas_id;
735 }
736 platform_set_drvdata(pdev, pas);
737
738 ret = device_init_wakeup(pas->dev, true);
739 if (ret)
740 goto free_rproc;
741
742 ret = qcom_pas_alloc_memory_region(pas);
743 if (ret)
744 goto free_rproc;
745
746 ret = qcom_pas_assign_memory_region(pas);
747 if (ret)
748 goto free_rproc;
749
750 ret = qcom_pas_init_clock(pas);
751 if (ret)
752 goto unassign_mem;
753
754 ret = qcom_pas_init_regulator(pas);
755 if (ret)
756 goto unassign_mem;
757
758 ret = qcom_pas_pds_attach(&pdev->dev, pas->proxy_pds, desc->proxy_pd_names);
759 if (ret < 0)
760 goto unassign_mem;
761 pas->proxy_pd_count = ret;
762
763 ret = qcom_q6v5_init(&pas->q6v5, pdev, rproc, desc->crash_reason_smem,
764 desc->load_state, qcom_pas_handover);
765 if (ret)
766 goto detach_proxy_pds;
767
768 qcom_add_glink_subdev(rproc, &pas->glink_subdev, desc->ssr_name);
769 qcom_add_smd_subdev(rproc, &pas->smd_subdev);
770 qcom_add_pdm_subdev(rproc, &pas->pdm_subdev);
771 pas->sysmon = qcom_add_sysmon_subdev(rproc, desc->sysmon_name, desc->ssctl_id);
772 if (IS_ERR(pas->sysmon)) {
773 ret = PTR_ERR(pas->sysmon);
774 goto deinit_remove_pdm_smd_glink;
775 }
776
777 qcom_add_ssr_subdev(rproc, &pas->ssr_subdev, desc->ssr_name);
778 ret = rproc_add(rproc);
779 if (ret)
780 goto remove_ssr_sysmon;
781
782 return 0;
783
784 remove_ssr_sysmon:
785 qcom_remove_ssr_subdev(rproc, &pas->ssr_subdev);
786 qcom_remove_sysmon_subdev(pas->sysmon);
787 deinit_remove_pdm_smd_glink:
788 qcom_remove_pdm_subdev(rproc, &pas->pdm_subdev);
789 qcom_remove_smd_subdev(rproc, &pas->smd_subdev);
790 qcom_remove_glink_subdev(rproc, &pas->glink_subdev);
791 qcom_q6v5_deinit(&pas->q6v5);
792 detach_proxy_pds:
793 qcom_pas_pds_detach(pas, pas->proxy_pds, pas->proxy_pd_count);
794 unassign_mem:
795 qcom_pas_unassign_memory_region(pas);
796 free_rproc:
797 device_init_wakeup(pas->dev, false);
798
799 return ret;
800 }
801
qcom_pas_remove(struct platform_device * pdev)802 static void qcom_pas_remove(struct platform_device *pdev)
803 {
804 struct qcom_pas *pas = platform_get_drvdata(pdev);
805
806 rproc_del(pas->rproc);
807
808 qcom_q6v5_deinit(&pas->q6v5);
809 qcom_pas_unassign_memory_region(pas);
810 qcom_remove_glink_subdev(pas->rproc, &pas->glink_subdev);
811 qcom_remove_sysmon_subdev(pas->sysmon);
812 qcom_remove_smd_subdev(pas->rproc, &pas->smd_subdev);
813 qcom_remove_pdm_subdev(pas->rproc, &pas->pdm_subdev);
814 qcom_remove_ssr_subdev(pas->rproc, &pas->ssr_subdev);
815 qcom_pas_pds_detach(pas, pas->proxy_pds, pas->proxy_pd_count);
816 device_init_wakeup(pas->dev, false);
817 }
818
819 static const struct qcom_pas_data adsp_resource_init = {
820 .crash_reason_smem = 423,
821 .firmware_name = "adsp.mdt",
822 .pas_id = 1,
823 .auto_boot = true,
824 .ssr_name = "lpass",
825 .sysmon_name = "adsp",
826 .ssctl_id = 0x14,
827 };
828
829 static const struct qcom_pas_data sa8775p_adsp_resource = {
830 .crash_reason_smem = 423,
831 .firmware_name = "adsp.mbn",
832 .pas_id = 1,
833 .minidump_id = 5,
834 .auto_boot = true,
835 .proxy_pd_names = (char*[]){
836 "lcx",
837 "lmx",
838 NULL
839 },
840 .load_state = "adsp",
841 .ssr_name = "lpass",
842 .sysmon_name = "adsp",
843 .ssctl_id = 0x14,
844 };
845
846 static const struct qcom_pas_data sdm845_adsp_resource_init = {
847 .crash_reason_smem = 423,
848 .firmware_name = "adsp.mdt",
849 .pas_id = 1,
850 .auto_boot = true,
851 .load_state = "adsp",
852 .ssr_name = "lpass",
853 .sysmon_name = "adsp",
854 .ssctl_id = 0x14,
855 };
856
857 static const struct qcom_pas_data sm6350_adsp_resource = {
858 .crash_reason_smem = 423,
859 .firmware_name = "adsp.mdt",
860 .pas_id = 1,
861 .auto_boot = true,
862 .proxy_pd_names = (char*[]){
863 "lcx",
864 "lmx",
865 NULL
866 },
867 .load_state = "adsp",
868 .ssr_name = "lpass",
869 .sysmon_name = "adsp",
870 .ssctl_id = 0x14,
871 };
872
873 static const struct qcom_pas_data sm6375_mpss_resource = {
874 .crash_reason_smem = 421,
875 .firmware_name = "modem.mdt",
876 .pas_id = 4,
877 .minidump_id = 3,
878 .auto_boot = false,
879 .proxy_pd_names = (char*[]){
880 "cx",
881 NULL
882 },
883 .ssr_name = "mpss",
884 .sysmon_name = "modem",
885 .ssctl_id = 0x12,
886 };
887
888 static const struct qcom_pas_data sm8150_adsp_resource = {
889 .crash_reason_smem = 423,
890 .firmware_name = "adsp.mdt",
891 .pas_id = 1,
892 .auto_boot = true,
893 .proxy_pd_names = (char*[]){
894 "cx",
895 NULL
896 },
897 .load_state = "adsp",
898 .ssr_name = "lpass",
899 .sysmon_name = "adsp",
900 .ssctl_id = 0x14,
901 };
902
903 static const struct qcom_pas_data sm8250_adsp_resource = {
904 .crash_reason_smem = 423,
905 .firmware_name = "adsp.mdt",
906 .pas_id = 1,
907 .minidump_id = 5,
908 .auto_boot = true,
909 .proxy_pd_names = (char*[]){
910 "lcx",
911 "lmx",
912 NULL
913 },
914 .load_state = "adsp",
915 .ssr_name = "lpass",
916 .sysmon_name = "adsp",
917 .ssctl_id = 0x14,
918 };
919
920 static const struct qcom_pas_data sm8350_adsp_resource = {
921 .crash_reason_smem = 423,
922 .firmware_name = "adsp.mdt",
923 .pas_id = 1,
924 .auto_boot = true,
925 .proxy_pd_names = (char*[]){
926 "lcx",
927 "lmx",
928 NULL
929 },
930 .load_state = "adsp",
931 .ssr_name = "lpass",
932 .sysmon_name = "adsp",
933 .ssctl_id = 0x14,
934 };
935
936 static const struct qcom_pas_data msm8996_adsp_resource = {
937 .crash_reason_smem = 423,
938 .firmware_name = "adsp.mdt",
939 .pas_id = 1,
940 .auto_boot = true,
941 .proxy_pd_names = (char*[]){
942 "cx",
943 NULL
944 },
945 .ssr_name = "lpass",
946 .sysmon_name = "adsp",
947 .ssctl_id = 0x14,
948 };
949
950 static const struct qcom_pas_data cdsp_resource_init = {
951 .crash_reason_smem = 601,
952 .firmware_name = "cdsp.mdt",
953 .pas_id = 18,
954 .auto_boot = true,
955 .ssr_name = "cdsp",
956 .sysmon_name = "cdsp",
957 .ssctl_id = 0x17,
958 };
959
960 static const struct qcom_pas_data sa8775p_cdsp0_resource = {
961 .crash_reason_smem = 601,
962 .firmware_name = "cdsp0.mbn",
963 .pas_id = 18,
964 .minidump_id = 7,
965 .auto_boot = true,
966 .proxy_pd_names = (char*[]){
967 "cx",
968 "mxc",
969 "nsp",
970 NULL
971 },
972 .load_state = "cdsp",
973 .ssr_name = "cdsp",
974 .sysmon_name = "cdsp",
975 .ssctl_id = 0x17,
976 };
977
978 static const struct qcom_pas_data sa8775p_cdsp1_resource = {
979 .crash_reason_smem = 633,
980 .firmware_name = "cdsp1.mbn",
981 .pas_id = 30,
982 .minidump_id = 20,
983 .auto_boot = true,
984 .proxy_pd_names = (char*[]){
985 "cx",
986 "mxc",
987 "nsp",
988 NULL
989 },
990 .load_state = "nsp",
991 .ssr_name = "cdsp1",
992 .sysmon_name = "cdsp1",
993 .ssctl_id = 0x20,
994 };
995
996 static const struct qcom_pas_data sdm845_cdsp_resource_init = {
997 .crash_reason_smem = 601,
998 .firmware_name = "cdsp.mdt",
999 .pas_id = 18,
1000 .auto_boot = true,
1001 .load_state = "cdsp",
1002 .ssr_name = "cdsp",
1003 .sysmon_name = "cdsp",
1004 .ssctl_id = 0x17,
1005 };
1006
1007 static const struct qcom_pas_data sm6350_cdsp_resource = {
1008 .crash_reason_smem = 601,
1009 .firmware_name = "cdsp.mdt",
1010 .pas_id = 18,
1011 .auto_boot = true,
1012 .proxy_pd_names = (char*[]){
1013 "cx",
1014 "mx",
1015 NULL
1016 },
1017 .load_state = "cdsp",
1018 .ssr_name = "cdsp",
1019 .sysmon_name = "cdsp",
1020 .ssctl_id = 0x17,
1021 };
1022
1023 static const struct qcom_pas_data sm8150_cdsp_resource = {
1024 .crash_reason_smem = 601,
1025 .firmware_name = "cdsp.mdt",
1026 .pas_id = 18,
1027 .auto_boot = true,
1028 .proxy_pd_names = (char*[]){
1029 "cx",
1030 NULL
1031 },
1032 .load_state = "cdsp",
1033 .ssr_name = "cdsp",
1034 .sysmon_name = "cdsp",
1035 .ssctl_id = 0x17,
1036 };
1037
1038 static const struct qcom_pas_data sm8250_cdsp_resource = {
1039 .crash_reason_smem = 601,
1040 .firmware_name = "cdsp.mdt",
1041 .pas_id = 18,
1042 .auto_boot = true,
1043 .proxy_pd_names = (char*[]){
1044 "cx",
1045 NULL
1046 },
1047 .load_state = "cdsp",
1048 .ssr_name = "cdsp",
1049 .sysmon_name = "cdsp",
1050 .ssctl_id = 0x17,
1051 };
1052
1053 static const struct qcom_pas_data sc8280xp_nsp0_resource = {
1054 .crash_reason_smem = 601,
1055 .firmware_name = "cdsp.mdt",
1056 .pas_id = 18,
1057 .auto_boot = true,
1058 .proxy_pd_names = (char*[]){
1059 "nsp",
1060 NULL
1061 },
1062 .ssr_name = "cdsp0",
1063 .sysmon_name = "cdsp",
1064 .ssctl_id = 0x17,
1065 };
1066
1067 static const struct qcom_pas_data sc8280xp_nsp1_resource = {
1068 .crash_reason_smem = 633,
1069 .firmware_name = "cdsp.mdt",
1070 .pas_id = 30,
1071 .auto_boot = true,
1072 .proxy_pd_names = (char*[]){
1073 "nsp",
1074 NULL
1075 },
1076 .ssr_name = "cdsp1",
1077 .sysmon_name = "cdsp1",
1078 .ssctl_id = 0x20,
1079 };
1080
1081 static const struct qcom_pas_data x1e80100_adsp_resource = {
1082 .crash_reason_smem = 423,
1083 .firmware_name = "adsp.mdt",
1084 .dtb_firmware_name = "adsp_dtb.mdt",
1085 .pas_id = 1,
1086 .dtb_pas_id = 0x24,
1087 .lite_pas_id = 0x1f,
1088 .minidump_id = 5,
1089 .auto_boot = true,
1090 .proxy_pd_names = (char*[]){
1091 "lcx",
1092 "lmx",
1093 NULL
1094 },
1095 .load_state = "adsp",
1096 .ssr_name = "lpass",
1097 .sysmon_name = "adsp",
1098 .ssctl_id = 0x14,
1099 };
1100
1101 static const struct qcom_pas_data x1e80100_cdsp_resource = {
1102 .crash_reason_smem = 601,
1103 .firmware_name = "cdsp.mdt",
1104 .dtb_firmware_name = "cdsp_dtb.mdt",
1105 .pas_id = 18,
1106 .dtb_pas_id = 0x25,
1107 .minidump_id = 7,
1108 .auto_boot = true,
1109 .proxy_pd_names = (char*[]){
1110 "cx",
1111 "mxc",
1112 "nsp",
1113 NULL
1114 },
1115 .load_state = "cdsp",
1116 .ssr_name = "cdsp",
1117 .sysmon_name = "cdsp",
1118 .ssctl_id = 0x17,
1119 };
1120
1121 static const struct qcom_pas_data sm8350_cdsp_resource = {
1122 .crash_reason_smem = 601,
1123 .firmware_name = "cdsp.mdt",
1124 .pas_id = 18,
1125 .minidump_id = 7,
1126 .auto_boot = true,
1127 .proxy_pd_names = (char*[]){
1128 "cx",
1129 "mxc",
1130 NULL
1131 },
1132 .load_state = "cdsp",
1133 .ssr_name = "cdsp",
1134 .sysmon_name = "cdsp",
1135 .ssctl_id = 0x17,
1136 };
1137
1138 static const struct qcom_pas_data sa8775p_gpdsp0_resource = {
1139 .crash_reason_smem = 640,
1140 .firmware_name = "gpdsp0.mbn",
1141 .pas_id = 39,
1142 .minidump_id = 21,
1143 .auto_boot = true,
1144 .proxy_pd_names = (char*[]){
1145 "cx",
1146 "mxc",
1147 NULL
1148 },
1149 .load_state = "gpdsp0",
1150 .ssr_name = "gpdsp0",
1151 .sysmon_name = "gpdsp0",
1152 .ssctl_id = 0x21,
1153 };
1154
1155 static const struct qcom_pas_data sa8775p_gpdsp1_resource = {
1156 .crash_reason_smem = 641,
1157 .firmware_name = "gpdsp1.mbn",
1158 .pas_id = 40,
1159 .minidump_id = 22,
1160 .auto_boot = true,
1161 .proxy_pd_names = (char*[]){
1162 "cx",
1163 "mxc",
1164 NULL
1165 },
1166 .load_state = "gpdsp1",
1167 .ssr_name = "gpdsp1",
1168 .sysmon_name = "gpdsp1",
1169 .ssctl_id = 0x22,
1170 };
1171
1172 static const struct qcom_pas_data mpss_resource_init = {
1173 .crash_reason_smem = 421,
1174 .firmware_name = "modem.mdt",
1175 .pas_id = 4,
1176 .minidump_id = 3,
1177 .auto_boot = false,
1178 .proxy_pd_names = (char*[]){
1179 "cx",
1180 "mss",
1181 NULL
1182 },
1183 .load_state = "modem",
1184 .ssr_name = "mpss",
1185 .sysmon_name = "modem",
1186 .ssctl_id = 0x12,
1187 };
1188
1189 static const struct qcom_pas_data sc8180x_mpss_resource = {
1190 .crash_reason_smem = 421,
1191 .firmware_name = "modem.mdt",
1192 .pas_id = 4,
1193 .auto_boot = false,
1194 .proxy_pd_names = (char*[]){
1195 "cx",
1196 NULL
1197 },
1198 .load_state = "modem",
1199 .ssr_name = "mpss",
1200 .sysmon_name = "modem",
1201 .ssctl_id = 0x12,
1202 };
1203
1204 static const struct qcom_pas_data msm8996_slpi_resource_init = {
1205 .crash_reason_smem = 424,
1206 .firmware_name = "slpi.mdt",
1207 .pas_id = 12,
1208 .auto_boot = true,
1209 .proxy_pd_names = (char*[]){
1210 "ssc_cx",
1211 NULL
1212 },
1213 .ssr_name = "dsps",
1214 .sysmon_name = "slpi",
1215 .ssctl_id = 0x16,
1216 };
1217
1218 static const struct qcom_pas_data sdm845_slpi_resource_init = {
1219 .crash_reason_smem = 424,
1220 .firmware_name = "slpi.mdt",
1221 .pas_id = 12,
1222 .auto_boot = true,
1223 .proxy_pd_names = (char*[]){
1224 "lcx",
1225 "lmx",
1226 NULL
1227 },
1228 .load_state = "slpi",
1229 .ssr_name = "dsps",
1230 .sysmon_name = "slpi",
1231 .ssctl_id = 0x16,
1232 };
1233
1234 static const struct qcom_pas_data wcss_resource_init = {
1235 .crash_reason_smem = 421,
1236 .firmware_name = "wcnss.mdt",
1237 .pas_id = 6,
1238 .auto_boot = true,
1239 .ssr_name = "mpss",
1240 .sysmon_name = "wcnss",
1241 .ssctl_id = 0x12,
1242 };
1243
1244 static const struct qcom_pas_data sdx55_mpss_resource = {
1245 .crash_reason_smem = 421,
1246 .firmware_name = "modem.mdt",
1247 .pas_id = 4,
1248 .auto_boot = true,
1249 .proxy_pd_names = (char*[]){
1250 "cx",
1251 "mss",
1252 NULL
1253 },
1254 .ssr_name = "mpss",
1255 .sysmon_name = "modem",
1256 .ssctl_id = 0x22,
1257 };
1258
1259 static const struct qcom_pas_data sm8450_mpss_resource = {
1260 .crash_reason_smem = 421,
1261 .firmware_name = "modem.mdt",
1262 .pas_id = 4,
1263 .minidump_id = 3,
1264 .auto_boot = false,
1265 .decrypt_shutdown = true,
1266 .proxy_pd_names = (char*[]){
1267 "cx",
1268 "mss",
1269 NULL
1270 },
1271 .load_state = "modem",
1272 .ssr_name = "mpss",
1273 .sysmon_name = "modem",
1274 .ssctl_id = 0x12,
1275 };
1276
1277 static const struct qcom_pas_data sm8550_adsp_resource = {
1278 .crash_reason_smem = 423,
1279 .firmware_name = "adsp.mdt",
1280 .dtb_firmware_name = "adsp_dtb.mdt",
1281 .pas_id = 1,
1282 .dtb_pas_id = 0x24,
1283 .minidump_id = 5,
1284 .auto_boot = true,
1285 .proxy_pd_names = (char*[]){
1286 "lcx",
1287 "lmx",
1288 NULL
1289 },
1290 .load_state = "adsp",
1291 .ssr_name = "lpass",
1292 .sysmon_name = "adsp",
1293 .ssctl_id = 0x14,
1294 .smem_host_id = 2,
1295 };
1296
1297 static const struct qcom_pas_data sm8550_cdsp_resource = {
1298 .crash_reason_smem = 601,
1299 .firmware_name = "cdsp.mdt",
1300 .dtb_firmware_name = "cdsp_dtb.mdt",
1301 .pas_id = 18,
1302 .dtb_pas_id = 0x25,
1303 .minidump_id = 7,
1304 .auto_boot = true,
1305 .proxy_pd_names = (char*[]){
1306 "cx",
1307 "mxc",
1308 "nsp",
1309 NULL
1310 },
1311 .load_state = "cdsp",
1312 .ssr_name = "cdsp",
1313 .sysmon_name = "cdsp",
1314 .ssctl_id = 0x17,
1315 .smem_host_id = 5,
1316 };
1317
1318 static const struct qcom_pas_data sm8550_mpss_resource = {
1319 .crash_reason_smem = 421,
1320 .firmware_name = "modem.mdt",
1321 .dtb_firmware_name = "modem_dtb.mdt",
1322 .pas_id = 4,
1323 .dtb_pas_id = 0x26,
1324 .minidump_id = 3,
1325 .auto_boot = false,
1326 .decrypt_shutdown = true,
1327 .proxy_pd_names = (char*[]){
1328 "cx",
1329 "mss",
1330 NULL
1331 },
1332 .load_state = "modem",
1333 .ssr_name = "mpss",
1334 .sysmon_name = "modem",
1335 .ssctl_id = 0x12,
1336 .smem_host_id = 1,
1337 .region_assign_idx = 2,
1338 .region_assign_count = 1,
1339 .region_assign_vmid = QCOM_SCM_VMID_MSS_MSA,
1340 };
1341
1342 static const struct qcom_pas_data sc7280_wpss_resource = {
1343 .crash_reason_smem = 626,
1344 .firmware_name = "wpss.mdt",
1345 .pas_id = 6,
1346 .minidump_id = 4,
1347 .auto_boot = false,
1348 .proxy_pd_names = (char*[]){
1349 "cx",
1350 "mx",
1351 NULL
1352 },
1353 .load_state = "wpss",
1354 .ssr_name = "wpss",
1355 .sysmon_name = "wpss",
1356 .ssctl_id = 0x19,
1357 };
1358
1359 static const struct qcom_pas_data sm8650_cdsp_resource = {
1360 .crash_reason_smem = 601,
1361 .firmware_name = "cdsp.mdt",
1362 .dtb_firmware_name = "cdsp_dtb.mdt",
1363 .pas_id = 18,
1364 .dtb_pas_id = 0x25,
1365 .minidump_id = 7,
1366 .auto_boot = true,
1367 .proxy_pd_names = (char*[]){
1368 "cx",
1369 "mxc",
1370 "nsp",
1371 NULL
1372 },
1373 .load_state = "cdsp",
1374 .ssr_name = "cdsp",
1375 .sysmon_name = "cdsp",
1376 .ssctl_id = 0x17,
1377 .smem_host_id = 5,
1378 .region_assign_idx = 2,
1379 .region_assign_count = 1,
1380 .region_assign_shared = true,
1381 .region_assign_vmid = QCOM_SCM_VMID_CDSP,
1382 };
1383
1384 static const struct qcom_pas_data sm8650_mpss_resource = {
1385 .crash_reason_smem = 421,
1386 .firmware_name = "modem.mdt",
1387 .dtb_firmware_name = "modem_dtb.mdt",
1388 .pas_id = 4,
1389 .dtb_pas_id = 0x26,
1390 .minidump_id = 3,
1391 .auto_boot = false,
1392 .decrypt_shutdown = true,
1393 .proxy_pd_names = (char*[]){
1394 "cx",
1395 "mss",
1396 NULL
1397 },
1398 .load_state = "modem",
1399 .ssr_name = "mpss",
1400 .sysmon_name = "modem",
1401 .ssctl_id = 0x12,
1402 .smem_host_id = 1,
1403 .region_assign_idx = 2,
1404 .region_assign_count = 3,
1405 .region_assign_vmid = QCOM_SCM_VMID_MSS_MSA,
1406 };
1407
1408 static const struct qcom_pas_data sm8750_mpss_resource = {
1409 .crash_reason_smem = 421,
1410 .firmware_name = "modem.mdt",
1411 .dtb_firmware_name = "modem_dtb.mdt",
1412 .pas_id = 4,
1413 .dtb_pas_id = 0x26,
1414 .minidump_id = 3,
1415 .auto_boot = false,
1416 .decrypt_shutdown = true,
1417 .proxy_pd_names = (char*[]){
1418 "cx",
1419 "mss",
1420 NULL
1421 },
1422 .load_state = "modem",
1423 .ssr_name = "mpss",
1424 .sysmon_name = "modem",
1425 .ssctl_id = 0x12,
1426 .smem_host_id = 1,
1427 .region_assign_idx = 2,
1428 .region_assign_count = 2,
1429 .region_assign_vmid = QCOM_SCM_VMID_MSS_MSA,
1430 };
1431
1432 static const struct of_device_id qcom_pas_of_match[] = {
1433 { .compatible = "qcom,msm8226-adsp-pil", .data = &msm8996_adsp_resource},
1434 { .compatible = "qcom,msm8953-adsp-pil", .data = &msm8996_adsp_resource},
1435 { .compatible = "qcom,msm8974-adsp-pil", .data = &adsp_resource_init},
1436 { .compatible = "qcom,msm8996-adsp-pil", .data = &msm8996_adsp_resource},
1437 { .compatible = "qcom,msm8996-slpi-pil", .data = &msm8996_slpi_resource_init},
1438 { .compatible = "qcom,msm8998-adsp-pas", .data = &msm8996_adsp_resource},
1439 { .compatible = "qcom,msm8998-slpi-pas", .data = &msm8996_slpi_resource_init},
1440 { .compatible = "qcom,qcs404-adsp-pas", .data = &adsp_resource_init },
1441 { .compatible = "qcom,qcs404-cdsp-pas", .data = &cdsp_resource_init },
1442 { .compatible = "qcom,qcs404-wcss-pas", .data = &wcss_resource_init },
1443 { .compatible = "qcom,sa8775p-adsp-pas", .data = &sa8775p_adsp_resource},
1444 { .compatible = "qcom,sa8775p-cdsp0-pas", .data = &sa8775p_cdsp0_resource},
1445 { .compatible = "qcom,sa8775p-cdsp1-pas", .data = &sa8775p_cdsp1_resource},
1446 { .compatible = "qcom,sa8775p-gpdsp0-pas", .data = &sa8775p_gpdsp0_resource},
1447 { .compatible = "qcom,sa8775p-gpdsp1-pas", .data = &sa8775p_gpdsp1_resource},
1448 { .compatible = "qcom,sar2130p-adsp-pas", .data = &sm8350_adsp_resource},
1449 { .compatible = "qcom,sc7180-adsp-pas", .data = &sm8250_adsp_resource},
1450 { .compatible = "qcom,sc7180-mpss-pas", .data = &mpss_resource_init},
1451 { .compatible = "qcom,sc7280-adsp-pas", .data = &sm8350_adsp_resource},
1452 { .compatible = "qcom,sc7280-cdsp-pas", .data = &sm6350_cdsp_resource},
1453 { .compatible = "qcom,sc7280-mpss-pas", .data = &mpss_resource_init},
1454 { .compatible = "qcom,sc7280-wpss-pas", .data = &sc7280_wpss_resource},
1455 { .compatible = "qcom,sc8180x-adsp-pas", .data = &sm8150_adsp_resource},
1456 { .compatible = "qcom,sc8180x-cdsp-pas", .data = &sm8150_cdsp_resource},
1457 { .compatible = "qcom,sc8180x-mpss-pas", .data = &sc8180x_mpss_resource},
1458 { .compatible = "qcom,sc8280xp-adsp-pas", .data = &sm8250_adsp_resource},
1459 { .compatible = "qcom,sc8280xp-nsp0-pas", .data = &sc8280xp_nsp0_resource},
1460 { .compatible = "qcom,sc8280xp-nsp1-pas", .data = &sc8280xp_nsp1_resource},
1461 { .compatible = "qcom,sdm660-adsp-pas", .data = &adsp_resource_init},
1462 { .compatible = "qcom,sdm845-adsp-pas", .data = &sdm845_adsp_resource_init},
1463 { .compatible = "qcom,sdm845-cdsp-pas", .data = &sdm845_cdsp_resource_init},
1464 { .compatible = "qcom,sdm845-slpi-pas", .data = &sdm845_slpi_resource_init},
1465 { .compatible = "qcom,sdx55-mpss-pas", .data = &sdx55_mpss_resource},
1466 { .compatible = "qcom,sdx75-mpss-pas", .data = &sm8650_mpss_resource},
1467 { .compatible = "qcom,sm6115-adsp-pas", .data = &adsp_resource_init},
1468 { .compatible = "qcom,sm6115-cdsp-pas", .data = &cdsp_resource_init},
1469 { .compatible = "qcom,sm6115-mpss-pas", .data = &sc8180x_mpss_resource},
1470 { .compatible = "qcom,sm6350-adsp-pas", .data = &sm6350_adsp_resource},
1471 { .compatible = "qcom,sm6350-cdsp-pas", .data = &sm6350_cdsp_resource},
1472 { .compatible = "qcom,sm6350-mpss-pas", .data = &mpss_resource_init},
1473 { .compatible = "qcom,sm6375-adsp-pas", .data = &sm6350_adsp_resource},
1474 { .compatible = "qcom,sm6375-cdsp-pas", .data = &sm8150_cdsp_resource},
1475 { .compatible = "qcom,sm6375-mpss-pas", .data = &sm6375_mpss_resource},
1476 { .compatible = "qcom,sm8150-adsp-pas", .data = &sm8150_adsp_resource},
1477 { .compatible = "qcom,sm8150-cdsp-pas", .data = &sm8150_cdsp_resource},
1478 { .compatible = "qcom,sm8150-mpss-pas", .data = &mpss_resource_init},
1479 { .compatible = "qcom,sm8150-slpi-pas", .data = &sdm845_slpi_resource_init},
1480 { .compatible = "qcom,sm8250-adsp-pas", .data = &sm8250_adsp_resource},
1481 { .compatible = "qcom,sm8250-cdsp-pas", .data = &sm8250_cdsp_resource},
1482 { .compatible = "qcom,sm8250-slpi-pas", .data = &sdm845_slpi_resource_init},
1483 { .compatible = "qcom,sm8350-adsp-pas", .data = &sm8350_adsp_resource},
1484 { .compatible = "qcom,sm8350-cdsp-pas", .data = &sm8350_cdsp_resource},
1485 { .compatible = "qcom,sm8350-slpi-pas", .data = &sdm845_slpi_resource_init},
1486 { .compatible = "qcom,sm8350-mpss-pas", .data = &mpss_resource_init},
1487 { .compatible = "qcom,sm8450-adsp-pas", .data = &sm8350_adsp_resource},
1488 { .compatible = "qcom,sm8450-cdsp-pas", .data = &sm8350_cdsp_resource},
1489 { .compatible = "qcom,sm8450-slpi-pas", .data = &sdm845_slpi_resource_init},
1490 { .compatible = "qcom,sm8450-mpss-pas", .data = &sm8450_mpss_resource},
1491 { .compatible = "qcom,sm8550-adsp-pas", .data = &sm8550_adsp_resource},
1492 { .compatible = "qcom,sm8550-cdsp-pas", .data = &sm8550_cdsp_resource},
1493 { .compatible = "qcom,sm8550-mpss-pas", .data = &sm8550_mpss_resource},
1494 { .compatible = "qcom,sm8650-adsp-pas", .data = &sm8550_adsp_resource},
1495 { .compatible = "qcom,sm8650-cdsp-pas", .data = &sm8650_cdsp_resource},
1496 { .compatible = "qcom,sm8650-mpss-pas", .data = &sm8650_mpss_resource},
1497 { .compatible = "qcom,sm8750-mpss-pas", .data = &sm8750_mpss_resource},
1498 { .compatible = "qcom,x1e80100-adsp-pas", .data = &x1e80100_adsp_resource},
1499 { .compatible = "qcom,x1e80100-cdsp-pas", .data = &x1e80100_cdsp_resource},
1500 { },
1501 };
1502 MODULE_DEVICE_TABLE(of, qcom_pas_of_match);
1503
1504 static struct platform_driver qcom_pas_driver = {
1505 .probe = qcom_pas_probe,
1506 .remove = qcom_pas_remove,
1507 .driver = {
1508 .name = "qcom_q6v5_pas",
1509 .of_match_table = qcom_pas_of_match,
1510 },
1511 };
1512
1513 module_platform_driver(qcom_pas_driver);
1514 MODULE_DESCRIPTION("Qualcomm Peripheral Authentication Service remoteproc driver");
1515 MODULE_LICENSE("GPL v2");
1516