blob: ffe7456e77139e5d53b2545936dc937fa7df74cf [file] [log] [blame]
Pierre-Louis Bossarte149ca22020-05-01 09:58:50 -05001/* SPDX-License-Identifier: (GPL-2.0-only OR BSD-3-Clause) */
Liam Girdwoodd1d95fc2019-04-12 11:05:13 -05002/*
3 * This file is provided under a dual BSD/GPLv2 license. When using or
4 * redistributing this file, you may do so under either license.
5 *
6 * Copyright(c) 2018 Intel Corporation. All rights reserved.
7 *
8 * Author: Liam Girdwood <liam.r.girdwood@linux.intel.com>
9 */
10
11#ifndef __SOUND_SOC_SOF_IO_H
12#define __SOUND_SOC_SOF_IO_H
13
14#include <linux/device.h>
15#include <linux/interrupt.h>
16#include <linux/kernel.h>
17#include <linux/types.h>
18#include <sound/pcm.h>
19#include "sof-priv.h"
20
21#define sof_ops(sdev) \
22 ((sdev)->pdata->desc->ops)
23
24/* Mandatory operations are verified during probing */
25
26/* init */
27static inline int snd_sof_probe(struct snd_sof_dev *sdev)
28{
29 return sof_ops(sdev)->probe(sdev);
30}
31
32static inline int snd_sof_remove(struct snd_sof_dev *sdev)
33{
34 if (sof_ops(sdev)->remove)
35 return sof_ops(sdev)->remove(sdev);
36
37 return 0;
38}
39
Keyon Jie7edb3052021-01-13 17:26:14 +020040static inline int snd_sof_shutdown(struct snd_sof_dev *sdev)
41{
42 if (sof_ops(sdev)->shutdown)
43 return sof_ops(sdev)->shutdown(sdev);
44
45 return 0;
46}
47
Liam Girdwoodd1d95fc2019-04-12 11:05:13 -050048/* control */
49
50/*
51 * snd_sof_dsp_run returns the core mask of the cores that are available
52 * after successful fw boot
53 */
54static inline int snd_sof_dsp_run(struct snd_sof_dev *sdev)
55{
56 return sof_ops(sdev)->run(sdev);
57}
58
Fred Oha70eb702020-11-27 18:40:21 +020059static inline int snd_sof_dsp_stall(struct snd_sof_dev *sdev, unsigned int core_mask)
Liam Girdwoodd1d95fc2019-04-12 11:05:13 -050060{
61 if (sof_ops(sdev)->stall)
Fred Oha70eb702020-11-27 18:40:21 +020062 return sof_ops(sdev)->stall(sdev, core_mask);
Liam Girdwoodd1d95fc2019-04-12 11:05:13 -050063
64 return 0;
65}
66
67static inline int snd_sof_dsp_reset(struct snd_sof_dev *sdev)
68{
69 if (sof_ops(sdev)->reset)
70 return sof_ops(sdev)->reset(sdev);
71
72 return 0;
73}
74
Ranjani Sridharan9ea80742021-11-19 21:26:20 +020075/* dsp core get/put */
Ranjani Sridharanc414d5d2021-11-19 21:26:14 +020076static inline int snd_sof_dsp_core_get(struct snd_sof_dev *sdev, int core)
77{
78 if (core > sdev->num_cores - 1) {
79 dev_err(sdev->dev, "invalid core id: %d for num_cores: %d\n", core,
80 sdev->num_cores);
81 return -EINVAL;
82 }
83
84 if (sof_ops(sdev)->core_get) {
85 int ret;
86
87 /* if current ref_count is > 0, increment it and return */
88 if (sdev->dsp_core_ref_count[core] > 0) {
89 sdev->dsp_core_ref_count[core]++;
90 return 0;
91 }
92
93 /* power up the core */
94 ret = sof_ops(sdev)->core_get(sdev, core);
95 if (ret < 0)
96 return ret;
97
98 /* increment ref_count */
99 sdev->dsp_core_ref_count[core]++;
100
101 /* and update enabled_cores_mask */
102 sdev->enabled_cores_mask |= BIT(core);
103
104 dev_dbg(sdev->dev, "Core %d powered up\n", core);
105 }
106
107 return 0;
108}
109
110static inline int snd_sof_dsp_core_put(struct snd_sof_dev *sdev, int core)
111{
112 if (core > sdev->num_cores - 1) {
113 dev_err(sdev->dev, "invalid core id: %d for num_cores: %d\n", core,
114 sdev->num_cores);
115 return -EINVAL;
116 }
117
118 if (sof_ops(sdev)->core_put) {
119 int ret;
120
121 /* decrement ref_count and return if it is > 0 */
122 if (--(sdev->dsp_core_ref_count[core]) > 0)
123 return 0;
124
125 /* power down the core */
126 ret = sof_ops(sdev)->core_put(sdev, core);
127 if (ret < 0)
128 return ret;
129
130 /* and update enabled_cores_mask */
131 sdev->enabled_cores_mask &= ~BIT(core);
132
133 dev_dbg(sdev->dev, "Core %d powered down\n", core);
134 }
135
136 return 0;
137}
138
Liam Girdwoodd1d95fc2019-04-12 11:05:13 -0500139/* pre/post fw load */
140static inline int snd_sof_dsp_pre_fw_run(struct snd_sof_dev *sdev)
141{
142 if (sof_ops(sdev)->pre_fw_run)
143 return sof_ops(sdev)->pre_fw_run(sdev);
144
145 return 0;
146}
147
148static inline int snd_sof_dsp_post_fw_run(struct snd_sof_dev *sdev)
149{
150 if (sof_ops(sdev)->post_fw_run)
151 return sof_ops(sdev)->post_fw_run(sdev);
152
153 return 0;
154}
155
Fred Ohe984f3ef2020-11-27 18:40:18 +0200156/* parse platform specific extended manifest */
157static inline int snd_sof_dsp_parse_platform_ext_manifest(struct snd_sof_dev *sdev,
158 const struct sof_ext_man_elem_header *hdr)
159{
160 if (sof_ops(sdev)->parse_platform_ext_manifest)
161 return sof_ops(sdev)->parse_platform_ext_manifest(sdev, hdr);
162
163 return 0;
164}
165
Daniel Balutace8234a2019-07-22 09:13:47 -0500166/* misc */
167
168/**
169 * snd_sof_dsp_get_bar_index - Maps a section type with a BAR index
170 *
171 * @sdev: sof device
172 * @type: section type as described by snd_sof_fw_blk_type
173 *
174 * Returns the corresponding BAR index (a positive integer) or -EINVAL
175 * in case there is no mapping
176 */
177static inline int snd_sof_dsp_get_bar_index(struct snd_sof_dev *sdev, u32 type)
178{
179 if (sof_ops(sdev)->get_bar_index)
180 return sof_ops(sdev)->get_bar_index(sdev, type);
181
182 return sdev->mmio_bar;
183}
184
Daniel Balutabb9c93f2019-08-07 10:01:59 -0500185static inline int snd_sof_dsp_get_mailbox_offset(struct snd_sof_dev *sdev)
186{
187 if (sof_ops(sdev)->get_mailbox_offset)
188 return sof_ops(sdev)->get_mailbox_offset(sdev);
189
190 dev_err(sdev->dev, "error: %s not defined\n", __func__);
191 return -ENOTSUPP;
192}
193
Daniel Balutae17422c2019-08-07 10:02:00 -0500194static inline int snd_sof_dsp_get_window_offset(struct snd_sof_dev *sdev,
195 u32 id)
196{
197 if (sof_ops(sdev)->get_window_offset)
198 return sof_ops(sdev)->get_window_offset(sdev, id);
199
200 dev_err(sdev->dev, "error: %s not defined\n", __func__);
201 return -ENOTSUPP;
202}
Liam Girdwoodd1d95fc2019-04-12 11:05:13 -0500203/* power management */
204static inline int snd_sof_dsp_resume(struct snd_sof_dev *sdev)
205{
206 if (sof_ops(sdev)->resume)
207 return sof_ops(sdev)->resume(sdev);
208
209 return 0;
210}
211
Ranjani Sridharan61e285c2020-01-29 16:07:22 -0600212static inline int snd_sof_dsp_suspend(struct snd_sof_dev *sdev,
213 u32 target_state)
Liam Girdwoodd1d95fc2019-04-12 11:05:13 -0500214{
215 if (sof_ops(sdev)->suspend)
Ranjani Sridharan61e285c2020-01-29 16:07:22 -0600216 return sof_ops(sdev)->suspend(sdev, target_state);
Liam Girdwoodd1d95fc2019-04-12 11:05:13 -0500217
218 return 0;
219}
220
221static inline int snd_sof_dsp_runtime_resume(struct snd_sof_dev *sdev)
222{
223 if (sof_ops(sdev)->runtime_resume)
224 return sof_ops(sdev)->runtime_resume(sdev);
225
226 return 0;
227}
228
Fred Oh1c38c922019-07-22 09:13:50 -0500229static inline int snd_sof_dsp_runtime_suspend(struct snd_sof_dev *sdev)
Liam Girdwoodd1d95fc2019-04-12 11:05:13 -0500230{
231 if (sof_ops(sdev)->runtime_suspend)
Fred Oh1c38c922019-07-22 09:13:50 -0500232 return sof_ops(sdev)->runtime_suspend(sdev);
Liam Girdwoodd1d95fc2019-04-12 11:05:13 -0500233
234 return 0;
235}
236
Kai Vehmanen62fde972019-07-02 16:24:27 +0300237static inline int snd_sof_dsp_runtime_idle(struct snd_sof_dev *sdev)
238{
239 if (sof_ops(sdev)->runtime_idle)
240 return sof_ops(sdev)->runtime_idle(sdev);
241
242 return 0;
243}
244
Ranjani Sridharan7077a072019-06-12 12:23:38 -0500245static inline int snd_sof_dsp_hw_params_upon_resume(struct snd_sof_dev *sdev)
Ranjani Sridharaned3baac2019-04-30 18:09:31 -0500246{
247 if (sof_ops(sdev)->set_hw_params_upon_resume)
Ranjani Sridharan7077a072019-06-12 12:23:38 -0500248 return sof_ops(sdev)->set_hw_params_upon_resume(sdev);
249 return 0;
Ranjani Sridharaned3baac2019-04-30 18:09:31 -0500250}
251
Liam Girdwoodd1d95fc2019-04-12 11:05:13 -0500252static inline int snd_sof_dsp_set_clk(struct snd_sof_dev *sdev, u32 freq)
253{
254 if (sof_ops(sdev)->set_clk)
255 return sof_ops(sdev)->set_clk(sdev, freq);
256
257 return 0;
258}
259
Ranjani Sridharan61e285c2020-01-29 16:07:22 -0600260static inline int
261snd_sof_dsp_set_power_state(struct snd_sof_dev *sdev,
262 const struct sof_dsp_power_state *target_state)
Keyon Jiee8f112d2019-10-25 17:40:59 -0500263{
Keyon Jie8b66d7c2021-01-05 17:56:40 +0200264 int ret = 0;
Keyon Jiee8f112d2019-10-25 17:40:59 -0500265
Keyon Jie8b66d7c2021-01-05 17:56:40 +0200266 mutex_lock(&sdev->power_state_access);
267
268 if (sof_ops(sdev)->set_power_state)
269 ret = sof_ops(sdev)->set_power_state(sdev, target_state);
270
271 mutex_unlock(&sdev->power_state_access);
272
273 return ret;
Keyon Jiee8f112d2019-10-25 17:40:59 -0500274}
275
Liam Girdwoodd1d95fc2019-04-12 11:05:13 -0500276/* debug */
Peter Ujfalusi2f148432021-12-23 13:36:14 +0200277void snd_sof_dsp_dbg_dump(struct snd_sof_dev *sdev, const char *msg, u32 flags);
Pan Xiuli5e4a27f2019-04-30 18:09:32 -0500278
Peter Ujfalusi07e833b2021-09-15 15:21:12 +0300279static inline int snd_sof_debugfs_add_region_item(struct snd_sof_dev *sdev,
280 enum snd_sof_fw_blk_type blk_type, u32 offset, size_t size,
281 const char *name, enum sof_debugfs_access_type access_type)
282{
283 if (sof_ops(sdev) && sof_ops(sdev)->debugfs_add_region_item)
284 return sof_ops(sdev)->debugfs_add_region_item(sdev, blk_type, offset,
285 size, name, access_type);
286
287 return 0;
288}
289
Liam Girdwoodd1d95fc2019-04-12 11:05:13 -0500290/* register IO */
291static inline void snd_sof_dsp_write(struct snd_sof_dev *sdev, u32 bar,
292 u32 offset, u32 value)
293{
294 if (sof_ops(sdev)->write) {
295 sof_ops(sdev)->write(sdev, sdev->bar[bar] + offset, value);
296 return;
297 }
298
299 dev_err_ratelimited(sdev->dev, "error: %s not defined\n", __func__);
300}
301
302static inline void snd_sof_dsp_write64(struct snd_sof_dev *sdev, u32 bar,
303 u32 offset, u64 value)
304{
305 if (sof_ops(sdev)->write64) {
306 sof_ops(sdev)->write64(sdev, sdev->bar[bar] + offset, value);
307 return;
308 }
309
310 dev_err_ratelimited(sdev->dev, "error: %s not defined\n", __func__);
311}
312
313static inline u32 snd_sof_dsp_read(struct snd_sof_dev *sdev, u32 bar,
314 u32 offset)
315{
316 if (sof_ops(sdev)->read)
317 return sof_ops(sdev)->read(sdev, sdev->bar[bar] + offset);
318
319 dev_err(sdev->dev, "error: %s not defined\n", __func__);
320 return -ENOTSUPP;
321}
322
323static inline u64 snd_sof_dsp_read64(struct snd_sof_dev *sdev, u32 bar,
324 u32 offset)
325{
326 if (sof_ops(sdev)->read64)
327 return sof_ops(sdev)->read64(sdev, sdev->bar[bar] + offset);
328
329 dev_err(sdev->dev, "error: %s not defined\n", __func__);
330 return -ENOTSUPP;
331}
332
333/* block IO */
Peter Ujfalusi4624bb22021-09-15 15:21:11 +0300334static inline int snd_sof_dsp_block_read(struct snd_sof_dev *sdev,
335 enum snd_sof_fw_blk_type blk_type,
336 u32 offset, void *dest, size_t bytes)
Liam Girdwoodd1d95fc2019-04-12 11:05:13 -0500337{
Peter Ujfalusi4624bb22021-09-15 15:21:11 +0300338 return sof_ops(sdev)->block_read(sdev, blk_type, offset, dest, bytes);
Liam Girdwoodd1d95fc2019-04-12 11:05:13 -0500339}
340
Peter Ujfalusi4624bb22021-09-15 15:21:11 +0300341static inline int snd_sof_dsp_block_write(struct snd_sof_dev *sdev,
342 enum snd_sof_fw_blk_type blk_type,
343 u32 offset, void *src, size_t bytes)
Liam Girdwoodd1d95fc2019-04-12 11:05:13 -0500344{
Peter Ujfalusi4624bb22021-09-15 15:21:11 +0300345 return sof_ops(sdev)->block_write(sdev, blk_type, offset, src, bytes);
Liam Girdwoodd1d95fc2019-04-12 11:05:13 -0500346}
347
Daniel Balutaf71f59d2021-10-04 18:21:44 +0300348/* mailbox IO */
349static inline void snd_sof_dsp_mailbox_read(struct snd_sof_dev *sdev,
350 u32 offset, void *dest, size_t bytes)
351{
352 if (sof_ops(sdev)->mailbox_read)
353 sof_ops(sdev)->mailbox_read(sdev, offset, dest, bytes);
354}
355
356static inline void snd_sof_dsp_mailbox_write(struct snd_sof_dev *sdev,
357 u32 offset, void *src, size_t bytes)
358{
359 if (sof_ops(sdev)->mailbox_write)
360 sof_ops(sdev)->mailbox_write(sdev, offset, src, bytes);
361}
362
Liam Girdwoodd1d95fc2019-04-12 11:05:13 -0500363/* ipc */
364static inline int snd_sof_dsp_send_msg(struct snd_sof_dev *sdev,
365 struct snd_sof_ipc_msg *msg)
366{
367 return sof_ops(sdev)->send_msg(sdev, msg);
368}
369
370/* host DMA trace */
371static inline int snd_sof_dma_trace_init(struct snd_sof_dev *sdev,
372 u32 *stream_tag)
373{
374 if (sof_ops(sdev)->trace_init)
375 return sof_ops(sdev)->trace_init(sdev, stream_tag);
376
377 return 0;
378}
379
380static inline int snd_sof_dma_trace_release(struct snd_sof_dev *sdev)
381{
382 if (sof_ops(sdev)->trace_release)
383 return sof_ops(sdev)->trace_release(sdev);
384
385 return 0;
386}
387
388static inline int snd_sof_dma_trace_trigger(struct snd_sof_dev *sdev, int cmd)
389{
390 if (sof_ops(sdev)->trace_trigger)
391 return sof_ops(sdev)->trace_trigger(sdev, cmd);
392
393 return 0;
394}
395
396/* host PCM ops */
397static inline int
398snd_sof_pcm_platform_open(struct snd_sof_dev *sdev,
399 struct snd_pcm_substream *substream)
400{
401 if (sof_ops(sdev) && sof_ops(sdev)->pcm_open)
402 return sof_ops(sdev)->pcm_open(sdev, substream);
403
404 return 0;
405}
406
407/* disconnect pcm substream to a host stream */
408static inline int
409snd_sof_pcm_platform_close(struct snd_sof_dev *sdev,
410 struct snd_pcm_substream *substream)
411{
412 if (sof_ops(sdev) && sof_ops(sdev)->pcm_close)
413 return sof_ops(sdev)->pcm_close(sdev, substream);
414
415 return 0;
416}
417
418/* host stream hw params */
419static inline int
420snd_sof_pcm_platform_hw_params(struct snd_sof_dev *sdev,
421 struct snd_pcm_substream *substream,
422 struct snd_pcm_hw_params *params,
423 struct sof_ipc_stream_params *ipc_params)
424{
425 if (sof_ops(sdev) && sof_ops(sdev)->pcm_hw_params)
426 return sof_ops(sdev)->pcm_hw_params(sdev, substream,
427 params, ipc_params);
428
429 return 0;
430}
431
Ranjani Sridharan93146bc2019-06-12 12:23:39 -0500432/* host stream hw free */
433static inline int
434snd_sof_pcm_platform_hw_free(struct snd_sof_dev *sdev,
435 struct snd_pcm_substream *substream)
436{
437 if (sof_ops(sdev) && sof_ops(sdev)->pcm_hw_free)
438 return sof_ops(sdev)->pcm_hw_free(sdev, substream);
439
440 return 0;
441}
442
Liam Girdwoodd1d95fc2019-04-12 11:05:13 -0500443/* host stream trigger */
444static inline int
445snd_sof_pcm_platform_trigger(struct snd_sof_dev *sdev,
446 struct snd_pcm_substream *substream, int cmd)
447{
448 if (sof_ops(sdev) && sof_ops(sdev)->pcm_trigger)
449 return sof_ops(sdev)->pcm_trigger(sdev, substream, cmd);
450
451 return 0;
452}
453
Peter Ujfalusi96ec1742021-09-14 15:53:56 +0300454/* Firmware loading */
455static inline int snd_sof_load_firmware(struct snd_sof_dev *sdev)
456{
457 dev_dbg(sdev->dev, "loading firmware\n");
458
459 return sof_ops(sdev)->load_firmware(sdev);
460}
461
Liam Girdwoodd1d95fc2019-04-12 11:05:13 -0500462/* host DSP message data */
Guennadi Liakhovetski6a0ba072021-09-28 13:35:16 +0300463static inline int snd_sof_ipc_msg_data(struct snd_sof_dev *sdev,
464 struct snd_pcm_substream *substream,
465 void *p, size_t sz)
Liam Girdwoodd1d95fc2019-04-12 11:05:13 -0500466{
Guennadi Liakhovetski6a0ba072021-09-28 13:35:16 +0300467 return sof_ops(sdev)->ipc_msg_data(sdev, substream, p, sz);
Liam Girdwoodd1d95fc2019-04-12 11:05:13 -0500468}
469
470/* host configure DSP HW parameters */
471static inline int
472snd_sof_ipc_pcm_params(struct snd_sof_dev *sdev,
473 struct snd_pcm_substream *substream,
474 const struct sof_ipc_pcm_params_reply *reply)
475{
476 return sof_ops(sdev)->ipc_pcm_params(sdev, substream, reply);
477}
478
479/* host stream pointer */
480static inline snd_pcm_uframes_t
481snd_sof_pcm_platform_pointer(struct snd_sof_dev *sdev,
482 struct snd_pcm_substream *substream)
483{
484 if (sof_ops(sdev) && sof_ops(sdev)->pcm_pointer)
485 return sof_ops(sdev)->pcm_pointer(sdev, substream);
486
487 return 0;
488}
489
Ranjani Sridharan4a39ea32021-11-19 17:08:51 -0600490/* pcm ack */
491static inline int snd_sof_pcm_platform_ack(struct snd_sof_dev *sdev,
492 struct snd_pcm_substream *substream)
493{
494 if (sof_ops(sdev) && sof_ops(sdev)->pcm_ack)
495 return sof_ops(sdev)->pcm_ack(sdev, substream);
496
497 return 0;
498}
499
Cezary Rojewskie145e9a2020-02-18 15:39:20 +0100500#if IS_ENABLED(CONFIG_SND_SOC_SOF_DEBUG_PROBES)
501static inline int
502snd_sof_probe_compr_assign(struct snd_sof_dev *sdev,
503 struct snd_compr_stream *cstream, struct snd_soc_dai *dai)
504{
505 return sof_ops(sdev)->probe_assign(sdev, cstream, dai);
506}
507
508static inline int
509snd_sof_probe_compr_free(struct snd_sof_dev *sdev,
510 struct snd_compr_stream *cstream, struct snd_soc_dai *dai)
511{
512 return sof_ops(sdev)->probe_free(sdev, cstream, dai);
513}
514
515static inline int
516snd_sof_probe_compr_set_params(struct snd_sof_dev *sdev,
517 struct snd_compr_stream *cstream,
518 struct snd_compr_params *params, struct snd_soc_dai *dai)
519{
520 return sof_ops(sdev)->probe_set_params(sdev, cstream, params, dai);
521}
522
523static inline int
524snd_sof_probe_compr_trigger(struct snd_sof_dev *sdev,
525 struct snd_compr_stream *cstream, int cmd,
526 struct snd_soc_dai *dai)
527{
528 return sof_ops(sdev)->probe_trigger(sdev, cstream, cmd, dai);
529}
530
531static inline int
532snd_sof_probe_compr_pointer(struct snd_sof_dev *sdev,
533 struct snd_compr_stream *cstream,
534 struct snd_compr_tstamp *tstamp, struct snd_soc_dai *dai)
535{
536 if (sof_ops(sdev) && sof_ops(sdev)->probe_pointer)
537 return sof_ops(sdev)->probe_pointer(sdev, cstream, tstamp, dai);
538
539 return 0;
540}
541#endif
542
Daniel Baluta285880a2019-12-04 15:15:53 -0600543/* machine driver */
544static inline int
545snd_sof_machine_register(struct snd_sof_dev *sdev, void *pdata)
546{
547 if (sof_ops(sdev) && sof_ops(sdev)->machine_register)
548 return sof_ops(sdev)->machine_register(sdev, pdata);
549
550 return 0;
551}
552
553static inline void
554snd_sof_machine_unregister(struct snd_sof_dev *sdev, void *pdata)
555{
556 if (sof_ops(sdev) && sof_ops(sdev)->machine_unregister)
557 sof_ops(sdev)->machine_unregister(sdev, pdata);
558}
559
Guennadi Liakhovetskicb515f12021-12-16 17:24:20 -0600560static inline struct snd_soc_acpi_mach *
Daniel Baluta285880a2019-12-04 15:15:53 -0600561snd_sof_machine_select(struct snd_sof_dev *sdev)
562{
563 if (sof_ops(sdev) && sof_ops(sdev)->machine_select)
Guennadi Liakhovetskicb515f12021-12-16 17:24:20 -0600564 return sof_ops(sdev)->machine_select(sdev);
565
566 return NULL;
Daniel Baluta285880a2019-12-04 15:15:53 -0600567}
568
569static inline void
Guennadi Liakhovetskicb515f12021-12-16 17:24:20 -0600570snd_sof_set_mach_params(struct snd_soc_acpi_mach *mach,
Pierre-Louis Bossart17e9d6b2021-04-09 15:01:18 -0700571 struct snd_sof_dev *sdev)
Daniel Baluta285880a2019-12-04 15:15:53 -0600572{
Daniel Baluta285880a2019-12-04 15:15:53 -0600573 if (sof_ops(sdev) && sof_ops(sdev)->set_mach_params)
Pierre-Louis Bossart17e9d6b2021-04-09 15:01:18 -0700574 sof_ops(sdev)->set_mach_params(mach, sdev);
Daniel Baluta285880a2019-12-04 15:15:53 -0600575}
576
Liam Girdwoodd1d95fc2019-04-12 11:05:13 -0500577/**
578 * snd_sof_dsp_register_poll_timeout - Periodically poll an address
579 * until a condition is met or a timeout occurs
580 * @op: accessor function (takes @addr as its only argument)
581 * @addr: Address to poll
582 * @val: Variable to read the value into
583 * @cond: Break condition (usually involving @val)
584 * @sleep_us: Maximum time to sleep between reads in us (0
585 * tight-loops). Should be less than ~20ms since usleep_range
Mauro Carvalho Chehab458f69e2019-06-12 14:53:00 -0300586 * is used (see Documentation/timers/timers-howto.rst).
Liam Girdwoodd1d95fc2019-04-12 11:05:13 -0500587 * @timeout_us: Timeout in us, 0 means never timeout
588 *
589 * Returns 0 on success and -ETIMEDOUT upon a timeout. In either
590 * case, the last read value at @addr is stored in @val. Must not
591 * be called from atomic context if sleep_us or timeout_us are used.
592 *
593 * This is modelled after the readx_poll_timeout macros in linux/iopoll.h.
594 */
595#define snd_sof_dsp_read_poll_timeout(sdev, bar, offset, val, cond, sleep_us, timeout_us) \
596({ \
597 u64 __timeout_us = (timeout_us); \
598 unsigned long __sleep_us = (sleep_us); \
599 ktime_t __timeout = ktime_add_us(ktime_get(), __timeout_us); \
600 might_sleep_if((__sleep_us) != 0); \
601 for (;;) { \
602 (val) = snd_sof_dsp_read(sdev, bar, offset); \
603 if (cond) { \
604 dev_dbg(sdev->dev, \
Keyon Jie3b2e93e2021-05-21 12:28:00 +0300605 "FW Poll Status: reg[%#x]=%#x successful\n", \
606 (offset), (val)); \
Liam Girdwoodd1d95fc2019-04-12 11:05:13 -0500607 break; \
608 } \
609 if (__timeout_us && \
610 ktime_compare(ktime_get(), __timeout) > 0) { \
611 (val) = snd_sof_dsp_read(sdev, bar, offset); \
612 dev_dbg(sdev->dev, \
Keyon Jie3b2e93e2021-05-21 12:28:00 +0300613 "FW Poll Status: reg[%#x]=%#x timedout\n", \
614 (offset), (val)); \
Liam Girdwoodd1d95fc2019-04-12 11:05:13 -0500615 break; \
616 } \
617 if (__sleep_us) \
618 usleep_range((__sleep_us >> 2) + 1, __sleep_us); \
619 } \
620 (cond) ? 0 : -ETIMEDOUT; \
621})
622
623/* This is for registers bits with attribute RWC */
624bool snd_sof_pci_update_bits(struct snd_sof_dev *sdev, u32 offset,
625 u32 mask, u32 value);
626
627bool snd_sof_dsp_update_bits_unlocked(struct snd_sof_dev *sdev, u32 bar,
628 u32 offset, u32 mask, u32 value);
629
630bool snd_sof_dsp_update_bits64_unlocked(struct snd_sof_dev *sdev, u32 bar,
631 u32 offset, u64 mask, u64 value);
632
633bool snd_sof_dsp_update_bits(struct snd_sof_dev *sdev, u32 bar, u32 offset,
634 u32 mask, u32 value);
635
636bool snd_sof_dsp_update_bits64(struct snd_sof_dev *sdev, u32 bar,
637 u32 offset, u64 mask, u64 value);
638
639void snd_sof_dsp_update_bits_forced(struct snd_sof_dev *sdev, u32 bar,
640 u32 offset, u32 mask, u32 value);
641
642int snd_sof_dsp_register_poll(struct snd_sof_dev *sdev, u32 bar, u32 offset,
643 u32 mask, u32 target, u32 timeout_ms,
644 u32 interval_us);
645
Peter Ujfalusib2b10aa2021-12-23 13:36:13 +0200646void snd_sof_dsp_panic(struct snd_sof_dev *sdev, u32 offset, bool non_recoverable);
Liam Girdwoodd1d95fc2019-04-12 11:05:13 -0500647#endif