reset: starfive: Factor out common JH71X0 reset code
[platform/kernel/linux-starfive.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         of_node_put(node);
453         if (ret)
454                 return ret;
455
456         adsp->mem_phys = adsp->mem_reloc = r.start;
457         adsp->mem_size = resource_size(&r);
458         adsp->mem_region = devm_ioremap_wc(adsp->dev, adsp->mem_phys, adsp->mem_size);
459         if (!adsp->mem_region) {
460                 dev_err(adsp->dev, "unable to map memory region: %pa+%zx\n",
461                         &r.start, adsp->mem_size);
462                 return -EBUSY;
463         }
464
465         return 0;
466 }
467
468 static int adsp_probe(struct platform_device *pdev)
469 {
470         const struct adsp_data *desc;
471         struct qcom_adsp *adsp;
472         struct rproc *rproc;
473         const char *fw_name;
474         const struct rproc_ops *ops = &adsp_ops;
475         int ret;
476
477         desc = of_device_get_match_data(&pdev->dev);
478         if (!desc)
479                 return -EINVAL;
480
481         if (!qcom_scm_is_available())
482                 return -EPROBE_DEFER;
483
484         fw_name = desc->firmware_name;
485         ret = of_property_read_string(pdev->dev.of_node, "firmware-name",
486                                       &fw_name);
487         if (ret < 0 && ret != -EINVAL)
488                 return ret;
489
490         if (desc->minidump_id)
491                 ops = &adsp_minidump_ops;
492
493         rproc = rproc_alloc(&pdev->dev, pdev->name, ops, fw_name, sizeof(*adsp));
494
495         if (!rproc) {
496                 dev_err(&pdev->dev, "unable to allocate remoteproc\n");
497                 return -ENOMEM;
498         }
499
500         rproc->auto_boot = desc->auto_boot;
501         rproc_coredump_set_elf_info(rproc, ELFCLASS32, EM_NONE);
502
503         adsp = (struct qcom_adsp *)rproc->priv;
504         adsp->dev = &pdev->dev;
505         adsp->rproc = rproc;
506         adsp->minidump_id = desc->minidump_id;
507         adsp->pas_id = desc->pas_id;
508         adsp->has_aggre2_clk = desc->has_aggre2_clk;
509         adsp->info_name = desc->sysmon_name;
510         adsp->decrypt_shutdown = desc->decrypt_shutdown;
511         platform_set_drvdata(pdev, adsp);
512
513         ret = device_init_wakeup(adsp->dev, true);
514         if (ret)
515                 goto free_rproc;
516
517         ret = adsp_alloc_memory_region(adsp);
518         if (ret)
519                 goto free_rproc;
520
521         ret = adsp_init_clock(adsp);
522         if (ret)
523                 goto free_rproc;
524
525         ret = adsp_init_regulator(adsp);
526         if (ret)
527                 goto free_rproc;
528
529         ret = adsp_pds_attach(&pdev->dev, adsp->proxy_pds,
530                               desc->proxy_pd_names);
531         if (ret < 0)
532                 goto free_rproc;
533         adsp->proxy_pd_count = ret;
534
535         ret = qcom_q6v5_init(&adsp->q6v5, pdev, rproc, desc->crash_reason_smem, desc->load_state,
536                              qcom_pas_handover);
537         if (ret)
538                 goto detach_proxy_pds;
539
540         qcom_add_glink_subdev(rproc, &adsp->glink_subdev, desc->ssr_name);
541         qcom_add_smd_subdev(rproc, &adsp->smd_subdev);
542         qcom_add_ssr_subdev(rproc, &adsp->ssr_subdev, desc->ssr_name);
543         adsp->sysmon = qcom_add_sysmon_subdev(rproc,
544                                               desc->sysmon_name,
545                                               desc->ssctl_id);
546         if (IS_ERR(adsp->sysmon)) {
547                 ret = PTR_ERR(adsp->sysmon);
548                 goto detach_proxy_pds;
549         }
550
551         ret = rproc_add(rproc);
552         if (ret)
553                 goto detach_proxy_pds;
554
555         return 0;
556
557 detach_proxy_pds:
558         adsp_pds_detach(adsp, adsp->proxy_pds, adsp->proxy_pd_count);
559 free_rproc:
560         device_init_wakeup(adsp->dev, false);
561         rproc_free(rproc);
562
563         return ret;
564 }
565
566 static int adsp_remove(struct platform_device *pdev)
567 {
568         struct qcom_adsp *adsp = platform_get_drvdata(pdev);
569
570         rproc_del(adsp->rproc);
571
572         qcom_q6v5_deinit(&adsp->q6v5);
573         qcom_remove_glink_subdev(adsp->rproc, &adsp->glink_subdev);
574         qcom_remove_sysmon_subdev(adsp->sysmon);
575         qcom_remove_smd_subdev(adsp->rproc, &adsp->smd_subdev);
576         qcom_remove_ssr_subdev(adsp->rproc, &adsp->ssr_subdev);
577         adsp_pds_detach(adsp, adsp->proxy_pds, adsp->proxy_pd_count);
578         device_init_wakeup(adsp->dev, false);
579         rproc_free(adsp->rproc);
580
581         return 0;
582 }
583
584 static const struct adsp_data adsp_resource_init = {
585                 .crash_reason_smem = 423,
586                 .firmware_name = "adsp.mdt",
587                 .pas_id = 1,
588                 .has_aggre2_clk = false,
589                 .auto_boot = true,
590                 .ssr_name = "lpass",
591                 .sysmon_name = "adsp",
592                 .ssctl_id = 0x14,
593 };
594
595 static const struct adsp_data sdm845_adsp_resource_init = {
596                 .crash_reason_smem = 423,
597                 .firmware_name = "adsp.mdt",
598                 .pas_id = 1,
599                 .has_aggre2_clk = false,
600                 .auto_boot = true,
601                 .load_state = "adsp",
602                 .ssr_name = "lpass",
603                 .sysmon_name = "adsp",
604                 .ssctl_id = 0x14,
605 };
606
607 static const struct adsp_data sm6350_adsp_resource = {
608         .crash_reason_smem = 423,
609         .firmware_name = "adsp.mdt",
610         .pas_id = 1,
611         .has_aggre2_clk = false,
612         .auto_boot = true,
613         .proxy_pd_names = (char*[]){
614                 "lcx",
615                 "lmx",
616                 NULL
617         },
618         .load_state = "adsp",
619         .ssr_name = "lpass",
620         .sysmon_name = "adsp",
621         .ssctl_id = 0x14,
622 };
623
624 static const struct adsp_data sm8150_adsp_resource = {
625                 .crash_reason_smem = 423,
626                 .firmware_name = "adsp.mdt",
627                 .pas_id = 1,
628                 .has_aggre2_clk = false,
629                 .auto_boot = true,
630                 .proxy_pd_names = (char*[]){
631                         "cx",
632                         NULL
633                 },
634                 .load_state = "adsp",
635                 .ssr_name = "lpass",
636                 .sysmon_name = "adsp",
637                 .ssctl_id = 0x14,
638 };
639
640 static const struct adsp_data sm8250_adsp_resource = {
641         .crash_reason_smem = 423,
642         .firmware_name = "adsp.mdt",
643         .pas_id = 1,
644         .has_aggre2_clk = false,
645         .auto_boot = true,
646         .proxy_pd_names = (char*[]){
647                 "lcx",
648                 "lmx",
649                 NULL
650         },
651         .load_state = "adsp",
652         .ssr_name = "lpass",
653         .sysmon_name = "adsp",
654         .ssctl_id = 0x14,
655 };
656
657 static const struct adsp_data sm8350_adsp_resource = {
658         .crash_reason_smem = 423,
659         .firmware_name = "adsp.mdt",
660         .pas_id = 1,
661         .has_aggre2_clk = false,
662         .auto_boot = true,
663         .proxy_pd_names = (char*[]){
664                 "lcx",
665                 "lmx",
666                 NULL
667         },
668         .load_state = "adsp",
669         .ssr_name = "lpass",
670         .sysmon_name = "adsp",
671         .ssctl_id = 0x14,
672 };
673
674 static const struct adsp_data msm8996_adsp_resource = {
675                 .crash_reason_smem = 423,
676                 .firmware_name = "adsp.mdt",
677                 .pas_id = 1,
678                 .has_aggre2_clk = false,
679                 .auto_boot = true,
680                 .proxy_pd_names = (char*[]){
681                         "cx",
682                         NULL
683                 },
684                 .ssr_name = "lpass",
685                 .sysmon_name = "adsp",
686                 .ssctl_id = 0x14,
687 };
688
689 static const struct adsp_data cdsp_resource_init = {
690         .crash_reason_smem = 601,
691         .firmware_name = "cdsp.mdt",
692         .pas_id = 18,
693         .has_aggre2_clk = false,
694         .auto_boot = true,
695         .ssr_name = "cdsp",
696         .sysmon_name = "cdsp",
697         .ssctl_id = 0x17,
698 };
699
700 static const struct adsp_data sdm845_cdsp_resource_init = {
701         .crash_reason_smem = 601,
702         .firmware_name = "cdsp.mdt",
703         .pas_id = 18,
704         .has_aggre2_clk = false,
705         .auto_boot = true,
706         .load_state = "cdsp",
707         .ssr_name = "cdsp",
708         .sysmon_name = "cdsp",
709         .ssctl_id = 0x17,
710 };
711
712 static const struct adsp_data sm6350_cdsp_resource = {
713         .crash_reason_smem = 601,
714         .firmware_name = "cdsp.mdt",
715         .pas_id = 18,
716         .has_aggre2_clk = false,
717         .auto_boot = true,
718         .proxy_pd_names = (char*[]){
719                 "cx",
720                 "mx",
721                 NULL
722         },
723         .load_state = "cdsp",
724         .ssr_name = "cdsp",
725         .sysmon_name = "cdsp",
726         .ssctl_id = 0x17,
727 };
728
729 static const struct adsp_data sm8150_cdsp_resource = {
730         .crash_reason_smem = 601,
731         .firmware_name = "cdsp.mdt",
732         .pas_id = 18,
733         .has_aggre2_clk = false,
734         .auto_boot = true,
735         .proxy_pd_names = (char*[]){
736                 "cx",
737                 NULL
738         },
739         .load_state = "cdsp",
740         .ssr_name = "cdsp",
741         .sysmon_name = "cdsp",
742         .ssctl_id = 0x17,
743 };
744
745 static const struct adsp_data sm8250_cdsp_resource = {
746         .crash_reason_smem = 601,
747         .firmware_name = "cdsp.mdt",
748         .pas_id = 18,
749         .has_aggre2_clk = false,
750         .auto_boot = true,
751         .proxy_pd_names = (char*[]){
752                 "cx",
753                 NULL
754         },
755         .load_state = "cdsp",
756         .ssr_name = "cdsp",
757         .sysmon_name = "cdsp",
758         .ssctl_id = 0x17,
759 };
760
761 static const struct adsp_data sc8280xp_nsp0_resource = {
762         .crash_reason_smem = 601,
763         .firmware_name = "cdsp.mdt",
764         .pas_id = 18,
765         .has_aggre2_clk = false,
766         .auto_boot = true,
767         .proxy_pd_names = (char*[]){
768                 "nsp",
769                 NULL
770         },
771         .ssr_name = "cdsp0",
772         .sysmon_name = "cdsp",
773         .ssctl_id = 0x17,
774 };
775
776 static const struct adsp_data sc8280xp_nsp1_resource = {
777         .crash_reason_smem = 633,
778         .firmware_name = "cdsp.mdt",
779         .pas_id = 30,
780         .has_aggre2_clk = false,
781         .auto_boot = true,
782         .proxy_pd_names = (char*[]){
783                 "nsp",
784                 NULL
785         },
786         .ssr_name = "cdsp1",
787         .sysmon_name = "cdsp1",
788         .ssctl_id = 0x20,
789 };
790
791 static const struct adsp_data sm8350_cdsp_resource = {
792         .crash_reason_smem = 601,
793         .firmware_name = "cdsp.mdt",
794         .pas_id = 18,
795         .has_aggre2_clk = false,
796         .auto_boot = true,
797         .proxy_pd_names = (char*[]){
798                 "cx",
799                 "mxc",
800                 NULL
801         },
802         .load_state = "cdsp",
803         .ssr_name = "cdsp",
804         .sysmon_name = "cdsp",
805         .ssctl_id = 0x17,
806 };
807
808 static const struct adsp_data mpss_resource_init = {
809         .crash_reason_smem = 421,
810         .firmware_name = "modem.mdt",
811         .pas_id = 4,
812         .minidump_id = 3,
813         .has_aggre2_clk = false,
814         .auto_boot = false,
815         .proxy_pd_names = (char*[]){
816                 "cx",
817                 "mss",
818                 NULL
819         },
820         .load_state = "modem",
821         .ssr_name = "mpss",
822         .sysmon_name = "modem",
823         .ssctl_id = 0x12,
824 };
825
826 static const struct adsp_data sc8180x_mpss_resource = {
827         .crash_reason_smem = 421,
828         .firmware_name = "modem.mdt",
829         .pas_id = 4,
830         .has_aggre2_clk = false,
831         .auto_boot = false,
832         .proxy_pd_names = (char*[]){
833                 "cx",
834                 NULL
835         },
836         .load_state = "modem",
837         .ssr_name = "mpss",
838         .sysmon_name = "modem",
839         .ssctl_id = 0x12,
840 };
841
842 static const struct adsp_data slpi_resource_init = {
843                 .crash_reason_smem = 424,
844                 .firmware_name = "slpi.mdt",
845                 .pas_id = 12,
846                 .has_aggre2_clk = true,
847                 .auto_boot = true,
848                 .proxy_pd_names = (char*[]){
849                         "ssc_cx",
850                         NULL
851                 },
852                 .ssr_name = "dsps",
853                 .sysmon_name = "slpi",
854                 .ssctl_id = 0x16,
855 };
856
857 static const struct adsp_data sm8150_slpi_resource = {
858                 .crash_reason_smem = 424,
859                 .firmware_name = "slpi.mdt",
860                 .pas_id = 12,
861                 .has_aggre2_clk = false,
862                 .auto_boot = true,
863                 .proxy_pd_names = (char*[]){
864                         "lcx",
865                         "lmx",
866                         NULL
867                 },
868                 .load_state = "slpi",
869                 .ssr_name = "dsps",
870                 .sysmon_name = "slpi",
871                 .ssctl_id = 0x16,
872 };
873
874 static const struct adsp_data sm8250_slpi_resource = {
875         .crash_reason_smem = 424,
876         .firmware_name = "slpi.mdt",
877         .pas_id = 12,
878         .has_aggre2_clk = false,
879         .auto_boot = true,
880         .proxy_pd_names = (char*[]){
881                 "lcx",
882                 "lmx",
883                 NULL
884         },
885         .load_state = "slpi",
886         .ssr_name = "dsps",
887         .sysmon_name = "slpi",
888         .ssctl_id = 0x16,
889 };
890
891 static const struct adsp_data sm8350_slpi_resource = {
892         .crash_reason_smem = 424,
893         .firmware_name = "slpi.mdt",
894         .pas_id = 12,
895         .has_aggre2_clk = false,
896         .auto_boot = true,
897         .proxy_pd_names = (char*[]){
898                 "lcx",
899                 "lmx",
900                 NULL
901         },
902         .load_state = "slpi",
903         .ssr_name = "dsps",
904         .sysmon_name = "slpi",
905         .ssctl_id = 0x16,
906 };
907
908 static const struct adsp_data wcss_resource_init = {
909         .crash_reason_smem = 421,
910         .firmware_name = "wcnss.mdt",
911         .pas_id = 6,
912         .auto_boot = true,
913         .ssr_name = "mpss",
914         .sysmon_name = "wcnss",
915         .ssctl_id = 0x12,
916 };
917
918 static const struct adsp_data sdx55_mpss_resource = {
919         .crash_reason_smem = 421,
920         .firmware_name = "modem.mdt",
921         .pas_id = 4,
922         .has_aggre2_clk = false,
923         .auto_boot = true,
924         .proxy_pd_names = (char*[]){
925                 "cx",
926                 "mss",
927                 NULL
928         },
929         .ssr_name = "mpss",
930         .sysmon_name = "modem",
931         .ssctl_id = 0x22,
932 };
933
934 static const struct adsp_data sm8450_mpss_resource = {
935         .crash_reason_smem = 421,
936         .firmware_name = "modem.mdt",
937         .pas_id = 4,
938         .minidump_id = 3,
939         .has_aggre2_clk = false,
940         .auto_boot = false,
941         .decrypt_shutdown = true,
942         .proxy_pd_names = (char*[]){
943                 "cx",
944                 "mss",
945                 NULL
946         },
947         .load_state = "modem",
948         .ssr_name = "mpss",
949         .sysmon_name = "modem",
950         .ssctl_id = 0x12,
951 };
952
953 static const struct of_device_id adsp_of_match[] = {
954         { .compatible = "qcom,msm8226-adsp-pil", .data = &adsp_resource_init},
955         { .compatible = "qcom,msm8974-adsp-pil", .data = &adsp_resource_init},
956         { .compatible = "qcom,msm8996-adsp-pil", .data = &msm8996_adsp_resource},
957         { .compatible = "qcom,msm8996-slpi-pil", .data = &slpi_resource_init},
958         { .compatible = "qcom,msm8998-adsp-pas", .data = &msm8996_adsp_resource},
959         { .compatible = "qcom,msm8998-slpi-pas", .data = &slpi_resource_init},
960         { .compatible = "qcom,qcs404-adsp-pas", .data = &adsp_resource_init },
961         { .compatible = "qcom,qcs404-cdsp-pas", .data = &cdsp_resource_init },
962         { .compatible = "qcom,qcs404-wcss-pas", .data = &wcss_resource_init },
963         { .compatible = "qcom,sc7180-mpss-pas", .data = &mpss_resource_init},
964         { .compatible = "qcom,sc7280-mpss-pas", .data = &mpss_resource_init},
965         { .compatible = "qcom,sc8180x-adsp-pas", .data = &sm8150_adsp_resource},
966         { .compatible = "qcom,sc8180x-cdsp-pas", .data = &sm8150_cdsp_resource},
967         { .compatible = "qcom,sc8180x-mpss-pas", .data = &sc8180x_mpss_resource},
968         { .compatible = "qcom,sc8280xp-adsp-pas", .data = &sm8250_adsp_resource},
969         { .compatible = "qcom,sc8280xp-nsp0-pas", .data = &sc8280xp_nsp0_resource},
970         { .compatible = "qcom,sc8280xp-nsp1-pas", .data = &sc8280xp_nsp1_resource},
971         { .compatible = "qcom,sdm660-adsp-pas", .data = &adsp_resource_init},
972         { .compatible = "qcom,sdm845-adsp-pas", .data = &sdm845_adsp_resource_init},
973         { .compatible = "qcom,sdm845-cdsp-pas", .data = &sdm845_cdsp_resource_init},
974         { .compatible = "qcom,sdx55-mpss-pas", .data = &sdx55_mpss_resource},
975         { .compatible = "qcom,sm6350-adsp-pas", .data = &sm6350_adsp_resource},
976         { .compatible = "qcom,sm6350-cdsp-pas", .data = &sm6350_cdsp_resource},
977         { .compatible = "qcom,sm6350-mpss-pas", .data = &mpss_resource_init},
978         { .compatible = "qcom,sm8150-adsp-pas", .data = &sm8150_adsp_resource},
979         { .compatible = "qcom,sm8150-cdsp-pas", .data = &sm8150_cdsp_resource},
980         { .compatible = "qcom,sm8150-mpss-pas", .data = &mpss_resource_init},
981         { .compatible = "qcom,sm8150-slpi-pas", .data = &sm8150_slpi_resource},
982         { .compatible = "qcom,sm8250-adsp-pas", .data = &sm8250_adsp_resource},
983         { .compatible = "qcom,sm8250-cdsp-pas", .data = &sm8250_cdsp_resource},
984         { .compatible = "qcom,sm8250-slpi-pas", .data = &sm8250_slpi_resource},
985         { .compatible = "qcom,sm8350-adsp-pas", .data = &sm8350_adsp_resource},
986         { .compatible = "qcom,sm8350-cdsp-pas", .data = &sm8350_cdsp_resource},
987         { .compatible = "qcom,sm8350-slpi-pas", .data = &sm8350_slpi_resource},
988         { .compatible = "qcom,sm8350-mpss-pas", .data = &mpss_resource_init},
989         { .compatible = "qcom,sm8450-adsp-pas", .data = &sm8350_adsp_resource},
990         { .compatible = "qcom,sm8450-cdsp-pas", .data = &sm8350_cdsp_resource},
991         { .compatible = "qcom,sm8450-slpi-pas", .data = &sm8350_slpi_resource},
992         { .compatible = "qcom,sm8450-mpss-pas", .data = &sm8450_mpss_resource},
993         { },
994 };
995 MODULE_DEVICE_TABLE(of, adsp_of_match);
996
997 static struct platform_driver adsp_driver = {
998         .probe = adsp_probe,
999         .remove = adsp_remove,
1000         .driver = {
1001                 .name = "qcom_q6v5_pas",
1002                 .of_match_table = adsp_of_match,
1003         },
1004 };
1005
1006 module_platform_driver(adsp_driver);
1007 MODULE_DESCRIPTION("Qualcomm Hexagon v5 Peripheral Authentication Service driver");
1008 MODULE_LICENSE("GPL v2");