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 <xf86xv.h> 34 #include <xf86Crtc.h> 35 #include <damage.h> 36 #include <X11/extensions/dpmsconst.h> 37 38 #ifdef GLAMOR_HAS_GBM 39 #define GLAMOR_FOR_XORG 1 40 #include "glamor.h" 41 #include <gbm.h> 42 #endif 43 44 #include "drmmode_display.h" 45 #define MS_LOGLEVEL_DEBUG 4 46 47 typedef enum { 48 OPTION_SW_CURSOR, 49 OPTION_DEVICE_PATH, 50 OPTION_SHADOW_FB, 51 OPTION_ACCEL_METHOD, 52 OPTION_PAGEFLIP, 53 OPTION_ZAPHOD_HEADS, 54 OPTION_DOUBLE_SHADOW, 55 OPTION_ATOMIC, 56 OPTION_USE_GAMMA_LUT, 57 OPTION_FLIP_FB, 58 OPTION_FLIP_FB_RATE, 59 OPTION_BIND_CURRENT, 60 OPTION_NO_EDID, 61 OPTION_HOTPLUG_RESET, 62 OPTION_WARM_UP, 63 OPTION_VIRTUAL_SIZE, 64 OPTION_PADDING, 65 } modesettingOpts; 66 67 typedef struct 68 { 69 int fd; 70 int fd_ref; 71 unsigned long fd_wakeup_registered; /* server generation for which fd has been registered for wakeup handling */ 72 int fd_wakeup_ref; 73 unsigned int assigned_crtcs; 74 } modesettingEntRec, *modesettingEntPtr; 75 76 typedef void (*ms_drm_handler_proc)(uint64_t frame, 77 uint64_t usec, 78 void *data); 79 80 typedef void (*ms_drm_abort_proc)(void *data); 81 82 /** 83 * A tracked handler for an event that will hopefully be generated by 84 * the kernel, and what to do when it is encountered. 85 */ 86 struct ms_drm_queue { 87 struct xorg_list list; 88 xf86CrtcPtr crtc; 89 uint32_t seq; 90 void *data; 91 ScrnInfoPtr scrn; 92 ms_drm_handler_proc handler; 93 ms_drm_abort_proc abort; 94 }; 95 96 typedef struct _modesettingRec { 97 int fd; 98 Bool fd_passed; 99 100 int Chipset; 101 EntityInfoPtr pEnt; 102 103 Bool noAccel; 104 CloseScreenProcPtr CloseScreen; 105 CreateWindowProcPtr CreateWindow; 106 unsigned int SaveGeneration; 107 108 CreateScreenResourcesProcPtr createScreenResources; 109 ScreenBlockHandlerProcPtr BlockHandler; 110 miPointerSpriteFuncPtr SpriteFuncs; 111 void *driver; 112 113 drmmode_rec drmmode; 114 115 drmEventContext event_context; 116 117 /** 118 * Page flipping stuff. 119 * @{ 120 */ 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 Bool async_pageflip; 135 136 Bool warm_up; 137 138 XF86VideoAdaptorPtr adaptor; 139 } modesettingRec, *modesettingPtr; 140 141 #define modesettingPTR(p) ((modesettingPtr)((p)->driverPrivate)) 142 modesettingEntPtr ms_ent_priv(ScrnInfoPtr scrn); 143 144 uint32_t ms_drm_queue_alloc(xf86CrtcPtr crtc, 145 void *data, 146 ms_drm_handler_proc handler, 147 ms_drm_abort_proc abort); 148 149 typedef enum ms_queue_flag { 150 MS_QUEUE_ABSOLUTE = 0, 151 MS_QUEUE_RELATIVE = 1, 152 MS_QUEUE_NEXT_ON_MISS = 2 153 } ms_queue_flag; 154 155 Bool ms_queue_vblank(xf86CrtcPtr crtc, ms_queue_flag flags, 156 uint64_t msc, uint64_t *msc_queued, uint32_t seq); 157 158 void ms_drm_abort(ScrnInfoPtr scrn, 159 Bool (*match)(void *data, void *match_data), 160 void *match_data); 161 void ms_drm_abort_seq(ScrnInfoPtr scrn, uint32_t seq); 162 163 Bool ms_crtc_on(xf86CrtcPtr crtc); 164 165 xf86CrtcPtr ms_dri2_crtc_covering_drawable(DrawablePtr pDraw); 166 RRCrtcPtr ms_randr_crtc_covering_drawable(DrawablePtr pDraw); 167 168 int ms_get_crtc_ust_msc(xf86CrtcPtr crtc, CARD64 *ust, CARD64 *msc); 169 170 uint64_t ms_kernel_msc_to_crtc_msc(xf86CrtcPtr crtc, uint64_t sequence, Bool is64bit); 171 172 173 Bool ms_dri2_screen_init(ScreenPtr screen); 174 void ms_dri2_close_screen(ScreenPtr screen); 175 176 Bool ms_vblank_screen_init(ScreenPtr screen); 177 void ms_vblank_close_screen(ScreenPtr screen); 178 179 Bool ms_present_screen_init(ScreenPtr screen); 180 181 typedef void (*ms_pageflip_handler_proc)(modesettingPtr ms, 182 uint64_t frame, 183 uint64_t usec, 184 void *data); 185 186 typedef void (*ms_pageflip_abort_proc)(modesettingPtr ms, void *data); 187 188 Bool ms_do_pageflip_bo(ScreenPtr screen, 189 drmmode_bo *new_front_bo, 190 void *event, 191 int ref_crtc_vblank_pipe, 192 xf86CrtcPtr target_crtc, 193 Bool async, 194 ms_pageflip_handler_proc pageflip_handler, 195 ms_pageflip_abort_proc pageflip_abort); 196 197 Bool ms_do_pageflip(ScreenPtr screen, 198 PixmapPtr new_front, 199 void *event, 200 int ref_crtc_vblank_pipe, 201 Bool async, 202 ms_pageflip_handler_proc pageflip_handler, 203 ms_pageflip_abort_proc pageflip_abort); 204 205 int ms_flush_drm_events(ScreenPtr screen); 206 207 Bool ms_copy_area(PixmapPtr pSrc, PixmapPtr pDst, 208 pixman_f_transform_t *transform, RegionPtr clip); 209 210 Bool ms_init_exa(ScrnInfoPtr scrn); 211 void ms_deinit_exa(ScrnInfoPtr scrn); 212 Bool ms_exa_set_pixmap_bo(ScrnInfoPtr scrn, PixmapPtr pPixmap, 213 struct dumb_bo *bo, Bool owned); 214 struct dumb_bo *ms_exa_bo_from_pixmap(ScreenPtr screen, PixmapPtr pixmap); 215 void ms_exa_exchange_buffers(PixmapPtr front, PixmapPtr back); 216 Bool ms_exa_back_pixmap_from_fd(PixmapPtr pixmap, int fd, 217 CARD16 width, CARD16 height, 218 CARD16 stride, CARD8 depth, CARD8 bpp); 219 int ms_exa_shareable_fd_from_pixmap(ScreenPtr screen, PixmapPtr pixmap, 220 CARD16 *stride, CARD32 *size); 221 222 Bool ms_exa_prepare_access(PixmapPtr pPix, int index); 223 void ms_exa_finish_access(PixmapPtr pPix, int index); 224 225 Bool ms_exa_copy_area(PixmapPtr pSrc, PixmapPtr pDst, 226 pixman_f_transform_t *transform, RegionPtr clip); 227 228 XF86VideoAdaptorPtr ms_exa_xv_init(ScreenPtr screen, int num_texture_ports); 229 230 #ifdef DRI3 231 Bool ms_exa_dri3_init(ScreenPtr screen); 232 #endif 233 234 void ms_exchange_buffers(PixmapPtr front, PixmapPtr back); 235 int ms_name_from_pixmap(PixmapPtr pixmap, CARD16 *stride, CARD32 *size); 236