xref: /linux/drivers/remoteproc/qcom_q6v5_adsp.c (revision d6fd48ef)
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_address.h>
18 #include <linux/of_device.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 
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 
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 
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 
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 
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 
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 
322 static int adsp_load(struct rproc *rproc, const struct firmware *fw)
323 {
324 	struct qcom_adsp *adsp = (struct qcom_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 
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 
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 
380 static int adsp_start(struct rproc *rproc)
381 {
382 	struct qcom_adsp *adsp = (struct qcom_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 
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 
470 static int adsp_stop(struct rproc *rproc)
471 {
472 	struct qcom_adsp *adsp = (struct qcom_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 
493 static void *adsp_da_to_va(struct rproc *rproc, u64 da, size_t len, bool *is_iomem)
494 {
495 	struct qcom_adsp *adsp = (struct qcom_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 
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 
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 
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 
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 
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 
638 static int adsp_alloc_memory_region(struct qcom_adsp *adsp)
639 {
640 	struct device_node *node;
641 	struct resource r;
642 	int ret;
643 
644 	node = of_parse_phandle(adsp->dev->of_node, "memory-region", 0);
645 	if (!node) {
646 		dev_err(adsp->dev, "no memory-region specified\n");
647 		return -EINVAL;
648 	}
649 
650 	ret = of_address_to_resource(node, 0, &r);
651 	of_node_put(node);
652 	if (ret)
653 		return ret;
654 
655 	adsp->mem_phys = adsp->mem_reloc = r.start;
656 	adsp->mem_size = resource_size(&r);
657 	adsp->mem_region = devm_ioremap_wc(adsp->dev,
658 				adsp->mem_phys, adsp->mem_size);
659 	if (!adsp->mem_region) {
660 		dev_err(adsp->dev, "unable to map memory region: %pa+%zx\n",
661 			&r.start, adsp->mem_size);
662 		return -EBUSY;
663 	}
664 
665 	return 0;
666 }
667 
668 static int adsp_probe(struct platform_device *pdev)
669 {
670 	const struct adsp_pil_data *desc;
671 	const char *firmware_name;
672 	struct qcom_adsp *adsp;
673 	struct rproc *rproc;
674 	int ret;
675 
676 	desc = of_device_get_match_data(&pdev->dev);
677 	if (!desc)
678 		return -EINVAL;
679 
680 	firmware_name = desc->firmware_name;
681 	ret = of_property_read_string(pdev->dev.of_node, "firmware-name",
682 				      &firmware_name);
683 	if (ret < 0 && ret != -EINVAL) {
684 		dev_err(&pdev->dev, "unable to read firmware-name\n");
685 		return ret;
686 	}
687 
688 	rproc = rproc_alloc(&pdev->dev, pdev->name, &adsp_ops,
689 			    firmware_name, sizeof(*adsp));
690 	if (!rproc) {
691 		dev_err(&pdev->dev, "unable to allocate remoteproc\n");
692 		return -ENOMEM;
693 	}
694 
695 	rproc->auto_boot = desc->auto_boot;
696 	rproc->has_iommu = desc->has_iommu;
697 	rproc_coredump_set_elf_info(rproc, ELFCLASS32, EM_NONE);
698 
699 	adsp = (struct qcom_adsp *)rproc->priv;
700 	adsp->dev = &pdev->dev;
701 	adsp->rproc = rproc;
702 	adsp->info_name = desc->sysmon_name;
703 	adsp->has_iommu = desc->has_iommu;
704 
705 	platform_set_drvdata(pdev, adsp);
706 
707 	if (desc->is_wpss)
708 		adsp->shutdown = qcom_wpss_shutdown;
709 	else
710 		adsp->shutdown = qcom_adsp_shutdown;
711 
712 	ret = adsp_alloc_memory_region(adsp);
713 	if (ret)
714 		goto free_rproc;
715 
716 	ret = adsp_init_clock(adsp, desc->clk_ids);
717 	if (ret)
718 		goto free_rproc;
719 
720 	ret = qcom_rproc_pds_attach(adsp->dev, adsp,
721 				    desc->proxy_pd_names);
722 	if (ret < 0) {
723 		dev_err(&pdev->dev, "Failed to attach proxy power domains\n");
724 		goto free_rproc;
725 	}
726 	adsp->proxy_pd_count = ret;
727 
728 	ret = adsp_init_reset(adsp);
729 	if (ret)
730 		goto disable_pm;
731 
732 	ret = adsp_init_mmio(adsp, pdev);
733 	if (ret)
734 		goto disable_pm;
735 
736 	ret = qcom_q6v5_init(&adsp->q6v5, pdev, rproc, desc->crash_reason_smem,
737 			     desc->load_state, qcom_adsp_pil_handover);
738 	if (ret)
739 		goto disable_pm;
740 
741 	qcom_add_glink_subdev(rproc, &adsp->glink_subdev, desc->ssr_name);
742 	qcom_add_ssr_subdev(rproc, &adsp->ssr_subdev, desc->ssr_name);
743 	adsp->sysmon = qcom_add_sysmon_subdev(rproc,
744 					      desc->sysmon_name,
745 					      desc->ssctl_id);
746 	if (IS_ERR(adsp->sysmon)) {
747 		ret = PTR_ERR(adsp->sysmon);
748 		goto disable_pm;
749 	}
750 
751 	ret = rproc_add(rproc);
752 	if (ret)
753 		goto disable_pm;
754 
755 	return 0;
756 
757 disable_pm:
758 	qcom_rproc_pds_detach(adsp, adsp->proxy_pds, adsp->proxy_pd_count);
759 
760 free_rproc:
761 	rproc_free(rproc);
762 
763 	return ret;
764 }
765 
766 static int adsp_remove(struct platform_device *pdev)
767 {
768 	struct qcom_adsp *adsp = platform_get_drvdata(pdev);
769 
770 	rproc_del(adsp->rproc);
771 
772 	qcom_q6v5_deinit(&adsp->q6v5);
773 	qcom_remove_glink_subdev(adsp->rproc, &adsp->glink_subdev);
774 	qcom_remove_sysmon_subdev(adsp->sysmon);
775 	qcom_remove_ssr_subdev(adsp->rproc, &adsp->ssr_subdev);
776 	qcom_rproc_pds_detach(adsp, adsp->proxy_pds, adsp->proxy_pd_count);
777 	rproc_free(adsp->rproc);
778 
779 	return 0;
780 }
781 
782 static const struct adsp_pil_data adsp_resource_init = {
783 	.crash_reason_smem = 423,
784 	.firmware_name = "adsp.mdt",
785 	.ssr_name = "lpass",
786 	.sysmon_name = "adsp",
787 	.ssctl_id = 0x14,
788 	.is_wpss = false,
789 	.auto_boot = true,
790 	.clk_ids = (const char*[]) {
791 		"sway_cbcr", "lpass_ahbs_aon_cbcr", "lpass_ahbm_aon_cbcr",
792 		"qdsp6ss_xo", "qdsp6ss_sleep", "qdsp6ss_core", NULL
793 	},
794 	.num_clks = 7,
795 	.proxy_pd_names = (const char*[]) {
796 		"cx", NULL
797 	},
798 };
799 
800 static const struct adsp_pil_data adsp_sc7280_resource_init = {
801 	.crash_reason_smem = 423,
802 	.firmware_name = "adsp.pbn",
803 	.load_state = "adsp",
804 	.ssr_name = "lpass",
805 	.sysmon_name = "adsp",
806 	.ssctl_id = 0x14,
807 	.has_iommu = true,
808 	.auto_boot = true,
809 	.clk_ids = (const char*[]) {
810 		"gcc_cfg_noc_lpass", NULL
811 	},
812 	.num_clks = 1,
813 };
814 
815 static const struct adsp_pil_data cdsp_resource_init = {
816 	.crash_reason_smem = 601,
817 	.firmware_name = "cdsp.mdt",
818 	.ssr_name = "cdsp",
819 	.sysmon_name = "cdsp",
820 	.ssctl_id = 0x17,
821 	.is_wpss = false,
822 	.auto_boot = true,
823 	.clk_ids = (const char*[]) {
824 		"sway", "tbu", "bimc", "ahb_aon", "q6ss_slave", "q6ss_master",
825 		"q6_axim", NULL
826 	},
827 	.num_clks = 7,
828 	.proxy_pd_names = (const char*[]) {
829 		"cx", NULL
830 	},
831 };
832 
833 static const struct adsp_pil_data wpss_resource_init = {
834 	.crash_reason_smem = 626,
835 	.firmware_name = "wpss.mdt",
836 	.ssr_name = "wpss",
837 	.sysmon_name = "wpss",
838 	.ssctl_id = 0x19,
839 	.is_wpss = true,
840 	.auto_boot = false,
841 	.load_state = "wpss",
842 	.clk_ids = (const char*[]) {
843 		"ahb_bdg", "ahb", "rscp", NULL
844 	},
845 	.num_clks = 3,
846 	.proxy_pd_names = (const char*[]) {
847 		"cx", "mx", NULL
848 	},
849 };
850 
851 static const struct of_device_id adsp_of_match[] = {
852 	{ .compatible = "qcom,qcs404-cdsp-pil", .data = &cdsp_resource_init },
853 	{ .compatible = "qcom,sc7280-adsp-pil", .data = &adsp_sc7280_resource_init },
854 	{ .compatible = "qcom,sc7280-wpss-pil", .data = &wpss_resource_init },
855 	{ .compatible = "qcom,sdm845-adsp-pil", .data = &adsp_resource_init },
856 	{ },
857 };
858 MODULE_DEVICE_TABLE(of, adsp_of_match);
859 
860 static struct platform_driver adsp_pil_driver = {
861 	.probe = adsp_probe,
862 	.remove = adsp_remove,
863 	.driver = {
864 		.name = "qcom_q6v5_adsp",
865 		.of_match_table = adsp_of_match,
866 	},
867 };
868 
869 module_platform_driver(adsp_pil_driver);
870 MODULE_DESCRIPTION("QTI SDM845 ADSP Peripheral Image Loader");
871 MODULE_LICENSE("GPL v2");
872