]> git.kernelconcepts.de Git - karo-tx-linux.git/blob - drivers/remoteproc/qcom_q6v5_pil.c
remoteproc: qcom: mdt_loader: Use signed type for offset
[karo-tx-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
36 #include "remoteproc_internal.h"
37 #include "qcom_common.h"
38
39 #include <linux/qcom_scm.h>
40
41 #define MPSS_CRASH_REASON_SMEM          421
42
43 /* RMB Status Register Values */
44 #define RMB_PBL_SUCCESS                 0x1
45
46 #define RMB_MBA_XPU_UNLOCKED            0x1
47 #define RMB_MBA_XPU_UNLOCKED_SCRIBBLED  0x2
48 #define RMB_MBA_META_DATA_AUTH_SUCCESS  0x3
49 #define RMB_MBA_AUTH_COMPLETE           0x4
50
51 /* PBL/MBA interface registers */
52 #define RMB_MBA_IMAGE_REG               0x00
53 #define RMB_PBL_STATUS_REG              0x04
54 #define RMB_MBA_COMMAND_REG             0x08
55 #define RMB_MBA_STATUS_REG              0x0C
56 #define RMB_PMI_META_DATA_REG           0x10
57 #define RMB_PMI_CODE_START_REG          0x14
58 #define RMB_PMI_CODE_LENGTH_REG         0x18
59
60 #define RMB_CMD_META_DATA_READY         0x1
61 #define RMB_CMD_LOAD_READY              0x2
62
63 /* QDSP6SS Register Offsets */
64 #define QDSP6SS_RESET_REG               0x014
65 #define QDSP6SS_GFMUX_CTL_REG           0x020
66 #define QDSP6SS_PWR_CTL_REG             0x030
67
68 /* AXI Halt Register Offsets */
69 #define AXI_HALTREQ_REG                 0x0
70 #define AXI_HALTACK_REG                 0x4
71 #define AXI_IDLE_REG                    0x8
72
73 #define HALT_ACK_TIMEOUT_MS             100
74
75 /* QDSP6SS_RESET */
76 #define Q6SS_STOP_CORE                  BIT(0)
77 #define Q6SS_CORE_ARES                  BIT(1)
78 #define Q6SS_BUS_ARES_ENABLE            BIT(2)
79
80 /* QDSP6SS_GFMUX_CTL */
81 #define Q6SS_CLK_ENABLE                 BIT(1)
82
83 /* QDSP6SS_PWR_CTL */
84 #define Q6SS_L2DATA_SLP_NRET_N_0        BIT(0)
85 #define Q6SS_L2DATA_SLP_NRET_N_1        BIT(1)
86 #define Q6SS_L2DATA_SLP_NRET_N_2        BIT(2)
87 #define Q6SS_L2TAG_SLP_NRET_N           BIT(16)
88 #define Q6SS_ETB_SLP_NRET_N             BIT(17)
89 #define Q6SS_L2DATA_STBY_N              BIT(18)
90 #define Q6SS_SLP_RET_N                  BIT(19)
91 #define Q6SS_CLAMP_IO                   BIT(20)
92 #define QDSS_BHS_ON                     BIT(21)
93 #define QDSS_LDO_BYP                    BIT(22)
94
95 struct reg_info {
96         struct regulator *reg;
97         int uV;
98         int uA;
99 };
100
101 struct qcom_mss_reg_res {
102         const char *supply;
103         int uV;
104         int uA;
105 };
106
107 struct rproc_hexagon_res {
108         const char *hexagon_mba_image;
109         struct qcom_mss_reg_res *proxy_supply;
110         struct qcom_mss_reg_res *active_supply;
111         char **proxy_clk_names;
112         char **active_clk_names;
113 };
114
115 struct q6v5 {
116         struct device *dev;
117         struct rproc *rproc;
118
119         void __iomem *reg_base;
120         void __iomem *rmb_base;
121
122         struct regmap *halt_map;
123         u32 halt_q6;
124         u32 halt_modem;
125         u32 halt_nc;
126
127         struct reset_control *mss_restart;
128
129         struct qcom_smem_state *state;
130         unsigned stop_bit;
131
132         struct clk *active_clks[8];
133         struct clk *proxy_clks[4];
134         int active_clk_count;
135         int proxy_clk_count;
136
137         struct reg_info active_regs[1];
138         struct reg_info proxy_regs[3];
139         int active_reg_count;
140         int proxy_reg_count;
141
142         struct completion start_done;
143         struct completion stop_done;
144         bool running;
145
146         phys_addr_t mba_phys;
147         void *mba_region;
148         size_t mba_size;
149
150         phys_addr_t mpss_phys;
151         phys_addr_t mpss_reloc;
152         void *mpss_region;
153         size_t mpss_size;
154
155         struct qcom_rproc_subdev smd_subdev;
156 };
157
158 static int q6v5_regulator_init(struct device *dev, struct reg_info *regs,
159                                const struct qcom_mss_reg_res *reg_res)
160 {
161         int rc;
162         int i;
163
164         if (!reg_res)
165                 return 0;
166
167         for (i = 0; reg_res[i].supply; i++) {
168                 regs[i].reg = devm_regulator_get(dev, reg_res[i].supply);
169                 if (IS_ERR(regs[i].reg)) {
170                         rc = PTR_ERR(regs[i].reg);
171                         if (rc != -EPROBE_DEFER)
172                                 dev_err(dev, "Failed to get %s\n regulator",
173                                         reg_res[i].supply);
174                         return rc;
175                 }
176
177                 regs[i].uV = reg_res[i].uV;
178                 regs[i].uA = reg_res[i].uA;
179         }
180
181         return i;
182 }
183
184 static int q6v5_regulator_enable(struct q6v5 *qproc,
185                                  struct reg_info *regs, int count)
186 {
187         int ret;
188         int i;
189
190         for (i = 0; i < count; i++) {
191                 if (regs[i].uV > 0) {
192                         ret = regulator_set_voltage(regs[i].reg,
193                                         regs[i].uV, INT_MAX);
194                         if (ret) {
195                                 dev_err(qproc->dev,
196                                         "Failed to request voltage for %d.\n",
197                                                 i);
198                                 goto err;
199                         }
200                 }
201
202                 if (regs[i].uA > 0) {
203                         ret = regulator_set_load(regs[i].reg,
204                                                  regs[i].uA);
205                         if (ret < 0) {
206                                 dev_err(qproc->dev,
207                                         "Failed to set regulator mode\n");
208                                 goto err;
209                         }
210                 }
211
212                 ret = regulator_enable(regs[i].reg);
213                 if (ret) {
214                         dev_err(qproc->dev, "Regulator enable failed\n");
215                         goto err;
216                 }
217         }
218
219         return 0;
220 err:
221         for (; i >= 0; i--) {
222                 if (regs[i].uV > 0)
223                         regulator_set_voltage(regs[i].reg, 0, INT_MAX);
224
225                 if (regs[i].uA > 0)
226                         regulator_set_load(regs[i].reg, 0);
227
228                 regulator_disable(regs[i].reg);
229         }
230
231         return ret;
232 }
233
234 static void q6v5_regulator_disable(struct q6v5 *qproc,
235                                    struct reg_info *regs, int count)
236 {
237         int i;
238
239         for (i = 0; i < count; i++) {
240                 if (regs[i].uV > 0)
241                         regulator_set_voltage(regs[i].reg, 0, INT_MAX);
242
243                 if (regs[i].uA > 0)
244                         regulator_set_load(regs[i].reg, 0);
245
246                 regulator_disable(regs[i].reg);
247         }
248 }
249
250 static int q6v5_clk_enable(struct device *dev,
251                            struct clk **clks, int count)
252 {
253         int rc;
254         int i;
255
256         for (i = 0; i < count; i++) {
257                 rc = clk_prepare_enable(clks[i]);
258                 if (rc) {
259                         dev_err(dev, "Clock enable failed\n");
260                         goto err;
261                 }
262         }
263
264         return 0;
265 err:
266         for (i--; i >= 0; i--)
267                 clk_disable_unprepare(clks[i]);
268
269         return rc;
270 }
271
272 static void q6v5_clk_disable(struct device *dev,
273                              struct clk **clks, int count)
274 {
275         int i;
276
277         for (i = 0; i < count; i++)
278                 clk_disable_unprepare(clks[i]);
279 }
280
281 static struct resource_table *q6v5_find_rsc_table(struct rproc *rproc,
282                                                   const struct firmware *fw,
283                                                   int *tablesz)
284 {
285         static struct resource_table table = { .ver = 1, };
286
287         *tablesz = sizeof(table);
288         return &table;
289 }
290
291 static int q6v5_load(struct rproc *rproc, const struct firmware *fw)
292 {
293         struct q6v5 *qproc = rproc->priv;
294
295         memcpy(qproc->mba_region, fw->data, fw->size);
296
297         return 0;
298 }
299
300 static const struct rproc_fw_ops q6v5_fw_ops = {
301         .find_rsc_table = q6v5_find_rsc_table,
302         .load = q6v5_load,
303 };
304
305 static int q6v5_rmb_pbl_wait(struct q6v5 *qproc, int ms)
306 {
307         unsigned long timeout;
308         s32 val;
309
310         timeout = jiffies + msecs_to_jiffies(ms);
311         for (;;) {
312                 val = readl(qproc->rmb_base + RMB_PBL_STATUS_REG);
313                 if (val)
314                         break;
315
316                 if (time_after(jiffies, timeout))
317                         return -ETIMEDOUT;
318
319                 msleep(1);
320         }
321
322         return val;
323 }
324
325 static int q6v5_rmb_mba_wait(struct q6v5 *qproc, u32 status, int ms)
326 {
327
328         unsigned long timeout;
329         s32 val;
330
331         timeout = jiffies + msecs_to_jiffies(ms);
332         for (;;) {
333                 val = readl(qproc->rmb_base + RMB_MBA_STATUS_REG);
334                 if (val < 0)
335                         break;
336
337                 if (!status && val)
338                         break;
339                 else if (status && val == status)
340                         break;
341
342                 if (time_after(jiffies, timeout))
343                         return -ETIMEDOUT;
344
345                 msleep(1);
346         }
347
348         return val;
349 }
350
351 static int q6v5proc_reset(struct q6v5 *qproc)
352 {
353         u32 val;
354         int ret;
355
356         /* Assert resets, stop core */
357         val = readl(qproc->reg_base + QDSP6SS_RESET_REG);
358         val |= (Q6SS_CORE_ARES | Q6SS_BUS_ARES_ENABLE | Q6SS_STOP_CORE);
359         writel(val, qproc->reg_base + QDSP6SS_RESET_REG);
360
361         /* Enable power block headswitch, and wait for it to stabilize */
362         val = readl(qproc->reg_base + QDSP6SS_PWR_CTL_REG);
363         val |= QDSS_BHS_ON | QDSS_LDO_BYP;
364         writel(val, qproc->reg_base + QDSP6SS_PWR_CTL_REG);
365         udelay(1);
366
367         /*
368          * Turn on memories. L2 banks should be done individually
369          * to minimize inrush current.
370          */
371         val = readl(qproc->reg_base + QDSP6SS_PWR_CTL_REG);
372         val |= Q6SS_SLP_RET_N | Q6SS_L2TAG_SLP_NRET_N |
373                 Q6SS_ETB_SLP_NRET_N | Q6SS_L2DATA_STBY_N;
374         writel(val, qproc->reg_base + QDSP6SS_PWR_CTL_REG);
375         val |= Q6SS_L2DATA_SLP_NRET_N_2;
376         writel(val, qproc->reg_base + QDSP6SS_PWR_CTL_REG);
377         val |= Q6SS_L2DATA_SLP_NRET_N_1;
378         writel(val, qproc->reg_base + QDSP6SS_PWR_CTL_REG);
379         val |= Q6SS_L2DATA_SLP_NRET_N_0;
380         writel(val, qproc->reg_base + QDSP6SS_PWR_CTL_REG);
381
382         /* Remove IO clamp */
383         val &= ~Q6SS_CLAMP_IO;
384         writel(val, qproc->reg_base + QDSP6SS_PWR_CTL_REG);
385
386         /* Bring core out of reset */
387         val = readl(qproc->reg_base + QDSP6SS_RESET_REG);
388         val &= ~Q6SS_CORE_ARES;
389         writel(val, qproc->reg_base + QDSP6SS_RESET_REG);
390
391         /* Turn on core clock */
392         val = readl(qproc->reg_base + QDSP6SS_GFMUX_CTL_REG);
393         val |= Q6SS_CLK_ENABLE;
394         writel(val, qproc->reg_base + QDSP6SS_GFMUX_CTL_REG);
395
396         /* Start core execution */
397         val = readl(qproc->reg_base + QDSP6SS_RESET_REG);
398         val &= ~Q6SS_STOP_CORE;
399         writel(val, qproc->reg_base + QDSP6SS_RESET_REG);
400
401         /* Wait for PBL status */
402         ret = q6v5_rmb_pbl_wait(qproc, 1000);
403         if (ret == -ETIMEDOUT) {
404                 dev_err(qproc->dev, "PBL boot timed out\n");
405         } else if (ret != RMB_PBL_SUCCESS) {
406                 dev_err(qproc->dev, "PBL returned unexpected status %d\n", ret);
407                 ret = -EINVAL;
408         } else {
409                 ret = 0;
410         }
411
412         return ret;
413 }
414
415 static void q6v5proc_halt_axi_port(struct q6v5 *qproc,
416                                    struct regmap *halt_map,
417                                    u32 offset)
418 {
419         unsigned long timeout;
420         unsigned int val;
421         int ret;
422
423         /* Check if we're already idle */
424         ret = regmap_read(halt_map, offset + AXI_IDLE_REG, &val);
425         if (!ret && val)
426                 return;
427
428         /* Assert halt request */
429         regmap_write(halt_map, offset + AXI_HALTREQ_REG, 1);
430
431         /* Wait for halt */
432         timeout = jiffies + msecs_to_jiffies(HALT_ACK_TIMEOUT_MS);
433         for (;;) {
434                 ret = regmap_read(halt_map, offset + AXI_HALTACK_REG, &val);
435                 if (ret || val || time_after(jiffies, timeout))
436                         break;
437
438                 msleep(1);
439         }
440
441         ret = regmap_read(halt_map, offset + AXI_IDLE_REG, &val);
442         if (ret || !val)
443                 dev_err(qproc->dev, "port failed halt\n");
444
445         /* Clear halt request (port will remain halted until reset) */
446         regmap_write(halt_map, offset + AXI_HALTREQ_REG, 0);
447 }
448
449 static int q6v5_mpss_init_image(struct q6v5 *qproc, const struct firmware *fw)
450 {
451         unsigned long dma_attrs = DMA_ATTR_FORCE_CONTIGUOUS;
452         dma_addr_t phys;
453         void *ptr;
454         int ret;
455
456         ptr = dma_alloc_attrs(qproc->dev, fw->size, &phys, GFP_KERNEL, dma_attrs);
457         if (!ptr) {
458                 dev_err(qproc->dev, "failed to allocate mdt buffer\n");
459                 return -ENOMEM;
460         }
461
462         memcpy(ptr, fw->data, fw->size);
463
464         writel(phys, qproc->rmb_base + RMB_PMI_META_DATA_REG);
465         writel(RMB_CMD_META_DATA_READY, qproc->rmb_base + RMB_MBA_COMMAND_REG);
466
467         ret = q6v5_rmb_mba_wait(qproc, RMB_MBA_META_DATA_AUTH_SUCCESS, 1000);
468         if (ret == -ETIMEDOUT)
469                 dev_err(qproc->dev, "MPSS header authentication timed out\n");
470         else if (ret < 0)
471                 dev_err(qproc->dev, "MPSS header authentication failed: %d\n", ret);
472
473         dma_free_attrs(qproc->dev, fw->size, ptr, phys, dma_attrs);
474
475         return ret < 0 ? ret : 0;
476 }
477
478 static bool q6v5_phdr_valid(const struct elf32_phdr *phdr)
479 {
480         if (phdr->p_type != PT_LOAD)
481                 return false;
482
483         if ((phdr->p_flags & QCOM_MDT_TYPE_MASK) == QCOM_MDT_TYPE_HASH)
484                 return false;
485
486         if (!phdr->p_memsz)
487                 return false;
488
489         return true;
490 }
491
492 static int q6v5_mpss_load(struct q6v5 *qproc)
493 {
494         const struct elf32_phdr *phdrs;
495         const struct elf32_phdr *phdr;
496         const struct firmware *seg_fw;
497         const struct firmware *fw;
498         struct elf32_hdr *ehdr;
499         phys_addr_t mpss_reloc;
500         phys_addr_t boot_addr;
501         phys_addr_t min_addr = (phys_addr_t)ULLONG_MAX;
502         phys_addr_t max_addr = 0;
503         bool relocate = false;
504         char seg_name[10];
505         ssize_t offset;
506         size_t size;
507         void *ptr;
508         int ret;
509         int i;
510
511         ret = request_firmware(&fw, "modem.mdt", qproc->dev);
512         if (ret < 0) {
513                 dev_err(qproc->dev, "unable to load modem.mdt\n");
514                 return ret;
515         }
516
517         /* Initialize the RMB validator */
518         writel(0, qproc->rmb_base + RMB_PMI_CODE_LENGTH_REG);
519
520         ret = q6v5_mpss_init_image(qproc, fw);
521         if (ret)
522                 goto release_firmware;
523
524         ehdr = (struct elf32_hdr *)fw->data;
525         phdrs = (struct elf32_phdr *)(ehdr + 1);
526
527         for (i = 0; i < ehdr->e_phnum; i++) {
528                 phdr = &phdrs[i];
529
530                 if (!q6v5_phdr_valid(phdr))
531                         continue;
532
533                 if (phdr->p_flags & QCOM_MDT_RELOCATABLE)
534                         relocate = true;
535
536                 if (phdr->p_paddr < min_addr)
537                         min_addr = phdr->p_paddr;
538
539                 if (phdr->p_paddr + phdr->p_memsz > max_addr)
540                         max_addr = ALIGN(phdr->p_paddr + phdr->p_memsz, SZ_4K);
541         }
542
543         mpss_reloc = relocate ? min_addr : qproc->mpss_phys;
544
545         for (i = 0; i < ehdr->e_phnum; i++) {
546                 phdr = &phdrs[i];
547
548                 if (!q6v5_phdr_valid(phdr))
549                         continue;
550
551                 offset = phdr->p_paddr - mpss_reloc;
552                 if (offset < 0 || offset + phdr->p_memsz > qproc->mpss_size) {
553                         dev_err(qproc->dev, "segment outside memory range\n");
554                         ret = -EINVAL;
555                         goto release_firmware;
556                 }
557
558                 ptr = qproc->mpss_region + offset;
559
560                 if (phdr->p_filesz) {
561                         snprintf(seg_name, sizeof(seg_name), "modem.b%02d", i);
562                         ret = request_firmware(&seg_fw, seg_name, qproc->dev);
563                         if (ret) {
564                                 dev_err(qproc->dev, "failed to load %s\n", seg_name);
565                                 goto release_firmware;
566                         }
567
568                         memcpy(ptr, seg_fw->data, seg_fw->size);
569
570                         release_firmware(seg_fw);
571                 }
572
573                 if (phdr->p_memsz > phdr->p_filesz) {
574                         memset(ptr + phdr->p_filesz, 0,
575                                phdr->p_memsz - phdr->p_filesz);
576                 }
577
578                 size = readl(qproc->rmb_base + RMB_PMI_CODE_LENGTH_REG);
579                 if (!size) {
580                         boot_addr = relocate ? qproc->mpss_phys : min_addr;
581                         writel(boot_addr, qproc->rmb_base + RMB_PMI_CODE_START_REG);
582                         writel(RMB_CMD_LOAD_READY, qproc->rmb_base + RMB_MBA_COMMAND_REG);
583                 }
584
585                 size += phdr->p_memsz;
586                 writel(size, qproc->rmb_base + RMB_PMI_CODE_LENGTH_REG);
587         }
588
589         ret = q6v5_rmb_mba_wait(qproc, RMB_MBA_AUTH_COMPLETE, 10000);
590         if (ret == -ETIMEDOUT)
591                 dev_err(qproc->dev, "MPSS authentication timed out\n");
592         else if (ret < 0)
593                 dev_err(qproc->dev, "MPSS authentication failed: %d\n", ret);
594
595 release_firmware:
596         release_firmware(fw);
597
598         return ret < 0 ? ret : 0;
599 }
600
601 static int q6v5_start(struct rproc *rproc)
602 {
603         struct q6v5 *qproc = (struct q6v5 *)rproc->priv;
604         int ret;
605
606         ret = q6v5_regulator_enable(qproc, qproc->proxy_regs,
607                                     qproc->proxy_reg_count);
608         if (ret) {
609                 dev_err(qproc->dev, "failed to enable proxy supplies\n");
610                 return ret;
611         }
612
613         ret = q6v5_clk_enable(qproc->dev, qproc->proxy_clks,
614                               qproc->proxy_clk_count);
615         if (ret) {
616                 dev_err(qproc->dev, "failed to enable proxy clocks\n");
617                 goto disable_proxy_reg;
618         }
619
620         ret = q6v5_regulator_enable(qproc, qproc->active_regs,
621                                     qproc->active_reg_count);
622         if (ret) {
623                 dev_err(qproc->dev, "failed to enable supplies\n");
624                 goto disable_proxy_clk;
625         }
626         ret = reset_control_deassert(qproc->mss_restart);
627         if (ret) {
628                 dev_err(qproc->dev, "failed to deassert mss restart\n");
629                 goto disable_vdd;
630         }
631
632         ret = q6v5_clk_enable(qproc->dev, qproc->active_clks,
633                               qproc->active_clk_count);
634         if (ret) {
635                 dev_err(qproc->dev, "failed to enable clocks\n");
636                 goto assert_reset;
637         }
638
639         writel(qproc->mba_phys, qproc->rmb_base + RMB_MBA_IMAGE_REG);
640
641         ret = q6v5proc_reset(qproc);
642         if (ret)
643                 goto halt_axi_ports;
644
645         ret = q6v5_rmb_mba_wait(qproc, 0, 5000);
646         if (ret == -ETIMEDOUT) {
647                 dev_err(qproc->dev, "MBA boot timed out\n");
648                 goto halt_axi_ports;
649         } else if (ret != RMB_MBA_XPU_UNLOCKED &&
650                    ret != RMB_MBA_XPU_UNLOCKED_SCRIBBLED) {
651                 dev_err(qproc->dev, "MBA returned unexpected status %d\n", ret);
652                 ret = -EINVAL;
653                 goto halt_axi_ports;
654         }
655
656         dev_info(qproc->dev, "MBA booted, loading mpss\n");
657
658         ret = q6v5_mpss_load(qproc);
659         if (ret)
660                 goto halt_axi_ports;
661
662         ret = wait_for_completion_timeout(&qproc->start_done,
663                                           msecs_to_jiffies(5000));
664         if (ret == 0) {
665                 dev_err(qproc->dev, "start timed out\n");
666                 ret = -ETIMEDOUT;
667                 goto halt_axi_ports;
668         }
669
670         qproc->running = true;
671
672         q6v5_clk_disable(qproc->dev, qproc->proxy_clks,
673                          qproc->proxy_clk_count);
674         q6v5_regulator_disable(qproc, qproc->proxy_regs,
675                                qproc->proxy_reg_count);
676
677         return 0;
678
679 halt_axi_ports:
680         q6v5proc_halt_axi_port(qproc, qproc->halt_map, qproc->halt_q6);
681         q6v5proc_halt_axi_port(qproc, qproc->halt_map, qproc->halt_modem);
682         q6v5proc_halt_axi_port(qproc, qproc->halt_map, qproc->halt_nc);
683         q6v5_clk_disable(qproc->dev, qproc->active_clks,
684                          qproc->active_clk_count);
685 assert_reset:
686         reset_control_assert(qproc->mss_restart);
687 disable_vdd:
688         q6v5_regulator_disable(qproc, qproc->active_regs,
689                                qproc->active_reg_count);
690 disable_proxy_clk:
691         q6v5_clk_disable(qproc->dev, qproc->proxy_clks,
692                          qproc->proxy_clk_count);
693 disable_proxy_reg:
694         q6v5_regulator_disable(qproc, qproc->proxy_regs,
695                                qproc->proxy_reg_count);
696
697         return ret;
698 }
699
700 static int q6v5_stop(struct rproc *rproc)
701 {
702         struct q6v5 *qproc = (struct q6v5 *)rproc->priv;
703         int ret;
704
705         qproc->running = false;
706
707         qcom_smem_state_update_bits(qproc->state,
708                                     BIT(qproc->stop_bit), BIT(qproc->stop_bit));
709
710         ret = wait_for_completion_timeout(&qproc->stop_done,
711                                           msecs_to_jiffies(5000));
712         if (ret == 0)
713                 dev_err(qproc->dev, "timed out on wait\n");
714
715         qcom_smem_state_update_bits(qproc->state, BIT(qproc->stop_bit), 0);
716
717         q6v5proc_halt_axi_port(qproc, qproc->halt_map, qproc->halt_q6);
718         q6v5proc_halt_axi_port(qproc, qproc->halt_map, qproc->halt_modem);
719         q6v5proc_halt_axi_port(qproc, qproc->halt_map, qproc->halt_nc);
720
721         reset_control_assert(qproc->mss_restart);
722         q6v5_clk_disable(qproc->dev, qproc->active_clks,
723                          qproc->active_clk_count);
724         q6v5_regulator_disable(qproc, qproc->active_regs,
725                                qproc->active_reg_count);
726
727         return 0;
728 }
729
730 static void *q6v5_da_to_va(struct rproc *rproc, u64 da, int len)
731 {
732         struct q6v5 *qproc = rproc->priv;
733         int offset;
734
735         offset = da - qproc->mpss_reloc;
736         if (offset < 0 || offset + len > qproc->mpss_size)
737                 return NULL;
738
739         return qproc->mpss_region + offset;
740 }
741
742 static const struct rproc_ops q6v5_ops = {
743         .start = q6v5_start,
744         .stop = q6v5_stop,
745         .da_to_va = q6v5_da_to_va,
746 };
747
748 static irqreturn_t q6v5_wdog_interrupt(int irq, void *dev)
749 {
750         struct q6v5 *qproc = dev;
751         size_t len;
752         char *msg;
753
754         /* Sometimes the stop triggers a watchdog rather than a stop-ack */
755         if (!qproc->running) {
756                 complete(&qproc->stop_done);
757                 return IRQ_HANDLED;
758         }
759
760         msg = qcom_smem_get(QCOM_SMEM_HOST_ANY, MPSS_CRASH_REASON_SMEM, &len);
761         if (!IS_ERR(msg) && len > 0 && msg[0])
762                 dev_err(qproc->dev, "watchdog received: %s\n", msg);
763         else
764                 dev_err(qproc->dev, "watchdog without message\n");
765
766         rproc_report_crash(qproc->rproc, RPROC_WATCHDOG);
767
768         if (!IS_ERR(msg))
769                 msg[0] = '\0';
770
771         return IRQ_HANDLED;
772 }
773
774 static irqreturn_t q6v5_fatal_interrupt(int irq, void *dev)
775 {
776         struct q6v5 *qproc = dev;
777         size_t len;
778         char *msg;
779
780         msg = qcom_smem_get(QCOM_SMEM_HOST_ANY, MPSS_CRASH_REASON_SMEM, &len);
781         if (!IS_ERR(msg) && len > 0 && msg[0])
782                 dev_err(qproc->dev, "fatal error received: %s\n", msg);
783         else
784                 dev_err(qproc->dev, "fatal error without message\n");
785
786         rproc_report_crash(qproc->rproc, RPROC_FATAL_ERROR);
787
788         if (!IS_ERR(msg))
789                 msg[0] = '\0';
790
791         return IRQ_HANDLED;
792 }
793
794 static irqreturn_t q6v5_handover_interrupt(int irq, void *dev)
795 {
796         struct q6v5 *qproc = dev;
797
798         complete(&qproc->start_done);
799         return IRQ_HANDLED;
800 }
801
802 static irqreturn_t q6v5_stop_ack_interrupt(int irq, void *dev)
803 {
804         struct q6v5 *qproc = dev;
805
806         complete(&qproc->stop_done);
807         return IRQ_HANDLED;
808 }
809
810 static int q6v5_init_mem(struct q6v5 *qproc, struct platform_device *pdev)
811 {
812         struct of_phandle_args args;
813         struct resource *res;
814         int ret;
815
816         res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "qdsp6");
817         qproc->reg_base = devm_ioremap_resource(&pdev->dev, res);
818         if (IS_ERR(qproc->reg_base))
819                 return PTR_ERR(qproc->reg_base);
820
821         res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "rmb");
822         qproc->rmb_base = devm_ioremap_resource(&pdev->dev, res);
823         if (IS_ERR(qproc->rmb_base))
824                 return PTR_ERR(qproc->rmb_base);
825
826         ret = of_parse_phandle_with_fixed_args(pdev->dev.of_node,
827                                                "qcom,halt-regs", 3, 0, &args);
828         if (ret < 0) {
829                 dev_err(&pdev->dev, "failed to parse qcom,halt-regs\n");
830                 return -EINVAL;
831         }
832
833         qproc->halt_map = syscon_node_to_regmap(args.np);
834         of_node_put(args.np);
835         if (IS_ERR(qproc->halt_map))
836                 return PTR_ERR(qproc->halt_map);
837
838         qproc->halt_q6 = args.args[0];
839         qproc->halt_modem = args.args[1];
840         qproc->halt_nc = args.args[2];
841
842         return 0;
843 }
844
845 static int q6v5_init_clocks(struct device *dev, struct clk **clks,
846                 char **clk_names)
847 {
848         int i;
849
850         if (!clk_names)
851                 return 0;
852
853         for (i = 0; clk_names[i]; i++) {
854                 clks[i] = devm_clk_get(dev, clk_names[i]);
855                 if (IS_ERR(clks[i])) {
856                         int rc = PTR_ERR(clks[i]);
857
858                         if (rc != -EPROBE_DEFER)
859                                 dev_err(dev, "Failed to get %s clock\n",
860                                         clk_names[i]);
861                         return rc;
862                 }
863         }
864
865         return i;
866 }
867
868 static int q6v5_init_reset(struct q6v5 *qproc)
869 {
870         qproc->mss_restart = devm_reset_control_get(qproc->dev, NULL);
871         if (IS_ERR(qproc->mss_restart)) {
872                 dev_err(qproc->dev, "failed to acquire mss restart\n");
873                 return PTR_ERR(qproc->mss_restart);
874         }
875
876         return 0;
877 }
878
879 static int q6v5_request_irq(struct q6v5 *qproc,
880                              struct platform_device *pdev,
881                              const char *name,
882                              irq_handler_t thread_fn)
883 {
884         int ret;
885
886         ret = platform_get_irq_byname(pdev, name);
887         if (ret < 0) {
888                 dev_err(&pdev->dev, "no %s IRQ defined\n", name);
889                 return ret;
890         }
891
892         ret = devm_request_threaded_irq(&pdev->dev, ret,
893                                         NULL, thread_fn,
894                                         IRQF_TRIGGER_RISING | IRQF_ONESHOT,
895                                         "q6v5", qproc);
896         if (ret)
897                 dev_err(&pdev->dev, "request %s IRQ failed\n", name);
898
899         return ret;
900 }
901
902 static int q6v5_alloc_memory_region(struct q6v5 *qproc)
903 {
904         struct device_node *child;
905         struct device_node *node;
906         struct resource r;
907         int ret;
908
909         child = of_get_child_by_name(qproc->dev->of_node, "mba");
910         node = of_parse_phandle(child, "memory-region", 0);
911         ret = of_address_to_resource(node, 0, &r);
912         if (ret) {
913                 dev_err(qproc->dev, "unable to resolve mba region\n");
914                 return ret;
915         }
916
917         qproc->mba_phys = r.start;
918         qproc->mba_size = resource_size(&r);
919         qproc->mba_region = devm_ioremap_wc(qproc->dev, qproc->mba_phys, qproc->mba_size);
920         if (!qproc->mba_region) {
921                 dev_err(qproc->dev, "unable to map memory region: %pa+%zx\n",
922                         &r.start, qproc->mba_size);
923                 return -EBUSY;
924         }
925
926         child = of_get_child_by_name(qproc->dev->of_node, "mpss");
927         node = of_parse_phandle(child, "memory-region", 0);
928         ret = of_address_to_resource(node, 0, &r);
929         if (ret) {
930                 dev_err(qproc->dev, "unable to resolve mpss region\n");
931                 return ret;
932         }
933
934         qproc->mpss_phys = qproc->mpss_reloc = r.start;
935         qproc->mpss_size = resource_size(&r);
936         qproc->mpss_region = devm_ioremap_wc(qproc->dev, qproc->mpss_phys, qproc->mpss_size);
937         if (!qproc->mpss_region) {
938                 dev_err(qproc->dev, "unable to map memory region: %pa+%zx\n",
939                         &r.start, qproc->mpss_size);
940                 return -EBUSY;
941         }
942
943         return 0;
944 }
945
946 static int q6v5_probe(struct platform_device *pdev)
947 {
948         const struct rproc_hexagon_res *desc;
949         struct q6v5 *qproc;
950         struct rproc *rproc;
951         int ret;
952
953         desc = of_device_get_match_data(&pdev->dev);
954         if (!desc)
955                 return -EINVAL;
956
957         rproc = rproc_alloc(&pdev->dev, pdev->name, &q6v5_ops,
958                             desc->hexagon_mba_image, sizeof(*qproc));
959         if (!rproc) {
960                 dev_err(&pdev->dev, "failed to allocate rproc\n");
961                 return -ENOMEM;
962         }
963
964         rproc->fw_ops = &q6v5_fw_ops;
965
966         qproc = (struct q6v5 *)rproc->priv;
967         qproc->dev = &pdev->dev;
968         qproc->rproc = rproc;
969         platform_set_drvdata(pdev, qproc);
970
971         init_completion(&qproc->start_done);
972         init_completion(&qproc->stop_done);
973
974         ret = q6v5_init_mem(qproc, pdev);
975         if (ret)
976                 goto free_rproc;
977
978         ret = q6v5_alloc_memory_region(qproc);
979         if (ret)
980                 goto free_rproc;
981
982         ret = q6v5_init_clocks(&pdev->dev, qproc->proxy_clks,
983                                desc->proxy_clk_names);
984         if (ret < 0) {
985                 dev_err(&pdev->dev, "Failed to get proxy clocks.\n");
986                 goto free_rproc;
987         }
988         qproc->proxy_clk_count = ret;
989
990         ret = q6v5_init_clocks(&pdev->dev, qproc->active_clks,
991                                desc->active_clk_names);
992         if (ret < 0) {
993                 dev_err(&pdev->dev, "Failed to get active clocks.\n");
994                 goto free_rproc;
995         }
996         qproc->active_clk_count = ret;
997
998         ret = q6v5_regulator_init(&pdev->dev, qproc->proxy_regs,
999                                   desc->proxy_supply);
1000         if (ret < 0) {
1001                 dev_err(&pdev->dev, "Failed to get proxy regulators.\n");
1002                 goto free_rproc;
1003         }
1004         qproc->proxy_reg_count = ret;
1005
1006         ret = q6v5_regulator_init(&pdev->dev,  qproc->active_regs,
1007                                   desc->active_supply);
1008         if (ret < 0) {
1009                 dev_err(&pdev->dev, "Failed to get active regulators.\n");
1010                 goto free_rproc;
1011         }
1012         qproc->active_reg_count = ret;
1013
1014         ret = q6v5_init_reset(qproc);
1015         if (ret)
1016                 goto free_rproc;
1017
1018         ret = q6v5_request_irq(qproc, pdev, "wdog", q6v5_wdog_interrupt);
1019         if (ret < 0)
1020                 goto free_rproc;
1021
1022         ret = q6v5_request_irq(qproc, pdev, "fatal", q6v5_fatal_interrupt);
1023         if (ret < 0)
1024                 goto free_rproc;
1025
1026         ret = q6v5_request_irq(qproc, pdev, "handover", q6v5_handover_interrupt);
1027         if (ret < 0)
1028                 goto free_rproc;
1029
1030         ret = q6v5_request_irq(qproc, pdev, "stop-ack", q6v5_stop_ack_interrupt);
1031         if (ret < 0)
1032                 goto free_rproc;
1033
1034         qproc->state = qcom_smem_state_get(&pdev->dev, "stop", &qproc->stop_bit);
1035         if (IS_ERR(qproc->state)) {
1036                 ret = PTR_ERR(qproc->state);
1037                 goto free_rproc;
1038         }
1039
1040         qcom_add_smd_subdev(rproc, &qproc->smd_subdev);
1041
1042         ret = rproc_add(rproc);
1043         if (ret)
1044                 goto free_rproc;
1045
1046         return 0;
1047
1048 free_rproc:
1049         rproc_free(rproc);
1050
1051         return ret;
1052 }
1053
1054 static int q6v5_remove(struct platform_device *pdev)
1055 {
1056         struct q6v5 *qproc = platform_get_drvdata(pdev);
1057
1058         rproc_del(qproc->rproc);
1059
1060         qcom_remove_smd_subdev(qproc->rproc, &qproc->smd_subdev);
1061         rproc_free(qproc->rproc);
1062
1063         return 0;
1064 }
1065
1066 static const struct rproc_hexagon_res msm8916_mss = {
1067         .hexagon_mba_image = "mba.mbn",
1068         .proxy_supply = (struct qcom_mss_reg_res[]) {
1069                 {
1070                         .supply = "mx",
1071                         .uV = 1050000,
1072                 },
1073                 {
1074                         .supply = "cx",
1075                         .uA = 100000,
1076                 },
1077                 {
1078                         .supply = "pll",
1079                         .uA = 100000,
1080                 },
1081                 {}
1082         },
1083         .proxy_clk_names = (char*[]){
1084                 "xo",
1085                 NULL
1086         },
1087         .active_clk_names = (char*[]){
1088                 "iface",
1089                 "bus",
1090                 "mem",
1091                 NULL
1092         },
1093 };
1094
1095 static const struct rproc_hexagon_res msm8974_mss = {
1096         .hexagon_mba_image = "mba.b00",
1097         .proxy_supply = (struct qcom_mss_reg_res[]) {
1098                 {
1099                         .supply = "mx",
1100                         .uV = 1050000,
1101                 },
1102                 {
1103                         .supply = "cx",
1104                         .uA = 100000,
1105                 },
1106                 {
1107                         .supply = "pll",
1108                         .uA = 100000,
1109                 },
1110                 {}
1111         },
1112         .active_supply = (struct qcom_mss_reg_res[]) {
1113                 {
1114                         .supply = "mss",
1115                         .uV = 1050000,
1116                         .uA = 100000,
1117                 },
1118                 {}
1119         },
1120         .proxy_clk_names = (char*[]){
1121                 "xo",
1122                 NULL
1123         },
1124         .active_clk_names = (char*[]){
1125                 "iface",
1126                 "bus",
1127                 "mem",
1128                 NULL
1129         },
1130 };
1131
1132 static const struct of_device_id q6v5_of_match[] = {
1133         { .compatible = "qcom,q6v5-pil", .data = &msm8916_mss},
1134         { .compatible = "qcom,msm8916-mss-pil", .data = &msm8916_mss},
1135         { .compatible = "qcom,msm8974-mss-pil", .data = &msm8974_mss},
1136         { },
1137 };
1138 MODULE_DEVICE_TABLE(of, q6v5_of_match);
1139
1140 static struct platform_driver q6v5_driver = {
1141         .probe = q6v5_probe,
1142         .remove = q6v5_remove,
1143         .driver = {
1144                 .name = "qcom-q6v5-pil",
1145                 .of_match_table = q6v5_of_match,
1146         },
1147 };
1148 module_platform_driver(q6v5_driver);
1149
1150 MODULE_DESCRIPTION("Peripheral Image Loader for Hexagon");
1151 MODULE_LICENSE("GPL v2");