Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0-only
0002 /*
0003  * Qualcomm ADSP/SLPI Peripheral Image Loader for MSM8974 and MSM8996
0004  *
0005  * Copyright (C) 2016 Linaro Ltd
0006  * Copyright (C) 2014 Sony Mobile Communications AB
0007  * Copyright (c) 2012-2013, The Linux Foundation. All rights reserved.
0008  */
0009 
0010 #include <linux/clk.h>
0011 #include <linux/delay.h>
0012 #include <linux/firmware.h>
0013 #include <linux/interrupt.h>
0014 #include <linux/kernel.h>
0015 #include <linux/module.h>
0016 #include <linux/of_address.h>
0017 #include <linux/of_device.h>
0018 #include <linux/platform_device.h>
0019 #include <linux/pm_domain.h>
0020 #include <linux/pm_runtime.h>
0021 #include <linux/qcom_scm.h>
0022 #include <linux/regulator/consumer.h>
0023 #include <linux/remoteproc.h>
0024 #include <linux/soc/qcom/mdt_loader.h>
0025 #include <linux/soc/qcom/smem.h>
0026 #include <linux/soc/qcom/smem_state.h>
0027 
0028 #include "qcom_common.h"
0029 #include "qcom_pil_info.h"
0030 #include "qcom_q6v5.h"
0031 #include "remoteproc_internal.h"
0032 
0033 #define ADSP_DECRYPT_SHUTDOWN_DELAY_MS  100
0034 
0035 struct adsp_data {
0036     int crash_reason_smem;
0037     const char *firmware_name;
0038     int pas_id;
0039     unsigned int minidump_id;
0040     bool has_aggre2_clk;
0041     bool auto_boot;
0042     bool decrypt_shutdown;
0043 
0044     char **proxy_pd_names;
0045 
0046     const char *load_state;
0047     const char *ssr_name;
0048     const char *sysmon_name;
0049     int ssctl_id;
0050 };
0051 
0052 struct qcom_adsp {
0053     struct device *dev;
0054     struct rproc *rproc;
0055 
0056     struct qcom_q6v5 q6v5;
0057 
0058     struct clk *xo;
0059     struct clk *aggre2_clk;
0060 
0061     struct regulator *cx_supply;
0062     struct regulator *px_supply;
0063 
0064     struct device *proxy_pds[3];
0065 
0066     int proxy_pd_count;
0067 
0068     int pas_id;
0069     unsigned int minidump_id;
0070     int crash_reason_smem;
0071     bool has_aggre2_clk;
0072     bool decrypt_shutdown;
0073     const char *info_name;
0074 
0075     struct completion start_done;
0076     struct completion stop_done;
0077 
0078     phys_addr_t mem_phys;
0079     phys_addr_t mem_reloc;
0080     void *mem_region;
0081     size_t mem_size;
0082 
0083     struct qcom_rproc_glink glink_subdev;
0084     struct qcom_rproc_subdev smd_subdev;
0085     struct qcom_rproc_ssr ssr_subdev;
0086     struct qcom_sysmon *sysmon;
0087 
0088     struct qcom_scm_pas_metadata pas_metadata;
0089 };
0090 
0091 static void adsp_minidump(struct rproc *rproc)
0092 {
0093     struct qcom_adsp *adsp = rproc->priv;
0094 
0095     if (rproc->dump_conf == RPROC_COREDUMP_DISABLED)
0096         return;
0097 
0098     qcom_minidump(rproc, adsp->minidump_id);
0099 }
0100 
0101 static int adsp_pds_enable(struct qcom_adsp *adsp, struct device **pds,
0102                size_t pd_count)
0103 {
0104     int ret;
0105     int i;
0106 
0107     for (i = 0; i < pd_count; i++) {
0108         dev_pm_genpd_set_performance_state(pds[i], INT_MAX);
0109         ret = pm_runtime_get_sync(pds[i]);
0110         if (ret < 0) {
0111             pm_runtime_put_noidle(pds[i]);
0112             dev_pm_genpd_set_performance_state(pds[i], 0);
0113             goto unroll_pd_votes;
0114         }
0115     }
0116 
0117     return 0;
0118 
0119 unroll_pd_votes:
0120     for (i--; i >= 0; i--) {
0121         dev_pm_genpd_set_performance_state(pds[i], 0);
0122         pm_runtime_put(pds[i]);
0123     }
0124 
0125     return ret;
0126 };
0127 
0128 static void adsp_pds_disable(struct qcom_adsp *adsp, struct device **pds,
0129                  size_t pd_count)
0130 {
0131     int i;
0132 
0133     for (i = 0; i < pd_count; i++) {
0134         dev_pm_genpd_set_performance_state(pds[i], 0);
0135         pm_runtime_put(pds[i]);
0136     }
0137 }
0138 
0139 static int adsp_shutdown_poll_decrypt(struct qcom_adsp *adsp)
0140 {
0141     unsigned int retry_num = 50;
0142     int ret;
0143 
0144     do {
0145         msleep(ADSP_DECRYPT_SHUTDOWN_DELAY_MS);
0146         ret = qcom_scm_pas_shutdown(adsp->pas_id);
0147     } while (ret == -EINVAL && --retry_num);
0148 
0149     return ret;
0150 }
0151 
0152 static int adsp_unprepare(struct rproc *rproc)
0153 {
0154     struct qcom_adsp *adsp = (struct qcom_adsp *)rproc->priv;
0155 
0156     /*
0157      * adsp_load() did pass pas_metadata to the SCM driver for storing
0158      * metadata context. It might have been released already if
0159      * auth_and_reset() was successful, but in other cases clean it up
0160      * here.
0161      */
0162     qcom_scm_pas_metadata_release(&adsp->pas_metadata);
0163 
0164     return 0;
0165 }
0166 
0167 static int adsp_load(struct rproc *rproc, const struct firmware *fw)
0168 {
0169     struct qcom_adsp *adsp = (struct qcom_adsp *)rproc->priv;
0170     int ret;
0171 
0172     ret = qcom_mdt_pas_init(adsp->dev, fw, rproc->firmware, adsp->pas_id,
0173                 adsp->mem_phys, &adsp->pas_metadata);
0174     if (ret)
0175         return ret;
0176 
0177     ret = qcom_mdt_load_no_init(adsp->dev, fw, rproc->firmware, adsp->pas_id,
0178                     adsp->mem_region, adsp->mem_phys, adsp->mem_size,
0179                     &adsp->mem_reloc);
0180     if (ret)
0181         return ret;
0182 
0183     qcom_pil_info_store(adsp->info_name, adsp->mem_phys, adsp->mem_size);
0184 
0185     return 0;
0186 }
0187 
0188 static int adsp_start(struct rproc *rproc)
0189 {
0190     struct qcom_adsp *adsp = (struct qcom_adsp *)rproc->priv;
0191     int ret;
0192 
0193     ret = qcom_q6v5_prepare(&adsp->q6v5);
0194     if (ret)
0195         return ret;
0196 
0197     ret = adsp_pds_enable(adsp, adsp->proxy_pds, adsp->proxy_pd_count);
0198     if (ret < 0)
0199         goto disable_irqs;
0200 
0201     ret = clk_prepare_enable(adsp->xo);
0202     if (ret)
0203         goto disable_proxy_pds;
0204 
0205     ret = clk_prepare_enable(adsp->aggre2_clk);
0206     if (ret)
0207         goto disable_xo_clk;
0208 
0209     if (adsp->cx_supply) {
0210         ret = regulator_enable(adsp->cx_supply);
0211         if (ret)
0212             goto disable_aggre2_clk;
0213     }
0214 
0215     if (adsp->px_supply) {
0216         ret = regulator_enable(adsp->px_supply);
0217         if (ret)
0218             goto disable_cx_supply;
0219     }
0220 
0221     ret = qcom_scm_pas_auth_and_reset(adsp->pas_id);
0222     if (ret) {
0223         dev_err(adsp->dev,
0224             "failed to authenticate image and release reset\n");
0225         goto disable_px_supply;
0226     }
0227 
0228     ret = qcom_q6v5_wait_for_start(&adsp->q6v5, msecs_to_jiffies(5000));
0229     if (ret == -ETIMEDOUT) {
0230         dev_err(adsp->dev, "start timed out\n");
0231         qcom_scm_pas_shutdown(adsp->pas_id);
0232         goto disable_px_supply;
0233     }
0234 
0235     qcom_scm_pas_metadata_release(&adsp->pas_metadata);
0236 
0237     return 0;
0238 
0239 disable_px_supply:
0240     if (adsp->px_supply)
0241         regulator_disable(adsp->px_supply);
0242 disable_cx_supply:
0243     if (adsp->cx_supply)
0244         regulator_disable(adsp->cx_supply);
0245 disable_aggre2_clk:
0246     clk_disable_unprepare(adsp->aggre2_clk);
0247 disable_xo_clk:
0248     clk_disable_unprepare(adsp->xo);
0249 disable_proxy_pds:
0250     adsp_pds_disable(adsp, adsp->proxy_pds, adsp->proxy_pd_count);
0251 disable_irqs:
0252     qcom_q6v5_unprepare(&adsp->q6v5);
0253 
0254     return ret;
0255 }
0256 
0257 static void qcom_pas_handover(struct qcom_q6v5 *q6v5)
0258 {
0259     struct qcom_adsp *adsp = container_of(q6v5, struct qcom_adsp, q6v5);
0260 
0261     if (adsp->px_supply)
0262         regulator_disable(adsp->px_supply);
0263     if (adsp->cx_supply)
0264         regulator_disable(adsp->cx_supply);
0265     clk_disable_unprepare(adsp->aggre2_clk);
0266     clk_disable_unprepare(adsp->xo);
0267     adsp_pds_disable(adsp, adsp->proxy_pds, adsp->proxy_pd_count);
0268 }
0269 
0270 static int adsp_stop(struct rproc *rproc)
0271 {
0272     struct qcom_adsp *adsp = (struct qcom_adsp *)rproc->priv;
0273     int handover;
0274     int ret;
0275 
0276     ret = qcom_q6v5_request_stop(&adsp->q6v5, adsp->sysmon);
0277     if (ret == -ETIMEDOUT)
0278         dev_err(adsp->dev, "timed out on wait\n");
0279 
0280     ret = qcom_scm_pas_shutdown(adsp->pas_id);
0281     if (ret && adsp->decrypt_shutdown)
0282         ret = adsp_shutdown_poll_decrypt(adsp);
0283 
0284     if (ret)
0285         dev_err(adsp->dev, "failed to shutdown: %d\n", ret);
0286 
0287     handover = qcom_q6v5_unprepare(&adsp->q6v5);
0288     if (handover)
0289         qcom_pas_handover(&adsp->q6v5);
0290 
0291     return ret;
0292 }
0293 
0294 static void *adsp_da_to_va(struct rproc *rproc, u64 da, size_t len, bool *is_iomem)
0295 {
0296     struct qcom_adsp *adsp = (struct qcom_adsp *)rproc->priv;
0297     int offset;
0298 
0299     offset = da - adsp->mem_reloc;
0300     if (offset < 0 || offset + len > adsp->mem_size)
0301         return NULL;
0302 
0303     if (is_iomem)
0304         *is_iomem = true;
0305 
0306     return adsp->mem_region + offset;
0307 }
0308 
0309 static unsigned long adsp_panic(struct rproc *rproc)
0310 {
0311     struct qcom_adsp *adsp = (struct qcom_adsp *)rproc->priv;
0312 
0313     return qcom_q6v5_panic(&adsp->q6v5);
0314 }
0315 
0316 static const struct rproc_ops adsp_ops = {
0317     .unprepare = adsp_unprepare,
0318     .start = adsp_start,
0319     .stop = adsp_stop,
0320     .da_to_va = adsp_da_to_va,
0321     .parse_fw = qcom_register_dump_segments,
0322     .load = adsp_load,
0323     .panic = adsp_panic,
0324 };
0325 
0326 static const struct rproc_ops adsp_minidump_ops = {
0327     .unprepare = adsp_unprepare,
0328     .start = adsp_start,
0329     .stop = adsp_stop,
0330     .da_to_va = adsp_da_to_va,
0331     .load = adsp_load,
0332     .panic = adsp_panic,
0333     .coredump = adsp_minidump,
0334 };
0335 
0336 static int adsp_init_clock(struct qcom_adsp *adsp)
0337 {
0338     int ret;
0339 
0340     adsp->xo = devm_clk_get(adsp->dev, "xo");
0341     if (IS_ERR(adsp->xo)) {
0342         ret = PTR_ERR(adsp->xo);
0343         if (ret != -EPROBE_DEFER)
0344             dev_err(adsp->dev, "failed to get xo clock");
0345         return ret;
0346     }
0347 
0348     if (adsp->has_aggre2_clk) {
0349         adsp->aggre2_clk = devm_clk_get(adsp->dev, "aggre2");
0350         if (IS_ERR(adsp->aggre2_clk)) {
0351             ret = PTR_ERR(adsp->aggre2_clk);
0352             if (ret != -EPROBE_DEFER)
0353                 dev_err(adsp->dev,
0354                     "failed to get aggre2 clock");
0355             return ret;
0356         }
0357     }
0358 
0359     return 0;
0360 }
0361 
0362 static int adsp_init_regulator(struct qcom_adsp *adsp)
0363 {
0364     adsp->cx_supply = devm_regulator_get_optional(adsp->dev, "cx");
0365     if (IS_ERR(adsp->cx_supply)) {
0366         if (PTR_ERR(adsp->cx_supply) == -ENODEV)
0367             adsp->cx_supply = NULL;
0368         else
0369             return PTR_ERR(adsp->cx_supply);
0370     }
0371 
0372     if (adsp->cx_supply)
0373         regulator_set_load(adsp->cx_supply, 100000);
0374 
0375     adsp->px_supply = devm_regulator_get_optional(adsp->dev, "px");
0376     if (IS_ERR(adsp->px_supply)) {
0377         if (PTR_ERR(adsp->px_supply) == -ENODEV)
0378             adsp->px_supply = NULL;
0379         else
0380             return PTR_ERR(adsp->px_supply);
0381     }
0382 
0383     return 0;
0384 }
0385 
0386 static int adsp_pds_attach(struct device *dev, struct device **devs,
0387                char **pd_names)
0388 {
0389     size_t num_pds = 0;
0390     int ret;
0391     int i;
0392 
0393     if (!pd_names)
0394         return 0;
0395 
0396     /* Handle single power domain */
0397     if (dev->pm_domain) {
0398         devs[0] = dev;
0399         pm_runtime_enable(dev);
0400         return 1;
0401     }
0402 
0403     while (pd_names[num_pds])
0404         num_pds++;
0405 
0406     for (i = 0; i < num_pds; i++) {
0407         devs[i] = dev_pm_domain_attach_by_name(dev, pd_names[i]);
0408         if (IS_ERR_OR_NULL(devs[i])) {
0409             ret = PTR_ERR(devs[i]) ? : -ENODATA;
0410             goto unroll_attach;
0411         }
0412     }
0413 
0414     return num_pds;
0415 
0416 unroll_attach:
0417     for (i--; i >= 0; i--)
0418         dev_pm_domain_detach(devs[i], false);
0419 
0420     return ret;
0421 };
0422 
0423 static void adsp_pds_detach(struct qcom_adsp *adsp, struct device **pds,
0424                 size_t pd_count)
0425 {
0426     struct device *dev = adsp->dev;
0427     int i;
0428 
0429     /* Handle single power domain */
0430     if (dev->pm_domain && pd_count) {
0431         pm_runtime_disable(dev);
0432         return;
0433     }
0434 
0435     for (i = 0; i < pd_count; i++)
0436         dev_pm_domain_detach(pds[i], false);
0437 }
0438 
0439 static int adsp_alloc_memory_region(struct qcom_adsp *adsp)
0440 {
0441     struct device_node *node;
0442     struct resource r;
0443     int ret;
0444 
0445     node = of_parse_phandle(adsp->dev->of_node, "memory-region", 0);
0446     if (!node) {
0447         dev_err(adsp->dev, "no memory-region specified\n");
0448         return -EINVAL;
0449     }
0450 
0451     ret = of_address_to_resource(node, 0, &r);
0452     if (ret)
0453         return ret;
0454 
0455     adsp->mem_phys = adsp->mem_reloc = r.start;
0456     adsp->mem_size = resource_size(&r);
0457     adsp->mem_region = devm_ioremap_wc(adsp->dev, adsp->mem_phys, adsp->mem_size);
0458     if (!adsp->mem_region) {
0459         dev_err(adsp->dev, "unable to map memory region: %pa+%zx\n",
0460             &r.start, adsp->mem_size);
0461         return -EBUSY;
0462     }
0463 
0464     return 0;
0465 }
0466 
0467 static int adsp_probe(struct platform_device *pdev)
0468 {
0469     const struct adsp_data *desc;
0470     struct qcom_adsp *adsp;
0471     struct rproc *rproc;
0472     const char *fw_name;
0473     const struct rproc_ops *ops = &adsp_ops;
0474     int ret;
0475 
0476     desc = of_device_get_match_data(&pdev->dev);
0477     if (!desc)
0478         return -EINVAL;
0479 
0480     if (!qcom_scm_is_available())
0481         return -EPROBE_DEFER;
0482 
0483     fw_name = desc->firmware_name;
0484     ret = of_property_read_string(pdev->dev.of_node, "firmware-name",
0485                       &fw_name);
0486     if (ret < 0 && ret != -EINVAL)
0487         return ret;
0488 
0489     if (desc->minidump_id)
0490         ops = &adsp_minidump_ops;
0491 
0492     rproc = rproc_alloc(&pdev->dev, pdev->name, ops, fw_name, sizeof(*adsp));
0493 
0494     if (!rproc) {
0495         dev_err(&pdev->dev, "unable to allocate remoteproc\n");
0496         return -ENOMEM;
0497     }
0498 
0499     rproc->auto_boot = desc->auto_boot;
0500     rproc_coredump_set_elf_info(rproc, ELFCLASS32, EM_NONE);
0501 
0502     adsp = (struct qcom_adsp *)rproc->priv;
0503     adsp->dev = &pdev->dev;
0504     adsp->rproc = rproc;
0505     adsp->minidump_id = desc->minidump_id;
0506     adsp->pas_id = desc->pas_id;
0507     adsp->has_aggre2_clk = desc->has_aggre2_clk;
0508     adsp->info_name = desc->sysmon_name;
0509     adsp->decrypt_shutdown = desc->decrypt_shutdown;
0510     platform_set_drvdata(pdev, adsp);
0511 
0512     ret = device_init_wakeup(adsp->dev, true);
0513     if (ret)
0514         goto free_rproc;
0515 
0516     ret = adsp_alloc_memory_region(adsp);
0517     if (ret)
0518         goto free_rproc;
0519 
0520     ret = adsp_init_clock(adsp);
0521     if (ret)
0522         goto free_rproc;
0523 
0524     ret = adsp_init_regulator(adsp);
0525     if (ret)
0526         goto free_rproc;
0527 
0528     ret = adsp_pds_attach(&pdev->dev, adsp->proxy_pds,
0529                   desc->proxy_pd_names);
0530     if (ret < 0)
0531         goto free_rproc;
0532     adsp->proxy_pd_count = ret;
0533 
0534     ret = qcom_q6v5_init(&adsp->q6v5, pdev, rproc, desc->crash_reason_smem, desc->load_state,
0535                  qcom_pas_handover);
0536     if (ret)
0537         goto detach_proxy_pds;
0538 
0539     qcom_add_glink_subdev(rproc, &adsp->glink_subdev, desc->ssr_name);
0540     qcom_add_smd_subdev(rproc, &adsp->smd_subdev);
0541     qcom_add_ssr_subdev(rproc, &adsp->ssr_subdev, desc->ssr_name);
0542     adsp->sysmon = qcom_add_sysmon_subdev(rproc,
0543                           desc->sysmon_name,
0544                           desc->ssctl_id);
0545     if (IS_ERR(adsp->sysmon)) {
0546         ret = PTR_ERR(adsp->sysmon);
0547         goto detach_proxy_pds;
0548     }
0549 
0550     ret = rproc_add(rproc);
0551     if (ret)
0552         goto detach_proxy_pds;
0553 
0554     return 0;
0555 
0556 detach_proxy_pds:
0557     adsp_pds_detach(adsp, adsp->proxy_pds, adsp->proxy_pd_count);
0558 free_rproc:
0559     rproc_free(rproc);
0560 
0561     return ret;
0562 }
0563 
0564 static int adsp_remove(struct platform_device *pdev)
0565 {
0566     struct qcom_adsp *adsp = platform_get_drvdata(pdev);
0567 
0568     rproc_del(adsp->rproc);
0569 
0570     qcom_q6v5_deinit(&adsp->q6v5);
0571     qcom_remove_glink_subdev(adsp->rproc, &adsp->glink_subdev);
0572     qcom_remove_sysmon_subdev(adsp->sysmon);
0573     qcom_remove_smd_subdev(adsp->rproc, &adsp->smd_subdev);
0574     qcom_remove_ssr_subdev(adsp->rproc, &adsp->ssr_subdev);
0575     rproc_free(adsp->rproc);
0576 
0577     return 0;
0578 }
0579 
0580 static const struct adsp_data adsp_resource_init = {
0581         .crash_reason_smem = 423,
0582         .firmware_name = "adsp.mdt",
0583         .pas_id = 1,
0584         .has_aggre2_clk = false,
0585         .auto_boot = true,
0586         .ssr_name = "lpass",
0587         .sysmon_name = "adsp",
0588         .ssctl_id = 0x14,
0589 };
0590 
0591 static const struct adsp_data sdm845_adsp_resource_init = {
0592         .crash_reason_smem = 423,
0593         .firmware_name = "adsp.mdt",
0594         .pas_id = 1,
0595         .has_aggre2_clk = false,
0596         .auto_boot = true,
0597         .load_state = "adsp",
0598         .ssr_name = "lpass",
0599         .sysmon_name = "adsp",
0600         .ssctl_id = 0x14,
0601 };
0602 
0603 static const struct adsp_data sm6350_adsp_resource = {
0604     .crash_reason_smem = 423,
0605     .firmware_name = "adsp.mdt",
0606     .pas_id = 1,
0607     .has_aggre2_clk = false,
0608     .auto_boot = true,
0609     .proxy_pd_names = (char*[]){
0610         "lcx",
0611         "lmx",
0612         NULL
0613     },
0614     .load_state = "adsp",
0615     .ssr_name = "lpass",
0616     .sysmon_name = "adsp",
0617     .ssctl_id = 0x14,
0618 };
0619 
0620 static const struct adsp_data sm8150_adsp_resource = {
0621         .crash_reason_smem = 423,
0622         .firmware_name = "adsp.mdt",
0623         .pas_id = 1,
0624         .has_aggre2_clk = false,
0625         .auto_boot = true,
0626         .proxy_pd_names = (char*[]){
0627             "cx",
0628             NULL
0629         },
0630         .load_state = "adsp",
0631         .ssr_name = "lpass",
0632         .sysmon_name = "adsp",
0633         .ssctl_id = 0x14,
0634 };
0635 
0636 static const struct adsp_data sm8250_adsp_resource = {
0637     .crash_reason_smem = 423,
0638     .firmware_name = "adsp.mdt",
0639     .pas_id = 1,
0640     .has_aggre2_clk = false,
0641     .auto_boot = true,
0642     .proxy_pd_names = (char*[]){
0643         "lcx",
0644         "lmx",
0645         NULL
0646     },
0647     .load_state = "adsp",
0648     .ssr_name = "lpass",
0649     .sysmon_name = "adsp",
0650     .ssctl_id = 0x14,
0651 };
0652 
0653 static const struct adsp_data sm8350_adsp_resource = {
0654     .crash_reason_smem = 423,
0655     .firmware_name = "adsp.mdt",
0656     .pas_id = 1,
0657     .has_aggre2_clk = false,
0658     .auto_boot = true,
0659     .proxy_pd_names = (char*[]){
0660         "lcx",
0661         "lmx",
0662         NULL
0663     },
0664     .load_state = "adsp",
0665     .ssr_name = "lpass",
0666     .sysmon_name = "adsp",
0667     .ssctl_id = 0x14,
0668 };
0669 
0670 static const struct adsp_data msm8996_adsp_resource = {
0671         .crash_reason_smem = 423,
0672         .firmware_name = "adsp.mdt",
0673         .pas_id = 1,
0674         .has_aggre2_clk = false,
0675         .auto_boot = true,
0676         .proxy_pd_names = (char*[]){
0677             "cx",
0678             NULL
0679         },
0680         .ssr_name = "lpass",
0681         .sysmon_name = "adsp",
0682         .ssctl_id = 0x14,
0683 };
0684 
0685 static const struct adsp_data cdsp_resource_init = {
0686     .crash_reason_smem = 601,
0687     .firmware_name = "cdsp.mdt",
0688     .pas_id = 18,
0689     .has_aggre2_clk = false,
0690     .auto_boot = true,
0691     .ssr_name = "cdsp",
0692     .sysmon_name = "cdsp",
0693     .ssctl_id = 0x17,
0694 };
0695 
0696 static const struct adsp_data sdm845_cdsp_resource_init = {
0697     .crash_reason_smem = 601,
0698     .firmware_name = "cdsp.mdt",
0699     .pas_id = 18,
0700     .has_aggre2_clk = false,
0701     .auto_boot = true,
0702     .load_state = "cdsp",
0703     .ssr_name = "cdsp",
0704     .sysmon_name = "cdsp",
0705     .ssctl_id = 0x17,
0706 };
0707 
0708 static const struct adsp_data sm6350_cdsp_resource = {
0709     .crash_reason_smem = 601,
0710     .firmware_name = "cdsp.mdt",
0711     .pas_id = 18,
0712     .has_aggre2_clk = false,
0713     .auto_boot = true,
0714     .proxy_pd_names = (char*[]){
0715         "cx",
0716         "mx",
0717         NULL
0718     },
0719     .load_state = "cdsp",
0720     .ssr_name = "cdsp",
0721     .sysmon_name = "cdsp",
0722     .ssctl_id = 0x17,
0723 };
0724 
0725 static const struct adsp_data sm8150_cdsp_resource = {
0726     .crash_reason_smem = 601,
0727     .firmware_name = "cdsp.mdt",
0728     .pas_id = 18,
0729     .has_aggre2_clk = false,
0730     .auto_boot = true,
0731     .proxy_pd_names = (char*[]){
0732         "cx",
0733         NULL
0734     },
0735     .load_state = "cdsp",
0736     .ssr_name = "cdsp",
0737     .sysmon_name = "cdsp",
0738     .ssctl_id = 0x17,
0739 };
0740 
0741 static const struct adsp_data sm8250_cdsp_resource = {
0742     .crash_reason_smem = 601,
0743     .firmware_name = "cdsp.mdt",
0744     .pas_id = 18,
0745     .has_aggre2_clk = false,
0746     .auto_boot = true,
0747     .proxy_pd_names = (char*[]){
0748         "cx",
0749         NULL
0750     },
0751     .load_state = "cdsp",
0752     .ssr_name = "cdsp",
0753     .sysmon_name = "cdsp",
0754     .ssctl_id = 0x17,
0755 };
0756 
0757 static const struct adsp_data sc8280xp_nsp0_resource = {
0758     .crash_reason_smem = 601,
0759     .firmware_name = "cdsp.mdt",
0760     .pas_id = 18,
0761     .has_aggre2_clk = false,
0762     .auto_boot = true,
0763     .proxy_pd_names = (char*[]){
0764         "nsp",
0765         NULL
0766     },
0767     .ssr_name = "cdsp0",
0768     .sysmon_name = "cdsp",
0769     .ssctl_id = 0x17,
0770 };
0771 
0772 static const struct adsp_data sc8280xp_nsp1_resource = {
0773     .crash_reason_smem = 633,
0774     .firmware_name = "cdsp.mdt",
0775     .pas_id = 30,
0776     .has_aggre2_clk = false,
0777     .auto_boot = true,
0778     .proxy_pd_names = (char*[]){
0779         "nsp",
0780         NULL
0781     },
0782     .ssr_name = "cdsp1",
0783     .sysmon_name = "cdsp1",
0784     .ssctl_id = 0x20,
0785 };
0786 
0787 static const struct adsp_data sm8350_cdsp_resource = {
0788     .crash_reason_smem = 601,
0789     .firmware_name = "cdsp.mdt",
0790     .pas_id = 18,
0791     .has_aggre2_clk = false,
0792     .auto_boot = true,
0793     .proxy_pd_names = (char*[]){
0794         "cx",
0795         "mxc",
0796         NULL
0797     },
0798     .load_state = "cdsp",
0799     .ssr_name = "cdsp",
0800     .sysmon_name = "cdsp",
0801     .ssctl_id = 0x17,
0802 };
0803 
0804 static const struct adsp_data mpss_resource_init = {
0805     .crash_reason_smem = 421,
0806     .firmware_name = "modem.mdt",
0807     .pas_id = 4,
0808     .minidump_id = 3,
0809     .has_aggre2_clk = false,
0810     .auto_boot = false,
0811     .proxy_pd_names = (char*[]){
0812         "cx",
0813         "mss",
0814         NULL
0815     },
0816     .load_state = "modem",
0817     .ssr_name = "mpss",
0818     .sysmon_name = "modem",
0819     .ssctl_id = 0x12,
0820 };
0821 
0822 static const struct adsp_data sc8180x_mpss_resource = {
0823     .crash_reason_smem = 421,
0824     .firmware_name = "modem.mdt",
0825     .pas_id = 4,
0826     .has_aggre2_clk = false,
0827     .auto_boot = false,
0828     .proxy_pd_names = (char*[]){
0829         "cx",
0830         NULL
0831     },
0832     .load_state = "modem",
0833     .ssr_name = "mpss",
0834     .sysmon_name = "modem",
0835     .ssctl_id = 0x12,
0836 };
0837 
0838 static const struct adsp_data slpi_resource_init = {
0839         .crash_reason_smem = 424,
0840         .firmware_name = "slpi.mdt",
0841         .pas_id = 12,
0842         .has_aggre2_clk = true,
0843         .auto_boot = true,
0844         .proxy_pd_names = (char*[]){
0845             "ssc_cx",
0846             NULL
0847         },
0848         .ssr_name = "dsps",
0849         .sysmon_name = "slpi",
0850         .ssctl_id = 0x16,
0851 };
0852 
0853 static const struct adsp_data sm8150_slpi_resource = {
0854         .crash_reason_smem = 424,
0855         .firmware_name = "slpi.mdt",
0856         .pas_id = 12,
0857         .has_aggre2_clk = false,
0858         .auto_boot = true,
0859         .proxy_pd_names = (char*[]){
0860             "lcx",
0861             "lmx",
0862             NULL
0863         },
0864         .load_state = "slpi",
0865         .ssr_name = "dsps",
0866         .sysmon_name = "slpi",
0867         .ssctl_id = 0x16,
0868 };
0869 
0870 static const struct adsp_data sm8250_slpi_resource = {
0871     .crash_reason_smem = 424,
0872     .firmware_name = "slpi.mdt",
0873     .pas_id = 12,
0874     .has_aggre2_clk = false,
0875     .auto_boot = true,
0876     .proxy_pd_names = (char*[]){
0877         "lcx",
0878         "lmx",
0879         NULL
0880     },
0881     .load_state = "slpi",
0882     .ssr_name = "dsps",
0883     .sysmon_name = "slpi",
0884     .ssctl_id = 0x16,
0885 };
0886 
0887 static const struct adsp_data sm8350_slpi_resource = {
0888     .crash_reason_smem = 424,
0889     .firmware_name = "slpi.mdt",
0890     .pas_id = 12,
0891     .has_aggre2_clk = false,
0892     .auto_boot = true,
0893     .proxy_pd_names = (char*[]){
0894         "lcx",
0895         "lmx",
0896         NULL
0897     },
0898     .load_state = "slpi",
0899     .ssr_name = "dsps",
0900     .sysmon_name = "slpi",
0901     .ssctl_id = 0x16,
0902 };
0903 
0904 static const struct adsp_data wcss_resource_init = {
0905     .crash_reason_smem = 421,
0906     .firmware_name = "wcnss.mdt",
0907     .pas_id = 6,
0908     .auto_boot = true,
0909     .ssr_name = "mpss",
0910     .sysmon_name = "wcnss",
0911     .ssctl_id = 0x12,
0912 };
0913 
0914 static const struct adsp_data sdx55_mpss_resource = {
0915     .crash_reason_smem = 421,
0916     .firmware_name = "modem.mdt",
0917     .pas_id = 4,
0918     .has_aggre2_clk = false,
0919     .auto_boot = true,
0920     .proxy_pd_names = (char*[]){
0921         "cx",
0922         "mss",
0923         NULL
0924     },
0925     .ssr_name = "mpss",
0926     .sysmon_name = "modem",
0927     .ssctl_id = 0x22,
0928 };
0929 
0930 static const struct adsp_data sm8450_mpss_resource = {
0931     .crash_reason_smem = 421,
0932     .firmware_name = "modem.mdt",
0933     .pas_id = 4,
0934     .minidump_id = 3,
0935     .has_aggre2_clk = false,
0936     .auto_boot = false,
0937     .decrypt_shutdown = true,
0938     .proxy_pd_names = (char*[]){
0939         "cx",
0940         "mss",
0941         NULL
0942     },
0943     .load_state = "modem",
0944     .ssr_name = "mpss",
0945     .sysmon_name = "modem",
0946     .ssctl_id = 0x12,
0947 };
0948 
0949 static const struct of_device_id adsp_of_match[] = {
0950     { .compatible = "qcom,msm8226-adsp-pil", .data = &adsp_resource_init},
0951     { .compatible = "qcom,msm8974-adsp-pil", .data = &adsp_resource_init},
0952     { .compatible = "qcom,msm8996-adsp-pil", .data = &msm8996_adsp_resource},
0953     { .compatible = "qcom,msm8996-slpi-pil", .data = &slpi_resource_init},
0954     { .compatible = "qcom,msm8998-adsp-pas", .data = &msm8996_adsp_resource},
0955     { .compatible = "qcom,msm8998-slpi-pas", .data = &slpi_resource_init},
0956     { .compatible = "qcom,qcs404-adsp-pas", .data = &adsp_resource_init },
0957     { .compatible = "qcom,qcs404-cdsp-pas", .data = &cdsp_resource_init },
0958     { .compatible = "qcom,qcs404-wcss-pas", .data = &wcss_resource_init },
0959     { .compatible = "qcom,sc7180-mpss-pas", .data = &mpss_resource_init},
0960     { .compatible = "qcom,sc7280-mpss-pas", .data = &mpss_resource_init},
0961     { .compatible = "qcom,sc8180x-adsp-pas", .data = &sm8150_adsp_resource},
0962     { .compatible = "qcom,sc8180x-cdsp-pas", .data = &sm8150_cdsp_resource},
0963     { .compatible = "qcom,sc8180x-mpss-pas", .data = &sc8180x_mpss_resource},
0964     { .compatible = "qcom,sc8280xp-adsp-pas", .data = &sm8250_adsp_resource},
0965     { .compatible = "qcom,sc8280xp-nsp0-pas", .data = &sc8280xp_nsp0_resource},
0966     { .compatible = "qcom,sc8280xp-nsp1-pas", .data = &sc8280xp_nsp1_resource},
0967     { .compatible = "qcom,sdm660-adsp-pas", .data = &adsp_resource_init},
0968     { .compatible = "qcom,sdm845-adsp-pas", .data = &sdm845_adsp_resource_init},
0969     { .compatible = "qcom,sdm845-cdsp-pas", .data = &sdm845_cdsp_resource_init},
0970     { .compatible = "qcom,sdx55-mpss-pas", .data = &sdx55_mpss_resource},
0971     { .compatible = "qcom,sm6350-adsp-pas", .data = &sm6350_adsp_resource},
0972     { .compatible = "qcom,sm6350-cdsp-pas", .data = &sm6350_cdsp_resource},
0973     { .compatible = "qcom,sm6350-mpss-pas", .data = &mpss_resource_init},
0974     { .compatible = "qcom,sm8150-adsp-pas", .data = &sm8150_adsp_resource},
0975     { .compatible = "qcom,sm8150-cdsp-pas", .data = &sm8150_cdsp_resource},
0976     { .compatible = "qcom,sm8150-mpss-pas", .data = &mpss_resource_init},
0977     { .compatible = "qcom,sm8150-slpi-pas", .data = &sm8150_slpi_resource},
0978     { .compatible = "qcom,sm8250-adsp-pas", .data = &sm8250_adsp_resource},
0979     { .compatible = "qcom,sm8250-cdsp-pas", .data = &sm8250_cdsp_resource},
0980     { .compatible = "qcom,sm8250-slpi-pas", .data = &sm8250_slpi_resource},
0981     { .compatible = "qcom,sm8350-adsp-pas", .data = &sm8350_adsp_resource},
0982     { .compatible = "qcom,sm8350-cdsp-pas", .data = &sm8350_cdsp_resource},
0983     { .compatible = "qcom,sm8350-slpi-pas", .data = &sm8350_slpi_resource},
0984     { .compatible = "qcom,sm8350-mpss-pas", .data = &mpss_resource_init},
0985     { .compatible = "qcom,sm8450-adsp-pas", .data = &sm8350_adsp_resource},
0986     { .compatible = "qcom,sm8450-cdsp-pas", .data = &sm8350_cdsp_resource},
0987     { .compatible = "qcom,sm8450-slpi-pas", .data = &sm8350_slpi_resource},
0988     { .compatible = "qcom,sm8450-mpss-pas", .data = &sm8450_mpss_resource},
0989     { },
0990 };
0991 MODULE_DEVICE_TABLE(of, adsp_of_match);
0992 
0993 static struct platform_driver adsp_driver = {
0994     .probe = adsp_probe,
0995     .remove = adsp_remove,
0996     .driver = {
0997         .name = "qcom_q6v5_pas",
0998         .of_match_table = adsp_of_match,
0999     },
1000 };
1001 
1002 module_platform_driver(adsp_driver);
1003 MODULE_DESCRIPTION("Qualcomm Hexagon v5 Peripheral Authentication Service driver");
1004 MODULE_LICENSE("GPL v2");