1/*
2 * Copyright 2008 Tungsten Graphics, Inc., Cedar Park, Texas.
3 * Copyright 2019 NVIDIA CORPORATION
4 * All Rights Reserved.
5 *
6 * Permission is hereby granted, free of charge, to any person obtaining a
7 * copy of this software and associated documentation files (the
8 * "Software"), to deal in the Software without restriction, including
9 * without limitation the rights to use, copy, modify, merge, publish,
10 * distribute, sub license, and/or sell copies of the Software, and to
11 * permit persons to whom the Software is furnished to do so, subject to
12 * the following conditions:
13 *
14 * The above copyright notice and this permission notice (including the
15 * next paragraph) shall be included in all copies or substantial portions
16 * of the Software.
17 *
18 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
19 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
20 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
21 * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR
22 * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
23 * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
24 * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
25 *
26 *
27 * Author: Alan Hourihane <alanh@tungstengraphics.com>
28 * Additional contributors:
29 *   Aaron Plattner <aplattner@nvidia.com>
30 */
31
32#include <errno.h>
33#include <drm.h>
34#include <xf86drm.h>
35#include <xf86Crtc.h>
36#include <damage.h>
37#include <X11/extensions/dpmsconst.h>
38#include <shadow.h>
39#ifdef GLAMOR_HAS_GBM
40#define GLAMOR_FOR_XORG 1
41#include "glamor.h"
42#include <gbm.h>
43#endif
44
45#include "drmmode_display.h"
46#define MS_LOGLEVEL_DEBUG 4
47
48struct ms_vrr_priv {
49    Bool variable_refresh;
50};
51
52typedef enum {
53    OPTION_SW_CURSOR,
54    OPTION_DEVICE_PATH,
55    OPTION_SHADOW_FB,
56    OPTION_ACCEL_METHOD,
57    OPTION_PAGEFLIP,
58    OPTION_ZAPHOD_HEADS,
59    OPTION_DOUBLE_SHADOW,
60    OPTION_ATOMIC,
61    OPTION_VARIABLE_REFRESH,
62    OPTION_USE_GAMMA_LUT,
63    OPTION_ASYNC_FLIP_SECONDARIES,
64} modesettingOpts;
65
66typedef struct
67{
68    int fd;
69    int fd_ref;
70    unsigned long fd_wakeup_registered; /* server generation for which fd has been registered for wakeup handling */
71    int fd_wakeup_ref;
72    unsigned int assigned_crtcs;
73} modesettingEntRec, *modesettingEntPtr;
74
75typedef void (*ms_drm_handler_proc)(uint64_t frame,
76                                    uint64_t usec,
77                                    void *data);
78
79typedef void (*ms_drm_abort_proc)(void *data);
80
81/**
82 * A tracked handler for an event that will hopefully be generated by
83 * the kernel, and what to do when it is encountered.
84 */
85struct ms_drm_queue {
86    struct xorg_list list;
87    xf86CrtcPtr crtc;
88    uint32_t seq;
89    void *data;
90    ScrnInfoPtr scrn;
91    ms_drm_handler_proc handler;
92    ms_drm_abort_proc abort;
93};
94
95typedef struct _modesettingRec {
96    int fd;
97    Bool fd_passed;
98
99    int Chipset;
100    EntityInfoPtr pEnt;
101
102    Bool noAccel;
103    CloseScreenProcPtr CloseScreen;
104    CreateWindowProcPtr CreateWindow;
105    unsigned int SaveGeneration;
106
107    CreateScreenResourcesProcPtr createScreenResources;
108    ScreenBlockHandlerProcPtr BlockHandler;
109    miPointerSpriteFuncPtr SpriteFuncs;
110    void *driver;
111
112    drmmode_rec drmmode;
113
114    drmEventContext event_context;
115
116    /**
117     * Page flipping stuff.
118     *  @{
119     */
120    Bool atomic_modeset_capable;
121    Bool atomic_modeset;
122    Bool pending_modeset;
123    /** @} */
124
125    DamagePtr damage;
126    Bool dirty_enabled;
127
128    uint32_t cursor_width, cursor_height;
129
130    Bool has_queue_sequence;
131    Bool tried_queue_sequence;
132
133    Bool kms_has_modifiers;
134
135    /* VRR support */
136    Bool vrr_support;
137    WindowPtr flip_window;
138
139    Bool is_connector_vrr_capable;
140    uint32_t connector_prop_id;
141
142    /* shadow API */
143    struct {
144        Bool (*Setup)(ScreenPtr);
145        Bool (*Add)(ScreenPtr, PixmapPtr, ShadowUpdateProc, ShadowWindowProc,
146                    int, void *);
147        void (*Remove)(ScreenPtr, PixmapPtr);
148        void (*Update32to24)(ScreenPtr, shadowBufPtr);
149        void (*UpdatePacked)(ScreenPtr, shadowBufPtr);
150    } shadow;
151
152#ifdef GLAMOR_HAS_GBM
153    /* glamor API */
154    struct {
155        Bool (*back_pixmap_from_fd)(PixmapPtr, int, CARD16, CARD16, CARD16,
156                                    CARD8, CARD8);
157        void (*block_handler)(ScreenPtr);
158        void (*clear_pixmap)(PixmapPtr);
159        Bool (*egl_create_textured_pixmap)(PixmapPtr, int, int);
160        Bool (*egl_create_textured_pixmap_from_gbm_bo)(PixmapPtr,
161                                                       struct gbm_bo *,
162                                                       Bool);
163        void (*egl_exchange_buffers)(PixmapPtr, PixmapPtr);
164        struct gbm_device *(*egl_get_gbm_device)(ScreenPtr);
165        Bool (*egl_init)(ScrnInfoPtr, int);
166        void (*finish)(ScreenPtr);
167        struct gbm_bo *(*gbm_bo_from_pixmap)(ScreenPtr, PixmapPtr);
168        Bool (*init)(ScreenPtr, unsigned int);
169        int (*name_from_pixmap)(PixmapPtr, CARD16 *, CARD32 *);
170        void (*set_drawable_modifiers_func)(ScreenPtr,
171                                            GetDrawableModifiersFuncPtr);
172        int (*shareable_fd_from_pixmap)(ScreenPtr, PixmapPtr, CARD16 *,
173                                        CARD32 *);
174        Bool (*supports_pixmap_import_export)(ScreenPtr);
175        XF86VideoAdaptorPtr (*xv_init)(ScreenPtr, int);
176        const char *(*egl_get_driver_name)(ScreenPtr);
177    } glamor;
178#endif
179} modesettingRec, *modesettingPtr;
180
181#define glamor_finish(screen) ms->glamor.finish(screen)
182
183#define modesettingPTR(p) ((modesettingPtr)((p)->driverPrivate))
184modesettingEntPtr ms_ent_priv(ScrnInfoPtr scrn);
185
186uint32_t ms_drm_queue_alloc(xf86CrtcPtr crtc,
187                            void *data,
188                            ms_drm_handler_proc handler,
189                            ms_drm_abort_proc abort);
190
191typedef enum ms_queue_flag {
192    MS_QUEUE_ABSOLUTE = 0,
193    MS_QUEUE_RELATIVE = 1,
194    MS_QUEUE_NEXT_ON_MISS = 2
195} ms_queue_flag;
196
197Bool ms_queue_vblank(xf86CrtcPtr crtc, ms_queue_flag flags,
198                     uint64_t msc, uint64_t *msc_queued, uint32_t seq);
199
200void ms_drm_abort(ScrnInfoPtr scrn,
201                  Bool (*match)(void *data, void *match_data),
202                  void *match_data);
203void ms_drm_abort_seq(ScrnInfoPtr scrn, uint32_t seq);
204
205Bool xf86_crtc_on(xf86CrtcPtr crtc);
206
207xf86CrtcPtr ms_dri2_crtc_covering_drawable(DrawablePtr pDraw);
208RRCrtcPtr   ms_randr_crtc_covering_drawable(DrawablePtr pDraw);
209
210int ms_get_crtc_ust_msc(xf86CrtcPtr crtc, uint64_t *ust, uint64_t *msc);
211
212uint64_t ms_kernel_msc_to_crtc_msc(xf86CrtcPtr crtc, uint64_t sequence, Bool is64bit);
213
214
215Bool ms_dri2_screen_init(ScreenPtr screen);
216void ms_dri2_close_screen(ScreenPtr screen);
217
218Bool ms_vblank_screen_init(ScreenPtr screen);
219void ms_vblank_close_screen(ScreenPtr screen);
220
221Bool ms_present_screen_init(ScreenPtr screen);
222
223#ifdef GLAMOR_HAS_GBM
224
225typedef void (*ms_pageflip_handler_proc)(modesettingPtr ms,
226                                         uint64_t frame,
227                                         uint64_t usec,
228                                         void *data);
229
230typedef void (*ms_pageflip_abort_proc)(modesettingPtr ms, void *data);
231
232Bool ms_do_pageflip(ScreenPtr screen,
233                    PixmapPtr new_front,
234                    void *event,
235                    int ref_crtc_vblank_pipe,
236                    Bool async,
237                    ms_pageflip_handler_proc pageflip_handler,
238                    ms_pageflip_abort_proc pageflip_abort,
239                    const char *log_prefix);
240
241#endif
242
243int ms_flush_drm_events(ScreenPtr screen);
244Bool ms_window_has_variable_refresh(modesettingPtr ms, WindowPtr win);
245void ms_present_set_screen_vrr(ScrnInfoPtr scrn, Bool vrr_enabled);
246