1 // SPDX-License-Identifier: GPL-2.0 2 /* 3 * (C) COPYRIGHT 2016 ARM Limited. All rights reserved. 4 * Author: Brian Starkey <brian.starkey@arm.com> 5 * 6 * This program is free software and is provided to you under the terms of the 7 * GNU General Public License version 2 as published by the Free Software 8 * Foundation, and any use by you of this program is subject to the terms 9 * of such GNU licence. 10 */ 11 12 #include <linux/dma-fence.h> 13 #include <linux/export.h> 14 15 #include <drm/drm_crtc.h> 16 #include <drm/drm_device.h> 17 #include <drm/drm_drv.h> 18 #include <drm/drm_framebuffer.h> 19 #include <drm/drm_managed.h> 20 #include <drm/drm_modeset_helper_vtables.h> 21 #include <drm/drm_property.h> 22 #include <drm/drm_writeback.h> 23 24 /** 25 * DOC: overview 26 * 27 * Writeback connectors are used to expose hardware which can write the output 28 * from a CRTC to a memory buffer. They are used and act similarly to other 29 * types of connectors, with some important differences: 30 * 31 * * Writeback connectors don't provide a way to output visually to the user. 32 * 33 * * Writeback connectors are visible to userspace only when the client sets 34 * DRM_CLIENT_CAP_WRITEBACK_CONNECTORS. 35 * 36 * * Writeback connectors don't have EDID. 37 * 38 * A framebuffer may only be attached to a writeback connector when the 39 * connector is attached to a CRTC. The WRITEBACK_FB_ID property which sets the 40 * framebuffer applies only to a single commit (see below). A framebuffer may 41 * not be attached while the CRTC is off. 42 * 43 * Unlike with planes, when a writeback framebuffer is removed by userspace DRM 44 * makes no attempt to remove it from active use by the connector. This is 45 * because no method is provided to abort a writeback operation, and in any 46 * case making a new commit whilst a writeback is ongoing is undefined (see 47 * WRITEBACK_OUT_FENCE_PTR below). As soon as the current writeback is finished, 48 * the framebuffer will automatically no longer be in active use. As it will 49 * also have already been removed from the framebuffer list, there will be no 50 * way for any userspace application to retrieve a reference to it in the 51 * intervening period. 52 * 53 * Writeback connectors have some additional properties, which userspace 54 * can use to query and control them: 55 * 56 * "WRITEBACK_FB_ID": 57 * Write-only object property storing a DRM_MODE_OBJECT_FB: it stores the 58 * framebuffer to be written by the writeback connector. This property is 59 * similar to the FB_ID property on planes, but will always read as zero 60 * and is not preserved across commits. 61 * Userspace must set this property to an output buffer every time it 62 * wishes the buffer to get filled. 63 * 64 * "WRITEBACK_PIXEL_FORMATS": 65 * Immutable blob property to store the supported pixel formats table. The 66 * data is an array of u32 DRM_FORMAT_* fourcc values. 67 * Userspace can use this blob to find out what pixel formats are supported 68 * by the connector's writeback engine. 69 * 70 * "WRITEBACK_OUT_FENCE_PTR": 71 * Userspace can use this property to provide a pointer for the kernel to 72 * fill with a sync_file file descriptor, which will signal once the 73 * writeback is finished. The value should be the address of a 32-bit 74 * signed integer, cast to a u64. 75 * Userspace should wait for this fence to signal before making another 76 * commit affecting any of the same CRTCs, Planes or Connectors. 77 * **Failure to do so will result in undefined behaviour.** 78 * For this reason it is strongly recommended that all userspace 79 * applications making use of writeback connectors *always* retrieve an 80 * out-fence for the commit and use it appropriately. 81 * From userspace, this property will always read as zero. 82 */ 83 84 #define fence_to_wb_connector(x) container_of(x->lock, \ 85 struct drm_writeback_connector, \ 86 fence_lock) 87 88 static const char *drm_writeback_fence_get_driver_name(struct dma_fence *fence) 89 { 90 struct drm_writeback_connector *wb_connector = 91 fence_to_wb_connector(fence); 92 93 return wb_connector->base.dev->driver->name; 94 } 95 96 static const char * 97 drm_writeback_fence_get_timeline_name(struct dma_fence *fence) 98 { 99 struct drm_writeback_connector *wb_connector = 100 fence_to_wb_connector(fence); 101 102 return wb_connector->timeline_name; 103 } 104 105 static const struct dma_fence_ops drm_writeback_fence_ops = { 106 .get_driver_name = drm_writeback_fence_get_driver_name, 107 .get_timeline_name = drm_writeback_fence_get_timeline_name, 108 }; 109 110 static int create_writeback_properties(struct drm_device *dev) 111 { 112 struct drm_property *prop; 113 114 if (!dev->mode_config.writeback_fb_id_property) { 115 prop = drm_property_create_object(dev, DRM_MODE_PROP_ATOMIC, 116 "WRITEBACK_FB_ID", 117 DRM_MODE_OBJECT_FB); 118 if (!prop) 119 return -ENOMEM; 120 dev->mode_config.writeback_fb_id_property = prop; 121 } 122 123 if (!dev->mode_config.writeback_pixel_formats_property) { 124 prop = drm_property_create(dev, DRM_MODE_PROP_BLOB | 125 DRM_MODE_PROP_ATOMIC | 126 DRM_MODE_PROP_IMMUTABLE, 127 "WRITEBACK_PIXEL_FORMATS", 0); 128 if (!prop) 129 return -ENOMEM; 130 dev->mode_config.writeback_pixel_formats_property = prop; 131 } 132 133 if (!dev->mode_config.writeback_out_fence_ptr_property) { 134 prop = drm_property_create_range(dev, DRM_MODE_PROP_ATOMIC, 135 "WRITEBACK_OUT_FENCE_PTR", 0, 136 U64_MAX); 137 if (!prop) 138 return -ENOMEM; 139 dev->mode_config.writeback_out_fence_ptr_property = prop; 140 } 141 142 return 0; 143 } 144 145 static const struct drm_encoder_funcs drm_writeback_encoder_funcs = { 146 .destroy = drm_encoder_cleanup, 147 }; 148 149 /** 150 * drm_writeback_connector_init - Initialize a writeback connector and its properties 151 * @dev: DRM device 152 * @wb_connector: Writeback connector to initialize 153 * @con_funcs: Connector funcs vtable 154 * @enc_helper_funcs: Encoder helper funcs vtable to be used by the internal encoder 155 * @formats: Array of supported pixel formats for the writeback engine 156 * @n_formats: Length of the formats array 157 * @possible_crtcs: possible crtcs for the internal writeback encoder 158 * 159 * This function creates the writeback-connector-specific properties if they 160 * have not been already created, initializes the connector as 161 * type DRM_MODE_CONNECTOR_WRITEBACK, and correctly initializes the property 162 * values. It will also create an internal encoder associated with the 163 * drm_writeback_connector and set it to use the @enc_helper_funcs vtable for 164 * the encoder helper. 165 * 166 * Drivers should always use this function instead of drm_connector_init() to 167 * set up writeback connectors. 168 * 169 * Returns: 0 on success, or a negative error code 170 */ 171 int drm_writeback_connector_init(struct drm_device *dev, 172 struct drm_writeback_connector *wb_connector, 173 const struct drm_connector_funcs *con_funcs, 174 const struct drm_encoder_helper_funcs *enc_helper_funcs, 175 const u32 *formats, int n_formats, 176 u32 possible_crtcs) 177 { 178 int ret = 0; 179 180 drm_encoder_helper_add(&wb_connector->encoder, enc_helper_funcs); 181 182 wb_connector->encoder.possible_crtcs = possible_crtcs; 183 184 ret = drm_encoder_init(dev, &wb_connector->encoder, 185 &drm_writeback_encoder_funcs, 186 DRM_MODE_ENCODER_VIRTUAL, NULL); 187 if (ret) 188 return ret; 189 190 ret = drm_writeback_connector_init_with_encoder(dev, wb_connector, &wb_connector->encoder, 191 con_funcs, formats, n_formats); 192 193 if (ret) 194 drm_encoder_cleanup(&wb_connector->encoder); 195 196 return ret; 197 } 198 EXPORT_SYMBOL(drm_writeback_connector_init); 199 200 static void delete_writeback_properties(struct drm_device *dev) 201 { 202 if (dev->mode_config.writeback_pixel_formats_property) { 203 drm_property_destroy(dev, dev->mode_config.writeback_pixel_formats_property); 204 dev->mode_config.writeback_pixel_formats_property = NULL; 205 } 206 if (dev->mode_config.writeback_out_fence_ptr_property) { 207 drm_property_destroy(dev, dev->mode_config.writeback_out_fence_ptr_property); 208 dev->mode_config.writeback_out_fence_ptr_property = NULL; 209 } 210 if (dev->mode_config.writeback_fb_id_property) { 211 drm_property_destroy(dev, dev->mode_config.writeback_fb_id_property); 212 dev->mode_config.writeback_fb_id_property = NULL; 213 } 214 } 215 216 /** 217 * __drm_writeback_connector_init - Initialize a writeback connector with 218 * a custom encoder 219 * 220 * @dev: DRM device 221 * @wb_connector: Writeback connector to initialize 222 * @enc: handle to the already initialized drm encoder 223 * @formats: Array of supported pixel formats for the writeback engine 224 * @n_formats: Length of the formats array 225 * 226 * This function creates the writeback-connector-specific properties if they 227 * have not been already created, initializes the connector as 228 * type DRM_MODE_CONNECTOR_WRITEBACK, and correctly initializes the property 229 * values. 230 * 231 * This function assumes that the drm_writeback_connector's encoder has already been 232 * created and initialized before invoking this function. 233 * 234 * In addition, this function also assumes that callers of this API will manage 235 * assigning the encoder helper functions, possible_crtcs and any other encoder 236 * specific operation. 237 * 238 * Returns: 0 on success, or a negative error code 239 */ 240 static int __drm_writeback_connector_init(struct drm_device *dev, 241 struct drm_writeback_connector *wb_connector, 242 struct drm_encoder *enc, const u32 *formats, 243 int n_formats) 244 { 245 struct drm_connector *connector = &wb_connector->base; 246 struct drm_mode_config *config = &dev->mode_config; 247 struct drm_property_blob *blob; 248 int ret = create_writeback_properties(dev); 249 250 if (ret != 0) 251 goto failed_properties; 252 253 connector->interlace_allowed = 0; 254 255 ret = drm_connector_attach_encoder(connector, enc); 256 if (ret) 257 goto failed_properties; 258 259 blob = drm_property_create_blob(dev, n_formats * sizeof(*formats), 260 formats); 261 if (IS_ERR(blob)) { 262 ret = PTR_ERR(blob); 263 goto failed_properties; 264 } 265 266 INIT_LIST_HEAD(&wb_connector->job_queue); 267 spin_lock_init(&wb_connector->job_lock); 268 269 wb_connector->fence_context = dma_fence_context_alloc(1); 270 spin_lock_init(&wb_connector->fence_lock); 271 snprintf(wb_connector->timeline_name, 272 sizeof(wb_connector->timeline_name), 273 "CONNECTOR:%d-%s", connector->base.id, connector->name); 274 275 drm_object_attach_property(&connector->base, 276 config->writeback_out_fence_ptr_property, 0); 277 278 drm_object_attach_property(&connector->base, 279 config->writeback_fb_id_property, 0); 280 281 drm_object_attach_property(&connector->base, 282 config->writeback_pixel_formats_property, 283 blob->base.id); 284 wb_connector->pixel_formats_blob_ptr = blob; 285 286 return 0; 287 failed_properties: 288 delete_writeback_properties(dev); 289 return ret; 290 } 291 292 /** 293 * drm_writeback_connector_init_with_encoder - Initialize a writeback connector with 294 * a custom encoder 295 * 296 * @dev: DRM device 297 * @wb_connector: Writeback connector to initialize 298 * @enc: handle to the already initialized drm encoder 299 * @con_funcs: Connector funcs vtable 300 * @formats: Array of supported pixel formats for the writeback engine 301 * @n_formats: Length of the formats array 302 * 303 * This function creates the writeback-connector-specific properties if they 304 * have not been already created, initializes the connector as 305 * type DRM_MODE_CONNECTOR_WRITEBACK, and correctly initializes the property 306 * values. 307 * 308 * This function assumes that the drm_writeback_connector's encoder has already been 309 * created and initialized before invoking this function. 310 * 311 * In addition, this function also assumes that callers of this API will manage 312 * assigning the encoder helper functions, possible_crtcs and any other encoder 313 * specific operation. 314 * 315 * Drivers should always use this function instead of drm_connector_init() to 316 * set up writeback connectors if they want to manage themselves the lifetime of the 317 * associated encoder. 318 * 319 * Returns: 0 on success, or a negative error code 320 */ 321 int drm_writeback_connector_init_with_encoder(struct drm_device *dev, 322 struct drm_writeback_connector *wb_connector, 323 struct drm_encoder *enc, 324 const struct drm_connector_funcs *con_funcs, 325 const u32 *formats, int n_formats) 326 { 327 struct drm_connector *connector = &wb_connector->base; 328 int ret; 329 330 ret = drm_connector_init(dev, connector, con_funcs, 331 DRM_MODE_CONNECTOR_WRITEBACK); 332 if (ret) 333 return ret; 334 335 ret = __drm_writeback_connector_init(dev, wb_connector, enc, formats, 336 n_formats); 337 if (ret) 338 drm_connector_cleanup(connector); 339 340 return ret; 341 } 342 EXPORT_SYMBOL(drm_writeback_connector_init_with_encoder); 343 344 /** 345 * drm_writeback_connector_cleanup - Cleanup the writeback connector 346 * @dev: DRM device 347 * @data: Pointer to the writeback connector to clean up 348 * 349 * This will decrement the reference counter of blobs and destroy properties. It 350 * will also clean the remaining jobs in this writeback connector. Caution: This helper will not 351 * clean up the attached encoder and the drm_connector. 352 */ 353 static void drm_writeback_connector_cleanup(struct drm_device *dev, 354 void *data) 355 { 356 unsigned long flags; 357 struct drm_writeback_job *pos, *n; 358 struct drm_writeback_connector *wb_connector = data; 359 360 delete_writeback_properties(dev); 361 drm_property_blob_put(wb_connector->pixel_formats_blob_ptr); 362 363 spin_lock_irqsave(&wb_connector->job_lock, flags); 364 list_for_each_entry_safe(pos, n, &wb_connector->job_queue, list_entry) { 365 list_del(&pos->list_entry); 366 drm_writeback_cleanup_job(pos); 367 } 368 spin_unlock_irqrestore(&wb_connector->job_lock, flags); 369 } 370 371 /** 372 * drmm_writeback_connector_init - Initialize a writeback connector with 373 * a custom encoder 374 * 375 * @dev: DRM device 376 * @wb_connector: Writeback connector to initialize 377 * @con_funcs: Connector funcs vtable 378 * @enc: Encoder to connect this writeback connector 379 * @formats: Array of supported pixel formats for the writeback engine 380 * @n_formats: Length of the formats array 381 * 382 * This function initialize a writeback connector and register its cleanup. 383 * 384 * This function creates the writeback-connector-specific properties if they 385 * have not been already created, initializes the connector as 386 * type DRM_MODE_CONNECTOR_WRITEBACK, and correctly initializes the property 387 * values. 388 * 389 * Returns: 0 on success, or a negative error code 390 */ 391 int drmm_writeback_connector_init(struct drm_device *dev, 392 struct drm_writeback_connector *wb_connector, 393 const struct drm_connector_funcs *con_funcs, 394 struct drm_encoder *enc, 395 const u32 *formats, int n_formats) 396 { 397 struct drm_connector *connector = &wb_connector->base; 398 int ret; 399 400 ret = drmm_connector_init(dev, connector, con_funcs, 401 DRM_MODE_CONNECTOR_WRITEBACK, NULL); 402 if (ret) 403 return ret; 404 405 ret = __drm_writeback_connector_init(dev, wb_connector, enc, formats, 406 n_formats); 407 if (ret) 408 return ret; 409 410 ret = drmm_add_action_or_reset(dev, drm_writeback_connector_cleanup, 411 wb_connector); 412 if (ret) 413 return ret; 414 415 return 0; 416 } 417 EXPORT_SYMBOL(drmm_writeback_connector_init); 418 419 int drm_writeback_set_fb(struct drm_connector_state *conn_state, 420 struct drm_framebuffer *fb) 421 { 422 WARN_ON(conn_state->connector->connector_type != DRM_MODE_CONNECTOR_WRITEBACK); 423 424 if (!conn_state->writeback_job) { 425 conn_state->writeback_job = 426 kzalloc(sizeof(*conn_state->writeback_job), GFP_KERNEL); 427 if (!conn_state->writeback_job) 428 return -ENOMEM; 429 430 conn_state->writeback_job->connector = 431 drm_connector_to_writeback(conn_state->connector); 432 } 433 434 drm_framebuffer_assign(&conn_state->writeback_job->fb, fb); 435 return 0; 436 } 437 438 int drm_writeback_prepare_job(struct drm_writeback_job *job) 439 { 440 struct drm_writeback_connector *connector = job->connector; 441 const struct drm_connector_helper_funcs *funcs = 442 connector->base.helper_private; 443 int ret; 444 445 if (funcs->prepare_writeback_job) { 446 ret = funcs->prepare_writeback_job(connector, job); 447 if (ret < 0) 448 return ret; 449 } 450 451 job->prepared = true; 452 return 0; 453 } 454 EXPORT_SYMBOL(drm_writeback_prepare_job); 455 456 /** 457 * drm_writeback_queue_job - Queue a writeback job for later signalling 458 * @wb_connector: The writeback connector to queue a job on 459 * @conn_state: The connector state containing the job to queue 460 * 461 * This function adds the job contained in @conn_state to the job_queue for a 462 * writeback connector. It takes ownership of the writeback job and sets the 463 * @conn_state->writeback_job to NULL, and so no access to the job may be 464 * performed by the caller after this function returns. 465 * 466 * Drivers must ensure that for a given writeback connector, jobs are queued in 467 * exactly the same order as they will be completed by the hardware (and 468 * signaled via drm_writeback_signal_completion). 469 * 470 * For every call to drm_writeback_queue_job() there must be exactly one call to 471 * drm_writeback_signal_completion() 472 * 473 * See also: drm_writeback_signal_completion() 474 */ 475 void drm_writeback_queue_job(struct drm_writeback_connector *wb_connector, 476 struct drm_connector_state *conn_state) 477 { 478 struct drm_writeback_job *job; 479 unsigned long flags; 480 481 job = conn_state->writeback_job; 482 conn_state->writeback_job = NULL; 483 484 spin_lock_irqsave(&wb_connector->job_lock, flags); 485 list_add_tail(&job->list_entry, &wb_connector->job_queue); 486 spin_unlock_irqrestore(&wb_connector->job_lock, flags); 487 } 488 EXPORT_SYMBOL(drm_writeback_queue_job); 489 490 void drm_writeback_cleanup_job(struct drm_writeback_job *job) 491 { 492 struct drm_writeback_connector *connector = job->connector; 493 const struct drm_connector_helper_funcs *funcs = 494 connector->base.helper_private; 495 496 if (job->prepared && funcs->cleanup_writeback_job) 497 funcs->cleanup_writeback_job(connector, job); 498 499 if (job->fb) 500 drm_framebuffer_put(job->fb); 501 502 if (job->out_fence) 503 dma_fence_put(job->out_fence); 504 505 kfree(job); 506 } 507 EXPORT_SYMBOL(drm_writeback_cleanup_job); 508 509 /* 510 * @cleanup_work: deferred cleanup of a writeback job 511 * 512 * The job cannot be cleaned up directly in drm_writeback_signal_completion, 513 * because it may be called in interrupt context. Dropping the framebuffer 514 * reference can sleep, and so the cleanup is deferred to a workqueue. 515 */ 516 static void cleanup_work(struct work_struct *work) 517 { 518 struct drm_writeback_job *job = container_of(work, 519 struct drm_writeback_job, 520 cleanup_work); 521 522 drm_writeback_cleanup_job(job); 523 } 524 525 /** 526 * drm_writeback_signal_completion - Signal the completion of a writeback job 527 * @wb_connector: The writeback connector whose job is complete 528 * @status: Status code to set in the writeback out_fence (0 for success) 529 * 530 * Drivers should call this to signal the completion of a previously queued 531 * writeback job. It should be called as soon as possible after the hardware 532 * has finished writing, and may be called from interrupt context. 533 * It is the driver's responsibility to ensure that for a given connector, the 534 * hardware completes writeback jobs in the same order as they are queued. 535 * 536 * Unless the driver is holding its own reference to the framebuffer, it must 537 * not be accessed after calling this function. 538 * 539 * See also: drm_writeback_queue_job() 540 */ 541 void 542 drm_writeback_signal_completion(struct drm_writeback_connector *wb_connector, 543 int status) 544 { 545 unsigned long flags; 546 struct drm_writeback_job *job; 547 struct dma_fence *out_fence; 548 549 spin_lock_irqsave(&wb_connector->job_lock, flags); 550 job = list_first_entry_or_null(&wb_connector->job_queue, 551 struct drm_writeback_job, 552 list_entry); 553 if (job) 554 list_del(&job->list_entry); 555 556 spin_unlock_irqrestore(&wb_connector->job_lock, flags); 557 558 if (WARN_ON(!job)) 559 return; 560 561 out_fence = job->out_fence; 562 if (out_fence) { 563 if (status) 564 dma_fence_set_error(out_fence, status); 565 dma_fence_signal(out_fence); 566 dma_fence_put(out_fence); 567 job->out_fence = NULL; 568 } 569 570 INIT_WORK(&job->cleanup_work, cleanup_work); 571 queue_work(system_long_wq, &job->cleanup_work); 572 } 573 EXPORT_SYMBOL(drm_writeback_signal_completion); 574 575 struct dma_fence * 576 drm_writeback_get_out_fence(struct drm_writeback_connector *wb_connector) 577 { 578 struct dma_fence *fence; 579 580 if (WARN_ON(wb_connector->base.connector_type != 581 DRM_MODE_CONNECTOR_WRITEBACK)) 582 return NULL; 583 584 fence = kzalloc(sizeof(*fence), GFP_KERNEL); 585 if (!fence) 586 return NULL; 587 588 dma_fence_init(fence, &drm_writeback_fence_ops, 589 &wb_connector->fence_lock, wb_connector->fence_context, 590 ++wb_connector->fence_seqno); 591 592 return fence; 593 } 594 EXPORT_SYMBOL(drm_writeback_get_out_fence); 595