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