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