xref: /linux/drivers/remoteproc/qcom_q6v5_pas.c (revision 111857421c93fc88924106436741bd2f5b8bc220)
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