Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit d83ef853 authored by Ben Skeggs's avatar Ben Skeggs
Browse files

drm/nouveau: implement hooks for needed for drm vblank timestamping support



Signed-off-by: default avatarBen Skeggs <bskeggs@redhat.com>
parent d2fa7d32
Loading
Loading
Loading
Loading
+80 −0
Original line number Original line Diff line number Diff line
@@ -68,6 +68,86 @@ nouveau_display_vblank_disable(struct drm_device *dev, int head)
		nouveau_event_put(disp->vblank[head]);
		nouveau_event_put(disp->vblank[head]);
}
}


static inline int
calc(int blanks, int blanke, int total, int line)
{
	if (blanke >= blanks) {
		if (line >= blanks)
			line -= total;
	} else {
		if (line >= blanks)
			line -= total;
		line -= blanke + 1;
	}
	return line;
}

int
nouveau_display_scanoutpos_head(struct drm_crtc *crtc, int *vpos, int *hpos,
				ktime_t *stime, ktime_t *etime)
{
	const u32 mthd = NV04_DISP_SCANOUTPOS + nouveau_crtc(crtc)->index;
	struct nouveau_display *disp = nouveau_display(crtc->dev);
	struct nv04_display_scanoutpos args;
	int ret, retry = 1;

	do {
		ret = nv_exec(disp->core, mthd, &args, sizeof(args));
		if (ret != 0)
			return 0;

		if (args.vline) {
			ret |= DRM_SCANOUTPOS_ACCURATE;
			ret |= DRM_SCANOUTPOS_VALID;
			break;
		}

		if (retry) ndelay(crtc->linedur_ns);
	} while (retry--);

	*hpos = calc(args.hblanks, args.hblanke, args.htotal, args.hline);
	*vpos = calc(args.vblanks, args.vblanke, args.vtotal, args.vline);
	if (stime) *stime = ns_to_ktime(args.time[0]);
	if (etime) *etime = ns_to_ktime(args.time[1]);

	if (*vpos < 0)
		ret |= DRM_SCANOUTPOS_INVBL;
	return ret;
}

int
nouveau_display_scanoutpos(struct drm_device *dev, int head, unsigned int flags,
			   int *vpos, int *hpos, ktime_t *stime, ktime_t *etime)
{
	struct drm_crtc *crtc;

	list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) {
		if (nouveau_crtc(crtc)->index == head) {
			return nouveau_display_scanoutpos_head(crtc, vpos, hpos,
							       stime, etime);
		}
	}

	return 0;
}

int
nouveau_display_vblstamp(struct drm_device *dev, int head, int *max_error,
			 struct timeval *time, unsigned flags)
{
	struct drm_crtc *crtc;

	list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) {
		if (nouveau_crtc(crtc)->index == head) {
			return drm_calc_vbltimestamp_from_scanoutpos(dev,
					head, max_error, time, flags, crtc,
					&crtc->hwmode);
		}
	}

	return -EINVAL;
}

static void
static void
nouveau_display_vblank_fini(struct drm_device *dev)
nouveau_display_vblank_fini(struct drm_device *dev)
{
{
+4 −0
Original line number Original line Diff line number Diff line
@@ -64,6 +64,10 @@ void nouveau_display_repin(struct drm_device *dev);
void nouveau_display_resume(struct drm_device *dev);
void nouveau_display_resume(struct drm_device *dev);
int  nouveau_display_vblank_enable(struct drm_device *, int);
int  nouveau_display_vblank_enable(struct drm_device *, int);
void nouveau_display_vblank_disable(struct drm_device *, int);
void nouveau_display_vblank_disable(struct drm_device *, int);
int  nouveau_display_scanoutpos(struct drm_device *, int, unsigned int,
				int *, int *, ktime_t *, ktime_t *);
int  nouveau_display_vblstamp(struct drm_device *, int, int *,
			      struct timeval *, unsigned);


int  nouveau_crtc_page_flip(struct drm_crtc *crtc, struct drm_framebuffer *fb,
int  nouveau_crtc_page_flip(struct drm_crtc *crtc, struct drm_framebuffer *fb,
			    struct drm_pending_vblank_event *event,
			    struct drm_pending_vblank_event *event,
+2 −0
Original line number Original line Diff line number Diff line
@@ -798,6 +798,8 @@ driver = {
	.get_vblank_counter = drm_vblank_count,
	.get_vblank_counter = drm_vblank_count,
	.enable_vblank = nouveau_display_vblank_enable,
	.enable_vblank = nouveau_display_vblank_enable,
	.disable_vblank = nouveau_display_vblank_disable,
	.disable_vblank = nouveau_display_vblank_disable,
	.get_scanout_position = nouveau_display_scanoutpos,
	.get_vblank_timestamp = nouveau_display_vblstamp,


	.ioctls = nouveau_ioctls,
	.ioctls = nouveau_ioctls,
	.num_ioctls = ARRAY_SIZE(nouveau_ioctls),
	.num_ioctls = ARRAY_SIZE(nouveau_ioctls),