forked from thesofproject/sof
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathipc.h
More file actions
244 lines (200 loc) · 6.56 KB
/
ipc.h
File metadata and controls
244 lines (200 loc) · 6.56 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
/* SPDX-License-Identifier: BSD-3-Clause
*
* Copyright(c) 2016 Intel Corporation. All rights reserved.
*
* Author: Liam Girdwood <liam.r.girdwood@linux.intel.com>
* Keyon Jie <yang.jie@linux.intel.com>
*/
#ifndef __SOF_DRIVERS_IPC_H__
#define __SOF_DRIVERS_IPC_H__
#include <sof/list.h>
#include <sof/platform.h>
#include <sof/schedule/task.h>
#include <sof/spinlock.h>
#include <sof/trace/dma-trace.h>
#include <sof/trace/trace.h>
#include <ipc/header.h>
#include <stdint.h>
struct comp_buffer;
struct comp_dev;
struct dai_config;
struct dma;
struct dma_sg_elem_array;
struct pipeline;
struct sof;
struct sof_ipc_buffer;
struct sof_ipc_comp;
struct sof_ipc_comp_event;
struct sof_ipc_dai_config;
struct sof_ipc_host_buffer;
struct sof_ipc_pipe_comp_connect;
struct sof_ipc_pipe_new;
struct sof_ipc_stream_posn;
#define trace_ipc(format, ...) \
trace_event(TRACE_CLASS_IPC, format, ##__VA_ARGS__)
#define tracev_ipc(format, ...) \
tracev_event(TRACE_CLASS_IPC, format, ##__VA_ARGS__)
#define trace_ipc_error(format, ...) \
trace_error(TRACE_CLASS_IPC, format, ##__VA_ARGS__)
#define MSG_QUEUE_SIZE 12
#define COMP_TYPE_COMPONENT 1
#define COMP_TYPE_BUFFER 2
#define COMP_TYPE_PIPELINE 3
/* validates internal non tail structures within IPC command structure */
#define IPC_IS_SIZE_INVALID(object) \
object.hdr.size == sizeof(object) ? 0 : 1
/* convenience error trace for mismatched internal structures */
#define IPC_SIZE_ERROR_TRACE(class, object) \
trace_error(class, "ipc: size %d expected %d", \
object.hdr.size, sizeof(object))
/* IPC generic component device */
struct ipc_comp_dev {
uint16_t type; /* COMP_TYPE_ */
uint16_t state;
/* component type data */
union {
struct comp_dev *cd;
struct comp_buffer *cb;
struct pipeline *pipeline;
};
/* lists */
struct list_item list; /* list in components */
};
struct ipc_msg {
uint32_t header; /* specific to platform */
uint32_t tx_size; /* payload size in bytes */
uint8_t tx_data[SOF_IPC_MSG_MAX_SIZE]; /* pointer to payload data */
uint32_t rx_size; /* payload size in bytes */
uint8_t rx_data[SOF_IPC_MSG_MAX_SIZE]; /* pointer to payload data */
struct list_item list;
void (*cb)(void *cb_data, void *mailbox_data);
void *cb_data;
};
struct ipc_shared_context {
struct ipc_msg *dsp_msg; /* current message to host */
uint32_t dsp_pending;
struct list_item msg_list;
struct list_item empty_list;
struct ipc_msg message[MSG_QUEUE_SIZE];
struct list_item comp_list; /* list of component devices */
};
struct ipc {
uint32_t host_pending;
spinlock_t lock;
void *comp_data;
/* RX call back */
int (*cb)(struct ipc_msg *msg);
/* DMA for Trace*/
struct dma_trace_data *dmat;
/* PM */
int pm_prepare_D3; /* do we need to prepare for D3 */
/* mmap for posn_offset */
struct pipeline *posn_map[PLATFORM_MAX_STREAMS];
/* context shared between cores */
struct ipc_shared_context *shared_ctx;
/* processing task */
struct task ipc_task;
void *private;
};
#define ipc_set_drvdata(ipc, data) \
((ipc)->private = data)
#define ipc_get_drvdata(ipc) \
((ipc)->private)
int ipc_init(struct sof *sof);
/**
* \brief Provides platform specific IPC initialization.
* @param ipc Global IPC context
* @return 0 if succeeded, error code otherwise.
*
* This function must be implemented by the platform. It is called from the
* main IPC code, at the end of ipc_init().
*
* If the platform requires any private data to be associated with the IPC
* context, it may allocate it here and attach to the global context using
* ipc_set_drvdata(). Other platform specific IPC functions, like
* ipc_platform_do_cmd(), may obtain it later from the context using
* ipc_get_drvdata().
*/
int platform_ipc_init(struct ipc *ipc);
void ipc_free(struct ipc *ipc);
int ipc_process_msg_queue(void);
uint64_t ipc_process_task(void *data);
void ipc_schedule_process(struct ipc *ipc);
int ipc_stream_send_position(struct comp_dev *cdev,
struct sof_ipc_stream_posn *posn);
int ipc_send_comp_notification(struct comp_dev *cdev,
struct sof_ipc_comp_event *event);
int ipc_stream_send_xrun(struct comp_dev *cdev,
struct sof_ipc_stream_posn *posn);
int ipc_queue_host_message(struct ipc *ipc, uint32_t header, void *tx_data,
size_t tx_bytes, uint32_t replace);
void ipc_platform_do_cmd(struct ipc *ipc);
void ipc_platform_send_msg(struct ipc *ipc);
/**
* \brief Data provided by the platform which use ipc...page_descriptors().
*
* Note: this should be made private for ipc-host-ptable.c and ipc
* drivers for platforms that use ptables.
*/
struct ipc_data_host_buffer {
/* DMA */
struct dma *dmac;
uint8_t *page_table;
};
/**
* \brief Retrieves the ipc_data_host_buffer allocated by the platform ipc.
* @return Pointer to the data.
*
* This function must be implemented by platforms which use
* ipc...page_descriptors() while processing host page tables.
*/
struct ipc_data_host_buffer *ipc_platform_get_host_buffer(struct ipc *ipc);
/**
* \brief Processes page tables for the host buffer.
* @param[in] ipc Ipc
* @param[in] ring Ring description sent via Ipc
* @param[in] direction Direction (playback/capture)
* @param[out] elem_array Array of SG elements
* @param[out] ring_size Size of the ring
* @return Status, 0 if successful, error code otherwise.
*/
int ipc_process_host_buffer(struct ipc *ipc,
struct sof_ipc_host_buffer *ring,
uint32_t direction,
struct dma_sg_elem_array *elem_array,
uint32_t *ring_size);
/*
* IPC Component creation and destruction.
*/
int ipc_comp_new(struct ipc *ipc, struct sof_ipc_comp *new);
int ipc_comp_free(struct ipc *ipc, uint32_t comp_id);
/*
* IPC Buffer creation and destruction.
*/
int ipc_buffer_new(struct ipc *ipc, struct sof_ipc_buffer *buffer);
int ipc_buffer_free(struct ipc *ipc, uint32_t buffer_id);
/*
* IPC Pipeline creation and destruction.
*/
int ipc_pipeline_new(struct ipc *ipc, struct sof_ipc_pipe_new *pipeline);
int ipc_pipeline_free(struct ipc *ipc, uint32_t comp_id);
int ipc_pipeline_complete(struct ipc *ipc, uint32_t comp_id);
/*
* Pipeline component and buffer connections.
*/
int ipc_comp_connect(struct ipc *ipc,
struct sof_ipc_pipe_comp_connect *connect);
/*
* Get component by ID.
*/
struct ipc_comp_dev *ipc_get_comp(struct ipc *ipc, uint32_t id);
/*
* Configure all DAI components attached to DAI.
*/
int ipc_comp_dai_config(struct ipc *ipc, struct sof_ipc_dai_config *config);
/* send DMA trace host buffer position to host */
int ipc_dma_trace_send_position(void);
/* get posn offset by pipeline. */
int ipc_get_posn_offset(struct ipc *ipc, struct pipeline *pipe);
int ipc_cmd(void);
#endif /* __SOF_DRIVERS_IPC_H__ */