root/sound/soc/sof/ops.h

/* [<][>][^][v][top][bottom][index][help] */

INCLUDED FROM


DEFINITIONS

This source file includes following definitions.
  1. snd_sof_probe
  2. snd_sof_remove
  3. snd_sof_dsp_run
  4. snd_sof_dsp_stall
  5. snd_sof_dsp_reset
  6. snd_sof_dsp_core_power_up
  7. snd_sof_dsp_core_power_down
  8. snd_sof_dsp_pre_fw_run
  9. snd_sof_dsp_post_fw_run
  10. snd_sof_dsp_get_bar_index
  11. snd_sof_dsp_get_mailbox_offset
  12. snd_sof_dsp_get_window_offset
  13. snd_sof_dsp_resume
  14. snd_sof_dsp_suspend
  15. snd_sof_dsp_runtime_resume
  16. snd_sof_dsp_runtime_suspend
  17. snd_sof_dsp_runtime_idle
  18. snd_sof_dsp_hw_params_upon_resume
  19. snd_sof_dsp_set_clk
  20. snd_sof_dsp_dbg_dump
  21. snd_sof_ipc_dump
  22. snd_sof_dsp_write
  23. snd_sof_dsp_write64
  24. snd_sof_dsp_read
  25. snd_sof_dsp_read64
  26. snd_sof_dsp_block_read
  27. snd_sof_dsp_block_write
  28. snd_sof_dsp_send_msg
  29. snd_sof_dma_trace_init
  30. snd_sof_dma_trace_release
  31. snd_sof_dma_trace_trigger
  32. snd_sof_pcm_platform_open
  33. snd_sof_pcm_platform_close
  34. snd_sof_pcm_platform_hw_params
  35. snd_sof_pcm_platform_hw_free
  36. snd_sof_pcm_platform_trigger
  37. snd_sof_ipc_msg_data
  38. snd_sof_ipc_pcm_params
  39. snd_sof_pcm_platform_pointer
  40. sof_get_ops

   1 /* SPDX-License-Identifier: (GPL-2.0 OR BSD-3-Clause) */
   2 /*
   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 */
  27 static inline int snd_sof_probe(struct snd_sof_dev *sdev)
  28 {
  29         return sof_ops(sdev)->probe(sdev);
  30 }
  31 
  32 static 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 
  40 /* control */
  41 
  42 /*
  43  * snd_sof_dsp_run returns the core mask of the cores that are available
  44  * after successful fw boot
  45  */
  46 static inline int snd_sof_dsp_run(struct snd_sof_dev *sdev)
  47 {
  48         return sof_ops(sdev)->run(sdev);
  49 }
  50 
  51 static inline int snd_sof_dsp_stall(struct snd_sof_dev *sdev)
  52 {
  53         if (sof_ops(sdev)->stall)
  54                 return sof_ops(sdev)->stall(sdev);
  55 
  56         return 0;
  57 }
  58 
  59 static inline int snd_sof_dsp_reset(struct snd_sof_dev *sdev)
  60 {
  61         if (sof_ops(sdev)->reset)
  62                 return sof_ops(sdev)->reset(sdev);
  63 
  64         return 0;
  65 }
  66 
  67 /* dsp core power up/power down */
  68 static inline int snd_sof_dsp_core_power_up(struct snd_sof_dev *sdev,
  69                                             unsigned int core_mask)
  70 {
  71         if (sof_ops(sdev)->core_power_up)
  72                 return sof_ops(sdev)->core_power_up(sdev, core_mask);
  73 
  74         return 0;
  75 }
  76 
  77 static inline int snd_sof_dsp_core_power_down(struct snd_sof_dev *sdev,
  78                                               unsigned int core_mask)
  79 {
  80         if (sof_ops(sdev)->core_power_down)
  81                 return sof_ops(sdev)->core_power_down(sdev, core_mask);
  82 
  83         return 0;
  84 }
  85 
  86 /* pre/post fw load */
  87 static inline int snd_sof_dsp_pre_fw_run(struct snd_sof_dev *sdev)
  88 {
  89         if (sof_ops(sdev)->pre_fw_run)
  90                 return sof_ops(sdev)->pre_fw_run(sdev);
  91 
  92         return 0;
  93 }
  94 
  95 static inline int snd_sof_dsp_post_fw_run(struct snd_sof_dev *sdev)
  96 {
  97         if (sof_ops(sdev)->post_fw_run)
  98                 return sof_ops(sdev)->post_fw_run(sdev);
  99 
 100         return 0;
 101 }
 102 
 103 /* misc */
 104 
 105 /**
 106  * snd_sof_dsp_get_bar_index - Maps a section type with a BAR index
 107  *
 108  * @sdev: sof device
 109  * @type: section type as described by snd_sof_fw_blk_type
 110  *
 111  * Returns the corresponding BAR index (a positive integer) or -EINVAL
 112  * in case there is no mapping
 113  */
 114 static inline int snd_sof_dsp_get_bar_index(struct snd_sof_dev *sdev, u32 type)
 115 {
 116         if (sof_ops(sdev)->get_bar_index)
 117                 return sof_ops(sdev)->get_bar_index(sdev, type);
 118 
 119         return sdev->mmio_bar;
 120 }
 121 
 122 static inline int snd_sof_dsp_get_mailbox_offset(struct snd_sof_dev *sdev)
 123 {
 124         if (sof_ops(sdev)->get_mailbox_offset)
 125                 return sof_ops(sdev)->get_mailbox_offset(sdev);
 126 
 127         dev_err(sdev->dev, "error: %s not defined\n", __func__);
 128         return -ENOTSUPP;
 129 }
 130 
 131 static inline int snd_sof_dsp_get_window_offset(struct snd_sof_dev *sdev,
 132                                                 u32 id)
 133 {
 134         if (sof_ops(sdev)->get_window_offset)
 135                 return sof_ops(sdev)->get_window_offset(sdev, id);
 136 
 137         dev_err(sdev->dev, "error: %s not defined\n", __func__);
 138         return -ENOTSUPP;
 139 }
 140 /* power management */
 141 static inline int snd_sof_dsp_resume(struct snd_sof_dev *sdev)
 142 {
 143         if (sof_ops(sdev)->resume)
 144                 return sof_ops(sdev)->resume(sdev);
 145 
 146         return 0;
 147 }
 148 
 149 static inline int snd_sof_dsp_suspend(struct snd_sof_dev *sdev)
 150 {
 151         if (sof_ops(sdev)->suspend)
 152                 return sof_ops(sdev)->suspend(sdev);
 153 
 154         return 0;
 155 }
 156 
 157 static inline int snd_sof_dsp_runtime_resume(struct snd_sof_dev *sdev)
 158 {
 159         if (sof_ops(sdev)->runtime_resume)
 160                 return sof_ops(sdev)->runtime_resume(sdev);
 161 
 162         return 0;
 163 }
 164 
 165 static inline int snd_sof_dsp_runtime_suspend(struct snd_sof_dev *sdev)
 166 {
 167         if (sof_ops(sdev)->runtime_suspend)
 168                 return sof_ops(sdev)->runtime_suspend(sdev);
 169 
 170         return 0;
 171 }
 172 
 173 static inline int snd_sof_dsp_runtime_idle(struct snd_sof_dev *sdev)
 174 {
 175         if (sof_ops(sdev)->runtime_idle)
 176                 return sof_ops(sdev)->runtime_idle(sdev);
 177 
 178         return 0;
 179 }
 180 
 181 static inline int snd_sof_dsp_hw_params_upon_resume(struct snd_sof_dev *sdev)
 182 {
 183         if (sof_ops(sdev)->set_hw_params_upon_resume)
 184                 return sof_ops(sdev)->set_hw_params_upon_resume(sdev);
 185         return 0;
 186 }
 187 
 188 static inline int snd_sof_dsp_set_clk(struct snd_sof_dev *sdev, u32 freq)
 189 {
 190         if (sof_ops(sdev)->set_clk)
 191                 return sof_ops(sdev)->set_clk(sdev, freq);
 192 
 193         return 0;
 194 }
 195 
 196 /* debug */
 197 static inline void snd_sof_dsp_dbg_dump(struct snd_sof_dev *sdev, u32 flags)
 198 {
 199         if (sof_ops(sdev)->dbg_dump)
 200                 return sof_ops(sdev)->dbg_dump(sdev, flags);
 201 }
 202 
 203 static inline void snd_sof_ipc_dump(struct snd_sof_dev *sdev)
 204 {
 205         if (sof_ops(sdev)->ipc_dump)
 206                 return sof_ops(sdev)->ipc_dump(sdev);
 207 }
 208 
 209 /* register IO */
 210 static inline void snd_sof_dsp_write(struct snd_sof_dev *sdev, u32 bar,
 211                                      u32 offset, u32 value)
 212 {
 213         if (sof_ops(sdev)->write) {
 214                 sof_ops(sdev)->write(sdev, sdev->bar[bar] + offset, value);
 215                 return;
 216         }
 217 
 218         dev_err_ratelimited(sdev->dev, "error: %s not defined\n", __func__);
 219 }
 220 
 221 static inline void snd_sof_dsp_write64(struct snd_sof_dev *sdev, u32 bar,
 222                                        u32 offset, u64 value)
 223 {
 224         if (sof_ops(sdev)->write64) {
 225                 sof_ops(sdev)->write64(sdev, sdev->bar[bar] + offset, value);
 226                 return;
 227         }
 228 
 229         dev_err_ratelimited(sdev->dev, "error: %s not defined\n", __func__);
 230 }
 231 
 232 static inline u32 snd_sof_dsp_read(struct snd_sof_dev *sdev, u32 bar,
 233                                    u32 offset)
 234 {
 235         if (sof_ops(sdev)->read)
 236                 return sof_ops(sdev)->read(sdev, sdev->bar[bar] + offset);
 237 
 238         dev_err(sdev->dev, "error: %s not defined\n", __func__);
 239         return -ENOTSUPP;
 240 }
 241 
 242 static inline u64 snd_sof_dsp_read64(struct snd_sof_dev *sdev, u32 bar,
 243                                      u32 offset)
 244 {
 245         if (sof_ops(sdev)->read64)
 246                 return sof_ops(sdev)->read64(sdev, sdev->bar[bar] + offset);
 247 
 248         dev_err(sdev->dev, "error: %s not defined\n", __func__);
 249         return -ENOTSUPP;
 250 }
 251 
 252 /* block IO */
 253 static inline void snd_sof_dsp_block_read(struct snd_sof_dev *sdev, u32 bar,
 254                                           u32 offset, void *dest, size_t bytes)
 255 {
 256         sof_ops(sdev)->block_read(sdev, bar, offset, dest, bytes);
 257 }
 258 
 259 static inline void snd_sof_dsp_block_write(struct snd_sof_dev *sdev, u32 bar,
 260                                            u32 offset, void *src, size_t bytes)
 261 {
 262         sof_ops(sdev)->block_write(sdev, bar, offset, src, bytes);
 263 }
 264 
 265 /* ipc */
 266 static inline int snd_sof_dsp_send_msg(struct snd_sof_dev *sdev,
 267                                        struct snd_sof_ipc_msg *msg)
 268 {
 269         return sof_ops(sdev)->send_msg(sdev, msg);
 270 }
 271 
 272 /* host DMA trace */
 273 static inline int snd_sof_dma_trace_init(struct snd_sof_dev *sdev,
 274                                          u32 *stream_tag)
 275 {
 276         if (sof_ops(sdev)->trace_init)
 277                 return sof_ops(sdev)->trace_init(sdev, stream_tag);
 278 
 279         return 0;
 280 }
 281 
 282 static inline int snd_sof_dma_trace_release(struct snd_sof_dev *sdev)
 283 {
 284         if (sof_ops(sdev)->trace_release)
 285                 return sof_ops(sdev)->trace_release(sdev);
 286 
 287         return 0;
 288 }
 289 
 290 static inline int snd_sof_dma_trace_trigger(struct snd_sof_dev *sdev, int cmd)
 291 {
 292         if (sof_ops(sdev)->trace_trigger)
 293                 return sof_ops(sdev)->trace_trigger(sdev, cmd);
 294 
 295         return 0;
 296 }
 297 
 298 /* host PCM ops */
 299 static inline int
 300 snd_sof_pcm_platform_open(struct snd_sof_dev *sdev,
 301                           struct snd_pcm_substream *substream)
 302 {
 303         if (sof_ops(sdev) && sof_ops(sdev)->pcm_open)
 304                 return sof_ops(sdev)->pcm_open(sdev, substream);
 305 
 306         return 0;
 307 }
 308 
 309 /* disconnect pcm substream to a host stream */
 310 static inline int
 311 snd_sof_pcm_platform_close(struct snd_sof_dev *sdev,
 312                            struct snd_pcm_substream *substream)
 313 {
 314         if (sof_ops(sdev) && sof_ops(sdev)->pcm_close)
 315                 return sof_ops(sdev)->pcm_close(sdev, substream);
 316 
 317         return 0;
 318 }
 319 
 320 /* host stream hw params */
 321 static inline int
 322 snd_sof_pcm_platform_hw_params(struct snd_sof_dev *sdev,
 323                                struct snd_pcm_substream *substream,
 324                                struct snd_pcm_hw_params *params,
 325                                struct sof_ipc_stream_params *ipc_params)
 326 {
 327         if (sof_ops(sdev) && sof_ops(sdev)->pcm_hw_params)
 328                 return sof_ops(sdev)->pcm_hw_params(sdev, substream,
 329                                                     params, ipc_params);
 330 
 331         return 0;
 332 }
 333 
 334 /* host stream hw free */
 335 static inline int
 336 snd_sof_pcm_platform_hw_free(struct snd_sof_dev *sdev,
 337                              struct snd_pcm_substream *substream)
 338 {
 339         if (sof_ops(sdev) && sof_ops(sdev)->pcm_hw_free)
 340                 return sof_ops(sdev)->pcm_hw_free(sdev, substream);
 341 
 342         return 0;
 343 }
 344 
 345 /* host stream trigger */
 346 static inline int
 347 snd_sof_pcm_platform_trigger(struct snd_sof_dev *sdev,
 348                              struct snd_pcm_substream *substream, int cmd)
 349 {
 350         if (sof_ops(sdev) && sof_ops(sdev)->pcm_trigger)
 351                 return sof_ops(sdev)->pcm_trigger(sdev, substream, cmd);
 352 
 353         return 0;
 354 }
 355 
 356 /* host DSP message data */
 357 static inline void snd_sof_ipc_msg_data(struct snd_sof_dev *sdev,
 358                                         struct snd_pcm_substream *substream,
 359                                         void *p, size_t sz)
 360 {
 361         sof_ops(sdev)->ipc_msg_data(sdev, substream, p, sz);
 362 }
 363 
 364 /* host configure DSP HW parameters */
 365 static inline int
 366 snd_sof_ipc_pcm_params(struct snd_sof_dev *sdev,
 367                        struct snd_pcm_substream *substream,
 368                        const struct sof_ipc_pcm_params_reply *reply)
 369 {
 370         return sof_ops(sdev)->ipc_pcm_params(sdev, substream, reply);
 371 }
 372 
 373 /* host stream pointer */
 374 static inline snd_pcm_uframes_t
 375 snd_sof_pcm_platform_pointer(struct snd_sof_dev *sdev,
 376                              struct snd_pcm_substream *substream)
 377 {
 378         if (sof_ops(sdev) && sof_ops(sdev)->pcm_pointer)
 379                 return sof_ops(sdev)->pcm_pointer(sdev, substream);
 380 
 381         return 0;
 382 }
 383 
 384 static inline const struct snd_sof_dsp_ops
 385 *sof_get_ops(const struct sof_dev_desc *d,
 386              const struct sof_ops_table mach_ops[], int asize)
 387 {
 388         int i;
 389 
 390         for (i = 0; i < asize; i++) {
 391                 if (d == mach_ops[i].desc)
 392                         return mach_ops[i].ops;
 393         }
 394 
 395         /* not found */
 396         return NULL;
 397 }
 398 
 399 /**
 400  * snd_sof_dsp_register_poll_timeout - Periodically poll an address
 401  * until a condition is met or a timeout occurs
 402  * @op: accessor function (takes @addr as its only argument)
 403  * @addr: Address to poll
 404  * @val: Variable to read the value into
 405  * @cond: Break condition (usually involving @val)
 406  * @sleep_us: Maximum time to sleep between reads in us (0
 407  *            tight-loops).  Should be less than ~20ms since usleep_range
 408  *            is used (see Documentation/timers/timers-howto.rst).
 409  * @timeout_us: Timeout in us, 0 means never timeout
 410  *
 411  * Returns 0 on success and -ETIMEDOUT upon a timeout. In either
 412  * case, the last read value at @addr is stored in @val. Must not
 413  * be called from atomic context if sleep_us or timeout_us are used.
 414  *
 415  * This is modelled after the readx_poll_timeout macros in linux/iopoll.h.
 416  */
 417 #define snd_sof_dsp_read_poll_timeout(sdev, bar, offset, val, cond, sleep_us, timeout_us) \
 418 ({ \
 419         u64 __timeout_us = (timeout_us); \
 420         unsigned long __sleep_us = (sleep_us); \
 421         ktime_t __timeout = ktime_add_us(ktime_get(), __timeout_us); \
 422         might_sleep_if((__sleep_us) != 0); \
 423         for (;;) {                                                      \
 424                 (val) = snd_sof_dsp_read(sdev, bar, offset);            \
 425                 if (cond) { \
 426                         dev_dbg(sdev->dev, \
 427                                 "FW Poll Status: reg=%#x successful\n", (val)); \
 428                         break; \
 429                 } \
 430                 if (__timeout_us && \
 431                     ktime_compare(ktime_get(), __timeout) > 0) { \
 432                         (val) = snd_sof_dsp_read(sdev, bar, offset); \
 433                         dev_dbg(sdev->dev, \
 434                                 "FW Poll Status: reg=%#x timedout\n", (val)); \
 435                         break; \
 436                 } \
 437                 if (__sleep_us) \
 438                         usleep_range((__sleep_us >> 2) + 1, __sleep_us); \
 439         } \
 440         (cond) ? 0 : -ETIMEDOUT; \
 441 })
 442 
 443 /* This is for registers bits with attribute RWC */
 444 bool snd_sof_pci_update_bits(struct snd_sof_dev *sdev, u32 offset,
 445                              u32 mask, u32 value);
 446 
 447 bool snd_sof_dsp_update_bits_unlocked(struct snd_sof_dev *sdev, u32 bar,
 448                                       u32 offset, u32 mask, u32 value);
 449 
 450 bool snd_sof_dsp_update_bits64_unlocked(struct snd_sof_dev *sdev, u32 bar,
 451                                         u32 offset, u64 mask, u64 value);
 452 
 453 bool snd_sof_dsp_update_bits(struct snd_sof_dev *sdev, u32 bar, u32 offset,
 454                              u32 mask, u32 value);
 455 
 456 bool snd_sof_dsp_update_bits64(struct snd_sof_dev *sdev, u32 bar,
 457                                u32 offset, u64 mask, u64 value);
 458 
 459 void snd_sof_dsp_update_bits_forced(struct snd_sof_dev *sdev, u32 bar,
 460                                     u32 offset, u32 mask, u32 value);
 461 
 462 int snd_sof_dsp_register_poll(struct snd_sof_dev *sdev, u32 bar, u32 offset,
 463                               u32 mask, u32 target, u32 timeout_ms,
 464                               u32 interval_us);
 465 
 466 void snd_sof_dsp_panic(struct snd_sof_dev *sdev, u32 offset);
 467 #endif

/* [<][>][^][v][top][bottom][index][help] */