aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/gpu/drm/msm/mdp/mdp5
diff options
context:
space:
mode:
authorDaniel Vetter <daniel.vetter@ffwll.ch>2017-05-09 10:03:28 -0400
committerDaniel Vetter <daniel.vetter@ffwll.ch>2017-05-10 04:21:31 -0400
commit1bf6ad622b9be58484279978f85716fbb10d545b (patch)
treef7add5183253140848bff995e5084e8fd35dacb8 /drivers/gpu/drm/msm/mdp/mdp5
parent2a39b88bc121645e95a2b3b25a97ef4ceb4208b8 (diff)
drm/vblank: drop the mode argument from drm_calc_vbltimestamp_from_scanoutpos
If we restrict this helper to only kms drivers (which is the case) we can look up the correct mode easily ourselves. But it's a bit tricky: - All legacy drivers look at crtc->hwmode. But that is updated already at the beginning of the modeset helper, which means when we disable a pipe. Hence the final timestamps might be a bit off. But since this is an existing bug I'm not going to change it, but just try to be bug-for-bug compatible with the current code. This only applies to radeon&amdgpu. - i915 tries to get it perfect by updating crtc->hwmode when the pipe is off (i.e. vblank->enabled = false). - All other atomic drivers look at crtc->state->adjusted_mode. Those that look at state->requested_mode simply don't adjust their mode, so it's the same. That has two problems: Accessing crtc->state from interrupt handling code is unsafe, and it's updated before we shut down the pipe. For nonblocking modesets it's even worse. For atomic drivers try to implement what i915 does. To do that we add a new hwmode field to the vblank structure, and update it from drm_calc_timestamping_constants(). For atomic drivers that's called from the right spot by the helper library already, so all fine. But for safety let's enforce that. For legacy driver this function is only called at the end (oh the fun), which is broken, so again let's not bother and just stay bug-for-bug compatible. The benefit is that we can use drm_calc_vbltimestamp_from_scanoutpos directly to implement ->get_vblank_timestamp in every driver, deleting a lot of code. v2: Completely new approach, trying to mimick the i915 solution. v3: Fixup kerneldoc. v4: Drop the WARN_ON to check that the vblank is off, atomic helpers currently unconditionally call this. Recomputing the same stuff should be harmless. v5: Fix typos and move misplaced hunks to the right patches (Neil). v6: Undo hunk movement (kbuild). Cc: Mario Kleiner <mario.kleiner@tuebingen.mpg.de> Cc: Eric Anholt <eric@anholt.net> Cc: Rob Clark <robdclark@gmail.com> Cc: linux-arm-msm@vger.kernel.org Cc: freedreno@lists.freedesktop.org Cc: Alex Deucher <alexander.deucher@amd.com> Cc: Christian König <christian.koenig@amd.com> Cc: Ben Skeggs <bskeggs@redhat.com> Reviewed-by: Neil Armstrong <narmstrong@baylibre.com> Acked-by: Ville Syrjälä <ville.syrjala@linux.intel.com> Signed-off-by: Daniel Vetter <daniel.vetter@intel.com> Link: http://patchwork.freedesktop.org/patch/msgid/20170509140329.24114-4-daniel.vetter@ffwll.ch
Diffstat (limited to 'drivers/gpu/drm/msm/mdp/mdp5')
-rw-r--r--drivers/gpu/drm/msm/mdp/mdp5/mdp5_kms.c45
1 files changed, 8 insertions, 37 deletions
diff --git a/drivers/gpu/drm/msm/mdp/mdp5/mdp5_kms.c b/drivers/gpu/drm/msm/mdp/mdp5/mdp5_kms.c
index 07e2b1335f65..e2b3346ead48 100644
--- a/drivers/gpu/drm/msm/mdp/mdp5/mdp5_kms.c
+++ b/drivers/gpu/drm/msm/mdp/mdp5/mdp5_kms.c
@@ -527,31 +527,28 @@ static struct drm_encoder *get_encoder_from_crtc(struct drm_crtc *crtc)
527 return NULL; 527 return NULL;
528} 528}
529 529
530static int mdp5_get_scanoutpos(struct drm_device *dev, unsigned int pipe, 530static bool mdp5_get_scanoutpos(struct drm_device *dev, unsigned int pipe,
531 unsigned int flags, int *vpos, int *hpos, 531 bool in_vblank_irq, int *vpos, int *hpos,
532 ktime_t *stime, ktime_t *etime, 532 ktime_t *stime, ktime_t *etime,
533 const struct drm_display_mode *mode) 533 const struct drm_display_mode *mode)
534{ 534{
535 struct msm_drm_private *priv = dev->dev_private; 535 struct msm_drm_private *priv = dev->dev_private;
536 struct drm_crtc *crtc; 536 struct drm_crtc *crtc;
537 struct drm_encoder *encoder; 537 struct drm_encoder *encoder;
538 int line, vsw, vbp, vactive_start, vactive_end, vfp_end; 538 int line, vsw, vbp, vactive_start, vactive_end, vfp_end;
539 int ret = 0;
540 539
541 crtc = priv->crtcs[pipe]; 540 crtc = priv->crtcs[pipe];
542 if (!crtc) { 541 if (!crtc) {
543 DRM_ERROR("Invalid crtc %d\n", pipe); 542 DRM_ERROR("Invalid crtc %d\n", pipe);
544 return 0; 543 return false;
545 } 544 }
546 545
547 encoder = get_encoder_from_crtc(crtc); 546 encoder = get_encoder_from_crtc(crtc);
548 if (!encoder) { 547 if (!encoder) {
549 DRM_ERROR("no encoder found for crtc %d\n", pipe); 548 DRM_ERROR("no encoder found for crtc %d\n", pipe);
550 return 0; 549 return false;
551 } 550 }
552 551
553 ret |= DRM_SCANOUTPOS_VALID | DRM_SCANOUTPOS_ACCURATE;
554
555 vsw = mode->crtc_vsync_end - mode->crtc_vsync_start; 552 vsw = mode->crtc_vsync_end - mode->crtc_vsync_start;
556 vbp = mode->crtc_vtotal - mode->crtc_vsync_end; 553 vbp = mode->crtc_vtotal - mode->crtc_vsync_end;
557 554
@@ -575,10 +572,8 @@ static int mdp5_get_scanoutpos(struct drm_device *dev, unsigned int pipe,
575 572
576 if (line < vactive_start) { 573 if (line < vactive_start) {
577 line -= vactive_start; 574 line -= vactive_start;
578 ret |= DRM_SCANOUTPOS_IN_VBLANK;
579 } else if (line > vactive_end) { 575 } else if (line > vactive_end) {
580 line = line - vfp_end - vactive_start; 576 line = line - vfp_end - vactive_start;
581 ret |= DRM_SCANOUTPOS_IN_VBLANK;
582 } else { 577 } else {
583 line -= vactive_start; 578 line -= vactive_start;
584 } 579 }
@@ -589,31 +584,7 @@ static int mdp5_get_scanoutpos(struct drm_device *dev, unsigned int pipe,
589 if (etime) 584 if (etime)
590 *etime = ktime_get(); 585 *etime = ktime_get();
591 586
592 return ret; 587 return true;
593}
594
595static bool mdp5_get_vblank_timestamp(struct drm_device *dev, unsigned int pipe,
596 int *max_error,
597 struct timeval *vblank_time,
598 bool in_vblank_irq)
599{
600 struct msm_drm_private *priv = dev->dev_private;
601 struct drm_crtc *crtc;
602
603 if (pipe < 0 || pipe >= priv->num_crtcs) {
604 DRM_ERROR("Invalid crtc %d\n", pipe);
605 return false;
606 }
607
608 crtc = priv->crtcs[pipe];
609 if (!crtc) {
610 DRM_ERROR("Invalid crtc %d\n", pipe);
611 return false;
612 }
613
614 return drm_calc_vbltimestamp_from_scanoutpos(dev, pipe, max_error,
615 vblank_time, in_vblank_irq,
616 &crtc->mode);
617} 588}
618 589
619static u32 mdp5_get_vblank_counter(struct drm_device *dev, unsigned int pipe) 590static u32 mdp5_get_vblank_counter(struct drm_device *dev, unsigned int pipe)
@@ -725,7 +696,7 @@ struct msm_kms *mdp5_kms_init(struct drm_device *dev)
725 dev->mode_config.max_width = 0xffff; 696 dev->mode_config.max_width = 0xffff;
726 dev->mode_config.max_height = 0xffff; 697 dev->mode_config.max_height = 0xffff;
727 698
728 dev->driver->get_vblank_timestamp = mdp5_get_vblank_timestamp; 699 dev->driver->get_vblank_timestamp = drm_calc_vbltimestamp_from_scanoutpos;
729 dev->driver->get_scanout_position = mdp5_get_scanoutpos; 700 dev->driver->get_scanout_position = mdp5_get_scanoutpos;
730 dev->driver->get_vblank_counter = mdp5_get_vblank_counter; 701 dev->driver->get_vblank_counter = mdp5_get_vblank_counter;
731 dev->max_vblank_count = 0xffffffff; 702 dev->max_vblank_count = 0xffffffff;