File: | dev/pci/drm/drm_crtc.c |
Warning: | line 896, column 8 Branch condition evaluates to a garbage value |
Press '?' to see keyboard shortcuts
Keyboard shortcuts:
1 | /* | ||||||||||||||||||
2 | * Copyright (c) 2006-2008 Intel Corporation | ||||||||||||||||||
3 | * Copyright (c) 2007 Dave Airlie <airlied@linux.ie> | ||||||||||||||||||
4 | * Copyright (c) 2008 Red Hat Inc. | ||||||||||||||||||
5 | * | ||||||||||||||||||
6 | * DRM core CRTC related functions | ||||||||||||||||||
7 | * | ||||||||||||||||||
8 | * Permission to use, copy, modify, distribute, and sell this software and its | ||||||||||||||||||
9 | * documentation for any purpose is hereby granted without fee, provided that | ||||||||||||||||||
10 | * the above copyright notice appear in all copies and that both that copyright | ||||||||||||||||||
11 | * notice and this permission notice appear in supporting documentation, and | ||||||||||||||||||
12 | * that the name of the copyright holders not be used in advertising or | ||||||||||||||||||
13 | * publicity pertaining to distribution of the software without specific, | ||||||||||||||||||
14 | * written prior permission. The copyright holders make no representations | ||||||||||||||||||
15 | * about the suitability of this software for any purpose. It is provided "as | ||||||||||||||||||
16 | * is" without express or implied warranty. | ||||||||||||||||||
17 | * | ||||||||||||||||||
18 | * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, | ||||||||||||||||||
19 | * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO | ||||||||||||||||||
20 | * EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY SPECIAL, INDIRECT OR | ||||||||||||||||||
21 | * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, | ||||||||||||||||||
22 | * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER | ||||||||||||||||||
23 | * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE | ||||||||||||||||||
24 | * OF THIS SOFTWARE. | ||||||||||||||||||
25 | * | ||||||||||||||||||
26 | * Authors: | ||||||||||||||||||
27 | * Keith Packard | ||||||||||||||||||
28 | * Eric Anholt <eric@anholt.net> | ||||||||||||||||||
29 | * Dave Airlie <airlied@linux.ie> | ||||||||||||||||||
30 | * Jesse Barnes <jesse.barnes@intel.com> | ||||||||||||||||||
31 | */ | ||||||||||||||||||
32 | #include <linux/ctype.h> | ||||||||||||||||||
33 | #include <linux/list.h> | ||||||||||||||||||
34 | #include <linux/slab.h> | ||||||||||||||||||
35 | #include <linux/export.h> | ||||||||||||||||||
36 | #include <linux/dma-fence.h> | ||||||||||||||||||
37 | #include <linux/uaccess.h> | ||||||||||||||||||
38 | #include <drm/drm_blend.h> | ||||||||||||||||||
39 | #include <drm/drm_crtc.h> | ||||||||||||||||||
40 | #include <drm/drm_edid.h> | ||||||||||||||||||
41 | #include <drm/drm_fourcc.h> | ||||||||||||||||||
42 | #include <drm/drm_framebuffer.h> | ||||||||||||||||||
43 | #include <drm/drm_managed.h> | ||||||||||||||||||
44 | #include <drm/drm_modeset_lock.h> | ||||||||||||||||||
45 | #include <drm/drm_atomic.h> | ||||||||||||||||||
46 | #include <drm/drm_auth.h> | ||||||||||||||||||
47 | #include <drm/drm_debugfs_crc.h> | ||||||||||||||||||
48 | #include <drm/drm_drv.h> | ||||||||||||||||||
49 | #include <drm/drm_print.h> | ||||||||||||||||||
50 | #include <drm/drm_file.h> | ||||||||||||||||||
51 | |||||||||||||||||||
52 | #include "drm_crtc_internal.h" | ||||||||||||||||||
53 | #include "drm_internal.h" | ||||||||||||||||||
54 | |||||||||||||||||||
55 | /** | ||||||||||||||||||
56 | * DOC: overview | ||||||||||||||||||
57 | * | ||||||||||||||||||
58 | * A CRTC represents the overall display pipeline. It receives pixel data from | ||||||||||||||||||
59 | * &drm_plane and blends them together. The &drm_display_mode is also attached | ||||||||||||||||||
60 | * to the CRTC, specifying display timings. On the output side the data is fed | ||||||||||||||||||
61 | * to one or more &drm_encoder, which are then each connected to one | ||||||||||||||||||
62 | * &drm_connector. | ||||||||||||||||||
63 | * | ||||||||||||||||||
64 | * To create a CRTC, a KMS drivers allocates and zeroes an instances of | ||||||||||||||||||
65 | * &struct drm_crtc (possibly as part of a larger structure) and registers it | ||||||||||||||||||
66 | * with a call to drm_crtc_init_with_planes(). | ||||||||||||||||||
67 | * | ||||||||||||||||||
68 | * The CRTC is also the entry point for legacy modeset operations, see | ||||||||||||||||||
69 | * &drm_crtc_funcs.set_config, legacy plane operations, see | ||||||||||||||||||
70 | * &drm_crtc_funcs.page_flip and &drm_crtc_funcs.cursor_set2, and other legacy | ||||||||||||||||||
71 | * operations like &drm_crtc_funcs.gamma_set. For atomic drivers all these | ||||||||||||||||||
72 | * features are controlled through &drm_property and | ||||||||||||||||||
73 | * &drm_mode_config_funcs.atomic_check. | ||||||||||||||||||
74 | */ | ||||||||||||||||||
75 | |||||||||||||||||||
76 | /** | ||||||||||||||||||
77 | * drm_crtc_from_index - find the registered CRTC at an index | ||||||||||||||||||
78 | * @dev: DRM device | ||||||||||||||||||
79 | * @idx: index of registered CRTC to find for | ||||||||||||||||||
80 | * | ||||||||||||||||||
81 | * Given a CRTC index, return the registered CRTC from DRM device's | ||||||||||||||||||
82 | * list of CRTCs with matching index. This is the inverse of drm_crtc_index(). | ||||||||||||||||||
83 | * It's useful in the vblank callbacks (like &drm_driver.enable_vblank or | ||||||||||||||||||
84 | * &drm_driver.disable_vblank), since that still deals with indices instead | ||||||||||||||||||
85 | * of pointers to &struct drm_crtc." | ||||||||||||||||||
86 | */ | ||||||||||||||||||
87 | struct drm_crtc *drm_crtc_from_index(struct drm_device *dev, int idx) | ||||||||||||||||||
88 | { | ||||||||||||||||||
89 | struct drm_crtc *crtc; | ||||||||||||||||||
90 | |||||||||||||||||||
91 | drm_for_each_crtc(crtc, dev)for (crtc = ({ const __typeof( ((__typeof(*crtc) *)0)->head ) *__mptr = ((&(dev)->mode_config.crtc_list)->next ); (__typeof(*crtc) *)( (char *)__mptr - __builtin_offsetof(__typeof (*crtc), head) );}); &crtc->head != (&(dev)->mode_config .crtc_list); crtc = ({ const __typeof( ((__typeof(*crtc) *)0) ->head ) *__mptr = (crtc->head.next); (__typeof(*crtc) * )( (char *)__mptr - __builtin_offsetof(__typeof(*crtc), head) );})) | ||||||||||||||||||
92 | if (idx == crtc->index) | ||||||||||||||||||
93 | return crtc; | ||||||||||||||||||
94 | |||||||||||||||||||
95 | return NULL((void *)0); | ||||||||||||||||||
96 | } | ||||||||||||||||||
97 | EXPORT_SYMBOL(drm_crtc_from_index); | ||||||||||||||||||
98 | |||||||||||||||||||
99 | int drm_crtc_force_disable(struct drm_crtc *crtc) | ||||||||||||||||||
100 | { | ||||||||||||||||||
101 | struct drm_mode_set set = { | ||||||||||||||||||
102 | .crtc = crtc, | ||||||||||||||||||
103 | }; | ||||||||||||||||||
104 | |||||||||||||||||||
105 | WARN_ON(drm_drv_uses_atomic_modeset(crtc->dev))({ int __ret = !!(drm_drv_uses_atomic_modeset(crtc->dev)); if (__ret) printf("WARNING %s failed at %s:%d\n", "drm_drv_uses_atomic_modeset(crtc->dev)" , "/usr/src/sys/dev/pci/drm/drm_crtc.c", 105); __builtin_expect (!!(__ret), 0); }); | ||||||||||||||||||
106 | |||||||||||||||||||
107 | return drm_mode_set_config_internal(&set); | ||||||||||||||||||
108 | } | ||||||||||||||||||
109 | |||||||||||||||||||
110 | static unsigned int drm_num_crtcs(struct drm_device *dev) | ||||||||||||||||||
111 | { | ||||||||||||||||||
112 | unsigned int num = 0; | ||||||||||||||||||
113 | struct drm_crtc *tmp; | ||||||||||||||||||
114 | |||||||||||||||||||
115 | drm_for_each_crtc(tmp, dev)for (tmp = ({ const __typeof( ((__typeof(*tmp) *)0)->head ) *__mptr = ((&(dev)->mode_config.crtc_list)->next); (__typeof(*tmp) *)( (char *)__mptr - __builtin_offsetof(__typeof (*tmp), head) );}); &tmp->head != (&(dev)->mode_config .crtc_list); tmp = ({ const __typeof( ((__typeof(*tmp) *)0)-> head ) *__mptr = (tmp->head.next); (__typeof(*tmp) *)( (char *)__mptr - __builtin_offsetof(__typeof(*tmp), head) );})) { | ||||||||||||||||||
116 | num++; | ||||||||||||||||||
117 | } | ||||||||||||||||||
118 | |||||||||||||||||||
119 | return num; | ||||||||||||||||||
120 | } | ||||||||||||||||||
121 | |||||||||||||||||||
122 | int drm_crtc_register_all(struct drm_device *dev) | ||||||||||||||||||
123 | { | ||||||||||||||||||
124 | struct drm_crtc *crtc; | ||||||||||||||||||
125 | int ret = 0; | ||||||||||||||||||
126 | |||||||||||||||||||
127 | drm_for_each_crtc(crtc, dev)for (crtc = ({ const __typeof( ((__typeof(*crtc) *)0)->head ) *__mptr = ((&(dev)->mode_config.crtc_list)->next ); (__typeof(*crtc) *)( (char *)__mptr - __builtin_offsetof(__typeof (*crtc), head) );}); &crtc->head != (&(dev)->mode_config .crtc_list); crtc = ({ const __typeof( ((__typeof(*crtc) *)0) ->head ) *__mptr = (crtc->head.next); (__typeof(*crtc) * )( (char *)__mptr - __builtin_offsetof(__typeof(*crtc), head) );})) { | ||||||||||||||||||
128 | drm_debugfs_crtc_add(crtc); | ||||||||||||||||||
129 | |||||||||||||||||||
130 | if (crtc->funcs->late_register) | ||||||||||||||||||
131 | ret = crtc->funcs->late_register(crtc); | ||||||||||||||||||
132 | if (ret) | ||||||||||||||||||
133 | return ret; | ||||||||||||||||||
134 | } | ||||||||||||||||||
135 | |||||||||||||||||||
136 | return 0; | ||||||||||||||||||
137 | } | ||||||||||||||||||
138 | |||||||||||||||||||
139 | void drm_crtc_unregister_all(struct drm_device *dev) | ||||||||||||||||||
140 | { | ||||||||||||||||||
141 | struct drm_crtc *crtc; | ||||||||||||||||||
142 | |||||||||||||||||||
143 | drm_for_each_crtc(crtc, dev)for (crtc = ({ const __typeof( ((__typeof(*crtc) *)0)->head ) *__mptr = ((&(dev)->mode_config.crtc_list)->next ); (__typeof(*crtc) *)( (char *)__mptr - __builtin_offsetof(__typeof (*crtc), head) );}); &crtc->head != (&(dev)->mode_config .crtc_list); crtc = ({ const __typeof( ((__typeof(*crtc) *)0) ->head ) *__mptr = (crtc->head.next); (__typeof(*crtc) * )( (char *)__mptr - __builtin_offsetof(__typeof(*crtc), head) );})) { | ||||||||||||||||||
144 | if (crtc->funcs->early_unregister) | ||||||||||||||||||
145 | crtc->funcs->early_unregister(crtc); | ||||||||||||||||||
146 | drm_debugfs_crtc_remove(crtc); | ||||||||||||||||||
147 | } | ||||||||||||||||||
148 | } | ||||||||||||||||||
149 | |||||||||||||||||||
150 | static int drm_crtc_crc_init(struct drm_crtc *crtc) | ||||||||||||||||||
151 | { | ||||||||||||||||||
152 | #ifdef CONFIG_DEBUG_FS | ||||||||||||||||||
153 | mtx_init(&crtc->crc.lock, IPL_NONE)do { (void)(((void *)0)); (void)(0); __mtx_init((&crtc-> crc.lock), ((((0x0)) > 0x0 && ((0x0)) < 0x9) ? 0x9 : ((0x0)))); } while (0); | ||||||||||||||||||
154 | init_waitqueue_head(&crtc->crc.wq); | ||||||||||||||||||
155 | crtc->crc.source = kstrdup("auto", GFP_KERNEL(0x0001 | 0x0004)); | ||||||||||||||||||
156 | if (!crtc->crc.source) | ||||||||||||||||||
157 | return -ENOMEM12; | ||||||||||||||||||
158 | #endif | ||||||||||||||||||
159 | return 0; | ||||||||||||||||||
160 | } | ||||||||||||||||||
161 | |||||||||||||||||||
162 | static void drm_crtc_crc_fini(struct drm_crtc *crtc) | ||||||||||||||||||
163 | { | ||||||||||||||||||
164 | #ifdef CONFIG_DEBUG_FS | ||||||||||||||||||
165 | kfree(crtc->crc.source); | ||||||||||||||||||
166 | #endif | ||||||||||||||||||
167 | } | ||||||||||||||||||
168 | |||||||||||||||||||
169 | static const struct dma_fence_ops drm_crtc_fence_ops; | ||||||||||||||||||
170 | |||||||||||||||||||
171 | static struct drm_crtc *fence_to_crtc(struct dma_fence *fence) | ||||||||||||||||||
172 | { | ||||||||||||||||||
173 | BUG_ON(fence->ops != &drm_crtc_fence_ops)((!(fence->ops != &drm_crtc_fence_ops)) ? (void)0 : __assert ("diagnostic ", "/usr/src/sys/dev/pci/drm/drm_crtc.c", 173, "!(fence->ops != &drm_crtc_fence_ops)" )); | ||||||||||||||||||
174 | return container_of(fence->lock, struct drm_crtc, fence_lock)({ const __typeof( ((struct drm_crtc *)0)->fence_lock ) *__mptr = (fence->lock); (struct drm_crtc *)( (char *)__mptr - __builtin_offsetof (struct drm_crtc, fence_lock) );}); | ||||||||||||||||||
175 | } | ||||||||||||||||||
176 | |||||||||||||||||||
177 | static const char *drm_crtc_fence_get_driver_name(struct dma_fence *fence) | ||||||||||||||||||
178 | { | ||||||||||||||||||
179 | struct drm_crtc *crtc = fence_to_crtc(fence); | ||||||||||||||||||
180 | |||||||||||||||||||
181 | return crtc->dev->driver->name; | ||||||||||||||||||
182 | } | ||||||||||||||||||
183 | |||||||||||||||||||
184 | static const char *drm_crtc_fence_get_timeline_name(struct dma_fence *fence) | ||||||||||||||||||
185 | { | ||||||||||||||||||
186 | struct drm_crtc *crtc = fence_to_crtc(fence); | ||||||||||||||||||
187 | |||||||||||||||||||
188 | return crtc->timeline_name; | ||||||||||||||||||
189 | } | ||||||||||||||||||
190 | |||||||||||||||||||
191 | static const struct dma_fence_ops drm_crtc_fence_ops = { | ||||||||||||||||||
192 | .get_driver_name = drm_crtc_fence_get_driver_name, | ||||||||||||||||||
193 | .get_timeline_name = drm_crtc_fence_get_timeline_name, | ||||||||||||||||||
194 | }; | ||||||||||||||||||
195 | |||||||||||||||||||
196 | struct dma_fence *drm_crtc_create_fence(struct drm_crtc *crtc) | ||||||||||||||||||
197 | { | ||||||||||||||||||
198 | struct dma_fence *fence; | ||||||||||||||||||
199 | |||||||||||||||||||
200 | fence = kzalloc(sizeof(*fence), GFP_KERNEL(0x0001 | 0x0004)); | ||||||||||||||||||
201 | if (!fence) | ||||||||||||||||||
202 | return NULL((void *)0); | ||||||||||||||||||
203 | |||||||||||||||||||
204 | dma_fence_init(fence, &drm_crtc_fence_ops, &crtc->fence_lock, | ||||||||||||||||||
205 | crtc->fence_context, ++crtc->fence_seqno); | ||||||||||||||||||
206 | |||||||||||||||||||
207 | return fence; | ||||||||||||||||||
208 | } | ||||||||||||||||||
209 | |||||||||||||||||||
210 | /** | ||||||||||||||||||
211 | * DOC: standard CRTC properties | ||||||||||||||||||
212 | * | ||||||||||||||||||
213 | * DRM CRTCs have a few standardized properties: | ||||||||||||||||||
214 | * | ||||||||||||||||||
215 | * ACTIVE: | ||||||||||||||||||
216 | * Atomic property for setting the power state of the CRTC. When set to 1 | ||||||||||||||||||
217 | * the CRTC will actively display content. When set to 0 the CRTC will be | ||||||||||||||||||
218 | * powered off. There is no expectation that user-space will reset CRTC | ||||||||||||||||||
219 | * resources like the mode and planes when setting ACTIVE to 0. | ||||||||||||||||||
220 | * | ||||||||||||||||||
221 | * User-space can rely on an ACTIVE change to 1 to never fail an atomic | ||||||||||||||||||
222 | * test as long as no other property has changed. If a change to ACTIVE | ||||||||||||||||||
223 | * fails an atomic test, this is a driver bug. For this reason setting | ||||||||||||||||||
224 | * ACTIVE to 0 must not release internal resources (like reserved memory | ||||||||||||||||||
225 | * bandwidth or clock generators). | ||||||||||||||||||
226 | * | ||||||||||||||||||
227 | * Note that the legacy DPMS property on connectors is internally routed | ||||||||||||||||||
228 | * to control this property for atomic drivers. | ||||||||||||||||||
229 | * MODE_ID: | ||||||||||||||||||
230 | * Atomic property for setting the CRTC display timings. The value is the | ||||||||||||||||||
231 | * ID of a blob containing the DRM mode info. To disable the CRTC, | ||||||||||||||||||
232 | * user-space must set this property to 0. | ||||||||||||||||||
233 | * | ||||||||||||||||||
234 | * Setting MODE_ID to 0 will release reserved resources for the CRTC. | ||||||||||||||||||
235 | * SCALING_FILTER: | ||||||||||||||||||
236 | * Atomic property for setting the scaling filter for CRTC scaler | ||||||||||||||||||
237 | * | ||||||||||||||||||
238 | * The value of this property can be one of the following: | ||||||||||||||||||
239 | * | ||||||||||||||||||
240 | * Default: | ||||||||||||||||||
241 | * Driver's default scaling filter | ||||||||||||||||||
242 | * Nearest Neighbor: | ||||||||||||||||||
243 | * Nearest Neighbor scaling filter | ||||||||||||||||||
244 | */ | ||||||||||||||||||
245 | |||||||||||||||||||
246 | __printf(6, 0)__attribute__((__format__(__kprintf__,6,0))) | ||||||||||||||||||
247 | static int __drm_crtc_init_with_planes(struct drm_device *dev, struct drm_crtc *crtc, | ||||||||||||||||||
248 | struct drm_plane *primary, | ||||||||||||||||||
249 | struct drm_plane *cursor, | ||||||||||||||||||
250 | const struct drm_crtc_funcs *funcs, | ||||||||||||||||||
251 | const char *name, va_list ap) | ||||||||||||||||||
252 | { | ||||||||||||||||||
253 | struct drm_mode_config *config = &dev->mode_config; | ||||||||||||||||||
254 | int ret; | ||||||||||||||||||
255 | |||||||||||||||||||
256 | WARN_ON(primary && primary->type != DRM_PLANE_TYPE_PRIMARY)({ int __ret = !!(primary && primary->type != DRM_PLANE_TYPE_PRIMARY ); if (__ret) printf("WARNING %s failed at %s:%d\n", "primary && primary->type != DRM_PLANE_TYPE_PRIMARY" , "/usr/src/sys/dev/pci/drm/drm_crtc.c", 256); __builtin_expect (!!(__ret), 0); }); | ||||||||||||||||||
257 | WARN_ON(cursor && cursor->type != DRM_PLANE_TYPE_CURSOR)({ int __ret = !!(cursor && cursor->type != DRM_PLANE_TYPE_CURSOR ); if (__ret) printf("WARNING %s failed at %s:%d\n", "cursor && cursor->type != DRM_PLANE_TYPE_CURSOR" , "/usr/src/sys/dev/pci/drm/drm_crtc.c", 257); __builtin_expect (!!(__ret), 0); }); | ||||||||||||||||||
258 | |||||||||||||||||||
259 | /* crtc index is used with 32bit bitmasks */ | ||||||||||||||||||
260 | if (WARN_ON(config->num_crtc >= 32)({ int __ret = !!(config->num_crtc >= 32); if (__ret) printf ("WARNING %s failed at %s:%d\n", "config->num_crtc >= 32" , "/usr/src/sys/dev/pci/drm/drm_crtc.c", 260); __builtin_expect (!!(__ret), 0); })) | ||||||||||||||||||
261 | return -EINVAL22; | ||||||||||||||||||
262 | |||||||||||||||||||
263 | WARN_ON(drm_drv_uses_atomic_modeset(dev) &&({ int __ret = !!(drm_drv_uses_atomic_modeset(dev) && (!funcs->atomic_destroy_state || !funcs->atomic_duplicate_state )); if (__ret) printf("WARNING %s failed at %s:%d\n", "drm_drv_uses_atomic_modeset(dev) && (!funcs->atomic_destroy_state || !funcs->atomic_duplicate_state)" , "/usr/src/sys/dev/pci/drm/drm_crtc.c", 265); __builtin_expect (!!(__ret), 0); }) | ||||||||||||||||||
264 | (!funcs->atomic_destroy_state ||({ int __ret = !!(drm_drv_uses_atomic_modeset(dev) && (!funcs->atomic_destroy_state || !funcs->atomic_duplicate_state )); if (__ret) printf("WARNING %s failed at %s:%d\n", "drm_drv_uses_atomic_modeset(dev) && (!funcs->atomic_destroy_state || !funcs->atomic_duplicate_state)" , "/usr/src/sys/dev/pci/drm/drm_crtc.c", 265); __builtin_expect (!!(__ret), 0); }) | ||||||||||||||||||
265 | !funcs->atomic_duplicate_state))({ int __ret = !!(drm_drv_uses_atomic_modeset(dev) && (!funcs->atomic_destroy_state || !funcs->atomic_duplicate_state )); if (__ret) printf("WARNING %s failed at %s:%d\n", "drm_drv_uses_atomic_modeset(dev) && (!funcs->atomic_destroy_state || !funcs->atomic_duplicate_state)" , "/usr/src/sys/dev/pci/drm/drm_crtc.c", 265); __builtin_expect (!!(__ret), 0); }); | ||||||||||||||||||
266 | |||||||||||||||||||
267 | crtc->dev = dev; | ||||||||||||||||||
268 | crtc->funcs = funcs; | ||||||||||||||||||
269 | |||||||||||||||||||
270 | INIT_LIST_HEAD(&crtc->commit_list); | ||||||||||||||||||
271 | mtx_init(&crtc->commit_lock, IPL_NONE)do { (void)(((void *)0)); (void)(0); __mtx_init((&crtc-> commit_lock), ((((0x0)) > 0x0 && ((0x0)) < 0x9) ? 0x9 : ((0x0)))); } while (0); | ||||||||||||||||||
272 | |||||||||||||||||||
273 | drm_modeset_lock_init(&crtc->mutex); | ||||||||||||||||||
274 | ret = drm_mode_object_add(dev, &crtc->base, DRM_MODE_OBJECT_CRTC0xcccccccc); | ||||||||||||||||||
275 | if (ret) | ||||||||||||||||||
276 | return ret; | ||||||||||||||||||
277 | |||||||||||||||||||
278 | if (name) { | ||||||||||||||||||
279 | crtc->name = kvasprintf(GFP_KERNEL(0x0001 | 0x0004), name, ap); | ||||||||||||||||||
280 | } else { | ||||||||||||||||||
281 | crtc->name = kasprintf(GFP_KERNEL(0x0001 | 0x0004), "crtc-%d", | ||||||||||||||||||
282 | drm_num_crtcs(dev)); | ||||||||||||||||||
283 | } | ||||||||||||||||||
284 | if (!crtc->name) { | ||||||||||||||||||
285 | drm_mode_object_unregister(dev, &crtc->base); | ||||||||||||||||||
286 | return -ENOMEM12; | ||||||||||||||||||
287 | } | ||||||||||||||||||
288 | |||||||||||||||||||
289 | crtc->fence_context = dma_fence_context_alloc(1); | ||||||||||||||||||
290 | mtx_init(&crtc->fence_lock, IPL_TTY)do { (void)(((void *)0)); (void)(0); __mtx_init((&crtc-> fence_lock), ((((0x9)) > 0x0 && ((0x9)) < 0x9) ? 0x9 : ((0x9)))); } while (0); | ||||||||||||||||||
291 | snprintf(crtc->timeline_name, sizeof(crtc->timeline_name), | ||||||||||||||||||
292 | "CRTC:%d-%s", crtc->base.id, crtc->name); | ||||||||||||||||||
293 | |||||||||||||||||||
294 | crtc->base.properties = &crtc->properties; | ||||||||||||||||||
295 | |||||||||||||||||||
296 | list_add_tail(&crtc->head, &config->crtc_list); | ||||||||||||||||||
297 | crtc->index = config->num_crtc++; | ||||||||||||||||||
298 | |||||||||||||||||||
299 | crtc->primary = primary; | ||||||||||||||||||
300 | crtc->cursor = cursor; | ||||||||||||||||||
301 | if (primary && !primary->possible_crtcs) | ||||||||||||||||||
302 | primary->possible_crtcs = drm_crtc_mask(crtc); | ||||||||||||||||||
303 | if (cursor && !cursor->possible_crtcs) | ||||||||||||||||||
304 | cursor->possible_crtcs = drm_crtc_mask(crtc); | ||||||||||||||||||
305 | |||||||||||||||||||
306 | ret = drm_crtc_crc_init(crtc); | ||||||||||||||||||
307 | if (ret) { | ||||||||||||||||||
308 | drm_mode_object_unregister(dev, &crtc->base); | ||||||||||||||||||
309 | return ret; | ||||||||||||||||||
310 | } | ||||||||||||||||||
311 | |||||||||||||||||||
312 | if (drm_core_check_feature(dev, DRIVER_ATOMIC)) { | ||||||||||||||||||
313 | drm_object_attach_property(&crtc->base, config->prop_active, 0); | ||||||||||||||||||
314 | drm_object_attach_property(&crtc->base, config->prop_mode_id, 0); | ||||||||||||||||||
315 | drm_object_attach_property(&crtc->base, | ||||||||||||||||||
316 | config->prop_out_fence_ptr, 0); | ||||||||||||||||||
317 | drm_object_attach_property(&crtc->base, | ||||||||||||||||||
318 | config->prop_vrr_enabled, 0); | ||||||||||||||||||
319 | } | ||||||||||||||||||
320 | |||||||||||||||||||
321 | return 0; | ||||||||||||||||||
322 | } | ||||||||||||||||||
323 | |||||||||||||||||||
324 | /** | ||||||||||||||||||
325 | * drm_crtc_init_with_planes - Initialise a new CRTC object with | ||||||||||||||||||
326 | * specified primary and cursor planes. | ||||||||||||||||||
327 | * @dev: DRM device | ||||||||||||||||||
328 | * @crtc: CRTC object to init | ||||||||||||||||||
329 | * @primary: Primary plane for CRTC | ||||||||||||||||||
330 | * @cursor: Cursor plane for CRTC | ||||||||||||||||||
331 | * @funcs: callbacks for the new CRTC | ||||||||||||||||||
332 | * @name: printf style format string for the CRTC name, or NULL for default name | ||||||||||||||||||
333 | * | ||||||||||||||||||
334 | * Inits a new object created as base part of a driver crtc object. Drivers | ||||||||||||||||||
335 | * should use this function instead of drm_crtc_init(), which is only provided | ||||||||||||||||||
336 | * for backwards compatibility with drivers which do not yet support universal | ||||||||||||||||||
337 | * planes). For really simple hardware which has only 1 plane look at | ||||||||||||||||||
338 | * drm_simple_display_pipe_init() instead. | ||||||||||||||||||
339 | * The &drm_crtc_funcs.destroy hook should call drm_crtc_cleanup() and kfree() | ||||||||||||||||||
340 | * the crtc structure. The crtc structure should not be allocated with | ||||||||||||||||||
341 | * devm_kzalloc(). | ||||||||||||||||||
342 | * | ||||||||||||||||||
343 | * The @primary and @cursor planes are only relevant for legacy uAPI, see | ||||||||||||||||||
344 | * &drm_crtc.primary and &drm_crtc.cursor. | ||||||||||||||||||
345 | * | ||||||||||||||||||
346 | * Note: consider using drmm_crtc_alloc_with_planes() or | ||||||||||||||||||
347 | * drmm_crtc_init_with_planes() instead of drm_crtc_init_with_planes() | ||||||||||||||||||
348 | * to let the DRM managed resource infrastructure take care of cleanup | ||||||||||||||||||
349 | * and deallocation. | ||||||||||||||||||
350 | * | ||||||||||||||||||
351 | * Returns: | ||||||||||||||||||
352 | * Zero on success, error code on failure. | ||||||||||||||||||
353 | */ | ||||||||||||||||||
354 | int drm_crtc_init_with_planes(struct drm_device *dev, struct drm_crtc *crtc, | ||||||||||||||||||
355 | struct drm_plane *primary, | ||||||||||||||||||
356 | struct drm_plane *cursor, | ||||||||||||||||||
357 | const struct drm_crtc_funcs *funcs, | ||||||||||||||||||
358 | const char *name, ...) | ||||||||||||||||||
359 | { | ||||||||||||||||||
360 | va_list ap; | ||||||||||||||||||
361 | int ret; | ||||||||||||||||||
362 | |||||||||||||||||||
363 | WARN_ON(!funcs->destroy)({ int __ret = !!(!funcs->destroy); if (__ret) printf("WARNING %s failed at %s:%d\n" , "!funcs->destroy", "/usr/src/sys/dev/pci/drm/drm_crtc.c" , 363); __builtin_expect(!!(__ret), 0); }); | ||||||||||||||||||
364 | |||||||||||||||||||
365 | va_start(ap, name)__builtin_va_start((ap), name); | ||||||||||||||||||
366 | ret = __drm_crtc_init_with_planes(dev, crtc, primary, cursor, funcs, | ||||||||||||||||||
367 | name, ap); | ||||||||||||||||||
368 | va_end(ap)__builtin_va_end((ap)); | ||||||||||||||||||
369 | |||||||||||||||||||
370 | return ret; | ||||||||||||||||||
371 | } | ||||||||||||||||||
372 | EXPORT_SYMBOL(drm_crtc_init_with_planes); | ||||||||||||||||||
373 | |||||||||||||||||||
374 | static void drmm_crtc_init_with_planes_cleanup(struct drm_device *dev, | ||||||||||||||||||
375 | void *ptr) | ||||||||||||||||||
376 | { | ||||||||||||||||||
377 | struct drm_crtc *crtc = ptr; | ||||||||||||||||||
378 | |||||||||||||||||||
379 | drm_crtc_cleanup(crtc); | ||||||||||||||||||
380 | } | ||||||||||||||||||
381 | |||||||||||||||||||
382 | __printf(6, 0)__attribute__((__format__(__kprintf__,6,0))) | ||||||||||||||||||
383 | static int __drmm_crtc_init_with_planes(struct drm_device *dev, | ||||||||||||||||||
384 | struct drm_crtc *crtc, | ||||||||||||||||||
385 | struct drm_plane *primary, | ||||||||||||||||||
386 | struct drm_plane *cursor, | ||||||||||||||||||
387 | const struct drm_crtc_funcs *funcs, | ||||||||||||||||||
388 | const char *name, | ||||||||||||||||||
389 | va_list args) | ||||||||||||||||||
390 | { | ||||||||||||||||||
391 | int ret; | ||||||||||||||||||
392 | |||||||||||||||||||
393 | drm_WARN_ON(dev, funcs && funcs->destroy)({ int __ret = !!((funcs && funcs->destroy)); if ( __ret) printf("%s %s: " "%s", dev_driver_string(((dev))->dev ), "", "drm_WARN_ON(" "funcs && funcs->destroy" ")" ); __builtin_expect(!!(__ret), 0); }); | ||||||||||||||||||
394 | |||||||||||||||||||
395 | ret = __drm_crtc_init_with_planes(dev, crtc, primary, cursor, funcs, | ||||||||||||||||||
396 | name, args); | ||||||||||||||||||
397 | if (ret) | ||||||||||||||||||
398 | return ret; | ||||||||||||||||||
399 | |||||||||||||||||||
400 | ret = drmm_add_action_or_reset(dev, drmm_crtc_init_with_planes_cleanup, | ||||||||||||||||||
401 | crtc); | ||||||||||||||||||
402 | if (ret) | ||||||||||||||||||
403 | return ret; | ||||||||||||||||||
404 | |||||||||||||||||||
405 | return 0; | ||||||||||||||||||
406 | } | ||||||||||||||||||
407 | |||||||||||||||||||
408 | /** | ||||||||||||||||||
409 | * drmm_crtc_init_with_planes - Initialise a new CRTC object with | ||||||||||||||||||
410 | * specified primary and cursor planes. | ||||||||||||||||||
411 | * @dev: DRM device | ||||||||||||||||||
412 | * @crtc: CRTC object to init | ||||||||||||||||||
413 | * @primary: Primary plane for CRTC | ||||||||||||||||||
414 | * @cursor: Cursor plane for CRTC | ||||||||||||||||||
415 | * @funcs: callbacks for the new CRTC | ||||||||||||||||||
416 | * @name: printf style format string for the CRTC name, or NULL for default name | ||||||||||||||||||
417 | * | ||||||||||||||||||
418 | * Inits a new object created as base part of a driver crtc object. Drivers | ||||||||||||||||||
419 | * should use this function instead of drm_crtc_init(), which is only provided | ||||||||||||||||||
420 | * for backwards compatibility with drivers which do not yet support universal | ||||||||||||||||||
421 | * planes). For really simple hardware which has only 1 plane look at | ||||||||||||||||||
422 | * drm_simple_display_pipe_init() instead. | ||||||||||||||||||
423 | * | ||||||||||||||||||
424 | * Cleanup is automatically handled through registering | ||||||||||||||||||
425 | * drmm_crtc_cleanup() with drmm_add_action(). The crtc structure should | ||||||||||||||||||
426 | * be allocated with drmm_kzalloc(). | ||||||||||||||||||
427 | * | ||||||||||||||||||
428 | * The @drm_crtc_funcs.destroy hook must be NULL. | ||||||||||||||||||
429 | * | ||||||||||||||||||
430 | * The @primary and @cursor planes are only relevant for legacy uAPI, see | ||||||||||||||||||
431 | * &drm_crtc.primary and &drm_crtc.cursor. | ||||||||||||||||||
432 | * | ||||||||||||||||||
433 | * Returns: | ||||||||||||||||||
434 | * Zero on success, error code on failure. | ||||||||||||||||||
435 | */ | ||||||||||||||||||
436 | int drmm_crtc_init_with_planes(struct drm_device *dev, struct drm_crtc *crtc, | ||||||||||||||||||
437 | struct drm_plane *primary, | ||||||||||||||||||
438 | struct drm_plane *cursor, | ||||||||||||||||||
439 | const struct drm_crtc_funcs *funcs, | ||||||||||||||||||
440 | const char *name, ...) | ||||||||||||||||||
441 | { | ||||||||||||||||||
442 | va_list ap; | ||||||||||||||||||
443 | int ret; | ||||||||||||||||||
444 | |||||||||||||||||||
445 | va_start(ap, name)__builtin_va_start((ap), name); | ||||||||||||||||||
446 | ret = __drmm_crtc_init_with_planes(dev, crtc, primary, cursor, funcs, | ||||||||||||||||||
447 | name, ap); | ||||||||||||||||||
448 | va_end(ap)__builtin_va_end((ap)); | ||||||||||||||||||
449 | if (ret) | ||||||||||||||||||
450 | return ret; | ||||||||||||||||||
451 | |||||||||||||||||||
452 | return 0; | ||||||||||||||||||
453 | } | ||||||||||||||||||
454 | EXPORT_SYMBOL(drmm_crtc_init_with_planes); | ||||||||||||||||||
455 | |||||||||||||||||||
456 | void *__drmm_crtc_alloc_with_planes(struct drm_device *dev, | ||||||||||||||||||
457 | size_t size, size_t offset, | ||||||||||||||||||
458 | struct drm_plane *primary, | ||||||||||||||||||
459 | struct drm_plane *cursor, | ||||||||||||||||||
460 | const struct drm_crtc_funcs *funcs, | ||||||||||||||||||
461 | const char *name, ...) | ||||||||||||||||||
462 | { | ||||||||||||||||||
463 | void *container; | ||||||||||||||||||
464 | struct drm_crtc *crtc; | ||||||||||||||||||
465 | va_list ap; | ||||||||||||||||||
466 | int ret; | ||||||||||||||||||
467 | |||||||||||||||||||
468 | if (WARN_ON(!funcs || funcs->destroy)({ int __ret = !!(!funcs || funcs->destroy); if (__ret) printf ("WARNING %s failed at %s:%d\n", "!funcs || funcs->destroy" , "/usr/src/sys/dev/pci/drm/drm_crtc.c", 468); __builtin_expect (!!(__ret), 0); })) | ||||||||||||||||||
469 | return ERR_PTR(-EINVAL22); | ||||||||||||||||||
470 | |||||||||||||||||||
471 | container = drmm_kzalloc(dev, size, GFP_KERNEL(0x0001 | 0x0004)); | ||||||||||||||||||
472 | if (!container) | ||||||||||||||||||
473 | return ERR_PTR(-ENOMEM12); | ||||||||||||||||||
474 | |||||||||||||||||||
475 | crtc = container + offset; | ||||||||||||||||||
476 | |||||||||||||||||||
477 | va_start(ap, name)__builtin_va_start((ap), name); | ||||||||||||||||||
478 | ret = __drmm_crtc_init_with_planes(dev, crtc, primary, cursor, funcs, | ||||||||||||||||||
479 | name, ap); | ||||||||||||||||||
480 | va_end(ap)__builtin_va_end((ap)); | ||||||||||||||||||
481 | if (ret) | ||||||||||||||||||
482 | return ERR_PTR(ret); | ||||||||||||||||||
483 | |||||||||||||||||||
484 | return container; | ||||||||||||||||||
485 | } | ||||||||||||||||||
486 | EXPORT_SYMBOL(__drmm_crtc_alloc_with_planes); | ||||||||||||||||||
487 | |||||||||||||||||||
488 | /** | ||||||||||||||||||
489 | * drm_crtc_cleanup - Clean up the core crtc usage | ||||||||||||||||||
490 | * @crtc: CRTC to cleanup | ||||||||||||||||||
491 | * | ||||||||||||||||||
492 | * This function cleans up @crtc and removes it from the DRM mode setting | ||||||||||||||||||
493 | * core. Note that the function does *not* free the crtc structure itself, | ||||||||||||||||||
494 | * this is the responsibility of the caller. | ||||||||||||||||||
495 | */ | ||||||||||||||||||
496 | void drm_crtc_cleanup(struct drm_crtc *crtc) | ||||||||||||||||||
497 | { | ||||||||||||||||||
498 | struct drm_device *dev = crtc->dev; | ||||||||||||||||||
499 | |||||||||||||||||||
500 | /* Note that the crtc_list is considered to be static; should we | ||||||||||||||||||
501 | * remove the drm_crtc at runtime we would have to decrement all | ||||||||||||||||||
502 | * the indices on the drm_crtc after us in the crtc_list. | ||||||||||||||||||
503 | */ | ||||||||||||||||||
504 | |||||||||||||||||||
505 | drm_crtc_crc_fini(crtc); | ||||||||||||||||||
506 | |||||||||||||||||||
507 | kfree(crtc->gamma_store); | ||||||||||||||||||
508 | crtc->gamma_store = NULL((void *)0); | ||||||||||||||||||
509 | |||||||||||||||||||
510 | drm_modeset_lock_fini(&crtc->mutex); | ||||||||||||||||||
511 | |||||||||||||||||||
512 | drm_mode_object_unregister(dev, &crtc->base); | ||||||||||||||||||
513 | list_del(&crtc->head); | ||||||||||||||||||
514 | dev->mode_config.num_crtc--; | ||||||||||||||||||
515 | |||||||||||||||||||
516 | WARN_ON(crtc->state && !crtc->funcs->atomic_destroy_state)({ int __ret = !!(crtc->state && !crtc->funcs-> atomic_destroy_state); if (__ret) printf("WARNING %s failed at %s:%d\n" , "crtc->state && !crtc->funcs->atomic_destroy_state" , "/usr/src/sys/dev/pci/drm/drm_crtc.c", 516); __builtin_expect (!!(__ret), 0); }); | ||||||||||||||||||
517 | if (crtc->state && crtc->funcs->atomic_destroy_state) | ||||||||||||||||||
518 | crtc->funcs->atomic_destroy_state(crtc, crtc->state); | ||||||||||||||||||
519 | |||||||||||||||||||
520 | kfree(crtc->name); | ||||||||||||||||||
521 | |||||||||||||||||||
522 | memset(crtc, 0, sizeof(*crtc))__builtin_memset((crtc), (0), (sizeof(*crtc))); | ||||||||||||||||||
523 | } | ||||||||||||||||||
524 | EXPORT_SYMBOL(drm_crtc_cleanup); | ||||||||||||||||||
525 | |||||||||||||||||||
526 | /** | ||||||||||||||||||
527 | * drm_mode_getcrtc - get CRTC configuration | ||||||||||||||||||
528 | * @dev: drm device for the ioctl | ||||||||||||||||||
529 | * @data: data pointer for the ioctl | ||||||||||||||||||
530 | * @file_priv: drm file for the ioctl call | ||||||||||||||||||
531 | * | ||||||||||||||||||
532 | * Construct a CRTC configuration structure to return to the user. | ||||||||||||||||||
533 | * | ||||||||||||||||||
534 | * Called by the user via ioctl. | ||||||||||||||||||
535 | * | ||||||||||||||||||
536 | * Returns: | ||||||||||||||||||
537 | * Zero on success, negative errno on failure. | ||||||||||||||||||
538 | */ | ||||||||||||||||||
539 | int drm_mode_getcrtc(struct drm_device *dev, | ||||||||||||||||||
540 | void *data, struct drm_file *file_priv) | ||||||||||||||||||
541 | { | ||||||||||||||||||
542 | struct drm_mode_crtc *crtc_resp = data; | ||||||||||||||||||
543 | struct drm_crtc *crtc; | ||||||||||||||||||
544 | struct drm_plane *plane; | ||||||||||||||||||
545 | |||||||||||||||||||
546 | if (!drm_core_check_feature(dev, DRIVER_MODESET)) | ||||||||||||||||||
547 | return -EOPNOTSUPP45; | ||||||||||||||||||
548 | |||||||||||||||||||
549 | crtc = drm_crtc_find(dev, file_priv, crtc_resp->crtc_id); | ||||||||||||||||||
550 | if (!crtc) | ||||||||||||||||||
551 | return -ENOENT2; | ||||||||||||||||||
552 | |||||||||||||||||||
553 | plane = crtc->primary; | ||||||||||||||||||
554 | |||||||||||||||||||
555 | crtc_resp->gamma_size = crtc->gamma_size; | ||||||||||||||||||
556 | |||||||||||||||||||
557 | drm_modeset_lock(&plane->mutex, NULL((void *)0)); | ||||||||||||||||||
558 | if (plane->state && plane->state->fb) | ||||||||||||||||||
559 | crtc_resp->fb_id = plane->state->fb->base.id; | ||||||||||||||||||
560 | else if (!plane->state && plane->fb) | ||||||||||||||||||
561 | crtc_resp->fb_id = plane->fb->base.id; | ||||||||||||||||||
562 | else | ||||||||||||||||||
563 | crtc_resp->fb_id = 0; | ||||||||||||||||||
564 | |||||||||||||||||||
565 | if (plane->state) { | ||||||||||||||||||
566 | crtc_resp->x = plane->state->src_x >> 16; | ||||||||||||||||||
567 | crtc_resp->y = plane->state->src_y >> 16; | ||||||||||||||||||
568 | } | ||||||||||||||||||
569 | drm_modeset_unlock(&plane->mutex); | ||||||||||||||||||
570 | |||||||||||||||||||
571 | drm_modeset_lock(&crtc->mutex, NULL((void *)0)); | ||||||||||||||||||
572 | if (crtc->state) { | ||||||||||||||||||
573 | if (crtc->state->enable) { | ||||||||||||||||||
574 | drm_mode_convert_to_umode(&crtc_resp->mode, &crtc->state->mode); | ||||||||||||||||||
575 | crtc_resp->mode_valid = 1; | ||||||||||||||||||
576 | } else { | ||||||||||||||||||
577 | crtc_resp->mode_valid = 0; | ||||||||||||||||||
578 | } | ||||||||||||||||||
579 | } else { | ||||||||||||||||||
580 | crtc_resp->x = crtc->x; | ||||||||||||||||||
581 | crtc_resp->y = crtc->y; | ||||||||||||||||||
582 | |||||||||||||||||||
583 | if (crtc->enabled) { | ||||||||||||||||||
584 | drm_mode_convert_to_umode(&crtc_resp->mode, &crtc->mode); | ||||||||||||||||||
585 | crtc_resp->mode_valid = 1; | ||||||||||||||||||
586 | |||||||||||||||||||
587 | } else { | ||||||||||||||||||
588 | crtc_resp->mode_valid = 0; | ||||||||||||||||||
589 | } | ||||||||||||||||||
590 | } | ||||||||||||||||||
591 | if (!file_priv->aspect_ratio_allowed) | ||||||||||||||||||
592 | crtc_resp->mode.flags &= ~DRM_MODE_FLAG_PIC_AR_MASK(0x0F<<19); | ||||||||||||||||||
593 | drm_modeset_unlock(&crtc->mutex); | ||||||||||||||||||
594 | |||||||||||||||||||
595 | return 0; | ||||||||||||||||||
596 | } | ||||||||||||||||||
597 | |||||||||||||||||||
598 | static int __drm_mode_set_config_internal(struct drm_mode_set *set, | ||||||||||||||||||
599 | struct drm_modeset_acquire_ctx *ctx) | ||||||||||||||||||
600 | { | ||||||||||||||||||
601 | struct drm_crtc *crtc = set->crtc; | ||||||||||||||||||
602 | struct drm_framebuffer *fb; | ||||||||||||||||||
603 | struct drm_crtc *tmp; | ||||||||||||||||||
604 | int ret; | ||||||||||||||||||
605 | |||||||||||||||||||
606 | WARN_ON(drm_drv_uses_atomic_modeset(crtc->dev))({ int __ret = !!(drm_drv_uses_atomic_modeset(crtc->dev)); if (__ret) printf("WARNING %s failed at %s:%d\n", "drm_drv_uses_atomic_modeset(crtc->dev)" , "/usr/src/sys/dev/pci/drm/drm_crtc.c", 606); __builtin_expect (!!(__ret), 0); }); | ||||||||||||||||||
607 | |||||||||||||||||||
608 | /* | ||||||||||||||||||
609 | * NOTE: ->set_config can also disable other crtcs (if we steal all | ||||||||||||||||||
610 | * connectors from it), hence we need to refcount the fbs across all | ||||||||||||||||||
611 | * crtcs. Atomic modeset will have saner semantics ... | ||||||||||||||||||
612 | */ | ||||||||||||||||||
613 | drm_for_each_crtc(tmp, crtc->dev)for (tmp = ({ const __typeof( ((__typeof(*tmp) *)0)->head ) *__mptr = ((&(crtc->dev)->mode_config.crtc_list)-> next); (__typeof(*tmp) *)( (char *)__mptr - __builtin_offsetof (__typeof(*tmp), head) );}); &tmp->head != (&(crtc ->dev)->mode_config.crtc_list); tmp = ({ const __typeof ( ((__typeof(*tmp) *)0)->head ) *__mptr = (tmp->head.next ); (__typeof(*tmp) *)( (char *)__mptr - __builtin_offsetof(__typeof (*tmp), head) );})) { | ||||||||||||||||||
614 | struct drm_plane *plane = tmp->primary; | ||||||||||||||||||
615 | |||||||||||||||||||
616 | plane->old_fb = plane->fb; | ||||||||||||||||||
617 | } | ||||||||||||||||||
618 | |||||||||||||||||||
619 | fb = set->fb; | ||||||||||||||||||
620 | |||||||||||||||||||
621 | ret = crtc->funcs->set_config(set, ctx); | ||||||||||||||||||
622 | if (ret == 0) { | ||||||||||||||||||
623 | struct drm_plane *plane = crtc->primary; | ||||||||||||||||||
624 | |||||||||||||||||||
625 | plane->crtc = fb ? crtc : NULL((void *)0); | ||||||||||||||||||
626 | plane->fb = fb; | ||||||||||||||||||
627 | } | ||||||||||||||||||
628 | |||||||||||||||||||
629 | drm_for_each_crtc(tmp, crtc->dev)for (tmp = ({ const __typeof( ((__typeof(*tmp) *)0)->head ) *__mptr = ((&(crtc->dev)->mode_config.crtc_list)-> next); (__typeof(*tmp) *)( (char *)__mptr - __builtin_offsetof (__typeof(*tmp), head) );}); &tmp->head != (&(crtc ->dev)->mode_config.crtc_list); tmp = ({ const __typeof ( ((__typeof(*tmp) *)0)->head ) *__mptr = (tmp->head.next ); (__typeof(*tmp) *)( (char *)__mptr - __builtin_offsetof(__typeof (*tmp), head) );})) { | ||||||||||||||||||
630 | struct drm_plane *plane = tmp->primary; | ||||||||||||||||||
631 | |||||||||||||||||||
632 | if (plane->fb) | ||||||||||||||||||
633 | drm_framebuffer_get(plane->fb); | ||||||||||||||||||
634 | if (plane->old_fb) | ||||||||||||||||||
635 | drm_framebuffer_put(plane->old_fb); | ||||||||||||||||||
636 | plane->old_fb = NULL((void *)0); | ||||||||||||||||||
637 | } | ||||||||||||||||||
638 | |||||||||||||||||||
639 | return ret; | ||||||||||||||||||
640 | } | ||||||||||||||||||
641 | |||||||||||||||||||
642 | /** | ||||||||||||||||||
643 | * drm_mode_set_config_internal - helper to call &drm_mode_config_funcs.set_config | ||||||||||||||||||
644 | * @set: modeset config to set | ||||||||||||||||||
645 | * | ||||||||||||||||||
646 | * This is a little helper to wrap internal calls to the | ||||||||||||||||||
647 | * &drm_mode_config_funcs.set_config driver interface. The only thing it adds is | ||||||||||||||||||
648 | * correct refcounting dance. | ||||||||||||||||||
649 | * | ||||||||||||||||||
650 | * This should only be used by non-atomic legacy drivers. | ||||||||||||||||||
651 | * | ||||||||||||||||||
652 | * Returns: | ||||||||||||||||||
653 | * Zero on success, negative errno on failure. | ||||||||||||||||||
654 | */ | ||||||||||||||||||
655 | int drm_mode_set_config_internal(struct drm_mode_set *set) | ||||||||||||||||||
656 | { | ||||||||||||||||||
657 | WARN_ON(drm_drv_uses_atomic_modeset(set->crtc->dev))({ int __ret = !!(drm_drv_uses_atomic_modeset(set->crtc-> dev)); if (__ret) printf("WARNING %s failed at %s:%d\n", "drm_drv_uses_atomic_modeset(set->crtc->dev)" , "/usr/src/sys/dev/pci/drm/drm_crtc.c", 657); __builtin_expect (!!(__ret), 0); }); | ||||||||||||||||||
658 | |||||||||||||||||||
659 | return __drm_mode_set_config_internal(set, NULL((void *)0)); | ||||||||||||||||||
660 | } | ||||||||||||||||||
661 | EXPORT_SYMBOL(drm_mode_set_config_internal); | ||||||||||||||||||
662 | |||||||||||||||||||
663 | /** | ||||||||||||||||||
664 | * drm_crtc_check_viewport - Checks that a framebuffer is big enough for the | ||||||||||||||||||
665 | * CRTC viewport | ||||||||||||||||||
666 | * @crtc: CRTC that framebuffer will be displayed on | ||||||||||||||||||
667 | * @x: x panning | ||||||||||||||||||
668 | * @y: y panning | ||||||||||||||||||
669 | * @mode: mode that framebuffer will be displayed under | ||||||||||||||||||
670 | * @fb: framebuffer to check size of | ||||||||||||||||||
671 | */ | ||||||||||||||||||
672 | int drm_crtc_check_viewport(const struct drm_crtc *crtc, | ||||||||||||||||||
673 | int x, int y, | ||||||||||||||||||
674 | const struct drm_display_mode *mode, | ||||||||||||||||||
675 | const struct drm_framebuffer *fb) | ||||||||||||||||||
676 | |||||||||||||||||||
677 | { | ||||||||||||||||||
678 | int hdisplay, vdisplay; | ||||||||||||||||||
679 | |||||||||||||||||||
680 | drm_mode_get_hv_timing(mode, &hdisplay, &vdisplay); | ||||||||||||||||||
681 | |||||||||||||||||||
682 | if (crtc->state && | ||||||||||||||||||
683 | drm_rotation_90_or_270(crtc->primary->state->rotation)) | ||||||||||||||||||
684 | swap(hdisplay, vdisplay)do { __typeof(hdisplay) __tmp = (hdisplay); (hdisplay) = (vdisplay ); (vdisplay) = __tmp; } while(0); | ||||||||||||||||||
685 | |||||||||||||||||||
686 | return drm_framebuffer_check_src_coords(x << 16, y << 16, | ||||||||||||||||||
687 | hdisplay << 16, vdisplay << 16, | ||||||||||||||||||
688 | fb); | ||||||||||||||||||
689 | } | ||||||||||||||||||
690 | EXPORT_SYMBOL(drm_crtc_check_viewport); | ||||||||||||||||||
691 | |||||||||||||||||||
692 | /** | ||||||||||||||||||
693 | * drm_mode_setcrtc - set CRTC configuration | ||||||||||||||||||
694 | * @dev: drm device for the ioctl | ||||||||||||||||||
695 | * @data: data pointer for the ioctl | ||||||||||||||||||
696 | * @file_priv: drm file for the ioctl call | ||||||||||||||||||
697 | * | ||||||||||||||||||
698 | * Build a new CRTC configuration based on user request. | ||||||||||||||||||
699 | * | ||||||||||||||||||
700 | * Called by the user via ioctl. | ||||||||||||||||||
701 | * | ||||||||||||||||||
702 | * Returns: | ||||||||||||||||||
703 | * Zero on success, negative errno on failure. | ||||||||||||||||||
704 | */ | ||||||||||||||||||
705 | int drm_mode_setcrtc(struct drm_device *dev, void *data, | ||||||||||||||||||
706 | struct drm_file *file_priv) | ||||||||||||||||||
707 | { | ||||||||||||||||||
708 | struct drm_mode_config *config = &dev->mode_config; | ||||||||||||||||||
709 | struct drm_mode_crtc *crtc_req = data; | ||||||||||||||||||
710 | struct drm_crtc *crtc; | ||||||||||||||||||
711 | struct drm_plane *plane; | ||||||||||||||||||
712 | struct drm_connector **connector_set = NULL((void *)0), *connector; | ||||||||||||||||||
713 | struct drm_framebuffer *fb = NULL((void *)0); | ||||||||||||||||||
714 | struct drm_display_mode *mode = NULL((void *)0); | ||||||||||||||||||
715 | struct drm_mode_set set; | ||||||||||||||||||
716 | uint32_t __user *set_connectors_ptr; | ||||||||||||||||||
717 | struct drm_modeset_acquire_ctx ctx; | ||||||||||||||||||
718 | int ret; | ||||||||||||||||||
719 | int i; | ||||||||||||||||||
720 | |||||||||||||||||||
721 | if (!drm_core_check_feature(dev, DRIVER_MODESET)) | ||||||||||||||||||
722 | return -EOPNOTSUPP45; | ||||||||||||||||||
723 | |||||||||||||||||||
724 | /* | ||||||||||||||||||
725 | * Universal plane src offsets are only 16.16, prevent havoc for | ||||||||||||||||||
726 | * drivers using universal plane code internally. | ||||||||||||||||||
727 | */ | ||||||||||||||||||
728 | if (crtc_req->x & 0xffff0000 || crtc_req->y & 0xffff0000) | ||||||||||||||||||
| |||||||||||||||||||
729 | return -ERANGE34; | ||||||||||||||||||
730 | |||||||||||||||||||
731 | crtc = drm_crtc_find(dev, file_priv, crtc_req->crtc_id); | ||||||||||||||||||
732 | if (!crtc
| ||||||||||||||||||
733 | DRM_DEBUG_KMS("Unknown CRTC ID %d\n", crtc_req->crtc_id)___drm_dbg(((void *)0), DRM_UT_KMS, "Unknown CRTC ID %d\n", crtc_req ->crtc_id); | ||||||||||||||||||
734 | return -ENOENT2; | ||||||||||||||||||
735 | } | ||||||||||||||||||
736 | DRM_DEBUG_KMS("[CRTC:%d:%s]\n", crtc->base.id, crtc->name)___drm_dbg(((void *)0), DRM_UT_KMS, "[CRTC:%d:%s]\n", crtc-> base.id, crtc->name); | ||||||||||||||||||
737 | |||||||||||||||||||
738 | plane = crtc->primary; | ||||||||||||||||||
739 | |||||||||||||||||||
740 | /* allow disabling with the primary plane leased */ | ||||||||||||||||||
741 | if (crtc_req->mode_valid && !drm_lease_held(file_priv, plane->base.id)(1)) | ||||||||||||||||||
742 | return -EACCES13; | ||||||||||||||||||
743 | |||||||||||||||||||
744 | DRM_MODESET_LOCK_ALL_BEGIN(dev, ctx,if (!drm_drv_uses_atomic_modeset(dev)) rw_enter_write(&dev ->mode_config.mutex); drm_modeset_acquire_init(&ctx, ( 1UL << (0))); modeset_lock_retry: ret = drm_modeset_lock_all_ctx (dev, &ctx); if (ret) goto modeset_lock_fail; | ||||||||||||||||||
745 | DRM_MODESET_ACQUIRE_INTERRUPTIBLE, ret)if (!drm_drv_uses_atomic_modeset(dev)) rw_enter_write(&dev ->mode_config.mutex); drm_modeset_acquire_init(&ctx, ( 1UL << (0))); modeset_lock_retry: ret = drm_modeset_lock_all_ctx (dev, &ctx); if (ret) goto modeset_lock_fail;; | ||||||||||||||||||
746 | |||||||||||||||||||
747 | if (crtc_req->mode_valid
| ||||||||||||||||||
748 | /* If we have a mode we need a framebuffer. */ | ||||||||||||||||||
749 | /* If we pass -1, set the mode with the currently bound fb */ | ||||||||||||||||||
750 | if (crtc_req->fb_id == -1) { | ||||||||||||||||||
751 | struct drm_framebuffer *old_fb; | ||||||||||||||||||
752 | |||||||||||||||||||
753 | if (plane->state) | ||||||||||||||||||
754 | old_fb = plane->state->fb; | ||||||||||||||||||
755 | else | ||||||||||||||||||
756 | old_fb = plane->fb; | ||||||||||||||||||
757 | |||||||||||||||||||
758 | if (!old_fb) { | ||||||||||||||||||
759 | DRM_DEBUG_KMS("CRTC doesn't have current FB\n")___drm_dbg(((void *)0), DRM_UT_KMS, "CRTC doesn't have current FB\n" ); | ||||||||||||||||||
760 | ret = -EINVAL22; | ||||||||||||||||||
761 | goto out; | ||||||||||||||||||
762 | } | ||||||||||||||||||
763 | |||||||||||||||||||
764 | fb = old_fb; | ||||||||||||||||||
765 | /* Make refcounting symmetric with the lookup path. */ | ||||||||||||||||||
766 | drm_framebuffer_get(fb); | ||||||||||||||||||
767 | } else { | ||||||||||||||||||
768 | fb = drm_framebuffer_lookup(dev, file_priv, crtc_req->fb_id); | ||||||||||||||||||
769 | if (!fb) { | ||||||||||||||||||
770 | DRM_DEBUG_KMS("Unknown FB ID%d\n",___drm_dbg(((void *)0), DRM_UT_KMS, "Unknown FB ID%d\n", crtc_req ->fb_id) | ||||||||||||||||||
771 | crtc_req->fb_id)___drm_dbg(((void *)0), DRM_UT_KMS, "Unknown FB ID%d\n", crtc_req ->fb_id); | ||||||||||||||||||
772 | ret = -ENOENT2; | ||||||||||||||||||
773 | goto out; | ||||||||||||||||||
774 | } | ||||||||||||||||||
775 | } | ||||||||||||||||||
776 | |||||||||||||||||||
777 | mode = drm_mode_create(dev); | ||||||||||||||||||
778 | if (!mode) { | ||||||||||||||||||
779 | ret = -ENOMEM12; | ||||||||||||||||||
780 | goto out; | ||||||||||||||||||
781 | } | ||||||||||||||||||
782 | if (!file_priv->aspect_ratio_allowed && | ||||||||||||||||||
783 | (crtc_req->mode.flags & DRM_MODE_FLAG_PIC_AR_MASK(0x0F<<19)) != DRM_MODE_FLAG_PIC_AR_NONE(0<<19)) { | ||||||||||||||||||
784 | DRM_DEBUG_KMS("Unexpected aspect-ratio flag bits\n")___drm_dbg(((void *)0), DRM_UT_KMS, "Unexpected aspect-ratio flag bits\n" ); | ||||||||||||||||||
785 | ret = -EINVAL22; | ||||||||||||||||||
786 | goto out; | ||||||||||||||||||
787 | } | ||||||||||||||||||
788 | |||||||||||||||||||
789 | |||||||||||||||||||
790 | ret = drm_mode_convert_umode(dev, mode, &crtc_req->mode); | ||||||||||||||||||
791 | if (ret) { | ||||||||||||||||||
792 | DRM_DEBUG_KMS("Invalid mode (ret=%d, status=%s)\n",___drm_dbg(((void *)0), DRM_UT_KMS, "Invalid mode (ret=%d, status=%s)\n" , ret, drm_get_mode_status_name(mode->status)) | ||||||||||||||||||
793 | ret, drm_get_mode_status_name(mode->status))___drm_dbg(((void *)0), DRM_UT_KMS, "Invalid mode (ret=%d, status=%s)\n" , ret, drm_get_mode_status_name(mode->status)); | ||||||||||||||||||
794 | drm_mode_debug_printmodeline(mode); | ||||||||||||||||||
795 | goto out; | ||||||||||||||||||
796 | } | ||||||||||||||||||
797 | |||||||||||||||||||
798 | /* | ||||||||||||||||||
799 | * Check whether the primary plane supports the fb pixel format. | ||||||||||||||||||
800 | * Drivers not implementing the universal planes API use a | ||||||||||||||||||
801 | * default formats list provided by the DRM core which doesn't | ||||||||||||||||||
802 | * match real hardware capabilities. Skip the check in that | ||||||||||||||||||
803 | * case. | ||||||||||||||||||
804 | */ | ||||||||||||||||||
805 | if (!plane->format_default) { | ||||||||||||||||||
806 | ret = drm_plane_check_pixel_format(plane, | ||||||||||||||||||
807 | fb->format->format, | ||||||||||||||||||
808 | fb->modifier); | ||||||||||||||||||
809 | if (ret) { | ||||||||||||||||||
810 | DRM_DEBUG_KMS("Invalid pixel format %p4cc, modifier 0x%llx\n",___drm_dbg(((void *)0), DRM_UT_KMS, "Invalid pixel format %p4cc, modifier 0x%llx\n" , &fb->format->format, fb->modifier) | ||||||||||||||||||
811 | &fb->format->format,___drm_dbg(((void *)0), DRM_UT_KMS, "Invalid pixel format %p4cc, modifier 0x%llx\n" , &fb->format->format, fb->modifier) | ||||||||||||||||||
812 | fb->modifier)___drm_dbg(((void *)0), DRM_UT_KMS, "Invalid pixel format %p4cc, modifier 0x%llx\n" , &fb->format->format, fb->modifier); | ||||||||||||||||||
813 | goto out; | ||||||||||||||||||
814 | } | ||||||||||||||||||
815 | } | ||||||||||||||||||
816 | |||||||||||||||||||
817 | ret = drm_crtc_check_viewport(crtc, crtc_req->x, crtc_req->y, | ||||||||||||||||||
818 | mode, fb); | ||||||||||||||||||
819 | if (ret) | ||||||||||||||||||
820 | goto out; | ||||||||||||||||||
821 | |||||||||||||||||||
822 | } | ||||||||||||||||||
823 | |||||||||||||||||||
824 | if (crtc_req->count_connectors == 0 && mode) { | ||||||||||||||||||
825 | DRM_DEBUG_KMS("Count connectors is 0 but mode set\n")___drm_dbg(((void *)0), DRM_UT_KMS, "Count connectors is 0 but mode set\n" ); | ||||||||||||||||||
826 | ret = -EINVAL22; | ||||||||||||||||||
827 | goto out; | ||||||||||||||||||
828 | } | ||||||||||||||||||
829 | |||||||||||||||||||
830 | if (crtc_req->count_connectors
| ||||||||||||||||||
831 | DRM_DEBUG_KMS("Count connectors is %d but no mode or fb set\n",___drm_dbg(((void *)0), DRM_UT_KMS, "Count connectors is %d but no mode or fb set\n" , crtc_req->count_connectors) | ||||||||||||||||||
832 | crtc_req->count_connectors)___drm_dbg(((void *)0), DRM_UT_KMS, "Count connectors is %d but no mode or fb set\n" , crtc_req->count_connectors); | ||||||||||||||||||
833 | ret = -EINVAL22; | ||||||||||||||||||
834 | goto out; | ||||||||||||||||||
835 | } | ||||||||||||||||||
836 | |||||||||||||||||||
837 | if (crtc_req->count_connectors
| ||||||||||||||||||
838 | u32 out_id; | ||||||||||||||||||
839 | |||||||||||||||||||
840 | /* Avoid unbounded kernel memory allocation */ | ||||||||||||||||||
841 | if (crtc_req->count_connectors > config->num_connector) { | ||||||||||||||||||
842 | ret = -EINVAL22; | ||||||||||||||||||
843 | goto out; | ||||||||||||||||||
844 | } | ||||||||||||||||||
845 | |||||||||||||||||||
846 | connector_set = kmalloc_array(crtc_req->count_connectors, | ||||||||||||||||||
847 | sizeof(struct drm_connector *), | ||||||||||||||||||
848 | GFP_KERNEL(0x0001 | 0x0004)); | ||||||||||||||||||
849 | if (!connector_set) { | ||||||||||||||||||
850 | ret = -ENOMEM12; | ||||||||||||||||||
851 | goto out; | ||||||||||||||||||
852 | } | ||||||||||||||||||
853 | |||||||||||||||||||
854 | for (i = 0; i
| ||||||||||||||||||
855 | connector_set[i] = NULL((void *)0); | ||||||||||||||||||
856 | set_connectors_ptr = (uint32_t __user *)(unsigned long)crtc_req->set_connectors_ptr; | ||||||||||||||||||
857 | if (get_user(out_id, &set_connectors_ptr[i])-copyin(&set_connectors_ptr[i], &(out_id), sizeof(out_id ))) { | ||||||||||||||||||
858 | ret = -EFAULT14; | ||||||||||||||||||
859 | goto out; | ||||||||||||||||||
860 | } | ||||||||||||||||||
861 | |||||||||||||||||||
862 | connector = drm_connector_lookup(dev, file_priv, out_id); | ||||||||||||||||||
863 | if (!connector) { | ||||||||||||||||||
864 | DRM_DEBUG_KMS("Connector id %d unknown\n",___drm_dbg(((void *)0), DRM_UT_KMS, "Connector id %d unknown\n" , out_id) | ||||||||||||||||||
865 | out_id)___drm_dbg(((void *)0), DRM_UT_KMS, "Connector id %d unknown\n" , out_id); | ||||||||||||||||||
866 | ret = -ENOENT2; | ||||||||||||||||||
867 | goto out; | ||||||||||||||||||
868 | } | ||||||||||||||||||
869 | DRM_DEBUG_KMS("[CONNECTOR:%d:%s]\n",___drm_dbg(((void *)0), DRM_UT_KMS, "[CONNECTOR:%d:%s]\n", connector ->base.id, connector->name) | ||||||||||||||||||
870 | connector->base.id,___drm_dbg(((void *)0), DRM_UT_KMS, "[CONNECTOR:%d:%s]\n", connector ->base.id, connector->name) | ||||||||||||||||||
871 | connector->name)___drm_dbg(((void *)0), DRM_UT_KMS, "[CONNECTOR:%d:%s]\n", connector ->base.id, connector->name); | ||||||||||||||||||
872 | |||||||||||||||||||
873 | connector_set[i] = connector; | ||||||||||||||||||
874 | } | ||||||||||||||||||
875 | } | ||||||||||||||||||
876 | |||||||||||||||||||
877 | set.crtc = crtc; | ||||||||||||||||||
878 | set.x = crtc_req->x; | ||||||||||||||||||
879 | set.y = crtc_req->y; | ||||||||||||||||||
880 | set.mode = mode; | ||||||||||||||||||
881 | set.connectors = connector_set; | ||||||||||||||||||
882 | set.num_connectors = crtc_req->count_connectors; | ||||||||||||||||||
883 | set.fb = fb; | ||||||||||||||||||
884 | |||||||||||||||||||
885 | if (drm_drv_uses_atomic_modeset(dev)) | ||||||||||||||||||
886 | ret = crtc->funcs->set_config(&set, &ctx); | ||||||||||||||||||
887 | else | ||||||||||||||||||
888 | ret = __drm_mode_set_config_internal(&set, &ctx); | ||||||||||||||||||
889 | |||||||||||||||||||
890 | out: | ||||||||||||||||||
891 | if (fb
| ||||||||||||||||||
892 | drm_framebuffer_put(fb); | ||||||||||||||||||
893 | |||||||||||||||||||
894 | if (connector_set
| ||||||||||||||||||
895 | for (i = 0; i
| ||||||||||||||||||
896 | if (connector_set[i]) | ||||||||||||||||||
| |||||||||||||||||||
897 | drm_connector_put(connector_set[i]); | ||||||||||||||||||
898 | } | ||||||||||||||||||
899 | } | ||||||||||||||||||
900 | kfree(connector_set); | ||||||||||||||||||
901 | drm_mode_destroy(dev, mode); | ||||||||||||||||||
902 | |||||||||||||||||||
903 | /* In case we need to retry... */ | ||||||||||||||||||
904 | connector_set = NULL((void *)0); | ||||||||||||||||||
905 | fb = NULL((void *)0); | ||||||||||||||||||
906 | mode = NULL((void *)0); | ||||||||||||||||||
907 | |||||||||||||||||||
908 | DRM_MODESET_LOCK_ALL_END(dev, ctx, ret)modeset_lock_fail: if (ret == -11) { ret = drm_modeset_backoff (&ctx); if (!ret) goto modeset_lock_retry; } drm_modeset_drop_locks (&ctx); drm_modeset_acquire_fini(&ctx); if (!drm_drv_uses_atomic_modeset (dev)) rw_exit_write(&dev->mode_config.mutex);; | ||||||||||||||||||
909 | |||||||||||||||||||
910 | return ret; | ||||||||||||||||||
911 | } | ||||||||||||||||||
912 | |||||||||||||||||||
913 | int drm_mode_crtc_set_obj_prop(struct drm_mode_object *obj, | ||||||||||||||||||
914 | struct drm_property *property, | ||||||||||||||||||
915 | uint64_t value) | ||||||||||||||||||
916 | { | ||||||||||||||||||
917 | int ret = -EINVAL22; | ||||||||||||||||||
918 | struct drm_crtc *crtc = obj_to_crtc(obj)({ const __typeof( ((struct drm_crtc *)0)->base ) *__mptr = (obj); (struct drm_crtc *)( (char *)__mptr - __builtin_offsetof (struct drm_crtc, base) );}); | ||||||||||||||||||
919 | |||||||||||||||||||
920 | if (crtc->funcs->set_property) | ||||||||||||||||||
921 | ret = crtc->funcs->set_property(crtc, property, value); | ||||||||||||||||||
922 | if (!ret) | ||||||||||||||||||
923 | drm_object_property_set_value(obj, property, value); | ||||||||||||||||||
924 | |||||||||||||||||||
925 | return ret; | ||||||||||||||||||
926 | } | ||||||||||||||||||
927 | |||||||||||||||||||
928 | /** | ||||||||||||||||||
929 | * drm_crtc_create_scaling_filter_property - create a new scaling filter | ||||||||||||||||||
930 | * property | ||||||||||||||||||
931 | * | ||||||||||||||||||
932 | * @crtc: drm CRTC | ||||||||||||||||||
933 | * @supported_filters: bitmask of supported scaling filters, must include | ||||||||||||||||||
934 | * BIT(DRM_SCALING_FILTER_DEFAULT). | ||||||||||||||||||
935 | * | ||||||||||||||||||
936 | * This function lets driver to enable the scaling filter property on a given | ||||||||||||||||||
937 | * CRTC. | ||||||||||||||||||
938 | * | ||||||||||||||||||
939 | * RETURNS: | ||||||||||||||||||
940 | * Zero for success or -errno | ||||||||||||||||||
941 | */ | ||||||||||||||||||
942 | int drm_crtc_create_scaling_filter_property(struct drm_crtc *crtc, | ||||||||||||||||||
943 | unsigned int supported_filters) | ||||||||||||||||||
944 | { | ||||||||||||||||||
945 | struct drm_property *prop = | ||||||||||||||||||
946 | drm_create_scaling_filter_prop(crtc->dev, supported_filters); | ||||||||||||||||||
947 | |||||||||||||||||||
948 | if (IS_ERR(prop)) | ||||||||||||||||||
949 | return PTR_ERR(prop); | ||||||||||||||||||
950 | |||||||||||||||||||
951 | drm_object_attach_property(&crtc->base, prop, | ||||||||||||||||||
952 | DRM_SCALING_FILTER_DEFAULT); | ||||||||||||||||||
953 | crtc->scaling_filter_property = prop; | ||||||||||||||||||
954 | |||||||||||||||||||
955 | return 0; | ||||||||||||||||||
956 | } | ||||||||||||||||||
957 | EXPORT_SYMBOL(drm_crtc_create_scaling_filter_property); |
1 | /* |
2 | * Copyright © 2006 Keith Packard |
3 | * Copyright © 2007-2008 Dave Airlie |
4 | * Copyright © 2007-2008 Intel Corporation |
5 | * Jesse Barnes <jesse.barnes@intel.com> |
6 | * |
7 | * Permission is hereby granted, free of charge, to any person obtaining a |
8 | * copy of this software and associated documentation files (the "Software"), |
9 | * to deal in the Software without restriction, including without limitation |
10 | * the rights to use, copy, modify, merge, publish, distribute, sublicense, |
11 | * and/or sell copies of the Software, and to permit persons to whom the |
12 | * Software is furnished to do so, subject to the following conditions: |
13 | * |
14 | * The above copyright notice and this permission notice shall be included in |
15 | * all copies or substantial portions of the Software. |
16 | * |
17 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR |
18 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, |
19 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL |
20 | * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR |
21 | * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, |
22 | * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR |
23 | * OTHER DEALINGS IN THE SOFTWARE. |
24 | */ |
25 | #ifndef __DRM_CRTC_H__ |
26 | #define __DRM_CRTC_H__ |
27 | |
28 | #include <linux/spinlock.h> |
29 | #include <linux/types.h> |
30 | #include <drm/drm_modeset_lock.h> |
31 | #include <drm/drm_mode_object.h> |
32 | #include <drm/drm_modes.h> |
33 | #include <drm/drm_device.h> |
34 | #include <drm/drm_plane.h> |
35 | #include <drm/drm_debugfs_crc.h> |
36 | #include <drm/drm_mode_config.h> |
37 | |
38 | struct drm_connector; |
39 | struct drm_device; |
40 | struct drm_framebuffer; |
41 | struct drm_mode_set; |
42 | struct drm_file; |
43 | struct drm_printer; |
44 | struct drm_self_refresh_data; |
45 | struct device_node; |
46 | struct edid; |
47 | |
48 | static inline int64_t U642I64(uint64_t val) |
49 | { |
50 | return (int64_t)*((int64_t *)&val); |
51 | } |
52 | static inline uint64_t I642U64(int64_t val) |
53 | { |
54 | return (uint64_t)*((uint64_t *)&val); |
55 | } |
56 | |
57 | struct drm_crtc; |
58 | struct drm_pending_vblank_event; |
59 | struct drm_plane; |
60 | struct drm_bridge; |
61 | struct drm_atomic_state; |
62 | |
63 | struct drm_crtc_helper_funcs; |
64 | struct drm_plane_helper_funcs; |
65 | |
66 | /** |
67 | * struct drm_crtc_state - mutable CRTC state |
68 | * |
69 | * Note that the distinction between @enable and @active is rather subtle: |
70 | * Flipping @active while @enable is set without changing anything else may |
71 | * never return in a failure from the &drm_mode_config_funcs.atomic_check |
72 | * callback. Userspace assumes that a DPMS On will always succeed. In other |
73 | * words: @enable controls resource assignment, @active controls the actual |
74 | * hardware state. |
75 | * |
76 | * The three booleans active_changed, connectors_changed and mode_changed are |
77 | * intended to indicate whether a full modeset is needed, rather than strictly |
78 | * describing what has changed in a commit. See also: |
79 | * drm_atomic_crtc_needs_modeset() |
80 | * |
81 | * WARNING: Transitional helpers (like drm_helper_crtc_mode_set() or |
82 | * drm_helper_crtc_mode_set_base()) do not maintain many of the derived control |
83 | * state like @plane_mask so drivers not converted over to atomic helpers should |
84 | * not rely on these being accurate! |
85 | */ |
86 | struct drm_crtc_state { |
87 | /** @crtc: backpointer to the CRTC */ |
88 | struct drm_crtc *crtc; |
89 | |
90 | /** |
91 | * @enable: Whether the CRTC should be enabled, gates all other state. |
92 | * This controls reservations of shared resources. Actual hardware state |
93 | * is controlled by @active. |
94 | */ |
95 | bool_Bool enable; |
96 | |
97 | /** |
98 | * @active: Whether the CRTC is actively displaying (used for DPMS). |
99 | * Implies that @enable is set. The driver must not release any shared |
100 | * resources if @active is set to false but @enable still true, because |
101 | * userspace expects that a DPMS ON always succeeds. |
102 | * |
103 | * Hence drivers must not consult @active in their various |
104 | * &drm_mode_config_funcs.atomic_check callback to reject an atomic |
105 | * commit. They can consult it to aid in the computation of derived |
106 | * hardware state, since even in the DPMS OFF state the display hardware |
107 | * should be as much powered down as when the CRTC is completely |
108 | * disabled through setting @enable to false. |
109 | */ |
110 | bool_Bool active; |
111 | |
112 | /** |
113 | * @planes_changed: Planes on this crtc are updated. Used by the atomic |
114 | * helpers and drivers to steer the atomic commit control flow. |
115 | */ |
116 | bool_Bool planes_changed : 1; |
117 | |
118 | /** |
119 | * @mode_changed: @mode or @enable has been changed. Used by the atomic |
120 | * helpers and drivers to steer the atomic commit control flow. See also |
121 | * drm_atomic_crtc_needs_modeset(). |
122 | * |
123 | * Drivers are supposed to set this for any CRTC state changes that |
124 | * require a full modeset. They can also reset it to false if e.g. a |
125 | * @mode change can be done without a full modeset by only changing |
126 | * scaler settings. |
127 | */ |
128 | bool_Bool mode_changed : 1; |
129 | |
130 | /** |
131 | * @active_changed: @active has been toggled. Used by the atomic |
132 | * helpers and drivers to steer the atomic commit control flow. See also |
133 | * drm_atomic_crtc_needs_modeset(). |
134 | */ |
135 | bool_Bool active_changed : 1; |
136 | |
137 | /** |
138 | * @connectors_changed: Connectors to this crtc have been updated, |
139 | * either in their state or routing. Used by the atomic |
140 | * helpers and drivers to steer the atomic commit control flow. See also |
141 | * drm_atomic_crtc_needs_modeset(). |
142 | * |
143 | * Drivers are supposed to set this as-needed from their own atomic |
144 | * check code, e.g. from &drm_encoder_helper_funcs.atomic_check |
145 | */ |
146 | bool_Bool connectors_changed : 1; |
147 | /** |
148 | * @zpos_changed: zpos values of planes on this crtc have been updated. |
149 | * Used by the atomic helpers and drivers to steer the atomic commit |
150 | * control flow. |
151 | */ |
152 | bool_Bool zpos_changed : 1; |
153 | /** |
154 | * @color_mgmt_changed: Color management properties have changed |
155 | * (@gamma_lut, @degamma_lut or @ctm). Used by the atomic helpers and |
156 | * drivers to steer the atomic commit control flow. |
157 | */ |
158 | bool_Bool color_mgmt_changed : 1; |
159 | |
160 | /** |
161 | * @no_vblank: |
162 | * |
163 | * Reflects the ability of a CRTC to send VBLANK events. This state |
164 | * usually depends on the pipeline configuration. If set to true, DRM |
165 | * atomic helpers will send out a fake VBLANK event during display |
166 | * updates after all hardware changes have been committed. This is |
167 | * implemented in drm_atomic_helper_fake_vblank(). |
168 | * |
169 | * One usage is for drivers and/or hardware without support for VBLANK |
170 | * interrupts. Such drivers typically do not initialize vblanking |
171 | * (i.e., call drm_vblank_init() with the number of CRTCs). For CRTCs |
172 | * without initialized vblanking, this field is set to true in |
173 | * drm_atomic_helper_check_modeset(), and a fake VBLANK event will be |
174 | * send out on each update of the display pipeline by |
175 | * drm_atomic_helper_fake_vblank(). |
176 | * |
177 | * Another usage is CRTCs feeding a writeback connector operating in |
178 | * oneshot mode. In this case the fake VBLANK event is only generated |
179 | * when a job is queued to the writeback connector, and we want the |
180 | * core to fake VBLANK events when this part of the pipeline hasn't |
181 | * changed but others had or when the CRTC and connectors are being |
182 | * disabled. |
183 | * |
184 | * __drm_atomic_helper_crtc_duplicate_state() will not reset the value |
185 | * from the current state, the CRTC driver is then responsible for |
186 | * updating this field when needed. |
187 | * |
188 | * Note that the combination of &drm_crtc_state.event == NULL and |
189 | * &drm_crtc_state.no_blank == true is valid and usually used when the |
190 | * writeback connector attached to the CRTC has a new job queued. In |
191 | * this case the driver will send the VBLANK event on its own when the |
192 | * writeback job is complete. |
193 | */ |
194 | bool_Bool no_vblank : 1; |
195 | |
196 | /** |
197 | * @plane_mask: Bitmask of drm_plane_mask(plane) of planes attached to |
198 | * this CRTC. |
199 | */ |
200 | u32 plane_mask; |
201 | |
202 | /** |
203 | * @connector_mask: Bitmask of drm_connector_mask(connector) of |
204 | * connectors attached to this CRTC. |
205 | */ |
206 | u32 connector_mask; |
207 | |
208 | /** |
209 | * @encoder_mask: Bitmask of drm_encoder_mask(encoder) of encoders |
210 | * attached to this CRTC. |
211 | */ |
212 | u32 encoder_mask; |
213 | |
214 | /** |
215 | * @adjusted_mode: |
216 | * |
217 | * Internal display timings which can be used by the driver to handle |
218 | * differences between the mode requested by userspace in @mode and what |
219 | * is actually programmed into the hardware. |
220 | * |
221 | * For drivers using &drm_bridge, this stores hardware display timings |
222 | * used between the CRTC and the first bridge. For other drivers, the |
223 | * meaning of the adjusted_mode field is purely driver implementation |
224 | * defined information, and will usually be used to store the hardware |
225 | * display timings used between the CRTC and encoder blocks. |
226 | */ |
227 | struct drm_display_mode adjusted_mode; |
228 | |
229 | /** |
230 | * @mode: |
231 | * |
232 | * Display timings requested by userspace. The driver should try to |
233 | * match the refresh rate as close as possible (but note that it's |
234 | * undefined what exactly is close enough, e.g. some of the HDMI modes |
235 | * only differ in less than 1% of the refresh rate). The active width |
236 | * and height as observed by userspace for positioning planes must match |
237 | * exactly. |
238 | * |
239 | * For external connectors where the sink isn't fixed (like with a |
240 | * built-in panel), this mode here should match the physical mode on the |
241 | * wire to the last details (i.e. including sync polarities and |
242 | * everything). |
243 | */ |
244 | struct drm_display_mode mode; |
245 | |
246 | /** |
247 | * @mode_blob: &drm_property_blob for @mode, for exposing the mode to |
248 | * atomic userspace. |
249 | */ |
250 | struct drm_property_blob *mode_blob; |
251 | |
252 | /** |
253 | * @degamma_lut: |
254 | * |
255 | * Lookup table for converting framebuffer pixel data before apply the |
256 | * color conversion matrix @ctm. See drm_crtc_enable_color_mgmt(). The |
257 | * blob (if not NULL) is an array of &struct drm_color_lut. |
258 | */ |
259 | struct drm_property_blob *degamma_lut; |
260 | |
261 | /** |
262 | * @ctm: |
263 | * |
264 | * Color transformation matrix. See drm_crtc_enable_color_mgmt(). The |
265 | * blob (if not NULL) is a &struct drm_color_ctm. |
266 | */ |
267 | struct drm_property_blob *ctm; |
268 | |
269 | /** |
270 | * @gamma_lut: |
271 | * |
272 | * Lookup table for converting pixel data after the color conversion |
273 | * matrix @ctm. See drm_crtc_enable_color_mgmt(). The blob (if not |
274 | * NULL) is an array of &struct drm_color_lut. |
275 | * |
276 | * Note that for mostly historical reasons stemming from Xorg heritage, |
277 | * this is also used to store the color map (also sometimes color lut, |
278 | * CLUT or color palette) for indexed formats like DRM_FORMAT_C8. |
279 | */ |
280 | struct drm_property_blob *gamma_lut; |
281 | |
282 | /** |
283 | * @target_vblank: |
284 | * |
285 | * Target vertical blank period when a page flip |
286 | * should take effect. |
287 | */ |
288 | u32 target_vblank; |
289 | |
290 | /** |
291 | * @async_flip: |
292 | * |
293 | * This is set when DRM_MODE_PAGE_FLIP_ASYNC is set in the legacy |
294 | * PAGE_FLIP IOCTL. It's not wired up for the atomic IOCTL itself yet. |
295 | */ |
296 | bool_Bool async_flip; |
297 | |
298 | /** |
299 | * @vrr_enabled: |
300 | * |
301 | * Indicates if variable refresh rate should be enabled for the CRTC. |
302 | * Support for the requested vrr state will depend on driver and |
303 | * hardware capabiltiy - lacking support is not treated as failure. |
304 | */ |
305 | bool_Bool vrr_enabled; |
306 | |
307 | /** |
308 | * @self_refresh_active: |
309 | * |
310 | * Used by the self refresh helpers to denote when a self refresh |
311 | * transition is occurring. This will be set on enable/disable callbacks |
312 | * when self refresh is being enabled or disabled. In some cases, it may |
313 | * not be desirable to fully shut off the crtc during self refresh. |
314 | * CRTC's can inspect this flag and determine the best course of action. |
315 | */ |
316 | bool_Bool self_refresh_active; |
317 | |
318 | /** |
319 | * @scaling_filter: |
320 | * |
321 | * Scaling filter to be applied |
322 | */ |
323 | enum drm_scaling_filter scaling_filter; |
324 | |
325 | /** |
326 | * @event: |
327 | * |
328 | * Optional pointer to a DRM event to signal upon completion of the |
329 | * state update. The driver must send out the event when the atomic |
330 | * commit operation completes. There are two cases: |
331 | * |
332 | * - The event is for a CRTC which is being disabled through this |
333 | * atomic commit. In that case the event can be send out any time |
334 | * after the hardware has stopped scanning out the current |
335 | * framebuffers. It should contain the timestamp and counter for the |
336 | * last vblank before the display pipeline was shut off. The simplest |
337 | * way to achieve that is calling drm_crtc_send_vblank_event() |
338 | * somewhen after drm_crtc_vblank_off() has been called. |
339 | * |
340 | * - For a CRTC which is enabled at the end of the commit (even when it |
341 | * undergoes an full modeset) the vblank timestamp and counter must |
342 | * be for the vblank right before the first frame that scans out the |
343 | * new set of buffers. Again the event can only be sent out after the |
344 | * hardware has stopped scanning out the old buffers. |
345 | * |
346 | * - Events for disabled CRTCs are not allowed, and drivers can ignore |
347 | * that case. |
348 | * |
349 | * For very simple hardware without VBLANK interrupt, enabling |
350 | * &struct drm_crtc_state.no_vblank makes DRM's atomic commit helpers |
351 | * send a fake VBLANK event at the end of the display update after all |
352 | * hardware changes have been applied. See |
353 | * drm_atomic_helper_fake_vblank(). |
354 | * |
355 | * For more complex hardware this |
356 | * can be handled by the drm_crtc_send_vblank_event() function, |
357 | * which the driver should call on the provided event upon completion of |
358 | * the atomic commit. Note that if the driver supports vblank signalling |
359 | * and timestamping the vblank counters and timestamps must agree with |
360 | * the ones returned from page flip events. With the current vblank |
361 | * helper infrastructure this can be achieved by holding a vblank |
362 | * reference while the page flip is pending, acquired through |
363 | * drm_crtc_vblank_get() and released with drm_crtc_vblank_put(). |
364 | * Drivers are free to implement their own vblank counter and timestamp |
365 | * tracking though, e.g. if they have accurate timestamp registers in |
366 | * hardware. |
367 | * |
368 | * For hardware which supports some means to synchronize vblank |
369 | * interrupt delivery with committing display state there's also |
370 | * drm_crtc_arm_vblank_event(). See the documentation of that function |
371 | * for a detailed discussion of the constraints it needs to be used |
372 | * safely. |
373 | * |
374 | * If the device can't notify of flip completion in a race-free way |
375 | * at all, then the event should be armed just after the page flip is |
376 | * committed. In the worst case the driver will send the event to |
377 | * userspace one frame too late. This doesn't allow for a real atomic |
378 | * update, but it should avoid tearing. |
379 | */ |
380 | struct drm_pending_vblank_event *event; |
381 | |
382 | /** |
383 | * @commit: |
384 | * |
385 | * This tracks how the commit for this update proceeds through the |
386 | * various phases. This is never cleared, except when we destroy the |
387 | * state, so that subsequent commits can synchronize with previous ones. |
388 | */ |
389 | struct drm_crtc_commit *commit; |
390 | |
391 | /** @state: backpointer to global drm_atomic_state */ |
392 | struct drm_atomic_state *state; |
393 | }; |
394 | |
395 | /** |
396 | * struct drm_crtc_funcs - control CRTCs for a given device |
397 | * |
398 | * The drm_crtc_funcs structure is the central CRTC management structure |
399 | * in the DRM. Each CRTC controls one or more connectors (note that the name |
400 | * CRTC is simply historical, a CRTC may control LVDS, VGA, DVI, TV out, etc. |
401 | * connectors, not just CRTs). |
402 | * |
403 | * Each driver is responsible for filling out this structure at startup time, |
404 | * in addition to providing other modesetting features, like i2c and DDC |
405 | * bus accessors. |
406 | */ |
407 | struct drm_crtc_funcs { |
408 | /** |
409 | * @reset: |
410 | * |
411 | * Reset CRTC hardware and software state to off. This function isn't |
412 | * called by the core directly, only through drm_mode_config_reset(). |
413 | * It's not a helper hook only for historical reasons. |
414 | * |
415 | * Atomic drivers can use drm_atomic_helper_crtc_reset() to reset |
416 | * atomic state using this hook. |
417 | */ |
418 | void (*reset)(struct drm_crtc *crtc); |
419 | |
420 | /** |
421 | * @cursor_set: |
422 | * |
423 | * Update the cursor image. The cursor position is relative to the CRTC |
424 | * and can be partially or fully outside of the visible area. |
425 | * |
426 | * Note that contrary to all other KMS functions the legacy cursor entry |
427 | * points don't take a framebuffer object, but instead take directly a |
428 | * raw buffer object id from the driver's buffer manager (which is |
429 | * either GEM or TTM for current drivers). |
430 | * |
431 | * This entry point is deprecated, drivers should instead implement |
432 | * universal plane support and register a proper cursor plane using |
433 | * drm_crtc_init_with_planes(). |
434 | * |
435 | * This callback is optional |
436 | * |
437 | * RETURNS: |
438 | * |
439 | * 0 on success or a negative error code on failure. |
440 | */ |
441 | int (*cursor_set)(struct drm_crtc *crtc, struct drm_file *file_priv, |
442 | uint32_t handle, uint32_t width, uint32_t height); |
443 | |
444 | /** |
445 | * @cursor_set2: |
446 | * |
447 | * Update the cursor image, including hotspot information. The hotspot |
448 | * must not affect the cursor position in CRTC coordinates, but is only |
449 | * meant as a hint for virtualized display hardware to coordinate the |
450 | * guests and hosts cursor position. The cursor hotspot is relative to |
451 | * the cursor image. Otherwise this works exactly like @cursor_set. |
452 | * |
453 | * This entry point is deprecated, drivers should instead implement |
454 | * universal plane support and register a proper cursor plane using |
455 | * drm_crtc_init_with_planes(). |
456 | * |
457 | * This callback is optional. |
458 | * |
459 | * RETURNS: |
460 | * |
461 | * 0 on success or a negative error code on failure. |
462 | */ |
463 | int (*cursor_set2)(struct drm_crtc *crtc, struct drm_file *file_priv, |
464 | uint32_t handle, uint32_t width, uint32_t height, |
465 | int32_t hot_x, int32_t hot_y); |
466 | |
467 | /** |
468 | * @cursor_move: |
469 | * |
470 | * Update the cursor position. The cursor does not need to be visible |
471 | * when this hook is called. |
472 | * |
473 | * This entry point is deprecated, drivers should instead implement |
474 | * universal plane support and register a proper cursor plane using |
475 | * drm_crtc_init_with_planes(). |
476 | * |
477 | * This callback is optional. |
478 | * |
479 | * RETURNS: |
480 | * |
481 | * 0 on success or a negative error code on failure. |
482 | */ |
483 | int (*cursor_move)(struct drm_crtc *crtc, int x, int y); |
484 | |
485 | /** |
486 | * @gamma_set: |
487 | * |
488 | * Set gamma on the CRTC. |
489 | * |
490 | * This callback is optional. |
491 | * |
492 | * Atomic drivers who want to support gamma tables should implement the |
493 | * atomic color management support, enabled by calling |
494 | * drm_crtc_enable_color_mgmt(), which then supports the legacy gamma |
495 | * interface through the drm_atomic_helper_legacy_gamma_set() |
496 | * compatibility implementation. |
497 | */ |
498 | int (*gamma_set)(struct drm_crtc *crtc, u16 *r, u16 *g, u16 *b, |
499 | uint32_t size, |
500 | struct drm_modeset_acquire_ctx *ctx); |
501 | |
502 | /** |
503 | * @destroy: |
504 | * |
505 | * Clean up CRTC resources. This is only called at driver unload time |
506 | * through drm_mode_config_cleanup() since a CRTC cannot be hotplugged |
507 | * in DRM. |
508 | */ |
509 | void (*destroy)(struct drm_crtc *crtc); |
510 | |
511 | /** |
512 | * @set_config: |
513 | * |
514 | * This is the main legacy entry point to change the modeset state on a |
515 | * CRTC. All the details of the desired configuration are passed in a |
516 | * &struct drm_mode_set - see there for details. |
517 | * |
518 | * Drivers implementing atomic modeset should use |
519 | * drm_atomic_helper_set_config() to implement this hook. |
520 | * |
521 | * RETURNS: |
522 | * |
523 | * 0 on success or a negative error code on failure. |
524 | */ |
525 | int (*set_config)(struct drm_mode_set *set, |
526 | struct drm_modeset_acquire_ctx *ctx); |
527 | |
528 | /** |
529 | * @page_flip: |
530 | * |
531 | * Legacy entry point to schedule a flip to the given framebuffer. |
532 | * |
533 | * Page flipping is a synchronization mechanism that replaces the frame |
534 | * buffer being scanned out by the CRTC with a new frame buffer during |
535 | * vertical blanking, avoiding tearing (except when requested otherwise |
536 | * through the DRM_MODE_PAGE_FLIP_ASYNC flag). When an application |
537 | * requests a page flip the DRM core verifies that the new frame buffer |
538 | * is large enough to be scanned out by the CRTC in the currently |
539 | * configured mode and then calls this hook with a pointer to the new |
540 | * frame buffer. |
541 | * |
542 | * The driver must wait for any pending rendering to the new framebuffer |
543 | * to complete before executing the flip. It should also wait for any |
544 | * pending rendering from other drivers if the underlying buffer is a |
545 | * shared dma-buf. |
546 | * |
547 | * An application can request to be notified when the page flip has |
548 | * completed. The drm core will supply a &struct drm_event in the event |
549 | * parameter in this case. This can be handled by the |
550 | * drm_crtc_send_vblank_event() function, which the driver should call on |
551 | * the provided event upon completion of the flip. Note that if |
552 | * the driver supports vblank signalling and timestamping the vblank |
553 | * counters and timestamps must agree with the ones returned from page |
554 | * flip events. With the current vblank helper infrastructure this can |
555 | * be achieved by holding a vblank reference while the page flip is |
556 | * pending, acquired through drm_crtc_vblank_get() and released with |
557 | * drm_crtc_vblank_put(). Drivers are free to implement their own vblank |
558 | * counter and timestamp tracking though, e.g. if they have accurate |
559 | * timestamp registers in hardware. |
560 | * |
561 | * This callback is optional. |
562 | * |
563 | * NOTE: |
564 | * |
565 | * Very early versions of the KMS ABI mandated that the driver must |
566 | * block (but not reject) any rendering to the old framebuffer until the |
567 | * flip operation has completed and the old framebuffer is no longer |
568 | * visible. This requirement has been lifted, and userspace is instead |
569 | * expected to request delivery of an event and wait with recycling old |
570 | * buffers until such has been received. |
571 | * |
572 | * RETURNS: |
573 | * |
574 | * 0 on success or a negative error code on failure. Note that if a |
575 | * page flip operation is already pending the callback should return |
576 | * -EBUSY. Pageflips on a disabled CRTC (either by setting a NULL mode |
577 | * or just runtime disabled through DPMS respectively the new atomic |
578 | * "ACTIVE" state) should result in an -EINVAL error code. Note that |
579 | * drm_atomic_helper_page_flip() checks this already for atomic drivers. |
580 | */ |
581 | int (*page_flip)(struct drm_crtc *crtc, |
582 | struct drm_framebuffer *fb, |
583 | struct drm_pending_vblank_event *event, |
584 | uint32_t flags, |
585 | struct drm_modeset_acquire_ctx *ctx); |
586 | |
587 | /** |
588 | * @page_flip_target: |
589 | * |
590 | * Same as @page_flip but with an additional parameter specifying the |
591 | * absolute target vertical blank period (as reported by |
592 | * drm_crtc_vblank_count()) when the flip should take effect. |
593 | * |
594 | * Note that the core code calls drm_crtc_vblank_get before this entry |
595 | * point, and will call drm_crtc_vblank_put if this entry point returns |
596 | * any non-0 error code. It's the driver's responsibility to call |
597 | * drm_crtc_vblank_put after this entry point returns 0, typically when |
598 | * the flip completes. |
599 | */ |
600 | int (*page_flip_target)(struct drm_crtc *crtc, |
601 | struct drm_framebuffer *fb, |
602 | struct drm_pending_vblank_event *event, |
603 | uint32_t flags, uint32_t target, |
604 | struct drm_modeset_acquire_ctx *ctx); |
605 | |
606 | /** |
607 | * @set_property: |
608 | * |
609 | * This is the legacy entry point to update a property attached to the |
610 | * CRTC. |
611 | * |
612 | * This callback is optional if the driver does not support any legacy |
613 | * driver-private properties. For atomic drivers it is not used because |
614 | * property handling is done entirely in the DRM core. |
615 | * |
616 | * RETURNS: |
617 | * |
618 | * 0 on success or a negative error code on failure. |
619 | */ |
620 | int (*set_property)(struct drm_crtc *crtc, |
621 | struct drm_property *property, uint64_t val); |
622 | |
623 | /** |
624 | * @atomic_duplicate_state: |
625 | * |
626 | * Duplicate the current atomic state for this CRTC and return it. |
627 | * The core and helpers guarantee that any atomic state duplicated with |
628 | * this hook and still owned by the caller (i.e. not transferred to the |
629 | * driver by calling &drm_mode_config_funcs.atomic_commit) will be |
630 | * cleaned up by calling the @atomic_destroy_state hook in this |
631 | * structure. |
632 | * |
633 | * This callback is mandatory for atomic drivers. |
634 | * |
635 | * Atomic drivers which don't subclass &struct drm_crtc_state should use |
636 | * drm_atomic_helper_crtc_duplicate_state(). Drivers that subclass the |
637 | * state structure to extend it with driver-private state should use |
638 | * __drm_atomic_helper_crtc_duplicate_state() to make sure shared state is |
639 | * duplicated in a consistent fashion across drivers. |
640 | * |
641 | * It is an error to call this hook before &drm_crtc.state has been |
642 | * initialized correctly. |
643 | * |
644 | * NOTE: |
645 | * |
646 | * If the duplicate state references refcounted resources this hook must |
647 | * acquire a reference for each of them. The driver must release these |
648 | * references again in @atomic_destroy_state. |
649 | * |
650 | * RETURNS: |
651 | * |
652 | * Duplicated atomic state or NULL when the allocation failed. |
653 | */ |
654 | struct drm_crtc_state *(*atomic_duplicate_state)(struct drm_crtc *crtc); |
655 | |
656 | /** |
657 | * @atomic_destroy_state: |
658 | * |
659 | * Destroy a state duplicated with @atomic_duplicate_state and release |
660 | * or unreference all resources it references |
661 | * |
662 | * This callback is mandatory for atomic drivers. |
663 | */ |
664 | void (*atomic_destroy_state)(struct drm_crtc *crtc, |
665 | struct drm_crtc_state *state); |
666 | |
667 | /** |
668 | * @atomic_set_property: |
669 | * |
670 | * Decode a driver-private property value and store the decoded value |
671 | * into the passed-in state structure. Since the atomic core decodes all |
672 | * standardized properties (even for extensions beyond the core set of |
673 | * properties which might not be implemented by all drivers) this |
674 | * requires drivers to subclass the state structure. |
675 | * |
676 | * Such driver-private properties should really only be implemented for |
677 | * truly hardware/vendor specific state. Instead it is preferred to |
678 | * standardize atomic extension and decode the properties used to expose |
679 | * such an extension in the core. |
680 | * |
681 | * Do not call this function directly, use |
682 | * drm_atomic_crtc_set_property() instead. |
683 | * |
684 | * This callback is optional if the driver does not support any |
685 | * driver-private atomic properties. |
686 | * |
687 | * NOTE: |
688 | * |
689 | * This function is called in the state assembly phase of atomic |
690 | * modesets, which can be aborted for any reason (including on |
691 | * userspace's request to just check whether a configuration would be |
692 | * possible). Drivers MUST NOT touch any persistent state (hardware or |
693 | * software) or data structures except the passed in @state parameter. |
694 | * |
695 | * Also since userspace controls in which order properties are set this |
696 | * function must not do any input validation (since the state update is |
697 | * incomplete and hence likely inconsistent). Instead any such input |
698 | * validation must be done in the various atomic_check callbacks. |
699 | * |
700 | * RETURNS: |
701 | * |
702 | * 0 if the property has been found, -EINVAL if the property isn't |
703 | * implemented by the driver (which should never happen, the core only |
704 | * asks for properties attached to this CRTC). No other validation is |
705 | * allowed by the driver. The core already checks that the property |
706 | * value is within the range (integer, valid enum value, ...) the driver |
707 | * set when registering the property. |
708 | */ |
709 | int (*atomic_set_property)(struct drm_crtc *crtc, |
710 | struct drm_crtc_state *state, |
711 | struct drm_property *property, |
712 | uint64_t val); |
713 | /** |
714 | * @atomic_get_property: |
715 | * |
716 | * Reads out the decoded driver-private property. This is used to |
717 | * implement the GETCRTC IOCTL. |
718 | * |
719 | * Do not call this function directly, use |
720 | * drm_atomic_crtc_get_property() instead. |
721 | * |
722 | * This callback is optional if the driver does not support any |
723 | * driver-private atomic properties. |
724 | * |
725 | * RETURNS: |
726 | * |
727 | * 0 on success, -EINVAL if the property isn't implemented by the |
728 | * driver (which should never happen, the core only asks for |
729 | * properties attached to this CRTC). |
730 | */ |
731 | int (*atomic_get_property)(struct drm_crtc *crtc, |
732 | const struct drm_crtc_state *state, |
733 | struct drm_property *property, |
734 | uint64_t *val); |
735 | |
736 | /** |
737 | * @late_register: |
738 | * |
739 | * This optional hook can be used to register additional userspace |
740 | * interfaces attached to the crtc like debugfs interfaces. |
741 | * It is called late in the driver load sequence from drm_dev_register(). |
742 | * Everything added from this callback should be unregistered in |
743 | * the early_unregister callback. |
744 | * |
745 | * Returns: |
746 | * |
747 | * 0 on success, or a negative error code on failure. |
748 | */ |
749 | int (*late_register)(struct drm_crtc *crtc); |
750 | |
751 | /** |
752 | * @early_unregister: |
753 | * |
754 | * This optional hook should be used to unregister the additional |
755 | * userspace interfaces attached to the crtc from |
756 | * @late_register. It is called from drm_dev_unregister(), |
757 | * early in the driver unload sequence to disable userspace access |
758 | * before data structures are torndown. |
759 | */ |
760 | void (*early_unregister)(struct drm_crtc *crtc); |
761 | |
762 | /** |
763 | * @set_crc_source: |
764 | * |
765 | * Changes the source of CRC checksums of frames at the request of |
766 | * userspace, typically for testing purposes. The sources available are |
767 | * specific of each driver and a %NULL value indicates that CRC |
768 | * generation is to be switched off. |
769 | * |
770 | * When CRC generation is enabled, the driver should call |
771 | * drm_crtc_add_crc_entry() at each frame, providing any information |
772 | * that characterizes the frame contents in the crcN arguments, as |
773 | * provided from the configured source. Drivers must accept an "auto" |
774 | * source name that will select a default source for this CRTC. |
775 | * |
776 | * This may trigger an atomic modeset commit if necessary, to enable CRC |
777 | * generation. |
778 | * |
779 | * Note that "auto" can depend upon the current modeset configuration, |
780 | * e.g. it could pick an encoder or output specific CRC sampling point. |
781 | * |
782 | * This callback is optional if the driver does not support any CRC |
783 | * generation functionality. |
784 | * |
785 | * RETURNS: |
786 | * |
787 | * 0 on success or a negative error code on failure. |
788 | */ |
789 | int (*set_crc_source)(struct drm_crtc *crtc, const char *source); |
790 | |
791 | /** |
792 | * @verify_crc_source: |
793 | * |
794 | * verifies the source of CRC checksums of frames before setting the |
795 | * source for CRC and during crc open. Source parameter can be NULL |
796 | * while disabling crc source. |
797 | * |
798 | * This callback is optional if the driver does not support any CRC |
799 | * generation functionality. |
800 | * |
801 | * RETURNS: |
802 | * |
803 | * 0 on success or a negative error code on failure. |
804 | */ |
805 | int (*verify_crc_source)(struct drm_crtc *crtc, const char *source, |
806 | size_t *values_cnt); |
807 | /** |
808 | * @get_crc_sources: |
809 | * |
810 | * Driver callback for getting a list of all the available sources for |
811 | * CRC generation. This callback depends upon verify_crc_source, So |
812 | * verify_crc_source callback should be implemented before implementing |
813 | * this. Driver can pass full list of available crc sources, this |
814 | * callback does the verification on each crc-source before passing it |
815 | * to userspace. |
816 | * |
817 | * This callback is optional if the driver does not support exporting of |
818 | * possible CRC sources list. |
819 | * |
820 | * RETURNS: |
821 | * |
822 | * a constant character pointer to the list of all the available CRC |
823 | * sources. On failure driver should return NULL. count should be |
824 | * updated with number of sources in list. if zero we don't process any |
825 | * source from the list. |
826 | */ |
827 | const char *const *(*get_crc_sources)(struct drm_crtc *crtc, |
828 | size_t *count); |
829 | |
830 | /** |
831 | * @atomic_print_state: |
832 | * |
833 | * If driver subclasses &struct drm_crtc_state, it should implement |
834 | * this optional hook for printing additional driver specific state. |
835 | * |
836 | * Do not call this directly, use drm_atomic_crtc_print_state() |
837 | * instead. |
838 | */ |
839 | void (*atomic_print_state)(struct drm_printer *p, |
840 | const struct drm_crtc_state *state); |
841 | |
842 | /** |
843 | * @get_vblank_counter: |
844 | * |
845 | * Driver callback for fetching a raw hardware vblank counter for the |
846 | * CRTC. It's meant to be used by new drivers as the replacement of |
847 | * &drm_driver.get_vblank_counter hook. |
848 | * |
849 | * This callback is optional. If a device doesn't have a hardware |
850 | * counter, the driver can simply leave the hook as NULL. The DRM core |
851 | * will account for missed vblank events while interrupts where disabled |
852 | * based on system timestamps. |
853 | * |
854 | * Wraparound handling and loss of events due to modesetting is dealt |
855 | * with in the DRM core code, as long as drivers call |
856 | * drm_crtc_vblank_off() and drm_crtc_vblank_on() when disabling or |
857 | * enabling a CRTC. |
858 | * |
859 | * See also &drm_device.vblank_disable_immediate and |
860 | * &drm_device.max_vblank_count. |
861 | * |
862 | * Returns: |
863 | * |
864 | * Raw vblank counter value. |
865 | */ |
866 | u32 (*get_vblank_counter)(struct drm_crtc *crtc); |
867 | |
868 | /** |
869 | * @enable_vblank: |
870 | * |
871 | * Enable vblank interrupts for the CRTC. It's meant to be used by |
872 | * new drivers as the replacement of &drm_driver.enable_vblank hook. |
873 | * |
874 | * Returns: |
875 | * |
876 | * Zero on success, appropriate errno if the vblank interrupt cannot |
877 | * be enabled. |
878 | */ |
879 | int (*enable_vblank)(struct drm_crtc *crtc); |
880 | |
881 | /** |
882 | * @disable_vblank: |
883 | * |
884 | * Disable vblank interrupts for the CRTC. It's meant to be used by |
885 | * new drivers as the replacement of &drm_driver.disable_vblank hook. |
886 | */ |
887 | void (*disable_vblank)(struct drm_crtc *crtc); |
888 | |
889 | /** |
890 | * @get_vblank_timestamp: |
891 | * |
892 | * Called by drm_get_last_vbltimestamp(). Should return a precise |
893 | * timestamp when the most recent vblank interval ended or will end. |
894 | * |
895 | * Specifically, the timestamp in @vblank_time should correspond as |
896 | * closely as possible to the time when the first video scanline of |
897 | * the video frame after the end of vblank will start scanning out, |
898 | * the time immediately after end of the vblank interval. If the |
899 | * @crtc is currently inside vblank, this will be a time in the future. |
900 | * If the @crtc is currently scanning out a frame, this will be the |
901 | * past start time of the current scanout. This is meant to adhere |
902 | * to the OpenML OML_sync_control extension specification. |
903 | * |
904 | * Parameters: |
905 | * |
906 | * crtc: |
907 | * CRTC for which timestamp should be returned. |
908 | * max_error: |
909 | * Maximum allowable timestamp error in nanoseconds. |
910 | * Implementation should strive to provide timestamp |
911 | * with an error of at most max_error nanoseconds. |
912 | * Returns true upper bound on error for timestamp. |
913 | * vblank_time: |
914 | * Target location for returned vblank timestamp. |
915 | * in_vblank_irq: |
916 | * True when called from drm_crtc_handle_vblank(). Some drivers |
917 | * need to apply some workarounds for gpu-specific vblank irq quirks |
918 | * if flag is set. |
919 | * |
920 | * Returns: |
921 | * |
922 | * True on success, false on failure, which means the core should |
923 | * fallback to a simple timestamp taken in drm_crtc_handle_vblank(). |
924 | */ |
925 | bool_Bool (*get_vblank_timestamp)(struct drm_crtc *crtc, |
926 | int *max_error, |
927 | ktime_t *vblank_time, |
928 | bool_Bool in_vblank_irq); |
929 | }; |
930 | |
931 | /** |
932 | * struct drm_crtc - central CRTC control structure |
933 | * |
934 | * Each CRTC may have one or more connectors associated with it. This structure |
935 | * allows the CRTC to be controlled. |
936 | */ |
937 | struct drm_crtc { |
938 | /** @dev: parent DRM device */ |
939 | struct drm_device *dev; |
940 | /** @port: OF node used by drm_of_find_possible_crtcs(). */ |
941 | struct device_node *port; |
942 | /** |
943 | * @head: |
944 | * |
945 | * List of all CRTCs on @dev, linked from &drm_mode_config.crtc_list. |
946 | * Invariant over the lifetime of @dev and therefore does not need |
947 | * locking. |
948 | */ |
949 | struct list_head head; |
950 | |
951 | /** @name: human readable name, can be overwritten by the driver */ |
952 | char *name; |
953 | |
954 | /** |
955 | * @mutex: |
956 | * |
957 | * This provides a read lock for the overall CRTC state (mode, dpms |
958 | * state, ...) and a write lock for everything which can be update |
959 | * without a full modeset (fb, cursor data, CRTC properties ...). A full |
960 | * modeset also need to grab &drm_mode_config.connection_mutex. |
961 | * |
962 | * For atomic drivers specifically this protects @state. |
963 | */ |
964 | struct drm_modeset_lock mutex; |
965 | |
966 | /** @base: base KMS object for ID tracking etc. */ |
967 | struct drm_mode_object base; |
968 | |
969 | /** |
970 | * @primary: |
971 | * Primary plane for this CRTC. Note that this is only |
972 | * relevant for legacy IOCTL, it specifies the plane implicitly used by |
973 | * the SETCRTC and PAGE_FLIP IOCTLs. It does not have any significance |
974 | * beyond that. |
975 | */ |
976 | struct drm_plane *primary; |
977 | |
978 | /** |
979 | * @cursor: |
980 | * Cursor plane for this CRTC. Note that this is only relevant for |
981 | * legacy IOCTL, it specifies the plane implicitly used by the SETCURSOR |
982 | * and SETCURSOR2 IOCTLs. It does not have any significance |
983 | * beyond that. |
984 | */ |
985 | struct drm_plane *cursor; |
986 | |
987 | /** |
988 | * @index: Position inside the mode_config.list, can be used as an array |
989 | * index. It is invariant over the lifetime of the CRTC. |
990 | */ |
991 | unsigned index; |
992 | |
993 | /** |
994 | * @cursor_x: Current x position of the cursor, used for universal |
995 | * cursor planes because the SETCURSOR IOCTL only can update the |
996 | * framebuffer without supplying the coordinates. Drivers should not use |
997 | * this directly, atomic drivers should look at &drm_plane_state.crtc_x |
998 | * of the cursor plane instead. |
999 | */ |
1000 | int cursor_x; |
1001 | /** |
1002 | * @cursor_y: Current y position of the cursor, used for universal |
1003 | * cursor planes because the SETCURSOR IOCTL only can update the |
1004 | * framebuffer without supplying the coordinates. Drivers should not use |
1005 | * this directly, atomic drivers should look at &drm_plane_state.crtc_y |
1006 | * of the cursor plane instead. |
1007 | */ |
1008 | int cursor_y; |
1009 | |
1010 | /** |
1011 | * @enabled: |
1012 | * |
1013 | * Is this CRTC enabled? Should only be used by legacy drivers, atomic |
1014 | * drivers should instead consult &drm_crtc_state.enable and |
1015 | * &drm_crtc_state.active. Atomic drivers can update this by calling |
1016 | * drm_atomic_helper_update_legacy_modeset_state(). |
1017 | */ |
1018 | bool_Bool enabled; |
1019 | |
1020 | /** |
1021 | * @mode: |
1022 | * |
1023 | * Current mode timings. Should only be used by legacy drivers, atomic |
1024 | * drivers should instead consult &drm_crtc_state.mode. Atomic drivers |
1025 | * can update this by calling |
1026 | * drm_atomic_helper_update_legacy_modeset_state(). |
1027 | */ |
1028 | struct drm_display_mode mode; |
1029 | |
1030 | /** |
1031 | * @hwmode: |
1032 | * |
1033 | * Programmed mode in hw, after adjustments for encoders, crtc, panel |
1034 | * scaling etc. Should only be used by legacy drivers, for high |
1035 | * precision vblank timestamps in |
1036 | * drm_crtc_vblank_helper_get_vblank_timestamp(). |
1037 | * |
1038 | * Note that atomic drivers should not use this, but instead use |
1039 | * &drm_crtc_state.adjusted_mode. And for high-precision timestamps |
1040 | * drm_crtc_vblank_helper_get_vblank_timestamp() used |
1041 | * &drm_vblank_crtc.hwmode, |
1042 | * which is filled out by calling drm_calc_timestamping_constants(). |
1043 | */ |
1044 | struct drm_display_mode hwmode; |
1045 | |
1046 | /** |
1047 | * @x: |
1048 | * x position on screen. Should only be used by legacy drivers, atomic |
1049 | * drivers should look at &drm_plane_state.crtc_x of the primary plane |
1050 | * instead. Updated by calling |
1051 | * drm_atomic_helper_update_legacy_modeset_state(). |
1052 | */ |
1053 | int x; |
1054 | /** |
1055 | * @y: |
1056 | * y position on screen. Should only be used by legacy drivers, atomic |
1057 | * drivers should look at &drm_plane_state.crtc_y of the primary plane |
1058 | * instead. Updated by calling |
1059 | * drm_atomic_helper_update_legacy_modeset_state(). |
1060 | */ |
1061 | int y; |
1062 | |
1063 | /** @funcs: CRTC control functions */ |
1064 | const struct drm_crtc_funcs *funcs; |
1065 | |
1066 | /** |
1067 | * @gamma_size: Size of legacy gamma ramp reported to userspace. Set up |
1068 | * by calling drm_mode_crtc_set_gamma_size(). |
1069 | * |
1070 | * Note that atomic drivers need to instead use |
1071 | * &drm_crtc_state.gamma_lut. See drm_crtc_enable_color_mgmt(). |
1072 | */ |
1073 | uint32_t gamma_size; |
1074 | |
1075 | /** |
1076 | * @gamma_store: Gamma ramp values used by the legacy SETGAMMA and |
1077 | * GETGAMMA IOCTls. Set up by calling drm_mode_crtc_set_gamma_size(). |
1078 | * |
1079 | * Note that atomic drivers need to instead use |
1080 | * &drm_crtc_state.gamma_lut. See drm_crtc_enable_color_mgmt(). |
1081 | */ |
1082 | uint16_t *gamma_store; |
1083 | |
1084 | /** @helper_private: mid-layer private data */ |
1085 | const struct drm_crtc_helper_funcs *helper_private; |
1086 | |
1087 | /** @properties: property tracking for this CRTC */ |
1088 | struct drm_object_properties properties; |
1089 | |
1090 | /** |
1091 | * @scaling_filter_property: property to apply a particular filter while |
1092 | * scaling. |
1093 | */ |
1094 | struct drm_property *scaling_filter_property; |
1095 | |
1096 | /** |
1097 | * @state: |
1098 | * |
1099 | * Current atomic state for this CRTC. |
1100 | * |
1101 | * This is protected by @mutex. Note that nonblocking atomic commits |
1102 | * access the current CRTC state without taking locks. Either by going |
1103 | * through the &struct drm_atomic_state pointers, see |
1104 | * for_each_oldnew_crtc_in_state(), for_each_old_crtc_in_state() and |
1105 | * for_each_new_crtc_in_state(). Or through careful ordering of atomic |
1106 | * commit operations as implemented in the atomic helpers, see |
1107 | * &struct drm_crtc_commit. |
1108 | */ |
1109 | struct drm_crtc_state *state; |
1110 | |
1111 | /** |
1112 | * @commit_list: |
1113 | * |
1114 | * List of &drm_crtc_commit structures tracking pending commits. |
1115 | * Protected by @commit_lock. This list holds its own full reference, |
1116 | * as does the ongoing commit. |
1117 | * |
1118 | * "Note that the commit for a state change is also tracked in |
1119 | * &drm_crtc_state.commit. For accessing the immediately preceding |
1120 | * commit in an atomic update it is recommended to just use that |
1121 | * pointer in the old CRTC state, since accessing that doesn't need |
1122 | * any locking or list-walking. @commit_list should only be used to |
1123 | * stall for framebuffer cleanup that's signalled through |
1124 | * &drm_crtc_commit.cleanup_done." |
1125 | */ |
1126 | struct list_head commit_list; |
1127 | |
1128 | /** |
1129 | * @commit_lock: |
1130 | * |
1131 | * Spinlock to protect @commit_list. |
1132 | */ |
1133 | spinlock_t commit_lock; |
1134 | |
1135 | /** |
1136 | * @debugfs_entry: |
1137 | * |
1138 | * Debugfs directory for this CRTC. |
1139 | */ |
1140 | struct dentry *debugfs_entry; |
1141 | |
1142 | /** |
1143 | * @crc: |
1144 | * |
1145 | * Configuration settings of CRC capture. |
1146 | */ |
1147 | struct drm_crtc_crc crc; |
1148 | |
1149 | /** |
1150 | * @fence_context: |
1151 | * |
1152 | * timeline context used for fence operations. |
1153 | */ |
1154 | unsigned int fence_context; |
1155 | |
1156 | /** |
1157 | * @fence_lock: |
1158 | * |
1159 | * spinlock to protect the fences in the fence_context. |
1160 | */ |
1161 | spinlock_t fence_lock; |
1162 | /** |
1163 | * @fence_seqno: |
1164 | * |
1165 | * Seqno variable used as monotonic counter for the fences |
1166 | * created on the CRTC's timeline. |
1167 | */ |
1168 | unsigned long fence_seqno; |
1169 | |
1170 | /** |
1171 | * @timeline_name: |
1172 | * |
1173 | * The name of the CRTC's fence timeline. |
1174 | */ |
1175 | char timeline_name[32]; |
1176 | |
1177 | /** |
1178 | * @self_refresh_data: Holds the state for the self refresh helpers |
1179 | * |
1180 | * Initialized via drm_self_refresh_helper_init(). |
1181 | */ |
1182 | struct drm_self_refresh_data *self_refresh_data; |
1183 | }; |
1184 | |
1185 | /** |
1186 | * struct drm_mode_set - new values for a CRTC config change |
1187 | * @fb: framebuffer to use for new config |
1188 | * @crtc: CRTC whose configuration we're about to change |
1189 | * @mode: mode timings to use |
1190 | * @x: position of this CRTC relative to @fb |
1191 | * @y: position of this CRTC relative to @fb |
1192 | * @connectors: array of connectors to drive with this CRTC if possible |
1193 | * @num_connectors: size of @connectors array |
1194 | * |
1195 | * This represents a modeset configuration for the legacy SETCRTC ioctl and is |
1196 | * also used internally. Atomic drivers instead use &drm_atomic_state. |
1197 | */ |
1198 | struct drm_mode_set { |
1199 | struct drm_framebuffer *fb; |
1200 | struct drm_crtc *crtc; |
1201 | struct drm_display_mode *mode; |
1202 | |
1203 | uint32_t x; |
1204 | uint32_t y; |
1205 | |
1206 | struct drm_connector **connectors; |
1207 | size_t num_connectors; |
1208 | }; |
1209 | |
1210 | #define obj_to_crtc(x)({ const __typeof( ((struct drm_crtc *)0)->base ) *__mptr = (x); (struct drm_crtc *)( (char *)__mptr - __builtin_offsetof (struct drm_crtc, base) );}) container_of(x, struct drm_crtc, base)({ const __typeof( ((struct drm_crtc *)0)->base ) *__mptr = (x); (struct drm_crtc *)( (char *)__mptr - __builtin_offsetof (struct drm_crtc, base) );}) |
1211 | |
1212 | __printf(6, 7)__attribute__((__format__(__kprintf__,6,7))) |
1213 | int drm_crtc_init_with_planes(struct drm_device *dev, |
1214 | struct drm_crtc *crtc, |
1215 | struct drm_plane *primary, |
1216 | struct drm_plane *cursor, |
1217 | const struct drm_crtc_funcs *funcs, |
1218 | const char *name, ...); |
1219 | |
1220 | __printf(6, 7)__attribute__((__format__(__kprintf__,6,7))) |
1221 | int drmm_crtc_init_with_planes(struct drm_device *dev, |
1222 | struct drm_crtc *crtc, |
1223 | struct drm_plane *primary, |
1224 | struct drm_plane *cursor, |
1225 | const struct drm_crtc_funcs *funcs, |
1226 | const char *name, ...); |
1227 | |
1228 | void drm_crtc_cleanup(struct drm_crtc *crtc); |
1229 | |
1230 | __printf(7, 8)__attribute__((__format__(__kprintf__,7,8))) |
1231 | void *__drmm_crtc_alloc_with_planes(struct drm_device *dev, |
1232 | size_t size, size_t offset, |
1233 | struct drm_plane *primary, |
1234 | struct drm_plane *cursor, |
1235 | const struct drm_crtc_funcs *funcs, |
1236 | const char *name, ...); |
1237 | |
1238 | /** |
1239 | * drmm_crtc_alloc_with_planes - Allocate and initialize a new CRTC object with |
1240 | * specified primary and cursor planes. |
1241 | * @dev: DRM device |
1242 | * @type: the type of the struct which contains struct &drm_crtc |
1243 | * @member: the name of the &drm_crtc within @type. |
1244 | * @primary: Primary plane for CRTC |
1245 | * @cursor: Cursor plane for CRTC |
1246 | * @funcs: callbacks for the new CRTC |
1247 | * @name: printf style format string for the CRTC name, or NULL for default name |
1248 | * |
1249 | * Allocates and initializes a new crtc object. Cleanup is automatically |
1250 | * handled through registering drmm_crtc_cleanup() with drmm_add_action(). |
1251 | * |
1252 | * The @drm_crtc_funcs.destroy hook must be NULL. |
1253 | * |
1254 | * Returns: |
1255 | * Pointer to new crtc, or ERR_PTR on failure. |
1256 | */ |
1257 | #define drmm_crtc_alloc_with_planes(dev, type, member, primary, cursor, funcs, name, ...)((type *)__drmm_crtc_alloc_with_planes(dev, sizeof(type), __builtin_offsetof (type, member), primary, cursor, funcs, name, ...)) \ |
1258 | ((type *)__drmm_crtc_alloc_with_planes(dev, sizeof(type), \ |
1259 | offsetof(type, member)__builtin_offsetof(type, member), \ |
1260 | primary, cursor, funcs, \ |
1261 | name, ##__VA_ARGS__)) |
1262 | |
1263 | /** |
1264 | * drm_crtc_index - find the index of a registered CRTC |
1265 | * @crtc: CRTC to find index for |
1266 | * |
1267 | * Given a registered CRTC, return the index of that CRTC within a DRM |
1268 | * device's list of CRTCs. |
1269 | */ |
1270 | static inline unsigned int drm_crtc_index(const struct drm_crtc *crtc) |
1271 | { |
1272 | return crtc->index; |
1273 | } |
1274 | |
1275 | /** |
1276 | * drm_crtc_mask - find the mask of a registered CRTC |
1277 | * @crtc: CRTC to find mask for |
1278 | * |
1279 | * Given a registered CRTC, return the mask bit of that CRTC for the |
1280 | * &drm_encoder.possible_crtcs and &drm_plane.possible_crtcs fields. |
1281 | */ |
1282 | static inline uint32_t drm_crtc_mask(const struct drm_crtc *crtc) |
1283 | { |
1284 | return 1 << drm_crtc_index(crtc); |
1285 | } |
1286 | |
1287 | int drm_mode_set_config_internal(struct drm_mode_set *set); |
1288 | struct drm_crtc *drm_crtc_from_index(struct drm_device *dev, int idx); |
1289 | |
1290 | /** |
1291 | * drm_crtc_find - look up a CRTC object from its ID |
1292 | * @dev: DRM device |
1293 | * @file_priv: drm file to check for lease against. |
1294 | * @id: &drm_mode_object ID |
1295 | * |
1296 | * This can be used to look up a CRTC from its userspace ID. Only used by |
1297 | * drivers for legacy IOCTLs and interface, nowadays extensions to the KMS |
1298 | * userspace interface should be done using &drm_property. |
1299 | */ |
1300 | static inline struct drm_crtc *drm_crtc_find(struct drm_device *dev, |
1301 | struct drm_file *file_priv, |
1302 | uint32_t id) |
1303 | { |
1304 | struct drm_mode_object *mo; |
1305 | mo = drm_mode_object_find(dev, file_priv, id, DRM_MODE_OBJECT_CRTC0xcccccccc); |
1306 | return mo ? obj_to_crtc(mo)({ const __typeof( ((struct drm_crtc *)0)->base ) *__mptr = (mo); (struct drm_crtc *)( (char *)__mptr - __builtin_offsetof (struct drm_crtc, base) );}) : NULL((void *)0); |
1307 | } |
1308 | |
1309 | /** |
1310 | * drm_for_each_crtc - iterate over all CRTCs |
1311 | * @crtc: a &struct drm_crtc as the loop cursor |
1312 | * @dev: the &struct drm_device |
1313 | * |
1314 | * Iterate over all CRTCs of @dev. |
1315 | */ |
1316 | #define drm_for_each_crtc(crtc, dev)for (crtc = ({ const __typeof( ((__typeof(*crtc) *)0)->head ) *__mptr = ((&(dev)->mode_config.crtc_list)->next ); (__typeof(*crtc) *)( (char *)__mptr - __builtin_offsetof(__typeof (*crtc), head) );}); &crtc->head != (&(dev)->mode_config .crtc_list); crtc = ({ const __typeof( ((__typeof(*crtc) *)0) ->head ) *__mptr = (crtc->head.next); (__typeof(*crtc) * )( (char *)__mptr - __builtin_offsetof(__typeof(*crtc), head) );})) \ |
1317 | list_for_each_entry(crtc, &(dev)->mode_config.crtc_list, head)for (crtc = ({ const __typeof( ((__typeof(*crtc) *)0)->head ) *__mptr = ((&(dev)->mode_config.crtc_list)->next ); (__typeof(*crtc) *)( (char *)__mptr - __builtin_offsetof(__typeof (*crtc), head) );}); &crtc->head != (&(dev)->mode_config .crtc_list); crtc = ({ const __typeof( ((__typeof(*crtc) *)0) ->head ) *__mptr = (crtc->head.next); (__typeof(*crtc) * )( (char *)__mptr - __builtin_offsetof(__typeof(*crtc), head) );})) |
1318 | |
1319 | /** |
1320 | * drm_for_each_crtc_reverse - iterate over all CRTCs in reverse order |
1321 | * @crtc: a &struct drm_crtc as the loop cursor |
1322 | * @dev: the &struct drm_device |
1323 | * |
1324 | * Iterate over all CRTCs of @dev. |
1325 | */ |
1326 | #define drm_for_each_crtc_reverse(crtc, dev)for (crtc = ({ const __typeof( ((__typeof(*crtc) *)0)->head ) *__mptr = ((&(dev)->mode_config.crtc_list)->prev ); (__typeof(*crtc) *)( (char *)__mptr - __builtin_offsetof(__typeof (*crtc), head) );}); &crtc->head != (&(dev)->mode_config .crtc_list); crtc = ({ const __typeof( ((__typeof(*crtc) *)0) ->head ) *__mptr = (crtc->head.prev); (__typeof(*crtc) * )( (char *)__mptr - __builtin_offsetof(__typeof(*crtc), head) );})) \ |
1327 | list_for_each_entry_reverse(crtc, &(dev)->mode_config.crtc_list, head)for (crtc = ({ const __typeof( ((__typeof(*crtc) *)0)->head ) *__mptr = ((&(dev)->mode_config.crtc_list)->prev ); (__typeof(*crtc) *)( (char *)__mptr - __builtin_offsetof(__typeof (*crtc), head) );}); &crtc->head != (&(dev)->mode_config .crtc_list); crtc = ({ const __typeof( ((__typeof(*crtc) *)0) ->head ) *__mptr = (crtc->head.prev); (__typeof(*crtc) * )( (char *)__mptr - __builtin_offsetof(__typeof(*crtc), head) );})) |
1328 | |
1329 | int drm_crtc_create_scaling_filter_property(struct drm_crtc *crtc, |
1330 | unsigned int supported_filters); |
1331 | |
1332 | #endif /* __DRM_CRTC_H__ */ |
1 | /* Public domain. */ | ||||||
2 | |||||||
3 | #ifndef _LINUX_SLAB_H | ||||||
4 | #define _LINUX_SLAB_H | ||||||
5 | |||||||
6 | #include <sys/types.h> | ||||||
7 | #include <sys/malloc.h> | ||||||
8 | |||||||
9 | #include <linux/types.h> | ||||||
10 | #include <linux/workqueue.h> | ||||||
11 | #include <linux/gfp.h> | ||||||
12 | |||||||
13 | #include <linux/processor.h> /* for CACHELINESIZE */ | ||||||
14 | |||||||
15 | #define ARCH_KMALLOC_MINALIGN64 CACHELINESIZE64 | ||||||
16 | |||||||
17 | #define ZERO_SIZE_PTR((void *)0) NULL((void *)0) | ||||||
18 | |||||||
19 | static inline void * | ||||||
20 | kmalloc(size_t size, int flags) | ||||||
21 | { | ||||||
22 | return malloc(size, M_DRM145, flags); | ||||||
23 | } | ||||||
24 | |||||||
25 | static inline void * | ||||||
26 | kmalloc_array(size_t n, size_t size, int flags) | ||||||
27 | { | ||||||
28 | if (n
| ||||||
29 | return NULL((void *)0); | ||||||
30 | return malloc(n * size, M_DRM145, flags); | ||||||
31 | } | ||||||
32 | |||||||
33 | static inline void * | ||||||
34 | kcalloc(size_t n, size_t size, int flags) | ||||||
35 | { | ||||||
36 | if (n != 0 && SIZE_MAX0xffffffffffffffffUL / n < size) | ||||||
37 | return NULL((void *)0); | ||||||
38 | return malloc(n * size, M_DRM145, flags | M_ZERO0x0008); | ||||||
39 | } | ||||||
40 | |||||||
41 | static inline void * | ||||||
42 | kzalloc(size_t size, int flags) | ||||||
43 | { | ||||||
44 | return malloc(size, M_DRM145, flags | M_ZERO0x0008); | ||||||
45 | } | ||||||
46 | |||||||
47 | static inline void | ||||||
48 | kfree(const void *objp) | ||||||
49 | { | ||||||
50 | free((void *)objp, M_DRM145, 0); | ||||||
51 | } | ||||||
52 | |||||||
53 | #endif |