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