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