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