xref: /openbmc/linux/sound/soc/sof/ops.h (revision c414d5df9d05471aa47f50fca7fa4412daca7ac7)
1e149ca29SPierre-Louis Bossart /* SPDX-License-Identifier: (GPL-2.0-only OR BSD-3-Clause) */
2d1d95fcbSLiam Girdwood /*
3d1d95fcbSLiam Girdwood  * This file is provided under a dual BSD/GPLv2 license.  When using or
4d1d95fcbSLiam Girdwood  * redistributing this file, you may do so under either license.
5d1d95fcbSLiam Girdwood  *
6d1d95fcbSLiam Girdwood  * Copyright(c) 2018 Intel Corporation. All rights reserved.
7d1d95fcbSLiam Girdwood  *
8d1d95fcbSLiam Girdwood  * Author: Liam Girdwood <liam.r.girdwood@linux.intel.com>
9d1d95fcbSLiam Girdwood  */
10d1d95fcbSLiam Girdwood 
11d1d95fcbSLiam Girdwood #ifndef __SOUND_SOC_SOF_IO_H
12d1d95fcbSLiam Girdwood #define __SOUND_SOC_SOF_IO_H
13d1d95fcbSLiam Girdwood 
14d1d95fcbSLiam Girdwood #include <linux/device.h>
15d1d95fcbSLiam Girdwood #include <linux/interrupt.h>
16d1d95fcbSLiam Girdwood #include <linux/kernel.h>
17d1d95fcbSLiam Girdwood #include <linux/types.h>
18d1d95fcbSLiam Girdwood #include <sound/pcm.h>
19d1d95fcbSLiam Girdwood #include "sof-priv.h"
20d1d95fcbSLiam Girdwood 
21d1d95fcbSLiam Girdwood #define sof_ops(sdev) \
22d1d95fcbSLiam Girdwood 	((sdev)->pdata->desc->ops)
23d1d95fcbSLiam Girdwood 
24d1d95fcbSLiam Girdwood /* Mandatory operations are verified during probing */
25d1d95fcbSLiam Girdwood 
26d1d95fcbSLiam Girdwood /* init */
27d1d95fcbSLiam Girdwood static inline int snd_sof_probe(struct snd_sof_dev *sdev)
28d1d95fcbSLiam Girdwood {
29d1d95fcbSLiam Girdwood 	return sof_ops(sdev)->probe(sdev);
30d1d95fcbSLiam Girdwood }
31d1d95fcbSLiam Girdwood 
32d1d95fcbSLiam Girdwood static inline int snd_sof_remove(struct snd_sof_dev *sdev)
33d1d95fcbSLiam Girdwood {
34d1d95fcbSLiam Girdwood 	if (sof_ops(sdev)->remove)
35d1d95fcbSLiam Girdwood 		return sof_ops(sdev)->remove(sdev);
36d1d95fcbSLiam Girdwood 
37d1d95fcbSLiam Girdwood 	return 0;
38d1d95fcbSLiam Girdwood }
39d1d95fcbSLiam Girdwood 
407edb3051SKeyon Jie static inline int snd_sof_shutdown(struct snd_sof_dev *sdev)
417edb3051SKeyon Jie {
427edb3051SKeyon Jie 	if (sof_ops(sdev)->shutdown)
437edb3051SKeyon Jie 		return sof_ops(sdev)->shutdown(sdev);
447edb3051SKeyon Jie 
457edb3051SKeyon Jie 	return 0;
467edb3051SKeyon Jie }
477edb3051SKeyon Jie 
48d1d95fcbSLiam Girdwood /* control */
49d1d95fcbSLiam Girdwood 
50d1d95fcbSLiam Girdwood /*
51d1d95fcbSLiam Girdwood  * snd_sof_dsp_run returns the core mask of the cores that are available
52d1d95fcbSLiam Girdwood  * after successful fw boot
53d1d95fcbSLiam Girdwood  */
54d1d95fcbSLiam Girdwood static inline int snd_sof_dsp_run(struct snd_sof_dev *sdev)
55d1d95fcbSLiam Girdwood {
56d1d95fcbSLiam Girdwood 	return sof_ops(sdev)->run(sdev);
57d1d95fcbSLiam Girdwood }
58d1d95fcbSLiam Girdwood 
59a70eb708SFred Oh static inline int snd_sof_dsp_stall(struct snd_sof_dev *sdev, unsigned int core_mask)
60d1d95fcbSLiam Girdwood {
61d1d95fcbSLiam Girdwood 	if (sof_ops(sdev)->stall)
62a70eb708SFred Oh 		return sof_ops(sdev)->stall(sdev, core_mask);
63d1d95fcbSLiam Girdwood 
64d1d95fcbSLiam Girdwood 	return 0;
65d1d95fcbSLiam Girdwood }
66d1d95fcbSLiam Girdwood 
67d1d95fcbSLiam Girdwood static inline int snd_sof_dsp_reset(struct snd_sof_dev *sdev)
68d1d95fcbSLiam Girdwood {
69d1d95fcbSLiam Girdwood 	if (sof_ops(sdev)->reset)
70d1d95fcbSLiam Girdwood 		return sof_ops(sdev)->reset(sdev);
71d1d95fcbSLiam Girdwood 
72d1d95fcbSLiam Girdwood 	return 0;
73d1d95fcbSLiam Girdwood }
74d1d95fcbSLiam Girdwood 
75d1d95fcbSLiam Girdwood /* dsp core power up/power down */
76d1d95fcbSLiam Girdwood static inline int snd_sof_dsp_core_power_up(struct snd_sof_dev *sdev,
77d1d95fcbSLiam Girdwood 					    unsigned int core_mask)
78d1d95fcbSLiam Girdwood {
7942077f08SBard Liao 	int ret = 0;
80d1d95fcbSLiam Girdwood 
8130876e2aSBard Liao 	core_mask &= ~sdev->enabled_cores_mask;
8230876e2aSBard Liao 	if (sof_ops(sdev)->core_power_up && core_mask) {
8342077f08SBard Liao 		ret = sof_ops(sdev)->core_power_up(sdev, core_mask);
8442077f08SBard Liao 		if (!ret)
8542077f08SBard Liao 			sdev->enabled_cores_mask |= core_mask;
8642077f08SBard Liao 	}
8742077f08SBard Liao 
8842077f08SBard Liao 	return ret;
89d1d95fcbSLiam Girdwood }
90d1d95fcbSLiam Girdwood 
91d1d95fcbSLiam Girdwood static inline int snd_sof_dsp_core_power_down(struct snd_sof_dev *sdev,
92d1d95fcbSLiam Girdwood 					      unsigned int core_mask)
93d1d95fcbSLiam Girdwood {
9442077f08SBard Liao 	int ret = 0;
95d1d95fcbSLiam Girdwood 
9630876e2aSBard Liao 	core_mask &= sdev->enabled_cores_mask;
9730876e2aSBard Liao 	if (sof_ops(sdev)->core_power_down && core_mask) {
9842077f08SBard Liao 		ret = sof_ops(sdev)->core_power_down(sdev, core_mask);
9942077f08SBard Liao 		if (!ret)
10042077f08SBard Liao 			sdev->enabled_cores_mask &= ~core_mask;
10142077f08SBard Liao 	}
10242077f08SBard Liao 
10342077f08SBard Liao 	return ret;
104d1d95fcbSLiam Girdwood }
105d1d95fcbSLiam Girdwood 
106*c414d5dfSRanjani Sridharan static inline int snd_sof_dsp_core_get(struct snd_sof_dev *sdev, int core)
107*c414d5dfSRanjani Sridharan {
108*c414d5dfSRanjani Sridharan 	if (core > sdev->num_cores - 1) {
109*c414d5dfSRanjani Sridharan 		dev_err(sdev->dev, "invalid core id: %d for num_cores: %d\n", core,
110*c414d5dfSRanjani Sridharan 			sdev->num_cores);
111*c414d5dfSRanjani Sridharan 		return -EINVAL;
112*c414d5dfSRanjani Sridharan 	}
113*c414d5dfSRanjani Sridharan 
114*c414d5dfSRanjani Sridharan 	if (sof_ops(sdev)->core_get) {
115*c414d5dfSRanjani Sridharan 		int ret;
116*c414d5dfSRanjani Sridharan 
117*c414d5dfSRanjani Sridharan 		/* if current ref_count is > 0, increment it and return */
118*c414d5dfSRanjani Sridharan 		if (sdev->dsp_core_ref_count[core] > 0) {
119*c414d5dfSRanjani Sridharan 			sdev->dsp_core_ref_count[core]++;
120*c414d5dfSRanjani Sridharan 			return 0;
121*c414d5dfSRanjani Sridharan 		}
122*c414d5dfSRanjani Sridharan 
123*c414d5dfSRanjani Sridharan 		/* power up the core */
124*c414d5dfSRanjani Sridharan 		ret = sof_ops(sdev)->core_get(sdev, core);
125*c414d5dfSRanjani Sridharan 		if (ret < 0)
126*c414d5dfSRanjani Sridharan 			return ret;
127*c414d5dfSRanjani Sridharan 
128*c414d5dfSRanjani Sridharan 		/* increment ref_count */
129*c414d5dfSRanjani Sridharan 		sdev->dsp_core_ref_count[core]++;
130*c414d5dfSRanjani Sridharan 
131*c414d5dfSRanjani Sridharan 		/* and update enabled_cores_mask */
132*c414d5dfSRanjani Sridharan 		sdev->enabled_cores_mask |= BIT(core);
133*c414d5dfSRanjani Sridharan 
134*c414d5dfSRanjani Sridharan 		dev_dbg(sdev->dev, "Core %d powered up\n", core);
135*c414d5dfSRanjani Sridharan 	}
136*c414d5dfSRanjani Sridharan 
137*c414d5dfSRanjani Sridharan 	return 0;
138*c414d5dfSRanjani Sridharan }
139*c414d5dfSRanjani Sridharan 
140*c414d5dfSRanjani Sridharan static inline int snd_sof_dsp_core_put(struct snd_sof_dev *sdev, int core)
141*c414d5dfSRanjani Sridharan {
142*c414d5dfSRanjani Sridharan 	if (core > sdev->num_cores - 1) {
143*c414d5dfSRanjani Sridharan 		dev_err(sdev->dev, "invalid core id: %d for num_cores: %d\n", core,
144*c414d5dfSRanjani Sridharan 			sdev->num_cores);
145*c414d5dfSRanjani Sridharan 		return -EINVAL;
146*c414d5dfSRanjani Sridharan 	}
147*c414d5dfSRanjani Sridharan 
148*c414d5dfSRanjani Sridharan 	if (sof_ops(sdev)->core_put) {
149*c414d5dfSRanjani Sridharan 		int ret;
150*c414d5dfSRanjani Sridharan 
151*c414d5dfSRanjani Sridharan 		/* decrement ref_count and return if it is > 0 */
152*c414d5dfSRanjani Sridharan 		if (--(sdev->dsp_core_ref_count[core]) > 0)
153*c414d5dfSRanjani Sridharan 			return 0;
154*c414d5dfSRanjani Sridharan 
155*c414d5dfSRanjani Sridharan 		/* power down the core */
156*c414d5dfSRanjani Sridharan 		ret = sof_ops(sdev)->core_put(sdev, core);
157*c414d5dfSRanjani Sridharan 		if (ret < 0)
158*c414d5dfSRanjani Sridharan 			return ret;
159*c414d5dfSRanjani Sridharan 
160*c414d5dfSRanjani Sridharan 		/* and update enabled_cores_mask */
161*c414d5dfSRanjani Sridharan 		sdev->enabled_cores_mask &= ~BIT(core);
162*c414d5dfSRanjani Sridharan 
163*c414d5dfSRanjani Sridharan 		dev_dbg(sdev->dev, "Core %d powered down\n", core);
164*c414d5dfSRanjani Sridharan 	}
165*c414d5dfSRanjani Sridharan 
166*c414d5dfSRanjani Sridharan 	return 0;
167*c414d5dfSRanjani Sridharan }
168*c414d5dfSRanjani Sridharan 
169d1d95fcbSLiam Girdwood /* pre/post fw load */
170d1d95fcbSLiam Girdwood static inline int snd_sof_dsp_pre_fw_run(struct snd_sof_dev *sdev)
171d1d95fcbSLiam Girdwood {
172d1d95fcbSLiam Girdwood 	if (sof_ops(sdev)->pre_fw_run)
173d1d95fcbSLiam Girdwood 		return sof_ops(sdev)->pre_fw_run(sdev);
174d1d95fcbSLiam Girdwood 
175d1d95fcbSLiam Girdwood 	return 0;
176d1d95fcbSLiam Girdwood }
177d1d95fcbSLiam Girdwood 
178d1d95fcbSLiam Girdwood static inline int snd_sof_dsp_post_fw_run(struct snd_sof_dev *sdev)
179d1d95fcbSLiam Girdwood {
180d1d95fcbSLiam Girdwood 	if (sof_ops(sdev)->post_fw_run)
181d1d95fcbSLiam Girdwood 		return sof_ops(sdev)->post_fw_run(sdev);
182d1d95fcbSLiam Girdwood 
183d1d95fcbSLiam Girdwood 	return 0;
184d1d95fcbSLiam Girdwood }
185d1d95fcbSLiam Girdwood 
186e984f3efSFred Oh /* parse platform specific extended manifest */
187e984f3efSFred Oh static inline int snd_sof_dsp_parse_platform_ext_manifest(struct snd_sof_dev *sdev,
188e984f3efSFred Oh 							  const struct sof_ext_man_elem_header *hdr)
189e984f3efSFred Oh {
190e984f3efSFred Oh 	if (sof_ops(sdev)->parse_platform_ext_manifest)
191e984f3efSFred Oh 		return sof_ops(sdev)->parse_platform_ext_manifest(sdev, hdr);
192e984f3efSFred Oh 
193e984f3efSFred Oh 	return 0;
194e984f3efSFred Oh }
195e984f3efSFred Oh 
196ce8234a6SDaniel Baluta /* misc */
197ce8234a6SDaniel Baluta 
198ce8234a6SDaniel Baluta /**
199ce8234a6SDaniel Baluta  * snd_sof_dsp_get_bar_index - Maps a section type with a BAR index
200ce8234a6SDaniel Baluta  *
201ce8234a6SDaniel Baluta  * @sdev: sof device
202ce8234a6SDaniel Baluta  * @type: section type as described by snd_sof_fw_blk_type
203ce8234a6SDaniel Baluta  *
204ce8234a6SDaniel Baluta  * Returns the corresponding BAR index (a positive integer) or -EINVAL
205ce8234a6SDaniel Baluta  * in case there is no mapping
206ce8234a6SDaniel Baluta  */
207ce8234a6SDaniel Baluta static inline int snd_sof_dsp_get_bar_index(struct snd_sof_dev *sdev, u32 type)
208ce8234a6SDaniel Baluta {
209ce8234a6SDaniel Baluta 	if (sof_ops(sdev)->get_bar_index)
210ce8234a6SDaniel Baluta 		return sof_ops(sdev)->get_bar_index(sdev, type);
211ce8234a6SDaniel Baluta 
212ce8234a6SDaniel Baluta 	return sdev->mmio_bar;
213ce8234a6SDaniel Baluta }
214ce8234a6SDaniel Baluta 
215bb9c93f5SDaniel Baluta static inline int snd_sof_dsp_get_mailbox_offset(struct snd_sof_dev *sdev)
216bb9c93f5SDaniel Baluta {
217bb9c93f5SDaniel Baluta 	if (sof_ops(sdev)->get_mailbox_offset)
218bb9c93f5SDaniel Baluta 		return sof_ops(sdev)->get_mailbox_offset(sdev);
219bb9c93f5SDaniel Baluta 
220bb9c93f5SDaniel Baluta 	dev_err(sdev->dev, "error: %s not defined\n", __func__);
221bb9c93f5SDaniel Baluta 	return -ENOTSUPP;
222bb9c93f5SDaniel Baluta }
223bb9c93f5SDaniel Baluta 
224e17422cdSDaniel Baluta static inline int snd_sof_dsp_get_window_offset(struct snd_sof_dev *sdev,
225e17422cdSDaniel Baluta 						u32 id)
226e17422cdSDaniel Baluta {
227e17422cdSDaniel Baluta 	if (sof_ops(sdev)->get_window_offset)
228e17422cdSDaniel Baluta 		return sof_ops(sdev)->get_window_offset(sdev, id);
229e17422cdSDaniel Baluta 
230e17422cdSDaniel Baluta 	dev_err(sdev->dev, "error: %s not defined\n", __func__);
231e17422cdSDaniel Baluta 	return -ENOTSUPP;
232e17422cdSDaniel Baluta }
233d1d95fcbSLiam Girdwood /* power management */
234d1d95fcbSLiam Girdwood static inline int snd_sof_dsp_resume(struct snd_sof_dev *sdev)
235d1d95fcbSLiam Girdwood {
236d1d95fcbSLiam Girdwood 	if (sof_ops(sdev)->resume)
237d1d95fcbSLiam Girdwood 		return sof_ops(sdev)->resume(sdev);
238d1d95fcbSLiam Girdwood 
239d1d95fcbSLiam Girdwood 	return 0;
240d1d95fcbSLiam Girdwood }
241d1d95fcbSLiam Girdwood 
24261e285caSRanjani Sridharan static inline int snd_sof_dsp_suspend(struct snd_sof_dev *sdev,
24361e285caSRanjani Sridharan 				      u32 target_state)
244d1d95fcbSLiam Girdwood {
245d1d95fcbSLiam Girdwood 	if (sof_ops(sdev)->suspend)
24661e285caSRanjani Sridharan 		return sof_ops(sdev)->suspend(sdev, target_state);
247d1d95fcbSLiam Girdwood 
248d1d95fcbSLiam Girdwood 	return 0;
249d1d95fcbSLiam Girdwood }
250d1d95fcbSLiam Girdwood 
251d1d95fcbSLiam Girdwood static inline int snd_sof_dsp_runtime_resume(struct snd_sof_dev *sdev)
252d1d95fcbSLiam Girdwood {
253d1d95fcbSLiam Girdwood 	if (sof_ops(sdev)->runtime_resume)
254d1d95fcbSLiam Girdwood 		return sof_ops(sdev)->runtime_resume(sdev);
255d1d95fcbSLiam Girdwood 
256d1d95fcbSLiam Girdwood 	return 0;
257d1d95fcbSLiam Girdwood }
258d1d95fcbSLiam Girdwood 
2591c38c922SFred Oh static inline int snd_sof_dsp_runtime_suspend(struct snd_sof_dev *sdev)
260d1d95fcbSLiam Girdwood {
261d1d95fcbSLiam Girdwood 	if (sof_ops(sdev)->runtime_suspend)
2621c38c922SFred Oh 		return sof_ops(sdev)->runtime_suspend(sdev);
263d1d95fcbSLiam Girdwood 
264d1d95fcbSLiam Girdwood 	return 0;
265d1d95fcbSLiam Girdwood }
266d1d95fcbSLiam Girdwood 
26762fde977SKai Vehmanen static inline int snd_sof_dsp_runtime_idle(struct snd_sof_dev *sdev)
26862fde977SKai Vehmanen {
26962fde977SKai Vehmanen 	if (sof_ops(sdev)->runtime_idle)
27062fde977SKai Vehmanen 		return sof_ops(sdev)->runtime_idle(sdev);
27162fde977SKai Vehmanen 
27262fde977SKai Vehmanen 	return 0;
27362fde977SKai Vehmanen }
27462fde977SKai Vehmanen 
2757077a07aSRanjani Sridharan static inline int snd_sof_dsp_hw_params_upon_resume(struct snd_sof_dev *sdev)
276ed3baacdSRanjani Sridharan {
277ed3baacdSRanjani Sridharan 	if (sof_ops(sdev)->set_hw_params_upon_resume)
2787077a07aSRanjani Sridharan 		return sof_ops(sdev)->set_hw_params_upon_resume(sdev);
2797077a07aSRanjani Sridharan 	return 0;
280ed3baacdSRanjani Sridharan }
281ed3baacdSRanjani Sridharan 
282d1d95fcbSLiam Girdwood static inline int snd_sof_dsp_set_clk(struct snd_sof_dev *sdev, u32 freq)
283d1d95fcbSLiam Girdwood {
284d1d95fcbSLiam Girdwood 	if (sof_ops(sdev)->set_clk)
285d1d95fcbSLiam Girdwood 		return sof_ops(sdev)->set_clk(sdev, freq);
286d1d95fcbSLiam Girdwood 
287d1d95fcbSLiam Girdwood 	return 0;
288d1d95fcbSLiam Girdwood }
289d1d95fcbSLiam Girdwood 
29061e285caSRanjani Sridharan static inline int
29161e285caSRanjani Sridharan snd_sof_dsp_set_power_state(struct snd_sof_dev *sdev,
29261e285caSRanjani Sridharan 			    const struct sof_dsp_power_state *target_state)
293e8f112d8SKeyon Jie {
2948b66d7c5SKeyon Jie 	int ret = 0;
295e8f112d8SKeyon Jie 
2968b66d7c5SKeyon Jie 	mutex_lock(&sdev->power_state_access);
2978b66d7c5SKeyon Jie 
2988b66d7c5SKeyon Jie 	if (sof_ops(sdev)->set_power_state)
2998b66d7c5SKeyon Jie 		ret = sof_ops(sdev)->set_power_state(sdev, target_state);
3008b66d7c5SKeyon Jie 
3018b66d7c5SKeyon Jie 	mutex_unlock(&sdev->power_state_access);
3028b66d7c5SKeyon Jie 
3038b66d7c5SKeyon Jie 	return ret;
304e8f112d8SKeyon Jie }
305e8f112d8SKeyon Jie 
306d1d95fcbSLiam Girdwood /* debug */
307360fa323SPeter Ujfalusi void snd_sof_dsp_dbg_dump(struct snd_sof_dev *sdev, u32 flags);
3085e4a27fdSPan Xiuli 
30907e833b4SPeter Ujfalusi static inline int snd_sof_debugfs_add_region_item(struct snd_sof_dev *sdev,
31007e833b4SPeter Ujfalusi 		enum snd_sof_fw_blk_type blk_type, u32 offset, size_t size,
31107e833b4SPeter Ujfalusi 		const char *name, enum sof_debugfs_access_type access_type)
31207e833b4SPeter Ujfalusi {
31307e833b4SPeter Ujfalusi 	if (sof_ops(sdev) && sof_ops(sdev)->debugfs_add_region_item)
31407e833b4SPeter Ujfalusi 		return sof_ops(sdev)->debugfs_add_region_item(sdev, blk_type, offset,
31507e833b4SPeter Ujfalusi 							      size, name, access_type);
31607e833b4SPeter Ujfalusi 
31707e833b4SPeter Ujfalusi 	return 0;
31807e833b4SPeter Ujfalusi }
31907e833b4SPeter Ujfalusi 
320d1d95fcbSLiam Girdwood /* register IO */
321d1d95fcbSLiam Girdwood static inline void snd_sof_dsp_write(struct snd_sof_dev *sdev, u32 bar,
322d1d95fcbSLiam Girdwood 				     u32 offset, u32 value)
323d1d95fcbSLiam Girdwood {
324d1d95fcbSLiam Girdwood 	if (sof_ops(sdev)->write) {
325d1d95fcbSLiam Girdwood 		sof_ops(sdev)->write(sdev, sdev->bar[bar] + offset, value);
326d1d95fcbSLiam Girdwood 		return;
327d1d95fcbSLiam Girdwood 	}
328d1d95fcbSLiam Girdwood 
329d1d95fcbSLiam Girdwood 	dev_err_ratelimited(sdev->dev, "error: %s not defined\n", __func__);
330d1d95fcbSLiam Girdwood }
331d1d95fcbSLiam Girdwood 
332d1d95fcbSLiam Girdwood static inline void snd_sof_dsp_write64(struct snd_sof_dev *sdev, u32 bar,
333d1d95fcbSLiam Girdwood 				       u32 offset, u64 value)
334d1d95fcbSLiam Girdwood {
335d1d95fcbSLiam Girdwood 	if (sof_ops(sdev)->write64) {
336d1d95fcbSLiam Girdwood 		sof_ops(sdev)->write64(sdev, sdev->bar[bar] + offset, value);
337d1d95fcbSLiam Girdwood 		return;
338d1d95fcbSLiam Girdwood 	}
339d1d95fcbSLiam Girdwood 
340d1d95fcbSLiam Girdwood 	dev_err_ratelimited(sdev->dev, "error: %s not defined\n", __func__);
341d1d95fcbSLiam Girdwood }
342d1d95fcbSLiam Girdwood 
343d1d95fcbSLiam Girdwood static inline u32 snd_sof_dsp_read(struct snd_sof_dev *sdev, u32 bar,
344d1d95fcbSLiam Girdwood 				   u32 offset)
345d1d95fcbSLiam Girdwood {
346d1d95fcbSLiam Girdwood 	if (sof_ops(sdev)->read)
347d1d95fcbSLiam Girdwood 		return sof_ops(sdev)->read(sdev, sdev->bar[bar] + offset);
348d1d95fcbSLiam Girdwood 
349d1d95fcbSLiam Girdwood 	dev_err(sdev->dev, "error: %s not defined\n", __func__);
350d1d95fcbSLiam Girdwood 	return -ENOTSUPP;
351d1d95fcbSLiam Girdwood }
352d1d95fcbSLiam Girdwood 
353d1d95fcbSLiam Girdwood static inline u64 snd_sof_dsp_read64(struct snd_sof_dev *sdev, u32 bar,
354d1d95fcbSLiam Girdwood 				     u32 offset)
355d1d95fcbSLiam Girdwood {
356d1d95fcbSLiam Girdwood 	if (sof_ops(sdev)->read64)
357d1d95fcbSLiam Girdwood 		return sof_ops(sdev)->read64(sdev, sdev->bar[bar] + offset);
358d1d95fcbSLiam Girdwood 
359d1d95fcbSLiam Girdwood 	dev_err(sdev->dev, "error: %s not defined\n", __func__);
360d1d95fcbSLiam Girdwood 	return -ENOTSUPP;
361d1d95fcbSLiam Girdwood }
362d1d95fcbSLiam Girdwood 
363d1d95fcbSLiam Girdwood /* block IO */
3644624bb2fSPeter Ujfalusi static inline int snd_sof_dsp_block_read(struct snd_sof_dev *sdev,
3654624bb2fSPeter Ujfalusi 					 enum snd_sof_fw_blk_type blk_type,
366d1d95fcbSLiam Girdwood 					 u32 offset, void *dest, size_t bytes)
367d1d95fcbSLiam Girdwood {
3684624bb2fSPeter Ujfalusi 	return sof_ops(sdev)->block_read(sdev, blk_type, offset, dest, bytes);
369d1d95fcbSLiam Girdwood }
370d1d95fcbSLiam Girdwood 
3714624bb2fSPeter Ujfalusi static inline int snd_sof_dsp_block_write(struct snd_sof_dev *sdev,
3724624bb2fSPeter Ujfalusi 					  enum snd_sof_fw_blk_type blk_type,
373d1d95fcbSLiam Girdwood 					  u32 offset, void *src, size_t bytes)
374d1d95fcbSLiam Girdwood {
3754624bb2fSPeter Ujfalusi 	return sof_ops(sdev)->block_write(sdev, blk_type, offset, src, bytes);
376d1d95fcbSLiam Girdwood }
377d1d95fcbSLiam Girdwood 
378f71f59ddSDaniel Baluta /* mailbox IO */
379f71f59ddSDaniel Baluta static inline void snd_sof_dsp_mailbox_read(struct snd_sof_dev *sdev,
380f71f59ddSDaniel Baluta 					    u32 offset, void *dest, size_t bytes)
381f71f59ddSDaniel Baluta {
382f71f59ddSDaniel Baluta 	if (sof_ops(sdev)->mailbox_read)
383f71f59ddSDaniel Baluta 		sof_ops(sdev)->mailbox_read(sdev, offset, dest, bytes);
384f71f59ddSDaniel Baluta }
385f71f59ddSDaniel Baluta 
386f71f59ddSDaniel Baluta static inline void snd_sof_dsp_mailbox_write(struct snd_sof_dev *sdev,
387f71f59ddSDaniel Baluta 					     u32 offset, void *src, size_t bytes)
388f71f59ddSDaniel Baluta {
389f71f59ddSDaniel Baluta 	if (sof_ops(sdev)->mailbox_write)
390f71f59ddSDaniel Baluta 		sof_ops(sdev)->mailbox_write(sdev, offset, src, bytes);
391f71f59ddSDaniel Baluta }
392f71f59ddSDaniel Baluta 
393d1d95fcbSLiam Girdwood /* ipc */
394d1d95fcbSLiam Girdwood static inline int snd_sof_dsp_send_msg(struct snd_sof_dev *sdev,
395d1d95fcbSLiam Girdwood 				       struct snd_sof_ipc_msg *msg)
396d1d95fcbSLiam Girdwood {
397d1d95fcbSLiam Girdwood 	return sof_ops(sdev)->send_msg(sdev, msg);
398d1d95fcbSLiam Girdwood }
399d1d95fcbSLiam Girdwood 
400d1d95fcbSLiam Girdwood /* host DMA trace */
401d1d95fcbSLiam Girdwood static inline int snd_sof_dma_trace_init(struct snd_sof_dev *sdev,
402d1d95fcbSLiam Girdwood 					 u32 *stream_tag)
403d1d95fcbSLiam Girdwood {
404d1d95fcbSLiam Girdwood 	if (sof_ops(sdev)->trace_init)
405d1d95fcbSLiam Girdwood 		return sof_ops(sdev)->trace_init(sdev, stream_tag);
406d1d95fcbSLiam Girdwood 
407d1d95fcbSLiam Girdwood 	return 0;
408d1d95fcbSLiam Girdwood }
409d1d95fcbSLiam Girdwood 
410d1d95fcbSLiam Girdwood static inline int snd_sof_dma_trace_release(struct snd_sof_dev *sdev)
411d1d95fcbSLiam Girdwood {
412d1d95fcbSLiam Girdwood 	if (sof_ops(sdev)->trace_release)
413d1d95fcbSLiam Girdwood 		return sof_ops(sdev)->trace_release(sdev);
414d1d95fcbSLiam Girdwood 
415d1d95fcbSLiam Girdwood 	return 0;
416d1d95fcbSLiam Girdwood }
417d1d95fcbSLiam Girdwood 
418d1d95fcbSLiam Girdwood static inline int snd_sof_dma_trace_trigger(struct snd_sof_dev *sdev, int cmd)
419d1d95fcbSLiam Girdwood {
420d1d95fcbSLiam Girdwood 	if (sof_ops(sdev)->trace_trigger)
421d1d95fcbSLiam Girdwood 		return sof_ops(sdev)->trace_trigger(sdev, cmd);
422d1d95fcbSLiam Girdwood 
423d1d95fcbSLiam Girdwood 	return 0;
424d1d95fcbSLiam Girdwood }
425d1d95fcbSLiam Girdwood 
426d1d95fcbSLiam Girdwood /* host PCM ops */
427d1d95fcbSLiam Girdwood static inline int
428d1d95fcbSLiam Girdwood snd_sof_pcm_platform_open(struct snd_sof_dev *sdev,
429d1d95fcbSLiam Girdwood 			  struct snd_pcm_substream *substream)
430d1d95fcbSLiam Girdwood {
431d1d95fcbSLiam Girdwood 	if (sof_ops(sdev) && sof_ops(sdev)->pcm_open)
432d1d95fcbSLiam Girdwood 		return sof_ops(sdev)->pcm_open(sdev, substream);
433d1d95fcbSLiam Girdwood 
434d1d95fcbSLiam Girdwood 	return 0;
435d1d95fcbSLiam Girdwood }
436d1d95fcbSLiam Girdwood 
437d1d95fcbSLiam Girdwood /* disconnect pcm substream to a host stream */
438d1d95fcbSLiam Girdwood static inline int
439d1d95fcbSLiam Girdwood snd_sof_pcm_platform_close(struct snd_sof_dev *sdev,
440d1d95fcbSLiam Girdwood 			   struct snd_pcm_substream *substream)
441d1d95fcbSLiam Girdwood {
442d1d95fcbSLiam Girdwood 	if (sof_ops(sdev) && sof_ops(sdev)->pcm_close)
443d1d95fcbSLiam Girdwood 		return sof_ops(sdev)->pcm_close(sdev, substream);
444d1d95fcbSLiam Girdwood 
445d1d95fcbSLiam Girdwood 	return 0;
446d1d95fcbSLiam Girdwood }
447d1d95fcbSLiam Girdwood 
448d1d95fcbSLiam Girdwood /* host stream hw params */
449d1d95fcbSLiam Girdwood static inline int
450d1d95fcbSLiam Girdwood snd_sof_pcm_platform_hw_params(struct snd_sof_dev *sdev,
451d1d95fcbSLiam Girdwood 			       struct snd_pcm_substream *substream,
452d1d95fcbSLiam Girdwood 			       struct snd_pcm_hw_params *params,
453d1d95fcbSLiam Girdwood 			       struct sof_ipc_stream_params *ipc_params)
454d1d95fcbSLiam Girdwood {
455d1d95fcbSLiam Girdwood 	if (sof_ops(sdev) && sof_ops(sdev)->pcm_hw_params)
456d1d95fcbSLiam Girdwood 		return sof_ops(sdev)->pcm_hw_params(sdev, substream,
457d1d95fcbSLiam Girdwood 						    params, ipc_params);
458d1d95fcbSLiam Girdwood 
459d1d95fcbSLiam Girdwood 	return 0;
460d1d95fcbSLiam Girdwood }
461d1d95fcbSLiam Girdwood 
46293146bc2SRanjani Sridharan /* host stream hw free */
46393146bc2SRanjani Sridharan static inline int
46493146bc2SRanjani Sridharan snd_sof_pcm_platform_hw_free(struct snd_sof_dev *sdev,
46593146bc2SRanjani Sridharan 			     struct snd_pcm_substream *substream)
46693146bc2SRanjani Sridharan {
46793146bc2SRanjani Sridharan 	if (sof_ops(sdev) && sof_ops(sdev)->pcm_hw_free)
46893146bc2SRanjani Sridharan 		return sof_ops(sdev)->pcm_hw_free(sdev, substream);
46993146bc2SRanjani Sridharan 
47093146bc2SRanjani Sridharan 	return 0;
47193146bc2SRanjani Sridharan }
47293146bc2SRanjani Sridharan 
473d1d95fcbSLiam Girdwood /* host stream trigger */
474d1d95fcbSLiam Girdwood static inline int
475d1d95fcbSLiam Girdwood snd_sof_pcm_platform_trigger(struct snd_sof_dev *sdev,
476d1d95fcbSLiam Girdwood 			     struct snd_pcm_substream *substream, int cmd)
477d1d95fcbSLiam Girdwood {
478d1d95fcbSLiam Girdwood 	if (sof_ops(sdev) && sof_ops(sdev)->pcm_trigger)
479d1d95fcbSLiam Girdwood 		return sof_ops(sdev)->pcm_trigger(sdev, substream, cmd);
480d1d95fcbSLiam Girdwood 
481d1d95fcbSLiam Girdwood 	return 0;
482d1d95fcbSLiam Girdwood }
483d1d95fcbSLiam Girdwood 
48496ec1741SPeter Ujfalusi /* Firmware loading */
48596ec1741SPeter Ujfalusi static inline int snd_sof_load_firmware(struct snd_sof_dev *sdev)
48696ec1741SPeter Ujfalusi {
48796ec1741SPeter Ujfalusi 	dev_dbg(sdev->dev, "loading firmware\n");
48896ec1741SPeter Ujfalusi 
48996ec1741SPeter Ujfalusi 	return sof_ops(sdev)->load_firmware(sdev);
49096ec1741SPeter Ujfalusi }
49196ec1741SPeter Ujfalusi 
492d1d95fcbSLiam Girdwood /* host DSP message data */
4936a0ba071SGuennadi Liakhovetski static inline int snd_sof_ipc_msg_data(struct snd_sof_dev *sdev,
494d1d95fcbSLiam Girdwood 				       struct snd_pcm_substream *substream,
495d1d95fcbSLiam Girdwood 				       void *p, size_t sz)
496d1d95fcbSLiam Girdwood {
4976a0ba071SGuennadi Liakhovetski 	return sof_ops(sdev)->ipc_msg_data(sdev, substream, p, sz);
498d1d95fcbSLiam Girdwood }
499d1d95fcbSLiam Girdwood 
500d1d95fcbSLiam Girdwood /* host configure DSP HW parameters */
501d1d95fcbSLiam Girdwood static inline int
502d1d95fcbSLiam Girdwood snd_sof_ipc_pcm_params(struct snd_sof_dev *sdev,
503d1d95fcbSLiam Girdwood 		       struct snd_pcm_substream *substream,
504d1d95fcbSLiam Girdwood 		       const struct sof_ipc_pcm_params_reply *reply)
505d1d95fcbSLiam Girdwood {
506d1d95fcbSLiam Girdwood 	return sof_ops(sdev)->ipc_pcm_params(sdev, substream, reply);
507d1d95fcbSLiam Girdwood }
508d1d95fcbSLiam Girdwood 
509d1d95fcbSLiam Girdwood /* host stream pointer */
510d1d95fcbSLiam Girdwood static inline snd_pcm_uframes_t
511d1d95fcbSLiam Girdwood snd_sof_pcm_platform_pointer(struct snd_sof_dev *sdev,
512d1d95fcbSLiam Girdwood 			     struct snd_pcm_substream *substream)
513d1d95fcbSLiam Girdwood {
514d1d95fcbSLiam Girdwood 	if (sof_ops(sdev) && sof_ops(sdev)->pcm_pointer)
515d1d95fcbSLiam Girdwood 		return sof_ops(sdev)->pcm_pointer(sdev, substream);
516d1d95fcbSLiam Girdwood 
517d1d95fcbSLiam Girdwood 	return 0;
518d1d95fcbSLiam Girdwood }
519d1d95fcbSLiam Girdwood 
520e145e9afSCezary Rojewski #if IS_ENABLED(CONFIG_SND_SOC_SOF_DEBUG_PROBES)
521e145e9afSCezary Rojewski static inline int
522e145e9afSCezary Rojewski snd_sof_probe_compr_assign(struct snd_sof_dev *sdev,
523e145e9afSCezary Rojewski 		struct snd_compr_stream *cstream, struct snd_soc_dai *dai)
524e145e9afSCezary Rojewski {
525e145e9afSCezary Rojewski 	return sof_ops(sdev)->probe_assign(sdev, cstream, dai);
526e145e9afSCezary Rojewski }
527e145e9afSCezary Rojewski 
528e145e9afSCezary Rojewski static inline int
529e145e9afSCezary Rojewski snd_sof_probe_compr_free(struct snd_sof_dev *sdev,
530e145e9afSCezary Rojewski 		struct snd_compr_stream *cstream, struct snd_soc_dai *dai)
531e145e9afSCezary Rojewski {
532e145e9afSCezary Rojewski 	return sof_ops(sdev)->probe_free(sdev, cstream, dai);
533e145e9afSCezary Rojewski }
534e145e9afSCezary Rojewski 
535e145e9afSCezary Rojewski static inline int
536e145e9afSCezary Rojewski snd_sof_probe_compr_set_params(struct snd_sof_dev *sdev,
537e145e9afSCezary Rojewski 		struct snd_compr_stream *cstream,
538e145e9afSCezary Rojewski 		struct snd_compr_params *params, struct snd_soc_dai *dai)
539e145e9afSCezary Rojewski {
540e145e9afSCezary Rojewski 	return sof_ops(sdev)->probe_set_params(sdev, cstream, params, dai);
541e145e9afSCezary Rojewski }
542e145e9afSCezary Rojewski 
543e145e9afSCezary Rojewski static inline int
544e145e9afSCezary Rojewski snd_sof_probe_compr_trigger(struct snd_sof_dev *sdev,
545e145e9afSCezary Rojewski 		struct snd_compr_stream *cstream, int cmd,
546e145e9afSCezary Rojewski 		struct snd_soc_dai *dai)
547e145e9afSCezary Rojewski {
548e145e9afSCezary Rojewski 	return sof_ops(sdev)->probe_trigger(sdev, cstream, cmd, dai);
549e145e9afSCezary Rojewski }
550e145e9afSCezary Rojewski 
551e145e9afSCezary Rojewski static inline int
552e145e9afSCezary Rojewski snd_sof_probe_compr_pointer(struct snd_sof_dev *sdev,
553e145e9afSCezary Rojewski 		struct snd_compr_stream *cstream,
554e145e9afSCezary Rojewski 		struct snd_compr_tstamp *tstamp, struct snd_soc_dai *dai)
555e145e9afSCezary Rojewski {
556e145e9afSCezary Rojewski 	if (sof_ops(sdev) && sof_ops(sdev)->probe_pointer)
557e145e9afSCezary Rojewski 		return sof_ops(sdev)->probe_pointer(sdev, cstream, tstamp, dai);
558e145e9afSCezary Rojewski 
559e145e9afSCezary Rojewski 	return 0;
560e145e9afSCezary Rojewski }
561e145e9afSCezary Rojewski #endif
562e145e9afSCezary Rojewski 
563285880a2SDaniel Baluta /* machine driver */
564285880a2SDaniel Baluta static inline int
565285880a2SDaniel Baluta snd_sof_machine_register(struct snd_sof_dev *sdev, void *pdata)
566285880a2SDaniel Baluta {
567285880a2SDaniel Baluta 	if (sof_ops(sdev) && sof_ops(sdev)->machine_register)
568285880a2SDaniel Baluta 		return sof_ops(sdev)->machine_register(sdev, pdata);
569285880a2SDaniel Baluta 
570285880a2SDaniel Baluta 	return 0;
571285880a2SDaniel Baluta }
572285880a2SDaniel Baluta 
573285880a2SDaniel Baluta static inline void
574285880a2SDaniel Baluta snd_sof_machine_unregister(struct snd_sof_dev *sdev, void *pdata)
575285880a2SDaniel Baluta {
576285880a2SDaniel Baluta 	if (sof_ops(sdev) && sof_ops(sdev)->machine_unregister)
577285880a2SDaniel Baluta 		sof_ops(sdev)->machine_unregister(sdev, pdata);
578285880a2SDaniel Baluta }
579285880a2SDaniel Baluta 
580285880a2SDaniel Baluta static inline void
581285880a2SDaniel Baluta snd_sof_machine_select(struct snd_sof_dev *sdev)
582285880a2SDaniel Baluta {
583285880a2SDaniel Baluta 	if (sof_ops(sdev) && sof_ops(sdev)->machine_select)
584285880a2SDaniel Baluta 		sof_ops(sdev)->machine_select(sdev);
585285880a2SDaniel Baluta }
586285880a2SDaniel Baluta 
587285880a2SDaniel Baluta static inline void
588285880a2SDaniel Baluta snd_sof_set_mach_params(const struct snd_soc_acpi_mach *mach,
58917e9d6b0SPierre-Louis Bossart 			struct snd_sof_dev *sdev)
590285880a2SDaniel Baluta {
591285880a2SDaniel Baluta 	if (sof_ops(sdev) && sof_ops(sdev)->set_mach_params)
59217e9d6b0SPierre-Louis Bossart 		sof_ops(sdev)->set_mach_params(mach, sdev);
593285880a2SDaniel Baluta }
594285880a2SDaniel Baluta 
595d1d95fcbSLiam Girdwood /**
596d1d95fcbSLiam Girdwood  * snd_sof_dsp_register_poll_timeout - Periodically poll an address
597d1d95fcbSLiam Girdwood  * until a condition is met or a timeout occurs
598d1d95fcbSLiam Girdwood  * @op: accessor function (takes @addr as its only argument)
599d1d95fcbSLiam Girdwood  * @addr: Address to poll
600d1d95fcbSLiam Girdwood  * @val: Variable to read the value into
601d1d95fcbSLiam Girdwood  * @cond: Break condition (usually involving @val)
602d1d95fcbSLiam Girdwood  * @sleep_us: Maximum time to sleep between reads in us (0
603d1d95fcbSLiam Girdwood  *            tight-loops).  Should be less than ~20ms since usleep_range
604458f69efSMauro Carvalho Chehab  *            is used (see Documentation/timers/timers-howto.rst).
605d1d95fcbSLiam Girdwood  * @timeout_us: Timeout in us, 0 means never timeout
606d1d95fcbSLiam Girdwood  *
607d1d95fcbSLiam Girdwood  * Returns 0 on success and -ETIMEDOUT upon a timeout. In either
608d1d95fcbSLiam Girdwood  * case, the last read value at @addr is stored in @val. Must not
609d1d95fcbSLiam Girdwood  * be called from atomic context if sleep_us or timeout_us are used.
610d1d95fcbSLiam Girdwood  *
611d1d95fcbSLiam Girdwood  * This is modelled after the readx_poll_timeout macros in linux/iopoll.h.
612d1d95fcbSLiam Girdwood  */
613d1d95fcbSLiam Girdwood #define snd_sof_dsp_read_poll_timeout(sdev, bar, offset, val, cond, sleep_us, timeout_us) \
614d1d95fcbSLiam Girdwood ({ \
615d1d95fcbSLiam Girdwood 	u64 __timeout_us = (timeout_us); \
616d1d95fcbSLiam Girdwood 	unsigned long __sleep_us = (sleep_us); \
617d1d95fcbSLiam Girdwood 	ktime_t __timeout = ktime_add_us(ktime_get(), __timeout_us); \
618d1d95fcbSLiam Girdwood 	might_sleep_if((__sleep_us) != 0); \
619d1d95fcbSLiam Girdwood 	for (;;) {							\
620d1d95fcbSLiam Girdwood 		(val) = snd_sof_dsp_read(sdev, bar, offset);		\
621d1d95fcbSLiam Girdwood 		if (cond) { \
622d1d95fcbSLiam Girdwood 			dev_dbg(sdev->dev, \
6233b2e93edSKeyon Jie 				"FW Poll Status: reg[%#x]=%#x successful\n", \
6243b2e93edSKeyon Jie 				(offset), (val)); \
625d1d95fcbSLiam Girdwood 			break; \
626d1d95fcbSLiam Girdwood 		} \
627d1d95fcbSLiam Girdwood 		if (__timeout_us && \
628d1d95fcbSLiam Girdwood 		    ktime_compare(ktime_get(), __timeout) > 0) { \
629d1d95fcbSLiam Girdwood 			(val) = snd_sof_dsp_read(sdev, bar, offset); \
630d1d95fcbSLiam Girdwood 			dev_dbg(sdev->dev, \
6313b2e93edSKeyon Jie 				"FW Poll Status: reg[%#x]=%#x timedout\n", \
6323b2e93edSKeyon Jie 				(offset), (val)); \
633d1d95fcbSLiam Girdwood 			break; \
634d1d95fcbSLiam Girdwood 		} \
635d1d95fcbSLiam Girdwood 		if (__sleep_us) \
636d1d95fcbSLiam Girdwood 			usleep_range((__sleep_us >> 2) + 1, __sleep_us); \
637d1d95fcbSLiam Girdwood 	} \
638d1d95fcbSLiam Girdwood 	(cond) ? 0 : -ETIMEDOUT; \
639d1d95fcbSLiam Girdwood })
640d1d95fcbSLiam Girdwood 
641d1d95fcbSLiam Girdwood /* This is for registers bits with attribute RWC */
642d1d95fcbSLiam Girdwood bool snd_sof_pci_update_bits(struct snd_sof_dev *sdev, u32 offset,
643d1d95fcbSLiam Girdwood 			     u32 mask, u32 value);
644d1d95fcbSLiam Girdwood 
645d1d95fcbSLiam Girdwood bool snd_sof_dsp_update_bits_unlocked(struct snd_sof_dev *sdev, u32 bar,
646d1d95fcbSLiam Girdwood 				      u32 offset, u32 mask, u32 value);
647d1d95fcbSLiam Girdwood 
648d1d95fcbSLiam Girdwood bool snd_sof_dsp_update_bits64_unlocked(struct snd_sof_dev *sdev, u32 bar,
649d1d95fcbSLiam Girdwood 					u32 offset, u64 mask, u64 value);
650d1d95fcbSLiam Girdwood 
651d1d95fcbSLiam Girdwood bool snd_sof_dsp_update_bits(struct snd_sof_dev *sdev, u32 bar, u32 offset,
652d1d95fcbSLiam Girdwood 			     u32 mask, u32 value);
653d1d95fcbSLiam Girdwood 
654d1d95fcbSLiam Girdwood bool snd_sof_dsp_update_bits64(struct snd_sof_dev *sdev, u32 bar,
655d1d95fcbSLiam Girdwood 			       u32 offset, u64 mask, u64 value);
656d1d95fcbSLiam Girdwood 
657d1d95fcbSLiam Girdwood void snd_sof_dsp_update_bits_forced(struct snd_sof_dev *sdev, u32 bar,
658d1d95fcbSLiam Girdwood 				    u32 offset, u32 mask, u32 value);
659d1d95fcbSLiam Girdwood 
660d1d95fcbSLiam Girdwood int snd_sof_dsp_register_poll(struct snd_sof_dev *sdev, u32 bar, u32 offset,
661d1d95fcbSLiam Girdwood 			      u32 mask, u32 target, u32 timeout_ms,
662d1d95fcbSLiam Girdwood 			      u32 interval_us);
663d1d95fcbSLiam Girdwood 
664d1d95fcbSLiam Girdwood void snd_sof_dsp_panic(struct snd_sof_dev *sdev, u32 offset);
665d1d95fcbSLiam Girdwood #endif
666