1 // SPDX-License-Identifier: GPL-2.0 2 /* 3 * Qualcomm Technology Inc. ADSP Peripheral Image Loader for SDM845. 4 * Copyright (c) 2018, The Linux Foundation. All rights reserved. 5 */ 6 7 #include <linux/clk.h> 8 #include <linux/delay.h> 9 #include <linux/firmware.h> 10 #include <linux/interrupt.h> 11 #include <linux/io.h> 12 #include <linux/iommu.h> 13 #include <linux/iopoll.h> 14 #include <linux/kernel.h> 15 #include <linux/mfd/syscon.h> 16 #include <linux/module.h> 17 #include <linux/of_address.h> 18 #include <linux/of_device.h> 19 #include <linux/platform_device.h> 20 #include <linux/pm_domain.h> 21 #include <linux/pm_runtime.h> 22 #include <linux/regmap.h> 23 #include <linux/remoteproc.h> 24 #include <linux/reset.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 /* time out value */ 35 #define ACK_TIMEOUT 1000 36 #define ACK_TIMEOUT_US 1000000 37 #define BOOT_FSM_TIMEOUT 10000 38 /* mask values */ 39 #define EVB_MASK GENMASK(27, 4) 40 /*QDSP6SS register offsets*/ 41 #define RST_EVB_REG 0x10 42 #define CORE_START_REG 0x400 43 #define BOOT_CMD_REG 0x404 44 #define BOOT_STATUS_REG 0x408 45 #define RET_CFG_REG 0x1C 46 /*TCSR register offsets*/ 47 #define LPASS_MASTER_IDLE_REG 0x8 48 #define LPASS_HALTACK_REG 0x4 49 #define LPASS_PWR_ON_REG 0x10 50 #define LPASS_HALTREQ_REG 0x0 51 52 #define SID_MASK_DEFAULT 0xF 53 54 #define QDSP6SS_XO_CBCR 0x38 55 #define QDSP6SS_CORE_CBCR 0x20 56 #define QDSP6SS_SLEEP_CBCR 0x3c 57 58 #define QCOM_Q6V5_RPROC_PROXY_PD_MAX 3 59 60 #define LPASS_BOOT_CORE_START BIT(0) 61 #define LPASS_BOOT_CMD_START BIT(0) 62 #define LPASS_EFUSE_Q6SS_EVB_SEL 0x0 63 64 struct adsp_pil_data { 65 int crash_reason_smem; 66 const char *firmware_name; 67 68 const char *ssr_name; 69 const char *sysmon_name; 70 int ssctl_id; 71 bool is_wpss; 72 bool has_iommu; 73 bool auto_boot; 74 75 const char **clk_ids; 76 int num_clks; 77 const char **proxy_pd_names; 78 const char *load_state; 79 }; 80 81 struct qcom_adsp { 82 struct device *dev; 83 struct rproc *rproc; 84 85 struct qcom_q6v5 q6v5; 86 87 struct clk *xo; 88 89 int num_clks; 90 struct clk_bulk_data *clks; 91 92 void __iomem *qdsp6ss_base; 93 void __iomem *lpass_efuse; 94 95 struct reset_control *pdc_sync_reset; 96 struct reset_control *restart; 97 98 struct regmap *halt_map; 99 unsigned int halt_lpass; 100 101 int crash_reason_smem; 102 const char *info_name; 103 104 struct completion start_done; 105 struct completion stop_done; 106 107 phys_addr_t mem_phys; 108 phys_addr_t mem_reloc; 109 void *mem_region; 110 size_t mem_size; 111 bool has_iommu; 112 113 struct device *proxy_pds[QCOM_Q6V5_RPROC_PROXY_PD_MAX]; 114 size_t proxy_pd_count; 115 116 struct qcom_rproc_glink glink_subdev; 117 struct qcom_rproc_ssr ssr_subdev; 118 struct qcom_sysmon *sysmon; 119 120 int (*shutdown)(struct qcom_adsp *adsp); 121 }; 122 123 static int qcom_rproc_pds_attach(struct device *dev, struct qcom_adsp *adsp, 124 const char **pd_names) 125 { 126 struct device **devs = adsp->proxy_pds; 127 size_t num_pds = 0; 128 int ret; 129 int i; 130 131 if (!pd_names) 132 return 0; 133 134 /* Handle single power domain */ 135 if (dev->pm_domain) { 136 devs[0] = dev; 137 pm_runtime_enable(dev); 138 return 1; 139 } 140 141 while (pd_names[num_pds]) 142 num_pds++; 143 144 if (num_pds > ARRAY_SIZE(adsp->proxy_pds)) 145 return -E2BIG; 146 147 for (i = 0; i < num_pds; i++) { 148 devs[i] = dev_pm_domain_attach_by_name(dev, pd_names[i]); 149 if (IS_ERR_OR_NULL(devs[i])) { 150 ret = PTR_ERR(devs[i]) ? : -ENODATA; 151 goto unroll_attach; 152 } 153 } 154 155 return num_pds; 156 157 unroll_attach: 158 for (i--; i >= 0; i--) 159 dev_pm_domain_detach(devs[i], false); 160 161 return ret; 162 } 163 164 static void qcom_rproc_pds_detach(struct qcom_adsp *adsp, struct device **pds, 165 size_t pd_count) 166 { 167 struct device *dev = adsp->dev; 168 int i; 169 170 /* Handle single power domain */ 171 if (dev->pm_domain && pd_count) { 172 pm_runtime_disable(dev); 173 return; 174 } 175 176 for (i = 0; i < pd_count; i++) 177 dev_pm_domain_detach(pds[i], false); 178 } 179 180 static int qcom_rproc_pds_enable(struct qcom_adsp *adsp, struct device **pds, 181 size_t pd_count) 182 { 183 int ret; 184 int i; 185 186 for (i = 0; i < pd_count; i++) { 187 dev_pm_genpd_set_performance_state(pds[i], INT_MAX); 188 ret = pm_runtime_resume_and_get(pds[i]); 189 if (ret < 0) { 190 dev_pm_genpd_set_performance_state(pds[i], 0); 191 goto unroll_pd_votes; 192 } 193 } 194 195 return 0; 196 197 unroll_pd_votes: 198 for (i--; i >= 0; i--) { 199 dev_pm_genpd_set_performance_state(pds[i], 0); 200 pm_runtime_put(pds[i]); 201 } 202 203 return ret; 204 } 205 206 static void qcom_rproc_pds_disable(struct qcom_adsp *adsp, struct device **pds, 207 size_t pd_count) 208 { 209 int i; 210 211 for (i = 0; i < pd_count; i++) { 212 dev_pm_genpd_set_performance_state(pds[i], 0); 213 pm_runtime_put(pds[i]); 214 } 215 } 216 217 static int qcom_wpss_shutdown(struct qcom_adsp *adsp) 218 { 219 unsigned int val; 220 221 regmap_write(adsp->halt_map, adsp->halt_lpass + LPASS_HALTREQ_REG, 1); 222 223 /* Wait for halt ACK from QDSP6 */ 224 regmap_read_poll_timeout(adsp->halt_map, 225 adsp->halt_lpass + LPASS_HALTACK_REG, val, 226 val, 1000, ACK_TIMEOUT_US); 227 228 /* Assert the WPSS PDC Reset */ 229 reset_control_assert(adsp->pdc_sync_reset); 230 231 /* Place the WPSS processor into reset */ 232 reset_control_assert(adsp->restart); 233 234 /* wait after asserting subsystem restart from AOSS */ 235 usleep_range(200, 205); 236 237 /* Remove the WPSS reset */ 238 reset_control_deassert(adsp->restart); 239 240 /* De-assert the WPSS PDC Reset */ 241 reset_control_deassert(adsp->pdc_sync_reset); 242 243 usleep_range(100, 105); 244 245 clk_bulk_disable_unprepare(adsp->num_clks, adsp->clks); 246 247 regmap_write(adsp->halt_map, adsp->halt_lpass + LPASS_HALTREQ_REG, 0); 248 249 /* Wait for halt ACK from QDSP6 */ 250 regmap_read_poll_timeout(adsp->halt_map, 251 adsp->halt_lpass + LPASS_HALTACK_REG, val, 252 !val, 1000, ACK_TIMEOUT_US); 253 254 return 0; 255 } 256 257 static int qcom_adsp_shutdown(struct qcom_adsp *adsp) 258 { 259 unsigned long timeout; 260 unsigned int val; 261 int ret; 262 263 /* Reset the retention logic */ 264 val = readl(adsp->qdsp6ss_base + RET_CFG_REG); 265 val |= 0x1; 266 writel(val, adsp->qdsp6ss_base + RET_CFG_REG); 267 268 clk_bulk_disable_unprepare(adsp->num_clks, adsp->clks); 269 270 /* QDSP6 master port needs to be explicitly halted */ 271 ret = regmap_read(adsp->halt_map, 272 adsp->halt_lpass + LPASS_PWR_ON_REG, &val); 273 if (ret || !val) 274 goto reset; 275 276 ret = regmap_read(adsp->halt_map, 277 adsp->halt_lpass + LPASS_MASTER_IDLE_REG, 278 &val); 279 if (ret || val) 280 goto reset; 281 282 regmap_write(adsp->halt_map, 283 adsp->halt_lpass + LPASS_HALTREQ_REG, 1); 284 285 /* Wait for halt ACK from QDSP6 */ 286 timeout = jiffies + msecs_to_jiffies(ACK_TIMEOUT); 287 for (;;) { 288 ret = regmap_read(adsp->halt_map, 289 adsp->halt_lpass + LPASS_HALTACK_REG, &val); 290 if (ret || val || time_after(jiffies, timeout)) 291 break; 292 293 usleep_range(1000, 1100); 294 } 295 296 ret = regmap_read(adsp->halt_map, 297 adsp->halt_lpass + LPASS_MASTER_IDLE_REG, &val); 298 if (ret || !val) 299 dev_err(adsp->dev, "port failed halt\n"); 300 301 reset: 302 /* Assert the LPASS PDC Reset */ 303 reset_control_assert(adsp->pdc_sync_reset); 304 /* Place the LPASS processor into reset */ 305 reset_control_assert(adsp->restart); 306 /* wait after asserting subsystem restart from AOSS */ 307 usleep_range(200, 300); 308 309 /* Clear the halt request for the AXIM and AHBM for Q6 */ 310 regmap_write(adsp->halt_map, adsp->halt_lpass + LPASS_HALTREQ_REG, 0); 311 312 /* De-assert the LPASS PDC Reset */ 313 reset_control_deassert(adsp->pdc_sync_reset); 314 /* Remove the LPASS reset */ 315 reset_control_deassert(adsp->restart); 316 /* wait after de-asserting subsystem restart from AOSS */ 317 usleep_range(200, 300); 318 319 return 0; 320 } 321 322 static int adsp_load(struct rproc *rproc, const struct firmware *fw) 323 { 324 struct qcom_adsp *adsp = rproc->priv; 325 int ret; 326 327 ret = qcom_mdt_load_no_init(adsp->dev, fw, rproc->firmware, 0, 328 adsp->mem_region, adsp->mem_phys, 329 adsp->mem_size, &adsp->mem_reloc); 330 if (ret) 331 return ret; 332 333 qcom_pil_info_store(adsp->info_name, adsp->mem_phys, adsp->mem_size); 334 335 return 0; 336 } 337 338 static void adsp_unmap_carveout(struct rproc *rproc) 339 { 340 struct qcom_adsp *adsp = rproc->priv; 341 342 if (adsp->has_iommu) 343 iommu_unmap(rproc->domain, adsp->mem_phys, adsp->mem_size); 344 } 345 346 static int adsp_map_carveout(struct rproc *rproc) 347 { 348 struct qcom_adsp *adsp = rproc->priv; 349 struct of_phandle_args args; 350 long long sid; 351 unsigned long iova; 352 int ret; 353 354 if (!adsp->has_iommu) 355 return 0; 356 357 if (!rproc->domain) 358 return -EINVAL; 359 360 ret = of_parse_phandle_with_args(adsp->dev->of_node, "iommus", "#iommu-cells", 0, &args); 361 if (ret < 0) 362 return ret; 363 364 sid = args.args[0] & SID_MASK_DEFAULT; 365 366 /* Add SID configuration for ADSP Firmware to SMMU */ 367 iova = adsp->mem_phys | (sid << 32); 368 369 ret = iommu_map(rproc->domain, iova, adsp->mem_phys, 370 adsp->mem_size, IOMMU_READ | IOMMU_WRITE, 371 GFP_KERNEL); 372 if (ret) { 373 dev_err(adsp->dev, "Unable to map ADSP Physical Memory\n"); 374 return ret; 375 } 376 377 return 0; 378 } 379 380 static int adsp_start(struct rproc *rproc) 381 { 382 struct qcom_adsp *adsp = rproc->priv; 383 int ret; 384 unsigned int val; 385 386 ret = qcom_q6v5_prepare(&adsp->q6v5); 387 if (ret) 388 return ret; 389 390 ret = adsp_map_carveout(rproc); 391 if (ret) { 392 dev_err(adsp->dev, "ADSP smmu mapping failed\n"); 393 goto disable_irqs; 394 } 395 396 ret = clk_prepare_enable(adsp->xo); 397 if (ret) 398 goto adsp_smmu_unmap; 399 400 ret = qcom_rproc_pds_enable(adsp, adsp->proxy_pds, 401 adsp->proxy_pd_count); 402 if (ret < 0) 403 goto disable_xo_clk; 404 405 ret = clk_bulk_prepare_enable(adsp->num_clks, adsp->clks); 406 if (ret) { 407 dev_err(adsp->dev, "adsp clk_enable failed\n"); 408 goto disable_power_domain; 409 } 410 411 /* Enable the XO clock */ 412 writel(1, adsp->qdsp6ss_base + QDSP6SS_XO_CBCR); 413 414 /* Enable the QDSP6SS sleep clock */ 415 writel(1, adsp->qdsp6ss_base + QDSP6SS_SLEEP_CBCR); 416 417 /* Enable the QDSP6 core clock */ 418 writel(1, adsp->qdsp6ss_base + QDSP6SS_CORE_CBCR); 419 420 /* Program boot address */ 421 writel(adsp->mem_phys >> 4, adsp->qdsp6ss_base + RST_EVB_REG); 422 423 if (adsp->lpass_efuse) 424 writel(LPASS_EFUSE_Q6SS_EVB_SEL, adsp->lpass_efuse); 425 426 /* De-assert QDSP6 stop core. QDSP6 will execute after out of reset */ 427 writel(LPASS_BOOT_CORE_START, adsp->qdsp6ss_base + CORE_START_REG); 428 429 /* Trigger boot FSM to start QDSP6 */ 430 writel(LPASS_BOOT_CMD_START, adsp->qdsp6ss_base + BOOT_CMD_REG); 431 432 /* Wait for core to come out of reset */ 433 ret = readl_poll_timeout(adsp->qdsp6ss_base + BOOT_STATUS_REG, 434 val, (val & BIT(0)) != 0, 10, BOOT_FSM_TIMEOUT); 435 if (ret) { 436 dev_err(adsp->dev, "failed to bootup adsp\n"); 437 goto disable_adsp_clks; 438 } 439 440 ret = qcom_q6v5_wait_for_start(&adsp->q6v5, msecs_to_jiffies(5 * HZ)); 441 if (ret == -ETIMEDOUT) { 442 dev_err(adsp->dev, "start timed out\n"); 443 goto disable_adsp_clks; 444 } 445 446 return 0; 447 448 disable_adsp_clks: 449 clk_bulk_disable_unprepare(adsp->num_clks, adsp->clks); 450 disable_power_domain: 451 qcom_rproc_pds_disable(adsp, adsp->proxy_pds, adsp->proxy_pd_count); 452 disable_xo_clk: 453 clk_disable_unprepare(adsp->xo); 454 adsp_smmu_unmap: 455 adsp_unmap_carveout(rproc); 456 disable_irqs: 457 qcom_q6v5_unprepare(&adsp->q6v5); 458 459 return ret; 460 } 461 462 static void qcom_adsp_pil_handover(struct qcom_q6v5 *q6v5) 463 { 464 struct qcom_adsp *adsp = container_of(q6v5, struct qcom_adsp, q6v5); 465 466 clk_disable_unprepare(adsp->xo); 467 qcom_rproc_pds_disable(adsp, adsp->proxy_pds, adsp->proxy_pd_count); 468 } 469 470 static int adsp_stop(struct rproc *rproc) 471 { 472 struct qcom_adsp *adsp = rproc->priv; 473 int handover; 474 int ret; 475 476 ret = qcom_q6v5_request_stop(&adsp->q6v5, adsp->sysmon); 477 if (ret == -ETIMEDOUT) 478 dev_err(adsp->dev, "timed out on wait\n"); 479 480 ret = adsp->shutdown(adsp); 481 if (ret) 482 dev_err(adsp->dev, "failed to shutdown: %d\n", ret); 483 484 adsp_unmap_carveout(rproc); 485 486 handover = qcom_q6v5_unprepare(&adsp->q6v5); 487 if (handover) 488 qcom_adsp_pil_handover(&adsp->q6v5); 489 490 return ret; 491 } 492 493 static void *adsp_da_to_va(struct rproc *rproc, u64 da, size_t len, bool *is_iomem) 494 { 495 struct qcom_adsp *adsp = rproc->priv; 496 int offset; 497 498 offset = da - adsp->mem_reloc; 499 if (offset < 0 || offset + len > adsp->mem_size) 500 return NULL; 501 502 return adsp->mem_region + offset; 503 } 504 505 static int adsp_parse_firmware(struct rproc *rproc, const struct firmware *fw) 506 { 507 struct qcom_adsp *adsp = rproc->priv; 508 int ret; 509 510 ret = qcom_register_dump_segments(rproc, fw); 511 if (ret) { 512 dev_err(&rproc->dev, "Error in registering dump segments\n"); 513 return ret; 514 } 515 516 if (adsp->has_iommu) { 517 ret = rproc_elf_load_rsc_table(rproc, fw); 518 if (ret) { 519 dev_err(&rproc->dev, "Error in loading resource table\n"); 520 return ret; 521 } 522 } 523 return 0; 524 } 525 526 static unsigned long adsp_panic(struct rproc *rproc) 527 { 528 struct qcom_adsp *adsp = rproc->priv; 529 530 return qcom_q6v5_panic(&adsp->q6v5); 531 } 532 533 static const struct rproc_ops adsp_ops = { 534 .start = adsp_start, 535 .stop = adsp_stop, 536 .da_to_va = adsp_da_to_va, 537 .parse_fw = adsp_parse_firmware, 538 .load = adsp_load, 539 .panic = adsp_panic, 540 }; 541 542 static int adsp_init_clock(struct qcom_adsp *adsp, const char **clk_ids) 543 { 544 int num_clks = 0; 545 int i, ret; 546 547 adsp->xo = devm_clk_get(adsp->dev, "xo"); 548 if (IS_ERR(adsp->xo)) { 549 ret = PTR_ERR(adsp->xo); 550 if (ret != -EPROBE_DEFER) 551 dev_err(adsp->dev, "failed to get xo clock"); 552 return ret; 553 } 554 555 for (i = 0; clk_ids[i]; i++) 556 num_clks++; 557 558 adsp->num_clks = num_clks; 559 adsp->clks = devm_kcalloc(adsp->dev, adsp->num_clks, 560 sizeof(*adsp->clks), GFP_KERNEL); 561 if (!adsp->clks) 562 return -ENOMEM; 563 564 for (i = 0; i < adsp->num_clks; i++) 565 adsp->clks[i].id = clk_ids[i]; 566 567 return devm_clk_bulk_get(adsp->dev, adsp->num_clks, adsp->clks); 568 } 569 570 static int adsp_init_reset(struct qcom_adsp *adsp) 571 { 572 adsp->pdc_sync_reset = devm_reset_control_get_optional_exclusive(adsp->dev, 573 "pdc_sync"); 574 if (IS_ERR(adsp->pdc_sync_reset)) { 575 dev_err(adsp->dev, "failed to acquire pdc_sync reset\n"); 576 return PTR_ERR(adsp->pdc_sync_reset); 577 } 578 579 adsp->restart = devm_reset_control_get_optional_exclusive(adsp->dev, "restart"); 580 581 /* Fall back to the old "cc_lpass" if "restart" is absent */ 582 if (!adsp->restart) 583 adsp->restart = devm_reset_control_get_exclusive(adsp->dev, "cc_lpass"); 584 585 if (IS_ERR(adsp->restart)) { 586 dev_err(adsp->dev, "failed to acquire restart\n"); 587 return PTR_ERR(adsp->restart); 588 } 589 590 return 0; 591 } 592 593 static int adsp_init_mmio(struct qcom_adsp *adsp, 594 struct platform_device *pdev) 595 { 596 struct resource *efuse_region; 597 struct device_node *syscon; 598 int ret; 599 600 adsp->qdsp6ss_base = devm_platform_ioremap_resource(pdev, 0); 601 if (IS_ERR(adsp->qdsp6ss_base)) { 602 dev_err(adsp->dev, "failed to map QDSP6SS registers\n"); 603 return PTR_ERR(adsp->qdsp6ss_base); 604 } 605 606 efuse_region = platform_get_resource(pdev, IORESOURCE_MEM, 1); 607 if (!efuse_region) { 608 adsp->lpass_efuse = NULL; 609 dev_dbg(adsp->dev, "failed to get efuse memory region\n"); 610 } else { 611 adsp->lpass_efuse = devm_ioremap_resource(&pdev->dev, efuse_region); 612 if (IS_ERR(adsp->lpass_efuse)) { 613 dev_err(adsp->dev, "failed to map efuse registers\n"); 614 return PTR_ERR(adsp->lpass_efuse); 615 } 616 } 617 syscon = of_parse_phandle(pdev->dev.of_node, "qcom,halt-regs", 0); 618 if (!syscon) { 619 dev_err(&pdev->dev, "failed to parse qcom,halt-regs\n"); 620 return -EINVAL; 621 } 622 623 adsp->halt_map = syscon_node_to_regmap(syscon); 624 of_node_put(syscon); 625 if (IS_ERR(adsp->halt_map)) 626 return PTR_ERR(adsp->halt_map); 627 628 ret = of_property_read_u32_index(pdev->dev.of_node, "qcom,halt-regs", 629 1, &adsp->halt_lpass); 630 if (ret < 0) { 631 dev_err(&pdev->dev, "no offset in syscon\n"); 632 return ret; 633 } 634 635 return 0; 636 } 637 638 static int adsp_alloc_memory_region(struct qcom_adsp *adsp) 639 { 640 struct device_node *node; 641 struct resource r; 642 int ret; 643 644 node = of_parse_phandle(adsp->dev->of_node, "memory-region", 0); 645 if (!node) { 646 dev_err(adsp->dev, "no memory-region specified\n"); 647 return -EINVAL; 648 } 649 650 ret = of_address_to_resource(node, 0, &r); 651 of_node_put(node); 652 if (ret) 653 return ret; 654 655 adsp->mem_phys = adsp->mem_reloc = r.start; 656 adsp->mem_size = resource_size(&r); 657 adsp->mem_region = devm_ioremap_wc(adsp->dev, 658 adsp->mem_phys, adsp->mem_size); 659 if (!adsp->mem_region) { 660 dev_err(adsp->dev, "unable to map memory region: %pa+%zx\n", 661 &r.start, adsp->mem_size); 662 return -EBUSY; 663 } 664 665 return 0; 666 } 667 668 static int adsp_probe(struct platform_device *pdev) 669 { 670 const struct adsp_pil_data *desc; 671 const char *firmware_name; 672 struct qcom_adsp *adsp; 673 struct rproc *rproc; 674 int ret; 675 676 desc = of_device_get_match_data(&pdev->dev); 677 if (!desc) 678 return -EINVAL; 679 680 firmware_name = desc->firmware_name; 681 ret = of_property_read_string(pdev->dev.of_node, "firmware-name", 682 &firmware_name); 683 if (ret < 0 && ret != -EINVAL) { 684 dev_err(&pdev->dev, "unable to read firmware-name\n"); 685 return ret; 686 } 687 688 rproc = rproc_alloc(&pdev->dev, pdev->name, &adsp_ops, 689 firmware_name, sizeof(*adsp)); 690 if (!rproc) { 691 dev_err(&pdev->dev, "unable to allocate remoteproc\n"); 692 return -ENOMEM; 693 } 694 695 rproc->auto_boot = desc->auto_boot; 696 rproc->has_iommu = desc->has_iommu; 697 rproc_coredump_set_elf_info(rproc, ELFCLASS32, EM_NONE); 698 699 adsp = rproc->priv; 700 adsp->dev = &pdev->dev; 701 adsp->rproc = rproc; 702 adsp->info_name = desc->sysmon_name; 703 adsp->has_iommu = desc->has_iommu; 704 705 platform_set_drvdata(pdev, adsp); 706 707 if (desc->is_wpss) 708 adsp->shutdown = qcom_wpss_shutdown; 709 else 710 adsp->shutdown = qcom_adsp_shutdown; 711 712 ret = adsp_alloc_memory_region(adsp); 713 if (ret) 714 goto free_rproc; 715 716 ret = adsp_init_clock(adsp, desc->clk_ids); 717 if (ret) 718 goto free_rproc; 719 720 ret = qcom_rproc_pds_attach(adsp->dev, adsp, 721 desc->proxy_pd_names); 722 if (ret < 0) { 723 dev_err(&pdev->dev, "Failed to attach proxy power domains\n"); 724 goto free_rproc; 725 } 726 adsp->proxy_pd_count = ret; 727 728 ret = adsp_init_reset(adsp); 729 if (ret) 730 goto disable_pm; 731 732 ret = adsp_init_mmio(adsp, pdev); 733 if (ret) 734 goto disable_pm; 735 736 ret = qcom_q6v5_init(&adsp->q6v5, pdev, rproc, desc->crash_reason_smem, 737 desc->load_state, qcom_adsp_pil_handover); 738 if (ret) 739 goto disable_pm; 740 741 qcom_add_glink_subdev(rproc, &adsp->glink_subdev, desc->ssr_name); 742 qcom_add_ssr_subdev(rproc, &adsp->ssr_subdev, desc->ssr_name); 743 adsp->sysmon = qcom_add_sysmon_subdev(rproc, 744 desc->sysmon_name, 745 desc->ssctl_id); 746 if (IS_ERR(adsp->sysmon)) { 747 ret = PTR_ERR(adsp->sysmon); 748 goto disable_pm; 749 } 750 751 ret = rproc_add(rproc); 752 if (ret) 753 goto disable_pm; 754 755 return 0; 756 757 disable_pm: 758 qcom_rproc_pds_detach(adsp, adsp->proxy_pds, adsp->proxy_pd_count); 759 760 free_rproc: 761 rproc_free(rproc); 762 763 return ret; 764 } 765 766 static void adsp_remove(struct platform_device *pdev) 767 { 768 struct qcom_adsp *adsp = platform_get_drvdata(pdev); 769 770 rproc_del(adsp->rproc); 771 772 qcom_q6v5_deinit(&adsp->q6v5); 773 qcom_remove_glink_subdev(adsp->rproc, &adsp->glink_subdev); 774 qcom_remove_sysmon_subdev(adsp->sysmon); 775 qcom_remove_ssr_subdev(adsp->rproc, &adsp->ssr_subdev); 776 qcom_rproc_pds_detach(adsp, adsp->proxy_pds, adsp->proxy_pd_count); 777 rproc_free(adsp->rproc); 778 } 779 780 static const struct adsp_pil_data adsp_resource_init = { 781 .crash_reason_smem = 423, 782 .firmware_name = "adsp.mdt", 783 .ssr_name = "lpass", 784 .sysmon_name = "adsp", 785 .ssctl_id = 0x14, 786 .is_wpss = false, 787 .auto_boot = true, 788 .clk_ids = (const char*[]) { 789 "sway_cbcr", "lpass_ahbs_aon_cbcr", "lpass_ahbm_aon_cbcr", 790 "qdsp6ss_xo", "qdsp6ss_sleep", "qdsp6ss_core", NULL 791 }, 792 .num_clks = 7, 793 .proxy_pd_names = (const char*[]) { 794 "cx", NULL 795 }, 796 }; 797 798 static const struct adsp_pil_data adsp_sc7280_resource_init = { 799 .crash_reason_smem = 423, 800 .firmware_name = "adsp.pbn", 801 .load_state = "adsp", 802 .ssr_name = "lpass", 803 .sysmon_name = "adsp", 804 .ssctl_id = 0x14, 805 .has_iommu = true, 806 .auto_boot = true, 807 .clk_ids = (const char*[]) { 808 "gcc_cfg_noc_lpass", NULL 809 }, 810 .num_clks = 1, 811 }; 812 813 static const struct adsp_pil_data cdsp_resource_init = { 814 .crash_reason_smem = 601, 815 .firmware_name = "cdsp.mdt", 816 .ssr_name = "cdsp", 817 .sysmon_name = "cdsp", 818 .ssctl_id = 0x17, 819 .is_wpss = false, 820 .auto_boot = true, 821 .clk_ids = (const char*[]) { 822 "sway", "tbu", "bimc", "ahb_aon", "q6ss_slave", "q6ss_master", 823 "q6_axim", NULL 824 }, 825 .num_clks = 7, 826 .proxy_pd_names = (const char*[]) { 827 "cx", NULL 828 }, 829 }; 830 831 static const struct adsp_pil_data wpss_resource_init = { 832 .crash_reason_smem = 626, 833 .firmware_name = "wpss.mdt", 834 .ssr_name = "wpss", 835 .sysmon_name = "wpss", 836 .ssctl_id = 0x19, 837 .is_wpss = true, 838 .auto_boot = false, 839 .load_state = "wpss", 840 .clk_ids = (const char*[]) { 841 "ahb_bdg", "ahb", "rscp", NULL 842 }, 843 .num_clks = 3, 844 .proxy_pd_names = (const char*[]) { 845 "cx", "mx", NULL 846 }, 847 }; 848 849 static const struct of_device_id adsp_of_match[] = { 850 { .compatible = "qcom,qcs404-cdsp-pil", .data = &cdsp_resource_init }, 851 { .compatible = "qcom,sc7280-adsp-pil", .data = &adsp_sc7280_resource_init }, 852 { .compatible = "qcom,sc7280-wpss-pil", .data = &wpss_resource_init }, 853 { .compatible = "qcom,sdm845-adsp-pil", .data = &adsp_resource_init }, 854 { }, 855 }; 856 MODULE_DEVICE_TABLE(of, adsp_of_match); 857 858 static struct platform_driver adsp_pil_driver = { 859 .probe = adsp_probe, 860 .remove_new = adsp_remove, 861 .driver = { 862 .name = "qcom_q6v5_adsp", 863 .of_match_table = adsp_of_match, 864 }, 865 }; 866 867 module_platform_driver(adsp_pil_driver); 868 MODULE_DESCRIPTION("QTI SDM845 ADSP Peripheral Image Loader"); 869 MODULE_LICENSE("GPL v2"); 870