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