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