1 // SPDX-License-Identifier: GPL-2.0-only 2 /* 3 * Qualcomm Peripheral Authentication Service remoteproc driver 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.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> 28 29 #include "qcom_common.h" 30 #include "qcom_pil_info.h" 31 #include "qcom_q6v5.h" 32 #include "remoteproc_internal.h" 33 34 #define QCOM_PAS_DECRYPT_SHUTDOWN_DELAY_MS 100 35 36 #define MAX_ASSIGN_COUNT 3 37 38 struct qcom_pas_data { 39 int crash_reason_smem; 40 const char *firmware_name; 41 const char *dtb_firmware_name; 42 int pas_id; 43 int dtb_pas_id; 44 int lite_pas_id; 45 unsigned int minidump_id; 46 bool auto_boot; 47 bool decrypt_shutdown; 48 49 char **proxy_pd_names; 50 51 const char *load_state; 52 const char *ssr_name; 53 const char *sysmon_name; 54 int ssctl_id; 55 unsigned int smem_host_id; 56 57 int region_assign_idx; 58 int region_assign_count; 59 bool region_assign_shared; 60 int region_assign_vmid; 61 }; 62 63 struct qcom_pas { 64 struct device *dev; 65 struct rproc *rproc; 66 67 struct qcom_q6v5 q6v5; 68 69 struct clk *xo; 70 struct clk *aggre2_clk; 71 72 struct regulator *cx_supply; 73 struct regulator *px_supply; 74 75 struct device *proxy_pds[3]; 76 77 int proxy_pd_count; 78 79 const char *dtb_firmware_name; 80 int pas_id; 81 int dtb_pas_id; 82 int lite_pas_id; 83 unsigned int minidump_id; 84 int crash_reason_smem; 85 unsigned int smem_host_id; 86 bool decrypt_shutdown; 87 const char *info_name; 88 89 const struct firmware *firmware; 90 const struct firmware *dtb_firmware; 91 92 struct completion start_done; 93 struct completion stop_done; 94 95 phys_addr_t mem_phys; 96 phys_addr_t dtb_mem_phys; 97 phys_addr_t mem_reloc; 98 phys_addr_t dtb_mem_reloc; 99 phys_addr_t region_assign_phys[MAX_ASSIGN_COUNT]; 100 void *mem_region; 101 void *dtb_mem_region; 102 size_t mem_size; 103 size_t dtb_mem_size; 104 size_t region_assign_size[MAX_ASSIGN_COUNT]; 105 106 int region_assign_idx; 107 int region_assign_count; 108 bool region_assign_shared; 109 int region_assign_vmid; 110 u64 region_assign_owners[MAX_ASSIGN_COUNT]; 111 112 struct qcom_rproc_glink glink_subdev; 113 struct qcom_rproc_subdev smd_subdev; 114 struct qcom_rproc_pdm pdm_subdev; 115 struct qcom_rproc_ssr ssr_subdev; 116 struct qcom_sysmon *sysmon; 117 118 struct qcom_scm_pas_metadata pas_metadata; 119 struct qcom_scm_pas_metadata dtb_pas_metadata; 120 }; 121 122 static void qcom_pas_segment_dump(struct rproc *rproc, 123 struct rproc_dump_segment *segment, 124 void *dest, size_t offset, size_t size) 125 { 126 struct qcom_pas *pas = rproc->priv; 127 int total_offset; 128 129 total_offset = segment->da + segment->offset + offset - pas->mem_phys; 130 if (total_offset < 0 || total_offset + size > pas->mem_size) { 131 dev_err(pas->dev, 132 "invalid copy request for segment %pad with offset %zu and size %zu)\n", 133 &segment->da, offset, size); 134 memset(dest, 0xff, size); 135 return; 136 } 137 138 memcpy_fromio(dest, pas->mem_region + total_offset, size); 139 } 140 141 static void qcom_pas_minidump(struct rproc *rproc) 142 { 143 struct qcom_pas *pas = rproc->priv; 144 145 if (rproc->dump_conf == RPROC_COREDUMP_DISABLED) 146 return; 147 148 qcom_minidump(rproc, pas->minidump_id, qcom_pas_segment_dump); 149 } 150 151 static int qcom_pas_pds_enable(struct qcom_pas *pas, struct device **pds, 152 size_t pd_count) 153 { 154 int ret; 155 int i; 156 157 for (i = 0; i < pd_count; i++) { 158 dev_pm_genpd_set_performance_state(pds[i], INT_MAX); 159 ret = pm_runtime_get_sync(pds[i]); 160 if (ret < 0) { 161 pm_runtime_put_noidle(pds[i]); 162 dev_pm_genpd_set_performance_state(pds[i], 0); 163 goto unroll_pd_votes; 164 } 165 } 166 167 return 0; 168 169 unroll_pd_votes: 170 for (i--; i >= 0; i--) { 171 dev_pm_genpd_set_performance_state(pds[i], 0); 172 pm_runtime_put(pds[i]); 173 } 174 175 return ret; 176 }; 177 178 static void qcom_pas_pds_disable(struct qcom_pas *pas, struct device **pds, 179 size_t pd_count) 180 { 181 int i; 182 183 for (i = 0; i < pd_count; i++) { 184 dev_pm_genpd_set_performance_state(pds[i], 0); 185 pm_runtime_put(pds[i]); 186 } 187 } 188 189 static int qcom_pas_shutdown_poll_decrypt(struct qcom_pas *pas) 190 { 191 unsigned int retry_num = 50; 192 int ret; 193 194 do { 195 msleep(QCOM_PAS_DECRYPT_SHUTDOWN_DELAY_MS); 196 ret = qcom_scm_pas_shutdown(pas->pas_id); 197 } while (ret == -EINVAL && --retry_num); 198 199 return ret; 200 } 201 202 static int qcom_pas_unprepare(struct rproc *rproc) 203 { 204 struct qcom_pas *pas = rproc->priv; 205 206 /* 207 * qcom_pas_load() did pass pas_metadata to the SCM driver for storing 208 * metadata context. It might have been released already if 209 * auth_and_reset() was successful, but in other cases clean it up 210 * here. 211 */ 212 qcom_scm_pas_metadata_release(&pas->pas_metadata); 213 if (pas->dtb_pas_id) 214 qcom_scm_pas_metadata_release(&pas->dtb_pas_metadata); 215 216 return 0; 217 } 218 219 static int qcom_pas_load(struct rproc *rproc, const struct firmware *fw) 220 { 221 struct qcom_pas *pas = rproc->priv; 222 int ret; 223 224 /* Store firmware handle to be used in qcom_pas_start() */ 225 pas->firmware = fw; 226 227 if (pas->lite_pas_id) 228 ret = qcom_scm_pas_shutdown(pas->lite_pas_id); 229 230 if (pas->dtb_pas_id) { 231 ret = request_firmware(&pas->dtb_firmware, pas->dtb_firmware_name, pas->dev); 232 if (ret) { 233 dev_err(pas->dev, "request_firmware failed for %s: %d\n", 234 pas->dtb_firmware_name, ret); 235 return ret; 236 } 237 238 ret = qcom_mdt_pas_init(pas->dev, pas->dtb_firmware, pas->dtb_firmware_name, 239 pas->dtb_pas_id, pas->dtb_mem_phys, 240 &pas->dtb_pas_metadata); 241 if (ret) 242 goto release_dtb_firmware; 243 244 ret = qcom_mdt_load_no_init(pas->dev, pas->dtb_firmware, pas->dtb_firmware_name, 245 pas->dtb_pas_id, pas->dtb_mem_region, 246 pas->dtb_mem_phys, pas->dtb_mem_size, 247 &pas->dtb_mem_reloc); 248 if (ret) 249 goto release_dtb_metadata; 250 } 251 252 return 0; 253 254 release_dtb_metadata: 255 qcom_scm_pas_metadata_release(&pas->dtb_pas_metadata); 256 257 release_dtb_firmware: 258 release_firmware(pas->dtb_firmware); 259 260 return ret; 261 } 262 263 static int qcom_pas_start(struct rproc *rproc) 264 { 265 struct qcom_pas *pas = rproc->priv; 266 int ret; 267 268 ret = qcom_q6v5_prepare(&pas->q6v5); 269 if (ret) 270 return ret; 271 272 ret = qcom_pas_pds_enable(pas, pas->proxy_pds, pas->proxy_pd_count); 273 if (ret < 0) 274 goto disable_irqs; 275 276 ret = clk_prepare_enable(pas->xo); 277 if (ret) 278 goto disable_proxy_pds; 279 280 ret = clk_prepare_enable(pas->aggre2_clk); 281 if (ret) 282 goto disable_xo_clk; 283 284 if (pas->cx_supply) { 285 ret = regulator_enable(pas->cx_supply); 286 if (ret) 287 goto disable_aggre2_clk; 288 } 289 290 if (pas->px_supply) { 291 ret = regulator_enable(pas->px_supply); 292 if (ret) 293 goto disable_cx_supply; 294 } 295 296 if (pas->dtb_pas_id) { 297 ret = qcom_scm_pas_auth_and_reset(pas->dtb_pas_id); 298 if (ret) { 299 dev_err(pas->dev, 300 "failed to authenticate dtb image and release reset\n"); 301 goto disable_px_supply; 302 } 303 } 304 305 ret = qcom_mdt_pas_init(pas->dev, pas->firmware, rproc->firmware, pas->pas_id, 306 pas->mem_phys, &pas->pas_metadata); 307 if (ret) 308 goto disable_px_supply; 309 310 ret = qcom_mdt_load_no_init(pas->dev, pas->firmware, rproc->firmware, pas->pas_id, 311 pas->mem_region, pas->mem_phys, pas->mem_size, 312 &pas->mem_reloc); 313 if (ret) 314 goto release_pas_metadata; 315 316 qcom_pil_info_store(pas->info_name, pas->mem_phys, pas->mem_size); 317 318 ret = qcom_scm_pas_auth_and_reset(pas->pas_id); 319 if (ret) { 320 dev_err(pas->dev, 321 "failed to authenticate image and release reset\n"); 322 goto release_pas_metadata; 323 } 324 325 ret = qcom_q6v5_wait_for_start(&pas->q6v5, msecs_to_jiffies(5000)); 326 if (ret == -ETIMEDOUT) { 327 dev_err(pas->dev, "start timed out\n"); 328 qcom_scm_pas_shutdown(pas->pas_id); 329 goto release_pas_metadata; 330 } 331 332 qcom_scm_pas_metadata_release(&pas->pas_metadata); 333 if (pas->dtb_pas_id) 334 qcom_scm_pas_metadata_release(&pas->dtb_pas_metadata); 335 336 /* firmware is used to pass reference from qcom_pas_start(), drop it now */ 337 pas->firmware = NULL; 338 339 return 0; 340 341 release_pas_metadata: 342 qcom_scm_pas_metadata_release(&pas->pas_metadata); 343 if (pas->dtb_pas_id) 344 qcom_scm_pas_metadata_release(&pas->dtb_pas_metadata); 345 disable_px_supply: 346 if (pas->px_supply) 347 regulator_disable(pas->px_supply); 348 disable_cx_supply: 349 if (pas->cx_supply) 350 regulator_disable(pas->cx_supply); 351 disable_aggre2_clk: 352 clk_disable_unprepare(pas->aggre2_clk); 353 disable_xo_clk: 354 clk_disable_unprepare(pas->xo); 355 disable_proxy_pds: 356 qcom_pas_pds_disable(pas, pas->proxy_pds, pas->proxy_pd_count); 357 disable_irqs: 358 qcom_q6v5_unprepare(&pas->q6v5); 359 360 /* firmware is used to pass reference from qcom_pas_start(), drop it now */ 361 pas->firmware = NULL; 362 363 return ret; 364 } 365 366 static void qcom_pas_handover(struct qcom_q6v5 *q6v5) 367 { 368 struct qcom_pas *pas = container_of(q6v5, struct qcom_pas, q6v5); 369 370 if (pas->px_supply) 371 regulator_disable(pas->px_supply); 372 if (pas->cx_supply) 373 regulator_disable(pas->cx_supply); 374 clk_disable_unprepare(pas->aggre2_clk); 375 clk_disable_unprepare(pas->xo); 376 qcom_pas_pds_disable(pas, pas->proxy_pds, pas->proxy_pd_count); 377 } 378 379 static int qcom_pas_stop(struct rproc *rproc) 380 { 381 struct qcom_pas *pas = rproc->priv; 382 int handover; 383 int ret; 384 385 ret = qcom_q6v5_request_stop(&pas->q6v5, pas->sysmon); 386 if (ret == -ETIMEDOUT) 387 dev_err(pas->dev, "timed out on wait\n"); 388 389 ret = qcom_scm_pas_shutdown(pas->pas_id); 390 if (ret && pas->decrypt_shutdown) 391 ret = qcom_pas_shutdown_poll_decrypt(pas); 392 393 if (ret) 394 dev_err(pas->dev, "failed to shutdown: %d\n", ret); 395 396 if (pas->dtb_pas_id) { 397 ret = qcom_scm_pas_shutdown(pas->dtb_pas_id); 398 if (ret) 399 dev_err(pas->dev, "failed to shutdown dtb: %d\n", ret); 400 } 401 402 handover = qcom_q6v5_unprepare(&pas->q6v5); 403 if (handover) 404 qcom_pas_handover(&pas->q6v5); 405 406 if (pas->smem_host_id) 407 ret = qcom_smem_bust_hwspin_lock_by_host(pas->smem_host_id); 408 409 return ret; 410 } 411 412 static void *qcom_pas_da_to_va(struct rproc *rproc, u64 da, size_t len, bool *is_iomem) 413 { 414 struct qcom_pas *pas = rproc->priv; 415 int offset; 416 417 offset = da - pas->mem_reloc; 418 if (offset < 0 || offset + len > pas->mem_size) 419 return NULL; 420 421 if (is_iomem) 422 *is_iomem = true; 423 424 return pas->mem_region + offset; 425 } 426 427 static unsigned long qcom_pas_panic(struct rproc *rproc) 428 { 429 struct qcom_pas *pas = rproc->priv; 430 431 return qcom_q6v5_panic(&pas->q6v5); 432 } 433 434 static const struct rproc_ops qcom_pas_ops = { 435 .unprepare = qcom_pas_unprepare, 436 .start = qcom_pas_start, 437 .stop = qcom_pas_stop, 438 .da_to_va = qcom_pas_da_to_va, 439 .parse_fw = qcom_register_dump_segments, 440 .load = qcom_pas_load, 441 .panic = qcom_pas_panic, 442 }; 443 444 static const struct rproc_ops qcom_pas_minidump_ops = { 445 .unprepare = qcom_pas_unprepare, 446 .start = qcom_pas_start, 447 .stop = qcom_pas_stop, 448 .da_to_va = qcom_pas_da_to_va, 449 .parse_fw = qcom_register_dump_segments, 450 .load = qcom_pas_load, 451 .panic = qcom_pas_panic, 452 .coredump = qcom_pas_minidump, 453 }; 454 455 static int qcom_pas_init_clock(struct qcom_pas *pas) 456 { 457 pas->xo = devm_clk_get(pas->dev, "xo"); 458 if (IS_ERR(pas->xo)) 459 return dev_err_probe(pas->dev, PTR_ERR(pas->xo), 460 "failed to get xo clock"); 461 462 pas->aggre2_clk = devm_clk_get_optional(pas->dev, "aggre2"); 463 if (IS_ERR(pas->aggre2_clk)) 464 return dev_err_probe(pas->dev, PTR_ERR(pas->aggre2_clk), 465 "failed to get aggre2 clock"); 466 467 return 0; 468 } 469 470 static int qcom_pas_init_regulator(struct qcom_pas *pas) 471 { 472 pas->cx_supply = devm_regulator_get_optional(pas->dev, "cx"); 473 if (IS_ERR(pas->cx_supply)) { 474 if (PTR_ERR(pas->cx_supply) == -ENODEV) 475 pas->cx_supply = NULL; 476 else 477 return PTR_ERR(pas->cx_supply); 478 } 479 480 if (pas->cx_supply) 481 regulator_set_load(pas->cx_supply, 100000); 482 483 pas->px_supply = devm_regulator_get_optional(pas->dev, "px"); 484 if (IS_ERR(pas->px_supply)) { 485 if (PTR_ERR(pas->px_supply) == -ENODEV) 486 pas->px_supply = NULL; 487 else 488 return PTR_ERR(pas->px_supply); 489 } 490 491 return 0; 492 } 493 494 static int qcom_pas_pds_attach(struct device *dev, struct device **devs, char **pd_names) 495 { 496 size_t num_pds = 0; 497 int ret; 498 int i; 499 500 if (!pd_names) 501 return 0; 502 503 while (pd_names[num_pds]) 504 num_pds++; 505 506 /* Handle single power domain */ 507 if (num_pds == 1 && dev->pm_domain) { 508 devs[0] = dev; 509 pm_runtime_enable(dev); 510 return 1; 511 } 512 513 for (i = 0; i < num_pds; i++) { 514 devs[i] = dev_pm_domain_attach_by_name(dev, pd_names[i]); 515 if (IS_ERR_OR_NULL(devs[i])) { 516 ret = PTR_ERR(devs[i]) ? : -ENODATA; 517 goto unroll_attach; 518 } 519 } 520 521 return num_pds; 522 523 unroll_attach: 524 for (i--; i >= 0; i--) 525 dev_pm_domain_detach(devs[i], false); 526 527 return ret; 528 }; 529 530 static void qcom_pas_pds_detach(struct qcom_pas *pas, struct device **pds, size_t pd_count) 531 { 532 struct device *dev = pas->dev; 533 int i; 534 535 /* Handle single power domain */ 536 if (pd_count == 1 && dev->pm_domain) { 537 pm_runtime_disable(dev); 538 return; 539 } 540 541 for (i = 0; i < pd_count; i++) 542 dev_pm_domain_detach(pds[i], false); 543 } 544 545 static int qcom_pas_alloc_memory_region(struct qcom_pas *pas) 546 { 547 struct reserved_mem *rmem; 548 struct device_node *node; 549 550 node = of_parse_phandle(pas->dev->of_node, "memory-region", 0); 551 if (!node) { 552 dev_err(pas->dev, "no memory-region specified\n"); 553 return -EINVAL; 554 } 555 556 rmem = of_reserved_mem_lookup(node); 557 of_node_put(node); 558 if (!rmem) { 559 dev_err(pas->dev, "unable to resolve memory-region\n"); 560 return -EINVAL; 561 } 562 563 pas->mem_phys = pas->mem_reloc = rmem->base; 564 pas->mem_size = rmem->size; 565 pas->mem_region = devm_ioremap_wc(pas->dev, pas->mem_phys, pas->mem_size); 566 if (!pas->mem_region) { 567 dev_err(pas->dev, "unable to map memory region: %pa+%zx\n", 568 &rmem->base, pas->mem_size); 569 return -EBUSY; 570 } 571 572 if (!pas->dtb_pas_id) 573 return 0; 574 575 node = of_parse_phandle(pas->dev->of_node, "memory-region", 1); 576 if (!node) { 577 dev_err(pas->dev, "no dtb memory-region specified\n"); 578 return -EINVAL; 579 } 580 581 rmem = of_reserved_mem_lookup(node); 582 of_node_put(node); 583 if (!rmem) { 584 dev_err(pas->dev, "unable to resolve dtb memory-region\n"); 585 return -EINVAL; 586 } 587 588 pas->dtb_mem_phys = pas->dtb_mem_reloc = rmem->base; 589 pas->dtb_mem_size = rmem->size; 590 pas->dtb_mem_region = devm_ioremap_wc(pas->dev, pas->dtb_mem_phys, pas->dtb_mem_size); 591 if (!pas->dtb_mem_region) { 592 dev_err(pas->dev, "unable to map dtb memory region: %pa+%zx\n", 593 &rmem->base, pas->dtb_mem_size); 594 return -EBUSY; 595 } 596 597 return 0; 598 } 599 600 static int qcom_pas_assign_memory_region(struct qcom_pas *pas) 601 { 602 struct qcom_scm_vmperm perm[MAX_ASSIGN_COUNT]; 603 struct device_node *node; 604 unsigned int perm_size; 605 int offset; 606 int ret; 607 608 if (!pas->region_assign_idx) 609 return 0; 610 611 for (offset = 0; offset < pas->region_assign_count; ++offset) { 612 struct reserved_mem *rmem = NULL; 613 614 node = of_parse_phandle(pas->dev->of_node, "memory-region", 615 pas->region_assign_idx + offset); 616 if (node) 617 rmem = of_reserved_mem_lookup(node); 618 of_node_put(node); 619 if (!rmem) { 620 dev_err(pas->dev, "unable to resolve shareable memory-region index %d\n", 621 offset); 622 return -EINVAL; 623 } 624 625 if (pas->region_assign_shared) { 626 perm[0].vmid = QCOM_SCM_VMID_HLOS; 627 perm[0].perm = QCOM_SCM_PERM_RW; 628 perm[1].vmid = pas->region_assign_vmid; 629 perm[1].perm = QCOM_SCM_PERM_RW; 630 perm_size = 2; 631 } else { 632 perm[0].vmid = pas->region_assign_vmid; 633 perm[0].perm = QCOM_SCM_PERM_RW; 634 perm_size = 1; 635 } 636 637 pas->region_assign_phys[offset] = rmem->base; 638 pas->region_assign_size[offset] = rmem->size; 639 pas->region_assign_owners[offset] = BIT(QCOM_SCM_VMID_HLOS); 640 641 ret = qcom_scm_assign_mem(pas->region_assign_phys[offset], 642 pas->region_assign_size[offset], 643 &pas->region_assign_owners[offset], 644 perm, perm_size); 645 if (ret < 0) { 646 dev_err(pas->dev, "assign memory %d failed\n", offset); 647 return ret; 648 } 649 } 650 651 return 0; 652 } 653 654 static void qcom_pas_unassign_memory_region(struct qcom_pas *pas) 655 { 656 struct qcom_scm_vmperm perm; 657 int offset; 658 int ret; 659 660 if (!pas->region_assign_idx || pas->region_assign_shared) 661 return; 662 663 for (offset = 0; offset < pas->region_assign_count; ++offset) { 664 perm.vmid = QCOM_SCM_VMID_HLOS; 665 perm.perm = QCOM_SCM_PERM_RW; 666 667 ret = qcom_scm_assign_mem(pas->region_assign_phys[offset], 668 pas->region_assign_size[offset], 669 &pas->region_assign_owners[offset], 670 &perm, 1); 671 if (ret < 0) 672 dev_err(pas->dev, "unassign memory %d failed\n", offset); 673 } 674 } 675 676 static int qcom_pas_probe(struct platform_device *pdev) 677 { 678 const struct qcom_pas_data *desc; 679 struct qcom_pas *pas; 680 struct rproc *rproc; 681 const char *fw_name, *dtb_fw_name = NULL; 682 const struct rproc_ops *ops = &qcom_pas_ops; 683 int ret; 684 685 desc = of_device_get_match_data(&pdev->dev); 686 if (!desc) 687 return -EINVAL; 688 689 if (!qcom_scm_is_available()) 690 return -EPROBE_DEFER; 691 692 fw_name = desc->firmware_name; 693 ret = of_property_read_string(pdev->dev.of_node, "firmware-name", 694 &fw_name); 695 if (ret < 0 && ret != -EINVAL) 696 return ret; 697 698 if (desc->dtb_firmware_name) { 699 dtb_fw_name = desc->dtb_firmware_name; 700 ret = of_property_read_string_index(pdev->dev.of_node, "firmware-name", 1, 701 &dtb_fw_name); 702 if (ret < 0 && ret != -EINVAL) 703 return ret; 704 } 705 706 if (desc->minidump_id) 707 ops = &qcom_pas_minidump_ops; 708 709 rproc = devm_rproc_alloc(&pdev->dev, desc->sysmon_name, ops, fw_name, sizeof(*pas)); 710 711 if (!rproc) { 712 dev_err(&pdev->dev, "unable to allocate remoteproc\n"); 713 return -ENOMEM; 714 } 715 716 rproc->auto_boot = desc->auto_boot; 717 rproc_coredump_set_elf_info(rproc, ELFCLASS32, EM_NONE); 718 719 pas = rproc->priv; 720 pas->dev = &pdev->dev; 721 pas->rproc = rproc; 722 pas->minidump_id = desc->minidump_id; 723 pas->pas_id = desc->pas_id; 724 pas->lite_pas_id = desc->lite_pas_id; 725 pas->info_name = desc->sysmon_name; 726 pas->smem_host_id = desc->smem_host_id; 727 pas->decrypt_shutdown = desc->decrypt_shutdown; 728 pas->region_assign_idx = desc->region_assign_idx; 729 pas->region_assign_count = min_t(int, MAX_ASSIGN_COUNT, desc->region_assign_count); 730 pas->region_assign_vmid = desc->region_assign_vmid; 731 pas->region_assign_shared = desc->region_assign_shared; 732 if (dtb_fw_name) { 733 pas->dtb_firmware_name = dtb_fw_name; 734 pas->dtb_pas_id = desc->dtb_pas_id; 735 } 736 platform_set_drvdata(pdev, pas); 737 738 ret = device_init_wakeup(pas->dev, true); 739 if (ret) 740 goto free_rproc; 741 742 ret = qcom_pas_alloc_memory_region(pas); 743 if (ret) 744 goto free_rproc; 745 746 ret = qcom_pas_assign_memory_region(pas); 747 if (ret) 748 goto free_rproc; 749 750 ret = qcom_pas_init_clock(pas); 751 if (ret) 752 goto unassign_mem; 753 754 ret = qcom_pas_init_regulator(pas); 755 if (ret) 756 goto unassign_mem; 757 758 ret = qcom_pas_pds_attach(&pdev->dev, pas->proxy_pds, desc->proxy_pd_names); 759 if (ret < 0) 760 goto unassign_mem; 761 pas->proxy_pd_count = ret; 762 763 ret = qcom_q6v5_init(&pas->q6v5, pdev, rproc, desc->crash_reason_smem, 764 desc->load_state, qcom_pas_handover); 765 if (ret) 766 goto detach_proxy_pds; 767 768 qcom_add_glink_subdev(rproc, &pas->glink_subdev, desc->ssr_name); 769 qcom_add_smd_subdev(rproc, &pas->smd_subdev); 770 qcom_add_pdm_subdev(rproc, &pas->pdm_subdev); 771 pas->sysmon = qcom_add_sysmon_subdev(rproc, desc->sysmon_name, desc->ssctl_id); 772 if (IS_ERR(pas->sysmon)) { 773 ret = PTR_ERR(pas->sysmon); 774 goto deinit_remove_pdm_smd_glink; 775 } 776 777 qcom_add_ssr_subdev(rproc, &pas->ssr_subdev, desc->ssr_name); 778 ret = rproc_add(rproc); 779 if (ret) 780 goto remove_ssr_sysmon; 781 782 return 0; 783 784 remove_ssr_sysmon: 785 qcom_remove_ssr_subdev(rproc, &pas->ssr_subdev); 786 qcom_remove_sysmon_subdev(pas->sysmon); 787 deinit_remove_pdm_smd_glink: 788 qcom_remove_pdm_subdev(rproc, &pas->pdm_subdev); 789 qcom_remove_smd_subdev(rproc, &pas->smd_subdev); 790 qcom_remove_glink_subdev(rproc, &pas->glink_subdev); 791 qcom_q6v5_deinit(&pas->q6v5); 792 detach_proxy_pds: 793 qcom_pas_pds_detach(pas, pas->proxy_pds, pas->proxy_pd_count); 794 unassign_mem: 795 qcom_pas_unassign_memory_region(pas); 796 free_rproc: 797 device_init_wakeup(pas->dev, false); 798 799 return ret; 800 } 801 802 static void qcom_pas_remove(struct platform_device *pdev) 803 { 804 struct qcom_pas *pas = platform_get_drvdata(pdev); 805 806 rproc_del(pas->rproc); 807 808 qcom_q6v5_deinit(&pas->q6v5); 809 qcom_pas_unassign_memory_region(pas); 810 qcom_remove_glink_subdev(pas->rproc, &pas->glink_subdev); 811 qcom_remove_sysmon_subdev(pas->sysmon); 812 qcom_remove_smd_subdev(pas->rproc, &pas->smd_subdev); 813 qcom_remove_pdm_subdev(pas->rproc, &pas->pdm_subdev); 814 qcom_remove_ssr_subdev(pas->rproc, &pas->ssr_subdev); 815 qcom_pas_pds_detach(pas, pas->proxy_pds, pas->proxy_pd_count); 816 device_init_wakeup(pas->dev, false); 817 } 818 819 static const struct qcom_pas_data adsp_resource_init = { 820 .crash_reason_smem = 423, 821 .firmware_name = "adsp.mdt", 822 .pas_id = 1, 823 .auto_boot = true, 824 .ssr_name = "lpass", 825 .sysmon_name = "adsp", 826 .ssctl_id = 0x14, 827 }; 828 829 static const struct qcom_pas_data sa8775p_adsp_resource = { 830 .crash_reason_smem = 423, 831 .firmware_name = "adsp.mbn", 832 .pas_id = 1, 833 .minidump_id = 5, 834 .auto_boot = true, 835 .proxy_pd_names = (char*[]){ 836 "lcx", 837 "lmx", 838 NULL 839 }, 840 .load_state = "adsp", 841 .ssr_name = "lpass", 842 .sysmon_name = "adsp", 843 .ssctl_id = 0x14, 844 }; 845 846 static const struct qcom_pas_data sdm845_adsp_resource_init = { 847 .crash_reason_smem = 423, 848 .firmware_name = "adsp.mdt", 849 .pas_id = 1, 850 .auto_boot = true, 851 .load_state = "adsp", 852 .ssr_name = "lpass", 853 .sysmon_name = "adsp", 854 .ssctl_id = 0x14, 855 }; 856 857 static const struct qcom_pas_data sm6350_adsp_resource = { 858 .crash_reason_smem = 423, 859 .firmware_name = "adsp.mdt", 860 .pas_id = 1, 861 .auto_boot = true, 862 .proxy_pd_names = (char*[]){ 863 "lcx", 864 "lmx", 865 NULL 866 }, 867 .load_state = "adsp", 868 .ssr_name = "lpass", 869 .sysmon_name = "adsp", 870 .ssctl_id = 0x14, 871 }; 872 873 static const struct qcom_pas_data sm6375_mpss_resource = { 874 .crash_reason_smem = 421, 875 .firmware_name = "modem.mdt", 876 .pas_id = 4, 877 .minidump_id = 3, 878 .auto_boot = false, 879 .proxy_pd_names = (char*[]){ 880 "cx", 881 NULL 882 }, 883 .ssr_name = "mpss", 884 .sysmon_name = "modem", 885 .ssctl_id = 0x12, 886 }; 887 888 static const struct qcom_pas_data sm8150_adsp_resource = { 889 .crash_reason_smem = 423, 890 .firmware_name = "adsp.mdt", 891 .pas_id = 1, 892 .auto_boot = true, 893 .proxy_pd_names = (char*[]){ 894 "cx", 895 NULL 896 }, 897 .load_state = "adsp", 898 .ssr_name = "lpass", 899 .sysmon_name = "adsp", 900 .ssctl_id = 0x14, 901 }; 902 903 static const struct qcom_pas_data sm8250_adsp_resource = { 904 .crash_reason_smem = 423, 905 .firmware_name = "adsp.mdt", 906 .pas_id = 1, 907 .minidump_id = 5, 908 .auto_boot = true, 909 .proxy_pd_names = (char*[]){ 910 "lcx", 911 "lmx", 912 NULL 913 }, 914 .load_state = "adsp", 915 .ssr_name = "lpass", 916 .sysmon_name = "adsp", 917 .ssctl_id = 0x14, 918 }; 919 920 static const struct qcom_pas_data sm8350_adsp_resource = { 921 .crash_reason_smem = 423, 922 .firmware_name = "adsp.mdt", 923 .pas_id = 1, 924 .auto_boot = true, 925 .proxy_pd_names = (char*[]){ 926 "lcx", 927 "lmx", 928 NULL 929 }, 930 .load_state = "adsp", 931 .ssr_name = "lpass", 932 .sysmon_name = "adsp", 933 .ssctl_id = 0x14, 934 }; 935 936 static const struct qcom_pas_data msm8996_adsp_resource = { 937 .crash_reason_smem = 423, 938 .firmware_name = "adsp.mdt", 939 .pas_id = 1, 940 .auto_boot = true, 941 .proxy_pd_names = (char*[]){ 942 "cx", 943 NULL 944 }, 945 .ssr_name = "lpass", 946 .sysmon_name = "adsp", 947 .ssctl_id = 0x14, 948 }; 949 950 static const struct qcom_pas_data cdsp_resource_init = { 951 .crash_reason_smem = 601, 952 .firmware_name = "cdsp.mdt", 953 .pas_id = 18, 954 .auto_boot = true, 955 .ssr_name = "cdsp", 956 .sysmon_name = "cdsp", 957 .ssctl_id = 0x17, 958 }; 959 960 static const struct qcom_pas_data sa8775p_cdsp0_resource = { 961 .crash_reason_smem = 601, 962 .firmware_name = "cdsp0.mbn", 963 .pas_id = 18, 964 .minidump_id = 7, 965 .auto_boot = true, 966 .proxy_pd_names = (char*[]){ 967 "cx", 968 "mxc", 969 "nsp", 970 NULL 971 }, 972 .load_state = "cdsp", 973 .ssr_name = "cdsp", 974 .sysmon_name = "cdsp", 975 .ssctl_id = 0x17, 976 }; 977 978 static const struct qcom_pas_data sa8775p_cdsp1_resource = { 979 .crash_reason_smem = 633, 980 .firmware_name = "cdsp1.mbn", 981 .pas_id = 30, 982 .minidump_id = 20, 983 .auto_boot = true, 984 .proxy_pd_names = (char*[]){ 985 "cx", 986 "mxc", 987 "nsp", 988 NULL 989 }, 990 .load_state = "nsp", 991 .ssr_name = "cdsp1", 992 .sysmon_name = "cdsp1", 993 .ssctl_id = 0x20, 994 }; 995 996 static const struct qcom_pas_data sdm845_cdsp_resource_init = { 997 .crash_reason_smem = 601, 998 .firmware_name = "cdsp.mdt", 999 .pas_id = 18, 1000 .auto_boot = true, 1001 .load_state = "cdsp", 1002 .ssr_name = "cdsp", 1003 .sysmon_name = "cdsp", 1004 .ssctl_id = 0x17, 1005 }; 1006 1007 static const struct qcom_pas_data sm6350_cdsp_resource = { 1008 .crash_reason_smem = 601, 1009 .firmware_name = "cdsp.mdt", 1010 .pas_id = 18, 1011 .auto_boot = true, 1012 .proxy_pd_names = (char*[]){ 1013 "cx", 1014 "mx", 1015 NULL 1016 }, 1017 .load_state = "cdsp", 1018 .ssr_name = "cdsp", 1019 .sysmon_name = "cdsp", 1020 .ssctl_id = 0x17, 1021 }; 1022 1023 static const struct qcom_pas_data sm8150_cdsp_resource = { 1024 .crash_reason_smem = 601, 1025 .firmware_name = "cdsp.mdt", 1026 .pas_id = 18, 1027 .auto_boot = true, 1028 .proxy_pd_names = (char*[]){ 1029 "cx", 1030 NULL 1031 }, 1032 .load_state = "cdsp", 1033 .ssr_name = "cdsp", 1034 .sysmon_name = "cdsp", 1035 .ssctl_id = 0x17, 1036 }; 1037 1038 static const struct qcom_pas_data sm8250_cdsp_resource = { 1039 .crash_reason_smem = 601, 1040 .firmware_name = "cdsp.mdt", 1041 .pas_id = 18, 1042 .auto_boot = true, 1043 .proxy_pd_names = (char*[]){ 1044 "cx", 1045 NULL 1046 }, 1047 .load_state = "cdsp", 1048 .ssr_name = "cdsp", 1049 .sysmon_name = "cdsp", 1050 .ssctl_id = 0x17, 1051 }; 1052 1053 static const struct qcom_pas_data sc8280xp_nsp0_resource = { 1054 .crash_reason_smem = 601, 1055 .firmware_name = "cdsp.mdt", 1056 .pas_id = 18, 1057 .auto_boot = true, 1058 .proxy_pd_names = (char*[]){ 1059 "nsp", 1060 NULL 1061 }, 1062 .ssr_name = "cdsp0", 1063 .sysmon_name = "cdsp", 1064 .ssctl_id = 0x17, 1065 }; 1066 1067 static const struct qcom_pas_data sc8280xp_nsp1_resource = { 1068 .crash_reason_smem = 633, 1069 .firmware_name = "cdsp.mdt", 1070 .pas_id = 30, 1071 .auto_boot = true, 1072 .proxy_pd_names = (char*[]){ 1073 "nsp", 1074 NULL 1075 }, 1076 .ssr_name = "cdsp1", 1077 .sysmon_name = "cdsp1", 1078 .ssctl_id = 0x20, 1079 }; 1080 1081 static const struct qcom_pas_data x1e80100_adsp_resource = { 1082 .crash_reason_smem = 423, 1083 .firmware_name = "adsp.mdt", 1084 .dtb_firmware_name = "adsp_dtb.mdt", 1085 .pas_id = 1, 1086 .dtb_pas_id = 0x24, 1087 .lite_pas_id = 0x1f, 1088 .minidump_id = 5, 1089 .auto_boot = true, 1090 .proxy_pd_names = (char*[]){ 1091 "lcx", 1092 "lmx", 1093 NULL 1094 }, 1095 .load_state = "adsp", 1096 .ssr_name = "lpass", 1097 .sysmon_name = "adsp", 1098 .ssctl_id = 0x14, 1099 }; 1100 1101 static const struct qcom_pas_data x1e80100_cdsp_resource = { 1102 .crash_reason_smem = 601, 1103 .firmware_name = "cdsp.mdt", 1104 .dtb_firmware_name = "cdsp_dtb.mdt", 1105 .pas_id = 18, 1106 .dtb_pas_id = 0x25, 1107 .minidump_id = 7, 1108 .auto_boot = true, 1109 .proxy_pd_names = (char*[]){ 1110 "cx", 1111 "mxc", 1112 "nsp", 1113 NULL 1114 }, 1115 .load_state = "cdsp", 1116 .ssr_name = "cdsp", 1117 .sysmon_name = "cdsp", 1118 .ssctl_id = 0x17, 1119 }; 1120 1121 static const struct qcom_pas_data sm8350_cdsp_resource = { 1122 .crash_reason_smem = 601, 1123 .firmware_name = "cdsp.mdt", 1124 .pas_id = 18, 1125 .minidump_id = 7, 1126 .auto_boot = true, 1127 .proxy_pd_names = (char*[]){ 1128 "cx", 1129 "mxc", 1130 NULL 1131 }, 1132 .load_state = "cdsp", 1133 .ssr_name = "cdsp", 1134 .sysmon_name = "cdsp", 1135 .ssctl_id = 0x17, 1136 }; 1137 1138 static const struct qcom_pas_data sa8775p_gpdsp0_resource = { 1139 .crash_reason_smem = 640, 1140 .firmware_name = "gpdsp0.mbn", 1141 .pas_id = 39, 1142 .minidump_id = 21, 1143 .auto_boot = true, 1144 .proxy_pd_names = (char*[]){ 1145 "cx", 1146 "mxc", 1147 NULL 1148 }, 1149 .load_state = "gpdsp0", 1150 .ssr_name = "gpdsp0", 1151 .sysmon_name = "gpdsp0", 1152 .ssctl_id = 0x21, 1153 }; 1154 1155 static const struct qcom_pas_data sa8775p_gpdsp1_resource = { 1156 .crash_reason_smem = 641, 1157 .firmware_name = "gpdsp1.mbn", 1158 .pas_id = 40, 1159 .minidump_id = 22, 1160 .auto_boot = true, 1161 .proxy_pd_names = (char*[]){ 1162 "cx", 1163 "mxc", 1164 NULL 1165 }, 1166 .load_state = "gpdsp1", 1167 .ssr_name = "gpdsp1", 1168 .sysmon_name = "gpdsp1", 1169 .ssctl_id = 0x22, 1170 }; 1171 1172 static const struct qcom_pas_data mpss_resource_init = { 1173 .crash_reason_smem = 421, 1174 .firmware_name = "modem.mdt", 1175 .pas_id = 4, 1176 .minidump_id = 3, 1177 .auto_boot = false, 1178 .proxy_pd_names = (char*[]){ 1179 "cx", 1180 "mss", 1181 NULL 1182 }, 1183 .load_state = "modem", 1184 .ssr_name = "mpss", 1185 .sysmon_name = "modem", 1186 .ssctl_id = 0x12, 1187 }; 1188 1189 static const struct qcom_pas_data sc8180x_mpss_resource = { 1190 .crash_reason_smem = 421, 1191 .firmware_name = "modem.mdt", 1192 .pas_id = 4, 1193 .auto_boot = false, 1194 .proxy_pd_names = (char*[]){ 1195 "cx", 1196 NULL 1197 }, 1198 .load_state = "modem", 1199 .ssr_name = "mpss", 1200 .sysmon_name = "modem", 1201 .ssctl_id = 0x12, 1202 }; 1203 1204 static const struct qcom_pas_data msm8996_slpi_resource_init = { 1205 .crash_reason_smem = 424, 1206 .firmware_name = "slpi.mdt", 1207 .pas_id = 12, 1208 .auto_boot = true, 1209 .proxy_pd_names = (char*[]){ 1210 "ssc_cx", 1211 NULL 1212 }, 1213 .ssr_name = "dsps", 1214 .sysmon_name = "slpi", 1215 .ssctl_id = 0x16, 1216 }; 1217 1218 static const struct qcom_pas_data sdm845_slpi_resource_init = { 1219 .crash_reason_smem = 424, 1220 .firmware_name = "slpi.mdt", 1221 .pas_id = 12, 1222 .auto_boot = true, 1223 .proxy_pd_names = (char*[]){ 1224 "lcx", 1225 "lmx", 1226 NULL 1227 }, 1228 .load_state = "slpi", 1229 .ssr_name = "dsps", 1230 .sysmon_name = "slpi", 1231 .ssctl_id = 0x16, 1232 }; 1233 1234 static const struct qcom_pas_data wcss_resource_init = { 1235 .crash_reason_smem = 421, 1236 .firmware_name = "wcnss.mdt", 1237 .pas_id = 6, 1238 .auto_boot = true, 1239 .ssr_name = "mpss", 1240 .sysmon_name = "wcnss", 1241 .ssctl_id = 0x12, 1242 }; 1243 1244 static const struct qcom_pas_data sdx55_mpss_resource = { 1245 .crash_reason_smem = 421, 1246 .firmware_name = "modem.mdt", 1247 .pas_id = 4, 1248 .auto_boot = true, 1249 .proxy_pd_names = (char*[]){ 1250 "cx", 1251 "mss", 1252 NULL 1253 }, 1254 .ssr_name = "mpss", 1255 .sysmon_name = "modem", 1256 .ssctl_id = 0x22, 1257 }; 1258 1259 static const struct qcom_pas_data sm8450_mpss_resource = { 1260 .crash_reason_smem = 421, 1261 .firmware_name = "modem.mdt", 1262 .pas_id = 4, 1263 .minidump_id = 3, 1264 .auto_boot = false, 1265 .decrypt_shutdown = true, 1266 .proxy_pd_names = (char*[]){ 1267 "cx", 1268 "mss", 1269 NULL 1270 }, 1271 .load_state = "modem", 1272 .ssr_name = "mpss", 1273 .sysmon_name = "modem", 1274 .ssctl_id = 0x12, 1275 }; 1276 1277 static const struct qcom_pas_data sm8550_adsp_resource = { 1278 .crash_reason_smem = 423, 1279 .firmware_name = "adsp.mdt", 1280 .dtb_firmware_name = "adsp_dtb.mdt", 1281 .pas_id = 1, 1282 .dtb_pas_id = 0x24, 1283 .minidump_id = 5, 1284 .auto_boot = true, 1285 .proxy_pd_names = (char*[]){ 1286 "lcx", 1287 "lmx", 1288 NULL 1289 }, 1290 .load_state = "adsp", 1291 .ssr_name = "lpass", 1292 .sysmon_name = "adsp", 1293 .ssctl_id = 0x14, 1294 .smem_host_id = 2, 1295 }; 1296 1297 static const struct qcom_pas_data sm8550_cdsp_resource = { 1298 .crash_reason_smem = 601, 1299 .firmware_name = "cdsp.mdt", 1300 .dtb_firmware_name = "cdsp_dtb.mdt", 1301 .pas_id = 18, 1302 .dtb_pas_id = 0x25, 1303 .minidump_id = 7, 1304 .auto_boot = true, 1305 .proxy_pd_names = (char*[]){ 1306 "cx", 1307 "mxc", 1308 "nsp", 1309 NULL 1310 }, 1311 .load_state = "cdsp", 1312 .ssr_name = "cdsp", 1313 .sysmon_name = "cdsp", 1314 .ssctl_id = 0x17, 1315 .smem_host_id = 5, 1316 }; 1317 1318 static const struct qcom_pas_data sm8550_mpss_resource = { 1319 .crash_reason_smem = 421, 1320 .firmware_name = "modem.mdt", 1321 .dtb_firmware_name = "modem_dtb.mdt", 1322 .pas_id = 4, 1323 .dtb_pas_id = 0x26, 1324 .minidump_id = 3, 1325 .auto_boot = false, 1326 .decrypt_shutdown = true, 1327 .proxy_pd_names = (char*[]){ 1328 "cx", 1329 "mss", 1330 NULL 1331 }, 1332 .load_state = "modem", 1333 .ssr_name = "mpss", 1334 .sysmon_name = "modem", 1335 .ssctl_id = 0x12, 1336 .smem_host_id = 1, 1337 .region_assign_idx = 2, 1338 .region_assign_count = 1, 1339 .region_assign_vmid = QCOM_SCM_VMID_MSS_MSA, 1340 }; 1341 1342 static const struct qcom_pas_data sc7280_wpss_resource = { 1343 .crash_reason_smem = 626, 1344 .firmware_name = "wpss.mdt", 1345 .pas_id = 6, 1346 .minidump_id = 4, 1347 .auto_boot = false, 1348 .proxy_pd_names = (char*[]){ 1349 "cx", 1350 "mx", 1351 NULL 1352 }, 1353 .load_state = "wpss", 1354 .ssr_name = "wpss", 1355 .sysmon_name = "wpss", 1356 .ssctl_id = 0x19, 1357 }; 1358 1359 static const struct qcom_pas_data sm8650_cdsp_resource = { 1360 .crash_reason_smem = 601, 1361 .firmware_name = "cdsp.mdt", 1362 .dtb_firmware_name = "cdsp_dtb.mdt", 1363 .pas_id = 18, 1364 .dtb_pas_id = 0x25, 1365 .minidump_id = 7, 1366 .auto_boot = true, 1367 .proxy_pd_names = (char*[]){ 1368 "cx", 1369 "mxc", 1370 "nsp", 1371 NULL 1372 }, 1373 .load_state = "cdsp", 1374 .ssr_name = "cdsp", 1375 .sysmon_name = "cdsp", 1376 .ssctl_id = 0x17, 1377 .smem_host_id = 5, 1378 .region_assign_idx = 2, 1379 .region_assign_count = 1, 1380 .region_assign_shared = true, 1381 .region_assign_vmid = QCOM_SCM_VMID_CDSP, 1382 }; 1383 1384 static const struct qcom_pas_data sm8650_mpss_resource = { 1385 .crash_reason_smem = 421, 1386 .firmware_name = "modem.mdt", 1387 .dtb_firmware_name = "modem_dtb.mdt", 1388 .pas_id = 4, 1389 .dtb_pas_id = 0x26, 1390 .minidump_id = 3, 1391 .auto_boot = false, 1392 .decrypt_shutdown = true, 1393 .proxy_pd_names = (char*[]){ 1394 "cx", 1395 "mss", 1396 NULL 1397 }, 1398 .load_state = "modem", 1399 .ssr_name = "mpss", 1400 .sysmon_name = "modem", 1401 .ssctl_id = 0x12, 1402 .smem_host_id = 1, 1403 .region_assign_idx = 2, 1404 .region_assign_count = 3, 1405 .region_assign_vmid = QCOM_SCM_VMID_MSS_MSA, 1406 }; 1407 1408 static const struct qcom_pas_data sm8750_mpss_resource = { 1409 .crash_reason_smem = 421, 1410 .firmware_name = "modem.mdt", 1411 .dtb_firmware_name = "modem_dtb.mdt", 1412 .pas_id = 4, 1413 .dtb_pas_id = 0x26, 1414 .minidump_id = 3, 1415 .auto_boot = false, 1416 .decrypt_shutdown = true, 1417 .proxy_pd_names = (char*[]){ 1418 "cx", 1419 "mss", 1420 NULL 1421 }, 1422 .load_state = "modem", 1423 .ssr_name = "mpss", 1424 .sysmon_name = "modem", 1425 .ssctl_id = 0x12, 1426 .smem_host_id = 1, 1427 .region_assign_idx = 2, 1428 .region_assign_count = 2, 1429 .region_assign_vmid = QCOM_SCM_VMID_MSS_MSA, 1430 }; 1431 1432 static const struct of_device_id qcom_pas_of_match[] = { 1433 { .compatible = "qcom,msm8226-adsp-pil", .data = &msm8996_adsp_resource}, 1434 { .compatible = "qcom,msm8953-adsp-pil", .data = &msm8996_adsp_resource}, 1435 { .compatible = "qcom,msm8974-adsp-pil", .data = &adsp_resource_init}, 1436 { .compatible = "qcom,msm8996-adsp-pil", .data = &msm8996_adsp_resource}, 1437 { .compatible = "qcom,msm8996-slpi-pil", .data = &msm8996_slpi_resource_init}, 1438 { .compatible = "qcom,msm8998-adsp-pas", .data = &msm8996_adsp_resource}, 1439 { .compatible = "qcom,msm8998-slpi-pas", .data = &msm8996_slpi_resource_init}, 1440 { .compatible = "qcom,qcs404-adsp-pas", .data = &adsp_resource_init }, 1441 { .compatible = "qcom,qcs404-cdsp-pas", .data = &cdsp_resource_init }, 1442 { .compatible = "qcom,qcs404-wcss-pas", .data = &wcss_resource_init }, 1443 { .compatible = "qcom,sa8775p-adsp-pas", .data = &sa8775p_adsp_resource}, 1444 { .compatible = "qcom,sa8775p-cdsp0-pas", .data = &sa8775p_cdsp0_resource}, 1445 { .compatible = "qcom,sa8775p-cdsp1-pas", .data = &sa8775p_cdsp1_resource}, 1446 { .compatible = "qcom,sa8775p-gpdsp0-pas", .data = &sa8775p_gpdsp0_resource}, 1447 { .compatible = "qcom,sa8775p-gpdsp1-pas", .data = &sa8775p_gpdsp1_resource}, 1448 { .compatible = "qcom,sar2130p-adsp-pas", .data = &sm8350_adsp_resource}, 1449 { .compatible = "qcom,sc7180-adsp-pas", .data = &sm8250_adsp_resource}, 1450 { .compatible = "qcom,sc7180-mpss-pas", .data = &mpss_resource_init}, 1451 { .compatible = "qcom,sc7280-adsp-pas", .data = &sm8350_adsp_resource}, 1452 { .compatible = "qcom,sc7280-cdsp-pas", .data = &sm6350_cdsp_resource}, 1453 { .compatible = "qcom,sc7280-mpss-pas", .data = &mpss_resource_init}, 1454 { .compatible = "qcom,sc7280-wpss-pas", .data = &sc7280_wpss_resource}, 1455 { .compatible = "qcom,sc8180x-adsp-pas", .data = &sm8150_adsp_resource}, 1456 { .compatible = "qcom,sc8180x-cdsp-pas", .data = &sm8150_cdsp_resource}, 1457 { .compatible = "qcom,sc8180x-mpss-pas", .data = &sc8180x_mpss_resource}, 1458 { .compatible = "qcom,sc8280xp-adsp-pas", .data = &sm8250_adsp_resource}, 1459 { .compatible = "qcom,sc8280xp-nsp0-pas", .data = &sc8280xp_nsp0_resource}, 1460 { .compatible = "qcom,sc8280xp-nsp1-pas", .data = &sc8280xp_nsp1_resource}, 1461 { .compatible = "qcom,sdm660-adsp-pas", .data = &adsp_resource_init}, 1462 { .compatible = "qcom,sdm845-adsp-pas", .data = &sdm845_adsp_resource_init}, 1463 { .compatible = "qcom,sdm845-cdsp-pas", .data = &sdm845_cdsp_resource_init}, 1464 { .compatible = "qcom,sdm845-slpi-pas", .data = &sdm845_slpi_resource_init}, 1465 { .compatible = "qcom,sdx55-mpss-pas", .data = &sdx55_mpss_resource}, 1466 { .compatible = "qcom,sdx75-mpss-pas", .data = &sm8650_mpss_resource}, 1467 { .compatible = "qcom,sm6115-adsp-pas", .data = &adsp_resource_init}, 1468 { .compatible = "qcom,sm6115-cdsp-pas", .data = &cdsp_resource_init}, 1469 { .compatible = "qcom,sm6115-mpss-pas", .data = &sc8180x_mpss_resource}, 1470 { .compatible = "qcom,sm6350-adsp-pas", .data = &sm6350_adsp_resource}, 1471 { .compatible = "qcom,sm6350-cdsp-pas", .data = &sm6350_cdsp_resource}, 1472 { .compatible = "qcom,sm6350-mpss-pas", .data = &mpss_resource_init}, 1473 { .compatible = "qcom,sm6375-adsp-pas", .data = &sm6350_adsp_resource}, 1474 { .compatible = "qcom,sm6375-cdsp-pas", .data = &sm8150_cdsp_resource}, 1475 { .compatible = "qcom,sm6375-mpss-pas", .data = &sm6375_mpss_resource}, 1476 { .compatible = "qcom,sm8150-adsp-pas", .data = &sm8150_adsp_resource}, 1477 { .compatible = "qcom,sm8150-cdsp-pas", .data = &sm8150_cdsp_resource}, 1478 { .compatible = "qcom,sm8150-mpss-pas", .data = &mpss_resource_init}, 1479 { .compatible = "qcom,sm8150-slpi-pas", .data = &sdm845_slpi_resource_init}, 1480 { .compatible = "qcom,sm8250-adsp-pas", .data = &sm8250_adsp_resource}, 1481 { .compatible = "qcom,sm8250-cdsp-pas", .data = &sm8250_cdsp_resource}, 1482 { .compatible = "qcom,sm8250-slpi-pas", .data = &sdm845_slpi_resource_init}, 1483 { .compatible = "qcom,sm8350-adsp-pas", .data = &sm8350_adsp_resource}, 1484 { .compatible = "qcom,sm8350-cdsp-pas", .data = &sm8350_cdsp_resource}, 1485 { .compatible = "qcom,sm8350-slpi-pas", .data = &sdm845_slpi_resource_init}, 1486 { .compatible = "qcom,sm8350-mpss-pas", .data = &mpss_resource_init}, 1487 { .compatible = "qcom,sm8450-adsp-pas", .data = &sm8350_adsp_resource}, 1488 { .compatible = "qcom,sm8450-cdsp-pas", .data = &sm8350_cdsp_resource}, 1489 { .compatible = "qcom,sm8450-slpi-pas", .data = &sdm845_slpi_resource_init}, 1490 { .compatible = "qcom,sm8450-mpss-pas", .data = &sm8450_mpss_resource}, 1491 { .compatible = "qcom,sm8550-adsp-pas", .data = &sm8550_adsp_resource}, 1492 { .compatible = "qcom,sm8550-cdsp-pas", .data = &sm8550_cdsp_resource}, 1493 { .compatible = "qcom,sm8550-mpss-pas", .data = &sm8550_mpss_resource}, 1494 { .compatible = "qcom,sm8650-adsp-pas", .data = &sm8550_adsp_resource}, 1495 { .compatible = "qcom,sm8650-cdsp-pas", .data = &sm8650_cdsp_resource}, 1496 { .compatible = "qcom,sm8650-mpss-pas", .data = &sm8650_mpss_resource}, 1497 { .compatible = "qcom,sm8750-mpss-pas", .data = &sm8750_mpss_resource}, 1498 { .compatible = "qcom,x1e80100-adsp-pas", .data = &x1e80100_adsp_resource}, 1499 { .compatible = "qcom,x1e80100-cdsp-pas", .data = &x1e80100_cdsp_resource}, 1500 { }, 1501 }; 1502 MODULE_DEVICE_TABLE(of, qcom_pas_of_match); 1503 1504 static struct platform_driver qcom_pas_driver = { 1505 .probe = qcom_pas_probe, 1506 .remove = qcom_pas_remove, 1507 .driver = { 1508 .name = "qcom_q6v5_pas", 1509 .of_match_table = qcom_pas_of_match, 1510 }, 1511 }; 1512 1513 module_platform_driver(qcom_pas_driver); 1514 MODULE_DESCRIPTION("Qualcomm Peripheral Authentication Service remoteproc driver"); 1515 MODULE_LICENSE("GPL v2"); 1516