1 // SPDX-License-Identifier: GPL-2.0-only
3 * Qualcomm self-authenticating modem subsystem remoteproc driver
5 * Copyright (C) 2016 Linaro Ltd.
6 * Copyright (C) 2014 Sony Mobile Communications AB
7 * Copyright (c) 2012-2013, The Linux Foundation. All rights reserved.
10 #include <linux/clk.h>
11 #include <linux/delay.h>
12 #include <linux/devcoredump.h>
13 #include <linux/dma-mapping.h>
14 #include <linux/interrupt.h>
15 #include <linux/kernel.h>
16 #include <linux/mfd/syscon.h>
17 #include <linux/module.h>
18 #include <linux/of_address.h>
19 #include <linux/of_device.h>
20 #include <linux/platform_device.h>
21 #include <linux/pm_domain.h>
22 #include <linux/pm_runtime.h>
23 #include <linux/regmap.h>
24 #include <linux/regulator/consumer.h>
25 #include <linux/remoteproc.h>
26 #include <linux/reset.h>
27 #include <linux/soc/qcom/mdt_loader.h>
28 #include <linux/iopoll.h>
29 #include <linux/slab.h>
31 #include "remoteproc_internal.h"
32 #include "qcom_common.h"
33 #include "qcom_pil_info.h"
34 #include "qcom_q6v5.h"
36 #include <linux/qcom_scm.h>
38 #define MPSS_CRASH_REASON_SMEM 421
40 #define MBA_LOG_SIZE SZ_4K
42 /* RMB Status Register Values */
43 #define RMB_PBL_SUCCESS 0x1
45 #define RMB_MBA_XPU_UNLOCKED 0x1
46 #define RMB_MBA_XPU_UNLOCKED_SCRIBBLED 0x2
47 #define RMB_MBA_META_DATA_AUTH_SUCCESS 0x3
48 #define RMB_MBA_AUTH_COMPLETE 0x4
50 /* PBL/MBA interface registers */
51 #define RMB_MBA_IMAGE_REG 0x00
52 #define RMB_PBL_STATUS_REG 0x04
53 #define RMB_MBA_COMMAND_REG 0x08
54 #define RMB_MBA_STATUS_REG 0x0C
55 #define RMB_PMI_META_DATA_REG 0x10
56 #define RMB_PMI_CODE_START_REG 0x14
57 #define RMB_PMI_CODE_LENGTH_REG 0x18
58 #define RMB_MBA_MSS_STATUS 0x40
59 #define RMB_MBA_ALT_RESET 0x44
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 QDSP6V6SS_MEM_PWR_CTL 0x034
70 #define QDSP6SS_STRAP_ACC 0x110
72 /* AXI Halt Register Offsets */
73 #define AXI_HALTREQ_REG 0x0
74 #define AXI_HALTACK_REG 0x4
75 #define AXI_IDLE_REG 0x8
76 #define AXI_GATING_VALID_OVERRIDE BIT(0)
78 #define HALT_ACK_TIMEOUT_US 100000
81 #define Q6SS_STOP_CORE BIT(0)
82 #define Q6SS_CORE_ARES BIT(1)
83 #define Q6SS_BUS_ARES_ENABLE BIT(2)
86 #define Q6SS_CBCR_CLKEN BIT(0)
87 #define Q6SS_CBCR_CLKOFF BIT(31)
88 #define Q6SS_CBCR_TIMEOUT_US 200
90 /* QDSP6SS_GFMUX_CTL */
91 #define Q6SS_CLK_ENABLE BIT(1)
94 #define Q6SS_L2DATA_SLP_NRET_N_0 BIT(0)
95 #define Q6SS_L2DATA_SLP_NRET_N_1 BIT(1)
96 #define Q6SS_L2DATA_SLP_NRET_N_2 BIT(2)
97 #define Q6SS_L2TAG_SLP_NRET_N BIT(16)
98 #define Q6SS_ETB_SLP_NRET_N BIT(17)
99 #define Q6SS_L2DATA_STBY_N BIT(18)
100 #define Q6SS_SLP_RET_N BIT(19)
101 #define Q6SS_CLAMP_IO BIT(20)
102 #define QDSS_BHS_ON BIT(21)
103 #define QDSS_LDO_BYP BIT(22)
105 /* QDSP6v56 parameters */
106 #define QDSP6v56_LDO_BYP BIT(25)
107 #define QDSP6v56_BHS_ON BIT(24)
108 #define QDSP6v56_CLAMP_WL BIT(21)
109 #define QDSP6v56_CLAMP_QMC_MEM BIT(22)
110 #define QDSP6SS_XO_CBCR 0x0038
111 #define QDSP6SS_ACC_OVERRIDE_VAL 0x20
113 /* QDSP6v65 parameters */
114 #define QDSP6SS_CORE_CBCR 0x20
115 #define QDSP6SS_SLEEP 0x3C
116 #define QDSP6SS_BOOT_CORE_START 0x400
117 #define QDSP6SS_BOOT_CMD 0x404
118 #define BOOT_FSM_TIMEOUT 10000
121 struct regulator
*reg
;
126 struct qcom_mss_reg_res
{
132 struct rproc_hexagon_res
{
133 const char *hexagon_mba_image
;
134 struct qcom_mss_reg_res
*proxy_supply
;
135 struct qcom_mss_reg_res
*fallback_proxy_supply
;
136 struct qcom_mss_reg_res
*active_supply
;
137 char **proxy_clk_names
;
138 char **reset_clk_names
;
139 char **active_clk_names
;
140 char **active_pd_names
;
141 char **proxy_pd_names
;
143 bool need_mem_protection
;
153 void __iomem
*reg_base
;
154 void __iomem
*rmb_base
;
156 struct regmap
*halt_map
;
157 struct regmap
*conn_map
;
164 struct reset_control
*mss_restart
;
165 struct reset_control
*pdc_reset
;
167 struct qcom_q6v5 q6v5
;
169 struct clk
*active_clks
[8];
170 struct clk
*reset_clks
[4];
171 struct clk
*proxy_clks
[4];
172 struct device
*active_pds
[1];
173 struct device
*proxy_pds
[3];
174 int active_clk_count
;
180 struct reg_info active_regs
[1];
181 struct reg_info proxy_regs
[1];
182 struct reg_info fallback_proxy_regs
[2];
183 int active_reg_count
;
185 int fallback_proxy_reg_count
;
187 bool dump_mba_loaded
;
188 size_t current_dump_size
;
189 size_t total_dump_size
;
191 phys_addr_t mba_phys
;
195 phys_addr_t mpss_phys
;
196 phys_addr_t mpss_reloc
;
199 struct qcom_rproc_glink glink_subdev
;
200 struct qcom_rproc_subdev smd_subdev
;
201 struct qcom_rproc_ssr ssr_subdev
;
202 struct qcom_sysmon
*sysmon
;
203 bool need_mem_protection
;
209 const char *hexagon_mdt_image
;
222 static int q6v5_regulator_init(struct device
*dev
, struct reg_info
*regs
,
223 const struct qcom_mss_reg_res
*reg_res
)
231 for (i
= 0; reg_res
[i
].supply
; i
++) {
232 regs
[i
].reg
= devm_regulator_get(dev
, reg_res
[i
].supply
);
233 if (IS_ERR(regs
[i
].reg
)) {
234 rc
= PTR_ERR(regs
[i
].reg
);
235 if (rc
!= -EPROBE_DEFER
)
236 dev_err(dev
, "Failed to get %s\n regulator",
241 regs
[i
].uV
= reg_res
[i
].uV
;
242 regs
[i
].uA
= reg_res
[i
].uA
;
248 static int q6v5_regulator_enable(struct q6v5
*qproc
,
249 struct reg_info
*regs
, int count
)
254 for (i
= 0; i
< count
; i
++) {
255 if (regs
[i
].uV
> 0) {
256 ret
= regulator_set_voltage(regs
[i
].reg
,
257 regs
[i
].uV
, INT_MAX
);
260 "Failed to request voltage for %d.\n",
266 if (regs
[i
].uA
> 0) {
267 ret
= regulator_set_load(regs
[i
].reg
,
271 "Failed to set regulator mode\n");
276 ret
= regulator_enable(regs
[i
].reg
);
278 dev_err(qproc
->dev
, "Regulator enable failed\n");
285 for (; i
>= 0; i
--) {
287 regulator_set_voltage(regs
[i
].reg
, 0, INT_MAX
);
290 regulator_set_load(regs
[i
].reg
, 0);
292 regulator_disable(regs
[i
].reg
);
298 static void q6v5_regulator_disable(struct q6v5
*qproc
,
299 struct reg_info
*regs
, int count
)
303 for (i
= 0; i
< count
; i
++) {
305 regulator_set_voltage(regs
[i
].reg
, 0, INT_MAX
);
308 regulator_set_load(regs
[i
].reg
, 0);
310 regulator_disable(regs
[i
].reg
);
314 static int q6v5_clk_enable(struct device
*dev
,
315 struct clk
**clks
, int count
)
320 for (i
= 0; i
< count
; i
++) {
321 rc
= clk_prepare_enable(clks
[i
]);
323 dev_err(dev
, "Clock enable failed\n");
330 for (i
--; i
>= 0; i
--)
331 clk_disable_unprepare(clks
[i
]);
336 static void q6v5_clk_disable(struct device
*dev
,
337 struct clk
**clks
, int count
)
341 for (i
= 0; i
< count
; i
++)
342 clk_disable_unprepare(clks
[i
]);
345 static int q6v5_pds_enable(struct q6v5
*qproc
, struct device
**pds
,
351 for (i
= 0; i
< pd_count
; i
++) {
352 dev_pm_genpd_set_performance_state(pds
[i
], INT_MAX
);
353 ret
= pm_runtime_get_sync(pds
[i
]);
355 pm_runtime_put_noidle(pds
[i
]);
356 dev_pm_genpd_set_performance_state(pds
[i
], 0);
357 goto unroll_pd_votes
;
364 for (i
--; i
>= 0; i
--) {
365 dev_pm_genpd_set_performance_state(pds
[i
], 0);
366 pm_runtime_put(pds
[i
]);
372 static void q6v5_pds_disable(struct q6v5
*qproc
, struct device
**pds
,
377 for (i
= 0; i
< pd_count
; i
++) {
378 dev_pm_genpd_set_performance_state(pds
[i
], 0);
379 pm_runtime_put(pds
[i
]);
383 static int q6v5_xfer_mem_ownership(struct q6v5
*qproc
, int *current_perm
,
384 bool local
, bool remote
, phys_addr_t addr
,
387 struct qcom_scm_vmperm next
[2];
390 if (!qproc
->need_mem_protection
)
393 if (local
== !!(*current_perm
& BIT(QCOM_SCM_VMID_HLOS
)) &&
394 remote
== !!(*current_perm
& BIT(QCOM_SCM_VMID_MSS_MSA
)))
398 next
[perms
].vmid
= QCOM_SCM_VMID_HLOS
;
399 next
[perms
].perm
= QCOM_SCM_PERM_RWX
;
404 next
[perms
].vmid
= QCOM_SCM_VMID_MSS_MSA
;
405 next
[perms
].perm
= QCOM_SCM_PERM_RW
;
409 return qcom_scm_assign_mem(addr
, ALIGN(size
, SZ_4K
),
410 current_perm
, next
, perms
);
413 static void q6v5_debug_policy_load(struct q6v5
*qproc
, void *mba_region
)
415 const struct firmware
*dp_fw
;
417 if (request_firmware_direct(&dp_fw
, "msadp", qproc
->dev
))
420 if (SZ_1M
+ dp_fw
->size
<= qproc
->mba_size
) {
421 memcpy(mba_region
+ SZ_1M
, dp_fw
->data
, dp_fw
->size
);
422 qproc
->dp_size
= dp_fw
->size
;
425 release_firmware(dp_fw
);
428 static int q6v5_load(struct rproc
*rproc
, const struct firmware
*fw
)
430 struct q6v5
*qproc
= rproc
->priv
;
433 /* MBA is restricted to a maximum size of 1M */
434 if (fw
->size
> qproc
->mba_size
|| fw
->size
> SZ_1M
) {
435 dev_err(qproc
->dev
, "MBA firmware load failed\n");
439 mba_region
= memremap(qproc
->mba_phys
, qproc
->mba_size
, MEMREMAP_WC
);
441 dev_err(qproc
->dev
, "unable to map memory region: %pa+%zx\n",
442 &qproc
->mba_phys
, qproc
->mba_size
);
446 memcpy(mba_region
, fw
->data
, fw
->size
);
447 q6v5_debug_policy_load(qproc
, mba_region
);
448 memunmap(mba_region
);
453 static int q6v5_reset_assert(struct q6v5
*qproc
)
457 if (qproc
->has_alt_reset
) {
458 reset_control_assert(qproc
->pdc_reset
);
459 ret
= reset_control_reset(qproc
->mss_restart
);
460 reset_control_deassert(qproc
->pdc_reset
);
461 } else if (qproc
->has_spare_reg
) {
463 * When the AXI pipeline is being reset with the Q6 modem partly
464 * operational there is possibility of AXI valid signal to
465 * glitch, leading to spurious transactions and Q6 hangs. A work
466 * around is employed by asserting the AXI_GATING_VALID_OVERRIDE
467 * BIT before triggering Q6 MSS reset. AXI_GATING_VALID_OVERRIDE
468 * is withdrawn post MSS assert followed by a MSS deassert,
469 * while holding the PDC reset.
471 reset_control_assert(qproc
->pdc_reset
);
472 regmap_update_bits(qproc
->conn_map
, qproc
->conn_box
,
473 AXI_GATING_VALID_OVERRIDE
, 1);
474 reset_control_assert(qproc
->mss_restart
);
475 reset_control_deassert(qproc
->pdc_reset
);
476 regmap_update_bits(qproc
->conn_map
, qproc
->conn_box
,
477 AXI_GATING_VALID_OVERRIDE
, 0);
478 ret
= reset_control_deassert(qproc
->mss_restart
);
480 ret
= reset_control_assert(qproc
->mss_restart
);
486 static int q6v5_reset_deassert(struct q6v5
*qproc
)
490 if (qproc
->has_alt_reset
) {
491 reset_control_assert(qproc
->pdc_reset
);
492 writel(1, qproc
->rmb_base
+ RMB_MBA_ALT_RESET
);
493 ret
= reset_control_reset(qproc
->mss_restart
);
494 writel(0, qproc
->rmb_base
+ RMB_MBA_ALT_RESET
);
495 reset_control_deassert(qproc
->pdc_reset
);
496 } else if (qproc
->has_spare_reg
) {
497 ret
= reset_control_reset(qproc
->mss_restart
);
499 ret
= reset_control_deassert(qproc
->mss_restart
);
505 static int q6v5_rmb_pbl_wait(struct q6v5
*qproc
, int ms
)
507 unsigned long timeout
;
510 timeout
= jiffies
+ msecs_to_jiffies(ms
);
512 val
= readl(qproc
->rmb_base
+ RMB_PBL_STATUS_REG
);
516 if (time_after(jiffies
, timeout
))
525 static int q6v5_rmb_mba_wait(struct q6v5
*qproc
, u32 status
, int ms
)
528 unsigned long timeout
;
531 timeout
= jiffies
+ msecs_to_jiffies(ms
);
533 val
= readl(qproc
->rmb_base
+ RMB_MBA_STATUS_REG
);
539 else if (status
&& val
== status
)
542 if (time_after(jiffies
, timeout
))
551 static void q6v5_dump_mba_logs(struct q6v5
*qproc
)
553 struct rproc
*rproc
= qproc
->rproc
;
557 if (!qproc
->has_mba_logs
)
560 if (q6v5_xfer_mem_ownership(qproc
, &qproc
->mba_perm
, true, false, qproc
->mba_phys
,
564 mba_region
= memremap(qproc
->mba_phys
, qproc
->mba_size
, MEMREMAP_WC
);
568 data
= vmalloc(MBA_LOG_SIZE
);
570 memcpy(data
, mba_region
, MBA_LOG_SIZE
);
571 dev_coredumpv(&rproc
->dev
, data
, MBA_LOG_SIZE
, GFP_KERNEL
);
573 memunmap(mba_region
);
576 static int q6v5proc_reset(struct q6v5
*qproc
)
582 if (qproc
->version
== MSS_SDM845
) {
583 val
= readl(qproc
->reg_base
+ QDSP6SS_SLEEP
);
584 val
|= Q6SS_CBCR_CLKEN
;
585 writel(val
, qproc
->reg_base
+ QDSP6SS_SLEEP
);
587 ret
= readl_poll_timeout(qproc
->reg_base
+ QDSP6SS_SLEEP
,
588 val
, !(val
& Q6SS_CBCR_CLKOFF
), 1,
589 Q6SS_CBCR_TIMEOUT_US
);
591 dev_err(qproc
->dev
, "QDSP6SS Sleep clock timed out\n");
595 /* De-assert QDSP6 stop core */
596 writel(1, qproc
->reg_base
+ QDSP6SS_BOOT_CORE_START
);
597 /* Trigger boot FSM */
598 writel(1, qproc
->reg_base
+ QDSP6SS_BOOT_CMD
);
600 ret
= readl_poll_timeout(qproc
->rmb_base
+ RMB_MBA_MSS_STATUS
,
601 val
, (val
& BIT(0)) != 0, 10, BOOT_FSM_TIMEOUT
);
603 dev_err(qproc
->dev
, "Boot FSM failed to complete.\n");
604 /* Reset the modem so that boot FSM is in reset state */
605 q6v5_reset_deassert(qproc
);
610 } else if (qproc
->version
== MSS_SC7180
) {
611 val
= readl(qproc
->reg_base
+ QDSP6SS_SLEEP
);
612 val
|= Q6SS_CBCR_CLKEN
;
613 writel(val
, qproc
->reg_base
+ QDSP6SS_SLEEP
);
615 ret
= readl_poll_timeout(qproc
->reg_base
+ QDSP6SS_SLEEP
,
616 val
, !(val
& Q6SS_CBCR_CLKOFF
), 1,
617 Q6SS_CBCR_TIMEOUT_US
);
619 dev_err(qproc
->dev
, "QDSP6SS Sleep clock timed out\n");
623 /* Turn on the XO clock needed for PLL setup */
624 val
= readl(qproc
->reg_base
+ QDSP6SS_XO_CBCR
);
625 val
|= Q6SS_CBCR_CLKEN
;
626 writel(val
, qproc
->reg_base
+ QDSP6SS_XO_CBCR
);
628 ret
= readl_poll_timeout(qproc
->reg_base
+ QDSP6SS_XO_CBCR
,
629 val
, !(val
& Q6SS_CBCR_CLKOFF
), 1,
630 Q6SS_CBCR_TIMEOUT_US
);
632 dev_err(qproc
->dev
, "QDSP6SS XO clock timed out\n");
636 /* Configure Q6 core CBCR to auto-enable after reset sequence */
637 val
= readl(qproc
->reg_base
+ QDSP6SS_CORE_CBCR
);
638 val
|= Q6SS_CBCR_CLKEN
;
639 writel(val
, qproc
->reg_base
+ QDSP6SS_CORE_CBCR
);
641 /* De-assert the Q6 stop core signal */
642 writel(1, qproc
->reg_base
+ QDSP6SS_BOOT_CORE_START
);
644 /* Wait for 10 us for any staggering logic to settle */
645 usleep_range(10, 20);
647 /* Trigger the boot FSM to start the Q6 out-of-reset sequence */
648 writel(1, qproc
->reg_base
+ QDSP6SS_BOOT_CMD
);
650 /* Poll the MSS_STATUS for FSM completion */
651 ret
= readl_poll_timeout(qproc
->rmb_base
+ RMB_MBA_MSS_STATUS
,
652 val
, (val
& BIT(0)) != 0, 10, BOOT_FSM_TIMEOUT
);
654 dev_err(qproc
->dev
, "Boot FSM failed to complete.\n");
655 /* Reset the modem so that boot FSM is in reset state */
656 q6v5_reset_deassert(qproc
);
660 } else if (qproc
->version
== MSS_MSM8996
||
661 qproc
->version
== MSS_MSM8998
) {
664 /* Override the ACC value if required */
665 writel(QDSP6SS_ACC_OVERRIDE_VAL
,
666 qproc
->reg_base
+ QDSP6SS_STRAP_ACC
);
668 /* Assert resets, stop core */
669 val
= readl(qproc
->reg_base
+ QDSP6SS_RESET_REG
);
670 val
|= Q6SS_CORE_ARES
| Q6SS_BUS_ARES_ENABLE
| Q6SS_STOP_CORE
;
671 writel(val
, qproc
->reg_base
+ QDSP6SS_RESET_REG
);
673 /* BHS require xo cbcr to be enabled */
674 val
= readl(qproc
->reg_base
+ QDSP6SS_XO_CBCR
);
675 val
|= Q6SS_CBCR_CLKEN
;
676 writel(val
, qproc
->reg_base
+ QDSP6SS_XO_CBCR
);
678 /* Read CLKOFF bit to go low indicating CLK is enabled */
679 ret
= readl_poll_timeout(qproc
->reg_base
+ QDSP6SS_XO_CBCR
,
680 val
, !(val
& Q6SS_CBCR_CLKOFF
), 1,
681 Q6SS_CBCR_TIMEOUT_US
);
684 "xo cbcr enabling timed out (rc:%d)\n", ret
);
687 /* Enable power block headswitch and wait for it to stabilize */
688 val
= readl(qproc
->reg_base
+ QDSP6SS_PWR_CTL_REG
);
689 val
|= QDSP6v56_BHS_ON
;
690 writel(val
, qproc
->reg_base
+ QDSP6SS_PWR_CTL_REG
);
691 val
|= readl(qproc
->reg_base
+ QDSP6SS_PWR_CTL_REG
);
694 /* Put LDO in bypass mode */
695 val
|= QDSP6v56_LDO_BYP
;
696 writel(val
, qproc
->reg_base
+ QDSP6SS_PWR_CTL_REG
);
698 /* Deassert QDSP6 compiler memory clamp */
699 val
= readl(qproc
->reg_base
+ QDSP6SS_PWR_CTL_REG
);
700 val
&= ~QDSP6v56_CLAMP_QMC_MEM
;
701 writel(val
, qproc
->reg_base
+ QDSP6SS_PWR_CTL_REG
);
703 /* Deassert memory peripheral sleep and L2 memory standby */
704 val
|= Q6SS_L2DATA_STBY_N
| Q6SS_SLP_RET_N
;
705 writel(val
, qproc
->reg_base
+ QDSP6SS_PWR_CTL_REG
);
707 /* Turn on L1, L2, ETB and JU memories 1 at a time */
708 if (qproc
->version
== MSS_MSM8996
) {
709 mem_pwr_ctl
= QDSP6SS_MEM_PWR_CTL
;
713 mem_pwr_ctl
= QDSP6V6SS_MEM_PWR_CTL
;
716 val
= readl(qproc
->reg_base
+ mem_pwr_ctl
);
717 for (; i
>= 0; i
--) {
719 writel(val
, qproc
->reg_base
+ mem_pwr_ctl
);
721 * Read back value to ensure the write is done then
722 * wait for 1us for both memory peripheral and data
725 val
|= readl(qproc
->reg_base
+ mem_pwr_ctl
);
728 /* Remove word line clamp */
729 val
= readl(qproc
->reg_base
+ QDSP6SS_PWR_CTL_REG
);
730 val
&= ~QDSP6v56_CLAMP_WL
;
731 writel(val
, qproc
->reg_base
+ QDSP6SS_PWR_CTL_REG
);
733 /* Assert resets, stop core */
734 val
= readl(qproc
->reg_base
+ QDSP6SS_RESET_REG
);
735 val
|= Q6SS_CORE_ARES
| Q6SS_BUS_ARES_ENABLE
| Q6SS_STOP_CORE
;
736 writel(val
, qproc
->reg_base
+ QDSP6SS_RESET_REG
);
738 /* Enable power block headswitch and wait for it to stabilize */
739 val
= readl(qproc
->reg_base
+ QDSP6SS_PWR_CTL_REG
);
740 val
|= QDSS_BHS_ON
| QDSS_LDO_BYP
;
741 writel(val
, qproc
->reg_base
+ QDSP6SS_PWR_CTL_REG
);
742 val
|= readl(qproc
->reg_base
+ QDSP6SS_PWR_CTL_REG
);
745 * Turn on memories. L2 banks should be done individually
746 * to minimize inrush current.
748 val
= readl(qproc
->reg_base
+ QDSP6SS_PWR_CTL_REG
);
749 val
|= Q6SS_SLP_RET_N
| Q6SS_L2TAG_SLP_NRET_N
|
750 Q6SS_ETB_SLP_NRET_N
| Q6SS_L2DATA_STBY_N
;
751 writel(val
, qproc
->reg_base
+ QDSP6SS_PWR_CTL_REG
);
752 val
|= Q6SS_L2DATA_SLP_NRET_N_2
;
753 writel(val
, qproc
->reg_base
+ QDSP6SS_PWR_CTL_REG
);
754 val
|= Q6SS_L2DATA_SLP_NRET_N_1
;
755 writel(val
, qproc
->reg_base
+ QDSP6SS_PWR_CTL_REG
);
756 val
|= Q6SS_L2DATA_SLP_NRET_N_0
;
757 writel(val
, qproc
->reg_base
+ QDSP6SS_PWR_CTL_REG
);
759 /* Remove IO clamp */
760 val
&= ~Q6SS_CLAMP_IO
;
761 writel(val
, qproc
->reg_base
+ QDSP6SS_PWR_CTL_REG
);
763 /* Bring core out of reset */
764 val
= readl(qproc
->reg_base
+ QDSP6SS_RESET_REG
);
765 val
&= ~Q6SS_CORE_ARES
;
766 writel(val
, qproc
->reg_base
+ QDSP6SS_RESET_REG
);
768 /* Turn on core clock */
769 val
= readl(qproc
->reg_base
+ QDSP6SS_GFMUX_CTL_REG
);
770 val
|= Q6SS_CLK_ENABLE
;
771 writel(val
, qproc
->reg_base
+ QDSP6SS_GFMUX_CTL_REG
);
773 /* Start core execution */
774 val
= readl(qproc
->reg_base
+ QDSP6SS_RESET_REG
);
775 val
&= ~Q6SS_STOP_CORE
;
776 writel(val
, qproc
->reg_base
+ QDSP6SS_RESET_REG
);
779 /* Wait for PBL status */
780 ret
= q6v5_rmb_pbl_wait(qproc
, 1000);
781 if (ret
== -ETIMEDOUT
) {
782 dev_err(qproc
->dev
, "PBL boot timed out\n");
783 } else if (ret
!= RMB_PBL_SUCCESS
) {
784 dev_err(qproc
->dev
, "PBL returned unexpected status %d\n", ret
);
793 static void q6v5proc_halt_axi_port(struct q6v5
*qproc
,
794 struct regmap
*halt_map
,
800 /* Check if we're already idle */
801 ret
= regmap_read(halt_map
, offset
+ AXI_IDLE_REG
, &val
);
805 /* Assert halt request */
806 regmap_write(halt_map
, offset
+ AXI_HALTREQ_REG
, 1);
809 regmap_read_poll_timeout(halt_map
, offset
+ AXI_HALTACK_REG
, val
,
810 val
, 1000, HALT_ACK_TIMEOUT_US
);
812 ret
= regmap_read(halt_map
, offset
+ AXI_IDLE_REG
, &val
);
814 dev_err(qproc
->dev
, "port failed halt\n");
816 /* Clear halt request (port will remain halted until reset) */
817 regmap_write(halt_map
, offset
+ AXI_HALTREQ_REG
, 0);
820 static int q6v5_mpss_init_image(struct q6v5
*qproc
, const struct firmware
*fw
)
822 unsigned long dma_attrs
= DMA_ATTR_FORCE_CONTIGUOUS
;
831 metadata
= qcom_mdt_read_metadata(fw
, &size
);
832 if (IS_ERR(metadata
))
833 return PTR_ERR(metadata
);
835 ptr
= dma_alloc_attrs(qproc
->dev
, size
, &phys
, GFP_KERNEL
, dma_attrs
);
838 dev_err(qproc
->dev
, "failed to allocate mdt buffer\n");
842 memcpy(ptr
, metadata
, size
);
844 /* Hypervisor mapping to access metadata by modem */
845 mdata_perm
= BIT(QCOM_SCM_VMID_HLOS
);
846 ret
= q6v5_xfer_mem_ownership(qproc
, &mdata_perm
, false, true,
850 "assigning Q6 access to metadata failed: %d\n", ret
);
855 writel(phys
, qproc
->rmb_base
+ RMB_PMI_META_DATA_REG
);
856 writel(RMB_CMD_META_DATA_READY
, qproc
->rmb_base
+ RMB_MBA_COMMAND_REG
);
858 ret
= q6v5_rmb_mba_wait(qproc
, RMB_MBA_META_DATA_AUTH_SUCCESS
, 1000);
859 if (ret
== -ETIMEDOUT
)
860 dev_err(qproc
->dev
, "MPSS header authentication timed out\n");
862 dev_err(qproc
->dev
, "MPSS header authentication failed: %d\n", ret
);
864 /* Metadata authentication done, remove modem access */
865 xferop_ret
= q6v5_xfer_mem_ownership(qproc
, &mdata_perm
, true, false,
869 "mdt buffer not reclaimed system may become unstable\n");
872 dma_free_attrs(qproc
->dev
, size
, ptr
, phys
, dma_attrs
);
875 return ret
< 0 ? ret
: 0;
878 static bool q6v5_phdr_valid(const struct elf32_phdr
*phdr
)
880 if (phdr
->p_type
!= PT_LOAD
)
883 if ((phdr
->p_flags
& QCOM_MDT_TYPE_MASK
) == QCOM_MDT_TYPE_HASH
)
892 static int q6v5_mba_load(struct q6v5
*qproc
)
896 bool mba_load_err
= false;
898 qcom_q6v5_prepare(&qproc
->q6v5
);
900 ret
= q6v5_pds_enable(qproc
, qproc
->active_pds
, qproc
->active_pd_count
);
902 dev_err(qproc
->dev
, "failed to enable active power domains\n");
906 ret
= q6v5_pds_enable(qproc
, qproc
->proxy_pds
, qproc
->proxy_pd_count
);
908 dev_err(qproc
->dev
, "failed to enable proxy power domains\n");
909 goto disable_active_pds
;
912 ret
= q6v5_regulator_enable(qproc
, qproc
->fallback_proxy_regs
,
913 qproc
->fallback_proxy_reg_count
);
915 dev_err(qproc
->dev
, "failed to enable fallback proxy supplies\n");
916 goto disable_proxy_pds
;
919 ret
= q6v5_regulator_enable(qproc
, qproc
->proxy_regs
,
920 qproc
->proxy_reg_count
);
922 dev_err(qproc
->dev
, "failed to enable proxy supplies\n");
923 goto disable_fallback_proxy_reg
;
926 ret
= q6v5_clk_enable(qproc
->dev
, qproc
->proxy_clks
,
927 qproc
->proxy_clk_count
);
929 dev_err(qproc
->dev
, "failed to enable proxy clocks\n");
930 goto disable_proxy_reg
;
933 ret
= q6v5_regulator_enable(qproc
, qproc
->active_regs
,
934 qproc
->active_reg_count
);
936 dev_err(qproc
->dev
, "failed to enable supplies\n");
937 goto disable_proxy_clk
;
940 ret
= q6v5_clk_enable(qproc
->dev
, qproc
->reset_clks
,
941 qproc
->reset_clk_count
);
943 dev_err(qproc
->dev
, "failed to enable reset clocks\n");
947 ret
= q6v5_reset_deassert(qproc
);
949 dev_err(qproc
->dev
, "failed to deassert mss restart\n");
950 goto disable_reset_clks
;
953 ret
= q6v5_clk_enable(qproc
->dev
, qproc
->active_clks
,
954 qproc
->active_clk_count
);
956 dev_err(qproc
->dev
, "failed to enable clocks\n");
961 * Some versions of the MBA firmware will upon boot wipe the MPSS region as well, so provide
962 * the Q6 access to this region.
964 ret
= q6v5_xfer_mem_ownership(qproc
, &qproc
->mpss_perm
, false, true,
965 qproc
->mpss_phys
, qproc
->mpss_size
);
967 dev_err(qproc
->dev
, "assigning Q6 access to mpss memory failed: %d\n", ret
);
968 goto disable_active_clks
;
971 /* Assign MBA image access in DDR to q6 */
972 ret
= q6v5_xfer_mem_ownership(qproc
, &qproc
->mba_perm
, false, true,
973 qproc
->mba_phys
, qproc
->mba_size
);
976 "assigning Q6 access to mba memory failed: %d\n", ret
);
977 goto disable_active_clks
;
980 writel(qproc
->mba_phys
, qproc
->rmb_base
+ RMB_MBA_IMAGE_REG
);
981 if (qproc
->dp_size
) {
982 writel(qproc
->mba_phys
+ SZ_1M
, qproc
->rmb_base
+ RMB_PMI_CODE_START_REG
);
983 writel(qproc
->dp_size
, qproc
->rmb_base
+ RMB_PMI_CODE_LENGTH_REG
);
986 ret
= q6v5proc_reset(qproc
);
990 ret
= q6v5_rmb_mba_wait(qproc
, 0, 5000);
991 if (ret
== -ETIMEDOUT
) {
992 dev_err(qproc
->dev
, "MBA boot timed out\n");
994 } else if (ret
!= RMB_MBA_XPU_UNLOCKED
&&
995 ret
!= RMB_MBA_XPU_UNLOCKED_SCRIBBLED
) {
996 dev_err(qproc
->dev
, "MBA returned unexpected status %d\n", ret
);
1001 qproc
->dump_mba_loaded
= true;
1005 q6v5proc_halt_axi_port(qproc
, qproc
->halt_map
, qproc
->halt_q6
);
1006 q6v5proc_halt_axi_port(qproc
, qproc
->halt_map
, qproc
->halt_modem
);
1007 q6v5proc_halt_axi_port(qproc
, qproc
->halt_map
, qproc
->halt_nc
);
1008 mba_load_err
= true;
1010 xfermemop_ret
= q6v5_xfer_mem_ownership(qproc
, &qproc
->mba_perm
, true,
1011 false, qproc
->mba_phys
,
1013 if (xfermemop_ret
) {
1015 "Failed to reclaim mba buffer, system may become unstable\n");
1016 } else if (mba_load_err
) {
1017 q6v5_dump_mba_logs(qproc
);
1020 disable_active_clks
:
1021 q6v5_clk_disable(qproc
->dev
, qproc
->active_clks
,
1022 qproc
->active_clk_count
);
1024 q6v5_reset_assert(qproc
);
1026 q6v5_clk_disable(qproc
->dev
, qproc
->reset_clks
,
1027 qproc
->reset_clk_count
);
1029 q6v5_regulator_disable(qproc
, qproc
->active_regs
,
1030 qproc
->active_reg_count
);
1032 q6v5_clk_disable(qproc
->dev
, qproc
->proxy_clks
,
1033 qproc
->proxy_clk_count
);
1035 q6v5_regulator_disable(qproc
, qproc
->proxy_regs
,
1036 qproc
->proxy_reg_count
);
1037 disable_fallback_proxy_reg
:
1038 q6v5_regulator_disable(qproc
, qproc
->fallback_proxy_regs
,
1039 qproc
->fallback_proxy_reg_count
);
1041 q6v5_pds_disable(qproc
, qproc
->proxy_pds
, qproc
->proxy_pd_count
);
1043 q6v5_pds_disable(qproc
, qproc
->active_pds
, qproc
->active_pd_count
);
1045 qcom_q6v5_unprepare(&qproc
->q6v5
);
1050 static void q6v5_mba_reclaim(struct q6v5
*qproc
)
1055 qproc
->dump_mba_loaded
= false;
1058 q6v5proc_halt_axi_port(qproc
, qproc
->halt_map
, qproc
->halt_q6
);
1059 q6v5proc_halt_axi_port(qproc
, qproc
->halt_map
, qproc
->halt_modem
);
1060 q6v5proc_halt_axi_port(qproc
, qproc
->halt_map
, qproc
->halt_nc
);
1061 if (qproc
->version
== MSS_MSM8996
) {
1063 * To avoid high MX current during LPASS/MSS restart.
1065 val
= readl(qproc
->reg_base
+ QDSP6SS_PWR_CTL_REG
);
1066 val
|= Q6SS_CLAMP_IO
| QDSP6v56_CLAMP_WL
|
1067 QDSP6v56_CLAMP_QMC_MEM
;
1068 writel(val
, qproc
->reg_base
+ QDSP6SS_PWR_CTL_REG
);
1071 q6v5_reset_assert(qproc
);
1073 q6v5_clk_disable(qproc
->dev
, qproc
->reset_clks
,
1074 qproc
->reset_clk_count
);
1075 q6v5_clk_disable(qproc
->dev
, qproc
->active_clks
,
1076 qproc
->active_clk_count
);
1077 q6v5_regulator_disable(qproc
, qproc
->active_regs
,
1078 qproc
->active_reg_count
);
1079 q6v5_pds_disable(qproc
, qproc
->active_pds
, qproc
->active_pd_count
);
1081 /* In case of failure or coredump scenario where reclaiming MBA memory
1082 * could not happen reclaim it here.
1084 ret
= q6v5_xfer_mem_ownership(qproc
, &qproc
->mba_perm
, true, false,
1089 ret
= qcom_q6v5_unprepare(&qproc
->q6v5
);
1091 q6v5_pds_disable(qproc
, qproc
->proxy_pds
,
1092 qproc
->proxy_pd_count
);
1093 q6v5_clk_disable(qproc
->dev
, qproc
->proxy_clks
,
1094 qproc
->proxy_clk_count
);
1095 q6v5_regulator_disable(qproc
, qproc
->fallback_proxy_regs
,
1096 qproc
->fallback_proxy_reg_count
);
1097 q6v5_regulator_disable(qproc
, qproc
->proxy_regs
,
1098 qproc
->proxy_reg_count
);
1102 static int q6v5_reload_mba(struct rproc
*rproc
)
1104 struct q6v5
*qproc
= rproc
->priv
;
1105 const struct firmware
*fw
;
1108 ret
= request_firmware(&fw
, rproc
->firmware
, qproc
->dev
);
1112 q6v5_load(rproc
, fw
);
1113 ret
= q6v5_mba_load(qproc
);
1114 release_firmware(fw
);
1119 static int q6v5_mpss_load(struct q6v5
*qproc
)
1121 const struct elf32_phdr
*phdrs
;
1122 const struct elf32_phdr
*phdr
;
1123 const struct firmware
*seg_fw
;
1124 const struct firmware
*fw
;
1125 struct elf32_hdr
*ehdr
;
1126 phys_addr_t mpss_reloc
;
1127 phys_addr_t boot_addr
;
1128 phys_addr_t min_addr
= PHYS_ADDR_MAX
;
1129 phys_addr_t max_addr
= 0;
1131 bool relocate
= false;
1140 fw_name_len
= strlen(qproc
->hexagon_mdt_image
);
1141 if (fw_name_len
<= 4)
1144 fw_name
= kstrdup(qproc
->hexagon_mdt_image
, GFP_KERNEL
);
1148 ret
= request_firmware(&fw
, fw_name
, qproc
->dev
);
1150 dev_err(qproc
->dev
, "unable to load %s\n", fw_name
);
1154 /* Initialize the RMB validator */
1155 writel(0, qproc
->rmb_base
+ RMB_PMI_CODE_LENGTH_REG
);
1157 ret
= q6v5_mpss_init_image(qproc
, fw
);
1159 goto release_firmware
;
1161 ehdr
= (struct elf32_hdr
*)fw
->data
;
1162 phdrs
= (struct elf32_phdr
*)(ehdr
+ 1);
1164 for (i
= 0; i
< ehdr
->e_phnum
; i
++) {
1167 if (!q6v5_phdr_valid(phdr
))
1170 if (phdr
->p_flags
& QCOM_MDT_RELOCATABLE
)
1173 if (phdr
->p_paddr
< min_addr
)
1174 min_addr
= phdr
->p_paddr
;
1176 if (phdr
->p_paddr
+ phdr
->p_memsz
> max_addr
)
1177 max_addr
= ALIGN(phdr
->p_paddr
+ phdr
->p_memsz
, SZ_4K
);
1181 * In case of a modem subsystem restart on secure devices, the modem
1182 * memory can be reclaimed only after MBA is loaded.
1184 q6v5_xfer_mem_ownership(qproc
, &qproc
->mpss_perm
, true, false,
1185 qproc
->mpss_phys
, qproc
->mpss_size
);
1187 /* Share ownership between Linux and MSS, during segment loading */
1188 ret
= q6v5_xfer_mem_ownership(qproc
, &qproc
->mpss_perm
, true, true,
1189 qproc
->mpss_phys
, qproc
->mpss_size
);
1192 "assigning Q6 access to mpss memory failed: %d\n", ret
);
1194 goto release_firmware
;
1197 mpss_reloc
= relocate
? min_addr
: qproc
->mpss_phys
;
1198 qproc
->mpss_reloc
= mpss_reloc
;
1199 /* Load firmware segments */
1200 for (i
= 0; i
< ehdr
->e_phnum
; i
++) {
1203 if (!q6v5_phdr_valid(phdr
))
1206 offset
= phdr
->p_paddr
- mpss_reloc
;
1207 if (offset
< 0 || offset
+ phdr
->p_memsz
> qproc
->mpss_size
) {
1208 dev_err(qproc
->dev
, "segment outside memory range\n");
1210 goto release_firmware
;
1213 ptr
= memremap(qproc
->mpss_phys
+ offset
, phdr
->p_memsz
, MEMREMAP_WC
);
1216 "unable to map memory region: %pa+%zx-%x\n",
1217 &qproc
->mpss_phys
, offset
, phdr
->p_memsz
);
1218 goto release_firmware
;
1221 if (phdr
->p_filesz
&& phdr
->p_offset
< fw
->size
) {
1222 /* Firmware is large enough to be non-split */
1223 if (phdr
->p_offset
+ phdr
->p_filesz
> fw
->size
) {
1225 "failed to load segment %d from truncated file %s\n",
1229 goto release_firmware
;
1232 memcpy(ptr
, fw
->data
+ phdr
->p_offset
, phdr
->p_filesz
);
1233 } else if (phdr
->p_filesz
) {
1234 /* Replace "xxx.xxx" with "xxx.bxx" */
1235 sprintf(fw_name
+ fw_name_len
- 3, "b%02d", i
);
1236 ret
= request_firmware_into_buf(&seg_fw
, fw_name
, qproc
->dev
,
1237 ptr
, phdr
->p_filesz
);
1239 dev_err(qproc
->dev
, "failed to load %s\n", fw_name
);
1241 goto release_firmware
;
1244 release_firmware(seg_fw
);
1247 if (phdr
->p_memsz
> phdr
->p_filesz
) {
1248 memset(ptr
+ phdr
->p_filesz
, 0,
1249 phdr
->p_memsz
- phdr
->p_filesz
);
1252 size
+= phdr
->p_memsz
;
1254 code_length
= readl(qproc
->rmb_base
+ RMB_PMI_CODE_LENGTH_REG
);
1256 boot_addr
= relocate
? qproc
->mpss_phys
: min_addr
;
1257 writel(boot_addr
, qproc
->rmb_base
+ RMB_PMI_CODE_START_REG
);
1258 writel(RMB_CMD_LOAD_READY
, qproc
->rmb_base
+ RMB_MBA_COMMAND_REG
);
1260 writel(size
, qproc
->rmb_base
+ RMB_PMI_CODE_LENGTH_REG
);
1262 ret
= readl(qproc
->rmb_base
+ RMB_MBA_STATUS_REG
);
1264 dev_err(qproc
->dev
, "MPSS authentication failed: %d\n",
1266 goto release_firmware
;
1270 /* Transfer ownership of modem ddr region to q6 */
1271 ret
= q6v5_xfer_mem_ownership(qproc
, &qproc
->mpss_perm
, false, true,
1272 qproc
->mpss_phys
, qproc
->mpss_size
);
1275 "assigning Q6 access to mpss memory failed: %d\n", ret
);
1277 goto release_firmware
;
1280 ret
= q6v5_rmb_mba_wait(qproc
, RMB_MBA_AUTH_COMPLETE
, 10000);
1281 if (ret
== -ETIMEDOUT
)
1282 dev_err(qproc
->dev
, "MPSS authentication timed out\n");
1284 dev_err(qproc
->dev
, "MPSS authentication failed: %d\n", ret
);
1286 qcom_pil_info_store("modem", qproc
->mpss_phys
, qproc
->mpss_size
);
1289 release_firmware(fw
);
1293 return ret
< 0 ? ret
: 0;
1296 static void qcom_q6v5_dump_segment(struct rproc
*rproc
,
1297 struct rproc_dump_segment
*segment
,
1298 void *dest
, size_t cp_offset
, size_t size
)
1301 struct q6v5
*qproc
= rproc
->priv
;
1302 int offset
= segment
->da
- qproc
->mpss_reloc
;
1305 /* Unlock mba before copying segments */
1306 if (!qproc
->dump_mba_loaded
) {
1307 ret
= q6v5_reload_mba(rproc
);
1309 /* Reset ownership back to Linux to copy segments */
1310 ret
= q6v5_xfer_mem_ownership(qproc
, &qproc
->mpss_perm
,
1318 ptr
= memremap(qproc
->mpss_phys
+ offset
+ cp_offset
, size
, MEMREMAP_WC
);
1321 memcpy(dest
, ptr
, size
);
1324 memset(dest
, 0xff, size
);
1327 qproc
->current_dump_size
+= size
;
1329 /* Reclaim mba after copying segments */
1330 if (qproc
->current_dump_size
== qproc
->total_dump_size
) {
1331 if (qproc
->dump_mba_loaded
) {
1332 /* Try to reset ownership back to Q6 */
1333 q6v5_xfer_mem_ownership(qproc
, &qproc
->mpss_perm
,
1337 q6v5_mba_reclaim(qproc
);
1342 static int q6v5_start(struct rproc
*rproc
)
1344 struct q6v5
*qproc
= (struct q6v5
*)rproc
->priv
;
1348 ret
= q6v5_mba_load(qproc
);
1352 dev_info(qproc
->dev
, "MBA booted with%s debug policy, loading mpss\n",
1353 qproc
->dp_size
? "" : "out");
1355 ret
= q6v5_mpss_load(qproc
);
1359 ret
= qcom_q6v5_wait_for_start(&qproc
->q6v5
, msecs_to_jiffies(5000));
1360 if (ret
== -ETIMEDOUT
) {
1361 dev_err(qproc
->dev
, "start timed out\n");
1365 xfermemop_ret
= q6v5_xfer_mem_ownership(qproc
, &qproc
->mba_perm
, true,
1366 false, qproc
->mba_phys
,
1370 "Failed to reclaim mba buffer system may become unstable\n");
1372 /* Reset Dump Segment Mask */
1373 qproc
->current_dump_size
= 0;
1378 q6v5_mba_reclaim(qproc
);
1379 q6v5_dump_mba_logs(qproc
);
1384 static int q6v5_stop(struct rproc
*rproc
)
1386 struct q6v5
*qproc
= (struct q6v5
*)rproc
->priv
;
1389 ret
= qcom_q6v5_request_stop(&qproc
->q6v5
, qproc
->sysmon
);
1390 if (ret
== -ETIMEDOUT
)
1391 dev_err(qproc
->dev
, "timed out on wait\n");
1393 q6v5_mba_reclaim(qproc
);
1398 static int qcom_q6v5_register_dump_segments(struct rproc
*rproc
,
1399 const struct firmware
*mba_fw
)
1401 const struct firmware
*fw
;
1402 const struct elf32_phdr
*phdrs
;
1403 const struct elf32_phdr
*phdr
;
1404 const struct elf32_hdr
*ehdr
;
1405 struct q6v5
*qproc
= rproc
->priv
;
1409 ret
= request_firmware(&fw
, qproc
->hexagon_mdt_image
, qproc
->dev
);
1411 dev_err(qproc
->dev
, "unable to load %s\n",
1412 qproc
->hexagon_mdt_image
);
1416 rproc_coredump_set_elf_info(rproc
, ELFCLASS32
, EM_NONE
);
1418 ehdr
= (struct elf32_hdr
*)fw
->data
;
1419 phdrs
= (struct elf32_phdr
*)(ehdr
+ 1);
1420 qproc
->total_dump_size
= 0;
1422 for (i
= 0; i
< ehdr
->e_phnum
; i
++) {
1425 if (!q6v5_phdr_valid(phdr
))
1428 ret
= rproc_coredump_add_custom_segment(rproc
, phdr
->p_paddr
,
1430 qcom_q6v5_dump_segment
,
1435 qproc
->total_dump_size
+= phdr
->p_memsz
;
1438 release_firmware(fw
);
1442 static const struct rproc_ops q6v5_ops
= {
1443 .start
= q6v5_start
,
1445 .parse_fw
= qcom_q6v5_register_dump_segments
,
1449 static void qcom_msa_handover(struct qcom_q6v5
*q6v5
)
1451 struct q6v5
*qproc
= container_of(q6v5
, struct q6v5
, q6v5
);
1453 q6v5_clk_disable(qproc
->dev
, qproc
->proxy_clks
,
1454 qproc
->proxy_clk_count
);
1455 q6v5_regulator_disable(qproc
, qproc
->proxy_regs
,
1456 qproc
->proxy_reg_count
);
1457 q6v5_regulator_disable(qproc
, qproc
->fallback_proxy_regs
,
1458 qproc
->fallback_proxy_reg_count
);
1459 q6v5_pds_disable(qproc
, qproc
->proxy_pds
, qproc
->proxy_pd_count
);
1462 static int q6v5_init_mem(struct q6v5
*qproc
, struct platform_device
*pdev
)
1464 struct of_phandle_args args
;
1465 struct resource
*res
;
1468 res
= platform_get_resource_byname(pdev
, IORESOURCE_MEM
, "qdsp6");
1469 qproc
->reg_base
= devm_ioremap_resource(&pdev
->dev
, res
);
1470 if (IS_ERR(qproc
->reg_base
))
1471 return PTR_ERR(qproc
->reg_base
);
1473 res
= platform_get_resource_byname(pdev
, IORESOURCE_MEM
, "rmb");
1474 qproc
->rmb_base
= devm_ioremap_resource(&pdev
->dev
, res
);
1475 if (IS_ERR(qproc
->rmb_base
))
1476 return PTR_ERR(qproc
->rmb_base
);
1478 ret
= of_parse_phandle_with_fixed_args(pdev
->dev
.of_node
,
1479 "qcom,halt-regs", 3, 0, &args
);
1481 dev_err(&pdev
->dev
, "failed to parse qcom,halt-regs\n");
1485 qproc
->halt_map
= syscon_node_to_regmap(args
.np
);
1486 of_node_put(args
.np
);
1487 if (IS_ERR(qproc
->halt_map
))
1488 return PTR_ERR(qproc
->halt_map
);
1490 qproc
->halt_q6
= args
.args
[0];
1491 qproc
->halt_modem
= args
.args
[1];
1492 qproc
->halt_nc
= args
.args
[2];
1494 if (qproc
->has_spare_reg
) {
1495 ret
= of_parse_phandle_with_fixed_args(pdev
->dev
.of_node
,
1499 dev_err(&pdev
->dev
, "failed to parse spare-regs\n");
1503 qproc
->conn_map
= syscon_node_to_regmap(args
.np
);
1504 of_node_put(args
.np
);
1505 if (IS_ERR(qproc
->conn_map
))
1506 return PTR_ERR(qproc
->conn_map
);
1508 qproc
->conn_box
= args
.args
[0];
1514 static int q6v5_init_clocks(struct device
*dev
, struct clk
**clks
,
1522 for (i
= 0; clk_names
[i
]; i
++) {
1523 clks
[i
] = devm_clk_get(dev
, clk_names
[i
]);
1524 if (IS_ERR(clks
[i
])) {
1525 int rc
= PTR_ERR(clks
[i
]);
1527 if (rc
!= -EPROBE_DEFER
)
1528 dev_err(dev
, "Failed to get %s clock\n",
1537 static int q6v5_pds_attach(struct device
*dev
, struct device
**devs
,
1547 while (pd_names
[num_pds
])
1550 for (i
= 0; i
< num_pds
; i
++) {
1551 devs
[i
] = dev_pm_domain_attach_by_name(dev
, pd_names
[i
]);
1552 if (IS_ERR_OR_NULL(devs
[i
])) {
1553 ret
= PTR_ERR(devs
[i
]) ? : -ENODATA
;
1561 for (i
--; i
>= 0; i
--)
1562 dev_pm_domain_detach(devs
[i
], false);
1567 static void q6v5_pds_detach(struct q6v5
*qproc
, struct device
**pds
,
1572 for (i
= 0; i
< pd_count
; i
++)
1573 dev_pm_domain_detach(pds
[i
], false);
1576 static int q6v5_init_reset(struct q6v5
*qproc
)
1578 qproc
->mss_restart
= devm_reset_control_get_exclusive(qproc
->dev
,
1580 if (IS_ERR(qproc
->mss_restart
)) {
1581 dev_err(qproc
->dev
, "failed to acquire mss restart\n");
1582 return PTR_ERR(qproc
->mss_restart
);
1585 if (qproc
->has_alt_reset
|| qproc
->has_spare_reg
) {
1586 qproc
->pdc_reset
= devm_reset_control_get_exclusive(qproc
->dev
,
1588 if (IS_ERR(qproc
->pdc_reset
)) {
1589 dev_err(qproc
->dev
, "failed to acquire pdc reset\n");
1590 return PTR_ERR(qproc
->pdc_reset
);
1597 static int q6v5_alloc_memory_region(struct q6v5
*qproc
)
1599 struct device_node
*child
;
1600 struct device_node
*node
;
1605 * In the absence of mba/mpss sub-child, extract the mba and mpss
1606 * reserved memory regions from device's memory-region property.
1608 child
= of_get_child_by_name(qproc
->dev
->of_node
, "mba");
1610 node
= of_parse_phandle(qproc
->dev
->of_node
,
1611 "memory-region", 0);
1613 node
= of_parse_phandle(child
, "memory-region", 0);
1615 ret
= of_address_to_resource(node
, 0, &r
);
1617 dev_err(qproc
->dev
, "unable to resolve mba region\n");
1622 qproc
->mba_phys
= r
.start
;
1623 qproc
->mba_size
= resource_size(&r
);
1626 node
= of_parse_phandle(qproc
->dev
->of_node
,
1627 "memory-region", 1);
1629 child
= of_get_child_by_name(qproc
->dev
->of_node
, "mpss");
1630 node
= of_parse_phandle(child
, "memory-region", 0);
1633 ret
= of_address_to_resource(node
, 0, &r
);
1635 dev_err(qproc
->dev
, "unable to resolve mpss region\n");
1640 qproc
->mpss_phys
= qproc
->mpss_reloc
= r
.start
;
1641 qproc
->mpss_size
= resource_size(&r
);
1646 static int q6v5_probe(struct platform_device
*pdev
)
1648 const struct rproc_hexagon_res
*desc
;
1650 struct rproc
*rproc
;
1651 const char *mba_image
;
1654 desc
= of_device_get_match_data(&pdev
->dev
);
1658 if (desc
->need_mem_protection
&& !qcom_scm_is_available())
1659 return -EPROBE_DEFER
;
1661 mba_image
= desc
->hexagon_mba_image
;
1662 ret
= of_property_read_string_index(pdev
->dev
.of_node
, "firmware-name",
1664 if (ret
< 0 && ret
!= -EINVAL
)
1667 rproc
= rproc_alloc(&pdev
->dev
, pdev
->name
, &q6v5_ops
,
1668 mba_image
, sizeof(*qproc
));
1670 dev_err(&pdev
->dev
, "failed to allocate rproc\n");
1674 rproc
->auto_boot
= false;
1675 rproc_coredump_set_elf_info(rproc
, ELFCLASS32
, EM_NONE
);
1677 qproc
= (struct q6v5
*)rproc
->priv
;
1678 qproc
->dev
= &pdev
->dev
;
1679 qproc
->rproc
= rproc
;
1680 qproc
->hexagon_mdt_image
= "modem.mdt";
1681 ret
= of_property_read_string_index(pdev
->dev
.of_node
, "firmware-name",
1682 1, &qproc
->hexagon_mdt_image
);
1683 if (ret
< 0 && ret
!= -EINVAL
)
1686 platform_set_drvdata(pdev
, qproc
);
1688 qproc
->has_spare_reg
= desc
->has_spare_reg
;
1689 ret
= q6v5_init_mem(qproc
, pdev
);
1693 ret
= q6v5_alloc_memory_region(qproc
);
1697 ret
= q6v5_init_clocks(&pdev
->dev
, qproc
->proxy_clks
,
1698 desc
->proxy_clk_names
);
1700 dev_err(&pdev
->dev
, "Failed to get proxy clocks.\n");
1703 qproc
->proxy_clk_count
= ret
;
1705 ret
= q6v5_init_clocks(&pdev
->dev
, qproc
->reset_clks
,
1706 desc
->reset_clk_names
);
1708 dev_err(&pdev
->dev
, "Failed to get reset clocks.\n");
1711 qproc
->reset_clk_count
= ret
;
1713 ret
= q6v5_init_clocks(&pdev
->dev
, qproc
->active_clks
,
1714 desc
->active_clk_names
);
1716 dev_err(&pdev
->dev
, "Failed to get active clocks.\n");
1719 qproc
->active_clk_count
= ret
;
1721 ret
= q6v5_regulator_init(&pdev
->dev
, qproc
->proxy_regs
,
1722 desc
->proxy_supply
);
1724 dev_err(&pdev
->dev
, "Failed to get proxy regulators.\n");
1727 qproc
->proxy_reg_count
= ret
;
1729 ret
= q6v5_regulator_init(&pdev
->dev
, qproc
->active_regs
,
1730 desc
->active_supply
);
1732 dev_err(&pdev
->dev
, "Failed to get active regulators.\n");
1735 qproc
->active_reg_count
= ret
;
1737 ret
= q6v5_pds_attach(&pdev
->dev
, qproc
->active_pds
,
1738 desc
->active_pd_names
);
1740 dev_err(&pdev
->dev
, "Failed to attach active power domains\n");
1743 qproc
->active_pd_count
= ret
;
1745 ret
= q6v5_pds_attach(&pdev
->dev
, qproc
->proxy_pds
,
1746 desc
->proxy_pd_names
);
1747 /* Fallback to regulators for old device trees */
1748 if (ret
== -ENODATA
&& desc
->fallback_proxy_supply
) {
1749 ret
= q6v5_regulator_init(&pdev
->dev
,
1750 qproc
->fallback_proxy_regs
,
1751 desc
->fallback_proxy_supply
);
1753 dev_err(&pdev
->dev
, "Failed to get fallback proxy regulators.\n");
1754 goto detach_active_pds
;
1756 qproc
->fallback_proxy_reg_count
= ret
;
1757 } else if (ret
< 0) {
1758 dev_err(&pdev
->dev
, "Failed to init power domains\n");
1759 goto detach_active_pds
;
1761 qproc
->proxy_pd_count
= ret
;
1764 qproc
->has_alt_reset
= desc
->has_alt_reset
;
1765 ret
= q6v5_init_reset(qproc
);
1767 goto detach_proxy_pds
;
1769 qproc
->version
= desc
->version
;
1770 qproc
->need_mem_protection
= desc
->need_mem_protection
;
1771 qproc
->has_mba_logs
= desc
->has_mba_logs
;
1773 ret
= qcom_q6v5_init(&qproc
->q6v5
, pdev
, rproc
, MPSS_CRASH_REASON_SMEM
,
1776 goto detach_proxy_pds
;
1778 qproc
->mpss_perm
= BIT(QCOM_SCM_VMID_HLOS
);
1779 qproc
->mba_perm
= BIT(QCOM_SCM_VMID_HLOS
);
1780 qcom_add_glink_subdev(rproc
, &qproc
->glink_subdev
, "mpss");
1781 qcom_add_smd_subdev(rproc
, &qproc
->smd_subdev
);
1782 qcom_add_ssr_subdev(rproc
, &qproc
->ssr_subdev
, "mpss");
1783 qproc
->sysmon
= qcom_add_sysmon_subdev(rproc
, "modem", 0x12);
1784 if (IS_ERR(qproc
->sysmon
)) {
1785 ret
= PTR_ERR(qproc
->sysmon
);
1786 goto remove_subdevs
;
1789 ret
= rproc_add(rproc
);
1791 goto remove_sysmon_subdev
;
1795 remove_sysmon_subdev
:
1796 qcom_remove_sysmon_subdev(qproc
->sysmon
);
1798 qcom_remove_ssr_subdev(rproc
, &qproc
->ssr_subdev
);
1799 qcom_remove_smd_subdev(rproc
, &qproc
->smd_subdev
);
1800 qcom_remove_glink_subdev(rproc
, &qproc
->glink_subdev
);
1802 q6v5_pds_detach(qproc
, qproc
->proxy_pds
, qproc
->proxy_pd_count
);
1804 q6v5_pds_detach(qproc
, qproc
->active_pds
, qproc
->active_pd_count
);
1811 static int q6v5_remove(struct platform_device
*pdev
)
1813 struct q6v5
*qproc
= platform_get_drvdata(pdev
);
1814 struct rproc
*rproc
= qproc
->rproc
;
1818 qcom_remove_sysmon_subdev(qproc
->sysmon
);
1819 qcom_remove_ssr_subdev(rproc
, &qproc
->ssr_subdev
);
1820 qcom_remove_smd_subdev(rproc
, &qproc
->smd_subdev
);
1821 qcom_remove_glink_subdev(rproc
, &qproc
->glink_subdev
);
1823 q6v5_pds_detach(qproc
, qproc
->proxy_pds
, qproc
->proxy_pd_count
);
1824 q6v5_pds_detach(qproc
, qproc
->active_pds
, qproc
->active_pd_count
);
1831 static const struct rproc_hexagon_res sc7180_mss
= {
1832 .hexagon_mba_image
= "mba.mbn",
1833 .proxy_clk_names
= (char*[]){
1837 .reset_clk_names
= (char*[]){
1843 .active_clk_names
= (char*[]){
1848 .active_pd_names
= (char*[]){
1852 .proxy_pd_names
= (char*[]){
1858 .need_mem_protection
= true,
1859 .has_alt_reset
= false,
1860 .has_mba_logs
= true,
1861 .has_spare_reg
= true,
1862 .version
= MSS_SC7180
,
1865 static const struct rproc_hexagon_res sdm845_mss
= {
1866 .hexagon_mba_image
= "mba.mbn",
1867 .proxy_clk_names
= (char*[]){
1872 .reset_clk_names
= (char*[]){
1877 .active_clk_names
= (char*[]){
1884 .active_pd_names
= (char*[]){
1888 .proxy_pd_names
= (char*[]){
1894 .need_mem_protection
= true,
1895 .has_alt_reset
= true,
1896 .has_mba_logs
= false,
1897 .has_spare_reg
= false,
1898 .version
= MSS_SDM845
,
1901 static const struct rproc_hexagon_res msm8998_mss
= {
1902 .hexagon_mba_image
= "mba.mbn",
1903 .proxy_clk_names
= (char*[]){
1909 .active_clk_names
= (char*[]){
1917 .proxy_pd_names
= (char*[]){
1922 .need_mem_protection
= true,
1923 .has_alt_reset
= false,
1924 .has_mba_logs
= false,
1925 .has_spare_reg
= false,
1926 .version
= MSS_MSM8998
,
1929 static const struct rproc_hexagon_res msm8996_mss
= {
1930 .hexagon_mba_image
= "mba.mbn",
1931 .proxy_supply
= (struct qcom_mss_reg_res
[]) {
1938 .proxy_clk_names
= (char*[]){
1944 .active_clk_names
= (char*[]){
1953 .need_mem_protection
= true,
1954 .has_alt_reset
= false,
1955 .has_mba_logs
= false,
1956 .has_spare_reg
= false,
1957 .version
= MSS_MSM8996
,
1960 static const struct rproc_hexagon_res msm8916_mss
= {
1961 .hexagon_mba_image
= "mba.mbn",
1962 .proxy_supply
= (struct qcom_mss_reg_res
[]) {
1969 .fallback_proxy_supply
= (struct qcom_mss_reg_res
[]) {
1980 .proxy_clk_names
= (char*[]){
1984 .active_clk_names
= (char*[]){
1990 .proxy_pd_names
= (char*[]){
1995 .need_mem_protection
= false,
1996 .has_alt_reset
= false,
1997 .has_mba_logs
= false,
1998 .has_spare_reg
= false,
1999 .version
= MSS_MSM8916
,
2002 static const struct rproc_hexagon_res msm8974_mss
= {
2003 .hexagon_mba_image
= "mba.b00",
2004 .proxy_supply
= (struct qcom_mss_reg_res
[]) {
2011 .fallback_proxy_supply
= (struct qcom_mss_reg_res
[]) {
2022 .active_supply
= (struct qcom_mss_reg_res
[]) {
2030 .proxy_clk_names
= (char*[]){
2034 .active_clk_names
= (char*[]){
2040 .proxy_pd_names
= (char*[]){
2045 .need_mem_protection
= false,
2046 .has_alt_reset
= false,
2047 .has_mba_logs
= false,
2048 .has_spare_reg
= false,
2049 .version
= MSS_MSM8974
,
2052 static const struct of_device_id q6v5_of_match
[] = {
2053 { .compatible
= "qcom,q6v5-pil", .data
= &msm8916_mss
},
2054 { .compatible
= "qcom,msm8916-mss-pil", .data
= &msm8916_mss
},
2055 { .compatible
= "qcom,msm8974-mss-pil", .data
= &msm8974_mss
},
2056 { .compatible
= "qcom,msm8996-mss-pil", .data
= &msm8996_mss
},
2057 { .compatible
= "qcom,msm8998-mss-pil", .data
= &msm8998_mss
},
2058 { .compatible
= "qcom,sc7180-mss-pil", .data
= &sc7180_mss
},
2059 { .compatible
= "qcom,sdm845-mss-pil", .data
= &sdm845_mss
},
2062 MODULE_DEVICE_TABLE(of
, q6v5_of_match
);
2064 static struct platform_driver q6v5_driver
= {
2065 .probe
= q6v5_probe
,
2066 .remove
= q6v5_remove
,
2068 .name
= "qcom-q6v5-mss",
2069 .of_match_table
= q6v5_of_match
,
2072 module_platform_driver(q6v5_driver
);
2074 MODULE_DESCRIPTION("Qualcomm Self-authenticating modem remoteproc driver");
2075 MODULE_LICENSE("GPL v2");