1935774cdSBrian Starkey /* SPDX-License-Identifier: GPL-2.0 */ 2935774cdSBrian Starkey /* 3935774cdSBrian Starkey * (C) COPYRIGHT 2016 ARM Limited. All rights reserved. 4935774cdSBrian Starkey * Author: Brian Starkey <brian.starkey@arm.com> 5935774cdSBrian Starkey * 6935774cdSBrian Starkey * This program is free software and is provided to you under the terms of the 7935774cdSBrian Starkey * GNU General Public License version 2 as published by the Free Software 8935774cdSBrian Starkey * Foundation, and any use by you of this program is subject to the terms 9935774cdSBrian Starkey * of such GNU licence. 10935774cdSBrian Starkey */ 11935774cdSBrian Starkey 12935774cdSBrian Starkey #ifndef __DRM_WRITEBACK_H__ 13935774cdSBrian Starkey #define __DRM_WRITEBACK_H__ 14935774cdSBrian Starkey #include <drm/drm_connector.h> 15935774cdSBrian Starkey #include <drm/drm_encoder.h> 16935774cdSBrian Starkey #include <linux/workqueue.h> 17935774cdSBrian Starkey 18935774cdSBrian Starkey struct drm_writeback_connector { 19935774cdSBrian Starkey struct drm_connector base; 20935774cdSBrian Starkey 21935774cdSBrian Starkey /** 22935774cdSBrian Starkey * @encoder: Internal encoder used by the connector to fulfill 23935774cdSBrian Starkey * the DRM framework requirements. The users of the 24935774cdSBrian Starkey * @drm_writeback_connector control the behaviour of the @encoder 25935774cdSBrian Starkey * by passing the @enc_funcs parameter to drm_writeback_connector_init() 26935774cdSBrian Starkey * function. 27935774cdSBrian Starkey */ 28935774cdSBrian Starkey struct drm_encoder encoder; 29935774cdSBrian Starkey 30935774cdSBrian Starkey /** 31935774cdSBrian Starkey * @pixel_formats_blob_ptr: 32935774cdSBrian Starkey * 33935774cdSBrian Starkey * DRM blob property data for the pixel formats list on writeback 34935774cdSBrian Starkey * connectors 35935774cdSBrian Starkey * See also drm_writeback_connector_init() 36935774cdSBrian Starkey */ 37935774cdSBrian Starkey struct drm_property_blob *pixel_formats_blob_ptr; 38935774cdSBrian Starkey 39935774cdSBrian Starkey /** @job_lock: Protects job_queue */ 40935774cdSBrian Starkey spinlock_t job_lock; 41935774cdSBrian Starkey 42935774cdSBrian Starkey /** 43935774cdSBrian Starkey * @job_queue: 44935774cdSBrian Starkey * 45935774cdSBrian Starkey * Holds a list of a connector's writeback jobs; the last item is the 46935774cdSBrian Starkey * most recent. The first item may be either waiting for the hardware 47935774cdSBrian Starkey * to begin writing, or currently being written. 48935774cdSBrian Starkey * 49935774cdSBrian Starkey * See also: drm_writeback_queue_job() and 50935774cdSBrian Starkey * drm_writeback_signal_completion() 51935774cdSBrian Starkey */ 52935774cdSBrian Starkey struct list_head job_queue; 53b13cc8ddSBrian Starkey 54b13cc8ddSBrian Starkey /** 55b13cc8ddSBrian Starkey * @fence_context: 56b13cc8ddSBrian Starkey * 57b13cc8ddSBrian Starkey * timeline context used for fence operations. 58b13cc8ddSBrian Starkey */ 59b13cc8ddSBrian Starkey unsigned int fence_context; 60b13cc8ddSBrian Starkey /** 61b13cc8ddSBrian Starkey * @fence_lock: 62b13cc8ddSBrian Starkey * 63b13cc8ddSBrian Starkey * spinlock to protect the fences in the fence_context. 64b13cc8ddSBrian Starkey */ 65b13cc8ddSBrian Starkey spinlock_t fence_lock; 66b13cc8ddSBrian Starkey /** 67b13cc8ddSBrian Starkey * @fence_seqno: 68b13cc8ddSBrian Starkey * 69b13cc8ddSBrian Starkey * Seqno variable used as monotonic counter for the fences 70b13cc8ddSBrian Starkey * created on the connector's timeline. 71b13cc8ddSBrian Starkey */ 72b13cc8ddSBrian Starkey unsigned long fence_seqno; 73b13cc8ddSBrian Starkey /** 74b13cc8ddSBrian Starkey * @timeline_name: 75b13cc8ddSBrian Starkey * 76b13cc8ddSBrian Starkey * The name of the connector's fence timeline. 77b13cc8ddSBrian Starkey */ 78b13cc8ddSBrian Starkey char timeline_name[32]; 79935774cdSBrian Starkey }; 80935774cdSBrian Starkey 81935774cdSBrian Starkey struct drm_writeback_job { 82935774cdSBrian Starkey /** 839d2230dcSLaurent Pinchart * @connector: 849d2230dcSLaurent Pinchart * 859d2230dcSLaurent Pinchart * Back-pointer to the writeback connector associated with the job 869d2230dcSLaurent Pinchart */ 879d2230dcSLaurent Pinchart struct drm_writeback_connector *connector; 889d2230dcSLaurent Pinchart 899d2230dcSLaurent Pinchart /** 909d2230dcSLaurent Pinchart * @prepared: 919d2230dcSLaurent Pinchart * 929d2230dcSLaurent Pinchart * Set when the job has been prepared with drm_writeback_prepare_job() 939d2230dcSLaurent Pinchart */ 949d2230dcSLaurent Pinchart bool prepared; 959d2230dcSLaurent Pinchart 969d2230dcSLaurent Pinchart /** 97935774cdSBrian Starkey * @cleanup_work: 98935774cdSBrian Starkey * 99935774cdSBrian Starkey * Used to allow drm_writeback_signal_completion to defer dropping the 100935774cdSBrian Starkey * framebuffer reference to a workqueue 101935774cdSBrian Starkey */ 102935774cdSBrian Starkey struct work_struct cleanup_work; 103935774cdSBrian Starkey 104935774cdSBrian Starkey /** 105935774cdSBrian Starkey * @list_entry: 106935774cdSBrian Starkey * 107935774cdSBrian Starkey * List item for the writeback connector's @job_queue 108935774cdSBrian Starkey */ 109935774cdSBrian Starkey struct list_head list_entry; 110935774cdSBrian Starkey 111935774cdSBrian Starkey /** 112935774cdSBrian Starkey * @fb: 113935774cdSBrian Starkey * 114935774cdSBrian Starkey * Framebuffer to be written to by the writeback connector. Do not set 1159d2230dcSLaurent Pinchart * directly, use drm_writeback_set_fb() 116935774cdSBrian Starkey */ 117935774cdSBrian Starkey struct drm_framebuffer *fb; 118b13cc8ddSBrian Starkey 119b13cc8ddSBrian Starkey /** 120b13cc8ddSBrian Starkey * @out_fence: 121b13cc8ddSBrian Starkey * 122b13cc8ddSBrian Starkey * Fence which will signal once the writeback has completed 123b13cc8ddSBrian Starkey */ 124b13cc8ddSBrian Starkey struct dma_fence *out_fence; 1259d2230dcSLaurent Pinchart 1269d2230dcSLaurent Pinchart /** 1279d2230dcSLaurent Pinchart * @priv: 1289d2230dcSLaurent Pinchart * 1299d2230dcSLaurent Pinchart * Driver-private data 1309d2230dcSLaurent Pinchart */ 1319d2230dcSLaurent Pinchart void *priv; 132935774cdSBrian Starkey }; 133935774cdSBrian Starkey 134b82c1f8fSBoris Brezillon static inline struct drm_writeback_connector * 135b82c1f8fSBoris Brezillon drm_connector_to_writeback(struct drm_connector *connector) 136b82c1f8fSBoris Brezillon { 137b82c1f8fSBoris Brezillon return container_of(connector, struct drm_writeback_connector, base); 138b82c1f8fSBoris Brezillon } 139b82c1f8fSBoris Brezillon 140935774cdSBrian Starkey int drm_writeback_connector_init(struct drm_device *dev, 141935774cdSBrian Starkey struct drm_writeback_connector *wb_connector, 142935774cdSBrian Starkey const struct drm_connector_funcs *con_funcs, 143935774cdSBrian Starkey const struct drm_encoder_helper_funcs *enc_helper_funcs, 144935774cdSBrian Starkey const u32 *formats, int n_formats); 145935774cdSBrian Starkey 1469d2230dcSLaurent Pinchart int drm_writeback_set_fb(struct drm_connector_state *conn_state, 1479d2230dcSLaurent Pinchart struct drm_framebuffer *fb); 1489d2230dcSLaurent Pinchart 1499d2230dcSLaurent Pinchart int drm_writeback_prepare_job(struct drm_writeback_job *job); 1509d2230dcSLaurent Pinchart 151935774cdSBrian Starkey void drm_writeback_queue_job(struct drm_writeback_connector *wb_connector, 15297eb9eaeSLaurent Pinchart struct drm_connector_state *conn_state); 153935774cdSBrian Starkey 154935774cdSBrian Starkey void drm_writeback_cleanup_job(struct drm_writeback_job *job); 155b13cc8ddSBrian Starkey 156b13cc8ddSBrian Starkey void 157b13cc8ddSBrian Starkey drm_writeback_signal_completion(struct drm_writeback_connector *wb_connector, 158b13cc8ddSBrian Starkey int status); 159b13cc8ddSBrian Starkey 160b13cc8ddSBrian Starkey struct dma_fence * 161b13cc8ddSBrian Starkey drm_writeback_get_out_fence(struct drm_writeback_connector *wb_connector); 162935774cdSBrian Starkey #endif 163