forked from thesofproject/sof
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathpipeline.h
More file actions
432 lines (379 loc) · 12.2 KB
/
pipeline.h
File metadata and controls
432 lines (379 loc) · 12.2 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
/* SPDX-License-Identifier: BSD-3-Clause
*
* Copyright(c) 2016 Intel Corporation. All rights reserved.
*
* Author: Liam Girdwood <liam.r.girdwood@linux.intel.com>
*/
#ifndef __SOF_AUDIO_PIPELINE_H__
#define __SOF_AUDIO_PIPELINE_H__
#include <sof/lib/cpu.h>
#include <sof/lib/mailbox.h>
#include <sof/lib/memory.h>
#include <sof/list.h>
#include <rtos/task.h>
#include <rtos/sof.h>
#include <rtos/spinlock.h>
#include <sof/audio/pipeline-trace.h>
#include <ipc/topology.h>
#include <user/trace.h>
#include <errno.h>
#include <stdbool.h>
#include <stdint.h>
struct comp_buffer;
struct comp_dev;
struct ipc;
struct ipc_msg;
/*
* Pipeline status to stop execution of current path, but to keep the
* pipeline alive, when processing COMP_TRIGGER_STOP or COMP_TRIGGER_PAUSE
*/
#define PPL_STATUS_PATH_STOP 1
/*
* Pipeline status to stop execution of current path, and to terminate the
* pipeline, when processing COMP_TRIGGER_STOP or COMP_TRIGGER_PAUSE
*/
#define PPL_STATUS_PATH_TERMINATE 2
/* Pipeline scheduled in another thread other than ipc thread */
#define PPL_STATUS_SCHEDULED 2
/* pipeline connection directions */
#define PPL_CONN_DIR_COMP_TO_BUFFER 0
#define PPL_CONN_DIR_BUFFER_TO_COMP 1
/* pipeline processing directions */
#define PPL_DIR_DOWNSTREAM 0
#define PPL_DIR_UPSTREAM 1
/*
* Audio pipeline.
*/
struct pipeline {
uint32_t comp_id; /**< component id for pipeline */
uint32_t pipeline_id; /**< pipeline id */
uint32_t sched_id; /**< Scheduling component id */
uint32_t core; /**< core we run on */
uint32_t period; /**< execution period in us*/
uint32_t priority; /**< priority level 0 (low) to 10 (max) */
uint32_t period_mips; /**< worst case instruction count per period */
uint32_t frames_per_sched;/**< output frames of pipeline, 0 is variable */
uint32_t xrun_limit_usecs; /**< report xruns greater than limit */
uint32_t time_domain; /**< scheduling time domain */
uint32_t attributes; /**< pipeline attributes from IPC extension msg/ */
/* runtime status */
int32_t xrun_bytes; /* last xrun length */
uint32_t status; /* pipeline status */
struct tr_ctx tctx; /* trace settings */
/* scheduling */
struct task *pipe_task; /* pipeline processing task */
struct pipeline *sched_next; /* pipeline scheduled after this */
struct pipeline *sched_prev; /* pipeline scheduled before this */
/* component that drives scheduling in this pipe */
struct comp_dev *sched_comp;
/* source component for this pipe */
struct comp_dev *source_comp;
/* sink component for this pipe */
struct comp_dev *sink_comp;
struct list_item list; /**< list in walk context */
/* position update */
uint32_t posn_offset; /* position update array offset*/
struct ipc_msg *msg;
struct {
int cmd;
struct comp_dev *host;
unsigned int delay; /* period count */
bool aborted; /* STOP or PAUSE failed, stay active */
bool pending; /* trigger scheduled but not executed yet */
} trigger;
};
struct pipeline_walk_context {
int (*comp_func)(struct comp_dev *cd, struct comp_buffer *buffer,
struct pipeline_walk_context *ctx, int dir);
void *comp_data;
void (*buff_func)(struct comp_buffer *buffer, void *data);
void *buff_data;
struct comp_buffer *incoming;
/**< pipelines to be scheduled after trigger walk */
struct list_item pipelines;
/*
* If this flag is set, pipeline_for_each_comp() will skip all
* incompletely initialised components, i.e. those, whose .pipeline ==
* NULL. Such components should not be skipped during initialisation
* and clean up, but they should be skipped during streaming.
*/
bool skip_incomplete;
};
/* generic pipeline data used by pipeline_comp_* functions */
struct pipeline_data {
struct comp_dev *start;
struct sof_ipc_pcm_params *params;
struct sof_ipc_stream_posn *posn;
struct pipeline *p;
int cmd;
uint32_t delay_ms; /* between PRE_{START,RELEASE} and {START,RELEASE} */
};
/** \brief Task type registered by pipelines. */
struct pipeline_task {
struct task task; /**< parent structure */
bool registrable; /**< should task be registered on irq */
struct comp_dev *sched_comp; /**< pipeline scheduling component */
};
#define pipeline_task_get(t) container_of(t, struct pipeline_task, task)
/*
* Pipeline Graph APIs
*
* These APIs are used to construct and bind pipeline graphs. They are also
* used to query pipeline fundamental configuration.
*/
/**
* \brief Creates a new pipeline.
* \param[in] pipeline_id Pipeline ID number.
* \param[in] priority Pipeline scheduling priority.
* \param[in] comp_id Pipeline component ID number.
* \return New pipeline pointer or NULL.
*/
struct pipeline *pipeline_new(uint32_t pipeline_id, uint32_t priority, uint32_t comp_id);
/**
* \brief Free's a pipeline.
* \param[in] p pipeline.
* \return 0 on success.
*/
int pipeline_free(struct pipeline *p);
/**
* \brief Connect components in a pipeline.
* \param[in] comp connecting component.
* \param[in] buffer connecting buffer.
* \param[in] dir Connection direction.
* \return 0 on success.
*/
int pipeline_connect(struct comp_dev *comp, struct comp_buffer *buffer,
int dir);
/**
* \brief Creates a new pipeline.
* \param[in] comp connecting component.
* \param[in] buffer connecting buffer.
* \param[in] dir Connection direction.
*/
void pipeline_disconnect(struct comp_dev *comp, struct comp_buffer *buffer,
int dir);
/**
* \brief Completes a pipeline.
* \param[in] p pipeline.
* \param[in] source Pipeline component device.
* \param[in] sink Pipeline component device.
* \return 0 on success.
*/
int pipeline_complete(struct pipeline *p, struct comp_dev *source,
struct comp_dev *sink);
/**
* \brief Initializes pipeline position structure.
* \param[in,out] sof Pointer to sof structure.
*/
void pipeline_posn_init(struct sof *sof);
/**
* \brief Resets the pipeline and free runtime resources.
* \param[in] p pipeline.
* \param[in] host_cd Host DMA component device.
* \return 0 on success.
*/
int pipeline_reset(struct pipeline *p, struct comp_dev *host_cd);
/**
* \brief Walks the pipeline graph for each component.
* \param[in] current Current pipeline component.
* \param[in] ctx Pipeline graph walk context.
* \param[in] dir Walk direction.
* \return 0 on success.
*/
int pipeline_for_each_comp(struct comp_dev *current,
struct pipeline_walk_context *ctx, int dir);
/**
* \brief Walks pipeline graph to find dai component.
* \param[in] pipeline_id is the start pipeline id.
* \param[in] dir is the direction of the traversal.
* \return dai component.
*/
struct comp_dev *pipeline_get_dai_comp(uint32_t pipeline_id, int dir);
#if CONFIG_IPC_MAJOR_4
/**
* \brief Walks pipeline graph to find dai component and latency.
* \param[in] pipeline_id is the start pipeline id.
* \param[out] latency to dai.
* \return dai component.
*/
struct comp_dev *pipeline_get_dai_comp_latency(uint32_t pipeline_id, uint32_t *latency);
#endif
/**
* Retrieves pipeline id from pipeline.
* @param p pipeline.
* @return pipeline id.
*/
static inline uint32_t pipeline_id(struct pipeline *p)
{
return p->pipeline_id;
}
/*
* Pipeline configuration APIs
*
* These APIs are used to configure the runtime parameters of a pipeline.
*/
/**
* \brief Creates a new pipeline.
* \param[in] p pipeline.
* \param[in] cd Pipeline component device.
* \param[in] params Pipeline parameters.
* \return 0 on success.
*/
int pipeline_params(struct pipeline *p, struct comp_dev *cd,
struct sof_ipc_pcm_params *params);
/**
* \brief Creates a new pipeline.
* \param[in] p pipeline.
* \param[in,out] cd Pipeline component device.
* \return 0 on success.
*/
int pipeline_prepare(struct pipeline *p, struct comp_dev *cd);
/*
* Pipeline stream APIs
*
* These APIs are used to control pipeline processing work.
*/
/**
* \brief Trigger pipeline - IPC context
* \param[in] p pipeline.
* \param[in] host Host DMA component.
* \param[in] cmd Pipeline trigger command.
* \return 0 on success.
*/
int pipeline_trigger(struct pipeline *p, struct comp_dev *host, int cmd);
/**
* \brief Trigger pipeline - either IPC or pipeline task context
* \param[in] p pipeline.
* \param[in] host Host DMA component.
* \param[in] cmd Pipeline trigger command.
* \return 0 on success.
*/
int pipeline_trigger_run(struct pipeline *p, struct comp_dev *host, int cmd);
/**
* \brief Copy data along a pipeline.
* \param[in] p pipeline.
* \return 0 on success.
*/
int pipeline_copy(struct pipeline *p);
/**
* \brief Get time pipeline timestamps from host to dai.
* \param[in] p pipeline.
* \param[in] host_dev Host DMA component.
* \param[in,out] posn Pipeline stream position.
*/
void pipeline_get_timestamp(struct pipeline *p, struct comp_dev *host_dev,
struct sof_ipc_stream_posn *posn);
/*
* Pipeline scheduling APIs
*
* These APIs are used to schedule pipeline processing work.
*/
/**
* \brief Checks if two pipelines have the same scheduling component.
* \param[in] current This pipeline.
* \param[in] previous Other pipeline.
* \return true if both pipelines are scheduled together.
*/
static inline bool pipeline_is_same_sched_comp(struct pipeline *current,
struct pipeline *previous)
{
return current->sched_comp == previous->sched_comp;
}
/**
* \brief Is pipeline is scheduled with timer.
* \param[in] p pipeline.
* \return true if pipeline uses timer based scheduling.
*/
static inline bool pipeline_is_timer_driven(struct pipeline *p)
{
return p->time_domain == SOF_TIME_DOMAIN_TIMER;
}
/**
* \brief Is pipeline is scheduled on this core.
* \param[in] p pipeline.
* \return true if pipeline core ID == current core ID.
*/
static inline bool pipeline_is_this_cpu(struct pipeline *p)
{
return p->core == cpu_get_id();
}
/**
* \brief Init an LL task for a pipeline.
* \param[in] p pipeline.
* \return 0 on success.
*/
int pipeline_comp_ll_task_init(struct pipeline *p);
/**
* \brief Init a DP task for a component
* \param[in] comp a component the task is created for
* \return 0 on success.
*/
int pipeline_comp_dp_task_init(struct comp_dev *comp);
/**
* \brief Free's a pipeline.
* \param[in] p pipeline.
* \param[in] start Pipelien start time in microseconds.
*/
void pipeline_schedule_copy(struct pipeline *p, uint64_t start);
/**
* \brief Trigger pipeline's scheduling component.
* \param[in] p pipeline.
* \param[in,out] comp Pipeline component device.
* \param[in] ctx Pipeline graph walk context.
*/
void pipeline_comp_trigger_sched_comp(struct pipeline *p,
struct comp_dev *comp,
struct pipeline_walk_context *ctx);
/**
* \brief Schedule all triggered pipelines.
* \param[in] ctx Pipeline graph walk context.
* \param[in] cmd Trigger command.
*/
void pipeline_schedule_triggered(struct pipeline_walk_context *ctx,
int cmd);
/**
* \brief Configure pipeline scheduling.
* \param[in] p pipeline.
* \param[in] sched_id Scheduling component ID.
* \param[in] core DSP core pipeline runs on.
* \param[in] period Pipeline scheduling period in us.
* \param[in] period_mips Pipeline worst case MCPS per period.
* \param[in] frames_per_sched Pipeline frames processed per schedule.
* \param[in] time_domain Pipeline scheduling time domain.
*/
void pipeline_schedule_config(struct pipeline *p, uint32_t sched_id,
uint32_t core, uint32_t period,
uint32_t period_mips, uint32_t frames_per_sched,
uint32_t time_domain);
/*
* Pipeline error handling APIs
*
* These APIs are used to handle, report and recover from pipeline errors.
*/
/**
* \brief Recover the pipeline from a XRUN condition.
* \param[in] p pipeline.
* \return 0 on success.
*/
int pipeline_xrun_recover(struct pipeline *p);
/**
* \brief Perform xrun recovery.
* \param[in] p pipeline.
* \param[in] cmd Trigger command.
* \return 0 on success.
*/
int pipeline_xrun_handle_trigger(struct pipeline *p, int cmd);
/**
* \brief notify host that we have XRUN.
* \param[in] p pipeline.
* \param[in] dev Pipeline component device.
* \param[in] bytes Number of bytes we have over or under run.
*/
void pipeline_xrun(struct pipeline *p, struct comp_dev *dev, int32_t bytes);
/**
* \brief Set tolerance for pipeline xrun handling.
* \param[in] p pipeline.
* \param[in] xrun_limit_usecs Limit in micro secs that pipeline will tolerate.
*/
int pipeline_xrun_set_limit(struct pipeline *p, uint32_t xrun_limit_usecs);
#endif /* __SOF_AUDIO_PIPELINE_H__ */