Linux Audio

Check our new training course

Loading...
v6.13.7
   1// SPDX-License-Identifier: GPL-2.0-only
   2/*
   3 * Qualcomm ADSP/SLPI Peripheral Image Loader for MSM8974 and MSM8996
   4 *
   5 * Copyright (C) 2016 Linaro Ltd
   6 * Copyright (C) 2014 Sony Mobile Communications AB
   7 * Copyright (c) 2012-2013, The Linux Foundation. All rights reserved.
   8 */
   9
  10#include <linux/clk.h>
  11#include <linux/delay.h>
  12#include <linux/firmware.h>
  13#include <linux/interrupt.h>
  14#include <linux/kernel.h>
  15#include <linux/module.h>
  16#include <linux/of.h>
  17#include <linux/of_address.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/firmware/qcom/qcom_scm.h>
  23#include <linux/regulator/consumer.h>
  24#include <linux/remoteproc.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#define ADSP_DECRYPT_SHUTDOWN_DELAY_MS	100
  35
  36#define MAX_ASSIGN_COUNT 3
  37
  38struct adsp_data {
  39	int crash_reason_smem;
  40	const char *firmware_name;
  41	const char *dtb_firmware_name;
  42	int pas_id;
  43	int dtb_pas_id;
  44	int lite_pas_id;
  45	unsigned int minidump_id;
  46	bool auto_boot;
  47	bool decrypt_shutdown;
  48
  49	char **proxy_pd_names;
  50
  51	const char *load_state;
  52	const char *ssr_name;
  53	const char *sysmon_name;
  54	int ssctl_id;
  55	unsigned int smem_host_id;
  56
  57	int region_assign_idx;
  58	int region_assign_count;
  59	bool region_assign_shared;
  60	int region_assign_vmid;
  61};
  62
  63struct qcom_adsp {
  64	struct device *dev;
  65	struct rproc *rproc;
  66
  67	struct qcom_q6v5 q6v5;
  68
  69	struct clk *xo;
  70	struct clk *aggre2_clk;
  71
  72	struct regulator *cx_supply;
  73	struct regulator *px_supply;
  74
  75	struct device *proxy_pds[3];
  76
  77	int proxy_pd_count;
  78
  79	const char *dtb_firmware_name;
  80	int pas_id;
  81	int dtb_pas_id;
  82	int lite_pas_id;
  83	unsigned int minidump_id;
  84	int crash_reason_smem;
  85	unsigned int smem_host_id;
  86	bool decrypt_shutdown;
  87	const char *info_name;
  88
  89	const struct firmware *firmware;
  90	const struct firmware *dtb_firmware;
  91
  92	struct completion start_done;
  93	struct completion stop_done;
  94
  95	phys_addr_t mem_phys;
  96	phys_addr_t dtb_mem_phys;
  97	phys_addr_t mem_reloc;
  98	phys_addr_t dtb_mem_reloc;
  99	phys_addr_t region_assign_phys[MAX_ASSIGN_COUNT];
 100	void *mem_region;
 101	void *dtb_mem_region;
 102	size_t mem_size;
 103	size_t dtb_mem_size;
 104	size_t region_assign_size[MAX_ASSIGN_COUNT];
 105
 106	int region_assign_idx;
 107	int region_assign_count;
 108	bool region_assign_shared;
 109	int region_assign_vmid;
 110	u64 region_assign_owners[MAX_ASSIGN_COUNT];
 111
 112	struct qcom_rproc_glink glink_subdev;
 113	struct qcom_rproc_subdev smd_subdev;
 114	struct qcom_rproc_pdm pdm_subdev;
 115	struct qcom_rproc_ssr ssr_subdev;
 116	struct qcom_sysmon *sysmon;
 117
 118	struct qcom_scm_pas_metadata pas_metadata;
 119	struct qcom_scm_pas_metadata dtb_pas_metadata;
 120};
 121
 122static void adsp_segment_dump(struct rproc *rproc, struct rproc_dump_segment *segment,
 123		       void *dest, size_t offset, size_t size)
 124{
 125	struct qcom_adsp *adsp = rproc->priv;
 126	int total_offset;
 127
 128	total_offset = segment->da + segment->offset + offset - adsp->mem_phys;
 129	if (total_offset < 0 || total_offset + size > adsp->mem_size) {
 130		dev_err(adsp->dev,
 131			"invalid copy request for segment %pad with offset %zu and size %zu)\n",
 132			&segment->da, offset, size);
 133		memset(dest, 0xff, size);
 134		return;
 135	}
 136
 137	memcpy_fromio(dest, adsp->mem_region + total_offset, size);
 138}
 139
 140static void adsp_minidump(struct rproc *rproc)
 141{
 142	struct qcom_adsp *adsp = rproc->priv;
 143
 144	if (rproc->dump_conf == RPROC_COREDUMP_DISABLED)
 145		return;
 146
 147	qcom_minidump(rproc, adsp->minidump_id, adsp_segment_dump);
 148}
 149
 150static int adsp_pds_enable(struct qcom_adsp *adsp, struct device **pds,
 151			   size_t pd_count)
 152{
 153	int ret;
 154	int i;
 155
 156	for (i = 0; i < pd_count; i++) {
 157		dev_pm_genpd_set_performance_state(pds[i], INT_MAX);
 158		ret = pm_runtime_get_sync(pds[i]);
 159		if (ret < 0) {
 160			pm_runtime_put_noidle(pds[i]);
 161			dev_pm_genpd_set_performance_state(pds[i], 0);
 162			goto unroll_pd_votes;
 163		}
 164	}
 165
 166	return 0;
 167
 168unroll_pd_votes:
 169	for (i--; i >= 0; i--) {
 170		dev_pm_genpd_set_performance_state(pds[i], 0);
 171		pm_runtime_put(pds[i]);
 172	}
 173
 174	return ret;
 175};
 176
 177static void adsp_pds_disable(struct qcom_adsp *adsp, struct device **pds,
 178			     size_t pd_count)
 179{
 180	int i;
 181
 182	for (i = 0; i < pd_count; i++) {
 183		dev_pm_genpd_set_performance_state(pds[i], 0);
 184		pm_runtime_put(pds[i]);
 185	}
 186}
 187
 188static int adsp_shutdown_poll_decrypt(struct qcom_adsp *adsp)
 189{
 190	unsigned int retry_num = 50;
 191	int ret;
 192
 193	do {
 194		msleep(ADSP_DECRYPT_SHUTDOWN_DELAY_MS);
 195		ret = qcom_scm_pas_shutdown(adsp->pas_id);
 196	} while (ret == -EINVAL && --retry_num);
 197
 198	return ret;
 199}
 200
 201static int adsp_unprepare(struct rproc *rproc)
 202{
 203	struct qcom_adsp *adsp = rproc->priv;
 204
 205	/*
 206	 * adsp_load() did pass pas_metadata to the SCM driver for storing
 207	 * metadata context. It might have been released already if
 208	 * auth_and_reset() was successful, but in other cases clean it up
 209	 * here.
 210	 */
 211	qcom_scm_pas_metadata_release(&adsp->pas_metadata);
 212	if (adsp->dtb_pas_id)
 213		qcom_scm_pas_metadata_release(&adsp->dtb_pas_metadata);
 214
 215	return 0;
 216}
 217
 218static int adsp_load(struct rproc *rproc, const struct firmware *fw)
 219{
 220	struct qcom_adsp *adsp = rproc->priv;
 221	int ret;
 222
 223	/* Store firmware handle to be used in adsp_start() */
 224	adsp->firmware = fw;
 225
 226	if (adsp->lite_pas_id)
 227		ret = qcom_scm_pas_shutdown(adsp->lite_pas_id);
 228
 229	if (adsp->dtb_pas_id) {
 230		ret = request_firmware(&adsp->dtb_firmware, adsp->dtb_firmware_name, adsp->dev);
 231		if (ret) {
 232			dev_err(adsp->dev, "request_firmware failed for %s: %d\n",
 233				adsp->dtb_firmware_name, ret);
 234			return ret;
 235		}
 236
 237		ret = qcom_mdt_pas_init(adsp->dev, adsp->dtb_firmware, adsp->dtb_firmware_name,
 238					adsp->dtb_pas_id, adsp->dtb_mem_phys,
 239					&adsp->dtb_pas_metadata);
 240		if (ret)
 241			goto release_dtb_firmware;
 242
 243		ret = qcom_mdt_load_no_init(adsp->dev, adsp->dtb_firmware, adsp->dtb_firmware_name,
 244					    adsp->dtb_pas_id, adsp->dtb_mem_region,
 245					    adsp->dtb_mem_phys, adsp->dtb_mem_size,
 246					    &adsp->dtb_mem_reloc);
 247		if (ret)
 248			goto release_dtb_metadata;
 249	}
 250
 251	return 0;
 252
 253release_dtb_metadata:
 254	qcom_scm_pas_metadata_release(&adsp->dtb_pas_metadata);
 255
 256release_dtb_firmware:
 257	release_firmware(adsp->dtb_firmware);
 258
 259	return ret;
 260}
 261
 262static int adsp_start(struct rproc *rproc)
 263{
 264	struct qcom_adsp *adsp = rproc->priv;
 265	int ret;
 266
 267	ret = qcom_q6v5_prepare(&adsp->q6v5);
 268	if (ret)
 269		return ret;
 270
 271	ret = adsp_pds_enable(adsp, adsp->proxy_pds, adsp->proxy_pd_count);
 272	if (ret < 0)
 273		goto disable_irqs;
 274
 275	ret = clk_prepare_enable(adsp->xo);
 276	if (ret)
 277		goto disable_proxy_pds;
 278
 279	ret = clk_prepare_enable(adsp->aggre2_clk);
 280	if (ret)
 281		goto disable_xo_clk;
 282
 283	if (adsp->cx_supply) {
 284		ret = regulator_enable(adsp->cx_supply);
 285		if (ret)
 286			goto disable_aggre2_clk;
 287	}
 288
 289	if (adsp->px_supply) {
 290		ret = regulator_enable(adsp->px_supply);
 291		if (ret)
 292			goto disable_cx_supply;
 293	}
 294
 295	if (adsp->dtb_pas_id) {
 296		ret = qcom_scm_pas_auth_and_reset(adsp->dtb_pas_id);
 297		if (ret) {
 298			dev_err(adsp->dev,
 299				"failed to authenticate dtb image and release reset\n");
 300			goto disable_px_supply;
 301		}
 302	}
 303
 304	ret = qcom_mdt_pas_init(adsp->dev, adsp->firmware, rproc->firmware, adsp->pas_id,
 305				adsp->mem_phys, &adsp->pas_metadata);
 306	if (ret)
 307		goto disable_px_supply;
 308
 309	ret = qcom_mdt_load_no_init(adsp->dev, adsp->firmware, rproc->firmware, adsp->pas_id,
 310				    adsp->mem_region, adsp->mem_phys, adsp->mem_size,
 311				    &adsp->mem_reloc);
 312	if (ret)
 313		goto release_pas_metadata;
 314
 315	qcom_pil_info_store(adsp->info_name, adsp->mem_phys, adsp->mem_size);
 316
 317	ret = qcom_scm_pas_auth_and_reset(adsp->pas_id);
 318	if (ret) {
 319		dev_err(adsp->dev,
 320			"failed to authenticate image and release reset\n");
 321		goto release_pas_metadata;
 322	}
 323
 324	ret = qcom_q6v5_wait_for_start(&adsp->q6v5, msecs_to_jiffies(5000));
 325	if (ret == -ETIMEDOUT) {
 326		dev_err(adsp->dev, "start timed out\n");
 327		qcom_scm_pas_shutdown(adsp->pas_id);
 328		goto release_pas_metadata;
 329	}
 330
 331	qcom_scm_pas_metadata_release(&adsp->pas_metadata);
 332	if (adsp->dtb_pas_id)
 333		qcom_scm_pas_metadata_release(&adsp->dtb_pas_metadata);
 334
 335	/* Remove pointer to the loaded firmware, only valid in adsp_load() & adsp_start() */
 336	adsp->firmware = NULL;
 337
 338	return 0;
 339
 340release_pas_metadata:
 341	qcom_scm_pas_metadata_release(&adsp->pas_metadata);
 342	if (adsp->dtb_pas_id)
 343		qcom_scm_pas_metadata_release(&adsp->dtb_pas_metadata);
 344disable_px_supply:
 345	if (adsp->px_supply)
 346		regulator_disable(adsp->px_supply);
 347disable_cx_supply:
 348	if (adsp->cx_supply)
 349		regulator_disable(adsp->cx_supply);
 350disable_aggre2_clk:
 351	clk_disable_unprepare(adsp->aggre2_clk);
 352disable_xo_clk:
 353	clk_disable_unprepare(adsp->xo);
 354disable_proxy_pds:
 355	adsp_pds_disable(adsp, adsp->proxy_pds, adsp->proxy_pd_count);
 356disable_irqs:
 357	qcom_q6v5_unprepare(&adsp->q6v5);
 358
 359	/* Remove pointer to the loaded firmware, only valid in adsp_load() & adsp_start() */
 360	adsp->firmware = NULL;
 361
 362	return ret;
 363}
 364
 365static void qcom_pas_handover(struct qcom_q6v5 *q6v5)
 366{
 367	struct qcom_adsp *adsp = container_of(q6v5, struct qcom_adsp, q6v5);
 368
 369	if (adsp->px_supply)
 370		regulator_disable(adsp->px_supply);
 371	if (adsp->cx_supply)
 372		regulator_disable(adsp->cx_supply);
 373	clk_disable_unprepare(adsp->aggre2_clk);
 374	clk_disable_unprepare(adsp->xo);
 375	adsp_pds_disable(adsp, adsp->proxy_pds, adsp->proxy_pd_count);
 376}
 377
 378static int adsp_stop(struct rproc *rproc)
 379{
 380	struct qcom_adsp *adsp = rproc->priv;
 381	int handover;
 382	int ret;
 383
 384	ret = qcom_q6v5_request_stop(&adsp->q6v5, adsp->sysmon);
 385	if (ret == -ETIMEDOUT)
 386		dev_err(adsp->dev, "timed out on wait\n");
 387
 388	ret = qcom_scm_pas_shutdown(adsp->pas_id);
 389	if (ret && adsp->decrypt_shutdown)
 390		ret = adsp_shutdown_poll_decrypt(adsp);
 391
 392	if (ret)
 393		dev_err(adsp->dev, "failed to shutdown: %d\n", ret);
 394
 395	if (adsp->dtb_pas_id) {
 396		ret = qcom_scm_pas_shutdown(adsp->dtb_pas_id);
 397		if (ret)
 398			dev_err(adsp->dev, "failed to shutdown dtb: %d\n", ret);
 399	}
 400
 401	handover = qcom_q6v5_unprepare(&adsp->q6v5);
 402	if (handover)
 403		qcom_pas_handover(&adsp->q6v5);
 404
 405	if (adsp->smem_host_id)
 406		ret = qcom_smem_bust_hwspin_lock_by_host(adsp->smem_host_id);
 407
 408	return ret;
 409}
 410
 411static void *adsp_da_to_va(struct rproc *rproc, u64 da, size_t len, bool *is_iomem)
 412{
 413	struct qcom_adsp *adsp = rproc->priv;
 414	int offset;
 415
 416	offset = da - adsp->mem_reloc;
 417	if (offset < 0 || offset + len > adsp->mem_size)
 418		return NULL;
 419
 420	if (is_iomem)
 421		*is_iomem = true;
 422
 423	return adsp->mem_region + offset;
 424}
 425
 426static unsigned long adsp_panic(struct rproc *rproc)
 427{
 428	struct qcom_adsp *adsp = rproc->priv;
 429
 430	return qcom_q6v5_panic(&adsp->q6v5);
 431}
 432
 433static const struct rproc_ops adsp_ops = {
 434	.unprepare = adsp_unprepare,
 435	.start = adsp_start,
 436	.stop = adsp_stop,
 437	.da_to_va = adsp_da_to_va,
 438	.parse_fw = qcom_register_dump_segments,
 439	.load = adsp_load,
 440	.panic = adsp_panic,
 441};
 442
 443static const struct rproc_ops adsp_minidump_ops = {
 444	.unprepare = adsp_unprepare,
 445	.start = adsp_start,
 446	.stop = adsp_stop,
 447	.da_to_va = adsp_da_to_va,
 448	.parse_fw = qcom_register_dump_segments,
 449	.load = adsp_load,
 450	.panic = adsp_panic,
 451	.coredump = adsp_minidump,
 452};
 453
 454static int adsp_init_clock(struct qcom_adsp *adsp)
 455{
 456	adsp->xo = devm_clk_get(adsp->dev, "xo");
 457	if (IS_ERR(adsp->xo))
 458		return dev_err_probe(adsp->dev, PTR_ERR(adsp->xo),
 459				     "failed to get xo clock");
 460
 
 
 
 
 
 
 
 461
 462	adsp->aggre2_clk = devm_clk_get_optional(adsp->dev, "aggre2");
 463	if (IS_ERR(adsp->aggre2_clk))
 464		return dev_err_probe(adsp->dev, PTR_ERR(adsp->aggre2_clk),
 465				     "failed to get aggre2 clock");
 
 
 
 
 466
 467	return 0;
 468}
 469
 470static int adsp_init_regulator(struct qcom_adsp *adsp)
 471{
 472	adsp->cx_supply = devm_regulator_get_optional(adsp->dev, "cx");
 473	if (IS_ERR(adsp->cx_supply)) {
 474		if (PTR_ERR(adsp->cx_supply) == -ENODEV)
 475			adsp->cx_supply = NULL;
 476		else
 477			return PTR_ERR(adsp->cx_supply);
 478	}
 479
 480	if (adsp->cx_supply)
 481		regulator_set_load(adsp->cx_supply, 100000);
 482
 483	adsp->px_supply = devm_regulator_get_optional(adsp->dev, "px");
 484	if (IS_ERR(adsp->px_supply)) {
 485		if (PTR_ERR(adsp->px_supply) == -ENODEV)
 486			adsp->px_supply = NULL;
 487		else
 488			return PTR_ERR(adsp->px_supply);
 489	}
 490
 491	return 0;
 492}
 493
 494static int adsp_pds_attach(struct device *dev, struct device **devs,
 495			   char **pd_names)
 496{
 497	size_t num_pds = 0;
 498	int ret;
 499	int i;
 500
 501	if (!pd_names)
 502		return 0;
 503
 504	/* Handle single power domain */
 505	if (dev->pm_domain) {
 506		devs[0] = dev;
 507		pm_runtime_enable(dev);
 508		return 1;
 509	}
 510
 511	while (pd_names[num_pds])
 512		num_pds++;
 513
 514	for (i = 0; i < num_pds; i++) {
 515		devs[i] = dev_pm_domain_attach_by_name(dev, pd_names[i]);
 516		if (IS_ERR_OR_NULL(devs[i])) {
 517			ret = PTR_ERR(devs[i]) ? : -ENODATA;
 518			goto unroll_attach;
 519		}
 520	}
 521
 522	return num_pds;
 523
 524unroll_attach:
 525	for (i--; i >= 0; i--)
 526		dev_pm_domain_detach(devs[i], false);
 527
 528	return ret;
 529};
 530
 531static void adsp_pds_detach(struct qcom_adsp *adsp, struct device **pds,
 532			    size_t pd_count)
 533{
 534	struct device *dev = adsp->dev;
 535	int i;
 536
 537	/* Handle single power domain */
 538	if (dev->pm_domain && pd_count) {
 539		pm_runtime_disable(dev);
 540		return;
 541	}
 542
 543	for (i = 0; i < pd_count; i++)
 544		dev_pm_domain_detach(pds[i], false);
 545}
 546
 547static int adsp_alloc_memory_region(struct qcom_adsp *adsp)
 548{
 549	struct reserved_mem *rmem;
 550	struct device_node *node;
 551
 552	node = of_parse_phandle(adsp->dev->of_node, "memory-region", 0);
 553	if (!node) {
 554		dev_err(adsp->dev, "no memory-region specified\n");
 555		return -EINVAL;
 556	}
 557
 558	rmem = of_reserved_mem_lookup(node);
 559	of_node_put(node);
 560	if (!rmem) {
 561		dev_err(adsp->dev, "unable to resolve memory-region\n");
 562		return -EINVAL;
 563	}
 564
 565	adsp->mem_phys = adsp->mem_reloc = rmem->base;
 566	adsp->mem_size = rmem->size;
 567	adsp->mem_region = devm_ioremap_wc(adsp->dev, adsp->mem_phys, adsp->mem_size);
 568	if (!adsp->mem_region) {
 569		dev_err(adsp->dev, "unable to map memory region: %pa+%zx\n",
 570			&rmem->base, adsp->mem_size);
 571		return -EBUSY;
 572	}
 573
 574	if (!adsp->dtb_pas_id)
 575		return 0;
 576
 577	node = of_parse_phandle(adsp->dev->of_node, "memory-region", 1);
 578	if (!node) {
 579		dev_err(adsp->dev, "no dtb memory-region specified\n");
 580		return -EINVAL;
 581	}
 582
 583	rmem = of_reserved_mem_lookup(node);
 584	of_node_put(node);
 585	if (!rmem) {
 586		dev_err(adsp->dev, "unable to resolve dtb memory-region\n");
 587		return -EINVAL;
 588	}
 589
 590	adsp->dtb_mem_phys = adsp->dtb_mem_reloc = rmem->base;
 591	adsp->dtb_mem_size = rmem->size;
 592	adsp->dtb_mem_region = devm_ioremap_wc(adsp->dev, adsp->dtb_mem_phys, adsp->dtb_mem_size);
 593	if (!adsp->dtb_mem_region) {
 594		dev_err(adsp->dev, "unable to map dtb memory region: %pa+%zx\n",
 595			&rmem->base, adsp->dtb_mem_size);
 596		return -EBUSY;
 597	}
 598
 599	return 0;
 600}
 601
 602static int adsp_assign_memory_region(struct qcom_adsp *adsp)
 603{
 604	struct qcom_scm_vmperm perm[MAX_ASSIGN_COUNT];
 
 605	struct device_node *node;
 606	unsigned int perm_size;
 607	int offset;
 608	int ret;
 609
 610	if (!adsp->region_assign_idx)
 611		return 0;
 612
 613	for (offset = 0; offset < adsp->region_assign_count; ++offset) {
 614		struct reserved_mem *rmem = NULL;
 615
 616		node = of_parse_phandle(adsp->dev->of_node, "memory-region",
 617					adsp->region_assign_idx + offset);
 618		if (node)
 619			rmem = of_reserved_mem_lookup(node);
 620		of_node_put(node);
 621		if (!rmem) {
 622			dev_err(adsp->dev, "unable to resolve shareable memory-region index %d\n",
 623				offset);
 624			return -EINVAL;
 625		}
 626
 627		if (adsp->region_assign_shared)  {
 628			perm[0].vmid = QCOM_SCM_VMID_HLOS;
 629			perm[0].perm = QCOM_SCM_PERM_RW;
 630			perm[1].vmid = adsp->region_assign_vmid;
 631			perm[1].perm = QCOM_SCM_PERM_RW;
 632			perm_size = 2;
 633		} else {
 634			perm[0].vmid = adsp->region_assign_vmid;
 635			perm[0].perm = QCOM_SCM_PERM_RW;
 636			perm_size = 1;
 637		}
 638
 639		adsp->region_assign_phys[offset] = rmem->base;
 640		adsp->region_assign_size[offset] = rmem->size;
 641		adsp->region_assign_owners[offset] = BIT(QCOM_SCM_VMID_HLOS);
 642
 643		ret = qcom_scm_assign_mem(adsp->region_assign_phys[offset],
 644					  adsp->region_assign_size[offset],
 645					  &adsp->region_assign_owners[offset],
 646					  perm, perm_size);
 647		if (ret < 0) {
 648			dev_err(adsp->dev, "assign memory %d failed\n", offset);
 649			return ret;
 650		}
 651	}
 652
 653	return 0;
 654}
 655
 656static void adsp_unassign_memory_region(struct qcom_adsp *adsp)
 657{
 658	struct qcom_scm_vmperm perm;
 659	int offset;
 660	int ret;
 661
 662	if (!adsp->region_assign_idx || adsp->region_assign_shared)
 663		return;
 664
 665	for (offset = 0; offset < adsp->region_assign_count; ++offset) {
 666		perm.vmid = QCOM_SCM_VMID_HLOS;
 667		perm.perm = QCOM_SCM_PERM_RW;
 668
 669		ret = qcom_scm_assign_mem(adsp->region_assign_phys[offset],
 670					  adsp->region_assign_size[offset],
 671					  &adsp->region_assign_owners[offset],
 672					  &perm, 1);
 673		if (ret < 0)
 674			dev_err(adsp->dev, "unassign memory %d failed\n", offset);
 675	}
 676}
 677
 678static int adsp_probe(struct platform_device *pdev)
 679{
 680	const struct adsp_data *desc;
 681	struct qcom_adsp *adsp;
 682	struct rproc *rproc;
 683	const char *fw_name, *dtb_fw_name = NULL;
 684	const struct rproc_ops *ops = &adsp_ops;
 685	int ret;
 686
 687	desc = of_device_get_match_data(&pdev->dev);
 688	if (!desc)
 689		return -EINVAL;
 690
 691	if (!qcom_scm_is_available())
 692		return -EPROBE_DEFER;
 693
 694	fw_name = desc->firmware_name;
 695	ret = of_property_read_string(pdev->dev.of_node, "firmware-name",
 696				      &fw_name);
 697	if (ret < 0 && ret != -EINVAL)
 698		return ret;
 699
 700	if (desc->dtb_firmware_name) {
 701		dtb_fw_name = desc->dtb_firmware_name;
 702		ret = of_property_read_string_index(pdev->dev.of_node, "firmware-name", 1,
 703						    &dtb_fw_name);
 704		if (ret < 0 && ret != -EINVAL)
 705			return ret;
 706	}
 707
 708	if (desc->minidump_id)
 709		ops = &adsp_minidump_ops;
 710
 711	rproc = devm_rproc_alloc(&pdev->dev, desc->sysmon_name, ops, fw_name, sizeof(*adsp));
 712
 713	if (!rproc) {
 714		dev_err(&pdev->dev, "unable to allocate remoteproc\n");
 715		return -ENOMEM;
 716	}
 717
 718	rproc->auto_boot = desc->auto_boot;
 719	rproc_coredump_set_elf_info(rproc, ELFCLASS32, EM_NONE);
 720
 721	adsp = rproc->priv;
 722	adsp->dev = &pdev->dev;
 723	adsp->rproc = rproc;
 724	adsp->minidump_id = desc->minidump_id;
 725	adsp->pas_id = desc->pas_id;
 726	adsp->lite_pas_id = desc->lite_pas_id;
 727	adsp->info_name = desc->sysmon_name;
 728	adsp->smem_host_id = desc->smem_host_id;
 729	adsp->decrypt_shutdown = desc->decrypt_shutdown;
 730	adsp->region_assign_idx = desc->region_assign_idx;
 731	adsp->region_assign_count = min_t(int, MAX_ASSIGN_COUNT, desc->region_assign_count);
 732	adsp->region_assign_vmid = desc->region_assign_vmid;
 733	adsp->region_assign_shared = desc->region_assign_shared;
 734	if (dtb_fw_name) {
 735		adsp->dtb_firmware_name = dtb_fw_name;
 736		adsp->dtb_pas_id = desc->dtb_pas_id;
 737	}
 738	platform_set_drvdata(pdev, adsp);
 739
 740	ret = device_init_wakeup(adsp->dev, true);
 741	if (ret)
 742		goto free_rproc;
 743
 744	ret = adsp_alloc_memory_region(adsp);
 745	if (ret)
 746		goto free_rproc;
 747
 748	ret = adsp_assign_memory_region(adsp);
 749	if (ret)
 750		goto free_rproc;
 751
 752	ret = adsp_init_clock(adsp);
 753	if (ret)
 754		goto unassign_mem;
 755
 756	ret = adsp_init_regulator(adsp);
 757	if (ret)
 758		goto unassign_mem;
 759
 760	ret = adsp_pds_attach(&pdev->dev, adsp->proxy_pds,
 761			      desc->proxy_pd_names);
 762	if (ret < 0)
 763		goto unassign_mem;
 764	adsp->proxy_pd_count = ret;
 765
 766	ret = qcom_q6v5_init(&adsp->q6v5, pdev, rproc, desc->crash_reason_smem, desc->load_state,
 767			     qcom_pas_handover);
 768	if (ret)
 769		goto detach_proxy_pds;
 770
 771	qcom_add_glink_subdev(rproc, &adsp->glink_subdev, desc->ssr_name);
 772	qcom_add_smd_subdev(rproc, &adsp->smd_subdev);
 773	qcom_add_pdm_subdev(rproc, &adsp->pdm_subdev);
 774	adsp->sysmon = qcom_add_sysmon_subdev(rproc,
 775					      desc->sysmon_name,
 776					      desc->ssctl_id);
 777	if (IS_ERR(adsp->sysmon)) {
 778		ret = PTR_ERR(adsp->sysmon);
 779		goto deinit_remove_pdm_smd_glink;
 780	}
 781
 782	qcom_add_ssr_subdev(rproc, &adsp->ssr_subdev, desc->ssr_name);
 783	ret = rproc_add(rproc);
 784	if (ret)
 785		goto remove_ssr_sysmon;
 786
 787	return 0;
 788
 789remove_ssr_sysmon:
 790	qcom_remove_ssr_subdev(rproc, &adsp->ssr_subdev);
 791	qcom_remove_sysmon_subdev(adsp->sysmon);
 792deinit_remove_pdm_smd_glink:
 793	qcom_remove_pdm_subdev(rproc, &adsp->pdm_subdev);
 794	qcom_remove_smd_subdev(rproc, &adsp->smd_subdev);
 795	qcom_remove_glink_subdev(rproc, &adsp->glink_subdev);
 796	qcom_q6v5_deinit(&adsp->q6v5);
 797detach_proxy_pds:
 798	adsp_pds_detach(adsp, adsp->proxy_pds, adsp->proxy_pd_count);
 799unassign_mem:
 800	adsp_unassign_memory_region(adsp);
 801free_rproc:
 802	device_init_wakeup(adsp->dev, false);
 
 803
 804	return ret;
 805}
 806
 807static void adsp_remove(struct platform_device *pdev)
 808{
 809	struct qcom_adsp *adsp = platform_get_drvdata(pdev);
 810
 811	rproc_del(adsp->rproc);
 812
 813	qcom_q6v5_deinit(&adsp->q6v5);
 814	adsp_unassign_memory_region(adsp);
 815	qcom_remove_glink_subdev(adsp->rproc, &adsp->glink_subdev);
 816	qcom_remove_sysmon_subdev(adsp->sysmon);
 817	qcom_remove_smd_subdev(adsp->rproc, &adsp->smd_subdev);
 818	qcom_remove_pdm_subdev(adsp->rproc, &adsp->pdm_subdev);
 819	qcom_remove_ssr_subdev(adsp->rproc, &adsp->ssr_subdev);
 820	adsp_pds_detach(adsp, adsp->proxy_pds, adsp->proxy_pd_count);
 821	device_init_wakeup(adsp->dev, false);
 
 822}
 823
 824static const struct adsp_data adsp_resource_init = {
 825	.crash_reason_smem = 423,
 826	.firmware_name = "adsp.mdt",
 827	.pas_id = 1,
 828	.auto_boot = true,
 829	.ssr_name = "lpass",
 830	.sysmon_name = "adsp",
 831	.ssctl_id = 0x14,
 832};
 833
 834static const struct adsp_data sa8775p_adsp_resource = {
 835	.crash_reason_smem = 423,
 836	.firmware_name = "adsp.mbn",
 837	.pas_id = 1,
 838	.minidump_id = 5,
 839	.auto_boot = true,
 840	.proxy_pd_names = (char*[]){
 841		"lcx",
 842		"lmx",
 843		NULL
 844	},
 845	.load_state = "adsp",
 846	.ssr_name = "lpass",
 847	.sysmon_name = "adsp",
 848	.ssctl_id = 0x14,
 849};
 850
 851static const struct adsp_data sdm845_adsp_resource_init = {
 852	.crash_reason_smem = 423,
 853	.firmware_name = "adsp.mdt",
 854	.pas_id = 1,
 855	.auto_boot = true,
 856	.load_state = "adsp",
 857	.ssr_name = "lpass",
 858	.sysmon_name = "adsp",
 859	.ssctl_id = 0x14,
 860};
 861
 862static const struct adsp_data sm6350_adsp_resource = {
 863	.crash_reason_smem = 423,
 864	.firmware_name = "adsp.mdt",
 865	.pas_id = 1,
 866	.auto_boot = true,
 867	.proxy_pd_names = (char*[]){
 868		"lcx",
 869		"lmx",
 870		NULL
 871	},
 872	.load_state = "adsp",
 873	.ssr_name = "lpass",
 874	.sysmon_name = "adsp",
 875	.ssctl_id = 0x14,
 876};
 877
 878static const struct adsp_data sm6375_mpss_resource = {
 879	.crash_reason_smem = 421,
 880	.firmware_name = "modem.mdt",
 881	.pas_id = 4,
 882	.minidump_id = 3,
 883	.auto_boot = false,
 884	.proxy_pd_names = (char*[]){
 885		"cx",
 886		NULL
 887	},
 888	.ssr_name = "mpss",
 889	.sysmon_name = "modem",
 890	.ssctl_id = 0x12,
 891};
 892
 893static const struct adsp_data sm8150_adsp_resource = {
 894	.crash_reason_smem = 423,
 895	.firmware_name = "adsp.mdt",
 896	.pas_id = 1,
 897	.auto_boot = true,
 898	.proxy_pd_names = (char*[]){
 899		"cx",
 900		NULL
 901	},
 902	.load_state = "adsp",
 903	.ssr_name = "lpass",
 904	.sysmon_name = "adsp",
 905	.ssctl_id = 0x14,
 906};
 907
 908static const struct adsp_data sm8250_adsp_resource = {
 909	.crash_reason_smem = 423,
 910	.firmware_name = "adsp.mdt",
 911	.pas_id = 1,
 912	.minidump_id = 5,
 913	.auto_boot = true,
 914	.proxy_pd_names = (char*[]){
 915		"lcx",
 916		"lmx",
 917		NULL
 918	},
 919	.load_state = "adsp",
 920	.ssr_name = "lpass",
 921	.sysmon_name = "adsp",
 922	.ssctl_id = 0x14,
 923};
 924
 925static const struct adsp_data sm8350_adsp_resource = {
 926	.crash_reason_smem = 423,
 927	.firmware_name = "adsp.mdt",
 928	.pas_id = 1,
 929	.auto_boot = true,
 930	.proxy_pd_names = (char*[]){
 931		"lcx",
 932		"lmx",
 933		NULL
 934	},
 935	.load_state = "adsp",
 936	.ssr_name = "lpass",
 937	.sysmon_name = "adsp",
 938	.ssctl_id = 0x14,
 939};
 940
 941static const struct adsp_data msm8996_adsp_resource = {
 942	.crash_reason_smem = 423,
 943	.firmware_name = "adsp.mdt",
 944	.pas_id = 1,
 945	.auto_boot = true,
 946	.proxy_pd_names = (char*[]){
 947		"cx",
 948		NULL
 949	},
 950	.ssr_name = "lpass",
 951	.sysmon_name = "adsp",
 952	.ssctl_id = 0x14,
 953};
 954
 955static const struct adsp_data cdsp_resource_init = {
 956	.crash_reason_smem = 601,
 957	.firmware_name = "cdsp.mdt",
 958	.pas_id = 18,
 959	.auto_boot = true,
 960	.ssr_name = "cdsp",
 961	.sysmon_name = "cdsp",
 962	.ssctl_id = 0x17,
 963};
 964
 965static const struct adsp_data sa8775p_cdsp0_resource = {
 966	.crash_reason_smem = 601,
 967	.firmware_name = "cdsp0.mbn",
 968	.pas_id = 18,
 969	.minidump_id = 7,
 970	.auto_boot = true,
 971	.proxy_pd_names = (char*[]){
 972		"cx",
 973		"mxc",
 974		"nsp",
 975		NULL
 976	},
 977	.load_state = "cdsp",
 978	.ssr_name = "cdsp",
 979	.sysmon_name = "cdsp",
 980	.ssctl_id = 0x17,
 981};
 982
 983static const struct adsp_data sa8775p_cdsp1_resource = {
 984	.crash_reason_smem = 633,
 985	.firmware_name = "cdsp1.mbn",
 986	.pas_id = 30,
 987	.minidump_id = 20,
 988	.auto_boot = true,
 989	.proxy_pd_names = (char*[]){
 990		"cx",
 991		"mxc",
 992		"nsp",
 993		NULL
 994	},
 995	.load_state = "nsp",
 996	.ssr_name = "cdsp1",
 997	.sysmon_name = "cdsp1",
 998	.ssctl_id = 0x20,
 999};
1000
1001static const struct adsp_data sdm845_cdsp_resource_init = {
1002	.crash_reason_smem = 601,
1003	.firmware_name = "cdsp.mdt",
1004	.pas_id = 18,
1005	.auto_boot = true,
1006	.load_state = "cdsp",
1007	.ssr_name = "cdsp",
1008	.sysmon_name = "cdsp",
1009	.ssctl_id = 0x17,
1010};
1011
1012static const struct adsp_data sm6350_cdsp_resource = {
1013	.crash_reason_smem = 601,
1014	.firmware_name = "cdsp.mdt",
1015	.pas_id = 18,
1016	.auto_boot = true,
1017	.proxy_pd_names = (char*[]){
1018		"cx",
1019		"mx",
1020		NULL
1021	},
1022	.load_state = "cdsp",
1023	.ssr_name = "cdsp",
1024	.sysmon_name = "cdsp",
1025	.ssctl_id = 0x17,
1026};
1027
1028static const struct adsp_data sm8150_cdsp_resource = {
1029	.crash_reason_smem = 601,
1030	.firmware_name = "cdsp.mdt",
1031	.pas_id = 18,
1032	.auto_boot = true,
1033	.proxy_pd_names = (char*[]){
1034		"cx",
1035		NULL
1036	},
1037	.load_state = "cdsp",
1038	.ssr_name = "cdsp",
1039	.sysmon_name = "cdsp",
1040	.ssctl_id = 0x17,
1041};
1042
1043static const struct adsp_data sm8250_cdsp_resource = {
1044	.crash_reason_smem = 601,
1045	.firmware_name = "cdsp.mdt",
1046	.pas_id = 18,
1047	.auto_boot = true,
1048	.proxy_pd_names = (char*[]){
1049		"cx",
1050		NULL
1051	},
1052	.load_state = "cdsp",
1053	.ssr_name = "cdsp",
1054	.sysmon_name = "cdsp",
1055	.ssctl_id = 0x17,
1056};
1057
1058static const struct adsp_data sc8280xp_nsp0_resource = {
1059	.crash_reason_smem = 601,
1060	.firmware_name = "cdsp.mdt",
1061	.pas_id = 18,
1062	.auto_boot = true,
1063	.proxy_pd_names = (char*[]){
1064		"nsp",
1065		NULL
1066	},
1067	.ssr_name = "cdsp0",
1068	.sysmon_name = "cdsp",
1069	.ssctl_id = 0x17,
1070};
1071
1072static const struct adsp_data sc8280xp_nsp1_resource = {
1073	.crash_reason_smem = 633,
1074	.firmware_name = "cdsp.mdt",
1075	.pas_id = 30,
1076	.auto_boot = true,
1077	.proxy_pd_names = (char*[]){
1078		"nsp",
1079		NULL
1080	},
1081	.ssr_name = "cdsp1",
1082	.sysmon_name = "cdsp1",
1083	.ssctl_id = 0x20,
1084};
1085
1086static const struct adsp_data x1e80100_adsp_resource = {
1087	.crash_reason_smem = 423,
1088	.firmware_name = "adsp.mdt",
1089	.dtb_firmware_name = "adsp_dtb.mdt",
1090	.pas_id = 1,
1091	.dtb_pas_id = 0x24,
1092	.lite_pas_id = 0x1f,
1093	.minidump_id = 5,
1094	.auto_boot = true,
1095	.proxy_pd_names = (char*[]){
1096		"lcx",
1097		"lmx",
1098		NULL
1099	},
1100	.load_state = "adsp",
1101	.ssr_name = "lpass",
1102	.sysmon_name = "adsp",
1103	.ssctl_id = 0x14,
1104};
1105
1106static const struct adsp_data x1e80100_cdsp_resource = {
1107	.crash_reason_smem = 601,
1108	.firmware_name = "cdsp.mdt",
1109	.dtb_firmware_name = "cdsp_dtb.mdt",
1110	.pas_id = 18,
1111	.dtb_pas_id = 0x25,
1112	.minidump_id = 7,
1113	.auto_boot = true,
1114	.proxy_pd_names = (char*[]){
1115		"cx",
1116		"mxc",
1117		"nsp",
1118		NULL
1119	},
1120	.load_state = "cdsp",
1121	.ssr_name = "cdsp",
1122	.sysmon_name = "cdsp",
1123	.ssctl_id = 0x17,
1124};
1125
1126static const struct adsp_data sm8350_cdsp_resource = {
1127	.crash_reason_smem = 601,
1128	.firmware_name = "cdsp.mdt",
1129	.pas_id = 18,
1130	.minidump_id = 7,
1131	.auto_boot = true,
1132	.proxy_pd_names = (char*[]){
1133		"cx",
1134		"mxc",
1135		NULL
1136	},
1137	.load_state = "cdsp",
1138	.ssr_name = "cdsp",
1139	.sysmon_name = "cdsp",
1140	.ssctl_id = 0x17,
1141};
1142
1143static const struct adsp_data sa8775p_gpdsp0_resource = {
1144	.crash_reason_smem = 640,
1145	.firmware_name = "gpdsp0.mbn",
1146	.pas_id = 39,
1147	.minidump_id = 21,
1148	.auto_boot = true,
1149	.proxy_pd_names = (char*[]){
1150		"cx",
1151		"mxc",
1152		NULL
1153	},
1154	.load_state = "gpdsp0",
1155	.ssr_name = "gpdsp0",
1156	.sysmon_name = "gpdsp0",
1157	.ssctl_id = 0x21,
1158};
1159
1160static const struct adsp_data sa8775p_gpdsp1_resource = {
1161	.crash_reason_smem = 641,
1162	.firmware_name = "gpdsp1.mbn",
1163	.pas_id = 40,
1164	.minidump_id = 22,
1165	.auto_boot = true,
1166	.proxy_pd_names = (char*[]){
1167		"cx",
1168		"mxc",
1169		NULL
1170	},
1171	.load_state = "gpdsp1",
1172	.ssr_name = "gpdsp1",
1173	.sysmon_name = "gpdsp1",
1174	.ssctl_id = 0x22,
1175};
1176
1177static const struct adsp_data mpss_resource_init = {
1178	.crash_reason_smem = 421,
1179	.firmware_name = "modem.mdt",
1180	.pas_id = 4,
1181	.minidump_id = 3,
1182	.auto_boot = false,
1183	.proxy_pd_names = (char*[]){
1184		"cx",
1185		"mss",
1186		NULL
1187	},
1188	.load_state = "modem",
1189	.ssr_name = "mpss",
1190	.sysmon_name = "modem",
1191	.ssctl_id = 0x12,
1192};
1193
1194static const struct adsp_data sc8180x_mpss_resource = {
1195	.crash_reason_smem = 421,
1196	.firmware_name = "modem.mdt",
1197	.pas_id = 4,
1198	.auto_boot = false,
1199	.proxy_pd_names = (char*[]){
1200		"cx",
1201		NULL
1202	},
1203	.load_state = "modem",
1204	.ssr_name = "mpss",
1205	.sysmon_name = "modem",
1206	.ssctl_id = 0x12,
1207};
1208
1209static const struct adsp_data msm8996_slpi_resource_init = {
1210	.crash_reason_smem = 424,
1211	.firmware_name = "slpi.mdt",
1212	.pas_id = 12,
1213	.auto_boot = true,
1214	.proxy_pd_names = (char*[]){
1215		"ssc_cx",
1216		NULL
1217	},
1218	.ssr_name = "dsps",
1219	.sysmon_name = "slpi",
1220	.ssctl_id = 0x16,
1221};
1222
1223static const struct adsp_data sdm845_slpi_resource_init = {
1224	.crash_reason_smem = 424,
1225	.firmware_name = "slpi.mdt",
1226	.pas_id = 12,
1227	.auto_boot = true,
1228	.proxy_pd_names = (char*[]){
1229		"lcx",
1230		"lmx",
1231		NULL
1232	},
1233	.load_state = "slpi",
1234	.ssr_name = "dsps",
1235	.sysmon_name = "slpi",
1236	.ssctl_id = 0x16,
1237};
1238
1239static const struct adsp_data wcss_resource_init = {
1240	.crash_reason_smem = 421,
1241	.firmware_name = "wcnss.mdt",
1242	.pas_id = 6,
1243	.auto_boot = true,
1244	.ssr_name = "mpss",
1245	.sysmon_name = "wcnss",
1246	.ssctl_id = 0x12,
1247};
1248
1249static const struct adsp_data sdx55_mpss_resource = {
1250	.crash_reason_smem = 421,
1251	.firmware_name = "modem.mdt",
1252	.pas_id = 4,
1253	.auto_boot = true,
1254	.proxy_pd_names = (char*[]){
1255		"cx",
1256		"mss",
1257		NULL
1258	},
1259	.ssr_name = "mpss",
1260	.sysmon_name = "modem",
1261	.ssctl_id = 0x22,
1262};
1263
1264static const struct adsp_data sm8450_mpss_resource = {
1265	.crash_reason_smem = 421,
1266	.firmware_name = "modem.mdt",
1267	.pas_id = 4,
1268	.minidump_id = 3,
1269	.auto_boot = false,
1270	.decrypt_shutdown = true,
1271	.proxy_pd_names = (char*[]){
1272		"cx",
1273		"mss",
1274		NULL
1275	},
1276	.load_state = "modem",
1277	.ssr_name = "mpss",
1278	.sysmon_name = "modem",
1279	.ssctl_id = 0x12,
1280};
1281
1282static const struct adsp_data sm8550_adsp_resource = {
1283	.crash_reason_smem = 423,
1284	.firmware_name = "adsp.mdt",
1285	.dtb_firmware_name = "adsp_dtb.mdt",
1286	.pas_id = 1,
1287	.dtb_pas_id = 0x24,
1288	.minidump_id = 5,
1289	.auto_boot = true,
1290	.proxy_pd_names = (char*[]){
1291		"lcx",
1292		"lmx",
1293		NULL
1294	},
1295	.load_state = "adsp",
1296	.ssr_name = "lpass",
1297	.sysmon_name = "adsp",
1298	.ssctl_id = 0x14,
1299	.smem_host_id = 2,
1300};
1301
1302static const struct adsp_data sm8550_cdsp_resource = {
1303	.crash_reason_smem = 601,
1304	.firmware_name = "cdsp.mdt",
1305	.dtb_firmware_name = "cdsp_dtb.mdt",
1306	.pas_id = 18,
1307	.dtb_pas_id = 0x25,
1308	.minidump_id = 7,
1309	.auto_boot = true,
1310	.proxy_pd_names = (char*[]){
1311		"cx",
1312		"mxc",
1313		"nsp",
1314		NULL
1315	},
1316	.load_state = "cdsp",
1317	.ssr_name = "cdsp",
1318	.sysmon_name = "cdsp",
1319	.ssctl_id = 0x17,
1320	.smem_host_id = 5,
1321};
1322
1323static const struct adsp_data sm8550_mpss_resource = {
1324	.crash_reason_smem = 421,
1325	.firmware_name = "modem.mdt",
1326	.dtb_firmware_name = "modem_dtb.mdt",
1327	.pas_id = 4,
1328	.dtb_pas_id = 0x26,
1329	.minidump_id = 3,
1330	.auto_boot = false,
1331	.decrypt_shutdown = true,
1332	.proxy_pd_names = (char*[]){
1333		"cx",
1334		"mss",
1335		NULL
1336	},
1337	.load_state = "modem",
1338	.ssr_name = "mpss",
1339	.sysmon_name = "modem",
1340	.ssctl_id = 0x12,
1341	.smem_host_id = 1,
1342	.region_assign_idx = 2,
1343	.region_assign_count = 1,
1344	.region_assign_vmid = QCOM_SCM_VMID_MSS_MSA,
1345};
1346
1347static const struct adsp_data sc7280_wpss_resource = {
1348	.crash_reason_smem = 626,
1349	.firmware_name = "wpss.mdt",
1350	.pas_id = 6,
1351	.auto_boot = false,
1352	.proxy_pd_names = (char*[]){
1353		"cx",
1354		"mx",
1355		NULL
1356	},
1357	.load_state = "wpss",
1358	.ssr_name = "wpss",
1359	.sysmon_name = "wpss",
1360	.ssctl_id = 0x19,
1361};
1362
1363static const struct adsp_data sm8650_cdsp_resource = {
1364	.crash_reason_smem = 601,
1365	.firmware_name = "cdsp.mdt",
1366	.dtb_firmware_name = "cdsp_dtb.mdt",
1367	.pas_id = 18,
1368	.dtb_pas_id = 0x25,
1369	.minidump_id = 7,
1370	.auto_boot = true,
1371	.proxy_pd_names = (char*[]){
1372		"cx",
1373		"mxc",
1374		"nsp",
1375		NULL
1376	},
1377	.load_state = "cdsp",
1378	.ssr_name = "cdsp",
1379	.sysmon_name = "cdsp",
1380	.ssctl_id = 0x17,
1381	.smem_host_id = 5,
1382	.region_assign_idx = 2,
1383	.region_assign_count = 1,
1384	.region_assign_shared = true,
1385	.region_assign_vmid = QCOM_SCM_VMID_CDSP,
1386};
1387
1388static const struct adsp_data sm8650_mpss_resource = {
1389	.crash_reason_smem = 421,
1390	.firmware_name = "modem.mdt",
1391	.dtb_firmware_name = "modem_dtb.mdt",
1392	.pas_id = 4,
1393	.dtb_pas_id = 0x26,
1394	.minidump_id = 3,
1395	.auto_boot = false,
1396	.decrypt_shutdown = true,
1397	.proxy_pd_names = (char*[]){
1398		"cx",
1399		"mss",
1400		NULL
1401	},
1402	.load_state = "modem",
1403	.ssr_name = "mpss",
1404	.sysmon_name = "modem",
1405	.ssctl_id = 0x12,
1406	.smem_host_id = 1,
1407	.region_assign_idx = 2,
1408	.region_assign_count = 3,
1409	.region_assign_vmid = QCOM_SCM_VMID_MSS_MSA,
1410};
1411
1412static const struct of_device_id adsp_of_match[] = {
1413	{ .compatible = "qcom,msm8226-adsp-pil", .data = &adsp_resource_init},
1414	{ .compatible = "qcom,msm8953-adsp-pil", .data = &msm8996_adsp_resource},
1415	{ .compatible = "qcom,msm8974-adsp-pil", .data = &adsp_resource_init},
1416	{ .compatible = "qcom,msm8996-adsp-pil", .data = &msm8996_adsp_resource},
1417	{ .compatible = "qcom,msm8996-slpi-pil", .data = &msm8996_slpi_resource_init},
1418	{ .compatible = "qcom,msm8998-adsp-pas", .data = &msm8996_adsp_resource},
1419	{ .compatible = "qcom,msm8998-slpi-pas", .data = &msm8996_slpi_resource_init},
1420	{ .compatible = "qcom,qcs404-adsp-pas", .data = &adsp_resource_init },
1421	{ .compatible = "qcom,qcs404-cdsp-pas", .data = &cdsp_resource_init },
1422	{ .compatible = "qcom,qcs404-wcss-pas", .data = &wcss_resource_init },
1423	{ .compatible = "qcom,sa8775p-adsp-pas", .data = &sa8775p_adsp_resource},
1424	{ .compatible = "qcom,sa8775p-cdsp0-pas", .data = &sa8775p_cdsp0_resource},
1425	{ .compatible = "qcom,sa8775p-cdsp1-pas", .data = &sa8775p_cdsp1_resource},
1426	{ .compatible = "qcom,sa8775p-gpdsp0-pas", .data = &sa8775p_gpdsp0_resource},
1427	{ .compatible = "qcom,sa8775p-gpdsp1-pas", .data = &sa8775p_gpdsp1_resource},
1428	{ .compatible = "qcom,sar2130p-adsp-pas", .data = &sm8350_adsp_resource},
1429	{ .compatible = "qcom,sc7180-adsp-pas", .data = &sm8250_adsp_resource},
1430	{ .compatible = "qcom,sc7180-mpss-pas", .data = &mpss_resource_init},
1431	{ .compatible = "qcom,sc7280-adsp-pas", .data = &sm8350_adsp_resource},
1432	{ .compatible = "qcom,sc7280-cdsp-pas", .data = &sm6350_cdsp_resource},
1433	{ .compatible = "qcom,sc7280-mpss-pas", .data = &mpss_resource_init},
1434	{ .compatible = "qcom,sc7280-wpss-pas", .data = &sc7280_wpss_resource},
1435	{ .compatible = "qcom,sc8180x-adsp-pas", .data = &sm8150_adsp_resource},
1436	{ .compatible = "qcom,sc8180x-cdsp-pas", .data = &sm8150_cdsp_resource},
1437	{ .compatible = "qcom,sc8180x-mpss-pas", .data = &sc8180x_mpss_resource},
1438	{ .compatible = "qcom,sc8280xp-adsp-pas", .data = &sm8250_adsp_resource},
1439	{ .compatible = "qcom,sc8280xp-nsp0-pas", .data = &sc8280xp_nsp0_resource},
1440	{ .compatible = "qcom,sc8280xp-nsp1-pas", .data = &sc8280xp_nsp1_resource},
1441	{ .compatible = "qcom,sdm660-adsp-pas", .data = &adsp_resource_init},
1442	{ .compatible = "qcom,sdm845-adsp-pas", .data = &sdm845_adsp_resource_init},
1443	{ .compatible = "qcom,sdm845-cdsp-pas", .data = &sdm845_cdsp_resource_init},
1444	{ .compatible = "qcom,sdm845-slpi-pas", .data = &sdm845_slpi_resource_init},
1445	{ .compatible = "qcom,sdx55-mpss-pas", .data = &sdx55_mpss_resource},
1446	{ .compatible = "qcom,sdx75-mpss-pas", .data = &sm8650_mpss_resource},
1447	{ .compatible = "qcom,sm6115-adsp-pas", .data = &adsp_resource_init},
1448	{ .compatible = "qcom,sm6115-cdsp-pas", .data = &cdsp_resource_init},
1449	{ .compatible = "qcom,sm6115-mpss-pas", .data = &sc8180x_mpss_resource},
1450	{ .compatible = "qcom,sm6350-adsp-pas", .data = &sm6350_adsp_resource},
1451	{ .compatible = "qcom,sm6350-cdsp-pas", .data = &sm6350_cdsp_resource},
1452	{ .compatible = "qcom,sm6350-mpss-pas", .data = &mpss_resource_init},
1453	{ .compatible = "qcom,sm6375-adsp-pas", .data = &sm6350_adsp_resource},
1454	{ .compatible = "qcom,sm6375-cdsp-pas", .data = &sm8150_cdsp_resource},
1455	{ .compatible = "qcom,sm6375-mpss-pas", .data = &sm6375_mpss_resource},
1456	{ .compatible = "qcom,sm8150-adsp-pas", .data = &sm8150_adsp_resource},
1457	{ .compatible = "qcom,sm8150-cdsp-pas", .data = &sm8150_cdsp_resource},
1458	{ .compatible = "qcom,sm8150-mpss-pas", .data = &mpss_resource_init},
1459	{ .compatible = "qcom,sm8150-slpi-pas", .data = &sdm845_slpi_resource_init},
1460	{ .compatible = "qcom,sm8250-adsp-pas", .data = &sm8250_adsp_resource},
1461	{ .compatible = "qcom,sm8250-cdsp-pas", .data = &sm8250_cdsp_resource},
1462	{ .compatible = "qcom,sm8250-slpi-pas", .data = &sdm845_slpi_resource_init},
1463	{ .compatible = "qcom,sm8350-adsp-pas", .data = &sm8350_adsp_resource},
1464	{ .compatible = "qcom,sm8350-cdsp-pas", .data = &sm8350_cdsp_resource},
1465	{ .compatible = "qcom,sm8350-slpi-pas", .data = &sdm845_slpi_resource_init},
1466	{ .compatible = "qcom,sm8350-mpss-pas", .data = &mpss_resource_init},
1467	{ .compatible = "qcom,sm8450-adsp-pas", .data = &sm8350_adsp_resource},
1468	{ .compatible = "qcom,sm8450-cdsp-pas", .data = &sm8350_cdsp_resource},
1469	{ .compatible = "qcom,sm8450-slpi-pas", .data = &sdm845_slpi_resource_init},
1470	{ .compatible = "qcom,sm8450-mpss-pas", .data = &sm8450_mpss_resource},
1471	{ .compatible = "qcom,sm8550-adsp-pas", .data = &sm8550_adsp_resource},
1472	{ .compatible = "qcom,sm8550-cdsp-pas", .data = &sm8550_cdsp_resource},
1473	{ .compatible = "qcom,sm8550-mpss-pas", .data = &sm8550_mpss_resource},
1474	{ .compatible = "qcom,sm8650-adsp-pas", .data = &sm8550_adsp_resource},
1475	{ .compatible = "qcom,sm8650-cdsp-pas", .data = &sm8650_cdsp_resource},
1476	{ .compatible = "qcom,sm8650-mpss-pas", .data = &sm8650_mpss_resource},
1477	{ .compatible = "qcom,x1e80100-adsp-pas", .data = &x1e80100_adsp_resource},
1478	{ .compatible = "qcom,x1e80100-cdsp-pas", .data = &x1e80100_cdsp_resource},
1479	{ },
1480};
1481MODULE_DEVICE_TABLE(of, adsp_of_match);
1482
1483static struct platform_driver adsp_driver = {
1484	.probe = adsp_probe,
1485	.remove = adsp_remove,
1486	.driver = {
1487		.name = "qcom_q6v5_pas",
1488		.of_match_table = adsp_of_match,
1489	},
1490};
1491
1492module_platform_driver(adsp_driver);
1493MODULE_DESCRIPTION("Qualcomm Hexagon v5 Peripheral Authentication Service driver");
1494MODULE_LICENSE("GPL v2");
v6.8
   1// SPDX-License-Identifier: GPL-2.0-only
   2/*
   3 * Qualcomm ADSP/SLPI Peripheral Image Loader for MSM8974 and MSM8996
   4 *
   5 * Copyright (C) 2016 Linaro Ltd
   6 * Copyright (C) 2014 Sony Mobile Communications AB
   7 * Copyright (c) 2012-2013, The Linux Foundation. All rights reserved.
   8 */
   9
  10#include <linux/clk.h>
  11#include <linux/delay.h>
  12#include <linux/firmware.h>
  13#include <linux/interrupt.h>
  14#include <linux/kernel.h>
  15#include <linux/module.h>
  16#include <linux/of.h>
  17#include <linux/of_address.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/firmware/qcom/qcom_scm.h>
  23#include <linux/regulator/consumer.h>
  24#include <linux/remoteproc.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#define ADSP_DECRYPT_SHUTDOWN_DELAY_MS	100
  35
 
 
  36struct adsp_data {
  37	int crash_reason_smem;
  38	const char *firmware_name;
  39	const char *dtb_firmware_name;
  40	int pas_id;
  41	int dtb_pas_id;
 
  42	unsigned int minidump_id;
  43	bool auto_boot;
  44	bool decrypt_shutdown;
  45
  46	char **proxy_pd_names;
  47
  48	const char *load_state;
  49	const char *ssr_name;
  50	const char *sysmon_name;
  51	int ssctl_id;
 
  52
  53	int region_assign_idx;
 
 
 
  54};
  55
  56struct qcom_adsp {
  57	struct device *dev;
  58	struct rproc *rproc;
  59
  60	struct qcom_q6v5 q6v5;
  61
  62	struct clk *xo;
  63	struct clk *aggre2_clk;
  64
  65	struct regulator *cx_supply;
  66	struct regulator *px_supply;
  67
  68	struct device *proxy_pds[3];
  69
  70	int proxy_pd_count;
  71
  72	const char *dtb_firmware_name;
  73	int pas_id;
  74	int dtb_pas_id;
 
  75	unsigned int minidump_id;
  76	int crash_reason_smem;
 
  77	bool decrypt_shutdown;
  78	const char *info_name;
  79
  80	const struct firmware *firmware;
  81	const struct firmware *dtb_firmware;
  82
  83	struct completion start_done;
  84	struct completion stop_done;
  85
  86	phys_addr_t mem_phys;
  87	phys_addr_t dtb_mem_phys;
  88	phys_addr_t mem_reloc;
  89	phys_addr_t dtb_mem_reloc;
  90	phys_addr_t region_assign_phys;
  91	void *mem_region;
  92	void *dtb_mem_region;
  93	size_t mem_size;
  94	size_t dtb_mem_size;
  95	size_t region_assign_size;
  96
  97	int region_assign_idx;
  98	u64 region_assign_perms;
 
 
 
  99
 100	struct qcom_rproc_glink glink_subdev;
 101	struct qcom_rproc_subdev smd_subdev;
 
 102	struct qcom_rproc_ssr ssr_subdev;
 103	struct qcom_sysmon *sysmon;
 104
 105	struct qcom_scm_pas_metadata pas_metadata;
 106	struct qcom_scm_pas_metadata dtb_pas_metadata;
 107};
 108
 109static void adsp_segment_dump(struct rproc *rproc, struct rproc_dump_segment *segment,
 110		       void *dest, size_t offset, size_t size)
 111{
 112	struct qcom_adsp *adsp = rproc->priv;
 113	int total_offset;
 114
 115	total_offset = segment->da + segment->offset + offset - adsp->mem_phys;
 116	if (total_offset < 0 || total_offset + size > adsp->mem_size) {
 117		dev_err(adsp->dev,
 118			"invalid copy request for segment %pad with offset %zu and size %zu)\n",
 119			&segment->da, offset, size);
 120		memset(dest, 0xff, size);
 121		return;
 122	}
 123
 124	memcpy_fromio(dest, adsp->mem_region + total_offset, size);
 125}
 126
 127static void adsp_minidump(struct rproc *rproc)
 128{
 129	struct qcom_adsp *adsp = rproc->priv;
 130
 131	if (rproc->dump_conf == RPROC_COREDUMP_DISABLED)
 132		return;
 133
 134	qcom_minidump(rproc, adsp->minidump_id, adsp_segment_dump);
 135}
 136
 137static int adsp_pds_enable(struct qcom_adsp *adsp, struct device **pds,
 138			   size_t pd_count)
 139{
 140	int ret;
 141	int i;
 142
 143	for (i = 0; i < pd_count; i++) {
 144		dev_pm_genpd_set_performance_state(pds[i], INT_MAX);
 145		ret = pm_runtime_get_sync(pds[i]);
 146		if (ret < 0) {
 147			pm_runtime_put_noidle(pds[i]);
 148			dev_pm_genpd_set_performance_state(pds[i], 0);
 149			goto unroll_pd_votes;
 150		}
 151	}
 152
 153	return 0;
 154
 155unroll_pd_votes:
 156	for (i--; i >= 0; i--) {
 157		dev_pm_genpd_set_performance_state(pds[i], 0);
 158		pm_runtime_put(pds[i]);
 159	}
 160
 161	return ret;
 162};
 163
 164static void adsp_pds_disable(struct qcom_adsp *adsp, struct device **pds,
 165			     size_t pd_count)
 166{
 167	int i;
 168
 169	for (i = 0; i < pd_count; i++) {
 170		dev_pm_genpd_set_performance_state(pds[i], 0);
 171		pm_runtime_put(pds[i]);
 172	}
 173}
 174
 175static int adsp_shutdown_poll_decrypt(struct qcom_adsp *adsp)
 176{
 177	unsigned int retry_num = 50;
 178	int ret;
 179
 180	do {
 181		msleep(ADSP_DECRYPT_SHUTDOWN_DELAY_MS);
 182		ret = qcom_scm_pas_shutdown(adsp->pas_id);
 183	} while (ret == -EINVAL && --retry_num);
 184
 185	return ret;
 186}
 187
 188static int adsp_unprepare(struct rproc *rproc)
 189{
 190	struct qcom_adsp *adsp = rproc->priv;
 191
 192	/*
 193	 * adsp_load() did pass pas_metadata to the SCM driver for storing
 194	 * metadata context. It might have been released already if
 195	 * auth_and_reset() was successful, but in other cases clean it up
 196	 * here.
 197	 */
 198	qcom_scm_pas_metadata_release(&adsp->pas_metadata);
 199	if (adsp->dtb_pas_id)
 200		qcom_scm_pas_metadata_release(&adsp->dtb_pas_metadata);
 201
 202	return 0;
 203}
 204
 205static int adsp_load(struct rproc *rproc, const struct firmware *fw)
 206{
 207	struct qcom_adsp *adsp = rproc->priv;
 208	int ret;
 209
 210	/* Store firmware handle to be used in adsp_start() */
 211	adsp->firmware = fw;
 212
 
 
 
 213	if (adsp->dtb_pas_id) {
 214		ret = request_firmware(&adsp->dtb_firmware, adsp->dtb_firmware_name, adsp->dev);
 215		if (ret) {
 216			dev_err(adsp->dev, "request_firmware failed for %s: %d\n",
 217				adsp->dtb_firmware_name, ret);
 218			return ret;
 219		}
 220
 221		ret = qcom_mdt_pas_init(adsp->dev, adsp->dtb_firmware, adsp->dtb_firmware_name,
 222					adsp->dtb_pas_id, adsp->dtb_mem_phys,
 223					&adsp->dtb_pas_metadata);
 224		if (ret)
 225			goto release_dtb_firmware;
 226
 227		ret = qcom_mdt_load_no_init(adsp->dev, adsp->dtb_firmware, adsp->dtb_firmware_name,
 228					    adsp->dtb_pas_id, adsp->dtb_mem_region,
 229					    adsp->dtb_mem_phys, adsp->dtb_mem_size,
 230					    &adsp->dtb_mem_reloc);
 231		if (ret)
 232			goto release_dtb_metadata;
 233	}
 234
 235	return 0;
 236
 237release_dtb_metadata:
 238	qcom_scm_pas_metadata_release(&adsp->dtb_pas_metadata);
 239
 240release_dtb_firmware:
 241	release_firmware(adsp->dtb_firmware);
 242
 243	return ret;
 244}
 245
 246static int adsp_start(struct rproc *rproc)
 247{
 248	struct qcom_adsp *adsp = rproc->priv;
 249	int ret;
 250
 251	ret = qcom_q6v5_prepare(&adsp->q6v5);
 252	if (ret)
 253		return ret;
 254
 255	ret = adsp_pds_enable(adsp, adsp->proxy_pds, adsp->proxy_pd_count);
 256	if (ret < 0)
 257		goto disable_irqs;
 258
 259	ret = clk_prepare_enable(adsp->xo);
 260	if (ret)
 261		goto disable_proxy_pds;
 262
 263	ret = clk_prepare_enable(adsp->aggre2_clk);
 264	if (ret)
 265		goto disable_xo_clk;
 266
 267	if (adsp->cx_supply) {
 268		ret = regulator_enable(adsp->cx_supply);
 269		if (ret)
 270			goto disable_aggre2_clk;
 271	}
 272
 273	if (adsp->px_supply) {
 274		ret = regulator_enable(adsp->px_supply);
 275		if (ret)
 276			goto disable_cx_supply;
 277	}
 278
 279	if (adsp->dtb_pas_id) {
 280		ret = qcom_scm_pas_auth_and_reset(adsp->dtb_pas_id);
 281		if (ret) {
 282			dev_err(adsp->dev,
 283				"failed to authenticate dtb image and release reset\n");
 284			goto disable_px_supply;
 285		}
 286	}
 287
 288	ret = qcom_mdt_pas_init(adsp->dev, adsp->firmware, rproc->firmware, adsp->pas_id,
 289				adsp->mem_phys, &adsp->pas_metadata);
 290	if (ret)
 291		goto disable_px_supply;
 292
 293	ret = qcom_mdt_load_no_init(adsp->dev, adsp->firmware, rproc->firmware, adsp->pas_id,
 294				    adsp->mem_region, adsp->mem_phys, adsp->mem_size,
 295				    &adsp->mem_reloc);
 296	if (ret)
 297		goto release_pas_metadata;
 298
 299	qcom_pil_info_store(adsp->info_name, adsp->mem_phys, adsp->mem_size);
 300
 301	ret = qcom_scm_pas_auth_and_reset(adsp->pas_id);
 302	if (ret) {
 303		dev_err(adsp->dev,
 304			"failed to authenticate image and release reset\n");
 305		goto release_pas_metadata;
 306	}
 307
 308	ret = qcom_q6v5_wait_for_start(&adsp->q6v5, msecs_to_jiffies(5000));
 309	if (ret == -ETIMEDOUT) {
 310		dev_err(adsp->dev, "start timed out\n");
 311		qcom_scm_pas_shutdown(adsp->pas_id);
 312		goto release_pas_metadata;
 313	}
 314
 315	qcom_scm_pas_metadata_release(&adsp->pas_metadata);
 316	if (adsp->dtb_pas_id)
 317		qcom_scm_pas_metadata_release(&adsp->dtb_pas_metadata);
 318
 319	/* Remove pointer to the loaded firmware, only valid in adsp_load() & adsp_start() */
 320	adsp->firmware = NULL;
 321
 322	return 0;
 323
 324release_pas_metadata:
 325	qcom_scm_pas_metadata_release(&adsp->pas_metadata);
 326	if (adsp->dtb_pas_id)
 327		qcom_scm_pas_metadata_release(&adsp->dtb_pas_metadata);
 328disable_px_supply:
 329	if (adsp->px_supply)
 330		regulator_disable(adsp->px_supply);
 331disable_cx_supply:
 332	if (adsp->cx_supply)
 333		regulator_disable(adsp->cx_supply);
 334disable_aggre2_clk:
 335	clk_disable_unprepare(adsp->aggre2_clk);
 336disable_xo_clk:
 337	clk_disable_unprepare(adsp->xo);
 338disable_proxy_pds:
 339	adsp_pds_disable(adsp, adsp->proxy_pds, adsp->proxy_pd_count);
 340disable_irqs:
 341	qcom_q6v5_unprepare(&adsp->q6v5);
 342
 343	/* Remove pointer to the loaded firmware, only valid in adsp_load() & adsp_start() */
 344	adsp->firmware = NULL;
 345
 346	return ret;
 347}
 348
 349static void qcom_pas_handover(struct qcom_q6v5 *q6v5)
 350{
 351	struct qcom_adsp *adsp = container_of(q6v5, struct qcom_adsp, q6v5);
 352
 353	if (adsp->px_supply)
 354		regulator_disable(adsp->px_supply);
 355	if (adsp->cx_supply)
 356		regulator_disable(adsp->cx_supply);
 357	clk_disable_unprepare(adsp->aggre2_clk);
 358	clk_disable_unprepare(adsp->xo);
 359	adsp_pds_disable(adsp, adsp->proxy_pds, adsp->proxy_pd_count);
 360}
 361
 362static int adsp_stop(struct rproc *rproc)
 363{
 364	struct qcom_adsp *adsp = rproc->priv;
 365	int handover;
 366	int ret;
 367
 368	ret = qcom_q6v5_request_stop(&adsp->q6v5, adsp->sysmon);
 369	if (ret == -ETIMEDOUT)
 370		dev_err(adsp->dev, "timed out on wait\n");
 371
 372	ret = qcom_scm_pas_shutdown(adsp->pas_id);
 373	if (ret && adsp->decrypt_shutdown)
 374		ret = adsp_shutdown_poll_decrypt(adsp);
 375
 376	if (ret)
 377		dev_err(adsp->dev, "failed to shutdown: %d\n", ret);
 378
 379	if (adsp->dtb_pas_id) {
 380		ret = qcom_scm_pas_shutdown(adsp->dtb_pas_id);
 381		if (ret)
 382			dev_err(adsp->dev, "failed to shutdown dtb: %d\n", ret);
 383	}
 384
 385	handover = qcom_q6v5_unprepare(&adsp->q6v5);
 386	if (handover)
 387		qcom_pas_handover(&adsp->q6v5);
 388
 
 
 
 389	return ret;
 390}
 391
 392static void *adsp_da_to_va(struct rproc *rproc, u64 da, size_t len, bool *is_iomem)
 393{
 394	struct qcom_adsp *adsp = rproc->priv;
 395	int offset;
 396
 397	offset = da - adsp->mem_reloc;
 398	if (offset < 0 || offset + len > adsp->mem_size)
 399		return NULL;
 400
 401	if (is_iomem)
 402		*is_iomem = true;
 403
 404	return adsp->mem_region + offset;
 405}
 406
 407static unsigned long adsp_panic(struct rproc *rproc)
 408{
 409	struct qcom_adsp *adsp = rproc->priv;
 410
 411	return qcom_q6v5_panic(&adsp->q6v5);
 412}
 413
 414static const struct rproc_ops adsp_ops = {
 415	.unprepare = adsp_unprepare,
 416	.start = adsp_start,
 417	.stop = adsp_stop,
 418	.da_to_va = adsp_da_to_va,
 419	.parse_fw = qcom_register_dump_segments,
 420	.load = adsp_load,
 421	.panic = adsp_panic,
 422};
 423
 424static const struct rproc_ops adsp_minidump_ops = {
 425	.unprepare = adsp_unprepare,
 426	.start = adsp_start,
 427	.stop = adsp_stop,
 428	.da_to_va = adsp_da_to_va,
 429	.parse_fw = qcom_register_dump_segments,
 430	.load = adsp_load,
 431	.panic = adsp_panic,
 432	.coredump = adsp_minidump,
 433};
 434
 435static int adsp_init_clock(struct qcom_adsp *adsp)
 436{
 437	int ret;
 
 
 
 438
 439	adsp->xo = devm_clk_get(adsp->dev, "xo");
 440	if (IS_ERR(adsp->xo)) {
 441		ret = PTR_ERR(adsp->xo);
 442		if (ret != -EPROBE_DEFER)
 443			dev_err(adsp->dev, "failed to get xo clock");
 444		return ret;
 445	}
 446
 447	adsp->aggre2_clk = devm_clk_get_optional(adsp->dev, "aggre2");
 448	if (IS_ERR(adsp->aggre2_clk)) {
 449		ret = PTR_ERR(adsp->aggre2_clk);
 450		if (ret != -EPROBE_DEFER)
 451			dev_err(adsp->dev,
 452				"failed to get aggre2 clock");
 453		return ret;
 454	}
 455
 456	return 0;
 457}
 458
 459static int adsp_init_regulator(struct qcom_adsp *adsp)
 460{
 461	adsp->cx_supply = devm_regulator_get_optional(adsp->dev, "cx");
 462	if (IS_ERR(adsp->cx_supply)) {
 463		if (PTR_ERR(adsp->cx_supply) == -ENODEV)
 464			adsp->cx_supply = NULL;
 465		else
 466			return PTR_ERR(adsp->cx_supply);
 467	}
 468
 469	if (adsp->cx_supply)
 470		regulator_set_load(adsp->cx_supply, 100000);
 471
 472	adsp->px_supply = devm_regulator_get_optional(adsp->dev, "px");
 473	if (IS_ERR(adsp->px_supply)) {
 474		if (PTR_ERR(adsp->px_supply) == -ENODEV)
 475			adsp->px_supply = NULL;
 476		else
 477			return PTR_ERR(adsp->px_supply);
 478	}
 479
 480	return 0;
 481}
 482
 483static int adsp_pds_attach(struct device *dev, struct device **devs,
 484			   char **pd_names)
 485{
 486	size_t num_pds = 0;
 487	int ret;
 488	int i;
 489
 490	if (!pd_names)
 491		return 0;
 492
 493	/* Handle single power domain */
 494	if (dev->pm_domain) {
 495		devs[0] = dev;
 496		pm_runtime_enable(dev);
 497		return 1;
 498	}
 499
 500	while (pd_names[num_pds])
 501		num_pds++;
 502
 503	for (i = 0; i < num_pds; i++) {
 504		devs[i] = dev_pm_domain_attach_by_name(dev, pd_names[i]);
 505		if (IS_ERR_OR_NULL(devs[i])) {
 506			ret = PTR_ERR(devs[i]) ? : -ENODATA;
 507			goto unroll_attach;
 508		}
 509	}
 510
 511	return num_pds;
 512
 513unroll_attach:
 514	for (i--; i >= 0; i--)
 515		dev_pm_domain_detach(devs[i], false);
 516
 517	return ret;
 518};
 519
 520static void adsp_pds_detach(struct qcom_adsp *adsp, struct device **pds,
 521			    size_t pd_count)
 522{
 523	struct device *dev = adsp->dev;
 524	int i;
 525
 526	/* Handle single power domain */
 527	if (dev->pm_domain && pd_count) {
 528		pm_runtime_disable(dev);
 529		return;
 530	}
 531
 532	for (i = 0; i < pd_count; i++)
 533		dev_pm_domain_detach(pds[i], false);
 534}
 535
 536static int adsp_alloc_memory_region(struct qcom_adsp *adsp)
 537{
 538	struct reserved_mem *rmem;
 539	struct device_node *node;
 540
 541	node = of_parse_phandle(adsp->dev->of_node, "memory-region", 0);
 542	if (!node) {
 543		dev_err(adsp->dev, "no memory-region specified\n");
 544		return -EINVAL;
 545	}
 546
 547	rmem = of_reserved_mem_lookup(node);
 548	of_node_put(node);
 549	if (!rmem) {
 550		dev_err(adsp->dev, "unable to resolve memory-region\n");
 551		return -EINVAL;
 552	}
 553
 554	adsp->mem_phys = adsp->mem_reloc = rmem->base;
 555	adsp->mem_size = rmem->size;
 556	adsp->mem_region = devm_ioremap_wc(adsp->dev, adsp->mem_phys, adsp->mem_size);
 557	if (!adsp->mem_region) {
 558		dev_err(adsp->dev, "unable to map memory region: %pa+%zx\n",
 559			&rmem->base, adsp->mem_size);
 560		return -EBUSY;
 561	}
 562
 563	if (!adsp->dtb_pas_id)
 564		return 0;
 565
 566	node = of_parse_phandle(adsp->dev->of_node, "memory-region", 1);
 567	if (!node) {
 568		dev_err(adsp->dev, "no dtb memory-region specified\n");
 569		return -EINVAL;
 570	}
 571
 572	rmem = of_reserved_mem_lookup(node);
 573	of_node_put(node);
 574	if (!rmem) {
 575		dev_err(adsp->dev, "unable to resolve dtb memory-region\n");
 576		return -EINVAL;
 577	}
 578
 579	adsp->dtb_mem_phys = adsp->dtb_mem_reloc = rmem->base;
 580	adsp->dtb_mem_size = rmem->size;
 581	adsp->dtb_mem_region = devm_ioremap_wc(adsp->dev, adsp->dtb_mem_phys, adsp->dtb_mem_size);
 582	if (!adsp->dtb_mem_region) {
 583		dev_err(adsp->dev, "unable to map dtb memory region: %pa+%zx\n",
 584			&rmem->base, adsp->dtb_mem_size);
 585		return -EBUSY;
 586	}
 587
 588	return 0;
 589}
 590
 591static int adsp_assign_memory_region(struct qcom_adsp *adsp)
 592{
 593	struct reserved_mem *rmem = NULL;
 594	struct qcom_scm_vmperm perm;
 595	struct device_node *node;
 
 
 596	int ret;
 597
 598	if (!adsp->region_assign_idx)
 599		return 0;
 600
 601	node = of_parse_phandle(adsp->dev->of_node, "memory-region", adsp->region_assign_idx);
 602	if (node)
 603		rmem = of_reserved_mem_lookup(node);
 604	of_node_put(node);
 605	if (!rmem) {
 606		dev_err(adsp->dev, "unable to resolve shareable memory-region\n");
 607		return -EINVAL;
 608	}
 
 
 
 
 
 609
 610	perm.vmid = QCOM_SCM_VMID_MSS_MSA;
 611	perm.perm = QCOM_SCM_PERM_RW;
 
 
 
 
 
 
 
 
 
 612
 613	adsp->region_assign_phys = rmem->base;
 614	adsp->region_assign_size = rmem->size;
 615	adsp->region_assign_perms = BIT(QCOM_SCM_VMID_HLOS);
 616
 617	ret = qcom_scm_assign_mem(adsp->region_assign_phys,
 618				  adsp->region_assign_size,
 619				  &adsp->region_assign_perms,
 620				  &perm, 1);
 621	if (ret < 0) {
 622		dev_err(adsp->dev, "assign memory failed\n");
 623		return ret;
 
 624	}
 625
 626	return 0;
 627}
 628
 629static void adsp_unassign_memory_region(struct qcom_adsp *adsp)
 630{
 631	struct qcom_scm_vmperm perm;
 
 632	int ret;
 633
 634	if (!adsp->region_assign_idx)
 635		return;
 636
 637	perm.vmid = QCOM_SCM_VMID_HLOS;
 638	perm.perm = QCOM_SCM_PERM_RW;
 639
 640	ret = qcom_scm_assign_mem(adsp->region_assign_phys,
 641				  adsp->region_assign_size,
 642				  &adsp->region_assign_perms,
 643				  &perm, 1);
 644	if (ret < 0)
 645		dev_err(adsp->dev, "unassign memory failed\n");
 
 
 646}
 647
 648static int adsp_probe(struct platform_device *pdev)
 649{
 650	const struct adsp_data *desc;
 651	struct qcom_adsp *adsp;
 652	struct rproc *rproc;
 653	const char *fw_name, *dtb_fw_name = NULL;
 654	const struct rproc_ops *ops = &adsp_ops;
 655	int ret;
 656
 657	desc = of_device_get_match_data(&pdev->dev);
 658	if (!desc)
 659		return -EINVAL;
 660
 661	if (!qcom_scm_is_available())
 662		return -EPROBE_DEFER;
 663
 664	fw_name = desc->firmware_name;
 665	ret = of_property_read_string(pdev->dev.of_node, "firmware-name",
 666				      &fw_name);
 667	if (ret < 0 && ret != -EINVAL)
 668		return ret;
 669
 670	if (desc->dtb_firmware_name) {
 671		dtb_fw_name = desc->dtb_firmware_name;
 672		ret = of_property_read_string_index(pdev->dev.of_node, "firmware-name", 1,
 673						    &dtb_fw_name);
 674		if (ret < 0 && ret != -EINVAL)
 675			return ret;
 676	}
 677
 678	if (desc->minidump_id)
 679		ops = &adsp_minidump_ops;
 680
 681	rproc = rproc_alloc(&pdev->dev, pdev->name, ops, fw_name, sizeof(*adsp));
 682
 683	if (!rproc) {
 684		dev_err(&pdev->dev, "unable to allocate remoteproc\n");
 685		return -ENOMEM;
 686	}
 687
 688	rproc->auto_boot = desc->auto_boot;
 689	rproc_coredump_set_elf_info(rproc, ELFCLASS32, EM_NONE);
 690
 691	adsp = rproc->priv;
 692	adsp->dev = &pdev->dev;
 693	adsp->rproc = rproc;
 694	adsp->minidump_id = desc->minidump_id;
 695	adsp->pas_id = desc->pas_id;
 
 696	adsp->info_name = desc->sysmon_name;
 
 697	adsp->decrypt_shutdown = desc->decrypt_shutdown;
 698	adsp->region_assign_idx = desc->region_assign_idx;
 
 
 
 699	if (dtb_fw_name) {
 700		adsp->dtb_firmware_name = dtb_fw_name;
 701		adsp->dtb_pas_id = desc->dtb_pas_id;
 702	}
 703	platform_set_drvdata(pdev, adsp);
 704
 705	ret = device_init_wakeup(adsp->dev, true);
 706	if (ret)
 707		goto free_rproc;
 708
 709	ret = adsp_alloc_memory_region(adsp);
 710	if (ret)
 711		goto free_rproc;
 712
 713	ret = adsp_assign_memory_region(adsp);
 714	if (ret)
 715		goto free_rproc;
 716
 717	ret = adsp_init_clock(adsp);
 718	if (ret)
 719		goto free_rproc;
 720
 721	ret = adsp_init_regulator(adsp);
 722	if (ret)
 723		goto free_rproc;
 724
 725	ret = adsp_pds_attach(&pdev->dev, adsp->proxy_pds,
 726			      desc->proxy_pd_names);
 727	if (ret < 0)
 728		goto free_rproc;
 729	adsp->proxy_pd_count = ret;
 730
 731	ret = qcom_q6v5_init(&adsp->q6v5, pdev, rproc, desc->crash_reason_smem, desc->load_state,
 732			     qcom_pas_handover);
 733	if (ret)
 734		goto detach_proxy_pds;
 735
 736	qcom_add_glink_subdev(rproc, &adsp->glink_subdev, desc->ssr_name);
 737	qcom_add_smd_subdev(rproc, &adsp->smd_subdev);
 
 738	adsp->sysmon = qcom_add_sysmon_subdev(rproc,
 739					      desc->sysmon_name,
 740					      desc->ssctl_id);
 741	if (IS_ERR(adsp->sysmon)) {
 742		ret = PTR_ERR(adsp->sysmon);
 743		goto detach_proxy_pds;
 744	}
 745
 746	qcom_add_ssr_subdev(rproc, &adsp->ssr_subdev, desc->ssr_name);
 747	ret = rproc_add(rproc);
 748	if (ret)
 749		goto detach_proxy_pds;
 750
 751	return 0;
 752
 
 
 
 
 
 
 
 
 753detach_proxy_pds:
 754	adsp_pds_detach(adsp, adsp->proxy_pds, adsp->proxy_pd_count);
 
 
 755free_rproc:
 756	device_init_wakeup(adsp->dev, false);
 757	rproc_free(rproc);
 758
 759	return ret;
 760}
 761
 762static void adsp_remove(struct platform_device *pdev)
 763{
 764	struct qcom_adsp *adsp = platform_get_drvdata(pdev);
 765
 766	rproc_del(adsp->rproc);
 767
 768	qcom_q6v5_deinit(&adsp->q6v5);
 769	adsp_unassign_memory_region(adsp);
 770	qcom_remove_glink_subdev(adsp->rproc, &adsp->glink_subdev);
 771	qcom_remove_sysmon_subdev(adsp->sysmon);
 772	qcom_remove_smd_subdev(adsp->rproc, &adsp->smd_subdev);
 
 773	qcom_remove_ssr_subdev(adsp->rproc, &adsp->ssr_subdev);
 774	adsp_pds_detach(adsp, adsp->proxy_pds, adsp->proxy_pd_count);
 775	device_init_wakeup(adsp->dev, false);
 776	rproc_free(adsp->rproc);
 777}
 778
 779static const struct adsp_data adsp_resource_init = {
 780		.crash_reason_smem = 423,
 781		.firmware_name = "adsp.mdt",
 782		.pas_id = 1,
 783		.auto_boot = true,
 784		.ssr_name = "lpass",
 785		.sysmon_name = "adsp",
 786		.ssctl_id = 0x14,
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 787};
 788
 789static const struct adsp_data sdm845_adsp_resource_init = {
 790		.crash_reason_smem = 423,
 791		.firmware_name = "adsp.mdt",
 792		.pas_id = 1,
 793		.auto_boot = true,
 794		.load_state = "adsp",
 795		.ssr_name = "lpass",
 796		.sysmon_name = "adsp",
 797		.ssctl_id = 0x14,
 798};
 799
 800static const struct adsp_data sm6350_adsp_resource = {
 801	.crash_reason_smem = 423,
 802	.firmware_name = "adsp.mdt",
 803	.pas_id = 1,
 804	.auto_boot = true,
 805	.proxy_pd_names = (char*[]){
 806		"lcx",
 807		"lmx",
 808		NULL
 809	},
 810	.load_state = "adsp",
 811	.ssr_name = "lpass",
 812	.sysmon_name = "adsp",
 813	.ssctl_id = 0x14,
 814};
 815
 816static const struct adsp_data sm6375_mpss_resource = {
 817	.crash_reason_smem = 421,
 818	.firmware_name = "modem.mdt",
 819	.pas_id = 4,
 820	.minidump_id = 3,
 821	.auto_boot = false,
 822	.proxy_pd_names = (char*[]){
 823		"cx",
 824		NULL
 825	},
 826	.ssr_name = "mpss",
 827	.sysmon_name = "modem",
 828	.ssctl_id = 0x12,
 829};
 830
 831static const struct adsp_data sm8150_adsp_resource = {
 832		.crash_reason_smem = 423,
 833		.firmware_name = "adsp.mdt",
 834		.pas_id = 1,
 835		.auto_boot = true,
 836		.proxy_pd_names = (char*[]){
 837			"cx",
 838			NULL
 839		},
 840		.load_state = "adsp",
 841		.ssr_name = "lpass",
 842		.sysmon_name = "adsp",
 843		.ssctl_id = 0x14,
 844};
 845
 846static const struct adsp_data sm8250_adsp_resource = {
 847	.crash_reason_smem = 423,
 848	.firmware_name = "adsp.mdt",
 849	.pas_id = 1,
 
 850	.auto_boot = true,
 851	.proxy_pd_names = (char*[]){
 852		"lcx",
 853		"lmx",
 854		NULL
 855	},
 856	.load_state = "adsp",
 857	.ssr_name = "lpass",
 858	.sysmon_name = "adsp",
 859	.ssctl_id = 0x14,
 860};
 861
 862static const struct adsp_data sm8350_adsp_resource = {
 863	.crash_reason_smem = 423,
 864	.firmware_name = "adsp.mdt",
 865	.pas_id = 1,
 866	.auto_boot = true,
 867	.proxy_pd_names = (char*[]){
 868		"lcx",
 869		"lmx",
 870		NULL
 871	},
 872	.load_state = "adsp",
 873	.ssr_name = "lpass",
 874	.sysmon_name = "adsp",
 875	.ssctl_id = 0x14,
 876};
 877
 878static const struct adsp_data msm8996_adsp_resource = {
 879		.crash_reason_smem = 423,
 880		.firmware_name = "adsp.mdt",
 881		.pas_id = 1,
 882		.auto_boot = true,
 883		.proxy_pd_names = (char*[]){
 884			"cx",
 885			NULL
 886		},
 887		.ssr_name = "lpass",
 888		.sysmon_name = "adsp",
 889		.ssctl_id = 0x14,
 890};
 891
 892static const struct adsp_data cdsp_resource_init = {
 893	.crash_reason_smem = 601,
 894	.firmware_name = "cdsp.mdt",
 895	.pas_id = 18,
 896	.auto_boot = true,
 897	.ssr_name = "cdsp",
 898	.sysmon_name = "cdsp",
 899	.ssctl_id = 0x17,
 900};
 901
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 902static const struct adsp_data sdm845_cdsp_resource_init = {
 903	.crash_reason_smem = 601,
 904	.firmware_name = "cdsp.mdt",
 905	.pas_id = 18,
 906	.auto_boot = true,
 907	.load_state = "cdsp",
 908	.ssr_name = "cdsp",
 909	.sysmon_name = "cdsp",
 910	.ssctl_id = 0x17,
 911};
 912
 913static const struct adsp_data sm6350_cdsp_resource = {
 914	.crash_reason_smem = 601,
 915	.firmware_name = "cdsp.mdt",
 916	.pas_id = 18,
 917	.auto_boot = true,
 918	.proxy_pd_names = (char*[]){
 919		"cx",
 920		"mx",
 921		NULL
 922	},
 923	.load_state = "cdsp",
 924	.ssr_name = "cdsp",
 925	.sysmon_name = "cdsp",
 926	.ssctl_id = 0x17,
 927};
 928
 929static const struct adsp_data sm8150_cdsp_resource = {
 930	.crash_reason_smem = 601,
 931	.firmware_name = "cdsp.mdt",
 932	.pas_id = 18,
 933	.auto_boot = true,
 934	.proxy_pd_names = (char*[]){
 935		"cx",
 936		NULL
 937	},
 938	.load_state = "cdsp",
 939	.ssr_name = "cdsp",
 940	.sysmon_name = "cdsp",
 941	.ssctl_id = 0x17,
 942};
 943
 944static const struct adsp_data sm8250_cdsp_resource = {
 945	.crash_reason_smem = 601,
 946	.firmware_name = "cdsp.mdt",
 947	.pas_id = 18,
 948	.auto_boot = true,
 949	.proxy_pd_names = (char*[]){
 950		"cx",
 951		NULL
 952	},
 953	.load_state = "cdsp",
 954	.ssr_name = "cdsp",
 955	.sysmon_name = "cdsp",
 956	.ssctl_id = 0x17,
 957};
 958
 959static const struct adsp_data sc8280xp_nsp0_resource = {
 960	.crash_reason_smem = 601,
 961	.firmware_name = "cdsp.mdt",
 962	.pas_id = 18,
 963	.auto_boot = true,
 964	.proxy_pd_names = (char*[]){
 965		"nsp",
 966		NULL
 967	},
 968	.ssr_name = "cdsp0",
 969	.sysmon_name = "cdsp",
 970	.ssctl_id = 0x17,
 971};
 972
 973static const struct adsp_data sc8280xp_nsp1_resource = {
 974	.crash_reason_smem = 633,
 975	.firmware_name = "cdsp.mdt",
 976	.pas_id = 30,
 977	.auto_boot = true,
 978	.proxy_pd_names = (char*[]){
 979		"nsp",
 980		NULL
 981	},
 982	.ssr_name = "cdsp1",
 983	.sysmon_name = "cdsp1",
 984	.ssctl_id = 0x20,
 985};
 986
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 987static const struct adsp_data sm8350_cdsp_resource = {
 988	.crash_reason_smem = 601,
 989	.firmware_name = "cdsp.mdt",
 990	.pas_id = 18,
 
 991	.auto_boot = true,
 992	.proxy_pd_names = (char*[]){
 993		"cx",
 994		"mxc",
 995		NULL
 996	},
 997	.load_state = "cdsp",
 998	.ssr_name = "cdsp",
 999	.sysmon_name = "cdsp",
1000	.ssctl_id = 0x17,
1001};
1002
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1003static const struct adsp_data mpss_resource_init = {
1004	.crash_reason_smem = 421,
1005	.firmware_name = "modem.mdt",
1006	.pas_id = 4,
1007	.minidump_id = 3,
1008	.auto_boot = false,
1009	.proxy_pd_names = (char*[]){
1010		"cx",
1011		"mss",
1012		NULL
1013	},
1014	.load_state = "modem",
1015	.ssr_name = "mpss",
1016	.sysmon_name = "modem",
1017	.ssctl_id = 0x12,
1018};
1019
1020static const struct adsp_data sc8180x_mpss_resource = {
1021	.crash_reason_smem = 421,
1022	.firmware_name = "modem.mdt",
1023	.pas_id = 4,
1024	.auto_boot = false,
1025	.proxy_pd_names = (char*[]){
1026		"cx",
1027		NULL
1028	},
1029	.load_state = "modem",
1030	.ssr_name = "mpss",
1031	.sysmon_name = "modem",
1032	.ssctl_id = 0x12,
1033};
1034
1035static const struct adsp_data msm8996_slpi_resource_init = {
1036		.crash_reason_smem = 424,
1037		.firmware_name = "slpi.mdt",
1038		.pas_id = 12,
1039		.auto_boot = true,
1040		.proxy_pd_names = (char*[]){
1041			"ssc_cx",
1042			NULL
1043		},
1044		.ssr_name = "dsps",
1045		.sysmon_name = "slpi",
1046		.ssctl_id = 0x16,
1047};
1048
1049static const struct adsp_data sdm845_slpi_resource_init = {
1050		.crash_reason_smem = 424,
1051		.firmware_name = "slpi.mdt",
1052		.pas_id = 12,
1053		.auto_boot = true,
1054		.proxy_pd_names = (char*[]){
1055			"lcx",
1056			"lmx",
1057			NULL
1058		},
1059		.load_state = "slpi",
1060		.ssr_name = "dsps",
1061		.sysmon_name = "slpi",
1062		.ssctl_id = 0x16,
1063};
1064
1065static const struct adsp_data wcss_resource_init = {
1066	.crash_reason_smem = 421,
1067	.firmware_name = "wcnss.mdt",
1068	.pas_id = 6,
1069	.auto_boot = true,
1070	.ssr_name = "mpss",
1071	.sysmon_name = "wcnss",
1072	.ssctl_id = 0x12,
1073};
1074
1075static const struct adsp_data sdx55_mpss_resource = {
1076	.crash_reason_smem = 421,
1077	.firmware_name = "modem.mdt",
1078	.pas_id = 4,
1079	.auto_boot = true,
1080	.proxy_pd_names = (char*[]){
1081		"cx",
1082		"mss",
1083		NULL
1084	},
1085	.ssr_name = "mpss",
1086	.sysmon_name = "modem",
1087	.ssctl_id = 0x22,
1088};
1089
1090static const struct adsp_data sm8450_mpss_resource = {
1091	.crash_reason_smem = 421,
1092	.firmware_name = "modem.mdt",
1093	.pas_id = 4,
1094	.minidump_id = 3,
1095	.auto_boot = false,
1096	.decrypt_shutdown = true,
1097	.proxy_pd_names = (char*[]){
1098		"cx",
1099		"mss",
1100		NULL
1101	},
1102	.load_state = "modem",
1103	.ssr_name = "mpss",
1104	.sysmon_name = "modem",
1105	.ssctl_id = 0x12,
1106};
1107
1108static const struct adsp_data sm8550_adsp_resource = {
1109	.crash_reason_smem = 423,
1110	.firmware_name = "adsp.mdt",
1111	.dtb_firmware_name = "adsp_dtb.mdt",
1112	.pas_id = 1,
1113	.dtb_pas_id = 0x24,
1114	.minidump_id = 5,
1115	.auto_boot = true,
1116	.proxy_pd_names = (char*[]){
1117		"lcx",
1118		"lmx",
1119		NULL
1120	},
1121	.load_state = "adsp",
1122	.ssr_name = "lpass",
1123	.sysmon_name = "adsp",
1124	.ssctl_id = 0x14,
 
1125};
1126
1127static const struct adsp_data sm8550_cdsp_resource = {
1128	.crash_reason_smem = 601,
1129	.firmware_name = "cdsp.mdt",
1130	.dtb_firmware_name = "cdsp_dtb.mdt",
1131	.pas_id = 18,
1132	.dtb_pas_id = 0x25,
1133	.minidump_id = 7,
1134	.auto_boot = true,
1135	.proxy_pd_names = (char*[]){
1136		"cx",
1137		"mxc",
1138		"nsp",
1139		NULL
1140	},
1141	.load_state = "cdsp",
1142	.ssr_name = "cdsp",
1143	.sysmon_name = "cdsp",
1144	.ssctl_id = 0x17,
 
1145};
1146
1147static const struct adsp_data sm8550_mpss_resource = {
1148	.crash_reason_smem = 421,
1149	.firmware_name = "modem.mdt",
1150	.dtb_firmware_name = "modem_dtb.mdt",
1151	.pas_id = 4,
1152	.dtb_pas_id = 0x26,
1153	.minidump_id = 3,
1154	.auto_boot = false,
1155	.decrypt_shutdown = true,
1156	.proxy_pd_names = (char*[]){
1157		"cx",
1158		"mss",
1159		NULL
1160	},
1161	.load_state = "modem",
1162	.ssr_name = "mpss",
1163	.sysmon_name = "modem",
1164	.ssctl_id = 0x12,
 
1165	.region_assign_idx = 2,
 
 
1166};
1167
1168static const struct adsp_data sc7280_wpss_resource = {
1169	.crash_reason_smem = 626,
1170	.firmware_name = "wpss.mdt",
1171	.pas_id = 6,
1172	.auto_boot = true,
1173	.proxy_pd_names = (char*[]){
1174		"cx",
1175		"mx",
1176		NULL
1177	},
1178	.load_state = "wpss",
1179	.ssr_name = "wpss",
1180	.sysmon_name = "wpss",
1181	.ssctl_id = 0x19,
1182};
1183
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1184static const struct of_device_id adsp_of_match[] = {
1185	{ .compatible = "qcom,msm8226-adsp-pil", .data = &adsp_resource_init},
1186	{ .compatible = "qcom,msm8953-adsp-pil", .data = &msm8996_adsp_resource},
1187	{ .compatible = "qcom,msm8974-adsp-pil", .data = &adsp_resource_init},
1188	{ .compatible = "qcom,msm8996-adsp-pil", .data = &msm8996_adsp_resource},
1189	{ .compatible = "qcom,msm8996-slpi-pil", .data = &msm8996_slpi_resource_init},
1190	{ .compatible = "qcom,msm8998-adsp-pas", .data = &msm8996_adsp_resource},
1191	{ .compatible = "qcom,msm8998-slpi-pas", .data = &msm8996_slpi_resource_init},
1192	{ .compatible = "qcom,qcs404-adsp-pas", .data = &adsp_resource_init },
1193	{ .compatible = "qcom,qcs404-cdsp-pas", .data = &cdsp_resource_init },
1194	{ .compatible = "qcom,qcs404-wcss-pas", .data = &wcss_resource_init },
 
 
 
 
 
 
1195	{ .compatible = "qcom,sc7180-adsp-pas", .data = &sm8250_adsp_resource},
1196	{ .compatible = "qcom,sc7180-mpss-pas", .data = &mpss_resource_init},
1197	{ .compatible = "qcom,sc7280-adsp-pas", .data = &sm8350_adsp_resource},
1198	{ .compatible = "qcom,sc7280-cdsp-pas", .data = &sm6350_cdsp_resource},
1199	{ .compatible = "qcom,sc7280-mpss-pas", .data = &mpss_resource_init},
1200	{ .compatible = "qcom,sc7280-wpss-pas", .data = &sc7280_wpss_resource},
1201	{ .compatible = "qcom,sc8180x-adsp-pas", .data = &sm8150_adsp_resource},
1202	{ .compatible = "qcom,sc8180x-cdsp-pas", .data = &sm8150_cdsp_resource},
1203	{ .compatible = "qcom,sc8180x-mpss-pas", .data = &sc8180x_mpss_resource},
1204	{ .compatible = "qcom,sc8280xp-adsp-pas", .data = &sm8250_adsp_resource},
1205	{ .compatible = "qcom,sc8280xp-nsp0-pas", .data = &sc8280xp_nsp0_resource},
1206	{ .compatible = "qcom,sc8280xp-nsp1-pas", .data = &sc8280xp_nsp1_resource},
1207	{ .compatible = "qcom,sdm660-adsp-pas", .data = &adsp_resource_init},
1208	{ .compatible = "qcom,sdm845-adsp-pas", .data = &sdm845_adsp_resource_init},
1209	{ .compatible = "qcom,sdm845-cdsp-pas", .data = &sdm845_cdsp_resource_init},
1210	{ .compatible = "qcom,sdm845-slpi-pas", .data = &sdm845_slpi_resource_init},
1211	{ .compatible = "qcom,sdx55-mpss-pas", .data = &sdx55_mpss_resource},
 
1212	{ .compatible = "qcom,sm6115-adsp-pas", .data = &adsp_resource_init},
1213	{ .compatible = "qcom,sm6115-cdsp-pas", .data = &cdsp_resource_init},
1214	{ .compatible = "qcom,sm6115-mpss-pas", .data = &sc8180x_mpss_resource},
1215	{ .compatible = "qcom,sm6350-adsp-pas", .data = &sm6350_adsp_resource},
1216	{ .compatible = "qcom,sm6350-cdsp-pas", .data = &sm6350_cdsp_resource},
1217	{ .compatible = "qcom,sm6350-mpss-pas", .data = &mpss_resource_init},
1218	{ .compatible = "qcom,sm6375-adsp-pas", .data = &sm6350_adsp_resource},
1219	{ .compatible = "qcom,sm6375-cdsp-pas", .data = &sm8150_cdsp_resource},
1220	{ .compatible = "qcom,sm6375-mpss-pas", .data = &sm6375_mpss_resource},
1221	{ .compatible = "qcom,sm8150-adsp-pas", .data = &sm8150_adsp_resource},
1222	{ .compatible = "qcom,sm8150-cdsp-pas", .data = &sm8150_cdsp_resource},
1223	{ .compatible = "qcom,sm8150-mpss-pas", .data = &mpss_resource_init},
1224	{ .compatible = "qcom,sm8150-slpi-pas", .data = &sdm845_slpi_resource_init},
1225	{ .compatible = "qcom,sm8250-adsp-pas", .data = &sm8250_adsp_resource},
1226	{ .compatible = "qcom,sm8250-cdsp-pas", .data = &sm8250_cdsp_resource},
1227	{ .compatible = "qcom,sm8250-slpi-pas", .data = &sdm845_slpi_resource_init},
1228	{ .compatible = "qcom,sm8350-adsp-pas", .data = &sm8350_adsp_resource},
1229	{ .compatible = "qcom,sm8350-cdsp-pas", .data = &sm8350_cdsp_resource},
1230	{ .compatible = "qcom,sm8350-slpi-pas", .data = &sdm845_slpi_resource_init},
1231	{ .compatible = "qcom,sm8350-mpss-pas", .data = &mpss_resource_init},
1232	{ .compatible = "qcom,sm8450-adsp-pas", .data = &sm8350_adsp_resource},
1233	{ .compatible = "qcom,sm8450-cdsp-pas", .data = &sm8350_cdsp_resource},
1234	{ .compatible = "qcom,sm8450-slpi-pas", .data = &sdm845_slpi_resource_init},
1235	{ .compatible = "qcom,sm8450-mpss-pas", .data = &sm8450_mpss_resource},
1236	{ .compatible = "qcom,sm8550-adsp-pas", .data = &sm8550_adsp_resource},
1237	{ .compatible = "qcom,sm8550-cdsp-pas", .data = &sm8550_cdsp_resource},
1238	{ .compatible = "qcom,sm8550-mpss-pas", .data = &sm8550_mpss_resource},
 
 
 
 
 
1239	{ },
1240};
1241MODULE_DEVICE_TABLE(of, adsp_of_match);
1242
1243static struct platform_driver adsp_driver = {
1244	.probe = adsp_probe,
1245	.remove_new = adsp_remove,
1246	.driver = {
1247		.name = "qcom_q6v5_pas",
1248		.of_match_table = adsp_of_match,
1249	},
1250};
1251
1252module_platform_driver(adsp_driver);
1253MODULE_DESCRIPTION("Qualcomm Hexagon v5 Peripheral Authentication Service driver");
1254MODULE_LICENSE("GPL v2");