Rewwork plane's atomic_check and atomic_update functions to clearly use
struct dpu_sw_pipe and struct dpu_hw_pipe_cfg. This is the last step towards
adding proper source split support.

Signed-off-by: Dmitry Baryshkov <dmitry.barysh...@linaro.org>
---
 drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c | 283 +++++++++++++---------
 1 file changed, 163 insertions(+), 120 deletions(-)

diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c 
b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
index 74b585f55b73..623f67247c2d 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
@@ -123,20 +123,19 @@ static struct dpu_kms *_dpu_plane_get_kms(struct 
drm_plane *plane)
 
 /**
  * _dpu_plane_calc_bw - calculate bandwidth required for a plane
- * @plane: Pointer to drm plane.
+ * @catalog: Points to dpu catalog structure
  * @fmt: Pointer to source buffer format
+ * @mode: Pointer to drm display mode
  * @pipe_cfg: Pointer to pipe configuration
  * Result: Updates calculated bandwidth in the plane state.
  * BW Equation: src_w * src_h * bpp * fps * (v_total / v_dest)
  * Prefill BW Equation: line src bytes * line_time
  */
-static void _dpu_plane_calc_bw(struct drm_plane *plane,
+static u64 _dpu_plane_calc_bw(const struct dpu_mdss_cfg *catalog,
        const struct dpu_format *fmt,
+       const struct drm_display_mode *mode,
        struct dpu_hw_pipe_cfg *pipe_cfg)
 {
-       struct dpu_plane_state *pstate;
-       struct drm_display_mode *mode;
-       struct dpu_kms *dpu_kms = _dpu_plane_get_kms(plane);
        int src_width, src_height, dst_height, fps;
        u64 plane_prefill_bw;
        u64 plane_bw;
@@ -144,9 +143,6 @@ static void _dpu_plane_calc_bw(struct drm_plane *plane,
        u64 scale_factor;
        int vbp, vpw, vfp;
 
-       pstate = to_dpu_plane_state(plane->state);
-       mode = &plane->state->crtc->mode;
-
        src_width = drm_rect_width(&pipe_cfg->src_rect);
        src_height = drm_rect_height(&pipe_cfg->src_rect);
        dst_height = drm_rect_height(&pipe_cfg->dst_rect);
@@ -154,7 +150,7 @@ static void _dpu_plane_calc_bw(struct drm_plane *plane,
        vbp = mode->vtotal - mode->vsync_end;
        vpw = mode->vsync_end - mode->vsync_start;
        vfp = mode->vsync_start - mode->vdisplay;
-       hw_latency_lines =  dpu_kms->catalog->perf.min_prefill_lines;
+       hw_latency_lines =  catalog->perf.min_prefill_lines;
        scale_factor = src_height > dst_height ?
                mult_frac(src_height, 1, dst_height) : 1;
 
@@ -174,37 +170,36 @@ static void _dpu_plane_calc_bw(struct drm_plane *plane,
                do_div(plane_prefill_bw, hw_latency_lines);
 
 
-       pstate->plane_fetch_bw = max(plane_bw, plane_prefill_bw);
+       return max(plane_bw, plane_prefill_bw);
 }
 
 /**
  * _dpu_plane_calc_clk - calculate clock required for a plane
- * @plane: Pointer to drm plane.
+ * @mode: Pointer to drm display mode
  * @pipe_cfg: Pointer to pipe configuration
  * Result: Updates calculated clock in the plane state.
  * Clock equation: dst_w * v_total * fps * (src_h / dst_h)
  */
-static void _dpu_plane_calc_clk(struct drm_plane *plane, struct 
dpu_hw_pipe_cfg *pipe_cfg)
+static u64 _dpu_plane_calc_clk(const struct drm_display_mode *mode,
+               struct dpu_hw_pipe_cfg *pipe_cfg)
 {
-       struct dpu_plane_state *pstate;
-       struct drm_display_mode *mode;
        int dst_width, src_height, dst_height, fps;
-
-       pstate = to_dpu_plane_state(plane->state);
-       mode = &plane->state->crtc->mode;
+       u64 plane_clk;
 
        src_height = drm_rect_height(&pipe_cfg->src_rect);
        dst_width = drm_rect_width(&pipe_cfg->dst_rect);
        dst_height = drm_rect_height(&pipe_cfg->dst_rect);
        fps = drm_mode_vrefresh(mode);
 
-       pstate->plane_clk =
+       plane_clk =
                dst_width * mode->vtotal * fps;
 
        if (src_height > dst_height) {
-               pstate->plane_clk *= src_height;
-               do_div(pstate->plane_clk, dst_height);
+               plane_clk *= src_height;
+               do_div(plane_clk, dst_height);
        }
+
+       return plane_clk;
 }
 
 /**
@@ -429,13 +424,14 @@ static void _dpu_plane_set_qos_ctrl(struct drm_plane 
*plane,
 /**
  * _dpu_plane_set_ot_limit - set OT limit for the given plane
  * @plane:             Pointer to drm plane
+ * @mode:              Pointer to drm display mode
  * @pipe:              Pointer to software pipe
- * @crtc:              Pointer to drm crtc
  * @pipe_cfg:          Pointer to pipe configuration
  */
 static void _dpu_plane_set_ot_limit(struct drm_plane *plane,
                struct dpu_sw_pipe *pipe,
-               struct drm_crtc *crtc, struct dpu_hw_pipe_cfg *pipe_cfg)
+               struct dpu_hw_pipe_cfg *pipe_cfg,
+               const struct drm_display_mode *mode)
 {
        struct dpu_plane *pdpu = to_dpu_plane(plane);
        struct dpu_vbif_set_ot_params ot_params;
@@ -447,7 +443,7 @@ static void _dpu_plane_set_ot_limit(struct drm_plane *plane,
        ot_params.width = drm_rect_width(&pipe_cfg->src_rect);
        ot_params.height = drm_rect_height(&pipe_cfg->src_rect);
        ot_params.is_wfd = !pdpu->is_rt_pipe;
-       ot_params.frame_rate = drm_mode_vrefresh(&crtc->mode);
+       ot_params.frame_rate = drm_mode_vrefresh(mode);
        ot_params.vbif_idx = VBIF_RT;
        ot_params.clk_ctrl = pipe->sspp->cap->clk_ctrl;
        ot_params.rd = true;
@@ -867,6 +863,55 @@ static void dpu_plane_cleanup_fb(struct drm_plane *plane,
        msm_framebuffer_cleanup(old_state->fb, old_pstate->aspace);
 }
 
+static int dpu_plane_atomic_check_pipe(struct dpu_plane *pdpu,
+               struct dpu_sw_pipe *pipe,
+               struct dpu_hw_pipe_cfg *pipe_cfg,
+               uint32_t max_linewidth,
+               const struct dpu_format *fmt)
+{
+       uint32_t min_src_size;
+
+       min_src_size = DPU_FORMAT_IS_YUV(fmt) ? 2 : 1;
+
+       if (DPU_FORMAT_IS_YUV(fmt) &&
+               (!(pipe->sspp->cap->features & DPU_SSPP_SCALER) ||
+                !(pipe->sspp->cap->features & DPU_SSPP_CSC_ANY))) {
+               DPU_DEBUG_PLANE(pdpu,
+                               "plane doesn't have scaler/csc for yuv\n");
+               return -EINVAL;
+
+       /* check src bounds */
+       } else if (drm_rect_width(&pipe_cfg->src_rect) < min_src_size ||
+                  drm_rect_height(&pipe_cfg->src_rect) < min_src_size) {
+               DPU_DEBUG_PLANE(pdpu, "invalid source " DRM_RECT_FMT "\n",
+                               DRM_RECT_ARG(&pipe_cfg->src_rect));
+               return -E2BIG;
+
+       /* valid yuv image */
+       } else if (DPU_FORMAT_IS_YUV(fmt) &&
+                  (pipe_cfg->src_rect.x1 & 0x1 || pipe_cfg->src_rect.y1 & 0x1 
||
+                   drm_rect_width(&pipe_cfg->src_rect) & 0x1 ||
+                   drm_rect_height(&pipe_cfg->src_rect) & 0x1)) {
+               DPU_DEBUG_PLANE(pdpu, "invalid yuv source " DRM_RECT_FMT "\n",
+                               DRM_RECT_ARG(&pipe_cfg->src_rect));
+               return -EINVAL;
+
+       /* min dst support */
+       } else if (drm_rect_width(&pipe_cfg->dst_rect) < 0x1 || 
drm_rect_height(&pipe_cfg->dst_rect) < 0x1) {
+               DPU_DEBUG_PLANE(pdpu, "invalid dest rect " DRM_RECT_FMT "\n",
+                               DRM_RECT_ARG(&pipe_cfg->dst_rect));
+               return -EINVAL;
+
+       /* check decimated source width */
+       } else if (drm_rect_width(&pipe_cfg->src_rect) > max_linewidth) {
+               DPU_DEBUG_PLANE(pdpu, "invalid src " DRM_RECT_FMT " line:%u\n",
+                               DRM_RECT_ARG(&pipe_cfg->src_rect), 
max_linewidth);
+               return -E2BIG;
+       }
+
+       return 0;
+}
+
 static int dpu_plane_atomic_check(struct drm_plane *plane,
                                  struct drm_atomic_state *state)
 {
@@ -880,7 +925,7 @@ static int dpu_plane_atomic_check(struct drm_plane *plane,
        const struct dpu_format *fmt;
        struct dpu_hw_pipe_cfg *pipe_cfg = &pstate->pipe_cfg;
        struct drm_rect fb_rect = { 0 };
-       uint32_t min_src_size, max_linewidth;
+       uint32_t max_linewidth;
 
        if (new_plane_state->crtc)
                crtc_state = drm_atomic_get_new_crtc_state(state,
@@ -898,8 +943,8 @@ static int dpu_plane_atomic_check(struct drm_plane *plane,
        if (!new_plane_state->visible)
                return 0;
 
-       pstate->pipe.multirect_index = DPU_SSPP_RECT_SOLO;
-       pstate->pipe.multirect_mode = DPU_SSPP_MULTIRECT_NONE;
+       pipe->multirect_index = DPU_SSPP_RECT_SOLO;
+       pipe->multirect_mode = DPU_SSPP_MULTIRECT_NONE;
 
        pstate->stage = DPU_STAGE_0 + pstate->base.normalized_zpos;
        if (pstate->stage >= pdpu->catalog->caps->max_mixer_blendstages) {
@@ -933,43 +978,9 @@ static int dpu_plane_atomic_check(struct drm_plane *plane,
 
        fmt = to_dpu_format(msm_framebuffer_format(new_plane_state->fb));
 
-       min_src_size = DPU_FORMAT_IS_YUV(fmt) ? 2 : 1;
-
-       if (DPU_FORMAT_IS_YUV(fmt) &&
-               (!(pipe->sspp->cap->features & DPU_SSPP_SCALER) ||
-                !(pipe->sspp->cap->features & DPU_SSPP_CSC_ANY))) {
-               DPU_DEBUG_PLANE(pdpu,
-                               "plane doesn't have scaler/csc for yuv\n");
-               return -EINVAL;
-
-       /* check src bounds */
-       } else if (drm_rect_width(&pipe_cfg->src_rect) < min_src_size ||
-                  drm_rect_height(&pipe_cfg->src_rect) < min_src_size) {
-               DPU_DEBUG_PLANE(pdpu, "invalid source " DRM_RECT_FMT "\n",
-                               DRM_RECT_ARG(&pipe_cfg->src_rect));
-               return -E2BIG;
-
-       /* valid yuv image */
-       } else if (DPU_FORMAT_IS_YUV(fmt) &&
-                  (pipe_cfg->src_rect.x1 & 0x1 || pipe_cfg->src_rect.y1 & 0x1 
||
-                   drm_rect_width(&pipe_cfg->src_rect) & 0x1 ||
-                   drm_rect_height(&pipe_cfg->src_rect) & 0x1)) {
-               DPU_DEBUG_PLANE(pdpu, "invalid yuv source " DRM_RECT_FMT "\n",
-                               DRM_RECT_ARG(&pipe_cfg->src_rect));
-               return -EINVAL;
-
-       /* min dst support */
-       } else if (drm_rect_width(&pipe_cfg->dst_rect) < 0x1 || 
drm_rect_height(&pipe_cfg->dst_rect) < 0x1) {
-               DPU_DEBUG_PLANE(pdpu, "invalid dest rect " DRM_RECT_FMT "\n",
-                               DRM_RECT_ARG(&pipe_cfg->dst_rect));
-               return -EINVAL;
-
-       /* check decimated source width */
-       } else if (drm_rect_width(&pipe_cfg->src_rect) > max_linewidth) {
-               DPU_DEBUG_PLANE(pdpu, "invalid src " DRM_RECT_FMT " line:%u\n",
-                               DRM_RECT_ARG(&pipe_cfg->src_rect), 
max_linewidth);
-               return -E2BIG;
-       }
+       ret = dpu_plane_atomic_check_pipe(pdpu, pipe, pipe_cfg, max_linewidth, 
fmt);
+       if (ret)
+               return ret;
 
        pstate->needs_qos_remap = drm_atomic_crtc_needs_modeset(crtc_state);
 
@@ -1028,51 +1039,18 @@ void dpu_plane_set_error(struct drm_plane *plane, bool 
error)
        pdpu->is_error = error;
 }
 
-static void dpu_plane_sspp_atomic_update(struct drm_plane *plane)
+static void dpu_plane_atomic_update_pipe(
+               struct dpu_sw_pipe *pipe,
+               struct dpu_hw_pipe_cfg *pipe_cfg,
+               unsigned int plane_rotation,
+               struct dpu_hw_fmt_layout *layout,
+               const struct dpu_format *fmt,
+               const struct dpu_mdss_cfg *catalog)
 {
-       uint32_t src_flags;
-       struct dpu_plane *pdpu = to_dpu_plane(plane);
-       struct drm_plane_state *state = plane->state;
-       struct dpu_plane_state *pstate = to_dpu_plane_state(state);
-       struct dpu_sw_pipe *pipe = &pstate->pipe;
-       struct drm_crtc *crtc = state->crtc;
-       struct drm_framebuffer *fb = state->fb;
-       bool is_rt_pipe, update_qos_remap;
-       const struct dpu_format *fmt =
-               to_dpu_format(msm_framebuffer_format(fb));
-       struct dpu_hw_pipe_cfg *pipe_cfg = &pstate->pipe_cfg;
-       struct dpu_hw_fmt_layout layout;
-       struct dpu_kms *kms = _dpu_plane_get_kms(&pdpu->base);
-       struct msm_gem_address_space *aspace = kms->base.aspace;
-       bool update_src_addr = true;
-       int ret;
-
-       ret = dpu_format_populate_layout(aspace, fb, &layout);
-       if (ret) {
-               DPU_ERROR_PLANE(pdpu, "failed to get format layout, %d\n", ret);
-               update_src_addr = false;
-       }
-
-       if (update_src_addr &&
+       if (layout &&
            pipe->sspp->ops.setup_sourceaddress) {
-               trace_dpu_plane_set_scanout(pipe, &layout);
-               pipe->sspp->ops.setup_sourceaddress(pipe, &layout);
-       }
-
-       pstate->pending = true;
-
-       is_rt_pipe = (dpu_crtc_get_client_type(crtc) != NRT_CLIENT);
-       _dpu_plane_set_qos_ctrl(plane, pipe, false, DPU_PLANE_QOS_PANIC_CTRL);
-
-       DPU_DEBUG_PLANE(pdpu, "FB[%u] " DRM_RECT_FP_FMT "->crtc%u " DRM_RECT_FMT
-                       ", %4.4s ubwc %d\n", fb->base.id, 
DRM_RECT_FP_ARG(&state->src),
-                       crtc->base.id, DRM_RECT_ARG(&state->dst),
-                       (char *)&fmt->base.pixel_format, 
DPU_FORMAT_IS_UBWC(fmt));
-
-       /* override for color fill */
-       if (pdpu->color_fill & DPU_PLANE_COLOR_FILL_FLAG) {
-               /* skip remaining processing on color fill */
-               return;
+               trace_dpu_plane_set_scanout(pipe, layout);
+               pipe->sspp->ops.setup_sourceaddress(pipe, layout);
        }
 
        if (pipe->sspp->ops.setup_rects) {
@@ -1088,10 +1066,11 @@ static void dpu_plane_sspp_atomic_update(struct 
drm_plane *plane)
 
        if (pipe->sspp->ops.setup_format) {
                unsigned int rotation;
+               uint32_t src_flags;
 
                src_flags = 0x0;
 
-               rotation = drm_rotation_simplify(state->rotation,
+               rotation = drm_rotation_simplify(plane_rotation,
                                                 DRM_MODE_ROTATE_0 |
                                                 DRM_MODE_REFLECT_X |
                                                 DRM_MODE_REFLECT_Y);
@@ -1110,7 +1089,7 @@ static void dpu_plane_sspp_atomic_update(struct drm_plane 
*plane)
 
                        memset(&cdp_cfg, 0, sizeof(struct dpu_hw_pipe_cdp_cfg));
 
-                       cdp_cfg.enable = pdpu->catalog->perf.cdp_cfg
+                       cdp_cfg.enable = catalog->perf.cdp_cfg
                                        [DPU_PERF_CDP_USAGE_RT].rd_enable;
                        cdp_cfg.ubwc_meta_enable =
                                        DPU_FORMAT_IS_UBWC(fmt);
@@ -1122,29 +1101,93 @@ static void dpu_plane_sspp_atomic_update(struct 
drm_plane *plane)
                        pipe->sspp->ops.setup_cdp(pipe, &cdp_cfg);
                }
        }
+}
+
+static void dpu_plane_atomic_update_qos(
+               struct drm_plane *plane,
+               struct dpu_plane_state *pstate,
+               struct dpu_sw_pipe *pipe,
+               struct dpu_hw_pipe_cfg *pipe_cfg,
+               const struct dpu_format *fmt,
+               const struct drm_display_mode *mode,
+               bool is_rt_pipe
+               )
+{
+       struct dpu_plane *pdpu = to_dpu_plane(plane);
+       bool update_qos_remap;
+
+       update_qos_remap = (is_rt_pipe != pdpu->is_rt_pipe) ||
+                       pstate->needs_qos_remap;
+
+       if (is_rt_pipe != pdpu->is_rt_pipe)
+               pdpu->is_rt_pipe = is_rt_pipe;
+       if (pstate->needs_qos_remap)
+               pstate->needs_qos_remap = false;
 
-       _dpu_plane_set_qos_lut(plane, pipe, fmt, &pstate->pipe_cfg);
+       _dpu_plane_set_qos_lut(plane, pipe, fmt, pipe_cfg);
        _dpu_plane_set_danger_lut(plane, pipe, fmt);
 
        if (plane->type != DRM_PLANE_TYPE_CURSOR) {
                _dpu_plane_set_qos_ctrl(plane, pipe, true, 
DPU_PLANE_QOS_PANIC_CTRL);
-               _dpu_plane_set_ot_limit(plane, pipe, crtc, &pstate->pipe_cfg);
+               _dpu_plane_set_ot_limit(plane, pipe, pipe_cfg, mode);
        }
 
-       update_qos_remap = (is_rt_pipe != pdpu->is_rt_pipe) ||
-                       pstate->needs_qos_remap;
-
-       if (update_qos_remap) {
-               if (is_rt_pipe != pdpu->is_rt_pipe)
-                       pdpu->is_rt_pipe = is_rt_pipe;
-               else if (pstate->needs_qos_remap)
-                       pstate->needs_qos_remap = false;
+       if (update_qos_remap)
                _dpu_plane_set_qos_remap(plane, pipe);
+}
+
+static void dpu_plane_sspp_atomic_update(struct drm_plane *plane)
+{
+       struct dpu_plane *pdpu = to_dpu_plane(plane);
+       struct drm_plane_state *state = plane->state;
+       struct dpu_plane_state *pstate = to_dpu_plane_state(state);
+       struct dpu_sw_pipe *pipe = &pstate->pipe;
+       struct drm_crtc *crtc = state->crtc;
+       struct drm_framebuffer *fb = state->fb;
+       bool is_rt_pipe;
+       const struct dpu_format *fmt =
+               to_dpu_format(msm_framebuffer_format(fb));
+       struct dpu_hw_pipe_cfg *pipe_cfg = &pstate->pipe_cfg;
+       struct dpu_hw_fmt_layout layout;
+       struct dpu_kms *kms = _dpu_plane_get_kms(&pdpu->base);
+       struct msm_gem_address_space *aspace = kms->base.aspace;
+       bool update_src_addr = true;
+       int ret;
+
+       ret = dpu_format_populate_layout(aspace, fb, &layout);
+       if (ret) {
+               DPU_ERROR_PLANE(pdpu, "failed to get format layout, %d\n", ret);
+               update_src_addr = false;
        }
 
-       _dpu_plane_calc_bw(plane, fmt, &pstate->pipe_cfg);
+       pstate->pending = true;
+
+       is_rt_pipe = (dpu_crtc_get_client_type(crtc) != NRT_CLIENT);
+       _dpu_plane_set_qos_ctrl(plane, pipe, false, DPU_PLANE_QOS_PANIC_CTRL);
+
+       DPU_DEBUG_PLANE(pdpu, "FB[%u] " DRM_RECT_FP_FMT "->crtc%u " DRM_RECT_FMT
+                       ", %4.4s ubwc %d\n", fb->base.id, 
DRM_RECT_FP_ARG(&state->src),
+                       crtc->base.id, DRM_RECT_ARG(&state->dst),
+                       (char *)&fmt->base.pixel_format, 
DPU_FORMAT_IS_UBWC(fmt));
+
+       /* override for color fill */
+       if (pdpu->color_fill & DPU_PLANE_COLOR_FILL_FLAG) {
+               /* skip remaining processing on color fill */
+               return;
+       }
+
+       dpu_plane_atomic_update_pipe(pipe, pipe_cfg,
+                       state->rotation,
+                       update_src_addr ? &layout : NULL,
+                       fmt, pdpu->catalog);
+
+       dpu_plane_atomic_update_qos(plane, pstate,
+                       pipe, pipe_cfg,
+                       fmt, &crtc->mode, is_rt_pipe);
+
+       pstate->plane_fetch_bw = _dpu_plane_calc_bw(pdpu->catalog, fmt, 
&crtc->mode, pipe_cfg);
 
-       _dpu_plane_calc_clk(plane, &pstate->pipe_cfg);
+       pstate->plane_clk = _dpu_plane_calc_clk(&crtc->mode, pipe_cfg);
 }
 
 static void _dpu_plane_atomic_disable(struct drm_plane *plane)
-- 
2.34.1

Reply via email to