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