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