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 * 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 */ 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 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 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 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 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