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