xref: /linux/drivers/remoteproc/qcom_q6v5_mss.c (revision 34e34736ea9a685664f57586f6e293aaff308858)
1 // SPDX-License-Identifier: GPL-2.0-only
2 /*
3  * Qualcomm self-authenticating modem subsystem remoteproc driver
4  *
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.
8  */
9 
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.h>
19 #include <linux/of_reserved_mem.h>
20 #include <linux/of_platform.h>
21 #include <linux/platform_device.h>
22 #include <linux/pm_domain.h>
23 #include <linux/pm_runtime.h>
24 #include <linux/regmap.h>
25 #include <linux/regulator/consumer.h>
26 #include <linux/remoteproc.h>
27 #include <linux/reset.h>
28 #include <linux/soc/qcom/mdt_loader.h>
29 #include <linux/iopoll.h>
30 #include <linux/slab.h>
31 
32 #include "remoteproc_internal.h"
33 #include "qcom_common.h"
34 #include "qcom_pil_info.h"
35 #include "qcom_q6v5.h"
36 
37 #include <linux/firmware/qcom/qcom_pas.h>
38 #include <linux/firmware/qcom/qcom_scm.h>
39 
40 #define MPSS_CRASH_REASON_SMEM		421
41 
42 #define MBA_LOG_SIZE			SZ_4K
43 
44 #define MPSS_PAS_ID			5
45 
46 /* RMB Status Register Values */
47 #define RMB_PBL_SUCCESS			0x1
48 
49 #define RMB_MBA_XPU_UNLOCKED		0x1
50 #define RMB_MBA_XPU_UNLOCKED_SCRIBBLED	0x2
51 #define RMB_MBA_META_DATA_AUTH_SUCCESS	0x3
52 #define RMB_MBA_AUTH_COMPLETE		0x4
53 
54 /* PBL/MBA interface registers */
55 #define RMB_MBA_IMAGE_REG		0x00
56 #define RMB_PBL_STATUS_REG		0x04
57 #define RMB_MBA_COMMAND_REG		0x08
58 #define RMB_MBA_STATUS_REG		0x0C
59 #define RMB_PMI_META_DATA_REG		0x10
60 #define RMB_PMI_CODE_START_REG		0x14
61 #define RMB_PMI_CODE_LENGTH_REG		0x18
62 #define RMB_MBA_MSS_STATUS		0x40
63 #define RMB_MBA_ALT_RESET		0x44
64 
65 #define RMB_CMD_META_DATA_READY		0x1
66 #define RMB_CMD_LOAD_READY		0x2
67 
68 /* QDSP6SS Register Offsets */
69 #define QDSP6SS_RESET_REG		0x014
70 #define QDSP6SS_GFMUX_CTL_REG		0x020
71 #define QDSP6SS_PWR_CTL_REG		0x030
72 #define QDSP6SS_MEM_PWR_CTL		0x0B0
73 #define QDSP6V6SS_MEM_PWR_CTL		0x034
74 #define QDSP6SS_STRAP_ACC		0x110
75 #define QDSP6V62SS_BHS_STATUS		0x0C4
76 
77 /* AXI Halt Register Offsets */
78 #define AXI_HALTREQ_REG			0x0
79 #define AXI_HALTACK_REG			0x4
80 #define AXI_IDLE_REG			0x8
81 #define AXI_GATING_VALID_OVERRIDE	BIT(0)
82 
83 #define HALT_ACK_TIMEOUT_US		100000
84 
85 /* QACCEPT Register Offsets */
86 #define QACCEPT_ACCEPT_REG		0x0
87 #define QACCEPT_ACTIVE_REG		0x4
88 #define QACCEPT_DENY_REG		0x8
89 #define QACCEPT_REQ_REG			0xC
90 
91 #define QACCEPT_TIMEOUT_US		50
92 
93 /* QDSP6SS_RESET */
94 #define Q6SS_STOP_CORE			BIT(0)
95 #define Q6SS_CORE_ARES			BIT(1)
96 #define Q6SS_BUS_ARES_ENABLE		BIT(2)
97 
98 /* QDSP6SS CBCR */
99 #define Q6SS_CBCR_CLKEN			BIT(0)
100 #define Q6SS_CBCR_CLKOFF		BIT(31)
101 #define Q6SS_CBCR_TIMEOUT_US		200
102 
103 /* QDSP6SS_GFMUX_CTL */
104 #define Q6SS_CLK_ENABLE			BIT(1)
105 
106 /* QDSP6SS_PWR_CTL */
107 #define Q6SS_L2DATA_SLP_NRET_N_0	BIT(0)
108 #define Q6SS_L2DATA_SLP_NRET_N_1	BIT(1)
109 #define Q6SS_L2DATA_SLP_NRET_N_2	BIT(2)
110 #define Q6SS_L2TAG_SLP_NRET_N		BIT(16)
111 #define Q6SS_ETB_SLP_NRET_N		BIT(17)
112 #define Q6SS_L2DATA_STBY_N		BIT(18)
113 #define Q6SS_SLP_RET_N			BIT(19)
114 #define Q6SS_CLAMP_IO			BIT(20)
115 #define QDSS_BHS_ON			BIT(21)
116 #define QDSS_LDO_BYP			BIT(22)
117 
118 /* QDSP6v55 parameters */
119 #define QDSP6V55_MEM_BITS		GENMASK(16, 8)
120 
121 /* QDSP6v56 parameters */
122 #define QDSP6v56_LDO_BYP		BIT(25)
123 #define QDSP6v56_BHS_ON		BIT(24)
124 #define QDSP6v56_CLAMP_WL		BIT(21)
125 #define QDSP6v56_CLAMP_QMC_MEM		BIT(22)
126 #define QDSP6SS_XO_CBCR		0x0038
127 #define QDSP6SS_ACC_OVERRIDE_VAL		0x20
128 #define QDSP6SS_ACC_OVERRIDE_VAL_9607	0x80800000
129 #define QDSP6v55_BHS_EN_REST_ACK	BIT(0)
130 
131 /* QDSP6v65 parameters */
132 #define QDSP6SS_CORE_CBCR		0x20
133 #define QDSP6SS_SLEEP                   0x3C
134 #define QDSP6SS_BOOT_CORE_START         0x400
135 #define QDSP6SS_BOOT_CMD                0x404
136 #define BOOT_FSM_TIMEOUT                10000
137 #define BHS_CHECK_MAX_LOOPS             200
138 
139 /* External power block headswitch */
140 #define EXTERNAL_BHS_ON			BIT(0)
141 #define EXTERNAL_BHS_STATUS		BIT(4)
142 #define EXTERNAL_BHS_TIMEOUT_US		50
143 
144 struct reg_info {
145 	struct regulator *reg;
146 	int uV;
147 	int uA;
148 };
149 
150 struct qcom_mss_reg_res {
151 	const char *supply;
152 	int uV;
153 	int uA;
154 };
155 
156 struct rproc_hexagon_res {
157 	const char *hexagon_mba_image;
158 	struct qcom_mss_reg_res *proxy_supply;
159 	struct qcom_mss_reg_res *fallback_proxy_supply;
160 	struct qcom_mss_reg_res *active_supply;
161 	char **proxy_clk_names;
162 	char **reset_clk_names;
163 	char **active_clk_names;
164 	char **proxy_pd_names;
165 	int version;
166 	int ssctl_id;
167 	bool need_mem_protection;
168 	bool need_pas_mem_setup;
169 	bool has_alt_reset;
170 	bool has_mba_logs;
171 	bool has_spare_reg;
172 	bool has_qaccept_regs;
173 	bool has_ext_bhs_reg;
174 	bool has_ext_cntl_regs;
175 	bool has_vq6;
176 };
177 
178 struct q6v5 {
179 	struct device *dev;
180 	struct rproc *rproc;
181 
182 	void __iomem *reg_base;
183 	void __iomem *rmb_base;
184 
185 	struct regmap *halt_map;
186 	struct regmap *conn_map;
187 
188 	u32 halt_q6;
189 	u32 halt_modem;
190 	u32 halt_nc;
191 	u32 halt_vq6;
192 	u32 conn_box;
193 	u32 ext_bhs;
194 
195 	u32 qaccept_mdm;
196 	u32 qaccept_cx;
197 	u32 qaccept_axi;
198 
199 	u32 axim1_clk_off;
200 	u32 crypto_clk_off;
201 	u32 force_clk_on;
202 	u32 rscc_disable;
203 
204 	struct reset_control *mss_restart;
205 	struct reset_control *pdc_reset;
206 
207 	struct qcom_q6v5 q6v5;
208 
209 	struct clk *active_clks[8];
210 	struct clk *reset_clks[4];
211 	struct clk *proxy_clks[4];
212 	struct device *proxy_pds[3];
213 	int active_clk_count;
214 	int reset_clk_count;
215 	int proxy_clk_count;
216 	int proxy_pd_count;
217 
218 	struct reg_info active_regs[1];
219 	struct reg_info proxy_regs[1];
220 	struct reg_info fallback_proxy_regs[2];
221 	int active_reg_count;
222 	int proxy_reg_count;
223 	int fallback_proxy_reg_count;
224 
225 	bool dump_mba_loaded;
226 	size_t current_dump_size;
227 	size_t total_dump_size;
228 
229 	phys_addr_t mba_phys;
230 	size_t mba_size;
231 	size_t dp_size;
232 
233 	phys_addr_t mdata_phys;
234 	size_t mdata_size;
235 
236 	phys_addr_t mpss_phys;
237 	phys_addr_t mpss_reloc;
238 	size_t mpss_size;
239 
240 	struct qcom_rproc_glink glink_subdev;
241 	struct qcom_rproc_subdev smd_subdev;
242 	struct qcom_rproc_pdm pdm_subdev;
243 	struct qcom_rproc_ssr ssr_subdev;
244 	struct qcom_sysmon *sysmon;
245 	struct platform_device *bam_dmux;
246 	bool need_mem_protection;
247 	bool need_pas_mem_setup;
248 	bool has_alt_reset;
249 	bool has_mba_logs;
250 	bool has_spare_reg;
251 	bool has_qaccept_regs;
252 	bool has_ext_bhs_reg;
253 	bool has_ext_cntl_regs;
254 	bool has_vq6;
255 	u64 mpss_perm;
256 	u64 mba_perm;
257 	const char *hexagon_mdt_image;
258 	int version;
259 };
260 
261 enum {
262 	MSS_MDM9607,
263 	MSS_MSM8226,
264 	MSS_MSM8909,
265 	MSS_MSM8916,
266 	MSS_MSM8917,
267 	MSS_MSM8926,
268 	MSS_MSM8937,
269 	MSS_MSM8940,
270 	MSS_MSM8953,
271 	MSS_MSM8974,
272 	MSS_MSM8996,
273 	MSS_MSM8998,
274 	MSS_SC7180,
275 	MSS_SC7280,
276 	MSS_SDM660,
277 	MSS_SDM845,
278 };
279 
q6v5_regulator_init(struct device * dev,struct reg_info * regs,const struct qcom_mss_reg_res * reg_res)280 static int q6v5_regulator_init(struct device *dev, struct reg_info *regs,
281 			       const struct qcom_mss_reg_res *reg_res)
282 {
283 	int i;
284 
285 	if (!reg_res)
286 		return 0;
287 
288 	for (i = 0; reg_res[i].supply; i++) {
289 		regs[i].reg = devm_regulator_get(dev, reg_res[i].supply);
290 		if (IS_ERR(regs[i].reg))
291 			return dev_err_probe(dev, PTR_ERR(regs[i].reg),
292 					     "Failed to get %s\n regulator",
293 					     reg_res[i].supply);
294 
295 		regs[i].uV = reg_res[i].uV;
296 		regs[i].uA = reg_res[i].uA;
297 	}
298 
299 	return i;
300 }
301 
q6v5_regulator_enable(struct q6v5 * qproc,struct reg_info * regs,int count)302 static int q6v5_regulator_enable(struct q6v5 *qproc,
303 				 struct reg_info *regs, int count)
304 {
305 	int ret;
306 	int i;
307 
308 	for (i = 0; i < count; i++) {
309 		if (regs[i].uV > 0) {
310 			ret = regulator_set_voltage(regs[i].reg,
311 					regs[i].uV, INT_MAX);
312 			if (ret) {
313 				dev_err(qproc->dev,
314 					"Failed to request voltage for %d.\n",
315 						i);
316 				goto err;
317 			}
318 		}
319 
320 		if (regs[i].uA > 0) {
321 			ret = regulator_set_load(regs[i].reg,
322 						 regs[i].uA);
323 			if (ret < 0) {
324 				dev_err(qproc->dev,
325 					"Failed to set regulator mode\n");
326 				goto err;
327 			}
328 		}
329 
330 		ret = regulator_enable(regs[i].reg);
331 		if (ret) {
332 			dev_err(qproc->dev, "Regulator enable failed\n");
333 			goto err;
334 		}
335 	}
336 
337 	return 0;
338 err:
339 	for (; i >= 0; i--) {
340 		if (regs[i].uV > 0)
341 			regulator_set_voltage(regs[i].reg, 0, INT_MAX);
342 
343 		if (regs[i].uA > 0)
344 			regulator_set_load(regs[i].reg, 0);
345 
346 		regulator_disable(regs[i].reg);
347 	}
348 
349 	return ret;
350 }
351 
q6v5_regulator_disable(struct q6v5 * qproc,struct reg_info * regs,int count)352 static void q6v5_regulator_disable(struct q6v5 *qproc,
353 				   struct reg_info *regs, int count)
354 {
355 	int i;
356 
357 	for (i = 0; i < count; i++) {
358 		if (regs[i].uV > 0)
359 			regulator_set_voltage(regs[i].reg, 0, INT_MAX);
360 
361 		if (regs[i].uA > 0)
362 			regulator_set_load(regs[i].reg, 0);
363 
364 		regulator_disable(regs[i].reg);
365 	}
366 }
367 
q6v5_clk_enable(struct device * dev,struct clk ** clks,int count)368 static int q6v5_clk_enable(struct device *dev,
369 			   struct clk **clks, int count)
370 {
371 	int rc;
372 	int i;
373 
374 	for (i = 0; i < count; i++) {
375 		rc = clk_prepare_enable(clks[i]);
376 		if (rc) {
377 			dev_err(dev, "Clock enable failed\n");
378 			goto err;
379 		}
380 	}
381 
382 	return 0;
383 err:
384 	for (i--; i >= 0; i--)
385 		clk_disable_unprepare(clks[i]);
386 
387 	return rc;
388 }
389 
q6v5_clk_disable(struct device * dev,struct clk ** clks,int count)390 static void q6v5_clk_disable(struct device *dev,
391 			     struct clk **clks, int count)
392 {
393 	int i;
394 
395 	for (i = 0; i < count; i++)
396 		clk_disable_unprepare(clks[i]);
397 }
398 
q6v5_pds_enable(struct q6v5 * qproc,struct device ** pds,size_t pd_count)399 static int q6v5_pds_enable(struct q6v5 *qproc, struct device **pds,
400 			   size_t pd_count)
401 {
402 	int ret;
403 	int i;
404 
405 	for (i = 0; i < pd_count; i++) {
406 		dev_pm_genpd_set_performance_state(pds[i], INT_MAX);
407 		ret = pm_runtime_get_sync(pds[i]);
408 		if (ret < 0) {
409 			pm_runtime_put_noidle(pds[i]);
410 			dev_pm_genpd_set_performance_state(pds[i], 0);
411 			goto unroll_pd_votes;
412 		}
413 	}
414 
415 	return 0;
416 
417 unroll_pd_votes:
418 	for (i--; i >= 0; i--) {
419 		dev_pm_genpd_set_performance_state(pds[i], 0);
420 		pm_runtime_put(pds[i]);
421 	}
422 
423 	return ret;
424 }
425 
q6v5_pds_disable(struct q6v5 * qproc,struct device ** pds,size_t pd_count)426 static void q6v5_pds_disable(struct q6v5 *qproc, struct device **pds,
427 			     size_t pd_count)
428 {
429 	int i;
430 
431 	for (i = 0; i < pd_count; i++) {
432 		dev_pm_genpd_set_performance_state(pds[i], 0);
433 		pm_runtime_put(pds[i]);
434 	}
435 }
436 
q6v5_external_bhs_enable(struct q6v5 * qproc)437 static int q6v5_external_bhs_enable(struct q6v5 *qproc)
438 {
439 	u32 val;
440 	int ret = 0;
441 
442 	/*
443 	 * Enable external power block headswitch and wait for it to
444 	 * stabilize
445 	 */
446 	regmap_set_bits(qproc->conn_map, qproc->ext_bhs, EXTERNAL_BHS_ON);
447 
448 	ret = regmap_read_poll_timeout(qproc->conn_map, qproc->ext_bhs,
449 				       val, val & EXTERNAL_BHS_STATUS,
450 				       1, EXTERNAL_BHS_TIMEOUT_US);
451 
452 	if (ret) {
453 		dev_err(qproc->dev, "External BHS timed out\n");
454 		ret = -ETIMEDOUT;
455 	}
456 
457 	return ret;
458 }
459 
q6v5_external_bhs_disable(struct q6v5 * qproc)460 static void q6v5_external_bhs_disable(struct q6v5 *qproc)
461 {
462 	regmap_clear_bits(qproc->conn_map, qproc->ext_bhs, EXTERNAL_BHS_ON);
463 }
464 
q6v5_xfer_mem_ownership(struct q6v5 * qproc,u64 * current_perm,bool local,bool remote,phys_addr_t addr,size_t size)465 static int q6v5_xfer_mem_ownership(struct q6v5 *qproc, u64 *current_perm,
466 				   bool local, bool remote, phys_addr_t addr,
467 				   size_t size)
468 {
469 	struct qcom_scm_vmperm next[2];
470 	int perms = 0;
471 
472 	if (!qproc->need_mem_protection)
473 		return 0;
474 
475 	if (local == !!(*current_perm & BIT(QCOM_SCM_VMID_HLOS)) &&
476 	    remote == !!(*current_perm & BIT(QCOM_SCM_VMID_MSS_MSA)))
477 		return 0;
478 
479 	if (local) {
480 		next[perms].vmid = QCOM_SCM_VMID_HLOS;
481 		next[perms].perm = QCOM_SCM_PERM_RWX;
482 		perms++;
483 	}
484 
485 	if (remote) {
486 		next[perms].vmid = QCOM_SCM_VMID_MSS_MSA;
487 		next[perms].perm = QCOM_SCM_PERM_RW;
488 		perms++;
489 	}
490 
491 	return qcom_scm_assign_mem(addr, ALIGN(size, SZ_4K),
492 				   current_perm, next, perms);
493 }
494 
q6v5_debug_policy_load(struct q6v5 * qproc,void * mba_region)495 static void q6v5_debug_policy_load(struct q6v5 *qproc, void *mba_region)
496 {
497 	const struct firmware *dp_fw;
498 
499 	if (request_firmware_direct(&dp_fw, "msadp", qproc->dev))
500 		return;
501 
502 	if (SZ_1M + dp_fw->size <= qproc->mba_size) {
503 		memcpy(mba_region + SZ_1M, dp_fw->data, dp_fw->size);
504 		qproc->dp_size = dp_fw->size;
505 	}
506 
507 	release_firmware(dp_fw);
508 }
509 
510 #define MSM8974_B00_OFFSET 0x1000
511 
q6v5_load(struct rproc * rproc,const struct firmware * fw)512 static int q6v5_load(struct rproc *rproc, const struct firmware *fw)
513 {
514 	struct q6v5 *qproc = rproc->priv;
515 	void *mba_region;
516 
517 	/* MBA is restricted to a maximum size of 1M */
518 	if (fw->size > qproc->mba_size || fw->size > SZ_1M) {
519 		dev_err(qproc->dev, "MBA firmware load failed\n");
520 		return -EINVAL;
521 	}
522 
523 	mba_region = memremap(qproc->mba_phys, qproc->mba_size, MEMREMAP_WC);
524 	if (!mba_region) {
525 		dev_err(qproc->dev, "unable to map memory region: %pa+%zx\n",
526 			&qproc->mba_phys, qproc->mba_size);
527 		return -EBUSY;
528 	}
529 
530 	if ((qproc->version == MSS_MSM8974 ||
531 	     qproc->version == MSS_MSM8226 ||
532 	     qproc->version == MSS_MSM8926) &&
533 	    fw->size > MSM8974_B00_OFFSET &&
534 	    !memcmp(fw->data, ELFMAG, SELFMAG))
535 		memcpy(mba_region, fw->data + MSM8974_B00_OFFSET, fw->size - MSM8974_B00_OFFSET);
536 	else
537 		memcpy(mba_region, fw->data, fw->size);
538 	q6v5_debug_policy_load(qproc, mba_region);
539 	memunmap(mba_region);
540 
541 	return 0;
542 }
543 
q6v5_reset_assert(struct q6v5 * qproc)544 static int q6v5_reset_assert(struct q6v5 *qproc)
545 {
546 	int ret;
547 
548 	if (qproc->has_alt_reset) {
549 		reset_control_assert(qproc->pdc_reset);
550 		ret = reset_control_reset(qproc->mss_restart);
551 		reset_control_deassert(qproc->pdc_reset);
552 	} else if (qproc->has_spare_reg) {
553 		/*
554 		 * When the AXI pipeline is being reset with the Q6 modem partly
555 		 * operational there is possibility of AXI valid signal to
556 		 * glitch, leading to spurious transactions and Q6 hangs. A work
557 		 * around is employed by asserting the AXI_GATING_VALID_OVERRIDE
558 		 * BIT before triggering Q6 MSS reset. AXI_GATING_VALID_OVERRIDE
559 		 * is withdrawn post MSS assert followed by a MSS deassert,
560 		 * while holding the PDC reset.
561 		 */
562 		reset_control_assert(qproc->pdc_reset);
563 		regmap_update_bits(qproc->conn_map, qproc->conn_box,
564 				   AXI_GATING_VALID_OVERRIDE, 1);
565 		reset_control_assert(qproc->mss_restart);
566 		reset_control_deassert(qproc->pdc_reset);
567 		regmap_update_bits(qproc->conn_map, qproc->conn_box,
568 				   AXI_GATING_VALID_OVERRIDE, 0);
569 		ret = reset_control_deassert(qproc->mss_restart);
570 	} else if (qproc->has_ext_cntl_regs) {
571 		regmap_write(qproc->conn_map, qproc->rscc_disable, 0);
572 		reset_control_assert(qproc->pdc_reset);
573 		reset_control_assert(qproc->mss_restart);
574 		reset_control_deassert(qproc->pdc_reset);
575 		ret = reset_control_deassert(qproc->mss_restart);
576 	} else {
577 		ret = reset_control_assert(qproc->mss_restart);
578 	}
579 
580 	return ret;
581 }
582 
q6v5_reset_deassert(struct q6v5 * qproc)583 static int q6v5_reset_deassert(struct q6v5 *qproc)
584 {
585 	int ret;
586 
587 	if (qproc->has_alt_reset) {
588 		reset_control_assert(qproc->pdc_reset);
589 		writel(1, qproc->rmb_base + RMB_MBA_ALT_RESET);
590 		ret = reset_control_reset(qproc->mss_restart);
591 		writel(0, qproc->rmb_base + RMB_MBA_ALT_RESET);
592 		reset_control_deassert(qproc->pdc_reset);
593 	} else if (qproc->has_spare_reg || qproc->has_ext_cntl_regs) {
594 		ret = reset_control_reset(qproc->mss_restart);
595 	} else {
596 		ret = reset_control_deassert(qproc->mss_restart);
597 	}
598 
599 	return ret;
600 }
601 
q6v5_rmb_pbl_wait(struct q6v5 * qproc,int ms)602 static int q6v5_rmb_pbl_wait(struct q6v5 *qproc, int ms)
603 {
604 	unsigned long timeout;
605 	s32 val;
606 
607 	timeout = jiffies + msecs_to_jiffies(ms);
608 	for (;;) {
609 		val = readl(qproc->rmb_base + RMB_PBL_STATUS_REG);
610 		if (val)
611 			break;
612 
613 		if (time_after(jiffies, timeout))
614 			return -ETIMEDOUT;
615 
616 		msleep(1);
617 	}
618 
619 	return val;
620 }
621 
q6v5_rmb_mba_wait(struct q6v5 * qproc,u32 status,int ms)622 static int q6v5_rmb_mba_wait(struct q6v5 *qproc, u32 status, int ms)
623 {
624 
625 	unsigned long timeout;
626 	s32 val;
627 
628 	timeout = jiffies + msecs_to_jiffies(ms);
629 	for (;;) {
630 		val = readl(qproc->rmb_base + RMB_MBA_STATUS_REG);
631 		if (val < 0)
632 			break;
633 
634 		if (!status && val)
635 			break;
636 		else if (status && val == status)
637 			break;
638 
639 		if (time_after(jiffies, timeout))
640 			return -ETIMEDOUT;
641 
642 		msleep(1);
643 	}
644 
645 	return val;
646 }
647 
q6v5_dump_mba_logs(struct q6v5 * qproc)648 static void q6v5_dump_mba_logs(struct q6v5 *qproc)
649 {
650 	struct rproc *rproc = qproc->rproc;
651 	void *data;
652 	void *mba_region;
653 
654 	if (!qproc->has_mba_logs)
655 		return;
656 
657 	if (q6v5_xfer_mem_ownership(qproc, &qproc->mba_perm, true, false, qproc->mba_phys,
658 				    qproc->mba_size))
659 		return;
660 
661 	mba_region = memremap(qproc->mba_phys, qproc->mba_size, MEMREMAP_WC);
662 	if (!mba_region)
663 		return;
664 
665 	data = vmalloc(MBA_LOG_SIZE);
666 	if (data) {
667 		memcpy(data, mba_region, MBA_LOG_SIZE);
668 		dev_coredumpv(&rproc->dev, data, MBA_LOG_SIZE, GFP_KERNEL);
669 	}
670 	memunmap(mba_region);
671 }
672 
q6v5proc_reset(struct q6v5 * qproc)673 static int q6v5proc_reset(struct q6v5 *qproc)
674 {
675 	u32 val;
676 	int ret;
677 	int i;
678 
679 	if (qproc->version == MSS_SDM845) {
680 		val = readl(qproc->reg_base + QDSP6SS_SLEEP);
681 		val |= Q6SS_CBCR_CLKEN;
682 		writel(val, qproc->reg_base + QDSP6SS_SLEEP);
683 
684 		ret = readl_poll_timeout(qproc->reg_base + QDSP6SS_SLEEP,
685 					 val, !(val & Q6SS_CBCR_CLKOFF), 1,
686 					 Q6SS_CBCR_TIMEOUT_US);
687 		if (ret) {
688 			dev_err(qproc->dev, "QDSP6SS Sleep clock timed out\n");
689 			return -ETIMEDOUT;
690 		}
691 
692 		/* De-assert QDSP6 stop core */
693 		writel(1, qproc->reg_base + QDSP6SS_BOOT_CORE_START);
694 		/* Trigger boot FSM */
695 		writel(1, qproc->reg_base + QDSP6SS_BOOT_CMD);
696 
697 		ret = readl_poll_timeout(qproc->rmb_base + RMB_MBA_MSS_STATUS,
698 				val, (val & BIT(0)) != 0, 10, BOOT_FSM_TIMEOUT);
699 		if (ret) {
700 			dev_err(qproc->dev, "Boot FSM failed to complete.\n");
701 			/* Reset the modem so that boot FSM is in reset state */
702 			q6v5_reset_deassert(qproc);
703 			return ret;
704 		}
705 
706 		goto pbl_wait;
707 	} else if (qproc->version == MSS_SC7180 || qproc->version == MSS_SC7280) {
708 		val = readl(qproc->reg_base + QDSP6SS_SLEEP);
709 		val |= Q6SS_CBCR_CLKEN;
710 		writel(val, qproc->reg_base + QDSP6SS_SLEEP);
711 
712 		ret = readl_poll_timeout(qproc->reg_base + QDSP6SS_SLEEP,
713 					 val, !(val & Q6SS_CBCR_CLKOFF), 1,
714 					 Q6SS_CBCR_TIMEOUT_US);
715 		if (ret) {
716 			dev_err(qproc->dev, "QDSP6SS Sleep clock timed out\n");
717 			return -ETIMEDOUT;
718 		}
719 
720 		/* Turn on the XO clock needed for PLL setup */
721 		val = readl(qproc->reg_base + QDSP6SS_XO_CBCR);
722 		val |= Q6SS_CBCR_CLKEN;
723 		writel(val, qproc->reg_base + QDSP6SS_XO_CBCR);
724 
725 		ret = readl_poll_timeout(qproc->reg_base + QDSP6SS_XO_CBCR,
726 					 val, !(val & Q6SS_CBCR_CLKOFF), 1,
727 					 Q6SS_CBCR_TIMEOUT_US);
728 		if (ret) {
729 			dev_err(qproc->dev, "QDSP6SS XO clock timed out\n");
730 			return -ETIMEDOUT;
731 		}
732 
733 		/* Configure Q6 core CBCR to auto-enable after reset sequence */
734 		val = readl(qproc->reg_base + QDSP6SS_CORE_CBCR);
735 		val |= Q6SS_CBCR_CLKEN;
736 		writel(val, qproc->reg_base + QDSP6SS_CORE_CBCR);
737 
738 		/* De-assert the Q6 stop core signal */
739 		writel(1, qproc->reg_base + QDSP6SS_BOOT_CORE_START);
740 
741 		/* Wait for 10 us for any staggering logic to settle */
742 		usleep_range(10, 20);
743 
744 		/* Trigger the boot FSM to start the Q6 out-of-reset sequence */
745 		writel(1, qproc->reg_base + QDSP6SS_BOOT_CMD);
746 
747 		/* Poll the MSS_STATUS for FSM completion */
748 		ret = readl_poll_timeout(qproc->rmb_base + RMB_MBA_MSS_STATUS,
749 					 val, (val & BIT(0)) != 0, 10, BOOT_FSM_TIMEOUT);
750 		if (ret) {
751 			dev_err(qproc->dev, "Boot FSM failed to complete.\n");
752 			/* Reset the modem so that boot FSM is in reset state */
753 			q6v5_reset_deassert(qproc);
754 			return ret;
755 		}
756 		goto pbl_wait;
757 	} else if (qproc->version == MSS_MDM9607 ||
758 		   qproc->version == MSS_MSM8909 ||
759 		   qproc->version == MSS_MSM8917 ||
760 		   qproc->version == MSS_MSM8937 ||
761 		   qproc->version == MSS_MSM8940 ||
762 		   qproc->version == MSS_MSM8953 ||
763 		   qproc->version == MSS_MSM8996 ||
764 		   qproc->version == MSS_MSM8998 ||
765 		   qproc->version == MSS_SDM660) {
766 
767 		/* Override the ACC value if required */
768 		if (qproc->version == MSS_MDM9607 ||
769 		    qproc->version == MSS_MSM8917 ||
770 		    qproc->version == MSS_MSM8937 ||
771 		    qproc->version == MSS_MSM8940)
772 			writel(QDSP6SS_ACC_OVERRIDE_VAL_9607,
773 			       qproc->reg_base + QDSP6SS_STRAP_ACC);
774 		else if (qproc->version != MSS_MSM8909 &&
775 			 qproc->version != MSS_MSM8953)
776 			writel(QDSP6SS_ACC_OVERRIDE_VAL,
777 			       qproc->reg_base + QDSP6SS_STRAP_ACC);
778 
779 		/* Assert resets, stop core */
780 		val = readl(qproc->reg_base + QDSP6SS_RESET_REG);
781 		val |= Q6SS_CORE_ARES | Q6SS_BUS_ARES_ENABLE | Q6SS_STOP_CORE;
782 		writel(val, qproc->reg_base + QDSP6SS_RESET_REG);
783 
784 		/* BHS require xo cbcr to be enabled */
785 		val = readl(qproc->reg_base + QDSP6SS_XO_CBCR);
786 		val |= Q6SS_CBCR_CLKEN;
787 		writel(val, qproc->reg_base + QDSP6SS_XO_CBCR);
788 
789 		/* Read CLKOFF bit to go low indicating CLK is enabled */
790 		ret = readl_poll_timeout(qproc->reg_base + QDSP6SS_XO_CBCR,
791 					 val, !(val & Q6SS_CBCR_CLKOFF), 1,
792 					 Q6SS_CBCR_TIMEOUT_US);
793 		if (ret) {
794 			dev_err(qproc->dev,
795 				"xo cbcr enabling timed out (rc:%d)\n", ret);
796 			return ret;
797 		}
798 		/* Enable power block headswitch and wait for it to stabilize */
799 		val = readl(qproc->reg_base + QDSP6SS_PWR_CTL_REG);
800 		val |= QDSP6v56_BHS_ON;
801 		writel(val, qproc->reg_base + QDSP6SS_PWR_CTL_REG);
802 		val |= readl(qproc->reg_base + QDSP6SS_PWR_CTL_REG);
803 		udelay(1);
804 
805 		if (qproc->version == MSS_SDM660) {
806 			ret = readl_relaxed_poll_timeout(qproc->reg_base + QDSP6V62SS_BHS_STATUS,
807 							 i, (i & QDSP6v55_BHS_EN_REST_ACK),
808 							 1, BHS_CHECK_MAX_LOOPS);
809 			if (ret == -ETIMEDOUT) {
810 				dev_err(qproc->dev, "BHS_EN_REST_ACK not set!\n");
811 				return -ETIMEDOUT;
812 			}
813 		}
814 
815 		/* Put LDO in bypass mode */
816 		val |= QDSP6v56_LDO_BYP;
817 		writel(val, qproc->reg_base + QDSP6SS_PWR_CTL_REG);
818 
819 		if (qproc->version != MSS_MSM8909) {
820 			int mem_pwr_ctl;
821 			int reverse;
822 
823 			/* Deassert QDSP6 compiler memory clamp */
824 			val = readl(qproc->reg_base + QDSP6SS_PWR_CTL_REG);
825 			val &= ~QDSP6v56_CLAMP_QMC_MEM;
826 			writel(val, qproc->reg_base + QDSP6SS_PWR_CTL_REG);
827 
828 			/* Deassert memory peripheral sleep and L2 memory standby */
829 			val |= Q6SS_L2DATA_STBY_N | Q6SS_SLP_RET_N;
830 			writel(val, qproc->reg_base + QDSP6SS_PWR_CTL_REG);
831 
832 			/* Turn on L1, L2, ETB and JU memories 1 at a time */
833 			if (qproc->version == MSS_MSM8940 ||
834 			    qproc->version == MSS_MSM8953 ||
835 			    qproc->version == MSS_MSM8996) {
836 				mem_pwr_ctl = QDSP6SS_MEM_PWR_CTL;
837 				i = 19;
838 				reverse = 0;
839 			} else if (qproc->version == MSS_MDM9607 ||
840 				   qproc->version == MSS_MSM8917 ||
841 				   qproc->version == MSS_MSM8937) {
842 				mem_pwr_ctl = QDSP6SS_MEM_PWR_CTL;
843 				i = 19;
844 				/*
845 				 * Set first 5 bits in reverse to avoid
846 				 * "inrush current" issues.
847 				 */
848 				reverse = 6;
849 			} else {
850 				/* MSS_MSM8998, MSS_SDM660 */
851 				mem_pwr_ctl = QDSP6V6SS_MEM_PWR_CTL;
852 				i = 28;
853 				reverse = 0;
854 			}
855 
856 			val = readl(qproc->reg_base + mem_pwr_ctl);
857 			for (; i >= reverse; i--) {
858 				val |= BIT(i);
859 				writel(val, qproc->reg_base + mem_pwr_ctl);
860 				val = readl(qproc->reg_base + mem_pwr_ctl);
861 				udelay(1);
862 			}
863 			for (i = 0; i < reverse; i++) {
864 				val |= BIT(i);
865 				writel(val, qproc->reg_base + mem_pwr_ctl);
866 				/*
867 				 * Read back value to ensure the write is done then
868 				 * wait for 1us for both memory peripheral and data
869 				 * array to turn on.
870 				 */
871 				val = readl(qproc->reg_base + mem_pwr_ctl);
872 				udelay(1);
873 			}
874 		} else {
875 			/* Turn on memories */
876 			val = readl(qproc->reg_base + QDSP6SS_PWR_CTL_REG);
877 			val |= Q6SS_SLP_RET_N | Q6SS_L2DATA_STBY_N |
878 			       Q6SS_ETB_SLP_NRET_N | QDSP6V55_MEM_BITS;
879 			writel(val, qproc->reg_base + QDSP6SS_PWR_CTL_REG);
880 
881 			/* Turn on L2 banks 1 at a time */
882 			for (i = 0; i <= 7; i++) {
883 				val |= BIT(i);
884 				writel(val, qproc->reg_base + QDSP6SS_PWR_CTL_REG);
885 			}
886 		}
887 
888 		/* Remove word line clamp */
889 		val = readl(qproc->reg_base + QDSP6SS_PWR_CTL_REG);
890 		val &= ~QDSP6v56_CLAMP_WL;
891 		writel(val, qproc->reg_base + QDSP6SS_PWR_CTL_REG);
892 	} else {
893 		/* Assert resets, stop core */
894 		val = readl(qproc->reg_base + QDSP6SS_RESET_REG);
895 		val |= Q6SS_CORE_ARES | Q6SS_BUS_ARES_ENABLE | Q6SS_STOP_CORE;
896 		writel(val, qproc->reg_base + QDSP6SS_RESET_REG);
897 
898 		/* Enable power block headswitch and wait for it to stabilize */
899 		val = readl(qproc->reg_base + QDSP6SS_PWR_CTL_REG);
900 		val |= QDSS_BHS_ON | QDSS_LDO_BYP;
901 		writel(val, qproc->reg_base + QDSP6SS_PWR_CTL_REG);
902 		val |= readl(qproc->reg_base + QDSP6SS_PWR_CTL_REG);
903 		udelay(1);
904 		/*
905 		 * Turn on memories. L2 banks should be done individually
906 		 * to minimize inrush current.
907 		 */
908 		val = readl(qproc->reg_base + QDSP6SS_PWR_CTL_REG);
909 		val |= Q6SS_SLP_RET_N | Q6SS_L2TAG_SLP_NRET_N |
910 			Q6SS_ETB_SLP_NRET_N | Q6SS_L2DATA_STBY_N;
911 		writel(val, qproc->reg_base + QDSP6SS_PWR_CTL_REG);
912 		val |= Q6SS_L2DATA_SLP_NRET_N_2;
913 		writel(val, qproc->reg_base + QDSP6SS_PWR_CTL_REG);
914 		val |= Q6SS_L2DATA_SLP_NRET_N_1;
915 		writel(val, qproc->reg_base + QDSP6SS_PWR_CTL_REG);
916 		val |= Q6SS_L2DATA_SLP_NRET_N_0;
917 		writel(val, qproc->reg_base + QDSP6SS_PWR_CTL_REG);
918 	}
919 	/* Remove IO clamp */
920 	val &= ~Q6SS_CLAMP_IO;
921 	writel(val, qproc->reg_base + QDSP6SS_PWR_CTL_REG);
922 
923 	/* Bring core out of reset */
924 	val = readl(qproc->reg_base + QDSP6SS_RESET_REG);
925 	val &= ~Q6SS_CORE_ARES;
926 	writel(val, qproc->reg_base + QDSP6SS_RESET_REG);
927 
928 	/* Turn on core clock */
929 	val = readl(qproc->reg_base + QDSP6SS_GFMUX_CTL_REG);
930 	val |= Q6SS_CLK_ENABLE;
931 	writel(val, qproc->reg_base + QDSP6SS_GFMUX_CTL_REG);
932 
933 	/* Start core execution */
934 	val = readl(qproc->reg_base + QDSP6SS_RESET_REG);
935 	val &= ~Q6SS_STOP_CORE;
936 	writel(val, qproc->reg_base + QDSP6SS_RESET_REG);
937 
938 pbl_wait:
939 	/* Wait for PBL status */
940 	ret = q6v5_rmb_pbl_wait(qproc, 1000);
941 	if (ret == -ETIMEDOUT) {
942 		dev_err(qproc->dev, "PBL boot timed out\n");
943 	} else if (ret != RMB_PBL_SUCCESS) {
944 		dev_err(qproc->dev, "PBL returned unexpected status %d\n", ret);
945 		ret = -EINVAL;
946 	} else {
947 		ret = 0;
948 	}
949 
950 	return ret;
951 }
952 
q6v5proc_enable_qchannel(struct q6v5 * qproc,struct regmap * map,u32 offset)953 static int q6v5proc_enable_qchannel(struct q6v5 *qproc, struct regmap *map, u32 offset)
954 {
955 	unsigned int val;
956 	int ret;
957 
958 	if (!qproc->has_qaccept_regs)
959 		return 0;
960 
961 	if (qproc->has_ext_cntl_regs) {
962 		regmap_write(qproc->conn_map, qproc->rscc_disable, 0);
963 		regmap_write(qproc->conn_map, qproc->force_clk_on, 1);
964 
965 		ret = regmap_read_poll_timeout(qproc->halt_map, qproc->axim1_clk_off, val,
966 					       !val, 1, Q6SS_CBCR_TIMEOUT_US);
967 		if (ret) {
968 			dev_err(qproc->dev, "failed to enable axim1 clock\n");
969 			return -ETIMEDOUT;
970 		}
971 	}
972 
973 	regmap_write(map, offset + QACCEPT_REQ_REG, 1);
974 
975 	/* Wait for accept */
976 	ret = regmap_read_poll_timeout(map, offset + QACCEPT_ACCEPT_REG, val, val, 5,
977 				       QACCEPT_TIMEOUT_US);
978 	if (ret) {
979 		dev_err(qproc->dev, "qchannel enable failed\n");
980 		return -ETIMEDOUT;
981 	}
982 
983 	return 0;
984 }
985 
q6v5proc_disable_qchannel(struct q6v5 * qproc,struct regmap * map,u32 offset)986 static void q6v5proc_disable_qchannel(struct q6v5 *qproc, struct regmap *map, u32 offset)
987 {
988 	int ret;
989 	unsigned int val, retry;
990 	unsigned int nretry = 10;
991 	bool takedown_complete = false;
992 
993 	if (!qproc->has_qaccept_regs)
994 		return;
995 
996 	while (!takedown_complete && nretry) {
997 		nretry--;
998 
999 		/* Wait for active transactions to complete */
1000 		regmap_read_poll_timeout(map, offset + QACCEPT_ACTIVE_REG, val, !val, 5,
1001 					 QACCEPT_TIMEOUT_US);
1002 
1003 		/* Request Q-channel transaction takedown */
1004 		regmap_write(map, offset + QACCEPT_REQ_REG, 0);
1005 
1006 		/*
1007 		 * If the request is denied, reset the Q-channel takedown request,
1008 		 * wait for active transactions to complete and retry takedown.
1009 		 */
1010 		retry = 10;
1011 		while (retry) {
1012 			usleep_range(5, 10);
1013 			retry--;
1014 			ret = regmap_read(map, offset + QACCEPT_DENY_REG, &val);
1015 			if (!ret && val) {
1016 				regmap_write(map, offset + QACCEPT_REQ_REG, 1);
1017 				break;
1018 			}
1019 
1020 			ret = regmap_read(map, offset + QACCEPT_ACCEPT_REG, &val);
1021 			if (!ret && !val) {
1022 				takedown_complete = true;
1023 				break;
1024 			}
1025 		}
1026 
1027 		if (!retry)
1028 			break;
1029 	}
1030 
1031 	/* Rely on mss_restart to clear out pending transactions on takedown failure */
1032 	if (!takedown_complete)
1033 		dev_err(qproc->dev, "qchannel takedown failed\n");
1034 }
1035 
q6v5proc_halt_axi_port(struct q6v5 * qproc,struct regmap * halt_map,u32 offset)1036 static void q6v5proc_halt_axi_port(struct q6v5 *qproc,
1037 				   struct regmap *halt_map,
1038 				   u32 offset)
1039 {
1040 	unsigned int val;
1041 	int ret;
1042 
1043 	/* Check if we're already idle */
1044 	ret = regmap_read(halt_map, offset + AXI_IDLE_REG, &val);
1045 	if (!ret && val)
1046 		return;
1047 
1048 	/* Assert halt request */
1049 	regmap_write(halt_map, offset + AXI_HALTREQ_REG, 1);
1050 
1051 	/* Wait for halt */
1052 	regmap_read_poll_timeout(halt_map, offset + AXI_HALTACK_REG, val,
1053 				 val, 1000, HALT_ACK_TIMEOUT_US);
1054 
1055 	ret = regmap_read(halt_map, offset + AXI_IDLE_REG, &val);
1056 	if (ret || !val)
1057 		dev_err(qproc->dev, "port failed halt\n");
1058 
1059 	/* Clear halt request (port will remain halted until reset) */
1060 	regmap_write(halt_map, offset + AXI_HALTREQ_REG, 0);
1061 }
1062 
q6v5_mpss_init_image(struct q6v5 * qproc,const struct firmware * fw,const char * fw_name)1063 static int q6v5_mpss_init_image(struct q6v5 *qproc, const struct firmware *fw,
1064 				const char *fw_name)
1065 {
1066 	unsigned long dma_attrs = DMA_ATTR_FORCE_CONTIGUOUS;
1067 	dma_addr_t phys;
1068 	void *metadata;
1069 	u64 mdata_perm;
1070 	int xferop_ret;
1071 	size_t size;
1072 	void *ptr;
1073 	int ret;
1074 
1075 	metadata = qcom_mdt_read_metadata(fw, &size, fw_name, qproc->dev);
1076 	if (IS_ERR(metadata))
1077 		return PTR_ERR(metadata);
1078 
1079 	if (qproc->mdata_phys) {
1080 		if (size > qproc->mdata_size) {
1081 			ret = -EINVAL;
1082 			dev_err(qproc->dev, "metadata size outside memory range\n");
1083 			goto free_metadata;
1084 		}
1085 
1086 		phys = qproc->mdata_phys;
1087 		ptr = memremap(qproc->mdata_phys, size, MEMREMAP_WC);
1088 		if (!ptr) {
1089 			ret = -EBUSY;
1090 			dev_err(qproc->dev, "unable to map memory region: %pa+%zx\n",
1091 				&qproc->mdata_phys, size);
1092 			goto free_metadata;
1093 		}
1094 	} else {
1095 		ptr = dma_alloc_attrs(qproc->dev, size, &phys, GFP_KERNEL, dma_attrs);
1096 		if (!ptr) {
1097 			ret = -ENOMEM;
1098 			dev_err(qproc->dev, "failed to allocate mdt buffer\n");
1099 			goto free_metadata;
1100 		}
1101 	}
1102 
1103 	memcpy(ptr, metadata, size);
1104 
1105 	if (qproc->mdata_phys)
1106 		memunmap(ptr);
1107 
1108 	/* Hypervisor mapping to access metadata by modem */
1109 	mdata_perm = BIT(QCOM_SCM_VMID_HLOS);
1110 	ret = q6v5_xfer_mem_ownership(qproc, &mdata_perm, false, true,
1111 				      phys, size);
1112 	if (ret) {
1113 		dev_err(qproc->dev,
1114 			"assigning Q6 access to metadata failed: %d\n", ret);
1115 		ret = -EAGAIN;
1116 		goto free_dma_attrs;
1117 	}
1118 
1119 	writel(phys, qproc->rmb_base + RMB_PMI_META_DATA_REG);
1120 	writel(RMB_CMD_META_DATA_READY, qproc->rmb_base + RMB_MBA_COMMAND_REG);
1121 
1122 	ret = q6v5_rmb_mba_wait(qproc, RMB_MBA_META_DATA_AUTH_SUCCESS, 1000);
1123 	if (ret == -ETIMEDOUT)
1124 		dev_err(qproc->dev, "MPSS header authentication timed out\n");
1125 	else if (ret < 0)
1126 		dev_err(qproc->dev, "MPSS header authentication failed: %d\n", ret);
1127 
1128 	/* Metadata authentication done, remove modem access */
1129 	xferop_ret = q6v5_xfer_mem_ownership(qproc, &mdata_perm, true, false,
1130 					     phys, size);
1131 	if (xferop_ret)
1132 		dev_warn(qproc->dev,
1133 			 "mdt buffer not reclaimed system may become unstable\n");
1134 
1135 free_dma_attrs:
1136 	if (!qproc->mdata_phys)
1137 		dma_free_attrs(qproc->dev, size, ptr, phys, dma_attrs);
1138 free_metadata:
1139 	kfree(metadata);
1140 
1141 	return ret < 0 ? ret : 0;
1142 }
1143 
q6v5_phdr_valid(const struct elf32_phdr * phdr)1144 static bool q6v5_phdr_valid(const struct elf32_phdr *phdr)
1145 {
1146 	if (phdr->p_type != PT_LOAD)
1147 		return false;
1148 
1149 	if ((phdr->p_flags & QCOM_MDT_TYPE_MASK) == QCOM_MDT_TYPE_HASH)
1150 		return false;
1151 
1152 	if (!phdr->p_memsz)
1153 		return false;
1154 
1155 	return true;
1156 }
1157 
q6v5_mba_load(struct q6v5 * qproc)1158 static int q6v5_mba_load(struct q6v5 *qproc)
1159 {
1160 	int ret;
1161 	int xfermemop_ret;
1162 	bool mba_load_err = false;
1163 
1164 	ret = qcom_q6v5_prepare(&qproc->q6v5);
1165 	if (ret)
1166 		return ret;
1167 
1168 	ret = q6v5_pds_enable(qproc, qproc->proxy_pds, qproc->proxy_pd_count);
1169 	if (ret < 0) {
1170 		dev_err(qproc->dev, "failed to enable proxy power domains\n");
1171 		goto disable_irqs;
1172 	}
1173 
1174 	ret = q6v5_regulator_enable(qproc, qproc->fallback_proxy_regs,
1175 				    qproc->fallback_proxy_reg_count);
1176 	if (ret) {
1177 		dev_err(qproc->dev, "failed to enable fallback proxy supplies\n");
1178 		goto disable_proxy_pds;
1179 	}
1180 
1181 	ret = q6v5_regulator_enable(qproc, qproc->proxy_regs,
1182 				    qproc->proxy_reg_count);
1183 	if (ret) {
1184 		dev_err(qproc->dev, "failed to enable proxy supplies\n");
1185 		goto disable_fallback_proxy_reg;
1186 	}
1187 
1188 	ret = q6v5_clk_enable(qproc->dev, qproc->proxy_clks,
1189 			      qproc->proxy_clk_count);
1190 	if (ret) {
1191 		dev_err(qproc->dev, "failed to enable proxy clocks\n");
1192 		goto disable_proxy_reg;
1193 	}
1194 
1195 	ret = q6v5_regulator_enable(qproc, qproc->active_regs,
1196 				    qproc->active_reg_count);
1197 	if (ret) {
1198 		dev_err(qproc->dev, "failed to enable supplies\n");
1199 		goto disable_proxy_clk;
1200 	}
1201 
1202 	if (qproc->has_ext_bhs_reg) {
1203 		ret = q6v5_external_bhs_enable(qproc);
1204 		if (ret < 0)
1205 			goto disable_vdd;
1206 	}
1207 
1208 	ret = q6v5_clk_enable(qproc->dev, qproc->reset_clks,
1209 			      qproc->reset_clk_count);
1210 	if (ret) {
1211 		dev_err(qproc->dev, "failed to enable reset clocks\n");
1212 		goto disable_ext_bhs;
1213 	}
1214 
1215 	ret = q6v5_reset_deassert(qproc);
1216 	if (ret) {
1217 		dev_err(qproc->dev, "failed to deassert mss restart\n");
1218 		goto disable_reset_clks;
1219 	}
1220 
1221 	ret = q6v5_clk_enable(qproc->dev, qproc->active_clks,
1222 			      qproc->active_clk_count);
1223 	if (ret) {
1224 		dev_err(qproc->dev, "failed to enable clocks\n");
1225 		goto assert_reset;
1226 	}
1227 
1228 	ret = q6v5proc_enable_qchannel(qproc, qproc->halt_map, qproc->qaccept_axi);
1229 	if (ret) {
1230 		dev_err(qproc->dev, "failed to enable axi bridge\n");
1231 		goto disable_active_clks;
1232 	}
1233 
1234 	/*
1235 	 * Some versions of the MBA firmware will upon boot wipe the MPSS region as well, so provide
1236 	 * the Q6 access to this region.
1237 	 */
1238 	ret = q6v5_xfer_mem_ownership(qproc, &qproc->mpss_perm, false, true,
1239 				      qproc->mpss_phys, qproc->mpss_size);
1240 	if (ret) {
1241 		dev_err(qproc->dev, "assigning Q6 access to mpss memory failed: %d\n", ret);
1242 		goto disable_active_clks;
1243 	}
1244 
1245 	/* Assign MBA image access in DDR to q6 */
1246 	ret = q6v5_xfer_mem_ownership(qproc, &qproc->mba_perm, false, true,
1247 				      qproc->mba_phys, qproc->mba_size);
1248 	if (ret) {
1249 		dev_err(qproc->dev,
1250 			"assigning Q6 access to mba memory failed: %d\n", ret);
1251 		goto disable_active_clks;
1252 	}
1253 
1254 	if (qproc->has_mba_logs)
1255 		qcom_pil_info_store("mba", qproc->mba_phys, MBA_LOG_SIZE);
1256 
1257 	writel(qproc->mba_phys, qproc->rmb_base + RMB_MBA_IMAGE_REG);
1258 	if (qproc->dp_size) {
1259 		writel(qproc->mba_phys + SZ_1M, qproc->rmb_base + RMB_PMI_CODE_START_REG);
1260 		writel(qproc->dp_size, qproc->rmb_base + RMB_PMI_CODE_LENGTH_REG);
1261 	}
1262 
1263 	ret = q6v5proc_reset(qproc);
1264 	if (ret)
1265 		goto reclaim_mba;
1266 
1267 	ret = q6v5_rmb_mba_wait(qproc, 0, 5000);
1268 	if (ret == -ETIMEDOUT) {
1269 		dev_err(qproc->dev, "MBA boot timed out\n");
1270 		goto halt_axi_ports;
1271 	} else if (ret != RMB_MBA_XPU_UNLOCKED &&
1272 		   ret != RMB_MBA_XPU_UNLOCKED_SCRIBBLED) {
1273 		dev_err(qproc->dev, "MBA returned unexpected status %d\n", ret);
1274 		ret = -EINVAL;
1275 		goto halt_axi_ports;
1276 	}
1277 
1278 	qproc->dump_mba_loaded = true;
1279 	return 0;
1280 
1281 halt_axi_ports:
1282 	q6v5proc_halt_axi_port(qproc, qproc->halt_map, qproc->halt_q6);
1283 	if (qproc->has_vq6)
1284 		q6v5proc_halt_axi_port(qproc, qproc->halt_map, qproc->halt_vq6);
1285 	q6v5proc_halt_axi_port(qproc, qproc->halt_map, qproc->halt_modem);
1286 	q6v5proc_halt_axi_port(qproc, qproc->halt_map, qproc->halt_nc);
1287 	q6v5proc_disable_qchannel(qproc, qproc->halt_map, qproc->qaccept_mdm);
1288 	q6v5proc_disable_qchannel(qproc, qproc->halt_map, qproc->qaccept_cx);
1289 	q6v5proc_disable_qchannel(qproc, qproc->halt_map, qproc->qaccept_axi);
1290 	mba_load_err = true;
1291 reclaim_mba:
1292 	xfermemop_ret = q6v5_xfer_mem_ownership(qproc, &qproc->mba_perm, true,
1293 						false, qproc->mba_phys,
1294 						qproc->mba_size);
1295 	if (xfermemop_ret) {
1296 		dev_err(qproc->dev,
1297 			"Failed to reclaim mba buffer, system may become unstable\n");
1298 	} else if (mba_load_err) {
1299 		q6v5_dump_mba_logs(qproc);
1300 	}
1301 
1302 disable_active_clks:
1303 	q6v5_clk_disable(qproc->dev, qproc->active_clks,
1304 			 qproc->active_clk_count);
1305 assert_reset:
1306 	q6v5_reset_assert(qproc);
1307 disable_reset_clks:
1308 	q6v5_clk_disable(qproc->dev, qproc->reset_clks,
1309 			 qproc->reset_clk_count);
1310 disable_ext_bhs:
1311 	if (qproc->has_ext_bhs_reg)
1312 		q6v5_external_bhs_disable(qproc);
1313 disable_vdd:
1314 	q6v5_regulator_disable(qproc, qproc->active_regs,
1315 			       qproc->active_reg_count);
1316 disable_proxy_clk:
1317 	q6v5_clk_disable(qproc->dev, qproc->proxy_clks,
1318 			 qproc->proxy_clk_count);
1319 disable_proxy_reg:
1320 	q6v5_regulator_disable(qproc, qproc->proxy_regs,
1321 			       qproc->proxy_reg_count);
1322 disable_fallback_proxy_reg:
1323 	q6v5_regulator_disable(qproc, qproc->fallback_proxy_regs,
1324 			       qproc->fallback_proxy_reg_count);
1325 disable_proxy_pds:
1326 	q6v5_pds_disable(qproc, qproc->proxy_pds, qproc->proxy_pd_count);
1327 disable_irqs:
1328 	qcom_q6v5_unprepare(&qproc->q6v5);
1329 
1330 	return ret;
1331 }
1332 
q6v5_mba_reclaim(struct q6v5 * qproc)1333 static void q6v5_mba_reclaim(struct q6v5 *qproc)
1334 {
1335 	int ret;
1336 	u32 val;
1337 
1338 	qproc->dump_mba_loaded = false;
1339 	qproc->dp_size = 0;
1340 
1341 	q6v5proc_halt_axi_port(qproc, qproc->halt_map, qproc->halt_q6);
1342 	if (qproc->has_vq6)
1343 		q6v5proc_halt_axi_port(qproc, qproc->halt_map, qproc->halt_vq6);
1344 	q6v5proc_halt_axi_port(qproc, qproc->halt_map, qproc->halt_modem);
1345 	q6v5proc_halt_axi_port(qproc, qproc->halt_map, qproc->halt_nc);
1346 	if (qproc->version == MSS_MSM8996) {
1347 		/*
1348 		 * To avoid high MX current during LPASS/MSS restart.
1349 		 */
1350 		val = readl(qproc->reg_base + QDSP6SS_PWR_CTL_REG);
1351 		val |= Q6SS_CLAMP_IO | QDSP6v56_CLAMP_WL |
1352 			QDSP6v56_CLAMP_QMC_MEM;
1353 		writel(val, qproc->reg_base + QDSP6SS_PWR_CTL_REG);
1354 	}
1355 
1356 	if (qproc->has_ext_cntl_regs) {
1357 		regmap_write(qproc->conn_map, qproc->rscc_disable, 1);
1358 
1359 		ret = regmap_read_poll_timeout(qproc->halt_map, qproc->axim1_clk_off, val,
1360 					       !val, 1, Q6SS_CBCR_TIMEOUT_US);
1361 		if (ret)
1362 			dev_err(qproc->dev, "failed to enable axim1 clock\n");
1363 
1364 		ret = regmap_read_poll_timeout(qproc->halt_map, qproc->crypto_clk_off, val,
1365 					       !val, 1, Q6SS_CBCR_TIMEOUT_US);
1366 		if (ret)
1367 			dev_err(qproc->dev, "failed to enable crypto clock\n");
1368 	}
1369 
1370 	q6v5proc_disable_qchannel(qproc, qproc->halt_map, qproc->qaccept_mdm);
1371 	q6v5proc_disable_qchannel(qproc, qproc->halt_map, qproc->qaccept_cx);
1372 	q6v5proc_disable_qchannel(qproc, qproc->halt_map, qproc->qaccept_axi);
1373 
1374 	q6v5_reset_assert(qproc);
1375 
1376 	q6v5_clk_disable(qproc->dev, qproc->reset_clks,
1377 			 qproc->reset_clk_count);
1378 	q6v5_clk_disable(qproc->dev, qproc->active_clks,
1379 			 qproc->active_clk_count);
1380 	if (qproc->has_ext_bhs_reg)
1381 		q6v5_external_bhs_disable(qproc);
1382 	q6v5_regulator_disable(qproc, qproc->active_regs,
1383 			       qproc->active_reg_count);
1384 
1385 	/* In case of failure or coredump scenario where reclaiming MBA memory
1386 	 * could not happen reclaim it here.
1387 	 */
1388 	ret = q6v5_xfer_mem_ownership(qproc, &qproc->mba_perm, true, false,
1389 				      qproc->mba_phys,
1390 				      qproc->mba_size);
1391 	WARN_ON(ret);
1392 
1393 	ret = qcom_q6v5_unprepare(&qproc->q6v5);
1394 	if (ret) {
1395 		q6v5_pds_disable(qproc, qproc->proxy_pds,
1396 				 qproc->proxy_pd_count);
1397 		q6v5_clk_disable(qproc->dev, qproc->proxy_clks,
1398 				 qproc->proxy_clk_count);
1399 		q6v5_regulator_disable(qproc, qproc->fallback_proxy_regs,
1400 				       qproc->fallback_proxy_reg_count);
1401 		q6v5_regulator_disable(qproc, qproc->proxy_regs,
1402 				       qproc->proxy_reg_count);
1403 	}
1404 }
1405 
q6v5_reload_mba(struct rproc * rproc)1406 static int q6v5_reload_mba(struct rproc *rproc)
1407 {
1408 	struct q6v5 *qproc = rproc->priv;
1409 	const struct firmware *fw;
1410 	int ret;
1411 
1412 	ret = request_firmware(&fw, rproc->firmware, qproc->dev);
1413 	if (ret < 0)
1414 		return ret;
1415 
1416 	q6v5_load(rproc, fw);
1417 	ret = q6v5_mba_load(qproc);
1418 	release_firmware(fw);
1419 
1420 	return ret;
1421 }
1422 
q6v5_mpss_load(struct q6v5 * qproc)1423 static int q6v5_mpss_load(struct q6v5 *qproc)
1424 {
1425 	const struct elf32_phdr *phdrs;
1426 	const struct elf32_phdr *phdr;
1427 	const struct firmware *seg_fw;
1428 	const struct firmware *fw;
1429 	struct elf32_hdr *ehdr;
1430 	phys_addr_t mpss_reloc;
1431 	phys_addr_t boot_addr;
1432 	phys_addr_t min_addr = PHYS_ADDR_MAX;
1433 	phys_addr_t max_addr = 0;
1434 	u32 code_length;
1435 	bool relocate = false;
1436 	char *fw_name;
1437 	size_t fw_name_len;
1438 	ssize_t offset;
1439 	size_t size = 0;
1440 	void *ptr;
1441 	int ret;
1442 	int i;
1443 
1444 	fw_name_len = strlen(qproc->hexagon_mdt_image);
1445 	if (fw_name_len <= 4)
1446 		return -EINVAL;
1447 
1448 	fw_name = kstrdup(qproc->hexagon_mdt_image, GFP_KERNEL);
1449 	if (!fw_name)
1450 		return -ENOMEM;
1451 
1452 	ret = request_firmware(&fw, fw_name, qproc->dev);
1453 	if (ret < 0) {
1454 		dev_err(qproc->dev, "unable to load %s\n", fw_name);
1455 		goto out;
1456 	}
1457 
1458 	/* Initialize the RMB validator */
1459 	writel(0, qproc->rmb_base + RMB_PMI_CODE_LENGTH_REG);
1460 
1461 	ret = q6v5_mpss_init_image(qproc, fw, qproc->hexagon_mdt_image);
1462 	if (ret)
1463 		goto release_firmware;
1464 
1465 	ehdr = (struct elf32_hdr *)fw->data;
1466 	phdrs = (struct elf32_phdr *)(ehdr + 1);
1467 
1468 	for (i = 0; i < ehdr->e_phnum; i++) {
1469 		phdr = &phdrs[i];
1470 
1471 		if (!q6v5_phdr_valid(phdr))
1472 			continue;
1473 
1474 		if (phdr->p_flags & QCOM_MDT_RELOCATABLE)
1475 			relocate = true;
1476 
1477 		if (phdr->p_paddr < min_addr)
1478 			min_addr = phdr->p_paddr;
1479 
1480 		if (phdr->p_paddr + phdr->p_memsz > max_addr)
1481 			max_addr = ALIGN(phdr->p_paddr + phdr->p_memsz, SZ_4K);
1482 	}
1483 
1484 	if (qproc->need_pas_mem_setup) {
1485 		ret = qcom_pas_mem_setup(MPSS_PAS_ID, qproc->mpss_phys, qproc->mpss_size);
1486 		if (ret) {
1487 			dev_err(qproc->dev,
1488 				"setting up mpss memory failed: %d\n", ret);
1489 			goto release_firmware;
1490 		}
1491 	}
1492 
1493 	/*
1494 	 * In case of a modem subsystem restart on secure devices, the modem
1495 	 * memory can be reclaimed only after MBA is loaded.
1496 	 */
1497 	q6v5_xfer_mem_ownership(qproc, &qproc->mpss_perm, true, false,
1498 				qproc->mpss_phys, qproc->mpss_size);
1499 
1500 	/* Share ownership between Linux and MSS, during segment loading */
1501 	ret = q6v5_xfer_mem_ownership(qproc, &qproc->mpss_perm, true, true,
1502 				      qproc->mpss_phys, qproc->mpss_size);
1503 	if (ret) {
1504 		dev_err(qproc->dev,
1505 			"assigning Q6 access to mpss memory failed: %d\n", ret);
1506 		ret = -EAGAIN;
1507 		goto release_firmware;
1508 	}
1509 
1510 	mpss_reloc = relocate ? min_addr : qproc->mpss_phys;
1511 	qproc->mpss_reloc = mpss_reloc;
1512 	/* Load firmware segments */
1513 	for (i = 0; i < ehdr->e_phnum; i++) {
1514 		phdr = &phdrs[i];
1515 
1516 		if (!q6v5_phdr_valid(phdr))
1517 			continue;
1518 
1519 		offset = phdr->p_paddr - mpss_reloc;
1520 		if (offset < 0 || offset + phdr->p_memsz > qproc->mpss_size) {
1521 			dev_err(qproc->dev, "segment outside memory range\n");
1522 			ret = -EINVAL;
1523 			goto release_firmware;
1524 		}
1525 
1526 		if (phdr->p_filesz > phdr->p_memsz) {
1527 			dev_err(qproc->dev,
1528 				"refusing to load segment %d with p_filesz > p_memsz\n",
1529 				i);
1530 			ret = -EINVAL;
1531 			goto release_firmware;
1532 		}
1533 
1534 		ptr = memremap(qproc->mpss_phys + offset, phdr->p_memsz, MEMREMAP_WC);
1535 		if (!ptr) {
1536 			dev_err(qproc->dev,
1537 				"unable to map memory region: %pa+%zx-%x\n",
1538 				&qproc->mpss_phys, offset, phdr->p_memsz);
1539 			goto release_firmware;
1540 		}
1541 
1542 		if (phdr->p_filesz && phdr->p_offset < fw->size) {
1543 			/* Firmware is large enough to be non-split */
1544 			if (phdr->p_offset + phdr->p_filesz > fw->size) {
1545 				dev_err(qproc->dev,
1546 					"failed to load segment %d from truncated file %s\n",
1547 					i, fw_name);
1548 				ret = -EINVAL;
1549 				memunmap(ptr);
1550 				goto release_firmware;
1551 			}
1552 
1553 			memcpy(ptr, fw->data + phdr->p_offset, phdr->p_filesz);
1554 		} else if (phdr->p_filesz) {
1555 			/* Replace "xxx.xxx" with "xxx.bxx" */
1556 			sprintf(fw_name + fw_name_len - 3, "b%02d", i);
1557 			ret = request_firmware_into_buf(&seg_fw, fw_name, qproc->dev,
1558 							ptr, phdr->p_filesz);
1559 			if (ret) {
1560 				dev_err(qproc->dev, "failed to load %s\n", fw_name);
1561 				memunmap(ptr);
1562 				goto release_firmware;
1563 			}
1564 
1565 			if (seg_fw->size != phdr->p_filesz) {
1566 				dev_err(qproc->dev,
1567 					"failed to load segment %d from truncated file %s\n",
1568 					i, fw_name);
1569 				ret = -EINVAL;
1570 				release_firmware(seg_fw);
1571 				memunmap(ptr);
1572 				goto release_firmware;
1573 			}
1574 
1575 			release_firmware(seg_fw);
1576 		}
1577 
1578 		if (phdr->p_memsz > phdr->p_filesz) {
1579 			memset(ptr + phdr->p_filesz, 0,
1580 			       phdr->p_memsz - phdr->p_filesz);
1581 		}
1582 		memunmap(ptr);
1583 		size += phdr->p_memsz;
1584 
1585 		code_length = readl(qproc->rmb_base + RMB_PMI_CODE_LENGTH_REG);
1586 		if (!code_length) {
1587 			boot_addr = relocate ? qproc->mpss_phys : min_addr;
1588 			writel(boot_addr, qproc->rmb_base + RMB_PMI_CODE_START_REG);
1589 			writel(RMB_CMD_LOAD_READY, qproc->rmb_base + RMB_MBA_COMMAND_REG);
1590 		}
1591 		writel(size, qproc->rmb_base + RMB_PMI_CODE_LENGTH_REG);
1592 
1593 		ret = readl(qproc->rmb_base + RMB_MBA_STATUS_REG);
1594 		if (ret < 0) {
1595 			dev_err(qproc->dev, "MPSS authentication failed: %d\n",
1596 				ret);
1597 			goto release_firmware;
1598 		}
1599 	}
1600 
1601 	/* Transfer ownership of modem ddr region to q6 */
1602 	ret = q6v5_xfer_mem_ownership(qproc, &qproc->mpss_perm, false, true,
1603 				      qproc->mpss_phys, qproc->mpss_size);
1604 	if (ret) {
1605 		dev_err(qproc->dev,
1606 			"assigning Q6 access to mpss memory failed: %d\n", ret);
1607 		ret = -EAGAIN;
1608 		goto release_firmware;
1609 	}
1610 
1611 	ret = q6v5_rmb_mba_wait(qproc, RMB_MBA_AUTH_COMPLETE, 10000);
1612 	if (ret == -ETIMEDOUT)
1613 		dev_err(qproc->dev, "MPSS authentication timed out\n");
1614 	else if (ret < 0)
1615 		dev_err(qproc->dev, "MPSS authentication failed: %d\n", ret);
1616 
1617 	qcom_pil_info_store("modem", qproc->mpss_phys, qproc->mpss_size);
1618 
1619 release_firmware:
1620 	release_firmware(fw);
1621 out:
1622 	kfree(fw_name);
1623 
1624 	return ret < 0 ? ret : 0;
1625 }
1626 
qcom_q6v5_dump_segment(struct rproc * rproc,struct rproc_dump_segment * segment,void * dest,size_t cp_offset,size_t size)1627 static void qcom_q6v5_dump_segment(struct rproc *rproc,
1628 				   struct rproc_dump_segment *segment,
1629 				   void *dest, size_t cp_offset, size_t size)
1630 {
1631 	int ret = 0;
1632 	struct q6v5 *qproc = rproc->priv;
1633 	int offset = segment->da - qproc->mpss_reloc;
1634 	void *ptr = NULL;
1635 
1636 	/* Unlock mba before copying segments */
1637 	if (!qproc->dump_mba_loaded) {
1638 		ret = q6v5_reload_mba(rproc);
1639 		if (!ret) {
1640 			/* Reset ownership back to Linux to copy segments */
1641 			ret = q6v5_xfer_mem_ownership(qproc, &qproc->mpss_perm,
1642 						      true, false,
1643 						      qproc->mpss_phys,
1644 						      qproc->mpss_size);
1645 		}
1646 	}
1647 
1648 	if (!ret)
1649 		ptr = memremap(qproc->mpss_phys + offset + cp_offset, size, MEMREMAP_WC);
1650 
1651 	if (ptr) {
1652 		memcpy(dest, ptr, size);
1653 		memunmap(ptr);
1654 	} else {
1655 		memset(dest, 0xff, size);
1656 	}
1657 
1658 	qproc->current_dump_size += size;
1659 
1660 	/* Reclaim mba after copying segments */
1661 	if (qproc->current_dump_size == qproc->total_dump_size) {
1662 		if (qproc->dump_mba_loaded) {
1663 			/* Try to reset ownership back to Q6 */
1664 			q6v5_xfer_mem_ownership(qproc, &qproc->mpss_perm,
1665 						false, true,
1666 						qproc->mpss_phys,
1667 						qproc->mpss_size);
1668 			q6v5_mba_reclaim(qproc);
1669 		}
1670 	}
1671 }
1672 
q6v5_start(struct rproc * rproc)1673 static int q6v5_start(struct rproc *rproc)
1674 {
1675 	struct q6v5 *qproc = rproc->priv;
1676 	int xfermemop_ret;
1677 	int ret;
1678 
1679 	ret = q6v5_mba_load(qproc);
1680 	if (ret)
1681 		return ret;
1682 
1683 	dev_info(qproc->dev, "MBA booted with%s debug policy, loading mpss\n",
1684 		 qproc->dp_size ? "" : "out");
1685 
1686 	ret = q6v5_mpss_load(qproc);
1687 	if (ret)
1688 		goto reclaim_mpss;
1689 
1690 	ret = qcom_q6v5_wait_for_start(&qproc->q6v5, msecs_to_jiffies(5000));
1691 	if (ret == -ETIMEDOUT) {
1692 		dev_err(qproc->dev, "start timed out\n");
1693 		goto reclaim_mpss;
1694 	}
1695 
1696 	xfermemop_ret = q6v5_xfer_mem_ownership(qproc, &qproc->mba_perm, true,
1697 						false, qproc->mba_phys,
1698 						qproc->mba_size);
1699 	if (xfermemop_ret)
1700 		dev_err(qproc->dev,
1701 			"Failed to reclaim mba buffer system may become unstable\n");
1702 
1703 	/* Reset Dump Segment Mask */
1704 	qproc->current_dump_size = 0;
1705 
1706 	return 0;
1707 
1708 reclaim_mpss:
1709 	q6v5_mba_reclaim(qproc);
1710 	q6v5_dump_mba_logs(qproc);
1711 
1712 	return ret;
1713 }
1714 
q6v5_stop(struct rproc * rproc)1715 static int q6v5_stop(struct rproc *rproc)
1716 {
1717 	struct q6v5 *qproc = rproc->priv;
1718 	int ret;
1719 
1720 	ret = qcom_q6v5_request_stop(&qproc->q6v5, qproc->sysmon);
1721 	if (ret == -ETIMEDOUT)
1722 		dev_err(qproc->dev, "timed out on wait\n");
1723 
1724 	q6v5_mba_reclaim(qproc);
1725 
1726 	return 0;
1727 }
1728 
qcom_q6v5_register_dump_segments(struct rproc * rproc,const struct firmware * mba_fw)1729 static int qcom_q6v5_register_dump_segments(struct rproc *rproc,
1730 					    const struct firmware *mba_fw)
1731 {
1732 	const struct firmware *fw;
1733 	const struct elf32_phdr *phdrs;
1734 	const struct elf32_phdr *phdr;
1735 	const struct elf32_hdr *ehdr;
1736 	struct q6v5 *qproc = rproc->priv;
1737 	unsigned long i;
1738 	int ret;
1739 
1740 	ret = request_firmware(&fw, qproc->hexagon_mdt_image, qproc->dev);
1741 	if (ret < 0) {
1742 		dev_err(qproc->dev, "unable to load %s\n",
1743 			qproc->hexagon_mdt_image);
1744 		return ret;
1745 	}
1746 
1747 	rproc_coredump_set_elf_info(rproc, ELFCLASS32, EM_NONE);
1748 
1749 	ehdr = (struct elf32_hdr *)fw->data;
1750 	phdrs = (struct elf32_phdr *)(ehdr + 1);
1751 	qproc->total_dump_size = 0;
1752 
1753 	for (i = 0; i < ehdr->e_phnum; i++) {
1754 		phdr = &phdrs[i];
1755 
1756 		if (!q6v5_phdr_valid(phdr))
1757 			continue;
1758 
1759 		ret = rproc_coredump_add_custom_segment(rproc, phdr->p_paddr,
1760 							phdr->p_memsz,
1761 							qcom_q6v5_dump_segment,
1762 							NULL);
1763 		if (ret)
1764 			break;
1765 
1766 		qproc->total_dump_size += phdr->p_memsz;
1767 	}
1768 
1769 	release_firmware(fw);
1770 	return ret;
1771 }
1772 
q6v5_panic(struct rproc * rproc)1773 static unsigned long q6v5_panic(struct rproc *rproc)
1774 {
1775 	struct q6v5 *qproc = rproc->priv;
1776 
1777 	return qcom_q6v5_panic(&qproc->q6v5);
1778 }
1779 
1780 static const struct rproc_ops q6v5_ops = {
1781 	.start = q6v5_start,
1782 	.stop = q6v5_stop,
1783 	.parse_fw = qcom_q6v5_register_dump_segments,
1784 	.load = q6v5_load,
1785 	.panic = q6v5_panic,
1786 };
1787 
qcom_msa_handover(struct qcom_q6v5 * q6v5)1788 static void qcom_msa_handover(struct qcom_q6v5 *q6v5)
1789 {
1790 	struct q6v5 *qproc = container_of(q6v5, struct q6v5, q6v5);
1791 
1792 	q6v5_clk_disable(qproc->dev, qproc->proxy_clks,
1793 			 qproc->proxy_clk_count);
1794 	q6v5_regulator_disable(qproc, qproc->proxy_regs,
1795 			       qproc->proxy_reg_count);
1796 	q6v5_regulator_disable(qproc, qproc->fallback_proxy_regs,
1797 			       qproc->fallback_proxy_reg_count);
1798 	q6v5_pds_disable(qproc, qproc->proxy_pds, qproc->proxy_pd_count);
1799 }
1800 
q6v5_init_mem(struct q6v5 * qproc,struct platform_device * pdev)1801 static int q6v5_init_mem(struct q6v5 *qproc, struct platform_device *pdev)
1802 {
1803 	struct of_phandle_args args;
1804 	int halt_cell_cnt = 3;
1805 	int ret;
1806 
1807 	qproc->reg_base = devm_platform_ioremap_resource_byname(pdev, "qdsp6");
1808 	if (IS_ERR(qproc->reg_base))
1809 		return PTR_ERR(qproc->reg_base);
1810 
1811 	qproc->rmb_base = devm_platform_ioremap_resource_byname(pdev, "rmb");
1812 	if (IS_ERR(qproc->rmb_base))
1813 		return PTR_ERR(qproc->rmb_base);
1814 
1815 	if (qproc->has_vq6)
1816 		halt_cell_cnt++;
1817 
1818 	ret = of_parse_phandle_with_fixed_args(pdev->dev.of_node,
1819 					       "qcom,halt-regs", halt_cell_cnt, 0, &args);
1820 	if (ret < 0) {
1821 		dev_err(&pdev->dev, "failed to parse qcom,halt-regs\n");
1822 		return -EINVAL;
1823 	}
1824 
1825 	qproc->halt_map = syscon_node_to_regmap(args.np);
1826 	of_node_put(args.np);
1827 	if (IS_ERR(qproc->halt_map))
1828 		return PTR_ERR(qproc->halt_map);
1829 
1830 	qproc->halt_q6 = args.args[0];
1831 	qproc->halt_modem = args.args[1];
1832 	qproc->halt_nc = args.args[2];
1833 
1834 	if (qproc->has_vq6)
1835 		qproc->halt_vq6 = args.args[3];
1836 
1837 	if (qproc->has_qaccept_regs) {
1838 		ret = of_parse_phandle_with_fixed_args(pdev->dev.of_node,
1839 						       "qcom,qaccept-regs",
1840 						       3, 0, &args);
1841 		if (ret < 0) {
1842 			dev_err(&pdev->dev, "failed to parse qaccept-regs\n");
1843 			return -EINVAL;
1844 		}
1845 
1846 		qproc->qaccept_mdm = args.args[0];
1847 		qproc->qaccept_cx = args.args[1];
1848 		qproc->qaccept_axi = args.args[2];
1849 	}
1850 
1851 	if (qproc->has_ext_bhs_reg) {
1852 		ret = of_parse_phandle_with_fixed_args(pdev->dev.of_node,
1853 						       "qcom,ext-bhs-reg",
1854 						       1, 0, &args);
1855 		if (ret < 0) {
1856 			dev_err(&pdev->dev, "failed to parse ext-bhs-reg index 0\n");
1857 			return -EINVAL;
1858 		}
1859 
1860 		qproc->conn_map = syscon_node_to_regmap(args.np);
1861 		of_node_put(args.np);
1862 		if (IS_ERR(qproc->conn_map))
1863 			return PTR_ERR(qproc->conn_map);
1864 
1865 		qproc->ext_bhs = args.args[0];
1866 	}
1867 
1868 	if (qproc->has_ext_cntl_regs) {
1869 		ret = of_parse_phandle_with_fixed_args(pdev->dev.of_node,
1870 						       "qcom,ext-regs",
1871 						       2, 0, &args);
1872 		if (ret < 0) {
1873 			dev_err(&pdev->dev, "failed to parse ext-regs index 0\n");
1874 			return -EINVAL;
1875 		}
1876 
1877 		qproc->conn_map = syscon_node_to_regmap(args.np);
1878 		of_node_put(args.np);
1879 		if (IS_ERR(qproc->conn_map))
1880 			return PTR_ERR(qproc->conn_map);
1881 
1882 		qproc->force_clk_on = args.args[0];
1883 		qproc->rscc_disable = args.args[1];
1884 
1885 		ret = of_parse_phandle_with_fixed_args(pdev->dev.of_node,
1886 						       "qcom,ext-regs",
1887 						       2, 1, &args);
1888 		if (ret < 0) {
1889 			dev_err(&pdev->dev, "failed to parse ext-regs index 1\n");
1890 			return -EINVAL;
1891 		}
1892 
1893 		qproc->axim1_clk_off = args.args[0];
1894 		qproc->crypto_clk_off = args.args[1];
1895 	}
1896 
1897 	if (qproc->has_spare_reg) {
1898 		ret = of_parse_phandle_with_fixed_args(pdev->dev.of_node,
1899 						       "qcom,spare-regs",
1900 						       1, 0, &args);
1901 		if (ret < 0) {
1902 			dev_err(&pdev->dev, "failed to parse spare-regs\n");
1903 			return -EINVAL;
1904 		}
1905 
1906 		qproc->conn_map = syscon_node_to_regmap(args.np);
1907 		of_node_put(args.np);
1908 		if (IS_ERR(qproc->conn_map))
1909 			return PTR_ERR(qproc->conn_map);
1910 
1911 		qproc->conn_box = args.args[0];
1912 	}
1913 
1914 	return 0;
1915 }
1916 
q6v5_init_clocks(struct device * dev,struct clk ** clks,char ** clk_names)1917 static int q6v5_init_clocks(struct device *dev, struct clk **clks,
1918 		char **clk_names)
1919 {
1920 	int i;
1921 
1922 	if (!clk_names)
1923 		return 0;
1924 
1925 	for (i = 0; clk_names[i]; i++) {
1926 		clks[i] = devm_clk_get(dev, clk_names[i]);
1927 		if (IS_ERR(clks[i]))
1928 			return dev_err_probe(dev, PTR_ERR(clks[i]),
1929 					     "Failed to get %s clock\n",
1930 					     clk_names[i]);
1931 	}
1932 
1933 	return i;
1934 }
1935 
q6v5_pds_attach(struct device * dev,struct device ** devs,char ** pd_names)1936 static int q6v5_pds_attach(struct device *dev, struct device **devs,
1937 			   char **pd_names)
1938 {
1939 	size_t num_pds = 0;
1940 	int ret;
1941 	int i;
1942 
1943 	if (!pd_names)
1944 		return 0;
1945 
1946 	while (pd_names[num_pds])
1947 		num_pds++;
1948 
1949 	/* Handle single power domain */
1950 	if (num_pds == 1 && dev->pm_domain) {
1951 		devs[0] = dev;
1952 		pm_runtime_enable(dev);
1953 		return 1;
1954 	}
1955 
1956 	for (i = 0; i < num_pds; i++) {
1957 		devs[i] = dev_pm_domain_attach_by_name(dev, pd_names[i]);
1958 		if (IS_ERR_OR_NULL(devs[i])) {
1959 			ret = PTR_ERR(devs[i]) ? : -ENODATA;
1960 			goto unroll_attach;
1961 		}
1962 	}
1963 
1964 	return num_pds;
1965 
1966 unroll_attach:
1967 	for (i--; i >= 0; i--)
1968 		dev_pm_domain_detach(devs[i], false);
1969 
1970 	return ret;
1971 }
1972 
q6v5_pds_detach(struct q6v5 * qproc,struct device ** pds,size_t pd_count)1973 static void q6v5_pds_detach(struct q6v5 *qproc, struct device **pds,
1974 			    size_t pd_count)
1975 {
1976 	struct device *dev = qproc->dev;
1977 	int i;
1978 
1979 	/* Handle single power domain */
1980 	if (pd_count == 1 && dev->pm_domain) {
1981 		pm_runtime_disable(dev);
1982 		return;
1983 	}
1984 
1985 	for (i = 0; i < pd_count; i++)
1986 		dev_pm_domain_detach(pds[i], false);
1987 }
1988 
q6v5_init_reset(struct q6v5 * qproc)1989 static int q6v5_init_reset(struct q6v5 *qproc)
1990 {
1991 	qproc->mss_restart = devm_reset_control_get_exclusive(qproc->dev,
1992 							      "mss_restart");
1993 	if (IS_ERR(qproc->mss_restart)) {
1994 		dev_err(qproc->dev, "failed to acquire mss restart\n");
1995 		return PTR_ERR(qproc->mss_restart);
1996 	}
1997 
1998 	if (qproc->has_alt_reset || qproc->has_spare_reg || qproc->has_ext_cntl_regs) {
1999 		qproc->pdc_reset = devm_reset_control_get_exclusive(qproc->dev,
2000 								    "pdc_reset");
2001 		if (IS_ERR(qproc->pdc_reset)) {
2002 			dev_err(qproc->dev, "failed to acquire pdc reset\n");
2003 			return PTR_ERR(qproc->pdc_reset);
2004 		}
2005 	}
2006 
2007 	return 0;
2008 }
2009 
q6v5_alloc_memory_region(struct q6v5 * qproc)2010 static int q6v5_alloc_memory_region(struct q6v5 *qproc)
2011 {
2012 	struct device_node *child;
2013 	struct resource res;
2014 	int ret;
2015 
2016 	/*
2017 	 * In the absence of mba/mpss sub-child, extract the mba and mpss
2018 	 * reserved memory regions from device's memory-region property.
2019 	 */
2020 	child = of_get_child_by_name(qproc->dev->of_node, "mba");
2021 	if (!child) {
2022 		ret = of_reserved_mem_region_to_resource(qproc->dev->of_node, 0, &res);
2023 	} else {
2024 		ret = of_reserved_mem_region_to_resource(child, 0, &res);
2025 		of_node_put(child);
2026 	}
2027 
2028 	if (ret) {
2029 		dev_err(qproc->dev, "unable to resolve mba region\n");
2030 		return ret;
2031 	}
2032 
2033 	qproc->mba_phys = res.start;
2034 	qproc->mba_size = resource_size(&res);
2035 
2036 	if (!child) {
2037 		ret = of_reserved_mem_region_to_resource(qproc->dev->of_node, 1, &res);
2038 	} else {
2039 		child = of_get_child_by_name(qproc->dev->of_node, "mpss");
2040 		ret = of_reserved_mem_region_to_resource(child, 0, &res);
2041 		of_node_put(child);
2042 	}
2043 
2044 	if (ret) {
2045 		dev_err(qproc->dev, "unable to resolve mpss region\n");
2046 		return ret;
2047 	}
2048 
2049 	qproc->mpss_phys = qproc->mpss_reloc = res.start;
2050 	qproc->mpss_size = resource_size(&res);
2051 
2052 	if (!child) {
2053 		ret = of_reserved_mem_region_to_resource(qproc->dev->of_node, 2, &res);
2054 	} else {
2055 		child = of_get_child_by_name(qproc->dev->of_node, "metadata");
2056 		ret = of_reserved_mem_region_to_resource(child, 0, &res);
2057 		of_node_put(child);
2058 	}
2059 
2060 	if (ret)
2061 		return 0;
2062 
2063 	qproc->mdata_phys = res.start;
2064 	qproc->mdata_size = resource_size(&res);
2065 
2066 	return 0;
2067 }
2068 
q6v5_probe(struct platform_device * pdev)2069 static int q6v5_probe(struct platform_device *pdev)
2070 {
2071 	const struct rproc_hexagon_res *desc;
2072 	struct device_node *node;
2073 	struct q6v5 *qproc;
2074 	struct rproc *rproc;
2075 	const char *mba_image;
2076 	int ret;
2077 
2078 	desc = of_device_get_match_data(&pdev->dev);
2079 	if (!desc)
2080 		return -EINVAL;
2081 
2082 	/*
2083 	 * Memory protection is done through qcom_scm_assign_mem(), which needs
2084 	 * SCM but not PAS. Only the memory setup path issues PAS calls, so
2085 	 * requiring PAS for every need_mem_protection platform prevents the
2086 	 * modem from probing at all on TZ firmware that offers no PAS.
2087 	 */
2088 	if (desc->need_mem_protection && !qcom_scm_is_available())
2089 		return -EPROBE_DEFER;
2090 
2091 	if (desc->need_pas_mem_setup && !qcom_pas_is_available())
2092 		return -EPROBE_DEFER;
2093 
2094 	mba_image = desc->hexagon_mba_image;
2095 	ret = of_property_read_string_index(pdev->dev.of_node, "firmware-name",
2096 					    0, &mba_image);
2097 	if (ret < 0 && ret != -EINVAL) {
2098 		dev_err(&pdev->dev, "unable to read mba firmware-name\n");
2099 		return ret;
2100 	}
2101 
2102 	rproc = devm_rproc_alloc(&pdev->dev, pdev->name, &q6v5_ops,
2103 				 mba_image, sizeof(*qproc));
2104 	if (!rproc) {
2105 		dev_err(&pdev->dev, "failed to allocate rproc\n");
2106 		return -ENOMEM;
2107 	}
2108 
2109 	rproc->auto_boot = false;
2110 	rproc_coredump_set_elf_info(rproc, ELFCLASS32, EM_NONE);
2111 
2112 	qproc = rproc->priv;
2113 	qproc->dev = &pdev->dev;
2114 	qproc->rproc = rproc;
2115 	qproc->hexagon_mdt_image = "modem.mdt";
2116 	ret = of_property_read_string_index(pdev->dev.of_node, "firmware-name",
2117 					    1, &qproc->hexagon_mdt_image);
2118 	if (ret < 0 && ret != -EINVAL) {
2119 		dev_err(&pdev->dev, "unable to read mpss firmware-name\n");
2120 		return ret;
2121 	}
2122 
2123 	platform_set_drvdata(pdev, qproc);
2124 
2125 	qproc->has_qaccept_regs = desc->has_qaccept_regs;
2126 	qproc->has_ext_bhs_reg = desc->has_ext_bhs_reg;
2127 	qproc->has_ext_cntl_regs = desc->has_ext_cntl_regs;
2128 	qproc->has_vq6 = desc->has_vq6;
2129 	qproc->has_spare_reg = desc->has_spare_reg;
2130 	ret = q6v5_init_mem(qproc, pdev);
2131 	if (ret)
2132 		return ret;
2133 
2134 	ret = q6v5_alloc_memory_region(qproc);
2135 	if (ret)
2136 		return ret;
2137 
2138 	ret = q6v5_init_clocks(&pdev->dev, qproc->proxy_clks,
2139 			       desc->proxy_clk_names);
2140 	if (ret < 0)
2141 		return ret;
2142 	qproc->proxy_clk_count = ret;
2143 
2144 	ret = q6v5_init_clocks(&pdev->dev, qproc->reset_clks,
2145 			       desc->reset_clk_names);
2146 	if (ret < 0)
2147 		return ret;
2148 	qproc->reset_clk_count = ret;
2149 
2150 	ret = q6v5_init_clocks(&pdev->dev, qproc->active_clks,
2151 			       desc->active_clk_names);
2152 	if (ret < 0)
2153 		return ret;
2154 	qproc->active_clk_count = ret;
2155 
2156 	ret = q6v5_regulator_init(&pdev->dev, qproc->proxy_regs,
2157 				  desc->proxy_supply);
2158 	if (ret < 0)
2159 		return ret;
2160 	qproc->proxy_reg_count = ret;
2161 
2162 	ret = q6v5_regulator_init(&pdev->dev,  qproc->active_regs,
2163 				  desc->active_supply);
2164 	if (ret < 0)
2165 		return ret;
2166 	qproc->active_reg_count = ret;
2167 
2168 	ret = q6v5_pds_attach(&pdev->dev, qproc->proxy_pds,
2169 			      desc->proxy_pd_names);
2170 	/* Fallback to regulators for old device trees */
2171 	if (ret == -ENODATA && desc->fallback_proxy_supply) {
2172 		ret = q6v5_regulator_init(&pdev->dev,
2173 					  qproc->fallback_proxy_regs,
2174 					  desc->fallback_proxy_supply);
2175 		if (ret < 0)
2176 			return ret;
2177 		qproc->fallback_proxy_reg_count = ret;
2178 	} else if (ret < 0) {
2179 		dev_err(&pdev->dev, "Failed to init power domains\n");
2180 		return ret;
2181 	} else {
2182 		qproc->proxy_pd_count = ret;
2183 	}
2184 
2185 	qproc->has_alt_reset = desc->has_alt_reset;
2186 	ret = q6v5_init_reset(qproc);
2187 	if (ret)
2188 		goto detach_proxy_pds;
2189 
2190 	qproc->version = desc->version;
2191 	qproc->need_mem_protection = desc->need_mem_protection;
2192 	qproc->has_mba_logs = desc->has_mba_logs;
2193 
2194 	ret = qcom_q6v5_init(&qproc->q6v5, pdev, rproc, MPSS_CRASH_REASON_SMEM, "modem",
2195 			     qcom_msa_handover);
2196 	if (ret)
2197 		goto detach_proxy_pds;
2198 
2199 	qproc->mpss_perm = BIT(QCOM_SCM_VMID_HLOS);
2200 	qproc->mba_perm = BIT(QCOM_SCM_VMID_HLOS);
2201 	qcom_add_glink_subdev(rproc, &qproc->glink_subdev, "mpss");
2202 	qcom_add_smd_subdev(rproc, &qproc->smd_subdev);
2203 	qcom_add_pdm_subdev(rproc, &qproc->pdm_subdev);
2204 	qcom_add_ssr_subdev(rproc, &qproc->ssr_subdev, "mpss");
2205 	qproc->sysmon = qcom_add_sysmon_subdev(rproc, "modem", desc->ssctl_id);
2206 	if (IS_ERR(qproc->sysmon)) {
2207 		ret = PTR_ERR(qproc->sysmon);
2208 		goto remove_subdevs;
2209 	}
2210 
2211 	ret = rproc_add(rproc);
2212 	if (ret)
2213 		goto remove_sysmon_subdev;
2214 
2215 	node = of_get_compatible_child(pdev->dev.of_node, "qcom,bam-dmux");
2216 	qproc->bam_dmux = of_platform_device_create(node, NULL, &pdev->dev);
2217 	of_node_put(node);
2218 
2219 	return 0;
2220 
2221 remove_sysmon_subdev:
2222 	qcom_remove_sysmon_subdev(qproc->sysmon);
2223 remove_subdevs:
2224 	qcom_remove_ssr_subdev(rproc, &qproc->ssr_subdev);
2225 	qcom_remove_smd_subdev(rproc, &qproc->smd_subdev);
2226 	qcom_remove_glink_subdev(rproc, &qproc->glink_subdev);
2227 detach_proxy_pds:
2228 	q6v5_pds_detach(qproc, qproc->proxy_pds, qproc->proxy_pd_count);
2229 
2230 	return ret;
2231 }
2232 
q6v5_remove(struct platform_device * pdev)2233 static void q6v5_remove(struct platform_device *pdev)
2234 {
2235 	struct q6v5 *qproc = platform_get_drvdata(pdev);
2236 	struct rproc *rproc = qproc->rproc;
2237 
2238 	if (qproc->bam_dmux)
2239 		of_platform_device_destroy(&qproc->bam_dmux->dev, NULL);
2240 	rproc_del(rproc);
2241 
2242 	qcom_q6v5_deinit(&qproc->q6v5);
2243 	qcom_remove_sysmon_subdev(qproc->sysmon);
2244 	qcom_remove_ssr_subdev(rproc, &qproc->ssr_subdev);
2245 	qcom_remove_pdm_subdev(rproc, &qproc->pdm_subdev);
2246 	qcom_remove_smd_subdev(rproc, &qproc->smd_subdev);
2247 	qcom_remove_glink_subdev(rproc, &qproc->glink_subdev);
2248 
2249 	q6v5_pds_detach(qproc, qproc->proxy_pds, qproc->proxy_pd_count);
2250 }
2251 
2252 static const struct rproc_hexagon_res sc7180_mss = {
2253 	.hexagon_mba_image = "mba.mbn",
2254 	.proxy_clk_names = (char*[]){
2255 		"xo",
2256 		NULL
2257 	},
2258 	.reset_clk_names = (char*[]){
2259 		"iface",
2260 		"bus",
2261 		"snoc_axi",
2262 		NULL
2263 	},
2264 	.active_clk_names = (char*[]){
2265 		"mnoc_axi",
2266 		"nav",
2267 		NULL
2268 	},
2269 	.proxy_pd_names = (char*[]){
2270 		"cx",
2271 		"mx",
2272 		"mss",
2273 		NULL
2274 	},
2275 	.need_mem_protection = true,
2276 	.need_pas_mem_setup = false,
2277 	.has_alt_reset = false,
2278 	.has_mba_logs = true,
2279 	.has_spare_reg = true,
2280 	.has_qaccept_regs = false,
2281 	.has_ext_bhs_reg = false,
2282 	.has_ext_cntl_regs = false,
2283 	.has_vq6 = false,
2284 	.version = MSS_SC7180,
2285 	.ssctl_id = 0x12,
2286 };
2287 
2288 static const struct rproc_hexagon_res sc7280_mss = {
2289 	.hexagon_mba_image = "mba.mbn",
2290 	.proxy_clk_names = (char*[]){
2291 		"xo",
2292 		"pka",
2293 		NULL
2294 	},
2295 	.active_clk_names = (char*[]){
2296 		"iface",
2297 		"offline",
2298 		"snoc_axi",
2299 		NULL
2300 	},
2301 	.proxy_pd_names = (char*[]){
2302 		"cx",
2303 		"mss",
2304 		NULL
2305 	},
2306 	.need_mem_protection = true,
2307 	.need_pas_mem_setup = false,
2308 	.has_alt_reset = false,
2309 	.has_mba_logs = true,
2310 	.has_spare_reg = false,
2311 	.has_qaccept_regs = true,
2312 	.has_ext_bhs_reg = false,
2313 	.has_ext_cntl_regs = true,
2314 	.has_vq6 = true,
2315 	.version = MSS_SC7280,
2316 	.ssctl_id = 0x12,
2317 };
2318 
2319 static const struct rproc_hexagon_res sdm660_mss = {
2320 	.hexagon_mba_image = "mba.mbn",
2321 	.proxy_clk_names = (char*[]){
2322 			"xo",
2323 			"qdss",
2324 			"mem",
2325 			NULL
2326 	},
2327 	.active_clk_names = (char*[]){
2328 			"iface",
2329 			"bus",
2330 			"gpll0_mss",
2331 			"mnoc_axi",
2332 			"snoc_axi",
2333 			NULL
2334 	},
2335 	.proxy_pd_names = (char*[]){
2336 			"cx",
2337 			"mx",
2338 			NULL
2339 	},
2340 	.need_mem_protection = true,
2341 	.need_pas_mem_setup = false,
2342 	.has_alt_reset = false,
2343 	.has_mba_logs = false,
2344 	.has_spare_reg = false,
2345 	.has_qaccept_regs = false,
2346 	.has_ext_bhs_reg = false,
2347 	.has_ext_cntl_regs = false,
2348 	.has_vq6 = false,
2349 	.version = MSS_SDM660,
2350 	.ssctl_id = 0x12,
2351 };
2352 
2353 static const struct rproc_hexagon_res sdm845_mss = {
2354 	.hexagon_mba_image = "mba.mbn",
2355 	.proxy_clk_names = (char*[]){
2356 			"xo",
2357 			"prng",
2358 			NULL
2359 	},
2360 	.reset_clk_names = (char*[]){
2361 			"iface",
2362 			"snoc_axi",
2363 			NULL
2364 	},
2365 	.active_clk_names = (char*[]){
2366 			"bus",
2367 			"mem",
2368 			"gpll0_mss",
2369 			"mnoc_axi",
2370 			NULL
2371 	},
2372 	.proxy_pd_names = (char*[]){
2373 			"cx",
2374 			"mx",
2375 			"mss",
2376 			NULL
2377 	},
2378 	.need_mem_protection = true,
2379 	.need_pas_mem_setup = false,
2380 	.has_alt_reset = true,
2381 	.has_mba_logs = false,
2382 	.has_spare_reg = false,
2383 	.has_qaccept_regs = false,
2384 	.has_ext_bhs_reg = false,
2385 	.has_ext_cntl_regs = false,
2386 	.has_vq6 = false,
2387 	.version = MSS_SDM845,
2388 	.ssctl_id = 0x12,
2389 };
2390 
2391 static const struct rproc_hexagon_res msm8998_mss = {
2392 	.hexagon_mba_image = "mba.mbn",
2393 	.proxy_clk_names = (char*[]){
2394 			"xo",
2395 			"qdss",
2396 			"mem",
2397 			NULL
2398 	},
2399 	.active_clk_names = (char*[]){
2400 			"iface",
2401 			"bus",
2402 			"gpll0_mss",
2403 			"mnoc_axi",
2404 			"snoc_axi",
2405 			NULL
2406 	},
2407 	.proxy_pd_names = (char*[]){
2408 			"cx",
2409 			"mx",
2410 			NULL
2411 	},
2412 	.need_mem_protection = true,
2413 	.need_pas_mem_setup = false,
2414 	.has_alt_reset = false,
2415 	.has_mba_logs = false,
2416 	.has_spare_reg = false,
2417 	.has_qaccept_regs = false,
2418 	.has_ext_bhs_reg = false,
2419 	.has_ext_cntl_regs = false,
2420 	.has_vq6 = false,
2421 	.version = MSS_MSM8998,
2422 	.ssctl_id = 0x12,
2423 };
2424 
2425 static const struct rproc_hexagon_res msm8996_mss = {
2426 	.hexagon_mba_image = "mba.mbn",
2427 	.proxy_supply = (struct qcom_mss_reg_res[]) {
2428 		{
2429 			.supply = "pll",
2430 			.uA = 100000,
2431 		},
2432 		{}
2433 	},
2434 	.proxy_clk_names = (char*[]){
2435 			"xo",
2436 			"qdss",
2437 			NULL
2438 	},
2439 	.active_clk_names = (char*[]){
2440 			"iface",
2441 			"bus",
2442 			"mem",
2443 			"gpll0_mss",
2444 			"snoc_axi",
2445 			"mnoc_axi",
2446 			NULL
2447 	},
2448 	.proxy_pd_names = (char*[]){
2449 			"mx",
2450 			"cx",
2451 			NULL
2452 	},
2453 	.need_mem_protection = true,
2454 	.need_pas_mem_setup = false,
2455 	.has_alt_reset = false,
2456 	.has_mba_logs = false,
2457 	.has_spare_reg = false,
2458 	.has_qaccept_regs = false,
2459 	.has_ext_bhs_reg = false,
2460 	.has_ext_cntl_regs = false,
2461 	.has_vq6 = false,
2462 	.version = MSS_MSM8996,
2463 	.ssctl_id = 0x12,
2464 };
2465 
2466 static const struct rproc_hexagon_res mdm9607_mss = {
2467 	.hexagon_mba_image = "mba.mbn",
2468 	.proxy_supply = (struct qcom_mss_reg_res[]) {
2469 		{
2470 			.supply = "pll",
2471 			.uA = 100000,
2472 		},
2473 		{}
2474 	},
2475 	.proxy_clk_names = (char*[]){
2476 		"xo",
2477 		NULL
2478 	},
2479 	.active_clk_names = (char*[]){
2480 		"iface",
2481 		"bus",
2482 		"mem",
2483 		NULL
2484 	},
2485 	.proxy_pd_names = (char*[]){
2486 		"mx",
2487 		"cx",
2488 		NULL
2489 	},
2490 	.need_mem_protection = false,
2491 	.has_alt_reset = false,
2492 	.has_mba_logs = false,
2493 	.has_spare_reg = false,
2494 	.has_qaccept_regs = false,
2495 	.has_ext_bhs_reg = false,
2496 	.has_ext_cntl_regs = false,
2497 	.has_vq6 = false,
2498 	.version = MSS_MDM9607,
2499 	.ssctl_id = 0x22,
2500 };
2501 
2502 static const struct rproc_hexagon_res msm8909_mss = {
2503 	.hexagon_mba_image = "mba.mbn",
2504 	.proxy_supply = (struct qcom_mss_reg_res[]) {
2505 		{
2506 			.supply = "pll",
2507 			.uA = 100000,
2508 		},
2509 		{}
2510 	},
2511 	.proxy_clk_names = (char*[]){
2512 		"xo",
2513 		NULL
2514 	},
2515 	.active_clk_names = (char*[]){
2516 		"iface",
2517 		"bus",
2518 		"mem",
2519 		NULL
2520 	},
2521 	.proxy_pd_names = (char*[]){
2522 		"mx",
2523 		"cx",
2524 		NULL
2525 	},
2526 	.need_mem_protection = false,
2527 	.need_pas_mem_setup = false,
2528 	.has_alt_reset = false,
2529 	.has_mba_logs = false,
2530 	.has_spare_reg = false,
2531 	.has_qaccept_regs = false,
2532 	.has_ext_bhs_reg = false,
2533 	.has_ext_cntl_regs = false,
2534 	.has_vq6 = false,
2535 	.version = MSS_MSM8909,
2536 	.ssctl_id = 0x12,
2537 };
2538 
2539 static const struct rproc_hexagon_res msm8916_mss = {
2540 	.hexagon_mba_image = "mba.mbn",
2541 	.proxy_supply = (struct qcom_mss_reg_res[]) {
2542 		{
2543 			.supply = "pll",
2544 			.uA = 100000,
2545 		},
2546 		{}
2547 	},
2548 	.fallback_proxy_supply = (struct qcom_mss_reg_res[]) {
2549 		{
2550 			.supply = "mx",
2551 			.uV = 1050000,
2552 		},
2553 		{
2554 			.supply = "cx",
2555 			.uA = 100000,
2556 		},
2557 		{}
2558 	},
2559 	.proxy_clk_names = (char*[]){
2560 		"xo",
2561 		NULL
2562 	},
2563 	.active_clk_names = (char*[]){
2564 		"iface",
2565 		"bus",
2566 		"mem",
2567 		NULL
2568 	},
2569 	.proxy_pd_names = (char*[]){
2570 		"mx",
2571 		"cx",
2572 		NULL
2573 	},
2574 	.need_mem_protection = false,
2575 	.need_pas_mem_setup = false,
2576 	.has_alt_reset = false,
2577 	.has_mba_logs = false,
2578 	.has_spare_reg = false,
2579 	.has_qaccept_regs = false,
2580 	.has_ext_bhs_reg = false,
2581 	.has_ext_cntl_regs = false,
2582 	.has_vq6 = false,
2583 	.version = MSS_MSM8916,
2584 	.ssctl_id = 0x12,
2585 };
2586 
2587 static const struct rproc_hexagon_res msm8917_mss = {
2588 	.hexagon_mba_image = "mba.mbn",
2589 	.proxy_supply = (struct qcom_mss_reg_res[]) {
2590 		{
2591 			.supply = "pll",
2592 			.uA = 100000,
2593 		},
2594 		{}
2595 	},
2596 	.active_supply = (struct qcom_mss_reg_res[]) {
2597 		{
2598 			.supply = "mss",
2599 			.uV = 1050000,
2600 			.uA = 100000,
2601 		},
2602 		{}
2603 	},
2604 	.proxy_clk_names = (char*[]){
2605 		"xo",
2606 		NULL
2607 	},
2608 	.active_clk_names = (char*[]){
2609 		"iface",
2610 		"bus",
2611 		"mem",
2612 		NULL
2613 	},
2614 	.proxy_pd_names = (char*[]) {
2615 		"cx",
2616 		"mx",
2617 		NULL
2618 	},
2619 	.need_mem_protection = false,
2620 	.need_pas_mem_setup = false,
2621 	.has_alt_reset = false,
2622 	.has_mba_logs = false,
2623 	.has_spare_reg = false,
2624 	.has_qaccept_regs = false,
2625 	.has_ext_bhs_reg = false,
2626 	.has_ext_cntl_regs = false,
2627 	.has_vq6 = false,
2628 	.version = MSS_MSM8917,
2629 	.ssctl_id = 0x12,
2630 };
2631 
2632 static const struct rproc_hexagon_res msm8937_mss = {
2633 	.hexagon_mba_image = "mba.mbn",
2634 	.proxy_supply = (struct qcom_mss_reg_res[]) {
2635 		{
2636 			.supply = "pll",
2637 			.uA = 100000,
2638 		},
2639 		{}
2640 	},
2641 	.active_supply = (struct qcom_mss_reg_res[]) {
2642 		{
2643 			.supply = "mss",
2644 			.uV = 1050000,
2645 			.uA = 100000,
2646 		},
2647 		{}
2648 	},
2649 	.proxy_clk_names = (char*[]){
2650 		"xo",
2651 		NULL
2652 	},
2653 	.active_clk_names = (char*[]){
2654 		"iface",
2655 		"bus",
2656 		"mem",
2657 		NULL
2658 	},
2659 	.proxy_pd_names = (char*[]) {
2660 		"cx",
2661 		"mx",
2662 		NULL
2663 	},
2664 	.need_mem_protection = false,
2665 	.need_pas_mem_setup = true,
2666 	.has_alt_reset = false,
2667 	.has_mba_logs = false,
2668 	.has_spare_reg = false,
2669 	.has_qaccept_regs = false,
2670 	.has_ext_bhs_reg = false,
2671 	.has_ext_cntl_regs = false,
2672 	.has_vq6 = false,
2673 	.version = MSS_MSM8937,
2674 	.ssctl_id = 0x12,
2675 };
2676 
2677 static const struct rproc_hexagon_res msm8940_mss = {
2678 	.hexagon_mba_image = "mba.mbn",
2679 	.proxy_supply = (struct qcom_mss_reg_res[]) {
2680 		{
2681 			.supply = "pll",
2682 			.uA = 100000,
2683 		},
2684 		{}
2685 	},
2686 	.active_supply = (struct qcom_mss_reg_res[]) {
2687 		{
2688 			.supply = "mss",
2689 			.uV = 1050000,
2690 			.uA = 100000,
2691 		},
2692 		{}
2693 	},
2694 	.proxy_clk_names = (char*[]){
2695 		"xo",
2696 		NULL
2697 	},
2698 	.active_clk_names = (char*[]){
2699 		"iface",
2700 		"bus",
2701 		"mem",
2702 		NULL
2703 	},
2704 	.proxy_pd_names = (char*[]) {
2705 		"cx",
2706 		"mx",
2707 		NULL
2708 	},
2709 	.need_mem_protection = false,
2710 	.need_pas_mem_setup = true,
2711 	.has_alt_reset = false,
2712 	.has_mba_logs = false,
2713 	.has_spare_reg = false,
2714 	.has_qaccept_regs = false,
2715 	.has_ext_bhs_reg = false,
2716 	.has_ext_cntl_regs = false,
2717 	.has_vq6 = false,
2718 	.version = MSS_MSM8940,
2719 	.ssctl_id = 0x12,
2720 };
2721 
2722 static const struct rproc_hexagon_res msm8953_mss = {
2723 	.hexagon_mba_image = "mba.mbn",
2724 	.proxy_supply = (struct qcom_mss_reg_res[]) {
2725 		{
2726 			.supply = "pll",
2727 			.uA = 100000,
2728 		},
2729 		{}
2730 	},
2731 	.proxy_clk_names = (char*[]){
2732 		"xo",
2733 		NULL
2734 	},
2735 	.active_clk_names = (char*[]){
2736 		"iface",
2737 		"bus",
2738 		"mem",
2739 		NULL
2740 	},
2741 	.proxy_pd_names = (char*[]) {
2742 		"cx",
2743 		"mx",
2744 		"mss",
2745 		NULL
2746 	},
2747 	.need_mem_protection = false,
2748 	.need_pas_mem_setup = true,
2749 	.has_alt_reset = false,
2750 	.has_mba_logs = false,
2751 	.has_spare_reg = false,
2752 	.has_qaccept_regs = false,
2753 	.has_ext_bhs_reg = false,
2754 	.has_ext_cntl_regs = false,
2755 	.has_vq6 = false,
2756 	.version = MSS_MSM8953,
2757 	.ssctl_id = 0x12,
2758 };
2759 
2760 static const struct rproc_hexagon_res msm8974_mss = {
2761 	.hexagon_mba_image = "mba.b00",
2762 	.proxy_supply = (struct qcom_mss_reg_res[]) {
2763 		{
2764 			.supply = "pll",
2765 			.uA = 100000,
2766 		},
2767 		{
2768 			.supply = "mx",
2769 			.uV = 1050000,
2770 		},
2771 		{}
2772 	},
2773 	.fallback_proxy_supply = (struct qcom_mss_reg_res[]) {
2774 		{
2775 			.supply = "cx",
2776 			.uA = 100000,
2777 		},
2778 		{}
2779 	},
2780 	.active_supply = (struct qcom_mss_reg_res[]) {
2781 		{
2782 			.supply = "mss",
2783 			.uV = 1050000,
2784 			.uA = 100000,
2785 		},
2786 		{}
2787 	},
2788 	.proxy_clk_names = (char*[]){
2789 		"xo",
2790 		NULL
2791 	},
2792 	.active_clk_names = (char*[]){
2793 		"iface",
2794 		"bus",
2795 		"mem",
2796 		NULL
2797 	},
2798 	.proxy_pd_names = (char*[]){
2799 		"cx",
2800 		NULL
2801 	},
2802 	.need_mem_protection = false,
2803 	.need_pas_mem_setup = false,
2804 	.has_alt_reset = false,
2805 	.has_mba_logs = false,
2806 	.has_spare_reg = false,
2807 	.has_qaccept_regs = false,
2808 	.has_ext_bhs_reg = false,
2809 	.has_ext_cntl_regs = false,
2810 	.has_vq6 = false,
2811 	.version = MSS_MSM8974,
2812 	.ssctl_id = 0x12,
2813 };
2814 
2815 static const struct rproc_hexagon_res msm8226_mss = {
2816 	.hexagon_mba_image = "mba.b00",
2817 	.proxy_supply = (struct qcom_mss_reg_res[]) {
2818 		{
2819 			.supply = "pll",
2820 			.uA = 100000,
2821 		},
2822 		{
2823 			.supply = "mx",
2824 			.uV = 1050000,
2825 		},
2826 		{}
2827 	},
2828 	.proxy_clk_names = (char*[]){
2829 		"xo",
2830 		NULL
2831 	},
2832 	.active_clk_names = (char*[]){
2833 		"iface",
2834 		"bus",
2835 		"mem",
2836 		NULL
2837 	},
2838 	.proxy_pd_names = (char*[]){
2839 		"cx",
2840 		NULL
2841 	},
2842 	.need_mem_protection = false,
2843 	.need_pas_mem_setup = false,
2844 	.has_alt_reset = false,
2845 	.has_mba_logs = false,
2846 	.has_spare_reg = false,
2847 	.has_qaccept_regs = false,
2848 	.has_ext_bhs_reg = true,
2849 	.has_ext_cntl_regs = false,
2850 	.has_vq6 = false,
2851 	.version = MSS_MSM8226,
2852 	.ssctl_id = 0x12,
2853 };
2854 
2855 static const struct rproc_hexagon_res msm8926_mss = {
2856 	.hexagon_mba_image = "mba.b00",
2857 	.proxy_supply = (struct qcom_mss_reg_res[]) {
2858 		{
2859 			.supply = "pll",
2860 			.uA = 100000,
2861 		},
2862 		{
2863 			.supply = "mx",
2864 			.uV = 1050000,
2865 		},
2866 		{}
2867 	},
2868 	.active_supply = (struct qcom_mss_reg_res[]) {
2869 		{
2870 			.supply = "mss",
2871 			.uV = 1050000,
2872 			.uA = 100000,
2873 		},
2874 		{}
2875 	},
2876 	.proxy_clk_names = (char*[]){
2877 		"xo",
2878 		NULL
2879 	},
2880 	.active_clk_names = (char*[]){
2881 		"iface",
2882 		"bus",
2883 		"mem",
2884 		NULL
2885 	},
2886 	.proxy_pd_names = (char*[]){
2887 		"cx",
2888 		NULL
2889 	},
2890 	.need_mem_protection = false,
2891 	.need_pas_mem_setup = false,
2892 	.has_alt_reset = false,
2893 	.has_mba_logs = false,
2894 	.has_spare_reg = false,
2895 	.has_qaccept_regs = false,
2896 	.has_ext_bhs_reg = false,
2897 	.has_ext_cntl_regs = false,
2898 	.has_vq6 = false,
2899 	.version = MSS_MSM8926,
2900 	.ssctl_id = 0x12,
2901 };
2902 
2903 static const struct of_device_id q6v5_of_match[] = {
2904 	{ .compatible = "qcom,q6v5-pil", .data = &msm8916_mss },
2905 	{ .compatible = "qcom,mdm9607-mss-pil", .data = &mdm9607_mss },
2906 	{ .compatible = "qcom,msm8226-mss-pil", .data = &msm8226_mss },
2907 	{ .compatible = "qcom,msm8909-mss-pil", .data = &msm8909_mss },
2908 	{ .compatible = "qcom,msm8916-mss-pil", .data = &msm8916_mss },
2909 	{ .compatible = "qcom,msm8917-mss-pil", .data = &msm8917_mss },
2910 	{ .compatible = "qcom,msm8926-mss-pil", .data = &msm8926_mss },
2911 	{ .compatible = "qcom,msm8937-mss-pil", .data = &msm8937_mss },
2912 	{ .compatible = "qcom,msm8940-mss-pil", .data = &msm8940_mss },
2913 	{ .compatible = "qcom,msm8953-mss-pil", .data = &msm8953_mss },
2914 	{ .compatible = "qcom,msm8974-mss-pil", .data = &msm8974_mss },
2915 	{ .compatible = "qcom,msm8996-mss-pil", .data = &msm8996_mss },
2916 	{ .compatible = "qcom,msm8998-mss-pil", .data = &msm8998_mss },
2917 	{ .compatible = "qcom,sc7180-mss-pil", .data = &sc7180_mss },
2918 	{ .compatible = "qcom,sc7280-mss-pil", .data = &sc7280_mss },
2919 	{ .compatible = "qcom,sdm660-mss-pil", .data = &sdm660_mss },
2920 	{ .compatible = "qcom,sdm845-mss-pil", .data = &sdm845_mss },
2921 	{ },
2922 };
2923 MODULE_DEVICE_TABLE(of, q6v5_of_match);
2924 
2925 static struct platform_driver q6v5_driver = {
2926 	.probe = q6v5_probe,
2927 	.remove = q6v5_remove,
2928 	.driver = {
2929 		.name = "qcom-q6v5-mss",
2930 		.of_match_table = q6v5_of_match,
2931 	},
2932 };
2933 module_platform_driver(q6v5_driver);
2934 
2935 MODULE_DESCRIPTION("Qualcomm Self-authenticating modem remoteproc driver");
2936 MODULE_LICENSE("GPL v2");
2937