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