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