diff options
author | Gustavo Padovan <gustavo.padovan@collabora.co.uk> | 2016-11-16 08:00:21 -0500 |
---|---|---|
committer | Daniel Vetter <daniel.vetter@ffwll.ch> | 2016-11-16 08:36:27 -0500 |
commit | beaf5af48034c9e2ebb8b2b1fb12dc4d8aeba99e (patch) | |
tree | 17d35317f20a49775472e62efe31e1f9bb87289a | |
parent | 6d6003c4b613c93973e4e870d83f4bed2ad9ac34 (diff) |
drm/fence: add out-fences support
Support DRM out-fences by creating a sync_file with a fence for each CRTC
that sets the OUT_FENCE_PTR property.
We use the out_fence pointer received in the OUT_FENCE_PTR prop to send
the sync_file fd back to userspace.
The sync_file and fd are allocated/created before commit, but the
fd_install operation only happens after we know that commit succeed.
v2: Comment by Rob Clark:
- Squash commit that adds DRM_MODE_ATOMIC_OUT_FENCE flag here.
Comment by Daniel Vetter:
- Add clean up code for out_fences
v3: Comments by Daniel Vetter:
- create DRM_MODE_ATOMIC_EVENT_MASK
- userspace should fill out_fences_ptr with the crtc_ids for which
it wants fences back.
v4: Create OUT_FENCE_PTR properties and remove old approach.
v5: Comments by Brian Starkey:
- Remove extra fence_get() in atomic_ioctl()
- Check ret before iterating on the crtc_state
- check ret before fd_install
- set fence_state to NULL at the beginning
- check fence_state->out_fence_ptr before put_user()
- change order of fput() and put_unused_fd() on failure
- Add access_ok() check to the out_fence_ptr received
- Rebase after fence -> dma_fence rename
- Store out_fence_ptr in the drm_atomic_state
- Split crtc_setup_out_fence()
- return -1 as out_fence with TEST_ONLY flag
v6: Comments by Daniel Vetter
- Add prepare/unprepare_crtc_signaling()
- move struct drm_out_fence_state to drm_atomic.c
- mark get_crtc_fence() as static
Comments by Brian Starkey
- proper set fence_ptr fence_state array
- isolate fence_idx increment
- improve error handling
v7: Comments by Daniel Vetter
- remove prefix from internal functions
- make out_fence_ptr an s64 pointer
- degrade DRM_INFO to DRM_DEBUG_ATOMIC when put_user fail
- fix doc issues
- filter out OUT_FENCE_PTR == NULL and do not fail in this case
- add complete_crtc_signalling()
- krealloc fence_state on demand
Comment by Brian Starkey
- remove unused crtc_state arg from get_out_fence()
v8: Comment by Brian Starkey
- cancel events before check for !fence_state
- convert a few lefovers u64 types for out_fence_ptr
- fix memleak by assign fence_state earlier after realloc
- proper accout num_fences in case of error
v9: Comment by Brian Starkey
- memset last position of fence_state after krealloc
Comments by Sean Paul
- pass install_fds in complete_crtc_signaling() instead of ret
- put_user(-1, fence_ptr) when decoding props
v10: Comment by Brian Starkey
- remove unneeded num_fences increment on error path
- kfree fence_state after installing fences fd
v11: rebase against latest drm-misc
v12: rebase again against latest drm-misc
Signed-off-by: Gustavo Padovan <gustavo.padovan@collabora.co.uk>
Reviewed-by: Brian Starkey <brian.starkey@arm.com> (v10)
Reviewed-by: Sean Paul <seanpaul@chromium.org>
Tested-by: Robert Foss <robert.foss@collabora.com> (v10)
[danvet: Appease checkpatch.]
Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
Link: http://patchwork.freedesktop.org/patch/msgid/1479301221-13056-1-git-send-email-gustavo@padovan.org
-rw-r--r-- | drivers/gpu/drm/drm_atomic.c | 241 | ||||
-rw-r--r-- | drivers/gpu/drm/drm_crtc.c | 2 | ||||
-rw-r--r-- | drivers/gpu/drm/drm_mode_config.c | 6 | ||||
-rw-r--r-- | include/drm/drm_atomic.h | 1 | ||||
-rw-r--r-- | include/drm/drm_mode_config.h | 6 |
5 files changed, 211 insertions, 45 deletions
diff --git a/drivers/gpu/drm/drm_atomic.c b/drivers/gpu/drm/drm_atomic.c index 3ad780ad24f9..b476ec585547 100644 --- a/drivers/gpu/drm/drm_atomic.c +++ b/drivers/gpu/drm/drm_atomic.c | |||
@@ -290,6 +290,23 @@ drm_atomic_get_crtc_state(struct drm_atomic_state *state, | |||
290 | } | 290 | } |
291 | EXPORT_SYMBOL(drm_atomic_get_crtc_state); | 291 | EXPORT_SYMBOL(drm_atomic_get_crtc_state); |
292 | 292 | ||
293 | static void set_out_fence_for_crtc(struct drm_atomic_state *state, | ||
294 | struct drm_crtc *crtc, s64 __user *fence_ptr) | ||
295 | { | ||
296 | state->crtcs[drm_crtc_index(crtc)].out_fence_ptr = fence_ptr; | ||
297 | } | ||
298 | |||
299 | static s64 __user *get_out_fence_for_crtc(struct drm_atomic_state *state, | ||
300 | struct drm_crtc *crtc) | ||
301 | { | ||
302 | s64 __user *fence_ptr; | ||
303 | |||
304 | fence_ptr = state->crtcs[drm_crtc_index(crtc)].out_fence_ptr; | ||
305 | state->crtcs[drm_crtc_index(crtc)].out_fence_ptr = NULL; | ||
306 | |||
307 | return fence_ptr; | ||
308 | } | ||
309 | |||
293 | /** | 310 | /** |
294 | * drm_atomic_set_mode_for_crtc - set mode for CRTC | 311 | * drm_atomic_set_mode_for_crtc - set mode for CRTC |
295 | * @state: the CRTC whose incoming state to update | 312 | * @state: the CRTC whose incoming state to update |
@@ -494,6 +511,16 @@ int drm_atomic_crtc_set_property(struct drm_crtc *crtc, | |||
494 | &replaced); | 511 | &replaced); |
495 | state->color_mgmt_changed |= replaced; | 512 | state->color_mgmt_changed |= replaced; |
496 | return ret; | 513 | return ret; |
514 | } else if (property == config->prop_out_fence_ptr) { | ||
515 | s64 __user *fence_ptr = u64_to_user_ptr(val); | ||
516 | |||
517 | if (!fence_ptr) | ||
518 | return 0; | ||
519 | |||
520 | if (put_user(-1, fence_ptr)) | ||
521 | return -EFAULT; | ||
522 | |||
523 | set_out_fence_for_crtc(state->state, crtc, fence_ptr); | ||
497 | } else if (crtc->funcs->atomic_set_property) | 524 | } else if (crtc->funcs->atomic_set_property) |
498 | return crtc->funcs->atomic_set_property(crtc, state, property, val); | 525 | return crtc->funcs->atomic_set_property(crtc, state, property, val); |
499 | else | 526 | else |
@@ -536,6 +563,8 @@ drm_atomic_crtc_get_property(struct drm_crtc *crtc, | |||
536 | *val = (state->ctm) ? state->ctm->base.id : 0; | 563 | *val = (state->ctm) ? state->ctm->base.id : 0; |
537 | else if (property == config->gamma_lut_property) | 564 | else if (property == config->gamma_lut_property) |
538 | *val = (state->gamma_lut) ? state->gamma_lut->base.id : 0; | 565 | *val = (state->gamma_lut) ? state->gamma_lut->base.id : 0; |
566 | else if (property == config->prop_out_fence_ptr) | ||
567 | *val = 0; | ||
539 | else if (crtc->funcs->atomic_get_property) | 568 | else if (crtc->funcs->atomic_get_property) |
540 | return crtc->funcs->atomic_get_property(crtc, state, property, val); | 569 | return crtc->funcs->atomic_get_property(crtc, state, property, val); |
541 | else | 570 | else |
@@ -1664,11 +1693,9 @@ int drm_atomic_debugfs_init(struct drm_minor *minor) | |||
1664 | */ | 1693 | */ |
1665 | 1694 | ||
1666 | static struct drm_pending_vblank_event *create_vblank_event( | 1695 | static struct drm_pending_vblank_event *create_vblank_event( |
1667 | struct drm_device *dev, struct drm_file *file_priv, | 1696 | struct drm_device *dev, uint64_t user_data) |
1668 | struct dma_fence *fence, uint64_t user_data) | ||
1669 | { | 1697 | { |
1670 | struct drm_pending_vblank_event *e = NULL; | 1698 | struct drm_pending_vblank_event *e = NULL; |
1671 | int ret; | ||
1672 | 1699 | ||
1673 | e = kzalloc(sizeof *e, GFP_KERNEL); | 1700 | e = kzalloc(sizeof *e, GFP_KERNEL); |
1674 | if (!e) | 1701 | if (!e) |
@@ -1678,17 +1705,6 @@ static struct drm_pending_vblank_event *create_vblank_event( | |||
1678 | e->event.base.length = sizeof(e->event); | 1705 | e->event.base.length = sizeof(e->event); |
1679 | e->event.user_data = user_data; | 1706 | e->event.user_data = user_data; |
1680 | 1707 | ||
1681 | if (file_priv) { | ||
1682 | ret = drm_event_reserve_init(dev, file_priv, &e->base, | ||
1683 | &e->event.base); | ||
1684 | if (ret) { | ||
1685 | kfree(e); | ||
1686 | return NULL; | ||
1687 | } | ||
1688 | } | ||
1689 | |||
1690 | e->base.fence = fence; | ||
1691 | |||
1692 | return e; | 1708 | return e; |
1693 | } | 1709 | } |
1694 | 1710 | ||
@@ -1793,6 +1809,165 @@ void drm_atomic_clean_old_fb(struct drm_device *dev, | |||
1793 | } | 1809 | } |
1794 | EXPORT_SYMBOL(drm_atomic_clean_old_fb); | 1810 | EXPORT_SYMBOL(drm_atomic_clean_old_fb); |
1795 | 1811 | ||
1812 | static struct dma_fence *get_crtc_fence(struct drm_crtc *crtc) | ||
1813 | { | ||
1814 | struct dma_fence *fence; | ||
1815 | |||
1816 | fence = kzalloc(sizeof(*fence), GFP_KERNEL); | ||
1817 | if (!fence) | ||
1818 | return NULL; | ||
1819 | |||
1820 | dma_fence_init(fence, &drm_crtc_fence_ops, &crtc->fence_lock, | ||
1821 | crtc->fence_context, ++crtc->fence_seqno); | ||
1822 | |||
1823 | return fence; | ||
1824 | } | ||
1825 | |||
1826 | struct drm_out_fence_state { | ||
1827 | s64 __user *out_fence_ptr; | ||
1828 | struct sync_file *sync_file; | ||
1829 | int fd; | ||
1830 | }; | ||
1831 | |||
1832 | static int setup_out_fence(struct drm_out_fence_state *fence_state, | ||
1833 | struct dma_fence *fence) | ||
1834 | { | ||
1835 | fence_state->fd = get_unused_fd_flags(O_CLOEXEC); | ||
1836 | if (fence_state->fd < 0) | ||
1837 | return fence_state->fd; | ||
1838 | |||
1839 | if (put_user(fence_state->fd, fence_state->out_fence_ptr)) | ||
1840 | return -EFAULT; | ||
1841 | |||
1842 | fence_state->sync_file = sync_file_create(fence); | ||
1843 | if (!fence_state->sync_file) | ||
1844 | return -ENOMEM; | ||
1845 | |||
1846 | return 0; | ||
1847 | } | ||
1848 | |||
1849 | static int prepare_crtc_signaling(struct drm_device *dev, | ||
1850 | struct drm_atomic_state *state, | ||
1851 | struct drm_mode_atomic *arg, | ||
1852 | struct drm_file *file_priv, | ||
1853 | struct drm_out_fence_state **fence_state, | ||
1854 | unsigned int *num_fences) | ||
1855 | { | ||
1856 | struct drm_crtc *crtc; | ||
1857 | struct drm_crtc_state *crtc_state; | ||
1858 | int i, ret; | ||
1859 | |||
1860 | if (arg->flags & DRM_MODE_ATOMIC_TEST_ONLY) | ||
1861 | return 0; | ||
1862 | |||
1863 | for_each_crtc_in_state(state, crtc, crtc_state, i) { | ||
1864 | u64 __user *fence_ptr; | ||
1865 | |||
1866 | fence_ptr = get_out_fence_for_crtc(crtc_state->state, crtc); | ||
1867 | |||
1868 | if (arg->flags & DRM_MODE_PAGE_FLIP_EVENT || fence_ptr) { | ||
1869 | struct drm_pending_vblank_event *e; | ||
1870 | |||
1871 | e = create_vblank_event(dev, arg->user_data); | ||
1872 | if (!e) | ||
1873 | return -ENOMEM; | ||
1874 | |||
1875 | crtc_state->event = e; | ||
1876 | } | ||
1877 | |||
1878 | if (arg->flags & DRM_MODE_PAGE_FLIP_EVENT) { | ||
1879 | struct drm_pending_vblank_event *e = crtc_state->event; | ||
1880 | |||
1881 | if (!file_priv) | ||
1882 | continue; | ||
1883 | |||
1884 | ret = drm_event_reserve_init(dev, file_priv, &e->base, | ||
1885 | &e->event.base); | ||
1886 | if (ret) { | ||
1887 | kfree(e); | ||
1888 | crtc_state->event = NULL; | ||
1889 | return ret; | ||
1890 | } | ||
1891 | } | ||
1892 | |||
1893 | if (fence_ptr) { | ||
1894 | struct dma_fence *fence; | ||
1895 | struct drm_out_fence_state *f; | ||
1896 | |||
1897 | f = krealloc(*fence_state, sizeof(**fence_state) * | ||
1898 | (*num_fences + 1), GFP_KERNEL); | ||
1899 | if (!f) | ||
1900 | return -ENOMEM; | ||
1901 | |||
1902 | memset(&f[*num_fences], 0, sizeof(*f)); | ||
1903 | |||
1904 | f[*num_fences].out_fence_ptr = fence_ptr; | ||
1905 | *fence_state = f; | ||
1906 | |||
1907 | fence = get_crtc_fence(crtc); | ||
1908 | if (!fence) | ||
1909 | return -ENOMEM; | ||
1910 | |||
1911 | ret = setup_out_fence(&f[(*num_fences)++], fence); | ||
1912 | if (ret) { | ||
1913 | dma_fence_put(fence); | ||
1914 | return ret; | ||
1915 | } | ||
1916 | |||
1917 | crtc_state->event->base.fence = fence; | ||
1918 | } | ||
1919 | } | ||
1920 | |||
1921 | return 0; | ||
1922 | } | ||
1923 | |||
1924 | static void complete_crtc_signaling(struct drm_device *dev, | ||
1925 | struct drm_atomic_state *state, | ||
1926 | struct drm_out_fence_state *fence_state, | ||
1927 | unsigned int num_fences, | ||
1928 | bool install_fds) | ||
1929 | { | ||
1930 | struct drm_crtc *crtc; | ||
1931 | struct drm_crtc_state *crtc_state; | ||
1932 | int i; | ||
1933 | |||
1934 | if (install_fds) { | ||
1935 | for (i = 0; i < num_fences; i++) | ||
1936 | fd_install(fence_state[i].fd, | ||
1937 | fence_state[i].sync_file->file); | ||
1938 | |||
1939 | kfree(fence_state); | ||
1940 | return; | ||
1941 | } | ||
1942 | |||
1943 | for_each_crtc_in_state(state, crtc, crtc_state, i) { | ||
1944 | /* | ||
1945 | * TEST_ONLY and PAGE_FLIP_EVENT are mutually | ||
1946 | * exclusive, if they weren't, this code should be | ||
1947 | * called on success for TEST_ONLY too. | ||
1948 | */ | ||
1949 | if (crtc_state->event) | ||
1950 | drm_event_cancel_free(dev, &crtc_state->event->base); | ||
1951 | } | ||
1952 | |||
1953 | if (!fence_state) | ||
1954 | return; | ||
1955 | |||
1956 | for (i = 0; i < num_fences; i++) { | ||
1957 | if (fence_state[i].sync_file) | ||
1958 | fput(fence_state[i].sync_file->file); | ||
1959 | if (fence_state[i].fd >= 0) | ||
1960 | put_unused_fd(fence_state[i].fd); | ||
1961 | |||
1962 | /* If this fails log error to the user */ | ||
1963 | if (fence_state[i].out_fence_ptr && | ||
1964 | put_user(-1, fence_state[i].out_fence_ptr)) | ||
1965 | DRM_DEBUG_ATOMIC("Couldn't clear out_fence_ptr\n"); | ||
1966 | } | ||
1967 | |||
1968 | kfree(fence_state); | ||
1969 | } | ||
1970 | |||
1796 | int drm_mode_atomic_ioctl(struct drm_device *dev, | 1971 | int drm_mode_atomic_ioctl(struct drm_device *dev, |
1797 | void *data, struct drm_file *file_priv) | 1972 | void *data, struct drm_file *file_priv) |
1798 | { | 1973 | { |
@@ -1805,11 +1980,10 @@ int drm_mode_atomic_ioctl(struct drm_device *dev, | |||
1805 | struct drm_atomic_state *state; | 1980 | struct drm_atomic_state *state; |
1806 | struct drm_modeset_acquire_ctx ctx; | 1981 | struct drm_modeset_acquire_ctx ctx; |
1807 | struct drm_plane *plane; | 1982 | struct drm_plane *plane; |
1808 | struct drm_crtc *crtc; | 1983 | struct drm_out_fence_state *fence_state = NULL; |
1809 | struct drm_crtc_state *crtc_state; | ||
1810 | unsigned plane_mask; | 1984 | unsigned plane_mask; |
1811 | int ret = 0; | 1985 | int ret = 0; |
1812 | unsigned int i, j; | 1986 | unsigned int i, j, num_fences = 0; |
1813 | 1987 | ||
1814 | /* disallow for drivers not supporting atomic: */ | 1988 | /* disallow for drivers not supporting atomic: */ |
1815 | if (!drm_core_check_feature(dev, DRIVER_ATOMIC)) | 1989 | if (!drm_core_check_feature(dev, DRIVER_ATOMIC)) |
@@ -1924,20 +2098,10 @@ retry: | |||
1924 | drm_mode_object_unreference(obj); | 2098 | drm_mode_object_unreference(obj); |
1925 | } | 2099 | } |
1926 | 2100 | ||
1927 | if (arg->flags & DRM_MODE_PAGE_FLIP_EVENT) { | 2101 | ret = prepare_crtc_signaling(dev, state, arg, file_priv, &fence_state, |
1928 | for_each_crtc_in_state(state, crtc, crtc_state, i) { | 2102 | &num_fences); |
1929 | struct drm_pending_vblank_event *e; | 2103 | if (ret) |
1930 | 2104 | goto out; | |
1931 | e = create_vblank_event(dev, file_priv, NULL, | ||
1932 | arg->user_data); | ||
1933 | if (!e) { | ||
1934 | ret = -ENOMEM; | ||
1935 | goto out; | ||
1936 | } | ||
1937 | |||
1938 | crtc_state->event = e; | ||
1939 | } | ||
1940 | } | ||
1941 | 2105 | ||
1942 | if (arg->flags & DRM_MODE_ATOMIC_TEST_ONLY) { | 2106 | if (arg->flags & DRM_MODE_ATOMIC_TEST_ONLY) { |
1943 | /* | 2107 | /* |
@@ -1957,20 +2121,7 @@ retry: | |||
1957 | out: | 2121 | out: |
1958 | drm_atomic_clean_old_fb(dev, plane_mask, ret); | 2122 | drm_atomic_clean_old_fb(dev, plane_mask, ret); |
1959 | 2123 | ||
1960 | if (ret && arg->flags & DRM_MODE_PAGE_FLIP_EVENT) { | 2124 | complete_crtc_signaling(dev, state, fence_state, num_fences, !ret); |
1961 | /* | ||
1962 | * TEST_ONLY and PAGE_FLIP_EVENT are mutually exclusive, | ||
1963 | * if they weren't, this code should be called on success | ||
1964 | * for TEST_ONLY too. | ||
1965 | */ | ||
1966 | |||
1967 | for_each_crtc_in_state(state, crtc, crtc_state, i) { | ||
1968 | if (!crtc_state->event) | ||
1969 | continue; | ||
1970 | |||
1971 | drm_event_cancel_free(dev, &crtc_state->event->base); | ||
1972 | } | ||
1973 | } | ||
1974 | 2125 | ||
1975 | if (ret == -EDEADLK) { | 2126 | if (ret == -EDEADLK) { |
1976 | drm_atomic_state_clear(state); | 2127 | drm_atomic_state_clear(state); |
diff --git a/drivers/gpu/drm/drm_crtc.c b/drivers/gpu/drm/drm_crtc.c index dbfae422241e..90931e039731 100644 --- a/drivers/gpu/drm/drm_crtc.c +++ b/drivers/gpu/drm/drm_crtc.c | |||
@@ -267,6 +267,8 @@ int drm_crtc_init_with_planes(struct drm_device *dev, struct drm_crtc *crtc, | |||
267 | if (drm_core_check_feature(dev, DRIVER_ATOMIC)) { | 267 | if (drm_core_check_feature(dev, DRIVER_ATOMIC)) { |
268 | drm_object_attach_property(&crtc->base, config->prop_active, 0); | 268 | drm_object_attach_property(&crtc->base, config->prop_active, 0); |
269 | drm_object_attach_property(&crtc->base, config->prop_mode_id, 0); | 269 | drm_object_attach_property(&crtc->base, config->prop_mode_id, 0); |
270 | drm_object_attach_property(&crtc->base, | ||
271 | config->prop_out_fence_ptr, 0); | ||
270 | } | 272 | } |
271 | 273 | ||
272 | return 0; | 274 | return 0; |
diff --git a/drivers/gpu/drm/drm_mode_config.c b/drivers/gpu/drm/drm_mode_config.c index 8bee2addf7b4..2735a5847ffa 100644 --- a/drivers/gpu/drm/drm_mode_config.c +++ b/drivers/gpu/drm/drm_mode_config.c | |||
@@ -314,6 +314,12 @@ static int drm_mode_create_standard_properties(struct drm_device *dev) | |||
314 | return -ENOMEM; | 314 | return -ENOMEM; |
315 | dev->mode_config.prop_in_fence_fd = prop; | 315 | dev->mode_config.prop_in_fence_fd = prop; |
316 | 316 | ||
317 | prop = drm_property_create_range(dev, DRM_MODE_PROP_ATOMIC, | ||
318 | "OUT_FENCE_PTR", 0, U64_MAX); | ||
319 | if (!prop) | ||
320 | return -ENOMEM; | ||
321 | dev->mode_config.prop_out_fence_ptr = prop; | ||
322 | |||
317 | prop = drm_property_create_object(dev, DRM_MODE_PROP_ATOMIC, | 323 | prop = drm_property_create_object(dev, DRM_MODE_PROP_ATOMIC, |
318 | "CRTC_ID", DRM_MODE_OBJECT_CRTC); | 324 | "CRTC_ID", DRM_MODE_OBJECT_CRTC); |
319 | if (!prop) | 325 | if (!prop) |
diff --git a/include/drm/drm_atomic.h b/include/drm/drm_atomic.h index 331bb100b718..c0eaec70a203 100644 --- a/include/drm/drm_atomic.h +++ b/include/drm/drm_atomic.h | |||
@@ -144,6 +144,7 @@ struct __drm_crtcs_state { | |||
144 | struct drm_crtc *ptr; | 144 | struct drm_crtc *ptr; |
145 | struct drm_crtc_state *state; | 145 | struct drm_crtc_state *state; |
146 | struct drm_crtc_commit *commit; | 146 | struct drm_crtc_commit *commit; |
147 | s64 __user *out_fence_ptr; | ||
147 | }; | 148 | }; |
148 | 149 | ||
149 | struct __drm_connnectors_state { | 150 | struct __drm_connnectors_state { |
diff --git a/include/drm/drm_mode_config.h b/include/drm/drm_mode_config.h index c6754ccefe2b..bf9991b20611 100644 --- a/include/drm/drm_mode_config.h +++ b/include/drm/drm_mode_config.h | |||
@@ -486,6 +486,12 @@ struct drm_mode_config { | |||
486 | */ | 486 | */ |
487 | struct drm_property *prop_in_fence_fd; | 487 | struct drm_property *prop_in_fence_fd; |
488 | /** | 488 | /** |
489 | * @prop_out_fence_ptr: Sync File fd pointer representing the | ||
490 | * outgoing fences for a CRTC. Userspace should provide a pointer to a | ||
491 | * value of type s64, and then cast that pointer to u64. | ||
492 | */ | ||
493 | struct drm_property *prop_out_fence_ptr; | ||
494 | /** | ||
489 | * @prop_crtc_id: Default atomic plane property to specify the | 495 | * @prop_crtc_id: Default atomic plane property to specify the |
490 | * &drm_crtc. | 496 | * &drm_crtc. |
491 | */ | 497 | */ |