qcom_q6v5_pas.c 36 KB

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