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 24*37e809d5SPierre-Louis Bossart static inline int sof_ops_init(struct snd_sof_dev *sdev) 25856601e5SPierre-Louis Bossart { 26856601e5SPierre-Louis Bossart if (sdev->pdata->desc->ops_init) 27*37e809d5SPierre-Louis Bossart return sdev->pdata->desc->ops_init(sdev); 28*37e809d5SPierre-Louis Bossart 29*37e809d5SPierre-Louis Bossart return 0; 30856601e5SPierre-Louis Bossart } 31856601e5SPierre-Louis Bossart 32d1d95fcbSLiam Girdwood /* Mandatory operations are verified during probing */ 33d1d95fcbSLiam Girdwood 34d1d95fcbSLiam Girdwood /* init */ 35d1d95fcbSLiam Girdwood static inline int snd_sof_probe(struct snd_sof_dev *sdev) 36d1d95fcbSLiam Girdwood { 37d1d95fcbSLiam Girdwood return sof_ops(sdev)->probe(sdev); 38d1d95fcbSLiam Girdwood } 39d1d95fcbSLiam Girdwood 40d1d95fcbSLiam Girdwood static inline int snd_sof_remove(struct snd_sof_dev *sdev) 41d1d95fcbSLiam Girdwood { 42d1d95fcbSLiam Girdwood if (sof_ops(sdev)->remove) 43d1d95fcbSLiam Girdwood return sof_ops(sdev)->remove(sdev); 44d1d95fcbSLiam Girdwood 45d1d95fcbSLiam Girdwood return 0; 46d1d95fcbSLiam Girdwood } 47d1d95fcbSLiam Girdwood 487edb3051SKeyon Jie static inline int snd_sof_shutdown(struct snd_sof_dev *sdev) 497edb3051SKeyon Jie { 507edb3051SKeyon Jie if (sof_ops(sdev)->shutdown) 517edb3051SKeyon Jie return sof_ops(sdev)->shutdown(sdev); 527edb3051SKeyon Jie 537edb3051SKeyon Jie return 0; 547edb3051SKeyon Jie } 557edb3051SKeyon Jie 56d1d95fcbSLiam Girdwood /* control */ 57d1d95fcbSLiam Girdwood 58d1d95fcbSLiam Girdwood /* 59d1d95fcbSLiam Girdwood * snd_sof_dsp_run returns the core mask of the cores that are available 60d1d95fcbSLiam Girdwood * after successful fw boot 61d1d95fcbSLiam Girdwood */ 62d1d95fcbSLiam Girdwood static inline int snd_sof_dsp_run(struct snd_sof_dev *sdev) 63d1d95fcbSLiam Girdwood { 64d1d95fcbSLiam Girdwood return sof_ops(sdev)->run(sdev); 65d1d95fcbSLiam Girdwood } 66d1d95fcbSLiam Girdwood 67a70eb708SFred Oh static inline int snd_sof_dsp_stall(struct snd_sof_dev *sdev, unsigned int core_mask) 68d1d95fcbSLiam Girdwood { 69d1d95fcbSLiam Girdwood if (sof_ops(sdev)->stall) 70a70eb708SFred Oh return sof_ops(sdev)->stall(sdev, core_mask); 71d1d95fcbSLiam Girdwood 72d1d95fcbSLiam Girdwood return 0; 73d1d95fcbSLiam Girdwood } 74d1d95fcbSLiam Girdwood 75d1d95fcbSLiam Girdwood static inline int snd_sof_dsp_reset(struct snd_sof_dev *sdev) 76d1d95fcbSLiam Girdwood { 77d1d95fcbSLiam Girdwood if (sof_ops(sdev)->reset) 78d1d95fcbSLiam Girdwood return sof_ops(sdev)->reset(sdev); 79d1d95fcbSLiam Girdwood 80d1d95fcbSLiam Girdwood return 0; 81d1d95fcbSLiam Girdwood } 82d1d95fcbSLiam Girdwood 839ea80748SRanjani Sridharan /* dsp core get/put */ 84c414d5dfSRanjani Sridharan static inline int snd_sof_dsp_core_get(struct snd_sof_dev *sdev, int core) 85c414d5dfSRanjani Sridharan { 86c414d5dfSRanjani Sridharan if (core > sdev->num_cores - 1) { 87c414d5dfSRanjani Sridharan dev_err(sdev->dev, "invalid core id: %d for num_cores: %d\n", core, 88c414d5dfSRanjani Sridharan sdev->num_cores); 89c414d5dfSRanjani Sridharan return -EINVAL; 90c414d5dfSRanjani Sridharan } 91c414d5dfSRanjani Sridharan 92c414d5dfSRanjani Sridharan if (sof_ops(sdev)->core_get) { 93c414d5dfSRanjani Sridharan int ret; 94c414d5dfSRanjani Sridharan 95c414d5dfSRanjani Sridharan /* if current ref_count is > 0, increment it and return */ 96c414d5dfSRanjani Sridharan if (sdev->dsp_core_ref_count[core] > 0) { 97c414d5dfSRanjani Sridharan sdev->dsp_core_ref_count[core]++; 98c414d5dfSRanjani Sridharan return 0; 99c414d5dfSRanjani Sridharan } 100c414d5dfSRanjani Sridharan 101c414d5dfSRanjani Sridharan /* power up the core */ 102c414d5dfSRanjani Sridharan ret = sof_ops(sdev)->core_get(sdev, core); 103c414d5dfSRanjani Sridharan if (ret < 0) 104c414d5dfSRanjani Sridharan return ret; 105c414d5dfSRanjani Sridharan 106c414d5dfSRanjani Sridharan /* increment ref_count */ 107c414d5dfSRanjani Sridharan sdev->dsp_core_ref_count[core]++; 108c414d5dfSRanjani Sridharan 109c414d5dfSRanjani Sridharan /* and update enabled_cores_mask */ 110c414d5dfSRanjani Sridharan sdev->enabled_cores_mask |= BIT(core); 111c414d5dfSRanjani Sridharan 112c414d5dfSRanjani Sridharan dev_dbg(sdev->dev, "Core %d powered up\n", core); 113c414d5dfSRanjani Sridharan } 114c414d5dfSRanjani Sridharan 115c414d5dfSRanjani Sridharan return 0; 116c414d5dfSRanjani Sridharan } 117c414d5dfSRanjani Sridharan 118c414d5dfSRanjani Sridharan static inline int snd_sof_dsp_core_put(struct snd_sof_dev *sdev, int core) 119c414d5dfSRanjani Sridharan { 120c414d5dfSRanjani Sridharan if (core > sdev->num_cores - 1) { 121c414d5dfSRanjani Sridharan dev_err(sdev->dev, "invalid core id: %d for num_cores: %d\n", core, 122c414d5dfSRanjani Sridharan sdev->num_cores); 123c414d5dfSRanjani Sridharan return -EINVAL; 124c414d5dfSRanjani Sridharan } 125c414d5dfSRanjani Sridharan 126c414d5dfSRanjani Sridharan if (sof_ops(sdev)->core_put) { 127c414d5dfSRanjani Sridharan int ret; 128c414d5dfSRanjani Sridharan 129c414d5dfSRanjani Sridharan /* decrement ref_count and return if it is > 0 */ 130c414d5dfSRanjani Sridharan if (--(sdev->dsp_core_ref_count[core]) > 0) 131c414d5dfSRanjani Sridharan return 0; 132c414d5dfSRanjani Sridharan 133c414d5dfSRanjani Sridharan /* power down the core */ 134c414d5dfSRanjani Sridharan ret = sof_ops(sdev)->core_put(sdev, core); 135c414d5dfSRanjani Sridharan if (ret < 0) 136c414d5dfSRanjani Sridharan return ret; 137c414d5dfSRanjani Sridharan 138c414d5dfSRanjani Sridharan /* and update enabled_cores_mask */ 139c414d5dfSRanjani Sridharan sdev->enabled_cores_mask &= ~BIT(core); 140c414d5dfSRanjani Sridharan 141c414d5dfSRanjani Sridharan dev_dbg(sdev->dev, "Core %d powered down\n", core); 142c414d5dfSRanjani Sridharan } 143c414d5dfSRanjani Sridharan 144c414d5dfSRanjani Sridharan return 0; 145c414d5dfSRanjani Sridharan } 146c414d5dfSRanjani Sridharan 147d1d95fcbSLiam Girdwood /* pre/post fw load */ 148d1d95fcbSLiam Girdwood static inline int snd_sof_dsp_pre_fw_run(struct snd_sof_dev *sdev) 149d1d95fcbSLiam Girdwood { 150d1d95fcbSLiam Girdwood if (sof_ops(sdev)->pre_fw_run) 151d1d95fcbSLiam Girdwood return sof_ops(sdev)->pre_fw_run(sdev); 152d1d95fcbSLiam Girdwood 153d1d95fcbSLiam Girdwood return 0; 154d1d95fcbSLiam Girdwood } 155d1d95fcbSLiam Girdwood 156d1d95fcbSLiam Girdwood static inline int snd_sof_dsp_post_fw_run(struct snd_sof_dev *sdev) 157d1d95fcbSLiam Girdwood { 158d1d95fcbSLiam Girdwood if (sof_ops(sdev)->post_fw_run) 159d1d95fcbSLiam Girdwood return sof_ops(sdev)->post_fw_run(sdev); 160d1d95fcbSLiam Girdwood 161d1d95fcbSLiam Girdwood return 0; 162d1d95fcbSLiam Girdwood } 163d1d95fcbSLiam Girdwood 164e984f3efSFred Oh /* parse platform specific extended manifest */ 165e984f3efSFred Oh static inline int snd_sof_dsp_parse_platform_ext_manifest(struct snd_sof_dev *sdev, 166e984f3efSFred Oh const struct sof_ext_man_elem_header *hdr) 167e984f3efSFred Oh { 168e984f3efSFred Oh if (sof_ops(sdev)->parse_platform_ext_manifest) 169e984f3efSFred Oh return sof_ops(sdev)->parse_platform_ext_manifest(sdev, hdr); 170e984f3efSFred Oh 171e984f3efSFred Oh return 0; 172e984f3efSFred Oh } 173e984f3efSFred Oh 174ce8234a6SDaniel Baluta /* misc */ 175ce8234a6SDaniel Baluta 176ce8234a6SDaniel Baluta /** 177ce8234a6SDaniel Baluta * snd_sof_dsp_get_bar_index - Maps a section type with a BAR index 178ce8234a6SDaniel Baluta * 179ce8234a6SDaniel Baluta * @sdev: sof device 180ce8234a6SDaniel Baluta * @type: section type as described by snd_sof_fw_blk_type 181ce8234a6SDaniel Baluta * 182ce8234a6SDaniel Baluta * Returns the corresponding BAR index (a positive integer) or -EINVAL 183ce8234a6SDaniel Baluta * in case there is no mapping 184ce8234a6SDaniel Baluta */ 185ce8234a6SDaniel Baluta static inline int snd_sof_dsp_get_bar_index(struct snd_sof_dev *sdev, u32 type) 186ce8234a6SDaniel Baluta { 187ce8234a6SDaniel Baluta if (sof_ops(sdev)->get_bar_index) 188ce8234a6SDaniel Baluta return sof_ops(sdev)->get_bar_index(sdev, type); 189ce8234a6SDaniel Baluta 190ce8234a6SDaniel Baluta return sdev->mmio_bar; 191ce8234a6SDaniel Baluta } 192ce8234a6SDaniel Baluta 193bb9c93f5SDaniel Baluta static inline int snd_sof_dsp_get_mailbox_offset(struct snd_sof_dev *sdev) 194bb9c93f5SDaniel Baluta { 195bb9c93f5SDaniel Baluta if (sof_ops(sdev)->get_mailbox_offset) 196bb9c93f5SDaniel Baluta return sof_ops(sdev)->get_mailbox_offset(sdev); 197bb9c93f5SDaniel Baluta 198bb9c93f5SDaniel Baluta dev_err(sdev->dev, "error: %s not defined\n", __func__); 199bb9c93f5SDaniel Baluta return -ENOTSUPP; 200bb9c93f5SDaniel Baluta } 201bb9c93f5SDaniel Baluta 202e17422cdSDaniel Baluta static inline int snd_sof_dsp_get_window_offset(struct snd_sof_dev *sdev, 203e17422cdSDaniel Baluta u32 id) 204e17422cdSDaniel Baluta { 205e17422cdSDaniel Baluta if (sof_ops(sdev)->get_window_offset) 206e17422cdSDaniel Baluta return sof_ops(sdev)->get_window_offset(sdev, id); 207e17422cdSDaniel Baluta 208e17422cdSDaniel Baluta dev_err(sdev->dev, "error: %s not defined\n", __func__); 209e17422cdSDaniel Baluta return -ENOTSUPP; 210e17422cdSDaniel Baluta } 211d1d95fcbSLiam Girdwood /* power management */ 212d1d95fcbSLiam Girdwood static inline int snd_sof_dsp_resume(struct snd_sof_dev *sdev) 213d1d95fcbSLiam Girdwood { 214d1d95fcbSLiam Girdwood if (sof_ops(sdev)->resume) 215d1d95fcbSLiam Girdwood return sof_ops(sdev)->resume(sdev); 216d1d95fcbSLiam Girdwood 217d1d95fcbSLiam Girdwood return 0; 218d1d95fcbSLiam Girdwood } 219d1d95fcbSLiam Girdwood 22061e285caSRanjani Sridharan static inline int snd_sof_dsp_suspend(struct snd_sof_dev *sdev, 22161e285caSRanjani Sridharan u32 target_state) 222d1d95fcbSLiam Girdwood { 223d1d95fcbSLiam Girdwood if (sof_ops(sdev)->suspend) 22461e285caSRanjani Sridharan return sof_ops(sdev)->suspend(sdev, target_state); 225d1d95fcbSLiam Girdwood 226d1d95fcbSLiam Girdwood return 0; 227d1d95fcbSLiam Girdwood } 228d1d95fcbSLiam Girdwood 229d1d95fcbSLiam Girdwood static inline int snd_sof_dsp_runtime_resume(struct snd_sof_dev *sdev) 230d1d95fcbSLiam Girdwood { 231d1d95fcbSLiam Girdwood if (sof_ops(sdev)->runtime_resume) 232d1d95fcbSLiam Girdwood return sof_ops(sdev)->runtime_resume(sdev); 233d1d95fcbSLiam Girdwood 234d1d95fcbSLiam Girdwood return 0; 235d1d95fcbSLiam Girdwood } 236d1d95fcbSLiam Girdwood 2371c38c922SFred Oh static inline int snd_sof_dsp_runtime_suspend(struct snd_sof_dev *sdev) 238d1d95fcbSLiam Girdwood { 239d1d95fcbSLiam Girdwood if (sof_ops(sdev)->runtime_suspend) 2401c38c922SFred Oh return sof_ops(sdev)->runtime_suspend(sdev); 241d1d95fcbSLiam Girdwood 242d1d95fcbSLiam Girdwood return 0; 243d1d95fcbSLiam Girdwood } 244d1d95fcbSLiam Girdwood 24562fde977SKai Vehmanen static inline int snd_sof_dsp_runtime_idle(struct snd_sof_dev *sdev) 24662fde977SKai Vehmanen { 24762fde977SKai Vehmanen if (sof_ops(sdev)->runtime_idle) 24862fde977SKai Vehmanen return sof_ops(sdev)->runtime_idle(sdev); 24962fde977SKai Vehmanen 25062fde977SKai Vehmanen return 0; 25162fde977SKai Vehmanen } 25262fde977SKai Vehmanen 2537077a07aSRanjani Sridharan static inline int snd_sof_dsp_hw_params_upon_resume(struct snd_sof_dev *sdev) 254ed3baacdSRanjani Sridharan { 255ed3baacdSRanjani Sridharan if (sof_ops(sdev)->set_hw_params_upon_resume) 2567077a07aSRanjani Sridharan return sof_ops(sdev)->set_hw_params_upon_resume(sdev); 2577077a07aSRanjani Sridharan return 0; 258ed3baacdSRanjani Sridharan } 259ed3baacdSRanjani Sridharan 260d1d95fcbSLiam Girdwood static inline int snd_sof_dsp_set_clk(struct snd_sof_dev *sdev, u32 freq) 261d1d95fcbSLiam Girdwood { 262d1d95fcbSLiam Girdwood if (sof_ops(sdev)->set_clk) 263d1d95fcbSLiam Girdwood return sof_ops(sdev)->set_clk(sdev, freq); 264d1d95fcbSLiam Girdwood 265d1d95fcbSLiam Girdwood return 0; 266d1d95fcbSLiam Girdwood } 267d1d95fcbSLiam Girdwood 26861e285caSRanjani Sridharan static inline int 26961e285caSRanjani Sridharan snd_sof_dsp_set_power_state(struct snd_sof_dev *sdev, 27061e285caSRanjani Sridharan const struct sof_dsp_power_state *target_state) 271e8f112d8SKeyon Jie { 2728b66d7c5SKeyon Jie int ret = 0; 273e8f112d8SKeyon Jie 2748b66d7c5SKeyon Jie mutex_lock(&sdev->power_state_access); 2758b66d7c5SKeyon Jie 2768b66d7c5SKeyon Jie if (sof_ops(sdev)->set_power_state) 2778b66d7c5SKeyon Jie ret = sof_ops(sdev)->set_power_state(sdev, target_state); 2788b66d7c5SKeyon Jie 2798b66d7c5SKeyon Jie mutex_unlock(&sdev->power_state_access); 2808b66d7c5SKeyon Jie 2818b66d7c5SKeyon Jie return ret; 282e8f112d8SKeyon Jie } 283e8f112d8SKeyon Jie 284d1d95fcbSLiam Girdwood /* debug */ 2852f148430SPeter Ujfalusi void snd_sof_dsp_dbg_dump(struct snd_sof_dev *sdev, const char *msg, u32 flags); 2865e4a27fdSPan Xiuli 28707e833b4SPeter Ujfalusi static inline int snd_sof_debugfs_add_region_item(struct snd_sof_dev *sdev, 28807e833b4SPeter Ujfalusi enum snd_sof_fw_blk_type blk_type, u32 offset, size_t size, 28907e833b4SPeter Ujfalusi const char *name, enum sof_debugfs_access_type access_type) 29007e833b4SPeter Ujfalusi { 29107e833b4SPeter Ujfalusi if (sof_ops(sdev) && sof_ops(sdev)->debugfs_add_region_item) 29207e833b4SPeter Ujfalusi return sof_ops(sdev)->debugfs_add_region_item(sdev, blk_type, offset, 29307e833b4SPeter Ujfalusi size, name, access_type); 29407e833b4SPeter Ujfalusi 29507e833b4SPeter Ujfalusi return 0; 29607e833b4SPeter Ujfalusi } 29707e833b4SPeter Ujfalusi 298d1d95fcbSLiam Girdwood /* register IO */ 299d1d95fcbSLiam Girdwood static inline void snd_sof_dsp_write(struct snd_sof_dev *sdev, u32 bar, 300d1d95fcbSLiam Girdwood u32 offset, u32 value) 301d1d95fcbSLiam Girdwood { 302d1d95fcbSLiam Girdwood if (sof_ops(sdev)->write) { 303d1d95fcbSLiam Girdwood sof_ops(sdev)->write(sdev, sdev->bar[bar] + offset, value); 304d1d95fcbSLiam Girdwood return; 305d1d95fcbSLiam Girdwood } 306d1d95fcbSLiam Girdwood 307d1d95fcbSLiam Girdwood dev_err_ratelimited(sdev->dev, "error: %s not defined\n", __func__); 308d1d95fcbSLiam Girdwood } 309d1d95fcbSLiam Girdwood 310d1d95fcbSLiam Girdwood static inline void snd_sof_dsp_write64(struct snd_sof_dev *sdev, u32 bar, 311d1d95fcbSLiam Girdwood u32 offset, u64 value) 312d1d95fcbSLiam Girdwood { 313d1d95fcbSLiam Girdwood if (sof_ops(sdev)->write64) { 314d1d95fcbSLiam Girdwood sof_ops(sdev)->write64(sdev, sdev->bar[bar] + offset, value); 315d1d95fcbSLiam Girdwood return; 316d1d95fcbSLiam Girdwood } 317d1d95fcbSLiam Girdwood 318d1d95fcbSLiam Girdwood dev_err_ratelimited(sdev->dev, "error: %s not defined\n", __func__); 319d1d95fcbSLiam Girdwood } 320d1d95fcbSLiam Girdwood 321d1d95fcbSLiam Girdwood static inline u32 snd_sof_dsp_read(struct snd_sof_dev *sdev, u32 bar, 322d1d95fcbSLiam Girdwood u32 offset) 323d1d95fcbSLiam Girdwood { 324d1d95fcbSLiam Girdwood if (sof_ops(sdev)->read) 325d1d95fcbSLiam Girdwood return sof_ops(sdev)->read(sdev, sdev->bar[bar] + offset); 326d1d95fcbSLiam Girdwood 327d1d95fcbSLiam Girdwood dev_err(sdev->dev, "error: %s not defined\n", __func__); 328d1d95fcbSLiam Girdwood return -ENOTSUPP; 329d1d95fcbSLiam Girdwood } 330d1d95fcbSLiam Girdwood 331d1d95fcbSLiam Girdwood static inline u64 snd_sof_dsp_read64(struct snd_sof_dev *sdev, u32 bar, 332d1d95fcbSLiam Girdwood u32 offset) 333d1d95fcbSLiam Girdwood { 334d1d95fcbSLiam Girdwood if (sof_ops(sdev)->read64) 335d1d95fcbSLiam Girdwood return sof_ops(sdev)->read64(sdev, sdev->bar[bar] + offset); 336d1d95fcbSLiam Girdwood 337d1d95fcbSLiam Girdwood dev_err(sdev->dev, "error: %s not defined\n", __func__); 338d1d95fcbSLiam Girdwood return -ENOTSUPP; 339d1d95fcbSLiam Girdwood } 340d1d95fcbSLiam Girdwood 341d1d95fcbSLiam Girdwood /* block IO */ 3424624bb2fSPeter Ujfalusi static inline int snd_sof_dsp_block_read(struct snd_sof_dev *sdev, 3434624bb2fSPeter Ujfalusi enum snd_sof_fw_blk_type blk_type, 344d1d95fcbSLiam Girdwood u32 offset, void *dest, size_t bytes) 345d1d95fcbSLiam Girdwood { 3464624bb2fSPeter Ujfalusi return sof_ops(sdev)->block_read(sdev, blk_type, offset, dest, bytes); 347d1d95fcbSLiam Girdwood } 348d1d95fcbSLiam Girdwood 3494624bb2fSPeter Ujfalusi static inline int snd_sof_dsp_block_write(struct snd_sof_dev *sdev, 3504624bb2fSPeter Ujfalusi enum snd_sof_fw_blk_type blk_type, 351d1d95fcbSLiam Girdwood u32 offset, void *src, size_t bytes) 352d1d95fcbSLiam Girdwood { 3534624bb2fSPeter Ujfalusi return sof_ops(sdev)->block_write(sdev, blk_type, offset, src, bytes); 354d1d95fcbSLiam Girdwood } 355d1d95fcbSLiam Girdwood 356f71f59ddSDaniel Baluta /* mailbox IO */ 357f71f59ddSDaniel Baluta static inline void snd_sof_dsp_mailbox_read(struct snd_sof_dev *sdev, 358f71f59ddSDaniel Baluta u32 offset, void *dest, size_t bytes) 359f71f59ddSDaniel Baluta { 360f71f59ddSDaniel Baluta if (sof_ops(sdev)->mailbox_read) 361f71f59ddSDaniel Baluta sof_ops(sdev)->mailbox_read(sdev, offset, dest, bytes); 362f71f59ddSDaniel Baluta } 363f71f59ddSDaniel Baluta 364f71f59ddSDaniel Baluta static inline void snd_sof_dsp_mailbox_write(struct snd_sof_dev *sdev, 365f71f59ddSDaniel Baluta u32 offset, void *src, size_t bytes) 366f71f59ddSDaniel Baluta { 367f71f59ddSDaniel Baluta if (sof_ops(sdev)->mailbox_write) 368f71f59ddSDaniel Baluta sof_ops(sdev)->mailbox_write(sdev, offset, src, bytes); 369f71f59ddSDaniel Baluta } 370f71f59ddSDaniel Baluta 371d1d95fcbSLiam Girdwood /* ipc */ 372d1d95fcbSLiam Girdwood static inline int snd_sof_dsp_send_msg(struct snd_sof_dev *sdev, 373d1d95fcbSLiam Girdwood struct snd_sof_ipc_msg *msg) 374d1d95fcbSLiam Girdwood { 375d1d95fcbSLiam Girdwood return sof_ops(sdev)->send_msg(sdev, msg); 376d1d95fcbSLiam Girdwood } 377d1d95fcbSLiam Girdwood 378d1d95fcbSLiam Girdwood /* host DMA trace */ 379d1d95fcbSLiam Girdwood static inline int snd_sof_dma_trace_init(struct snd_sof_dev *sdev, 380bab05b50SPeter Ujfalusi struct sof_ipc_dma_trace_params_ext *dtrace_params) 381d1d95fcbSLiam Girdwood { 382d1d95fcbSLiam Girdwood if (sof_ops(sdev)->trace_init) 383bab05b50SPeter Ujfalusi return sof_ops(sdev)->trace_init(sdev, dtrace_params); 384d1d95fcbSLiam Girdwood 385d1d95fcbSLiam Girdwood return 0; 386d1d95fcbSLiam Girdwood } 387d1d95fcbSLiam Girdwood 388d1d95fcbSLiam Girdwood static inline int snd_sof_dma_trace_release(struct snd_sof_dev *sdev) 389d1d95fcbSLiam Girdwood { 390d1d95fcbSLiam Girdwood if (sof_ops(sdev)->trace_release) 391d1d95fcbSLiam Girdwood return sof_ops(sdev)->trace_release(sdev); 392d1d95fcbSLiam Girdwood 393d1d95fcbSLiam Girdwood return 0; 394d1d95fcbSLiam Girdwood } 395d1d95fcbSLiam Girdwood 396d1d95fcbSLiam Girdwood static inline int snd_sof_dma_trace_trigger(struct snd_sof_dev *sdev, int cmd) 397d1d95fcbSLiam Girdwood { 398d1d95fcbSLiam Girdwood if (sof_ops(sdev)->trace_trigger) 399d1d95fcbSLiam Girdwood return sof_ops(sdev)->trace_trigger(sdev, cmd); 400d1d95fcbSLiam Girdwood 401d1d95fcbSLiam Girdwood return 0; 402d1d95fcbSLiam Girdwood } 403d1d95fcbSLiam Girdwood 404d1d95fcbSLiam Girdwood /* host PCM ops */ 405d1d95fcbSLiam Girdwood static inline int 406d1d95fcbSLiam Girdwood snd_sof_pcm_platform_open(struct snd_sof_dev *sdev, 407d1d95fcbSLiam Girdwood struct snd_pcm_substream *substream) 408d1d95fcbSLiam Girdwood { 409d1d95fcbSLiam Girdwood if (sof_ops(sdev) && sof_ops(sdev)->pcm_open) 410d1d95fcbSLiam Girdwood return sof_ops(sdev)->pcm_open(sdev, substream); 411d1d95fcbSLiam Girdwood 412d1d95fcbSLiam Girdwood return 0; 413d1d95fcbSLiam Girdwood } 414d1d95fcbSLiam Girdwood 415d1d95fcbSLiam Girdwood /* disconnect pcm substream to a host stream */ 416d1d95fcbSLiam Girdwood static inline int 417d1d95fcbSLiam Girdwood snd_sof_pcm_platform_close(struct snd_sof_dev *sdev, 418d1d95fcbSLiam Girdwood struct snd_pcm_substream *substream) 419d1d95fcbSLiam Girdwood { 420d1d95fcbSLiam Girdwood if (sof_ops(sdev) && sof_ops(sdev)->pcm_close) 421d1d95fcbSLiam Girdwood return sof_ops(sdev)->pcm_close(sdev, substream); 422d1d95fcbSLiam Girdwood 423d1d95fcbSLiam Girdwood return 0; 424d1d95fcbSLiam Girdwood } 425d1d95fcbSLiam Girdwood 426d1d95fcbSLiam Girdwood /* host stream hw params */ 427d1d95fcbSLiam Girdwood static inline int 428d1d95fcbSLiam Girdwood snd_sof_pcm_platform_hw_params(struct snd_sof_dev *sdev, 429d1d95fcbSLiam Girdwood struct snd_pcm_substream *substream, 430d1d95fcbSLiam Girdwood struct snd_pcm_hw_params *params, 43131f60a0cSPeter Ujfalusi struct snd_sof_platform_stream_params *platform_params) 432d1d95fcbSLiam Girdwood { 433d1d95fcbSLiam Girdwood if (sof_ops(sdev) && sof_ops(sdev)->pcm_hw_params) 43431f60a0cSPeter Ujfalusi return sof_ops(sdev)->pcm_hw_params(sdev, substream, params, 43531f60a0cSPeter Ujfalusi platform_params); 436d1d95fcbSLiam Girdwood 437d1d95fcbSLiam Girdwood return 0; 438d1d95fcbSLiam Girdwood } 439d1d95fcbSLiam Girdwood 44093146bc2SRanjani Sridharan /* host stream hw free */ 44193146bc2SRanjani Sridharan static inline int 44293146bc2SRanjani Sridharan snd_sof_pcm_platform_hw_free(struct snd_sof_dev *sdev, 44393146bc2SRanjani Sridharan struct snd_pcm_substream *substream) 44493146bc2SRanjani Sridharan { 44593146bc2SRanjani Sridharan if (sof_ops(sdev) && sof_ops(sdev)->pcm_hw_free) 44693146bc2SRanjani Sridharan return sof_ops(sdev)->pcm_hw_free(sdev, substream); 44793146bc2SRanjani Sridharan 44893146bc2SRanjani Sridharan return 0; 44993146bc2SRanjani Sridharan } 45093146bc2SRanjani Sridharan 451d1d95fcbSLiam Girdwood /* host stream trigger */ 452d1d95fcbSLiam Girdwood static inline int 453d1d95fcbSLiam Girdwood snd_sof_pcm_platform_trigger(struct snd_sof_dev *sdev, 454d1d95fcbSLiam Girdwood struct snd_pcm_substream *substream, int cmd) 455d1d95fcbSLiam Girdwood { 456d1d95fcbSLiam Girdwood if (sof_ops(sdev) && sof_ops(sdev)->pcm_trigger) 457d1d95fcbSLiam Girdwood return sof_ops(sdev)->pcm_trigger(sdev, substream, cmd); 458d1d95fcbSLiam Girdwood 459d1d95fcbSLiam Girdwood return 0; 460d1d95fcbSLiam Girdwood } 461d1d95fcbSLiam Girdwood 46296ec1741SPeter Ujfalusi /* Firmware loading */ 46396ec1741SPeter Ujfalusi static inline int snd_sof_load_firmware(struct snd_sof_dev *sdev) 46496ec1741SPeter Ujfalusi { 46596ec1741SPeter Ujfalusi dev_dbg(sdev->dev, "loading firmware\n"); 46696ec1741SPeter Ujfalusi 46796ec1741SPeter Ujfalusi return sof_ops(sdev)->load_firmware(sdev); 46896ec1741SPeter Ujfalusi } 46996ec1741SPeter Ujfalusi 470d1d95fcbSLiam Girdwood /* host DSP message data */ 4716a0ba071SGuennadi Liakhovetski static inline int snd_sof_ipc_msg_data(struct snd_sof_dev *sdev, 472d1d95fcbSLiam Girdwood struct snd_pcm_substream *substream, 473d1d95fcbSLiam Girdwood void *p, size_t sz) 474d1d95fcbSLiam Girdwood { 4756a0ba071SGuennadi Liakhovetski return sof_ops(sdev)->ipc_msg_data(sdev, substream, p, sz); 476d1d95fcbSLiam Girdwood } 477757ce810SPeter Ujfalusi /* host side configuration of the stream's data offset in stream mailbox area */ 478757ce810SPeter Ujfalusi static inline int 479757ce810SPeter Ujfalusi snd_sof_set_stream_data_offset(struct snd_sof_dev *sdev, 480757ce810SPeter Ujfalusi struct snd_pcm_substream *substream, 481757ce810SPeter Ujfalusi size_t posn_offset) 482757ce810SPeter Ujfalusi { 483757ce810SPeter Ujfalusi if (sof_ops(sdev) && sof_ops(sdev)->set_stream_data_offset) 484757ce810SPeter Ujfalusi return sof_ops(sdev)->set_stream_data_offset(sdev, substream, 485757ce810SPeter Ujfalusi posn_offset); 486757ce810SPeter Ujfalusi 487757ce810SPeter Ujfalusi return 0; 488757ce810SPeter Ujfalusi } 489757ce810SPeter Ujfalusi 490d1d95fcbSLiam Girdwood /* host stream pointer */ 491d1d95fcbSLiam Girdwood static inline snd_pcm_uframes_t 492d1d95fcbSLiam Girdwood snd_sof_pcm_platform_pointer(struct snd_sof_dev *sdev, 493d1d95fcbSLiam Girdwood struct snd_pcm_substream *substream) 494d1d95fcbSLiam Girdwood { 495d1d95fcbSLiam Girdwood if (sof_ops(sdev) && sof_ops(sdev)->pcm_pointer) 496d1d95fcbSLiam Girdwood return sof_ops(sdev)->pcm_pointer(sdev, substream); 497d1d95fcbSLiam Girdwood 498d1d95fcbSLiam Girdwood return 0; 499d1d95fcbSLiam Girdwood } 500d1d95fcbSLiam Girdwood 5014a39ea3fSRanjani Sridharan /* pcm ack */ 5024a39ea3fSRanjani Sridharan static inline int snd_sof_pcm_platform_ack(struct snd_sof_dev *sdev, 5034a39ea3fSRanjani Sridharan struct snd_pcm_substream *substream) 5044a39ea3fSRanjani Sridharan { 5054a39ea3fSRanjani Sridharan if (sof_ops(sdev) && sof_ops(sdev)->pcm_ack) 5064a39ea3fSRanjani Sridharan return sof_ops(sdev)->pcm_ack(sdev, substream); 5074a39ea3fSRanjani Sridharan 5084a39ea3fSRanjani Sridharan return 0; 5094a39ea3fSRanjani Sridharan } 5104a39ea3fSRanjani Sridharan 511285880a2SDaniel Baluta /* machine driver */ 512285880a2SDaniel Baluta static inline int 513285880a2SDaniel Baluta snd_sof_machine_register(struct snd_sof_dev *sdev, void *pdata) 514285880a2SDaniel Baluta { 515285880a2SDaniel Baluta if (sof_ops(sdev) && sof_ops(sdev)->machine_register) 516285880a2SDaniel Baluta return sof_ops(sdev)->machine_register(sdev, pdata); 517285880a2SDaniel Baluta 518285880a2SDaniel Baluta return 0; 519285880a2SDaniel Baluta } 520285880a2SDaniel Baluta 521285880a2SDaniel Baluta static inline void 522285880a2SDaniel Baluta snd_sof_machine_unregister(struct snd_sof_dev *sdev, void *pdata) 523285880a2SDaniel Baluta { 524285880a2SDaniel Baluta if (sof_ops(sdev) && sof_ops(sdev)->machine_unregister) 525285880a2SDaniel Baluta sof_ops(sdev)->machine_unregister(sdev, pdata); 526285880a2SDaniel Baluta } 527285880a2SDaniel Baluta 528cb515f10SGuennadi Liakhovetski static inline struct snd_soc_acpi_mach * 529285880a2SDaniel Baluta snd_sof_machine_select(struct snd_sof_dev *sdev) 530285880a2SDaniel Baluta { 531285880a2SDaniel Baluta if (sof_ops(sdev) && sof_ops(sdev)->machine_select) 532cb515f10SGuennadi Liakhovetski return sof_ops(sdev)->machine_select(sdev); 533cb515f10SGuennadi Liakhovetski 534cb515f10SGuennadi Liakhovetski return NULL; 535285880a2SDaniel Baluta } 536285880a2SDaniel Baluta 537285880a2SDaniel Baluta static inline void 538cb515f10SGuennadi Liakhovetski snd_sof_set_mach_params(struct snd_soc_acpi_mach *mach, 53917e9d6b0SPierre-Louis Bossart struct snd_sof_dev *sdev) 540285880a2SDaniel Baluta { 541285880a2SDaniel Baluta if (sof_ops(sdev) && sof_ops(sdev)->set_mach_params) 54217e9d6b0SPierre-Louis Bossart sof_ops(sdev)->set_mach_params(mach, sdev); 543285880a2SDaniel Baluta } 544285880a2SDaniel Baluta 545d1d95fcbSLiam Girdwood /** 546d1d95fcbSLiam Girdwood * snd_sof_dsp_register_poll_timeout - Periodically poll an address 547d1d95fcbSLiam Girdwood * until a condition is met or a timeout occurs 548d1d95fcbSLiam Girdwood * @op: accessor function (takes @addr as its only argument) 549d1d95fcbSLiam Girdwood * @addr: Address to poll 550d1d95fcbSLiam Girdwood * @val: Variable to read the value into 551d1d95fcbSLiam Girdwood * @cond: Break condition (usually involving @val) 552d1d95fcbSLiam Girdwood * @sleep_us: Maximum time to sleep between reads in us (0 553d1d95fcbSLiam Girdwood * tight-loops). Should be less than ~20ms since usleep_range 554458f69efSMauro Carvalho Chehab * is used (see Documentation/timers/timers-howto.rst). 555d1d95fcbSLiam Girdwood * @timeout_us: Timeout in us, 0 means never timeout 556d1d95fcbSLiam Girdwood * 557d1d95fcbSLiam Girdwood * Returns 0 on success and -ETIMEDOUT upon a timeout. In either 558d1d95fcbSLiam Girdwood * case, the last read value at @addr is stored in @val. Must not 559d1d95fcbSLiam Girdwood * be called from atomic context if sleep_us or timeout_us are used. 560d1d95fcbSLiam Girdwood * 561d1d95fcbSLiam Girdwood * This is modelled after the readx_poll_timeout macros in linux/iopoll.h. 562d1d95fcbSLiam Girdwood */ 563d1d95fcbSLiam Girdwood #define snd_sof_dsp_read_poll_timeout(sdev, bar, offset, val, cond, sleep_us, timeout_us) \ 564d1d95fcbSLiam Girdwood ({ \ 565d1d95fcbSLiam Girdwood u64 __timeout_us = (timeout_us); \ 566d1d95fcbSLiam Girdwood unsigned long __sleep_us = (sleep_us); \ 567d1d95fcbSLiam Girdwood ktime_t __timeout = ktime_add_us(ktime_get(), __timeout_us); \ 568d1d95fcbSLiam Girdwood might_sleep_if((__sleep_us) != 0); \ 569d1d95fcbSLiam Girdwood for (;;) { \ 570d1d95fcbSLiam Girdwood (val) = snd_sof_dsp_read(sdev, bar, offset); \ 571d1d95fcbSLiam Girdwood if (cond) { \ 572d1d95fcbSLiam Girdwood dev_dbg(sdev->dev, \ 5733b2e93edSKeyon Jie "FW Poll Status: reg[%#x]=%#x successful\n", \ 5743b2e93edSKeyon Jie (offset), (val)); \ 575d1d95fcbSLiam Girdwood break; \ 576d1d95fcbSLiam Girdwood } \ 577d1d95fcbSLiam Girdwood if (__timeout_us && \ 578d1d95fcbSLiam Girdwood ktime_compare(ktime_get(), __timeout) > 0) { \ 579d1d95fcbSLiam Girdwood (val) = snd_sof_dsp_read(sdev, bar, offset); \ 580d1d95fcbSLiam Girdwood dev_dbg(sdev->dev, \ 5813b2e93edSKeyon Jie "FW Poll Status: reg[%#x]=%#x timedout\n", \ 5823b2e93edSKeyon Jie (offset), (val)); \ 583d1d95fcbSLiam Girdwood break; \ 584d1d95fcbSLiam Girdwood } \ 585d1d95fcbSLiam Girdwood if (__sleep_us) \ 586d1d95fcbSLiam Girdwood usleep_range((__sleep_us >> 2) + 1, __sleep_us); \ 587d1d95fcbSLiam Girdwood } \ 588d1d95fcbSLiam Girdwood (cond) ? 0 : -ETIMEDOUT; \ 589d1d95fcbSLiam Girdwood }) 590d1d95fcbSLiam Girdwood 591d1d95fcbSLiam Girdwood /* This is for registers bits with attribute RWC */ 592d1d95fcbSLiam Girdwood bool snd_sof_pci_update_bits(struct snd_sof_dev *sdev, u32 offset, 593d1d95fcbSLiam Girdwood u32 mask, u32 value); 594d1d95fcbSLiam Girdwood 595d1d95fcbSLiam Girdwood bool snd_sof_dsp_update_bits_unlocked(struct snd_sof_dev *sdev, u32 bar, 596d1d95fcbSLiam Girdwood u32 offset, u32 mask, u32 value); 597d1d95fcbSLiam Girdwood 598d1d95fcbSLiam Girdwood bool snd_sof_dsp_update_bits64_unlocked(struct snd_sof_dev *sdev, u32 bar, 599d1d95fcbSLiam Girdwood u32 offset, u64 mask, u64 value); 600d1d95fcbSLiam Girdwood 601d1d95fcbSLiam Girdwood bool snd_sof_dsp_update_bits(struct snd_sof_dev *sdev, u32 bar, u32 offset, 602d1d95fcbSLiam Girdwood u32 mask, u32 value); 603d1d95fcbSLiam Girdwood 604d1d95fcbSLiam Girdwood bool snd_sof_dsp_update_bits64(struct snd_sof_dev *sdev, u32 bar, 605d1d95fcbSLiam Girdwood u32 offset, u64 mask, u64 value); 606d1d95fcbSLiam Girdwood 607d1d95fcbSLiam Girdwood void snd_sof_dsp_update_bits_forced(struct snd_sof_dev *sdev, u32 bar, 608d1d95fcbSLiam Girdwood u32 offset, u32 mask, u32 value); 609d1d95fcbSLiam Girdwood 610d1d95fcbSLiam Girdwood int snd_sof_dsp_register_poll(struct snd_sof_dev *sdev, u32 bar, u32 offset, 611d1d95fcbSLiam Girdwood u32 mask, u32 target, u32 timeout_ms, 612d1d95fcbSLiam Girdwood u32 interval_us); 613d1d95fcbSLiam Girdwood 614b2b10aa7SPeter Ujfalusi void snd_sof_dsp_panic(struct snd_sof_dev *sdev, u32 offset, bool non_recoverable); 615d1d95fcbSLiam Girdwood #endif 616