0001
0002
0003
0004
0005
0006
0007
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
0158
0159
0160
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
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
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");