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