xref: /linux/drivers/gpu/drm/vkms/vkms_config.h (revision ab93e0dd72c37d378dd936f031ffb83ff2bd87ce)
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