• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // SPDX-License-Identifier: GPL-2.0-only
2 /*
3  * Qualcomm ADSP/SLPI Peripheral Image Loader for MSM8974 and MSM8996
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/firmware.h>
12 #include <linux/interrupt.h>
13 #include <linux/kernel.h>
14 #include <linux/module.h>
15 #include <linux/of_address.h>
16 #include <linux/of_device.h>
17 #include <linux/platform_device.h>
18 #include <linux/pm_domain.h>
19 #include <linux/pm_runtime.h>
20 #include <linux/qcom_scm.h>
21 #include <linux/regulator/consumer.h>
22 #include <linux/remoteproc.h>
23 #include <linux/soc/qcom/mdt_loader.h>
24 #include <linux/soc/qcom/smem.h>
25 #include <linux/soc/qcom/smem_state.h>
26 
27 #include "qcom_common.h"
28 #include "qcom_pil_info.h"
29 #include "qcom_q6v5.h"
30 #include "remoteproc_internal.h"
31 
32 struct adsp_data {
33 	int crash_reason_smem;
34 	const char *firmware_name;
35 	int pas_id;
36 	unsigned int minidump_id;
37 	bool has_aggre2_clk;
38 	bool auto_boot;
39 
40 	char **active_pd_names;
41 	char **proxy_pd_names;
42 
43 	const char *ssr_name;
44 	const char *sysmon_name;
45 	int ssctl_id;
46 };
47 
48 struct qcom_adsp {
49 	struct device *dev;
50 	struct rproc *rproc;
51 
52 	struct qcom_q6v5 q6v5;
53 
54 	struct clk *xo;
55 	struct clk *aggre2_clk;
56 
57 	struct regulator *cx_supply;
58 	struct regulator *px_supply;
59 
60 	struct device *active_pds[1];
61 	struct device *proxy_pds[3];
62 
63 	int active_pd_count;
64 	int proxy_pd_count;
65 
66 	int pas_id;
67 	unsigned int minidump_id;
68 	int crash_reason_smem;
69 	bool has_aggre2_clk;
70 	const char *info_name;
71 
72 	struct completion start_done;
73 	struct completion stop_done;
74 
75 	phys_addr_t mem_phys;
76 	phys_addr_t mem_reloc;
77 	void *mem_region;
78 	size_t mem_size;
79 
80 	struct qcom_rproc_glink glink_subdev;
81 	struct qcom_rproc_subdev smd_subdev;
82 	struct qcom_rproc_ssr ssr_subdev;
83 	struct qcom_sysmon *sysmon;
84 };
85 
adsp_minidump(struct rproc * rproc)86 static void adsp_minidump(struct rproc *rproc)
87 {
88 	struct qcom_adsp *adsp = rproc->priv;
89 
90 	if (rproc->dump_conf == RPROC_COREDUMP_DISABLED)
91 		return;
92 
93 	qcom_minidump(rproc, adsp->minidump_id);
94 }
95 
adsp_pds_enable(struct qcom_adsp * adsp,struct device ** pds,size_t pd_count)96 static int adsp_pds_enable(struct qcom_adsp *adsp, struct device **pds,
97 			   size_t pd_count)
98 {
99 	int ret;
100 	int i;
101 
102 	for (i = 0; i < pd_count; i++) {
103 		dev_pm_genpd_set_performance_state(pds[i], INT_MAX);
104 		ret = pm_runtime_get_sync(pds[i]);
105 		if (ret < 0) {
106 			pm_runtime_put_noidle(pds[i]);
107 			dev_pm_genpd_set_performance_state(pds[i], 0);
108 			goto unroll_pd_votes;
109 		}
110 	}
111 
112 	return 0;
113 
114 unroll_pd_votes:
115 	for (i--; i >= 0; i--) {
116 		dev_pm_genpd_set_performance_state(pds[i], 0);
117 		pm_runtime_put(pds[i]);
118 	}
119 
120 	return ret;
121 };
122 
adsp_pds_disable(struct qcom_adsp * adsp,struct device ** pds,size_t pd_count)123 static void adsp_pds_disable(struct qcom_adsp *adsp, struct device **pds,
124 			     size_t pd_count)
125 {
126 	int i;
127 
128 	for (i = 0; i < pd_count; i++) {
129 		dev_pm_genpd_set_performance_state(pds[i], 0);
130 		pm_runtime_put(pds[i]);
131 	}
132 }
133 
adsp_load(struct rproc * rproc,const struct firmware * fw)134 static int adsp_load(struct rproc *rproc, const struct firmware *fw)
135 {
136 	struct qcom_adsp *adsp = (struct qcom_adsp *)rproc->priv;
137 	int ret;
138 
139 	ret = qcom_mdt_load(adsp->dev, fw, rproc->firmware, adsp->pas_id,
140 			    adsp->mem_region, adsp->mem_phys, adsp->mem_size,
141 			    &adsp->mem_reloc);
142 	if (ret)
143 		return ret;
144 
145 	qcom_pil_info_store(adsp->info_name, adsp->mem_phys, adsp->mem_size);
146 
147 	return 0;
148 }
149 
adsp_start(struct rproc * rproc)150 static int adsp_start(struct rproc *rproc)
151 {
152 	struct qcom_adsp *adsp = (struct qcom_adsp *)rproc->priv;
153 	int ret;
154 
155 	qcom_q6v5_prepare(&adsp->q6v5);
156 
157 	ret = adsp_pds_enable(adsp, adsp->active_pds, adsp->active_pd_count);
158 	if (ret < 0)
159 		goto disable_irqs;
160 
161 	ret = adsp_pds_enable(adsp, adsp->proxy_pds, adsp->proxy_pd_count);
162 	if (ret < 0)
163 		goto disable_active_pds;
164 
165 	ret = clk_prepare_enable(adsp->xo);
166 	if (ret)
167 		goto disable_proxy_pds;
168 
169 	ret = clk_prepare_enable(adsp->aggre2_clk);
170 	if (ret)
171 		goto disable_xo_clk;
172 
173 	ret = regulator_enable(adsp->cx_supply);
174 	if (ret)
175 		goto disable_aggre2_clk;
176 
177 	ret = regulator_enable(adsp->px_supply);
178 	if (ret)
179 		goto disable_cx_supply;
180 
181 	ret = qcom_scm_pas_auth_and_reset(adsp->pas_id);
182 	if (ret) {
183 		dev_err(adsp->dev,
184 			"failed to authenticate image and release reset\n");
185 		goto disable_px_supply;
186 	}
187 
188 	ret = qcom_q6v5_wait_for_start(&adsp->q6v5, msecs_to_jiffies(5000));
189 	if (ret == -ETIMEDOUT) {
190 		dev_err(adsp->dev, "start timed out\n");
191 		qcom_scm_pas_shutdown(adsp->pas_id);
192 		goto disable_px_supply;
193 	}
194 
195 	return 0;
196 
197 disable_px_supply:
198 	regulator_disable(adsp->px_supply);
199 disable_cx_supply:
200 	regulator_disable(adsp->cx_supply);
201 disable_aggre2_clk:
202 	clk_disable_unprepare(adsp->aggre2_clk);
203 disable_xo_clk:
204 	clk_disable_unprepare(adsp->xo);
205 disable_proxy_pds:
206 	adsp_pds_disable(adsp, adsp->proxy_pds, adsp->proxy_pd_count);
207 disable_active_pds:
208 	adsp_pds_disable(adsp, adsp->active_pds, adsp->active_pd_count);
209 disable_irqs:
210 	qcom_q6v5_unprepare(&adsp->q6v5);
211 
212 	return ret;
213 }
214 
qcom_pas_handover(struct qcom_q6v5 * q6v5)215 static void qcom_pas_handover(struct qcom_q6v5 *q6v5)
216 {
217 	struct qcom_adsp *adsp = container_of(q6v5, struct qcom_adsp, q6v5);
218 
219 	regulator_disable(adsp->px_supply);
220 	regulator_disable(adsp->cx_supply);
221 	clk_disable_unprepare(adsp->aggre2_clk);
222 	clk_disable_unprepare(adsp->xo);
223 	adsp_pds_disable(adsp, adsp->proxy_pds, adsp->proxy_pd_count);
224 }
225 
adsp_stop(struct rproc * rproc)226 static int adsp_stop(struct rproc *rproc)
227 {
228 	struct qcom_adsp *adsp = (struct qcom_adsp *)rproc->priv;
229 	int handover;
230 	int ret;
231 
232 	ret = qcom_q6v5_request_stop(&adsp->q6v5, adsp->sysmon);
233 	if (ret == -ETIMEDOUT)
234 		dev_err(adsp->dev, "timed out on wait\n");
235 
236 	ret = qcom_scm_pas_shutdown(adsp->pas_id);
237 	if (ret)
238 		dev_err(adsp->dev, "failed to shutdown: %d\n", ret);
239 
240 	adsp_pds_disable(adsp, adsp->active_pds, adsp->active_pd_count);
241 	handover = qcom_q6v5_unprepare(&adsp->q6v5);
242 	if (handover)
243 		qcom_pas_handover(&adsp->q6v5);
244 
245 	return ret;
246 }
247 
adsp_da_to_va(struct rproc * rproc,u64 da,size_t len,bool * is_iomem)248 static void *adsp_da_to_va(struct rproc *rproc, u64 da, size_t len, bool *is_iomem)
249 {
250 	struct qcom_adsp *adsp = (struct qcom_adsp *)rproc->priv;
251 	int offset;
252 
253 	offset = da - adsp->mem_reloc;
254 	if (offset < 0 || offset + len > adsp->mem_size)
255 		return NULL;
256 
257 	return adsp->mem_region + offset;
258 }
259 
adsp_panic(struct rproc * rproc)260 static unsigned long adsp_panic(struct rproc *rproc)
261 {
262 	struct qcom_adsp *adsp = (struct qcom_adsp *)rproc->priv;
263 
264 	return qcom_q6v5_panic(&adsp->q6v5);
265 }
266 
267 static const struct rproc_ops adsp_ops = {
268 	.start = adsp_start,
269 	.stop = adsp_stop,
270 	.da_to_va = adsp_da_to_va,
271 	.parse_fw = qcom_register_dump_segments,
272 	.load = adsp_load,
273 	.panic = adsp_panic,
274 };
275 
276 static const struct rproc_ops adsp_minidump_ops = {
277 	.start = adsp_start,
278 	.stop = adsp_stop,
279 	.da_to_va = adsp_da_to_va,
280 	.load = adsp_load,
281 	.panic = adsp_panic,
282 	.coredump = adsp_minidump,
283 };
284 
adsp_init_clock(struct qcom_adsp * adsp)285 static int adsp_init_clock(struct qcom_adsp *adsp)
286 {
287 	int ret;
288 
289 	adsp->xo = devm_clk_get(adsp->dev, "xo");
290 	if (IS_ERR(adsp->xo)) {
291 		ret = PTR_ERR(adsp->xo);
292 		if (ret != -EPROBE_DEFER)
293 			dev_err(adsp->dev, "failed to get xo clock");
294 		return ret;
295 	}
296 
297 	if (adsp->has_aggre2_clk) {
298 		adsp->aggre2_clk = devm_clk_get(adsp->dev, "aggre2");
299 		if (IS_ERR(adsp->aggre2_clk)) {
300 			ret = PTR_ERR(adsp->aggre2_clk);
301 			if (ret != -EPROBE_DEFER)
302 				dev_err(adsp->dev,
303 					"failed to get aggre2 clock");
304 			return ret;
305 		}
306 	}
307 
308 	return 0;
309 }
310 
adsp_init_regulator(struct qcom_adsp * adsp)311 static int adsp_init_regulator(struct qcom_adsp *adsp)
312 {
313 	adsp->cx_supply = devm_regulator_get(adsp->dev, "cx");
314 	if (IS_ERR(adsp->cx_supply))
315 		return PTR_ERR(adsp->cx_supply);
316 
317 	regulator_set_load(adsp->cx_supply, 100000);
318 
319 	adsp->px_supply = devm_regulator_get(adsp->dev, "px");
320 	return PTR_ERR_OR_ZERO(adsp->px_supply);
321 }
322 
adsp_pds_attach(struct device * dev,struct device ** devs,char ** pd_names)323 static int adsp_pds_attach(struct device *dev, struct device **devs,
324 			   char **pd_names)
325 {
326 	size_t num_pds = 0;
327 	int ret;
328 	int i;
329 
330 	if (!pd_names)
331 		return 0;
332 
333 	/* Handle single power domain */
334 	if (dev->pm_domain) {
335 		devs[0] = dev;
336 		pm_runtime_enable(dev);
337 		return 1;
338 	}
339 
340 	while (pd_names[num_pds])
341 		num_pds++;
342 
343 	for (i = 0; i < num_pds; i++) {
344 		devs[i] = dev_pm_domain_attach_by_name(dev, pd_names[i]);
345 		if (IS_ERR_OR_NULL(devs[i])) {
346 			ret = PTR_ERR(devs[i]) ? : -ENODATA;
347 			goto unroll_attach;
348 		}
349 	}
350 
351 	return num_pds;
352 
353 unroll_attach:
354 	for (i--; i >= 0; i--)
355 		dev_pm_domain_detach(devs[i], false);
356 
357 	return ret;
358 };
359 
adsp_pds_detach(struct qcom_adsp * adsp,struct device ** pds,size_t pd_count)360 static void adsp_pds_detach(struct qcom_adsp *adsp, struct device **pds,
361 			    size_t pd_count)
362 {
363 	struct device *dev = adsp->dev;
364 	int i;
365 
366 	/* Handle single power domain */
367 	if (dev->pm_domain && pd_count) {
368 		pm_runtime_disable(dev);
369 		return;
370 	}
371 
372 	for (i = 0; i < pd_count; i++)
373 		dev_pm_domain_detach(pds[i], false);
374 }
375 
adsp_alloc_memory_region(struct qcom_adsp * adsp)376 static int adsp_alloc_memory_region(struct qcom_adsp *adsp)
377 {
378 	struct device_node *node;
379 	struct resource r;
380 	int ret;
381 
382 	node = of_parse_phandle(adsp->dev->of_node, "memory-region", 0);
383 	if (!node) {
384 		dev_err(adsp->dev, "no memory-region specified\n");
385 		return -EINVAL;
386 	}
387 
388 	ret = of_address_to_resource(node, 0, &r);
389 	of_node_put(node);
390 	if (ret)
391 		return ret;
392 
393 	adsp->mem_phys = adsp->mem_reloc = r.start;
394 	adsp->mem_size = resource_size(&r);
395 	adsp->mem_region = devm_ioremap_wc(adsp->dev, adsp->mem_phys, adsp->mem_size);
396 	if (!adsp->mem_region) {
397 		dev_err(adsp->dev, "unable to map memory region: %pa+%zx\n",
398 			&r.start, adsp->mem_size);
399 		return -EBUSY;
400 	}
401 
402 	return 0;
403 }
404 
adsp_probe(struct platform_device * pdev)405 static int adsp_probe(struct platform_device *pdev)
406 {
407 	const struct adsp_data *desc;
408 	struct qcom_adsp *adsp;
409 	struct rproc *rproc;
410 	const char *fw_name;
411 	const struct rproc_ops *ops = &adsp_ops;
412 	int ret;
413 
414 	desc = of_device_get_match_data(&pdev->dev);
415 	if (!desc)
416 		return -EINVAL;
417 
418 	if (!qcom_scm_is_available())
419 		return -EPROBE_DEFER;
420 
421 	fw_name = desc->firmware_name;
422 	ret = of_property_read_string(pdev->dev.of_node, "firmware-name",
423 				      &fw_name);
424 	if (ret < 0 && ret != -EINVAL)
425 		return ret;
426 
427 	if (desc->minidump_id)
428 		ops = &adsp_minidump_ops;
429 
430 	rproc = rproc_alloc(&pdev->dev, pdev->name, ops, fw_name, sizeof(*adsp));
431 
432 	if (!rproc) {
433 		dev_err(&pdev->dev, "unable to allocate remoteproc\n");
434 		return -ENOMEM;
435 	}
436 
437 	rproc->auto_boot = desc->auto_boot;
438 	rproc_coredump_set_elf_info(rproc, ELFCLASS32, EM_NONE);
439 
440 	adsp = (struct qcom_adsp *)rproc->priv;
441 	adsp->dev = &pdev->dev;
442 	adsp->rproc = rproc;
443 	adsp->minidump_id = desc->minidump_id;
444 	adsp->pas_id = desc->pas_id;
445 	adsp->has_aggre2_clk = desc->has_aggre2_clk;
446 	adsp->info_name = desc->sysmon_name;
447 	platform_set_drvdata(pdev, adsp);
448 
449 	device_wakeup_enable(adsp->dev);
450 
451 	ret = adsp_alloc_memory_region(adsp);
452 	if (ret)
453 		goto free_rproc;
454 
455 	ret = adsp_init_clock(adsp);
456 	if (ret)
457 		goto free_rproc;
458 
459 	ret = adsp_init_regulator(adsp);
460 	if (ret)
461 		goto free_rproc;
462 
463 	ret = adsp_pds_attach(&pdev->dev, adsp->active_pds,
464 			      desc->active_pd_names);
465 	if (ret < 0)
466 		goto free_rproc;
467 	adsp->active_pd_count = ret;
468 
469 	ret = adsp_pds_attach(&pdev->dev, adsp->proxy_pds,
470 			      desc->proxy_pd_names);
471 	if (ret < 0)
472 		goto detach_active_pds;
473 	adsp->proxy_pd_count = ret;
474 
475 	ret = qcom_q6v5_init(&adsp->q6v5, pdev, rproc, desc->crash_reason_smem,
476 			     qcom_pas_handover);
477 	if (ret)
478 		goto detach_proxy_pds;
479 
480 	qcom_add_glink_subdev(rproc, &adsp->glink_subdev, desc->ssr_name);
481 	qcom_add_smd_subdev(rproc, &adsp->smd_subdev);
482 	qcom_add_ssr_subdev(rproc, &adsp->ssr_subdev, desc->ssr_name);
483 	adsp->sysmon = qcom_add_sysmon_subdev(rproc,
484 					      desc->sysmon_name,
485 					      desc->ssctl_id);
486 	if (IS_ERR(adsp->sysmon)) {
487 		ret = PTR_ERR(adsp->sysmon);
488 		goto detach_proxy_pds;
489 	}
490 
491 	ret = rproc_add(rproc);
492 	if (ret)
493 		goto detach_proxy_pds;
494 
495 	return 0;
496 
497 detach_proxy_pds:
498 	adsp_pds_detach(adsp, adsp->proxy_pds, adsp->proxy_pd_count);
499 detach_active_pds:
500 	adsp_pds_detach(adsp, adsp->active_pds, adsp->active_pd_count);
501 free_rproc:
502 	device_init_wakeup(adsp->dev, false);
503 	rproc_free(rproc);
504 
505 	return ret;
506 }
507 
adsp_remove(struct platform_device * pdev)508 static int adsp_remove(struct platform_device *pdev)
509 {
510 	struct qcom_adsp *adsp = platform_get_drvdata(pdev);
511 
512 	rproc_del(adsp->rproc);
513 
514 	qcom_remove_glink_subdev(adsp->rproc, &adsp->glink_subdev);
515 	qcom_remove_sysmon_subdev(adsp->sysmon);
516 	qcom_remove_smd_subdev(adsp->rproc, &adsp->smd_subdev);
517 	qcom_remove_ssr_subdev(adsp->rproc, &adsp->ssr_subdev);
518 	adsp_pds_detach(adsp, adsp->proxy_pds, adsp->proxy_pd_count);
519 	device_init_wakeup(adsp->dev, false);
520 	rproc_free(adsp->rproc);
521 
522 	return 0;
523 }
524 
525 static const struct adsp_data adsp_resource_init = {
526 		.crash_reason_smem = 423,
527 		.firmware_name = "adsp.mdt",
528 		.pas_id = 1,
529 		.has_aggre2_clk = false,
530 		.auto_boot = true,
531 		.ssr_name = "lpass",
532 		.sysmon_name = "adsp",
533 		.ssctl_id = 0x14,
534 };
535 
536 static const struct adsp_data sm8150_adsp_resource = {
537 		.crash_reason_smem = 423,
538 		.firmware_name = "adsp.mdt",
539 		.pas_id = 1,
540 		.has_aggre2_clk = false,
541 		.auto_boot = true,
542 		.active_pd_names = (char*[]){
543 			"load_state",
544 			NULL
545 		},
546 		.proxy_pd_names = (char*[]){
547 			"cx",
548 			NULL
549 		},
550 		.ssr_name = "lpass",
551 		.sysmon_name = "adsp",
552 		.ssctl_id = 0x14,
553 };
554 
555 static const struct adsp_data sm8250_adsp_resource = {
556 	.crash_reason_smem = 423,
557 	.firmware_name = "adsp.mdt",
558 	.pas_id = 1,
559 	.has_aggre2_clk = false,
560 	.auto_boot = true,
561 	.active_pd_names = (char*[]){
562 		"load_state",
563 		NULL
564 	},
565 	.proxy_pd_names = (char*[]){
566 		"lcx",
567 		"lmx",
568 		NULL
569 	},
570 	.ssr_name = "lpass",
571 	.sysmon_name = "adsp",
572 	.ssctl_id = 0x14,
573 };
574 
575 static const struct adsp_data sm8350_adsp_resource = {
576 	.crash_reason_smem = 423,
577 	.firmware_name = "adsp.mdt",
578 	.pas_id = 1,
579 	.has_aggre2_clk = false,
580 	.auto_boot = true,
581 	.active_pd_names = (char*[]){
582 		"load_state",
583 		NULL
584 	},
585 	.proxy_pd_names = (char*[]){
586 		"lcx",
587 		"lmx",
588 		NULL
589 	},
590 	.ssr_name = "lpass",
591 	.sysmon_name = "adsp",
592 	.ssctl_id = 0x14,
593 };
594 
595 static const struct adsp_data msm8998_adsp_resource = {
596 		.crash_reason_smem = 423,
597 		.firmware_name = "adsp.mdt",
598 		.pas_id = 1,
599 		.has_aggre2_clk = false,
600 		.auto_boot = true,
601 		.proxy_pd_names = (char*[]){
602 			"cx",
603 			NULL
604 		},
605 		.ssr_name = "lpass",
606 		.sysmon_name = "adsp",
607 		.ssctl_id = 0x14,
608 };
609 
610 static const struct adsp_data cdsp_resource_init = {
611 	.crash_reason_smem = 601,
612 	.firmware_name = "cdsp.mdt",
613 	.pas_id = 18,
614 	.has_aggre2_clk = false,
615 	.auto_boot = true,
616 	.ssr_name = "cdsp",
617 	.sysmon_name = "cdsp",
618 	.ssctl_id = 0x17,
619 };
620 
621 static const struct adsp_data sm8150_cdsp_resource = {
622 	.crash_reason_smem = 601,
623 	.firmware_name = "cdsp.mdt",
624 	.pas_id = 18,
625 	.has_aggre2_clk = false,
626 	.auto_boot = true,
627 	.active_pd_names = (char*[]){
628 		"load_state",
629 		NULL
630 	},
631 	.proxy_pd_names = (char*[]){
632 		"cx",
633 		NULL
634 	},
635 	.ssr_name = "cdsp",
636 	.sysmon_name = "cdsp",
637 	.ssctl_id = 0x17,
638 };
639 
640 static const struct adsp_data sm8250_cdsp_resource = {
641 	.crash_reason_smem = 601,
642 	.firmware_name = "cdsp.mdt",
643 	.pas_id = 18,
644 	.has_aggre2_clk = false,
645 	.auto_boot = true,
646 	.active_pd_names = (char*[]){
647 		"load_state",
648 		NULL
649 	},
650 	.proxy_pd_names = (char*[]){
651 		"cx",
652 		NULL
653 	},
654 	.ssr_name = "cdsp",
655 	.sysmon_name = "cdsp",
656 	.ssctl_id = 0x17,
657 };
658 
659 static const struct adsp_data sm8350_cdsp_resource = {
660 	.crash_reason_smem = 601,
661 	.firmware_name = "cdsp.mdt",
662 	.pas_id = 18,
663 	.has_aggre2_clk = false,
664 	.auto_boot = true,
665 	.active_pd_names = (char*[]){
666 		"load_state",
667 		NULL
668 	},
669 	.proxy_pd_names = (char*[]){
670 		"cx",
671 		"mxc",
672 		NULL
673 	},
674 	.ssr_name = "cdsp",
675 	.sysmon_name = "cdsp",
676 	.ssctl_id = 0x17,
677 };
678 
679 static const struct adsp_data mpss_resource_init = {
680 	.crash_reason_smem = 421,
681 	.firmware_name = "modem.mdt",
682 	.pas_id = 4,
683 	.minidump_id = 3,
684 	.has_aggre2_clk = false,
685 	.auto_boot = false,
686 	.active_pd_names = (char*[]){
687 		"load_state",
688 		NULL
689 	},
690 	.proxy_pd_names = (char*[]){
691 		"cx",
692 		"mss",
693 		NULL
694 	},
695 	.ssr_name = "mpss",
696 	.sysmon_name = "modem",
697 	.ssctl_id = 0x12,
698 };
699 
700 static const struct adsp_data sc8180x_mpss_resource = {
701 	.crash_reason_smem = 421,
702 	.firmware_name = "modem.mdt",
703 	.pas_id = 4,
704 	.has_aggre2_clk = false,
705 	.auto_boot = false,
706 	.active_pd_names = (char*[]){
707 		"load_state",
708 		NULL
709 	},
710 	.proxy_pd_names = (char*[]){
711 		"cx",
712 		NULL
713 	},
714 	.ssr_name = "mpss",
715 	.sysmon_name = "modem",
716 	.ssctl_id = 0x12,
717 };
718 
719 static const struct adsp_data slpi_resource_init = {
720 		.crash_reason_smem = 424,
721 		.firmware_name = "slpi.mdt",
722 		.pas_id = 12,
723 		.has_aggre2_clk = true,
724 		.auto_boot = true,
725 		.ssr_name = "dsps",
726 		.sysmon_name = "slpi",
727 		.ssctl_id = 0x16,
728 };
729 
730 static const struct adsp_data sm8150_slpi_resource = {
731 		.crash_reason_smem = 424,
732 		.firmware_name = "slpi.mdt",
733 		.pas_id = 12,
734 		.has_aggre2_clk = false,
735 		.auto_boot = true,
736 		.active_pd_names = (char*[]){
737 			"load_state",
738 			NULL
739 		},
740 		.proxy_pd_names = (char*[]){
741 			"lcx",
742 			"lmx",
743 			NULL
744 		},
745 		.ssr_name = "dsps",
746 		.sysmon_name = "slpi",
747 		.ssctl_id = 0x16,
748 };
749 
750 static const struct adsp_data sm8250_slpi_resource = {
751 	.crash_reason_smem = 424,
752 	.firmware_name = "slpi.mdt",
753 	.pas_id = 12,
754 	.has_aggre2_clk = false,
755 	.auto_boot = true,
756 	.active_pd_names = (char*[]){
757 		"load_state",
758 		NULL
759 	},
760 	.proxy_pd_names = (char*[]){
761 		"lcx",
762 		"lmx",
763 		NULL
764 	},
765 	.ssr_name = "dsps",
766 	.sysmon_name = "slpi",
767 	.ssctl_id = 0x16,
768 };
769 
770 static const struct adsp_data sm8350_slpi_resource = {
771 	.crash_reason_smem = 424,
772 	.firmware_name = "slpi.mdt",
773 	.pas_id = 12,
774 	.has_aggre2_clk = false,
775 	.auto_boot = true,
776 	.active_pd_names = (char*[]){
777 		"load_state",
778 		NULL
779 	},
780 	.proxy_pd_names = (char*[]){
781 		"lcx",
782 		"lmx",
783 		NULL
784 	},
785 	.ssr_name = "dsps",
786 	.sysmon_name = "slpi",
787 	.ssctl_id = 0x16,
788 };
789 
790 static const struct adsp_data msm8998_slpi_resource = {
791 		.crash_reason_smem = 424,
792 		.firmware_name = "slpi.mdt",
793 		.pas_id = 12,
794 		.has_aggre2_clk = true,
795 		.auto_boot = true,
796 		.proxy_pd_names = (char*[]){
797 			"ssc_cx",
798 			NULL
799 		},
800 		.ssr_name = "dsps",
801 		.sysmon_name = "slpi",
802 		.ssctl_id = 0x16,
803 };
804 
805 static const struct adsp_data wcss_resource_init = {
806 	.crash_reason_smem = 421,
807 	.firmware_name = "wcnss.mdt",
808 	.pas_id = 6,
809 	.auto_boot = true,
810 	.ssr_name = "mpss",
811 	.sysmon_name = "wcnss",
812 	.ssctl_id = 0x12,
813 };
814 
815 static const struct adsp_data sdx55_mpss_resource = {
816 	.crash_reason_smem = 421,
817 	.firmware_name = "modem.mdt",
818 	.pas_id = 4,
819 	.has_aggre2_clk = false,
820 	.auto_boot = true,
821 	.proxy_pd_names = (char*[]){
822 		"cx",
823 		"mss",
824 		NULL
825 	},
826 	.ssr_name = "mpss",
827 	.sysmon_name = "modem",
828 	.ssctl_id = 0x22,
829 };
830 
831 static const struct of_device_id adsp_of_match[] = {
832 	{ .compatible = "qcom,msm8974-adsp-pil", .data = &adsp_resource_init},
833 	{ .compatible = "qcom,msm8996-adsp-pil", .data = &adsp_resource_init},
834 	{ .compatible = "qcom,msm8996-slpi-pil", .data = &slpi_resource_init},
835 	{ .compatible = "qcom,msm8998-adsp-pas", .data = &msm8998_adsp_resource},
836 	{ .compatible = "qcom,msm8998-slpi-pas", .data = &msm8998_slpi_resource},
837 	{ .compatible = "qcom,qcs404-adsp-pas", .data = &adsp_resource_init },
838 	{ .compatible = "qcom,qcs404-cdsp-pas", .data = &cdsp_resource_init },
839 	{ .compatible = "qcom,qcs404-wcss-pas", .data = &wcss_resource_init },
840 	{ .compatible = "qcom,sc7180-mpss-pas", .data = &mpss_resource_init},
841 	{ .compatible = "qcom,sc8180x-adsp-pas", .data = &sm8150_adsp_resource},
842 	{ .compatible = "qcom,sc8180x-cdsp-pas", .data = &sm8150_cdsp_resource},
843 	{ .compatible = "qcom,sc8180x-mpss-pas", .data = &sc8180x_mpss_resource},
844 	{ .compatible = "qcom,sdm660-adsp-pas", .data = &adsp_resource_init},
845 	{ .compatible = "qcom,sdm845-adsp-pas", .data = &adsp_resource_init},
846 	{ .compatible = "qcom,sdm845-cdsp-pas", .data = &cdsp_resource_init},
847 	{ .compatible = "qcom,sdx55-mpss-pas", .data = &sdx55_mpss_resource},
848 	{ .compatible = "qcom,sm8150-adsp-pas", .data = &sm8150_adsp_resource},
849 	{ .compatible = "qcom,sm8150-cdsp-pas", .data = &sm8150_cdsp_resource},
850 	{ .compatible = "qcom,sm8150-mpss-pas", .data = &mpss_resource_init},
851 	{ .compatible = "qcom,sm8150-slpi-pas", .data = &sm8150_slpi_resource},
852 	{ .compatible = "qcom,sm8250-adsp-pas", .data = &sm8250_adsp_resource},
853 	{ .compatible = "qcom,sm8250-cdsp-pas", .data = &sm8250_cdsp_resource},
854 	{ .compatible = "qcom,sm8250-slpi-pas", .data = &sm8250_slpi_resource},
855 	{ .compatible = "qcom,sm8350-adsp-pas", .data = &sm8350_adsp_resource},
856 	{ .compatible = "qcom,sm8350-cdsp-pas", .data = &sm8350_cdsp_resource},
857 	{ .compatible = "qcom,sm8350-slpi-pas", .data = &sm8350_slpi_resource},
858 	{ .compatible = "qcom,sm8350-mpss-pas", .data = &mpss_resource_init},
859 	{ },
860 };
861 MODULE_DEVICE_TABLE(of, adsp_of_match);
862 
863 static struct platform_driver adsp_driver = {
864 	.probe = adsp_probe,
865 	.remove = adsp_remove,
866 	.driver = {
867 		.name = "qcom_q6v5_pas",
868 		.of_match_table = adsp_of_match,
869 	},
870 };
871 
872 module_platform_driver(adsp_driver);
873 MODULE_DESCRIPTION("Qualcomm Hexagon v5 Peripheral Authentication Service driver");
874 MODULE_LICENSE("GPL v2");
875