drmmode_display.h revision 24b90cf4
1/*
2 * Copyright © 2007 Red Hat, Inc.
3 *
4 * Permission is hereby granted, free of charge, to any person obtaining a
5 * copy of this software and associated documentation files (the "Software"),
6 * to deal in the Software without restriction, including without limitation
7 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8 * and/or sell copies of the Software, and to permit persons to whom the
9 * Software is furnished to do so, subject to the following conditions:
10 *
11 * The above copyright notice and this permission notice (including the next
12 * paragraph) shall be included in all copies or substantial portions of the
13 * Software.
14 *
15 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
18 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 * SOFTWARE.
22 *
23 * Authors:
24 *     Dave Airlie <airlied@redhat.com>
25 *
26 */
27#ifndef DRMMODE_DISPLAY_H
28#define DRMMODE_DISPLAY_H
29
30#include "xf86drmMode.h"
31#ifdef HAVE_LIBUDEV
32#include "libudev.h"
33#endif
34
35#include "amdgpu_drm_queue.h"
36#include "amdgpu_probe.h"
37#include "amdgpu.h"
38
39typedef struct {
40	ScrnInfoPtr scrn;
41#ifdef HAVE_LIBUDEV
42	struct udev_monitor *uevent_monitor;
43	InputHandlerProc uevent_handler;
44#endif
45	drmEventContext event_context;
46	int count_crtcs;
47
48	Bool delete_dp_12_displays;
49
50	Bool dri2_flipping;
51	Bool present_flipping;
52} drmmode_rec, *drmmode_ptr;
53
54typedef struct {
55	struct drmmode_fb *fb;
56	void *event_data;
57	int flip_count;
58	unsigned int fe_frame;
59	uint64_t fe_usec;
60	xf86CrtcPtr fe_crtc;
61	amdgpu_drm_handler_proc handler;
62	amdgpu_drm_abort_proc abort;
63} drmmode_flipdata_rec, *drmmode_flipdata_ptr;
64
65struct drmmode_fb {
66	int refcnt;
67	uint32_t handle;
68};
69
70struct drmmode_scanout {
71	struct amdgpu_buffer *bo;
72	PixmapPtr pixmap;
73	int width, height;
74};
75
76typedef struct {
77	drmmode_ptr drmmode;
78	drmModeCrtcPtr mode_crtc;
79	int hw_id;
80	struct amdgpu_buffer *cursor_buffer;
81	struct drmmode_scanout rotate;
82	struct drmmode_scanout scanout[2];
83	DamagePtr scanout_damage;
84	Bool ignore_damage;
85	RegionRec scanout_last_region;
86	unsigned scanout_id;
87	Bool scanout_update_pending;
88	Bool tear_free;
89
90	PixmapPtr prime_scanout_pixmap;
91
92	int dpms_mode;
93	CARD64 dpms_last_ust;
94	uint32_t dpms_last_seq;
95	int dpms_last_fps;
96	uint32_t interpolated_vblanks;
97
98	/* Modeset needed for DPMS on */
99	Bool need_modeset;
100	/* A flip to this FB is pending for this CRTC */
101	struct drmmode_fb *flip_pending;
102	/* The FB currently being scanned out by this CRTC, if any */
103	struct drmmode_fb *fb;
104
105#ifdef HAVE_PRESENT_H
106	/* Deferred processing of Present vblank event */
107	uint64_t present_vblank_event_id;
108	uint64_t present_vblank_usec;
109	unsigned present_vblank_msc;
110	Bool present_flip_expected;
111#endif
112} drmmode_crtc_private_rec, *drmmode_crtc_private_ptr;
113
114typedef struct {
115	drmModePropertyPtr mode_prop;
116	uint64_t value;
117	int num_atoms;		/* if range prop, num_atoms == 1; if enum prop, num_atoms == num_enums + 1 */
118	Atom *atoms;
119} drmmode_prop_rec, *drmmode_prop_ptr;
120
121typedef struct {
122	drmmode_ptr drmmode;
123	int output_id;
124	drmModeConnectorPtr mode_output;
125	drmModeEncoderPtr *mode_encoders;
126	drmModePropertyBlobPtr edid_blob;
127	int dpms_enum_id;
128	int num_props;
129	drmmode_prop_ptr props;
130	int enc_mask;
131	int enc_clone_mask;
132	int tear_free;
133} drmmode_output_private_rec, *drmmode_output_private_ptr;
134
135
136enum drmmode_flip_sync {
137    FLIP_VSYNC,
138    FLIP_ASYNC,
139};
140
141
142/* Can the page flip ioctl be used for this CRTC? */
143static inline Bool
144drmmode_crtc_can_flip(xf86CrtcPtr crtc)
145{
146	drmmode_crtc_private_ptr drmmode_crtc = crtc->driver_private;
147
148	return crtc->enabled &&
149		drmmode_crtc->dpms_mode == DPMSModeOn &&
150		!drmmode_crtc->rotate.bo &&
151		(drmmode_crtc->tear_free ||
152		 !drmmode_crtc->scanout[drmmode_crtc->scanout_id].bo);
153}
154
155
156static inline void
157drmmode_fb_reference_loc(int drm_fd, struct drmmode_fb **old, struct drmmode_fb *new,
158			 const char *caller, unsigned line)
159{
160	if (new) {
161		if (new->refcnt <= 0) {
162			FatalError("New FB's refcnt was %d at %s:%u",
163				   new->refcnt, caller, line);
164		}
165
166		new->refcnt++;
167	}
168
169	if (*old) {
170		if ((*old)->refcnt <= 0) {
171			FatalError("Old FB's refcnt was %d at %s:%u",
172				   (*old)->refcnt, caller, line);
173		}
174
175		if (--(*old)->refcnt == 0) {
176			drmModeRmFB(drm_fd, (*old)->handle);
177			free(*old);
178		}
179	}
180
181	*old = new;
182}
183
184#define drmmode_fb_reference(fd, old, new) \
185	drmmode_fb_reference_loc(fd, old, new, __func__, __LINE__)
186
187
188extern int drmmode_page_flip_target_absolute(AMDGPUEntPtr pAMDGPUEnt,
189					     drmmode_crtc_private_ptr drmmode_crtc,
190					     int fb_id, uint32_t flags,
191					     uintptr_t drm_queue_seq,
192					     uint32_t target_msc);
193extern int drmmode_page_flip_target_relative(AMDGPUEntPtr pAMDGPUEnt,
194					     drmmode_crtc_private_ptr drmmode_crtc,
195					     int fb_id, uint32_t flags,
196					     uintptr_t drm_queue_seq,
197					     uint32_t target_msc);
198extern Bool drmmode_pre_init(ScrnInfoPtr pScrn, drmmode_ptr drmmode, int cpp);
199extern void drmmode_init(ScrnInfoPtr pScrn, drmmode_ptr drmmode);
200extern void drmmode_fini(ScrnInfoPtr pScrn, drmmode_ptr drmmode);
201extern void drmmode_sprite_set_cursor(DeviceIntPtr pDev, ScreenPtr pScreen,
202				      CursorPtr pCursor, int x, int y);
203extern void drmmode_sprite_move_cursor(DeviceIntPtr pDev, ScreenPtr pScreen, int x,
204				       int y);
205extern void drmmode_set_cursor(ScrnInfoPtr scrn, drmmode_ptr drmmode, int id,
206			       struct amdgpu_buffer *bo);
207void drmmode_adjust_frame(ScrnInfoPtr pScrn, drmmode_ptr drmmode, int x, int y);
208extern Bool drmmode_set_desired_modes(ScrnInfoPtr pScrn, drmmode_ptr drmmode,
209				      Bool set_hw);
210extern void drmmode_copy_fb(ScrnInfoPtr pScrn, drmmode_ptr drmmode);
211extern Bool drmmode_setup_colormap(ScreenPtr pScreen, ScrnInfoPtr pScrn);
212
213extern void drmmode_crtc_scanout_destroy(drmmode_ptr drmmode,
214					 struct drmmode_scanout *scanout);
215void drmmode_crtc_scanout_free(drmmode_crtc_private_ptr drmmode_crtc);
216PixmapPtr drmmode_crtc_scanout_create(xf86CrtcPtr crtc,
217				      struct drmmode_scanout *scanout,
218				      int width, int height);
219
220extern void drmmode_uevent_init(ScrnInfoPtr scrn, drmmode_ptr drmmode);
221extern void drmmode_uevent_fini(ScrnInfoPtr scrn, drmmode_ptr drmmode);
222
223Bool drmmode_set_mode(xf86CrtcPtr crtc, struct drmmode_fb *fb,
224		      DisplayModePtr mode, int x, int y);
225
226extern int drmmode_get_crtc_id(xf86CrtcPtr crtc);
227extern int drmmode_get_pitch_align(ScrnInfoPtr scrn, int bpe);
228Bool amdgpu_do_pageflip(ScrnInfoPtr scrn, ClientPtr client,
229			PixmapPtr new_front, uint64_t id, void *data,
230			xf86CrtcPtr ref_crtc, amdgpu_drm_handler_proc handler,
231			amdgpu_drm_abort_proc abort,
232			enum drmmode_flip_sync flip_sync,
233			uint32_t target_msc);
234int drmmode_crtc_get_ust_msc(xf86CrtcPtr crtc, CARD64 *ust, CARD64 *msc);
235int drmmode_get_current_ust(int drm_fd, CARD64 * ust);
236
237Bool drmmode_wait_vblank(xf86CrtcPtr crtc, drmVBlankSeqType type,
238			 uint32_t target_seq, unsigned long signal,
239			 uint64_t *ust, uint32_t *result_seq);
240
241
242#endif
243