drmmode_display.h revision 8bf5c682
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 {
598bf5c682Smrg  struct drmmode_fb *fb;
60de2362d3Smrg  void *event_data;
618bf5c682Smrg  int flip_count;
62de2362d3Smrg  unsigned int fe_frame;
6318781e08Smrg  uint64_t fe_usec;
6418781e08Smrg  xf86CrtcPtr fe_crtc;
6518781e08Smrg  radeon_drm_handler_proc handler;
6618781e08Smrg  radeon_drm_abort_proc abort;
67de2362d3Smrg} drmmode_flipdata_rec, *drmmode_flipdata_ptr;
68de2362d3Smrg
698bf5c682Smrgstruct drmmode_fb {
708bf5c682Smrg	int refcnt;
718bf5c682Smrg	uint32_t handle;
728bf5c682Smrg};
738bf5c682Smrg
7418781e08Smrgstruct drmmode_scanout {
7518781e08Smrg    struct radeon_bo *bo;
7618781e08Smrg    PixmapPtr pixmap;
7718781e08Smrg    int width, height;
7818781e08Smrg};
79de2362d3Smrg
80de2362d3Smrgtypedef struct {
81de2362d3Smrg    drmmode_ptr drmmode;
82de2362d3Smrg    drmModeCrtcPtr mode_crtc;
83de2362d3Smrg    int hw_id;
84de2362d3Smrg    struct radeon_bo *cursor_bo;
8518781e08Smrg    struct drmmode_scanout rotate;
8618781e08Smrg    struct drmmode_scanout scanout[2];
8718781e08Smrg    DamagePtr scanout_damage;
888bf5c682Smrg    Bool ignore_damage;
8918781e08Smrg    RegionRec scanout_last_region;
9018781e08Smrg    unsigned scanout_id;
9118781e08Smrg    Bool scanout_update_pending;
923ed65abbSmrg    Bool tear_free;
938bf5c682Smrg
948bf5c682Smrg    PixmapPtr prime_scanout_pixmap;
958bf5c682Smrg
96de2362d3Smrg    int dpms_mode;
9718781e08Smrg    CARD64 dpms_last_ust;
9818781e08Smrg    uint32_t dpms_last_seq;
9918781e08Smrg    int dpms_last_fps;
10018781e08Smrg    uint32_t interpolated_vblanks;
10118781e08Smrg
10218781e08Smrg    /* Modeset needed (for DPMS on or after a page flip crossing with a
10318781e08Smrg     * modeset)
10418781e08Smrg     */
10518781e08Smrg    Bool need_modeset;
1068bf5c682Smrg    /* A flip to this FB is pending for this CRTC */
1078bf5c682Smrg    struct drmmode_fb *flip_pending;
1088bf5c682Smrg    /* The FB currently being scanned out by this CRTC, if any */
1098bf5c682Smrg    struct drmmode_fb *fb;
1108bf5c682Smrg
1118bf5c682Smrg#ifdef HAVE_PRESENT_H
1128bf5c682Smrg    /* Deferred processing of Present vblank event */
1138bf5c682Smrg    uint64_t present_vblank_event_id;
1148bf5c682Smrg    uint64_t present_vblank_usec;
1158bf5c682Smrg    unsigned present_vblank_msc;
1168bf5c682Smrg    Bool present_flip_expected;
1178bf5c682Smrg#endif
118de2362d3Smrg} drmmode_crtc_private_rec, *drmmode_crtc_private_ptr;
119de2362d3Smrg
120de2362d3Smrgtypedef struct {
121de2362d3Smrg    drmModePropertyPtr mode_prop;
122de2362d3Smrg    uint64_t value;
123de2362d3Smrg    int num_atoms; /* if range prop, num_atoms == 1; if enum prop, num_atoms == num_enums + 1 */
124de2362d3Smrg    Atom *atoms;
125de2362d3Smrg} drmmode_prop_rec, *drmmode_prop_ptr;
126de2362d3Smrg
127de2362d3Smrg
128de2362d3Smrgtypedef struct {
129de2362d3Smrg    drmmode_ptr drmmode;
130de2362d3Smrg    int output_id;
131de2362d3Smrg    drmModeConnectorPtr mode_output;
132de2362d3Smrg    drmModeEncoderPtr *mode_encoders;
133de2362d3Smrg    drmModePropertyBlobPtr edid_blob;
134de2362d3Smrg    int dpms_enum_id;
135de2362d3Smrg    int num_props;
136de2362d3Smrg    drmmode_prop_ptr props;
137de2362d3Smrg    int enc_mask;
138de2362d3Smrg    int enc_clone_mask;
1393ed65abbSmrg    int tear_free;
140de2362d3Smrg} drmmode_output_private_rec, *drmmode_output_private_ptr;
141de2362d3Smrg
142de2362d3Smrg
14318781e08Smrgenum drmmode_flip_sync {
14418781e08Smrg    FLIP_VSYNC,
14518781e08Smrg    FLIP_ASYNC,
14618781e08Smrg};
14718781e08Smrg
14818781e08Smrg
1498bf5c682Smrg/* Can the page flip ioctl be used for this CRTC? */
1508bf5c682Smrgstatic inline Bool
1518bf5c682Smrgdrmmode_crtc_can_flip(xf86CrtcPtr crtc)
1528bf5c682Smrg{
1538bf5c682Smrg    drmmode_crtc_private_ptr drmmode_crtc = crtc->driver_private;
1548bf5c682Smrg
1558bf5c682Smrg    return crtc->enabled &&
1568bf5c682Smrg	drmmode_crtc->dpms_mode == DPMSModeOn &&
1578bf5c682Smrg	!drmmode_crtc->rotate.bo &&
1588bf5c682Smrg	(drmmode_crtc->tear_free ||
1598bf5c682Smrg	 !drmmode_crtc->scanout[drmmode_crtc->scanout_id].bo);
1608bf5c682Smrg}
1618bf5c682Smrg
1628bf5c682Smrg
1638bf5c682Smrgstatic inline void
1648bf5c682Smrgdrmmode_fb_reference_loc(int drm_fd, struct drmmode_fb **old, struct drmmode_fb *new,
1658bf5c682Smrg			 const char *caller, unsigned line)
1668bf5c682Smrg{
1678bf5c682Smrg    if (new) {
1688bf5c682Smrg	if (new->refcnt <= 0) {
1698bf5c682Smrg	    FatalError("New FB's refcnt was %d at %s:%u",
1708bf5c682Smrg		       new->refcnt, caller, line);
1718bf5c682Smrg	}
1728bf5c682Smrg
1738bf5c682Smrg	new->refcnt++;
1748bf5c682Smrg    }
1758bf5c682Smrg
1768bf5c682Smrg    if (*old) {
1778bf5c682Smrg	if ((*old)->refcnt <= 0) {
1788bf5c682Smrg	    FatalError("Old FB's refcnt was %d at %s:%u",
1798bf5c682Smrg		       (*old)->refcnt, caller, line);
1808bf5c682Smrg	}
1818bf5c682Smrg
1828bf5c682Smrg	if (--(*old)->refcnt == 0) {
1838bf5c682Smrg	    drmModeRmFB(drm_fd, (*old)->handle);
1848bf5c682Smrg	    free(*old);
1858bf5c682Smrg	}
1868bf5c682Smrg    }
1878bf5c682Smrg
1888bf5c682Smrg    *old = new;
1898bf5c682Smrg}
1908bf5c682Smrg
1918bf5c682Smrg#define drmmode_fb_reference(fd, old, new) \
1928bf5c682Smrg    drmmode_fb_reference_loc(fd, old, new, __func__, __LINE__)
1938bf5c682Smrg
1948bf5c682Smrg
1953ed65abbSmrgextern int drmmode_page_flip_target_absolute(RADEONEntPtr pRADEONEnt,
1963ed65abbSmrg					     drmmode_crtc_private_ptr drmmode_crtc,
1973ed65abbSmrg					     int fb_id, uint32_t flags,
1983ed65abbSmrg					     uintptr_t drm_queue_seq,
1993ed65abbSmrg					     uint32_t target_msc);
2003ed65abbSmrgextern int drmmode_page_flip_target_relative(RADEONEntPtr pRADEONEnt,
2013ed65abbSmrg					     drmmode_crtc_private_ptr drmmode_crtc,
2023ed65abbSmrg					     int fb_id, uint32_t flags,
2033ed65abbSmrg					     uintptr_t drm_queue_seq,
2043ed65abbSmrg					     uint32_t target_msc);
205de2362d3Smrgextern Bool drmmode_pre_init(ScrnInfoPtr pScrn, drmmode_ptr drmmode, int cpp);
206de2362d3Smrgextern void drmmode_init(ScrnInfoPtr pScrn, drmmode_ptr drmmode);
20718781e08Smrgextern void drmmode_fini(ScrnInfoPtr pScrn, drmmode_ptr drmmode);
208de2362d3Smrgextern Bool drmmode_set_bufmgr(ScrnInfoPtr pScrn, drmmode_ptr drmmode, struct radeon_bo_manager *bufmgr);
2098bf5c682Smrgextern void drmmode_sprite_set_cursor(DeviceIntPtr pDev, ScreenPtr pScreen,
2108bf5c682Smrg				      CursorPtr pCursor, int x, int y);
2118bf5c682Smrgextern void drmmode_sprite_move_cursor(DeviceIntPtr pDev, ScreenPtr pScreen, int x,
2128bf5c682Smrg				       int y);
213de2362d3Smrgextern void drmmode_set_cursor(ScrnInfoPtr scrn, drmmode_ptr drmmode, int id, struct radeon_bo *bo);
214de2362d3Smrgvoid drmmode_adjust_frame(ScrnInfoPtr pScrn, drmmode_ptr drmmode, int x, int y);
21518781e08Smrgextern Bool drmmode_set_desired_modes(ScrnInfoPtr pScrn, drmmode_ptr drmmode,
21618781e08Smrg				      Bool set_hw);
217de2362d3Smrgextern void drmmode_copy_fb(ScrnInfoPtr pScrn, drmmode_ptr drmmode);
218de2362d3Smrgextern Bool drmmode_setup_colormap(ScreenPtr pScreen, ScrnInfoPtr pScrn);
219de2362d3Smrg
2208bf5c682Smrgextern void drmmode_crtc_scanout_destroy(drmmode_ptr drmmode,
2218bf5c682Smrg					 struct drmmode_scanout *scanout);
2228bf5c682Smrgvoid drmmode_crtc_scanout_free(drmmode_crtc_private_ptr drmmode_crtc);
2238bf5c682SmrgPixmapPtr drmmode_crtc_scanout_create(xf86CrtcPtr crtc,
2248bf5c682Smrg				      struct drmmode_scanout *scanout,
2258bf5c682Smrg				      int width, int height);
22618781e08Smrg
227de2362d3Smrgextern void drmmode_uevent_init(ScrnInfoPtr scrn, drmmode_ptr drmmode);
228de2362d3Smrgextern void drmmode_uevent_fini(ScrnInfoPtr scrn, drmmode_ptr drmmode);
229de2362d3Smrg
2308bf5c682SmrgBool drmmode_set_mode(xf86CrtcPtr crtc, struct drmmode_fb *fb,
2318bf5c682Smrg		      DisplayModePtr mode, int x, int y);
2328bf5c682Smrg
23318781e08Smrgextern int drmmode_get_crtc_id(xf86CrtcPtr crtc);
234de2362d3Smrgextern int drmmode_get_height_align(ScrnInfoPtr scrn, uint32_t tiling);
235de2362d3Smrgextern int drmmode_get_pitch_align(ScrnInfoPtr scrn, int bpe, uint32_t tiling);
236de2362d3Smrgextern int drmmode_get_base_align(ScrnInfoPtr scrn, int bpe, uint32_t tiling);
237de2362d3Smrg
23818781e08SmrgBool radeon_do_pageflip(ScrnInfoPtr scrn, ClientPtr client,
2398bf5c682Smrg			PixmapPtr new_front, uint64_t id, void *data,
2408bf5c682Smrg			xf86CrtcPtr ref_crtc, radeon_drm_handler_proc handler,
24118781e08Smrg			radeon_drm_abort_proc abort,
2423ed65abbSmrg			enum drmmode_flip_sync flip_sync,
2433ed65abbSmrg			uint32_t target_msc);
24418781e08Smrgint drmmode_crtc_get_ust_msc(xf86CrtcPtr crtc, CARD64 *ust, CARD64 *msc);
24518781e08Smrgint drmmode_get_current_ust(int drm_fd, CARD64 *ust);
246de2362d3Smrg
2478bf5c682SmrgBool drmmode_wait_vblank(xf86CrtcPtr crtc, drmVBlankSeqType type,
2488bf5c682Smrg			 uint32_t target_seq, unsigned long signal,
2498bf5c682Smrg			 uint64_t *ust, uint32_t *result_seq);
2508bf5c682Smrg
2518bf5c682Smrg
252de2362d3Smrg#endif
253de2362d3Smrg
254