diff options
author | Daniel Vetter <daniel.vetter@ffwll.ch> | 2016-06-16 08:18:30 -0400 |
---|---|---|
committer | Daniel Vetter <daniel.vetter@ffwll.ch> | 2016-06-16 08:18:30 -0400 |
commit | c19941218c9a1cae578dfbf30190b13b9cdb9aa8 (patch) | |
tree | 0014d2ac89e6209c565f5a8fc53abd8dce13e63e /include/drm | |
parent | 1c1a24d2db35d9e1b6d2a012a7d51af8be8011ac (diff) | |
parent | a0877f52035280370707bdefeddc6faa6478b892 (diff) |
Merge remote-tracking branch 'airlied/drm-next' into drm-intel-next-queued
Backmerge drm-next to get at the nonblocking atomic helpers, needed to
merge the i915 conversion.
Signed-off-by: Daniel Vetter <daniel.vetter@intel.com>
Diffstat (limited to 'include/drm')
-rw-r--r-- | include/drm/drmP.h | 23 | ||||
-rw-r--r-- | include/drm/drm_atomic.h | 82 | ||||
-rw-r--r-- | include/drm/drm_atomic_helper.h | 42 | ||||
-rw-r--r-- | include/drm/drm_crtc.h | 329 | ||||
-rw-r--r-- | include/drm/drm_crtc_helper.h | 3 | ||||
-rw-r--r-- | include/drm/drm_fb_helper.h | 11 | ||||
-rw-r--r-- | include/drm/drm_fourcc.h | 37 | ||||
-rw-r--r-- | include/drm/drm_mipi_dsi.h | 3 | ||||
-rw-r--r-- | include/drm/drm_modes.h | 2 | ||||
-rw-r--r-- | include/drm/drm_modeset_helper_vtables.h | 49 | ||||
-rw-r--r-- | include/drm/drm_simple_kms_helper.h | 94 |
11 files changed, 578 insertions, 97 deletions
diff --git a/include/drm/drmP.h b/include/drm/drmP.h index c5d29505f937..04310cb08111 100644 --- a/include/drm/drmP.h +++ b/include/drm/drmP.h | |||
@@ -57,6 +57,7 @@ | |||
57 | #include <linux/types.h> | 57 | #include <linux/types.h> |
58 | #include <linux/vmalloc.h> | 58 | #include <linux/vmalloc.h> |
59 | #include <linux/workqueue.h> | 59 | #include <linux/workqueue.h> |
60 | #include <linux/fence.h> | ||
60 | 61 | ||
61 | #include <asm/mman.h> | 62 | #include <asm/mman.h> |
62 | #include <asm/pgalloc.h> | 63 | #include <asm/pgalloc.h> |
@@ -67,6 +68,7 @@ | |||
67 | 68 | ||
68 | #include <drm/drm_agpsupport.h> | 69 | #include <drm/drm_agpsupport.h> |
69 | #include <drm/drm_crtc.h> | 70 | #include <drm/drm_crtc.h> |
71 | #include <drm/drm_fourcc.h> | ||
70 | #include <drm/drm_global.h> | 72 | #include <drm/drm_global.h> |
71 | #include <drm/drm_hashtab.h> | 73 | #include <drm/drm_hashtab.h> |
72 | #include <drm/drm_mem_util.h> | 74 | #include <drm/drm_mem_util.h> |
@@ -282,13 +284,14 @@ struct drm_ioctl_desc { | |||
282 | 284 | ||
283 | /* Event queued up for userspace to read */ | 285 | /* Event queued up for userspace to read */ |
284 | struct drm_pending_event { | 286 | struct drm_pending_event { |
287 | struct completion *completion; | ||
285 | struct drm_event *event; | 288 | struct drm_event *event; |
289 | struct fence *fence; | ||
286 | struct list_head link; | 290 | struct list_head link; |
287 | struct list_head pending_link; | 291 | struct list_head pending_link; |
288 | struct drm_file *file_priv; | 292 | struct drm_file *file_priv; |
289 | pid_t pid; /* pid of requester, no guarantee it's valid by the time | 293 | pid_t pid; /* pid of requester, no guarantee it's valid by the time |
290 | we deliver the event, for tracing only */ | 294 | we deliver the event, for tracing only */ |
291 | void (*destroy)(struct drm_pending_event *event); | ||
292 | }; | 295 | }; |
293 | 296 | ||
294 | /* initial implementaton using a linked list - todo hashtab */ | 297 | /* initial implementaton using a linked list - todo hashtab */ |
@@ -416,8 +419,6 @@ struct drm_driver { | |||
416 | void (*postclose) (struct drm_device *, struct drm_file *); | 419 | void (*postclose) (struct drm_device *, struct drm_file *); |
417 | void (*lastclose) (struct drm_device *); | 420 | void (*lastclose) (struct drm_device *); |
418 | int (*unload) (struct drm_device *); | 421 | int (*unload) (struct drm_device *); |
419 | int (*suspend) (struct drm_device *, pm_message_t state); | ||
420 | int (*resume) (struct drm_device *); | ||
421 | int (*dma_ioctl) (struct drm_device *dev, void *data, struct drm_file *file_priv); | 422 | int (*dma_ioctl) (struct drm_device *dev, void *data, struct drm_file *file_priv); |
422 | int (*dma_quiescent) (struct drm_device *); | 423 | int (*dma_quiescent) (struct drm_device *); |
423 | int (*context_dtor) (struct drm_device *dev, int context); | 424 | int (*context_dtor) (struct drm_device *dev, int context); |
@@ -430,7 +431,7 @@ struct drm_driver { | |||
430 | * | 431 | * |
431 | * Driver callback for fetching a raw hardware vblank counter for @crtc. | 432 | * Driver callback for fetching a raw hardware vblank counter for @crtc. |
432 | * If a device doesn't have a hardware counter, the driver can simply | 433 | * If a device doesn't have a hardware counter, the driver can simply |
433 | * return the value of drm_vblank_count. The DRM core will account for | 434 | * use drm_vblank_no_hw_counter() function. The DRM core will account for |
434 | * missed vblank events while interrupts where disabled based on system | 435 | * missed vblank events while interrupts where disabled based on system |
435 | * timestamps. | 436 | * timestamps. |
436 | * | 437 | * |
@@ -448,8 +449,8 @@ struct drm_driver { | |||
448 | * @pipe: which irq to enable | 449 | * @pipe: which irq to enable |
449 | * | 450 | * |
450 | * Enable vblank interrupts for @crtc. If the device doesn't have | 451 | * Enable vblank interrupts for @crtc. If the device doesn't have |
451 | * a hardware vblank counter, this routine should be a no-op, since | 452 | * a hardware vblank counter, the driver should use the |
452 | * interrupts will have to stay on to keep the count accurate. | 453 | * drm_vblank_no_hw_counter() function that keeps a virtual counter. |
453 | * | 454 | * |
454 | * RETURNS | 455 | * RETURNS |
455 | * Zero on success, appropriate errno if the given @crtc's vblank | 456 | * Zero on success, appropriate errno if the given @crtc's vblank |
@@ -463,8 +464,8 @@ struct drm_driver { | |||
463 | * @pipe: which irq to enable | 464 | * @pipe: which irq to enable |
464 | * | 465 | * |
465 | * Disable vblank interrupts for @crtc. If the device doesn't have | 466 | * Disable vblank interrupts for @crtc. If the device doesn't have |
466 | * a hardware vblank counter, this routine should be a no-op, since | 467 | * a hardware vblank counter, the driver should use the |
467 | * interrupts will have to stay on to keep the count accurate. | 468 | * drm_vblank_no_hw_counter() function that keeps a virtual counter. |
468 | */ | 469 | */ |
469 | void (*disable_vblank) (struct drm_device *dev, unsigned int pipe); | 470 | void (*disable_vblank) (struct drm_device *dev, unsigned int pipe); |
470 | 471 | ||
@@ -968,18 +969,12 @@ extern u32 drm_vblank_count_and_time(struct drm_device *dev, unsigned int pipe, | |||
968 | struct timeval *vblanktime); | 969 | struct timeval *vblanktime); |
969 | extern u32 drm_crtc_vblank_count_and_time(struct drm_crtc *crtc, | 970 | extern u32 drm_crtc_vblank_count_and_time(struct drm_crtc *crtc, |
970 | struct timeval *vblanktime); | 971 | struct timeval *vblanktime); |
971 | extern void drm_send_vblank_event(struct drm_device *dev, unsigned int pipe, | ||
972 | struct drm_pending_vblank_event *e); | ||
973 | extern void drm_crtc_send_vblank_event(struct drm_crtc *crtc, | 972 | extern void drm_crtc_send_vblank_event(struct drm_crtc *crtc, |
974 | struct drm_pending_vblank_event *e); | 973 | struct drm_pending_vblank_event *e); |
975 | extern void drm_arm_vblank_event(struct drm_device *dev, unsigned int pipe, | ||
976 | struct drm_pending_vblank_event *e); | ||
977 | extern void drm_crtc_arm_vblank_event(struct drm_crtc *crtc, | 974 | extern void drm_crtc_arm_vblank_event(struct drm_crtc *crtc, |
978 | struct drm_pending_vblank_event *e); | 975 | struct drm_pending_vblank_event *e); |
979 | extern bool drm_handle_vblank(struct drm_device *dev, unsigned int pipe); | 976 | extern bool drm_handle_vblank(struct drm_device *dev, unsigned int pipe); |
980 | extern bool drm_crtc_handle_vblank(struct drm_crtc *crtc); | 977 | extern bool drm_crtc_handle_vblank(struct drm_crtc *crtc); |
981 | extern int drm_vblank_get(struct drm_device *dev, unsigned int pipe); | ||
982 | extern void drm_vblank_put(struct drm_device *dev, unsigned int pipe); | ||
983 | extern int drm_crtc_vblank_get(struct drm_crtc *crtc); | 978 | extern int drm_crtc_vblank_get(struct drm_crtc *crtc); |
984 | extern void drm_crtc_vblank_put(struct drm_crtc *crtc); | 979 | extern void drm_crtc_vblank_put(struct drm_crtc *crtc); |
985 | extern void drm_wait_one_vblank(struct drm_device *dev, unsigned int pipe); | 980 | extern void drm_wait_one_vblank(struct drm_device *dev, unsigned int pipe); |
diff --git a/include/drm/drm_atomic.h b/include/drm/drm_atomic.h index 92c84e9ab09a..856a9c85a838 100644 --- a/include/drm/drm_atomic.h +++ b/include/drm/drm_atomic.h | |||
@@ -30,6 +30,12 @@ | |||
30 | 30 | ||
31 | #include <drm/drm_crtc.h> | 31 | #include <drm/drm_crtc.h> |
32 | 32 | ||
33 | void drm_crtc_commit_put(struct drm_crtc_commit *commit); | ||
34 | static inline void drm_crtc_commit_get(struct drm_crtc_commit *commit) | ||
35 | { | ||
36 | kref_get(&commit->ref); | ||
37 | } | ||
38 | |||
33 | struct drm_atomic_state * __must_check | 39 | struct drm_atomic_state * __must_check |
34 | drm_atomic_state_alloc(struct drm_device *dev); | 40 | drm_atomic_state_alloc(struct drm_device *dev); |
35 | void drm_atomic_state_clear(struct drm_atomic_state *state); | 41 | void drm_atomic_state_clear(struct drm_atomic_state *state); |
@@ -71,7 +77,7 @@ static inline struct drm_crtc_state * | |||
71 | drm_atomic_get_existing_crtc_state(struct drm_atomic_state *state, | 77 | drm_atomic_get_existing_crtc_state(struct drm_atomic_state *state, |
72 | struct drm_crtc *crtc) | 78 | struct drm_crtc *crtc) |
73 | { | 79 | { |
74 | return state->crtc_states[drm_crtc_index(crtc)]; | 80 | return state->crtcs[drm_crtc_index(crtc)].state; |
75 | } | 81 | } |
76 | 82 | ||
77 | /** | 83 | /** |
@@ -86,7 +92,7 @@ static inline struct drm_plane_state * | |||
86 | drm_atomic_get_existing_plane_state(struct drm_atomic_state *state, | 92 | drm_atomic_get_existing_plane_state(struct drm_atomic_state *state, |
87 | struct drm_plane *plane) | 93 | struct drm_plane *plane) |
88 | { | 94 | { |
89 | return state->plane_states[drm_plane_index(plane)]; | 95 | return state->planes[drm_plane_index(plane)].state; |
90 | } | 96 | } |
91 | 97 | ||
92 | /** | 98 | /** |
@@ -106,7 +112,43 @@ drm_atomic_get_existing_connector_state(struct drm_atomic_state *state, | |||
106 | if (index >= state->num_connector) | 112 | if (index >= state->num_connector) |
107 | return NULL; | 113 | return NULL; |
108 | 114 | ||
109 | return state->connector_states[index]; | 115 | return state->connectors[index].state; |
116 | } | ||
117 | |||
118 | /** | ||
119 | * __drm_atomic_get_current_plane_state - get current plane state | ||
120 | * @state: global atomic state object | ||
121 | * @plane: plane to grab | ||
122 | * | ||
123 | * This function returns the plane state for the given plane, either from | ||
124 | * @state, or if the plane isn't part of the atomic state update, from @plane. | ||
125 | * This is useful in atomic check callbacks, when drivers need to peek at, but | ||
126 | * not change, state of other planes, since it avoids threading an error code | ||
127 | * back up the call chain. | ||
128 | * | ||
129 | * WARNING: | ||
130 | * | ||
131 | * Note that this function is in general unsafe since it doesn't check for the | ||
132 | * required locking for access state structures. Drivers must ensure that it is | ||
133 | * safe to access the returned state structure through other means. One common | ||
134 | * example is when planes are fixed to a single CRTC, and the driver knows that | ||
135 | * the CRTC lock is held already. In that case holding the CRTC lock gives a | ||
136 | * read-lock on all planes connected to that CRTC. But if planes can be | ||
137 | * reassigned things get more tricky. In that case it's better to use | ||
138 | * drm_atomic_get_plane_state and wire up full error handling. | ||
139 | * | ||
140 | * Returns: | ||
141 | * | ||
142 | * Read-only pointer to the current plane state. | ||
143 | */ | ||
144 | static inline const struct drm_plane_state * | ||
145 | __drm_atomic_get_current_plane_state(struct drm_atomic_state *state, | ||
146 | struct drm_plane *plane) | ||
147 | { | ||
148 | if (state->planes[drm_plane_index(plane)].state) | ||
149 | return state->planes[drm_plane_index(plane)].state; | ||
150 | |||
151 | return plane->state; | ||
110 | } | 152 | } |
111 | 153 | ||
112 | int __must_check | 154 | int __must_check |
@@ -139,29 +181,39 @@ int __must_check drm_atomic_check_only(struct drm_atomic_state *state); | |||
139 | int __must_check drm_atomic_commit(struct drm_atomic_state *state); | 181 | int __must_check drm_atomic_commit(struct drm_atomic_state *state); |
140 | int __must_check drm_atomic_nonblocking_commit(struct drm_atomic_state *state); | 182 | int __must_check drm_atomic_nonblocking_commit(struct drm_atomic_state *state); |
141 | 183 | ||
142 | #define for_each_connector_in_state(state, connector, connector_state, __i) \ | 184 | #define for_each_connector_in_state(__state, connector, connector_state, __i) \ |
143 | for ((__i) = 0; \ | 185 | for ((__i) = 0; \ |
144 | (__i) < (state)->num_connector && \ | 186 | (__i) < (__state)->num_connector && \ |
145 | ((connector) = (state)->connectors[__i], \ | 187 | ((connector) = (__state)->connectors[__i].ptr, \ |
146 | (connector_state) = (state)->connector_states[__i], 1); \ | 188 | (connector_state) = (__state)->connectors[__i].state, 1); \ |
147 | (__i)++) \ | 189 | (__i)++) \ |
148 | for_each_if (connector) | 190 | for_each_if (connector) |
149 | 191 | ||
150 | #define for_each_crtc_in_state(state, crtc, crtc_state, __i) \ | 192 | #define for_each_crtc_in_state(__state, crtc, crtc_state, __i) \ |
151 | for ((__i) = 0; \ | 193 | for ((__i) = 0; \ |
152 | (__i) < (state)->dev->mode_config.num_crtc && \ | 194 | (__i) < (__state)->dev->mode_config.num_crtc && \ |
153 | ((crtc) = (state)->crtcs[__i], \ | 195 | ((crtc) = (__state)->crtcs[__i].ptr, \ |
154 | (crtc_state) = (state)->crtc_states[__i], 1); \ | 196 | (crtc_state) = (__state)->crtcs[__i].state, 1); \ |
155 | (__i)++) \ | 197 | (__i)++) \ |
156 | for_each_if (crtc_state) | 198 | for_each_if (crtc_state) |
157 | 199 | ||
158 | #define for_each_plane_in_state(state, plane, plane_state, __i) \ | 200 | #define for_each_plane_in_state(__state, plane, plane_state, __i) \ |
159 | for ((__i) = 0; \ | 201 | for ((__i) = 0; \ |
160 | (__i) < (state)->dev->mode_config.num_total_plane && \ | 202 | (__i) < (__state)->dev->mode_config.num_total_plane && \ |
161 | ((plane) = (state)->planes[__i], \ | 203 | ((plane) = (__state)->planes[__i].ptr, \ |
162 | (plane_state) = (state)->plane_states[__i], 1); \ | 204 | (plane_state) = (__state)->planes[__i].state, 1); \ |
163 | (__i)++) \ | 205 | (__i)++) \ |
164 | for_each_if (plane_state) | 206 | for_each_if (plane_state) |
207 | |||
208 | /** | ||
209 | * drm_atomic_crtc_needs_modeset - compute combined modeset need | ||
210 | * @state: &drm_crtc_state for the CRTC | ||
211 | * | ||
212 | * To give drivers flexibility struct &drm_crtc_state has 3 booleans to track | ||
213 | * whether the state CRTC changed enough to need a full modeset cycle: | ||
214 | * connectors_changed, mode_changed and active_change. This helper simply | ||
215 | * combines these three to compute the overall need for a modeset for @state. | ||
216 | */ | ||
165 | static inline bool | 217 | static inline bool |
166 | drm_atomic_crtc_needs_modeset(struct drm_crtc_state *state) | 218 | drm_atomic_crtc_needs_modeset(struct drm_crtc_state *state) |
167 | { | 219 | { |
diff --git a/include/drm/drm_atomic_helper.h b/include/drm/drm_atomic_helper.h index d473dcc91f54..d86ae5dcd7b4 100644 --- a/include/drm/drm_atomic_helper.h +++ b/include/drm/drm_atomic_helper.h | |||
@@ -38,6 +38,7 @@ int drm_atomic_helper_check_planes(struct drm_device *dev, | |||
38 | struct drm_atomic_state *state); | 38 | struct drm_atomic_state *state); |
39 | int drm_atomic_helper_check(struct drm_device *dev, | 39 | int drm_atomic_helper_check(struct drm_device *dev, |
40 | struct drm_atomic_state *state); | 40 | struct drm_atomic_state *state); |
41 | void drm_atomic_helper_commit_tail(struct drm_atomic_state *state); | ||
41 | int drm_atomic_helper_commit(struct drm_device *dev, | 42 | int drm_atomic_helper_commit(struct drm_device *dev, |
42 | struct drm_atomic_state *state, | 43 | struct drm_atomic_state *state, |
43 | bool nonblock); | 44 | bool nonblock); |
@@ -71,8 +72,15 @@ void drm_atomic_helper_commit_planes_on_crtc(struct drm_crtc_state *old_crtc_sta | |||
71 | void drm_atomic_helper_disable_planes_on_crtc(struct drm_crtc *crtc, | 72 | void drm_atomic_helper_disable_planes_on_crtc(struct drm_crtc *crtc, |
72 | bool atomic); | 73 | bool atomic); |
73 | 74 | ||
74 | void drm_atomic_helper_swap_state(struct drm_device *dev, | 75 | void drm_atomic_helper_swap_state(struct drm_atomic_state *state, |
75 | struct drm_atomic_state *state); | 76 | bool stall); |
77 | |||
78 | /* nonblocking commit helpers */ | ||
79 | int drm_atomic_helper_setup_commit(struct drm_atomic_state *state, | ||
80 | bool nonblock); | ||
81 | void drm_atomic_helper_wait_for_dependencies(struct drm_atomic_state *state); | ||
82 | void drm_atomic_helper_commit_hw_done(struct drm_atomic_state *state); | ||
83 | void drm_atomic_helper_commit_cleanup_done(struct drm_atomic_state *state); | ||
76 | 84 | ||
77 | /* implementations for legacy interfaces */ | 85 | /* implementations for legacy interfaces */ |
78 | int drm_atomic_helper_update_plane(struct drm_plane *plane, | 86 | int drm_atomic_helper_update_plane(struct drm_plane *plane, |
@@ -147,9 +155,9 @@ void | |||
147 | __drm_atomic_helper_connector_destroy_state(struct drm_connector_state *state); | 155 | __drm_atomic_helper_connector_destroy_state(struct drm_connector_state *state); |
148 | void drm_atomic_helper_connector_destroy_state(struct drm_connector *connector, | 156 | void drm_atomic_helper_connector_destroy_state(struct drm_connector *connector, |
149 | struct drm_connector_state *state); | 157 | struct drm_connector_state *state); |
150 | void drm_atomic_helper_legacy_gamma_set(struct drm_crtc *crtc, | 158 | int drm_atomic_helper_legacy_gamma_set(struct drm_crtc *crtc, |
151 | u16 *red, u16 *green, u16 *blue, | 159 | u16 *red, u16 *green, u16 *blue, |
152 | uint32_t start, uint32_t size); | 160 | uint32_t size); |
153 | 161 | ||
154 | /** | 162 | /** |
155 | * drm_atomic_crtc_for_each_plane - iterate over planes currently attached to CRTC | 163 | * drm_atomic_crtc_for_each_plane - iterate over planes currently attached to CRTC |
@@ -159,7 +167,7 @@ void drm_atomic_helper_legacy_gamma_set(struct drm_crtc *crtc, | |||
159 | * This iterates over the current state, useful (for example) when applying | 167 | * This iterates over the current state, useful (for example) when applying |
160 | * atomic state after it has been checked and swapped. To iterate over the | 168 | * atomic state after it has been checked and swapped. To iterate over the |
161 | * planes which *will* be attached (for ->atomic_check()) see | 169 | * planes which *will* be attached (for ->atomic_check()) see |
162 | * drm_crtc_for_each_pending_plane() | 170 | * drm_atomic_crtc_state_for_each_plane(). |
163 | */ | 171 | */ |
164 | #define drm_atomic_crtc_for_each_plane(plane, crtc) \ | 172 | #define drm_atomic_crtc_for_each_plane(plane, crtc) \ |
165 | drm_for_each_plane_mask(plane, (crtc)->dev, (crtc)->state->plane_mask) | 173 | drm_for_each_plane_mask(plane, (crtc)->dev, (crtc)->state->plane_mask) |
@@ -171,11 +179,31 @@ void drm_atomic_helper_legacy_gamma_set(struct drm_crtc *crtc, | |||
171 | * | 179 | * |
172 | * Similar to drm_crtc_for_each_plane(), but iterates the planes that will be | 180 | * Similar to drm_crtc_for_each_plane(), but iterates the planes that will be |
173 | * attached if the specified state is applied. Useful during (for example) | 181 | * attached if the specified state is applied. Useful during (for example) |
174 | * ->atomic_check() operations, to validate the incoming state | 182 | * ->atomic_check() operations, to validate the incoming state. |
175 | */ | 183 | */ |
176 | #define drm_atomic_crtc_state_for_each_plane(plane, crtc_state) \ | 184 | #define drm_atomic_crtc_state_for_each_plane(plane, crtc_state) \ |
177 | drm_for_each_plane_mask(plane, (crtc_state)->state->dev, (crtc_state)->plane_mask) | 185 | drm_for_each_plane_mask(plane, (crtc_state)->state->dev, (crtc_state)->plane_mask) |
178 | 186 | ||
187 | /** | ||
188 | * drm_crtc_atomic_state_for_each_plane_state - iterate over attached planes in new state | ||
189 | * @plane: the loop cursor | ||
190 | * @plane_state: loop cursor for the plane's state, must be const | ||
191 | * @crtc_state: the incoming crtc-state | ||
192 | * | ||
193 | * Similar to drm_crtc_for_each_plane(), but iterates the planes that will be | ||
194 | * attached if the specified state is applied. Useful during (for example) | ||
195 | * ->atomic_check() operations, to validate the incoming state. | ||
196 | * | ||
197 | * Compared to just drm_atomic_crtc_state_for_each_plane() this also fills in a | ||
198 | * const plane_state. This is useful when a driver just wants to peek at other | ||
199 | * active planes on this crtc, but does not need to change it. | ||
200 | */ | ||
201 | #define drm_atomic_crtc_state_for_each_plane_state(plane, plane_state, crtc_state) \ | ||
202 | drm_for_each_plane_mask(plane, (crtc_state)->state->dev, (crtc_state)->plane_mask) \ | ||
203 | for_each_if ((plane_state = \ | ||
204 | __drm_atomic_get_current_plane_state((crtc_state)->state, \ | ||
205 | plane))) | ||
206 | |||
179 | /* | 207 | /* |
180 | * drm_atomic_plane_disabling - check whether a plane is being disabled | 208 | * drm_atomic_plane_disabling - check whether a plane is being disabled |
181 | * @plane: plane object | 209 | * @plane: plane object |
diff --git a/include/drm/drm_crtc.h b/include/drm/drm_crtc.h index d1559cd04e3d..914baa8c161d 100644 --- a/include/drm/drm_crtc.h +++ b/include/drm/drm_crtc.h | |||
@@ -253,6 +253,8 @@ struct drm_framebuffer { | |||
253 | int bits_per_pixel; | 253 | int bits_per_pixel; |
254 | int flags; | 254 | int flags; |
255 | uint32_t pixel_format; /* fourcc format */ | 255 | uint32_t pixel_format; /* fourcc format */ |
256 | int hot_x; | ||
257 | int hot_y; | ||
256 | struct list_head filp_head; | 258 | struct list_head filp_head; |
257 | }; | 259 | }; |
258 | 260 | ||
@@ -314,6 +316,7 @@ struct drm_plane_helper_funcs; | |||
314 | * update to ensure framebuffer cleanup isn't done too early | 316 | * update to ensure framebuffer cleanup isn't done too early |
315 | * @adjusted_mode: for use by helpers and drivers to compute adjusted mode timings | 317 | * @adjusted_mode: for use by helpers and drivers to compute adjusted mode timings |
316 | * @mode: current mode timings | 318 | * @mode: current mode timings |
319 | * @mode_blob: &drm_property_blob for @mode | ||
317 | * @degamma_lut: Lookup table for converting framebuffer pixel data | 320 | * @degamma_lut: Lookup table for converting framebuffer pixel data |
318 | * before apply the conversion matrix | 321 | * before apply the conversion matrix |
319 | * @ctm: Transformation matrix | 322 | * @ctm: Transformation matrix |
@@ -478,8 +481,8 @@ struct drm_crtc_funcs { | |||
478 | * going on, which should eventually be unified to just one set of | 481 | * going on, which should eventually be unified to just one set of |
479 | * hooks. | 482 | * hooks. |
480 | */ | 483 | */ |
481 | void (*gamma_set)(struct drm_crtc *crtc, u16 *r, u16 *g, u16 *b, | 484 | int (*gamma_set)(struct drm_crtc *crtc, u16 *r, u16 *g, u16 *b, |
482 | uint32_t start, uint32_t size); | 485 | uint32_t size); |
483 | 486 | ||
484 | /** | 487 | /** |
485 | * @destroy: | 488 | * @destroy: |
@@ -708,6 +711,7 @@ struct drm_crtc_funcs { | |||
708 | * @dev: parent DRM device | 711 | * @dev: parent DRM device |
709 | * @port: OF node used by drm_of_find_possible_crtcs() | 712 | * @port: OF node used by drm_of_find_possible_crtcs() |
710 | * @head: list management | 713 | * @head: list management |
714 | * @name: human readable name, can be overwritten by the driver | ||
711 | * @mutex: per-CRTC locking | 715 | * @mutex: per-CRTC locking |
712 | * @base: base KMS object for ID tracking etc. | 716 | * @base: base KMS object for ID tracking etc. |
713 | * @primary: primary plane for this CRTC | 717 | * @primary: primary plane for this CRTC |
@@ -724,9 +728,6 @@ struct drm_crtc_funcs { | |||
724 | * @gamma_store: gamma ramp values | 728 | * @gamma_store: gamma ramp values |
725 | * @helper_private: mid-layer private data | 729 | * @helper_private: mid-layer private data |
726 | * @properties: property tracking for this CRTC | 730 | * @properties: property tracking for this CRTC |
727 | * @state: current atomic state for this CRTC | ||
728 | * @acquire_ctx: per-CRTC implicit acquire context used by atomic drivers for | ||
729 | * legacy IOCTLs | ||
730 | * | 731 | * |
731 | * Each CRTC may have one or more connectors associated with it. This structure | 732 | * Each CRTC may have one or more connectors associated with it. This structure |
732 | * allows the CRTC to be controlled. | 733 | * allows the CRTC to be controlled. |
@@ -738,12 +739,13 @@ struct drm_crtc { | |||
738 | 739 | ||
739 | char *name; | 740 | char *name; |
740 | 741 | ||
741 | /* | 742 | /** |
742 | * crtc mutex | 743 | * @mutex: |
743 | * | 744 | * |
744 | * This provides a read lock for the overall crtc state (mode, dpms | 745 | * This provides a read lock for the overall crtc state (mode, dpms |
745 | * state, ...) and a write lock for everything which can be update | 746 | * state, ...) and a write lock for everything which can be update |
746 | * without a full modeset (fb, cursor data, ...) | 747 | * without a full modeset (fb, cursor data, crtc properties ...). Full |
748 | * modeset also need to grab dev->mode_config.connection_mutex. | ||
747 | */ | 749 | */ |
748 | struct drm_modeset_lock mutex; | 750 | struct drm_modeset_lock mutex; |
749 | 751 | ||
@@ -753,6 +755,9 @@ struct drm_crtc { | |||
753 | struct drm_plane *primary; | 755 | struct drm_plane *primary; |
754 | struct drm_plane *cursor; | 756 | struct drm_plane *cursor; |
755 | 757 | ||
758 | /* position inside the mode_config.list, can be used as a [] idx */ | ||
759 | unsigned index; | ||
760 | |||
756 | /* position of cursor plane on crtc */ | 761 | /* position of cursor plane on crtc */ |
757 | int cursor_x; | 762 | int cursor_x; |
758 | int cursor_y; | 763 | int cursor_y; |
@@ -779,11 +784,37 @@ struct drm_crtc { | |||
779 | 784 | ||
780 | struct drm_object_properties properties; | 785 | struct drm_object_properties properties; |
781 | 786 | ||
787 | /** | ||
788 | * @state: | ||
789 | * | ||
790 | * Current atomic state for this CRTC. | ||
791 | */ | ||
782 | struct drm_crtc_state *state; | 792 | struct drm_crtc_state *state; |
783 | 793 | ||
784 | /* | 794 | /** |
785 | * For legacy crtc IOCTLs so that atomic drivers can get at the locking | 795 | * @commit_list: |
786 | * acquire context. | 796 | * |
797 | * List of &drm_crtc_commit structures tracking pending commits. | ||
798 | * Protected by @commit_lock. This list doesn't hold its own full | ||
799 | * reference, but burrows it from the ongoing commit. Commit entries | ||
800 | * must be removed from this list once the commit is fully completed, | ||
801 | * but before it's correspoding &drm_atomic_state gets destroyed. | ||
802 | */ | ||
803 | struct list_head commit_list; | ||
804 | |||
805 | /** | ||
806 | * @commit_lock: | ||
807 | * | ||
808 | * Spinlock to protect @commit_list. | ||
809 | */ | ||
810 | spinlock_t commit_lock; | ||
811 | |||
812 | /** | ||
813 | * @acquire_ctx: | ||
814 | * | ||
815 | * Per-CRTC implicit acquire context used by atomic drivers for legacy | ||
816 | * IOCTLs, so that atomic drivers can get at the locking acquire | ||
817 | * context. | ||
787 | */ | 818 | */ |
788 | struct drm_modeset_acquire_ctx *acquire_ctx; | 819 | struct drm_modeset_acquire_ctx *acquire_ctx; |
789 | }; | 820 | }; |
@@ -1078,7 +1109,7 @@ struct drm_encoder_funcs { | |||
1078 | * @dev: parent DRM device | 1109 | * @dev: parent DRM device |
1079 | * @head: list management | 1110 | * @head: list management |
1080 | * @base: base KMS object | 1111 | * @base: base KMS object |
1081 | * @name: encoder name | 1112 | * @name: human readable name, can be overwritten by the driver |
1082 | * @encoder_type: one of the %DRM_MODE_ENCODER_<foo> types in drm_mode.h | 1113 | * @encoder_type: one of the %DRM_MODE_ENCODER_<foo> types in drm_mode.h |
1083 | * @possible_crtcs: bitmask of potential CRTC bindings | 1114 | * @possible_crtcs: bitmask of potential CRTC bindings |
1084 | * @possible_clones: bitmask of potential sibling encoders for cloning | 1115 | * @possible_clones: bitmask of potential sibling encoders for cloning |
@@ -1097,6 +1128,10 @@ struct drm_encoder { | |||
1097 | struct drm_mode_object base; | 1128 | struct drm_mode_object base; |
1098 | char *name; | 1129 | char *name; |
1099 | int encoder_type; | 1130 | int encoder_type; |
1131 | |||
1132 | /* position inside the mode_config.list, can be used as a [] idx */ | ||
1133 | unsigned index; | ||
1134 | |||
1100 | uint32_t possible_crtcs; | 1135 | uint32_t possible_crtcs; |
1101 | uint32_t possible_clones; | 1136 | uint32_t possible_clones; |
1102 | 1137 | ||
@@ -1124,7 +1159,8 @@ struct drm_encoder { | |||
1124 | * @attr: sysfs attributes | 1159 | * @attr: sysfs attributes |
1125 | * @head: list management | 1160 | * @head: list management |
1126 | * @base: base KMS object | 1161 | * @base: base KMS object |
1127 | * @name: connector name | 1162 | * @name: human readable name, can be overwritten by the driver |
1163 | * @connector_id: compacted connector id useful indexing arrays | ||
1128 | * @connector_type: one of the %DRM_MODE_CONNECTOR_<foo> types from drm_mode.h | 1164 | * @connector_type: one of the %DRM_MODE_CONNECTOR_<foo> types from drm_mode.h |
1129 | * @connector_type_id: index into connector type enum | 1165 | * @connector_type_id: index into connector type enum |
1130 | * @interlace_allowed: can this connector handle interlaced modes? | 1166 | * @interlace_allowed: can this connector handle interlaced modes? |
@@ -1137,7 +1173,6 @@ struct drm_encoder { | |||
1137 | * @funcs: connector control functions | 1173 | * @funcs: connector control functions |
1138 | * @edid_blob_ptr: DRM property containing EDID if present | 1174 | * @edid_blob_ptr: DRM property containing EDID if present |
1139 | * @properties: property tracking for this connector | 1175 | * @properties: property tracking for this connector |
1140 | * @path_blob_ptr: DRM blob property data for the DP MST path property | ||
1141 | * @polled: a %DRM_CONNECTOR_POLL_<foo> value for core driven polling | 1176 | * @polled: a %DRM_CONNECTOR_POLL_<foo> value for core driven polling |
1142 | * @dpms: current dpms state | 1177 | * @dpms: current dpms state |
1143 | * @helper_private: mid-layer private data | 1178 | * @helper_private: mid-layer private data |
@@ -1200,8 +1235,23 @@ struct drm_connector { | |||
1200 | struct drm_property_blob *edid_blob_ptr; | 1235 | struct drm_property_blob *edid_blob_ptr; |
1201 | struct drm_object_properties properties; | 1236 | struct drm_object_properties properties; |
1202 | 1237 | ||
1238 | /** | ||
1239 | * @path_blob_ptr: | ||
1240 | * | ||
1241 | * DRM blob property data for the DP MST path property. | ||
1242 | */ | ||
1203 | struct drm_property_blob *path_blob_ptr; | 1243 | struct drm_property_blob *path_blob_ptr; |
1204 | 1244 | ||
1245 | /** | ||
1246 | * @tile_blob_ptr: | ||
1247 | * | ||
1248 | * DRM blob property data for the tile property (used mostly by DP MST). | ||
1249 | * This is meant for screens which are driven through separate display | ||
1250 | * pipelines represented by &drm_crtc, which might not be running with | ||
1251 | * genlocked clocks. For tiled panels which are genlocked, like | ||
1252 | * dual-link LVDS or dual-link DSI, the driver should try to not expose | ||
1253 | * the tiling and virtualize both &drm_crtc and &drm_plane if needed. | ||
1254 | */ | ||
1205 | struct drm_property_blob *tile_blob_ptr; | 1255 | struct drm_property_blob *tile_blob_ptr; |
1206 | 1256 | ||
1207 | uint8_t polled; /* DRM_CONNECTOR_POLL_* */ | 1257 | uint8_t polled; /* DRM_CONNECTOR_POLL_* */ |
@@ -1263,6 +1313,7 @@ struct drm_connector { | |||
1263 | * plane (in 16.16) | 1313 | * plane (in 16.16) |
1264 | * @src_w: width of visible portion of plane (in 16.16) | 1314 | * @src_w: width of visible portion of plane (in 16.16) |
1265 | * @src_h: height of visible portion of plane (in 16.16) | 1315 | * @src_h: height of visible portion of plane (in 16.16) |
1316 | * @rotation: rotation of the plane | ||
1266 | * @state: backpointer to global drm_atomic_state | 1317 | * @state: backpointer to global drm_atomic_state |
1267 | */ | 1318 | */ |
1268 | struct drm_plane_state { | 1319 | struct drm_plane_state { |
@@ -1503,6 +1554,7 @@ enum drm_plane_type { | |||
1503 | * struct drm_plane - central DRM plane control structure | 1554 | * struct drm_plane - central DRM plane control structure |
1504 | * @dev: DRM device this plane belongs to | 1555 | * @dev: DRM device this plane belongs to |
1505 | * @head: for list management | 1556 | * @head: for list management |
1557 | * @name: human readable name, can be overwritten by the driver | ||
1506 | * @base: base mode object | 1558 | * @base: base mode object |
1507 | * @possible_crtcs: pipes this plane can be bound to | 1559 | * @possible_crtcs: pipes this plane can be bound to |
1508 | * @format_types: array of formats supported by this plane | 1560 | * @format_types: array of formats supported by this plane |
@@ -1516,6 +1568,7 @@ enum drm_plane_type { | |||
1516 | * @properties: property tracking for this plane | 1568 | * @properties: property tracking for this plane |
1517 | * @type: type of plane (overlay, primary, cursor) | 1569 | * @type: type of plane (overlay, primary, cursor) |
1518 | * @state: current atomic state for this plane | 1570 | * @state: current atomic state for this plane |
1571 | * @helper_private: mid-layer private data | ||
1519 | */ | 1572 | */ |
1520 | struct drm_plane { | 1573 | struct drm_plane { |
1521 | struct drm_device *dev; | 1574 | struct drm_device *dev; |
@@ -1523,6 +1576,13 @@ struct drm_plane { | |||
1523 | 1576 | ||
1524 | char *name; | 1577 | char *name; |
1525 | 1578 | ||
1579 | /** | ||
1580 | * @mutex: | ||
1581 | * | ||
1582 | * Protects modeset plane state, together with the mutex of &drm_crtc | ||
1583 | * this plane is linked to (when active, getting actived or getting | ||
1584 | * disabled). | ||
1585 | */ | ||
1526 | struct drm_modeset_lock mutex; | 1586 | struct drm_modeset_lock mutex; |
1527 | 1587 | ||
1528 | struct drm_mode_object base; | 1588 | struct drm_mode_object base; |
@@ -1543,6 +1603,9 @@ struct drm_plane { | |||
1543 | 1603 | ||
1544 | enum drm_plane_type type; | 1604 | enum drm_plane_type type; |
1545 | 1605 | ||
1606 | /* position inside the mode_config.list, can be used as a [] idx */ | ||
1607 | unsigned index; | ||
1608 | |||
1546 | const struct drm_plane_helper_funcs *helper_private; | 1609 | const struct drm_plane_helper_funcs *helper_private; |
1547 | 1610 | ||
1548 | struct drm_plane_state *state; | 1611 | struct drm_plane_state *state; |
@@ -1694,18 +1757,136 @@ struct drm_bridge { | |||
1694 | }; | 1757 | }; |
1695 | 1758 | ||
1696 | /** | 1759 | /** |
1760 | * struct drm_crtc_commit - track modeset commits on a CRTC | ||
1761 | * | ||
1762 | * This structure is used to track pending modeset changes and atomic commit on | ||
1763 | * a per-CRTC basis. Since updating the list should never block this structure | ||
1764 | * is reference counted to allow waiters to safely wait on an event to complete, | ||
1765 | * without holding any locks. | ||
1766 | * | ||
1767 | * It has 3 different events in total to allow a fine-grained synchronization | ||
1768 | * between outstanding updates:: | ||
1769 | * | ||
1770 | * atomic commit thread hardware | ||
1771 | * | ||
1772 | * write new state into hardware ----> ... | ||
1773 | * signal hw_done | ||
1774 | * switch to new state on next | ||
1775 | * ... v/hblank | ||
1776 | * | ||
1777 | * wait for buffers to show up ... | ||
1778 | * | ||
1779 | * ... send completion irq | ||
1780 | * irq handler signals flip_done | ||
1781 | * cleanup old buffers | ||
1782 | * | ||
1783 | * signal cleanup_done | ||
1784 | * | ||
1785 | * wait for flip_done <---- | ||
1786 | * clean up atomic state | ||
1787 | * | ||
1788 | * The important bit to know is that cleanup_done is the terminal event, but the | ||
1789 | * ordering between flip_done and hw_done is entirely up to the specific driver | ||
1790 | * and modeset state change. | ||
1791 | * | ||
1792 | * For an implementation of how to use this look at | ||
1793 | * drm_atomic_helper_setup_commit() from the atomic helper library. | ||
1794 | */ | ||
1795 | struct drm_crtc_commit { | ||
1796 | /** | ||
1797 | * @crtc: | ||
1798 | * | ||
1799 | * DRM CRTC for this commit. | ||
1800 | */ | ||
1801 | struct drm_crtc *crtc; | ||
1802 | |||
1803 | /** | ||
1804 | * @ref: | ||
1805 | * | ||
1806 | * Reference count for this structure. Needed to allow blocking on | ||
1807 | * completions without the risk of the completion disappearing | ||
1808 | * meanwhile. | ||
1809 | */ | ||
1810 | struct kref ref; | ||
1811 | |||
1812 | /** | ||
1813 | * @flip_done: | ||
1814 | * | ||
1815 | * Will be signaled when the hardware has flipped to the new set of | ||
1816 | * buffers. Signals at the same time as when the drm event for this | ||
1817 | * commit is sent to userspace, or when an out-fence is singalled. Note | ||
1818 | * that for most hardware, in most cases this happens after @hw_done is | ||
1819 | * signalled. | ||
1820 | */ | ||
1821 | struct completion flip_done; | ||
1822 | |||
1823 | /** | ||
1824 | * @hw_done: | ||
1825 | * | ||
1826 | * Will be signalled when all hw register changes for this commit have | ||
1827 | * been written out. Especially when disabling a pipe this can be much | ||
1828 | * later than than @flip_done, since that can signal already when the | ||
1829 | * screen goes black, whereas to fully shut down a pipe more register | ||
1830 | * I/O is required. | ||
1831 | * | ||
1832 | * Note that this does not need to include separately reference-counted | ||
1833 | * resources like backing storage buffer pinning, or runtime pm | ||
1834 | * management. | ||
1835 | */ | ||
1836 | struct completion hw_done; | ||
1837 | |||
1838 | /** | ||
1839 | * @cleanup_done: | ||
1840 | * | ||
1841 | * Will be signalled after old buffers have been cleaned up by calling | ||
1842 | * drm_atomic_helper_cleanup_planes(). Since this can only happen after | ||
1843 | * a vblank wait completed it might be a bit later. This completion is | ||
1844 | * useful to throttle updates and avoid hardware updates getting ahead | ||
1845 | * of the buffer cleanup too much. | ||
1846 | */ | ||
1847 | struct completion cleanup_done; | ||
1848 | |||
1849 | /** | ||
1850 | * @commit_entry: | ||
1851 | * | ||
1852 | * Entry on the per-CRTC commit_list. Protected by crtc->commit_lock. | ||
1853 | */ | ||
1854 | struct list_head commit_entry; | ||
1855 | |||
1856 | /** | ||
1857 | * @event: | ||
1858 | * | ||
1859 | * &drm_pending_vblank_event pointer to clean up private events. | ||
1860 | */ | ||
1861 | struct drm_pending_vblank_event *event; | ||
1862 | }; | ||
1863 | |||
1864 | struct __drm_planes_state { | ||
1865 | struct drm_plane *ptr; | ||
1866 | struct drm_plane_state *state; | ||
1867 | }; | ||
1868 | |||
1869 | struct __drm_crtcs_state { | ||
1870 | struct drm_crtc *ptr; | ||
1871 | struct drm_crtc_state *state; | ||
1872 | struct drm_crtc_commit *commit; | ||
1873 | }; | ||
1874 | |||
1875 | struct __drm_connnectors_state { | ||
1876 | struct drm_connector *ptr; | ||
1877 | struct drm_connector_state *state; | ||
1878 | }; | ||
1879 | |||
1880 | /** | ||
1697 | * struct drm_atomic_state - the global state object for atomic updates | 1881 | * struct drm_atomic_state - the global state object for atomic updates |
1698 | * @dev: parent DRM device | 1882 | * @dev: parent DRM device |
1699 | * @allow_modeset: allow full modeset | 1883 | * @allow_modeset: allow full modeset |
1700 | * @legacy_cursor_update: hint to enforce legacy cursor IOCTL semantics | 1884 | * @legacy_cursor_update: hint to enforce legacy cursor IOCTL semantics |
1701 | * @legacy_set_config: Disable conflicting encoders instead of failing with -EINVAL. | 1885 | * @legacy_set_config: Disable conflicting encoders instead of failing with -EINVAL. |
1702 | * @planes: pointer to array of plane pointers | 1886 | * @planes: pointer to array of structures with per-plane data |
1703 | * @plane_states: pointer to array of plane states pointers | ||
1704 | * @crtcs: pointer to array of CRTC pointers | 1887 | * @crtcs: pointer to array of CRTC pointers |
1705 | * @crtc_states: pointer to array of CRTC states pointers | ||
1706 | * @num_connector: size of the @connectors and @connector_states arrays | 1888 | * @num_connector: size of the @connectors and @connector_states arrays |
1707 | * @connectors: pointer to array of connector pointers | 1889 | * @connectors: pointer to array of structures with per-connector data |
1708 | * @connector_states: pointer to array of connector states pointers | ||
1709 | * @acquire_ctx: acquire context for this atomic modeset state update | 1890 | * @acquire_ctx: acquire context for this atomic modeset state update |
1710 | */ | 1891 | */ |
1711 | struct drm_atomic_state { | 1892 | struct drm_atomic_state { |
@@ -1713,15 +1894,20 @@ struct drm_atomic_state { | |||
1713 | bool allow_modeset : 1; | 1894 | bool allow_modeset : 1; |
1714 | bool legacy_cursor_update : 1; | 1895 | bool legacy_cursor_update : 1; |
1715 | bool legacy_set_config : 1; | 1896 | bool legacy_set_config : 1; |
1716 | struct drm_plane **planes; | 1897 | struct __drm_planes_state *planes; |
1717 | struct drm_plane_state **plane_states; | 1898 | struct __drm_crtcs_state *crtcs; |
1718 | struct drm_crtc **crtcs; | ||
1719 | struct drm_crtc_state **crtc_states; | ||
1720 | int num_connector; | 1899 | int num_connector; |
1721 | struct drm_connector **connectors; | 1900 | struct __drm_connnectors_state *connectors; |
1722 | struct drm_connector_state **connector_states; | ||
1723 | 1901 | ||
1724 | struct drm_modeset_acquire_ctx *acquire_ctx; | 1902 | struct drm_modeset_acquire_ctx *acquire_ctx; |
1903 | |||
1904 | /** | ||
1905 | * @commit_work: | ||
1906 | * | ||
1907 | * Work item which can be used by the driver or helpers to execute the | ||
1908 | * commit without blocking. | ||
1909 | */ | ||
1910 | struct work_struct commit_work; | ||
1725 | }; | 1911 | }; |
1726 | 1912 | ||
1727 | 1913 | ||
@@ -2022,8 +2208,6 @@ struct drm_mode_config_funcs { | |||
2022 | * @connection_mutex: ww mutex protecting connector state and routing | 2208 | * @connection_mutex: ww mutex protecting connector state and routing |
2023 | * @acquire_ctx: global implicit acquire context used by atomic drivers for | 2209 | * @acquire_ctx: global implicit acquire context used by atomic drivers for |
2024 | * legacy IOCTLs | 2210 | * legacy IOCTLs |
2025 | * @idr_mutex: mutex for KMS ID allocation and management | ||
2026 | * @crtc_idr: main KMS ID tracking object | ||
2027 | * @fb_lock: mutex to protect fb state and lists | 2211 | * @fb_lock: mutex to protect fb state and lists |
2028 | * @num_fb: number of fbs available | 2212 | * @num_fb: number of fbs available |
2029 | * @fb_list: list of framebuffers available | 2213 | * @fb_list: list of framebuffers available |
@@ -2045,6 +2229,7 @@ struct drm_mode_config_funcs { | |||
2045 | * @fb_base: base address of the framebuffer | 2229 | * @fb_base: base address of the framebuffer |
2046 | * @poll_enabled: track polling support for this device | 2230 | * @poll_enabled: track polling support for this device |
2047 | * @poll_running: track polling status for this device | 2231 | * @poll_running: track polling status for this device |
2232 | * @delayed_event: track delayed poll uevent deliver for this device | ||
2048 | * @output_poll_work: delayed work for polling in process context | 2233 | * @output_poll_work: delayed work for polling in process context |
2049 | * @property_blob_list: list of all the blob property objects | 2234 | * @property_blob_list: list of all the blob property objects |
2050 | * @blob_lock: mutex for blob property allocation and management | 2235 | * @blob_lock: mutex for blob property allocation and management |
@@ -2063,6 +2248,7 @@ struct drm_mode_config_funcs { | |||
2063 | * @async_page_flip: does this device support async flips on the primary plane? | 2248 | * @async_page_flip: does this device support async flips on the primary plane? |
2064 | * @cursor_width: hint to userspace for max cursor width | 2249 | * @cursor_width: hint to userspace for max cursor width |
2065 | * @cursor_height: hint to userspace for max cursor height | 2250 | * @cursor_height: hint to userspace for max cursor height |
2251 | * @helper_private: mid-layer private data | ||
2066 | * | 2252 | * |
2067 | * Core mode resource tracking structure. All CRTC, encoders, and connectors | 2253 | * Core mode resource tracking structure. All CRTC, encoders, and connectors |
2068 | * enumerated by the driver are added here, as are global properties. Some | 2254 | * enumerated by the driver are added here, as are global properties. Some |
@@ -2072,10 +2258,30 @@ struct drm_mode_config { | |||
2072 | struct mutex mutex; /* protects configuration (mode lists etc.) */ | 2258 | struct mutex mutex; /* protects configuration (mode lists etc.) */ |
2073 | struct drm_modeset_lock connection_mutex; /* protects connector->encoder and encoder->crtc links */ | 2259 | struct drm_modeset_lock connection_mutex; /* protects connector->encoder and encoder->crtc links */ |
2074 | struct drm_modeset_acquire_ctx *acquire_ctx; /* for legacy _lock_all() / _unlock_all() */ | 2260 | struct drm_modeset_acquire_ctx *acquire_ctx; /* for legacy _lock_all() / _unlock_all() */ |
2075 | struct mutex idr_mutex; /* for IDR management */ | 2261 | |
2076 | struct idr crtc_idr; /* use this idr for all IDs, fb, crtc, connector, modes - just makes life easier */ | 2262 | /** |
2077 | struct idr tile_idr; /* use this idr for all IDs, fb, crtc, connector, modes - just makes life easier */ | 2263 | * @idr_mutex: |
2078 | /* this is limited to one for now */ | 2264 | * |
2265 | * Mutex for KMS ID allocation and management. Protects both @crtc_idr | ||
2266 | * and @tile_idr. | ||
2267 | */ | ||
2268 | struct mutex idr_mutex; | ||
2269 | |||
2270 | /** | ||
2271 | * @crtc_idr: | ||
2272 | * | ||
2273 | * Main KMS ID tracking object. Use this idr for all IDs, fb, crtc, | ||
2274 | * connector, modes - just makes life easier to have only one. | ||
2275 | */ | ||
2276 | struct idr crtc_idr; | ||
2277 | |||
2278 | /** | ||
2279 | * @tile_idr: | ||
2280 | * | ||
2281 | * Use this idr for allocating new IDs for tiled sinks like use in some | ||
2282 | * high-res DP MST screens. | ||
2283 | */ | ||
2284 | struct idr tile_idr; | ||
2079 | 2285 | ||
2080 | struct mutex fb_lock; /* proctects global and per-file fb lists */ | 2286 | struct mutex fb_lock; /* proctects global and per-file fb lists */ |
2081 | int num_fb; | 2287 | int num_fb; |
@@ -2177,11 +2383,17 @@ struct drm_mode_config { | |||
2177 | /* whether async page flip is supported or not */ | 2383 | /* whether async page flip is supported or not */ |
2178 | bool async_page_flip; | 2384 | bool async_page_flip; |
2179 | 2385 | ||
2180 | /* whether the driver supports fb modifiers */ | 2386 | /** |
2387 | * @allow_fb_modifiers: | ||
2388 | * | ||
2389 | * Whether the driver supports fb modifiers in the ADDFB2.1 ioctl call. | ||
2390 | */ | ||
2181 | bool allow_fb_modifiers; | 2391 | bool allow_fb_modifiers; |
2182 | 2392 | ||
2183 | /* cursor size */ | 2393 | /* cursor size */ |
2184 | uint32_t cursor_width, cursor_height; | 2394 | uint32_t cursor_width, cursor_height; |
2395 | |||
2396 | struct drm_mode_config_helper_funcs *helper_private; | ||
2185 | }; | 2397 | }; |
2186 | 2398 | ||
2187 | /** | 2399 | /** |
@@ -2230,7 +2442,18 @@ int drm_crtc_init_with_planes(struct drm_device *dev, | |||
2230 | const struct drm_crtc_funcs *funcs, | 2442 | const struct drm_crtc_funcs *funcs, |
2231 | const char *name, ...); | 2443 | const char *name, ...); |
2232 | extern void drm_crtc_cleanup(struct drm_crtc *crtc); | 2444 | extern void drm_crtc_cleanup(struct drm_crtc *crtc); |
2233 | extern unsigned int drm_crtc_index(struct drm_crtc *crtc); | 2445 | |
2446 | /** | ||
2447 | * drm_crtc_index - find the index of a registered CRTC | ||
2448 | * @crtc: CRTC to find index for | ||
2449 | * | ||
2450 | * Given a registered CRTC, return the index of that CRTC within a DRM | ||
2451 | * device's list of CRTCs. | ||
2452 | */ | ||
2453 | static inline unsigned int drm_crtc_index(struct drm_crtc *crtc) | ||
2454 | { | ||
2455 | return crtc->index; | ||
2456 | } | ||
2234 | 2457 | ||
2235 | /** | 2458 | /** |
2236 | * drm_crtc_mask - find the mask of a registered CRTC | 2459 | * drm_crtc_mask - find the mask of a registered CRTC |
@@ -2284,7 +2507,18 @@ int drm_encoder_init(struct drm_device *dev, | |||
2284 | struct drm_encoder *encoder, | 2507 | struct drm_encoder *encoder, |
2285 | const struct drm_encoder_funcs *funcs, | 2508 | const struct drm_encoder_funcs *funcs, |
2286 | int encoder_type, const char *name, ...); | 2509 | int encoder_type, const char *name, ...); |
2287 | extern unsigned int drm_encoder_index(struct drm_encoder *encoder); | 2510 | |
2511 | /** | ||
2512 | * drm_encoder_index - find the index of a registered encoder | ||
2513 | * @encoder: encoder to find index for | ||
2514 | * | ||
2515 | * Given a registered encoder, return the index of that encoder within a DRM | ||
2516 | * device's list of encoders. | ||
2517 | */ | ||
2518 | static inline unsigned int drm_encoder_index(struct drm_encoder *encoder) | ||
2519 | { | ||
2520 | return encoder->index; | ||
2521 | } | ||
2288 | 2522 | ||
2289 | /** | 2523 | /** |
2290 | * drm_encoder_crtc_ok - can a given crtc drive a given encoder? | 2524 | * drm_encoder_crtc_ok - can a given crtc drive a given encoder? |
@@ -2315,7 +2549,18 @@ extern int drm_plane_init(struct drm_device *dev, | |||
2315 | const uint32_t *formats, unsigned int format_count, | 2549 | const uint32_t *formats, unsigned int format_count, |
2316 | bool is_primary); | 2550 | bool is_primary); |
2317 | extern void drm_plane_cleanup(struct drm_plane *plane); | 2551 | extern void drm_plane_cleanup(struct drm_plane *plane); |
2318 | extern unsigned int drm_plane_index(struct drm_plane *plane); | 2552 | |
2553 | /** | ||
2554 | * drm_plane_index - find the index of a registered plane | ||
2555 | * @plane: plane to find index for | ||
2556 | * | ||
2557 | * Given a registered plane, return the index of that plane within a DRM | ||
2558 | * device's list of planes. | ||
2559 | */ | ||
2560 | static inline unsigned int drm_plane_index(struct drm_plane *plane) | ||
2561 | { | ||
2562 | return plane->index; | ||
2563 | } | ||
2319 | extern struct drm_plane * drm_plane_from_index(struct drm_device *dev, int idx); | 2564 | extern struct drm_plane * drm_plane_from_index(struct drm_device *dev, int idx); |
2320 | extern void drm_plane_force_disable(struct drm_plane *plane); | 2565 | extern void drm_plane_force_disable(struct drm_plane *plane); |
2321 | extern int drm_plane_check_pixel_format(const struct drm_plane *plane, | 2566 | extern int drm_plane_check_pixel_format(const struct drm_plane *plane, |
@@ -2540,20 +2785,14 @@ extern int drm_mode_plane_set_obj_prop(struct drm_plane *plane, | |||
2540 | extern int drm_mode_atomic_ioctl(struct drm_device *dev, | 2785 | extern int drm_mode_atomic_ioctl(struct drm_device *dev, |
2541 | void *data, struct drm_file *file_priv); | 2786 | void *data, struct drm_file *file_priv); |
2542 | 2787 | ||
2543 | extern void drm_fb_get_bpp_depth(uint32_t format, unsigned int *depth, | ||
2544 | int *bpp); | ||
2545 | extern int drm_format_num_planes(uint32_t format); | ||
2546 | extern int drm_format_plane_cpp(uint32_t format, int plane); | ||
2547 | extern int drm_format_horz_chroma_subsampling(uint32_t format); | ||
2548 | extern int drm_format_vert_chroma_subsampling(uint32_t format); | ||
2549 | extern int drm_format_plane_width(int width, uint32_t format, int plane); | ||
2550 | extern int drm_format_plane_height(int height, uint32_t format, int plane); | ||
2551 | extern const char *drm_get_format_name(uint32_t format); | ||
2552 | extern struct drm_property *drm_mode_create_rotation_property(struct drm_device *dev, | 2788 | extern struct drm_property *drm_mode_create_rotation_property(struct drm_device *dev, |
2553 | unsigned int supported_rotations); | 2789 | unsigned int supported_rotations); |
2554 | extern unsigned int drm_rotation_simplify(unsigned int rotation, | 2790 | extern unsigned int drm_rotation_simplify(unsigned int rotation, |
2555 | unsigned int supported_rotations); | 2791 | unsigned int supported_rotations); |
2556 | 2792 | extern void drm_crtc_enable_color_mgmt(struct drm_crtc *crtc, | |
2793 | uint degamma_lut_size, | ||
2794 | bool has_ctm, | ||
2795 | uint gamma_lut_size); | ||
2557 | /* Helpers */ | 2796 | /* Helpers */ |
2558 | 2797 | ||
2559 | static inline struct drm_plane *drm_plane_find(struct drm_device *dev, | 2798 | static inline struct drm_plane *drm_plane_find(struct drm_device *dev, |
diff --git a/include/drm/drm_crtc_helper.h b/include/drm/drm_crtc_helper.h index 97fa894d4ee2..4b37afa2b73b 100644 --- a/include/drm/drm_crtc_helper.h +++ b/include/drm/drm_crtc_helper.h | |||
@@ -48,9 +48,6 @@ extern bool drm_crtc_helper_set_mode(struct drm_crtc *crtc, | |||
48 | struct drm_display_mode *mode, | 48 | struct drm_display_mode *mode, |
49 | int x, int y, | 49 | int x, int y, |
50 | struct drm_framebuffer *old_fb); | 50 | struct drm_framebuffer *old_fb); |
51 | extern void drm_helper_crtc_enable_color_mgmt(struct drm_crtc *crtc, | ||
52 | int degamma_lut_size, | ||
53 | int gamma_lut_size); | ||
54 | extern bool drm_helper_crtc_in_use(struct drm_crtc *crtc); | 51 | extern bool drm_helper_crtc_in_use(struct drm_crtc *crtc); |
55 | extern bool drm_helper_encoder_in_use(struct drm_encoder *encoder); | 52 | extern bool drm_helper_encoder_in_use(struct drm_encoder *encoder); |
56 | 53 | ||
diff --git a/include/drm/drm_fb_helper.h b/include/drm/drm_fb_helper.h index 5b4aa35026a3..db8d4780eaa2 100644 --- a/include/drm/drm_fb_helper.h +++ b/include/drm/drm_fb_helper.h | |||
@@ -212,17 +212,6 @@ struct drm_fb_helper { | |||
212 | * needs to be reprobe when fbdev is in control again. | 212 | * needs to be reprobe when fbdev is in control again. |
213 | */ | 213 | */ |
214 | bool delayed_hotplug; | 214 | bool delayed_hotplug; |
215 | |||
216 | /** | ||
217 | * @atomic: | ||
218 | * | ||
219 | * Use atomic updates for restore_fbdev_mode(), etc. This defaults to | ||
220 | * true if driver has DRIVER_ATOMIC feature flag, but drivers can | ||
221 | * override it to true after drm_fb_helper_init() if they support atomic | ||
222 | * modeset but do not yet advertise DRIVER_ATOMIC (note that fb-helper | ||
223 | * does not require ASYNC commits). | ||
224 | */ | ||
225 | bool atomic; | ||
226 | }; | 215 | }; |
227 | 216 | ||
228 | #ifdef CONFIG_DRM_FBDEV_EMULATION | 217 | #ifdef CONFIG_DRM_FBDEV_EMULATION |
diff --git a/include/drm/drm_fourcc.h b/include/drm/drm_fourcc.h new file mode 100644 index 000000000000..7f90a396cf2b --- /dev/null +++ b/include/drm/drm_fourcc.h | |||
@@ -0,0 +1,37 @@ | |||
1 | /* | ||
2 | * Copyright (c) 2016 Laurent Pinchart <laurent.pinchart@ideasonboard.com> | ||
3 | * | ||
4 | * Permission to use, copy, modify, distribute, and sell this software and its | ||
5 | * documentation for any purpose is hereby granted without fee, provided that | ||
6 | * the above copyright notice appear in all copies and that both that copyright | ||
7 | * notice and this permission notice appear in supporting documentation, and | ||
8 | * that the name of the copyright holders not be used in advertising or | ||
9 | * publicity pertaining to distribution of the software without specific, | ||
10 | * written prior permission. The copyright holders make no representations | ||
11 | * about the suitability of this software for any purpose. It is provided "as | ||
12 | * is" without express or implied warranty. | ||
13 | * | ||
14 | * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, | ||
15 | * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO | ||
16 | * EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY SPECIAL, INDIRECT OR | ||
17 | * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, | ||
18 | * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER | ||
19 | * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE | ||
20 | * OF THIS SOFTWARE. | ||
21 | */ | ||
22 | #ifndef __DRM_FOURCC_H__ | ||
23 | #define __DRM_FOURCC_H__ | ||
24 | |||
25 | #include <linux/types.h> | ||
26 | #include <uapi/drm/drm_fourcc.h> | ||
27 | |||
28 | void drm_fb_get_bpp_depth(uint32_t format, unsigned int *depth, int *bpp); | ||
29 | int drm_format_num_planes(uint32_t format); | ||
30 | int drm_format_plane_cpp(uint32_t format, int plane); | ||
31 | int drm_format_horz_chroma_subsampling(uint32_t format); | ||
32 | int drm_format_vert_chroma_subsampling(uint32_t format); | ||
33 | int drm_format_plane_width(int width, uint32_t format, int plane); | ||
34 | int drm_format_plane_height(int height, uint32_t format, int plane); | ||
35 | const char *drm_get_format_name(uint32_t format); | ||
36 | |||
37 | #endif /* __DRM_FOURCC_H__ */ | ||
diff --git a/include/drm/drm_mipi_dsi.h b/include/drm/drm_mipi_dsi.h index 7a9840f8b38e..72f5b15e0738 100644 --- a/include/drm/drm_mipi_dsi.h +++ b/include/drm/drm_mipi_dsi.h | |||
@@ -180,6 +180,8 @@ struct mipi_dsi_device { | |||
180 | unsigned long mode_flags; | 180 | unsigned long mode_flags; |
181 | }; | 181 | }; |
182 | 182 | ||
183 | #define MIPI_DSI_MODULE_PREFIX "mipi-dsi:" | ||
184 | |||
183 | static inline struct mipi_dsi_device *to_mipi_dsi_device(struct device *dev) | 185 | static inline struct mipi_dsi_device *to_mipi_dsi_device(struct device *dev) |
184 | { | 186 | { |
185 | return container_of(dev, struct mipi_dsi_device, dev); | 187 | return container_of(dev, struct mipi_dsi_device, dev); |
@@ -263,6 +265,7 @@ int mipi_dsi_dcs_set_column_address(struct mipi_dsi_device *dsi, u16 start, | |||
263 | u16 end); | 265 | u16 end); |
264 | int mipi_dsi_dcs_set_page_address(struct mipi_dsi_device *dsi, u16 start, | 266 | int mipi_dsi_dcs_set_page_address(struct mipi_dsi_device *dsi, u16 start, |
265 | u16 end); | 267 | u16 end); |
268 | int mipi_dsi_set_tear_scanline(struct mipi_dsi_device *dsi, u16 param); | ||
266 | int mipi_dsi_dcs_set_tear_off(struct mipi_dsi_device *dsi); | 269 | int mipi_dsi_dcs_set_tear_off(struct mipi_dsi_device *dsi); |
267 | int mipi_dsi_dcs_set_tear_on(struct mipi_dsi_device *dsi, | 270 | int mipi_dsi_dcs_set_tear_on(struct mipi_dsi_device *dsi, |
268 | enum mipi_dsi_dcs_tear_mode mode); | 271 | enum mipi_dsi_dcs_tear_mode mode); |
diff --git a/include/drm/drm_modes.h b/include/drm/drm_modes.h index 625966a906f2..ff481770d76b 100644 --- a/include/drm/drm_modes.h +++ b/include/drm/drm_modes.h | |||
@@ -169,6 +169,8 @@ enum drm_mode_status { | |||
169 | * | 169 | * |
170 | * The horizontal and vertical timings are defined per the following diagram. | 170 | * The horizontal and vertical timings are defined per the following diagram. |
171 | * | 171 | * |
172 | * :: | ||
173 | * | ||
172 | * | 174 | * |
173 | * Active Front Sync Back | 175 | * Active Front Sync Back |
174 | * Region Porch Porch | 176 | * Region Porch Porch |
diff --git a/include/drm/drm_modeset_helper_vtables.h b/include/drm/drm_modeset_helper_vtables.h index d4619dc2eecb..b55f21857a98 100644 --- a/include/drm/drm_modeset_helper_vtables.h +++ b/include/drm/drm_modeset_helper_vtables.h | |||
@@ -736,6 +736,11 @@ struct drm_connector_helper_funcs { | |||
736 | * inspect dynamic configuration state should instead use | 736 | * inspect dynamic configuration state should instead use |
737 | * @atomic_best_encoder. | 737 | * @atomic_best_encoder. |
738 | * | 738 | * |
739 | * You can leave this function to NULL if the connector is only | ||
740 | * attached to a single encoder and you are using the atomic helpers. | ||
741 | * In this case, the core will call drm_atomic_helper_best_encoder() | ||
742 | * for you. | ||
743 | * | ||
739 | * RETURNS: | 744 | * RETURNS: |
740 | * | 745 | * |
741 | * Encoder that should be used for the given connector and connector | 746 | * Encoder that should be used for the given connector and connector |
@@ -752,8 +757,9 @@ struct drm_connector_helper_funcs { | |||
752 | * need to select the best encoder depending upon the desired | 757 | * need to select the best encoder depending upon the desired |
753 | * configuration and can't select it statically. | 758 | * configuration and can't select it statically. |
754 | * | 759 | * |
755 | * This function is used by drm_atomic_helper_check_modeset() and either | 760 | * This function is used by drm_atomic_helper_check_modeset(). |
756 | * this or @best_encoder is required. | 761 | * If it is not implemented, the core will fallback to @best_encoder |
762 | * (or drm_atomic_helper_best_encoder() if @best_encoder is NULL). | ||
757 | * | 763 | * |
758 | * NOTE: | 764 | * NOTE: |
759 | * | 765 | * |
@@ -925,4 +931,43 @@ static inline void drm_plane_helper_add(struct drm_plane *plane, | |||
925 | plane->helper_private = funcs; | 931 | plane->helper_private = funcs; |
926 | } | 932 | } |
927 | 933 | ||
934 | /** | ||
935 | * struct drm_mode_config_helper_funcs - global modeset helper operations | ||
936 | * | ||
937 | * These helper functions are used by the atomic helpers. | ||
938 | */ | ||
939 | struct drm_mode_config_helper_funcs { | ||
940 | /** | ||
941 | * @atomic_commit_tail: | ||
942 | * | ||
943 | * This hook is used by the default atomic_commit() hook implemented in | ||
944 | * drm_atomic_helper_commit() together with the nonblocking commit | ||
945 | * helpers (see drm_atomic_helper_setup_commit() for a starting point) | ||
946 | * to implement blocking and nonblocking commits easily. It is not used | ||
947 | * by the atomic helpers | ||
948 | * | ||
949 | * This hook should first commit the given atomic state to the hardware. | ||
950 | * But drivers can add more waiting calls at the start of their | ||
951 | * implementation, e.g. to wait for driver-internal request for implicit | ||
952 | * syncing, before starting to commit the update to the hardware. | ||
953 | * | ||
954 | * After the atomic update is committed to the hardware this hook needs | ||
955 | * to call drm_atomic_helper_commit_hw_done(). Then wait for the upate | ||
956 | * to be executed by the hardware, for example using | ||
957 | * drm_atomic_helper_wait_for_vblanks(), and then clean up the old | ||
958 | * framebuffers using drm_atomic_helper_cleanup_planes(). | ||
959 | * | ||
960 | * When disabling a CRTC this hook _must_ stall for the commit to | ||
961 | * complete. Vblank waits don't work on disabled CRTC, hence the core | ||
962 | * can't take care of this. And it also can't rely on the vblank event, | ||
963 | * since that can be signalled already when the screen shows black, | ||
964 | * which can happen much earlier than the last hardware access needed to | ||
965 | * shut off the display pipeline completely. | ||
966 | * | ||
967 | * This hook is optional, the default implementation is | ||
968 | * drm_atomic_helper_commit_tail(). | ||
969 | */ | ||
970 | void (*atomic_commit_tail)(struct drm_atomic_state *state); | ||
971 | }; | ||
972 | |||
928 | #endif | 973 | #endif |
diff --git a/include/drm/drm_simple_kms_helper.h b/include/drm/drm_simple_kms_helper.h new file mode 100644 index 000000000000..269039722f91 --- /dev/null +++ b/include/drm/drm_simple_kms_helper.h | |||
@@ -0,0 +1,94 @@ | |||
1 | /* | ||
2 | * Copyright (C) 2016 Noralf Trønnes | ||
3 | * | ||
4 | * This program is free software; you can redistribute it and/or modify | ||
5 | * it under the terms of the GNU General Public License as published by | ||
6 | * the Free Software Foundation; either version 2 of the License, or | ||
7 | * (at your option) any later version. | ||
8 | */ | ||
9 | |||
10 | #ifndef __LINUX_DRM_SIMPLE_KMS_HELPER_H | ||
11 | #define __LINUX_DRM_SIMPLE_KMS_HELPER_H | ||
12 | |||
13 | struct drm_simple_display_pipe; | ||
14 | |||
15 | /** | ||
16 | * struct drm_simple_display_pipe_funcs - helper operations for a simple | ||
17 | * display pipeline | ||
18 | */ | ||
19 | struct drm_simple_display_pipe_funcs { | ||
20 | /** | ||
21 | * @enable: | ||
22 | * | ||
23 | * This function should be used to enable the pipeline. | ||
24 | * It is called when the underlying crtc is enabled. | ||
25 | * This hook is optional. | ||
26 | */ | ||
27 | void (*enable)(struct drm_simple_display_pipe *pipe, | ||
28 | struct drm_crtc_state *crtc_state); | ||
29 | /** | ||
30 | * @disable: | ||
31 | * | ||
32 | * This function should be used to disable the pipeline. | ||
33 | * It is called when the underlying crtc is disabled. | ||
34 | * This hook is optional. | ||
35 | */ | ||
36 | void (*disable)(struct drm_simple_display_pipe *pipe); | ||
37 | |||
38 | /** | ||
39 | * @check: | ||
40 | * | ||
41 | * This function is called in the check phase of an atomic update, | ||
42 | * specifically when the underlying plane is checked. | ||
43 | * The simple display pipeline helpers already check that the plane is | ||
44 | * not scaled, fills the entire visible area and is always enabled | ||
45 | * when the crtc is also enabled. | ||
46 | * This hook is optional. | ||
47 | * | ||
48 | * RETURNS: | ||
49 | * | ||
50 | * 0 on success, -EINVAL if the state or the transition can't be | ||
51 | * supported, -ENOMEM on memory allocation failure and -EDEADLK if an | ||
52 | * attempt to obtain another state object ran into a &drm_modeset_lock | ||
53 | * deadlock. | ||
54 | */ | ||
55 | int (*check)(struct drm_simple_display_pipe *pipe, | ||
56 | struct drm_plane_state *plane_state, | ||
57 | struct drm_crtc_state *crtc_state); | ||
58 | /** | ||
59 | * @update: | ||
60 | * | ||
61 | * This function is called when the underlying plane state is updated. | ||
62 | * This hook is optional. | ||
63 | */ | ||
64 | void (*update)(struct drm_simple_display_pipe *pipe, | ||
65 | struct drm_plane_state *plane_state); | ||
66 | }; | ||
67 | |||
68 | /** | ||
69 | * struct drm_simple_display_pipe - simple display pipeline | ||
70 | * @crtc: CRTC control structure | ||
71 | * @plane: Plane control structure | ||
72 | * @encoder: Encoder control structure | ||
73 | * @connector: Connector control structure | ||
74 | * @funcs: Pipeline control functions (optional) | ||
75 | * | ||
76 | * Simple display pipeline with plane, crtc and encoder collapsed into one | ||
77 | * entity. It should be initialized by calling drm_simple_display_pipe_init(). | ||
78 | */ | ||
79 | struct drm_simple_display_pipe { | ||
80 | struct drm_crtc crtc; | ||
81 | struct drm_plane plane; | ||
82 | struct drm_encoder encoder; | ||
83 | struct drm_connector *connector; | ||
84 | |||
85 | const struct drm_simple_display_pipe_funcs *funcs; | ||
86 | }; | ||
87 | |||
88 | int drm_simple_display_pipe_init(struct drm_device *dev, | ||
89 | struct drm_simple_display_pipe *pipe, | ||
90 | const struct drm_simple_display_pipe_funcs *funcs, | ||
91 | const uint32_t *formats, unsigned int format_count, | ||
92 | struct drm_connector *connector); | ||
93 | |||
94 | #endif /* __LINUX_DRM_SIMPLE_KMS_HELPER_H */ | ||