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