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