1 /* SPDX-License-Identifier: GPL-2.0+ */
2
3 #ifndef _VKMS_CONFIG_H_
4 #define _VKMS_CONFIG_H_
5
6 #include <linux/list.h>
7 #include <linux/types.h>
8 #include <linux/xarray.h>
9
10 #include "vkms_drv.h"
11
12 /**
13 * struct vkms_config - General configuration for VKMS driver
14 *
15 * @dev_name: Name of the device
16 * @planes: List of planes configured for the device
17 * @crtcs: List of CRTCs configured for the device
18 * @encoders: List of encoders configured for the device
19 * @connectors: List of connectors configured for the device
20 * @dev: Used to store the current VKMS device. Only set when the device is instantiated.
21 */
22 struct vkms_config {
23 const char *dev_name;
24 struct list_head planes;
25 struct list_head crtcs;
26 struct list_head encoders;
27 struct list_head connectors;
28 struct vkms_device *dev;
29 };
30
31 /**
32 * struct vkms_config_plane
33 *
34 * @link: Link to the others planes in vkms_config
35 * @config: The vkms_config this plane belongs to
36 * @type: Type of the plane. The creator of configuration needs to ensures that
37 * at least one primary plane is present.
38 * @possible_crtcs: Array of CRTCs that can be used with this plane
39 * @plane: Internal usage. This pointer should never be considered as valid.
40 * It can be used to store a temporary reference to a VKMS plane during
41 * device creation. This pointer is not managed by the configuration and
42 * must be managed by other means.
43 */
44 struct vkms_config_plane {
45 struct list_head link;
46 struct vkms_config *config;
47
48 enum drm_plane_type type;
49 struct xarray possible_crtcs;
50
51 /* Internal usage */
52 struct vkms_plane *plane;
53 };
54
55 /**
56 * struct vkms_config_crtc
57 *
58 * @link: Link to the others CRTCs in vkms_config
59 * @config: The vkms_config this CRTC belongs to
60 * @writeback: If true, a writeback buffer can be attached to the CRTC
61 * @crtc: Internal usage. This pointer should never be considered as valid.
62 * It can be used to store a temporary reference to a VKMS CRTC during
63 * device creation. This pointer is not managed by the configuration and
64 * must be managed by other means.
65 */
66 struct vkms_config_crtc {
67 struct list_head link;
68 struct vkms_config *config;
69
70 bool writeback;
71
72 /* Internal usage */
73 struct vkms_output *crtc;
74 };
75
76 /**
77 * struct vkms_config_encoder
78 *
79 * @link: Link to the others encoders in vkms_config
80 * @config: The vkms_config this CRTC belongs to
81 * @possible_crtcs: Array of CRTCs that can be used with this encoder
82 * @encoder: Internal usage. This pointer should never be considered as valid.
83 * It can be used to store a temporary reference to a VKMS encoder
84 * during device creation. This pointer is not managed by the
85 * configuration and must be managed by other means.
86 */
87 struct vkms_config_encoder {
88 struct list_head link;
89 struct vkms_config *config;
90
91 struct xarray possible_crtcs;
92
93 /* Internal usage */
94 struct drm_encoder *encoder;
95 };
96
97 /**
98 * struct vkms_config_connector
99 *
100 * @link: Link to the others connector in vkms_config
101 * @config: The vkms_config this connector belongs to
102 * @possible_encoders: Array of encoders that can be used with this connector
103 * @connector: Internal usage. This pointer should never be considered as valid.
104 * It can be used to store a temporary reference to a VKMS connector
105 * during device creation. This pointer is not managed by the
106 * configuration and must be managed by other means.
107 */
108 struct vkms_config_connector {
109 struct list_head link;
110 struct vkms_config *config;
111
112 struct xarray possible_encoders;
113
114 /* Internal usage */
115 struct vkms_connector *connector;
116 };
117
118 /**
119 * vkms_config_for_each_plane - Iterate over the vkms_config planes
120 * @config: &struct vkms_config pointer
121 * @plane_cfg: &struct vkms_config_plane pointer used as cursor
122 */
123 #define vkms_config_for_each_plane(config, plane_cfg) \
124 list_for_each_entry((plane_cfg), &(config)->planes, link)
125
126 /**
127 * vkms_config_for_each_crtc - Iterate over the vkms_config CRTCs
128 * @config: &struct vkms_config pointer
129 * @crtc_cfg: &struct vkms_config_crtc pointer used as cursor
130 */
131 #define vkms_config_for_each_crtc(config, crtc_cfg) \
132 list_for_each_entry((crtc_cfg), &(config)->crtcs, link)
133
134 /**
135 * vkms_config_for_each_encoder - Iterate over the vkms_config encoders
136 * @config: &struct vkms_config pointer
137 * @encoder_cfg: &struct vkms_config_encoder pointer used as cursor
138 */
139 #define vkms_config_for_each_encoder(config, encoder_cfg) \
140 list_for_each_entry((encoder_cfg), &(config)->encoders, link)
141
142 /**
143 * vkms_config_for_each_connector - Iterate over the vkms_config connectors
144 * @config: &struct vkms_config pointer
145 * @connector_cfg: &struct vkms_config_connector pointer used as cursor
146 */
147 #define vkms_config_for_each_connector(config, connector_cfg) \
148 list_for_each_entry((connector_cfg), &(config)->connectors, link)
149
150 /**
151 * vkms_config_plane_for_each_possible_crtc - Iterate over the vkms_config_plane
152 * possible CRTCs
153 * @plane_cfg: &struct vkms_config_plane pointer
154 * @idx: Index of the cursor
155 * @possible_crtc: &struct vkms_config_crtc pointer used as cursor
156 */
157 #define vkms_config_plane_for_each_possible_crtc(plane_cfg, idx, possible_crtc) \
158 xa_for_each(&(plane_cfg)->possible_crtcs, idx, (possible_crtc))
159
160 /**
161 * vkms_config_encoder_for_each_possible_crtc - Iterate over the
162 * vkms_config_encoder possible CRTCs
163 * @encoder_cfg: &struct vkms_config_encoder pointer
164 * @idx: Index of the cursor
165 * @possible_crtc: &struct vkms_config_crtc pointer used as cursor
166 */
167 #define vkms_config_encoder_for_each_possible_crtc(encoder_cfg, idx, possible_crtc) \
168 xa_for_each(&(encoder_cfg)->possible_crtcs, idx, (possible_crtc))
169
170 /**
171 * vkms_config_connector_for_each_possible_encoder - Iterate over the
172 * vkms_config_connector possible encoders
173 * @connector_cfg: &struct vkms_config_connector pointer
174 * @idx: Index of the cursor
175 * @possible_encoder: &struct vkms_config_encoder pointer used as cursor
176 */
177 #define vkms_config_connector_for_each_possible_encoder(connector_cfg, idx, possible_encoder) \
178 xa_for_each(&(connector_cfg)->possible_encoders, idx, (possible_encoder))
179
180 /**
181 * vkms_config_create() - Create a new VKMS configuration
182 * @dev_name: Name of the device
183 *
184 * Returns:
185 * The new vkms_config or an error. Call vkms_config_destroy() to free the
186 * returned configuration.
187 */
188 struct vkms_config *vkms_config_create(const char *dev_name);
189
190 /**
191 * vkms_config_default_create() - Create the configuration for the default device
192 * @enable_cursor: Create or not a cursor plane
193 * @enable_writeback: Create or not a writeback connector
194 * @enable_overlay: Create or not overlay planes
195 *
196 * Returns:
197 * The default vkms_config or an error. Call vkms_config_destroy() to free the
198 * returned configuration.
199 */
200 struct vkms_config *vkms_config_default_create(bool enable_cursor,
201 bool enable_writeback,
202 bool enable_overlay);
203
204 /**
205 * vkms_config_destroy() - Free a VKMS configuration
206 * @config: vkms_config to free
207 */
208 void vkms_config_destroy(struct vkms_config *config);
209
210 /**
211 * vkms_config_get_device_name() - Return the name of the device
212 * @config: Configuration to get the device name from
213 *
214 * Returns:
215 * The device name. Only valid while @config is valid.
216 */
217 static inline const char *
vkms_config_get_device_name(struct vkms_config * config)218 vkms_config_get_device_name(struct vkms_config *config)
219 {
220 return config->dev_name;
221 }
222
223 /**
224 * vkms_config_get_num_crtcs() - Return the number of CRTCs in the configuration
225 * @config: Configuration to get the number of CRTCs from
226 */
vkms_config_get_num_crtcs(struct vkms_config * config)227 static inline size_t vkms_config_get_num_crtcs(struct vkms_config *config)
228 {
229 return list_count_nodes(&config->crtcs);
230 }
231
232 /**
233 * vkms_config_is_valid() - Validate a configuration
234 * @config: Configuration to validate
235 *
236 * Returns:
237 * Whether the configuration is valid or not.
238 * For example, a configuration without primary planes is not valid.
239 */
240 bool vkms_config_is_valid(const struct vkms_config *config);
241
242 /**
243 * vkms_config_register_debugfs() - Register a debugfs file to show the device's
244 * configuration
245 * @vkms_device: Device to register
246 */
247 void vkms_config_register_debugfs(struct vkms_device *vkms_device);
248
249 /**
250 * vkms_config_create_plane() - Add a new plane configuration
251 * @config: Configuration to add the plane to
252 *
253 * Returns:
254 * The new plane configuration or an error. Call vkms_config_destroy_plane() to
255 * free the returned plane configuration.
256 */
257 struct vkms_config_plane *vkms_config_create_plane(struct vkms_config *config);
258
259 /**
260 * vkms_config_destroy_plane() - Remove and free a plane configuration
261 * @plane_cfg: Plane configuration to destroy
262 */
263 void vkms_config_destroy_plane(struct vkms_config_plane *plane_cfg);
264
265 /**
266 * vkms_config_plane_type() - Return the plane type
267 * @plane_cfg: Plane to get the type from
268 */
269 static inline enum drm_plane_type
vkms_config_plane_get_type(struct vkms_config_plane * plane_cfg)270 vkms_config_plane_get_type(struct vkms_config_plane *plane_cfg)
271 {
272 return plane_cfg->type;
273 }
274
275 /**
276 * vkms_config_plane_set_type() - Set the plane type
277 * @plane_cfg: Plane to set the type to
278 * @type: New plane type
279 */
280 static inline void
vkms_config_plane_set_type(struct vkms_config_plane * plane_cfg,enum drm_plane_type type)281 vkms_config_plane_set_type(struct vkms_config_plane *plane_cfg,
282 enum drm_plane_type type)
283 {
284 plane_cfg->type = type;
285 }
286
287 /**
288 * vkms_config_plane_attach_crtc - Attach a plane to a CRTC
289 * @plane_cfg: Plane to attach
290 * @crtc_cfg: CRTC to attach @plane_cfg to
291 */
292 int __must_check vkms_config_plane_attach_crtc(struct vkms_config_plane *plane_cfg,
293 struct vkms_config_crtc *crtc_cfg);
294
295 /**
296 * vkms_config_plane_detach_crtc - Detach a plane from a CRTC
297 * @plane_cfg: Plane to detach
298 * @crtc_cfg: CRTC to detach @plane_cfg from
299 */
300 void vkms_config_plane_detach_crtc(struct vkms_config_plane *plane_cfg,
301 struct vkms_config_crtc *crtc_cfg);
302
303 /**
304 * vkms_config_create_crtc() - Add a new CRTC configuration
305 * @config: Configuration to add the CRTC to
306 *
307 * Returns:
308 * The new CRTC configuration or an error. Call vkms_config_destroy_crtc() to
309 * free the returned CRTC configuration.
310 */
311 struct vkms_config_crtc *vkms_config_create_crtc(struct vkms_config *config);
312
313 /**
314 * vkms_config_destroy_crtc() - Remove and free a CRTC configuration
315 * @config: Configuration to remove the CRTC from
316 * @crtc_cfg: CRTC configuration to destroy
317 */
318 void vkms_config_destroy_crtc(struct vkms_config *config,
319 struct vkms_config_crtc *crtc_cfg);
320
321 /**
322 * vkms_config_crtc_get_writeback() - If a writeback connector will be created
323 * @crtc_cfg: CRTC with or without a writeback connector
324 */
325 static inline bool
vkms_config_crtc_get_writeback(struct vkms_config_crtc * crtc_cfg)326 vkms_config_crtc_get_writeback(struct vkms_config_crtc *crtc_cfg)
327 {
328 return crtc_cfg->writeback;
329 }
330
331 /**
332 * vkms_config_crtc_set_writeback() - If a writeback connector will be created
333 * @crtc_cfg: Target CRTC
334 * @writeback: Enable or disable the writeback connector
335 */
336 static inline void
vkms_config_crtc_set_writeback(struct vkms_config_crtc * crtc_cfg,bool writeback)337 vkms_config_crtc_set_writeback(struct vkms_config_crtc *crtc_cfg,
338 bool writeback)
339 {
340 crtc_cfg->writeback = writeback;
341 }
342
343 /**
344 * vkms_config_crtc_primary_plane() - Return the primary plane for a CRTC
345 * @config: Configuration containing the CRTC
346 * @crtc_config: Target CRTC
347 *
348 * Note that, if multiple primary planes are found, the first one is returned.
349 * In this case, the configuration will be invalid. See vkms_config_is_valid().
350 *
351 * Returns:
352 * The primary plane or NULL if none is assigned yet.
353 */
354 struct vkms_config_plane *vkms_config_crtc_primary_plane(const struct vkms_config *config,
355 struct vkms_config_crtc *crtc_cfg);
356
357 /**
358 * vkms_config_crtc_cursor_plane() - Return the cursor plane for a CRTC
359 * @config: Configuration containing the CRTC
360 * @crtc_config: Target CRTC
361 *
362 * Note that, if multiple cursor planes are found, the first one is returned.
363 * In this case, the configuration will be invalid. See vkms_config_is_valid().
364 *
365 * Returns:
366 * The cursor plane or NULL if none is assigned yet.
367 */
368 struct vkms_config_plane *vkms_config_crtc_cursor_plane(const struct vkms_config *config,
369 struct vkms_config_crtc *crtc_cfg);
370
371 /**
372 * vkms_config_create_encoder() - Add a new encoder configuration
373 * @config: Configuration to add the encoder to
374 *
375 * Returns:
376 * The new encoder configuration or an error. Call vkms_config_destroy_encoder()
377 * to free the returned encoder configuration.
378 */
379 struct vkms_config_encoder *vkms_config_create_encoder(struct vkms_config *config);
380
381 /**
382 * vkms_config_destroy_encoder() - Remove and free a encoder configuration
383 * @config: Configuration to remove the encoder from
384 * @encoder_cfg: Encoder configuration to destroy
385 */
386 void vkms_config_destroy_encoder(struct vkms_config *config,
387 struct vkms_config_encoder *encoder_cfg);
388
389 /**
390 * vkms_config_encoder_attach_crtc - Attach a encoder to a CRTC
391 * @encoder_cfg: Encoder to attach
392 * @crtc_cfg: CRTC to attach @encoder_cfg to
393 */
394 int __must_check vkms_config_encoder_attach_crtc(struct vkms_config_encoder *encoder_cfg,
395 struct vkms_config_crtc *crtc_cfg);
396
397 /**
398 * vkms_config_encoder_detach_crtc - Detach a encoder from a CRTC
399 * @encoder_cfg: Encoder to detach
400 * @crtc_cfg: CRTC to detach @encoder_cfg from
401 */
402 void vkms_config_encoder_detach_crtc(struct vkms_config_encoder *encoder_cfg,
403 struct vkms_config_crtc *crtc_cfg);
404
405 /**
406 * vkms_config_create_connector() - Add a new connector configuration
407 * @config: Configuration to add the connector to
408 *
409 * Returns:
410 * The new connector configuration or an error. Call
411 * vkms_config_destroy_connector() to free the returned connector configuration.
412 */
413 struct vkms_config_connector *vkms_config_create_connector(struct vkms_config *config);
414
415 /**
416 * vkms_config_destroy_connector() - Remove and free a connector configuration
417 * @connector_cfg: Connector configuration to destroy
418 */
419 void vkms_config_destroy_connector(struct vkms_config_connector *connector_cfg);
420
421 /**
422 * vkms_config_connector_attach_encoder - Attach a connector to an encoder
423 * @connector_cfg: Connector to attach
424 * @encoder_cfg: Encoder to attach @connector_cfg to
425 */
426 int __must_check vkms_config_connector_attach_encoder(struct vkms_config_connector *connector_cfg,
427 struct vkms_config_encoder *encoder_cfg);
428
429 /**
430 * vkms_config_connector_detach_encoder - Detach a connector from an encoder
431 * @connector_cfg: Connector to detach
432 * @encoder_cfg: Encoder to detach @connector_cfg from
433 */
434 void vkms_config_connector_detach_encoder(struct vkms_config_connector *connector_cfg,
435 struct vkms_config_encoder *encoder_cfg);
436
437 #endif /* _VKMS_CONFIG_H_ */
438