1 /* SPDX-License-Identifier: GPL-2.0 */
2 /*
3  * Broadcom BM2835 V4L2 driver
4  *
5  * Copyright © 2013 Raspberry Pi (Trading) Ltd.
6  *
7  * Authors: Vincent Sanders <vincent.sanders@collabora.co.uk>
8  *          Dave Stevenson <dsteve@broadcom.com>
9  *          Simon Mellor <simellor@broadcom.com>
10  *          Luke Diamand <luked@broadcom.com>
11  */
12 
13 /* all the data structures which serialise the MMAL protocol. note
14  * these are directly mapped onto the recived message data.
15  *
16  * BEWARE: They seem to *assume* pointers are u32 and that there is no
17  * structure padding!
18  *
19  * NOTE: this implementation uses kernel types to ensure sizes. Rather
20  * than assigning values to enums to force their size the
21  * implementation uses fixed size types and not the enums (though the
22  * comments have the actual enum type
23  */
24 
25 #define VC_MMAL_VER 15
26 #define VC_MMAL_MIN_VER 10
27 #define VC_MMAL_SERVER_NAME  MAKE_FOURCC("mmal")
28 
29 /* max total message size is 512 bytes */
30 #define MMAL_MSG_MAX_SIZE 512
31 /* with six 32bit header elements max payload is therefore 488 bytes */
32 #define MMAL_MSG_MAX_PAYLOAD 488
33 
34 #include "mmal-msg-common.h"
35 #include "mmal-msg-format.h"
36 #include "mmal-msg-port.h"
37 
38 enum mmal_msg_type {
39 	MMAL_MSG_TYPE_QUIT = 1,
40 	MMAL_MSG_TYPE_SERVICE_CLOSED,
41 	MMAL_MSG_TYPE_GET_VERSION,
42 	MMAL_MSG_TYPE_COMPONENT_CREATE,
43 	MMAL_MSG_TYPE_COMPONENT_DESTROY, /* 5 */
44 	MMAL_MSG_TYPE_COMPONENT_ENABLE,
45 	MMAL_MSG_TYPE_COMPONENT_DISABLE,
46 	MMAL_MSG_TYPE_PORT_INFO_GET,
47 	MMAL_MSG_TYPE_PORT_INFO_SET,
48 	MMAL_MSG_TYPE_PORT_ACTION, /* 10 */
49 	MMAL_MSG_TYPE_BUFFER_FROM_HOST,
50 	MMAL_MSG_TYPE_BUFFER_TO_HOST,
51 	MMAL_MSG_TYPE_GET_STATS,
52 	MMAL_MSG_TYPE_PORT_PARAMETER_SET,
53 	MMAL_MSG_TYPE_PORT_PARAMETER_GET, /* 15 */
54 	MMAL_MSG_TYPE_EVENT_TO_HOST,
55 	MMAL_MSG_TYPE_GET_CORE_STATS_FOR_PORT,
56 	MMAL_MSG_TYPE_OPAQUE_ALLOCATOR,
57 	MMAL_MSG_TYPE_CONSUME_MEM,
58 	MMAL_MSG_TYPE_LMK, /* 20 */
59 	MMAL_MSG_TYPE_OPAQUE_ALLOCATOR_DESC,
60 	MMAL_MSG_TYPE_DRM_GET_LHS32,
61 	MMAL_MSG_TYPE_DRM_GET_TIME,
62 	MMAL_MSG_TYPE_BUFFER_FROM_HOST_ZEROLEN,
63 	MMAL_MSG_TYPE_PORT_FLUSH, /* 25 */
64 	MMAL_MSG_TYPE_HOST_LOG,
65 	MMAL_MSG_TYPE_MSG_LAST
66 };
67 
68 /* port action request messages differ depending on the action type */
69 enum mmal_msg_port_action_type {
70 	MMAL_MSG_PORT_ACTION_TYPE_UNKNOWN = 0,      /* Unknown action */
71 	MMAL_MSG_PORT_ACTION_TYPE_ENABLE,           /* Enable a port */
72 	MMAL_MSG_PORT_ACTION_TYPE_DISABLE,          /* Disable a port */
73 	MMAL_MSG_PORT_ACTION_TYPE_FLUSH,            /* Flush a port */
74 	MMAL_MSG_PORT_ACTION_TYPE_CONNECT,          /* Connect ports */
75 	MMAL_MSG_PORT_ACTION_TYPE_DISCONNECT,       /* Disconnect ports */
76 	MMAL_MSG_PORT_ACTION_TYPE_SET_REQUIREMENTS, /* Set buffer requirements*/
77 };
78 
79 struct mmal_msg_header {
80 	u32 magic;
81 	u32 type; /** enum mmal_msg_type */
82 
83 	/* Opaque handle to the control service */
84 	u32 control_service;
85 
86 	u32 context; /** a u32 per message context */
87 	u32 status; /** The status of the vchiq operation */
88 	u32 padding;
89 };
90 
91 /* Send from VC to host to report version */
92 struct mmal_msg_version {
93 	u32 flags;
94 	u32 major;
95 	u32 minor;
96 	u32 minimum;
97 };
98 
99 /* request to VC to create component */
100 struct mmal_msg_component_create {
101 	u32 client_component; /* component context */
102 	char name[128];
103 	u32 pid;                /* For debug */
104 };
105 
106 /* reply from VC to component creation request */
107 struct mmal_msg_component_create_reply {
108 	u32 status;	/* enum mmal_msg_status - how does this differ to
109 			 * the one in the header?
110 			 */
111 	u32 component_handle; /* VideoCore handle for component */
112 	u32 input_num;        /* Number of input ports */
113 	u32 output_num;       /* Number of output ports */
114 	u32 clock_num;        /* Number of clock ports */
115 };
116 
117 /* request to VC to destroy a component */
118 struct mmal_msg_component_destroy {
119 	u32 component_handle;
120 };
121 
122 struct mmal_msg_component_destroy_reply {
123 	u32 status; /** The component destruction status */
124 };
125 
126 /* request and reply to VC to enable a component */
127 struct mmal_msg_component_enable {
128 	u32 component_handle;
129 };
130 
131 struct mmal_msg_component_enable_reply {
132 	u32 status; /** The component enable status */
133 };
134 
135 /* request and reply to VC to disable a component */
136 struct mmal_msg_component_disable {
137 	u32 component_handle;
138 };
139 
140 struct mmal_msg_component_disable_reply {
141 	u32 status; /** The component disable status */
142 };
143 
144 /* request to VC to get port information */
145 struct mmal_msg_port_info_get {
146 	u32 component_handle;  /* component handle port is associated with */
147 	u32 port_type;         /* enum mmal_msg_port_type */
148 	u32 index;             /* port index to query */
149 };
150 
151 /* reply from VC to get port info request */
152 struct mmal_msg_port_info_get_reply {
153 	u32 status; /** enum mmal_msg_status */
154 	u32 component_handle;  /* component handle port is associated with */
155 	u32 port_type;         /* enum mmal_msg_port_type */
156 	u32 port_index;        /* port indexed in query */
157 	s32 found;             /* unused */
158 	u32 port_handle;               /**< Handle to use for this port */
159 	struct mmal_port port;
160 	struct mmal_es_format format; /* elementary stream format */
161 	union mmal_es_specific_format es; /* es type specific data */
162 	u8 extradata[MMAL_FORMAT_EXTRADATA_MAX_SIZE]; /* es extra data */
163 };
164 
165 /* request to VC to set port information */
166 struct mmal_msg_port_info_set {
167 	u32 component_handle;
168 	u32 port_type;         /* enum mmal_msg_port_type */
169 	u32 port_index;           /* port indexed in query */
170 	struct mmal_port port;
171 	struct mmal_es_format format;
172 	union mmal_es_specific_format es;
173 	u8 extradata[MMAL_FORMAT_EXTRADATA_MAX_SIZE];
174 };
175 
176 /* reply from VC to port info set request */
177 struct mmal_msg_port_info_set_reply {
178 	u32 status;
179 	u32 component_handle;  /* component handle port is associated with */
180 	u32 port_type;         /* enum mmal_msg_port_type */
181 	u32 index;             /* port indexed in query */
182 	s32 found;             /* unused */
183 	u32 port_handle;               /**< Handle to use for this port */
184 	struct mmal_port port;
185 	struct mmal_es_format format;
186 	union mmal_es_specific_format es;
187 	u8 extradata[MMAL_FORMAT_EXTRADATA_MAX_SIZE];
188 };
189 
190 /* port action requests that take a mmal_port as a parameter */
191 struct mmal_msg_port_action_port {
192 	u32 component_handle;
193 	u32 port_handle;
194 	u32 action; /* enum mmal_msg_port_action_type */
195 	struct mmal_port port;
196 };
197 
198 /* port action requests that take handles as a parameter */
199 struct mmal_msg_port_action_handle {
200 	u32 component_handle;
201 	u32 port_handle;
202 	u32 action; /* enum mmal_msg_port_action_type */
203 	u32 connect_component_handle;
204 	u32 connect_port_handle;
205 };
206 
207 struct mmal_msg_port_action_reply {
208 	u32 status; /** The port action operation status */
209 };
210 
211 /* MMAL buffer transfer */
212 
213 /** Size of space reserved in a buffer message for short messages. */
214 #define MMAL_VC_SHORT_DATA 128
215 
216 /** Signals that the current payload is the end of the stream of data */
217 #define MMAL_BUFFER_HEADER_FLAG_EOS                    BIT(0)
218 /** Signals that the start of the current payload starts a frame */
219 #define MMAL_BUFFER_HEADER_FLAG_FRAME_START            BIT(1)
220 /** Signals that the end of the current payload ends a frame */
221 #define MMAL_BUFFER_HEADER_FLAG_FRAME_END              BIT(2)
222 /** Signals that the current payload contains only complete frames (>1) */
223 #define MMAL_BUFFER_HEADER_FLAG_FRAME                  \
224 	(MMAL_BUFFER_HEADER_FLAG_FRAME_START|MMAL_BUFFER_HEADER_FLAG_FRAME_END)
225 /** Signals that the current payload is a keyframe (i.e. self decodable) */
226 #define MMAL_BUFFER_HEADER_FLAG_KEYFRAME               BIT(3)
227 /** Signals a discontinuity in the stream of data (e.g. after a seek).
228  * Can be used for instance by a decoder to reset its state
229  */
230 #define MMAL_BUFFER_HEADER_FLAG_DISCONTINUITY          BIT(4)
231 /** Signals a buffer containing some kind of config data for the component
232  * (e.g. codec config data)
233  */
234 #define MMAL_BUFFER_HEADER_FLAG_CONFIG                 BIT(5)
235 /** Signals an encrypted payload */
236 #define MMAL_BUFFER_HEADER_FLAG_ENCRYPTED              BIT(6)
237 /** Signals a buffer containing side information */
238 #define MMAL_BUFFER_HEADER_FLAG_CODECSIDEINFO          BIT(7)
239 /** Signals a buffer which is the snapshot/postview image from a stills
240  * capture
241  */
242 #define MMAL_BUFFER_HEADER_FLAGS_SNAPSHOT              BIT(8)
243 /** Signals a buffer which contains data known to be corrupted */
244 #define MMAL_BUFFER_HEADER_FLAG_CORRUPTED              BIT(9)
245 /** Signals that a buffer failed to be transmitted */
246 #define MMAL_BUFFER_HEADER_FLAG_TRANSMISSION_FAILED    BIT(10)
247 
248 struct mmal_driver_buffer {
249 	u32 magic;
250 	u32 component_handle;
251 	u32 port_handle;
252 	u32 client_context;
253 };
254 
255 /* buffer header */
256 struct mmal_buffer_header {
257 	u32 next; /* next header */
258 	u32 priv; /* framework private data */
259 	u32 cmd;
260 	u32 data;
261 	u32 alloc_size;
262 	u32 length;
263 	u32 offset;
264 	u32 flags;
265 	s64 pts;
266 	s64 dts;
267 	u32 type;
268 	u32 user_data;
269 };
270 
271 struct mmal_buffer_header_type_specific {
272 	union {
273 		struct {
274 		u32 planes;
275 		u32 offset[4];
276 		u32 pitch[4];
277 		u32 flags;
278 		} video;
279 	} u;
280 };
281 
282 struct mmal_msg_buffer_from_host {
283 	/* The front 32 bytes of the buffer header are copied
284 	 * back to us in the reply to allow for context. This
285 	 * area is used to store two mmal_driver_buffer structures to
286 	 * allow for multiple concurrent service users.
287 	 */
288 	/* control data */
289 	struct mmal_driver_buffer drvbuf;
290 
291 	/* referenced control data for passthrough buffer management */
292 	struct mmal_driver_buffer drvbuf_ref;
293 	struct mmal_buffer_header buffer_header; /* buffer header itself */
294 	struct mmal_buffer_header_type_specific buffer_header_type_specific;
295 	s32 is_zero_copy;
296 	s32 has_reference;
297 
298 	/** allows short data to be xfered in control message */
299 	u32 payload_in_message;
300 	u8 short_data[MMAL_VC_SHORT_DATA];
301 };
302 
303 /* port parameter setting */
304 
305 #define MMAL_WORKER_PORT_PARAMETER_SPACE      96
306 
307 struct mmal_msg_port_parameter_set {
308 	u32 component_handle; /* component */
309 	u32 port_handle;      /* port */
310 	u32 id;     /* Parameter ID  */
311 	u32 size;      /* Parameter size */
312 	uint32_t value[MMAL_WORKER_PORT_PARAMETER_SPACE];
313 };
314 
315 struct mmal_msg_port_parameter_set_reply {
316 	u32 status;	/* enum mmal_msg_status todo: how does this
317 			 * differ to the one in the header?
318 			 */
319 };
320 
321 /* port parameter getting */
322 
323 struct mmal_msg_port_parameter_get {
324 	u32 component_handle; /* component */
325 	u32 port_handle;      /* port */
326 	u32 id;     /* Parameter ID  */
327 	u32 size;      /* Parameter size */
328 };
329 
330 struct mmal_msg_port_parameter_get_reply {
331 	u32 status;           /* Status of mmal_port_parameter_get call */
332 	u32 id;     /* Parameter ID  */
333 	u32 size;      /* Parameter size */
334 	uint32_t value[MMAL_WORKER_PORT_PARAMETER_SPACE];
335 };
336 
337 /* event messages */
338 #define MMAL_WORKER_EVENT_SPACE 256
339 
340 struct mmal_msg_event_to_host {
341 	u32 client_component; /* component context */
342 
343 	u32 port_type;
344 	u32 port_num;
345 
346 	u32 cmd;
347 	u32 length;
348 	u8 data[MMAL_WORKER_EVENT_SPACE];
349 	u32 delayed_buffer;
350 };
351 
352 /* all mmal messages are serialised through this structure */
353 struct mmal_msg {
354 	/* header */
355 	struct mmal_msg_header h;
356 	/* payload */
357 	union {
358 		struct mmal_msg_version version;
359 
360 		struct mmal_msg_component_create component_create;
361 		struct mmal_msg_component_create_reply component_create_reply;
362 
363 		struct mmal_msg_component_destroy component_destroy;
364 		struct mmal_msg_component_destroy_reply component_destroy_reply;
365 
366 		struct mmal_msg_component_enable component_enable;
367 		struct mmal_msg_component_enable_reply component_enable_reply;
368 
369 		struct mmal_msg_component_disable component_disable;
370 		struct mmal_msg_component_disable_reply component_disable_reply;
371 
372 		struct mmal_msg_port_info_get port_info_get;
373 		struct mmal_msg_port_info_get_reply port_info_get_reply;
374 
375 		struct mmal_msg_port_info_set port_info_set;
376 		struct mmal_msg_port_info_set_reply port_info_set_reply;
377 
378 		struct mmal_msg_port_action_port port_action_port;
379 		struct mmal_msg_port_action_handle port_action_handle;
380 		struct mmal_msg_port_action_reply port_action_reply;
381 
382 		struct mmal_msg_buffer_from_host buffer_from_host;
383 
384 		struct mmal_msg_port_parameter_set port_parameter_set;
385 		struct mmal_msg_port_parameter_set_reply
386 			port_parameter_set_reply;
387 		struct mmal_msg_port_parameter_get
388 			port_parameter_get;
389 		struct mmal_msg_port_parameter_get_reply
390 			port_parameter_get_reply;
391 
392 		struct mmal_msg_event_to_host event_to_host;
393 
394 		u8 payload[MMAL_MSG_MAX_PAYLOAD];
395 	} u;
396 };
397