1 // SPDX-License-Identifier: GPL-2.0-only 2 /* 3 * Qualcomm ADSP/SLPI Peripheral Image Loader for MSM8974 and MSM8996 4 * 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. 8 */ 9 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> 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/qcom_scm.h> 22 #include <linux/regulator/consumer.h> 23 #include <linux/remoteproc.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 #define ADSP_DECRYPT_SHUTDOWN_DELAY_MS 100 34 35 struct adsp_data { 36 int crash_reason_smem; 37 const char *firmware_name; 38 int pas_id; 39 unsigned int minidump_id; 40 bool has_aggre2_clk; 41 bool auto_boot; 42 bool decrypt_shutdown; 43 44 char **proxy_pd_names; 45 46 const char *load_state; 47 const char *ssr_name; 48 const char *sysmon_name; 49 int ssctl_id; 50 }; 51 52 struct qcom_adsp { 53 struct device *dev; 54 struct rproc *rproc; 55 56 struct qcom_q6v5 q6v5; 57 58 struct clk *xo; 59 struct clk *aggre2_clk; 60 61 struct regulator *cx_supply; 62 struct regulator *px_supply; 63 64 struct device *proxy_pds[3]; 65 66 int proxy_pd_count; 67 68 int pas_id; 69 unsigned int minidump_id; 70 int crash_reason_smem; 71 bool has_aggre2_clk; 72 bool decrypt_shutdown; 73 const char *info_name; 74 75 struct completion start_done; 76 struct completion stop_done; 77 78 phys_addr_t mem_phys; 79 phys_addr_t mem_reloc; 80 void *mem_region; 81 size_t mem_size; 82 83 struct qcom_rproc_glink glink_subdev; 84 struct qcom_rproc_subdev smd_subdev; 85 struct qcom_rproc_ssr ssr_subdev; 86 struct qcom_sysmon *sysmon; 87 88 struct qcom_scm_pas_metadata pas_metadata; 89 }; 90 91 static void adsp_minidump(struct rproc *rproc) 92 { 93 struct qcom_adsp *adsp = rproc->priv; 94 95 if (rproc->dump_conf == RPROC_COREDUMP_DISABLED) 96 return; 97 98 qcom_minidump(rproc, adsp->minidump_id); 99 } 100 101 static int adsp_pds_enable(struct qcom_adsp *adsp, struct device **pds, 102 size_t pd_count) 103 { 104 int ret; 105 int i; 106 107 for (i = 0; i < pd_count; i++) { 108 dev_pm_genpd_set_performance_state(pds[i], INT_MAX); 109 ret = pm_runtime_get_sync(pds[i]); 110 if (ret < 0) { 111 pm_runtime_put_noidle(pds[i]); 112 dev_pm_genpd_set_performance_state(pds[i], 0); 113 goto unroll_pd_votes; 114 } 115 } 116 117 return 0; 118 119 unroll_pd_votes: 120 for (i--; i >= 0; i--) { 121 dev_pm_genpd_set_performance_state(pds[i], 0); 122 pm_runtime_put(pds[i]); 123 } 124 125 return ret; 126 }; 127 128 static void adsp_pds_disable(struct qcom_adsp *adsp, struct device **pds, 129 size_t pd_count) 130 { 131 int i; 132 133 for (i = 0; i < pd_count; i++) { 134 dev_pm_genpd_set_performance_state(pds[i], 0); 135 pm_runtime_put(pds[i]); 136 } 137 } 138 139 static int adsp_shutdown_poll_decrypt(struct qcom_adsp *adsp) 140 { 141 unsigned int retry_num = 50; 142 int ret; 143 144 do { 145 msleep(ADSP_DECRYPT_SHUTDOWN_DELAY_MS); 146 ret = qcom_scm_pas_shutdown(adsp->pas_id); 147 } while (ret == -EINVAL && --retry_num); 148 149 return ret; 150 } 151 152 static int adsp_unprepare(struct rproc *rproc) 153 { 154 struct qcom_adsp *adsp = (struct qcom_adsp *)rproc->priv; 155 156 /* 157 * adsp_load() did pass pas_metadata to the SCM driver for storing 158 * metadata context. It might have been released already if 159 * auth_and_reset() was successful, but in other cases clean it up 160 * here. 161 */ 162 qcom_scm_pas_metadata_release(&adsp->pas_metadata); 163 164 return 0; 165 } 166 167 static int adsp_load(struct rproc *rproc, const struct firmware *fw) 168 { 169 struct qcom_adsp *adsp = (struct qcom_adsp *)rproc->priv; 170 int ret; 171 172 ret = qcom_mdt_pas_init(adsp->dev, fw, rproc->firmware, adsp->pas_id, 173 adsp->mem_phys, &adsp->pas_metadata); 174 if (ret) 175 return ret; 176 177 ret = qcom_mdt_load_no_init(adsp->dev, fw, rproc->firmware, adsp->pas_id, 178 adsp->mem_region, adsp->mem_phys, adsp->mem_size, 179 &adsp->mem_reloc); 180 if (ret) 181 return ret; 182 183 qcom_pil_info_store(adsp->info_name, adsp->mem_phys, adsp->mem_size); 184 185 return 0; 186 } 187 188 static int adsp_start(struct rproc *rproc) 189 { 190 struct qcom_adsp *adsp = (struct qcom_adsp *)rproc->priv; 191 int ret; 192 193 ret = qcom_q6v5_prepare(&adsp->q6v5); 194 if (ret) 195 return ret; 196 197 ret = adsp_pds_enable(adsp, adsp->proxy_pds, adsp->proxy_pd_count); 198 if (ret < 0) 199 goto disable_irqs; 200 201 ret = clk_prepare_enable(adsp->xo); 202 if (ret) 203 goto disable_proxy_pds; 204 205 ret = clk_prepare_enable(adsp->aggre2_clk); 206 if (ret) 207 goto disable_xo_clk; 208 209 if (adsp->cx_supply) { 210 ret = regulator_enable(adsp->cx_supply); 211 if (ret) 212 goto disable_aggre2_clk; 213 } 214 215 if (adsp->px_supply) { 216 ret = regulator_enable(adsp->px_supply); 217 if (ret) 218 goto disable_cx_supply; 219 } 220 221 ret = qcom_scm_pas_auth_and_reset(adsp->pas_id); 222 if (ret) { 223 dev_err(adsp->dev, 224 "failed to authenticate image and release reset\n"); 225 goto disable_px_supply; 226 } 227 228 ret = qcom_q6v5_wait_for_start(&adsp->q6v5, msecs_to_jiffies(5000)); 229 if (ret == -ETIMEDOUT) { 230 dev_err(adsp->dev, "start timed out\n"); 231 qcom_scm_pas_shutdown(adsp->pas_id); 232 goto disable_px_supply; 233 } 234 235 qcom_scm_pas_metadata_release(&adsp->pas_metadata); 236 237 return 0; 238 239 disable_px_supply: 240 if (adsp->px_supply) 241 regulator_disable(adsp->px_supply); 242 disable_cx_supply: 243 if (adsp->cx_supply) 244 regulator_disable(adsp->cx_supply); 245 disable_aggre2_clk: 246 clk_disable_unprepare(adsp->aggre2_clk); 247 disable_xo_clk: 248 clk_disable_unprepare(adsp->xo); 249 disable_proxy_pds: 250 adsp_pds_disable(adsp, adsp->proxy_pds, adsp->proxy_pd_count); 251 disable_irqs: 252 qcom_q6v5_unprepare(&adsp->q6v5); 253 254 return ret; 255 } 256 257 static void qcom_pas_handover(struct qcom_q6v5 *q6v5) 258 { 259 struct qcom_adsp *adsp = container_of(q6v5, struct qcom_adsp, q6v5); 260 261 if (adsp->px_supply) 262 regulator_disable(adsp->px_supply); 263 if (adsp->cx_supply) 264 regulator_disable(adsp->cx_supply); 265 clk_disable_unprepare(adsp->aggre2_clk); 266 clk_disable_unprepare(adsp->xo); 267 adsp_pds_disable(adsp, adsp->proxy_pds, adsp->proxy_pd_count); 268 } 269 270 static int adsp_stop(struct rproc *rproc) 271 { 272 struct qcom_adsp *adsp = (struct qcom_adsp *)rproc->priv; 273 int handover; 274 int ret; 275 276 ret = qcom_q6v5_request_stop(&adsp->q6v5, adsp->sysmon); 277 if (ret == -ETIMEDOUT) 278 dev_err(adsp->dev, "timed out on wait\n"); 279 280 ret = qcom_scm_pas_shutdown(adsp->pas_id); 281 if (ret && adsp->decrypt_shutdown) 282 ret = adsp_shutdown_poll_decrypt(adsp); 283 284 if (ret) 285 dev_err(adsp->dev, "failed to shutdown: %d\n", ret); 286 287 handover = qcom_q6v5_unprepare(&adsp->q6v5); 288 if (handover) 289 qcom_pas_handover(&adsp->q6v5); 290 291 return ret; 292 } 293 294 static void *adsp_da_to_va(struct rproc *rproc, u64 da, size_t len, bool *is_iomem) 295 { 296 struct qcom_adsp *adsp = (struct qcom_adsp *)rproc->priv; 297 int offset; 298 299 offset = da - adsp->mem_reloc; 300 if (offset < 0 || offset + len > adsp->mem_size) 301 return NULL; 302 303 if (is_iomem) 304 *is_iomem = true; 305 306 return adsp->mem_region + offset; 307 } 308 309 static unsigned long adsp_panic(struct rproc *rproc) 310 { 311 struct qcom_adsp *adsp = (struct qcom_adsp *)rproc->priv; 312 313 return qcom_q6v5_panic(&adsp->q6v5); 314 } 315 316 static const struct rproc_ops adsp_ops = { 317 .unprepare = adsp_unprepare, 318 .start = adsp_start, 319 .stop = adsp_stop, 320 .da_to_va = adsp_da_to_va, 321 .parse_fw = qcom_register_dump_segments, 322 .load = adsp_load, 323 .panic = adsp_panic, 324 }; 325 326 static const struct rproc_ops adsp_minidump_ops = { 327 .unprepare = adsp_unprepare, 328 .start = adsp_start, 329 .stop = adsp_stop, 330 .da_to_va = adsp_da_to_va, 331 .load = adsp_load, 332 .panic = adsp_panic, 333 .coredump = adsp_minidump, 334 }; 335 336 static int adsp_init_clock(struct qcom_adsp *adsp) 337 { 338 int ret; 339 340 adsp->xo = devm_clk_get(adsp->dev, "xo"); 341 if (IS_ERR(adsp->xo)) { 342 ret = PTR_ERR(adsp->xo); 343 if (ret != -EPROBE_DEFER) 344 dev_err(adsp->dev, "failed to get xo clock"); 345 return ret; 346 } 347 348 if (adsp->has_aggre2_clk) { 349 adsp->aggre2_clk = devm_clk_get(adsp->dev, "aggre2"); 350 if (IS_ERR(adsp->aggre2_clk)) { 351 ret = PTR_ERR(adsp->aggre2_clk); 352 if (ret != -EPROBE_DEFER) 353 dev_err(adsp->dev, 354 "failed to get aggre2 clock"); 355 return ret; 356 } 357 } 358 359 return 0; 360 } 361 362 static int adsp_init_regulator(struct qcom_adsp *adsp) 363 { 364 adsp->cx_supply = devm_regulator_get_optional(adsp->dev, "cx"); 365 if (IS_ERR(adsp->cx_supply)) { 366 if (PTR_ERR(adsp->cx_supply) == -ENODEV) 367 adsp->cx_supply = NULL; 368 else 369 return PTR_ERR(adsp->cx_supply); 370 } 371 372 if (adsp->cx_supply) 373 regulator_set_load(adsp->cx_supply, 100000); 374 375 adsp->px_supply = devm_regulator_get_optional(adsp->dev, "px"); 376 if (IS_ERR(adsp->px_supply)) { 377 if (PTR_ERR(adsp->px_supply) == -ENODEV) 378 adsp->px_supply = NULL; 379 else 380 return PTR_ERR(adsp->px_supply); 381 } 382 383 return 0; 384 } 385 386 static int adsp_pds_attach(struct device *dev, struct device **devs, 387 char **pd_names) 388 { 389 size_t num_pds = 0; 390 int ret; 391 int i; 392 393 if (!pd_names) 394 return 0; 395 396 /* Handle single power domain */ 397 if (dev->pm_domain) { 398 devs[0] = dev; 399 pm_runtime_enable(dev); 400 return 1; 401 } 402 403 while (pd_names[num_pds]) 404 num_pds++; 405 406 for (i = 0; i < num_pds; i++) { 407 devs[i] = dev_pm_domain_attach_by_name(dev, pd_names[i]); 408 if (IS_ERR_OR_NULL(devs[i])) { 409 ret = PTR_ERR(devs[i]) ? : -ENODATA; 410 goto unroll_attach; 411 } 412 } 413 414 return num_pds; 415 416 unroll_attach: 417 for (i--; i >= 0; i--) 418 dev_pm_domain_detach(devs[i], false); 419 420 return ret; 421 }; 422 423 static void adsp_pds_detach(struct qcom_adsp *adsp, struct device **pds, 424 size_t pd_count) 425 { 426 struct device *dev = adsp->dev; 427 int i; 428 429 /* Handle single power domain */ 430 if (dev->pm_domain && pd_count) { 431 pm_runtime_disable(dev); 432 return; 433 } 434 435 for (i = 0; i < pd_count; i++) 436 dev_pm_domain_detach(pds[i], false); 437 } 438 439 static int adsp_alloc_memory_region(struct qcom_adsp *adsp) 440 { 441 struct device_node *node; 442 struct resource r; 443 int ret; 444 445 node = of_parse_phandle(adsp->dev->of_node, "memory-region", 0); 446 if (!node) { 447 dev_err(adsp->dev, "no memory-region specified\n"); 448 return -EINVAL; 449 } 450 451 ret = of_address_to_resource(node, 0, &r); 452 of_node_put(node); 453 if (ret) 454 return ret; 455 456 adsp->mem_phys = adsp->mem_reloc = r.start; 457 adsp->mem_size = resource_size(&r); 458 adsp->mem_region = devm_ioremap_wc(adsp->dev, adsp->mem_phys, adsp->mem_size); 459 if (!adsp->mem_region) { 460 dev_err(adsp->dev, "unable to map memory region: %pa+%zx\n", 461 &r.start, adsp->mem_size); 462 return -EBUSY; 463 } 464 465 return 0; 466 } 467 468 static int adsp_probe(struct platform_device *pdev) 469 { 470 const struct adsp_data *desc; 471 struct qcom_adsp *adsp; 472 struct rproc *rproc; 473 const char *fw_name; 474 const struct rproc_ops *ops = &adsp_ops; 475 int ret; 476 477 desc = of_device_get_match_data(&pdev->dev); 478 if (!desc) 479 return -EINVAL; 480 481 if (!qcom_scm_is_available()) 482 return -EPROBE_DEFER; 483 484 fw_name = desc->firmware_name; 485 ret = of_property_read_string(pdev->dev.of_node, "firmware-name", 486 &fw_name); 487 if (ret < 0 && ret != -EINVAL) 488 return ret; 489 490 if (desc->minidump_id) 491 ops = &adsp_minidump_ops; 492 493 rproc = rproc_alloc(&pdev->dev, pdev->name, ops, fw_name, sizeof(*adsp)); 494 495 if (!rproc) { 496 dev_err(&pdev->dev, "unable to allocate remoteproc\n"); 497 return -ENOMEM; 498 } 499 500 rproc->auto_boot = desc->auto_boot; 501 rproc_coredump_set_elf_info(rproc, ELFCLASS32, EM_NONE); 502 503 adsp = (struct qcom_adsp *)rproc->priv; 504 adsp->dev = &pdev->dev; 505 adsp->rproc = rproc; 506 adsp->minidump_id = desc->minidump_id; 507 adsp->pas_id = desc->pas_id; 508 adsp->has_aggre2_clk = desc->has_aggre2_clk; 509 adsp->info_name = desc->sysmon_name; 510 adsp->decrypt_shutdown = desc->decrypt_shutdown; 511 platform_set_drvdata(pdev, adsp); 512 513 ret = device_init_wakeup(adsp->dev, true); 514 if (ret) 515 goto free_rproc; 516 517 ret = adsp_alloc_memory_region(adsp); 518 if (ret) 519 goto free_rproc; 520 521 ret = adsp_init_clock(adsp); 522 if (ret) 523 goto free_rproc; 524 525 ret = adsp_init_regulator(adsp); 526 if (ret) 527 goto free_rproc; 528 529 ret = adsp_pds_attach(&pdev->dev, adsp->proxy_pds, 530 desc->proxy_pd_names); 531 if (ret < 0) 532 goto free_rproc; 533 adsp->proxy_pd_count = ret; 534 535 ret = qcom_q6v5_init(&adsp->q6v5, pdev, rproc, desc->crash_reason_smem, desc->load_state, 536 qcom_pas_handover); 537 if (ret) 538 goto detach_proxy_pds; 539 540 qcom_add_glink_subdev(rproc, &adsp->glink_subdev, desc->ssr_name); 541 qcom_add_smd_subdev(rproc, &adsp->smd_subdev); 542 qcom_add_ssr_subdev(rproc, &adsp->ssr_subdev, desc->ssr_name); 543 adsp->sysmon = qcom_add_sysmon_subdev(rproc, 544 desc->sysmon_name, 545 desc->ssctl_id); 546 if (IS_ERR(adsp->sysmon)) { 547 ret = PTR_ERR(adsp->sysmon); 548 goto detach_proxy_pds; 549 } 550 551 ret = rproc_add(rproc); 552 if (ret) 553 goto detach_proxy_pds; 554 555 return 0; 556 557 detach_proxy_pds: 558 adsp_pds_detach(adsp, adsp->proxy_pds, adsp->proxy_pd_count); 559 free_rproc: 560 device_init_wakeup(adsp->dev, false); 561 rproc_free(rproc); 562 563 return ret; 564 } 565 566 static int adsp_remove(struct platform_device *pdev) 567 { 568 struct qcom_adsp *adsp = platform_get_drvdata(pdev); 569 570 rproc_del(adsp->rproc); 571 572 qcom_q6v5_deinit(&adsp->q6v5); 573 qcom_remove_glink_subdev(adsp->rproc, &adsp->glink_subdev); 574 qcom_remove_sysmon_subdev(adsp->sysmon); 575 qcom_remove_smd_subdev(adsp->rproc, &adsp->smd_subdev); 576 qcom_remove_ssr_subdev(adsp->rproc, &adsp->ssr_subdev); 577 adsp_pds_detach(adsp, adsp->proxy_pds, adsp->proxy_pd_count); 578 device_init_wakeup(adsp->dev, false); 579 rproc_free(adsp->rproc); 580 581 return 0; 582 } 583 584 static const struct adsp_data adsp_resource_init = { 585 .crash_reason_smem = 423, 586 .firmware_name = "adsp.mdt", 587 .pas_id = 1, 588 .has_aggre2_clk = false, 589 .auto_boot = true, 590 .ssr_name = "lpass", 591 .sysmon_name = "adsp", 592 .ssctl_id = 0x14, 593 }; 594 595 static const struct adsp_data sdm845_adsp_resource_init = { 596 .crash_reason_smem = 423, 597 .firmware_name = "adsp.mdt", 598 .pas_id = 1, 599 .has_aggre2_clk = false, 600 .auto_boot = true, 601 .load_state = "adsp", 602 .ssr_name = "lpass", 603 .sysmon_name = "adsp", 604 .ssctl_id = 0x14, 605 }; 606 607 static const struct adsp_data sm6350_adsp_resource = { 608 .crash_reason_smem = 423, 609 .firmware_name = "adsp.mdt", 610 .pas_id = 1, 611 .has_aggre2_clk = false, 612 .auto_boot = true, 613 .proxy_pd_names = (char*[]){ 614 "lcx", 615 "lmx", 616 NULL 617 }, 618 .load_state = "adsp", 619 .ssr_name = "lpass", 620 .sysmon_name = "adsp", 621 .ssctl_id = 0x14, 622 }; 623 624 static const struct adsp_data sm8150_adsp_resource = { 625 .crash_reason_smem = 423, 626 .firmware_name = "adsp.mdt", 627 .pas_id = 1, 628 .has_aggre2_clk = false, 629 .auto_boot = true, 630 .proxy_pd_names = (char*[]){ 631 "cx", 632 NULL 633 }, 634 .load_state = "adsp", 635 .ssr_name = "lpass", 636 .sysmon_name = "adsp", 637 .ssctl_id = 0x14, 638 }; 639 640 static const struct adsp_data sm8250_adsp_resource = { 641 .crash_reason_smem = 423, 642 .firmware_name = "adsp.mdt", 643 .pas_id = 1, 644 .has_aggre2_clk = false, 645 .auto_boot = true, 646 .proxy_pd_names = (char*[]){ 647 "lcx", 648 "lmx", 649 NULL 650 }, 651 .load_state = "adsp", 652 .ssr_name = "lpass", 653 .sysmon_name = "adsp", 654 .ssctl_id = 0x14, 655 }; 656 657 static const struct adsp_data sm8350_adsp_resource = { 658 .crash_reason_smem = 423, 659 .firmware_name = "adsp.mdt", 660 .pas_id = 1, 661 .has_aggre2_clk = false, 662 .auto_boot = true, 663 .proxy_pd_names = (char*[]){ 664 "lcx", 665 "lmx", 666 NULL 667 }, 668 .load_state = "adsp", 669 .ssr_name = "lpass", 670 .sysmon_name = "adsp", 671 .ssctl_id = 0x14, 672 }; 673 674 static const struct adsp_data msm8996_adsp_resource = { 675 .crash_reason_smem = 423, 676 .firmware_name = "adsp.mdt", 677 .pas_id = 1, 678 .has_aggre2_clk = false, 679 .auto_boot = true, 680 .proxy_pd_names = (char*[]){ 681 "cx", 682 NULL 683 }, 684 .ssr_name = "lpass", 685 .sysmon_name = "adsp", 686 .ssctl_id = 0x14, 687 }; 688 689 static const struct adsp_data cdsp_resource_init = { 690 .crash_reason_smem = 601, 691 .firmware_name = "cdsp.mdt", 692 .pas_id = 18, 693 .has_aggre2_clk = false, 694 .auto_boot = true, 695 .ssr_name = "cdsp", 696 .sysmon_name = "cdsp", 697 .ssctl_id = 0x17, 698 }; 699 700 static const struct adsp_data sdm845_cdsp_resource_init = { 701 .crash_reason_smem = 601, 702 .firmware_name = "cdsp.mdt", 703 .pas_id = 18, 704 .has_aggre2_clk = false, 705 .auto_boot = true, 706 .load_state = "cdsp", 707 .ssr_name = "cdsp", 708 .sysmon_name = "cdsp", 709 .ssctl_id = 0x17, 710 }; 711 712 static const struct adsp_data sm6350_cdsp_resource = { 713 .crash_reason_smem = 601, 714 .firmware_name = "cdsp.mdt", 715 .pas_id = 18, 716 .has_aggre2_clk = false, 717 .auto_boot = true, 718 .proxy_pd_names = (char*[]){ 719 "cx", 720 "mx", 721 NULL 722 }, 723 .load_state = "cdsp", 724 .ssr_name = "cdsp", 725 .sysmon_name = "cdsp", 726 .ssctl_id = 0x17, 727 }; 728 729 static const struct adsp_data sm8150_cdsp_resource = { 730 .crash_reason_smem = 601, 731 .firmware_name = "cdsp.mdt", 732 .pas_id = 18, 733 .has_aggre2_clk = false, 734 .auto_boot = true, 735 .proxy_pd_names = (char*[]){ 736 "cx", 737 NULL 738 }, 739 .load_state = "cdsp", 740 .ssr_name = "cdsp", 741 .sysmon_name = "cdsp", 742 .ssctl_id = 0x17, 743 }; 744 745 static const struct adsp_data sm8250_cdsp_resource = { 746 .crash_reason_smem = 601, 747 .firmware_name = "cdsp.mdt", 748 .pas_id = 18, 749 .has_aggre2_clk = false, 750 .auto_boot = true, 751 .proxy_pd_names = (char*[]){ 752 "cx", 753 NULL 754 }, 755 .load_state = "cdsp", 756 .ssr_name = "cdsp", 757 .sysmon_name = "cdsp", 758 .ssctl_id = 0x17, 759 }; 760 761 static const struct adsp_data sc8280xp_nsp0_resource = { 762 .crash_reason_smem = 601, 763 .firmware_name = "cdsp.mdt", 764 .pas_id = 18, 765 .has_aggre2_clk = false, 766 .auto_boot = true, 767 .proxy_pd_names = (char*[]){ 768 "nsp", 769 NULL 770 }, 771 .ssr_name = "cdsp0", 772 .sysmon_name = "cdsp", 773 .ssctl_id = 0x17, 774 }; 775 776 static const struct adsp_data sc8280xp_nsp1_resource = { 777 .crash_reason_smem = 633, 778 .firmware_name = "cdsp.mdt", 779 .pas_id = 30, 780 .has_aggre2_clk = false, 781 .auto_boot = true, 782 .proxy_pd_names = (char*[]){ 783 "nsp", 784 NULL 785 }, 786 .ssr_name = "cdsp1", 787 .sysmon_name = "cdsp1", 788 .ssctl_id = 0x20, 789 }; 790 791 static const struct adsp_data sm8350_cdsp_resource = { 792 .crash_reason_smem = 601, 793 .firmware_name = "cdsp.mdt", 794 .pas_id = 18, 795 .has_aggre2_clk = false, 796 .auto_boot = true, 797 .proxy_pd_names = (char*[]){ 798 "cx", 799 "mxc", 800 NULL 801 }, 802 .load_state = "cdsp", 803 .ssr_name = "cdsp", 804 .sysmon_name = "cdsp", 805 .ssctl_id = 0x17, 806 }; 807 808 static const struct adsp_data mpss_resource_init = { 809 .crash_reason_smem = 421, 810 .firmware_name = "modem.mdt", 811 .pas_id = 4, 812 .minidump_id = 3, 813 .has_aggre2_clk = false, 814 .auto_boot = false, 815 .proxy_pd_names = (char*[]){ 816 "cx", 817 "mss", 818 NULL 819 }, 820 .load_state = "modem", 821 .ssr_name = "mpss", 822 .sysmon_name = "modem", 823 .ssctl_id = 0x12, 824 }; 825 826 static const struct adsp_data sc8180x_mpss_resource = { 827 .crash_reason_smem = 421, 828 .firmware_name = "modem.mdt", 829 .pas_id = 4, 830 .has_aggre2_clk = false, 831 .auto_boot = false, 832 .proxy_pd_names = (char*[]){ 833 "cx", 834 NULL 835 }, 836 .load_state = "modem", 837 .ssr_name = "mpss", 838 .sysmon_name = "modem", 839 .ssctl_id = 0x12, 840 }; 841 842 static const struct adsp_data slpi_resource_init = { 843 .crash_reason_smem = 424, 844 .firmware_name = "slpi.mdt", 845 .pas_id = 12, 846 .has_aggre2_clk = true, 847 .auto_boot = true, 848 .proxy_pd_names = (char*[]){ 849 "ssc_cx", 850 NULL 851 }, 852 .ssr_name = "dsps", 853 .sysmon_name = "slpi", 854 .ssctl_id = 0x16, 855 }; 856 857 static const struct adsp_data sm8150_slpi_resource = { 858 .crash_reason_smem = 424, 859 .firmware_name = "slpi.mdt", 860 .pas_id = 12, 861 .has_aggre2_clk = false, 862 .auto_boot = true, 863 .proxy_pd_names = (char*[]){ 864 "lcx", 865 "lmx", 866 NULL 867 }, 868 .load_state = "slpi", 869 .ssr_name = "dsps", 870 .sysmon_name = "slpi", 871 .ssctl_id = 0x16, 872 }; 873 874 static const struct adsp_data sm8250_slpi_resource = { 875 .crash_reason_smem = 424, 876 .firmware_name = "slpi.mdt", 877 .pas_id = 12, 878 .has_aggre2_clk = false, 879 .auto_boot = true, 880 .proxy_pd_names = (char*[]){ 881 "lcx", 882 "lmx", 883 NULL 884 }, 885 .load_state = "slpi", 886 .ssr_name = "dsps", 887 .sysmon_name = "slpi", 888 .ssctl_id = 0x16, 889 }; 890 891 static const struct adsp_data sm8350_slpi_resource = { 892 .crash_reason_smem = 424, 893 .firmware_name = "slpi.mdt", 894 .pas_id = 12, 895 .has_aggre2_clk = false, 896 .auto_boot = true, 897 .proxy_pd_names = (char*[]){ 898 "lcx", 899 "lmx", 900 NULL 901 }, 902 .load_state = "slpi", 903 .ssr_name = "dsps", 904 .sysmon_name = "slpi", 905 .ssctl_id = 0x16, 906 }; 907 908 static const struct adsp_data wcss_resource_init = { 909 .crash_reason_smem = 421, 910 .firmware_name = "wcnss.mdt", 911 .pas_id = 6, 912 .auto_boot = true, 913 .ssr_name = "mpss", 914 .sysmon_name = "wcnss", 915 .ssctl_id = 0x12, 916 }; 917 918 static const struct adsp_data sdx55_mpss_resource = { 919 .crash_reason_smem = 421, 920 .firmware_name = "modem.mdt", 921 .pas_id = 4, 922 .has_aggre2_clk = false, 923 .auto_boot = true, 924 .proxy_pd_names = (char*[]){ 925 "cx", 926 "mss", 927 NULL 928 }, 929 .ssr_name = "mpss", 930 .sysmon_name = "modem", 931 .ssctl_id = 0x22, 932 }; 933 934 static const struct adsp_data sm8450_mpss_resource = { 935 .crash_reason_smem = 421, 936 .firmware_name = "modem.mdt", 937 .pas_id = 4, 938 .minidump_id = 3, 939 .has_aggre2_clk = false, 940 .auto_boot = false, 941 .decrypt_shutdown = true, 942 .proxy_pd_names = (char*[]){ 943 "cx", 944 "mss", 945 NULL 946 }, 947 .load_state = "modem", 948 .ssr_name = "mpss", 949 .sysmon_name = "modem", 950 .ssctl_id = 0x12, 951 }; 952 953 static const struct of_device_id adsp_of_match[] = { 954 { .compatible = "qcom,msm8226-adsp-pil", .data = &adsp_resource_init}, 955 { .compatible = "qcom,msm8974-adsp-pil", .data = &adsp_resource_init}, 956 { .compatible = "qcom,msm8996-adsp-pil", .data = &msm8996_adsp_resource}, 957 { .compatible = "qcom,msm8996-slpi-pil", .data = &slpi_resource_init}, 958 { .compatible = "qcom,msm8998-adsp-pas", .data = &msm8996_adsp_resource}, 959 { .compatible = "qcom,msm8998-slpi-pas", .data = &slpi_resource_init}, 960 { .compatible = "qcom,qcs404-adsp-pas", .data = &adsp_resource_init }, 961 { .compatible = "qcom,qcs404-cdsp-pas", .data = &cdsp_resource_init }, 962 { .compatible = "qcom,qcs404-wcss-pas", .data = &wcss_resource_init }, 963 { .compatible = "qcom,sc7180-mpss-pas", .data = &mpss_resource_init}, 964 { .compatible = "qcom,sc7280-mpss-pas", .data = &mpss_resource_init}, 965 { .compatible = "qcom,sc8180x-adsp-pas", .data = &sm8150_adsp_resource}, 966 { .compatible = "qcom,sc8180x-cdsp-pas", .data = &sm8150_cdsp_resource}, 967 { .compatible = "qcom,sc8180x-mpss-pas", .data = &sc8180x_mpss_resource}, 968 { .compatible = "qcom,sc8280xp-adsp-pas", .data = &sm8250_adsp_resource}, 969 { .compatible = "qcom,sc8280xp-nsp0-pas", .data = &sc8280xp_nsp0_resource}, 970 { .compatible = "qcom,sc8280xp-nsp1-pas", .data = &sc8280xp_nsp1_resource}, 971 { .compatible = "qcom,sdm660-adsp-pas", .data = &adsp_resource_init}, 972 { .compatible = "qcom,sdm845-adsp-pas", .data = &sdm845_adsp_resource_init}, 973 { .compatible = "qcom,sdm845-cdsp-pas", .data = &sdm845_cdsp_resource_init}, 974 { .compatible = "qcom,sdx55-mpss-pas", .data = &sdx55_mpss_resource}, 975 { .compatible = "qcom,sm6350-adsp-pas", .data = &sm6350_adsp_resource}, 976 { .compatible = "qcom,sm6350-cdsp-pas", .data = &sm6350_cdsp_resource}, 977 { .compatible = "qcom,sm6350-mpss-pas", .data = &mpss_resource_init}, 978 { .compatible = "qcom,sm8150-adsp-pas", .data = &sm8150_adsp_resource}, 979 { .compatible = "qcom,sm8150-cdsp-pas", .data = &sm8150_cdsp_resource}, 980 { .compatible = "qcom,sm8150-mpss-pas", .data = &mpss_resource_init}, 981 { .compatible = "qcom,sm8150-slpi-pas", .data = &sm8150_slpi_resource}, 982 { .compatible = "qcom,sm8250-adsp-pas", .data = &sm8250_adsp_resource}, 983 { .compatible = "qcom,sm8250-cdsp-pas", .data = &sm8250_cdsp_resource}, 984 { .compatible = "qcom,sm8250-slpi-pas", .data = &sm8250_slpi_resource}, 985 { .compatible = "qcom,sm8350-adsp-pas", .data = &sm8350_adsp_resource}, 986 { .compatible = "qcom,sm8350-cdsp-pas", .data = &sm8350_cdsp_resource}, 987 { .compatible = "qcom,sm8350-slpi-pas", .data = &sm8350_slpi_resource}, 988 { .compatible = "qcom,sm8350-mpss-pas", .data = &mpss_resource_init}, 989 { .compatible = "qcom,sm8450-adsp-pas", .data = &sm8350_adsp_resource}, 990 { .compatible = "qcom,sm8450-cdsp-pas", .data = &sm8350_cdsp_resource}, 991 { .compatible = "qcom,sm8450-slpi-pas", .data = &sm8350_slpi_resource}, 992 { .compatible = "qcom,sm8450-mpss-pas", .data = &sm8450_mpss_resource}, 993 { }, 994 }; 995 MODULE_DEVICE_TABLE(of, adsp_of_match); 996 997 static struct platform_driver adsp_driver = { 998 .probe = adsp_probe, 999 .remove = adsp_remove, 1000 .driver = { 1001 .name = "qcom_q6v5_pas", 1002 .of_match_table = adsp_of_match, 1003 }, 1004 }; 1005 1006 module_platform_driver(adsp_driver); 1007 MODULE_DESCRIPTION("Qualcomm Hexagon v5 Peripheral Authentication Service driver"); 1008 MODULE_LICENSE("GPL v2"); 1009