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