1 // SPDX-License-Identifier: GPL-2.0-only
3 * Qualcomm ADSP/SLPI Peripheral Image Loader for MSM8974 and MSM8996
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.
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>
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>
29 #include "qcom_common.h"
30 #include "qcom_pil_info.h"
31 #include "qcom_q6v5.h"
32 #include "remoteproc_internal.h"
34 #define ADSP_DECRYPT_SHUTDOWN_DELAY_MS 100
36 #define MAX_ASSIGN_COUNT 3
39 int crash_reason_smem;
40 const char *firmware_name;
41 const char *dtb_firmware_name;
45 unsigned int minidump_id;
47 bool decrypt_shutdown;
49 char **proxy_pd_names;
51 const char *load_state;
53 const char *sysmon_name;
56 int region_assign_idx;
57 int region_assign_count;
58 bool region_assign_shared;
59 int region_assign_vmid;
66 struct qcom_q6v5 q6v5;
69 struct clk *aggre2_clk;
71 struct regulator *cx_supply;
72 struct regulator *px_supply;
74 struct device *proxy_pds[3];
78 const char *dtb_firmware_name;
82 unsigned int minidump_id;
83 int crash_reason_smem;
84 bool decrypt_shutdown;
85 const char *info_name;
87 const struct firmware *firmware;
88 const struct firmware *dtb_firmware;
90 struct completion start_done;
91 struct completion stop_done;
94 phys_addr_t dtb_mem_phys;
95 phys_addr_t mem_reloc;
96 phys_addr_t dtb_mem_reloc;
97 phys_addr_t region_assign_phys[MAX_ASSIGN_COUNT];
102 size_t region_assign_size[MAX_ASSIGN_COUNT];
104 int region_assign_idx;
105 int region_assign_count;
106 bool region_assign_shared;
107 int region_assign_vmid;
108 u64 region_assign_owners[MAX_ASSIGN_COUNT];
110 struct qcom_rproc_glink glink_subdev;
111 struct qcom_rproc_subdev smd_subdev;
112 struct qcom_rproc_ssr ssr_subdev;
113 struct qcom_sysmon *sysmon;
115 struct qcom_scm_pas_metadata pas_metadata;
116 struct qcom_scm_pas_metadata dtb_pas_metadata;
119 static void adsp_segment_dump(struct rproc *rproc, struct rproc_dump_segment *segment,
120 void *dest, size_t offset, size_t size)
122 struct qcom_adsp *adsp = rproc->priv;
125 total_offset = segment->da + segment->offset + offset - adsp->mem_phys;
126 if (total_offset < 0 || total_offset + size > adsp->mem_size) {
128 "invalid copy request for segment %pad with offset %zu and size %zu)\n",
129 &segment->da, offset, size);
130 memset(dest, 0xff, size);
134 memcpy_fromio(dest, adsp->mem_region + total_offset, size);
137 static void adsp_minidump(struct rproc *rproc)
139 struct qcom_adsp *adsp = rproc->priv;
141 if (rproc->dump_conf == RPROC_COREDUMP_DISABLED)
144 qcom_minidump(rproc, adsp->minidump_id, adsp_segment_dump);
147 static int adsp_pds_enable(struct qcom_adsp *adsp, struct device **pds,
153 for (i = 0; i < pd_count; i++) {
154 dev_pm_genpd_set_performance_state(pds[i], INT_MAX);
155 ret = pm_runtime_get_sync(pds[i]);
157 pm_runtime_put_noidle(pds[i]);
158 dev_pm_genpd_set_performance_state(pds[i], 0);
159 goto unroll_pd_votes;
166 for (i--; i >= 0; i--) {
167 dev_pm_genpd_set_performance_state(pds[i], 0);
168 pm_runtime_put(pds[i]);
174 static void adsp_pds_disable(struct qcom_adsp *adsp, struct device **pds,
179 for (i = 0; i < pd_count; i++) {
180 dev_pm_genpd_set_performance_state(pds[i], 0);
181 pm_runtime_put(pds[i]);
185 static int adsp_shutdown_poll_decrypt(struct qcom_adsp *adsp)
187 unsigned int retry_num = 50;
191 msleep(ADSP_DECRYPT_SHUTDOWN_DELAY_MS);
192 ret = qcom_scm_pas_shutdown(adsp->pas_id);
193 } while (ret == -EINVAL && --retry_num);
198 static int adsp_unprepare(struct rproc *rproc)
200 struct qcom_adsp *adsp = rproc->priv;
203 * adsp_load() did pass pas_metadata to the SCM driver for storing
204 * metadata context. It might have been released already if
205 * auth_and_reset() was successful, but in other cases clean it up
208 qcom_scm_pas_metadata_release(&adsp->pas_metadata);
209 if (adsp->dtb_pas_id)
210 qcom_scm_pas_metadata_release(&adsp->dtb_pas_metadata);
215 static int adsp_load(struct rproc *rproc, const struct firmware *fw)
217 struct qcom_adsp *adsp = rproc->priv;
220 /* Store firmware handle to be used in adsp_start() */
223 if (adsp->lite_pas_id)
224 ret = qcom_scm_pas_shutdown(adsp->lite_pas_id);
226 if (adsp->dtb_pas_id) {
227 ret = request_firmware(&adsp->dtb_firmware, adsp->dtb_firmware_name, adsp->dev);
229 dev_err(adsp->dev, "request_firmware failed for %s: %d\n",
230 adsp->dtb_firmware_name, ret);
234 ret = qcom_mdt_pas_init(adsp->dev, adsp->dtb_firmware, adsp->dtb_firmware_name,
235 adsp->dtb_pas_id, adsp->dtb_mem_phys,
236 &adsp->dtb_pas_metadata);
238 goto release_dtb_firmware;
240 ret = qcom_mdt_load_no_init(adsp->dev, adsp->dtb_firmware, adsp->dtb_firmware_name,
241 adsp->dtb_pas_id, adsp->dtb_mem_region,
242 adsp->dtb_mem_phys, adsp->dtb_mem_size,
243 &adsp->dtb_mem_reloc);
245 goto release_dtb_metadata;
250 release_dtb_metadata:
251 qcom_scm_pas_metadata_release(&adsp->dtb_pas_metadata);
253 release_dtb_firmware:
254 release_firmware(adsp->dtb_firmware);
259 static int adsp_start(struct rproc *rproc)
261 struct qcom_adsp *adsp = rproc->priv;
264 ret = qcom_q6v5_prepare(&adsp->q6v5);
268 ret = adsp_pds_enable(adsp, adsp->proxy_pds, adsp->proxy_pd_count);
272 ret = clk_prepare_enable(adsp->xo);
274 goto disable_proxy_pds;
276 ret = clk_prepare_enable(adsp->aggre2_clk);
280 if (adsp->cx_supply) {
281 ret = regulator_enable(adsp->cx_supply);
283 goto disable_aggre2_clk;
286 if (adsp->px_supply) {
287 ret = regulator_enable(adsp->px_supply);
289 goto disable_cx_supply;
292 if (adsp->dtb_pas_id) {
293 ret = qcom_scm_pas_auth_and_reset(adsp->dtb_pas_id);
296 "failed to authenticate dtb image and release reset\n");
297 goto disable_px_supply;
301 ret = qcom_mdt_pas_init(adsp->dev, adsp->firmware, rproc->firmware, adsp->pas_id,
302 adsp->mem_phys, &adsp->pas_metadata);
304 goto disable_px_supply;
306 ret = qcom_mdt_load_no_init(adsp->dev, adsp->firmware, rproc->firmware, adsp->pas_id,
307 adsp->mem_region, adsp->mem_phys, adsp->mem_size,
310 goto release_pas_metadata;
312 qcom_pil_info_store(adsp->info_name, adsp->mem_phys, adsp->mem_size);
314 ret = qcom_scm_pas_auth_and_reset(adsp->pas_id);
317 "failed to authenticate image and release reset\n");
318 goto release_pas_metadata;
321 ret = qcom_q6v5_wait_for_start(&adsp->q6v5, msecs_to_jiffies(5000));
322 if (ret == -ETIMEDOUT) {
323 dev_err(adsp->dev, "start timed out\n");
324 qcom_scm_pas_shutdown(adsp->pas_id);
325 goto release_pas_metadata;
328 qcom_scm_pas_metadata_release(&adsp->pas_metadata);
329 if (adsp->dtb_pas_id)
330 qcom_scm_pas_metadata_release(&adsp->dtb_pas_metadata);
332 /* Remove pointer to the loaded firmware, only valid in adsp_load() & adsp_start() */
333 adsp->firmware = NULL;
337 release_pas_metadata:
338 qcom_scm_pas_metadata_release(&adsp->pas_metadata);
339 if (adsp->dtb_pas_id)
340 qcom_scm_pas_metadata_release(&adsp->dtb_pas_metadata);
343 regulator_disable(adsp->px_supply);
346 regulator_disable(adsp->cx_supply);
348 clk_disable_unprepare(adsp->aggre2_clk);
350 clk_disable_unprepare(adsp->xo);
352 adsp_pds_disable(adsp, adsp->proxy_pds, adsp->proxy_pd_count);
354 qcom_q6v5_unprepare(&adsp->q6v5);
356 /* Remove pointer to the loaded firmware, only valid in adsp_load() & adsp_start() */
357 adsp->firmware = NULL;
362 static void qcom_pas_handover(struct qcom_q6v5 *q6v5)
364 struct qcom_adsp *adsp = container_of(q6v5, struct qcom_adsp, q6v5);
367 regulator_disable(adsp->px_supply);
369 regulator_disable(adsp->cx_supply);
370 clk_disable_unprepare(adsp->aggre2_clk);
371 clk_disable_unprepare(adsp->xo);
372 adsp_pds_disable(adsp, adsp->proxy_pds, adsp->proxy_pd_count);
375 static int adsp_stop(struct rproc *rproc)
377 struct qcom_adsp *adsp = rproc->priv;
381 ret = qcom_q6v5_request_stop(&adsp->q6v5, adsp->sysmon);
382 if (ret == -ETIMEDOUT)
383 dev_err(adsp->dev, "timed out on wait\n");
385 ret = qcom_scm_pas_shutdown(adsp->pas_id);
386 if (ret && adsp->decrypt_shutdown)
387 ret = adsp_shutdown_poll_decrypt(adsp);
390 dev_err(adsp->dev, "failed to shutdown: %d\n", ret);
392 if (adsp->dtb_pas_id) {
393 ret = qcom_scm_pas_shutdown(adsp->dtb_pas_id);
395 dev_err(adsp->dev, "failed to shutdown dtb: %d\n", ret);
398 handover = qcom_q6v5_unprepare(&adsp->q6v5);
400 qcom_pas_handover(&adsp->q6v5);
405 static void *adsp_da_to_va(struct rproc *rproc, u64 da, size_t len, bool *is_iomem)
407 struct qcom_adsp *adsp = rproc->priv;
410 offset = da - adsp->mem_reloc;
411 if (offset < 0 || offset + len > adsp->mem_size)
417 return adsp->mem_region + offset;
420 static unsigned long adsp_panic(struct rproc *rproc)
422 struct qcom_adsp *adsp = rproc->priv;
424 return qcom_q6v5_panic(&adsp->q6v5);
427 static const struct rproc_ops adsp_ops = {
428 .unprepare = adsp_unprepare,
431 .da_to_va = adsp_da_to_va,
432 .parse_fw = qcom_register_dump_segments,
437 static const struct rproc_ops adsp_minidump_ops = {
438 .unprepare = adsp_unprepare,
441 .da_to_va = adsp_da_to_va,
442 .parse_fw = qcom_register_dump_segments,
445 .coredump = adsp_minidump,
448 static int adsp_init_clock(struct qcom_adsp *adsp)
452 adsp->xo = devm_clk_get(adsp->dev, "xo");
453 if (IS_ERR(adsp->xo)) {
454 ret = PTR_ERR(adsp->xo);
455 if (ret != -EPROBE_DEFER)
456 dev_err(adsp->dev, "failed to get xo clock");
460 adsp->aggre2_clk = devm_clk_get_optional(adsp->dev, "aggre2");
461 if (IS_ERR(adsp->aggre2_clk)) {
462 ret = PTR_ERR(adsp->aggre2_clk);
463 if (ret != -EPROBE_DEFER)
465 "failed to get aggre2 clock");
472 static int adsp_init_regulator(struct qcom_adsp *adsp)
474 adsp->cx_supply = devm_regulator_get_optional(adsp->dev, "cx");
475 if (IS_ERR(adsp->cx_supply)) {
476 if (PTR_ERR(adsp->cx_supply) == -ENODEV)
477 adsp->cx_supply = NULL;
479 return PTR_ERR(adsp->cx_supply);
483 regulator_set_load(adsp->cx_supply, 100000);
485 adsp->px_supply = devm_regulator_get_optional(adsp->dev, "px");
486 if (IS_ERR(adsp->px_supply)) {
487 if (PTR_ERR(adsp->px_supply) == -ENODEV)
488 adsp->px_supply = NULL;
490 return PTR_ERR(adsp->px_supply);
496 static int adsp_pds_attach(struct device *dev, struct device **devs,
506 /* Handle single power domain */
507 if (dev->pm_domain) {
509 pm_runtime_enable(dev);
513 while (pd_names[num_pds])
516 for (i = 0; i < num_pds; i++) {
517 devs[i] = dev_pm_domain_attach_by_name(dev, pd_names[i]);
518 if (IS_ERR_OR_NULL(devs[i])) {
519 ret = PTR_ERR(devs[i]) ? : -ENODATA;
527 for (i--; i >= 0; i--)
528 dev_pm_domain_detach(devs[i], false);
533 static void adsp_pds_detach(struct qcom_adsp *adsp, struct device **pds,
536 struct device *dev = adsp->dev;
539 /* Handle single power domain */
540 if (dev->pm_domain && pd_count) {
541 pm_runtime_disable(dev);
545 for (i = 0; i < pd_count; i++)
546 dev_pm_domain_detach(pds[i], false);
549 static int adsp_alloc_memory_region(struct qcom_adsp *adsp)
551 struct reserved_mem *rmem;
552 struct device_node *node;
554 node = of_parse_phandle(adsp->dev->of_node, "memory-region", 0);
556 dev_err(adsp->dev, "no memory-region specified\n");
560 rmem = of_reserved_mem_lookup(node);
563 dev_err(adsp->dev, "unable to resolve memory-region\n");
567 adsp->mem_phys = adsp->mem_reloc = rmem->base;
568 adsp->mem_size = rmem->size;
569 adsp->mem_region = devm_ioremap_wc(adsp->dev, adsp->mem_phys, adsp->mem_size);
570 if (!adsp->mem_region) {
571 dev_err(adsp->dev, "unable to map memory region: %pa+%zx\n",
572 &rmem->base, adsp->mem_size);
576 if (!adsp->dtb_pas_id)
579 node = of_parse_phandle(adsp->dev->of_node, "memory-region", 1);
581 dev_err(adsp->dev, "no dtb memory-region specified\n");
585 rmem = of_reserved_mem_lookup(node);
588 dev_err(adsp->dev, "unable to resolve dtb memory-region\n");
592 adsp->dtb_mem_phys = adsp->dtb_mem_reloc = rmem->base;
593 adsp->dtb_mem_size = rmem->size;
594 adsp->dtb_mem_region = devm_ioremap_wc(adsp->dev, adsp->dtb_mem_phys, adsp->dtb_mem_size);
595 if (!adsp->dtb_mem_region) {
596 dev_err(adsp->dev, "unable to map dtb memory region: %pa+%zx\n",
597 &rmem->base, adsp->dtb_mem_size);
604 static int adsp_assign_memory_region(struct qcom_adsp *adsp)
606 struct qcom_scm_vmperm perm[MAX_ASSIGN_COUNT];
607 struct device_node *node;
608 unsigned int perm_size;
612 if (!adsp->region_assign_idx)
615 for (offset = 0; offset < adsp->region_assign_count; ++offset) {
616 struct reserved_mem *rmem = NULL;
618 node = of_parse_phandle(adsp->dev->of_node, "memory-region",
619 adsp->region_assign_idx + offset);
621 rmem = of_reserved_mem_lookup(node);
624 dev_err(adsp->dev, "unable to resolve shareable memory-region index %d\n",
629 if (adsp->region_assign_shared) {
630 perm[0].vmid = QCOM_SCM_VMID_HLOS;
631 perm[0].perm = QCOM_SCM_PERM_RW;
632 perm[1].vmid = adsp->region_assign_vmid;
633 perm[1].perm = QCOM_SCM_PERM_RW;
636 perm[0].vmid = adsp->region_assign_vmid;
637 perm[0].perm = QCOM_SCM_PERM_RW;
641 adsp->region_assign_phys[offset] = rmem->base;
642 adsp->region_assign_size[offset] = rmem->size;
643 adsp->region_assign_owners[offset] = BIT(QCOM_SCM_VMID_HLOS);
645 ret = qcom_scm_assign_mem(adsp->region_assign_phys[offset],
646 adsp->region_assign_size[offset],
647 &adsp->region_assign_owners[offset],
650 dev_err(adsp->dev, "assign memory %d failed\n", offset);
658 static void adsp_unassign_memory_region(struct qcom_adsp *adsp)
660 struct qcom_scm_vmperm perm;
664 if (!adsp->region_assign_idx || adsp->region_assign_shared)
667 for (offset = 0; offset < adsp->region_assign_count; ++offset) {
668 perm.vmid = QCOM_SCM_VMID_HLOS;
669 perm.perm = QCOM_SCM_PERM_RW;
671 ret = qcom_scm_assign_mem(adsp->region_assign_phys[offset],
672 adsp->region_assign_size[offset],
673 &adsp->region_assign_owners[offset],
676 dev_err(adsp->dev, "unassign memory %d failed\n", offset);
680 static int adsp_probe(struct platform_device *pdev)
682 const struct adsp_data *desc;
683 struct qcom_adsp *adsp;
685 const char *fw_name, *dtb_fw_name = NULL;
686 const struct rproc_ops *ops = &adsp_ops;
689 desc = of_device_get_match_data(&pdev->dev);
693 if (!qcom_scm_is_available())
694 return -EPROBE_DEFER;
696 fw_name = desc->firmware_name;
697 ret = of_property_read_string(pdev->dev.of_node, "firmware-name",
699 if (ret < 0 && ret != -EINVAL)
702 if (desc->dtb_firmware_name) {
703 dtb_fw_name = desc->dtb_firmware_name;
704 ret = of_property_read_string_index(pdev->dev.of_node, "firmware-name", 1,
706 if (ret < 0 && ret != -EINVAL)
710 if (desc->minidump_id)
711 ops = &adsp_minidump_ops;
713 rproc = devm_rproc_alloc(&pdev->dev, pdev->name, ops, fw_name, sizeof(*adsp));
716 dev_err(&pdev->dev, "unable to allocate remoteproc\n");
720 rproc->auto_boot = desc->auto_boot;
721 rproc_coredump_set_elf_info(rproc, ELFCLASS32, EM_NONE);
724 adsp->dev = &pdev->dev;
726 adsp->minidump_id = desc->minidump_id;
727 adsp->pas_id = desc->pas_id;
728 adsp->lite_pas_id = desc->lite_pas_id;
729 adsp->info_name = desc->sysmon_name;
730 adsp->decrypt_shutdown = desc->decrypt_shutdown;
731 adsp->region_assign_idx = desc->region_assign_idx;
732 adsp->region_assign_count = min_t(int, MAX_ASSIGN_COUNT, desc->region_assign_count);
733 adsp->region_assign_vmid = desc->region_assign_vmid;
734 adsp->region_assign_shared = desc->region_assign_shared;
736 adsp->dtb_firmware_name = dtb_fw_name;
737 adsp->dtb_pas_id = desc->dtb_pas_id;
739 platform_set_drvdata(pdev, adsp);
741 ret = device_init_wakeup(adsp->dev, true);
745 ret = adsp_alloc_memory_region(adsp);
749 ret = adsp_assign_memory_region(adsp);
753 ret = adsp_init_clock(adsp);
757 ret = adsp_init_regulator(adsp);
761 ret = adsp_pds_attach(&pdev->dev, adsp->proxy_pds,
762 desc->proxy_pd_names);
765 adsp->proxy_pd_count = ret;
767 ret = qcom_q6v5_init(&adsp->q6v5, pdev, rproc, desc->crash_reason_smem, desc->load_state,
770 goto detach_proxy_pds;
772 qcom_add_glink_subdev(rproc, &adsp->glink_subdev, desc->ssr_name);
773 qcom_add_smd_subdev(rproc, &adsp->smd_subdev);
774 adsp->sysmon = qcom_add_sysmon_subdev(rproc,
777 if (IS_ERR(adsp->sysmon)) {
778 ret = PTR_ERR(adsp->sysmon);
779 goto detach_proxy_pds;
782 qcom_add_ssr_subdev(rproc, &adsp->ssr_subdev, desc->ssr_name);
783 ret = rproc_add(rproc);
785 goto detach_proxy_pds;
790 adsp_pds_detach(adsp, adsp->proxy_pds, adsp->proxy_pd_count);
792 device_init_wakeup(adsp->dev, false);
797 static void adsp_remove(struct platform_device *pdev)
799 struct qcom_adsp *adsp = platform_get_drvdata(pdev);
801 rproc_del(adsp->rproc);
803 qcom_q6v5_deinit(&adsp->q6v5);
804 adsp_unassign_memory_region(adsp);
805 qcom_remove_glink_subdev(adsp->rproc, &adsp->glink_subdev);
806 qcom_remove_sysmon_subdev(adsp->sysmon);
807 qcom_remove_smd_subdev(adsp->rproc, &adsp->smd_subdev);
808 qcom_remove_ssr_subdev(adsp->rproc, &adsp->ssr_subdev);
809 adsp_pds_detach(adsp, adsp->proxy_pds, adsp->proxy_pd_count);
810 device_init_wakeup(adsp->dev, false);
813 static const struct adsp_data adsp_resource_init = {
814 .crash_reason_smem = 423,
815 .firmware_name = "adsp.mdt",
819 .sysmon_name = "adsp",
823 static const struct adsp_data sdm845_adsp_resource_init = {
824 .crash_reason_smem = 423,
825 .firmware_name = "adsp.mdt",
828 .load_state = "adsp",
830 .sysmon_name = "adsp",
834 static const struct adsp_data sm6350_adsp_resource = {
835 .crash_reason_smem = 423,
836 .firmware_name = "adsp.mdt",
839 .proxy_pd_names = (char*[]){
844 .load_state = "adsp",
846 .sysmon_name = "adsp",
850 static const struct adsp_data sm6375_mpss_resource = {
851 .crash_reason_smem = 421,
852 .firmware_name = "modem.mdt",
856 .proxy_pd_names = (char*[]){
861 .sysmon_name = "modem",
865 static const struct adsp_data sm8150_adsp_resource = {
866 .crash_reason_smem = 423,
867 .firmware_name = "adsp.mdt",
870 .proxy_pd_names = (char*[]){
874 .load_state = "adsp",
876 .sysmon_name = "adsp",
880 static const struct adsp_data sm8250_adsp_resource = {
881 .crash_reason_smem = 423,
882 .firmware_name = "adsp.mdt",
885 .proxy_pd_names = (char*[]){
890 .load_state = "adsp",
892 .sysmon_name = "adsp",
896 static const struct adsp_data sm8350_adsp_resource = {
897 .crash_reason_smem = 423,
898 .firmware_name = "adsp.mdt",
901 .proxy_pd_names = (char*[]){
906 .load_state = "adsp",
908 .sysmon_name = "adsp",
912 static const struct adsp_data msm8996_adsp_resource = {
913 .crash_reason_smem = 423,
914 .firmware_name = "adsp.mdt",
917 .proxy_pd_names = (char*[]){
922 .sysmon_name = "adsp",
926 static const struct adsp_data cdsp_resource_init = {
927 .crash_reason_smem = 601,
928 .firmware_name = "cdsp.mdt",
932 .sysmon_name = "cdsp",
936 static const struct adsp_data sdm845_cdsp_resource_init = {
937 .crash_reason_smem = 601,
938 .firmware_name = "cdsp.mdt",
941 .load_state = "cdsp",
943 .sysmon_name = "cdsp",
947 static const struct adsp_data sm6350_cdsp_resource = {
948 .crash_reason_smem = 601,
949 .firmware_name = "cdsp.mdt",
952 .proxy_pd_names = (char*[]){
957 .load_state = "cdsp",
959 .sysmon_name = "cdsp",
963 static const struct adsp_data sm8150_cdsp_resource = {
964 .crash_reason_smem = 601,
965 .firmware_name = "cdsp.mdt",
968 .proxy_pd_names = (char*[]){
972 .load_state = "cdsp",
974 .sysmon_name = "cdsp",
978 static const struct adsp_data sm8250_cdsp_resource = {
979 .crash_reason_smem = 601,
980 .firmware_name = "cdsp.mdt",
983 .proxy_pd_names = (char*[]){
987 .load_state = "cdsp",
989 .sysmon_name = "cdsp",
993 static const struct adsp_data sc8280xp_nsp0_resource = {
994 .crash_reason_smem = 601,
995 .firmware_name = "cdsp.mdt",
998 .proxy_pd_names = (char*[]){
1002 .ssr_name = "cdsp0",
1003 .sysmon_name = "cdsp",
1007 static const struct adsp_data sc8280xp_nsp1_resource = {
1008 .crash_reason_smem = 633,
1009 .firmware_name = "cdsp.mdt",
1012 .proxy_pd_names = (char*[]){
1016 .ssr_name = "cdsp1",
1017 .sysmon_name = "cdsp1",
1021 static const struct adsp_data x1e80100_adsp_resource = {
1022 .crash_reason_smem = 423,
1023 .firmware_name = "adsp.mdt",
1024 .dtb_firmware_name = "adsp_dtb.mdt",
1027 .lite_pas_id = 0x1f,
1030 .proxy_pd_names = (char*[]){
1035 .load_state = "adsp",
1036 .ssr_name = "lpass",
1037 .sysmon_name = "adsp",
1041 static const struct adsp_data x1e80100_cdsp_resource = {
1042 .crash_reason_smem = 601,
1043 .firmware_name = "cdsp.mdt",
1044 .dtb_firmware_name = "cdsp_dtb.mdt",
1049 .proxy_pd_names = (char*[]){
1055 .load_state = "cdsp",
1057 .sysmon_name = "cdsp",
1061 static const struct adsp_data sm8350_cdsp_resource = {
1062 .crash_reason_smem = 601,
1063 .firmware_name = "cdsp.mdt",
1066 .proxy_pd_names = (char*[]){
1071 .load_state = "cdsp",
1073 .sysmon_name = "cdsp",
1077 static const struct adsp_data mpss_resource_init = {
1078 .crash_reason_smem = 421,
1079 .firmware_name = "modem.mdt",
1083 .proxy_pd_names = (char*[]){
1088 .load_state = "modem",
1090 .sysmon_name = "modem",
1094 static const struct adsp_data sc8180x_mpss_resource = {
1095 .crash_reason_smem = 421,
1096 .firmware_name = "modem.mdt",
1099 .proxy_pd_names = (char*[]){
1103 .load_state = "modem",
1105 .sysmon_name = "modem",
1109 static const struct adsp_data msm8996_slpi_resource_init = {
1110 .crash_reason_smem = 424,
1111 .firmware_name = "slpi.mdt",
1114 .proxy_pd_names = (char*[]){
1119 .sysmon_name = "slpi",
1123 static const struct adsp_data sdm845_slpi_resource_init = {
1124 .crash_reason_smem = 424,
1125 .firmware_name = "slpi.mdt",
1128 .proxy_pd_names = (char*[]){
1133 .load_state = "slpi",
1135 .sysmon_name = "slpi",
1139 static const struct adsp_data wcss_resource_init = {
1140 .crash_reason_smem = 421,
1141 .firmware_name = "wcnss.mdt",
1145 .sysmon_name = "wcnss",
1149 static const struct adsp_data sdx55_mpss_resource = {
1150 .crash_reason_smem = 421,
1151 .firmware_name = "modem.mdt",
1154 .proxy_pd_names = (char*[]){
1160 .sysmon_name = "modem",
1164 static const struct adsp_data sm8450_mpss_resource = {
1165 .crash_reason_smem = 421,
1166 .firmware_name = "modem.mdt",
1170 .decrypt_shutdown = true,
1171 .proxy_pd_names = (char*[]){
1176 .load_state = "modem",
1178 .sysmon_name = "modem",
1182 static const struct adsp_data sm8550_adsp_resource = {
1183 .crash_reason_smem = 423,
1184 .firmware_name = "adsp.mdt",
1185 .dtb_firmware_name = "adsp_dtb.mdt",
1190 .proxy_pd_names = (char*[]){
1195 .load_state = "adsp",
1196 .ssr_name = "lpass",
1197 .sysmon_name = "adsp",
1201 static const struct adsp_data sm8550_cdsp_resource = {
1202 .crash_reason_smem = 601,
1203 .firmware_name = "cdsp.mdt",
1204 .dtb_firmware_name = "cdsp_dtb.mdt",
1209 .proxy_pd_names = (char*[]){
1215 .load_state = "cdsp",
1217 .sysmon_name = "cdsp",
1221 static const struct adsp_data sm8550_mpss_resource = {
1222 .crash_reason_smem = 421,
1223 .firmware_name = "modem.mdt",
1224 .dtb_firmware_name = "modem_dtb.mdt",
1229 .decrypt_shutdown = true,
1230 .proxy_pd_names = (char*[]){
1235 .load_state = "modem",
1237 .sysmon_name = "modem",
1239 .region_assign_idx = 2,
1240 .region_assign_count = 1,
1241 .region_assign_vmid = QCOM_SCM_VMID_MSS_MSA,
1244 static const struct adsp_data sc7280_wpss_resource = {
1245 .crash_reason_smem = 626,
1246 .firmware_name = "wpss.mdt",
1249 .proxy_pd_names = (char*[]){
1254 .load_state = "wpss",
1256 .sysmon_name = "wpss",
1260 static const struct adsp_data sm8650_cdsp_resource = {
1261 .crash_reason_smem = 601,
1262 .firmware_name = "cdsp.mdt",
1263 .dtb_firmware_name = "cdsp_dtb.mdt",
1268 .proxy_pd_names = (char*[]){
1274 .load_state = "cdsp",
1276 .sysmon_name = "cdsp",
1278 .region_assign_idx = 2,
1279 .region_assign_count = 1,
1280 .region_assign_shared = true,
1281 .region_assign_vmid = QCOM_SCM_VMID_CDSP,
1284 static const struct adsp_data sm8650_mpss_resource = {
1285 .crash_reason_smem = 421,
1286 .firmware_name = "modem.mdt",
1287 .dtb_firmware_name = "modem_dtb.mdt",
1292 .decrypt_shutdown = true,
1293 .proxy_pd_names = (char*[]){
1298 .load_state = "modem",
1300 .sysmon_name = "modem",
1302 .region_assign_idx = 2,
1303 .region_assign_count = 3,
1304 .region_assign_vmid = QCOM_SCM_VMID_MSS_MSA,
1307 static const struct of_device_id adsp_of_match[] = {
1308 { .compatible = "qcom,msm8226-adsp-pil", .data = &adsp_resource_init},
1309 { .compatible = "qcom,msm8953-adsp-pil", .data = &msm8996_adsp_resource},
1310 { .compatible = "qcom,msm8974-adsp-pil", .data = &adsp_resource_init},
1311 { .compatible = "qcom,msm8996-adsp-pil", .data = &msm8996_adsp_resource},
1312 { .compatible = "qcom,msm8996-slpi-pil", .data = &msm8996_slpi_resource_init},
1313 { .compatible = "qcom,msm8998-adsp-pas", .data = &msm8996_adsp_resource},
1314 { .compatible = "qcom,msm8998-slpi-pas", .data = &msm8996_slpi_resource_init},
1315 { .compatible = "qcom,qcs404-adsp-pas", .data = &adsp_resource_init },
1316 { .compatible = "qcom,qcs404-cdsp-pas", .data = &cdsp_resource_init },
1317 { .compatible = "qcom,qcs404-wcss-pas", .data = &wcss_resource_init },
1318 { .compatible = "qcom,sc7180-adsp-pas", .data = &sm8250_adsp_resource},
1319 { .compatible = "qcom,sc7180-mpss-pas", .data = &mpss_resource_init},
1320 { .compatible = "qcom,sc7280-adsp-pas", .data = &sm8350_adsp_resource},
1321 { .compatible = "qcom,sc7280-cdsp-pas", .data = &sm6350_cdsp_resource},
1322 { .compatible = "qcom,sc7280-mpss-pas", .data = &mpss_resource_init},
1323 { .compatible = "qcom,sc7280-wpss-pas", .data = &sc7280_wpss_resource},
1324 { .compatible = "qcom,sc8180x-adsp-pas", .data = &sm8150_adsp_resource},
1325 { .compatible = "qcom,sc8180x-cdsp-pas", .data = &sm8150_cdsp_resource},
1326 { .compatible = "qcom,sc8180x-mpss-pas", .data = &sc8180x_mpss_resource},
1327 { .compatible = "qcom,sc8280xp-adsp-pas", .data = &sm8250_adsp_resource},
1328 { .compatible = "qcom,sc8280xp-nsp0-pas", .data = &sc8280xp_nsp0_resource},
1329 { .compatible = "qcom,sc8280xp-nsp1-pas", .data = &sc8280xp_nsp1_resource},
1330 { .compatible = "qcom,sdm660-adsp-pas", .data = &adsp_resource_init},
1331 { .compatible = "qcom,sdm845-adsp-pas", .data = &sdm845_adsp_resource_init},
1332 { .compatible = "qcom,sdm845-cdsp-pas", .data = &sdm845_cdsp_resource_init},
1333 { .compatible = "qcom,sdm845-slpi-pas", .data = &sdm845_slpi_resource_init},
1334 { .compatible = "qcom,sdx55-mpss-pas", .data = &sdx55_mpss_resource},
1335 { .compatible = "qcom,sm6115-adsp-pas", .data = &adsp_resource_init},
1336 { .compatible = "qcom,sm6115-cdsp-pas", .data = &cdsp_resource_init},
1337 { .compatible = "qcom,sm6115-mpss-pas", .data = &sc8180x_mpss_resource},
1338 { .compatible = "qcom,sm6350-adsp-pas", .data = &sm6350_adsp_resource},
1339 { .compatible = "qcom,sm6350-cdsp-pas", .data = &sm6350_cdsp_resource},
1340 { .compatible = "qcom,sm6350-mpss-pas", .data = &mpss_resource_init},
1341 { .compatible = "qcom,sm6375-adsp-pas", .data = &sm6350_adsp_resource},
1342 { .compatible = "qcom,sm6375-cdsp-pas", .data = &sm8150_cdsp_resource},
1343 { .compatible = "qcom,sm6375-mpss-pas", .data = &sm6375_mpss_resource},
1344 { .compatible = "qcom,sm8150-adsp-pas", .data = &sm8150_adsp_resource},
1345 { .compatible = "qcom,sm8150-cdsp-pas", .data = &sm8150_cdsp_resource},
1346 { .compatible = "qcom,sm8150-mpss-pas", .data = &mpss_resource_init},
1347 { .compatible = "qcom,sm8150-slpi-pas", .data = &sdm845_slpi_resource_init},
1348 { .compatible = "qcom,sm8250-adsp-pas", .data = &sm8250_adsp_resource},
1349 { .compatible = "qcom,sm8250-cdsp-pas", .data = &sm8250_cdsp_resource},
1350 { .compatible = "qcom,sm8250-slpi-pas", .data = &sdm845_slpi_resource_init},
1351 { .compatible = "qcom,sm8350-adsp-pas", .data = &sm8350_adsp_resource},
1352 { .compatible = "qcom,sm8350-cdsp-pas", .data = &sm8350_cdsp_resource},
1353 { .compatible = "qcom,sm8350-slpi-pas", .data = &sdm845_slpi_resource_init},
1354 { .compatible = "qcom,sm8350-mpss-pas", .data = &mpss_resource_init},
1355 { .compatible = "qcom,sm8450-adsp-pas", .data = &sm8350_adsp_resource},
1356 { .compatible = "qcom,sm8450-cdsp-pas", .data = &sm8350_cdsp_resource},
1357 { .compatible = "qcom,sm8450-slpi-pas", .data = &sdm845_slpi_resource_init},
1358 { .compatible = "qcom,sm8450-mpss-pas", .data = &sm8450_mpss_resource},
1359 { .compatible = "qcom,sm8550-adsp-pas", .data = &sm8550_adsp_resource},
1360 { .compatible = "qcom,sm8550-cdsp-pas", .data = &sm8550_cdsp_resource},
1361 { .compatible = "qcom,sm8550-mpss-pas", .data = &sm8550_mpss_resource},
1362 { .compatible = "qcom,sm8650-adsp-pas", .data = &sm8550_adsp_resource},
1363 { .compatible = "qcom,sm8650-cdsp-pas", .data = &sm8650_cdsp_resource},
1364 { .compatible = "qcom,sm8650-mpss-pas", .data = &sm8650_mpss_resource},
1365 { .compatible = "qcom,x1e80100-adsp-pas", .data = &x1e80100_adsp_resource},
1366 { .compatible = "qcom,x1e80100-cdsp-pas", .data = &x1e80100_cdsp_resource},
1369 MODULE_DEVICE_TABLE(of, adsp_of_match);
1371 static struct platform_driver adsp_driver = {
1372 .probe = adsp_probe,
1373 .remove_new = adsp_remove,
1375 .name = "qcom_q6v5_pas",
1376 .of_match_table = adsp_of_match,
1380 module_platform_driver(adsp_driver);
1381 MODULE_DESCRIPTION("Qualcomm Hexagon v5 Peripheral Authentication Service driver");
1382 MODULE_LICENSE("GPL v2");