1 // SPDX-License-Identifier: GPL-2.0-only 2 /* 3 * Qualcomm self-authenticating modem subsystem 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/devcoredump.h> 13 #include <linux/dma-mapping.h> 14 #include <linux/interrupt.h> 15 #include <linux/kernel.h> 16 #include <linux/mfd/syscon.h> 17 #include <linux/module.h> 18 #include <linux/of_address.h> 19 #include <linux/of_device.h> 20 #include <linux/platform_device.h> 21 #include <linux/pm_domain.h> 22 #include <linux/pm_runtime.h> 23 #include <linux/regmap.h> 24 #include <linux/regulator/consumer.h> 25 #include <linux/remoteproc.h> 26 #include "linux/remoteproc/qcom_q6v5_ipa_notify.h" 27 #include <linux/reset.h> 28 #include <linux/soc/qcom/mdt_loader.h> 29 #include <linux/iopoll.h> 30 31 #include "remoteproc_internal.h" 32 #include "qcom_common.h" 33 #include "qcom_pil_info.h" 34 #include "qcom_q6v5.h" 35 36 #include <linux/qcom_scm.h> 37 38 #define MPSS_CRASH_REASON_SMEM 421 39 40 #define MBA_LOG_SIZE SZ_4K 41 42 /* RMB Status Register Values */ 43 #define RMB_PBL_SUCCESS 0x1 44 45 #define RMB_MBA_XPU_UNLOCKED 0x1 46 #define RMB_MBA_XPU_UNLOCKED_SCRIBBLED 0x2 47 #define RMB_MBA_META_DATA_AUTH_SUCCESS 0x3 48 #define RMB_MBA_AUTH_COMPLETE 0x4 49 50 /* PBL/MBA interface registers */ 51 #define RMB_MBA_IMAGE_REG 0x00 52 #define RMB_PBL_STATUS_REG 0x04 53 #define RMB_MBA_COMMAND_REG 0x08 54 #define RMB_MBA_STATUS_REG 0x0C 55 #define RMB_PMI_META_DATA_REG 0x10 56 #define RMB_PMI_CODE_START_REG 0x14 57 #define RMB_PMI_CODE_LENGTH_REG 0x18 58 #define RMB_MBA_MSS_STATUS 0x40 59 #define RMB_MBA_ALT_RESET 0x44 60 61 #define RMB_CMD_META_DATA_READY 0x1 62 #define RMB_CMD_LOAD_READY 0x2 63 64 /* QDSP6SS Register Offsets */ 65 #define QDSP6SS_RESET_REG 0x014 66 #define QDSP6SS_GFMUX_CTL_REG 0x020 67 #define QDSP6SS_PWR_CTL_REG 0x030 68 #define QDSP6SS_MEM_PWR_CTL 0x0B0 69 #define QDSP6V6SS_MEM_PWR_CTL 0x034 70 #define QDSP6SS_STRAP_ACC 0x110 71 72 /* AXI Halt Register Offsets */ 73 #define AXI_HALTREQ_REG 0x0 74 #define AXI_HALTACK_REG 0x4 75 #define AXI_IDLE_REG 0x8 76 #define AXI_GATING_VALID_OVERRIDE BIT(0) 77 78 #define HALT_ACK_TIMEOUT_US 100000 79 80 /* QDSP6SS_RESET */ 81 #define Q6SS_STOP_CORE BIT(0) 82 #define Q6SS_CORE_ARES BIT(1) 83 #define Q6SS_BUS_ARES_ENABLE BIT(2) 84 85 /* QDSP6SS CBCR */ 86 #define Q6SS_CBCR_CLKEN BIT(0) 87 #define Q6SS_CBCR_CLKOFF BIT(31) 88 #define Q6SS_CBCR_TIMEOUT_US 200 89 90 /* QDSP6SS_GFMUX_CTL */ 91 #define Q6SS_CLK_ENABLE BIT(1) 92 93 /* QDSP6SS_PWR_CTL */ 94 #define Q6SS_L2DATA_SLP_NRET_N_0 BIT(0) 95 #define Q6SS_L2DATA_SLP_NRET_N_1 BIT(1) 96 #define Q6SS_L2DATA_SLP_NRET_N_2 BIT(2) 97 #define Q6SS_L2TAG_SLP_NRET_N BIT(16) 98 #define Q6SS_ETB_SLP_NRET_N BIT(17) 99 #define Q6SS_L2DATA_STBY_N BIT(18) 100 #define Q6SS_SLP_RET_N BIT(19) 101 #define Q6SS_CLAMP_IO BIT(20) 102 #define QDSS_BHS_ON BIT(21) 103 #define QDSS_LDO_BYP BIT(22) 104 105 /* QDSP6v56 parameters */ 106 #define QDSP6v56_LDO_BYP BIT(25) 107 #define QDSP6v56_BHS_ON BIT(24) 108 #define QDSP6v56_CLAMP_WL BIT(21) 109 #define QDSP6v56_CLAMP_QMC_MEM BIT(22) 110 #define QDSP6SS_XO_CBCR 0x0038 111 #define QDSP6SS_ACC_OVERRIDE_VAL 0x20 112 113 /* QDSP6v65 parameters */ 114 #define QDSP6SS_CORE_CBCR 0x20 115 #define QDSP6SS_SLEEP 0x3C 116 #define QDSP6SS_BOOT_CORE_START 0x400 117 #define QDSP6SS_BOOT_CMD 0x404 118 #define BOOT_FSM_TIMEOUT 10000 119 120 struct reg_info { 121 struct regulator *reg; 122 int uV; 123 int uA; 124 }; 125 126 struct qcom_mss_reg_res { 127 const char *supply; 128 int uV; 129 int uA; 130 }; 131 132 struct rproc_hexagon_res { 133 const char *hexagon_mba_image; 134 struct qcom_mss_reg_res *proxy_supply; 135 struct qcom_mss_reg_res *active_supply; 136 char **proxy_clk_names; 137 char **reset_clk_names; 138 char **active_clk_names; 139 char **active_pd_names; 140 char **proxy_pd_names; 141 int version; 142 bool need_mem_protection; 143 bool has_alt_reset; 144 bool has_mba_logs; 145 bool has_spare_reg; 146 }; 147 148 struct q6v5 { 149 struct device *dev; 150 struct rproc *rproc; 151 152 void __iomem *reg_base; 153 void __iomem *rmb_base; 154 155 struct regmap *halt_map; 156 struct regmap *conn_map; 157 158 u32 halt_q6; 159 u32 halt_modem; 160 u32 halt_nc; 161 u32 conn_box; 162 163 struct reset_control *mss_restart; 164 struct reset_control *pdc_reset; 165 166 struct qcom_q6v5 q6v5; 167 168 struct clk *active_clks[8]; 169 struct clk *reset_clks[4]; 170 struct clk *proxy_clks[4]; 171 struct device *active_pds[1]; 172 struct device *proxy_pds[3]; 173 int active_clk_count; 174 int reset_clk_count; 175 int proxy_clk_count; 176 int active_pd_count; 177 int proxy_pd_count; 178 179 struct reg_info active_regs[1]; 180 struct reg_info proxy_regs[3]; 181 int active_reg_count; 182 int proxy_reg_count; 183 184 bool dump_mba_loaded; 185 size_t current_dump_size; 186 size_t total_dump_size; 187 188 phys_addr_t mba_phys; 189 void *mba_region; 190 size_t mba_size; 191 size_t dp_size; 192 193 phys_addr_t mpss_phys; 194 phys_addr_t mpss_reloc; 195 size_t mpss_size; 196 197 struct qcom_rproc_glink glink_subdev; 198 struct qcom_rproc_subdev smd_subdev; 199 struct qcom_rproc_ssr ssr_subdev; 200 struct qcom_rproc_ipa_notify ipa_notify_subdev; 201 struct qcom_sysmon *sysmon; 202 bool need_mem_protection; 203 bool has_alt_reset; 204 bool has_mba_logs; 205 bool has_spare_reg; 206 int mpss_perm; 207 int mba_perm; 208 const char *hexagon_mdt_image; 209 int version; 210 }; 211 212 enum { 213 MSS_MSM8916, 214 MSS_MSM8974, 215 MSS_MSM8996, 216 MSS_MSM8998, 217 MSS_SC7180, 218 MSS_SDM845, 219 }; 220 221 static int q6v5_regulator_init(struct device *dev, struct reg_info *regs, 222 const struct qcom_mss_reg_res *reg_res) 223 { 224 int rc; 225 int i; 226 227 if (!reg_res) 228 return 0; 229 230 for (i = 0; reg_res[i].supply; i++) { 231 regs[i].reg = devm_regulator_get(dev, reg_res[i].supply); 232 if (IS_ERR(regs[i].reg)) { 233 rc = PTR_ERR(regs[i].reg); 234 if (rc != -EPROBE_DEFER) 235 dev_err(dev, "Failed to get %s\n regulator", 236 reg_res[i].supply); 237 return rc; 238 } 239 240 regs[i].uV = reg_res[i].uV; 241 regs[i].uA = reg_res[i].uA; 242 } 243 244 return i; 245 } 246 247 static int q6v5_regulator_enable(struct q6v5 *qproc, 248 struct reg_info *regs, int count) 249 { 250 int ret; 251 int i; 252 253 for (i = 0; i < count; i++) { 254 if (regs[i].uV > 0) { 255 ret = regulator_set_voltage(regs[i].reg, 256 regs[i].uV, INT_MAX); 257 if (ret) { 258 dev_err(qproc->dev, 259 "Failed to request voltage for %d.\n", 260 i); 261 goto err; 262 } 263 } 264 265 if (regs[i].uA > 0) { 266 ret = regulator_set_load(regs[i].reg, 267 regs[i].uA); 268 if (ret < 0) { 269 dev_err(qproc->dev, 270 "Failed to set regulator mode\n"); 271 goto err; 272 } 273 } 274 275 ret = regulator_enable(regs[i].reg); 276 if (ret) { 277 dev_err(qproc->dev, "Regulator enable failed\n"); 278 goto err; 279 } 280 } 281 282 return 0; 283 err: 284 for (; i >= 0; i--) { 285 if (regs[i].uV > 0) 286 regulator_set_voltage(regs[i].reg, 0, INT_MAX); 287 288 if (regs[i].uA > 0) 289 regulator_set_load(regs[i].reg, 0); 290 291 regulator_disable(regs[i].reg); 292 } 293 294 return ret; 295 } 296 297 static void q6v5_regulator_disable(struct q6v5 *qproc, 298 struct reg_info *regs, int count) 299 { 300 int i; 301 302 for (i = 0; i < count; i++) { 303 if (regs[i].uV > 0) 304 regulator_set_voltage(regs[i].reg, 0, INT_MAX); 305 306 if (regs[i].uA > 0) 307 regulator_set_load(regs[i].reg, 0); 308 309 regulator_disable(regs[i].reg); 310 } 311 } 312 313 static int q6v5_clk_enable(struct device *dev, 314 struct clk **clks, int count) 315 { 316 int rc; 317 int i; 318 319 for (i = 0; i < count; i++) { 320 rc = clk_prepare_enable(clks[i]); 321 if (rc) { 322 dev_err(dev, "Clock enable failed\n"); 323 goto err; 324 } 325 } 326 327 return 0; 328 err: 329 for (i--; i >= 0; i--) 330 clk_disable_unprepare(clks[i]); 331 332 return rc; 333 } 334 335 static void q6v5_clk_disable(struct device *dev, 336 struct clk **clks, int count) 337 { 338 int i; 339 340 for (i = 0; i < count; i++) 341 clk_disable_unprepare(clks[i]); 342 } 343 344 static int q6v5_pds_enable(struct q6v5 *qproc, struct device **pds, 345 size_t pd_count) 346 { 347 int ret; 348 int i; 349 350 for (i = 0; i < pd_count; i++) { 351 dev_pm_genpd_set_performance_state(pds[i], INT_MAX); 352 ret = pm_runtime_get_sync(pds[i]); 353 if (ret < 0) 354 goto unroll_pd_votes; 355 } 356 357 return 0; 358 359 unroll_pd_votes: 360 for (i--; i >= 0; i--) { 361 dev_pm_genpd_set_performance_state(pds[i], 0); 362 pm_runtime_put(pds[i]); 363 } 364 365 return ret; 366 } 367 368 static void q6v5_pds_disable(struct q6v5 *qproc, struct device **pds, 369 size_t pd_count) 370 { 371 int i; 372 373 for (i = 0; i < pd_count; i++) { 374 dev_pm_genpd_set_performance_state(pds[i], 0); 375 pm_runtime_put(pds[i]); 376 } 377 } 378 379 static int q6v5_xfer_mem_ownership(struct q6v5 *qproc, int *current_perm, 380 bool local, bool remote, phys_addr_t addr, 381 size_t size) 382 { 383 struct qcom_scm_vmperm next[2]; 384 int perms = 0; 385 386 if (!qproc->need_mem_protection) 387 return 0; 388 389 if (local == !!(*current_perm & BIT(QCOM_SCM_VMID_HLOS)) && 390 remote == !!(*current_perm & BIT(QCOM_SCM_VMID_MSS_MSA))) 391 return 0; 392 393 if (local) { 394 next[perms].vmid = QCOM_SCM_VMID_HLOS; 395 next[perms].perm = QCOM_SCM_PERM_RWX; 396 perms++; 397 } 398 399 if (remote) { 400 next[perms].vmid = QCOM_SCM_VMID_MSS_MSA; 401 next[perms].perm = QCOM_SCM_PERM_RW; 402 perms++; 403 } 404 405 return qcom_scm_assign_mem(addr, ALIGN(size, SZ_4K), 406 current_perm, next, perms); 407 } 408 409 static void q6v5_debug_policy_load(struct q6v5 *qproc) 410 { 411 const struct firmware *dp_fw; 412 413 if (request_firmware_direct(&dp_fw, "msadp", qproc->dev)) 414 return; 415 416 if (SZ_1M + dp_fw->size <= qproc->mba_size) { 417 memcpy(qproc->mba_region + SZ_1M, dp_fw->data, dp_fw->size); 418 qproc->dp_size = dp_fw->size; 419 } 420 421 release_firmware(dp_fw); 422 } 423 424 static int q6v5_load(struct rproc *rproc, const struct firmware *fw) 425 { 426 struct q6v5 *qproc = rproc->priv; 427 428 /* MBA is restricted to a maximum size of 1M */ 429 if (fw->size > qproc->mba_size || fw->size > SZ_1M) { 430 dev_err(qproc->dev, "MBA firmware load failed\n"); 431 return -EINVAL; 432 } 433 434 memcpy(qproc->mba_region, fw->data, fw->size); 435 q6v5_debug_policy_load(qproc); 436 437 return 0; 438 } 439 440 static int q6v5_reset_assert(struct q6v5 *qproc) 441 { 442 int ret; 443 444 if (qproc->has_alt_reset) { 445 reset_control_assert(qproc->pdc_reset); 446 ret = reset_control_reset(qproc->mss_restart); 447 reset_control_deassert(qproc->pdc_reset); 448 } else if (qproc->has_spare_reg) { 449 /* 450 * When the AXI pipeline is being reset with the Q6 modem partly 451 * operational there is possibility of AXI valid signal to 452 * glitch, leading to spurious transactions and Q6 hangs. A work 453 * around is employed by asserting the AXI_GATING_VALID_OVERRIDE 454 * BIT before triggering Q6 MSS reset. AXI_GATING_VALID_OVERRIDE 455 * is withdrawn post MSS assert followed by a MSS deassert, 456 * while holding the PDC reset. 457 */ 458 reset_control_assert(qproc->pdc_reset); 459 regmap_update_bits(qproc->conn_map, qproc->conn_box, 460 AXI_GATING_VALID_OVERRIDE, 1); 461 reset_control_assert(qproc->mss_restart); 462 reset_control_deassert(qproc->pdc_reset); 463 regmap_update_bits(qproc->conn_map, qproc->conn_box, 464 AXI_GATING_VALID_OVERRIDE, 0); 465 ret = reset_control_deassert(qproc->mss_restart); 466 } else { 467 ret = reset_control_assert(qproc->mss_restart); 468 } 469 470 return ret; 471 } 472 473 static int q6v5_reset_deassert(struct q6v5 *qproc) 474 { 475 int ret; 476 477 if (qproc->has_alt_reset) { 478 reset_control_assert(qproc->pdc_reset); 479 writel(1, qproc->rmb_base + RMB_MBA_ALT_RESET); 480 ret = reset_control_reset(qproc->mss_restart); 481 writel(0, qproc->rmb_base + RMB_MBA_ALT_RESET); 482 reset_control_deassert(qproc->pdc_reset); 483 } else if (qproc->has_spare_reg) { 484 ret = reset_control_reset(qproc->mss_restart); 485 } else { 486 ret = reset_control_deassert(qproc->mss_restart); 487 } 488 489 return ret; 490 } 491 492 static int q6v5_rmb_pbl_wait(struct q6v5 *qproc, int ms) 493 { 494 unsigned long timeout; 495 s32 val; 496 497 timeout = jiffies + msecs_to_jiffies(ms); 498 for (;;) { 499 val = readl(qproc->rmb_base + RMB_PBL_STATUS_REG); 500 if (val) 501 break; 502 503 if (time_after(jiffies, timeout)) 504 return -ETIMEDOUT; 505 506 msleep(1); 507 } 508 509 return val; 510 } 511 512 static int q6v5_rmb_mba_wait(struct q6v5 *qproc, u32 status, int ms) 513 { 514 515 unsigned long timeout; 516 s32 val; 517 518 timeout = jiffies + msecs_to_jiffies(ms); 519 for (;;) { 520 val = readl(qproc->rmb_base + RMB_MBA_STATUS_REG); 521 if (val < 0) 522 break; 523 524 if (!status && val) 525 break; 526 else if (status && val == status) 527 break; 528 529 if (time_after(jiffies, timeout)) 530 return -ETIMEDOUT; 531 532 msleep(1); 533 } 534 535 return val; 536 } 537 538 static void q6v5_dump_mba_logs(struct q6v5 *qproc) 539 { 540 struct rproc *rproc = qproc->rproc; 541 void *data; 542 543 if (!qproc->has_mba_logs) 544 return; 545 546 if (q6v5_xfer_mem_ownership(qproc, &qproc->mba_perm, true, false, qproc->mba_phys, 547 qproc->mba_size)) 548 return; 549 550 data = vmalloc(MBA_LOG_SIZE); 551 if (!data) 552 return; 553 554 memcpy(data, qproc->mba_region, MBA_LOG_SIZE); 555 dev_coredumpv(&rproc->dev, data, MBA_LOG_SIZE, GFP_KERNEL); 556 } 557 558 static int q6v5proc_reset(struct q6v5 *qproc) 559 { 560 u32 val; 561 int ret; 562 int i; 563 564 if (qproc->version == MSS_SDM845) { 565 val = readl(qproc->reg_base + QDSP6SS_SLEEP); 566 val |= Q6SS_CBCR_CLKEN; 567 writel(val, qproc->reg_base + QDSP6SS_SLEEP); 568 569 ret = readl_poll_timeout(qproc->reg_base + QDSP6SS_SLEEP, 570 val, !(val & Q6SS_CBCR_CLKOFF), 1, 571 Q6SS_CBCR_TIMEOUT_US); 572 if (ret) { 573 dev_err(qproc->dev, "QDSP6SS Sleep clock timed out\n"); 574 return -ETIMEDOUT; 575 } 576 577 /* De-assert QDSP6 stop core */ 578 writel(1, qproc->reg_base + QDSP6SS_BOOT_CORE_START); 579 /* Trigger boot FSM */ 580 writel(1, qproc->reg_base + QDSP6SS_BOOT_CMD); 581 582 ret = readl_poll_timeout(qproc->rmb_base + RMB_MBA_MSS_STATUS, 583 val, (val & BIT(0)) != 0, 10, BOOT_FSM_TIMEOUT); 584 if (ret) { 585 dev_err(qproc->dev, "Boot FSM failed to complete.\n"); 586 /* Reset the modem so that boot FSM is in reset state */ 587 q6v5_reset_deassert(qproc); 588 return ret; 589 } 590 591 goto pbl_wait; 592 } else if (qproc->version == MSS_SC7180) { 593 val = readl(qproc->reg_base + QDSP6SS_SLEEP); 594 val |= Q6SS_CBCR_CLKEN; 595 writel(val, qproc->reg_base + QDSP6SS_SLEEP); 596 597 ret = readl_poll_timeout(qproc->reg_base + QDSP6SS_SLEEP, 598 val, !(val & Q6SS_CBCR_CLKOFF), 1, 599 Q6SS_CBCR_TIMEOUT_US); 600 if (ret) { 601 dev_err(qproc->dev, "QDSP6SS Sleep clock timed out\n"); 602 return -ETIMEDOUT; 603 } 604 605 /* Turn on the XO clock needed for PLL setup */ 606 val = readl(qproc->reg_base + QDSP6SS_XO_CBCR); 607 val |= Q6SS_CBCR_CLKEN; 608 writel(val, qproc->reg_base + QDSP6SS_XO_CBCR); 609 610 ret = readl_poll_timeout(qproc->reg_base + QDSP6SS_XO_CBCR, 611 val, !(val & Q6SS_CBCR_CLKOFF), 1, 612 Q6SS_CBCR_TIMEOUT_US); 613 if (ret) { 614 dev_err(qproc->dev, "QDSP6SS XO clock timed out\n"); 615 return -ETIMEDOUT; 616 } 617 618 /* Configure Q6 core CBCR to auto-enable after reset sequence */ 619 val = readl(qproc->reg_base + QDSP6SS_CORE_CBCR); 620 val |= Q6SS_CBCR_CLKEN; 621 writel(val, qproc->reg_base + QDSP6SS_CORE_CBCR); 622 623 /* De-assert the Q6 stop core signal */ 624 writel(1, qproc->reg_base + QDSP6SS_BOOT_CORE_START); 625 626 /* Wait for 10 us for any staggering logic to settle */ 627 usleep_range(10, 20); 628 629 /* Trigger the boot FSM to start the Q6 out-of-reset sequence */ 630 writel(1, qproc->reg_base + QDSP6SS_BOOT_CMD); 631 632 /* Poll the MSS_STATUS for FSM completion */ 633 ret = readl_poll_timeout(qproc->rmb_base + RMB_MBA_MSS_STATUS, 634 val, (val & BIT(0)) != 0, 10, BOOT_FSM_TIMEOUT); 635 if (ret) { 636 dev_err(qproc->dev, "Boot FSM failed to complete.\n"); 637 /* Reset the modem so that boot FSM is in reset state */ 638 q6v5_reset_deassert(qproc); 639 return ret; 640 } 641 goto pbl_wait; 642 } else if (qproc->version == MSS_MSM8996 || 643 qproc->version == MSS_MSM8998) { 644 int mem_pwr_ctl; 645 646 /* Override the ACC value if required */ 647 writel(QDSP6SS_ACC_OVERRIDE_VAL, 648 qproc->reg_base + QDSP6SS_STRAP_ACC); 649 650 /* Assert resets, stop core */ 651 val = readl(qproc->reg_base + QDSP6SS_RESET_REG); 652 val |= Q6SS_CORE_ARES | Q6SS_BUS_ARES_ENABLE | Q6SS_STOP_CORE; 653 writel(val, qproc->reg_base + QDSP6SS_RESET_REG); 654 655 /* BHS require xo cbcr to be enabled */ 656 val = readl(qproc->reg_base + QDSP6SS_XO_CBCR); 657 val |= Q6SS_CBCR_CLKEN; 658 writel(val, qproc->reg_base + QDSP6SS_XO_CBCR); 659 660 /* Read CLKOFF bit to go low indicating CLK is enabled */ 661 ret = readl_poll_timeout(qproc->reg_base + QDSP6SS_XO_CBCR, 662 val, !(val & Q6SS_CBCR_CLKOFF), 1, 663 Q6SS_CBCR_TIMEOUT_US); 664 if (ret) { 665 dev_err(qproc->dev, 666 "xo cbcr enabling timed out (rc:%d)\n", ret); 667 return ret; 668 } 669 /* Enable power block headswitch and wait for it to stabilize */ 670 val = readl(qproc->reg_base + QDSP6SS_PWR_CTL_REG); 671 val |= QDSP6v56_BHS_ON; 672 writel(val, qproc->reg_base + QDSP6SS_PWR_CTL_REG); 673 val |= readl(qproc->reg_base + QDSP6SS_PWR_CTL_REG); 674 udelay(1); 675 676 /* Put LDO in bypass mode */ 677 val |= QDSP6v56_LDO_BYP; 678 writel(val, qproc->reg_base + QDSP6SS_PWR_CTL_REG); 679 680 /* Deassert QDSP6 compiler memory clamp */ 681 val = readl(qproc->reg_base + QDSP6SS_PWR_CTL_REG); 682 val &= ~QDSP6v56_CLAMP_QMC_MEM; 683 writel(val, qproc->reg_base + QDSP6SS_PWR_CTL_REG); 684 685 /* Deassert memory peripheral sleep and L2 memory standby */ 686 val |= Q6SS_L2DATA_STBY_N | Q6SS_SLP_RET_N; 687 writel(val, qproc->reg_base + QDSP6SS_PWR_CTL_REG); 688 689 /* Turn on L1, L2, ETB and JU memories 1 at a time */ 690 if (qproc->version == MSS_MSM8996) { 691 mem_pwr_ctl = QDSP6SS_MEM_PWR_CTL; 692 i = 19; 693 } else { 694 /* MSS_MSM8998 */ 695 mem_pwr_ctl = QDSP6V6SS_MEM_PWR_CTL; 696 i = 28; 697 } 698 val = readl(qproc->reg_base + mem_pwr_ctl); 699 for (; i >= 0; i--) { 700 val |= BIT(i); 701 writel(val, qproc->reg_base + mem_pwr_ctl); 702 /* 703 * Read back value to ensure the write is done then 704 * wait for 1us for both memory peripheral and data 705 * array to turn on. 706 */ 707 val |= readl(qproc->reg_base + mem_pwr_ctl); 708 udelay(1); 709 } 710 /* Remove word line clamp */ 711 val = readl(qproc->reg_base + QDSP6SS_PWR_CTL_REG); 712 val &= ~QDSP6v56_CLAMP_WL; 713 writel(val, qproc->reg_base + QDSP6SS_PWR_CTL_REG); 714 } else { 715 /* Assert resets, stop core */ 716 val = readl(qproc->reg_base + QDSP6SS_RESET_REG); 717 val |= Q6SS_CORE_ARES | Q6SS_BUS_ARES_ENABLE | Q6SS_STOP_CORE; 718 writel(val, qproc->reg_base + QDSP6SS_RESET_REG); 719 720 /* Enable power block headswitch and wait for it to stabilize */ 721 val = readl(qproc->reg_base + QDSP6SS_PWR_CTL_REG); 722 val |= QDSS_BHS_ON | QDSS_LDO_BYP; 723 writel(val, qproc->reg_base + QDSP6SS_PWR_CTL_REG); 724 val |= readl(qproc->reg_base + QDSP6SS_PWR_CTL_REG); 725 udelay(1); 726 /* 727 * Turn on memories. L2 banks should be done individually 728 * to minimize inrush current. 729 */ 730 val = readl(qproc->reg_base + QDSP6SS_PWR_CTL_REG); 731 val |= Q6SS_SLP_RET_N | Q6SS_L2TAG_SLP_NRET_N | 732 Q6SS_ETB_SLP_NRET_N | Q6SS_L2DATA_STBY_N; 733 writel(val, qproc->reg_base + QDSP6SS_PWR_CTL_REG); 734 val |= Q6SS_L2DATA_SLP_NRET_N_2; 735 writel(val, qproc->reg_base + QDSP6SS_PWR_CTL_REG); 736 val |= Q6SS_L2DATA_SLP_NRET_N_1; 737 writel(val, qproc->reg_base + QDSP6SS_PWR_CTL_REG); 738 val |= Q6SS_L2DATA_SLP_NRET_N_0; 739 writel(val, qproc->reg_base + QDSP6SS_PWR_CTL_REG); 740 } 741 /* Remove IO clamp */ 742 val &= ~Q6SS_CLAMP_IO; 743 writel(val, qproc->reg_base + QDSP6SS_PWR_CTL_REG); 744 745 /* Bring core out of reset */ 746 val = readl(qproc->reg_base + QDSP6SS_RESET_REG); 747 val &= ~Q6SS_CORE_ARES; 748 writel(val, qproc->reg_base + QDSP6SS_RESET_REG); 749 750 /* Turn on core clock */ 751 val = readl(qproc->reg_base + QDSP6SS_GFMUX_CTL_REG); 752 val |= Q6SS_CLK_ENABLE; 753 writel(val, qproc->reg_base + QDSP6SS_GFMUX_CTL_REG); 754 755 /* Start core execution */ 756 val = readl(qproc->reg_base + QDSP6SS_RESET_REG); 757 val &= ~Q6SS_STOP_CORE; 758 writel(val, qproc->reg_base + QDSP6SS_RESET_REG); 759 760 pbl_wait: 761 /* Wait for PBL status */ 762 ret = q6v5_rmb_pbl_wait(qproc, 1000); 763 if (ret == -ETIMEDOUT) { 764 dev_err(qproc->dev, "PBL boot timed out\n"); 765 } else if (ret != RMB_PBL_SUCCESS) { 766 dev_err(qproc->dev, "PBL returned unexpected status %d\n", ret); 767 ret = -EINVAL; 768 } else { 769 ret = 0; 770 } 771 772 return ret; 773 } 774 775 static void q6v5proc_halt_axi_port(struct q6v5 *qproc, 776 struct regmap *halt_map, 777 u32 offset) 778 { 779 unsigned int val; 780 int ret; 781 782 /* Check if we're already idle */ 783 ret = regmap_read(halt_map, offset + AXI_IDLE_REG, &val); 784 if (!ret && val) 785 return; 786 787 /* Assert halt request */ 788 regmap_write(halt_map, offset + AXI_HALTREQ_REG, 1); 789 790 /* Wait for halt */ 791 regmap_read_poll_timeout(halt_map, offset + AXI_HALTACK_REG, val, 792 val, 1000, HALT_ACK_TIMEOUT_US); 793 794 ret = regmap_read(halt_map, offset + AXI_IDLE_REG, &val); 795 if (ret || !val) 796 dev_err(qproc->dev, "port failed halt\n"); 797 798 /* Clear halt request (port will remain halted until reset) */ 799 regmap_write(halt_map, offset + AXI_HALTREQ_REG, 0); 800 } 801 802 static int q6v5_mpss_init_image(struct q6v5 *qproc, const struct firmware *fw) 803 { 804 unsigned long dma_attrs = DMA_ATTR_FORCE_CONTIGUOUS; 805 dma_addr_t phys; 806 void *metadata; 807 int mdata_perm; 808 int xferop_ret; 809 size_t size; 810 void *ptr; 811 int ret; 812 813 metadata = qcom_mdt_read_metadata(fw, &size); 814 if (IS_ERR(metadata)) 815 return PTR_ERR(metadata); 816 817 ptr = dma_alloc_attrs(qproc->dev, size, &phys, GFP_KERNEL, dma_attrs); 818 if (!ptr) { 819 kfree(metadata); 820 dev_err(qproc->dev, "failed to allocate mdt buffer\n"); 821 return -ENOMEM; 822 } 823 824 memcpy(ptr, metadata, size); 825 826 /* Hypervisor mapping to access metadata by modem */ 827 mdata_perm = BIT(QCOM_SCM_VMID_HLOS); 828 ret = q6v5_xfer_mem_ownership(qproc, &mdata_perm, false, true, 829 phys, size); 830 if (ret) { 831 dev_err(qproc->dev, 832 "assigning Q6 access to metadata failed: %d\n", ret); 833 ret = -EAGAIN; 834 goto free_dma_attrs; 835 } 836 837 writel(phys, qproc->rmb_base + RMB_PMI_META_DATA_REG); 838 writel(RMB_CMD_META_DATA_READY, qproc->rmb_base + RMB_MBA_COMMAND_REG); 839 840 ret = q6v5_rmb_mba_wait(qproc, RMB_MBA_META_DATA_AUTH_SUCCESS, 1000); 841 if (ret == -ETIMEDOUT) 842 dev_err(qproc->dev, "MPSS header authentication timed out\n"); 843 else if (ret < 0) 844 dev_err(qproc->dev, "MPSS header authentication failed: %d\n", ret); 845 846 /* Metadata authentication done, remove modem access */ 847 xferop_ret = q6v5_xfer_mem_ownership(qproc, &mdata_perm, true, false, 848 phys, size); 849 if (xferop_ret) 850 dev_warn(qproc->dev, 851 "mdt buffer not reclaimed system may become unstable\n"); 852 853 free_dma_attrs: 854 dma_free_attrs(qproc->dev, size, ptr, phys, dma_attrs); 855 kfree(metadata); 856 857 return ret < 0 ? ret : 0; 858 } 859 860 static bool q6v5_phdr_valid(const struct elf32_phdr *phdr) 861 { 862 if (phdr->p_type != PT_LOAD) 863 return false; 864 865 if ((phdr->p_flags & QCOM_MDT_TYPE_MASK) == QCOM_MDT_TYPE_HASH) 866 return false; 867 868 if (!phdr->p_memsz) 869 return false; 870 871 return true; 872 } 873 874 static int q6v5_mba_load(struct q6v5 *qproc) 875 { 876 int ret; 877 int xfermemop_ret; 878 bool mba_load_err = false; 879 880 qcom_q6v5_prepare(&qproc->q6v5); 881 882 ret = q6v5_pds_enable(qproc, qproc->active_pds, qproc->active_pd_count); 883 if (ret < 0) { 884 dev_err(qproc->dev, "failed to enable active power domains\n"); 885 goto disable_irqs; 886 } 887 888 ret = q6v5_pds_enable(qproc, qproc->proxy_pds, qproc->proxy_pd_count); 889 if (ret < 0) { 890 dev_err(qproc->dev, "failed to enable proxy power domains\n"); 891 goto disable_active_pds; 892 } 893 894 ret = q6v5_regulator_enable(qproc, qproc->proxy_regs, 895 qproc->proxy_reg_count); 896 if (ret) { 897 dev_err(qproc->dev, "failed to enable proxy supplies\n"); 898 goto disable_proxy_pds; 899 } 900 901 ret = q6v5_clk_enable(qproc->dev, qproc->proxy_clks, 902 qproc->proxy_clk_count); 903 if (ret) { 904 dev_err(qproc->dev, "failed to enable proxy clocks\n"); 905 goto disable_proxy_reg; 906 } 907 908 ret = q6v5_regulator_enable(qproc, qproc->active_regs, 909 qproc->active_reg_count); 910 if (ret) { 911 dev_err(qproc->dev, "failed to enable supplies\n"); 912 goto disable_proxy_clk; 913 } 914 915 ret = q6v5_clk_enable(qproc->dev, qproc->reset_clks, 916 qproc->reset_clk_count); 917 if (ret) { 918 dev_err(qproc->dev, "failed to enable reset clocks\n"); 919 goto disable_vdd; 920 } 921 922 ret = q6v5_reset_deassert(qproc); 923 if (ret) { 924 dev_err(qproc->dev, "failed to deassert mss restart\n"); 925 goto disable_reset_clks; 926 } 927 928 ret = q6v5_clk_enable(qproc->dev, qproc->active_clks, 929 qproc->active_clk_count); 930 if (ret) { 931 dev_err(qproc->dev, "failed to enable clocks\n"); 932 goto assert_reset; 933 } 934 935 /* Assign MBA image access in DDR to q6 */ 936 ret = q6v5_xfer_mem_ownership(qproc, &qproc->mba_perm, false, true, 937 qproc->mba_phys, qproc->mba_size); 938 if (ret) { 939 dev_err(qproc->dev, 940 "assigning Q6 access to mba memory failed: %d\n", ret); 941 goto disable_active_clks; 942 } 943 944 writel(qproc->mba_phys, qproc->rmb_base + RMB_MBA_IMAGE_REG); 945 if (qproc->dp_size) { 946 writel(qproc->mba_phys + SZ_1M, qproc->rmb_base + RMB_PMI_CODE_START_REG); 947 writel(qproc->dp_size, qproc->rmb_base + RMB_PMI_CODE_LENGTH_REG); 948 } 949 950 ret = q6v5proc_reset(qproc); 951 if (ret) 952 goto reclaim_mba; 953 954 ret = q6v5_rmb_mba_wait(qproc, 0, 5000); 955 if (ret == -ETIMEDOUT) { 956 dev_err(qproc->dev, "MBA boot timed out\n"); 957 goto halt_axi_ports; 958 } else if (ret != RMB_MBA_XPU_UNLOCKED && 959 ret != RMB_MBA_XPU_UNLOCKED_SCRIBBLED) { 960 dev_err(qproc->dev, "MBA returned unexpected status %d\n", ret); 961 ret = -EINVAL; 962 goto halt_axi_ports; 963 } 964 965 qproc->dump_mba_loaded = true; 966 return 0; 967 968 halt_axi_ports: 969 q6v5proc_halt_axi_port(qproc, qproc->halt_map, qproc->halt_q6); 970 q6v5proc_halt_axi_port(qproc, qproc->halt_map, qproc->halt_modem); 971 q6v5proc_halt_axi_port(qproc, qproc->halt_map, qproc->halt_nc); 972 mba_load_err = true; 973 reclaim_mba: 974 xfermemop_ret = q6v5_xfer_mem_ownership(qproc, &qproc->mba_perm, true, 975 false, qproc->mba_phys, 976 qproc->mba_size); 977 if (xfermemop_ret) { 978 dev_err(qproc->dev, 979 "Failed to reclaim mba buffer, system may become unstable\n"); 980 } else if (mba_load_err) { 981 q6v5_dump_mba_logs(qproc); 982 } 983 984 disable_active_clks: 985 q6v5_clk_disable(qproc->dev, qproc->active_clks, 986 qproc->active_clk_count); 987 assert_reset: 988 q6v5_reset_assert(qproc); 989 disable_reset_clks: 990 q6v5_clk_disable(qproc->dev, qproc->reset_clks, 991 qproc->reset_clk_count); 992 disable_vdd: 993 q6v5_regulator_disable(qproc, qproc->active_regs, 994 qproc->active_reg_count); 995 disable_proxy_clk: 996 q6v5_clk_disable(qproc->dev, qproc->proxy_clks, 997 qproc->proxy_clk_count); 998 disable_proxy_reg: 999 q6v5_regulator_disable(qproc, qproc->proxy_regs, 1000 qproc->proxy_reg_count); 1001 disable_proxy_pds: 1002 q6v5_pds_disable(qproc, qproc->proxy_pds, qproc->proxy_pd_count); 1003 disable_active_pds: 1004 q6v5_pds_disable(qproc, qproc->active_pds, qproc->active_pd_count); 1005 disable_irqs: 1006 qcom_q6v5_unprepare(&qproc->q6v5); 1007 1008 return ret; 1009 } 1010 1011 static void q6v5_mba_reclaim(struct q6v5 *qproc) 1012 { 1013 int ret; 1014 u32 val; 1015 1016 qproc->dump_mba_loaded = false; 1017 qproc->dp_size = 0; 1018 1019 q6v5proc_halt_axi_port(qproc, qproc->halt_map, qproc->halt_q6); 1020 q6v5proc_halt_axi_port(qproc, qproc->halt_map, qproc->halt_modem); 1021 q6v5proc_halt_axi_port(qproc, qproc->halt_map, qproc->halt_nc); 1022 if (qproc->version == MSS_MSM8996) { 1023 /* 1024 * To avoid high MX current during LPASS/MSS restart. 1025 */ 1026 val = readl(qproc->reg_base + QDSP6SS_PWR_CTL_REG); 1027 val |= Q6SS_CLAMP_IO | QDSP6v56_CLAMP_WL | 1028 QDSP6v56_CLAMP_QMC_MEM; 1029 writel(val, qproc->reg_base + QDSP6SS_PWR_CTL_REG); 1030 } 1031 1032 q6v5_reset_assert(qproc); 1033 1034 q6v5_clk_disable(qproc->dev, qproc->reset_clks, 1035 qproc->reset_clk_count); 1036 q6v5_clk_disable(qproc->dev, qproc->active_clks, 1037 qproc->active_clk_count); 1038 q6v5_regulator_disable(qproc, qproc->active_regs, 1039 qproc->active_reg_count); 1040 q6v5_pds_disable(qproc, qproc->active_pds, qproc->active_pd_count); 1041 1042 /* In case of failure or coredump scenario where reclaiming MBA memory 1043 * could not happen reclaim it here. 1044 */ 1045 ret = q6v5_xfer_mem_ownership(qproc, &qproc->mba_perm, true, false, 1046 qproc->mba_phys, 1047 qproc->mba_size); 1048 WARN_ON(ret); 1049 1050 ret = qcom_q6v5_unprepare(&qproc->q6v5); 1051 if (ret) { 1052 q6v5_pds_disable(qproc, qproc->proxy_pds, 1053 qproc->proxy_pd_count); 1054 q6v5_clk_disable(qproc->dev, qproc->proxy_clks, 1055 qproc->proxy_clk_count); 1056 q6v5_regulator_disable(qproc, qproc->proxy_regs, 1057 qproc->proxy_reg_count); 1058 } 1059 } 1060 1061 static int q6v5_reload_mba(struct rproc *rproc) 1062 { 1063 struct q6v5 *qproc = rproc->priv; 1064 const struct firmware *fw; 1065 int ret; 1066 1067 ret = request_firmware(&fw, rproc->firmware, qproc->dev); 1068 if (ret < 0) 1069 return ret; 1070 1071 q6v5_load(rproc, fw); 1072 ret = q6v5_mba_load(qproc); 1073 release_firmware(fw); 1074 1075 return ret; 1076 } 1077 1078 static int q6v5_mpss_load(struct q6v5 *qproc) 1079 { 1080 const struct elf32_phdr *phdrs; 1081 const struct elf32_phdr *phdr; 1082 const struct firmware *seg_fw; 1083 const struct firmware *fw; 1084 struct elf32_hdr *ehdr; 1085 phys_addr_t mpss_reloc; 1086 phys_addr_t boot_addr; 1087 phys_addr_t min_addr = PHYS_ADDR_MAX; 1088 phys_addr_t max_addr = 0; 1089 u32 code_length; 1090 bool relocate = false; 1091 char *fw_name; 1092 size_t fw_name_len; 1093 ssize_t offset; 1094 size_t size = 0; 1095 void *ptr; 1096 int ret; 1097 int i; 1098 1099 fw_name_len = strlen(qproc->hexagon_mdt_image); 1100 if (fw_name_len <= 4) 1101 return -EINVAL; 1102 1103 fw_name = kstrdup(qproc->hexagon_mdt_image, GFP_KERNEL); 1104 if (!fw_name) 1105 return -ENOMEM; 1106 1107 ret = request_firmware(&fw, fw_name, qproc->dev); 1108 if (ret < 0) { 1109 dev_err(qproc->dev, "unable to load %s\n", fw_name); 1110 goto out; 1111 } 1112 1113 /* Initialize the RMB validator */ 1114 writel(0, qproc->rmb_base + RMB_PMI_CODE_LENGTH_REG); 1115 1116 ret = q6v5_mpss_init_image(qproc, fw); 1117 if (ret) 1118 goto release_firmware; 1119 1120 ehdr = (struct elf32_hdr *)fw->data; 1121 phdrs = (struct elf32_phdr *)(ehdr + 1); 1122 1123 for (i = 0; i < ehdr->e_phnum; i++) { 1124 phdr = &phdrs[i]; 1125 1126 if (!q6v5_phdr_valid(phdr)) 1127 continue; 1128 1129 if (phdr->p_flags & QCOM_MDT_RELOCATABLE) 1130 relocate = true; 1131 1132 if (phdr->p_paddr < min_addr) 1133 min_addr = phdr->p_paddr; 1134 1135 if (phdr->p_paddr + phdr->p_memsz > max_addr) 1136 max_addr = ALIGN(phdr->p_paddr + phdr->p_memsz, SZ_4K); 1137 } 1138 1139 /** 1140 * In case of a modem subsystem restart on secure devices, the modem 1141 * memory can be reclaimed only after MBA is loaded. For modem cold 1142 * boot this will be a nop 1143 */ 1144 q6v5_xfer_mem_ownership(qproc, &qproc->mpss_perm, true, false, 1145 qproc->mpss_phys, qproc->mpss_size); 1146 1147 /* Share ownership between Linux and MSS, during segment loading */ 1148 ret = q6v5_xfer_mem_ownership(qproc, &qproc->mpss_perm, true, true, 1149 qproc->mpss_phys, qproc->mpss_size); 1150 if (ret) { 1151 dev_err(qproc->dev, 1152 "assigning Q6 access to mpss memory failed: %d\n", ret); 1153 ret = -EAGAIN; 1154 goto release_firmware; 1155 } 1156 1157 mpss_reloc = relocate ? min_addr : qproc->mpss_phys; 1158 qproc->mpss_reloc = mpss_reloc; 1159 /* Load firmware segments */ 1160 for (i = 0; i < ehdr->e_phnum; i++) { 1161 phdr = &phdrs[i]; 1162 1163 if (!q6v5_phdr_valid(phdr)) 1164 continue; 1165 1166 offset = phdr->p_paddr - mpss_reloc; 1167 if (offset < 0 || offset + phdr->p_memsz > qproc->mpss_size) { 1168 dev_err(qproc->dev, "segment outside memory range\n"); 1169 ret = -EINVAL; 1170 goto release_firmware; 1171 } 1172 1173 ptr = ioremap_wc(qproc->mpss_phys + offset, phdr->p_memsz); 1174 if (!ptr) { 1175 dev_err(qproc->dev, 1176 "unable to map memory region: %pa+%zx-%x\n", 1177 &qproc->mpss_phys, offset, phdr->p_memsz); 1178 goto release_firmware; 1179 } 1180 1181 if (phdr->p_filesz && phdr->p_offset < fw->size) { 1182 /* Firmware is large enough to be non-split */ 1183 if (phdr->p_offset + phdr->p_filesz > fw->size) { 1184 dev_err(qproc->dev, 1185 "failed to load segment %d from truncated file %s\n", 1186 i, fw_name); 1187 ret = -EINVAL; 1188 iounmap(ptr); 1189 goto release_firmware; 1190 } 1191 1192 memcpy(ptr, fw->data + phdr->p_offset, phdr->p_filesz); 1193 } else if (phdr->p_filesz) { 1194 /* Replace "xxx.xxx" with "xxx.bxx" */ 1195 sprintf(fw_name + fw_name_len - 3, "b%02d", i); 1196 ret = request_firmware_into_buf(&seg_fw, fw_name, qproc->dev, 1197 ptr, phdr->p_filesz); 1198 if (ret) { 1199 dev_err(qproc->dev, "failed to load %s\n", fw_name); 1200 iounmap(ptr); 1201 goto release_firmware; 1202 } 1203 1204 release_firmware(seg_fw); 1205 } 1206 1207 if (phdr->p_memsz > phdr->p_filesz) { 1208 memset(ptr + phdr->p_filesz, 0, 1209 phdr->p_memsz - phdr->p_filesz); 1210 } 1211 iounmap(ptr); 1212 size += phdr->p_memsz; 1213 1214 code_length = readl(qproc->rmb_base + RMB_PMI_CODE_LENGTH_REG); 1215 if (!code_length) { 1216 boot_addr = relocate ? qproc->mpss_phys : min_addr; 1217 writel(boot_addr, qproc->rmb_base + RMB_PMI_CODE_START_REG); 1218 writel(RMB_CMD_LOAD_READY, qproc->rmb_base + RMB_MBA_COMMAND_REG); 1219 } 1220 writel(size, qproc->rmb_base + RMB_PMI_CODE_LENGTH_REG); 1221 1222 ret = readl(qproc->rmb_base + RMB_MBA_STATUS_REG); 1223 if (ret < 0) { 1224 dev_err(qproc->dev, "MPSS authentication failed: %d\n", 1225 ret); 1226 goto release_firmware; 1227 } 1228 } 1229 1230 /* Transfer ownership of modem ddr region to q6 */ 1231 ret = q6v5_xfer_mem_ownership(qproc, &qproc->mpss_perm, false, true, 1232 qproc->mpss_phys, qproc->mpss_size); 1233 if (ret) { 1234 dev_err(qproc->dev, 1235 "assigning Q6 access to mpss memory failed: %d\n", ret); 1236 ret = -EAGAIN; 1237 goto release_firmware; 1238 } 1239 1240 ret = q6v5_rmb_mba_wait(qproc, RMB_MBA_AUTH_COMPLETE, 10000); 1241 if (ret == -ETIMEDOUT) 1242 dev_err(qproc->dev, "MPSS authentication timed out\n"); 1243 else if (ret < 0) 1244 dev_err(qproc->dev, "MPSS authentication failed: %d\n", ret); 1245 1246 qcom_pil_info_store("modem", qproc->mpss_phys, qproc->mpss_size); 1247 1248 release_firmware: 1249 release_firmware(fw); 1250 out: 1251 kfree(fw_name); 1252 1253 return ret < 0 ? ret : 0; 1254 } 1255 1256 static void qcom_q6v5_dump_segment(struct rproc *rproc, 1257 struct rproc_dump_segment *segment, 1258 void *dest, size_t cp_offset, size_t size) 1259 { 1260 int ret = 0; 1261 struct q6v5 *qproc = rproc->priv; 1262 int offset = segment->da - qproc->mpss_reloc; 1263 void *ptr = NULL; 1264 1265 /* Unlock mba before copying segments */ 1266 if (!qproc->dump_mba_loaded) { 1267 ret = q6v5_reload_mba(rproc); 1268 if (!ret) { 1269 /* Reset ownership back to Linux to copy segments */ 1270 ret = q6v5_xfer_mem_ownership(qproc, &qproc->mpss_perm, 1271 true, false, 1272 qproc->mpss_phys, 1273 qproc->mpss_size); 1274 } 1275 } 1276 1277 if (!ret) 1278 ptr = ioremap_wc(qproc->mpss_phys + offset + cp_offset, size); 1279 1280 if (ptr) { 1281 memcpy(dest, ptr, size); 1282 iounmap(ptr); 1283 } else { 1284 memset(dest, 0xff, size); 1285 } 1286 1287 qproc->current_dump_size += size; 1288 1289 /* Reclaim mba after copying segments */ 1290 if (qproc->current_dump_size == qproc->total_dump_size) { 1291 if (qproc->dump_mba_loaded) { 1292 /* Try to reset ownership back to Q6 */ 1293 q6v5_xfer_mem_ownership(qproc, &qproc->mpss_perm, 1294 false, true, 1295 qproc->mpss_phys, 1296 qproc->mpss_size); 1297 q6v5_mba_reclaim(qproc); 1298 } 1299 } 1300 } 1301 1302 static int q6v5_start(struct rproc *rproc) 1303 { 1304 struct q6v5 *qproc = (struct q6v5 *)rproc->priv; 1305 int xfermemop_ret; 1306 int ret; 1307 1308 ret = q6v5_mba_load(qproc); 1309 if (ret) 1310 return ret; 1311 1312 dev_info(qproc->dev, "MBA booted with%s debug policy, loading mpss\n", 1313 qproc->dp_size ? "" : "out"); 1314 1315 ret = q6v5_mpss_load(qproc); 1316 if (ret) 1317 goto reclaim_mpss; 1318 1319 ret = qcom_q6v5_wait_for_start(&qproc->q6v5, msecs_to_jiffies(5000)); 1320 if (ret == -ETIMEDOUT) { 1321 dev_err(qproc->dev, "start timed out\n"); 1322 goto reclaim_mpss; 1323 } 1324 1325 xfermemop_ret = q6v5_xfer_mem_ownership(qproc, &qproc->mba_perm, true, 1326 false, qproc->mba_phys, 1327 qproc->mba_size); 1328 if (xfermemop_ret) 1329 dev_err(qproc->dev, 1330 "Failed to reclaim mba buffer system may become unstable\n"); 1331 1332 /* Reset Dump Segment Mask */ 1333 qproc->current_dump_size = 0; 1334 1335 return 0; 1336 1337 reclaim_mpss: 1338 q6v5_mba_reclaim(qproc); 1339 q6v5_dump_mba_logs(qproc); 1340 1341 return ret; 1342 } 1343 1344 static int q6v5_stop(struct rproc *rproc) 1345 { 1346 struct q6v5 *qproc = (struct q6v5 *)rproc->priv; 1347 int ret; 1348 1349 ret = qcom_q6v5_request_stop(&qproc->q6v5); 1350 if (ret == -ETIMEDOUT) 1351 dev_err(qproc->dev, "timed out on wait\n"); 1352 1353 q6v5_mba_reclaim(qproc); 1354 1355 return 0; 1356 } 1357 1358 static int qcom_q6v5_register_dump_segments(struct rproc *rproc, 1359 const struct firmware *mba_fw) 1360 { 1361 const struct firmware *fw; 1362 const struct elf32_phdr *phdrs; 1363 const struct elf32_phdr *phdr; 1364 const struct elf32_hdr *ehdr; 1365 struct q6v5 *qproc = rproc->priv; 1366 unsigned long i; 1367 int ret; 1368 1369 ret = request_firmware(&fw, qproc->hexagon_mdt_image, qproc->dev); 1370 if (ret < 0) { 1371 dev_err(qproc->dev, "unable to load %s\n", 1372 qproc->hexagon_mdt_image); 1373 return ret; 1374 } 1375 1376 rproc_coredump_set_elf_info(rproc, ELFCLASS32, EM_NONE); 1377 1378 ehdr = (struct elf32_hdr *)fw->data; 1379 phdrs = (struct elf32_phdr *)(ehdr + 1); 1380 qproc->total_dump_size = 0; 1381 1382 for (i = 0; i < ehdr->e_phnum; i++) { 1383 phdr = &phdrs[i]; 1384 1385 if (!q6v5_phdr_valid(phdr)) 1386 continue; 1387 1388 ret = rproc_coredump_add_custom_segment(rproc, phdr->p_paddr, 1389 phdr->p_memsz, 1390 qcom_q6v5_dump_segment, 1391 NULL); 1392 if (ret) 1393 break; 1394 1395 qproc->total_dump_size += phdr->p_memsz; 1396 } 1397 1398 release_firmware(fw); 1399 return ret; 1400 } 1401 1402 static const struct rproc_ops q6v5_ops = { 1403 .start = q6v5_start, 1404 .stop = q6v5_stop, 1405 .parse_fw = qcom_q6v5_register_dump_segments, 1406 .load = q6v5_load, 1407 }; 1408 1409 static void qcom_msa_handover(struct qcom_q6v5 *q6v5) 1410 { 1411 struct q6v5 *qproc = container_of(q6v5, struct q6v5, q6v5); 1412 1413 q6v5_clk_disable(qproc->dev, qproc->proxy_clks, 1414 qproc->proxy_clk_count); 1415 q6v5_regulator_disable(qproc, qproc->proxy_regs, 1416 qproc->proxy_reg_count); 1417 q6v5_pds_disable(qproc, qproc->proxy_pds, qproc->proxy_pd_count); 1418 } 1419 1420 static int q6v5_init_mem(struct q6v5 *qproc, struct platform_device *pdev) 1421 { 1422 struct of_phandle_args args; 1423 struct resource *res; 1424 int ret; 1425 1426 res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "qdsp6"); 1427 qproc->reg_base = devm_ioremap_resource(&pdev->dev, res); 1428 if (IS_ERR(qproc->reg_base)) 1429 return PTR_ERR(qproc->reg_base); 1430 1431 res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "rmb"); 1432 qproc->rmb_base = devm_ioremap_resource(&pdev->dev, res); 1433 if (IS_ERR(qproc->rmb_base)) 1434 return PTR_ERR(qproc->rmb_base); 1435 1436 ret = of_parse_phandle_with_fixed_args(pdev->dev.of_node, 1437 "qcom,halt-regs", 3, 0, &args); 1438 if (ret < 0) { 1439 dev_err(&pdev->dev, "failed to parse qcom,halt-regs\n"); 1440 return -EINVAL; 1441 } 1442 1443 qproc->halt_map = syscon_node_to_regmap(args.np); 1444 of_node_put(args.np); 1445 if (IS_ERR(qproc->halt_map)) 1446 return PTR_ERR(qproc->halt_map); 1447 1448 qproc->halt_q6 = args.args[0]; 1449 qproc->halt_modem = args.args[1]; 1450 qproc->halt_nc = args.args[2]; 1451 1452 if (qproc->has_spare_reg) { 1453 ret = of_parse_phandle_with_fixed_args(pdev->dev.of_node, 1454 "qcom,spare-regs", 1455 1, 0, &args); 1456 if (ret < 0) { 1457 dev_err(&pdev->dev, "failed to parse spare-regs\n"); 1458 return -EINVAL; 1459 } 1460 1461 qproc->conn_map = syscon_node_to_regmap(args.np); 1462 of_node_put(args.np); 1463 if (IS_ERR(qproc->conn_map)) 1464 return PTR_ERR(qproc->conn_map); 1465 1466 qproc->conn_box = args.args[0]; 1467 } 1468 1469 return 0; 1470 } 1471 1472 static int q6v5_init_clocks(struct device *dev, struct clk **clks, 1473 char **clk_names) 1474 { 1475 int i; 1476 1477 if (!clk_names) 1478 return 0; 1479 1480 for (i = 0; clk_names[i]; i++) { 1481 clks[i] = devm_clk_get(dev, clk_names[i]); 1482 if (IS_ERR(clks[i])) { 1483 int rc = PTR_ERR(clks[i]); 1484 1485 if (rc != -EPROBE_DEFER) 1486 dev_err(dev, "Failed to get %s clock\n", 1487 clk_names[i]); 1488 return rc; 1489 } 1490 } 1491 1492 return i; 1493 } 1494 1495 static int q6v5_pds_attach(struct device *dev, struct device **devs, 1496 char **pd_names) 1497 { 1498 size_t num_pds = 0; 1499 int ret; 1500 int i; 1501 1502 if (!pd_names) 1503 return 0; 1504 1505 while (pd_names[num_pds]) 1506 num_pds++; 1507 1508 for (i = 0; i < num_pds; i++) { 1509 devs[i] = dev_pm_domain_attach_by_name(dev, pd_names[i]); 1510 if (IS_ERR_OR_NULL(devs[i])) { 1511 ret = PTR_ERR(devs[i]) ? : -ENODATA; 1512 goto unroll_attach; 1513 } 1514 } 1515 1516 return num_pds; 1517 1518 unroll_attach: 1519 for (i--; i >= 0; i--) 1520 dev_pm_domain_detach(devs[i], false); 1521 1522 return ret; 1523 } 1524 1525 static void q6v5_pds_detach(struct q6v5 *qproc, struct device **pds, 1526 size_t pd_count) 1527 { 1528 int i; 1529 1530 for (i = 0; i < pd_count; i++) 1531 dev_pm_domain_detach(pds[i], false); 1532 } 1533 1534 static int q6v5_init_reset(struct q6v5 *qproc) 1535 { 1536 qproc->mss_restart = devm_reset_control_get_exclusive(qproc->dev, 1537 "mss_restart"); 1538 if (IS_ERR(qproc->mss_restart)) { 1539 dev_err(qproc->dev, "failed to acquire mss restart\n"); 1540 return PTR_ERR(qproc->mss_restart); 1541 } 1542 1543 if (qproc->has_alt_reset || qproc->has_spare_reg) { 1544 qproc->pdc_reset = devm_reset_control_get_exclusive(qproc->dev, 1545 "pdc_reset"); 1546 if (IS_ERR(qproc->pdc_reset)) { 1547 dev_err(qproc->dev, "failed to acquire pdc reset\n"); 1548 return PTR_ERR(qproc->pdc_reset); 1549 } 1550 } 1551 1552 return 0; 1553 } 1554 1555 static int q6v5_alloc_memory_region(struct q6v5 *qproc) 1556 { 1557 struct device_node *child; 1558 struct device_node *node; 1559 struct resource r; 1560 int ret; 1561 1562 /* 1563 * In the absence of mba/mpss sub-child, extract the mba and mpss 1564 * reserved memory regions from device's memory-region property. 1565 */ 1566 child = of_get_child_by_name(qproc->dev->of_node, "mba"); 1567 if (!child) 1568 node = of_parse_phandle(qproc->dev->of_node, 1569 "memory-region", 0); 1570 else 1571 node = of_parse_phandle(child, "memory-region", 0); 1572 1573 ret = of_address_to_resource(node, 0, &r); 1574 if (ret) { 1575 dev_err(qproc->dev, "unable to resolve mba region\n"); 1576 return ret; 1577 } 1578 of_node_put(node); 1579 1580 qproc->mba_phys = r.start; 1581 qproc->mba_size = resource_size(&r); 1582 qproc->mba_region = devm_ioremap_wc(qproc->dev, qproc->mba_phys, qproc->mba_size); 1583 if (!qproc->mba_region) { 1584 dev_err(qproc->dev, "unable to map memory region: %pa+%zx\n", 1585 &r.start, qproc->mba_size); 1586 return -EBUSY; 1587 } 1588 1589 if (!child) { 1590 node = of_parse_phandle(qproc->dev->of_node, 1591 "memory-region", 1); 1592 } else { 1593 child = of_get_child_by_name(qproc->dev->of_node, "mpss"); 1594 node = of_parse_phandle(child, "memory-region", 0); 1595 } 1596 1597 ret = of_address_to_resource(node, 0, &r); 1598 if (ret) { 1599 dev_err(qproc->dev, "unable to resolve mpss region\n"); 1600 return ret; 1601 } 1602 of_node_put(node); 1603 1604 qproc->mpss_phys = qproc->mpss_reloc = r.start; 1605 qproc->mpss_size = resource_size(&r); 1606 1607 return 0; 1608 } 1609 1610 #if IS_ENABLED(CONFIG_QCOM_Q6V5_IPA_NOTIFY) 1611 1612 /* Register IPA notification function */ 1613 int qcom_register_ipa_notify(struct rproc *rproc, qcom_ipa_notify_t notify, 1614 void *data) 1615 { 1616 struct qcom_rproc_ipa_notify *ipa_notify; 1617 struct q6v5 *qproc = rproc->priv; 1618 1619 if (!notify) 1620 return -EINVAL; 1621 1622 ipa_notify = &qproc->ipa_notify_subdev; 1623 if (ipa_notify->notify) 1624 return -EBUSY; 1625 1626 ipa_notify->notify = notify; 1627 ipa_notify->data = data; 1628 1629 return 0; 1630 } 1631 EXPORT_SYMBOL_GPL(qcom_register_ipa_notify); 1632 1633 /* Deregister IPA notification function */ 1634 void qcom_deregister_ipa_notify(struct rproc *rproc) 1635 { 1636 struct q6v5 *qproc = rproc->priv; 1637 1638 qproc->ipa_notify_subdev.notify = NULL; 1639 } 1640 EXPORT_SYMBOL_GPL(qcom_deregister_ipa_notify); 1641 #endif /* !IS_ENABLED(CONFIG_QCOM_Q6V5_IPA_NOTIFY) */ 1642 1643 static int q6v5_probe(struct platform_device *pdev) 1644 { 1645 const struct rproc_hexagon_res *desc; 1646 struct q6v5 *qproc; 1647 struct rproc *rproc; 1648 const char *mba_image; 1649 int ret; 1650 1651 desc = of_device_get_match_data(&pdev->dev); 1652 if (!desc) 1653 return -EINVAL; 1654 1655 if (desc->need_mem_protection && !qcom_scm_is_available()) 1656 return -EPROBE_DEFER; 1657 1658 mba_image = desc->hexagon_mba_image; 1659 ret = of_property_read_string_index(pdev->dev.of_node, "firmware-name", 1660 0, &mba_image); 1661 if (ret < 0 && ret != -EINVAL) 1662 return ret; 1663 1664 rproc = rproc_alloc(&pdev->dev, pdev->name, &q6v5_ops, 1665 mba_image, sizeof(*qproc)); 1666 if (!rproc) { 1667 dev_err(&pdev->dev, "failed to allocate rproc\n"); 1668 return -ENOMEM; 1669 } 1670 1671 rproc->auto_boot = false; 1672 rproc_coredump_set_elf_info(rproc, ELFCLASS32, EM_NONE); 1673 1674 qproc = (struct q6v5 *)rproc->priv; 1675 qproc->dev = &pdev->dev; 1676 qproc->rproc = rproc; 1677 qproc->hexagon_mdt_image = "modem.mdt"; 1678 ret = of_property_read_string_index(pdev->dev.of_node, "firmware-name", 1679 1, &qproc->hexagon_mdt_image); 1680 if (ret < 0 && ret != -EINVAL) 1681 goto free_rproc; 1682 1683 platform_set_drvdata(pdev, qproc); 1684 1685 qproc->has_spare_reg = desc->has_spare_reg; 1686 ret = q6v5_init_mem(qproc, pdev); 1687 if (ret) 1688 goto free_rproc; 1689 1690 ret = q6v5_alloc_memory_region(qproc); 1691 if (ret) 1692 goto free_rproc; 1693 1694 ret = q6v5_init_clocks(&pdev->dev, qproc->proxy_clks, 1695 desc->proxy_clk_names); 1696 if (ret < 0) { 1697 dev_err(&pdev->dev, "Failed to get proxy clocks.\n"); 1698 goto free_rproc; 1699 } 1700 qproc->proxy_clk_count = ret; 1701 1702 ret = q6v5_init_clocks(&pdev->dev, qproc->reset_clks, 1703 desc->reset_clk_names); 1704 if (ret < 0) { 1705 dev_err(&pdev->dev, "Failed to get reset clocks.\n"); 1706 goto free_rproc; 1707 } 1708 qproc->reset_clk_count = ret; 1709 1710 ret = q6v5_init_clocks(&pdev->dev, qproc->active_clks, 1711 desc->active_clk_names); 1712 if (ret < 0) { 1713 dev_err(&pdev->dev, "Failed to get active clocks.\n"); 1714 goto free_rproc; 1715 } 1716 qproc->active_clk_count = ret; 1717 1718 ret = q6v5_regulator_init(&pdev->dev, qproc->proxy_regs, 1719 desc->proxy_supply); 1720 if (ret < 0) { 1721 dev_err(&pdev->dev, "Failed to get proxy regulators.\n"); 1722 goto free_rproc; 1723 } 1724 qproc->proxy_reg_count = ret; 1725 1726 ret = q6v5_regulator_init(&pdev->dev, qproc->active_regs, 1727 desc->active_supply); 1728 if (ret < 0) { 1729 dev_err(&pdev->dev, "Failed to get active regulators.\n"); 1730 goto free_rproc; 1731 } 1732 qproc->active_reg_count = ret; 1733 1734 ret = q6v5_pds_attach(&pdev->dev, qproc->active_pds, 1735 desc->active_pd_names); 1736 if (ret < 0) { 1737 dev_err(&pdev->dev, "Failed to attach active power domains\n"); 1738 goto free_rproc; 1739 } 1740 qproc->active_pd_count = ret; 1741 1742 ret = q6v5_pds_attach(&pdev->dev, qproc->proxy_pds, 1743 desc->proxy_pd_names); 1744 if (ret < 0) { 1745 dev_err(&pdev->dev, "Failed to init power domains\n"); 1746 goto detach_active_pds; 1747 } 1748 qproc->proxy_pd_count = ret; 1749 1750 qproc->has_alt_reset = desc->has_alt_reset; 1751 ret = q6v5_init_reset(qproc); 1752 if (ret) 1753 goto detach_proxy_pds; 1754 1755 qproc->version = desc->version; 1756 qproc->need_mem_protection = desc->need_mem_protection; 1757 qproc->has_mba_logs = desc->has_mba_logs; 1758 1759 ret = qcom_q6v5_init(&qproc->q6v5, pdev, rproc, MPSS_CRASH_REASON_SMEM, 1760 qcom_msa_handover); 1761 if (ret) 1762 goto detach_proxy_pds; 1763 1764 qproc->mpss_perm = BIT(QCOM_SCM_VMID_HLOS); 1765 qproc->mba_perm = BIT(QCOM_SCM_VMID_HLOS); 1766 qcom_add_glink_subdev(rproc, &qproc->glink_subdev, "mpss"); 1767 qcom_add_smd_subdev(rproc, &qproc->smd_subdev); 1768 qcom_add_ssr_subdev(rproc, &qproc->ssr_subdev, "mpss"); 1769 qcom_add_ipa_notify_subdev(rproc, &qproc->ipa_notify_subdev); 1770 qproc->sysmon = qcom_add_sysmon_subdev(rproc, "modem", 0x12); 1771 if (IS_ERR(qproc->sysmon)) { 1772 ret = PTR_ERR(qproc->sysmon); 1773 goto remove_subdevs; 1774 } 1775 1776 ret = rproc_add(rproc); 1777 if (ret) 1778 goto remove_sysmon_subdev; 1779 1780 return 0; 1781 1782 remove_sysmon_subdev: 1783 qcom_remove_sysmon_subdev(qproc->sysmon); 1784 remove_subdevs: 1785 qcom_remove_ipa_notify_subdev(qproc->rproc, &qproc->ipa_notify_subdev); 1786 qcom_remove_ssr_subdev(rproc, &qproc->ssr_subdev); 1787 qcom_remove_smd_subdev(rproc, &qproc->smd_subdev); 1788 qcom_remove_glink_subdev(rproc, &qproc->glink_subdev); 1789 detach_proxy_pds: 1790 q6v5_pds_detach(qproc, qproc->proxy_pds, qproc->proxy_pd_count); 1791 detach_active_pds: 1792 q6v5_pds_detach(qproc, qproc->active_pds, qproc->active_pd_count); 1793 free_rproc: 1794 rproc_free(rproc); 1795 1796 return ret; 1797 } 1798 1799 static int q6v5_remove(struct platform_device *pdev) 1800 { 1801 struct q6v5 *qproc = platform_get_drvdata(pdev); 1802 struct rproc *rproc = qproc->rproc; 1803 1804 rproc_del(rproc); 1805 1806 qcom_remove_sysmon_subdev(qproc->sysmon); 1807 qcom_remove_ipa_notify_subdev(rproc, &qproc->ipa_notify_subdev); 1808 qcom_remove_ssr_subdev(rproc, &qproc->ssr_subdev); 1809 qcom_remove_smd_subdev(rproc, &qproc->smd_subdev); 1810 qcom_remove_glink_subdev(rproc, &qproc->glink_subdev); 1811 1812 q6v5_pds_detach(qproc, qproc->proxy_pds, qproc->proxy_pd_count); 1813 q6v5_pds_detach(qproc, qproc->active_pds, qproc->active_pd_count); 1814 1815 rproc_free(rproc); 1816 1817 return 0; 1818 } 1819 1820 static const struct rproc_hexagon_res sc7180_mss = { 1821 .hexagon_mba_image = "mba.mbn", 1822 .proxy_clk_names = (char*[]){ 1823 "xo", 1824 NULL 1825 }, 1826 .reset_clk_names = (char*[]){ 1827 "iface", 1828 "bus", 1829 "snoc_axi", 1830 NULL 1831 }, 1832 .active_clk_names = (char*[]){ 1833 "mnoc_axi", 1834 "nav", 1835 NULL 1836 }, 1837 .active_pd_names = (char*[]){ 1838 "load_state", 1839 NULL 1840 }, 1841 .proxy_pd_names = (char*[]){ 1842 "cx", 1843 "mx", 1844 "mss", 1845 NULL 1846 }, 1847 .need_mem_protection = true, 1848 .has_alt_reset = false, 1849 .has_mba_logs = true, 1850 .has_spare_reg = true, 1851 .version = MSS_SC7180, 1852 }; 1853 1854 static const struct rproc_hexagon_res sdm845_mss = { 1855 .hexagon_mba_image = "mba.mbn", 1856 .proxy_clk_names = (char*[]){ 1857 "xo", 1858 "prng", 1859 NULL 1860 }, 1861 .reset_clk_names = (char*[]){ 1862 "iface", 1863 "snoc_axi", 1864 NULL 1865 }, 1866 .active_clk_names = (char*[]){ 1867 "bus", 1868 "mem", 1869 "gpll0_mss", 1870 "mnoc_axi", 1871 NULL 1872 }, 1873 .active_pd_names = (char*[]){ 1874 "load_state", 1875 NULL 1876 }, 1877 .proxy_pd_names = (char*[]){ 1878 "cx", 1879 "mx", 1880 "mss", 1881 NULL 1882 }, 1883 .need_mem_protection = true, 1884 .has_alt_reset = true, 1885 .has_mba_logs = false, 1886 .has_spare_reg = false, 1887 .version = MSS_SDM845, 1888 }; 1889 1890 static const struct rproc_hexagon_res msm8998_mss = { 1891 .hexagon_mba_image = "mba.mbn", 1892 .proxy_clk_names = (char*[]){ 1893 "xo", 1894 "qdss", 1895 "mem", 1896 NULL 1897 }, 1898 .active_clk_names = (char*[]){ 1899 "iface", 1900 "bus", 1901 "gpll0_mss", 1902 "mnoc_axi", 1903 "snoc_axi", 1904 NULL 1905 }, 1906 .proxy_pd_names = (char*[]){ 1907 "cx", 1908 "mx", 1909 NULL 1910 }, 1911 .need_mem_protection = true, 1912 .has_alt_reset = false, 1913 .has_mba_logs = false, 1914 .has_spare_reg = false, 1915 .version = MSS_MSM8998, 1916 }; 1917 1918 static const struct rproc_hexagon_res msm8996_mss = { 1919 .hexagon_mba_image = "mba.mbn", 1920 .proxy_supply = (struct qcom_mss_reg_res[]) { 1921 { 1922 .supply = "pll", 1923 .uA = 100000, 1924 }, 1925 {} 1926 }, 1927 .proxy_clk_names = (char*[]){ 1928 "xo", 1929 "pnoc", 1930 "qdss", 1931 NULL 1932 }, 1933 .active_clk_names = (char*[]){ 1934 "iface", 1935 "bus", 1936 "mem", 1937 "gpll0_mss", 1938 "snoc_axi", 1939 "mnoc_axi", 1940 NULL 1941 }, 1942 .need_mem_protection = true, 1943 .has_alt_reset = false, 1944 .has_mba_logs = false, 1945 .has_spare_reg = false, 1946 .version = MSS_MSM8996, 1947 }; 1948 1949 static const struct rproc_hexagon_res msm8916_mss = { 1950 .hexagon_mba_image = "mba.mbn", 1951 .proxy_supply = (struct qcom_mss_reg_res[]) { 1952 { 1953 .supply = "mx", 1954 .uV = 1050000, 1955 }, 1956 { 1957 .supply = "cx", 1958 .uA = 100000, 1959 }, 1960 { 1961 .supply = "pll", 1962 .uA = 100000, 1963 }, 1964 {} 1965 }, 1966 .proxy_clk_names = (char*[]){ 1967 "xo", 1968 NULL 1969 }, 1970 .active_clk_names = (char*[]){ 1971 "iface", 1972 "bus", 1973 "mem", 1974 NULL 1975 }, 1976 .need_mem_protection = false, 1977 .has_alt_reset = false, 1978 .has_mba_logs = false, 1979 .has_spare_reg = false, 1980 .version = MSS_MSM8916, 1981 }; 1982 1983 static const struct rproc_hexagon_res msm8974_mss = { 1984 .hexagon_mba_image = "mba.b00", 1985 .proxy_supply = (struct qcom_mss_reg_res[]) { 1986 { 1987 .supply = "mx", 1988 .uV = 1050000, 1989 }, 1990 { 1991 .supply = "cx", 1992 .uA = 100000, 1993 }, 1994 { 1995 .supply = "pll", 1996 .uA = 100000, 1997 }, 1998 {} 1999 }, 2000 .active_supply = (struct qcom_mss_reg_res[]) { 2001 { 2002 .supply = "mss", 2003 .uV = 1050000, 2004 .uA = 100000, 2005 }, 2006 {} 2007 }, 2008 .proxy_clk_names = (char*[]){ 2009 "xo", 2010 NULL 2011 }, 2012 .active_clk_names = (char*[]){ 2013 "iface", 2014 "bus", 2015 "mem", 2016 NULL 2017 }, 2018 .need_mem_protection = false, 2019 .has_alt_reset = false, 2020 .has_mba_logs = false, 2021 .has_spare_reg = false, 2022 .version = MSS_MSM8974, 2023 }; 2024 2025 static const struct of_device_id q6v5_of_match[] = { 2026 { .compatible = "qcom,q6v5-pil", .data = &msm8916_mss}, 2027 { .compatible = "qcom,msm8916-mss-pil", .data = &msm8916_mss}, 2028 { .compatible = "qcom,msm8974-mss-pil", .data = &msm8974_mss}, 2029 { .compatible = "qcom,msm8996-mss-pil", .data = &msm8996_mss}, 2030 { .compatible = "qcom,msm8998-mss-pil", .data = &msm8998_mss}, 2031 { .compatible = "qcom,sc7180-mss-pil", .data = &sc7180_mss}, 2032 { .compatible = "qcom,sdm845-mss-pil", .data = &sdm845_mss}, 2033 { }, 2034 }; 2035 MODULE_DEVICE_TABLE(of, q6v5_of_match); 2036 2037 static struct platform_driver q6v5_driver = { 2038 .probe = q6v5_probe, 2039 .remove = q6v5_remove, 2040 .driver = { 2041 .name = "qcom-q6v5-mss", 2042 .of_match_table = q6v5_of_match, 2043 }, 2044 }; 2045 module_platform_driver(q6v5_driver); 2046 2047 MODULE_DESCRIPTION("Qualcomm Self-authenticating modem remoteproc driver"); 2048 MODULE_LICENSE("GPL v2"); 2049