Merge branch 'for-6.9/amd-sfh' into for-linus
[sfrench/cifs-2.6.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.h>
17 #include <linux/of_address.h>
18 #include <linux/of_reserved_mem.h>
19 #include <linux/platform_device.h>
20 #include <linux/pm_domain.h>
21 #include <linux/pm_runtime.h>
22 #include <linux/firmware/qcom/qcom_scm.h>
23 #include <linux/regulator/consumer.h>
24 #include <linux/remoteproc.h>
25 #include <linux/soc/qcom/mdt_loader.h>
26 #include <linux/soc/qcom/smem.h>
27 #include <linux/soc/qcom/smem_state.h>
28
29 #include "qcom_common.h"
30 #include "qcom_pil_info.h"
31 #include "qcom_q6v5.h"
32 #include "remoteproc_internal.h"
33
34 #define ADSP_DECRYPT_SHUTDOWN_DELAY_MS  100
35
36 struct adsp_data {
37         int crash_reason_smem;
38         const char *firmware_name;
39         const char *dtb_firmware_name;
40         int pas_id;
41         int dtb_pas_id;
42         unsigned int minidump_id;
43         bool auto_boot;
44         bool decrypt_shutdown;
45
46         char **proxy_pd_names;
47
48         const char *load_state;
49         const char *ssr_name;
50         const char *sysmon_name;
51         int ssctl_id;
52
53         int region_assign_idx;
54 };
55
56 struct qcom_adsp {
57         struct device *dev;
58         struct rproc *rproc;
59
60         struct qcom_q6v5 q6v5;
61
62         struct clk *xo;
63         struct clk *aggre2_clk;
64
65         struct regulator *cx_supply;
66         struct regulator *px_supply;
67
68         struct device *proxy_pds[3];
69
70         int proxy_pd_count;
71
72         const char *dtb_firmware_name;
73         int pas_id;
74         int dtb_pas_id;
75         unsigned int minidump_id;
76         int crash_reason_smem;
77         bool decrypt_shutdown;
78         const char *info_name;
79
80         const struct firmware *firmware;
81         const struct firmware *dtb_firmware;
82
83         struct completion start_done;
84         struct completion stop_done;
85
86         phys_addr_t mem_phys;
87         phys_addr_t dtb_mem_phys;
88         phys_addr_t mem_reloc;
89         phys_addr_t dtb_mem_reloc;
90         phys_addr_t region_assign_phys;
91         void *mem_region;
92         void *dtb_mem_region;
93         size_t mem_size;
94         size_t dtb_mem_size;
95         size_t region_assign_size;
96
97         int region_assign_idx;
98         u64 region_assign_perms;
99
100         struct qcom_rproc_glink glink_subdev;
101         struct qcom_rproc_subdev smd_subdev;
102         struct qcom_rproc_ssr ssr_subdev;
103         struct qcom_sysmon *sysmon;
104
105         struct qcom_scm_pas_metadata pas_metadata;
106         struct qcom_scm_pas_metadata dtb_pas_metadata;
107 };
108
109 static void adsp_segment_dump(struct rproc *rproc, struct rproc_dump_segment *segment,
110                        void *dest, size_t offset, size_t size)
111 {
112         struct qcom_adsp *adsp = rproc->priv;
113         int total_offset;
114
115         total_offset = segment->da + segment->offset + offset - adsp->mem_phys;
116         if (total_offset < 0 || total_offset + size > adsp->mem_size) {
117                 dev_err(adsp->dev,
118                         "invalid copy request for segment %pad with offset %zu and size %zu)\n",
119                         &segment->da, offset, size);
120                 memset(dest, 0xff, size);
121                 return;
122         }
123
124         memcpy_fromio(dest, adsp->mem_region + total_offset, size);
125 }
126
127 static void adsp_minidump(struct rproc *rproc)
128 {
129         struct qcom_adsp *adsp = rproc->priv;
130
131         if (rproc->dump_conf == RPROC_COREDUMP_DISABLED)
132                 return;
133
134         qcom_minidump(rproc, adsp->minidump_id, adsp_segment_dump);
135 }
136
137 static int adsp_pds_enable(struct qcom_adsp *adsp, struct device **pds,
138                            size_t pd_count)
139 {
140         int ret;
141         int i;
142
143         for (i = 0; i < pd_count; i++) {
144                 dev_pm_genpd_set_performance_state(pds[i], INT_MAX);
145                 ret = pm_runtime_get_sync(pds[i]);
146                 if (ret < 0) {
147                         pm_runtime_put_noidle(pds[i]);
148                         dev_pm_genpd_set_performance_state(pds[i], 0);
149                         goto unroll_pd_votes;
150                 }
151         }
152
153         return 0;
154
155 unroll_pd_votes:
156         for (i--; i >= 0; i--) {
157                 dev_pm_genpd_set_performance_state(pds[i], 0);
158                 pm_runtime_put(pds[i]);
159         }
160
161         return ret;
162 };
163
164 static void adsp_pds_disable(struct qcom_adsp *adsp, struct device **pds,
165                              size_t pd_count)
166 {
167         int i;
168
169         for (i = 0; i < pd_count; i++) {
170                 dev_pm_genpd_set_performance_state(pds[i], 0);
171                 pm_runtime_put(pds[i]);
172         }
173 }
174
175 static int adsp_shutdown_poll_decrypt(struct qcom_adsp *adsp)
176 {
177         unsigned int retry_num = 50;
178         int ret;
179
180         do {
181                 msleep(ADSP_DECRYPT_SHUTDOWN_DELAY_MS);
182                 ret = qcom_scm_pas_shutdown(adsp->pas_id);
183         } while (ret == -EINVAL && --retry_num);
184
185         return ret;
186 }
187
188 static int adsp_unprepare(struct rproc *rproc)
189 {
190         struct qcom_adsp *adsp = rproc->priv;
191
192         /*
193          * adsp_load() did pass pas_metadata to the SCM driver for storing
194          * metadata context. It might have been released already if
195          * auth_and_reset() was successful, but in other cases clean it up
196          * here.
197          */
198         qcom_scm_pas_metadata_release(&adsp->pas_metadata);
199         if (adsp->dtb_pas_id)
200                 qcom_scm_pas_metadata_release(&adsp->dtb_pas_metadata);
201
202         return 0;
203 }
204
205 static int adsp_load(struct rproc *rproc, const struct firmware *fw)
206 {
207         struct qcom_adsp *adsp = rproc->priv;
208         int ret;
209
210         /* Store firmware handle to be used in adsp_start() */
211         adsp->firmware = fw;
212
213         if (adsp->dtb_pas_id) {
214                 ret = request_firmware(&adsp->dtb_firmware, adsp->dtb_firmware_name, adsp->dev);
215                 if (ret) {
216                         dev_err(adsp->dev, "request_firmware failed for %s: %d\n",
217                                 adsp->dtb_firmware_name, ret);
218                         return ret;
219                 }
220
221                 ret = qcom_mdt_pas_init(adsp->dev, adsp->dtb_firmware, adsp->dtb_firmware_name,
222                                         adsp->dtb_pas_id, adsp->dtb_mem_phys,
223                                         &adsp->dtb_pas_metadata);
224                 if (ret)
225                         goto release_dtb_firmware;
226
227                 ret = qcom_mdt_load_no_init(adsp->dev, adsp->dtb_firmware, adsp->dtb_firmware_name,
228                                             adsp->dtb_pas_id, adsp->dtb_mem_region,
229                                             adsp->dtb_mem_phys, adsp->dtb_mem_size,
230                                             &adsp->dtb_mem_reloc);
231                 if (ret)
232                         goto release_dtb_metadata;
233         }
234
235         return 0;
236
237 release_dtb_metadata:
238         qcom_scm_pas_metadata_release(&adsp->dtb_pas_metadata);
239
240 release_dtb_firmware:
241         release_firmware(adsp->dtb_firmware);
242
243         return ret;
244 }
245
246 static int adsp_start(struct rproc *rproc)
247 {
248         struct qcom_adsp *adsp = rproc->priv;
249         int ret;
250
251         ret = qcom_q6v5_prepare(&adsp->q6v5);
252         if (ret)
253                 return ret;
254
255         ret = adsp_pds_enable(adsp, adsp->proxy_pds, adsp->proxy_pd_count);
256         if (ret < 0)
257                 goto disable_irqs;
258
259         ret = clk_prepare_enable(adsp->xo);
260         if (ret)
261                 goto disable_proxy_pds;
262
263         ret = clk_prepare_enable(adsp->aggre2_clk);
264         if (ret)
265                 goto disable_xo_clk;
266
267         if (adsp->cx_supply) {
268                 ret = regulator_enable(adsp->cx_supply);
269                 if (ret)
270                         goto disable_aggre2_clk;
271         }
272
273         if (adsp->px_supply) {
274                 ret = regulator_enable(adsp->px_supply);
275                 if (ret)
276                         goto disable_cx_supply;
277         }
278
279         if (adsp->dtb_pas_id) {
280                 ret = qcom_scm_pas_auth_and_reset(adsp->dtb_pas_id);
281                 if (ret) {
282                         dev_err(adsp->dev,
283                                 "failed to authenticate dtb image and release reset\n");
284                         goto disable_px_supply;
285                 }
286         }
287
288         ret = qcom_mdt_pas_init(adsp->dev, adsp->firmware, rproc->firmware, adsp->pas_id,
289                                 adsp->mem_phys, &adsp->pas_metadata);
290         if (ret)
291                 goto disable_px_supply;
292
293         ret = qcom_mdt_load_no_init(adsp->dev, adsp->firmware, rproc->firmware, adsp->pas_id,
294                                     adsp->mem_region, adsp->mem_phys, adsp->mem_size,
295                                     &adsp->mem_reloc);
296         if (ret)
297                 goto release_pas_metadata;
298
299         qcom_pil_info_store(adsp->info_name, adsp->mem_phys, adsp->mem_size);
300
301         ret = qcom_scm_pas_auth_and_reset(adsp->pas_id);
302         if (ret) {
303                 dev_err(adsp->dev,
304                         "failed to authenticate image and release reset\n");
305                 goto release_pas_metadata;
306         }
307
308         ret = qcom_q6v5_wait_for_start(&adsp->q6v5, msecs_to_jiffies(5000));
309         if (ret == -ETIMEDOUT) {
310                 dev_err(adsp->dev, "start timed out\n");
311                 qcom_scm_pas_shutdown(adsp->pas_id);
312                 goto release_pas_metadata;
313         }
314
315         qcom_scm_pas_metadata_release(&adsp->pas_metadata);
316         if (adsp->dtb_pas_id)
317                 qcom_scm_pas_metadata_release(&adsp->dtb_pas_metadata);
318
319         /* Remove pointer to the loaded firmware, only valid in adsp_load() & adsp_start() */
320         adsp->firmware = NULL;
321
322         return 0;
323
324 release_pas_metadata:
325         qcom_scm_pas_metadata_release(&adsp->pas_metadata);
326         if (adsp->dtb_pas_id)
327                 qcom_scm_pas_metadata_release(&adsp->dtb_pas_metadata);
328 disable_px_supply:
329         if (adsp->px_supply)
330                 regulator_disable(adsp->px_supply);
331 disable_cx_supply:
332         if (adsp->cx_supply)
333                 regulator_disable(adsp->cx_supply);
334 disable_aggre2_clk:
335         clk_disable_unprepare(adsp->aggre2_clk);
336 disable_xo_clk:
337         clk_disable_unprepare(adsp->xo);
338 disable_proxy_pds:
339         adsp_pds_disable(adsp, adsp->proxy_pds, adsp->proxy_pd_count);
340 disable_irqs:
341         qcom_q6v5_unprepare(&adsp->q6v5);
342
343         /* Remove pointer to the loaded firmware, only valid in adsp_load() & adsp_start() */
344         adsp->firmware = NULL;
345
346         return ret;
347 }
348
349 static void qcom_pas_handover(struct qcom_q6v5 *q6v5)
350 {
351         struct qcom_adsp *adsp = container_of(q6v5, struct qcom_adsp, q6v5);
352
353         if (adsp->px_supply)
354                 regulator_disable(adsp->px_supply);
355         if (adsp->cx_supply)
356                 regulator_disable(adsp->cx_supply);
357         clk_disable_unprepare(adsp->aggre2_clk);
358         clk_disable_unprepare(adsp->xo);
359         adsp_pds_disable(adsp, adsp->proxy_pds, adsp->proxy_pd_count);
360 }
361
362 static int adsp_stop(struct rproc *rproc)
363 {
364         struct qcom_adsp *adsp = rproc->priv;
365         int handover;
366         int ret;
367
368         ret = qcom_q6v5_request_stop(&adsp->q6v5, adsp->sysmon);
369         if (ret == -ETIMEDOUT)
370                 dev_err(adsp->dev, "timed out on wait\n");
371
372         ret = qcom_scm_pas_shutdown(adsp->pas_id);
373         if (ret && adsp->decrypt_shutdown)
374                 ret = adsp_shutdown_poll_decrypt(adsp);
375
376         if (ret)
377                 dev_err(adsp->dev, "failed to shutdown: %d\n", ret);
378
379         if (adsp->dtb_pas_id) {
380                 ret = qcom_scm_pas_shutdown(adsp->dtb_pas_id);
381                 if (ret)
382                         dev_err(adsp->dev, "failed to shutdown dtb: %d\n", ret);
383         }
384
385         handover = qcom_q6v5_unprepare(&adsp->q6v5);
386         if (handover)
387                 qcom_pas_handover(&adsp->q6v5);
388
389         return ret;
390 }
391
392 static void *adsp_da_to_va(struct rproc *rproc, u64 da, size_t len, bool *is_iomem)
393 {
394         struct qcom_adsp *adsp = rproc->priv;
395         int offset;
396
397         offset = da - adsp->mem_reloc;
398         if (offset < 0 || offset + len > adsp->mem_size)
399                 return NULL;
400
401         if (is_iomem)
402                 *is_iomem = true;
403
404         return adsp->mem_region + offset;
405 }
406
407 static unsigned long adsp_panic(struct rproc *rproc)
408 {
409         struct qcom_adsp *adsp = rproc->priv;
410
411         return qcom_q6v5_panic(&adsp->q6v5);
412 }
413
414 static const struct rproc_ops adsp_ops = {
415         .unprepare = adsp_unprepare,
416         .start = adsp_start,
417         .stop = adsp_stop,
418         .da_to_va = adsp_da_to_va,
419         .parse_fw = qcom_register_dump_segments,
420         .load = adsp_load,
421         .panic = adsp_panic,
422 };
423
424 static const struct rproc_ops adsp_minidump_ops = {
425         .unprepare = adsp_unprepare,
426         .start = adsp_start,
427         .stop = adsp_stop,
428         .da_to_va = adsp_da_to_va,
429         .parse_fw = qcom_register_dump_segments,
430         .load = adsp_load,
431         .panic = adsp_panic,
432         .coredump = adsp_minidump,
433 };
434
435 static int adsp_init_clock(struct qcom_adsp *adsp)
436 {
437         int ret;
438
439         adsp->xo = devm_clk_get(adsp->dev, "xo");
440         if (IS_ERR(adsp->xo)) {
441                 ret = PTR_ERR(adsp->xo);
442                 if (ret != -EPROBE_DEFER)
443                         dev_err(adsp->dev, "failed to get xo clock");
444                 return ret;
445         }
446
447         adsp->aggre2_clk = devm_clk_get_optional(adsp->dev, "aggre2");
448         if (IS_ERR(adsp->aggre2_clk)) {
449                 ret = PTR_ERR(adsp->aggre2_clk);
450                 if (ret != -EPROBE_DEFER)
451                         dev_err(adsp->dev,
452                                 "failed to get aggre2 clock");
453                 return ret;
454         }
455
456         return 0;
457 }
458
459 static int adsp_init_regulator(struct qcom_adsp *adsp)
460 {
461         adsp->cx_supply = devm_regulator_get_optional(adsp->dev, "cx");
462         if (IS_ERR(adsp->cx_supply)) {
463                 if (PTR_ERR(adsp->cx_supply) == -ENODEV)
464                         adsp->cx_supply = NULL;
465                 else
466                         return PTR_ERR(adsp->cx_supply);
467         }
468
469         if (adsp->cx_supply)
470                 regulator_set_load(adsp->cx_supply, 100000);
471
472         adsp->px_supply = devm_regulator_get_optional(adsp->dev, "px");
473         if (IS_ERR(adsp->px_supply)) {
474                 if (PTR_ERR(adsp->px_supply) == -ENODEV)
475                         adsp->px_supply = NULL;
476                 else
477                         return PTR_ERR(adsp->px_supply);
478         }
479
480         return 0;
481 }
482
483 static int adsp_pds_attach(struct device *dev, struct device **devs,
484                            char **pd_names)
485 {
486         size_t num_pds = 0;
487         int ret;
488         int i;
489
490         if (!pd_names)
491                 return 0;
492
493         /* Handle single power domain */
494         if (dev->pm_domain) {
495                 devs[0] = dev;
496                 pm_runtime_enable(dev);
497                 return 1;
498         }
499
500         while (pd_names[num_pds])
501                 num_pds++;
502
503         for (i = 0; i < num_pds; i++) {
504                 devs[i] = dev_pm_domain_attach_by_name(dev, pd_names[i]);
505                 if (IS_ERR_OR_NULL(devs[i])) {
506                         ret = PTR_ERR(devs[i]) ? : -ENODATA;
507                         goto unroll_attach;
508                 }
509         }
510
511         return num_pds;
512
513 unroll_attach:
514         for (i--; i >= 0; i--)
515                 dev_pm_domain_detach(devs[i], false);
516
517         return ret;
518 };
519
520 static void adsp_pds_detach(struct qcom_adsp *adsp, struct device **pds,
521                             size_t pd_count)
522 {
523         struct device *dev = adsp->dev;
524         int i;
525
526         /* Handle single power domain */
527         if (dev->pm_domain && pd_count) {
528                 pm_runtime_disable(dev);
529                 return;
530         }
531
532         for (i = 0; i < pd_count; i++)
533                 dev_pm_domain_detach(pds[i], false);
534 }
535
536 static int adsp_alloc_memory_region(struct qcom_adsp *adsp)
537 {
538         struct reserved_mem *rmem;
539         struct device_node *node;
540
541         node = of_parse_phandle(adsp->dev->of_node, "memory-region", 0);
542         if (!node) {
543                 dev_err(adsp->dev, "no memory-region specified\n");
544                 return -EINVAL;
545         }
546
547         rmem = of_reserved_mem_lookup(node);
548         of_node_put(node);
549         if (!rmem) {
550                 dev_err(adsp->dev, "unable to resolve memory-region\n");
551                 return -EINVAL;
552         }
553
554         adsp->mem_phys = adsp->mem_reloc = rmem->base;
555         adsp->mem_size = rmem->size;
556         adsp->mem_region = devm_ioremap_wc(adsp->dev, adsp->mem_phys, adsp->mem_size);
557         if (!adsp->mem_region) {
558                 dev_err(adsp->dev, "unable to map memory region: %pa+%zx\n",
559                         &rmem->base, adsp->mem_size);
560                 return -EBUSY;
561         }
562
563         if (!adsp->dtb_pas_id)
564                 return 0;
565
566         node = of_parse_phandle(adsp->dev->of_node, "memory-region", 1);
567         if (!node) {
568                 dev_err(adsp->dev, "no dtb memory-region specified\n");
569                 return -EINVAL;
570         }
571
572         rmem = of_reserved_mem_lookup(node);
573         of_node_put(node);
574         if (!rmem) {
575                 dev_err(adsp->dev, "unable to resolve dtb memory-region\n");
576                 return -EINVAL;
577         }
578
579         adsp->dtb_mem_phys = adsp->dtb_mem_reloc = rmem->base;
580         adsp->dtb_mem_size = rmem->size;
581         adsp->dtb_mem_region = devm_ioremap_wc(adsp->dev, adsp->dtb_mem_phys, adsp->dtb_mem_size);
582         if (!adsp->dtb_mem_region) {
583                 dev_err(adsp->dev, "unable to map dtb memory region: %pa+%zx\n",
584                         &rmem->base, adsp->dtb_mem_size);
585                 return -EBUSY;
586         }
587
588         return 0;
589 }
590
591 static int adsp_assign_memory_region(struct qcom_adsp *adsp)
592 {
593         struct reserved_mem *rmem = NULL;
594         struct qcom_scm_vmperm perm;
595         struct device_node *node;
596         int ret;
597
598         if (!adsp->region_assign_idx)
599                 return 0;
600
601         node = of_parse_phandle(adsp->dev->of_node, "memory-region", adsp->region_assign_idx);
602         if (node)
603                 rmem = of_reserved_mem_lookup(node);
604         of_node_put(node);
605         if (!rmem) {
606                 dev_err(adsp->dev, "unable to resolve shareable memory-region\n");
607                 return -EINVAL;
608         }
609
610         perm.vmid = QCOM_SCM_VMID_MSS_MSA;
611         perm.perm = QCOM_SCM_PERM_RW;
612
613         adsp->region_assign_phys = rmem->base;
614         adsp->region_assign_size = rmem->size;
615         adsp->region_assign_perms = BIT(QCOM_SCM_VMID_HLOS);
616
617         ret = qcom_scm_assign_mem(adsp->region_assign_phys,
618                                   adsp->region_assign_size,
619                                   &adsp->region_assign_perms,
620                                   &perm, 1);
621         if (ret < 0) {
622                 dev_err(adsp->dev, "assign memory failed\n");
623                 return ret;
624         }
625
626         return 0;
627 }
628
629 static void adsp_unassign_memory_region(struct qcom_adsp *adsp)
630 {
631         struct qcom_scm_vmperm perm;
632         int ret;
633
634         if (!adsp->region_assign_idx)
635                 return;
636
637         perm.vmid = QCOM_SCM_VMID_HLOS;
638         perm.perm = QCOM_SCM_PERM_RW;
639
640         ret = qcom_scm_assign_mem(adsp->region_assign_phys,
641                                   adsp->region_assign_size,
642                                   &adsp->region_assign_perms,
643                                   &perm, 1);
644         if (ret < 0)
645                 dev_err(adsp->dev, "unassign memory failed\n");
646 }
647
648 static int adsp_probe(struct platform_device *pdev)
649 {
650         const struct adsp_data *desc;
651         struct qcom_adsp *adsp;
652         struct rproc *rproc;
653         const char *fw_name, *dtb_fw_name = NULL;
654         const struct rproc_ops *ops = &adsp_ops;
655         int ret;
656
657         desc = of_device_get_match_data(&pdev->dev);
658         if (!desc)
659                 return -EINVAL;
660
661         if (!qcom_scm_is_available())
662                 return -EPROBE_DEFER;
663
664         fw_name = desc->firmware_name;
665         ret = of_property_read_string(pdev->dev.of_node, "firmware-name",
666                                       &fw_name);
667         if (ret < 0 && ret != -EINVAL)
668                 return ret;
669
670         if (desc->dtb_firmware_name) {
671                 dtb_fw_name = desc->dtb_firmware_name;
672                 ret = of_property_read_string_index(pdev->dev.of_node, "firmware-name", 1,
673                                                     &dtb_fw_name);
674                 if (ret < 0 && ret != -EINVAL)
675                         return ret;
676         }
677
678         if (desc->minidump_id)
679                 ops = &adsp_minidump_ops;
680
681         rproc = rproc_alloc(&pdev->dev, pdev->name, ops, fw_name, sizeof(*adsp));
682
683         if (!rproc) {
684                 dev_err(&pdev->dev, "unable to allocate remoteproc\n");
685                 return -ENOMEM;
686         }
687
688         rproc->auto_boot = desc->auto_boot;
689         rproc_coredump_set_elf_info(rproc, ELFCLASS32, EM_NONE);
690
691         adsp = rproc->priv;
692         adsp->dev = &pdev->dev;
693         adsp->rproc = rproc;
694         adsp->minidump_id = desc->minidump_id;
695         adsp->pas_id = desc->pas_id;
696         adsp->info_name = desc->sysmon_name;
697         adsp->decrypt_shutdown = desc->decrypt_shutdown;
698         adsp->region_assign_idx = desc->region_assign_idx;
699         if (dtb_fw_name) {
700                 adsp->dtb_firmware_name = dtb_fw_name;
701                 adsp->dtb_pas_id = desc->dtb_pas_id;
702         }
703         platform_set_drvdata(pdev, adsp);
704
705         ret = device_init_wakeup(adsp->dev, true);
706         if (ret)
707                 goto free_rproc;
708
709         ret = adsp_alloc_memory_region(adsp);
710         if (ret)
711                 goto free_rproc;
712
713         ret = adsp_assign_memory_region(adsp);
714         if (ret)
715                 goto free_rproc;
716
717         ret = adsp_init_clock(adsp);
718         if (ret)
719                 goto free_rproc;
720
721         ret = adsp_init_regulator(adsp);
722         if (ret)
723                 goto free_rproc;
724
725         ret = adsp_pds_attach(&pdev->dev, adsp->proxy_pds,
726                               desc->proxy_pd_names);
727         if (ret < 0)
728                 goto free_rproc;
729         adsp->proxy_pd_count = ret;
730
731         ret = qcom_q6v5_init(&adsp->q6v5, pdev, rproc, desc->crash_reason_smem, desc->load_state,
732                              qcom_pas_handover);
733         if (ret)
734                 goto detach_proxy_pds;
735
736         qcom_add_glink_subdev(rproc, &adsp->glink_subdev, desc->ssr_name);
737         qcom_add_smd_subdev(rproc, &adsp->smd_subdev);
738         adsp->sysmon = qcom_add_sysmon_subdev(rproc,
739                                               desc->sysmon_name,
740                                               desc->ssctl_id);
741         if (IS_ERR(adsp->sysmon)) {
742                 ret = PTR_ERR(adsp->sysmon);
743                 goto detach_proxy_pds;
744         }
745
746         qcom_add_ssr_subdev(rproc, &adsp->ssr_subdev, desc->ssr_name);
747         ret = rproc_add(rproc);
748         if (ret)
749                 goto detach_proxy_pds;
750
751         return 0;
752
753 detach_proxy_pds:
754         adsp_pds_detach(adsp, adsp->proxy_pds, adsp->proxy_pd_count);
755 free_rproc:
756         device_init_wakeup(adsp->dev, false);
757         rproc_free(rproc);
758
759         return ret;
760 }
761
762 static void adsp_remove(struct platform_device *pdev)
763 {
764         struct qcom_adsp *adsp = platform_get_drvdata(pdev);
765
766         rproc_del(adsp->rproc);
767
768         qcom_q6v5_deinit(&adsp->q6v5);
769         adsp_unassign_memory_region(adsp);
770         qcom_remove_glink_subdev(adsp->rproc, &adsp->glink_subdev);
771         qcom_remove_sysmon_subdev(adsp->sysmon);
772         qcom_remove_smd_subdev(adsp->rproc, &adsp->smd_subdev);
773         qcom_remove_ssr_subdev(adsp->rproc, &adsp->ssr_subdev);
774         adsp_pds_detach(adsp, adsp->proxy_pds, adsp->proxy_pd_count);
775         device_init_wakeup(adsp->dev, false);
776         rproc_free(adsp->rproc);
777 }
778
779 static const struct adsp_data adsp_resource_init = {
780                 .crash_reason_smem = 423,
781                 .firmware_name = "adsp.mdt",
782                 .pas_id = 1,
783                 .auto_boot = true,
784                 .ssr_name = "lpass",
785                 .sysmon_name = "adsp",
786                 .ssctl_id = 0x14,
787 };
788
789 static const struct adsp_data sdm845_adsp_resource_init = {
790                 .crash_reason_smem = 423,
791                 .firmware_name = "adsp.mdt",
792                 .pas_id = 1,
793                 .auto_boot = true,
794                 .load_state = "adsp",
795                 .ssr_name = "lpass",
796                 .sysmon_name = "adsp",
797                 .ssctl_id = 0x14,
798 };
799
800 static const struct adsp_data sm6350_adsp_resource = {
801         .crash_reason_smem = 423,
802         .firmware_name = "adsp.mdt",
803         .pas_id = 1,
804         .auto_boot = true,
805         .proxy_pd_names = (char*[]){
806                 "lcx",
807                 "lmx",
808                 NULL
809         },
810         .load_state = "adsp",
811         .ssr_name = "lpass",
812         .sysmon_name = "adsp",
813         .ssctl_id = 0x14,
814 };
815
816 static const struct adsp_data sm6375_mpss_resource = {
817         .crash_reason_smem = 421,
818         .firmware_name = "modem.mdt",
819         .pas_id = 4,
820         .minidump_id = 3,
821         .auto_boot = false,
822         .proxy_pd_names = (char*[]){
823                 "cx",
824                 NULL
825         },
826         .ssr_name = "mpss",
827         .sysmon_name = "modem",
828         .ssctl_id = 0x12,
829 };
830
831 static const struct adsp_data sm8150_adsp_resource = {
832                 .crash_reason_smem = 423,
833                 .firmware_name = "adsp.mdt",
834                 .pas_id = 1,
835                 .auto_boot = true,
836                 .proxy_pd_names = (char*[]){
837                         "cx",
838                         NULL
839                 },
840                 .load_state = "adsp",
841                 .ssr_name = "lpass",
842                 .sysmon_name = "adsp",
843                 .ssctl_id = 0x14,
844 };
845
846 static const struct adsp_data sm8250_adsp_resource = {
847         .crash_reason_smem = 423,
848         .firmware_name = "adsp.mdt",
849         .pas_id = 1,
850         .auto_boot = true,
851         .proxy_pd_names = (char*[]){
852                 "lcx",
853                 "lmx",
854                 NULL
855         },
856         .load_state = "adsp",
857         .ssr_name = "lpass",
858         .sysmon_name = "adsp",
859         .ssctl_id = 0x14,
860 };
861
862 static const struct adsp_data sm8350_adsp_resource = {
863         .crash_reason_smem = 423,
864         .firmware_name = "adsp.mdt",
865         .pas_id = 1,
866         .auto_boot = true,
867         .proxy_pd_names = (char*[]){
868                 "lcx",
869                 "lmx",
870                 NULL
871         },
872         .load_state = "adsp",
873         .ssr_name = "lpass",
874         .sysmon_name = "adsp",
875         .ssctl_id = 0x14,
876 };
877
878 static const struct adsp_data msm8996_adsp_resource = {
879                 .crash_reason_smem = 423,
880                 .firmware_name = "adsp.mdt",
881                 .pas_id = 1,
882                 .auto_boot = true,
883                 .proxy_pd_names = (char*[]){
884                         "cx",
885                         NULL
886                 },
887                 .ssr_name = "lpass",
888                 .sysmon_name = "adsp",
889                 .ssctl_id = 0x14,
890 };
891
892 static const struct adsp_data cdsp_resource_init = {
893         .crash_reason_smem = 601,
894         .firmware_name = "cdsp.mdt",
895         .pas_id = 18,
896         .auto_boot = true,
897         .ssr_name = "cdsp",
898         .sysmon_name = "cdsp",
899         .ssctl_id = 0x17,
900 };
901
902 static const struct adsp_data sdm845_cdsp_resource_init = {
903         .crash_reason_smem = 601,
904         .firmware_name = "cdsp.mdt",
905         .pas_id = 18,
906         .auto_boot = true,
907         .load_state = "cdsp",
908         .ssr_name = "cdsp",
909         .sysmon_name = "cdsp",
910         .ssctl_id = 0x17,
911 };
912
913 static const struct adsp_data sm6350_cdsp_resource = {
914         .crash_reason_smem = 601,
915         .firmware_name = "cdsp.mdt",
916         .pas_id = 18,
917         .auto_boot = true,
918         .proxy_pd_names = (char*[]){
919                 "cx",
920                 "mx",
921                 NULL
922         },
923         .load_state = "cdsp",
924         .ssr_name = "cdsp",
925         .sysmon_name = "cdsp",
926         .ssctl_id = 0x17,
927 };
928
929 static const struct adsp_data sm8150_cdsp_resource = {
930         .crash_reason_smem = 601,
931         .firmware_name = "cdsp.mdt",
932         .pas_id = 18,
933         .auto_boot = true,
934         .proxy_pd_names = (char*[]){
935                 "cx",
936                 NULL
937         },
938         .load_state = "cdsp",
939         .ssr_name = "cdsp",
940         .sysmon_name = "cdsp",
941         .ssctl_id = 0x17,
942 };
943
944 static const struct adsp_data sm8250_cdsp_resource = {
945         .crash_reason_smem = 601,
946         .firmware_name = "cdsp.mdt",
947         .pas_id = 18,
948         .auto_boot = true,
949         .proxy_pd_names = (char*[]){
950                 "cx",
951                 NULL
952         },
953         .load_state = "cdsp",
954         .ssr_name = "cdsp",
955         .sysmon_name = "cdsp",
956         .ssctl_id = 0x17,
957 };
958
959 static const struct adsp_data sc8280xp_nsp0_resource = {
960         .crash_reason_smem = 601,
961         .firmware_name = "cdsp.mdt",
962         .pas_id = 18,
963         .auto_boot = true,
964         .proxy_pd_names = (char*[]){
965                 "nsp",
966                 NULL
967         },
968         .ssr_name = "cdsp0",
969         .sysmon_name = "cdsp",
970         .ssctl_id = 0x17,
971 };
972
973 static const struct adsp_data sc8280xp_nsp1_resource = {
974         .crash_reason_smem = 633,
975         .firmware_name = "cdsp.mdt",
976         .pas_id = 30,
977         .auto_boot = true,
978         .proxy_pd_names = (char*[]){
979                 "nsp",
980                 NULL
981         },
982         .ssr_name = "cdsp1",
983         .sysmon_name = "cdsp1",
984         .ssctl_id = 0x20,
985 };
986
987 static const struct adsp_data sm8350_cdsp_resource = {
988         .crash_reason_smem = 601,
989         .firmware_name = "cdsp.mdt",
990         .pas_id = 18,
991         .auto_boot = true,
992         .proxy_pd_names = (char*[]){
993                 "cx",
994                 "mxc",
995                 NULL
996         },
997         .load_state = "cdsp",
998         .ssr_name = "cdsp",
999         .sysmon_name = "cdsp",
1000         .ssctl_id = 0x17,
1001 };
1002
1003 static const struct adsp_data mpss_resource_init = {
1004         .crash_reason_smem = 421,
1005         .firmware_name = "modem.mdt",
1006         .pas_id = 4,
1007         .minidump_id = 3,
1008         .auto_boot = false,
1009         .proxy_pd_names = (char*[]){
1010                 "cx",
1011                 "mss",
1012                 NULL
1013         },
1014         .load_state = "modem",
1015         .ssr_name = "mpss",
1016         .sysmon_name = "modem",
1017         .ssctl_id = 0x12,
1018 };
1019
1020 static const struct adsp_data sc8180x_mpss_resource = {
1021         .crash_reason_smem = 421,
1022         .firmware_name = "modem.mdt",
1023         .pas_id = 4,
1024         .auto_boot = false,
1025         .proxy_pd_names = (char*[]){
1026                 "cx",
1027                 NULL
1028         },
1029         .load_state = "modem",
1030         .ssr_name = "mpss",
1031         .sysmon_name = "modem",
1032         .ssctl_id = 0x12,
1033 };
1034
1035 static const struct adsp_data msm8996_slpi_resource_init = {
1036                 .crash_reason_smem = 424,
1037                 .firmware_name = "slpi.mdt",
1038                 .pas_id = 12,
1039                 .auto_boot = true,
1040                 .proxy_pd_names = (char*[]){
1041                         "ssc_cx",
1042                         NULL
1043                 },
1044                 .ssr_name = "dsps",
1045                 .sysmon_name = "slpi",
1046                 .ssctl_id = 0x16,
1047 };
1048
1049 static const struct adsp_data sdm845_slpi_resource_init = {
1050                 .crash_reason_smem = 424,
1051                 .firmware_name = "slpi.mdt",
1052                 .pas_id = 12,
1053                 .auto_boot = true,
1054                 .proxy_pd_names = (char*[]){
1055                         "lcx",
1056                         "lmx",
1057                         NULL
1058                 },
1059                 .load_state = "slpi",
1060                 .ssr_name = "dsps",
1061                 .sysmon_name = "slpi",
1062                 .ssctl_id = 0x16,
1063 };
1064
1065 static const struct adsp_data wcss_resource_init = {
1066         .crash_reason_smem = 421,
1067         .firmware_name = "wcnss.mdt",
1068         .pas_id = 6,
1069         .auto_boot = true,
1070         .ssr_name = "mpss",
1071         .sysmon_name = "wcnss",
1072         .ssctl_id = 0x12,
1073 };
1074
1075 static const struct adsp_data sdx55_mpss_resource = {
1076         .crash_reason_smem = 421,
1077         .firmware_name = "modem.mdt",
1078         .pas_id = 4,
1079         .auto_boot = true,
1080         .proxy_pd_names = (char*[]){
1081                 "cx",
1082                 "mss",
1083                 NULL
1084         },
1085         .ssr_name = "mpss",
1086         .sysmon_name = "modem",
1087         .ssctl_id = 0x22,
1088 };
1089
1090 static const struct adsp_data sm8450_mpss_resource = {
1091         .crash_reason_smem = 421,
1092         .firmware_name = "modem.mdt",
1093         .pas_id = 4,
1094         .minidump_id = 3,
1095         .auto_boot = false,
1096         .decrypt_shutdown = true,
1097         .proxy_pd_names = (char*[]){
1098                 "cx",
1099                 "mss",
1100                 NULL
1101         },
1102         .load_state = "modem",
1103         .ssr_name = "mpss",
1104         .sysmon_name = "modem",
1105         .ssctl_id = 0x12,
1106 };
1107
1108 static const struct adsp_data sm8550_adsp_resource = {
1109         .crash_reason_smem = 423,
1110         .firmware_name = "adsp.mdt",
1111         .dtb_firmware_name = "adsp_dtb.mdt",
1112         .pas_id = 1,
1113         .dtb_pas_id = 0x24,
1114         .minidump_id = 5,
1115         .auto_boot = true,
1116         .proxy_pd_names = (char*[]){
1117                 "lcx",
1118                 "lmx",
1119                 NULL
1120         },
1121         .load_state = "adsp",
1122         .ssr_name = "lpass",
1123         .sysmon_name = "adsp",
1124         .ssctl_id = 0x14,
1125 };
1126
1127 static const struct adsp_data sm8550_cdsp_resource = {
1128         .crash_reason_smem = 601,
1129         .firmware_name = "cdsp.mdt",
1130         .dtb_firmware_name = "cdsp_dtb.mdt",
1131         .pas_id = 18,
1132         .dtb_pas_id = 0x25,
1133         .minidump_id = 7,
1134         .auto_boot = true,
1135         .proxy_pd_names = (char*[]){
1136                 "cx",
1137                 "mxc",
1138                 "nsp",
1139                 NULL
1140         },
1141         .load_state = "cdsp",
1142         .ssr_name = "cdsp",
1143         .sysmon_name = "cdsp",
1144         .ssctl_id = 0x17,
1145 };
1146
1147 static const struct adsp_data sm8550_mpss_resource = {
1148         .crash_reason_smem = 421,
1149         .firmware_name = "modem.mdt",
1150         .dtb_firmware_name = "modem_dtb.mdt",
1151         .pas_id = 4,
1152         .dtb_pas_id = 0x26,
1153         .minidump_id = 3,
1154         .auto_boot = false,
1155         .decrypt_shutdown = true,
1156         .proxy_pd_names = (char*[]){
1157                 "cx",
1158                 "mss",
1159                 NULL
1160         },
1161         .load_state = "modem",
1162         .ssr_name = "mpss",
1163         .sysmon_name = "modem",
1164         .ssctl_id = 0x12,
1165         .region_assign_idx = 2,
1166 };
1167
1168 static const struct adsp_data sc7280_wpss_resource = {
1169         .crash_reason_smem = 626,
1170         .firmware_name = "wpss.mdt",
1171         .pas_id = 6,
1172         .auto_boot = true,
1173         .proxy_pd_names = (char*[]){
1174                 "cx",
1175                 "mx",
1176                 NULL
1177         },
1178         .load_state = "wpss",
1179         .ssr_name = "wpss",
1180         .sysmon_name = "wpss",
1181         .ssctl_id = 0x19,
1182 };
1183
1184 static const struct of_device_id adsp_of_match[] = {
1185         { .compatible = "qcom,msm8226-adsp-pil", .data = &adsp_resource_init},
1186         { .compatible = "qcom,msm8953-adsp-pil", .data = &msm8996_adsp_resource},
1187         { .compatible = "qcom,msm8974-adsp-pil", .data = &adsp_resource_init},
1188         { .compatible = "qcom,msm8996-adsp-pil", .data = &msm8996_adsp_resource},
1189         { .compatible = "qcom,msm8996-slpi-pil", .data = &msm8996_slpi_resource_init},
1190         { .compatible = "qcom,msm8998-adsp-pas", .data = &msm8996_adsp_resource},
1191         { .compatible = "qcom,msm8998-slpi-pas", .data = &msm8996_slpi_resource_init},
1192         { .compatible = "qcom,qcs404-adsp-pas", .data = &adsp_resource_init },
1193         { .compatible = "qcom,qcs404-cdsp-pas", .data = &cdsp_resource_init },
1194         { .compatible = "qcom,qcs404-wcss-pas", .data = &wcss_resource_init },
1195         { .compatible = "qcom,sc7180-adsp-pas", .data = &sm8250_adsp_resource},
1196         { .compatible = "qcom,sc7180-mpss-pas", .data = &mpss_resource_init},
1197         { .compatible = "qcom,sc7280-adsp-pas", .data = &sm8350_adsp_resource},
1198         { .compatible = "qcom,sc7280-cdsp-pas", .data = &sm6350_cdsp_resource},
1199         { .compatible = "qcom,sc7280-mpss-pas", .data = &mpss_resource_init},
1200         { .compatible = "qcom,sc7280-wpss-pas", .data = &sc7280_wpss_resource},
1201         { .compatible = "qcom,sc8180x-adsp-pas", .data = &sm8150_adsp_resource},
1202         { .compatible = "qcom,sc8180x-cdsp-pas", .data = &sm8150_cdsp_resource},
1203         { .compatible = "qcom,sc8180x-mpss-pas", .data = &sc8180x_mpss_resource},
1204         { .compatible = "qcom,sc8280xp-adsp-pas", .data = &sm8250_adsp_resource},
1205         { .compatible = "qcom,sc8280xp-nsp0-pas", .data = &sc8280xp_nsp0_resource},
1206         { .compatible = "qcom,sc8280xp-nsp1-pas", .data = &sc8280xp_nsp1_resource},
1207         { .compatible = "qcom,sdm660-adsp-pas", .data = &adsp_resource_init},
1208         { .compatible = "qcom,sdm845-adsp-pas", .data = &sdm845_adsp_resource_init},
1209         { .compatible = "qcom,sdm845-cdsp-pas", .data = &sdm845_cdsp_resource_init},
1210         { .compatible = "qcom,sdm845-slpi-pas", .data = &sdm845_slpi_resource_init},
1211         { .compatible = "qcom,sdx55-mpss-pas", .data = &sdx55_mpss_resource},
1212         { .compatible = "qcom,sm6115-adsp-pas", .data = &adsp_resource_init},
1213         { .compatible = "qcom,sm6115-cdsp-pas", .data = &cdsp_resource_init},
1214         { .compatible = "qcom,sm6115-mpss-pas", .data = &sc8180x_mpss_resource},
1215         { .compatible = "qcom,sm6350-adsp-pas", .data = &sm6350_adsp_resource},
1216         { .compatible = "qcom,sm6350-cdsp-pas", .data = &sm6350_cdsp_resource},
1217         { .compatible = "qcom,sm6350-mpss-pas", .data = &mpss_resource_init},
1218         { .compatible = "qcom,sm6375-adsp-pas", .data = &sm6350_adsp_resource},
1219         { .compatible = "qcom,sm6375-cdsp-pas", .data = &sm8150_cdsp_resource},
1220         { .compatible = "qcom,sm6375-mpss-pas", .data = &sm6375_mpss_resource},
1221         { .compatible = "qcom,sm8150-adsp-pas", .data = &sm8150_adsp_resource},
1222         { .compatible = "qcom,sm8150-cdsp-pas", .data = &sm8150_cdsp_resource},
1223         { .compatible = "qcom,sm8150-mpss-pas", .data = &mpss_resource_init},
1224         { .compatible = "qcom,sm8150-slpi-pas", .data = &sdm845_slpi_resource_init},
1225         { .compatible = "qcom,sm8250-adsp-pas", .data = &sm8250_adsp_resource},
1226         { .compatible = "qcom,sm8250-cdsp-pas", .data = &sm8250_cdsp_resource},
1227         { .compatible = "qcom,sm8250-slpi-pas", .data = &sdm845_slpi_resource_init},
1228         { .compatible = "qcom,sm8350-adsp-pas", .data = &sm8350_adsp_resource},
1229         { .compatible = "qcom,sm8350-cdsp-pas", .data = &sm8350_cdsp_resource},
1230         { .compatible = "qcom,sm8350-slpi-pas", .data = &sdm845_slpi_resource_init},
1231         { .compatible = "qcom,sm8350-mpss-pas", .data = &mpss_resource_init},
1232         { .compatible = "qcom,sm8450-adsp-pas", .data = &sm8350_adsp_resource},
1233         { .compatible = "qcom,sm8450-cdsp-pas", .data = &sm8350_cdsp_resource},
1234         { .compatible = "qcom,sm8450-slpi-pas", .data = &sdm845_slpi_resource_init},
1235         { .compatible = "qcom,sm8450-mpss-pas", .data = &sm8450_mpss_resource},
1236         { .compatible = "qcom,sm8550-adsp-pas", .data = &sm8550_adsp_resource},
1237         { .compatible = "qcom,sm8550-cdsp-pas", .data = &sm8550_cdsp_resource},
1238         { .compatible = "qcom,sm8550-mpss-pas", .data = &sm8550_mpss_resource},
1239         { },
1240 };
1241 MODULE_DEVICE_TABLE(of, adsp_of_match);
1242
1243 static struct platform_driver adsp_driver = {
1244         .probe = adsp_probe,
1245         .remove_new = adsp_remove,
1246         .driver = {
1247                 .name = "qcom_q6v5_pas",
1248                 .of_match_table = adsp_of_match,
1249         },
1250 };
1251
1252 module_platform_driver(adsp_driver);
1253 MODULE_DESCRIPTION("Qualcomm Hexagon v5 Peripheral Authentication Service driver");
1254 MODULE_LICENSE("GPL v2");