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