Commit d47abc58 authored by Mario Kleiner's avatar Mario Kleiner Committed by Dave Airlie

drm/radeon: Push get_scanout_position() timestamping into kms driver.

Move the ktime_get() clock readouts and potential preempt_disable()
calls from drm core into kms driver to make it compatible with the
api changes in the drm core.

This should not introduce any change in functionality or behaviour
in radeon-kms, just a reshuffling of code.
Signed-off-by: default avatarMario Kleiner <mario.kleiner.de@gmail.com>
Reviewed-by: default avatarVille Syrjälä <ville.syrjala@linux.intel.com>
Reviewed-by: default avatarAlex Deucher <alexander.deucher@amd.com>
Signed-off-by: default avatarDave Airlie <airlied@redhat.com>
parent 8f6fce03
...@@ -307,7 +307,7 @@ void radeon_crtc_handle_flip(struct radeon_device *rdev, int crtc_id) ...@@ -307,7 +307,7 @@ void radeon_crtc_handle_flip(struct radeon_device *rdev, int crtc_id)
*/ */
if (update_pending && if (update_pending &&
(DRM_SCANOUTPOS_VALID & radeon_get_crtc_scanoutpos(rdev->ddev, crtc_id, (DRM_SCANOUTPOS_VALID & radeon_get_crtc_scanoutpos(rdev->ddev, crtc_id,
&vpos, &hpos)) && &vpos, &hpos, NULL, NULL)) &&
((vpos >= (99 * rdev->mode_info.crtcs[crtc_id]->base.hwmode.crtc_vdisplay)/100) || ((vpos >= (99 * rdev->mode_info.crtcs[crtc_id]->base.hwmode.crtc_vdisplay)/100) ||
(vpos < 0 && !ASIC_IS_AVIVO(rdev)))) { (vpos < 0 && !ASIC_IS_AVIVO(rdev)))) {
/* crtc didn't flip in this target vblank interval, /* crtc didn't flip in this target vblank interval,
...@@ -1596,12 +1596,17 @@ bool radeon_crtc_scaling_mode_fixup(struct drm_crtc *crtc, ...@@ -1596,12 +1596,17 @@ bool radeon_crtc_scaling_mode_fixup(struct drm_crtc *crtc,
} }
/* /*
* Retrieve current video scanout position of crtc on a given gpu. * Retrieve current video scanout position of crtc on a given gpu, and
* an optional accurate timestamp of when query happened.
* *
* \param dev Device to query. * \param dev Device to query.
* \param crtc Crtc to query. * \param crtc Crtc to query.
* \param *vpos Location where vertical scanout position should be stored. * \param *vpos Location where vertical scanout position should be stored.
* \param *hpos Location where horizontal scanout position should go. * \param *hpos Location where horizontal scanout position should go.
* \param *stime Target location for timestamp taken immediately before
* scanout position query. Can be NULL to skip timestamp.
* \param *etime Target location for timestamp taken immediately after
* scanout position query. Can be NULL to skip timestamp.
* *
* Returns vpos as a positive number while in active scanout area. * Returns vpos as a positive number while in active scanout area.
* Returns vpos as a negative number inside vblank, counting the number * Returns vpos as a negative number inside vblank, counting the number
...@@ -1617,7 +1622,8 @@ bool radeon_crtc_scaling_mode_fixup(struct drm_crtc *crtc, ...@@ -1617,7 +1622,8 @@ bool radeon_crtc_scaling_mode_fixup(struct drm_crtc *crtc,
* unknown small number of scanlines wrt. real scanout position. * unknown small number of scanlines wrt. real scanout position.
* *
*/ */
int radeon_get_crtc_scanoutpos(struct drm_device *dev, int crtc, int *vpos, int *hpos) int radeon_get_crtc_scanoutpos(struct drm_device *dev, int crtc, int *vpos, int *hpos,
ktime_t *stime, ktime_t *etime)
{ {
u32 stat_crtc = 0, vbl = 0, position = 0; u32 stat_crtc = 0, vbl = 0, position = 0;
int vbl_start, vbl_end, vtotal, ret = 0; int vbl_start, vbl_end, vtotal, ret = 0;
...@@ -1625,6 +1631,12 @@ int radeon_get_crtc_scanoutpos(struct drm_device *dev, int crtc, int *vpos, int ...@@ -1625,6 +1631,12 @@ int radeon_get_crtc_scanoutpos(struct drm_device *dev, int crtc, int *vpos, int
struct radeon_device *rdev = dev->dev_private; struct radeon_device *rdev = dev->dev_private;
/* preempt_disable_rt() should go right here in PREEMPT_RT patchset. */
/* Get optional system timestamp before query. */
if (stime)
*stime = ktime_get();
if (ASIC_IS_DCE4(rdev)) { if (ASIC_IS_DCE4(rdev)) {
if (crtc == 0) { if (crtc == 0) {
vbl = RREG32(EVERGREEN_CRTC_V_BLANK_START_END + vbl = RREG32(EVERGREEN_CRTC_V_BLANK_START_END +
...@@ -1707,6 +1719,12 @@ int radeon_get_crtc_scanoutpos(struct drm_device *dev, int crtc, int *vpos, int ...@@ -1707,6 +1719,12 @@ int radeon_get_crtc_scanoutpos(struct drm_device *dev, int crtc, int *vpos, int
} }
} }
/* Get optional system timestamp after query. */
if (etime)
*etime = ktime_get();
/* preempt_enable_rt() should go right here in PREEMPT_RT patchset. */
/* Decode into vertical and horizontal scanout position. */ /* Decode into vertical and horizontal scanout position. */
*vpos = position & 0x1fff; *vpos = position & 0x1fff;
*hpos = (position >> 16) & 0x1fff; *hpos = (position >> 16) & 0x1fff;
......
...@@ -107,7 +107,8 @@ int radeon_gem_object_open(struct drm_gem_object *obj, ...@@ -107,7 +107,8 @@ int radeon_gem_object_open(struct drm_gem_object *obj,
void radeon_gem_object_close(struct drm_gem_object *obj, void radeon_gem_object_close(struct drm_gem_object *obj,
struct drm_file *file_priv); struct drm_file *file_priv);
extern int radeon_get_crtc_scanoutpos(struct drm_device *dev, int crtc, extern int radeon_get_crtc_scanoutpos(struct drm_device *dev, int crtc,
int *vpos, int *hpos); int *vpos, int *hpos, ktime_t *stime,
ktime_t *etime);
extern const struct drm_ioctl_desc radeon_ioctls_kms[]; extern const struct drm_ioctl_desc radeon_ioctls_kms[];
extern int radeon_max_kms_ioctl; extern int radeon_max_kms_ioctl;
int radeon_mmap(struct file *filp, struct vm_area_struct *vma); int radeon_mmap(struct file *filp, struct vm_area_struct *vma);
......
...@@ -766,7 +766,8 @@ extern int radeon_crtc_cursor_move(struct drm_crtc *crtc, ...@@ -766,7 +766,8 @@ extern int radeon_crtc_cursor_move(struct drm_crtc *crtc,
int x, int y); int x, int y);
extern int radeon_get_crtc_scanoutpos(struct drm_device *dev, int crtc, extern int radeon_get_crtc_scanoutpos(struct drm_device *dev, int crtc,
int *vpos, int *hpos); int *vpos, int *hpos, ktime_t *stime,
ktime_t *etime);
extern bool radeon_combios_check_hardcoded_edid(struct radeon_device *rdev); extern bool radeon_combios_check_hardcoded_edid(struct radeon_device *rdev);
extern struct edid * extern struct edid *
......
...@@ -1487,7 +1487,7 @@ static bool radeon_pm_in_vbl(struct radeon_device *rdev) ...@@ -1487,7 +1487,7 @@ static bool radeon_pm_in_vbl(struct radeon_device *rdev)
*/ */
for (crtc = 0; (crtc < rdev->num_crtc) && in_vbl; crtc++) { for (crtc = 0; (crtc < rdev->num_crtc) && in_vbl; crtc++) {
if (rdev->pm.active_crtcs & (1 << crtc)) { if (rdev->pm.active_crtcs & (1 << crtc)) {
vbl_status = radeon_get_crtc_scanoutpos(rdev->ddev, crtc, &vpos, &hpos); vbl_status = radeon_get_crtc_scanoutpos(rdev->ddev, crtc, &vpos, &hpos, NULL, NULL);
if ((vbl_status & DRM_SCANOUTPOS_VALID) && if ((vbl_status & DRM_SCANOUTPOS_VALID) &&
!(vbl_status & DRM_SCANOUTPOS_INVBL)) !(vbl_status & DRM_SCANOUTPOS_INVBL))
in_vbl = false; in_vbl = false;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment