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