a14ff1142e761ba3ba44218fe7eab92ff1344a67
[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         device_init_wakeup(adsp->dev, false);
560         rproc_free(rproc);
561
562         return ret;
563 }
564
565 static int adsp_remove(struct platform_device *pdev)
566 {
567         struct qcom_adsp *adsp = platform_get_drvdata(pdev);
568
569         rproc_del(adsp->rproc);
570
571         qcom_q6v5_deinit(&adsp->q6v5);
572         qcom_remove_glink_subdev(adsp->rproc, &adsp->glink_subdev);
573         qcom_remove_sysmon_subdev(adsp->sysmon);
574         qcom_remove_smd_subdev(adsp->rproc, &adsp->smd_subdev);
575         qcom_remove_ssr_subdev(adsp->rproc, &adsp->ssr_subdev);
576         adsp_pds_detach(adsp, adsp->proxy_pds, adsp->proxy_pd_count);
577         device_init_wakeup(adsp->dev, false);
578         rproc_free(adsp->rproc);
579
580         return 0;
581 }
582
583 static const struct adsp_data adsp_resource_init = {
584                 .crash_reason_smem = 423,
585                 .firmware_name = "adsp.mdt",
586                 .pas_id = 1,
587                 .has_aggre2_clk = false,
588                 .auto_boot = true,
589                 .ssr_name = "lpass",
590                 .sysmon_name = "adsp",
591                 .ssctl_id = 0x14,
592 };
593
594 static const struct adsp_data sdm845_adsp_resource_init = {
595                 .crash_reason_smem = 423,
596                 .firmware_name = "adsp.mdt",
597                 .pas_id = 1,
598                 .has_aggre2_clk = false,
599                 .auto_boot = true,
600                 .load_state = "adsp",
601                 .ssr_name = "lpass",
602                 .sysmon_name = "adsp",
603                 .ssctl_id = 0x14,
604 };
605
606 static const struct adsp_data sm6350_adsp_resource = {
607         .crash_reason_smem = 423,
608         .firmware_name = "adsp.mdt",
609         .pas_id = 1,
610         .has_aggre2_clk = false,
611         .auto_boot = true,
612         .proxy_pd_names = (char*[]){
613                 "lcx",
614                 "lmx",
615                 NULL
616         },
617         .load_state = "adsp",
618         .ssr_name = "lpass",
619         .sysmon_name = "adsp",
620         .ssctl_id = 0x14,
621 };
622
623 static const struct adsp_data sm8150_adsp_resource = {
624                 .crash_reason_smem = 423,
625                 .firmware_name = "adsp.mdt",
626                 .pas_id = 1,
627                 .has_aggre2_clk = false,
628                 .auto_boot = true,
629                 .proxy_pd_names = (char*[]){
630                         "cx",
631                         NULL
632                 },
633                 .load_state = "adsp",
634                 .ssr_name = "lpass",
635                 .sysmon_name = "adsp",
636                 .ssctl_id = 0x14,
637 };
638
639 static const struct adsp_data sm8250_adsp_resource = {
640         .crash_reason_smem = 423,
641         .firmware_name = "adsp.mdt",
642         .pas_id = 1,
643         .has_aggre2_clk = false,
644         .auto_boot = true,
645         .proxy_pd_names = (char*[]){
646                 "lcx",
647                 "lmx",
648                 NULL
649         },
650         .load_state = "adsp",
651         .ssr_name = "lpass",
652         .sysmon_name = "adsp",
653         .ssctl_id = 0x14,
654 };
655
656 static const struct adsp_data sm8350_adsp_resource = {
657         .crash_reason_smem = 423,
658         .firmware_name = "adsp.mdt",
659         .pas_id = 1,
660         .has_aggre2_clk = false,
661         .auto_boot = true,
662         .proxy_pd_names = (char*[]){
663                 "lcx",
664                 "lmx",
665                 NULL
666         },
667         .load_state = "adsp",
668         .ssr_name = "lpass",
669         .sysmon_name = "adsp",
670         .ssctl_id = 0x14,
671 };
672
673 static const struct adsp_data msm8996_adsp_resource = {
674                 .crash_reason_smem = 423,
675                 .firmware_name = "adsp.mdt",
676                 .pas_id = 1,
677                 .has_aggre2_clk = false,
678                 .auto_boot = true,
679                 .proxy_pd_names = (char*[]){
680                         "cx",
681                         NULL
682                 },
683                 .ssr_name = "lpass",
684                 .sysmon_name = "adsp",
685                 .ssctl_id = 0x14,
686 };
687
688 static const struct adsp_data cdsp_resource_init = {
689         .crash_reason_smem = 601,
690         .firmware_name = "cdsp.mdt",
691         .pas_id = 18,
692         .has_aggre2_clk = false,
693         .auto_boot = true,
694         .ssr_name = "cdsp",
695         .sysmon_name = "cdsp",
696         .ssctl_id = 0x17,
697 };
698
699 static const struct adsp_data sdm845_cdsp_resource_init = {
700         .crash_reason_smem = 601,
701         .firmware_name = "cdsp.mdt",
702         .pas_id = 18,
703         .has_aggre2_clk = false,
704         .auto_boot = true,
705         .load_state = "cdsp",
706         .ssr_name = "cdsp",
707         .sysmon_name = "cdsp",
708         .ssctl_id = 0x17,
709 };
710
711 static const struct adsp_data sm6350_cdsp_resource = {
712         .crash_reason_smem = 601,
713         .firmware_name = "cdsp.mdt",
714         .pas_id = 18,
715         .has_aggre2_clk = false,
716         .auto_boot = true,
717         .proxy_pd_names = (char*[]){
718                 "cx",
719                 "mx",
720                 NULL
721         },
722         .load_state = "cdsp",
723         .ssr_name = "cdsp",
724         .sysmon_name = "cdsp",
725         .ssctl_id = 0x17,
726 };
727
728 static const struct adsp_data sm8150_cdsp_resource = {
729         .crash_reason_smem = 601,
730         .firmware_name = "cdsp.mdt",
731         .pas_id = 18,
732         .has_aggre2_clk = false,
733         .auto_boot = true,
734         .proxy_pd_names = (char*[]){
735                 "cx",
736                 NULL
737         },
738         .load_state = "cdsp",
739         .ssr_name = "cdsp",
740         .sysmon_name = "cdsp",
741         .ssctl_id = 0x17,
742 };
743
744 static const struct adsp_data sm8250_cdsp_resource = {
745         .crash_reason_smem = 601,
746         .firmware_name = "cdsp.mdt",
747         .pas_id = 18,
748         .has_aggre2_clk = false,
749         .auto_boot = true,
750         .proxy_pd_names = (char*[]){
751                 "cx",
752                 NULL
753         },
754         .load_state = "cdsp",
755         .ssr_name = "cdsp",
756         .sysmon_name = "cdsp",
757         .ssctl_id = 0x17,
758 };
759
760 static const struct adsp_data sc8280xp_nsp0_resource = {
761         .crash_reason_smem = 601,
762         .firmware_name = "cdsp.mdt",
763         .pas_id = 18,
764         .has_aggre2_clk = false,
765         .auto_boot = true,
766         .proxy_pd_names = (char*[]){
767                 "nsp",
768                 NULL
769         },
770         .ssr_name = "cdsp0",
771         .sysmon_name = "cdsp",
772         .ssctl_id = 0x17,
773 };
774
775 static const struct adsp_data sc8280xp_nsp1_resource = {
776         .crash_reason_smem = 633,
777         .firmware_name = "cdsp.mdt",
778         .pas_id = 30,
779         .has_aggre2_clk = false,
780         .auto_boot = true,
781         .proxy_pd_names = (char*[]){
782                 "nsp",
783                 NULL
784         },
785         .ssr_name = "cdsp1",
786         .sysmon_name = "cdsp1",
787         .ssctl_id = 0x20,
788 };
789
790 static const struct adsp_data sm8350_cdsp_resource = {
791         .crash_reason_smem = 601,
792         .firmware_name = "cdsp.mdt",
793         .pas_id = 18,
794         .has_aggre2_clk = false,
795         .auto_boot = true,
796         .proxy_pd_names = (char*[]){
797                 "cx",
798                 "mxc",
799                 NULL
800         },
801         .load_state = "cdsp",
802         .ssr_name = "cdsp",
803         .sysmon_name = "cdsp",
804         .ssctl_id = 0x17,
805 };
806
807 static const struct adsp_data mpss_resource_init = {
808         .crash_reason_smem = 421,
809         .firmware_name = "modem.mdt",
810         .pas_id = 4,
811         .minidump_id = 3,
812         .has_aggre2_clk = false,
813         .auto_boot = false,
814         .proxy_pd_names = (char*[]){
815                 "cx",
816                 "mss",
817                 NULL
818         },
819         .load_state = "modem",
820         .ssr_name = "mpss",
821         .sysmon_name = "modem",
822         .ssctl_id = 0x12,
823 };
824
825 static const struct adsp_data sc8180x_mpss_resource = {
826         .crash_reason_smem = 421,
827         .firmware_name = "modem.mdt",
828         .pas_id = 4,
829         .has_aggre2_clk = false,
830         .auto_boot = false,
831         .proxy_pd_names = (char*[]){
832                 "cx",
833                 NULL
834         },
835         .load_state = "modem",
836         .ssr_name = "mpss",
837         .sysmon_name = "modem",
838         .ssctl_id = 0x12,
839 };
840
841 static const struct adsp_data slpi_resource_init = {
842                 .crash_reason_smem = 424,
843                 .firmware_name = "slpi.mdt",
844                 .pas_id = 12,
845                 .has_aggre2_clk = true,
846                 .auto_boot = true,
847                 .proxy_pd_names = (char*[]){
848                         "ssc_cx",
849                         NULL
850                 },
851                 .ssr_name = "dsps",
852                 .sysmon_name = "slpi",
853                 .ssctl_id = 0x16,
854 };
855
856 static const struct adsp_data sm8150_slpi_resource = {
857                 .crash_reason_smem = 424,
858                 .firmware_name = "slpi.mdt",
859                 .pas_id = 12,
860                 .has_aggre2_clk = false,
861                 .auto_boot = true,
862                 .proxy_pd_names = (char*[]){
863                         "lcx",
864                         "lmx",
865                         NULL
866                 },
867                 .load_state = "slpi",
868                 .ssr_name = "dsps",
869                 .sysmon_name = "slpi",
870                 .ssctl_id = 0x16,
871 };
872
873 static const struct adsp_data sm8250_slpi_resource = {
874         .crash_reason_smem = 424,
875         .firmware_name = "slpi.mdt",
876         .pas_id = 12,
877         .has_aggre2_clk = false,
878         .auto_boot = true,
879         .proxy_pd_names = (char*[]){
880                 "lcx",
881                 "lmx",
882                 NULL
883         },
884         .load_state = "slpi",
885         .ssr_name = "dsps",
886         .sysmon_name = "slpi",
887         .ssctl_id = 0x16,
888 };
889
890 static const struct adsp_data sm8350_slpi_resource = {
891         .crash_reason_smem = 424,
892         .firmware_name = "slpi.mdt",
893         .pas_id = 12,
894         .has_aggre2_clk = false,
895         .auto_boot = true,
896         .proxy_pd_names = (char*[]){
897                 "lcx",
898                 "lmx",
899                 NULL
900         },
901         .load_state = "slpi",
902         .ssr_name = "dsps",
903         .sysmon_name = "slpi",
904         .ssctl_id = 0x16,
905 };
906
907 static const struct adsp_data wcss_resource_init = {
908         .crash_reason_smem = 421,
909         .firmware_name = "wcnss.mdt",
910         .pas_id = 6,
911         .auto_boot = true,
912         .ssr_name = "mpss",
913         .sysmon_name = "wcnss",
914         .ssctl_id = 0x12,
915 };
916
917 static const struct adsp_data sdx55_mpss_resource = {
918         .crash_reason_smem = 421,
919         .firmware_name = "modem.mdt",
920         .pas_id = 4,
921         .has_aggre2_clk = false,
922         .auto_boot = true,
923         .proxy_pd_names = (char*[]){
924                 "cx",
925                 "mss",
926                 NULL
927         },
928         .ssr_name = "mpss",
929         .sysmon_name = "modem",
930         .ssctl_id = 0x22,
931 };
932
933 static const struct adsp_data sm8450_mpss_resource = {
934         .crash_reason_smem = 421,
935         .firmware_name = "modem.mdt",
936         .pas_id = 4,
937         .minidump_id = 3,
938         .has_aggre2_clk = false,
939         .auto_boot = false,
940         .decrypt_shutdown = true,
941         .proxy_pd_names = (char*[]){
942                 "cx",
943                 "mss",
944                 NULL
945         },
946         .load_state = "modem",
947         .ssr_name = "mpss",
948         .sysmon_name = "modem",
949         .ssctl_id = 0x12,
950 };
951
952 static const struct of_device_id adsp_of_match[] = {
953         { .compatible = "qcom,msm8226-adsp-pil", .data = &adsp_resource_init},
954         { .compatible = "qcom,msm8974-adsp-pil", .data = &adsp_resource_init},
955         { .compatible = "qcom,msm8996-adsp-pil", .data = &msm8996_adsp_resource},
956         { .compatible = "qcom,msm8996-slpi-pil", .data = &slpi_resource_init},
957         { .compatible = "qcom,msm8998-adsp-pas", .data = &msm8996_adsp_resource},
958         { .compatible = "qcom,msm8998-slpi-pas", .data = &slpi_resource_init},
959         { .compatible = "qcom,qcs404-adsp-pas", .data = &adsp_resource_init },
960         { .compatible = "qcom,qcs404-cdsp-pas", .data = &cdsp_resource_init },
961         { .compatible = "qcom,qcs404-wcss-pas", .data = &wcss_resource_init },
962         { .compatible = "qcom,sc7180-mpss-pas", .data = &mpss_resource_init},
963         { .compatible = "qcom,sc7280-mpss-pas", .data = &mpss_resource_init},
964         { .compatible = "qcom,sc8180x-adsp-pas", .data = &sm8150_adsp_resource},
965         { .compatible = "qcom,sc8180x-cdsp-pas", .data = &sm8150_cdsp_resource},
966         { .compatible = "qcom,sc8180x-mpss-pas", .data = &sc8180x_mpss_resource},
967         { .compatible = "qcom,sc8280xp-adsp-pas", .data = &sm8250_adsp_resource},
968         { .compatible = "qcom,sc8280xp-nsp0-pas", .data = &sc8280xp_nsp0_resource},
969         { .compatible = "qcom,sc8280xp-nsp1-pas", .data = &sc8280xp_nsp1_resource},
970         { .compatible = "qcom,sdm660-adsp-pas", .data = &adsp_resource_init},
971         { .compatible = "qcom,sdm845-adsp-pas", .data = &sdm845_adsp_resource_init},
972         { .compatible = "qcom,sdm845-cdsp-pas", .data = &sdm845_cdsp_resource_init},
973         { .compatible = "qcom,sdx55-mpss-pas", .data = &sdx55_mpss_resource},
974         { .compatible = "qcom,sm6350-adsp-pas", .data = &sm6350_adsp_resource},
975         { .compatible = "qcom,sm6350-cdsp-pas", .data = &sm6350_cdsp_resource},
976         { .compatible = "qcom,sm6350-mpss-pas", .data = &mpss_resource_init},
977         { .compatible = "qcom,sm8150-adsp-pas", .data = &sm8150_adsp_resource},
978         { .compatible = "qcom,sm8150-cdsp-pas", .data = &sm8150_cdsp_resource},
979         { .compatible = "qcom,sm8150-mpss-pas", .data = &mpss_resource_init},
980         { .compatible = "qcom,sm8150-slpi-pas", .data = &sm8150_slpi_resource},
981         { .compatible = "qcom,sm8250-adsp-pas", .data = &sm8250_adsp_resource},
982         { .compatible = "qcom,sm8250-cdsp-pas", .data = &sm8250_cdsp_resource},
983         { .compatible = "qcom,sm8250-slpi-pas", .data = &sm8250_slpi_resource},
984         { .compatible = "qcom,sm8350-adsp-pas", .data = &sm8350_adsp_resource},
985         { .compatible = "qcom,sm8350-cdsp-pas", .data = &sm8350_cdsp_resource},
986         { .compatible = "qcom,sm8350-slpi-pas", .data = &sm8350_slpi_resource},
987         { .compatible = "qcom,sm8350-mpss-pas", .data = &mpss_resource_init},
988         { .compatible = "qcom,sm8450-adsp-pas", .data = &sm8350_adsp_resource},
989         { .compatible = "qcom,sm8450-cdsp-pas", .data = &sm8350_cdsp_resource},
990         { .compatible = "qcom,sm8450-slpi-pas", .data = &sm8350_slpi_resource},
991         { .compatible = "qcom,sm8450-mpss-pas", .data = &sm8450_mpss_resource},
992         { },
993 };
994 MODULE_DEVICE_TABLE(of, adsp_of_match);
995
996 static struct platform_driver adsp_driver = {
997         .probe = adsp_probe,
998         .remove = adsp_remove,
999         .driver = {
1000                 .name = "qcom_q6v5_pas",
1001                 .of_match_table = adsp_of_match,
1002         },
1003 };
1004
1005 module_platform_driver(adsp_driver);
1006 MODULE_DESCRIPTION("Qualcomm Hexagon v5 Peripheral Authentication Service driver");
1007 MODULE_LICENSE("GPL v2");