1 // SPDX-License-Identifier: GPL-2.0
2 /*
3  * Qualcomm Technology Inc. ADSP Peripheral Image Loader for SDM845.
4  * Copyright (c) 2018, The Linux Foundation. All rights reserved.
5  */
6 
7 #include <linux/clk.h>
8 #include <linux/delay.h>
9 #include <linux/firmware.h>
10 #include <linux/interrupt.h>
11 #include <linux/io.h>
12 #include <linux/iommu.h>
13 #include <linux/iopoll.h>
14 #include <linux/kernel.h>
15 #include <linux/mfd/syscon.h>
16 #include <linux/module.h>
17 #include <linux/of.h>
18 #include <linux/of_reserved_mem.h>
19 #include <linux/platform_device.h>
20 #include <linux/pm_domain.h>
21 #include <linux/pm_runtime.h>
22 #include <linux/regmap.h>
23 #include <linux/remoteproc.h>
24 #include <linux/reset.h>
25 #include <linux/soc/qcom/mdt_loader.h>
26 #include <linux/soc/qcom/smem.h>
27 #include <linux/soc/qcom/smem_state.h>
28 
29 #include "qcom_common.h"
30 #include "qcom_pil_info.h"
31 #include "qcom_q6v5.h"
32 #include "remoteproc_internal.h"
33 
34 /* time out value */
35 #define ACK_TIMEOUT			1000
36 #define ACK_TIMEOUT_US			1000000
37 #define BOOT_FSM_TIMEOUT		10000
38 /* mask values */
39 #define EVB_MASK			GENMASK(27, 4)
40 /*QDSP6SS register offsets*/
41 #define RST_EVB_REG			0x10
42 #define CORE_START_REG			0x400
43 #define BOOT_CMD_REG			0x404
44 #define BOOT_STATUS_REG			0x408
45 #define RET_CFG_REG			0x1C
46 /*TCSR register offsets*/
47 #define LPASS_MASTER_IDLE_REG		0x8
48 #define LPASS_HALTACK_REG		0x4
49 #define LPASS_PWR_ON_REG		0x10
50 #define LPASS_HALTREQ_REG		0x0
51 
52 #define SID_MASK_DEFAULT        0xF
53 
54 #define QDSP6SS_XO_CBCR		0x38
55 #define QDSP6SS_CORE_CBCR	0x20
56 #define QDSP6SS_SLEEP_CBCR	0x3c
57 
58 #define QCOM_Q6V5_RPROC_PROXY_PD_MAX	3
59 
60 #define LPASS_BOOT_CORE_START	BIT(0)
61 #define LPASS_BOOT_CMD_START	BIT(0)
62 #define LPASS_EFUSE_Q6SS_EVB_SEL 0x0
63 
64 struct adsp_pil_data {
65 	int crash_reason_smem;
66 	const char *firmware_name;
67 
68 	const char *ssr_name;
69 	const char *sysmon_name;
70 	int ssctl_id;
71 	bool is_wpss;
72 	bool has_iommu;
73 	bool auto_boot;
74 
75 	const char **clk_ids;
76 	int num_clks;
77 	const char **proxy_pd_names;
78 	const char *load_state;
79 };
80 
81 struct qcom_adsp {
82 	struct device *dev;
83 	struct rproc *rproc;
84 
85 	struct qcom_q6v5 q6v5;
86 
87 	struct clk *xo;
88 
89 	int num_clks;
90 	struct clk_bulk_data *clks;
91 
92 	void __iomem *qdsp6ss_base;
93 	void __iomem *lpass_efuse;
94 
95 	struct reset_control *pdc_sync_reset;
96 	struct reset_control *restart;
97 
98 	struct regmap *halt_map;
99 	unsigned int halt_lpass;
100 
101 	int crash_reason_smem;
102 	const char *info_name;
103 
104 	struct completion start_done;
105 	struct completion stop_done;
106 
107 	phys_addr_t mem_phys;
108 	phys_addr_t mem_reloc;
109 	void *mem_region;
110 	size_t mem_size;
111 	bool has_iommu;
112 
113 	struct device *proxy_pds[QCOM_Q6V5_RPROC_PROXY_PD_MAX];
114 	size_t proxy_pd_count;
115 
116 	struct qcom_rproc_glink glink_subdev;
117 	struct qcom_rproc_ssr ssr_subdev;
118 	struct qcom_sysmon *sysmon;
119 
120 	int (*shutdown)(struct qcom_adsp *adsp);
121 };
122 
qcom_rproc_pds_attach(struct device * dev,struct qcom_adsp * adsp,const char ** pd_names)123 static int qcom_rproc_pds_attach(struct device *dev, struct qcom_adsp *adsp,
124 				 const char **pd_names)
125 {
126 	struct device **devs = adsp->proxy_pds;
127 	size_t num_pds = 0;
128 	int ret;
129 	int i;
130 
131 	if (!pd_names)
132 		return 0;
133 
134 	/* Handle single power domain */
135 	if (dev->pm_domain) {
136 		devs[0] = dev;
137 		pm_runtime_enable(dev);
138 		return 1;
139 	}
140 
141 	while (pd_names[num_pds])
142 		num_pds++;
143 
144 	if (num_pds > ARRAY_SIZE(adsp->proxy_pds))
145 		return -E2BIG;
146 
147 	for (i = 0; i < num_pds; i++) {
148 		devs[i] = dev_pm_domain_attach_by_name(dev, pd_names[i]);
149 		if (IS_ERR_OR_NULL(devs[i])) {
150 			ret = PTR_ERR(devs[i]) ? : -ENODATA;
151 			goto unroll_attach;
152 		}
153 	}
154 
155 	return num_pds;
156 
157 unroll_attach:
158 	for (i--; i >= 0; i--)
159 		dev_pm_domain_detach(devs[i], false);
160 
161 	return ret;
162 }
163 
qcom_rproc_pds_detach(struct qcom_adsp * adsp,struct device ** pds,size_t pd_count)164 static void qcom_rproc_pds_detach(struct qcom_adsp *adsp, struct device **pds,
165 				  size_t pd_count)
166 {
167 	struct device *dev = adsp->dev;
168 	int i;
169 
170 	/* Handle single power domain */
171 	if (dev->pm_domain && pd_count) {
172 		pm_runtime_disable(dev);
173 		return;
174 	}
175 
176 	for (i = 0; i < pd_count; i++)
177 		dev_pm_domain_detach(pds[i], false);
178 }
179 
qcom_rproc_pds_enable(struct qcom_adsp * adsp,struct device ** pds,size_t pd_count)180 static int qcom_rproc_pds_enable(struct qcom_adsp *adsp, struct device **pds,
181 				 size_t pd_count)
182 {
183 	int ret;
184 	int i;
185 
186 	for (i = 0; i < pd_count; i++) {
187 		dev_pm_genpd_set_performance_state(pds[i], INT_MAX);
188 		ret = pm_runtime_resume_and_get(pds[i]);
189 		if (ret < 0) {
190 			dev_pm_genpd_set_performance_state(pds[i], 0);
191 			goto unroll_pd_votes;
192 		}
193 	}
194 
195 	return 0;
196 
197 unroll_pd_votes:
198 	for (i--; i >= 0; i--) {
199 		dev_pm_genpd_set_performance_state(pds[i], 0);
200 		pm_runtime_put(pds[i]);
201 	}
202 
203 	return ret;
204 }
205 
qcom_rproc_pds_disable(struct qcom_adsp * adsp,struct device ** pds,size_t pd_count)206 static void qcom_rproc_pds_disable(struct qcom_adsp *adsp, struct device **pds,
207 				   size_t pd_count)
208 {
209 	int i;
210 
211 	for (i = 0; i < pd_count; i++) {
212 		dev_pm_genpd_set_performance_state(pds[i], 0);
213 		pm_runtime_put(pds[i]);
214 	}
215 }
216 
qcom_wpss_shutdown(struct qcom_adsp * adsp)217 static int qcom_wpss_shutdown(struct qcom_adsp *adsp)
218 {
219 	unsigned int val;
220 
221 	regmap_write(adsp->halt_map, adsp->halt_lpass + LPASS_HALTREQ_REG, 1);
222 
223 	/* Wait for halt ACK from QDSP6 */
224 	regmap_read_poll_timeout(adsp->halt_map,
225 				 adsp->halt_lpass + LPASS_HALTACK_REG, val,
226 				 val, 1000, ACK_TIMEOUT_US);
227 
228 	/* Assert the WPSS PDC Reset */
229 	reset_control_assert(adsp->pdc_sync_reset);
230 
231 	/* Place the WPSS processor into reset */
232 	reset_control_assert(adsp->restart);
233 
234 	/* wait after asserting subsystem restart from AOSS */
235 	usleep_range(200, 205);
236 
237 	/* Remove the WPSS reset */
238 	reset_control_deassert(adsp->restart);
239 
240 	/* De-assert the WPSS PDC Reset */
241 	reset_control_deassert(adsp->pdc_sync_reset);
242 
243 	usleep_range(100, 105);
244 
245 	clk_bulk_disable_unprepare(adsp->num_clks, adsp->clks);
246 
247 	regmap_write(adsp->halt_map, adsp->halt_lpass + LPASS_HALTREQ_REG, 0);
248 
249 	/* Wait for halt ACK from QDSP6 */
250 	regmap_read_poll_timeout(adsp->halt_map,
251 				 adsp->halt_lpass + LPASS_HALTACK_REG, val,
252 				 !val, 1000, ACK_TIMEOUT_US);
253 
254 	return 0;
255 }
256 
qcom_adsp_shutdown(struct qcom_adsp * adsp)257 static int qcom_adsp_shutdown(struct qcom_adsp *adsp)
258 {
259 	unsigned long timeout;
260 	unsigned int val;
261 	int ret;
262 
263 	/* Reset the retention logic */
264 	val = readl(adsp->qdsp6ss_base + RET_CFG_REG);
265 	val |= 0x1;
266 	writel(val, adsp->qdsp6ss_base + RET_CFG_REG);
267 
268 	clk_bulk_disable_unprepare(adsp->num_clks, adsp->clks);
269 
270 	/* QDSP6 master port needs to be explicitly halted */
271 	ret = regmap_read(adsp->halt_map,
272 			adsp->halt_lpass + LPASS_PWR_ON_REG, &val);
273 	if (ret || !val)
274 		goto reset;
275 
276 	ret = regmap_read(adsp->halt_map,
277 			adsp->halt_lpass + LPASS_MASTER_IDLE_REG,
278 			&val);
279 	if (ret || val)
280 		goto reset;
281 
282 	regmap_write(adsp->halt_map,
283 			adsp->halt_lpass + LPASS_HALTREQ_REG, 1);
284 
285 	/* Wait for halt ACK from QDSP6 */
286 	timeout = jiffies + msecs_to_jiffies(ACK_TIMEOUT);
287 	for (;;) {
288 		ret = regmap_read(adsp->halt_map,
289 			adsp->halt_lpass + LPASS_HALTACK_REG, &val);
290 		if (ret || val || time_after(jiffies, timeout))
291 			break;
292 
293 		usleep_range(1000, 1100);
294 	}
295 
296 	ret = regmap_read(adsp->halt_map,
297 			adsp->halt_lpass + LPASS_MASTER_IDLE_REG, &val);
298 	if (ret || !val)
299 		dev_err(adsp->dev, "port failed halt\n");
300 
301 reset:
302 	/* Assert the LPASS PDC Reset */
303 	reset_control_assert(adsp->pdc_sync_reset);
304 	/* Place the LPASS processor into reset */
305 	reset_control_assert(adsp->restart);
306 	/* wait after asserting subsystem restart from AOSS */
307 	usleep_range(200, 300);
308 
309 	/* Clear the halt request for the AXIM and AHBM for Q6 */
310 	regmap_write(adsp->halt_map, adsp->halt_lpass + LPASS_HALTREQ_REG, 0);
311 
312 	/* De-assert the LPASS PDC Reset */
313 	reset_control_deassert(adsp->pdc_sync_reset);
314 	/* Remove the LPASS reset */
315 	reset_control_deassert(adsp->restart);
316 	/* wait after de-asserting subsystem restart from AOSS */
317 	usleep_range(200, 300);
318 
319 	return 0;
320 }
321 
adsp_load(struct rproc * rproc,const struct firmware * fw)322 static int adsp_load(struct rproc *rproc, const struct firmware *fw)
323 {
324 	struct qcom_adsp *adsp = rproc->priv;
325 	int ret;
326 
327 	ret = qcom_mdt_load_no_init(adsp->dev, fw, rproc->firmware, 0,
328 				    adsp->mem_region, adsp->mem_phys,
329 				    adsp->mem_size, &adsp->mem_reloc);
330 	if (ret)
331 		return ret;
332 
333 	qcom_pil_info_store(adsp->info_name, adsp->mem_phys, adsp->mem_size);
334 
335 	return 0;
336 }
337 
adsp_unmap_carveout(struct rproc * rproc)338 static void adsp_unmap_carveout(struct rproc *rproc)
339 {
340 	struct qcom_adsp *adsp = rproc->priv;
341 
342 	if (adsp->has_iommu)
343 		iommu_unmap(rproc->domain, adsp->mem_phys, adsp->mem_size);
344 }
345 
adsp_map_carveout(struct rproc * rproc)346 static int adsp_map_carveout(struct rproc *rproc)
347 {
348 	struct qcom_adsp *adsp = rproc->priv;
349 	struct of_phandle_args args;
350 	long long sid;
351 	unsigned long iova;
352 	int ret;
353 
354 	if (!adsp->has_iommu)
355 		return 0;
356 
357 	if (!rproc->domain)
358 		return -EINVAL;
359 
360 	ret = of_parse_phandle_with_args(adsp->dev->of_node, "iommus", "#iommu-cells", 0, &args);
361 	if (ret < 0)
362 		return ret;
363 
364 	sid = args.args[0] & SID_MASK_DEFAULT;
365 
366 	/* Add SID configuration for ADSP Firmware to SMMU */
367 	iova =  adsp->mem_phys | (sid << 32);
368 
369 	ret = iommu_map(rproc->domain, iova, adsp->mem_phys,
370 			adsp->mem_size,	IOMMU_READ | IOMMU_WRITE,
371 			GFP_KERNEL);
372 	if (ret) {
373 		dev_err(adsp->dev, "Unable to map ADSP Physical Memory\n");
374 		return ret;
375 	}
376 
377 	return 0;
378 }
379 
adsp_start(struct rproc * rproc)380 static int adsp_start(struct rproc *rproc)
381 {
382 	struct qcom_adsp *adsp = rproc->priv;
383 	int ret;
384 	unsigned int val;
385 
386 	ret = qcom_q6v5_prepare(&adsp->q6v5);
387 	if (ret)
388 		return ret;
389 
390 	ret = adsp_map_carveout(rproc);
391 	if (ret) {
392 		dev_err(adsp->dev, "ADSP smmu mapping failed\n");
393 		goto disable_irqs;
394 	}
395 
396 	ret = clk_prepare_enable(adsp->xo);
397 	if (ret)
398 		goto adsp_smmu_unmap;
399 
400 	ret = qcom_rproc_pds_enable(adsp, adsp->proxy_pds,
401 				    adsp->proxy_pd_count);
402 	if (ret < 0)
403 		goto disable_xo_clk;
404 
405 	ret = clk_bulk_prepare_enable(adsp->num_clks, adsp->clks);
406 	if (ret) {
407 		dev_err(adsp->dev, "adsp clk_enable failed\n");
408 		goto disable_power_domain;
409 	}
410 
411 	/* Enable the XO clock */
412 	writel(1, adsp->qdsp6ss_base + QDSP6SS_XO_CBCR);
413 
414 	/* Enable the QDSP6SS sleep clock */
415 	writel(1, adsp->qdsp6ss_base + QDSP6SS_SLEEP_CBCR);
416 
417 	/* Enable the QDSP6 core clock */
418 	writel(1, adsp->qdsp6ss_base + QDSP6SS_CORE_CBCR);
419 
420 	/* Program boot address */
421 	writel(adsp->mem_phys >> 4, adsp->qdsp6ss_base + RST_EVB_REG);
422 
423 	if (adsp->lpass_efuse)
424 		writel(LPASS_EFUSE_Q6SS_EVB_SEL, adsp->lpass_efuse);
425 
426 	/* De-assert QDSP6 stop core. QDSP6 will execute after out of reset */
427 	writel(LPASS_BOOT_CORE_START, adsp->qdsp6ss_base + CORE_START_REG);
428 
429 	/* Trigger boot FSM to start QDSP6 */
430 	writel(LPASS_BOOT_CMD_START, adsp->qdsp6ss_base + BOOT_CMD_REG);
431 
432 	/* Wait for core to come out of reset */
433 	ret = readl_poll_timeout(adsp->qdsp6ss_base + BOOT_STATUS_REG,
434 			val, (val & BIT(0)) != 0, 10, BOOT_FSM_TIMEOUT);
435 	if (ret) {
436 		dev_err(adsp->dev, "failed to bootup adsp\n");
437 		goto disable_adsp_clks;
438 	}
439 
440 	ret = qcom_q6v5_wait_for_start(&adsp->q6v5, msecs_to_jiffies(5 * HZ));
441 	if (ret == -ETIMEDOUT) {
442 		dev_err(adsp->dev, "start timed out\n");
443 		goto disable_adsp_clks;
444 	}
445 
446 	return 0;
447 
448 disable_adsp_clks:
449 	clk_bulk_disable_unprepare(adsp->num_clks, adsp->clks);
450 disable_power_domain:
451 	qcom_rproc_pds_disable(adsp, adsp->proxy_pds, adsp->proxy_pd_count);
452 disable_xo_clk:
453 	clk_disable_unprepare(adsp->xo);
454 adsp_smmu_unmap:
455 	adsp_unmap_carveout(rproc);
456 disable_irqs:
457 	qcom_q6v5_unprepare(&adsp->q6v5);
458 
459 	return ret;
460 }
461 
qcom_adsp_pil_handover(struct qcom_q6v5 * q6v5)462 static void qcom_adsp_pil_handover(struct qcom_q6v5 *q6v5)
463 {
464 	struct qcom_adsp *adsp = container_of(q6v5, struct qcom_adsp, q6v5);
465 
466 	clk_disable_unprepare(adsp->xo);
467 	qcom_rproc_pds_disable(adsp, adsp->proxy_pds, adsp->proxy_pd_count);
468 }
469 
adsp_stop(struct rproc * rproc)470 static int adsp_stop(struct rproc *rproc)
471 {
472 	struct qcom_adsp *adsp = rproc->priv;
473 	int handover;
474 	int ret;
475 
476 	ret = qcom_q6v5_request_stop(&adsp->q6v5, adsp->sysmon);
477 	if (ret == -ETIMEDOUT)
478 		dev_err(adsp->dev, "timed out on wait\n");
479 
480 	ret = adsp->shutdown(adsp);
481 	if (ret)
482 		dev_err(adsp->dev, "failed to shutdown: %d\n", ret);
483 
484 	adsp_unmap_carveout(rproc);
485 
486 	handover = qcom_q6v5_unprepare(&adsp->q6v5);
487 	if (handover)
488 		qcom_adsp_pil_handover(&adsp->q6v5);
489 
490 	return ret;
491 }
492 
adsp_da_to_va(struct rproc * rproc,u64 da,size_t len,bool * is_iomem)493 static void *adsp_da_to_va(struct rproc *rproc, u64 da, size_t len, bool *is_iomem)
494 {
495 	struct qcom_adsp *adsp = rproc->priv;
496 	int offset;
497 
498 	offset = da - adsp->mem_reloc;
499 	if (offset < 0 || offset + len > adsp->mem_size)
500 		return NULL;
501 
502 	return adsp->mem_region + offset;
503 }
504 
adsp_parse_firmware(struct rproc * rproc,const struct firmware * fw)505 static int adsp_parse_firmware(struct rproc *rproc, const struct firmware *fw)
506 {
507 	struct qcom_adsp *adsp = rproc->priv;
508 	int ret;
509 
510 	ret = qcom_register_dump_segments(rproc, fw);
511 	if (ret) {
512 		dev_err(&rproc->dev, "Error in registering dump segments\n");
513 		return ret;
514 	}
515 
516 	if (adsp->has_iommu) {
517 		ret = rproc_elf_load_rsc_table(rproc, fw);
518 		if (ret) {
519 			dev_err(&rproc->dev, "Error in loading resource table\n");
520 			return ret;
521 		}
522 	}
523 	return 0;
524 }
525 
adsp_panic(struct rproc * rproc)526 static unsigned long adsp_panic(struct rproc *rproc)
527 {
528 	struct qcom_adsp *adsp = rproc->priv;
529 
530 	return qcom_q6v5_panic(&adsp->q6v5);
531 }
532 
533 static const struct rproc_ops adsp_ops = {
534 	.start = adsp_start,
535 	.stop = adsp_stop,
536 	.da_to_va = adsp_da_to_va,
537 	.parse_fw = adsp_parse_firmware,
538 	.load = adsp_load,
539 	.panic = adsp_panic,
540 };
541 
adsp_init_clock(struct qcom_adsp * adsp,const char ** clk_ids)542 static int adsp_init_clock(struct qcom_adsp *adsp, const char **clk_ids)
543 {
544 	int num_clks = 0;
545 	int i, ret;
546 
547 	adsp->xo = devm_clk_get(adsp->dev, "xo");
548 	if (IS_ERR(adsp->xo)) {
549 		ret = PTR_ERR(adsp->xo);
550 		if (ret != -EPROBE_DEFER)
551 			dev_err(adsp->dev, "failed to get xo clock");
552 		return ret;
553 	}
554 
555 	for (i = 0; clk_ids[i]; i++)
556 		num_clks++;
557 
558 	adsp->num_clks = num_clks;
559 	adsp->clks = devm_kcalloc(adsp->dev, adsp->num_clks,
560 				sizeof(*adsp->clks), GFP_KERNEL);
561 	if (!adsp->clks)
562 		return -ENOMEM;
563 
564 	for (i = 0; i < adsp->num_clks; i++)
565 		adsp->clks[i].id = clk_ids[i];
566 
567 	return devm_clk_bulk_get(adsp->dev, adsp->num_clks, adsp->clks);
568 }
569 
adsp_init_reset(struct qcom_adsp * adsp)570 static int adsp_init_reset(struct qcom_adsp *adsp)
571 {
572 	adsp->pdc_sync_reset = devm_reset_control_get_optional_exclusive(adsp->dev,
573 			"pdc_sync");
574 	if (IS_ERR(adsp->pdc_sync_reset)) {
575 		dev_err(adsp->dev, "failed to acquire pdc_sync reset\n");
576 		return PTR_ERR(adsp->pdc_sync_reset);
577 	}
578 
579 	adsp->restart = devm_reset_control_get_optional_exclusive(adsp->dev, "restart");
580 
581 	/* Fall back to the  old "cc_lpass" if "restart" is absent */
582 	if (!adsp->restart)
583 		adsp->restart = devm_reset_control_get_exclusive(adsp->dev, "cc_lpass");
584 
585 	if (IS_ERR(adsp->restart)) {
586 		dev_err(adsp->dev, "failed to acquire restart\n");
587 		return PTR_ERR(adsp->restart);
588 	}
589 
590 	return 0;
591 }
592 
adsp_init_mmio(struct qcom_adsp * adsp,struct platform_device * pdev)593 static int adsp_init_mmio(struct qcom_adsp *adsp,
594 				struct platform_device *pdev)
595 {
596 	struct resource *efuse_region;
597 	struct device_node *syscon;
598 	int ret;
599 
600 	adsp->qdsp6ss_base = devm_platform_ioremap_resource(pdev, 0);
601 	if (IS_ERR(adsp->qdsp6ss_base)) {
602 		dev_err(adsp->dev, "failed to map QDSP6SS registers\n");
603 		return PTR_ERR(adsp->qdsp6ss_base);
604 	}
605 
606 	efuse_region = platform_get_resource(pdev, IORESOURCE_MEM, 1);
607 	if (!efuse_region) {
608 		adsp->lpass_efuse = NULL;
609 		dev_dbg(adsp->dev, "failed to get efuse memory region\n");
610 	} else {
611 		adsp->lpass_efuse = devm_ioremap_resource(&pdev->dev, efuse_region);
612 		if (IS_ERR(adsp->lpass_efuse)) {
613 			dev_err(adsp->dev, "failed to map efuse registers\n");
614 			return PTR_ERR(adsp->lpass_efuse);
615 		}
616 	}
617 	syscon = of_parse_phandle(pdev->dev.of_node, "qcom,halt-regs", 0);
618 	if (!syscon) {
619 		dev_err(&pdev->dev, "failed to parse qcom,halt-regs\n");
620 		return -EINVAL;
621 	}
622 
623 	adsp->halt_map = syscon_node_to_regmap(syscon);
624 	of_node_put(syscon);
625 	if (IS_ERR(adsp->halt_map))
626 		return PTR_ERR(adsp->halt_map);
627 
628 	ret = of_property_read_u32_index(pdev->dev.of_node, "qcom,halt-regs",
629 			1, &adsp->halt_lpass);
630 	if (ret < 0) {
631 		dev_err(&pdev->dev, "no offset in syscon\n");
632 		return ret;
633 	}
634 
635 	return 0;
636 }
637 
adsp_alloc_memory_region(struct qcom_adsp * adsp)638 static int adsp_alloc_memory_region(struct qcom_adsp *adsp)
639 {
640 	struct reserved_mem *rmem = NULL;
641 	struct device_node *node;
642 
643 	node = of_parse_phandle(adsp->dev->of_node, "memory-region", 0);
644 	if (node)
645 		rmem = of_reserved_mem_lookup(node);
646 	of_node_put(node);
647 
648 	if (!rmem) {
649 		dev_err(adsp->dev, "unable to resolve memory-region\n");
650 		return -EINVAL;
651 	}
652 
653 	adsp->mem_phys = adsp->mem_reloc = rmem->base;
654 	adsp->mem_size = rmem->size;
655 	adsp->mem_region = devm_ioremap_wc(adsp->dev,
656 				adsp->mem_phys, adsp->mem_size);
657 	if (!adsp->mem_region) {
658 		dev_err(adsp->dev, "unable to map memory region: %pa+%zx\n",
659 			&rmem->base, adsp->mem_size);
660 		return -EBUSY;
661 	}
662 
663 	return 0;
664 }
665 
adsp_probe(struct platform_device * pdev)666 static int adsp_probe(struct platform_device *pdev)
667 {
668 	const struct adsp_pil_data *desc;
669 	const char *firmware_name;
670 	struct qcom_adsp *adsp;
671 	struct rproc *rproc;
672 	int ret;
673 
674 	desc = of_device_get_match_data(&pdev->dev);
675 	if (!desc)
676 		return -EINVAL;
677 
678 	firmware_name = desc->firmware_name;
679 	ret = of_property_read_string(pdev->dev.of_node, "firmware-name",
680 				      &firmware_name);
681 	if (ret < 0 && ret != -EINVAL) {
682 		dev_err(&pdev->dev, "unable to read firmware-name\n");
683 		return ret;
684 	}
685 
686 	rproc = rproc_alloc(&pdev->dev, pdev->name, &adsp_ops,
687 			    firmware_name, sizeof(*adsp));
688 	if (!rproc) {
689 		dev_err(&pdev->dev, "unable to allocate remoteproc\n");
690 		return -ENOMEM;
691 	}
692 
693 	rproc->auto_boot = desc->auto_boot;
694 	rproc->has_iommu = desc->has_iommu;
695 	rproc_coredump_set_elf_info(rproc, ELFCLASS32, EM_NONE);
696 
697 	adsp = rproc->priv;
698 	adsp->dev = &pdev->dev;
699 	adsp->rproc = rproc;
700 	adsp->info_name = desc->sysmon_name;
701 	adsp->has_iommu = desc->has_iommu;
702 
703 	platform_set_drvdata(pdev, adsp);
704 
705 	if (desc->is_wpss)
706 		adsp->shutdown = qcom_wpss_shutdown;
707 	else
708 		adsp->shutdown = qcom_adsp_shutdown;
709 
710 	ret = adsp_alloc_memory_region(adsp);
711 	if (ret)
712 		goto free_rproc;
713 
714 	ret = adsp_init_clock(adsp, desc->clk_ids);
715 	if (ret)
716 		goto free_rproc;
717 
718 	ret = qcom_rproc_pds_attach(adsp->dev, adsp,
719 				    desc->proxy_pd_names);
720 	if (ret < 0) {
721 		dev_err(&pdev->dev, "Failed to attach proxy power domains\n");
722 		goto free_rproc;
723 	}
724 	adsp->proxy_pd_count = ret;
725 
726 	ret = adsp_init_reset(adsp);
727 	if (ret)
728 		goto disable_pm;
729 
730 	ret = adsp_init_mmio(adsp, pdev);
731 	if (ret)
732 		goto disable_pm;
733 
734 	ret = qcom_q6v5_init(&adsp->q6v5, pdev, rproc, desc->crash_reason_smem,
735 			     desc->load_state, qcom_adsp_pil_handover);
736 	if (ret)
737 		goto disable_pm;
738 
739 	qcom_add_glink_subdev(rproc, &adsp->glink_subdev, desc->ssr_name);
740 	qcom_add_ssr_subdev(rproc, &adsp->ssr_subdev, desc->ssr_name);
741 	adsp->sysmon = qcom_add_sysmon_subdev(rproc,
742 					      desc->sysmon_name,
743 					      desc->ssctl_id);
744 	if (IS_ERR(adsp->sysmon)) {
745 		ret = PTR_ERR(adsp->sysmon);
746 		goto disable_pm;
747 	}
748 
749 	ret = rproc_add(rproc);
750 	if (ret)
751 		goto disable_pm;
752 
753 	return 0;
754 
755 disable_pm:
756 	qcom_rproc_pds_detach(adsp, adsp->proxy_pds, adsp->proxy_pd_count);
757 
758 free_rproc:
759 	rproc_free(rproc);
760 
761 	return ret;
762 }
763 
adsp_remove(struct platform_device * pdev)764 static void adsp_remove(struct platform_device *pdev)
765 {
766 	struct qcom_adsp *adsp = platform_get_drvdata(pdev);
767 
768 	rproc_del(adsp->rproc);
769 
770 	qcom_q6v5_deinit(&adsp->q6v5);
771 	qcom_remove_glink_subdev(adsp->rproc, &adsp->glink_subdev);
772 	qcom_remove_sysmon_subdev(adsp->sysmon);
773 	qcom_remove_ssr_subdev(adsp->rproc, &adsp->ssr_subdev);
774 	qcom_rproc_pds_detach(adsp, adsp->proxy_pds, adsp->proxy_pd_count);
775 	rproc_free(adsp->rproc);
776 }
777 
778 static const struct adsp_pil_data adsp_resource_init = {
779 	.crash_reason_smem = 423,
780 	.firmware_name = "adsp.mdt",
781 	.ssr_name = "lpass",
782 	.sysmon_name = "adsp",
783 	.ssctl_id = 0x14,
784 	.is_wpss = false,
785 	.auto_boot = true,
786 	.clk_ids = (const char*[]) {
787 		"sway_cbcr", "lpass_ahbs_aon_cbcr", "lpass_ahbm_aon_cbcr",
788 		"qdsp6ss_xo", "qdsp6ss_sleep", "qdsp6ss_core", NULL
789 	},
790 	.num_clks = 7,
791 	.proxy_pd_names = (const char*[]) {
792 		"cx", NULL
793 	},
794 };
795 
796 static const struct adsp_pil_data adsp_sc7280_resource_init = {
797 	.crash_reason_smem = 423,
798 	.firmware_name = "adsp.pbn",
799 	.load_state = "adsp",
800 	.ssr_name = "lpass",
801 	.sysmon_name = "adsp",
802 	.ssctl_id = 0x14,
803 	.has_iommu = true,
804 	.auto_boot = true,
805 	.clk_ids = (const char*[]) {
806 		"gcc_cfg_noc_lpass", NULL
807 	},
808 	.num_clks = 1,
809 };
810 
811 static const struct adsp_pil_data cdsp_resource_init = {
812 	.crash_reason_smem = 601,
813 	.firmware_name = "cdsp.mdt",
814 	.ssr_name = "cdsp",
815 	.sysmon_name = "cdsp",
816 	.ssctl_id = 0x17,
817 	.is_wpss = false,
818 	.auto_boot = true,
819 	.clk_ids = (const char*[]) {
820 		"sway", "tbu", "bimc", "ahb_aon", "q6ss_slave", "q6ss_master",
821 		"q6_axim", NULL
822 	},
823 	.num_clks = 7,
824 	.proxy_pd_names = (const char*[]) {
825 		"cx", NULL
826 	},
827 };
828 
829 static const struct adsp_pil_data wpss_resource_init = {
830 	.crash_reason_smem = 626,
831 	.firmware_name = "wpss.mdt",
832 	.ssr_name = "wpss",
833 	.sysmon_name = "wpss",
834 	.ssctl_id = 0x19,
835 	.is_wpss = true,
836 	.auto_boot = false,
837 	.load_state = "wpss",
838 	.clk_ids = (const char*[]) {
839 		"ahb_bdg", "ahb", "rscp", NULL
840 	},
841 	.num_clks = 3,
842 	.proxy_pd_names = (const char*[]) {
843 		"cx", "mx", NULL
844 	},
845 };
846 
847 static const struct of_device_id adsp_of_match[] = {
848 	{ .compatible = "qcom,qcs404-cdsp-pil", .data = &cdsp_resource_init },
849 	{ .compatible = "qcom,sc7280-adsp-pil", .data = &adsp_sc7280_resource_init },
850 	{ .compatible = "qcom,sc7280-wpss-pil", .data = &wpss_resource_init },
851 	{ .compatible = "qcom,sdm845-adsp-pil", .data = &adsp_resource_init },
852 	{ },
853 };
854 MODULE_DEVICE_TABLE(of, adsp_of_match);
855 
856 static struct platform_driver adsp_pil_driver = {
857 	.probe = adsp_probe,
858 	.remove_new = adsp_remove,
859 	.driver = {
860 		.name = "qcom_q6v5_adsp",
861 		.of_match_table = adsp_of_match,
862 	},
863 };
864 
865 module_platform_driver(adsp_pil_driver);
866 MODULE_DESCRIPTION("QTI SDM845 ADSP Peripheral Image Loader");
867 MODULE_LICENSE("GPL v2");
868