1de2362d3Smrg/*
2de2362d3Smrg * Copyright © 2007 Red Hat, Inc.
3de2362d3Smrg *
4de2362d3Smrg * Permission is hereby granted, free of charge, to any person obtaining a
5de2362d3Smrg * copy of this software and associated documentation files (the "Software"),
6de2362d3Smrg * to deal in the Software without restriction, including without limitation
7de2362d3Smrg * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8de2362d3Smrg * and/or sell copies of the Software, and to permit persons to whom the
9de2362d3Smrg * Software is furnished to do so, subject to the following conditions:
10de2362d3Smrg *
11de2362d3Smrg * The above copyright notice and this permission notice (including the next
12de2362d3Smrg * paragraph) shall be included in all copies or substantial portions of the
13de2362d3Smrg * Software.
14de2362d3Smrg *
15de2362d3Smrg * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16de2362d3Smrg * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17de2362d3Smrg * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
18de2362d3Smrg * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19de2362d3Smrg * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20de2362d3Smrg * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21de2362d3Smrg * SOFTWARE.
22de2362d3Smrg *
23de2362d3Smrg * Authors:
24de2362d3Smrg *     Dave Airlie <airlied@redhat.com>
25de2362d3Smrg *
26de2362d3Smrg */
27de2362d3Smrg#ifndef DRMMODE_DISPLAY_H
28de2362d3Smrg#define DRMMODE_DISPLAY_H
29de2362d3Smrg
30de2362d3Smrg#include "xf86drmMode.h"
31de2362d3Smrg#ifdef HAVE_LIBUDEV
32de2362d3Smrg#include "libudev.h"
33de2362d3Smrg#endif
34de2362d3Smrg
3518781e08Smrg#include "radeon_drm_queue.h"
36de2362d3Smrg#include "radeon_probe.h"
37de2362d3Smrg
3818781e08Smrg#ifndef DRM_CAP_TIMESTAMP_MONOTONIC
3918781e08Smrg#define DRM_CAP_TIMESTAMP_MONOTONIC 0x6
4018781e08Smrg#endif
4118781e08Smrg
42de2362d3Smrgtypedef struct {
43de2362d3Smrg  struct radeon_bo_manager *bufmgr;
44de2362d3Smrg  ScrnInfoPtr scrn;
45de2362d3Smrg#ifdef HAVE_LIBUDEV
46de2362d3Smrg  struct udev_monitor *uevent_monitor;
47de2362d3Smrg  InputHandlerProc uevent_handler;
48de2362d3Smrg#endif
49de2362d3Smrg  drmEventContext event_context;
5018781e08Smrg  int count_crtcs;
5118781e08Smrg
5218781e08Smrg  Bool delete_dp_12_displays;
5318781e08Smrg
5418781e08Smrg  Bool dri2_flipping;
5518781e08Smrg  Bool present_flipping;
56de2362d3Smrg} drmmode_rec, *drmmode_ptr;
57de2362d3Smrg
58de2362d3Smrgtypedef struct {
59de2362d3Smrg  void *event_data;
608bf5c682Smrg  int flip_count;
61de2362d3Smrg  unsigned int fe_frame;
6218781e08Smrg  uint64_t fe_usec;
6318781e08Smrg  xf86CrtcPtr fe_crtc;
6418781e08Smrg  radeon_drm_handler_proc handler;
6518781e08Smrg  radeon_drm_abort_proc abort;
6639413783Smrg  struct drmmode_fb *fb[0];
67de2362d3Smrg} drmmode_flipdata_rec, *drmmode_flipdata_ptr;
68de2362d3Smrg
698bf5c682Smrgstruct drmmode_fb {
708bf5c682Smrg	int refcnt;
718bf5c682Smrg	uint32_t handle;
728bf5c682Smrg};
738bf5c682Smrg
74446f62d6Smrgenum drmmode_scanout_status {
75446f62d6Smrg    DRMMODE_SCANOUT_OK,
76446f62d6Smrg    DRMMODE_SCANOUT_FLIP_FAILED = 1u << 0,
77446f62d6Smrg    DRMMODE_SCANOUT_VBLANK_FAILED = 1u << 1,
78446f62d6Smrg};
79446f62d6Smrg
8018781e08Smrgstruct drmmode_scanout {
8139413783Smrg    struct radeon_buffer *bo;
8218781e08Smrg    PixmapPtr pixmap;
8318781e08Smrg    int width, height;
8418781e08Smrg};
85de2362d3Smrg
86de2362d3Smrgtypedef struct {
87de2362d3Smrg    drmmode_ptr drmmode;
88de2362d3Smrg    drmModeCrtcPtr mode_crtc;
89de2362d3Smrg    int hw_id;
90446f62d6Smrg
91446f62d6Smrg    CursorPtr cursor;
92446f62d6Smrg    int cursor_x;
93446f62d6Smrg    int cursor_y;
94446f62d6Smrg    int cursor_xhot;
95446f62d6Smrg    int cursor_yhot;
96446f62d6Smrg    unsigned cursor_id;
97446f62d6Smrg    struct radeon_bo *cursor_bo[2];
98446f62d6Smrg
9918781e08Smrg    struct drmmode_scanout rotate;
10018781e08Smrg    struct drmmode_scanout scanout[2];
10118781e08Smrg    DamagePtr scanout_damage;
1028bf5c682Smrg    Bool ignore_damage;
10318781e08Smrg    RegionRec scanout_last_region;
10418781e08Smrg    unsigned scanout_id;
10539413783Smrg    uintptr_t scanout_update_pending;
1063ed65abbSmrg    Bool tear_free;
107446f62d6Smrg    enum drmmode_scanout_status scanout_status;
1088bf5c682Smrg
1098bf5c682Smrg    PixmapPtr prime_scanout_pixmap;
1108bf5c682Smrg
111de2362d3Smrg    int dpms_mode;
11218781e08Smrg    CARD64 dpms_last_ust;
11318781e08Smrg    uint32_t dpms_last_seq;
11418781e08Smrg    int dpms_last_fps;
11518781e08Smrg    uint32_t interpolated_vblanks;
11618781e08Smrg
11718781e08Smrg    /* Modeset needed (for DPMS on or after a page flip crossing with a
11818781e08Smrg     * modeset)
11918781e08Smrg     */
12018781e08Smrg    Bool need_modeset;
12139413783Smrg    /* For keeping track of nested calls to drm_wait_pending_flip /
12239413783Smrg     * drm_queue_handle_deferred
12339413783Smrg     */
12439413783Smrg    int wait_flip_nesting_level;
1258bf5c682Smrg    /* A flip to this FB is pending for this CRTC */
1268bf5c682Smrg    struct drmmode_fb *flip_pending;
1278bf5c682Smrg    /* The FB currently being scanned out by this CRTC, if any */
1288bf5c682Smrg    struct drmmode_fb *fb;
129de2362d3Smrg} drmmode_crtc_private_rec, *drmmode_crtc_private_ptr;
130de2362d3Smrg
131de2362d3Smrgtypedef struct {
132de2362d3Smrg    drmModePropertyPtr mode_prop;
133de2362d3Smrg    uint64_t value;
134de2362d3Smrg    int num_atoms; /* if range prop, num_atoms == 1; if enum prop, num_atoms == num_enums + 1 */
135de2362d3Smrg    Atom *atoms;
136de2362d3Smrg} drmmode_prop_rec, *drmmode_prop_ptr;
137de2362d3Smrg
138de2362d3Smrg
139de2362d3Smrgtypedef struct {
140de2362d3Smrg    drmmode_ptr drmmode;
141de2362d3Smrg    int output_id;
142de2362d3Smrg    drmModeConnectorPtr mode_output;
143de2362d3Smrg    drmModeEncoderPtr *mode_encoders;
144de2362d3Smrg    drmModePropertyBlobPtr edid_blob;
145446f62d6Smrg#if XORG_VERSION_CURRENT >= XORG_VERSION_NUMERIC(1, 17, 99, 901, 0)
146446f62d6Smrg    drmModePropertyBlobPtr tile_blob;
147446f62d6Smrg#endif
148de2362d3Smrg    int dpms_enum_id;
149de2362d3Smrg    int num_props;
150de2362d3Smrg    drmmode_prop_ptr props;
151de2362d3Smrg    int enc_mask;
152de2362d3Smrg    int enc_clone_mask;
1533ed65abbSmrg    int tear_free;
154de2362d3Smrg} drmmode_output_private_rec, *drmmode_output_private_ptr;
155de2362d3Smrg
15639413783Smrgtypedef struct {
15739413783Smrg    uint32_t lessee_id;
15839413783Smrg} drmmode_lease_private_rec, *drmmode_lease_private_ptr;
15939413783Smrg
160de2362d3Smrg
16118781e08Smrgenum drmmode_flip_sync {
16218781e08Smrg    FLIP_VSYNC,
16318781e08Smrg    FLIP_ASYNC,
16418781e08Smrg};
16518781e08Smrg
16618781e08Smrg
1678bf5c682Smrg/* Can the page flip ioctl be used for this CRTC? */
1688bf5c682Smrgstatic inline Bool
1698bf5c682Smrgdrmmode_crtc_can_flip(xf86CrtcPtr crtc)
1708bf5c682Smrg{
1718bf5c682Smrg    drmmode_crtc_private_ptr drmmode_crtc = crtc->driver_private;
1728bf5c682Smrg
1738bf5c682Smrg    return crtc->enabled &&
1748bf5c682Smrg	drmmode_crtc->dpms_mode == DPMSModeOn &&
1758bf5c682Smrg	!drmmode_crtc->rotate.bo &&
1768bf5c682Smrg	(drmmode_crtc->tear_free ||
1778bf5c682Smrg	 !drmmode_crtc->scanout[drmmode_crtc->scanout_id].bo);
1788bf5c682Smrg}
1798bf5c682Smrg
1808bf5c682Smrg
1818bf5c682Smrgstatic inline void
1828bf5c682Smrgdrmmode_fb_reference_loc(int drm_fd, struct drmmode_fb **old, struct drmmode_fb *new,
1838bf5c682Smrg			 const char *caller, unsigned line)
1848bf5c682Smrg{
1858bf5c682Smrg    if (new) {
1868bf5c682Smrg	if (new->refcnt <= 0) {
1878bf5c682Smrg	    FatalError("New FB's refcnt was %d at %s:%u",
1888bf5c682Smrg		       new->refcnt, caller, line);
1898bf5c682Smrg	}
1908bf5c682Smrg
1918bf5c682Smrg	new->refcnt++;
1928bf5c682Smrg    }
1938bf5c682Smrg
1948bf5c682Smrg    if (*old) {
1958bf5c682Smrg	if ((*old)->refcnt <= 0) {
1968bf5c682Smrg	    FatalError("Old FB's refcnt was %d at %s:%u",
1978bf5c682Smrg		       (*old)->refcnt, caller, line);
1988bf5c682Smrg	}
1998bf5c682Smrg
2008bf5c682Smrg	if (--(*old)->refcnt == 0) {
2018bf5c682Smrg	    drmModeRmFB(drm_fd, (*old)->handle);
2028bf5c682Smrg	    free(*old);
2038bf5c682Smrg	}
2048bf5c682Smrg    }
2058bf5c682Smrg
2068bf5c682Smrg    *old = new;
2078bf5c682Smrg}
2088bf5c682Smrg
2098bf5c682Smrg#define drmmode_fb_reference(fd, old, new) \
2108bf5c682Smrg    drmmode_fb_reference_loc(fd, old, new, __func__, __LINE__)
2118bf5c682Smrg
2128bf5c682Smrg
2133ed65abbSmrgextern int drmmode_page_flip_target_absolute(RADEONEntPtr pRADEONEnt,
2143ed65abbSmrg					     drmmode_crtc_private_ptr drmmode_crtc,
2153ed65abbSmrg					     int fb_id, uint32_t flags,
2163ed65abbSmrg					     uintptr_t drm_queue_seq,
2173ed65abbSmrg					     uint32_t target_msc);
2183ed65abbSmrgextern int drmmode_page_flip_target_relative(RADEONEntPtr pRADEONEnt,
2193ed65abbSmrg					     drmmode_crtc_private_ptr drmmode_crtc,
2203ed65abbSmrg					     int fb_id, uint32_t flags,
2213ed65abbSmrg					     uintptr_t drm_queue_seq,
2223ed65abbSmrg					     uint32_t target_msc);
223de2362d3Smrgextern Bool drmmode_pre_init(ScrnInfoPtr pScrn, drmmode_ptr drmmode, int cpp);
224de2362d3Smrgextern void drmmode_init(ScrnInfoPtr pScrn, drmmode_ptr drmmode);
22518781e08Smrgextern void drmmode_fini(ScrnInfoPtr pScrn, drmmode_ptr drmmode);
226de2362d3Smrgextern Bool drmmode_set_bufmgr(ScrnInfoPtr pScrn, drmmode_ptr drmmode, struct radeon_bo_manager *bufmgr);
227de2362d3Smrgvoid drmmode_adjust_frame(ScrnInfoPtr pScrn, drmmode_ptr drmmode, int x, int y);
22818781e08Smrgextern Bool drmmode_set_desired_modes(ScrnInfoPtr pScrn, drmmode_ptr drmmode,
22918781e08Smrg				      Bool set_hw);
230de2362d3Smrgextern void drmmode_copy_fb(ScrnInfoPtr pScrn, drmmode_ptr drmmode);
231de2362d3Smrgextern Bool drmmode_setup_colormap(ScreenPtr pScreen, ScrnInfoPtr pScrn);
232de2362d3Smrg
2338bf5c682Smrgextern void drmmode_crtc_scanout_destroy(drmmode_ptr drmmode,
2348bf5c682Smrg					 struct drmmode_scanout *scanout);
235446f62d6Smrgvoid drmmode_crtc_scanout_free(xf86CrtcPtr crtc);
2368bf5c682SmrgPixmapPtr drmmode_crtc_scanout_create(xf86CrtcPtr crtc,
2378bf5c682Smrg				      struct drmmode_scanout *scanout,
2388bf5c682Smrg				      int width, int height);
23918781e08Smrg
240de2362d3Smrgextern void drmmode_uevent_init(ScrnInfoPtr scrn, drmmode_ptr drmmode);
241de2362d3Smrgextern void drmmode_uevent_fini(ScrnInfoPtr scrn, drmmode_ptr drmmode);
242de2362d3Smrg
2438bf5c682SmrgBool drmmode_set_mode(xf86CrtcPtr crtc, struct drmmode_fb *fb,
2448bf5c682Smrg		      DisplayModePtr mode, int x, int y);
2458bf5c682Smrg
24618781e08Smrgextern int drmmode_get_crtc_id(xf86CrtcPtr crtc);
247de2362d3Smrgextern int drmmode_get_height_align(ScrnInfoPtr scrn, uint32_t tiling);
248de2362d3Smrgextern int drmmode_get_pitch_align(ScrnInfoPtr scrn, int bpe, uint32_t tiling);
249de2362d3Smrgextern int drmmode_get_base_align(ScrnInfoPtr scrn, int bpe, uint32_t tiling);
250de2362d3Smrg
25118781e08SmrgBool radeon_do_pageflip(ScrnInfoPtr scrn, ClientPtr client,
2528bf5c682Smrg			PixmapPtr new_front, uint64_t id, void *data,
2538bf5c682Smrg			xf86CrtcPtr ref_crtc, radeon_drm_handler_proc handler,
25418781e08Smrg			radeon_drm_abort_proc abort,
2553ed65abbSmrg			enum drmmode_flip_sync flip_sync,
2563ed65abbSmrg			uint32_t target_msc);
25718781e08Smrgint drmmode_crtc_get_ust_msc(xf86CrtcPtr crtc, CARD64 *ust, CARD64 *msc);
25818781e08Smrgint drmmode_get_current_ust(int drm_fd, CARD64 *ust);
259de2362d3Smrg
2608bf5c682SmrgBool drmmode_wait_vblank(xf86CrtcPtr crtc, drmVBlankSeqType type,
2618bf5c682Smrg			 uint32_t target_seq, unsigned long signal,
2628bf5c682Smrg			 uint64_t *ust, uint32_t *result_seq);
2638bf5c682Smrg
2648bf5c682Smrg
265ad01e365Sjoergextern miPointerSpriteFuncRec drmmode_sprite_funcs;
26639413783Smrg
26739413783Smrg
268de2362d3Smrg#endif
269de2362d3Smrg
270