/* update sspp */
        _dpu_plane_color_fill_pipe(pstate, &pstate->pipe, &pstate->pipe_cfg.dst_rect,
                                   fill_color, fmt);
+
+       if (pstate->r_pipe.sspp)
+               _dpu_plane_color_fill_pipe(pstate, &pstate->r_pipe, &pstate->r_pipe_cfg.dst_rect,
+                                          fill_color, fmt);
 }
 
 int dpu_plane_validate_multirect_v2(struct dpu_multirect_plane_states *plane)
        int ret = 0, min_scale;
        struct dpu_plane *pdpu = to_dpu_plane(plane);
        struct dpu_plane_state *pstate = to_dpu_plane_state(new_plane_state);
+       struct dpu_sw_pipe *pipe = &pstate->pipe;
+       struct dpu_sw_pipe *r_pipe = &pstate->r_pipe;
        const struct drm_crtc_state *crtc_state = NULL;
        const struct dpu_format *fmt;
        struct dpu_sw_pipe_cfg *pipe_cfg = &pstate->pipe_cfg;
+       struct dpu_sw_pipe_cfg *r_pipe_cfg = &pstate->r_pipe_cfg;
        struct drm_rect fb_rect = { 0 };
        uint32_t max_linewidth;
        unsigned int rotation;
        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;
+       r_pipe->multirect_index = DPU_SSPP_RECT_SOLO;
+       r_pipe->multirect_mode = DPU_SSPP_MULTIRECT_NONE;
+       r_pipe->sspp = NULL;
 
        pstate->stage = DPU_STAGE_0 + pstate->base.normalized_zpos;
        if (pstate->stage >= pdpu->catalog->caps->max_mixer_blendstages) {
                return -E2BIG;
        }
 
+       fmt = to_dpu_format(msm_framebuffer_format(new_plane_state->fb));
+
        max_linewidth = pdpu->catalog->caps->max_linewidth;
 
-       /* check decimated source width */
        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;
-       }
+               /*
+                * In parallel multirect case only the half of the usual width
+                * is supported for tiled formats. If we are here, we know that
+                * full width is more than max_linewidth, thus each rect is
+                * wider than allowed.
+                */
+               if (DPU_FORMAT_IS_UBWC(fmt)) {
+                       DPU_DEBUG_PLANE(pdpu, "invalid src " DRM_RECT_FMT " line:%u, tiled format\n",
+                                       DRM_RECT_ARG(&pipe_cfg->src_rect), max_linewidth);
+                       return -E2BIG;
+               }
 
-       fmt = to_dpu_format(msm_framebuffer_format(new_plane_state->fb));
+               if (drm_rect_width(&pipe_cfg->src_rect) > 2 * 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, &pstate->pipe, pipe_cfg, fmt);
+               if (drm_rect_width(&pipe_cfg->src_rect) != drm_rect_width(&pipe_cfg->dst_rect) ||
+                   drm_rect_height(&pipe_cfg->src_rect) != drm_rect_height(&pipe_cfg->dst_rect) ||
+                   (!test_bit(DPU_SSPP_SMART_DMA_V1, &pipe->sspp->cap->features) &&
+                    !test_bit(DPU_SSPP_SMART_DMA_V2, &pipe->sspp->cap->features)) ||
+                   DPU_FORMAT_IS_YUV(fmt)) {
+                       DPU_DEBUG_PLANE(pdpu, "invalid src " DRM_RECT_FMT " line:%u, can't use split source\n",
+                                       DRM_RECT_ARG(&pipe_cfg->src_rect), max_linewidth);
+                       return -E2BIG;
+               }
+
+               /*
+                * Use multirect for wide plane. We do not support dynamic
+                * assignment of SSPPs, so we know the configuration.
+                */
+               pipe->multirect_index = DPU_SSPP_RECT_0;
+               pipe->multirect_mode = DPU_SSPP_MULTIRECT_PARALLEL;
+
+               r_pipe->sspp = pipe->sspp;
+               r_pipe->multirect_index = DPU_SSPP_RECT_1;
+               r_pipe->multirect_mode = DPU_SSPP_MULTIRECT_PARALLEL;
+
+               *r_pipe_cfg = *pipe_cfg;
+               pipe_cfg->src_rect.x2 = (pipe_cfg->src_rect.x1 + pipe_cfg->src_rect.x2) >> 1;
+               pipe_cfg->dst_rect.x2 = (pipe_cfg->dst_rect.x1 + pipe_cfg->dst_rect.x2) >> 1;
+               r_pipe_cfg->src_rect.x1 = pipe_cfg->src_rect.x2;
+               r_pipe_cfg->dst_rect.x1 = pipe_cfg->dst_rect.x2;
+       }
+
+       ret = dpu_plane_atomic_check_pipe(pdpu, pipe, pipe_cfg, fmt);
        if (ret)
                return ret;
 
+       if (r_pipe->sspp) {
+               ret = dpu_plane_atomic_check_pipe(pdpu, r_pipe, r_pipe_cfg, fmt);
+               if (ret)
+                       return ret;
+       }
+
        supported_rotations = DRM_MODE_REFLECT_MASK | DRM_MODE_ROTATE_0;
 
        if (pipe_hw_caps->features & BIT(DPU_SSPP_INLINE_ROTATION))
        else if (pdpu->color_fill & DPU_PLANE_COLOR_FILL_FLAG)
                /* force 100% alpha */
                _dpu_plane_color_fill(pdpu, pdpu->color_fill, 0xFF);
-       else
+       else {
                dpu_plane_flush_csc(pdpu, &pstate->pipe);
+               dpu_plane_flush_csc(pdpu, &pstate->r_pipe);
+       }
 
        /* flag h/w flush complete */
        if (plane->state)
        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 dpu_sw_pipe *r_pipe = &pstate->r_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_sw_pipe_cfg *pipe_cfg = &pstate->pipe_cfg;
-
+       struct dpu_sw_pipe_cfg *r_pipe_cfg = &pstate->r_pipe_cfg;
        struct dpu_kms *kms = _dpu_plane_get_kms(&pdpu->base);
        struct msm_gem_address_space *aspace = kms->base.aspace;
        struct dpu_hw_fmt_layout layout;
                                   drm_mode_vrefresh(&crtc->mode),
                                   layout_valid ? &layout : NULL);
 
+       if (r_pipe->sspp) {
+               dpu_plane_sspp_update_pipe(plane, r_pipe, r_pipe_cfg, fmt,
+                                          drm_mode_vrefresh(&crtc->mode),
+                                          layout_valid ? &layout : NULL);
+       }
+
        if (pstate->needs_qos_remap)
                pstate->needs_qos_remap = false;
 
                                                    &crtc->mode, pipe_cfg);
 
        pstate->plane_clk = _dpu_plane_calc_clk(&crtc->mode, pipe_cfg);
+
+       if (r_pipe->sspp) {
+               pstate->plane_fetch_bw += _dpu_plane_calc_bw(pdpu->catalog, fmt, &crtc->mode, r_pipe_cfg);
+
+               pstate->plane_clk = max(pstate->plane_clk, _dpu_plane_calc_clk(&crtc->mode, r_pipe_cfg));
+       }
 }
 
 static void _dpu_plane_atomic_disable(struct drm_plane *plane)
 {
        struct drm_plane_state *state = plane->state;
        struct dpu_plane_state *pstate = to_dpu_plane_state(state);
+       struct dpu_sw_pipe *r_pipe = &pstate->r_pipe;
 
        trace_dpu_plane_disable(DRMID(plane), false,
                                pstate->pipe.multirect_mode);
 
+       if (r_pipe->sspp) {
+               r_pipe->multirect_index = DPU_SSPP_RECT_SOLO;
+               r_pipe->multirect_mode = DPU_SSPP_MULTIRECT_NONE;
+
+               if (r_pipe->sspp->ops.setup_multirect)
+                       r_pipe->sspp->ops.setup_multirect(r_pipe);
+       }
+
        pstate->pending = true;
 }
 
                pstate = to_dpu_plane_state(plane->state);
                _dpu_plane_set_qos_ctrl(plane, &pstate->pipe, false, DPU_PLANE_QOS_PANIC_CTRL);
 
+               if (pstate->r_pipe.sspp)
+                       _dpu_plane_set_qos_ctrl(plane, &pstate->r_pipe, false, DPU_PLANE_QOS_PANIC_CTRL);
+
                mutex_destroy(&pdpu->lock);
 
                /* this will destroy the states as well */
                const struct drm_plane_state *state)
 {
        const struct dpu_plane_state *pstate = to_dpu_plane_state(state);
+       const struct dpu_sw_pipe *pipe = &pstate->pipe;
+       const struct dpu_sw_pipe_cfg *pipe_cfg = &pstate->pipe_cfg;
+       const struct dpu_sw_pipe *r_pipe = &pstate->r_pipe;
+       const struct dpu_sw_pipe_cfg *r_pipe_cfg = &pstate->r_pipe_cfg;
 
        drm_printf(p, "\tstage=%d\n", pstate->stage);
-       drm_printf(p, "\tsspp=%s\n", pstate->pipe.sspp->cap->name);
-       drm_printf(p, "\tmultirect_mode=%s\n", dpu_get_multirect_mode(pstate->pipe.multirect_mode));
-       drm_printf(p, "\tmultirect_index=%s\n",
-                  dpu_get_multirect_index(pstate->pipe.multirect_index));
+
+       drm_printf(p, "\tsspp[0]=%s\n", pipe->sspp->cap->name);
+       drm_printf(p, "\tmultirect_mode[0]=%s\n", dpu_get_multirect_mode(pipe->multirect_mode));
+       drm_printf(p, "\tmultirect_index[0]=%s\n",
+                  dpu_get_multirect_index(pipe->multirect_index));
+       drm_printf(p, "\tsrc[0]=" DRM_RECT_FMT "\n", DRM_RECT_ARG(&pipe_cfg->src_rect));
+       drm_printf(p, "\tdst[0]=" DRM_RECT_FMT "\n", DRM_RECT_ARG(&pipe_cfg->dst_rect));
+
+       if (r_pipe->sspp) {
+               drm_printf(p, "\tsspp[1]=%s\n", r_pipe->sspp->cap->name);
+               drm_printf(p, "\tmultirect_mode[1]=%s\n",
+                          dpu_get_multirect_mode(r_pipe->multirect_mode));
+               drm_printf(p, "\tmultirect_index[1]=%s\n",
+                          dpu_get_multirect_index(r_pipe->multirect_index));
+               drm_printf(p, "\tsrc[1]=" DRM_RECT_FMT "\n", DRM_RECT_ARG(&r_pipe_cfg->src_rect));
+               drm_printf(p, "\tdst[1]=" DRM_RECT_FMT "\n", DRM_RECT_ARG(&r_pipe_cfg->dst_rect));
+       }
 }
 
 static void dpu_plane_reset(struct drm_plane *plane)
         * This is the place where the state is allocated, so fill it fully.
         */
        pstate->pipe.sspp = dpu_rm_get_sspp(&dpu_kms->rm, pdpu->pipe);
+       pstate->pipe.multirect_index = DPU_SSPP_RECT_SOLO;
+       pstate->pipe.multirect_mode = DPU_SSPP_MULTIRECT_NONE;
+
+       pstate->r_pipe.sspp = NULL;
 
        __drm_atomic_helper_plane_reset(plane, &pstate->base);
 }
 
        pm_runtime_get_sync(&dpu_kms->pdev->dev);
        _dpu_plane_set_qos_ctrl(plane, &pstate->pipe, enable, DPU_PLANE_QOS_PANIC_CTRL);
+       if (pstate->r_pipe.sspp)
+               _dpu_plane_set_qos_ctrl(plane, &pstate->r_pipe, enable, DPU_PLANE_QOS_PANIC_CTRL);
        pm_runtime_put_sync(&dpu_kms->pdev->dev);
 }
 #endif