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