Commit | Line | Data |
---|---|---|
1802d0be | 1 | // SPDX-License-Identifier: GPL-2.0-only |
b9e718e9 | 2 | /* |
90a068ed | 3 | * Qualcomm ADSP/SLPI Peripheral Image Loader for MSM8974 and MSM8996 |
b9e718e9 BA |
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. | |
b9e718e9 BA |
8 | */ |
9 | ||
f33a7358 | 10 | #include <linux/clk.h> |
b9e718e9 BA |
11 | #include <linux/firmware.h> |
12 | #include <linux/interrupt.h> | |
13 | #include <linux/kernel.h> | |
14 | #include <linux/module.h> | |
15 | #include <linux/of_address.h> | |
16 | #include <linux/of_device.h> | |
17 | #include <linux/platform_device.h> | |
17ee2fb4 SS |
18 | #include <linux/pm_domain.h> |
19 | #include <linux/pm_runtime.h> | |
b9e718e9 BA |
20 | #include <linux/qcom_scm.h> |
21 | #include <linux/regulator/consumer.h> | |
22 | #include <linux/remoteproc.h> | |
2aad40d9 | 23 | #include <linux/soc/qcom/mdt_loader.h> |
b9e718e9 BA |
24 | #include <linux/soc/qcom/smem.h> |
25 | #include <linux/soc/qcom/smem_state.h> | |
26 | ||
bde440ee | 27 | #include "qcom_common.h" |
d4c78d21 | 28 | #include "qcom_pil_info.h" |
6103b1a6 | 29 | #include "qcom_q6v5.h" |
b9e718e9 BA |
30 | #include "remoteproc_internal.h" |
31 | ||
c7715e47 AKD |
32 | struct adsp_data { |
33 | int crash_reason_smem; | |
34 | const char *firmware_name; | |
35 | int pas_id; | |
8ed8485c | 36 | unsigned int minidump_id; |
e323fc03 | 37 | bool has_aggre2_clk; |
b7ff96cc | 38 | bool auto_boot; |
1fb82ee8 | 39 | |
17ee2fb4 SS |
40 | char **active_pd_names; |
41 | char **proxy_pd_names; | |
42 | ||
1e140df0 | 43 | const char *ssr_name; |
1fb82ee8 BA |
44 | const char *sysmon_name; |
45 | int ssctl_id; | |
c7715e47 | 46 | }; |
b9e718e9 BA |
47 | |
48 | struct qcom_adsp { | |
49 | struct device *dev; | |
50 | struct rproc *rproc; | |
51 | ||
6103b1a6 | 52 | struct qcom_q6v5 q6v5; |
b9e718e9 | 53 | |
f33a7358 | 54 | struct clk *xo; |
e323fc03 | 55 | struct clk *aggre2_clk; |
f33a7358 | 56 | |
b9e718e9 | 57 | struct regulator *cx_supply; |
e323fc03 | 58 | struct regulator *px_supply; |
b9e718e9 | 59 | |
17ee2fb4 SS |
60 | struct device *active_pds[1]; |
61 | struct device *proxy_pds[3]; | |
62 | ||
63 | int active_pd_count; | |
64 | int proxy_pd_count; | |
65 | ||
c7715e47 | 66 | int pas_id; |
8ed8485c | 67 | unsigned int minidump_id; |
c7715e47 | 68 | int crash_reason_smem; |
e323fc03 | 69 | bool has_aggre2_clk; |
d4c78d21 | 70 | const char *info_name; |
c7715e47 | 71 | |
b9e718e9 BA |
72 | struct completion start_done; |
73 | struct completion stop_done; | |
74 | ||
75 | phys_addr_t mem_phys; | |
76 | phys_addr_t mem_reloc; | |
77 | void *mem_region; | |
78 | size_t mem_size; | |
4b48921a | 79 | |
eea07023 | 80 | struct qcom_rproc_glink glink_subdev; |
4b48921a | 81 | struct qcom_rproc_subdev smd_subdev; |
1e140df0 | 82 | struct qcom_rproc_ssr ssr_subdev; |
1fb82ee8 | 83 | struct qcom_sysmon *sysmon; |
b9e718e9 BA |
84 | }; |
85 | ||
8ed8485c SG |
86 | static void adsp_minidump(struct rproc *rproc) |
87 | { | |
88 | struct qcom_adsp *adsp = rproc->priv; | |
89 | ||
90 | qcom_minidump(rproc, adsp->minidump_id); | |
91 | } | |
92 | ||
17ee2fb4 SS |
93 | static int adsp_pds_enable(struct qcom_adsp *adsp, struct device **pds, |
94 | size_t pd_count) | |
95 | { | |
96 | int ret; | |
97 | int i; | |
98 | ||
99 | for (i = 0; i < pd_count; i++) { | |
100 | dev_pm_genpd_set_performance_state(pds[i], INT_MAX); | |
101 | ret = pm_runtime_get_sync(pds[i]); | |
c0a6e5ee ZQ |
102 | if (ret < 0) { |
103 | pm_runtime_put_noidle(pds[i]); | |
104 | dev_pm_genpd_set_performance_state(pds[i], 0); | |
17ee2fb4 | 105 | goto unroll_pd_votes; |
c0a6e5ee | 106 | } |
17ee2fb4 SS |
107 | } |
108 | ||
109 | return 0; | |
110 | ||
111 | unroll_pd_votes: | |
112 | for (i--; i >= 0; i--) { | |
113 | dev_pm_genpd_set_performance_state(pds[i], 0); | |
114 | pm_runtime_put(pds[i]); | |
115 | } | |
116 | ||
117 | return ret; | |
118 | }; | |
119 | ||
120 | static void adsp_pds_disable(struct qcom_adsp *adsp, struct device **pds, | |
121 | size_t pd_count) | |
122 | { | |
123 | int i; | |
124 | ||
125 | for (i = 0; i < pd_count; i++) { | |
126 | dev_pm_genpd_set_performance_state(pds[i], 0); | |
127 | pm_runtime_put(pds[i]); | |
128 | } | |
129 | } | |
130 | ||
b9e718e9 BA |
131 | static int adsp_load(struct rproc *rproc, const struct firmware *fw) |
132 | { | |
133 | struct qcom_adsp *adsp = (struct qcom_adsp *)rproc->priv; | |
d4c78d21 | 134 | int ret; |
b9e718e9 | 135 | |
d4c78d21 BA |
136 | ret = qcom_mdt_load(adsp->dev, fw, rproc->firmware, adsp->pas_id, |
137 | adsp->mem_region, adsp->mem_phys, adsp->mem_size, | |
138 | &adsp->mem_reloc); | |
139 | if (ret) | |
140 | return ret; | |
4dd27f54 | 141 | |
d4c78d21 BA |
142 | qcom_pil_info_store(adsp->info_name, adsp->mem_phys, adsp->mem_size); |
143 | ||
144 | return 0; | |
b9e718e9 BA |
145 | } |
146 | ||
b9e718e9 BA |
147 | static int adsp_start(struct rproc *rproc) |
148 | { | |
149 | struct qcom_adsp *adsp = (struct qcom_adsp *)rproc->priv; | |
150 | int ret; | |
151 | ||
6103b1a6 BA |
152 | qcom_q6v5_prepare(&adsp->q6v5); |
153 | ||
17ee2fb4 SS |
154 | ret = adsp_pds_enable(adsp, adsp->active_pds, adsp->active_pd_count); |
155 | if (ret < 0) | |
156 | goto disable_irqs; | |
157 | ||
158 | ret = adsp_pds_enable(adsp, adsp->proxy_pds, adsp->proxy_pd_count); | |
159 | if (ret < 0) | |
160 | goto disable_active_pds; | |
161 | ||
f33a7358 | 162 | ret = clk_prepare_enable(adsp->xo); |
b9e718e9 | 163 | if (ret) |
17ee2fb4 | 164 | goto disable_proxy_pds; |
b9e718e9 | 165 | |
e323fc03 AKD |
166 | ret = clk_prepare_enable(adsp->aggre2_clk); |
167 | if (ret) | |
168 | goto disable_xo_clk; | |
169 | ||
f33a7358 SJ |
170 | ret = regulator_enable(adsp->cx_supply); |
171 | if (ret) | |
e323fc03 AKD |
172 | goto disable_aggre2_clk; |
173 | ||
174 | ret = regulator_enable(adsp->px_supply); | |
175 | if (ret) | |
176 | goto disable_cx_supply; | |
f33a7358 | 177 | |
c7715e47 | 178 | ret = qcom_scm_pas_auth_and_reset(adsp->pas_id); |
b9e718e9 BA |
179 | if (ret) { |
180 | dev_err(adsp->dev, | |
181 | "failed to authenticate image and release reset\n"); | |
e323fc03 | 182 | goto disable_px_supply; |
b9e718e9 BA |
183 | } |
184 | ||
6103b1a6 BA |
185 | ret = qcom_q6v5_wait_for_start(&adsp->q6v5, msecs_to_jiffies(5000)); |
186 | if (ret == -ETIMEDOUT) { | |
b9e718e9 | 187 | dev_err(adsp->dev, "start timed out\n"); |
c7715e47 | 188 | qcom_scm_pas_shutdown(adsp->pas_id); |
e323fc03 | 189 | goto disable_px_supply; |
b9e718e9 BA |
190 | } |
191 | ||
6103b1a6 | 192 | return 0; |
b9e718e9 | 193 | |
e323fc03 AKD |
194 | disable_px_supply: |
195 | regulator_disable(adsp->px_supply); | |
196 | disable_cx_supply: | |
b9e718e9 | 197 | regulator_disable(adsp->cx_supply); |
e323fc03 AKD |
198 | disable_aggre2_clk: |
199 | clk_disable_unprepare(adsp->aggre2_clk); | |
200 | disable_xo_clk: | |
f33a7358 | 201 | clk_disable_unprepare(adsp->xo); |
17ee2fb4 SS |
202 | disable_proxy_pds: |
203 | adsp_pds_disable(adsp, adsp->proxy_pds, adsp->proxy_pd_count); | |
204 | disable_active_pds: | |
205 | adsp_pds_disable(adsp, adsp->active_pds, adsp->active_pd_count); | |
2ac91aad SS |
206 | disable_irqs: |
207 | qcom_q6v5_unprepare(&adsp->q6v5); | |
b9e718e9 BA |
208 | |
209 | return ret; | |
210 | } | |
211 | ||
6103b1a6 BA |
212 | static void qcom_pas_handover(struct qcom_q6v5 *q6v5) |
213 | { | |
214 | struct qcom_adsp *adsp = container_of(q6v5, struct qcom_adsp, q6v5); | |
215 | ||
216 | regulator_disable(adsp->px_supply); | |
217 | regulator_disable(adsp->cx_supply); | |
218 | clk_disable_unprepare(adsp->aggre2_clk); | |
219 | clk_disable_unprepare(adsp->xo); | |
17ee2fb4 | 220 | adsp_pds_disable(adsp, adsp->proxy_pds, adsp->proxy_pd_count); |
6103b1a6 BA |
221 | } |
222 | ||
b9e718e9 BA |
223 | static int adsp_stop(struct rproc *rproc) |
224 | { | |
225 | struct qcom_adsp *adsp = (struct qcom_adsp *)rproc->priv; | |
6103b1a6 | 226 | int handover; |
b9e718e9 BA |
227 | int ret; |
228 | ||
ed5da808 | 229 | ret = qcom_q6v5_request_stop(&adsp->q6v5, adsp->sysmon); |
6103b1a6 | 230 | if (ret == -ETIMEDOUT) |
b9e718e9 BA |
231 | dev_err(adsp->dev, "timed out on wait\n"); |
232 | ||
c7715e47 | 233 | ret = qcom_scm_pas_shutdown(adsp->pas_id); |
b9e718e9 BA |
234 | if (ret) |
235 | dev_err(adsp->dev, "failed to shutdown: %d\n", ret); | |
236 | ||
17ee2fb4 | 237 | adsp_pds_disable(adsp, adsp->active_pds, adsp->active_pd_count); |
6103b1a6 BA |
238 | handover = qcom_q6v5_unprepare(&adsp->q6v5); |
239 | if (handover) | |
240 | qcom_pas_handover(&adsp->q6v5); | |
241 | ||
b9e718e9 BA |
242 | return ret; |
243 | } | |
244 | ||
40df0a91 | 245 | static void *adsp_da_to_va(struct rproc *rproc, u64 da, size_t len, bool *is_iomem) |
b9e718e9 BA |
246 | { |
247 | struct qcom_adsp *adsp = (struct qcom_adsp *)rproc->priv; | |
248 | int offset; | |
249 | ||
250 | offset = da - adsp->mem_reloc; | |
251 | if (offset < 0 || offset + len > adsp->mem_size) | |
252 | return NULL; | |
253 | ||
254 | return adsp->mem_region + offset; | |
255 | } | |
256 | ||
717c21ba BA |
257 | static unsigned long adsp_panic(struct rproc *rproc) |
258 | { | |
259 | struct qcom_adsp *adsp = (struct qcom_adsp *)rproc->priv; | |
260 | ||
261 | return qcom_q6v5_panic(&adsp->q6v5); | |
262 | } | |
263 | ||
b9e718e9 BA |
264 | static const struct rproc_ops adsp_ops = { |
265 | .start = adsp_start, | |
266 | .stop = adsp_stop, | |
267 | .da_to_va = adsp_da_to_va, | |
dcb57ed4 | 268 | .parse_fw = qcom_register_dump_segments, |
0f21f9cc | 269 | .load = adsp_load, |
717c21ba | 270 | .panic = adsp_panic, |
b9e718e9 BA |
271 | }; |
272 | ||
8ed8485c SG |
273 | static const struct rproc_ops adsp_minidump_ops = { |
274 | .start = adsp_start, | |
275 | .stop = adsp_stop, | |
276 | .da_to_va = adsp_da_to_va, | |
277 | .load = adsp_load, | |
278 | .panic = adsp_panic, | |
279 | .coredump = adsp_minidump, | |
280 | }; | |
281 | ||
f33a7358 SJ |
282 | static int adsp_init_clock(struct qcom_adsp *adsp) |
283 | { | |
284 | int ret; | |
285 | ||
286 | adsp->xo = devm_clk_get(adsp->dev, "xo"); | |
287 | if (IS_ERR(adsp->xo)) { | |
288 | ret = PTR_ERR(adsp->xo); | |
289 | if (ret != -EPROBE_DEFER) | |
290 | dev_err(adsp->dev, "failed to get xo clock"); | |
291 | return ret; | |
292 | } | |
293 | ||
e323fc03 AKD |
294 | if (adsp->has_aggre2_clk) { |
295 | adsp->aggre2_clk = devm_clk_get(adsp->dev, "aggre2"); | |
296 | if (IS_ERR(adsp->aggre2_clk)) { | |
297 | ret = PTR_ERR(adsp->aggre2_clk); | |
298 | if (ret != -EPROBE_DEFER) | |
299 | dev_err(adsp->dev, | |
300 | "failed to get aggre2 clock"); | |
301 | return ret; | |
302 | } | |
303 | } | |
304 | ||
f33a7358 SJ |
305 | return 0; |
306 | } | |
307 | ||
b9e718e9 BA |
308 | static int adsp_init_regulator(struct qcom_adsp *adsp) |
309 | { | |
310 | adsp->cx_supply = devm_regulator_get(adsp->dev, "cx"); | |
311 | if (IS_ERR(adsp->cx_supply)) | |
312 | return PTR_ERR(adsp->cx_supply); | |
313 | ||
314 | regulator_set_load(adsp->cx_supply, 100000); | |
315 | ||
e323fc03 | 316 | adsp->px_supply = devm_regulator_get(adsp->dev, "px"); |
c76929b3 | 317 | return PTR_ERR_OR_ZERO(adsp->px_supply); |
b9e718e9 BA |
318 | } |
319 | ||
17ee2fb4 SS |
320 | static int adsp_pds_attach(struct device *dev, struct device **devs, |
321 | char **pd_names) | |
322 | { | |
323 | size_t num_pds = 0; | |
324 | int ret; | |
325 | int i; | |
326 | ||
327 | if (!pd_names) | |
328 | return 0; | |
329 | ||
330 | /* Handle single power domain */ | |
331 | if (dev->pm_domain) { | |
332 | devs[0] = dev; | |
333 | pm_runtime_enable(dev); | |
334 | return 1; | |
335 | } | |
336 | ||
337 | while (pd_names[num_pds]) | |
338 | num_pds++; | |
339 | ||
340 | for (i = 0; i < num_pds; i++) { | |
341 | devs[i] = dev_pm_domain_attach_by_name(dev, pd_names[i]); | |
342 | if (IS_ERR_OR_NULL(devs[i])) { | |
343 | ret = PTR_ERR(devs[i]) ? : -ENODATA; | |
344 | goto unroll_attach; | |
345 | } | |
346 | } | |
347 | ||
348 | return num_pds; | |
349 | ||
350 | unroll_attach: | |
351 | for (i--; i >= 0; i--) | |
352 | dev_pm_domain_detach(devs[i], false); | |
353 | ||
354 | return ret; | |
355 | }; | |
356 | ||
357 | static void adsp_pds_detach(struct qcom_adsp *adsp, struct device **pds, | |
358 | size_t pd_count) | |
359 | { | |
360 | struct device *dev = adsp->dev; | |
361 | int i; | |
362 | ||
363 | /* Handle single power domain */ | |
364 | if (dev->pm_domain && pd_count) { | |
365 | pm_runtime_disable(dev); | |
366 | return; | |
367 | } | |
368 | ||
369 | for (i = 0; i < pd_count; i++) | |
370 | dev_pm_domain_detach(pds[i], false); | |
371 | } | |
372 | ||
b9e718e9 BA |
373 | static int adsp_alloc_memory_region(struct qcom_adsp *adsp) |
374 | { | |
375 | struct device_node *node; | |
376 | struct resource r; | |
377 | int ret; | |
378 | ||
379 | node = of_parse_phandle(adsp->dev->of_node, "memory-region", 0); | |
380 | if (!node) { | |
381 | dev_err(adsp->dev, "no memory-region specified\n"); | |
382 | return -EINVAL; | |
383 | } | |
384 | ||
385 | ret = of_address_to_resource(node, 0, &r); | |
386 | if (ret) | |
387 | return ret; | |
388 | ||
389 | adsp->mem_phys = adsp->mem_reloc = r.start; | |
390 | adsp->mem_size = resource_size(&r); | |
391 | adsp->mem_region = devm_ioremap_wc(adsp->dev, adsp->mem_phys, adsp->mem_size); | |
392 | if (!adsp->mem_region) { | |
393 | dev_err(adsp->dev, "unable to map memory region: %pa+%zx\n", | |
394 | &r.start, adsp->mem_size); | |
395 | return -EBUSY; | |
396 | } | |
397 | ||
398 | return 0; | |
399 | } | |
400 | ||
401 | static int adsp_probe(struct platform_device *pdev) | |
402 | { | |
c7715e47 | 403 | const struct adsp_data *desc; |
b9e718e9 BA |
404 | struct qcom_adsp *adsp; |
405 | struct rproc *rproc; | |
a5a4e02d | 406 | const char *fw_name; |
8ed8485c | 407 | const struct rproc_ops *ops = &adsp_ops; |
b9e718e9 BA |
408 | int ret; |
409 | ||
c7715e47 AKD |
410 | desc = of_device_get_match_data(&pdev->dev); |
411 | if (!desc) | |
412 | return -EINVAL; | |
413 | ||
b9e718e9 BA |
414 | if (!qcom_scm_is_available()) |
415 | return -EPROBE_DEFER; | |
416 | ||
a5a4e02d SS |
417 | fw_name = desc->firmware_name; |
418 | ret = of_property_read_string(pdev->dev.of_node, "firmware-name", | |
419 | &fw_name); | |
420 | if (ret < 0 && ret != -EINVAL) | |
421 | return ret; | |
422 | ||
8ed8485c SG |
423 | if (desc->minidump_id) |
424 | ops = &adsp_minidump_ops; | |
425 | ||
426 | rproc = rproc_alloc(&pdev->dev, pdev->name, ops, fw_name, sizeof(*adsp)); | |
427 | ||
b9e718e9 BA |
428 | if (!rproc) { |
429 | dev_err(&pdev->dev, "unable to allocate remoteproc\n"); | |
430 | return -ENOMEM; | |
431 | } | |
432 | ||
b7ff96cc | 433 | rproc->auto_boot = desc->auto_boot; |
3898fc99 | 434 | rproc_coredump_set_elf_info(rproc, ELFCLASS32, EM_NONE); |
b7ff96cc | 435 | |
b9e718e9 BA |
436 | adsp = (struct qcom_adsp *)rproc->priv; |
437 | adsp->dev = &pdev->dev; | |
438 | adsp->rproc = rproc; | |
8ed8485c | 439 | adsp->minidump_id = desc->minidump_id; |
c7715e47 | 440 | adsp->pas_id = desc->pas_id; |
e323fc03 | 441 | adsp->has_aggre2_clk = desc->has_aggre2_clk; |
d4c78d21 | 442 | adsp->info_name = desc->sysmon_name; |
b9e718e9 BA |
443 | platform_set_drvdata(pdev, adsp); |
444 | ||
a781e5aa RB |
445 | device_wakeup_enable(adsp->dev); |
446 | ||
b9e718e9 BA |
447 | ret = adsp_alloc_memory_region(adsp); |
448 | if (ret) | |
449 | goto free_rproc; | |
450 | ||
f33a7358 SJ |
451 | ret = adsp_init_clock(adsp); |
452 | if (ret) | |
453 | goto free_rproc; | |
454 | ||
b9e718e9 BA |
455 | ret = adsp_init_regulator(adsp); |
456 | if (ret) | |
457 | goto free_rproc; | |
458 | ||
17ee2fb4 SS |
459 | ret = adsp_pds_attach(&pdev->dev, adsp->active_pds, |
460 | desc->active_pd_names); | |
461 | if (ret < 0) | |
462 | goto free_rproc; | |
463 | adsp->active_pd_count = ret; | |
464 | ||
465 | ret = adsp_pds_attach(&pdev->dev, adsp->proxy_pds, | |
466 | desc->proxy_pd_names); | |
467 | if (ret < 0) | |
468 | goto detach_active_pds; | |
469 | adsp->proxy_pd_count = ret; | |
470 | ||
6103b1a6 BA |
471 | ret = qcom_q6v5_init(&adsp->q6v5, pdev, rproc, desc->crash_reason_smem, |
472 | qcom_pas_handover); | |
473 | if (ret) | |
17ee2fb4 | 474 | goto detach_proxy_pds; |
b9e718e9 | 475 | |
cd9fc8f1 | 476 | qcom_add_glink_subdev(rproc, &adsp->glink_subdev, desc->ssr_name); |
4b48921a | 477 | qcom_add_smd_subdev(rproc, &adsp->smd_subdev); |
1e140df0 | 478 | qcom_add_ssr_subdev(rproc, &adsp->ssr_subdev, desc->ssr_name); |
1fb82ee8 BA |
479 | adsp->sysmon = qcom_add_sysmon_subdev(rproc, |
480 | desc->sysmon_name, | |
481 | desc->ssctl_id); | |
027045a6 SS |
482 | if (IS_ERR(adsp->sysmon)) { |
483 | ret = PTR_ERR(adsp->sysmon); | |
17ee2fb4 | 484 | goto detach_proxy_pds; |
027045a6 | 485 | } |
4b48921a | 486 | |
b9e718e9 BA |
487 | ret = rproc_add(rproc); |
488 | if (ret) | |
17ee2fb4 | 489 | goto detach_proxy_pds; |
b9e718e9 BA |
490 | |
491 | return 0; | |
492 | ||
17ee2fb4 SS |
493 | detach_proxy_pds: |
494 | adsp_pds_detach(adsp, adsp->proxy_pds, adsp->proxy_pd_count); | |
495 | detach_active_pds: | |
496 | adsp_pds_detach(adsp, adsp->active_pds, adsp->active_pd_count); | |
b9e718e9 | 497 | free_rproc: |
90a80d88 | 498 | rproc_free(rproc); |
b9e718e9 BA |
499 | |
500 | return ret; | |
501 | } | |
502 | ||
503 | static int adsp_remove(struct platform_device *pdev) | |
504 | { | |
505 | struct qcom_adsp *adsp = platform_get_drvdata(pdev); | |
506 | ||
b9e718e9 | 507 | rproc_del(adsp->rproc); |
4b48921a | 508 | |
eea07023 | 509 | qcom_remove_glink_subdev(adsp->rproc, &adsp->glink_subdev); |
1fb82ee8 | 510 | qcom_remove_sysmon_subdev(adsp->sysmon); |
4b48921a | 511 | qcom_remove_smd_subdev(adsp->rproc, &adsp->smd_subdev); |
1e140df0 | 512 | qcom_remove_ssr_subdev(adsp->rproc, &adsp->ssr_subdev); |
90a80d88 | 513 | rproc_free(adsp->rproc); |
b9e718e9 BA |
514 | |
515 | return 0; | |
516 | } | |
517 | ||
c7715e47 AKD |
518 | static const struct adsp_data adsp_resource_init = { |
519 | .crash_reason_smem = 423, | |
520 | .firmware_name = "adsp.mdt", | |
521 | .pas_id = 1, | |
e323fc03 | 522 | .has_aggre2_clk = false, |
b7ff96cc | 523 | .auto_boot = true, |
1e140df0 | 524 | .ssr_name = "lpass", |
1fb82ee8 BA |
525 | .sysmon_name = "adsp", |
526 | .ssctl_id = 0x14, | |
c7715e47 AKD |
527 | }; |
528 | ||
15f4ae1e SS |
529 | static const struct adsp_data sm8150_adsp_resource = { |
530 | .crash_reason_smem = 423, | |
531 | .firmware_name = "adsp.mdt", | |
532 | .pas_id = 1, | |
533 | .has_aggre2_clk = false, | |
b7ff96cc | 534 | .auto_boot = true, |
15f4ae1e SS |
535 | .active_pd_names = (char*[]){ |
536 | "load_state", | |
537 | NULL | |
538 | }, | |
539 | .proxy_pd_names = (char*[]){ | |
540 | "cx", | |
541 | NULL | |
542 | }, | |
543 | .ssr_name = "lpass", | |
544 | .sysmon_name = "adsp", | |
545 | .ssctl_id = 0x14, | |
546 | }; | |
547 | ||
f6da4831 BA |
548 | static const struct adsp_data sm8250_adsp_resource = { |
549 | .crash_reason_smem = 423, | |
550 | .firmware_name = "adsp.mdt", | |
551 | .pas_id = 1, | |
552 | .has_aggre2_clk = false, | |
553 | .auto_boot = true, | |
554 | .active_pd_names = (char*[]){ | |
555 | "load_state", | |
556 | NULL | |
557 | }, | |
558 | .proxy_pd_names = (char*[]){ | |
559 | "lcx", | |
560 | "lmx", | |
561 | NULL | |
562 | }, | |
563 | .ssr_name = "lpass", | |
564 | .sysmon_name = "adsp", | |
565 | .ssctl_id = 0x14, | |
566 | }; | |
567 | ||
e8b4e9a2 VK |
568 | static const struct adsp_data sm8350_adsp_resource = { |
569 | .crash_reason_smem = 423, | |
570 | .firmware_name = "adsp.mdt", | |
571 | .pas_id = 1, | |
572 | .has_aggre2_clk = false, | |
573 | .auto_boot = true, | |
574 | .active_pd_names = (char*[]){ | |
575 | "load_state", | |
576 | NULL | |
577 | }, | |
578 | .proxy_pd_names = (char*[]){ | |
579 | "lcx", | |
580 | "lmx", | |
581 | NULL | |
582 | }, | |
583 | .ssr_name = "lpass", | |
584 | .sysmon_name = "adsp", | |
585 | .ssctl_id = 0x14, | |
586 | }; | |
587 | ||
7c77e317 SS |
588 | static const struct adsp_data msm8998_adsp_resource = { |
589 | .crash_reason_smem = 423, | |
590 | .firmware_name = "adsp.mdt", | |
591 | .pas_id = 1, | |
592 | .has_aggre2_clk = false, | |
593 | .auto_boot = true, | |
594 | .proxy_pd_names = (char*[]){ | |
595 | "cx", | |
596 | NULL | |
597 | }, | |
598 | .ssr_name = "lpass", | |
599 | .sysmon_name = "adsp", | |
600 | .ssctl_id = 0x14, | |
601 | }; | |
602 | ||
3b0d1b65 BA |
603 | static const struct adsp_data cdsp_resource_init = { |
604 | .crash_reason_smem = 601, | |
605 | .firmware_name = "cdsp.mdt", | |
606 | .pas_id = 18, | |
607 | .has_aggre2_clk = false, | |
b7ff96cc | 608 | .auto_boot = true, |
3b0d1b65 BA |
609 | .ssr_name = "cdsp", |
610 | .sysmon_name = "cdsp", | |
611 | .ssctl_id = 0x17, | |
612 | }; | |
613 | ||
15f4ae1e SS |
614 | static const struct adsp_data sm8150_cdsp_resource = { |
615 | .crash_reason_smem = 601, | |
616 | .firmware_name = "cdsp.mdt", | |
617 | .pas_id = 18, | |
618 | .has_aggre2_clk = false, | |
b7ff96cc | 619 | .auto_boot = true, |
15f4ae1e SS |
620 | .active_pd_names = (char*[]){ |
621 | "load_state", | |
622 | NULL | |
623 | }, | |
624 | .proxy_pd_names = (char*[]){ | |
625 | "cx", | |
626 | NULL | |
627 | }, | |
628 | .ssr_name = "cdsp", | |
629 | .sysmon_name = "cdsp", | |
630 | .ssctl_id = 0x17, | |
631 | }; | |
632 | ||
f6da4831 BA |
633 | static const struct adsp_data sm8250_cdsp_resource = { |
634 | .crash_reason_smem = 601, | |
635 | .firmware_name = "cdsp.mdt", | |
636 | .pas_id = 18, | |
637 | .has_aggre2_clk = false, | |
638 | .auto_boot = true, | |
639 | .active_pd_names = (char*[]){ | |
640 | "load_state", | |
641 | NULL | |
642 | }, | |
643 | .proxy_pd_names = (char*[]){ | |
644 | "cx", | |
645 | NULL | |
646 | }, | |
647 | .ssr_name = "cdsp", | |
648 | .sysmon_name = "cdsp", | |
649 | .ssctl_id = 0x17, | |
650 | }; | |
651 | ||
e8b4e9a2 VK |
652 | static const struct adsp_data sm8350_cdsp_resource = { |
653 | .crash_reason_smem = 601, | |
654 | .firmware_name = "cdsp.mdt", | |
655 | .pas_id = 18, | |
656 | .has_aggre2_clk = false, | |
657 | .auto_boot = true, | |
658 | .active_pd_names = (char*[]){ | |
659 | "load_state", | |
660 | NULL | |
661 | }, | |
662 | .proxy_pd_names = (char*[]){ | |
663 | "cx", | |
664 | NULL | |
665 | }, | |
666 | .ssr_name = "cdsp", | |
667 | .sysmon_name = "cdsp", | |
668 | .ssctl_id = 0x17, | |
669 | }; | |
670 | ||
15f4ae1e SS |
671 | static const struct adsp_data mpss_resource_init = { |
672 | .crash_reason_smem = 421, | |
673 | .firmware_name = "modem.mdt", | |
674 | .pas_id = 4, | |
d2debca4 | 675 | .minidump_id = 3, |
15f4ae1e | 676 | .has_aggre2_clk = false, |
b7ff96cc | 677 | .auto_boot = false, |
15f4ae1e SS |
678 | .active_pd_names = (char*[]){ |
679 | "load_state", | |
680 | NULL | |
681 | }, | |
682 | .proxy_pd_names = (char*[]){ | |
683 | "cx", | |
684 | "mss", | |
685 | NULL | |
686 | }, | |
687 | .ssr_name = "mpss", | |
688 | .sysmon_name = "modem", | |
689 | .ssctl_id = 0x12, | |
690 | }; | |
691 | ||
90a068ed AKD |
692 | static const struct adsp_data slpi_resource_init = { |
693 | .crash_reason_smem = 424, | |
694 | .firmware_name = "slpi.mdt", | |
695 | .pas_id = 12, | |
696 | .has_aggre2_clk = true, | |
b7ff96cc | 697 | .auto_boot = true, |
1e140df0 | 698 | .ssr_name = "dsps", |
1fb82ee8 BA |
699 | .sysmon_name = "slpi", |
700 | .ssctl_id = 0x16, | |
90a068ed AKD |
701 | }; |
702 | ||
15f4ae1e SS |
703 | static const struct adsp_data sm8150_slpi_resource = { |
704 | .crash_reason_smem = 424, | |
705 | .firmware_name = "slpi.mdt", | |
706 | .pas_id = 12, | |
707 | .has_aggre2_clk = false, | |
b7ff96cc | 708 | .auto_boot = true, |
15f4ae1e SS |
709 | .active_pd_names = (char*[]){ |
710 | "load_state", | |
711 | NULL | |
712 | }, | |
713 | .proxy_pd_names = (char*[]){ | |
714 | "lcx", | |
715 | "lmx", | |
716 | NULL | |
717 | }, | |
718 | .ssr_name = "dsps", | |
719 | .sysmon_name = "slpi", | |
720 | .ssctl_id = 0x16, | |
721 | }; | |
722 | ||
f6da4831 BA |
723 | static const struct adsp_data sm8250_slpi_resource = { |
724 | .crash_reason_smem = 424, | |
725 | .firmware_name = "slpi.mdt", | |
726 | .pas_id = 12, | |
727 | .has_aggre2_clk = false, | |
728 | .auto_boot = true, | |
729 | .active_pd_names = (char*[]){ | |
730 | "load_state", | |
731 | NULL | |
732 | }, | |
733 | .proxy_pd_names = (char*[]){ | |
734 | "lcx", | |
735 | "lmx", | |
736 | NULL | |
737 | }, | |
738 | .ssr_name = "dsps", | |
739 | .sysmon_name = "slpi", | |
740 | .ssctl_id = 0x16, | |
741 | }; | |
742 | ||
e8b4e9a2 VK |
743 | static const struct adsp_data sm8350_slpi_resource = { |
744 | .crash_reason_smem = 424, | |
745 | .firmware_name = "slpi.mdt", | |
746 | .pas_id = 12, | |
747 | .has_aggre2_clk = false, | |
748 | .auto_boot = true, | |
749 | .active_pd_names = (char*[]){ | |
750 | "load_state", | |
751 | NULL | |
752 | }, | |
753 | .proxy_pd_names = (char*[]){ | |
754 | "lcx", | |
755 | "lmx", | |
756 | NULL | |
757 | }, | |
758 | .ssr_name = "dsps", | |
759 | .sysmon_name = "slpi", | |
760 | .ssctl_id = 0x16, | |
761 | }; | |
762 | ||
7c77e317 SS |
763 | static const struct adsp_data msm8998_slpi_resource = { |
764 | .crash_reason_smem = 424, | |
765 | .firmware_name = "slpi.mdt", | |
766 | .pas_id = 12, | |
767 | .has_aggre2_clk = true, | |
768 | .auto_boot = true, | |
769 | .proxy_pd_names = (char*[]){ | |
770 | "ssc_cx", | |
771 | NULL | |
772 | }, | |
773 | .ssr_name = "dsps", | |
774 | .sysmon_name = "slpi", | |
775 | .ssctl_id = 0x16, | |
776 | }; | |
777 | ||
0af93682 BA |
778 | static const struct adsp_data wcss_resource_init = { |
779 | .crash_reason_smem = 421, | |
780 | .firmware_name = "wcnss.mdt", | |
781 | .pas_id = 6, | |
b7ff96cc | 782 | .auto_boot = true, |
0af93682 BA |
783 | .ssr_name = "mpss", |
784 | .sysmon_name = "wcnss", | |
785 | .ssctl_id = 0x12, | |
786 | }; | |
787 | ||
3fdba9d2 MS |
788 | static const struct adsp_data sdx55_mpss_resource = { |
789 | .crash_reason_smem = 421, | |
790 | .firmware_name = "modem.mdt", | |
791 | .pas_id = 4, | |
792 | .has_aggre2_clk = false, | |
793 | .auto_boot = true, | |
794 | .proxy_pd_names = (char*[]){ | |
795 | "cx", | |
796 | "mss", | |
797 | NULL | |
798 | }, | |
799 | .ssr_name = "mpss", | |
800 | .sysmon_name = "modem", | |
801 | .ssctl_id = 0x22, | |
802 | }; | |
803 | ||
b9e718e9 | 804 | static const struct of_device_id adsp_of_match[] = { |
c7715e47 AKD |
805 | { .compatible = "qcom,msm8974-adsp-pil", .data = &adsp_resource_init}, |
806 | { .compatible = "qcom,msm8996-adsp-pil", .data = &adsp_resource_init}, | |
90a068ed | 807 | { .compatible = "qcom,msm8996-slpi-pil", .data = &slpi_resource_init}, |
7c77e317 SS |
808 | { .compatible = "qcom,msm8998-adsp-pas", .data = &msm8998_adsp_resource}, |
809 | { .compatible = "qcom,msm8998-slpi-pas", .data = &msm8998_slpi_resource}, | |
0af93682 BA |
810 | { .compatible = "qcom,qcs404-adsp-pas", .data = &adsp_resource_init }, |
811 | { .compatible = "qcom,qcs404-cdsp-pas", .data = &cdsp_resource_init }, | |
812 | { .compatible = "qcom,qcs404-wcss-pas", .data = &wcss_resource_init }, | |
620d70b0 | 813 | { .compatible = "qcom,sc7180-mpss-pas", .data = &mpss_resource_init}, |
3b0d1b65 BA |
814 | { .compatible = "qcom,sdm845-adsp-pas", .data = &adsp_resource_init}, |
815 | { .compatible = "qcom,sdm845-cdsp-pas", .data = &cdsp_resource_init}, | |
3fdba9d2 | 816 | { .compatible = "qcom,sdx55-mpss-pas", .data = &sdx55_mpss_resource}, |
15f4ae1e SS |
817 | { .compatible = "qcom,sm8150-adsp-pas", .data = &sm8150_adsp_resource}, |
818 | { .compatible = "qcom,sm8150-cdsp-pas", .data = &sm8150_cdsp_resource}, | |
819 | { .compatible = "qcom,sm8150-mpss-pas", .data = &mpss_resource_init}, | |
820 | { .compatible = "qcom,sm8150-slpi-pas", .data = &sm8150_slpi_resource}, | |
f6da4831 BA |
821 | { .compatible = "qcom,sm8250-adsp-pas", .data = &sm8250_adsp_resource}, |
822 | { .compatible = "qcom,sm8250-cdsp-pas", .data = &sm8250_cdsp_resource}, | |
823 | { .compatible = "qcom,sm8250-slpi-pas", .data = &sm8250_slpi_resource}, | |
e8b4e9a2 VK |
824 | { .compatible = "qcom,sm8350-adsp-pas", .data = &sm8350_adsp_resource}, |
825 | { .compatible = "qcom,sm8350-cdsp-pas", .data = &sm8350_cdsp_resource}, | |
826 | { .compatible = "qcom,sm8350-slpi-pas", .data = &sm8350_slpi_resource}, | |
827 | { .compatible = "qcom,sm8350-mpss-pas", .data = &mpss_resource_init}, | |
b9e718e9 BA |
828 | { }, |
829 | }; | |
62423472 | 830 | MODULE_DEVICE_TABLE(of, adsp_of_match); |
b9e718e9 BA |
831 | |
832 | static struct platform_driver adsp_driver = { | |
833 | .probe = adsp_probe, | |
834 | .remove = adsp_remove, | |
835 | .driver = { | |
9e004f97 | 836 | .name = "qcom_q6v5_pas", |
b9e718e9 BA |
837 | .of_match_table = adsp_of_match, |
838 | }, | |
839 | }; | |
840 | ||
841 | module_platform_driver(adsp_driver); | |
9e004f97 | 842 | MODULE_DESCRIPTION("Qualcomm Hexagon v5 Peripheral Authentication Service driver"); |
b9e718e9 | 843 | MODULE_LICENSE("GPL v2"); |