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