18c2ecf20Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0-only
28c2ecf20Sopenharmony_ci/*
38c2ecf20Sopenharmony_ci * Qualcomm ADSP/SLPI Peripheral Image Loader for MSM8974 and MSM8996
48c2ecf20Sopenharmony_ci *
58c2ecf20Sopenharmony_ci * Copyright (C) 2016 Linaro Ltd
68c2ecf20Sopenharmony_ci * Copyright (C) 2014 Sony Mobile Communications AB
78c2ecf20Sopenharmony_ci * Copyright (c) 2012-2013, The Linux Foundation. All rights reserved.
88c2ecf20Sopenharmony_ci */
98c2ecf20Sopenharmony_ci
108c2ecf20Sopenharmony_ci#include <linux/clk.h>
118c2ecf20Sopenharmony_ci#include <linux/firmware.h>
128c2ecf20Sopenharmony_ci#include <linux/interrupt.h>
138c2ecf20Sopenharmony_ci#include <linux/kernel.h>
148c2ecf20Sopenharmony_ci#include <linux/module.h>
158c2ecf20Sopenharmony_ci#include <linux/of_address.h>
168c2ecf20Sopenharmony_ci#include <linux/of_device.h>
178c2ecf20Sopenharmony_ci#include <linux/platform_device.h>
188c2ecf20Sopenharmony_ci#include <linux/pm_domain.h>
198c2ecf20Sopenharmony_ci#include <linux/pm_runtime.h>
208c2ecf20Sopenharmony_ci#include <linux/qcom_scm.h>
218c2ecf20Sopenharmony_ci#include <linux/regulator/consumer.h>
228c2ecf20Sopenharmony_ci#include <linux/remoteproc.h>
238c2ecf20Sopenharmony_ci#include <linux/soc/qcom/mdt_loader.h>
248c2ecf20Sopenharmony_ci#include <linux/soc/qcom/smem.h>
258c2ecf20Sopenharmony_ci#include <linux/soc/qcom/smem_state.h>
268c2ecf20Sopenharmony_ci
278c2ecf20Sopenharmony_ci#include "qcom_common.h"
288c2ecf20Sopenharmony_ci#include "qcom_pil_info.h"
298c2ecf20Sopenharmony_ci#include "qcom_q6v5.h"
308c2ecf20Sopenharmony_ci#include "remoteproc_internal.h"
318c2ecf20Sopenharmony_ci
328c2ecf20Sopenharmony_cistruct adsp_data {
338c2ecf20Sopenharmony_ci	int crash_reason_smem;
348c2ecf20Sopenharmony_ci	const char *firmware_name;
358c2ecf20Sopenharmony_ci	int pas_id;
368c2ecf20Sopenharmony_ci	bool has_aggre2_clk;
378c2ecf20Sopenharmony_ci	bool auto_boot;
388c2ecf20Sopenharmony_ci
398c2ecf20Sopenharmony_ci	char **active_pd_names;
408c2ecf20Sopenharmony_ci	char **proxy_pd_names;
418c2ecf20Sopenharmony_ci
428c2ecf20Sopenharmony_ci	const char *ssr_name;
438c2ecf20Sopenharmony_ci	const char *sysmon_name;
448c2ecf20Sopenharmony_ci	int ssctl_id;
458c2ecf20Sopenharmony_ci};
468c2ecf20Sopenharmony_ci
478c2ecf20Sopenharmony_cistruct qcom_adsp {
488c2ecf20Sopenharmony_ci	struct device *dev;
498c2ecf20Sopenharmony_ci	struct rproc *rproc;
508c2ecf20Sopenharmony_ci
518c2ecf20Sopenharmony_ci	struct qcom_q6v5 q6v5;
528c2ecf20Sopenharmony_ci
538c2ecf20Sopenharmony_ci	struct clk *xo;
548c2ecf20Sopenharmony_ci	struct clk *aggre2_clk;
558c2ecf20Sopenharmony_ci
568c2ecf20Sopenharmony_ci	struct regulator *cx_supply;
578c2ecf20Sopenharmony_ci	struct regulator *px_supply;
588c2ecf20Sopenharmony_ci
598c2ecf20Sopenharmony_ci	struct device *active_pds[1];
608c2ecf20Sopenharmony_ci	struct device *proxy_pds[3];
618c2ecf20Sopenharmony_ci
628c2ecf20Sopenharmony_ci	int active_pd_count;
638c2ecf20Sopenharmony_ci	int proxy_pd_count;
648c2ecf20Sopenharmony_ci
658c2ecf20Sopenharmony_ci	int pas_id;
668c2ecf20Sopenharmony_ci	int crash_reason_smem;
678c2ecf20Sopenharmony_ci	bool has_aggre2_clk;
688c2ecf20Sopenharmony_ci	const char *info_name;
698c2ecf20Sopenharmony_ci
708c2ecf20Sopenharmony_ci	struct completion start_done;
718c2ecf20Sopenharmony_ci	struct completion stop_done;
728c2ecf20Sopenharmony_ci
738c2ecf20Sopenharmony_ci	phys_addr_t mem_phys;
748c2ecf20Sopenharmony_ci	phys_addr_t mem_reloc;
758c2ecf20Sopenharmony_ci	void *mem_region;
768c2ecf20Sopenharmony_ci	size_t mem_size;
778c2ecf20Sopenharmony_ci
788c2ecf20Sopenharmony_ci	struct qcom_rproc_glink glink_subdev;
798c2ecf20Sopenharmony_ci	struct qcom_rproc_subdev smd_subdev;
808c2ecf20Sopenharmony_ci	struct qcom_rproc_ssr ssr_subdev;
818c2ecf20Sopenharmony_ci	struct qcom_sysmon *sysmon;
828c2ecf20Sopenharmony_ci};
838c2ecf20Sopenharmony_ci
848c2ecf20Sopenharmony_cistatic int adsp_pds_enable(struct qcom_adsp *adsp, struct device **pds,
858c2ecf20Sopenharmony_ci			   size_t pd_count)
868c2ecf20Sopenharmony_ci{
878c2ecf20Sopenharmony_ci	int ret;
888c2ecf20Sopenharmony_ci	int i;
898c2ecf20Sopenharmony_ci
908c2ecf20Sopenharmony_ci	for (i = 0; i < pd_count; i++) {
918c2ecf20Sopenharmony_ci		dev_pm_genpd_set_performance_state(pds[i], INT_MAX);
928c2ecf20Sopenharmony_ci		ret = pm_runtime_get_sync(pds[i]);
938c2ecf20Sopenharmony_ci		if (ret < 0) {
948c2ecf20Sopenharmony_ci			pm_runtime_put_noidle(pds[i]);
958c2ecf20Sopenharmony_ci			dev_pm_genpd_set_performance_state(pds[i], 0);
968c2ecf20Sopenharmony_ci			goto unroll_pd_votes;
978c2ecf20Sopenharmony_ci		}
988c2ecf20Sopenharmony_ci	}
998c2ecf20Sopenharmony_ci
1008c2ecf20Sopenharmony_ci	return 0;
1018c2ecf20Sopenharmony_ci
1028c2ecf20Sopenharmony_ciunroll_pd_votes:
1038c2ecf20Sopenharmony_ci	for (i--; i >= 0; i--) {
1048c2ecf20Sopenharmony_ci		dev_pm_genpd_set_performance_state(pds[i], 0);
1058c2ecf20Sopenharmony_ci		pm_runtime_put(pds[i]);
1068c2ecf20Sopenharmony_ci	}
1078c2ecf20Sopenharmony_ci
1088c2ecf20Sopenharmony_ci	return ret;
1098c2ecf20Sopenharmony_ci};
1108c2ecf20Sopenharmony_ci
1118c2ecf20Sopenharmony_cistatic void adsp_pds_disable(struct qcom_adsp *adsp, struct device **pds,
1128c2ecf20Sopenharmony_ci			     size_t pd_count)
1138c2ecf20Sopenharmony_ci{
1148c2ecf20Sopenharmony_ci	int i;
1158c2ecf20Sopenharmony_ci
1168c2ecf20Sopenharmony_ci	for (i = 0; i < pd_count; i++) {
1178c2ecf20Sopenharmony_ci		dev_pm_genpd_set_performance_state(pds[i], 0);
1188c2ecf20Sopenharmony_ci		pm_runtime_put(pds[i]);
1198c2ecf20Sopenharmony_ci	}
1208c2ecf20Sopenharmony_ci}
1218c2ecf20Sopenharmony_ci
1228c2ecf20Sopenharmony_cistatic int adsp_load(struct rproc *rproc, const struct firmware *fw)
1238c2ecf20Sopenharmony_ci{
1248c2ecf20Sopenharmony_ci	struct qcom_adsp *adsp = (struct qcom_adsp *)rproc->priv;
1258c2ecf20Sopenharmony_ci	int ret;
1268c2ecf20Sopenharmony_ci
1278c2ecf20Sopenharmony_ci	ret = qcom_mdt_load(adsp->dev, fw, rproc->firmware, adsp->pas_id,
1288c2ecf20Sopenharmony_ci			    adsp->mem_region, adsp->mem_phys, adsp->mem_size,
1298c2ecf20Sopenharmony_ci			    &adsp->mem_reloc);
1308c2ecf20Sopenharmony_ci	if (ret)
1318c2ecf20Sopenharmony_ci		return ret;
1328c2ecf20Sopenharmony_ci
1338c2ecf20Sopenharmony_ci	qcom_pil_info_store(adsp->info_name, adsp->mem_phys, adsp->mem_size);
1348c2ecf20Sopenharmony_ci
1358c2ecf20Sopenharmony_ci	return 0;
1368c2ecf20Sopenharmony_ci}
1378c2ecf20Sopenharmony_ci
1388c2ecf20Sopenharmony_cistatic int adsp_start(struct rproc *rproc)
1398c2ecf20Sopenharmony_ci{
1408c2ecf20Sopenharmony_ci	struct qcom_adsp *adsp = (struct qcom_adsp *)rproc->priv;
1418c2ecf20Sopenharmony_ci	int ret;
1428c2ecf20Sopenharmony_ci
1438c2ecf20Sopenharmony_ci	qcom_q6v5_prepare(&adsp->q6v5);
1448c2ecf20Sopenharmony_ci
1458c2ecf20Sopenharmony_ci	ret = adsp_pds_enable(adsp, adsp->active_pds, adsp->active_pd_count);
1468c2ecf20Sopenharmony_ci	if (ret < 0)
1478c2ecf20Sopenharmony_ci		goto disable_irqs;
1488c2ecf20Sopenharmony_ci
1498c2ecf20Sopenharmony_ci	ret = adsp_pds_enable(adsp, adsp->proxy_pds, adsp->proxy_pd_count);
1508c2ecf20Sopenharmony_ci	if (ret < 0)
1518c2ecf20Sopenharmony_ci		goto disable_active_pds;
1528c2ecf20Sopenharmony_ci
1538c2ecf20Sopenharmony_ci	ret = clk_prepare_enable(adsp->xo);
1548c2ecf20Sopenharmony_ci	if (ret)
1558c2ecf20Sopenharmony_ci		goto disable_proxy_pds;
1568c2ecf20Sopenharmony_ci
1578c2ecf20Sopenharmony_ci	ret = clk_prepare_enable(adsp->aggre2_clk);
1588c2ecf20Sopenharmony_ci	if (ret)
1598c2ecf20Sopenharmony_ci		goto disable_xo_clk;
1608c2ecf20Sopenharmony_ci
1618c2ecf20Sopenharmony_ci	ret = regulator_enable(adsp->cx_supply);
1628c2ecf20Sopenharmony_ci	if (ret)
1638c2ecf20Sopenharmony_ci		goto disable_aggre2_clk;
1648c2ecf20Sopenharmony_ci
1658c2ecf20Sopenharmony_ci	ret = regulator_enable(adsp->px_supply);
1668c2ecf20Sopenharmony_ci	if (ret)
1678c2ecf20Sopenharmony_ci		goto disable_cx_supply;
1688c2ecf20Sopenharmony_ci
1698c2ecf20Sopenharmony_ci	ret = qcom_scm_pas_auth_and_reset(adsp->pas_id);
1708c2ecf20Sopenharmony_ci	if (ret) {
1718c2ecf20Sopenharmony_ci		dev_err(adsp->dev,
1728c2ecf20Sopenharmony_ci			"failed to authenticate image and release reset\n");
1738c2ecf20Sopenharmony_ci		goto disable_px_supply;
1748c2ecf20Sopenharmony_ci	}
1758c2ecf20Sopenharmony_ci
1768c2ecf20Sopenharmony_ci	ret = qcom_q6v5_wait_for_start(&adsp->q6v5, msecs_to_jiffies(5000));
1778c2ecf20Sopenharmony_ci	if (ret == -ETIMEDOUT) {
1788c2ecf20Sopenharmony_ci		dev_err(adsp->dev, "start timed out\n");
1798c2ecf20Sopenharmony_ci		qcom_scm_pas_shutdown(adsp->pas_id);
1808c2ecf20Sopenharmony_ci		goto disable_px_supply;
1818c2ecf20Sopenharmony_ci	}
1828c2ecf20Sopenharmony_ci
1838c2ecf20Sopenharmony_ci	return 0;
1848c2ecf20Sopenharmony_ci
1858c2ecf20Sopenharmony_cidisable_px_supply:
1868c2ecf20Sopenharmony_ci	regulator_disable(adsp->px_supply);
1878c2ecf20Sopenharmony_cidisable_cx_supply:
1888c2ecf20Sopenharmony_ci	regulator_disable(adsp->cx_supply);
1898c2ecf20Sopenharmony_cidisable_aggre2_clk:
1908c2ecf20Sopenharmony_ci	clk_disable_unprepare(adsp->aggre2_clk);
1918c2ecf20Sopenharmony_cidisable_xo_clk:
1928c2ecf20Sopenharmony_ci	clk_disable_unprepare(adsp->xo);
1938c2ecf20Sopenharmony_cidisable_proxy_pds:
1948c2ecf20Sopenharmony_ci	adsp_pds_disable(adsp, adsp->proxy_pds, adsp->proxy_pd_count);
1958c2ecf20Sopenharmony_cidisable_active_pds:
1968c2ecf20Sopenharmony_ci	adsp_pds_disable(adsp, adsp->active_pds, adsp->active_pd_count);
1978c2ecf20Sopenharmony_cidisable_irqs:
1988c2ecf20Sopenharmony_ci	qcom_q6v5_unprepare(&adsp->q6v5);
1998c2ecf20Sopenharmony_ci
2008c2ecf20Sopenharmony_ci	return ret;
2018c2ecf20Sopenharmony_ci}
2028c2ecf20Sopenharmony_ci
2038c2ecf20Sopenharmony_cistatic void qcom_pas_handover(struct qcom_q6v5 *q6v5)
2048c2ecf20Sopenharmony_ci{
2058c2ecf20Sopenharmony_ci	struct qcom_adsp *adsp = container_of(q6v5, struct qcom_adsp, q6v5);
2068c2ecf20Sopenharmony_ci
2078c2ecf20Sopenharmony_ci	regulator_disable(adsp->px_supply);
2088c2ecf20Sopenharmony_ci	regulator_disable(adsp->cx_supply);
2098c2ecf20Sopenharmony_ci	clk_disable_unprepare(adsp->aggre2_clk);
2108c2ecf20Sopenharmony_ci	clk_disable_unprepare(adsp->xo);
2118c2ecf20Sopenharmony_ci	adsp_pds_disable(adsp, adsp->proxy_pds, adsp->proxy_pd_count);
2128c2ecf20Sopenharmony_ci}
2138c2ecf20Sopenharmony_ci
2148c2ecf20Sopenharmony_cistatic int adsp_stop(struct rproc *rproc)
2158c2ecf20Sopenharmony_ci{
2168c2ecf20Sopenharmony_ci	struct qcom_adsp *adsp = (struct qcom_adsp *)rproc->priv;
2178c2ecf20Sopenharmony_ci	int handover;
2188c2ecf20Sopenharmony_ci	int ret;
2198c2ecf20Sopenharmony_ci
2208c2ecf20Sopenharmony_ci	ret = qcom_q6v5_request_stop(&adsp->q6v5);
2218c2ecf20Sopenharmony_ci	if (ret == -ETIMEDOUT)
2228c2ecf20Sopenharmony_ci		dev_err(adsp->dev, "timed out on wait\n");
2238c2ecf20Sopenharmony_ci
2248c2ecf20Sopenharmony_ci	ret = qcom_scm_pas_shutdown(adsp->pas_id);
2258c2ecf20Sopenharmony_ci	if (ret)
2268c2ecf20Sopenharmony_ci		dev_err(adsp->dev, "failed to shutdown: %d\n", ret);
2278c2ecf20Sopenharmony_ci
2288c2ecf20Sopenharmony_ci	adsp_pds_disable(adsp, adsp->active_pds, adsp->active_pd_count);
2298c2ecf20Sopenharmony_ci	handover = qcom_q6v5_unprepare(&adsp->q6v5);
2308c2ecf20Sopenharmony_ci	if (handover)
2318c2ecf20Sopenharmony_ci		qcom_pas_handover(&adsp->q6v5);
2328c2ecf20Sopenharmony_ci
2338c2ecf20Sopenharmony_ci	return ret;
2348c2ecf20Sopenharmony_ci}
2358c2ecf20Sopenharmony_ci
2368c2ecf20Sopenharmony_cistatic void *adsp_da_to_va(struct rproc *rproc, u64 da, size_t len)
2378c2ecf20Sopenharmony_ci{
2388c2ecf20Sopenharmony_ci	struct qcom_adsp *adsp = (struct qcom_adsp *)rproc->priv;
2398c2ecf20Sopenharmony_ci	int offset;
2408c2ecf20Sopenharmony_ci
2418c2ecf20Sopenharmony_ci	offset = da - adsp->mem_reloc;
2428c2ecf20Sopenharmony_ci	if (offset < 0 || offset + len > adsp->mem_size)
2438c2ecf20Sopenharmony_ci		return NULL;
2448c2ecf20Sopenharmony_ci
2458c2ecf20Sopenharmony_ci	return adsp->mem_region + offset;
2468c2ecf20Sopenharmony_ci}
2478c2ecf20Sopenharmony_ci
2488c2ecf20Sopenharmony_cistatic unsigned long adsp_panic(struct rproc *rproc)
2498c2ecf20Sopenharmony_ci{
2508c2ecf20Sopenharmony_ci	struct qcom_adsp *adsp = (struct qcom_adsp *)rproc->priv;
2518c2ecf20Sopenharmony_ci
2528c2ecf20Sopenharmony_ci	return qcom_q6v5_panic(&adsp->q6v5);
2538c2ecf20Sopenharmony_ci}
2548c2ecf20Sopenharmony_ci
2558c2ecf20Sopenharmony_cistatic const struct rproc_ops adsp_ops = {
2568c2ecf20Sopenharmony_ci	.start = adsp_start,
2578c2ecf20Sopenharmony_ci	.stop = adsp_stop,
2588c2ecf20Sopenharmony_ci	.da_to_va = adsp_da_to_va,
2598c2ecf20Sopenharmony_ci	.parse_fw = qcom_register_dump_segments,
2608c2ecf20Sopenharmony_ci	.load = adsp_load,
2618c2ecf20Sopenharmony_ci	.panic = adsp_panic,
2628c2ecf20Sopenharmony_ci};
2638c2ecf20Sopenharmony_ci
2648c2ecf20Sopenharmony_cistatic int adsp_init_clock(struct qcom_adsp *adsp)
2658c2ecf20Sopenharmony_ci{
2668c2ecf20Sopenharmony_ci	int ret;
2678c2ecf20Sopenharmony_ci
2688c2ecf20Sopenharmony_ci	adsp->xo = devm_clk_get(adsp->dev, "xo");
2698c2ecf20Sopenharmony_ci	if (IS_ERR(adsp->xo)) {
2708c2ecf20Sopenharmony_ci		ret = PTR_ERR(adsp->xo);
2718c2ecf20Sopenharmony_ci		if (ret != -EPROBE_DEFER)
2728c2ecf20Sopenharmony_ci			dev_err(adsp->dev, "failed to get xo clock");
2738c2ecf20Sopenharmony_ci		return ret;
2748c2ecf20Sopenharmony_ci	}
2758c2ecf20Sopenharmony_ci
2768c2ecf20Sopenharmony_ci	if (adsp->has_aggre2_clk) {
2778c2ecf20Sopenharmony_ci		adsp->aggre2_clk = devm_clk_get(adsp->dev, "aggre2");
2788c2ecf20Sopenharmony_ci		if (IS_ERR(adsp->aggre2_clk)) {
2798c2ecf20Sopenharmony_ci			ret = PTR_ERR(adsp->aggre2_clk);
2808c2ecf20Sopenharmony_ci			if (ret != -EPROBE_DEFER)
2818c2ecf20Sopenharmony_ci				dev_err(adsp->dev,
2828c2ecf20Sopenharmony_ci					"failed to get aggre2 clock");
2838c2ecf20Sopenharmony_ci			return ret;
2848c2ecf20Sopenharmony_ci		}
2858c2ecf20Sopenharmony_ci	}
2868c2ecf20Sopenharmony_ci
2878c2ecf20Sopenharmony_ci	return 0;
2888c2ecf20Sopenharmony_ci}
2898c2ecf20Sopenharmony_ci
2908c2ecf20Sopenharmony_cistatic int adsp_init_regulator(struct qcom_adsp *adsp)
2918c2ecf20Sopenharmony_ci{
2928c2ecf20Sopenharmony_ci	adsp->cx_supply = devm_regulator_get(adsp->dev, "cx");
2938c2ecf20Sopenharmony_ci	if (IS_ERR(adsp->cx_supply))
2948c2ecf20Sopenharmony_ci		return PTR_ERR(adsp->cx_supply);
2958c2ecf20Sopenharmony_ci
2968c2ecf20Sopenharmony_ci	regulator_set_load(adsp->cx_supply, 100000);
2978c2ecf20Sopenharmony_ci
2988c2ecf20Sopenharmony_ci	adsp->px_supply = devm_regulator_get(adsp->dev, "px");
2998c2ecf20Sopenharmony_ci	return PTR_ERR_OR_ZERO(adsp->px_supply);
3008c2ecf20Sopenharmony_ci}
3018c2ecf20Sopenharmony_ci
3028c2ecf20Sopenharmony_cistatic int adsp_pds_attach(struct device *dev, struct device **devs,
3038c2ecf20Sopenharmony_ci			   char **pd_names)
3048c2ecf20Sopenharmony_ci{
3058c2ecf20Sopenharmony_ci	size_t num_pds = 0;
3068c2ecf20Sopenharmony_ci	int ret;
3078c2ecf20Sopenharmony_ci	int i;
3088c2ecf20Sopenharmony_ci
3098c2ecf20Sopenharmony_ci	if (!pd_names)
3108c2ecf20Sopenharmony_ci		return 0;
3118c2ecf20Sopenharmony_ci
3128c2ecf20Sopenharmony_ci	/* Handle single power domain */
3138c2ecf20Sopenharmony_ci	if (dev->pm_domain) {
3148c2ecf20Sopenharmony_ci		devs[0] = dev;
3158c2ecf20Sopenharmony_ci		pm_runtime_enable(dev);
3168c2ecf20Sopenharmony_ci		return 1;
3178c2ecf20Sopenharmony_ci	}
3188c2ecf20Sopenharmony_ci
3198c2ecf20Sopenharmony_ci	while (pd_names[num_pds])
3208c2ecf20Sopenharmony_ci		num_pds++;
3218c2ecf20Sopenharmony_ci
3228c2ecf20Sopenharmony_ci	for (i = 0; i < num_pds; i++) {
3238c2ecf20Sopenharmony_ci		devs[i] = dev_pm_domain_attach_by_name(dev, pd_names[i]);
3248c2ecf20Sopenharmony_ci		if (IS_ERR_OR_NULL(devs[i])) {
3258c2ecf20Sopenharmony_ci			ret = PTR_ERR(devs[i]) ? : -ENODATA;
3268c2ecf20Sopenharmony_ci			goto unroll_attach;
3278c2ecf20Sopenharmony_ci		}
3288c2ecf20Sopenharmony_ci	}
3298c2ecf20Sopenharmony_ci
3308c2ecf20Sopenharmony_ci	return num_pds;
3318c2ecf20Sopenharmony_ci
3328c2ecf20Sopenharmony_ciunroll_attach:
3338c2ecf20Sopenharmony_ci	for (i--; i >= 0; i--)
3348c2ecf20Sopenharmony_ci		dev_pm_domain_detach(devs[i], false);
3358c2ecf20Sopenharmony_ci
3368c2ecf20Sopenharmony_ci	return ret;
3378c2ecf20Sopenharmony_ci};
3388c2ecf20Sopenharmony_ci
3398c2ecf20Sopenharmony_cistatic void adsp_pds_detach(struct qcom_adsp *adsp, struct device **pds,
3408c2ecf20Sopenharmony_ci			    size_t pd_count)
3418c2ecf20Sopenharmony_ci{
3428c2ecf20Sopenharmony_ci	struct device *dev = adsp->dev;
3438c2ecf20Sopenharmony_ci	int i;
3448c2ecf20Sopenharmony_ci
3458c2ecf20Sopenharmony_ci	/* Handle single power domain */
3468c2ecf20Sopenharmony_ci	if (dev->pm_domain && pd_count) {
3478c2ecf20Sopenharmony_ci		pm_runtime_disable(dev);
3488c2ecf20Sopenharmony_ci		return;
3498c2ecf20Sopenharmony_ci	}
3508c2ecf20Sopenharmony_ci
3518c2ecf20Sopenharmony_ci	for (i = 0; i < pd_count; i++)
3528c2ecf20Sopenharmony_ci		dev_pm_domain_detach(pds[i], false);
3538c2ecf20Sopenharmony_ci}
3548c2ecf20Sopenharmony_ci
3558c2ecf20Sopenharmony_cistatic int adsp_alloc_memory_region(struct qcom_adsp *adsp)
3568c2ecf20Sopenharmony_ci{
3578c2ecf20Sopenharmony_ci	struct device_node *node;
3588c2ecf20Sopenharmony_ci	struct resource r;
3598c2ecf20Sopenharmony_ci	int ret;
3608c2ecf20Sopenharmony_ci
3618c2ecf20Sopenharmony_ci	node = of_parse_phandle(adsp->dev->of_node, "memory-region", 0);
3628c2ecf20Sopenharmony_ci	if (!node) {
3638c2ecf20Sopenharmony_ci		dev_err(adsp->dev, "no memory-region specified\n");
3648c2ecf20Sopenharmony_ci		return -EINVAL;
3658c2ecf20Sopenharmony_ci	}
3668c2ecf20Sopenharmony_ci
3678c2ecf20Sopenharmony_ci	ret = of_address_to_resource(node, 0, &r);
3688c2ecf20Sopenharmony_ci	of_node_put(node);
3698c2ecf20Sopenharmony_ci	if (ret)
3708c2ecf20Sopenharmony_ci		return ret;
3718c2ecf20Sopenharmony_ci
3728c2ecf20Sopenharmony_ci	adsp->mem_phys = adsp->mem_reloc = r.start;
3738c2ecf20Sopenharmony_ci	adsp->mem_size = resource_size(&r);
3748c2ecf20Sopenharmony_ci	adsp->mem_region = devm_ioremap_wc(adsp->dev, adsp->mem_phys, adsp->mem_size);
3758c2ecf20Sopenharmony_ci	if (!adsp->mem_region) {
3768c2ecf20Sopenharmony_ci		dev_err(adsp->dev, "unable to map memory region: %pa+%zx\n",
3778c2ecf20Sopenharmony_ci			&r.start, adsp->mem_size);
3788c2ecf20Sopenharmony_ci		return -EBUSY;
3798c2ecf20Sopenharmony_ci	}
3808c2ecf20Sopenharmony_ci
3818c2ecf20Sopenharmony_ci	return 0;
3828c2ecf20Sopenharmony_ci}
3838c2ecf20Sopenharmony_ci
3848c2ecf20Sopenharmony_cistatic int adsp_probe(struct platform_device *pdev)
3858c2ecf20Sopenharmony_ci{
3868c2ecf20Sopenharmony_ci	const struct adsp_data *desc;
3878c2ecf20Sopenharmony_ci	struct qcom_adsp *adsp;
3888c2ecf20Sopenharmony_ci	struct rproc *rproc;
3898c2ecf20Sopenharmony_ci	const char *fw_name;
3908c2ecf20Sopenharmony_ci	int ret;
3918c2ecf20Sopenharmony_ci
3928c2ecf20Sopenharmony_ci	desc = of_device_get_match_data(&pdev->dev);
3938c2ecf20Sopenharmony_ci	if (!desc)
3948c2ecf20Sopenharmony_ci		return -EINVAL;
3958c2ecf20Sopenharmony_ci
3968c2ecf20Sopenharmony_ci	if (!qcom_scm_is_available())
3978c2ecf20Sopenharmony_ci		return -EPROBE_DEFER;
3988c2ecf20Sopenharmony_ci
3998c2ecf20Sopenharmony_ci	fw_name = desc->firmware_name;
4008c2ecf20Sopenharmony_ci	ret = of_property_read_string(pdev->dev.of_node, "firmware-name",
4018c2ecf20Sopenharmony_ci				      &fw_name);
4028c2ecf20Sopenharmony_ci	if (ret < 0 && ret != -EINVAL)
4038c2ecf20Sopenharmony_ci		return ret;
4048c2ecf20Sopenharmony_ci
4058c2ecf20Sopenharmony_ci	rproc = rproc_alloc(&pdev->dev, pdev->name, &adsp_ops,
4068c2ecf20Sopenharmony_ci			    fw_name, sizeof(*adsp));
4078c2ecf20Sopenharmony_ci	if (!rproc) {
4088c2ecf20Sopenharmony_ci		dev_err(&pdev->dev, "unable to allocate remoteproc\n");
4098c2ecf20Sopenharmony_ci		return -ENOMEM;
4108c2ecf20Sopenharmony_ci	}
4118c2ecf20Sopenharmony_ci
4128c2ecf20Sopenharmony_ci	rproc->auto_boot = desc->auto_boot;
4138c2ecf20Sopenharmony_ci	rproc_coredump_set_elf_info(rproc, ELFCLASS32, EM_NONE);
4148c2ecf20Sopenharmony_ci
4158c2ecf20Sopenharmony_ci	adsp = (struct qcom_adsp *)rproc->priv;
4168c2ecf20Sopenharmony_ci	adsp->dev = &pdev->dev;
4178c2ecf20Sopenharmony_ci	adsp->rproc = rproc;
4188c2ecf20Sopenharmony_ci	adsp->pas_id = desc->pas_id;
4198c2ecf20Sopenharmony_ci	adsp->has_aggre2_clk = desc->has_aggre2_clk;
4208c2ecf20Sopenharmony_ci	adsp->info_name = desc->sysmon_name;
4218c2ecf20Sopenharmony_ci	platform_set_drvdata(pdev, adsp);
4228c2ecf20Sopenharmony_ci
4238c2ecf20Sopenharmony_ci	device_wakeup_enable(adsp->dev);
4248c2ecf20Sopenharmony_ci
4258c2ecf20Sopenharmony_ci	ret = adsp_alloc_memory_region(adsp);
4268c2ecf20Sopenharmony_ci	if (ret)
4278c2ecf20Sopenharmony_ci		goto free_rproc;
4288c2ecf20Sopenharmony_ci
4298c2ecf20Sopenharmony_ci	ret = adsp_init_clock(adsp);
4308c2ecf20Sopenharmony_ci	if (ret)
4318c2ecf20Sopenharmony_ci		goto free_rproc;
4328c2ecf20Sopenharmony_ci
4338c2ecf20Sopenharmony_ci	ret = adsp_init_regulator(adsp);
4348c2ecf20Sopenharmony_ci	if (ret)
4358c2ecf20Sopenharmony_ci		goto free_rproc;
4368c2ecf20Sopenharmony_ci
4378c2ecf20Sopenharmony_ci	ret = adsp_pds_attach(&pdev->dev, adsp->active_pds,
4388c2ecf20Sopenharmony_ci			      desc->active_pd_names);
4398c2ecf20Sopenharmony_ci	if (ret < 0)
4408c2ecf20Sopenharmony_ci		goto free_rproc;
4418c2ecf20Sopenharmony_ci	adsp->active_pd_count = ret;
4428c2ecf20Sopenharmony_ci
4438c2ecf20Sopenharmony_ci	ret = adsp_pds_attach(&pdev->dev, adsp->proxy_pds,
4448c2ecf20Sopenharmony_ci			      desc->proxy_pd_names);
4458c2ecf20Sopenharmony_ci	if (ret < 0)
4468c2ecf20Sopenharmony_ci		goto detach_active_pds;
4478c2ecf20Sopenharmony_ci	adsp->proxy_pd_count = ret;
4488c2ecf20Sopenharmony_ci
4498c2ecf20Sopenharmony_ci	ret = qcom_q6v5_init(&adsp->q6v5, pdev, rproc, desc->crash_reason_smem,
4508c2ecf20Sopenharmony_ci			     qcom_pas_handover);
4518c2ecf20Sopenharmony_ci	if (ret)
4528c2ecf20Sopenharmony_ci		goto detach_proxy_pds;
4538c2ecf20Sopenharmony_ci
4548c2ecf20Sopenharmony_ci	qcom_add_glink_subdev(rproc, &adsp->glink_subdev, desc->ssr_name);
4558c2ecf20Sopenharmony_ci	qcom_add_smd_subdev(rproc, &adsp->smd_subdev);
4568c2ecf20Sopenharmony_ci	qcom_add_ssr_subdev(rproc, &adsp->ssr_subdev, desc->ssr_name);
4578c2ecf20Sopenharmony_ci	adsp->sysmon = qcom_add_sysmon_subdev(rproc,
4588c2ecf20Sopenharmony_ci					      desc->sysmon_name,
4598c2ecf20Sopenharmony_ci					      desc->ssctl_id);
4608c2ecf20Sopenharmony_ci	if (IS_ERR(adsp->sysmon)) {
4618c2ecf20Sopenharmony_ci		ret = PTR_ERR(adsp->sysmon);
4628c2ecf20Sopenharmony_ci		goto detach_proxy_pds;
4638c2ecf20Sopenharmony_ci	}
4648c2ecf20Sopenharmony_ci
4658c2ecf20Sopenharmony_ci	ret = rproc_add(rproc);
4668c2ecf20Sopenharmony_ci	if (ret)
4678c2ecf20Sopenharmony_ci		goto detach_proxy_pds;
4688c2ecf20Sopenharmony_ci
4698c2ecf20Sopenharmony_ci	return 0;
4708c2ecf20Sopenharmony_ci
4718c2ecf20Sopenharmony_cidetach_proxy_pds:
4728c2ecf20Sopenharmony_ci	adsp_pds_detach(adsp, adsp->proxy_pds, adsp->proxy_pd_count);
4738c2ecf20Sopenharmony_cidetach_active_pds:
4748c2ecf20Sopenharmony_ci	adsp_pds_detach(adsp, adsp->active_pds, adsp->active_pd_count);
4758c2ecf20Sopenharmony_cifree_rproc:
4768c2ecf20Sopenharmony_ci	device_init_wakeup(adsp->dev, false);
4778c2ecf20Sopenharmony_ci	rproc_free(rproc);
4788c2ecf20Sopenharmony_ci
4798c2ecf20Sopenharmony_ci	return ret;
4808c2ecf20Sopenharmony_ci}
4818c2ecf20Sopenharmony_ci
4828c2ecf20Sopenharmony_cistatic int adsp_remove(struct platform_device *pdev)
4838c2ecf20Sopenharmony_ci{
4848c2ecf20Sopenharmony_ci	struct qcom_adsp *adsp = platform_get_drvdata(pdev);
4858c2ecf20Sopenharmony_ci
4868c2ecf20Sopenharmony_ci	rproc_del(adsp->rproc);
4878c2ecf20Sopenharmony_ci
4888c2ecf20Sopenharmony_ci	qcom_remove_glink_subdev(adsp->rproc, &adsp->glink_subdev);
4898c2ecf20Sopenharmony_ci	qcom_remove_sysmon_subdev(adsp->sysmon);
4908c2ecf20Sopenharmony_ci	qcom_remove_smd_subdev(adsp->rproc, &adsp->smd_subdev);
4918c2ecf20Sopenharmony_ci	qcom_remove_ssr_subdev(adsp->rproc, &adsp->ssr_subdev);
4928c2ecf20Sopenharmony_ci	adsp_pds_detach(adsp, adsp->proxy_pds, adsp->proxy_pd_count);
4938c2ecf20Sopenharmony_ci	device_init_wakeup(adsp->dev, false);
4948c2ecf20Sopenharmony_ci	rproc_free(adsp->rproc);
4958c2ecf20Sopenharmony_ci
4968c2ecf20Sopenharmony_ci	return 0;
4978c2ecf20Sopenharmony_ci}
4988c2ecf20Sopenharmony_ci
4998c2ecf20Sopenharmony_cistatic const struct adsp_data adsp_resource_init = {
5008c2ecf20Sopenharmony_ci		.crash_reason_smem = 423,
5018c2ecf20Sopenharmony_ci		.firmware_name = "adsp.mdt",
5028c2ecf20Sopenharmony_ci		.pas_id = 1,
5038c2ecf20Sopenharmony_ci		.has_aggre2_clk = false,
5048c2ecf20Sopenharmony_ci		.auto_boot = true,
5058c2ecf20Sopenharmony_ci		.ssr_name = "lpass",
5068c2ecf20Sopenharmony_ci		.sysmon_name = "adsp",
5078c2ecf20Sopenharmony_ci		.ssctl_id = 0x14,
5088c2ecf20Sopenharmony_ci};
5098c2ecf20Sopenharmony_ci
5108c2ecf20Sopenharmony_cistatic const struct adsp_data sm8150_adsp_resource = {
5118c2ecf20Sopenharmony_ci		.crash_reason_smem = 423,
5128c2ecf20Sopenharmony_ci		.firmware_name = "adsp.mdt",
5138c2ecf20Sopenharmony_ci		.pas_id = 1,
5148c2ecf20Sopenharmony_ci		.has_aggre2_clk = false,
5158c2ecf20Sopenharmony_ci		.auto_boot = true,
5168c2ecf20Sopenharmony_ci		.active_pd_names = (char*[]){
5178c2ecf20Sopenharmony_ci			"load_state",
5188c2ecf20Sopenharmony_ci			NULL
5198c2ecf20Sopenharmony_ci		},
5208c2ecf20Sopenharmony_ci		.proxy_pd_names = (char*[]){
5218c2ecf20Sopenharmony_ci			"cx",
5228c2ecf20Sopenharmony_ci			NULL
5238c2ecf20Sopenharmony_ci		},
5248c2ecf20Sopenharmony_ci		.ssr_name = "lpass",
5258c2ecf20Sopenharmony_ci		.sysmon_name = "adsp",
5268c2ecf20Sopenharmony_ci		.ssctl_id = 0x14,
5278c2ecf20Sopenharmony_ci};
5288c2ecf20Sopenharmony_ci
5298c2ecf20Sopenharmony_cistatic const struct adsp_data sm8250_adsp_resource = {
5308c2ecf20Sopenharmony_ci	.crash_reason_smem = 423,
5318c2ecf20Sopenharmony_ci	.firmware_name = "adsp.mdt",
5328c2ecf20Sopenharmony_ci	.pas_id = 1,
5338c2ecf20Sopenharmony_ci	.has_aggre2_clk = false,
5348c2ecf20Sopenharmony_ci	.auto_boot = true,
5358c2ecf20Sopenharmony_ci	.active_pd_names = (char*[]){
5368c2ecf20Sopenharmony_ci		"load_state",
5378c2ecf20Sopenharmony_ci		NULL
5388c2ecf20Sopenharmony_ci	},
5398c2ecf20Sopenharmony_ci	.proxy_pd_names = (char*[]){
5408c2ecf20Sopenharmony_ci		"lcx",
5418c2ecf20Sopenharmony_ci		"lmx",
5428c2ecf20Sopenharmony_ci		NULL
5438c2ecf20Sopenharmony_ci	},
5448c2ecf20Sopenharmony_ci	.ssr_name = "lpass",
5458c2ecf20Sopenharmony_ci	.sysmon_name = "adsp",
5468c2ecf20Sopenharmony_ci	.ssctl_id = 0x14,
5478c2ecf20Sopenharmony_ci};
5488c2ecf20Sopenharmony_ci
5498c2ecf20Sopenharmony_cistatic const struct adsp_data msm8998_adsp_resource = {
5508c2ecf20Sopenharmony_ci		.crash_reason_smem = 423,
5518c2ecf20Sopenharmony_ci		.firmware_name = "adsp.mdt",
5528c2ecf20Sopenharmony_ci		.pas_id = 1,
5538c2ecf20Sopenharmony_ci		.has_aggre2_clk = false,
5548c2ecf20Sopenharmony_ci		.auto_boot = true,
5558c2ecf20Sopenharmony_ci		.proxy_pd_names = (char*[]){
5568c2ecf20Sopenharmony_ci			"cx",
5578c2ecf20Sopenharmony_ci			NULL
5588c2ecf20Sopenharmony_ci		},
5598c2ecf20Sopenharmony_ci		.ssr_name = "lpass",
5608c2ecf20Sopenharmony_ci		.sysmon_name = "adsp",
5618c2ecf20Sopenharmony_ci		.ssctl_id = 0x14,
5628c2ecf20Sopenharmony_ci};
5638c2ecf20Sopenharmony_ci
5648c2ecf20Sopenharmony_cistatic const struct adsp_data cdsp_resource_init = {
5658c2ecf20Sopenharmony_ci	.crash_reason_smem = 601,
5668c2ecf20Sopenharmony_ci	.firmware_name = "cdsp.mdt",
5678c2ecf20Sopenharmony_ci	.pas_id = 18,
5688c2ecf20Sopenharmony_ci	.has_aggre2_clk = false,
5698c2ecf20Sopenharmony_ci	.auto_boot = true,
5708c2ecf20Sopenharmony_ci	.ssr_name = "cdsp",
5718c2ecf20Sopenharmony_ci	.sysmon_name = "cdsp",
5728c2ecf20Sopenharmony_ci	.ssctl_id = 0x17,
5738c2ecf20Sopenharmony_ci};
5748c2ecf20Sopenharmony_ci
5758c2ecf20Sopenharmony_cistatic const struct adsp_data sm8150_cdsp_resource = {
5768c2ecf20Sopenharmony_ci	.crash_reason_smem = 601,
5778c2ecf20Sopenharmony_ci	.firmware_name = "cdsp.mdt",
5788c2ecf20Sopenharmony_ci	.pas_id = 18,
5798c2ecf20Sopenharmony_ci	.has_aggre2_clk = false,
5808c2ecf20Sopenharmony_ci	.auto_boot = true,
5818c2ecf20Sopenharmony_ci	.active_pd_names = (char*[]){
5828c2ecf20Sopenharmony_ci		"load_state",
5838c2ecf20Sopenharmony_ci		NULL
5848c2ecf20Sopenharmony_ci	},
5858c2ecf20Sopenharmony_ci	.proxy_pd_names = (char*[]){
5868c2ecf20Sopenharmony_ci		"cx",
5878c2ecf20Sopenharmony_ci		NULL
5888c2ecf20Sopenharmony_ci	},
5898c2ecf20Sopenharmony_ci	.ssr_name = "cdsp",
5908c2ecf20Sopenharmony_ci	.sysmon_name = "cdsp",
5918c2ecf20Sopenharmony_ci	.ssctl_id = 0x17,
5928c2ecf20Sopenharmony_ci};
5938c2ecf20Sopenharmony_ci
5948c2ecf20Sopenharmony_cistatic const struct adsp_data sm8250_cdsp_resource = {
5958c2ecf20Sopenharmony_ci	.crash_reason_smem = 601,
5968c2ecf20Sopenharmony_ci	.firmware_name = "cdsp.mdt",
5978c2ecf20Sopenharmony_ci	.pas_id = 18,
5988c2ecf20Sopenharmony_ci	.has_aggre2_clk = false,
5998c2ecf20Sopenharmony_ci	.auto_boot = true,
6008c2ecf20Sopenharmony_ci	.active_pd_names = (char*[]){
6018c2ecf20Sopenharmony_ci		"load_state",
6028c2ecf20Sopenharmony_ci		NULL
6038c2ecf20Sopenharmony_ci	},
6048c2ecf20Sopenharmony_ci	.proxy_pd_names = (char*[]){
6058c2ecf20Sopenharmony_ci		"cx",
6068c2ecf20Sopenharmony_ci		NULL
6078c2ecf20Sopenharmony_ci	},
6088c2ecf20Sopenharmony_ci	.ssr_name = "cdsp",
6098c2ecf20Sopenharmony_ci	.sysmon_name = "cdsp",
6108c2ecf20Sopenharmony_ci	.ssctl_id = 0x17,
6118c2ecf20Sopenharmony_ci};
6128c2ecf20Sopenharmony_ci
6138c2ecf20Sopenharmony_cistatic const struct adsp_data mpss_resource_init = {
6148c2ecf20Sopenharmony_ci	.crash_reason_smem = 421,
6158c2ecf20Sopenharmony_ci	.firmware_name = "modem.mdt",
6168c2ecf20Sopenharmony_ci	.pas_id = 4,
6178c2ecf20Sopenharmony_ci	.has_aggre2_clk = false,
6188c2ecf20Sopenharmony_ci	.auto_boot = false,
6198c2ecf20Sopenharmony_ci	.active_pd_names = (char*[]){
6208c2ecf20Sopenharmony_ci		"load_state",
6218c2ecf20Sopenharmony_ci		NULL
6228c2ecf20Sopenharmony_ci	},
6238c2ecf20Sopenharmony_ci	.proxy_pd_names = (char*[]){
6248c2ecf20Sopenharmony_ci		"cx",
6258c2ecf20Sopenharmony_ci		"mss",
6268c2ecf20Sopenharmony_ci		NULL
6278c2ecf20Sopenharmony_ci	},
6288c2ecf20Sopenharmony_ci	.ssr_name = "mpss",
6298c2ecf20Sopenharmony_ci	.sysmon_name = "modem",
6308c2ecf20Sopenharmony_ci	.ssctl_id = 0x12,
6318c2ecf20Sopenharmony_ci};
6328c2ecf20Sopenharmony_ci
6338c2ecf20Sopenharmony_cistatic const struct adsp_data slpi_resource_init = {
6348c2ecf20Sopenharmony_ci		.crash_reason_smem = 424,
6358c2ecf20Sopenharmony_ci		.firmware_name = "slpi.mdt",
6368c2ecf20Sopenharmony_ci		.pas_id = 12,
6378c2ecf20Sopenharmony_ci		.has_aggre2_clk = true,
6388c2ecf20Sopenharmony_ci		.auto_boot = true,
6398c2ecf20Sopenharmony_ci		.ssr_name = "dsps",
6408c2ecf20Sopenharmony_ci		.sysmon_name = "slpi",
6418c2ecf20Sopenharmony_ci		.ssctl_id = 0x16,
6428c2ecf20Sopenharmony_ci};
6438c2ecf20Sopenharmony_ci
6448c2ecf20Sopenharmony_cistatic const struct adsp_data sm8150_slpi_resource = {
6458c2ecf20Sopenharmony_ci		.crash_reason_smem = 424,
6468c2ecf20Sopenharmony_ci		.firmware_name = "slpi.mdt",
6478c2ecf20Sopenharmony_ci		.pas_id = 12,
6488c2ecf20Sopenharmony_ci		.has_aggre2_clk = false,
6498c2ecf20Sopenharmony_ci		.auto_boot = true,
6508c2ecf20Sopenharmony_ci		.active_pd_names = (char*[]){
6518c2ecf20Sopenharmony_ci			"load_state",
6528c2ecf20Sopenharmony_ci			NULL
6538c2ecf20Sopenharmony_ci		},
6548c2ecf20Sopenharmony_ci		.proxy_pd_names = (char*[]){
6558c2ecf20Sopenharmony_ci			"lcx",
6568c2ecf20Sopenharmony_ci			"lmx",
6578c2ecf20Sopenharmony_ci			NULL
6588c2ecf20Sopenharmony_ci		},
6598c2ecf20Sopenharmony_ci		.ssr_name = "dsps",
6608c2ecf20Sopenharmony_ci		.sysmon_name = "slpi",
6618c2ecf20Sopenharmony_ci		.ssctl_id = 0x16,
6628c2ecf20Sopenharmony_ci};
6638c2ecf20Sopenharmony_ci
6648c2ecf20Sopenharmony_cistatic const struct adsp_data sm8250_slpi_resource = {
6658c2ecf20Sopenharmony_ci	.crash_reason_smem = 424,
6668c2ecf20Sopenharmony_ci	.firmware_name = "slpi.mdt",
6678c2ecf20Sopenharmony_ci	.pas_id = 12,
6688c2ecf20Sopenharmony_ci	.has_aggre2_clk = false,
6698c2ecf20Sopenharmony_ci	.auto_boot = true,
6708c2ecf20Sopenharmony_ci	.active_pd_names = (char*[]){
6718c2ecf20Sopenharmony_ci		"load_state",
6728c2ecf20Sopenharmony_ci		NULL
6738c2ecf20Sopenharmony_ci	},
6748c2ecf20Sopenharmony_ci	.proxy_pd_names = (char*[]){
6758c2ecf20Sopenharmony_ci		"lcx",
6768c2ecf20Sopenharmony_ci		"lmx",
6778c2ecf20Sopenharmony_ci		NULL
6788c2ecf20Sopenharmony_ci	},
6798c2ecf20Sopenharmony_ci	.ssr_name = "dsps",
6808c2ecf20Sopenharmony_ci	.sysmon_name = "slpi",
6818c2ecf20Sopenharmony_ci	.ssctl_id = 0x16,
6828c2ecf20Sopenharmony_ci};
6838c2ecf20Sopenharmony_ci
6848c2ecf20Sopenharmony_cistatic const struct adsp_data msm8998_slpi_resource = {
6858c2ecf20Sopenharmony_ci		.crash_reason_smem = 424,
6868c2ecf20Sopenharmony_ci		.firmware_name = "slpi.mdt",
6878c2ecf20Sopenharmony_ci		.pas_id = 12,
6888c2ecf20Sopenharmony_ci		.has_aggre2_clk = true,
6898c2ecf20Sopenharmony_ci		.auto_boot = true,
6908c2ecf20Sopenharmony_ci		.proxy_pd_names = (char*[]){
6918c2ecf20Sopenharmony_ci			"ssc_cx",
6928c2ecf20Sopenharmony_ci			NULL
6938c2ecf20Sopenharmony_ci		},
6948c2ecf20Sopenharmony_ci		.ssr_name = "dsps",
6958c2ecf20Sopenharmony_ci		.sysmon_name = "slpi",
6968c2ecf20Sopenharmony_ci		.ssctl_id = 0x16,
6978c2ecf20Sopenharmony_ci};
6988c2ecf20Sopenharmony_ci
6998c2ecf20Sopenharmony_cistatic const struct adsp_data wcss_resource_init = {
7008c2ecf20Sopenharmony_ci	.crash_reason_smem = 421,
7018c2ecf20Sopenharmony_ci	.firmware_name = "wcnss.mdt",
7028c2ecf20Sopenharmony_ci	.pas_id = 6,
7038c2ecf20Sopenharmony_ci	.auto_boot = true,
7048c2ecf20Sopenharmony_ci	.ssr_name = "mpss",
7058c2ecf20Sopenharmony_ci	.sysmon_name = "wcnss",
7068c2ecf20Sopenharmony_ci	.ssctl_id = 0x12,
7078c2ecf20Sopenharmony_ci};
7088c2ecf20Sopenharmony_ci
7098c2ecf20Sopenharmony_cistatic const struct of_device_id adsp_of_match[] = {
7108c2ecf20Sopenharmony_ci	{ .compatible = "qcom,msm8974-adsp-pil", .data = &adsp_resource_init},
7118c2ecf20Sopenharmony_ci	{ .compatible = "qcom,msm8996-adsp-pil", .data = &adsp_resource_init},
7128c2ecf20Sopenharmony_ci	{ .compatible = "qcom,msm8996-slpi-pil", .data = &slpi_resource_init},
7138c2ecf20Sopenharmony_ci	{ .compatible = "qcom,msm8998-adsp-pas", .data = &msm8998_adsp_resource},
7148c2ecf20Sopenharmony_ci	{ .compatible = "qcom,msm8998-slpi-pas", .data = &msm8998_slpi_resource},
7158c2ecf20Sopenharmony_ci	{ .compatible = "qcom,qcs404-adsp-pas", .data = &adsp_resource_init },
7168c2ecf20Sopenharmony_ci	{ .compatible = "qcom,qcs404-cdsp-pas", .data = &cdsp_resource_init },
7178c2ecf20Sopenharmony_ci	{ .compatible = "qcom,qcs404-wcss-pas", .data = &wcss_resource_init },
7188c2ecf20Sopenharmony_ci	{ .compatible = "qcom,sc7180-mpss-pas", .data = &mpss_resource_init},
7198c2ecf20Sopenharmony_ci	{ .compatible = "qcom,sdm845-adsp-pas", .data = &adsp_resource_init},
7208c2ecf20Sopenharmony_ci	{ .compatible = "qcom,sdm845-cdsp-pas", .data = &cdsp_resource_init},
7218c2ecf20Sopenharmony_ci	{ .compatible = "qcom,sm8150-adsp-pas", .data = &sm8150_adsp_resource},
7228c2ecf20Sopenharmony_ci	{ .compatible = "qcom,sm8150-cdsp-pas", .data = &sm8150_cdsp_resource},
7238c2ecf20Sopenharmony_ci	{ .compatible = "qcom,sm8150-mpss-pas", .data = &mpss_resource_init},
7248c2ecf20Sopenharmony_ci	{ .compatible = "qcom,sm8150-slpi-pas", .data = &sm8150_slpi_resource},
7258c2ecf20Sopenharmony_ci	{ .compatible = "qcom,sm8250-adsp-pas", .data = &sm8250_adsp_resource},
7268c2ecf20Sopenharmony_ci	{ .compatible = "qcom,sm8250-cdsp-pas", .data = &sm8250_cdsp_resource},
7278c2ecf20Sopenharmony_ci	{ .compatible = "qcom,sm8250-slpi-pas", .data = &sm8250_slpi_resource},
7288c2ecf20Sopenharmony_ci	{ },
7298c2ecf20Sopenharmony_ci};
7308c2ecf20Sopenharmony_ciMODULE_DEVICE_TABLE(of, adsp_of_match);
7318c2ecf20Sopenharmony_ci
7328c2ecf20Sopenharmony_cistatic struct platform_driver adsp_driver = {
7338c2ecf20Sopenharmony_ci	.probe = adsp_probe,
7348c2ecf20Sopenharmony_ci	.remove = adsp_remove,
7358c2ecf20Sopenharmony_ci	.driver = {
7368c2ecf20Sopenharmony_ci		.name = "qcom_q6v5_pas",
7378c2ecf20Sopenharmony_ci		.of_match_table = adsp_of_match,
7388c2ecf20Sopenharmony_ci	},
7398c2ecf20Sopenharmony_ci};
7408c2ecf20Sopenharmony_ci
7418c2ecf20Sopenharmony_cimodule_platform_driver(adsp_driver);
7428c2ecf20Sopenharmony_ciMODULE_DESCRIPTION("Qualcomm Hexagon v5 Peripheral Authentication Service driver");
7438c2ecf20Sopenharmony_ciMODULE_LICENSE("GPL v2");
744