summaryrefslogtreecommitdiff
path: root/drivers/gpu/drm/msm/disp/mdp5/mdp5_plane.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/gpu/drm/msm/disp/mdp5/mdp5_plane.c')
-rw-r--r--drivers/gpu/drm/msm/disp/mdp5/mdp5_plane.c42
1 files changed, 42 insertions, 0 deletions
diff --git a/drivers/gpu/drm/msm/disp/mdp5/mdp5_plane.c b/drivers/gpu/drm/msm/disp/mdp5/mdp5_plane.c
index c6b69afcbac8..85275665558b 100644
--- a/drivers/gpu/drm/msm/disp/mdp5/mdp5_plane.c
+++ b/drivers/gpu/drm/msm/disp/mdp5/mdp5_plane.c
@@ -154,6 +154,46 @@ static void mdp5_plane_cleanup_fb(struct drm_plane *plane,
msm_framebuffer_cleanup(fb, kms->aspace);
}
+/* based on _dpu_plane_calc_bw */
+static void mdp5_plane_calc_bw(struct drm_plane_state *state, struct drm_crtc_state *crtc_state)
+{
+ struct drm_framebuffer *fb = state->fb;
+ struct mdp5_plane_state *pstate = to_mdp5_plane_state(state);
+ struct drm_display_mode *mode = &crtc_state->mode;
+ int bpp;
+ int src_width, src_height, dst_height, fps;
+ u64 plane_bw;
+ u32 hw_latency_lines;
+ u32 prefill_div;
+ u64 scale_factor;
+ int vbp, vpw, vfp;
+
+ src_width = drm_rect_width(&state->src) >> 16;
+ src_height = drm_rect_height(&state->src) >> 16;
+ dst_height = drm_rect_height(&state->dst);
+ fps = drm_mode_vrefresh(mode);
+ vbp = mode->vtotal - mode->vsync_end;
+ vpw = mode->vsync_end - mode->vsync_start;
+ vfp = mode->vsync_start - mode->vdisplay;
+ scale_factor = src_height > dst_height ?
+ mult_frac(src_height, 1, dst_height) : 1;
+
+ bpp = to_mdp_format(msm_framebuffer_format(fb))->cpp;
+
+ plane_bw = src_width * mode->vtotal * fps * bpp * scale_factor;
+
+ hw_latency_lines = 21; /* or 24? */
+ prefill_div = hw_latency_lines;
+ if (vbp + vpw > hw_latency_lines)
+ prefill_div = vbp + vpw;
+#if 0
+ else if (vbp + vpw + vfp < hw_latency_lines)
+ prefill_div = vbp + vpw + vfp;
+#endif
+
+ pstate->plane_bw = max(plane_bw, mult_frac(plane_bw, hw_latency_lines, prefill_div));
+}
+
static int mdp5_plane_atomic_check_with_state(struct drm_crtc_state *crtc_state,
struct drm_plane_state *state)
{
@@ -297,6 +337,8 @@ static int mdp5_plane_atomic_check_with_state(struct drm_crtc_state *crtc_state,
mdp5_pipe_release(state->state, old_hwpipe);
mdp5_pipe_release(state->state, old_right_hwpipe);
}
+
+ mdp5_plane_calc_bw(state, crtc_state);
} else {
mdp5_pipe_release(state->state, mdp5_state->hwpipe);
mdp5_pipe_release(state->state, mdp5_state->r_hwpipe);