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