From 3bb403bf421b5b00366a9041a7edc0a1f6494f5e Mon Sep 17 00:00:00 2001 From: Ville Syrjälä Date: Mon, 14 Sep 2015 22:43:44 +0300 Subject: drm: Stop using linedur_ns and pixeldur_ns for vblank timestamps MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit linedur_ns, and especially pixeldur_ns are becoming rather inaccurate to be used for the vblank timestamp correction. With 4k@60 the pixel duration is already below 2ns, so the amount of error due to the truncation to nanoseconds is introducing quite a bit of error. We can avoid such problems if we instead calculate the timestamp delta_ns directly from the dislay timings, avoiding the use of these intermediate truncated values. Signed-off-by: Ville Syrjälä Reviewed-by: Maarten Lankhorst [danvet: Squash in fixup from Thierry Reding for amdgpu.] Signed-off-by: Daniel Vetter --- drivers/gpu/drm/amd/amdgpu/amdgpu_display.c | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) (limited to 'drivers/gpu/drm/amd/amdgpu/amdgpu_display.c') diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_display.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_display.c index e3d70772b531..9b34a3410c32 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_display.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_display.c @@ -745,7 +745,8 @@ bool amdgpu_crtc_scaling_mode_fixup(struct drm_crtc *crtc, * */ int amdgpu_get_crtc_scanoutpos(struct drm_device *dev, int crtc, unsigned int flags, - int *vpos, int *hpos, ktime_t *stime, ktime_t *etime) + int *vpos, int *hpos, ktime_t *stime, ktime_t *etime, + const struct drm_display_mode *mode) { u32 vbl = 0, position = 0; int vbl_start, vbl_end, vtotal, ret = 0; @@ -781,7 +782,7 @@ int amdgpu_get_crtc_scanoutpos(struct drm_device *dev, int crtc, unsigned int fl } else { /* No: Fake something reasonable which gives at least ok results. */ - vbl_start = adev->mode_info.crtcs[crtc]->base.hwmode.crtc_vdisplay; + vbl_start = mode->crtc_vdisplay; vbl_end = 0; } @@ -797,7 +798,7 @@ int amdgpu_get_crtc_scanoutpos(struct drm_device *dev, int crtc, unsigned int fl /* Inside "upper part" of vblank area? Apply corrective offset if so: */ if (in_vbl && (*vpos >= vbl_start)) { - vtotal = adev->mode_info.crtcs[crtc]->base.hwmode.crtc_vtotal; + vtotal = mode->crtc_vtotal; *vpos = *vpos - vtotal; } @@ -819,8 +820,8 @@ int amdgpu_get_crtc_scanoutpos(struct drm_device *dev, int crtc, unsigned int fl * We only do this if DRM_CALLED_FROM_VBLIRQ. */ if ((flags & DRM_CALLED_FROM_VBLIRQ) && !in_vbl) { - vbl_start = adev->mode_info.crtcs[crtc]->base.hwmode.crtc_vdisplay; - vtotal = adev->mode_info.crtcs[crtc]->base.hwmode.crtc_vtotal; + vbl_start = mode->crtc_vdisplay; + vtotal = mode->crtc_vtotal; if (vbl_start - *vpos < vtotal / 100) { *vpos -= vtotal; -- cgit v1.2.3 From 88e72717c2de4181d8a6de1b04315953ad2bebdf Mon Sep 17 00:00:00 2001 From: Thierry Reding Date: Thu, 24 Sep 2015 18:35:31 +0200 Subject: drm/irq: Use unsigned int pipe in public API MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This continues the pattern started in commit cc1ef118fc09 ("drm/irq: Make pipe unsigned and name consistent"). This is applied to the public APIs and driver callbacks, so pretty much all drivers need to be updated to match the new prototypes. Cc: Christian König Cc: Alex Deucher Cc: Russell King Cc: Inki Dae Cc: Jianwei Wang Cc: Alison Wang Cc: Patrik Jakobsson Cc: Daniel Vetter Cc: Jani Nikula Cc: Philipp Zabel Cc: David Airlie Cc: Rob Clark Cc: Ben Skeggs Cc: Tomi Valkeinen Cc: Laurent Pinchart Cc: Mark Yao Cc: Benjamin Gaignard Cc: Vincent Abriou Cc: Thomas Hellstrom Signed-off-by: Thierry Reding Reviewed-by: Ville Syrjälä Signed-off-by: Daniel Vetter --- drivers/gpu/drm/amd/amdgpu/amdgpu.h | 8 +++--- drivers/gpu/drm/amd/amdgpu/amdgpu_display.c | 9 ++++--- drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c | 36 +++++++++++++------------- drivers/gpu/drm/amd/amdgpu/amdgpu_mode.h | 9 +++---- drivers/gpu/drm/armada/armada_drv.c | 8 +++--- drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_dc.c | 6 +++-- drivers/gpu/drm/drm_irq.c | 2 +- drivers/gpu/drm/exynos/exynos_drm_crtc.c | 4 +-- drivers/gpu/drm/exynos/exynos_drm_crtc.h | 4 +-- drivers/gpu/drm/fsl-dcu/fsl_dcu_drm_drv.c | 5 ++-- drivers/gpu/drm/gma500/psb_drv.h | 6 ++--- drivers/gpu/drm/gma500/psb_irq.c | 8 +++--- drivers/gpu/drm/gma500/psb_irq.h | 6 ++--- drivers/gpu/drm/i915/i915_irq.c | 34 ++++++++++++------------- drivers/gpu/drm/imx/imx-drm-core.c | 8 +++--- drivers/gpu/drm/mga/mga_drv.h | 6 ++--- drivers/gpu/drm/mga/mga_irq.c | 20 +++++++-------- drivers/gpu/drm/msm/msm_drv.c | 12 ++++----- drivers/gpu/drm/nouveau/nouveau_display.c | 23 +++++++++-------- drivers/gpu/drm/nouveau/nouveau_display.h | 12 ++++----- drivers/gpu/drm/omapdrm/omap_drv.h | 4 +-- drivers/gpu/drm/omapdrm/omap_irq.c | 16 ++++++------ drivers/gpu/drm/qxl/qxl_drv.c | 7 ++--- drivers/gpu/drm/r128/r128_drv.h | 6 ++--- drivers/gpu/drm/r128/r128_irq.c | 16 ++++++------ drivers/gpu/drm/radeon/radeon_display.c | 25 +++++++++--------- drivers/gpu/drm/radeon/radeon_drv.c | 13 +++++----- drivers/gpu/drm/radeon/radeon_drv.h | 6 ++--- drivers/gpu/drm/radeon/radeon_irq.c | 38 ++++++++++++++-------------- drivers/gpu/drm/radeon/radeon_mode.h | 5 ++-- drivers/gpu/drm/rcar-du/rcar_du_drv.c | 8 +++--- drivers/gpu/drm/rockchip/rockchip_drm_drv.c | 6 +++-- drivers/gpu/drm/shmobile/shmob_drm_drv.c | 4 +-- drivers/gpu/drm/sti/sti_crtc.c | 16 ++++++------ drivers/gpu/drm/sti/sti_crtc.h | 4 +-- drivers/gpu/drm/tegra/drm.c | 7 ++--- drivers/gpu/drm/tilcdc/tilcdc_drv.c | 4 +-- drivers/gpu/drm/via/via_drv.h | 6 ++--- drivers/gpu/drm/via/via_irq.c | 17 +++++++------ drivers/gpu/drm/vmwgfx/vmwgfx_drv.h | 6 ++--- drivers/gpu/drm/vmwgfx/vmwgfx_kms.c | 6 ++--- include/drm/drmP.h | 25 +++++++++--------- 42 files changed, 239 insertions(+), 232 deletions(-) (limited to 'drivers/gpu/drm/amd/amdgpu/amdgpu_display.c') diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu.h b/drivers/gpu/drm/amd/amdgpu/amdgpu.h index 6647fb26ef25..5e43178d07d5 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu.h +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu.h @@ -2349,10 +2349,10 @@ void amdgpu_driver_preclose_kms(struct drm_device *dev, struct drm_file *file_priv); int amdgpu_suspend_kms(struct drm_device *dev, bool suspend, bool fbcon); int amdgpu_resume_kms(struct drm_device *dev, bool resume, bool fbcon); -u32 amdgpu_get_vblank_counter_kms(struct drm_device *dev, int crtc); -int amdgpu_enable_vblank_kms(struct drm_device *dev, int crtc); -void amdgpu_disable_vblank_kms(struct drm_device *dev, int crtc); -int amdgpu_get_vblank_timestamp_kms(struct drm_device *dev, int crtc, +u32 amdgpu_get_vblank_counter_kms(struct drm_device *dev, unsigned int pipe); +int amdgpu_enable_vblank_kms(struct drm_device *dev, unsigned int pipe); +void amdgpu_disable_vblank_kms(struct drm_device *dev, unsigned int pipe); +int amdgpu_get_vblank_timestamp_kms(struct drm_device *dev, unsigned int pipe, int *max_error, struct timeval *vblank_time, unsigned flags); diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_display.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_display.c index 9b34a3410c32..de116398fa49 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_display.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_display.c @@ -721,7 +721,7 @@ bool amdgpu_crtc_scaling_mode_fixup(struct drm_crtc *crtc, * an optional accurate timestamp of when query happened. * * \param dev Device to query. - * \param crtc Crtc to query. + * \param pipe Crtc to query. * \param flags Flags from caller (DRM_CALLED_FROM_VBLIRQ or 0). * \param *vpos Location where vertical scanout position should be stored. * \param *hpos Location where horizontal scanout position should go. @@ -744,8 +744,9 @@ bool amdgpu_crtc_scaling_mode_fixup(struct drm_crtc *crtc, * unknown small number of scanlines wrt. real scanout position. * */ -int amdgpu_get_crtc_scanoutpos(struct drm_device *dev, int crtc, unsigned int flags, - int *vpos, int *hpos, ktime_t *stime, ktime_t *etime, +int amdgpu_get_crtc_scanoutpos(struct drm_device *dev, unsigned int pipe, + unsigned int flags, int *vpos, int *hpos, + ktime_t *stime, ktime_t *etime, const struct drm_display_mode *mode) { u32 vbl = 0, position = 0; @@ -760,7 +761,7 @@ int amdgpu_get_crtc_scanoutpos(struct drm_device *dev, int crtc, unsigned int fl if (stime) *stime = ktime_get(); - if (amdgpu_display_page_flip_get_scanoutpos(adev, crtc, &vbl, &position) == 0) + if (amdgpu_display_page_flip_get_scanoutpos(adev, pipe, &vbl, &position) == 0) ret |= DRM_SCANOUTPOS_VALID; /* Get optional system timestamp after query. */ diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c index 275f1c3dbba0..b9faaf800ae1 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c @@ -600,36 +600,36 @@ void amdgpu_driver_preclose_kms(struct drm_device *dev, * amdgpu_get_vblank_counter_kms - get frame count * * @dev: drm dev pointer - * @crtc: crtc to get the frame count from + * @pipe: crtc to get the frame count from * * Gets the frame count on the requested crtc (all asics). * Returns frame count on success, -EINVAL on failure. */ -u32 amdgpu_get_vblank_counter_kms(struct drm_device *dev, int crtc) +u32 amdgpu_get_vblank_counter_kms(struct drm_device *dev, unsigned int pipe) { struct amdgpu_device *adev = dev->dev_private; - if (crtc < 0 || crtc >= adev->mode_info.num_crtc) { - DRM_ERROR("Invalid crtc %d\n", crtc); + if (pipe >= adev->mode_info.num_crtc) { + DRM_ERROR("Invalid crtc %u\n", pipe); return -EINVAL; } - return amdgpu_display_vblank_get_counter(adev, crtc); + return amdgpu_display_vblank_get_counter(adev, pipe); } /** * amdgpu_enable_vblank_kms - enable vblank interrupt * * @dev: drm dev pointer - * @crtc: crtc to enable vblank interrupt for + * @pipe: crtc to enable vblank interrupt for * * Enable the interrupt on the requested crtc (all asics). * Returns 0 on success, -EINVAL on failure. */ -int amdgpu_enable_vblank_kms(struct drm_device *dev, int crtc) +int amdgpu_enable_vblank_kms(struct drm_device *dev, unsigned int pipe) { struct amdgpu_device *adev = dev->dev_private; - int idx = amdgpu_crtc_idx_to_irq_type(adev, crtc); + int idx = amdgpu_crtc_idx_to_irq_type(adev, pipe); return amdgpu_irq_get(adev, &adev->crtc_irq, idx); } @@ -638,14 +638,14 @@ int amdgpu_enable_vblank_kms(struct drm_device *dev, int crtc) * amdgpu_disable_vblank_kms - disable vblank interrupt * * @dev: drm dev pointer - * @crtc: crtc to disable vblank interrupt for + * @pipe: crtc to disable vblank interrupt for * * Disable the interrupt on the requested crtc (all asics). */ -void amdgpu_disable_vblank_kms(struct drm_device *dev, int crtc) +void amdgpu_disable_vblank_kms(struct drm_device *dev, unsigned int pipe) { struct amdgpu_device *adev = dev->dev_private; - int idx = amdgpu_crtc_idx_to_irq_type(adev, crtc); + int idx = amdgpu_crtc_idx_to_irq_type(adev, pipe); amdgpu_irq_put(adev, &adev->crtc_irq, idx); } @@ -663,26 +663,26 @@ void amdgpu_disable_vblank_kms(struct drm_device *dev, int crtc) * scanout position. (all asics). * Returns postive status flags on success, negative error on failure. */ -int amdgpu_get_vblank_timestamp_kms(struct drm_device *dev, int crtc, +int amdgpu_get_vblank_timestamp_kms(struct drm_device *dev, unsigned int pipe, int *max_error, struct timeval *vblank_time, unsigned flags) { - struct drm_crtc *drmcrtc; + struct drm_crtc *crtc; struct amdgpu_device *adev = dev->dev_private; - if (crtc < 0 || crtc >= dev->num_crtcs) { - DRM_ERROR("Invalid crtc %d\n", crtc); + if (pipe >= dev->num_crtcs) { + DRM_ERROR("Invalid crtc %u\n", pipe); return -EINVAL; } /* Get associated drm_crtc: */ - drmcrtc = &adev->mode_info.crtcs[crtc]->base; + crtc = &adev->mode_info.crtcs[pipe]->base; /* Helper routine in DRM core does all the work: */ - return drm_calc_vbltimestamp_from_scanoutpos(dev, crtc, max_error, + return drm_calc_vbltimestamp_from_scanoutpos(dev, pipe, max_error, vblank_time, flags, - &drmcrtc->hwmode); + &crtc->hwmode); } const struct drm_ioctl_desc amdgpu_ioctls_kms[] = { diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_mode.h b/drivers/gpu/drm/amd/amdgpu/amdgpu_mode.h index 2b03425f9740..f6b02994442b 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_mode.h +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_mode.h @@ -540,11 +540,10 @@ bool amdgpu_ddc_probe(struct amdgpu_connector *amdgpu_connector, bool use_aux); void amdgpu_encoder_set_active_device(struct drm_encoder *encoder); -int amdgpu_get_crtc_scanoutpos(struct drm_device *dev, int crtc, - unsigned int flags, - int *vpos, int *hpos, ktime_t *stime, - ktime_t *etime, - const struct drm_display_mode *mode); +int amdgpu_get_crtc_scanoutpos(struct drm_device *dev, unsigned int pipe, + unsigned int flags, int *vpos, int *hpos, + ktime_t *stime, ktime_t *etime, + const struct drm_display_mode *mode); int amdgpu_framebuffer_init(struct drm_device *dev, struct amdgpu_framebuffer *rfb, diff --git a/drivers/gpu/drm/armada/armada_drv.c b/drivers/gpu/drm/armada/armada_drv.c index 225034b74cda..a438886fcdb6 100644 --- a/drivers/gpu/drm/armada/armada_drv.c +++ b/drivers/gpu/drm/armada/armada_drv.c @@ -254,17 +254,17 @@ void armada_drm_vbl_event_remove(struct armada_crtc *dcrtc, } /* These are called under the vbl_lock. */ -static int armada_drm_enable_vblank(struct drm_device *dev, int crtc) +static int armada_drm_enable_vblank(struct drm_device *dev, unsigned int pipe) { struct armada_private *priv = dev->dev_private; - armada_drm_crtc_enable_irq(priv->dcrtc[crtc], VSYNC_IRQ_ENA); + armada_drm_crtc_enable_irq(priv->dcrtc[pipe], VSYNC_IRQ_ENA); return 0; } -static void armada_drm_disable_vblank(struct drm_device *dev, int crtc) +static void armada_drm_disable_vblank(struct drm_device *dev, unsigned int pipe) { struct armada_private *priv = dev->dev_private; - armada_drm_crtc_disable_irq(priv->dcrtc[crtc], VSYNC_IRQ_ENA); + armada_drm_crtc_disable_irq(priv->dcrtc[pipe], VSYNC_IRQ_ENA); } static struct drm_ioctl_desc armada_ioctls[] = { diff --git a/drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_dc.c b/drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_dc.c index 8bc62ec407f9..6dfb63ab54d2 100644 --- a/drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_dc.c +++ b/drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_dc.c @@ -656,7 +656,8 @@ static void atmel_hlcdc_dc_irq_uninstall(struct drm_device *dev) regmap_read(dc->hlcdc->regmap, ATMEL_HLCDC_ISR, &isr); } -static int atmel_hlcdc_dc_enable_vblank(struct drm_device *dev, int crtc) +static int atmel_hlcdc_dc_enable_vblank(struct drm_device *dev, + unsigned int pipe) { struct atmel_hlcdc_dc *dc = dev->dev_private; @@ -666,7 +667,8 @@ static int atmel_hlcdc_dc_enable_vblank(struct drm_device *dev, int crtc) return 0; } -static void atmel_hlcdc_dc_disable_vblank(struct drm_device *dev, int crtc) +static void atmel_hlcdc_dc_disable_vblank(struct drm_device *dev, + unsigned int pipe) { struct atmel_hlcdc_dc *dc = dev->dev_private; diff --git a/drivers/gpu/drm/drm_irq.c b/drivers/gpu/drm/drm_irq.c index 6bff6d3e570e..0659d9956b7c 100644 --- a/drivers/gpu/drm/drm_irq.c +++ b/drivers/gpu/drm/drm_irq.c @@ -877,7 +877,7 @@ drm_get_last_vbltimestamp(struct drm_device *dev, unsigned int pipe, * Returns: * The software vblank counter. */ -u32 drm_vblank_count(struct drm_device *dev, int pipe) +u32 drm_vblank_count(struct drm_device *dev, unsigned int pipe) { struct drm_vblank_crtc *vblank = &dev->vblank[pipe]; diff --git a/drivers/gpu/drm/exynos/exynos_drm_crtc.c b/drivers/gpu/drm/exynos/exynos_drm_crtc.c index 0872aa2f450f..f364d694a780 100644 --- a/drivers/gpu/drm/exynos/exynos_drm_crtc.c +++ b/drivers/gpu/drm/exynos/exynos_drm_crtc.c @@ -167,7 +167,7 @@ err_crtc: return ERR_PTR(ret); } -int exynos_drm_crtc_enable_vblank(struct drm_device *dev, int pipe) +int exynos_drm_crtc_enable_vblank(struct drm_device *dev, unsigned int pipe) { struct exynos_drm_private *private = dev->dev_private; struct exynos_drm_crtc *exynos_crtc = @@ -179,7 +179,7 @@ int exynos_drm_crtc_enable_vblank(struct drm_device *dev, int pipe) return 0; } -void exynos_drm_crtc_disable_vblank(struct drm_device *dev, int pipe) +void exynos_drm_crtc_disable_vblank(struct drm_device *dev, unsigned int pipe) { struct exynos_drm_private *private = dev->dev_private; struct exynos_drm_crtc *exynos_crtc = diff --git a/drivers/gpu/drm/exynos/exynos_drm_crtc.h b/drivers/gpu/drm/exynos/exynos_drm_crtc.h index f87d4abda6f7..f9f365bd0257 100644 --- a/drivers/gpu/drm/exynos/exynos_drm_crtc.h +++ b/drivers/gpu/drm/exynos/exynos_drm_crtc.h @@ -23,8 +23,8 @@ struct exynos_drm_crtc *exynos_drm_crtc_create(struct drm_device *drm_dev, enum exynos_drm_output_type type, const struct exynos_drm_crtc_ops *ops, void *context); -int exynos_drm_crtc_enable_vblank(struct drm_device *dev, int pipe); -void exynos_drm_crtc_disable_vblank(struct drm_device *dev, int pipe); +int exynos_drm_crtc_enable_vblank(struct drm_device *dev, unsigned int pipe); +void exynos_drm_crtc_disable_vblank(struct drm_device *dev, unsigned int pipe); void exynos_drm_crtc_wait_pending_update(struct exynos_drm_crtc *exynos_crtc); void exynos_drm_crtc_finish_update(struct exynos_drm_crtc *exynos_crtc, struct exynos_drm_plane *exynos_plane); diff --git a/drivers/gpu/drm/fsl-dcu/fsl_dcu_drm_drv.c b/drivers/gpu/drm/fsl-dcu/fsl_dcu_drm_drv.c index 9a8e2da47158..f1fd986ca332 100644 --- a/drivers/gpu/drm/fsl-dcu/fsl_dcu_drm_drv.c +++ b/drivers/gpu/drm/fsl-dcu/fsl_dcu_drm_drv.c @@ -140,7 +140,7 @@ static irqreturn_t fsl_dcu_drm_irq(int irq, void *arg) return IRQ_HANDLED; } -static int fsl_dcu_drm_enable_vblank(struct drm_device *dev, int crtc) +static int fsl_dcu_drm_enable_vblank(struct drm_device *dev, unsigned int pipe) { struct fsl_dcu_drm_device *fsl_dev = dev->dev_private; unsigned int value; @@ -156,7 +156,8 @@ static int fsl_dcu_drm_enable_vblank(struct drm_device *dev, int crtc) return 0; } -static void fsl_dcu_drm_disable_vblank(struct drm_device *dev, int crtc) +static void fsl_dcu_drm_disable_vblank(struct drm_device *dev, + unsigned int pipe) { struct fsl_dcu_drm_device *fsl_dev = dev->dev_private; unsigned int value; diff --git a/drivers/gpu/drm/gma500/psb_drv.h b/drivers/gpu/drm/gma500/psb_drv.h index e38057b91865..e21726ecac32 100644 --- a/drivers/gpu/drm/gma500/psb_drv.h +++ b/drivers/gpu/drm/gma500/psb_drv.h @@ -687,15 +687,15 @@ extern void psb_irq_turn_off_dpst(struct drm_device *dev); extern void psb_irq_uninstall_islands(struct drm_device *dev, int hw_islands); extern int psb_vblank_wait2(struct drm_device *dev, unsigned int *sequence); extern int psb_vblank_wait(struct drm_device *dev, unsigned int *sequence); -extern int psb_enable_vblank(struct drm_device *dev, int crtc); -extern void psb_disable_vblank(struct drm_device *dev, int crtc); +extern int psb_enable_vblank(struct drm_device *dev, unsigned int pipe); +extern void psb_disable_vblank(struct drm_device *dev, unsigned int pipe); void psb_enable_pipestat(struct drm_psb_private *dev_priv, int pipe, u32 mask); void psb_disable_pipestat(struct drm_psb_private *dev_priv, int pipe, u32 mask); -extern u32 psb_get_vblank_counter(struct drm_device *dev, int crtc); +extern u32 psb_get_vblank_counter(struct drm_device *dev, unsigned int pipe); /* framebuffer.c */ extern int psbfb_probed(struct drm_device *dev); diff --git a/drivers/gpu/drm/gma500/psb_irq.c b/drivers/gpu/drm/gma500/psb_irq.c index 624eb36511c5..78eb10902809 100644 --- a/drivers/gpu/drm/gma500/psb_irq.c +++ b/drivers/gpu/drm/gma500/psb_irq.c @@ -510,7 +510,7 @@ int psb_irq_disable_dpst(struct drm_device *dev) /* * It is used to enable VBLANK interrupt */ -int psb_enable_vblank(struct drm_device *dev, int pipe) +int psb_enable_vblank(struct drm_device *dev, unsigned int pipe) { struct drm_psb_private *dev_priv = dev->dev_private; unsigned long irqflags; @@ -549,7 +549,7 @@ int psb_enable_vblank(struct drm_device *dev, int pipe) /* * It is used to disable VBLANK interrupt */ -void psb_disable_vblank(struct drm_device *dev, int pipe) +void psb_disable_vblank(struct drm_device *dev, unsigned int pipe) { struct drm_psb_private *dev_priv = dev->dev_private; unsigned long irqflags; @@ -622,7 +622,7 @@ void mdfld_disable_te(struct drm_device *dev, int pipe) /* Called from drm generic code, passed a 'crtc', which * we use as a pipe index */ -u32 psb_get_vblank_counter(struct drm_device *dev, int pipe) +u32 psb_get_vblank_counter(struct drm_device *dev, unsigned int pipe) { uint32_t high_frame = PIPEAFRAMEHIGH; uint32_t low_frame = PIPEAFRAMEPIXEL; @@ -654,7 +654,7 @@ u32 psb_get_vblank_counter(struct drm_device *dev, int pipe) reg_val = REG_READ(pipeconf_reg); if (!(reg_val & PIPEACONF_ENABLE)) { - dev_err(dev->dev, "trying to get vblank count for disabled pipe %d\n", + dev_err(dev->dev, "trying to get vblank count for disabled pipe %u\n", pipe); goto psb_get_vblank_counter_exit; } diff --git a/drivers/gpu/drm/gma500/psb_irq.h b/drivers/gpu/drm/gma500/psb_irq.h index d0b45ffa1126..e6a81a8c9f35 100644 --- a/drivers/gpu/drm/gma500/psb_irq.h +++ b/drivers/gpu/drm/gma500/psb_irq.h @@ -38,9 +38,9 @@ int psb_irq_enable_dpst(struct drm_device *dev); int psb_irq_disable_dpst(struct drm_device *dev); void psb_irq_turn_on_dpst(struct drm_device *dev); void psb_irq_turn_off_dpst(struct drm_device *dev); -int psb_enable_vblank(struct drm_device *dev, int pipe); -void psb_disable_vblank(struct drm_device *dev, int pipe); -u32 psb_get_vblank_counter(struct drm_device *dev, int pipe); +int psb_enable_vblank(struct drm_device *dev, unsigned int pipe); +void psb_disable_vblank(struct drm_device *dev, unsigned int pipe); +u32 psb_get_vblank_counter(struct drm_device *dev, unsigned int pipe); int mdfld_enable_te(struct drm_device *dev, int pipe); void mdfld_disable_te(struct drm_device *dev, int pipe); diff --git a/drivers/gpu/drm/i915/i915_irq.c b/drivers/gpu/drm/i915/i915_irq.c index 88d064e80783..bc732eb52b50 100644 --- a/drivers/gpu/drm/i915/i915_irq.c +++ b/drivers/gpu/drm/i915/i915_irq.c @@ -554,7 +554,7 @@ static void i915_enable_asle_pipestat(struct drm_device *dev) * of horizontal active on the first line of vertical active */ -static u32 i8xx_get_vblank_counter(struct drm_device *dev, int pipe) +static u32 i8xx_get_vblank_counter(struct drm_device *dev, unsigned int pipe) { /* Gen2 doesn't have a hardware frame counter */ return 0; @@ -563,7 +563,7 @@ static u32 i8xx_get_vblank_counter(struct drm_device *dev, int pipe) /* Called from drm generic code, passed a 'crtc', which * we use as a pipe index */ -static u32 i915_get_vblank_counter(struct drm_device *dev, int pipe) +static u32 i915_get_vblank_counter(struct drm_device *dev, unsigned int pipe) { struct drm_i915_private *dev_priv = dev->dev_private; unsigned long high_frame; @@ -611,7 +611,7 @@ static u32 i915_get_vblank_counter(struct drm_device *dev, int pipe) return (((high1 << 8) | low) + (pixel >= vbl_start)) & 0xffffff; } -static u32 gm45_get_vblank_counter(struct drm_device *dev, int pipe) +static u32 gm45_get_vblank_counter(struct drm_device *dev, unsigned int pipe) { struct drm_i915_private *dev_priv = dev->dev_private; int reg = PIPE_FRMCOUNT_GM45(pipe); @@ -672,7 +672,7 @@ static int __intel_get_crtc_scanline(struct intel_crtc *crtc) return (position + crtc->scanline_offset) % vtotal; } -static int i915_get_crtc_scanoutpos(struct drm_device *dev, int pipe, +static int i915_get_crtc_scanoutpos(struct drm_device *dev, unsigned int pipe, unsigned int flags, int *vpos, int *hpos, ktime_t *stime, ktime_t *etime, const struct drm_display_mode *mode) @@ -809,27 +809,27 @@ int intel_get_crtc_scanline(struct intel_crtc *crtc) return position; } -static int i915_get_vblank_timestamp(struct drm_device *dev, int pipe, +static int i915_get_vblank_timestamp(struct drm_device *dev, unsigned int pipe, int *max_error, struct timeval *vblank_time, unsigned flags) { struct drm_crtc *crtc; - if (pipe < 0 || pipe >= INTEL_INFO(dev)->num_pipes) { - DRM_ERROR("Invalid crtc %d\n", pipe); + if (pipe >= INTEL_INFO(dev)->num_pipes) { + DRM_ERROR("Invalid crtc %u\n", pipe); return -EINVAL; } /* Get drm_crtc to timestamp: */ crtc = intel_get_crtc_for_pipe(dev, pipe); if (crtc == NULL) { - DRM_ERROR("Invalid crtc %d\n", pipe); + DRM_ERROR("Invalid crtc %u\n", pipe); return -EINVAL; } if (!crtc->hwmode.crtc_clock) { - DRM_DEBUG_KMS("crtc %d is disabled\n", pipe); + DRM_DEBUG_KMS("crtc %u is disabled\n", pipe); return -EBUSY; } @@ -2431,7 +2431,7 @@ void i915_handle_error(struct drm_device *dev, bool wedged, /* Called from drm generic code, passed 'crtc' which * we use as a pipe index */ -static int i915_enable_vblank(struct drm_device *dev, int pipe) +static int i915_enable_vblank(struct drm_device *dev, unsigned int pipe) { struct drm_i915_private *dev_priv = dev->dev_private; unsigned long irqflags; @@ -2448,7 +2448,7 @@ static int i915_enable_vblank(struct drm_device *dev, int pipe) return 0; } -static int ironlake_enable_vblank(struct drm_device *dev, int pipe) +static int ironlake_enable_vblank(struct drm_device *dev, unsigned int pipe) { struct drm_i915_private *dev_priv = dev->dev_private; unsigned long irqflags; @@ -2462,7 +2462,7 @@ static int ironlake_enable_vblank(struct drm_device *dev, int pipe) return 0; } -static int valleyview_enable_vblank(struct drm_device *dev, int pipe) +static int valleyview_enable_vblank(struct drm_device *dev, unsigned int pipe) { struct drm_i915_private *dev_priv = dev->dev_private; unsigned long irqflags; @@ -2475,7 +2475,7 @@ static int valleyview_enable_vblank(struct drm_device *dev, int pipe) return 0; } -static int gen8_enable_vblank(struct drm_device *dev, int pipe) +static int gen8_enable_vblank(struct drm_device *dev, unsigned int pipe) { struct drm_i915_private *dev_priv = dev->dev_private; unsigned long irqflags; @@ -2491,7 +2491,7 @@ static int gen8_enable_vblank(struct drm_device *dev, int pipe) /* Called from drm generic code, passed 'crtc' which * we use as a pipe index */ -static void i915_disable_vblank(struct drm_device *dev, int pipe) +static void i915_disable_vblank(struct drm_device *dev, unsigned int pipe) { struct drm_i915_private *dev_priv = dev->dev_private; unsigned long irqflags; @@ -2503,7 +2503,7 @@ static void i915_disable_vblank(struct drm_device *dev, int pipe) spin_unlock_irqrestore(&dev_priv->irq_lock, irqflags); } -static void ironlake_disable_vblank(struct drm_device *dev, int pipe) +static void ironlake_disable_vblank(struct drm_device *dev, unsigned int pipe) { struct drm_i915_private *dev_priv = dev->dev_private; unsigned long irqflags; @@ -2515,7 +2515,7 @@ static void ironlake_disable_vblank(struct drm_device *dev, int pipe) spin_unlock_irqrestore(&dev_priv->irq_lock, irqflags); } -static void valleyview_disable_vblank(struct drm_device *dev, int pipe) +static void valleyview_disable_vblank(struct drm_device *dev, unsigned int pipe) { struct drm_i915_private *dev_priv = dev->dev_private; unsigned long irqflags; @@ -2526,7 +2526,7 @@ static void valleyview_disable_vblank(struct drm_device *dev, int pipe) spin_unlock_irqrestore(&dev_priv->irq_lock, irqflags); } -static void gen8_disable_vblank(struct drm_device *dev, int pipe) +static void gen8_disable_vblank(struct drm_device *dev, unsigned int pipe) { struct drm_i915_private *dev_priv = dev->dev_private; unsigned long irqflags; diff --git a/drivers/gpu/drm/imx/imx-drm-core.c b/drivers/gpu/drm/imx/imx-drm-core.c index 74f505b0dd02..b880c12c6521 100644 --- a/drivers/gpu/drm/imx/imx-drm-core.c +++ b/drivers/gpu/drm/imx/imx-drm-core.c @@ -145,10 +145,10 @@ void imx_drm_handle_vblank(struct imx_drm_crtc *imx_drm_crtc) } EXPORT_SYMBOL_GPL(imx_drm_handle_vblank); -static int imx_drm_enable_vblank(struct drm_device *drm, int crtc) +static int imx_drm_enable_vblank(struct drm_device *drm, unsigned int pipe) { struct imx_drm_device *imxdrm = drm->dev_private; - struct imx_drm_crtc *imx_drm_crtc = imxdrm->crtc[crtc]; + struct imx_drm_crtc *imx_drm_crtc = imxdrm->crtc[pipe]; int ret; if (!imx_drm_crtc) @@ -163,10 +163,10 @@ static int imx_drm_enable_vblank(struct drm_device *drm, int crtc) return ret; } -static void imx_drm_disable_vblank(struct drm_device *drm, int crtc) +static void imx_drm_disable_vblank(struct drm_device *drm, unsigned int pipe) { struct imx_drm_device *imxdrm = drm->dev_private; - struct imx_drm_crtc *imx_drm_crtc = imxdrm->crtc[crtc]; + struct imx_drm_crtc *imx_drm_crtc = imxdrm->crtc[pipe]; if (!imx_drm_crtc) return; diff --git a/drivers/gpu/drm/mga/mga_drv.h b/drivers/gpu/drm/mga/mga_drv.h index b4a2014917e5..bb312339e0b0 100644 --- a/drivers/gpu/drm/mga/mga_drv.h +++ b/drivers/gpu/drm/mga/mga_drv.h @@ -183,9 +183,9 @@ extern int mga_warp_install_microcode(drm_mga_private_t *dev_priv); extern int mga_warp_init(drm_mga_private_t *dev_priv); /* mga_irq.c */ -extern int mga_enable_vblank(struct drm_device *dev, int crtc); -extern void mga_disable_vblank(struct drm_device *dev, int crtc); -extern u32 mga_get_vblank_counter(struct drm_device *dev, int crtc); +extern int mga_enable_vblank(struct drm_device *dev, unsigned int pipe); +extern void mga_disable_vblank(struct drm_device *dev, unsigned int pipe); +extern u32 mga_get_vblank_counter(struct drm_device *dev, unsigned int pipe); extern int mga_driver_fence_wait(struct drm_device *dev, unsigned int *sequence); extern int mga_driver_vblank_wait(struct drm_device *dev, unsigned int *sequence); extern irqreturn_t mga_driver_irq_handler(int irq, void *arg); diff --git a/drivers/gpu/drm/mga/mga_irq.c b/drivers/gpu/drm/mga/mga_irq.c index 1b071b8ff9dc..693ba708cfed 100644 --- a/drivers/gpu/drm/mga/mga_irq.c +++ b/drivers/gpu/drm/mga/mga_irq.c @@ -35,12 +35,12 @@ #include #include "mga_drv.h" -u32 mga_get_vblank_counter(struct drm_device *dev, int crtc) +u32 mga_get_vblank_counter(struct drm_device *dev, unsigned int pipe) { const drm_mga_private_t *const dev_priv = (drm_mga_private_t *) dev->dev_private; - if (crtc != 0) + if (pipe != 0) return 0; return atomic_read(&dev_priv->vbl_received); @@ -88,13 +88,13 @@ irqreturn_t mga_driver_irq_handler(int irq, void *arg) return IRQ_NONE; } -int mga_enable_vblank(struct drm_device *dev, int crtc) +int mga_enable_vblank(struct drm_device *dev, unsigned int pipe) { drm_mga_private_t *dev_priv = (drm_mga_private_t *) dev->dev_private; - if (crtc != 0) { - DRM_ERROR("tried to enable vblank on non-existent crtc %d\n", - crtc); + if (pipe != 0) { + DRM_ERROR("tried to enable vblank on non-existent crtc %u\n", + pipe); return 0; } @@ -103,11 +103,11 @@ int mga_enable_vblank(struct drm_device *dev, int crtc) } -void mga_disable_vblank(struct drm_device *dev, int crtc) +void mga_disable_vblank(struct drm_device *dev, unsigned int pipe) { - if (crtc != 0) { - DRM_ERROR("tried to disable vblank on non-existent crtc %d\n", - crtc); + if (pipe != 0) { + DRM_ERROR("tried to disable vblank on non-existent crtc %u\n", + pipe); } /* Do *NOT* disable the vertical refresh interrupt. MGA doesn't have diff --git a/drivers/gpu/drm/msm/msm_drv.c b/drivers/gpu/drm/msm/msm_drv.c index 0339c5d82d37..7e44511d0951 100644 --- a/drivers/gpu/drm/msm/msm_drv.c +++ b/drivers/gpu/drm/msm/msm_drv.c @@ -531,24 +531,24 @@ static void msm_irq_uninstall(struct drm_device *dev) kms->funcs->irq_uninstall(kms); } -static int msm_enable_vblank(struct drm_device *dev, int crtc_id) +static int msm_enable_vblank(struct drm_device *dev, unsigned int pipe) { struct msm_drm_private *priv = dev->dev_private; struct msm_kms *kms = priv->kms; if (!kms) return -ENXIO; - DBG("dev=%p, crtc=%d", dev, crtc_id); - return vblank_ctrl_queue_work(priv, crtc_id, true); + DBG("dev=%p, crtc=%u", dev, pipe); + return vblank_ctrl_queue_work(priv, pipe, true); } -static void msm_disable_vblank(struct drm_device *dev, int crtc_id) +static void msm_disable_vblank(struct drm_device *dev, unsigned int pipe) { struct msm_drm_private *priv = dev->dev_private; struct msm_kms *kms = priv->kms; if (!kms) return; - DBG("dev=%p, crtc=%d", dev, crtc_id); - vblank_ctrl_queue_work(priv, crtc_id, false); + DBG("dev=%p, crtc=%u", dev, pipe); + vblank_ctrl_queue_work(priv, pipe, false); } /* diff --git a/drivers/gpu/drm/nouveau/nouveau_display.c b/drivers/gpu/drm/nouveau/nouveau_display.c index a82c3cbe3127..886079dd9baa 100644 --- a/drivers/gpu/drm/nouveau/nouveau_display.c +++ b/drivers/gpu/drm/nouveau/nouveau_display.c @@ -51,12 +51,12 @@ nouveau_display_vblank_handler(struct nvif_notify *notify) } int -nouveau_display_vblank_enable(struct drm_device *dev, int head) +nouveau_display_vblank_enable(struct drm_device *dev, unsigned int pipe) { struct drm_crtc *crtc; list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) { struct nouveau_crtc *nv_crtc = nouveau_crtc(crtc); - if (nv_crtc->index == head) { + if (nv_crtc->index == pipe) { nvif_notify_get(&nv_crtc->vblank); return 0; } @@ -65,12 +65,12 @@ nouveau_display_vblank_enable(struct drm_device *dev, int head) } void -nouveau_display_vblank_disable(struct drm_device *dev, int head) +nouveau_display_vblank_disable(struct drm_device *dev, unsigned int pipe) { struct drm_crtc *crtc; list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) { struct nouveau_crtc *nv_crtc = nouveau_crtc(crtc); - if (nv_crtc->index == head) { + if (nv_crtc->index == pipe) { nvif_notify_put(&nv_crtc->vblank); return; } @@ -132,14 +132,15 @@ nouveau_display_scanoutpos_head(struct drm_crtc *crtc, int *vpos, int *hpos, } int -nouveau_display_scanoutpos(struct drm_device *dev, int head, unsigned int flags, - int *vpos, int *hpos, ktime_t *stime, ktime_t *etime, +nouveau_display_scanoutpos(struct drm_device *dev, unsigned int pipe, + unsigned int flags, int *vpos, int *hpos, + ktime_t *stime, ktime_t *etime, const struct drm_display_mode *mode) { struct drm_crtc *crtc; list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) { - if (nouveau_crtc(crtc)->index == head) { + if (nouveau_crtc(crtc)->index == pipe) { return nouveau_display_scanoutpos_head(crtc, vpos, hpos, stime, etime); } @@ -149,15 +150,15 @@ nouveau_display_scanoutpos(struct drm_device *dev, int head, unsigned int flags, } int -nouveau_display_vblstamp(struct drm_device *dev, int head, int *max_error, - struct timeval *time, unsigned flags) +nouveau_display_vblstamp(struct drm_device *dev, unsigned int pipe, + 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) { + if (nouveau_crtc(crtc)->index == pipe) { return drm_calc_vbltimestamp_from_scanoutpos(dev, - head, max_error, time, flags, + pipe, max_error, time, flags, &crtc->hwmode); } } diff --git a/drivers/gpu/drm/nouveau/nouveau_display.h b/drivers/gpu/drm/nouveau/nouveau_display.h index 4182d21538c5..856abe0f070d 100644 --- a/drivers/gpu/drm/nouveau/nouveau_display.h +++ b/drivers/gpu/drm/nouveau/nouveau_display.h @@ -65,12 +65,12 @@ int nouveau_display_init(struct drm_device *dev); void nouveau_display_fini(struct drm_device *dev); int nouveau_display_suspend(struct drm_device *dev, bool runtime); void nouveau_display_resume(struct drm_device *dev, bool runtime); -int nouveau_display_vblank_enable(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 *, - const struct drm_display_mode *); -int nouveau_display_vblstamp(struct drm_device *, int, int *, +int nouveau_display_vblank_enable(struct drm_device *, unsigned int); +void nouveau_display_vblank_disable(struct drm_device *, unsigned int); +int nouveau_display_scanoutpos(struct drm_device *, unsigned int, + unsigned int, int *, int *, ktime_t *, + ktime_t *, const struct drm_display_mode *); +int nouveau_display_vblstamp(struct drm_device *, unsigned int, int *, struct timeval *, unsigned); int nouveau_crtc_page_flip(struct drm_crtc *crtc, struct drm_framebuffer *fb, diff --git a/drivers/gpu/drm/omapdrm/omap_drv.h b/drivers/gpu/drm/omapdrm/omap_drv.h index 12081e61d45a..5c367aad8a6e 100644 --- a/drivers/gpu/drm/omapdrm/omap_drv.h +++ b/drivers/gpu/drm/omapdrm/omap_drv.h @@ -129,8 +129,8 @@ void omap_gem_describe_objects(struct list_head *list, struct seq_file *m); int omap_gem_resume(struct device *dev); #endif -int omap_irq_enable_vblank(struct drm_device *dev, int crtc_id); -void omap_irq_disable_vblank(struct drm_device *dev, int crtc_id); +int omap_irq_enable_vblank(struct drm_device *dev, unsigned int pipe); +void omap_irq_disable_vblank(struct drm_device *dev, unsigned int pipe); void __omap_irq_register(struct drm_device *dev, struct omap_drm_irq *irq); void __omap_irq_unregister(struct drm_device *dev, struct omap_drm_irq *irq); void omap_irq_register(struct drm_device *dev, struct omap_drm_irq *irq); diff --git a/drivers/gpu/drm/omapdrm/omap_irq.c b/drivers/gpu/drm/omapdrm/omap_irq.c index 249c0330d6ce..60e1e8016708 100644 --- a/drivers/gpu/drm/omapdrm/omap_irq.c +++ b/drivers/gpu/drm/omapdrm/omap_irq.c @@ -134,7 +134,7 @@ int omap_irq_wait(struct drm_device *dev, struct omap_irq_wait *wait, /** * enable_vblank - enable vblank interrupt events * @dev: DRM device - * @crtc: which irq to enable + * @pipe: which irq to enable * * Enable vblank interrupts for @crtc. If the device doesn't have * a hardware vblank counter, this routine should be a no-op, since @@ -144,13 +144,13 @@ int omap_irq_wait(struct drm_device *dev, struct omap_irq_wait *wait, * Zero on success, appropriate errno if the given @crtc's vblank * interrupt cannot be enabled. */ -int omap_irq_enable_vblank(struct drm_device *dev, int crtc_id) +int omap_irq_enable_vblank(struct drm_device *dev, unsigned int pipe) { struct omap_drm_private *priv = dev->dev_private; - struct drm_crtc *crtc = priv->crtcs[crtc_id]; + struct drm_crtc *crtc = priv->crtcs[pipe]; unsigned long flags; - DBG("dev=%p, crtc=%d", dev, crtc_id); + DBG("dev=%p, crtc=%u", dev, pipe); spin_lock_irqsave(&list_lock, flags); priv->vblank_mask |= pipe2vbl(crtc); @@ -163,19 +163,19 @@ int omap_irq_enable_vblank(struct drm_device *dev, int crtc_id) /** * disable_vblank - disable vblank interrupt events * @dev: DRM device - * @crtc: which irq to enable + * @pipe: which irq to enable * * Disable vblank interrupts for @crtc. If the device doesn't have * a hardware vblank counter, this routine should be a no-op, since * interrupts will have to stay on to keep the count accurate. */ -void omap_irq_disable_vblank(struct drm_device *dev, int crtc_id) +void omap_irq_disable_vblank(struct drm_device *dev, unsigned int pipe) { struct omap_drm_private *priv = dev->dev_private; - struct drm_crtc *crtc = priv->crtcs[crtc_id]; + struct drm_crtc *crtc = priv->crtcs[pipe]; unsigned long flags; - DBG("dev=%p, crtc=%d", dev, crtc_id); + DBG("dev=%p, crtc=%u", dev, pipe); spin_lock_irqsave(&list_lock, flags); priv->vblank_mask &= ~pipe2vbl(crtc); diff --git a/drivers/gpu/drm/qxl/qxl_drv.c b/drivers/gpu/drm/qxl/qxl_drv.c index 83f6f0b5e9ef..7307b07fe06b 100644 --- a/drivers/gpu/drm/qxl/qxl_drv.c +++ b/drivers/gpu/drm/qxl/qxl_drv.c @@ -196,17 +196,18 @@ static int qxl_pm_restore(struct device *dev) return qxl_drm_resume(drm_dev, false); } -static u32 qxl_noop_get_vblank_counter(struct drm_device *dev, int crtc) +static u32 qxl_noop_get_vblank_counter(struct drm_device *dev, + unsigned int pipe) { return 0; } -static int qxl_noop_enable_vblank(struct drm_device *dev, int crtc) +static int qxl_noop_enable_vblank(struct drm_device *dev, unsigned int pipe) { return 0; } -static void qxl_noop_disable_vblank(struct drm_device *dev, int crtc) +static void qxl_noop_disable_vblank(struct drm_device *dev, unsigned int pipe) { } diff --git a/drivers/gpu/drm/r128/r128_drv.h b/drivers/gpu/drm/r128/r128_drv.h index 723e5d6f10a4..09143b840482 100644 --- a/drivers/gpu/drm/r128/r128_drv.h +++ b/drivers/gpu/drm/r128/r128_drv.h @@ -154,9 +154,9 @@ extern int r128_wait_ring(drm_r128_private_t *dev_priv, int n); extern int r128_do_cce_idle(drm_r128_private_t *dev_priv); extern int r128_do_cleanup_cce(struct drm_device *dev); -extern int r128_enable_vblank(struct drm_device *dev, int crtc); -extern void r128_disable_vblank(struct drm_device *dev, int crtc); -extern u32 r128_get_vblank_counter(struct drm_device *dev, int crtc); +extern int r128_enable_vblank(struct drm_device *dev, unsigned int pipe); +extern void r128_disable_vblank(struct drm_device *dev, unsigned int pipe); +extern u32 r128_get_vblank_counter(struct drm_device *dev, unsigned int pipe); extern irqreturn_t r128_driver_irq_handler(int irq, void *arg); extern void r128_driver_irq_preinstall(struct drm_device *dev); extern int r128_driver_irq_postinstall(struct drm_device *dev); diff --git a/drivers/gpu/drm/r128/r128_irq.c b/drivers/gpu/drm/r128/r128_irq.c index c2ae496babb7..9730f4918944 100644 --- a/drivers/gpu/drm/r128/r128_irq.c +++ b/drivers/gpu/drm/r128/r128_irq.c @@ -34,11 +34,11 @@ #include #include "r128_drv.h" -u32 r128_get_vblank_counter(struct drm_device *dev, int crtc) +u32 r128_get_vblank_counter(struct drm_device *dev, unsigned int pipe) { const drm_r128_private_t *dev_priv = dev->dev_private; - if (crtc != 0) + if (pipe != 0) return 0; return atomic_read(&dev_priv->vbl_received); @@ -62,12 +62,12 @@ irqreturn_t r128_driver_irq_handler(int irq, void *arg) return IRQ_NONE; } -int r128_enable_vblank(struct drm_device *dev, int crtc) +int r128_enable_vblank(struct drm_device *dev, unsigned int pipe) { drm_r128_private_t *dev_priv = dev->dev_private; - if (crtc != 0) { - DRM_ERROR("%s: bad crtc %d\n", __func__, crtc); + if (pipe != 0) { + DRM_ERROR("%s: bad crtc %u\n", __func__, pipe); return -EINVAL; } @@ -75,10 +75,10 @@ int r128_enable_vblank(struct drm_device *dev, int crtc) return 0; } -void r128_disable_vblank(struct drm_device *dev, int crtc) +void r128_disable_vblank(struct drm_device *dev, unsigned int pipe) { - if (crtc != 0) - DRM_ERROR("%s: bad crtc %d\n", __func__, crtc); + if (pipe != 0) + DRM_ERROR("%s: bad crtc %u\n", __func__, pipe); /* * FIXME: implement proper interrupt disable by using the vblank diff --git a/drivers/gpu/drm/radeon/radeon_display.c b/drivers/gpu/drm/radeon/radeon_display.c index 0503af748d99..a58635c5db3d 100644 --- a/drivers/gpu/drm/radeon/radeon_display.c +++ b/drivers/gpu/drm/radeon/radeon_display.c @@ -1799,8 +1799,9 @@ bool radeon_crtc_scaling_mode_fixup(struct drm_crtc *crtc, * unknown small number of scanlines wrt. real scanout position. * */ -int radeon_get_crtc_scanoutpos(struct drm_device *dev, int crtc, unsigned int flags, - int *vpos, int *hpos, ktime_t *stime, ktime_t *etime, +int radeon_get_crtc_scanoutpos(struct drm_device *dev, unsigned int pipe, + unsigned int flags, int *vpos, int *hpos, + ktime_t *stime, ktime_t *etime, const struct drm_display_mode *mode) { u32 stat_crtc = 0, vbl = 0, position = 0; @@ -1816,42 +1817,42 @@ int radeon_get_crtc_scanoutpos(struct drm_device *dev, int crtc, unsigned int fl *stime = ktime_get(); if (ASIC_IS_DCE4(rdev)) { - if (crtc == 0) { + if (pipe == 0) { vbl = RREG32(EVERGREEN_CRTC_V_BLANK_START_END + EVERGREEN_CRTC0_REGISTER_OFFSET); position = RREG32(EVERGREEN_CRTC_STATUS_POSITION + EVERGREEN_CRTC0_REGISTER_OFFSET); ret |= DRM_SCANOUTPOS_VALID; } - if (crtc == 1) { + if (pipe == 1) { vbl = RREG32(EVERGREEN_CRTC_V_BLANK_START_END + EVERGREEN_CRTC1_REGISTER_OFFSET); position = RREG32(EVERGREEN_CRTC_STATUS_POSITION + EVERGREEN_CRTC1_REGISTER_OFFSET); ret |= DRM_SCANOUTPOS_VALID; } - if (crtc == 2) { + if (pipe == 2) { vbl = RREG32(EVERGREEN_CRTC_V_BLANK_START_END + EVERGREEN_CRTC2_REGISTER_OFFSET); position = RREG32(EVERGREEN_CRTC_STATUS_POSITION + EVERGREEN_CRTC2_REGISTER_OFFSET); ret |= DRM_SCANOUTPOS_VALID; } - if (crtc == 3) { + if (pipe == 3) { vbl = RREG32(EVERGREEN_CRTC_V_BLANK_START_END + EVERGREEN_CRTC3_REGISTER_OFFSET); position = RREG32(EVERGREEN_CRTC_STATUS_POSITION + EVERGREEN_CRTC3_REGISTER_OFFSET); ret |= DRM_SCANOUTPOS_VALID; } - if (crtc == 4) { + if (pipe == 4) { vbl = RREG32(EVERGREEN_CRTC_V_BLANK_START_END + EVERGREEN_CRTC4_REGISTER_OFFSET); position = RREG32(EVERGREEN_CRTC_STATUS_POSITION + EVERGREEN_CRTC4_REGISTER_OFFSET); ret |= DRM_SCANOUTPOS_VALID; } - if (crtc == 5) { + if (pipe == 5) { vbl = RREG32(EVERGREEN_CRTC_V_BLANK_START_END + EVERGREEN_CRTC5_REGISTER_OFFSET); position = RREG32(EVERGREEN_CRTC_STATUS_POSITION + @@ -1859,19 +1860,19 @@ int radeon_get_crtc_scanoutpos(struct drm_device *dev, int crtc, unsigned int fl ret |= DRM_SCANOUTPOS_VALID; } } else if (ASIC_IS_AVIVO(rdev)) { - if (crtc == 0) { + if (pipe == 0) { vbl = RREG32(AVIVO_D1CRTC_V_BLANK_START_END); position = RREG32(AVIVO_D1CRTC_STATUS_POSITION); ret |= DRM_SCANOUTPOS_VALID; } - if (crtc == 1) { + if (pipe == 1) { vbl = RREG32(AVIVO_D2CRTC_V_BLANK_START_END); position = RREG32(AVIVO_D2CRTC_STATUS_POSITION); ret |= DRM_SCANOUTPOS_VALID; } } else { /* Pre-AVIVO: Different encoding of scanout pos and vblank interval. */ - if (crtc == 0) { + if (pipe == 0) { /* Assume vbl_end == 0, get vbl_start from * upper 16 bits. */ @@ -1885,7 +1886,7 @@ int radeon_get_crtc_scanoutpos(struct drm_device *dev, int crtc, unsigned int fl ret |= DRM_SCANOUTPOS_VALID; } - if (crtc == 1) { + if (pipe == 1) { vbl = (RREG32(RADEON_CRTC2_V_TOTAL_DISP) & RADEON_CRTC_V_DISP) >> RADEON_CRTC_V_DISP_SHIFT; position = (RREG32(RADEON_CRTC2_VLINE_CRNT_VLINE) >> 16) & RADEON_CRTC_V_TOTAL; diff --git a/drivers/gpu/drm/radeon/radeon_drv.c b/drivers/gpu/drm/radeon/radeon_drv.c index e30c1d73b4ca..5b6a6f5b3619 100644 --- a/drivers/gpu/drm/radeon/radeon_drv.c +++ b/drivers/gpu/drm/radeon/radeon_drv.c @@ -105,10 +105,10 @@ void radeon_driver_preclose_kms(struct drm_device *dev, struct drm_file *file_priv); int radeon_suspend_kms(struct drm_device *dev, bool suspend, bool fbcon); int radeon_resume_kms(struct drm_device *dev, bool resume, bool fbcon); -u32 radeon_get_vblank_counter_kms(struct drm_device *dev, int crtc); -int radeon_enable_vblank_kms(struct drm_device *dev, int crtc); -void radeon_disable_vblank_kms(struct drm_device *dev, int crtc); -int radeon_get_vblank_timestamp_kms(struct drm_device *dev, int crtc, +u32 radeon_get_vblank_counter_kms(struct drm_device *dev, unsigned int pipe); +int radeon_enable_vblank_kms(struct drm_device *dev, unsigned int pipe); +void radeon_disable_vblank_kms(struct drm_device *dev, unsigned int pipe); +int radeon_get_vblank_timestamp_kms(struct drm_device *dev, unsigned int pipe, int *max_error, struct timeval *vblank_time, unsigned flags); @@ -124,9 +124,8 @@ void radeon_gem_object_close(struct drm_gem_object *obj, struct dma_buf *radeon_gem_prime_export(struct drm_device *dev, struct drm_gem_object *gobj, int flags); -extern int radeon_get_crtc_scanoutpos(struct drm_device *dev, int crtc, - unsigned int flags, - int *vpos, int *hpos, +extern int radeon_get_crtc_scanoutpos(struct drm_device *dev, unsigned int crtc, + unsigned int flags, int *vpos, int *hpos, ktime_t *stime, ktime_t *etime, const struct drm_display_mode *mode); extern bool radeon_is_px(struct drm_device *dev); diff --git a/drivers/gpu/drm/radeon/radeon_drv.h b/drivers/gpu/drm/radeon/radeon_drv.h index 46bd3938282c..0caafc7a6e17 100644 --- a/drivers/gpu/drm/radeon/radeon_drv.h +++ b/drivers/gpu/drm/radeon/radeon_drv.h @@ -404,9 +404,9 @@ extern int radeon_irq_emit(struct drm_device *dev, void *data, struct drm_file * extern int radeon_irq_wait(struct drm_device *dev, void *data, struct drm_file *file_priv); extern void radeon_do_release(struct drm_device * dev); -extern u32 radeon_get_vblank_counter(struct drm_device *dev, int crtc); -extern int radeon_enable_vblank(struct drm_device *dev, int crtc); -extern void radeon_disable_vblank(struct drm_device *dev, int crtc); +extern u32 radeon_get_vblank_counter(struct drm_device *dev, unsigned int pipe); +extern int radeon_enable_vblank(struct drm_device *dev, unsigned int pipe); +extern void radeon_disable_vblank(struct drm_device *dev, unsigned int pipe); extern irqreturn_t radeon_driver_irq_handler(int irq, void *arg); extern void radeon_driver_irq_preinstall(struct drm_device * dev); extern int radeon_driver_irq_postinstall(struct drm_device *dev); diff --git a/drivers/gpu/drm/radeon/radeon_irq.c b/drivers/gpu/drm/radeon/radeon_irq.c index 244b19bab2e7..688afb62f7c4 100644 --- a/drivers/gpu/drm/radeon/radeon_irq.c +++ b/drivers/gpu/drm/radeon/radeon_irq.c @@ -62,12 +62,12 @@ static void r500_vbl_irq_set_state(struct drm_device *dev, u32 mask, int state) RADEON_WRITE(R500_DxMODE_INT_MASK, dev_priv->r500_disp_irq_reg); } -int radeon_enable_vblank(struct drm_device *dev, int crtc) +int radeon_enable_vblank(struct drm_device *dev, unsigned int pipe) { drm_radeon_private_t *dev_priv = dev->dev_private; if ((dev_priv->flags & RADEON_FAMILY_MASK) >= CHIP_RS600) { - switch (crtc) { + switch (pipe) { case 0: r500_vbl_irq_set_state(dev, R500_D1MODE_INT_MASK, 1); break; @@ -75,12 +75,12 @@ int radeon_enable_vblank(struct drm_device *dev, int crtc) r500_vbl_irq_set_state(dev, R500_D2MODE_INT_MASK, 1); break; default: - DRM_ERROR("tried to enable vblank on non-existent crtc %d\n", - crtc); + DRM_ERROR("tried to enable vblank on non-existent crtc %u\n", + pipe); return -EINVAL; } } else { - switch (crtc) { + switch (pipe) { case 0: radeon_irq_set_state(dev, RADEON_CRTC_VBLANK_MASK, 1); break; @@ -88,8 +88,8 @@ int radeon_enable_vblank(struct drm_device *dev, int crtc) radeon_irq_set_state(dev, RADEON_CRTC2_VBLANK_MASK, 1); break; default: - DRM_ERROR("tried to enable vblank on non-existent crtc %d\n", - crtc); + DRM_ERROR("tried to enable vblank on non-existent crtc %u\n", + pipe); return -EINVAL; } } @@ -97,12 +97,12 @@ int radeon_enable_vblank(struct drm_device *dev, int crtc) return 0; } -void radeon_disable_vblank(struct drm_device *dev, int crtc) +void radeon_disable_vblank(struct drm_device *dev, unsigned int pipe) { drm_radeon_private_t *dev_priv = dev->dev_private; if ((dev_priv->flags & RADEON_FAMILY_MASK) >= CHIP_RS600) { - switch (crtc) { + switch (pipe) { case 0: r500_vbl_irq_set_state(dev, R500_D1MODE_INT_MASK, 0); break; @@ -110,12 +110,12 @@ void radeon_disable_vblank(struct drm_device *dev, int crtc) r500_vbl_irq_set_state(dev, R500_D2MODE_INT_MASK, 0); break; default: - DRM_ERROR("tried to enable vblank on non-existent crtc %d\n", - crtc); + DRM_ERROR("tried to enable vblank on non-existent crtc %u\n", + pipe); break; } } else { - switch (crtc) { + switch (pipe) { case 0: radeon_irq_set_state(dev, RADEON_CRTC_VBLANK_MASK, 0); break; @@ -123,8 +123,8 @@ void radeon_disable_vblank(struct drm_device *dev, int crtc) radeon_irq_set_state(dev, RADEON_CRTC2_VBLANK_MASK, 0); break; default: - DRM_ERROR("tried to enable vblank on non-existent crtc %d\n", - crtc); + DRM_ERROR("tried to enable vblank on non-existent crtc %u\n", + pipe); break; } } @@ -255,7 +255,7 @@ static int radeon_wait_irq(struct drm_device * dev, int swi_nr) return ret; } -u32 radeon_get_vblank_counter(struct drm_device *dev, int crtc) +u32 radeon_get_vblank_counter(struct drm_device *dev, unsigned int pipe) { drm_radeon_private_t *dev_priv = dev->dev_private; @@ -264,18 +264,18 @@ u32 radeon_get_vblank_counter(struct drm_device *dev, int crtc) return -EINVAL; } - if (crtc < 0 || crtc > 1) { - DRM_ERROR("Invalid crtc %d\n", crtc); + if (pipe > 1) { + DRM_ERROR("Invalid crtc %u\n", pipe); return -EINVAL; } if ((dev_priv->flags & RADEON_FAMILY_MASK) >= CHIP_RS600) { - if (crtc == 0) + if (pipe == 0) return RADEON_READ(R500_D1CRTC_FRAME_COUNT); else return RADEON_READ(R500_D2CRTC_FRAME_COUNT); } else { - if (crtc == 0) + if (pipe == 0) return RADEON_READ(RADEON_CRTC_CRNT_FRAME); else return RADEON_READ(RADEON_CRTC2_CRNT_FRAME); diff --git a/drivers/gpu/drm/radeon/radeon_mode.h b/drivers/gpu/drm/radeon/radeon_mode.h index 2317d04f8a09..de18f0668bea 100644 --- a/drivers/gpu/drm/radeon/radeon_mode.h +++ b/drivers/gpu/drm/radeon/radeon_mode.h @@ -874,9 +874,8 @@ extern int radeon_crtc_cursor_move(struct drm_crtc *crtc, int x, int y); extern void radeon_cursor_reset(struct drm_crtc *crtc); -extern int radeon_get_crtc_scanoutpos(struct drm_device *dev, int crtc, - unsigned int flags, - int *vpos, int *hpos, +extern int radeon_get_crtc_scanoutpos(struct drm_device *dev, unsigned int pipe, + unsigned int flags, int *vpos, int *hpos, ktime_t *stime, ktime_t *etime, const struct drm_display_mode *mode); diff --git a/drivers/gpu/drm/rcar-du/rcar_du_drv.c b/drivers/gpu/drm/rcar-du/rcar_du_drv.c index 780ca11512ba..bb806c4c2e65 100644 --- a/drivers/gpu/drm/rcar-du/rcar_du_drv.c +++ b/drivers/gpu/drm/rcar-du/rcar_du_drv.c @@ -221,20 +221,20 @@ static void rcar_du_lastclose(struct drm_device *dev) drm_fbdev_cma_restore_mode(rcdu->fbdev); } -static int rcar_du_enable_vblank(struct drm_device *dev, int crtc) +static int rcar_du_enable_vblank(struct drm_device *dev, unsigned int pipe) { struct rcar_du_device *rcdu = dev->dev_private; - rcar_du_crtc_enable_vblank(&rcdu->crtcs[crtc], true); + rcar_du_crtc_enable_vblank(&rcdu->crtcs[pipe], true); return 0; } -static void rcar_du_disable_vblank(struct drm_device *dev, int crtc) +static void rcar_du_disable_vblank(struct drm_device *dev, unsigned int pipe) { struct rcar_du_device *rcdu = dev->dev_private; - rcar_du_crtc_enable_vblank(&rcdu->crtcs[crtc], false); + rcar_du_crtc_enable_vblank(&rcdu->crtcs[pipe], false); } static const struct file_operations rcar_du_fops = { diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_drv.c b/drivers/gpu/drm/rockchip/rockchip_drm_drv.c index 9a0c2911272a..32c6098a99d1 100644 --- a/drivers/gpu/drm/rockchip/rockchip_drm_drv.c +++ b/drivers/gpu/drm/rockchip/rockchip_drm_drv.c @@ -103,7 +103,8 @@ static struct drm_crtc *rockchip_crtc_from_pipe(struct drm_device *drm, return NULL; } -static int rockchip_drm_crtc_enable_vblank(struct drm_device *dev, int pipe) +static int rockchip_drm_crtc_enable_vblank(struct drm_device *dev, + unsigned int pipe) { struct rockchip_drm_private *priv = dev->dev_private; struct drm_crtc *crtc = rockchip_crtc_from_pipe(dev, pipe); @@ -115,7 +116,8 @@ static int rockchip_drm_crtc_enable_vblank(struct drm_device *dev, int pipe) return 0; } -static void rockchip_drm_crtc_disable_vblank(struct drm_device *dev, int pipe) +static void rockchip_drm_crtc_disable_vblank(struct drm_device *dev, + unsigned int pipe) { struct rockchip_drm_private *priv = dev->dev_private; struct drm_crtc *crtc = rockchip_crtc_from_pipe(dev, pipe); diff --git a/drivers/gpu/drm/shmobile/shmob_drm_drv.c b/drivers/gpu/drm/shmobile/shmob_drm_drv.c index 666321de7b99..ca2f918a6587 100644 --- a/drivers/gpu/drm/shmobile/shmob_drm_drv.c +++ b/drivers/gpu/drm/shmobile/shmob_drm_drv.c @@ -231,7 +231,7 @@ static irqreturn_t shmob_drm_irq(int irq, void *arg) return IRQ_HANDLED; } -static int shmob_drm_enable_vblank(struct drm_device *dev, int crtc) +static int shmob_drm_enable_vblank(struct drm_device *dev, unsigned int pipe) { struct shmob_drm_device *sdev = dev->dev_private; @@ -240,7 +240,7 @@ static int shmob_drm_enable_vblank(struct drm_device *dev, int crtc) return 0; } -static void shmob_drm_disable_vblank(struct drm_device *dev, int crtc) +static void shmob_drm_disable_vblank(struct drm_device *dev, unsigned int pipe) { struct shmob_drm_device *sdev = dev->dev_private; diff --git a/drivers/gpu/drm/sti/sti_crtc.c b/drivers/gpu/drm/sti/sti_crtc.c index 018ffc970e96..493c4a3006ad 100644 --- a/drivers/gpu/drm/sti/sti_crtc.c +++ b/drivers/gpu/drm/sti/sti_crtc.c @@ -299,7 +299,7 @@ int sti_crtc_vblank_cb(struct notifier_block *nb, return 0; } -int sti_crtc_enable_vblank(struct drm_device *dev, int crtc) +int sti_crtc_enable_vblank(struct drm_device *dev, unsigned int pipe) { struct sti_private *dev_priv = dev->dev_private; struct sti_compositor *compo = dev_priv->compo; @@ -307,9 +307,9 @@ int sti_crtc_enable_vblank(struct drm_device *dev, int crtc) DRM_DEBUG_DRIVER("\n"); - if (sti_vtg_register_client(crtc == STI_MIXER_MAIN ? + if (sti_vtg_register_client(pipe == STI_MIXER_MAIN ? compo->vtg_main : compo->vtg_aux, - vtg_vblank_nb, crtc)) { + vtg_vblank_nb, pipe)) { DRM_ERROR("Cannot register VTG notifier\n"); return -EINVAL; } @@ -318,7 +318,7 @@ int sti_crtc_enable_vblank(struct drm_device *dev, int crtc) } EXPORT_SYMBOL(sti_crtc_enable_vblank); -void sti_crtc_disable_vblank(struct drm_device *drm_dev, int crtc) +void sti_crtc_disable_vblank(struct drm_device *drm_dev, unsigned int pipe) { struct sti_private *priv = drm_dev->dev_private; struct sti_compositor *compo = priv->compo; @@ -326,14 +326,14 @@ void sti_crtc_disable_vblank(struct drm_device *drm_dev, int crtc) DRM_DEBUG_DRIVER("\n"); - if (sti_vtg_unregister_client(crtc == STI_MIXER_MAIN ? + if (sti_vtg_unregister_client(pipe == STI_MIXER_MAIN ? compo->vtg_main : compo->vtg_aux, vtg_vblank_nb)) DRM_DEBUG_DRIVER("Warning: cannot unregister VTG notifier\n"); /* free the resources of the pending requests */ - if (compo->mixer[crtc]->pending_event) { - drm_vblank_put(drm_dev, crtc); - compo->mixer[crtc]->pending_event = NULL; + if (compo->mixer[pipe]->pending_event) { + drm_vblank_put(drm_dev, pipe); + compo->mixer[pipe]->pending_event = NULL; } } EXPORT_SYMBOL(sti_crtc_disable_vblank); diff --git a/drivers/gpu/drm/sti/sti_crtc.h b/drivers/gpu/drm/sti/sti_crtc.h index 51963e6ddbe7..3f2d89a3634d 100644 --- a/drivers/gpu/drm/sti/sti_crtc.h +++ b/drivers/gpu/drm/sti/sti_crtc.h @@ -13,8 +13,8 @@ struct sti_mixer; int sti_crtc_init(struct drm_device *drm_dev, struct sti_mixer *mixer, struct drm_plane *primary, struct drm_plane *cursor); -int sti_crtc_enable_vblank(struct drm_device *dev, int crtc); -void sti_crtc_disable_vblank(struct drm_device *dev, int crtc); +int sti_crtc_enable_vblank(struct drm_device *dev, unsigned int pipe); +void sti_crtc_disable_vblank(struct drm_device *dev, unsigned int pipe); int sti_crtc_vblank_cb(struct notifier_block *nb, unsigned long event, void *data); bool sti_crtc_is_main(struct drm_crtc *drm_crtc); diff --git a/drivers/gpu/drm/tegra/drm.c b/drivers/gpu/drm/tegra/drm.c index 2486bc24bff6..759e6af91e59 100644 --- a/drivers/gpu/drm/tegra/drm.c +++ b/drivers/gpu/drm/tegra/drm.c @@ -822,7 +822,8 @@ static struct drm_crtc *tegra_crtc_from_pipe(struct drm_device *drm, return NULL; } -static u32 tegra_drm_get_vblank_counter(struct drm_device *drm, int pipe) +static u32 tegra_drm_get_vblank_counter(struct drm_device *drm, + unsigned int pipe) { struct drm_crtc *crtc = tegra_crtc_from_pipe(drm, pipe); struct tegra_dc *dc = to_tegra_dc(crtc); @@ -833,7 +834,7 @@ static u32 tegra_drm_get_vblank_counter(struct drm_device *drm, int pipe) return tegra_dc_get_vblank_counter(dc); } -static int tegra_drm_enable_vblank(struct drm_device *drm, int pipe) +static int tegra_drm_enable_vblank(struct drm_device *drm, unsigned int pipe) { struct drm_crtc *crtc = tegra_crtc_from_pipe(drm, pipe); struct tegra_dc *dc = to_tegra_dc(crtc); @@ -846,7 +847,7 @@ static int tegra_drm_enable_vblank(struct drm_device *drm, int pipe) return 0; } -static void tegra_drm_disable_vblank(struct drm_device *drm, int pipe) +static void tegra_drm_disable_vblank(struct drm_device *drm, unsigned int pipe) { struct drm_crtc *crtc = tegra_crtc_from_pipe(drm, pipe); struct tegra_dc *dc = to_tegra_dc(crtc); diff --git a/drivers/gpu/drm/tilcdc/tilcdc_drv.c b/drivers/gpu/drm/tilcdc/tilcdc_drv.c index 0f283a3b932c..a5b8f5d39311 100644 --- a/drivers/gpu/drm/tilcdc/tilcdc_drv.c +++ b/drivers/gpu/drm/tilcdc/tilcdc_drv.c @@ -425,13 +425,13 @@ static void enable_vblank(struct drm_device *dev, bool enable) tilcdc_clear(dev, reg, mask); } -static int tilcdc_enable_vblank(struct drm_device *dev, int crtc) +static int tilcdc_enable_vblank(struct drm_device *dev, unsigned int pipe) { enable_vblank(dev, true); return 0; } -static void tilcdc_disable_vblank(struct drm_device *dev, int crtc) +static void tilcdc_disable_vblank(struct drm_device *dev, unsigned int pipe) { enable_vblank(dev, false); } diff --git a/drivers/gpu/drm/via/via_drv.h b/drivers/gpu/drm/via/via_drv.h index ef8c500b4a00..644093f5046c 100644 --- a/drivers/gpu/drm/via/via_drv.h +++ b/drivers/gpu/drm/via/via_drv.h @@ -136,9 +136,9 @@ extern int via_init_context(struct drm_device *dev, int context); extern int via_final_context(struct drm_device *dev, int context); extern int via_do_cleanup_map(struct drm_device *dev); -extern u32 via_get_vblank_counter(struct drm_device *dev, int crtc); -extern int via_enable_vblank(struct drm_device *dev, int crtc); -extern void via_disable_vblank(struct drm_device *dev, int crtc); +extern u32 via_get_vblank_counter(struct drm_device *dev, unsigned int pipe); +extern int via_enable_vblank(struct drm_device *dev, unsigned int pipe); +extern void via_disable_vblank(struct drm_device *dev, unsigned int pipe); extern irqreturn_t via_driver_irq_handler(int irq, void *arg); extern void via_driver_irq_preinstall(struct drm_device *dev); diff --git a/drivers/gpu/drm/via/via_irq.c b/drivers/gpu/drm/via/via_irq.c index 1319433816d3..ea8172c747a2 100644 --- a/drivers/gpu/drm/via/via_irq.c +++ b/drivers/gpu/drm/via/via_irq.c @@ -95,10 +95,11 @@ static unsigned time_diff(struct timeval *now, struct timeval *then) 1000000 - (then->tv_usec - now->tv_usec); } -u32 via_get_vblank_counter(struct drm_device *dev, int crtc) +u32 via_get_vblank_counter(struct drm_device *dev, unsigned int pipe) { drm_via_private_t *dev_priv = dev->dev_private; - if (crtc != 0) + + if (pipe != 0) return 0; return atomic_read(&dev_priv->vbl_received); @@ -170,13 +171,13 @@ static __inline__ void viadrv_acknowledge_irqs(drm_via_private_t *dev_priv) } } -int via_enable_vblank(struct drm_device *dev, int crtc) +int via_enable_vblank(struct drm_device *dev, unsigned int pipe) { drm_via_private_t *dev_priv = dev->dev_private; u32 status; - if (crtc != 0) { - DRM_ERROR("%s: bad crtc %d\n", __func__, crtc); + if (pipe != 0) { + DRM_ERROR("%s: bad crtc %u\n", __func__, pipe); return -EINVAL; } @@ -189,7 +190,7 @@ int via_enable_vblank(struct drm_device *dev, int crtc) return 0; } -void via_disable_vblank(struct drm_device *dev, int crtc) +void via_disable_vblank(struct drm_device *dev, unsigned int pipe) { drm_via_private_t *dev_priv = dev->dev_private; u32 status; @@ -200,8 +201,8 @@ void via_disable_vblank(struct drm_device *dev, int crtc) VIA_WRITE8(0x83d4, 0x11); VIA_WRITE8(0x83d5, VIA_READ8(0x83d5) & ~0x30); - if (crtc != 0) - DRM_ERROR("%s: bad crtc %d\n", __func__, crtc); + if (pipe != 0) + DRM_ERROR("%s: bad crtc %u\n", __func__, pipe); } static int diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_drv.h b/drivers/gpu/drm/vmwgfx/vmwgfx_drv.h index f19fd39b43e1..a613bd4851ba 100644 --- a/drivers/gpu/drm/vmwgfx/vmwgfx_drv.h +++ b/drivers/gpu/drm/vmwgfx/vmwgfx_drv.h @@ -914,9 +914,9 @@ void vmw_kms_idle_workqueues(struct vmw_master *vmaster); bool vmw_kms_validate_mode_vram(struct vmw_private *dev_priv, uint32_t pitch, uint32_t height); -u32 vmw_get_vblank_counter(struct drm_device *dev, int crtc); -int vmw_enable_vblank(struct drm_device *dev, int crtc); -void vmw_disable_vblank(struct drm_device *dev, int crtc); +u32 vmw_get_vblank_counter(struct drm_device *dev, unsigned int pipe); +int vmw_enable_vblank(struct drm_device *dev, unsigned int pipe); +void vmw_disable_vblank(struct drm_device *dev, unsigned int pipe); int vmw_kms_present(struct vmw_private *dev_priv, struct drm_file *file_priv, struct vmw_framebuffer *vfb, diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_kms.c b/drivers/gpu/drm/vmwgfx/vmwgfx_kms.c index 15a6c01cd016..03ffab2a6a9c 100644 --- a/drivers/gpu/drm/vmwgfx/vmwgfx_kms.c +++ b/drivers/gpu/drm/vmwgfx/vmwgfx_kms.c @@ -1263,7 +1263,7 @@ bool vmw_kms_validate_mode_vram(struct vmw_private *dev_priv, /** * Function called by DRM code called with vbl_lock held. */ -u32 vmw_get_vblank_counter(struct drm_device *dev, int crtc) +u32 vmw_get_vblank_counter(struct drm_device *dev, unsigned int pipe) { return 0; } @@ -1271,7 +1271,7 @@ u32 vmw_get_vblank_counter(struct drm_device *dev, int crtc) /** * Function called by DRM code called with vbl_lock held. */ -int vmw_enable_vblank(struct drm_device *dev, int crtc) +int vmw_enable_vblank(struct drm_device *dev, unsigned int pipe) { return -ENOSYS; } @@ -1279,7 +1279,7 @@ int vmw_enable_vblank(struct drm_device *dev, int crtc) /** * Function called by DRM code called with vbl_lock held. */ -void vmw_disable_vblank(struct drm_device *dev, int crtc) +void vmw_disable_vblank(struct drm_device *dev, unsigned int pipe) { } diff --git a/include/drm/drmP.h b/include/drm/drmP.h index 967d8a03c0e1..1cb1e842e64d 100644 --- a/include/drm/drmP.h +++ b/include/drm/drmP.h @@ -412,7 +412,7 @@ struct drm_driver { /** * get_vblank_counter - get raw hardware vblank counter * @dev: DRM device - * @crtc: counter to fetch + * @pipe: counter to fetch * * Driver callback for fetching a raw hardware vblank counter for @crtc. * If a device doesn't have a hardware counter, the driver can simply @@ -426,12 +426,12 @@ struct drm_driver { * RETURNS * Raw vblank counter value. */ - u32 (*get_vblank_counter) (struct drm_device *dev, int crtc); + u32 (*get_vblank_counter) (struct drm_device *dev, unsigned int pipe); /** * enable_vblank - enable vblank interrupt events * @dev: DRM device - * @crtc: which irq to enable + * @pipe: which irq to enable * * Enable vblank interrupts for @crtc. If the device doesn't have * a hardware vblank counter, this routine should be a no-op, since @@ -441,18 +441,18 @@ struct drm_driver { * Zero on success, appropriate errno if the given @crtc's vblank * interrupt cannot be enabled. */ - int (*enable_vblank) (struct drm_device *dev, int crtc); + int (*enable_vblank) (struct drm_device *dev, unsigned int pipe); /** * disable_vblank - disable vblank interrupt events * @dev: DRM device - * @crtc: which irq to enable + * @pipe: which irq to enable * * Disable vblank interrupts for @crtc. If the device doesn't have * a hardware vblank counter, this routine should be a no-op, since * interrupts will have to stay on to keep the count accurate. */ - void (*disable_vblank) (struct drm_device *dev, int crtc); + void (*disable_vblank) (struct drm_device *dev, unsigned int pipe); /** * Called by \c drm_device_is_agp. Typically used to determine if a @@ -474,7 +474,7 @@ struct drm_driver { * optional accurate ktime_get timestamp of when position was measured. * * \param dev DRM device. - * \param crtc Id of the crtc to query. + * \param pipe Id of the crtc to query. * \param flags Flags from the caller (DRM_CALLED_FROM_VBLIRQ or 0). * \param *vpos Target location for current vertical scanout position. * \param *hpos Target location for current horizontal scanout position. @@ -498,9 +498,8 @@ struct drm_driver { * but unknown small number of scanlines wrt. real scanout position. * */ - int (*get_scanout_position) (struct drm_device *dev, int crtc, - unsigned int flags, - int *vpos, int *hpos, + int (*get_scanout_position) (struct drm_device *dev, unsigned int pipe, + unsigned int flags, int *vpos, int *hpos, ktime_t *stime, ktime_t *etime, const struct drm_display_mode *mode); @@ -518,7 +517,7 @@ struct drm_driver { * to the OpenML OML_sync_control extension specification. * * \param dev dev DRM device handle. - * \param crtc crtc for which timestamp should be returned. + * \param pipe crtc for which timestamp should be returned. * \param *max_error Maximum allowable timestamp error in nanoseconds. * Implementation should strive to provide timestamp * with an error of at most *max_error nanoseconds. @@ -534,7 +533,7 @@ struct drm_driver { * negative number on failure. A positive status code on success, * which describes how the vblank_time timestamp was computed. */ - int (*get_vblank_timestamp) (struct drm_device *dev, int crtc, + int (*get_vblank_timestamp) (struct drm_device *dev, unsigned int pipe, int *max_error, struct timeval *vblank_time, unsigned flags); @@ -930,7 +929,7 @@ extern int drm_irq_uninstall(struct drm_device *dev); extern int drm_vblank_init(struct drm_device *dev, unsigned int num_crtcs); extern int drm_wait_vblank(struct drm_device *dev, void *data, struct drm_file *filp); -extern u32 drm_vblank_count(struct drm_device *dev, int pipe); +extern u32 drm_vblank_count(struct drm_device *dev, unsigned int pipe); extern u32 drm_crtc_vblank_count(struct drm_crtc *crtc); extern u32 drm_vblank_count_and_time(struct drm_device *dev, unsigned int pipe, struct timeval *vblanktime); -- cgit v1.2.3 From f6c7aba47bcc0b1cc2085c8d8af80f8c02f28269 Mon Sep 17 00:00:00 2001 From: Michel Dänzer Date: Thu, 8 Oct 2015 17:48:04 +0900 Subject: drm/amdgpu: Keep the pflip interrupts always enabled v7 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This fixes flickering issues caused by prematurely firing pflip interrupts. v2 (chk): add commit message, fix DCE V10/V11 and DM as well v3: Re-enable pflip interrupt wherever we re-enable a CRTC v4: Enable pflip interrupt in DAL as well v5: drop DAL changes for upstream v6: (agd): only enable interrupts on crtcs that exist v7: (agd): integrate suggestions from Michel Signed-off-by: Michel Dänzer Signed-off-by: Christian König Reviewed-by: Alex Deucher Cc: stable@vger.kernel.org --- drivers/gpu/drm/amd/amdgpu/amdgpu_display.c | 2 -- drivers/gpu/drm/amd/amdgpu/dce_v10_0.c | 30 +++++++++++++++++++++++++++-- drivers/gpu/drm/amd/amdgpu/dce_v11_0.c | 30 +++++++++++++++++++++++++++-- drivers/gpu/drm/amd/amdgpu/dce_v8_0.c | 30 +++++++++++++++++++++++++++-- 4 files changed, 84 insertions(+), 8 deletions(-) (limited to 'drivers/gpu/drm/amd/amdgpu/amdgpu_display.c') diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_display.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_display.c index e3d70772b531..dc29ed8145c2 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_display.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_display.c @@ -85,8 +85,6 @@ static void amdgpu_flip_work_func(struct work_struct *__work) /* We borrow the event spin lock for protecting flip_status */ spin_lock_irqsave(&crtc->dev->event_lock, flags); - /* set the proper interrupt */ - amdgpu_irq_get(adev, &adev->pageflip_irq, work->crtc_id); /* do the flip (mmio) */ adev->mode_info.funcs->page_flip(adev, work->crtc_id, work->base); /* set the flip status */ diff --git a/drivers/gpu/drm/amd/amdgpu/dce_v10_0.c b/drivers/gpu/drm/amd/amdgpu/dce_v10_0.c index e4d101b1252a..d4c82b625727 100644 --- a/drivers/gpu/drm/amd/amdgpu/dce_v10_0.c +++ b/drivers/gpu/drm/amd/amdgpu/dce_v10_0.c @@ -255,6 +255,24 @@ static u32 dce_v10_0_vblank_get_counter(struct amdgpu_device *adev, int crtc) return RREG32(mmCRTC_STATUS_FRAME_COUNT + crtc_offsets[crtc]); } +static void dce_v10_0_pageflip_interrupt_init(struct amdgpu_device *adev) +{ + unsigned i; + + /* Enable pflip interrupts */ + for (i = 0; i < adev->mode_info.num_crtc; i++) + amdgpu_irq_get(adev, &adev->pageflip_irq, i); +} + +static void dce_v10_0_pageflip_interrupt_fini(struct amdgpu_device *adev) +{ + unsigned i; + + /* Disable pflip interrupts */ + for (i = 0; i < adev->mode_info.num_crtc; i++) + amdgpu_irq_put(adev, &adev->pageflip_irq, i); +} + /** * dce_v10_0_page_flip - pageflip callback. * @@ -2663,9 +2681,10 @@ static void dce_v10_0_crtc_dpms(struct drm_crtc *crtc, int mode) dce_v10_0_vga_enable(crtc, true); amdgpu_atombios_crtc_blank(crtc, ATOM_DISABLE); dce_v10_0_vga_enable(crtc, false); - /* Make sure VBLANK interrupt is still enabled */ + /* Make sure VBLANK and PFLIP interrupts are still enabled */ type = amdgpu_crtc_idx_to_irq_type(adev, amdgpu_crtc->crtc_id); amdgpu_irq_update(adev, &adev->crtc_irq, type); + amdgpu_irq_update(adev, &adev->pageflip_irq, type); drm_vblank_post_modeset(dev, amdgpu_crtc->crtc_id); dce_v10_0_crtc_load_lut(crtc); break; @@ -3025,6 +3044,8 @@ static int dce_v10_0_hw_init(void *handle) dce_v10_0_audio_enable(adev, &adev->mode_info.audio.pin[i], false); } + dce_v10_0_pageflip_interrupt_init(adev); + return 0; } @@ -3039,6 +3060,8 @@ static int dce_v10_0_hw_fini(void *handle) dce_v10_0_audio_enable(adev, &adev->mode_info.audio.pin[i], false); } + dce_v10_0_pageflip_interrupt_fini(adev); + return 0; } @@ -3050,6 +3073,8 @@ static int dce_v10_0_suspend(void *handle) dce_v10_0_hpd_fini(adev); + dce_v10_0_pageflip_interrupt_fini(adev); + return 0; } @@ -3075,6 +3100,8 @@ static int dce_v10_0_resume(void *handle) /* initialize hpd */ dce_v10_0_hpd_init(adev); + dce_v10_0_pageflip_interrupt_init(adev); + return 0; } @@ -3369,7 +3396,6 @@ static int dce_v10_0_pageflip_irq(struct amdgpu_device *adev, spin_unlock_irqrestore(&adev->ddev->event_lock, flags); drm_vblank_put(adev->ddev, amdgpu_crtc->crtc_id); - amdgpu_irq_put(adev, &adev->pageflip_irq, crtc_id); queue_work(amdgpu_crtc->pflip_queue, &works->unpin_work); return 0; diff --git a/drivers/gpu/drm/amd/amdgpu/dce_v11_0.c b/drivers/gpu/drm/amd/amdgpu/dce_v11_0.c index fcd2ed558902..7e1cf5e4eebf 100644 --- a/drivers/gpu/drm/amd/amdgpu/dce_v11_0.c +++ b/drivers/gpu/drm/amd/amdgpu/dce_v11_0.c @@ -233,6 +233,24 @@ static u32 dce_v11_0_vblank_get_counter(struct amdgpu_device *adev, int crtc) return RREG32(mmCRTC_STATUS_FRAME_COUNT + crtc_offsets[crtc]); } +static void dce_v11_0_pageflip_interrupt_init(struct amdgpu_device *adev) +{ + unsigned i; + + /* Enable pflip interrupts */ + for (i = 0; i < adev->mode_info.num_crtc; i++) + amdgpu_irq_get(adev, &adev->pageflip_irq, i); +} + +static void dce_v11_0_pageflip_interrupt_fini(struct amdgpu_device *adev) +{ + unsigned i; + + /* Disable pflip interrupts */ + for (i = 0; i < adev->mode_info.num_crtc; i++) + amdgpu_irq_put(adev, &adev->pageflip_irq, i); +} + /** * dce_v11_0_page_flip - pageflip callback. * @@ -2640,9 +2658,10 @@ static void dce_v11_0_crtc_dpms(struct drm_crtc *crtc, int mode) dce_v11_0_vga_enable(crtc, true); amdgpu_atombios_crtc_blank(crtc, ATOM_DISABLE); dce_v11_0_vga_enable(crtc, false); - /* Make sure VBLANK interrupt is still enabled */ + /* Make sure VBLANK and PFLIP interrupts are still enabled */ type = amdgpu_crtc_idx_to_irq_type(adev, amdgpu_crtc->crtc_id); amdgpu_irq_update(adev, &adev->crtc_irq, type); + amdgpu_irq_update(adev, &adev->pageflip_irq, type); drm_vblank_post_modeset(dev, amdgpu_crtc->crtc_id); dce_v11_0_crtc_load_lut(crtc); break; @@ -3000,6 +3019,8 @@ static int dce_v11_0_hw_init(void *handle) dce_v11_0_audio_enable(adev, &adev->mode_info.audio.pin[i], false); } + dce_v11_0_pageflip_interrupt_init(adev); + return 0; } @@ -3014,6 +3035,8 @@ static int dce_v11_0_hw_fini(void *handle) dce_v11_0_audio_enable(adev, &adev->mode_info.audio.pin[i], false); } + dce_v11_0_pageflip_interrupt_fini(adev); + return 0; } @@ -3025,6 +3048,8 @@ static int dce_v11_0_suspend(void *handle) dce_v11_0_hpd_fini(adev); + dce_v11_0_pageflip_interrupt_fini(adev); + return 0; } @@ -3051,6 +3076,8 @@ static int dce_v11_0_resume(void *handle) /* initialize hpd */ dce_v11_0_hpd_init(adev); + dce_v11_0_pageflip_interrupt_init(adev); + return 0; } @@ -3345,7 +3372,6 @@ static int dce_v11_0_pageflip_irq(struct amdgpu_device *adev, spin_unlock_irqrestore(&adev->ddev->event_lock, flags); drm_vblank_put(adev->ddev, amdgpu_crtc->crtc_id); - amdgpu_irq_put(adev, &adev->pageflip_irq, crtc_id); queue_work(amdgpu_crtc->pflip_queue, &works->unpin_work); return 0; diff --git a/drivers/gpu/drm/amd/amdgpu/dce_v8_0.c b/drivers/gpu/drm/amd/amdgpu/dce_v8_0.c index c86911c2ea2a..34b9c2a9d8d4 100644 --- a/drivers/gpu/drm/amd/amdgpu/dce_v8_0.c +++ b/drivers/gpu/drm/amd/amdgpu/dce_v8_0.c @@ -204,6 +204,24 @@ static u32 dce_v8_0_vblank_get_counter(struct amdgpu_device *adev, int crtc) return RREG32(mmCRTC_STATUS_FRAME_COUNT + crtc_offsets[crtc]); } +static void dce_v8_0_pageflip_interrupt_init(struct amdgpu_device *adev) +{ + unsigned i; + + /* Enable pflip interrupts */ + for (i = 0; i < adev->mode_info.num_crtc; i++) + amdgpu_irq_get(adev, &adev->pageflip_irq, i); +} + +static void dce_v8_0_pageflip_interrupt_fini(struct amdgpu_device *adev) +{ + unsigned i; + + /* Disable pflip interrupts */ + for (i = 0; i < adev->mode_info.num_crtc; i++) + amdgpu_irq_put(adev, &adev->pageflip_irq, i); +} + /** * dce_v8_0_page_flip - pageflip callback. * @@ -2575,9 +2593,10 @@ static void dce_v8_0_crtc_dpms(struct drm_crtc *crtc, int mode) dce_v8_0_vga_enable(crtc, true); amdgpu_atombios_crtc_blank(crtc, ATOM_DISABLE); dce_v8_0_vga_enable(crtc, false); - /* Make sure VBLANK interrupt is still enabled */ + /* Make sure VBLANK and PFLIP interrupts are still enabled */ type = amdgpu_crtc_idx_to_irq_type(adev, amdgpu_crtc->crtc_id); amdgpu_irq_update(adev, &adev->crtc_irq, type); + amdgpu_irq_update(adev, &adev->pageflip_irq, type); drm_vblank_post_modeset(dev, amdgpu_crtc->crtc_id); dce_v8_0_crtc_load_lut(crtc); break; @@ -2933,6 +2952,8 @@ static int dce_v8_0_hw_init(void *handle) dce_v8_0_audio_enable(adev, &adev->mode_info.audio.pin[i], false); } + dce_v8_0_pageflip_interrupt_init(adev); + return 0; } @@ -2947,6 +2968,8 @@ static int dce_v8_0_hw_fini(void *handle) dce_v8_0_audio_enable(adev, &adev->mode_info.audio.pin[i], false); } + dce_v8_0_pageflip_interrupt_fini(adev); + return 0; } @@ -2958,6 +2981,8 @@ static int dce_v8_0_suspend(void *handle) dce_v8_0_hpd_fini(adev); + dce_v8_0_pageflip_interrupt_fini(adev); + return 0; } @@ -2981,6 +3006,8 @@ static int dce_v8_0_resume(void *handle) /* initialize hpd */ dce_v8_0_hpd_init(adev); + dce_v8_0_pageflip_interrupt_init(adev); + return 0; } @@ -3376,7 +3403,6 @@ static int dce_v8_0_pageflip_irq(struct amdgpu_device *adev, spin_unlock_irqrestore(&adev->ddev->event_lock, flags); drm_vblank_put(adev->ddev, amdgpu_crtc->crtc_id); - amdgpu_irq_put(adev, &adev->pageflip_irq, crtc_id); queue_work(amdgpu_crtc->pflip_queue, &works->unpin_work); return 0; -- cgit v1.2.3 From 0c418f10104d4aa1d6b83698790898dc9ef1c12d Mon Sep 17 00:00:00 2001 From: Christian König Date: Tue, 1 Sep 2015 15:13:53 +0200 Subject: drm/amdgpu: remove the exclusive lock MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Finally getting rid of it. Signed-off-by: Christian König --- drivers/gpu/drm/amd/amdgpu/amdgpu.h | 1 - drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c | 10 ++-------- drivers/gpu/drm/amd/amdgpu/amdgpu_device.c | 4 ---- drivers/gpu/drm/amd/amdgpu/amdgpu_display.c | 7 +------ drivers/gpu/drm/amd/amdgpu/amdgpu_fence.c | 21 +++++---------------- drivers/gpu/drm/amd/amdgpu/amdgpu_gem.c | 7 ------- 6 files changed, 8 insertions(+), 42 deletions(-) (limited to 'drivers/gpu/drm/amd/amdgpu/amdgpu_display.c') diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu.h b/drivers/gpu/drm/amd/amdgpu/amdgpu.h index 911d67032d57..39d96088f7b4 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu.h +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu.h @@ -1955,7 +1955,6 @@ struct amdgpu_device { struct device *dev; struct drm_device *ddev; struct pci_dev *pdev; - struct rw_semaphore exclusive_lock; /* ASIC */ enum amd_asic_type asic_type; diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c index 25012c790f8f..5fdc0394561e 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c @@ -831,11 +831,8 @@ int amdgpu_cs_ioctl(struct drm_device *dev, void *data, struct drm_file *filp) bool reserved_buffers = false; int i, r; - down_read(&adev->exclusive_lock); - if (!adev->accel_working) { - up_read(&adev->exclusive_lock); + if (!adev->accel_working) return -EBUSY; - } parser = amdgpu_cs_parser_create(adev, filp, NULL, NULL, 0); if (!parser) @@ -843,8 +840,7 @@ int amdgpu_cs_ioctl(struct drm_device *dev, void *data, struct drm_file *filp) r = amdgpu_cs_parser_init(parser, data); if (r) { DRM_ERROR("Failed to initialize parser !\n"); - kfree(parser); - up_read(&adev->exclusive_lock); + amdgpu_cs_parser_fini(parser, r, false); r = amdgpu_cs_handle_lockup(adev, r); return r; } @@ -915,14 +911,12 @@ int amdgpu_cs_ioctl(struct drm_device *dev, void *data, struct drm_file *filp) mutex_unlock(&job->job_lock); amdgpu_cs_parser_fini_late(parser); - up_read(&adev->exclusive_lock); return 0; } cs->out.handle = parser->ibs[parser->num_ibs - 1].sequence; out: amdgpu_cs_parser_fini(parser, r, reserved_buffers); - up_read(&adev->exclusive_lock); r = amdgpu_cs_handle_lockup(adev, r); return r; } diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c index 28c9ee334dd7..19e185ec3707 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c @@ -1418,7 +1418,6 @@ int amdgpu_device_init(struct amdgpu_device *adev, mutex_init(&adev->gfx.gpu_clock_mutex); mutex_init(&adev->srbm_mutex); mutex_init(&adev->grbm_idx_mutex); - init_rwsem(&adev->exclusive_lock); mutex_init(&adev->mn_lock); hash_init(adev->mn_hash); @@ -1814,8 +1813,6 @@ int amdgpu_gpu_reset(struct amdgpu_device *adev) int i, r; int resched; - down_write(&adev->exclusive_lock); - atomic_inc(&adev->gpu_reset_counter); /* block TTM */ @@ -1879,7 +1876,6 @@ retry: dev_info(adev->dev, "GPU reset failed\n"); } - up_write(&adev->exclusive_lock); return r; } diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_display.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_display.c index 9b34a3410c32..fdf7525cf120 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_display.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_display.c @@ -47,11 +47,8 @@ static void amdgpu_flip_wait_fence(struct amdgpu_device *adev, fence = to_amdgpu_fence(*f); if (fence) { r = fence_wait(&fence->base, false); - if (r == -EDEADLK) { - up_read(&adev->exclusive_lock); + if (r == -EDEADLK) r = amdgpu_gpu_reset(adev); - down_read(&adev->exclusive_lock); - } } else r = fence_wait(*f, false); @@ -77,7 +74,6 @@ static void amdgpu_flip_work_func(struct work_struct *__work) unsigned long flags; unsigned i; - down_read(&adev->exclusive_lock); amdgpu_flip_wait_fence(adev, &work->excl); for (i = 0; i < work->shared_count; ++i) amdgpu_flip_wait_fence(adev, &work->shared[i]); @@ -93,7 +89,6 @@ static void amdgpu_flip_work_func(struct work_struct *__work) amdgpuCrtc->pflip_status = AMDGPU_FLIP_SUBMITTED; spin_unlock_irqrestore(&crtc->dev->event_lock, flags); - up_read(&adev->exclusive_lock); } /* diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_fence.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_fence.c index 4010aa6b4e53..1fadc15e64ae 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_fence.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_fence.c @@ -260,16 +260,8 @@ static void amdgpu_fence_check_lockup(struct work_struct *work) lockup_work.work); ring = fence_drv->ring; - if (!down_read_trylock(&ring->adev->exclusive_lock)) { - /* just reschedule the check if a reset is going on */ - amdgpu_fence_schedule_check(ring); - return; - } - - if (amdgpu_fence_activity(ring)) { + if (amdgpu_fence_activity(ring)) wake_up_all(&ring->fence_drv.fence_queue); - } - up_read(&ring->adev->exclusive_lock); } /** @@ -317,18 +309,15 @@ static bool amdgpu_fence_is_signaled(struct fence *f) { struct amdgpu_fence *fence = to_amdgpu_fence(f); struct amdgpu_ring *ring = fence->ring; - struct amdgpu_device *adev = ring->adev; if (atomic64_read(&ring->fence_drv.last_seq) >= fence->seq) return true; - if (down_read_trylock(&adev->exclusive_lock)) { - amdgpu_fence_process(ring); - up_read(&adev->exclusive_lock); + amdgpu_fence_process(ring); + + if (atomic64_read(&ring->fence_drv.last_seq) >= fence->seq) + return true; - if (atomic64_read(&ring->fence_drv.last_seq) >= fence->seq) - return true; - } return false; } diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_gem.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_gem.c index 7297ca3a0ba7..d81ab785368a 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_gem.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_gem.c @@ -181,7 +181,6 @@ int amdgpu_gem_create_ioctl(struct drm_device *dev, void *data, bool kernel = false; int r; - down_read(&adev->exclusive_lock); /* create a gem object to contain this object in */ if (args->in.domains & (AMDGPU_GEM_DOMAIN_GDS | AMDGPU_GEM_DOMAIN_GWS | AMDGPU_GEM_DOMAIN_OA)) { @@ -214,11 +213,9 @@ int amdgpu_gem_create_ioctl(struct drm_device *dev, void *data, memset(args, 0, sizeof(*args)); args->out.handle = handle; - up_read(&adev->exclusive_lock); return 0; error_unlock: - up_read(&adev->exclusive_lock); r = amdgpu_gem_handle_lockup(adev, r); return r; } @@ -250,8 +247,6 @@ int amdgpu_gem_userptr_ioctl(struct drm_device *dev, void *data, return -EACCES; } - down_read(&adev->exclusive_lock); - /* create a gem object to contain this object in */ r = amdgpu_gem_object_create(adev, args->size, 0, AMDGPU_GEM_DOMAIN_CPU, 0, @@ -293,14 +288,12 @@ int amdgpu_gem_userptr_ioctl(struct drm_device *dev, void *data, goto handle_lockup; args->handle = handle; - up_read(&adev->exclusive_lock); return 0; release_object: drm_gem_object_unreference_unlocked(gobj); handle_lockup: - up_read(&adev->exclusive_lock); r = amdgpu_gem_handle_lockup(adev, r); return r; -- cgit v1.2.3 From 5c92d87d30b23844e6998d8318e4c19ee3a907ac Mon Sep 17 00:00:00 2001 From: Christian König Date: Wed, 21 Oct 2015 21:58:28 +0200 Subject: drm/amdgpu: stop leaking page flip fence MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit reservation_object_get_fences_rcu already takes the references. Signed-off-by: Christian König Reviewed-by: Alex Deucher Reviewed-by: Chunming Zhou Reviewed-by: Jammy Zhou --- drivers/gpu/drm/amd/amdgpu/amdgpu_display.c | 4 ---- 1 file changed, 4 deletions(-) (limited to 'drivers/gpu/drm/amd/amdgpu/amdgpu_display.c') diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_display.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_display.c index dc29ed8145c2..6c9e0902a414 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_display.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_display.c @@ -184,10 +184,6 @@ int amdgpu_crtc_page_flip(struct drm_crtc *crtc, goto cleanup; } - fence_get(work->excl); - for (i = 0; i < work->shared_count; ++i) - fence_get(work->shared[i]); - amdgpu_bo_get_tiling_flags(new_rbo, &tiling_flags); amdgpu_bo_unreserve(new_rbo); -- cgit v1.2.3 From e9d951a832d9a5db33f9d981a810a37f851f8b39 Mon Sep 17 00:00:00 2001 From: Christian König Date: Thu, 3 Dec 2015 19:55:51 +0100 Subject: drm/amdgpu: take a BO reference in the display code MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit No need for the GEM reference here. Reviewed-by: Michel Dänzer Signed-off-by: Christian König Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/amdgpu/amdgpu_display.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'drivers/gpu/drm/amd/amdgpu/amdgpu_display.c') diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_display.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_display.c index e173a5a02f0d..ddd7233bbac7 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_display.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_display.c @@ -109,7 +109,7 @@ static void amdgpu_unpin_work_func(struct work_struct *__work) } else DRM_ERROR("failed to reserve buffer after flip\n"); - drm_gem_object_unreference_unlocked(&work->old_rbo->gem_base); + amdgpu_bo_unref(&work->old_rbo); kfree(work->shared); kfree(work); } @@ -148,8 +148,8 @@ int amdgpu_crtc_page_flip(struct drm_crtc *crtc, obj = old_amdgpu_fb->obj; /* take a reference to the old object */ - drm_gem_object_reference(obj); work->old_rbo = gem_to_amdgpu_bo(obj); + amdgpu_bo_ref(work->old_rbo); new_amdgpu_fb = to_amdgpu_framebuffer(fb); obj = new_amdgpu_fb->obj; @@ -222,7 +222,7 @@ pflip_cleanup: amdgpu_bo_unreserve(new_rbo); cleanup: - drm_gem_object_unreference_unlocked(&work->old_rbo->gem_base); + amdgpu_bo_unref(&work->old_rbo); fence_put(work->excl); for (i = 0; i < work->shared_count; ++i) fence_put(work->shared[i]); -- cgit v1.2.3 From 8e36f9d33c134d5c6448ad65b423a9fd94e045cf Mon Sep 17 00:00:00 2001 From: Alex Deucher Date: Thu, 3 Dec 2015 12:31:56 -0500 Subject: drm/amdgpu: Fixup hw vblank counter/ts for new drm_update_vblank_count() (v3) commit 4dfd6486 "drm: Use vblank timestamps to guesstimate how many vblanks were missed" introduced in Linux 4.4-rc1 makes the drm core more fragile to drivers which don't update hw vblank counters and vblank timestamps in sync with firing of the vblank irq and essentially at leading edge of vblank. This exposed a problem with radeon-kms/amdgpu-kms which do not satisfy above requirements: The vblank irq fires a few scanlines before start of vblank, but programmed pageflips complete at start of vblank and vblank timestamps update at start of vblank, whereas the hw vblank counter increments only later, at start of vsync. This leads to problems like off by one errors for vblank counter updates, vblank counters apparently going backwards or vblank timestamps apparently having time going backwards. The net result is stuttering of graphics in games, or little hangs, as well as total failure of timing sensitive applications. See bug #93147 for an example of the regression on Linux 4.4-rc: https://bugs.freedesktop.org/show_bug.cgi?id=93147 This patch tries to align all above events better from the viewpoint of the drm core / of external callers to fix the problem: 1. The apparent start of vblank is shifted a few scanlines earlier, so the vblank irq now always happens after start of this extended vblank interval and thereby drm_update_vblank_count() always samples the updated vblank count and timestamp of the new vblank interval. To achieve this, the reporting of scanout positions by radeon_get_crtc_scanoutpos() now operates as if the vblank starts radeon_crtc->lb_vblank_lead_lines before the real start of the hw vblank interval. This means that the vblank timestamps which are based on these scanout positions will now update at this earlier start of vblank. 2. The driver->get_vblank_counter() function will bump the returned vblank count as read from the hw by +1 if the query happens after the shifted earlier start of the vblank, but before the real hw increment at start of vsync, so the counter appears to increment at start of vblank in sync with the timestamp update. 3. Calls from vblank irq-context and regular non-irq calls are now treated identical, always simulating the shifted vblank start, to avoid inconsistent results for queries happening from vblank irq vs. happening from drm_vblank_enable() or vblank_disable_fn(). 4. The radeon_flip_work_func will delay mmio programming a pageflip until the start of the real vblank iff it happens to execute inside the shifted earlier start of the vblank, so pageflips now also appear to execute at start of the shifted vblank, in sync with vblank counter and timestamp updates. This to avoid some races between updates of vblank count and timestamps that are used for swap scheduling and pageflip execution which could cause pageflips to execute before the scheduled target vblank. The lb_vblank_lead_lines "fudge" value is calculated as the size of the display controllers line buffer in scanlines for the given video mode: Vblank irq's are triggered by the line buffer logic when the line buffer refill for a video frame ends, ie. when the line buffer source read position enters the hw vblank. This means that a vblank irq could fire at most as many scanlines before the current reported scanout position of the crtc timing generator as the number of scanlines the line buffer can maximally hold for a given video mode. This patch has been successfully tested on a RV730 card with DCE-3 display engine and on a evergreen card with DCE-4 display engine, in single-display and dual-display configuration, with different video modes. A similar patch is needed for amdgpu-kms to fix the same problem. Limitations: - Maybe replace the udelay() in the flip_work_func() by a suitable usleep_range() for a bit better efficiency? Will try that. - Line buffer sizes in pixels are hard-coded on < DCE-4 to a value i just guessed to be high enough to work ok, lacking info on the true sizes atm. Probably fixes: fdo#93147 Port of Mario's radeon fix to amdgpu. Signed-off-by: Alex Deucher (v1) Reviewed-by: Mario Kleiner (v2) Refine amdgpu_flip_work_func() for better efficiency. In amdgpu_flip_work_func, replace the busy waiting udelay(5) with event lock held by a more performance and energy efficient usleep_range() until at least predicted true start of hw vblank, with some slack for scheduler happiness. Release the event lock during waits to not delay other outputs in doing their stuff, as the waiting can last up to 200 usecs in some cases. Also small fix to code comment and formatting in that function. (v2) Signed-off-by: Mario Kleiner (v3) Fix crash in crtc disabled case --- drivers/gpu/drm/amd/amdgpu/amdgpu_display.c | 102 +++++++++++++++++++++------- drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c | 48 ++++++++++++- drivers/gpu/drm/amd/amdgpu/amdgpu_mode.h | 5 ++ drivers/gpu/drm/amd/amdgpu/dce_v10_0.c | 5 +- drivers/gpu/drm/amd/amdgpu/dce_v11_0.c | 5 +- drivers/gpu/drm/amd/amdgpu/dce_v8_0.c | 5 +- 6 files changed, 140 insertions(+), 30 deletions(-) (limited to 'drivers/gpu/drm/amd/amdgpu/amdgpu_display.c') diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_display.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_display.c index ddd7233bbac7..5580d3420c3a 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_display.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_display.c @@ -73,6 +73,8 @@ static void amdgpu_flip_work_func(struct work_struct *__work) struct drm_crtc *crtc = &amdgpuCrtc->base; unsigned long flags; unsigned i; + int vpos, hpos, stat, min_udelay; + struct drm_vblank_crtc *vblank = &crtc->dev->vblank[work->crtc_id]; amdgpu_flip_wait_fence(adev, &work->excl); for (i = 0; i < work->shared_count; ++i) @@ -81,6 +83,41 @@ static void amdgpu_flip_work_func(struct work_struct *__work) /* We borrow the event spin lock for protecting flip_status */ spin_lock_irqsave(&crtc->dev->event_lock, flags); + /* If this happens to execute within the "virtually extended" vblank + * interval before the start of the real vblank interval then it needs + * to delay programming the mmio flip until the real vblank is entered. + * This prevents completing a flip too early due to the way we fudge + * our vblank counter and vblank timestamps in order to work around the + * problem that the hw fires vblank interrupts before actual start of + * vblank (when line buffer refilling is done for a frame). It + * complements the fudging logic in amdgpu_get_crtc_scanoutpos() for + * timestamping and amdgpu_get_vblank_counter_kms() for vblank counts. + * + * In practice this won't execute very often unless on very fast + * machines because the time window for this to happen is very small. + */ + for (;;) { + /* GET_DISTANCE_TO_VBLANKSTART returns distance to real vblank + * start in hpos, and to the "fudged earlier" vblank start in + * vpos. + */ + stat = amdgpu_get_crtc_scanoutpos(adev->ddev, work->crtc_id, + GET_DISTANCE_TO_VBLANKSTART, + &vpos, &hpos, NULL, NULL, + &crtc->hwmode); + + if ((stat & (DRM_SCANOUTPOS_VALID | DRM_SCANOUTPOS_ACCURATE)) != + (DRM_SCANOUTPOS_VALID | DRM_SCANOUTPOS_ACCURATE) || + !(vpos >= 0 && hpos <= 0)) + break; + + /* Sleep at least until estimated real start of hw vblank */ + spin_unlock_irqrestore(&crtc->dev->event_lock, flags); + min_udelay = (-hpos + 1) * max(vblank->linedur_ns / 1000, 5); + usleep_range(min_udelay, 2 * min_udelay); + spin_lock_irqsave(&crtc->dev->event_lock, flags); + }; + /* do the flip (mmio) */ adev->mode_info.funcs->page_flip(adev, work->crtc_id, work->base); /* set the flip status */ @@ -712,6 +749,15 @@ bool amdgpu_crtc_scaling_mode_fixup(struct drm_crtc *crtc, * \param dev Device to query. * \param pipe Crtc to query. * \param flags Flags from caller (DRM_CALLED_FROM_VBLIRQ or 0). + * For driver internal use only also supports these flags: + * + * USE_REAL_VBLANKSTART to use the real start of vblank instead + * of a fudged earlier start of vblank. + * + * GET_DISTANCE_TO_VBLANKSTART to return distance to the + * fudged earlier start of vblank in *vpos and the distance + * to true start of vblank in *hpos. + * * \param *vpos Location where vertical scanout position should be stored. * \param *hpos Location where horizontal scanout position should go. * \param *stime Target location for timestamp taken immediately before @@ -776,10 +822,40 @@ int amdgpu_get_crtc_scanoutpos(struct drm_device *dev, unsigned int pipe, vbl_end = 0; } + /* Called from driver internal vblank counter query code? */ + if (flags & GET_DISTANCE_TO_VBLANKSTART) { + /* Caller wants distance from real vbl_start in *hpos */ + *hpos = *vpos - vbl_start; + } + + /* Fudge vblank to start a few scanlines earlier to handle the + * problem that vblank irqs fire a few scanlines before start + * of vblank. Some driver internal callers need the true vblank + * start to be used and signal this via the USE_REAL_VBLANKSTART flag. + * + * The cause of the "early" vblank irq is that the irq is triggered + * by the line buffer logic when the line buffer read position enters + * the vblank, whereas our crtc scanout position naturally lags the + * line buffer read position. + */ + if (!(flags & USE_REAL_VBLANKSTART)) + vbl_start -= adev->mode_info.crtcs[pipe]->lb_vblank_lead_lines; + /* Test scanout position against vblank region. */ if ((*vpos < vbl_start) && (*vpos >= vbl_end)) in_vbl = false; + /* In vblank? */ + if (in_vbl) + ret |= DRM_SCANOUTPOS_IN_VBLANK; + + /* Called from driver internal vblank counter query code? */ + if (flags & GET_DISTANCE_TO_VBLANKSTART) { + /* Caller wants distance from fudged earlier vbl_start */ + *vpos -= vbl_start; + return ret; + } + /* Check if inside vblank area and apply corrective offsets: * vpos will then be >=0 in video scanout area, but negative * within vblank area, counting down the number of lines until @@ -795,32 +871,6 @@ int amdgpu_get_crtc_scanoutpos(struct drm_device *dev, unsigned int pipe, /* Correct for shifted end of vbl at vbl_end. */ *vpos = *vpos - vbl_end; - /* In vblank? */ - if (in_vbl) - ret |= DRM_SCANOUTPOS_IN_VBLANK; - - /* Is vpos outside nominal vblank area, but less than - * 1/100 of a frame height away from start of vblank? - * If so, assume this isn't a massively delayed vblank - * interrupt, but a vblank interrupt that fired a few - * microseconds before true start of vblank. Compensate - * by adding a full frame duration to the final timestamp. - * Happens, e.g., on ATI R500, R600. - * - * We only do this if DRM_CALLED_FROM_VBLIRQ. - */ - if ((flags & DRM_CALLED_FROM_VBLIRQ) && !in_vbl) { - vbl_start = mode->crtc_vdisplay; - vtotal = mode->crtc_vtotal; - - if (vbl_start - *vpos < vtotal / 100) { - *vpos -= vtotal; - - /* Signal this correction as "applied". */ - ret |= 0x8; - } - } - return ret; } diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c index 1618e2294a16..e23843f4d877 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c @@ -611,13 +611,59 @@ void amdgpu_driver_preclose_kms(struct drm_device *dev, u32 amdgpu_get_vblank_counter_kms(struct drm_device *dev, unsigned int pipe) { struct amdgpu_device *adev = dev->dev_private; + int vpos, hpos, stat; + u32 count; if (pipe >= adev->mode_info.num_crtc) { DRM_ERROR("Invalid crtc %u\n", pipe); return -EINVAL; } - return amdgpu_display_vblank_get_counter(adev, pipe); + /* The hw increments its frame counter at start of vsync, not at start + * of vblank, as is required by DRM core vblank counter handling. + * Cook the hw count here to make it appear to the caller as if it + * incremented at start of vblank. We measure distance to start of + * vblank in vpos. vpos therefore will be >= 0 between start of vblank + * and start of vsync, so vpos >= 0 means to bump the hw frame counter + * result by 1 to give the proper appearance to caller. + */ + if (adev->mode_info.crtcs[pipe]) { + /* Repeat readout if needed to provide stable result if + * we cross start of vsync during the queries. + */ + do { + count = amdgpu_display_vblank_get_counter(adev, pipe); + /* Ask amdgpu_get_crtc_scanoutpos to return vpos as + * distance to start of vblank, instead of regular + * vertical scanout pos. + */ + stat = amdgpu_get_crtc_scanoutpos( + dev, pipe, GET_DISTANCE_TO_VBLANKSTART, + &vpos, &hpos, NULL, NULL, + &adev->mode_info.crtcs[pipe]->base.hwmode); + } while (count != amdgpu_display_vblank_get_counter(adev, pipe)); + + if (((stat & (DRM_SCANOUTPOS_VALID | DRM_SCANOUTPOS_ACCURATE)) != + (DRM_SCANOUTPOS_VALID | DRM_SCANOUTPOS_ACCURATE))) { + DRM_DEBUG_VBL("Query failed! stat %d\n", stat); + } else { + DRM_DEBUG_VBL("crtc %d: dist from vblank start %d\n", + pipe, vpos); + + /* Bump counter if we are at >= leading edge of vblank, + * but before vsync where vpos would turn negative and + * the hw counter really increments. + */ + if (vpos >= 0) + count++; + } + } else { + /* Fallback to use value as is. */ + count = amdgpu_display_vblank_get_counter(adev, pipe); + DRM_DEBUG_VBL("NULL mode info! Returned count may be wrong.\n"); + } + + return count; } /** diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_mode.h b/drivers/gpu/drm/amd/amdgpu/amdgpu_mode.h index b62c1710cab6..064ebb347074 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_mode.h +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_mode.h @@ -407,6 +407,7 @@ struct amdgpu_crtc { u32 line_time; u32 wm_low; u32 wm_high; + u32 lb_vblank_lead_lines; struct drm_display_mode hw_mode; }; @@ -528,6 +529,10 @@ struct amdgpu_framebuffer { #define ENCODER_MODE_IS_DP(em) (((em) == ATOM_ENCODER_MODE_DP) || \ ((em) == ATOM_ENCODER_MODE_DP_MST)) +/* Driver internal use only flags of amdgpu_get_crtc_scanoutpos() */ +#define USE_REAL_VBLANKSTART (1 << 30) +#define GET_DISTANCE_TO_VBLANKSTART (1 << 31) + void amdgpu_link_encoder_connector(struct drm_device *dev); struct drm_connector * diff --git a/drivers/gpu/drm/amd/amdgpu/dce_v10_0.c b/drivers/gpu/drm/amd/amdgpu/dce_v10_0.c index cb0f7747e3dc..4dcc8fba5792 100644 --- a/drivers/gpu/drm/amd/amdgpu/dce_v10_0.c +++ b/drivers/gpu/drm/amd/amdgpu/dce_v10_0.c @@ -1250,7 +1250,7 @@ static void dce_v10_0_program_watermarks(struct amdgpu_device *adev, u32 pixel_period; u32 line_time = 0; u32 latency_watermark_a = 0, latency_watermark_b = 0; - u32 tmp, wm_mask; + u32 tmp, wm_mask, lb_vblank_lead_lines = 0; if (amdgpu_crtc->base.enabled && num_heads && mode) { pixel_period = 1000000 / (u32)mode->clock; @@ -1333,6 +1333,7 @@ static void dce_v10_0_program_watermarks(struct amdgpu_device *adev, (adev->mode_info.disp_priority == 2)) { DRM_DEBUG_KMS("force priority to high\n"); } + lb_vblank_lead_lines = DIV_ROUND_UP(lb_size, mode->crtc_hdisplay); } /* select wm A */ @@ -1357,6 +1358,8 @@ static void dce_v10_0_program_watermarks(struct amdgpu_device *adev, amdgpu_crtc->line_time = line_time; amdgpu_crtc->wm_high = latency_watermark_a; amdgpu_crtc->wm_low = latency_watermark_b; + /* Save number of lines the linebuffer leads before the scanout */ + amdgpu_crtc->lb_vblank_lead_lines = lb_vblank_lead_lines; } /** diff --git a/drivers/gpu/drm/amd/amdgpu/dce_v11_0.c b/drivers/gpu/drm/amd/amdgpu/dce_v11_0.c index 5af3721851d6..8f1e51128b33 100644 --- a/drivers/gpu/drm/amd/amdgpu/dce_v11_0.c +++ b/drivers/gpu/drm/amd/amdgpu/dce_v11_0.c @@ -1238,7 +1238,7 @@ static void dce_v11_0_program_watermarks(struct amdgpu_device *adev, u32 pixel_period; u32 line_time = 0; u32 latency_watermark_a = 0, latency_watermark_b = 0; - u32 tmp, wm_mask; + u32 tmp, wm_mask, lb_vblank_lead_lines = 0; if (amdgpu_crtc->base.enabled && num_heads && mode) { pixel_period = 1000000 / (u32)mode->clock; @@ -1321,6 +1321,7 @@ static void dce_v11_0_program_watermarks(struct amdgpu_device *adev, (adev->mode_info.disp_priority == 2)) { DRM_DEBUG_KMS("force priority to high\n"); } + lb_vblank_lead_lines = DIV_ROUND_UP(lb_size, mode->crtc_hdisplay); } /* select wm A */ @@ -1345,6 +1346,8 @@ static void dce_v11_0_program_watermarks(struct amdgpu_device *adev, amdgpu_crtc->line_time = line_time; amdgpu_crtc->wm_high = latency_watermark_a; amdgpu_crtc->wm_low = latency_watermark_b; + /* Save number of lines the linebuffer leads before the scanout */ + amdgpu_crtc->lb_vblank_lead_lines = lb_vblank_lead_lines; } /** diff --git a/drivers/gpu/drm/amd/amdgpu/dce_v8_0.c b/drivers/gpu/drm/amd/amdgpu/dce_v8_0.c index 4f7b49a6dc50..42d954dc436d 100644 --- a/drivers/gpu/drm/amd/amdgpu/dce_v8_0.c +++ b/drivers/gpu/drm/amd/amdgpu/dce_v8_0.c @@ -1193,7 +1193,7 @@ static void dce_v8_0_program_watermarks(struct amdgpu_device *adev, u32 pixel_period; u32 line_time = 0; u32 latency_watermark_a = 0, latency_watermark_b = 0; - u32 tmp, wm_mask; + u32 tmp, wm_mask, lb_vblank_lead_lines = 0; if (amdgpu_crtc->base.enabled && num_heads && mode) { pixel_period = 1000000 / (u32)mode->clock; @@ -1276,6 +1276,7 @@ static void dce_v8_0_program_watermarks(struct amdgpu_device *adev, (adev->mode_info.disp_priority == 2)) { DRM_DEBUG_KMS("force priority to high\n"); } + lb_vblank_lead_lines = DIV_ROUND_UP(lb_size, mode->crtc_hdisplay); } /* select wm A */ @@ -1302,6 +1303,8 @@ static void dce_v8_0_program_watermarks(struct amdgpu_device *adev, amdgpu_crtc->line_time = line_time; amdgpu_crtc->wm_high = latency_watermark_a; amdgpu_crtc->wm_low = latency_watermark_b; + /* Save number of lines the linebuffer leads before the scanout */ + amdgpu_crtc->lb_vblank_lead_lines = lb_vblank_lead_lines; } /** -- cgit v1.2.3