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