Merge tag 'rproc-v6.9' of git://git.kernel.org/pub/scm/linux/kernel/git/remoteproc...
[sfrench/cifs-2.6.git] / drivers / remoteproc / qcom_q6v5_adsp.c
1 // SPDX-License-Identifier: GPL-2.0
2 /*
3  * Qualcomm Technology Inc. ADSP Peripheral Image Loader for SDM845.
4  * Copyright (c) 2018, The Linux Foundation. All rights reserved.
5  */
6
7 #include <linux/clk.h>
8 #include <linux/delay.h>
9 #include <linux/firmware.h>
10 #include <linux/interrupt.h>
11 #include <linux/io.h>
12 #include <linux/iommu.h>
13 #include <linux/iopoll.h>
14 #include <linux/kernel.h>
15 #include <linux/mfd/syscon.h>
16 #include <linux/module.h>
17 #include <linux/of.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/regmap.h>
23 #include <linux/remoteproc.h>
24 #include <linux/reset.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 /* time out value */
35 #define ACK_TIMEOUT                     1000
36 #define ACK_TIMEOUT_US                  1000000
37 #define BOOT_FSM_TIMEOUT                10000
38 /* mask values */
39 #define EVB_MASK                        GENMASK(27, 4)
40 /*QDSP6SS register offsets*/
41 #define RST_EVB_REG                     0x10
42 #define CORE_START_REG                  0x400
43 #define BOOT_CMD_REG                    0x404
44 #define BOOT_STATUS_REG                 0x408
45 #define RET_CFG_REG                     0x1C
46 /*TCSR register offsets*/
47 #define LPASS_MASTER_IDLE_REG           0x8
48 #define LPASS_HALTACK_REG               0x4
49 #define LPASS_PWR_ON_REG                0x10
50 #define LPASS_HALTREQ_REG               0x0
51
52 #define SID_MASK_DEFAULT        0xF
53
54 #define QDSP6SS_XO_CBCR         0x38
55 #define QDSP6SS_CORE_CBCR       0x20
56 #define QDSP6SS_SLEEP_CBCR      0x3c
57
58 #define LPASS_BOOT_CORE_START   BIT(0)
59 #define LPASS_BOOT_CMD_START    BIT(0)
60 #define LPASS_EFUSE_Q6SS_EVB_SEL 0x0
61
62 struct adsp_pil_data {
63         int crash_reason_smem;
64         const char *firmware_name;
65
66         const char *ssr_name;
67         const char *sysmon_name;
68         int ssctl_id;
69         bool is_wpss;
70         bool has_iommu;
71         bool auto_boot;
72
73         const char **clk_ids;
74         int num_clks;
75         const char **pd_names;
76         unsigned int num_pds;
77         const char *load_state;
78 };
79
80 struct qcom_adsp {
81         struct device *dev;
82         struct rproc *rproc;
83
84         struct qcom_q6v5 q6v5;
85
86         struct clk *xo;
87
88         int num_clks;
89         struct clk_bulk_data *clks;
90
91         void __iomem *qdsp6ss_base;
92         void __iomem *lpass_efuse;
93
94         struct reset_control *pdc_sync_reset;
95         struct reset_control *restart;
96
97         struct regmap *halt_map;
98         unsigned int halt_lpass;
99
100         int crash_reason_smem;
101         const char *info_name;
102
103         struct completion start_done;
104         struct completion stop_done;
105
106         phys_addr_t mem_phys;
107         phys_addr_t mem_reloc;
108         void *mem_region;
109         size_t mem_size;
110         bool has_iommu;
111
112         struct dev_pm_domain_list *pd_list;
113
114         struct qcom_rproc_glink glink_subdev;
115         struct qcom_rproc_ssr ssr_subdev;
116         struct qcom_sysmon *sysmon;
117
118         int (*shutdown)(struct qcom_adsp *adsp);
119 };
120
121 static int qcom_rproc_pds_attach(struct qcom_adsp *adsp, const char **pd_names,
122                                  unsigned int num_pds)
123 {
124         struct device *dev = adsp->dev;
125         struct dev_pm_domain_attach_data pd_data = {
126                 .pd_names = pd_names,
127                 .num_pd_names = num_pds,
128         };
129         int ret;
130
131         /* Handle single power domain */
132         if (dev->pm_domain)
133                 goto out;
134
135         if (!pd_names)
136                 return 0;
137
138         ret = dev_pm_domain_attach_list(dev, &pd_data, &adsp->pd_list);
139         if (ret < 0)
140                 return ret;
141
142 out:
143         pm_runtime_enable(dev);
144         return 0;
145 }
146
147 static void qcom_rproc_pds_detach(struct qcom_adsp *adsp)
148 {
149         struct device *dev = adsp->dev;
150         struct dev_pm_domain_list *pds = adsp->pd_list;
151
152         dev_pm_domain_detach_list(pds);
153
154         if (dev->pm_domain || pds)
155                 pm_runtime_disable(adsp->dev);
156 }
157
158 static int qcom_rproc_pds_enable(struct qcom_adsp *adsp)
159 {
160         struct device *dev = adsp->dev;
161         struct dev_pm_domain_list *pds = adsp->pd_list;
162         int ret, i = 0;
163
164         if (!dev->pm_domain && !pds)
165                 return 0;
166
167         if (dev->pm_domain)
168                 dev_pm_genpd_set_performance_state(dev, INT_MAX);
169
170         while (pds && i < pds->num_pds) {
171                 dev_pm_genpd_set_performance_state(pds->pd_devs[i], INT_MAX);
172                 i++;
173         }
174
175         ret = pm_runtime_resume_and_get(dev);
176         if (ret < 0) {
177                 while (pds && i > 0) {
178                         i--;
179                         dev_pm_genpd_set_performance_state(pds->pd_devs[i], 0);
180                 }
181
182                 if (dev->pm_domain)
183                         dev_pm_genpd_set_performance_state(dev, 0);
184         }
185
186         return ret;
187 }
188
189 static void qcom_rproc_pds_disable(struct qcom_adsp *adsp)
190 {
191         struct device *dev = adsp->dev;
192         struct dev_pm_domain_list *pds = adsp->pd_list;
193         int i = 0;
194
195         if (!dev->pm_domain && !pds)
196                 return;
197
198         if (dev->pm_domain)
199                 dev_pm_genpd_set_performance_state(dev, 0);
200
201         while (pds && i < pds->num_pds) {
202                 dev_pm_genpd_set_performance_state(pds->pd_devs[i], 0);
203                 i++;
204         }
205
206         pm_runtime_put(dev);
207 }
208
209 static int qcom_wpss_shutdown(struct qcom_adsp *adsp)
210 {
211         unsigned int val;
212
213         regmap_write(adsp->halt_map, adsp->halt_lpass + LPASS_HALTREQ_REG, 1);
214
215         /* Wait for halt ACK from QDSP6 */
216         regmap_read_poll_timeout(adsp->halt_map,
217                                  adsp->halt_lpass + LPASS_HALTACK_REG, val,
218                                  val, 1000, ACK_TIMEOUT_US);
219
220         /* Assert the WPSS PDC Reset */
221         reset_control_assert(adsp->pdc_sync_reset);
222
223         /* Place the WPSS processor into reset */
224         reset_control_assert(adsp->restart);
225
226         /* wait after asserting subsystem restart from AOSS */
227         usleep_range(200, 205);
228
229         /* Remove the WPSS reset */
230         reset_control_deassert(adsp->restart);
231
232         /* De-assert the WPSS PDC Reset */
233         reset_control_deassert(adsp->pdc_sync_reset);
234
235         usleep_range(100, 105);
236
237         clk_bulk_disable_unprepare(adsp->num_clks, adsp->clks);
238
239         regmap_write(adsp->halt_map, adsp->halt_lpass + LPASS_HALTREQ_REG, 0);
240
241         /* Wait for halt ACK from QDSP6 */
242         regmap_read_poll_timeout(adsp->halt_map,
243                                  adsp->halt_lpass + LPASS_HALTACK_REG, val,
244                                  !val, 1000, ACK_TIMEOUT_US);
245
246         return 0;
247 }
248
249 static int qcom_adsp_shutdown(struct qcom_adsp *adsp)
250 {
251         unsigned long timeout;
252         unsigned int val;
253         int ret;
254
255         /* Reset the retention logic */
256         val = readl(adsp->qdsp6ss_base + RET_CFG_REG);
257         val |= 0x1;
258         writel(val, adsp->qdsp6ss_base + RET_CFG_REG);
259
260         clk_bulk_disable_unprepare(adsp->num_clks, adsp->clks);
261
262         /* QDSP6 master port needs to be explicitly halted */
263         ret = regmap_read(adsp->halt_map,
264                         adsp->halt_lpass + LPASS_PWR_ON_REG, &val);
265         if (ret || !val)
266                 goto reset;
267
268         ret = regmap_read(adsp->halt_map,
269                         adsp->halt_lpass + LPASS_MASTER_IDLE_REG,
270                         &val);
271         if (ret || val)
272                 goto reset;
273
274         regmap_write(adsp->halt_map,
275                         adsp->halt_lpass + LPASS_HALTREQ_REG, 1);
276
277         /* Wait for halt ACK from QDSP6 */
278         timeout = jiffies + msecs_to_jiffies(ACK_TIMEOUT);
279         for (;;) {
280                 ret = regmap_read(adsp->halt_map,
281                         adsp->halt_lpass + LPASS_HALTACK_REG, &val);
282                 if (ret || val || time_after(jiffies, timeout))
283                         break;
284
285                 usleep_range(1000, 1100);
286         }
287
288         ret = regmap_read(adsp->halt_map,
289                         adsp->halt_lpass + LPASS_MASTER_IDLE_REG, &val);
290         if (ret || !val)
291                 dev_err(adsp->dev, "port failed halt\n");
292
293 reset:
294         /* Assert the LPASS PDC Reset */
295         reset_control_assert(adsp->pdc_sync_reset);
296         /* Place the LPASS processor into reset */
297         reset_control_assert(adsp->restart);
298         /* wait after asserting subsystem restart from AOSS */
299         usleep_range(200, 300);
300
301         /* Clear the halt request for the AXIM and AHBM for Q6 */
302         regmap_write(adsp->halt_map, adsp->halt_lpass + LPASS_HALTREQ_REG, 0);
303
304         /* De-assert the LPASS PDC Reset */
305         reset_control_deassert(adsp->pdc_sync_reset);
306         /* Remove the LPASS reset */
307         reset_control_deassert(adsp->restart);
308         /* wait after de-asserting subsystem restart from AOSS */
309         usleep_range(200, 300);
310
311         return 0;
312 }
313
314 static int adsp_load(struct rproc *rproc, const struct firmware *fw)
315 {
316         struct qcom_adsp *adsp = rproc->priv;
317         int ret;
318
319         ret = qcom_mdt_load_no_init(adsp->dev, fw, rproc->firmware, 0,
320                                     adsp->mem_region, adsp->mem_phys,
321                                     adsp->mem_size, &adsp->mem_reloc);
322         if (ret)
323                 return ret;
324
325         qcom_pil_info_store(adsp->info_name, adsp->mem_phys, adsp->mem_size);
326
327         return 0;
328 }
329
330 static void adsp_unmap_carveout(struct rproc *rproc)
331 {
332         struct qcom_adsp *adsp = rproc->priv;
333
334         if (adsp->has_iommu)
335                 iommu_unmap(rproc->domain, adsp->mem_phys, adsp->mem_size);
336 }
337
338 static int adsp_map_carveout(struct rproc *rproc)
339 {
340         struct qcom_adsp *adsp = rproc->priv;
341         struct of_phandle_args args;
342         long long sid;
343         unsigned long iova;
344         int ret;
345
346         if (!adsp->has_iommu)
347                 return 0;
348
349         if (!rproc->domain)
350                 return -EINVAL;
351
352         ret = of_parse_phandle_with_args(adsp->dev->of_node, "iommus", "#iommu-cells", 0, &args);
353         if (ret < 0)
354                 return ret;
355
356         sid = args.args[0] & SID_MASK_DEFAULT;
357
358         /* Add SID configuration for ADSP Firmware to SMMU */
359         iova =  adsp->mem_phys | (sid << 32);
360
361         ret = iommu_map(rproc->domain, iova, adsp->mem_phys,
362                         adsp->mem_size, IOMMU_READ | IOMMU_WRITE,
363                         GFP_KERNEL);
364         if (ret) {
365                 dev_err(adsp->dev, "Unable to map ADSP Physical Memory\n");
366                 return ret;
367         }
368
369         return 0;
370 }
371
372 static int adsp_start(struct rproc *rproc)
373 {
374         struct qcom_adsp *adsp = rproc->priv;
375         int ret;
376         unsigned int val;
377
378         ret = qcom_q6v5_prepare(&adsp->q6v5);
379         if (ret)
380                 return ret;
381
382         ret = adsp_map_carveout(rproc);
383         if (ret) {
384                 dev_err(adsp->dev, "ADSP smmu mapping failed\n");
385                 goto disable_irqs;
386         }
387
388         ret = clk_prepare_enable(adsp->xo);
389         if (ret)
390                 goto adsp_smmu_unmap;
391
392         ret = qcom_rproc_pds_enable(adsp);
393         if (ret < 0)
394                 goto disable_xo_clk;
395
396         ret = clk_bulk_prepare_enable(adsp->num_clks, adsp->clks);
397         if (ret) {
398                 dev_err(adsp->dev, "adsp clk_enable failed\n");
399                 goto disable_power_domain;
400         }
401
402         /* Enable the XO clock */
403         writel(1, adsp->qdsp6ss_base + QDSP6SS_XO_CBCR);
404
405         /* Enable the QDSP6SS sleep clock */
406         writel(1, adsp->qdsp6ss_base + QDSP6SS_SLEEP_CBCR);
407
408         /* Enable the QDSP6 core clock */
409         writel(1, adsp->qdsp6ss_base + QDSP6SS_CORE_CBCR);
410
411         /* Program boot address */
412         writel(adsp->mem_phys >> 4, adsp->qdsp6ss_base + RST_EVB_REG);
413
414         if (adsp->lpass_efuse)
415                 writel(LPASS_EFUSE_Q6SS_EVB_SEL, adsp->lpass_efuse);
416
417         /* De-assert QDSP6 stop core. QDSP6 will execute after out of reset */
418         writel(LPASS_BOOT_CORE_START, adsp->qdsp6ss_base + CORE_START_REG);
419
420         /* Trigger boot FSM to start QDSP6 */
421         writel(LPASS_BOOT_CMD_START, adsp->qdsp6ss_base + BOOT_CMD_REG);
422
423         /* Wait for core to come out of reset */
424         ret = readl_poll_timeout(adsp->qdsp6ss_base + BOOT_STATUS_REG,
425                         val, (val & BIT(0)) != 0, 10, BOOT_FSM_TIMEOUT);
426         if (ret) {
427                 dev_err(adsp->dev, "failed to bootup adsp\n");
428                 goto disable_adsp_clks;
429         }
430
431         ret = qcom_q6v5_wait_for_start(&adsp->q6v5, msecs_to_jiffies(5 * HZ));
432         if (ret == -ETIMEDOUT) {
433                 dev_err(adsp->dev, "start timed out\n");
434                 goto disable_adsp_clks;
435         }
436
437         return 0;
438
439 disable_adsp_clks:
440         clk_bulk_disable_unprepare(adsp->num_clks, adsp->clks);
441 disable_power_domain:
442         qcom_rproc_pds_disable(adsp);
443 disable_xo_clk:
444         clk_disable_unprepare(adsp->xo);
445 adsp_smmu_unmap:
446         adsp_unmap_carveout(rproc);
447 disable_irqs:
448         qcom_q6v5_unprepare(&adsp->q6v5);
449
450         return ret;
451 }
452
453 static void qcom_adsp_pil_handover(struct qcom_q6v5 *q6v5)
454 {
455         struct qcom_adsp *adsp = container_of(q6v5, struct qcom_adsp, q6v5);
456
457         clk_disable_unprepare(adsp->xo);
458         qcom_rproc_pds_disable(adsp);
459 }
460
461 static int adsp_stop(struct rproc *rproc)
462 {
463         struct qcom_adsp *adsp = rproc->priv;
464         int handover;
465         int ret;
466
467         ret = qcom_q6v5_request_stop(&adsp->q6v5, adsp->sysmon);
468         if (ret == -ETIMEDOUT)
469                 dev_err(adsp->dev, "timed out on wait\n");
470
471         ret = adsp->shutdown(adsp);
472         if (ret)
473                 dev_err(adsp->dev, "failed to shutdown: %d\n", ret);
474
475         adsp_unmap_carveout(rproc);
476
477         handover = qcom_q6v5_unprepare(&adsp->q6v5);
478         if (handover)
479                 qcom_adsp_pil_handover(&adsp->q6v5);
480
481         return ret;
482 }
483
484 static void *adsp_da_to_va(struct rproc *rproc, u64 da, size_t len, bool *is_iomem)
485 {
486         struct qcom_adsp *adsp = rproc->priv;
487         int offset;
488
489         offset = da - adsp->mem_reloc;
490         if (offset < 0 || offset + len > adsp->mem_size)
491                 return NULL;
492
493         return adsp->mem_region + offset;
494 }
495
496 static int adsp_parse_firmware(struct rproc *rproc, const struct firmware *fw)
497 {
498         struct qcom_adsp *adsp = rproc->priv;
499         int ret;
500
501         ret = qcom_register_dump_segments(rproc, fw);
502         if (ret) {
503                 dev_err(&rproc->dev, "Error in registering dump segments\n");
504                 return ret;
505         }
506
507         if (adsp->has_iommu) {
508                 ret = rproc_elf_load_rsc_table(rproc, fw);
509                 if (ret) {
510                         dev_err(&rproc->dev, "Error in loading resource table\n");
511                         return ret;
512                 }
513         }
514         return 0;
515 }
516
517 static unsigned long adsp_panic(struct rproc *rproc)
518 {
519         struct qcom_adsp *adsp = rproc->priv;
520
521         return qcom_q6v5_panic(&adsp->q6v5);
522 }
523
524 static const struct rproc_ops adsp_ops = {
525         .start = adsp_start,
526         .stop = adsp_stop,
527         .da_to_va = adsp_da_to_va,
528         .parse_fw = adsp_parse_firmware,
529         .load = adsp_load,
530         .panic = adsp_panic,
531 };
532
533 static int adsp_init_clock(struct qcom_adsp *adsp, const char **clk_ids)
534 {
535         int num_clks = 0;
536         int i, ret;
537
538         adsp->xo = devm_clk_get(adsp->dev, "xo");
539         if (IS_ERR(adsp->xo)) {
540                 ret = PTR_ERR(adsp->xo);
541                 if (ret != -EPROBE_DEFER)
542                         dev_err(adsp->dev, "failed to get xo clock");
543                 return ret;
544         }
545
546         for (i = 0; clk_ids[i]; i++)
547                 num_clks++;
548
549         adsp->num_clks = num_clks;
550         adsp->clks = devm_kcalloc(adsp->dev, adsp->num_clks,
551                                 sizeof(*adsp->clks), GFP_KERNEL);
552         if (!adsp->clks)
553                 return -ENOMEM;
554
555         for (i = 0; i < adsp->num_clks; i++)
556                 adsp->clks[i].id = clk_ids[i];
557
558         return devm_clk_bulk_get(adsp->dev, adsp->num_clks, adsp->clks);
559 }
560
561 static int adsp_init_reset(struct qcom_adsp *adsp)
562 {
563         adsp->pdc_sync_reset = devm_reset_control_get_optional_exclusive(adsp->dev,
564                         "pdc_sync");
565         if (IS_ERR(adsp->pdc_sync_reset)) {
566                 dev_err(adsp->dev, "failed to acquire pdc_sync reset\n");
567                 return PTR_ERR(adsp->pdc_sync_reset);
568         }
569
570         adsp->restart = devm_reset_control_get_optional_exclusive(adsp->dev, "restart");
571
572         /* Fall back to the  old "cc_lpass" if "restart" is absent */
573         if (!adsp->restart)
574                 adsp->restart = devm_reset_control_get_exclusive(adsp->dev, "cc_lpass");
575
576         if (IS_ERR(adsp->restart)) {
577                 dev_err(adsp->dev, "failed to acquire restart\n");
578                 return PTR_ERR(adsp->restart);
579         }
580
581         return 0;
582 }
583
584 static int adsp_init_mmio(struct qcom_adsp *adsp,
585                                 struct platform_device *pdev)
586 {
587         struct resource *efuse_region;
588         struct device_node *syscon;
589         int ret;
590
591         adsp->qdsp6ss_base = devm_platform_ioremap_resource(pdev, 0);
592         if (IS_ERR(adsp->qdsp6ss_base)) {
593                 dev_err(adsp->dev, "failed to map QDSP6SS registers\n");
594                 return PTR_ERR(adsp->qdsp6ss_base);
595         }
596
597         efuse_region = platform_get_resource(pdev, IORESOURCE_MEM, 1);
598         if (!efuse_region) {
599                 adsp->lpass_efuse = NULL;
600                 dev_dbg(adsp->dev, "failed to get efuse memory region\n");
601         } else {
602                 adsp->lpass_efuse = devm_ioremap_resource(&pdev->dev, efuse_region);
603                 if (IS_ERR(adsp->lpass_efuse)) {
604                         dev_err(adsp->dev, "failed to map efuse registers\n");
605                         return PTR_ERR(adsp->lpass_efuse);
606                 }
607         }
608         syscon = of_parse_phandle(pdev->dev.of_node, "qcom,halt-regs", 0);
609         if (!syscon) {
610                 dev_err(&pdev->dev, "failed to parse qcom,halt-regs\n");
611                 return -EINVAL;
612         }
613
614         adsp->halt_map = syscon_node_to_regmap(syscon);
615         of_node_put(syscon);
616         if (IS_ERR(adsp->halt_map))
617                 return PTR_ERR(adsp->halt_map);
618
619         ret = of_property_read_u32_index(pdev->dev.of_node, "qcom,halt-regs",
620                         1, &adsp->halt_lpass);
621         if (ret < 0) {
622                 dev_err(&pdev->dev, "no offset in syscon\n");
623                 return ret;
624         }
625
626         return 0;
627 }
628
629 static int adsp_alloc_memory_region(struct qcom_adsp *adsp)
630 {
631         struct reserved_mem *rmem = NULL;
632         struct device_node *node;
633
634         node = of_parse_phandle(adsp->dev->of_node, "memory-region", 0);
635         if (node)
636                 rmem = of_reserved_mem_lookup(node);
637         of_node_put(node);
638
639         if (!rmem) {
640                 dev_err(adsp->dev, "unable to resolve memory-region\n");
641                 return -EINVAL;
642         }
643
644         adsp->mem_phys = adsp->mem_reloc = rmem->base;
645         adsp->mem_size = rmem->size;
646         adsp->mem_region = devm_ioremap_wc(adsp->dev,
647                                 adsp->mem_phys, adsp->mem_size);
648         if (!adsp->mem_region) {
649                 dev_err(adsp->dev, "unable to map memory region: %pa+%zx\n",
650                         &rmem->base, adsp->mem_size);
651                 return -EBUSY;
652         }
653
654         return 0;
655 }
656
657 static int adsp_probe(struct platform_device *pdev)
658 {
659         const struct adsp_pil_data *desc;
660         const char *firmware_name;
661         struct qcom_adsp *adsp;
662         struct rproc *rproc;
663         int ret;
664
665         desc = of_device_get_match_data(&pdev->dev);
666         if (!desc)
667                 return -EINVAL;
668
669         firmware_name = desc->firmware_name;
670         ret = of_property_read_string(pdev->dev.of_node, "firmware-name",
671                                       &firmware_name);
672         if (ret < 0 && ret != -EINVAL) {
673                 dev_err(&pdev->dev, "unable to read firmware-name\n");
674                 return ret;
675         }
676
677         rproc = devm_rproc_alloc(&pdev->dev, pdev->name, &adsp_ops,
678                                  firmware_name, sizeof(*adsp));
679         if (!rproc) {
680                 dev_err(&pdev->dev, "unable to allocate remoteproc\n");
681                 return -ENOMEM;
682         }
683
684         rproc->auto_boot = desc->auto_boot;
685         rproc->has_iommu = desc->has_iommu;
686         rproc_coredump_set_elf_info(rproc, ELFCLASS32, EM_NONE);
687
688         adsp = rproc->priv;
689         adsp->dev = &pdev->dev;
690         adsp->rproc = rproc;
691         adsp->info_name = desc->sysmon_name;
692         adsp->has_iommu = desc->has_iommu;
693
694         platform_set_drvdata(pdev, adsp);
695
696         if (desc->is_wpss)
697                 adsp->shutdown = qcom_wpss_shutdown;
698         else
699                 adsp->shutdown = qcom_adsp_shutdown;
700
701         ret = adsp_alloc_memory_region(adsp);
702         if (ret)
703                 return ret;
704
705         ret = adsp_init_clock(adsp, desc->clk_ids);
706         if (ret)
707                 return ret;
708
709         ret = qcom_rproc_pds_attach(adsp, desc->pd_names, desc->num_pds);
710         if (ret < 0) {
711                 dev_err(&pdev->dev, "Failed to attach proxy power domains\n");
712                 return ret;
713         }
714
715         ret = adsp_init_reset(adsp);
716         if (ret)
717                 goto disable_pm;
718
719         ret = adsp_init_mmio(adsp, pdev);
720         if (ret)
721                 goto disable_pm;
722
723         ret = qcom_q6v5_init(&adsp->q6v5, pdev, rproc, desc->crash_reason_smem,
724                              desc->load_state, qcom_adsp_pil_handover);
725         if (ret)
726                 goto disable_pm;
727
728         qcom_add_glink_subdev(rproc, &adsp->glink_subdev, desc->ssr_name);
729         qcom_add_ssr_subdev(rproc, &adsp->ssr_subdev, desc->ssr_name);
730         adsp->sysmon = qcom_add_sysmon_subdev(rproc,
731                                               desc->sysmon_name,
732                                               desc->ssctl_id);
733         if (IS_ERR(adsp->sysmon)) {
734                 ret = PTR_ERR(adsp->sysmon);
735                 goto disable_pm;
736         }
737
738         ret = rproc_add(rproc);
739         if (ret)
740                 goto disable_pm;
741
742         return 0;
743
744 disable_pm:
745         qcom_rproc_pds_detach(adsp);
746
747         return ret;
748 }
749
750 static void adsp_remove(struct platform_device *pdev)
751 {
752         struct qcom_adsp *adsp = platform_get_drvdata(pdev);
753
754         rproc_del(adsp->rproc);
755
756         qcom_q6v5_deinit(&adsp->q6v5);
757         qcom_remove_glink_subdev(adsp->rproc, &adsp->glink_subdev);
758         qcom_remove_sysmon_subdev(adsp->sysmon);
759         qcom_remove_ssr_subdev(adsp->rproc, &adsp->ssr_subdev);
760         qcom_rproc_pds_detach(adsp);
761 }
762
763 static const struct adsp_pil_data adsp_resource_init = {
764         .crash_reason_smem = 423,
765         .firmware_name = "adsp.mdt",
766         .ssr_name = "lpass",
767         .sysmon_name = "adsp",
768         .ssctl_id = 0x14,
769         .is_wpss = false,
770         .auto_boot = true,
771         .clk_ids = (const char*[]) {
772                 "sway_cbcr", "lpass_ahbs_aon_cbcr", "lpass_ahbm_aon_cbcr",
773                 "qdsp6ss_xo", "qdsp6ss_sleep", "qdsp6ss_core", NULL
774         },
775         .num_clks = 7,
776         .pd_names = (const char*[]) { "cx" },
777         .num_pds = 1,
778 };
779
780 static const struct adsp_pil_data adsp_sc7280_resource_init = {
781         .crash_reason_smem = 423,
782         .firmware_name = "adsp.pbn",
783         .load_state = "adsp",
784         .ssr_name = "lpass",
785         .sysmon_name = "adsp",
786         .ssctl_id = 0x14,
787         .has_iommu = true,
788         .auto_boot = true,
789         .clk_ids = (const char*[]) {
790                 "gcc_cfg_noc_lpass", NULL
791         },
792         .num_clks = 1,
793 };
794
795 static const struct adsp_pil_data cdsp_resource_init = {
796         .crash_reason_smem = 601,
797         .firmware_name = "cdsp.mdt",
798         .ssr_name = "cdsp",
799         .sysmon_name = "cdsp",
800         .ssctl_id = 0x17,
801         .is_wpss = false,
802         .auto_boot = true,
803         .clk_ids = (const char*[]) {
804                 "sway", "tbu", "bimc", "ahb_aon", "q6ss_slave", "q6ss_master",
805                 "q6_axim", NULL
806         },
807         .num_clks = 7,
808         .pd_names = (const char*[]) { "cx" },
809         .num_pds = 1,
810 };
811
812 static const struct adsp_pil_data wpss_resource_init = {
813         .crash_reason_smem = 626,
814         .firmware_name = "wpss.mdt",
815         .ssr_name = "wpss",
816         .sysmon_name = "wpss",
817         .ssctl_id = 0x19,
818         .is_wpss = true,
819         .auto_boot = false,
820         .load_state = "wpss",
821         .clk_ids = (const char*[]) {
822                 "ahb_bdg", "ahb", "rscp", NULL
823         },
824         .num_clks = 3,
825         .pd_names = (const char*[]) { "cx", "mx" },
826         .num_pds = 2,
827 };
828
829 static const struct of_device_id adsp_of_match[] = {
830         { .compatible = "qcom,qcs404-cdsp-pil", .data = &cdsp_resource_init },
831         { .compatible = "qcom,sc7280-adsp-pil", .data = &adsp_sc7280_resource_init },
832         { .compatible = "qcom,sc7280-wpss-pil", .data = &wpss_resource_init },
833         { .compatible = "qcom,sdm845-adsp-pil", .data = &adsp_resource_init },
834         { },
835 };
836 MODULE_DEVICE_TABLE(of, adsp_of_match);
837
838 static struct platform_driver adsp_pil_driver = {
839         .probe = adsp_probe,
840         .remove_new = adsp_remove,
841         .driver = {
842                 .name = "qcom_q6v5_adsp",
843                 .of_match_table = adsp_of_match,
844         },
845 };
846
847 module_platform_driver(adsp_pil_driver);
848 MODULE_DESCRIPTION("QTI SDM845 ADSP Peripheral Image Loader");
849 MODULE_LICENSE("GPL v2");