diff mbox series

[v6,4/5] drm/amdgpu: Correct get_crtc_scanoutpos behavior when vpos >= vtotal

Message ID 20181106202435.23556-5-nicholas.kazlauskas@amd.com (mailing list archive)
State New, archived
Headers show
Series A DRM API for adaptive sync and variable refresh rate support | expand

Commit Message

Kazlauskas, Nicholas Nov. 6, 2018, 8:24 p.m. UTC
When variable refresh rate is active the hardware counter can return
a position >= vtotal. This results in a vpos being returned from
amdgpu_display_get_crtc_scanoutpos that's a positive value. The
positive value indicates to the caller that the display is
currently in scanout when the display is actually still in vblank.

This is because the vfront porch duration is unknown with variable
refresh active and will end when either a page flip occurs or the
timeout specified by the driver/display is reached.

The behavior of the amdgpu_display_get_crtc_scanoutpos remains the
same when the position is below vtotal. When the position is above
vtotal the function will return a value that is effectively -vbl_end,
the size of the vback porch.

The only caller affected by this change is the DRM helper for
calculating vblank timestamps. This change corrects behavior for
calculating the page flip timestap from being the previous timestamp
to the calculation to the next timestamp when position >= vtotal.

Signed-off-by: Nicholas Kazlauskas <nicholas.kazlauskas@amd.com>
Cc: Michel Dänzer <michel@daenzer.net>
Cc: Harry Wentland <harry.wentland@amd.com>
---
 drivers/gpu/drm/amd/amdgpu/amdgpu_display.c | 7 ++++++-
 1 file changed, 6 insertions(+), 1 deletion(-)

Comments

Harry Wentland Nov. 7, 2018, 2:58 p.m. UTC | #1
On 2018-11-06 3:24 p.m., Nicholas Kazlauskas wrote:
> When variable refresh rate is active the hardware counter can return
> a position >= vtotal. This results in a vpos being returned from
> amdgpu_display_get_crtc_scanoutpos that's a positive value. The
> positive value indicates to the caller that the display is
> currently in scanout when the display is actually still in vblank.
> 
> This is because the vfront porch duration is unknown with variable
> refresh active and will end when either a page flip occurs or the
> timeout specified by the driver/display is reached.
> 
> The behavior of the amdgpu_display_get_crtc_scanoutpos remains the
> same when the position is below vtotal. When the position is above
> vtotal the function will return a value that is effectively -vbl_end,
> the size of the vback porch.
> 
> The only caller affected by this change is the DRM helper for
> calculating vblank timestamps. This change corrects behavior for
> calculating the page flip timestap from being the previous timestamp
> to the calculation to the next timestamp when position >= vtotal.
> 
> Signed-off-by: Nicholas Kazlauskas <nicholas.kazlauskas@amd.com>

Reviewed-by: Harry Wentland <harry.wentland@amd.com>

Harry

> Cc: Michel Dänzer <michel@daenzer.net>
> Cc: Harry Wentland <harry.wentland@amd.com>
> ---
>  drivers/gpu/drm/amd/amdgpu/amdgpu_display.c | 7 ++++++-
>  1 file changed, 6 insertions(+), 1 deletion(-)
> 
> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_display.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_display.c
> index 6748cd7fc129..cb331319f225 100644
> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_display.c
> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_display.c
> @@ -850,7 +850,12 @@ int amdgpu_display_get_crtc_scanoutpos(struct drm_device *dev,
>  	/* Inside "upper part" of vblank area? Apply corrective offset if so: */
>  	if (in_vbl && (*vpos >= vbl_start)) {
>  		vtotal = mode->crtc_vtotal;
> -		*vpos = *vpos - vtotal;
> +
> +		/* With variable refresh rate displays the vpos can exceed
> +		 * the vtotal value. Clamp to 0 to return -vbl_end instead
> +		 * of guessing the remaining number of lines until scanout.
> +		 */
> +		*vpos = (*vpos < vtotal) ? (*vpos - vtotal) : 0;
>  	}
>  
>  	/* Correct for shifted end of vbl at vbl_end. */
>
diff mbox series

Patch

diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_display.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_display.c
index 6748cd7fc129..cb331319f225 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_display.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_display.c
@@ -850,7 +850,12 @@  int amdgpu_display_get_crtc_scanoutpos(struct drm_device *dev,
 	/* Inside "upper part" of vblank area? Apply corrective offset if so: */
 	if (in_vbl && (*vpos >= vbl_start)) {
 		vtotal = mode->crtc_vtotal;
-		*vpos = *vpos - vtotal;
+
+		/* With variable refresh rate displays the vpos can exceed
+		 * the vtotal value. Clamp to 0 to return -vbl_end instead
+		 * of guessing the remaining number of lines until scanout.
+		 */
+		*vpos = (*vpos < vtotal) ? (*vpos - vtotal) : 0;
 	}
 
 	/* Correct for shifted end of vbl at vbl_end. */