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