1 /* SPDX-License-Identifier: BSD-3-Clause
2  *
3  * Copyright(c) 2016 Intel Corporation. All rights reserved.
4  *
5  * Author: Liam Girdwood <liam.r.girdwood@linux.intel.com>
6  *         Keyon Jie <yang.jie@linux.intel.com>
7  */
8 
9 #ifndef __SOF_IPC_TOPOLOGY_H__
10 #define __SOF_IPC_TOPOLOGY_H__
11 
12 #include <sof/audio/buffer.h>
13 #include <sof/audio/ipc-config.h>
14 #include <sof/audio/pipeline.h>
15 #include <sof/lib/alloc.h>
16 #include <sof/lib/memory.h>
17 #include <sof/list.h>
18 #include <sof/platform.h>
19 #include <sof/schedule/task.h>
20 #include <sof/sof.h>
21 #include <sof/spinlock.h>
22 #include <sof/trace/trace.h>
23 #include <sof/ipc/common.h>
24 #include <stdbool.h>
25 #include <stdint.h>
26 
27 /* generic IPC pipeline regardless of ABI MAJOR type that is always 4 byte aligned */
28 typedef uint32_t ipc_pipe_new;
29 typedef uint32_t ipc_pipe_comp_connect;
30 typedef uint32_t ipc_comp;
31 
32 /*
33  * Topology IPC logic uses standard types for abstract IPC features. This means all ABI MAJOR
34  * abstraction is done in the IPC layer only and not in the surrounding infrastructure.
35  */
36 #if CONFIG_IPC_MAJOR_3
37 #include <ipc/topology.h>
38 #define ipc_from_pipe_new(x) ((struct sof_ipc_pipe_new *)x)
39 #define ipc_from_pipe_connect(x) ((struct sof_ipc_pipe_comp_connect *)x)
40 #define ipc_from_comp_new(x) ((struct sof_ipc_comp *)x)
41 #define ipc_from_dai_config(x) ((struct sof_ipc_dai_config *)x)
42 #elif CONFIG_IPC_MAJOR_4
43 #include <ipc4/pipeline.h>
44 #include <ipc4/module.h>
45 #include <ipc4/gateway.h>
46 #define ipc_from_pipe_new(x) ((struct ipc4_pipeline_create *)x)
47 #define ipc_from_pipe_connect(x) ((struct ipc4_module_bind_unbind *)x)
48 
49 const struct comp_driver *ipc4_get_comp_drv(int module_id);
50 struct comp_dev *ipc4_get_comp_dev(uint32_t comp_id);
51 int ipc4_add_comp_dev(struct comp_dev *dev);
52 const struct comp_driver *ipc4_get_drv(uint8_t *uuid);
53 #else
54 #error "No or invalid IPC MAJOR version selected."
55 #endif
56 
57 #define ipc_to_pipe_new(x)	((ipc_pipe_new *)x)
58 #define ipc_to_pipe_connect(x)	((ipc_pipe_comp_connect *)x)
59 #define ipc_to_comp_new(x)	((ipc_comp *)x)
60 
61 struct ipc_msg;
62 
63 #define COMP_TYPE_COMPONENT	1
64 #define COMP_TYPE_BUFFER	2
65 #define COMP_TYPE_PIPELINE	3
66 
67 /* IPC generic component device */
68 struct ipc_comp_dev {
69 	uint16_t type;	/* COMP_TYPE_ */
70 	uint16_t core;
71 	uint32_t id;
72 
73 	/* component type data */
74 	union {
75 		struct comp_dev *cd;
76 		struct comp_buffer *cb;
77 		struct pipeline *pipeline;
78 	};
79 
80 	/* lists */
81 	struct list_item list;		/* list in components */
82 };
83 
84 /**
85  * \brief Create a new IPC component.
86  * @param ipc The global IPC context.
87  * @param new New IPC component descriptor.
88  * @return 0 on success or negative error.
89  */
90 int ipc_comp_new(struct ipc *ipc, ipc_comp *new);
91 
92 /**
93  * \brief Free an IPC component.
94  * @param ipc The global IPC context.
95  * @param comp_id Component ID to free.
96  * @return 0 on success or negative error.
97  */
98 int ipc_comp_free(struct ipc *ipc, uint32_t comp_id);
99 
100 /**
101  * \brief Create a new IPC buffer.
102  * @param ipc The global IPC context.
103  * @param buffer New IPC buffer descriptor.
104  * @return 0 on success or negative error.
105  */
106 int ipc_buffer_new(struct ipc *ipc, const struct sof_ipc_buffer *buffer);
107 
108 /**
109  * \brief Free an IPC buffer.
110  * @param ipc The global IPC context.
111  * @param buffer_id buffer ID to free.
112  * @return 0 on success or negative error.
113  */
114 int ipc_buffer_free(struct ipc *ipc, uint32_t buffer_id);
115 
116 /**
117  * \brief Create a new IPC pipeline.
118  * @param ipc The global IPC context.
119  * @param pipeline New IPC pipeline descriptor.
120  * @return 0 on success or negative error.
121  */
122 int ipc_pipeline_new(struct ipc *ipc, ipc_pipe_new *pipeline);
123 
124 /**
125  * \brief Free an IPC pipeline.
126  * @param ipc The global IPC context.
127  * @param comp_id Pipeline ID to free.
128  * @return 0 on success or negative error.
129  */
130 int ipc_pipeline_free(struct ipc *ipc, uint32_t comp_id);
131 
132 /**
133  * \brief Complete an IPC pipeline.
134  * @param ipc The global IPC context.
135  * @param comp_id Pipeline ID to complete.
136  * @return 0 on success or negative error.
137  */
138 int ipc_pipeline_complete(struct ipc *ipc, uint32_t comp_id);
139 
140 /**
141  * \brief Connect components together on a pipeline.
142  * @param ipc The global IPC context.
143  * @param connect Components to connect together..
144  * @return 0 on success or negative error.
145  */
146 int ipc_comp_connect(struct ipc *ipc, ipc_pipe_comp_connect *connect);
147 
148 /**
149  * \brief Disconnect components in a pipeline.
150  * @param ipc The global IPC context.
151  * @param connect Components.
152  * @return 0 on success or negative error.
153  */
154 int ipc_comp_disconnect(struct ipc *ipc, ipc_pipe_comp_connect *connect);
155 
156 /**
157  * \brief Get component device from component ID.
158  * @param ipc The global IPC context.
159  * @param id The component ID.
160  * @return Component device or NULL.
161  */
162 struct ipc_comp_dev *ipc_get_comp_by_id(struct ipc *ipc, uint32_t id);
163 
164 /**
165  * \brief Get component device from pipeline ID and type.
166  * @param ipc The global IPC context.
167  * @param type The component type.
168  * @param ppl_id The pipeline ID.
169  * @return component device or NULL.
170  */
171 struct ipc_comp_dev *ipc_get_comp_by_ppl_id(struct ipc *ipc, uint16_t type,
172 					    uint32_t ppl_id);
173 /**
174  * \brief Get buffer device from pipeline ID.
175  * @param ipc The global IPC context.
176  * @param pipeline_id The pipeline ID.
177  * @param dir Pipeline stream direction.
178  * @return Pipeline device or NULL.
179  */
180 struct ipc_comp_dev *ipc_get_ppl_comp(struct ipc *ipc,
181 				      uint32_t pipeline_id, int dir);
182 
183 /**
184  * \brief Get pipeline ID from component.
185  * @param icd The component device.
186  * @return Pipeline ID or negative error.
187  */
188 int32_t ipc_comp_pipe_id(const struct ipc_comp_dev *icd);
189 
190 /**
191  * \brief Configure all DAI components attached to DAI.
192  * @param ipc Global IPC context.
193  * @param common_config Common DAI configuration.
194  * @param spec_config Specific DAI configuration.
195  * @return 0 on success or negative error.
196  */
197 int ipc_comp_dai_config(struct ipc *ipc, struct ipc_config_dai *common_config,
198 			void *spec_config);
199 
200 /**
201  * \brief verify component params
202  * @param dev Component dev
203  * @param flag Component setting flag
204  * @param params Ipc params
205  * @return verify status
206  */
207 int comp_verify_params(struct comp_dev *dev, uint32_t flag,
208 		       struct sof_ipc_stream_params *params);
209 
210 /**
211  * \brief connect component and buffer
212  * @param comp Component dev
213  * @param comp_core comp core id
214  * @param buffer Component buffer
215  * @param buffer_core buffer core id
216  * @param dir connection direction
217  * @return connection status
218  */
219 int comp_buffer_connect(struct comp_dev *comp, uint32_t comp_core,
220 			struct comp_buffer *buffer, uint32_t buffer_core, uint32_t dir);
221 #endif
222