2 * Qualcomm Peripheral Image Loader
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.
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.
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.
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>
37 #include "remoteproc_internal.h"
38 #include "qcom_common.h"
40 #include <linux/qcom_scm.h>
42 #define MPSS_CRASH_REASON_SMEM 421
44 /* RMB Status Register Values */
45 #define RMB_PBL_SUCCESS 0x1
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
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
61 #define RMB_CMD_META_DATA_READY 0x1
62 #define RMB_CMD_LOAD_READY 0x2
64 /* QDSP6SS Register Offsets */
65 #define QDSP6SS_RESET_REG 0x014
66 #define QDSP6SS_GFMUX_CTL_REG 0x020
67 #define QDSP6SS_PWR_CTL_REG 0x030
68 #define QDSP6SS_MEM_PWR_CTL 0x0B0
69 #define QDSP6SS_STRAP_ACC 0x110
71 /* AXI Halt Register Offsets */
72 #define AXI_HALTREQ_REG 0x0
73 #define AXI_HALTACK_REG 0x4
74 #define AXI_IDLE_REG 0x8
76 #define HALT_ACK_TIMEOUT_MS 100
79 #define Q6SS_STOP_CORE BIT(0)
80 #define Q6SS_CORE_ARES BIT(1)
81 #define Q6SS_BUS_ARES_ENABLE BIT(2)
83 /* QDSP6SS_GFMUX_CTL */
84 #define Q6SS_CLK_ENABLE BIT(1)
87 #define Q6SS_L2DATA_SLP_NRET_N_0 BIT(0)
88 #define Q6SS_L2DATA_SLP_NRET_N_1 BIT(1)
89 #define Q6SS_L2DATA_SLP_NRET_N_2 BIT(2)
90 #define Q6SS_L2TAG_SLP_NRET_N BIT(16)
91 #define Q6SS_ETB_SLP_NRET_N BIT(17)
92 #define Q6SS_L2DATA_STBY_N BIT(18)
93 #define Q6SS_SLP_RET_N BIT(19)
94 #define Q6SS_CLAMP_IO BIT(20)
95 #define QDSS_BHS_ON BIT(21)
96 #define QDSS_LDO_BYP BIT(22)
98 /* QDSP6v56 parameters */
99 #define QDSP6v56_LDO_BYP BIT(25)
100 #define QDSP6v56_BHS_ON BIT(24)
101 #define QDSP6v56_CLAMP_WL BIT(21)
102 #define QDSP6v56_CLAMP_QMC_MEM BIT(22)
103 #define HALT_CHECK_MAX_LOOPS 200
104 #define QDSP6SS_XO_CBCR 0x0038
105 #define QDSP6SS_ACC_OVERRIDE_VAL 0x20
108 struct regulator
*reg
;
113 struct qcom_mss_reg_res
{
119 struct rproc_hexagon_res
{
120 const char *hexagon_mba_image
;
121 struct qcom_mss_reg_res
*proxy_supply
;
122 struct qcom_mss_reg_res
*active_supply
;
123 char **proxy_clk_names
;
124 char **active_clk_names
;
126 bool need_mem_protection
;
133 void __iomem
*reg_base
;
134 void __iomem
*rmb_base
;
136 struct regmap
*halt_map
;
141 struct reset_control
*mss_restart
;
143 struct qcom_smem_state
*state
;
146 struct clk
*active_clks
[8];
147 struct clk
*proxy_clks
[4];
148 int active_clk_count
;
151 struct reg_info active_regs
[1];
152 struct reg_info proxy_regs
[3];
153 int active_reg_count
;
156 struct completion start_done
;
157 struct completion stop_done
;
160 phys_addr_t mba_phys
;
164 phys_addr_t mpss_phys
;
165 phys_addr_t mpss_reloc
;
169 struct qcom_rproc_subdev smd_subdev
;
170 struct qcom_rproc_ssr ssr_subdev
;
171 bool need_mem_protection
;
183 static int q6v5_regulator_init(struct device
*dev
, struct reg_info
*regs
,
184 const struct qcom_mss_reg_res
*reg_res
)
192 for (i
= 0; reg_res
[i
].supply
; i
++) {
193 regs
[i
].reg
= devm_regulator_get(dev
, reg_res
[i
].supply
);
194 if (IS_ERR(regs
[i
].reg
)) {
195 rc
= PTR_ERR(regs
[i
].reg
);
196 if (rc
!= -EPROBE_DEFER
)
197 dev_err(dev
, "Failed to get %s\n regulator",
202 regs
[i
].uV
= reg_res
[i
].uV
;
203 regs
[i
].uA
= reg_res
[i
].uA
;
209 static int q6v5_regulator_enable(struct q6v5
*qproc
,
210 struct reg_info
*regs
, int count
)
215 for (i
= 0; i
< count
; i
++) {
216 if (regs
[i
].uV
> 0) {
217 ret
= regulator_set_voltage(regs
[i
].reg
,
218 regs
[i
].uV
, INT_MAX
);
221 "Failed to request voltage for %d.\n",
227 if (regs
[i
].uA
> 0) {
228 ret
= regulator_set_load(regs
[i
].reg
,
232 "Failed to set regulator mode\n");
237 ret
= regulator_enable(regs
[i
].reg
);
239 dev_err(qproc
->dev
, "Regulator enable failed\n");
246 for (; i
>= 0; i
--) {
248 regulator_set_voltage(regs
[i
].reg
, 0, INT_MAX
);
251 regulator_set_load(regs
[i
].reg
, 0);
253 regulator_disable(regs
[i
].reg
);
259 static void q6v5_regulator_disable(struct q6v5
*qproc
,
260 struct reg_info
*regs
, int count
)
264 for (i
= 0; i
< count
; i
++) {
266 regulator_set_voltage(regs
[i
].reg
, 0, INT_MAX
);
269 regulator_set_load(regs
[i
].reg
, 0);
271 regulator_disable(regs
[i
].reg
);
275 static int q6v5_clk_enable(struct device
*dev
,
276 struct clk
**clks
, int count
)
281 for (i
= 0; i
< count
; i
++) {
282 rc
= clk_prepare_enable(clks
[i
]);
284 dev_err(dev
, "Clock enable failed\n");
291 for (i
--; i
>= 0; i
--)
292 clk_disable_unprepare(clks
[i
]);
297 static void q6v5_clk_disable(struct device
*dev
,
298 struct clk
**clks
, int count
)
302 for (i
= 0; i
< count
; i
++)
303 clk_disable_unprepare(clks
[i
]);
306 static int q6v5_xfer_mem_ownership(struct q6v5
*qproc
, int *current_perm
,
307 bool remote_owner
, phys_addr_t addr
,
310 struct qcom_scm_vmperm next
;
312 if (!qproc
->need_mem_protection
)
314 if (remote_owner
&& *current_perm
== BIT(QCOM_SCM_VMID_MSS_MSA
))
316 if (!remote_owner
&& *current_perm
== BIT(QCOM_SCM_VMID_HLOS
))
319 next
.vmid
= remote_owner
? QCOM_SCM_VMID_MSS_MSA
: QCOM_SCM_VMID_HLOS
;
320 next
.perm
= remote_owner
? QCOM_SCM_PERM_RW
: QCOM_SCM_PERM_RWX
;
322 return qcom_scm_assign_mem(addr
, ALIGN(size
, SZ_4K
),
323 current_perm
, &next
, 1);
326 static int q6v5_load(struct rproc
*rproc
, const struct firmware
*fw
)
328 struct q6v5
*qproc
= rproc
->priv
;
330 memcpy(qproc
->mba_region
, fw
->data
, fw
->size
);
335 static int q6v5_rmb_pbl_wait(struct q6v5
*qproc
, int ms
)
337 unsigned long timeout
;
340 timeout
= jiffies
+ msecs_to_jiffies(ms
);
342 val
= readl(qproc
->rmb_base
+ RMB_PBL_STATUS_REG
);
346 if (time_after(jiffies
, timeout
))
355 static int q6v5_rmb_mba_wait(struct q6v5
*qproc
, u32 status
, int ms
)
358 unsigned long timeout
;
361 timeout
= jiffies
+ msecs_to_jiffies(ms
);
363 val
= readl(qproc
->rmb_base
+ RMB_MBA_STATUS_REG
);
369 else if (status
&& val
== status
)
372 if (time_after(jiffies
, timeout
))
381 static int q6v5proc_reset(struct q6v5
*qproc
)
388 if (qproc
->version
== MSS_MSM8996
) {
389 /* Override the ACC value if required */
390 writel(QDSP6SS_ACC_OVERRIDE_VAL
,
391 qproc
->reg_base
+ QDSP6SS_STRAP_ACC
);
393 /* Assert resets, stop core */
394 val
= readl(qproc
->reg_base
+ QDSP6SS_RESET_REG
);
395 val
|= Q6SS_CORE_ARES
| Q6SS_BUS_ARES_ENABLE
| Q6SS_STOP_CORE
;
396 writel(val
, qproc
->reg_base
+ QDSP6SS_RESET_REG
);
398 /* BHS require xo cbcr to be enabled */
399 val
= readl(qproc
->reg_base
+ QDSP6SS_XO_CBCR
);
401 writel(val
, qproc
->reg_base
+ QDSP6SS_XO_CBCR
);
403 /* Read CLKOFF bit to go low indicating CLK is enabled */
404 ret
= readl_poll_timeout(qproc
->reg_base
+ QDSP6SS_XO_CBCR
,
405 val
, !(val
& BIT(31)), 1,
406 HALT_CHECK_MAX_LOOPS
);
409 "xo cbcr enabling timed out (rc:%d)\n", ret
);
412 /* Enable power block headswitch and wait for it to stabilize */
413 val
= readl(qproc
->reg_base
+ QDSP6SS_PWR_CTL_REG
);
414 val
|= QDSP6v56_BHS_ON
;
415 writel(val
, qproc
->reg_base
+ QDSP6SS_PWR_CTL_REG
);
416 val
|= readl(qproc
->reg_base
+ QDSP6SS_PWR_CTL_REG
);
419 /* Put LDO in bypass mode */
420 val
|= QDSP6v56_LDO_BYP
;
421 writel(val
, qproc
->reg_base
+ QDSP6SS_PWR_CTL_REG
);
423 /* Deassert QDSP6 compiler memory clamp */
424 val
= readl(qproc
->reg_base
+ QDSP6SS_PWR_CTL_REG
);
425 val
&= ~QDSP6v56_CLAMP_QMC_MEM
;
426 writel(val
, qproc
->reg_base
+ QDSP6SS_PWR_CTL_REG
);
428 /* Deassert memory peripheral sleep and L2 memory standby */
429 val
|= Q6SS_L2DATA_STBY_N
| Q6SS_SLP_RET_N
;
430 writel(val
, qproc
->reg_base
+ QDSP6SS_PWR_CTL_REG
);
432 /* Turn on L1, L2, ETB and JU memories 1 at a time */
433 val
= readl(qproc
->reg_base
+ QDSP6SS_MEM_PWR_CTL
);
434 for (i
= 19; i
>= 0; i
--) {
436 writel(val
, qproc
->reg_base
+
437 QDSP6SS_MEM_PWR_CTL
);
439 * Read back value to ensure the write is done then
440 * wait for 1us for both memory peripheral and data
443 val
|= readl(qproc
->reg_base
+ QDSP6SS_MEM_PWR_CTL
);
446 /* Remove word line clamp */
447 val
= readl(qproc
->reg_base
+ QDSP6SS_PWR_CTL_REG
);
448 val
&= ~QDSP6v56_CLAMP_WL
;
449 writel(val
, qproc
->reg_base
+ QDSP6SS_PWR_CTL_REG
);
451 /* Assert resets, stop core */
452 val
= readl(qproc
->reg_base
+ QDSP6SS_RESET_REG
);
453 val
|= Q6SS_CORE_ARES
| Q6SS_BUS_ARES_ENABLE
| Q6SS_STOP_CORE
;
454 writel(val
, qproc
->reg_base
+ QDSP6SS_RESET_REG
);
456 /* Enable power block headswitch and wait for it to stabilize */
457 val
= readl(qproc
->reg_base
+ QDSP6SS_PWR_CTL_REG
);
458 val
|= QDSS_BHS_ON
| QDSS_LDO_BYP
;
459 writel(val
, qproc
->reg_base
+ QDSP6SS_PWR_CTL_REG
);
460 val
|= readl(qproc
->reg_base
+ QDSP6SS_PWR_CTL_REG
);
463 * Turn on memories. L2 banks should be done individually
464 * to minimize inrush current.
466 val
= readl(qproc
->reg_base
+ QDSP6SS_PWR_CTL_REG
);
467 val
|= Q6SS_SLP_RET_N
| Q6SS_L2TAG_SLP_NRET_N
|
468 Q6SS_ETB_SLP_NRET_N
| Q6SS_L2DATA_STBY_N
;
469 writel(val
, qproc
->reg_base
+ QDSP6SS_PWR_CTL_REG
);
470 val
|= Q6SS_L2DATA_SLP_NRET_N_2
;
471 writel(val
, qproc
->reg_base
+ QDSP6SS_PWR_CTL_REG
);
472 val
|= Q6SS_L2DATA_SLP_NRET_N_1
;
473 writel(val
, qproc
->reg_base
+ QDSP6SS_PWR_CTL_REG
);
474 val
|= Q6SS_L2DATA_SLP_NRET_N_0
;
475 writel(val
, qproc
->reg_base
+ QDSP6SS_PWR_CTL_REG
);
477 /* Remove IO clamp */
478 val
&= ~Q6SS_CLAMP_IO
;
479 writel(val
, qproc
->reg_base
+ QDSP6SS_PWR_CTL_REG
);
481 /* Bring core out of reset */
482 val
= readl(qproc
->reg_base
+ QDSP6SS_RESET_REG
);
483 val
&= ~Q6SS_CORE_ARES
;
484 writel(val
, qproc
->reg_base
+ QDSP6SS_RESET_REG
);
486 /* Turn on core clock */
487 val
= readl(qproc
->reg_base
+ QDSP6SS_GFMUX_CTL_REG
);
488 val
|= Q6SS_CLK_ENABLE
;
489 writel(val
, qproc
->reg_base
+ QDSP6SS_GFMUX_CTL_REG
);
491 /* Start core execution */
492 val
= readl(qproc
->reg_base
+ QDSP6SS_RESET_REG
);
493 val
&= ~Q6SS_STOP_CORE
;
494 writel(val
, qproc
->reg_base
+ QDSP6SS_RESET_REG
);
496 /* Wait for PBL status */
497 ret
= q6v5_rmb_pbl_wait(qproc
, 1000);
498 if (ret
== -ETIMEDOUT
) {
499 dev_err(qproc
->dev
, "PBL boot timed out\n");
500 } else if (ret
!= RMB_PBL_SUCCESS
) {
501 dev_err(qproc
->dev
, "PBL returned unexpected status %d\n", ret
);
510 static void q6v5proc_halt_axi_port(struct q6v5
*qproc
,
511 struct regmap
*halt_map
,
514 unsigned long timeout
;
518 /* Check if we're already idle */
519 ret
= regmap_read(halt_map
, offset
+ AXI_IDLE_REG
, &val
);
523 /* Assert halt request */
524 regmap_write(halt_map
, offset
+ AXI_HALTREQ_REG
, 1);
527 timeout
= jiffies
+ msecs_to_jiffies(HALT_ACK_TIMEOUT_MS
);
529 ret
= regmap_read(halt_map
, offset
+ AXI_HALTACK_REG
, &val
);
530 if (ret
|| val
|| time_after(jiffies
, timeout
))
536 ret
= regmap_read(halt_map
, offset
+ AXI_IDLE_REG
, &val
);
538 dev_err(qproc
->dev
, "port failed halt\n");
540 /* Clear halt request (port will remain halted until reset) */
541 regmap_write(halt_map
, offset
+ AXI_HALTREQ_REG
, 0);
544 static int q6v5_mpss_init_image(struct q6v5
*qproc
, const struct firmware
*fw
)
546 unsigned long dma_attrs
= DMA_ATTR_FORCE_CONTIGUOUS
;
553 ptr
= dma_alloc_attrs(qproc
->dev
, fw
->size
, &phys
, GFP_KERNEL
, dma_attrs
);
555 dev_err(qproc
->dev
, "failed to allocate mdt buffer\n");
559 memcpy(ptr
, fw
->data
, fw
->size
);
561 /* Hypervisor mapping to access metadata by modem */
562 mdata_perm
= BIT(QCOM_SCM_VMID_HLOS
);
563 ret
= q6v5_xfer_mem_ownership(qproc
, &mdata_perm
,
564 true, phys
, fw
->size
);
567 "assigning Q6 access to metadata failed: %d\n", ret
);
572 writel(phys
, qproc
->rmb_base
+ RMB_PMI_META_DATA_REG
);
573 writel(RMB_CMD_META_DATA_READY
, qproc
->rmb_base
+ RMB_MBA_COMMAND_REG
);
575 ret
= q6v5_rmb_mba_wait(qproc
, RMB_MBA_META_DATA_AUTH_SUCCESS
, 1000);
576 if (ret
== -ETIMEDOUT
)
577 dev_err(qproc
->dev
, "MPSS header authentication timed out\n");
579 dev_err(qproc
->dev
, "MPSS header authentication failed: %d\n", ret
);
581 /* Metadata authentication done, remove modem access */
582 xferop_ret
= q6v5_xfer_mem_ownership(qproc
, &mdata_perm
,
583 false, phys
, fw
->size
);
586 "mdt buffer not reclaimed system may become unstable\n");
589 dma_free_attrs(qproc
->dev
, fw
->size
, ptr
, phys
, dma_attrs
);
591 return ret
< 0 ? ret
: 0;
594 static bool q6v5_phdr_valid(const struct elf32_phdr
*phdr
)
596 if (phdr
->p_type
!= PT_LOAD
)
599 if ((phdr
->p_flags
& QCOM_MDT_TYPE_MASK
) == QCOM_MDT_TYPE_HASH
)
608 static int q6v5_mpss_load(struct q6v5
*qproc
)
610 const struct elf32_phdr
*phdrs
;
611 const struct elf32_phdr
*phdr
;
612 const struct firmware
*seg_fw
;
613 const struct firmware
*fw
;
614 struct elf32_hdr
*ehdr
;
615 phys_addr_t mpss_reloc
;
616 phys_addr_t boot_addr
;
617 phys_addr_t min_addr
= (phys_addr_t
)ULLONG_MAX
;
618 phys_addr_t max_addr
= 0;
619 bool relocate
= false;
627 ret
= request_firmware(&fw
, "modem.mdt", qproc
->dev
);
629 dev_err(qproc
->dev
, "unable to load modem.mdt\n");
633 /* Initialize the RMB validator */
634 writel(0, qproc
->rmb_base
+ RMB_PMI_CODE_LENGTH_REG
);
636 ret
= q6v5_mpss_init_image(qproc
, fw
);
638 goto release_firmware
;
640 ehdr
= (struct elf32_hdr
*)fw
->data
;
641 phdrs
= (struct elf32_phdr
*)(ehdr
+ 1);
643 for (i
= 0; i
< ehdr
->e_phnum
; i
++) {
646 if (!q6v5_phdr_valid(phdr
))
649 if (phdr
->p_flags
& QCOM_MDT_RELOCATABLE
)
652 if (phdr
->p_paddr
< min_addr
)
653 min_addr
= phdr
->p_paddr
;
655 if (phdr
->p_paddr
+ phdr
->p_memsz
> max_addr
)
656 max_addr
= ALIGN(phdr
->p_paddr
+ phdr
->p_memsz
, SZ_4K
);
659 mpss_reloc
= relocate
? min_addr
: qproc
->mpss_phys
;
660 /* Load firmware segments */
661 for (i
= 0; i
< ehdr
->e_phnum
; i
++) {
664 if (!q6v5_phdr_valid(phdr
))
667 offset
= phdr
->p_paddr
- mpss_reloc
;
668 if (offset
< 0 || offset
+ phdr
->p_memsz
> qproc
->mpss_size
) {
669 dev_err(qproc
->dev
, "segment outside memory range\n");
671 goto release_firmware
;
674 ptr
= qproc
->mpss_region
+ offset
;
676 if (phdr
->p_filesz
) {
677 snprintf(seg_name
, sizeof(seg_name
), "modem.b%02d", i
);
678 ret
= request_firmware(&seg_fw
, seg_name
, qproc
->dev
);
680 dev_err(qproc
->dev
, "failed to load %s\n", seg_name
);
681 goto release_firmware
;
684 memcpy(ptr
, seg_fw
->data
, seg_fw
->size
);
686 release_firmware(seg_fw
);
689 if (phdr
->p_memsz
> phdr
->p_filesz
) {
690 memset(ptr
+ phdr
->p_filesz
, 0,
691 phdr
->p_memsz
- phdr
->p_filesz
);
693 size
+= phdr
->p_memsz
;
696 /* Transfer ownership of modem ddr region to q6 */
697 ret
= q6v5_xfer_mem_ownership(qproc
, &qproc
->mpss_perm
, true,
698 qproc
->mpss_phys
, qproc
->mpss_size
);
701 "assigning Q6 access to mpss memory failed: %d\n", ret
);
703 goto release_firmware
;
706 boot_addr
= relocate
? qproc
->mpss_phys
: min_addr
;
707 writel(boot_addr
, qproc
->rmb_base
+ RMB_PMI_CODE_START_REG
);
708 writel(RMB_CMD_LOAD_READY
, qproc
->rmb_base
+ RMB_MBA_COMMAND_REG
);
709 writel(size
, qproc
->rmb_base
+ RMB_PMI_CODE_LENGTH_REG
);
711 ret
= q6v5_rmb_mba_wait(qproc
, RMB_MBA_AUTH_COMPLETE
, 10000);
712 if (ret
== -ETIMEDOUT
)
713 dev_err(qproc
->dev
, "MPSS authentication timed out\n");
715 dev_err(qproc
->dev
, "MPSS authentication failed: %d\n", ret
);
718 release_firmware(fw
);
720 return ret
< 0 ? ret
: 0;
723 static int q6v5_start(struct rproc
*rproc
)
725 struct q6v5
*qproc
= (struct q6v5
*)rproc
->priv
;
729 ret
= q6v5_regulator_enable(qproc
, qproc
->proxy_regs
,
730 qproc
->proxy_reg_count
);
732 dev_err(qproc
->dev
, "failed to enable proxy supplies\n");
736 ret
= q6v5_clk_enable(qproc
->dev
, qproc
->proxy_clks
,
737 qproc
->proxy_clk_count
);
739 dev_err(qproc
->dev
, "failed to enable proxy clocks\n");
740 goto disable_proxy_reg
;
743 ret
= q6v5_regulator_enable(qproc
, qproc
->active_regs
,
744 qproc
->active_reg_count
);
746 dev_err(qproc
->dev
, "failed to enable supplies\n");
747 goto disable_proxy_clk
;
749 ret
= reset_control_deassert(qproc
->mss_restart
);
751 dev_err(qproc
->dev
, "failed to deassert mss restart\n");
755 ret
= q6v5_clk_enable(qproc
->dev
, qproc
->active_clks
,
756 qproc
->active_clk_count
);
758 dev_err(qproc
->dev
, "failed to enable clocks\n");
762 /* Assign MBA image access in DDR to q6 */
763 xfermemop_ret
= q6v5_xfer_mem_ownership(qproc
, &qproc
->mba_perm
, true,
768 "assigning Q6 access to mba memory failed: %d\n",
770 goto disable_active_clks
;
773 writel(qproc
->mba_phys
, qproc
->rmb_base
+ RMB_MBA_IMAGE_REG
);
775 ret
= q6v5proc_reset(qproc
);
779 ret
= q6v5_rmb_mba_wait(qproc
, 0, 5000);
780 if (ret
== -ETIMEDOUT
) {
781 dev_err(qproc
->dev
, "MBA boot timed out\n");
783 } else if (ret
!= RMB_MBA_XPU_UNLOCKED
&&
784 ret
!= RMB_MBA_XPU_UNLOCKED_SCRIBBLED
) {
785 dev_err(qproc
->dev
, "MBA returned unexpected status %d\n", ret
);
790 dev_info(qproc
->dev
, "MBA booted, loading mpss\n");
792 ret
= q6v5_mpss_load(qproc
);
796 ret
= wait_for_completion_timeout(&qproc
->start_done
,
797 msecs_to_jiffies(5000));
799 dev_err(qproc
->dev
, "start timed out\n");
804 xfermemop_ret
= q6v5_xfer_mem_ownership(qproc
, &qproc
->mba_perm
, false,
809 "Failed to reclaim mba buffer system may become unstable\n");
810 qproc
->running
= true;
812 q6v5_clk_disable(qproc
->dev
, qproc
->proxy_clks
,
813 qproc
->proxy_clk_count
);
814 q6v5_regulator_disable(qproc
, qproc
->proxy_regs
,
815 qproc
->proxy_reg_count
);
820 xfermemop_ret
= q6v5_xfer_mem_ownership(qproc
, &qproc
->mpss_perm
,
821 false, qproc
->mpss_phys
,
823 WARN_ON(xfermemop_ret
);
826 q6v5proc_halt_axi_port(qproc
, qproc
->halt_map
, qproc
->halt_q6
);
827 q6v5proc_halt_axi_port(qproc
, qproc
->halt_map
, qproc
->halt_modem
);
828 q6v5proc_halt_axi_port(qproc
, qproc
->halt_map
, qproc
->halt_nc
);
831 xfermemop_ret
= q6v5_xfer_mem_ownership(qproc
, &qproc
->mba_perm
, false,
836 "Failed to reclaim mba buffer, system may become unstable\n");
840 q6v5_clk_disable(qproc
->dev
, qproc
->active_clks
,
841 qproc
->active_clk_count
);
844 reset_control_assert(qproc
->mss_restart
);
846 q6v5_regulator_disable(qproc
, qproc
->active_regs
,
847 qproc
->active_reg_count
);
849 q6v5_clk_disable(qproc
->dev
, qproc
->proxy_clks
,
850 qproc
->proxy_clk_count
);
852 q6v5_regulator_disable(qproc
, qproc
->proxy_regs
,
853 qproc
->proxy_reg_count
);
858 static int q6v5_stop(struct rproc
*rproc
)
860 struct q6v5
*qproc
= (struct q6v5
*)rproc
->priv
;
864 qproc
->running
= false;
866 qcom_smem_state_update_bits(qproc
->state
,
867 BIT(qproc
->stop_bit
), BIT(qproc
->stop_bit
));
869 ret
= wait_for_completion_timeout(&qproc
->stop_done
,
870 msecs_to_jiffies(5000));
872 dev_err(qproc
->dev
, "timed out on wait\n");
874 qcom_smem_state_update_bits(qproc
->state
, BIT(qproc
->stop_bit
), 0);
876 q6v5proc_halt_axi_port(qproc
, qproc
->halt_map
, qproc
->halt_q6
);
877 q6v5proc_halt_axi_port(qproc
, qproc
->halt_map
, qproc
->halt_modem
);
878 q6v5proc_halt_axi_port(qproc
, qproc
->halt_map
, qproc
->halt_nc
);
879 if (qproc
->version
== MSS_MSM8996
) {
881 * To avoid high MX current during LPASS/MSS restart.
883 val
= readl(qproc
->reg_base
+ QDSP6SS_PWR_CTL_REG
);
884 val
|= Q6SS_CLAMP_IO
| QDSP6v56_CLAMP_WL
|
885 QDSP6v56_CLAMP_QMC_MEM
;
886 writel(val
, qproc
->reg_base
+ QDSP6SS_PWR_CTL_REG
);
890 ret
= q6v5_xfer_mem_ownership(qproc
, &qproc
->mpss_perm
, false,
891 qproc
->mpss_phys
, qproc
->mpss_size
);
894 reset_control_assert(qproc
->mss_restart
);
895 q6v5_clk_disable(qproc
->dev
, qproc
->active_clks
,
896 qproc
->active_clk_count
);
897 q6v5_regulator_disable(qproc
, qproc
->active_regs
,
898 qproc
->active_reg_count
);
903 static void *q6v5_da_to_va(struct rproc
*rproc
, u64 da
, int len
)
905 struct q6v5
*qproc
= rproc
->priv
;
908 offset
= da
- qproc
->mpss_reloc
;
909 if (offset
< 0 || offset
+ len
> qproc
->mpss_size
)
912 return qproc
->mpss_region
+ offset
;
915 static const struct rproc_ops q6v5_ops
= {
918 .da_to_va
= q6v5_da_to_va
,
922 static irqreturn_t
q6v5_wdog_interrupt(int irq
, void *dev
)
924 struct q6v5
*qproc
= dev
;
928 /* Sometimes the stop triggers a watchdog rather than a stop-ack */
929 if (!qproc
->running
) {
930 complete(&qproc
->stop_done
);
934 msg
= qcom_smem_get(QCOM_SMEM_HOST_ANY
, MPSS_CRASH_REASON_SMEM
, &len
);
935 if (!IS_ERR(msg
) && len
> 0 && msg
[0])
936 dev_err(qproc
->dev
, "watchdog received: %s\n", msg
);
938 dev_err(qproc
->dev
, "watchdog without message\n");
940 rproc_report_crash(qproc
->rproc
, RPROC_WATCHDOG
);
948 static irqreturn_t
q6v5_fatal_interrupt(int irq
, void *dev
)
950 struct q6v5
*qproc
= dev
;
954 msg
= qcom_smem_get(QCOM_SMEM_HOST_ANY
, MPSS_CRASH_REASON_SMEM
, &len
);
955 if (!IS_ERR(msg
) && len
> 0 && msg
[0])
956 dev_err(qproc
->dev
, "fatal error received: %s\n", msg
);
958 dev_err(qproc
->dev
, "fatal error without message\n");
960 rproc_report_crash(qproc
->rproc
, RPROC_FATAL_ERROR
);
968 static irqreturn_t
q6v5_handover_interrupt(int irq
, void *dev
)
970 struct q6v5
*qproc
= dev
;
972 complete(&qproc
->start_done
);
976 static irqreturn_t
q6v5_stop_ack_interrupt(int irq
, void *dev
)
978 struct q6v5
*qproc
= dev
;
980 complete(&qproc
->stop_done
);
984 static int q6v5_init_mem(struct q6v5
*qproc
, struct platform_device
*pdev
)
986 struct of_phandle_args args
;
987 struct resource
*res
;
990 res
= platform_get_resource_byname(pdev
, IORESOURCE_MEM
, "qdsp6");
991 qproc
->reg_base
= devm_ioremap_resource(&pdev
->dev
, res
);
992 if (IS_ERR(qproc
->reg_base
))
993 return PTR_ERR(qproc
->reg_base
);
995 res
= platform_get_resource_byname(pdev
, IORESOURCE_MEM
, "rmb");
996 qproc
->rmb_base
= devm_ioremap_resource(&pdev
->dev
, res
);
997 if (IS_ERR(qproc
->rmb_base
))
998 return PTR_ERR(qproc
->rmb_base
);
1000 ret
= of_parse_phandle_with_fixed_args(pdev
->dev
.of_node
,
1001 "qcom,halt-regs", 3, 0, &args
);
1003 dev_err(&pdev
->dev
, "failed to parse qcom,halt-regs\n");
1007 qproc
->halt_map
= syscon_node_to_regmap(args
.np
);
1008 of_node_put(args
.np
);
1009 if (IS_ERR(qproc
->halt_map
))
1010 return PTR_ERR(qproc
->halt_map
);
1012 qproc
->halt_q6
= args
.args
[0];
1013 qproc
->halt_modem
= args
.args
[1];
1014 qproc
->halt_nc
= args
.args
[2];
1019 static int q6v5_init_clocks(struct device
*dev
, struct clk
**clks
,
1027 for (i
= 0; clk_names
[i
]; i
++) {
1028 clks
[i
] = devm_clk_get(dev
, clk_names
[i
]);
1029 if (IS_ERR(clks
[i
])) {
1030 int rc
= PTR_ERR(clks
[i
]);
1032 if (rc
!= -EPROBE_DEFER
)
1033 dev_err(dev
, "Failed to get %s clock\n",
1042 static int q6v5_init_reset(struct q6v5
*qproc
)
1044 qproc
->mss_restart
= devm_reset_control_get_exclusive(qproc
->dev
,
1046 if (IS_ERR(qproc
->mss_restart
)) {
1047 dev_err(qproc
->dev
, "failed to acquire mss restart\n");
1048 return PTR_ERR(qproc
->mss_restart
);
1054 static int q6v5_request_irq(struct q6v5
*qproc
,
1055 struct platform_device
*pdev
,
1057 irq_handler_t thread_fn
)
1061 ret
= platform_get_irq_byname(pdev
, name
);
1063 dev_err(&pdev
->dev
, "no %s IRQ defined\n", name
);
1067 ret
= devm_request_threaded_irq(&pdev
->dev
, ret
,
1069 IRQF_TRIGGER_RISING
| IRQF_ONESHOT
,
1072 dev_err(&pdev
->dev
, "request %s IRQ failed\n", name
);
1077 static int q6v5_alloc_memory_region(struct q6v5
*qproc
)
1079 struct device_node
*child
;
1080 struct device_node
*node
;
1084 child
= of_get_child_by_name(qproc
->dev
->of_node
, "mba");
1085 node
= of_parse_phandle(child
, "memory-region", 0);
1086 ret
= of_address_to_resource(node
, 0, &r
);
1088 dev_err(qproc
->dev
, "unable to resolve mba region\n");
1092 qproc
->mba_phys
= r
.start
;
1093 qproc
->mba_size
= resource_size(&r
);
1094 qproc
->mba_region
= devm_ioremap_wc(qproc
->dev
, qproc
->mba_phys
, qproc
->mba_size
);
1095 if (!qproc
->mba_region
) {
1096 dev_err(qproc
->dev
, "unable to map memory region: %pa+%zx\n",
1097 &r
.start
, qproc
->mba_size
);
1101 child
= of_get_child_by_name(qproc
->dev
->of_node
, "mpss");
1102 node
= of_parse_phandle(child
, "memory-region", 0);
1103 ret
= of_address_to_resource(node
, 0, &r
);
1105 dev_err(qproc
->dev
, "unable to resolve mpss region\n");
1109 qproc
->mpss_phys
= qproc
->mpss_reloc
= r
.start
;
1110 qproc
->mpss_size
= resource_size(&r
);
1111 qproc
->mpss_region
= devm_ioremap_wc(qproc
->dev
, qproc
->mpss_phys
, qproc
->mpss_size
);
1112 if (!qproc
->mpss_region
) {
1113 dev_err(qproc
->dev
, "unable to map memory region: %pa+%zx\n",
1114 &r
.start
, qproc
->mpss_size
);
1121 static int q6v5_probe(struct platform_device
*pdev
)
1123 const struct rproc_hexagon_res
*desc
;
1125 struct rproc
*rproc
;
1128 desc
= of_device_get_match_data(&pdev
->dev
);
1132 rproc
= rproc_alloc(&pdev
->dev
, pdev
->name
, &q6v5_ops
,
1133 desc
->hexagon_mba_image
, sizeof(*qproc
));
1135 dev_err(&pdev
->dev
, "failed to allocate rproc\n");
1139 qproc
= (struct q6v5
*)rproc
->priv
;
1140 qproc
->dev
= &pdev
->dev
;
1141 qproc
->rproc
= rproc
;
1142 platform_set_drvdata(pdev
, qproc
);
1144 init_completion(&qproc
->start_done
);
1145 init_completion(&qproc
->stop_done
);
1147 ret
= q6v5_init_mem(qproc
, pdev
);
1151 ret
= q6v5_alloc_memory_region(qproc
);
1155 ret
= q6v5_init_clocks(&pdev
->dev
, qproc
->proxy_clks
,
1156 desc
->proxy_clk_names
);
1158 dev_err(&pdev
->dev
, "Failed to get proxy clocks.\n");
1161 qproc
->proxy_clk_count
= ret
;
1163 ret
= q6v5_init_clocks(&pdev
->dev
, qproc
->active_clks
,
1164 desc
->active_clk_names
);
1166 dev_err(&pdev
->dev
, "Failed to get active clocks.\n");
1169 qproc
->active_clk_count
= ret
;
1171 ret
= q6v5_regulator_init(&pdev
->dev
, qproc
->proxy_regs
,
1172 desc
->proxy_supply
);
1174 dev_err(&pdev
->dev
, "Failed to get proxy regulators.\n");
1177 qproc
->proxy_reg_count
= ret
;
1179 ret
= q6v5_regulator_init(&pdev
->dev
, qproc
->active_regs
,
1180 desc
->active_supply
);
1182 dev_err(&pdev
->dev
, "Failed to get active regulators.\n");
1185 qproc
->active_reg_count
= ret
;
1187 ret
= q6v5_init_reset(qproc
);
1191 qproc
->version
= desc
->version
;
1192 qproc
->need_mem_protection
= desc
->need_mem_protection
;
1193 ret
= q6v5_request_irq(qproc
, pdev
, "wdog", q6v5_wdog_interrupt
);
1197 ret
= q6v5_request_irq(qproc
, pdev
, "fatal", q6v5_fatal_interrupt
);
1201 ret
= q6v5_request_irq(qproc
, pdev
, "handover", q6v5_handover_interrupt
);
1205 ret
= q6v5_request_irq(qproc
, pdev
, "stop-ack", q6v5_stop_ack_interrupt
);
1209 qproc
->state
= qcom_smem_state_get(&pdev
->dev
, "stop", &qproc
->stop_bit
);
1210 if (IS_ERR(qproc
->state
)) {
1211 ret
= PTR_ERR(qproc
->state
);
1214 qproc
->mpss_perm
= BIT(QCOM_SCM_VMID_HLOS
);
1215 qproc
->mba_perm
= BIT(QCOM_SCM_VMID_HLOS
);
1216 qcom_add_smd_subdev(rproc
, &qproc
->smd_subdev
);
1217 qcom_add_ssr_subdev(rproc
, &qproc
->ssr_subdev
, "mpss");
1219 ret
= rproc_add(rproc
);
1231 static int q6v5_remove(struct platform_device
*pdev
)
1233 struct q6v5
*qproc
= platform_get_drvdata(pdev
);
1235 rproc_del(qproc
->rproc
);
1237 qcom_remove_smd_subdev(qproc
->rproc
, &qproc
->smd_subdev
);
1238 qcom_remove_ssr_subdev(qproc
->rproc
, &qproc
->ssr_subdev
);
1239 rproc_free(qproc
->rproc
);
1244 static const struct rproc_hexagon_res msm8996_mss
= {
1245 .hexagon_mba_image
= "mba.mbn",
1246 .proxy_clk_names
= (char*[]){
1251 .active_clk_names
= (char*[]){
1258 .need_mem_protection
= true,
1259 .version
= MSS_MSM8996
,
1262 static const struct rproc_hexagon_res msm8916_mss
= {
1263 .hexagon_mba_image
= "mba.mbn",
1264 .proxy_supply
= (struct qcom_mss_reg_res
[]) {
1279 .proxy_clk_names
= (char*[]){
1283 .active_clk_names
= (char*[]){
1289 .need_mem_protection
= false,
1290 .version
= MSS_MSM8916
,
1293 static const struct rproc_hexagon_res msm8974_mss
= {
1294 .hexagon_mba_image
= "mba.b00",
1295 .proxy_supply
= (struct qcom_mss_reg_res
[]) {
1310 .active_supply
= (struct qcom_mss_reg_res
[]) {
1318 .proxy_clk_names
= (char*[]){
1322 .active_clk_names
= (char*[]){
1328 .need_mem_protection
= false,
1329 .version
= MSS_MSM8974
,
1332 static const struct of_device_id q6v5_of_match
[] = {
1333 { .compatible
= "qcom,q6v5-pil", .data
= &msm8916_mss
},
1334 { .compatible
= "qcom,msm8916-mss-pil", .data
= &msm8916_mss
},
1335 { .compatible
= "qcom,msm8974-mss-pil", .data
= &msm8974_mss
},
1336 { .compatible
= "qcom,msm8996-mss-pil", .data
= &msm8996_mss
},
1339 MODULE_DEVICE_TABLE(of
, q6v5_of_match
);
1341 static struct platform_driver q6v5_driver
= {
1342 .probe
= q6v5_probe
,
1343 .remove
= q6v5_remove
,
1345 .name
= "qcom-q6v5-pil",
1346 .of_match_table
= q6v5_of_match
,
1349 module_platform_driver(q6v5_driver
);
1351 MODULE_DESCRIPTION("Peripheral Image Loader for Hexagon");
1352 MODULE_LICENSE("GPL v2");