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