135c4bbdfSmrg/*
235c4bbdfSmrg * Copyright 2008 Tungsten Graphics, Inc., Cedar Park, Texas.
35a112b11Smrg * Copyright 2019 NVIDIA CORPORATION
435c4bbdfSmrg * All Rights Reserved.
535c4bbdfSmrg *
635c4bbdfSmrg * Permission is hereby granted, free of charge, to any person obtaining a
735c4bbdfSmrg * copy of this software and associated documentation files (the
835c4bbdfSmrg * "Software"), to deal in the Software without restriction, including
935c4bbdfSmrg * without limitation the rights to use, copy, modify, merge, publish,
1035c4bbdfSmrg * distribute, sub license, and/or sell copies of the Software, and to
1135c4bbdfSmrg * permit persons to whom the Software is furnished to do so, subject to
1235c4bbdfSmrg * the following conditions:
1335c4bbdfSmrg *
1435c4bbdfSmrg * The above copyright notice and this permission notice (including the
1535c4bbdfSmrg * next paragraph) shall be included in all copies or substantial portions
1635c4bbdfSmrg * of the Software.
1735c4bbdfSmrg *
1835c4bbdfSmrg * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
1935c4bbdfSmrg * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
2035c4bbdfSmrg * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
2135c4bbdfSmrg * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR
2235c4bbdfSmrg * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
2335c4bbdfSmrg * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
2435c4bbdfSmrg * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
2535c4bbdfSmrg *
2635c4bbdfSmrg *
2735c4bbdfSmrg * Author: Alan Hourihane <alanh@tungstengraphics.com>
285a112b11Smrg * Additional contributors:
295a112b11Smrg *   Aaron Plattner <aplattner@nvidia.com>
3035c4bbdfSmrg */
3135c4bbdfSmrg
3235c4bbdfSmrg#include <errno.h>
3335c4bbdfSmrg#include <drm.h>
3435c4bbdfSmrg#include <xf86drm.h>
3535c4bbdfSmrg#include <xf86Crtc.h>
3635c4bbdfSmrg#include <damage.h>
377e31ba66Smrg#include <X11/extensions/dpmsconst.h>
385a112b11Smrg#include <shadow.h>
397e31ba66Smrg#ifdef GLAMOR_HAS_GBM
4035c4bbdfSmrg#define GLAMOR_FOR_XORG 1
4135c4bbdfSmrg#include "glamor.h"
4235c4bbdfSmrg#include <gbm.h>
4335c4bbdfSmrg#endif
4435c4bbdfSmrg
4535c4bbdfSmrg#include "drmmode_display.h"
4635c4bbdfSmrg#define MS_LOGLEVEL_DEBUG 4
4735c4bbdfSmrg
485a112b11Smrgstruct ms_vrr_priv {
495a112b11Smrg    Bool variable_refresh;
505a112b11Smrg};
515a112b11Smrg
5235c4bbdfSmrgtypedef enum {
5335c4bbdfSmrg    OPTION_SW_CURSOR,
5435c4bbdfSmrg    OPTION_DEVICE_PATH,
5535c4bbdfSmrg    OPTION_SHADOW_FB,
5635c4bbdfSmrg    OPTION_ACCEL_METHOD,
5735c4bbdfSmrg    OPTION_PAGEFLIP,
5835c4bbdfSmrg    OPTION_ZAPHOD_HEADS,
597e31ba66Smrg    OPTION_DOUBLE_SHADOW,
60806e81e9Smrg    OPTION_ATOMIC,
615a112b11Smrg    OPTION_VARIABLE_REFRESH,
625a112b11Smrg    OPTION_USE_GAMMA_LUT,
635a112b11Smrg    OPTION_ASYNC_FLIP_SECONDARIES,
6435c4bbdfSmrg} modesettingOpts;
6535c4bbdfSmrg
6635c4bbdfSmrgtypedef struct
6735c4bbdfSmrg{
6835c4bbdfSmrg    int fd;
6935c4bbdfSmrg    int fd_ref;
7035c4bbdfSmrg    unsigned long fd_wakeup_registered; /* server generation for which fd has been registered for wakeup handling */
7135c4bbdfSmrg    int fd_wakeup_ref;
7235c4bbdfSmrg    unsigned int assigned_crtcs;
7335c4bbdfSmrg} modesettingEntRec, *modesettingEntPtr;
7435c4bbdfSmrg
7535c4bbdfSmrgtypedef void (*ms_drm_handler_proc)(uint64_t frame,
7635c4bbdfSmrg                                    uint64_t usec,
7735c4bbdfSmrg                                    void *data);
7835c4bbdfSmrg
7935c4bbdfSmrgtypedef void (*ms_drm_abort_proc)(void *data);
8035c4bbdfSmrg
8135c4bbdfSmrg/**
8235c4bbdfSmrg * A tracked handler for an event that will hopefully be generated by
8335c4bbdfSmrg * the kernel, and what to do when it is encountered.
8435c4bbdfSmrg */
8535c4bbdfSmrgstruct ms_drm_queue {
8635c4bbdfSmrg    struct xorg_list list;
8735c4bbdfSmrg    xf86CrtcPtr crtc;
8835c4bbdfSmrg    uint32_t seq;
8935c4bbdfSmrg    void *data;
9035c4bbdfSmrg    ScrnInfoPtr scrn;
9135c4bbdfSmrg    ms_drm_handler_proc handler;
9235c4bbdfSmrg    ms_drm_abort_proc abort;
9335c4bbdfSmrg};
9435c4bbdfSmrg
9535c4bbdfSmrgtypedef struct _modesettingRec {
9635c4bbdfSmrg    int fd;
977e31ba66Smrg    Bool fd_passed;
9835c4bbdfSmrg
9935c4bbdfSmrg    int Chipset;
10035c4bbdfSmrg    EntityInfoPtr pEnt;
10135c4bbdfSmrg
10235c4bbdfSmrg    Bool noAccel;
10335c4bbdfSmrg    CloseScreenProcPtr CloseScreen;
1047e31ba66Smrg    CreateWindowProcPtr CreateWindow;
10535c4bbdfSmrg    unsigned int SaveGeneration;
10635c4bbdfSmrg
10735c4bbdfSmrg    CreateScreenResourcesProcPtr createScreenResources;
10835c4bbdfSmrg    ScreenBlockHandlerProcPtr BlockHandler;
109806e81e9Smrg    miPointerSpriteFuncPtr SpriteFuncs;
11035c4bbdfSmrg    void *driver;
11135c4bbdfSmrg
11235c4bbdfSmrg    drmmode_rec drmmode;
11335c4bbdfSmrg
11435c4bbdfSmrg    drmEventContext event_context;
11535c4bbdfSmrg
11635c4bbdfSmrg    /**
11735c4bbdfSmrg     * Page flipping stuff.
11835c4bbdfSmrg     *  @{
11935c4bbdfSmrg     */
1205a112b11Smrg    Bool atomic_modeset_capable;
1217e31ba66Smrg    Bool atomic_modeset;
1227e31ba66Smrg    Bool pending_modeset;
12335c4bbdfSmrg    /** @} */
12435c4bbdfSmrg
12535c4bbdfSmrg    DamagePtr damage;
12635c4bbdfSmrg    Bool dirty_enabled;
12735c4bbdfSmrg
12835c4bbdfSmrg    uint32_t cursor_width, cursor_height;
1297e31ba66Smrg
1307e31ba66Smrg    Bool has_queue_sequence;
1317e31ba66Smrg    Bool tried_queue_sequence;
1327e31ba66Smrg
1337e31ba66Smrg    Bool kms_has_modifiers;
1347e31ba66Smrg
1355a112b11Smrg    /* VRR support */
1365a112b11Smrg    Bool vrr_support;
1375a112b11Smrg    WindowPtr flip_window;
1385a112b11Smrg
1395a112b11Smrg    Bool is_connector_vrr_capable;
1405a112b11Smrg    uint32_t connector_prop_id;
1415a112b11Smrg
1425a112b11Smrg    /* shadow API */
1435a112b11Smrg    struct {
1445a112b11Smrg        Bool (*Setup)(ScreenPtr);
1455a112b11Smrg        Bool (*Add)(ScreenPtr, PixmapPtr, ShadowUpdateProc, ShadowWindowProc,
1465a112b11Smrg                    int, void *);
1475a112b11Smrg        void (*Remove)(ScreenPtr, PixmapPtr);
1485a112b11Smrg        void (*Update32to24)(ScreenPtr, shadowBufPtr);
1495a112b11Smrg        void (*UpdatePacked)(ScreenPtr, shadowBufPtr);
1505a112b11Smrg    } shadow;
1515a112b11Smrg
1525a112b11Smrg#ifdef GLAMOR_HAS_GBM
1535a112b11Smrg    /* glamor API */
1545a112b11Smrg    struct {
1555a112b11Smrg        Bool (*back_pixmap_from_fd)(PixmapPtr, int, CARD16, CARD16, CARD16,
1565a112b11Smrg                                    CARD8, CARD8);
1575a112b11Smrg        void (*block_handler)(ScreenPtr);
1585a112b11Smrg        void (*clear_pixmap)(PixmapPtr);
1595a112b11Smrg        Bool (*egl_create_textured_pixmap)(PixmapPtr, int, int);
1605a112b11Smrg        Bool (*egl_create_textured_pixmap_from_gbm_bo)(PixmapPtr,
1615a112b11Smrg                                                       struct gbm_bo *,
1625a112b11Smrg                                                       Bool);
1635a112b11Smrg        void (*egl_exchange_buffers)(PixmapPtr, PixmapPtr);
1645a112b11Smrg        struct gbm_device *(*egl_get_gbm_device)(ScreenPtr);
1655a112b11Smrg        Bool (*egl_init)(ScrnInfoPtr, int);
1665a112b11Smrg        void (*finish)(ScreenPtr);
1675a112b11Smrg        struct gbm_bo *(*gbm_bo_from_pixmap)(ScreenPtr, PixmapPtr);
1685a112b11Smrg        Bool (*init)(ScreenPtr, unsigned int);
1695a112b11Smrg        int (*name_from_pixmap)(PixmapPtr, CARD16 *, CARD32 *);
1705a112b11Smrg        void (*set_drawable_modifiers_func)(ScreenPtr,
1715a112b11Smrg                                            GetDrawableModifiersFuncPtr);
1725a112b11Smrg        int (*shareable_fd_from_pixmap)(ScreenPtr, PixmapPtr, CARD16 *,
1735a112b11Smrg                                        CARD32 *);
1745a112b11Smrg        Bool (*supports_pixmap_import_export)(ScreenPtr);
1755a112b11Smrg        XF86VideoAdaptorPtr (*xv_init)(ScreenPtr, int);
1765a112b11Smrg        const char *(*egl_get_driver_name)(ScreenPtr);
1775a112b11Smrg    } glamor;
1785a112b11Smrg#endif
17935c4bbdfSmrg} modesettingRec, *modesettingPtr;
18035c4bbdfSmrg
1815a112b11Smrg#define glamor_finish(screen) ms->glamor.finish(screen)
1825a112b11Smrg
18335c4bbdfSmrg#define modesettingPTR(p) ((modesettingPtr)((p)->driverPrivate))
18435c4bbdfSmrgmodesettingEntPtr ms_ent_priv(ScrnInfoPtr scrn);
18535c4bbdfSmrg
18635c4bbdfSmrguint32_t ms_drm_queue_alloc(xf86CrtcPtr crtc,
18735c4bbdfSmrg                            void *data,
18835c4bbdfSmrg                            ms_drm_handler_proc handler,
18935c4bbdfSmrg                            ms_drm_abort_proc abort);
19035c4bbdfSmrg
1917e31ba66Smrgtypedef enum ms_queue_flag {
1927e31ba66Smrg    MS_QUEUE_ABSOLUTE = 0,
1937e31ba66Smrg    MS_QUEUE_RELATIVE = 1,
1947e31ba66Smrg    MS_QUEUE_NEXT_ON_MISS = 2
1957e31ba66Smrg} ms_queue_flag;
1967e31ba66Smrg
1977e31ba66SmrgBool ms_queue_vblank(xf86CrtcPtr crtc, ms_queue_flag flags,
1987e31ba66Smrg                     uint64_t msc, uint64_t *msc_queued, uint32_t seq);
1997e31ba66Smrg
20035c4bbdfSmrgvoid ms_drm_abort(ScrnInfoPtr scrn,
20135c4bbdfSmrg                  Bool (*match)(void *data, void *match_data),
20235c4bbdfSmrg                  void *match_data);
20335c4bbdfSmrgvoid ms_drm_abort_seq(ScrnInfoPtr scrn, uint32_t seq);
20435c4bbdfSmrg
205d44ca368SmrgBool xf86_crtc_on(xf86CrtcPtr crtc);
20635c4bbdfSmrg
20735c4bbdfSmrgxf86CrtcPtr ms_dri2_crtc_covering_drawable(DrawablePtr pDraw);
2084e185dc0SmrgRRCrtcPtr   ms_randr_crtc_covering_drawable(DrawablePtr pDraw);
20935c4bbdfSmrg
2102c83f951Sryoint ms_get_crtc_ust_msc(xf86CrtcPtr crtc, uint64_t *ust, uint64_t *msc);
21135c4bbdfSmrg
2127e31ba66Smrguint64_t ms_kernel_msc_to_crtc_msc(xf86CrtcPtr crtc, uint64_t sequence, Bool is64bit);
21335c4bbdfSmrg
21435c4bbdfSmrg
21535c4bbdfSmrgBool ms_dri2_screen_init(ScreenPtr screen);
21635c4bbdfSmrgvoid ms_dri2_close_screen(ScreenPtr screen);
21735c4bbdfSmrg
21835c4bbdfSmrgBool ms_vblank_screen_init(ScreenPtr screen);
21935c4bbdfSmrgvoid ms_vblank_close_screen(ScreenPtr screen);
22035c4bbdfSmrg
22135c4bbdfSmrgBool ms_present_screen_init(ScreenPtr screen);
2227e31ba66Smrg
2237e31ba66Smrg#ifdef GLAMOR_HAS_GBM
2247e31ba66Smrg
2257e31ba66Smrgtypedef void (*ms_pageflip_handler_proc)(modesettingPtr ms,
2267e31ba66Smrg                                         uint64_t frame,
2277e31ba66Smrg                                         uint64_t usec,
2287e31ba66Smrg                                         void *data);
2297e31ba66Smrg
2307e31ba66Smrgtypedef void (*ms_pageflip_abort_proc)(modesettingPtr ms, void *data);
2317e31ba66Smrg
2327e31ba66SmrgBool ms_do_pageflip(ScreenPtr screen,
2337e31ba66Smrg                    PixmapPtr new_front,
2347e31ba66Smrg                    void *event,
2357e31ba66Smrg                    int ref_crtc_vblank_pipe,
2367e31ba66Smrg                    Bool async,
2377e31ba66Smrg                    ms_pageflip_handler_proc pageflip_handler,
2385a112b11Smrg                    ms_pageflip_abort_proc pageflip_abort,
2395a112b11Smrg                    const char *log_prefix);
2407e31ba66Smrg
2417e31ba66Smrg#endif
2427e31ba66Smrg
2437e31ba66Smrgint ms_flush_drm_events(ScreenPtr screen);
2445a112b11SmrgBool ms_window_has_variable_refresh(modesettingPtr ms, WindowPtr win);
2455a112b11Smrgvoid ms_present_set_screen_vrr(ScrnInfoPtr scrn, Bool vrr_enabled);
246