Loading drivers/gpu/drm/msm/sde/sde_crtc.c +18 −18 Original line number Diff line number Diff line Loading @@ -1112,12 +1112,11 @@ static void _sde_crtc_blend_setup_mixer(struct drm_crtc *crtc, struct sde_hw_stage_cfg *stage_cfg; struct sde_rect plane_crtc_roi; u32 flush_mask = 0; u32 flush_mask, flush_sbuf, flush_tmp; uint32_t lm_idx = LEFT_MIXER, stage_idx; bool bg_alpha_enable[CRTC_DUAL_MIXERS] = {false}; int zpos_cnt[CRTC_DUAL_MIXERS][SDE_STAGE_MAX + 1] = { {0} }; int i; bool sbuf_mode = false; u32 prefill = 0; if (!sde_crtc || !mixer) { Loading @@ -1129,6 +1128,10 @@ static void _sde_crtc_blend_setup_mixer(struct drm_crtc *crtc, lm = mixer->hw_lm; stage_cfg = &sde_crtc->stage_cfg; cstate = to_sde_crtc_state(crtc->state); flush_sbuf = 0x0; cstate->sbuf_cfg.rot_op_mode = SDE_CTL_ROT_OP_MODE_OFFLINE; cstate->sbuf_prefill_line = 0; drm_atomic_crtc_for_each_plane(plane, crtc) { state = plane->state; Loading @@ -1144,10 +1147,16 @@ static void _sde_crtc_blend_setup_mixer(struct drm_crtc *crtc, fb = state->fb; if (sde_plane_is_sbuf_mode(plane, &prefill)) sbuf_mode = true; cstate->sbuf_cfg.rot_op_mode = SDE_CTL_ROT_OP_MODE_INLINE_SYNC; if (prefill > cstate->sbuf_prefill_line) cstate->sbuf_prefill_line = prefill; sde_plane_get_ctl_flush(plane, ctl, &flush_mask); sde_plane_get_ctl_flush(plane, ctl, &flush_mask, &flush_tmp); /* persist rotator flush bit(s) for one more commit */ flush_mask |= cstate->sbuf_flush_mask | flush_tmp; flush_sbuf |= flush_tmp; SDE_DEBUG("crtc %d stage:%d - plane %d sspp %d fb %d\n", crtc->base.id, Loading @@ -1163,7 +1172,8 @@ static void _sde_crtc_blend_setup_mixer(struct drm_crtc *crtc, state->src_x >> 16, state->src_y >> 16, state->src_w >> 16, state->src_h >> 16, state->crtc_x, state->crtc_y, state->crtc_w, state->crtc_h); state->crtc_w, state->crtc_h, cstate->sbuf_cfg.rot_op_mode); for (lm_idx = 0; lm_idx < sde_crtc->num_mixers; lm_idx++) { struct sde_rect intersect; Loading Loading @@ -1208,6 +1218,8 @@ static void _sde_crtc_blend_setup_mixer(struct drm_crtc *crtc, } } cstate->sbuf_flush_mask = flush_sbuf; if (lm && lm->ops.setup_dim_layer) { cstate = to_sde_crtc_state(crtc->state); for (i = 0; i < cstate->num_dim_layers; i++) Loading @@ -1215,20 +1227,8 @@ static void _sde_crtc_blend_setup_mixer(struct drm_crtc *crtc, mixer, &cstate->dim_layer[i]); } if (ctl->ops.setup_sbuf_cfg) { cstate = to_sde_crtc_state(crtc->state); if (!sbuf_mode) { cstate->sbuf_cfg.rot_op_mode = SDE_CTL_ROT_OP_MODE_OFFLINE; cstate->sbuf_prefill_line = 0; } else { cstate->sbuf_cfg.rot_op_mode = SDE_CTL_ROT_OP_MODE_INLINE_SYNC; cstate->sbuf_prefill_line = prefill; } if (ctl->ops.setup_sbuf_cfg) ctl->ops.setup_sbuf_cfg(ctl, &cstate->sbuf_cfg); } _sde_crtc_program_lm_output_roi(crtc); } Loading drivers/gpu/drm/msm/sde/sde_crtc.h +8 −2 Original line number Diff line number Diff line Loading @@ -272,6 +272,7 @@ struct sde_crtc_respool { * @new_perf: new performance state * @sbuf_cfg: stream buffer configuration * @sbuf_prefill_line: number of line for inline rotator prefetch * @sbuf_flush_mask: flush mask for inline rotator */ struct sde_crtc_state { struct drm_crtc_state base; Loading @@ -298,7 +299,8 @@ struct sde_crtc_state { struct sde_core_perf_params cur_perf; struct sde_core_perf_params new_perf; struct sde_ctl_sbuf_cfg sbuf_cfg; u64 sbuf_prefill_line; u32 sbuf_prefill_line; u32 sbuf_flush_mask; struct sde_crtc_respool rp; }; Loading Loading @@ -433,10 +435,14 @@ static inline bool sde_crtc_is_enabled(struct drm_crtc *crtc) */ static inline u32 sde_crtc_get_inline_prefill(struct drm_crtc *crtc) { struct sde_crtc_state *cstate; if (!crtc || !crtc->state) return 0; return to_sde_crtc_state(crtc->state)->sbuf_prefill_line; cstate = to_sde_crtc_state(crtc->state); return cstate->sbuf_cfg.rot_op_mode != SDE_CTL_ROT_OP_MODE_OFFLINE ? cstate->sbuf_prefill_line : 0; } /** Loading drivers/gpu/drm/msm/sde/sde_encoder_phys_vid.c +11 −3 Original line number Diff line number Diff line Loading @@ -222,7 +222,7 @@ static void programmable_fetch_config(struct sde_encoder_phys *phys_enc, * @rot_fetch_lines: number of line to prefill, or 0 to disable */ static void programmable_rot_fetch_config(struct sde_encoder_phys *phys_enc, u64 rot_fetch_lines) u32 rot_fetch_lines) { struct sde_encoder_phys_vid *vid_enc = to_sde_encoder_phys_vid(phys_enc); Loading @@ -232,9 +232,12 @@ static void programmable_rot_fetch_config(struct sde_encoder_phys *phys_enc, u32 horiz_total = 0; u32 vert_total = 0; u32 rot_fetch_start_vsync_counter = 0; u32 flush_mask = 0; unsigned long lock_flags; if (!phys_enc || !vid_enc->hw_intf || if (!phys_enc || !vid_enc->hw_intf || !phys_enc->hw_ctl || !phys_enc->hw_ctl->ops.get_bitmask_intf || !phys_enc->hw_ctl->ops.update_pending_flush || !vid_enc->hw_intf->ops.setup_rot_start) return; Loading @@ -253,9 +256,14 @@ static void programmable_rot_fetch_config(struct sde_encoder_phys *phys_enc, } SDE_DEBUG_VIDENC(vid_enc, "rot_fetch_lines %llu rot_fetch_start_vsync_counter %u\n", "rot_fetch_lines %u rot_fetch_start_vsync_counter %u\n", rot_fetch_lines, rot_fetch_start_vsync_counter); phys_enc->hw_ctl->ops.get_bitmask_intf( phys_enc->hw_ctl, &flush_mask, vid_enc->hw_intf->idx); phys_enc->hw_ctl->ops.update_pending_flush( phys_enc->hw_ctl, flush_mask); spin_lock_irqsave(phys_enc->enc_spinlock, lock_flags); vid_enc->hw_intf->ops.setup_rot_start(vid_enc->hw_intf, &f); spin_unlock_irqrestore(phys_enc->enc_spinlock, lock_flags); Loading drivers/gpu/drm/msm/sde/sde_plane.c +18 −18 Original line number Diff line number Diff line Loading @@ -1368,33 +1368,31 @@ static struct sde_crtc_res_ops fbo_res_ops = { static u32 sde_plane_rot_calc_prefill(struct drm_plane *plane) { struct drm_plane_state *state; struct drm_crtc_state *cstate; struct sde_plane_state *pstate; struct sde_plane_rot_state *rstate; struct sde_kms *sde_kms; u32 blocksize = 128; u32 prefill_line = 0; if (!plane || !plane->state || !plane->state->fb || !plane->state->crtc || !plane->state->crtc->state) { if (!plane || !plane->state || !plane->state->fb) { SDE_ERROR("invalid parameters\n"); return 0; } sde_kms = _sde_plane_get_kms(plane); state = plane->state; cstate = state->crtc->state; pstate = to_sde_plane_state(state); rstate = &pstate->rot; if (!rstate->rot_hw || !rstate->rot_hw->caps || !rstate->out_src_h || !sde_kms || !sde_kms->catalog) { SDE_ERROR("invalid parameters\n"); if (!sde_kms || !sde_kms->catalog) { SDE_ERROR("invalid kms\n"); return 0; } sde_format_get_block_size(rstate->out_fb_format, &blocksize, &blocksize); if (rstate->out_fb_format) sde_format_get_block_size(rstate->out_fb_format, &blocksize, &blocksize); prefill_line = blocksize + sde_kms->catalog->sbuf_headroom; SDE_DEBUG("plane%d prefill:%u\n", plane->base.id, prefill_line); Loading @@ -1416,7 +1414,7 @@ bool sde_plane_is_sbuf_mode(struct drm_plane *plane, u32 *prefill) struct sde_plane_rot_state *rstate = pstate ? &pstate->rot : NULL; bool sbuf_mode = rstate ? rstate->out_sbuf : false; if (prefill && sbuf_mode) if (prefill) *prefill = sde_plane_rot_calc_prefill(plane); return sbuf_mode; Loading Loading @@ -2447,16 +2445,16 @@ int sde_plane_validate_multirect_v2(struct sde_multirect_plane_states *plane) * sde_plane_get_ctl_flush - get control flush for the given plane * @plane: Pointer to drm plane structure * @ctl: Pointer to hardware control driver * @flush: Pointer to flush control word * @flush_sspp: Pointer to sspp flush control word * @flush_rot: Pointer to rotator flush control word */ void sde_plane_get_ctl_flush(struct drm_plane *plane, struct sde_hw_ctl *ctl, u32 *flush) u32 *flush_sspp, u32 *flush_rot) { struct sde_plane_state *pstate; struct sde_plane_rot_state *rstate; u32 bitmask; if (!plane || !flush) { if (!plane || !flush_sspp) { SDE_ERROR("invalid parameters\n"); return; } Loading @@ -2464,13 +2462,15 @@ void sde_plane_get_ctl_flush(struct drm_plane *plane, struct sde_hw_ctl *ctl, pstate = to_sde_plane_state(plane->state); rstate = &pstate->rot; bitmask = ctl->ops.get_bitmask_sspp(ctl, sde_plane_pipe(plane)); *flush_sspp = ctl->ops.get_bitmask_sspp(ctl, sde_plane_pipe(plane)); if (!flush_rot) return; *flush_rot = 0x0; if (sde_plane_is_sbuf_mode(plane, NULL) && rstate->rot_hw && ctl->ops.get_bitmask_rot) ctl->ops.get_bitmask_rot(ctl, &bitmask, rstate->rot_hw->idx); *flush = bitmask; ctl->ops.get_bitmask_rot(ctl, flush_rot, rstate->rot_hw->idx); } static int sde_plane_prepare_fb(struct drm_plane *plane, Loading drivers/gpu/drm/msm/sde/sde_plane.h +3 −2 Original line number Diff line number Diff line Loading @@ -172,10 +172,11 @@ bool is_sde_plane_virtual(struct drm_plane *plane); * sde_plane_get_ctl_flush - get control flush mask * @plane: Pointer to DRM plane object * @ctl: Pointer to control hardware * @flush: Pointer to updated flush mask * @flush_sspp: Pointer to sspp flush control word * @flush_rot: Pointer to rotator flush control word */ void sde_plane_get_ctl_flush(struct drm_plane *plane, struct sde_hw_ctl *ctl, u32 *flush); u32 *flush_sspp, u32 *flush_rot); /** * sde_plane_is_sbuf_mode - return status of stream buffer mode Loading Loading
drivers/gpu/drm/msm/sde/sde_crtc.c +18 −18 Original line number Diff line number Diff line Loading @@ -1112,12 +1112,11 @@ static void _sde_crtc_blend_setup_mixer(struct drm_crtc *crtc, struct sde_hw_stage_cfg *stage_cfg; struct sde_rect plane_crtc_roi; u32 flush_mask = 0; u32 flush_mask, flush_sbuf, flush_tmp; uint32_t lm_idx = LEFT_MIXER, stage_idx; bool bg_alpha_enable[CRTC_DUAL_MIXERS] = {false}; int zpos_cnt[CRTC_DUAL_MIXERS][SDE_STAGE_MAX + 1] = { {0} }; int i; bool sbuf_mode = false; u32 prefill = 0; if (!sde_crtc || !mixer) { Loading @@ -1129,6 +1128,10 @@ static void _sde_crtc_blend_setup_mixer(struct drm_crtc *crtc, lm = mixer->hw_lm; stage_cfg = &sde_crtc->stage_cfg; cstate = to_sde_crtc_state(crtc->state); flush_sbuf = 0x0; cstate->sbuf_cfg.rot_op_mode = SDE_CTL_ROT_OP_MODE_OFFLINE; cstate->sbuf_prefill_line = 0; drm_atomic_crtc_for_each_plane(plane, crtc) { state = plane->state; Loading @@ -1144,10 +1147,16 @@ static void _sde_crtc_blend_setup_mixer(struct drm_crtc *crtc, fb = state->fb; if (sde_plane_is_sbuf_mode(plane, &prefill)) sbuf_mode = true; cstate->sbuf_cfg.rot_op_mode = SDE_CTL_ROT_OP_MODE_INLINE_SYNC; if (prefill > cstate->sbuf_prefill_line) cstate->sbuf_prefill_line = prefill; sde_plane_get_ctl_flush(plane, ctl, &flush_mask); sde_plane_get_ctl_flush(plane, ctl, &flush_mask, &flush_tmp); /* persist rotator flush bit(s) for one more commit */ flush_mask |= cstate->sbuf_flush_mask | flush_tmp; flush_sbuf |= flush_tmp; SDE_DEBUG("crtc %d stage:%d - plane %d sspp %d fb %d\n", crtc->base.id, Loading @@ -1163,7 +1172,8 @@ static void _sde_crtc_blend_setup_mixer(struct drm_crtc *crtc, state->src_x >> 16, state->src_y >> 16, state->src_w >> 16, state->src_h >> 16, state->crtc_x, state->crtc_y, state->crtc_w, state->crtc_h); state->crtc_w, state->crtc_h, cstate->sbuf_cfg.rot_op_mode); for (lm_idx = 0; lm_idx < sde_crtc->num_mixers; lm_idx++) { struct sde_rect intersect; Loading Loading @@ -1208,6 +1218,8 @@ static void _sde_crtc_blend_setup_mixer(struct drm_crtc *crtc, } } cstate->sbuf_flush_mask = flush_sbuf; if (lm && lm->ops.setup_dim_layer) { cstate = to_sde_crtc_state(crtc->state); for (i = 0; i < cstate->num_dim_layers; i++) Loading @@ -1215,20 +1227,8 @@ static void _sde_crtc_blend_setup_mixer(struct drm_crtc *crtc, mixer, &cstate->dim_layer[i]); } if (ctl->ops.setup_sbuf_cfg) { cstate = to_sde_crtc_state(crtc->state); if (!sbuf_mode) { cstate->sbuf_cfg.rot_op_mode = SDE_CTL_ROT_OP_MODE_OFFLINE; cstate->sbuf_prefill_line = 0; } else { cstate->sbuf_cfg.rot_op_mode = SDE_CTL_ROT_OP_MODE_INLINE_SYNC; cstate->sbuf_prefill_line = prefill; } if (ctl->ops.setup_sbuf_cfg) ctl->ops.setup_sbuf_cfg(ctl, &cstate->sbuf_cfg); } _sde_crtc_program_lm_output_roi(crtc); } Loading
drivers/gpu/drm/msm/sde/sde_crtc.h +8 −2 Original line number Diff line number Diff line Loading @@ -272,6 +272,7 @@ struct sde_crtc_respool { * @new_perf: new performance state * @sbuf_cfg: stream buffer configuration * @sbuf_prefill_line: number of line for inline rotator prefetch * @sbuf_flush_mask: flush mask for inline rotator */ struct sde_crtc_state { struct drm_crtc_state base; Loading @@ -298,7 +299,8 @@ struct sde_crtc_state { struct sde_core_perf_params cur_perf; struct sde_core_perf_params new_perf; struct sde_ctl_sbuf_cfg sbuf_cfg; u64 sbuf_prefill_line; u32 sbuf_prefill_line; u32 sbuf_flush_mask; struct sde_crtc_respool rp; }; Loading Loading @@ -433,10 +435,14 @@ static inline bool sde_crtc_is_enabled(struct drm_crtc *crtc) */ static inline u32 sde_crtc_get_inline_prefill(struct drm_crtc *crtc) { struct sde_crtc_state *cstate; if (!crtc || !crtc->state) return 0; return to_sde_crtc_state(crtc->state)->sbuf_prefill_line; cstate = to_sde_crtc_state(crtc->state); return cstate->sbuf_cfg.rot_op_mode != SDE_CTL_ROT_OP_MODE_OFFLINE ? cstate->sbuf_prefill_line : 0; } /** Loading
drivers/gpu/drm/msm/sde/sde_encoder_phys_vid.c +11 −3 Original line number Diff line number Diff line Loading @@ -222,7 +222,7 @@ static void programmable_fetch_config(struct sde_encoder_phys *phys_enc, * @rot_fetch_lines: number of line to prefill, or 0 to disable */ static void programmable_rot_fetch_config(struct sde_encoder_phys *phys_enc, u64 rot_fetch_lines) u32 rot_fetch_lines) { struct sde_encoder_phys_vid *vid_enc = to_sde_encoder_phys_vid(phys_enc); Loading @@ -232,9 +232,12 @@ static void programmable_rot_fetch_config(struct sde_encoder_phys *phys_enc, u32 horiz_total = 0; u32 vert_total = 0; u32 rot_fetch_start_vsync_counter = 0; u32 flush_mask = 0; unsigned long lock_flags; if (!phys_enc || !vid_enc->hw_intf || if (!phys_enc || !vid_enc->hw_intf || !phys_enc->hw_ctl || !phys_enc->hw_ctl->ops.get_bitmask_intf || !phys_enc->hw_ctl->ops.update_pending_flush || !vid_enc->hw_intf->ops.setup_rot_start) return; Loading @@ -253,9 +256,14 @@ static void programmable_rot_fetch_config(struct sde_encoder_phys *phys_enc, } SDE_DEBUG_VIDENC(vid_enc, "rot_fetch_lines %llu rot_fetch_start_vsync_counter %u\n", "rot_fetch_lines %u rot_fetch_start_vsync_counter %u\n", rot_fetch_lines, rot_fetch_start_vsync_counter); phys_enc->hw_ctl->ops.get_bitmask_intf( phys_enc->hw_ctl, &flush_mask, vid_enc->hw_intf->idx); phys_enc->hw_ctl->ops.update_pending_flush( phys_enc->hw_ctl, flush_mask); spin_lock_irqsave(phys_enc->enc_spinlock, lock_flags); vid_enc->hw_intf->ops.setup_rot_start(vid_enc->hw_intf, &f); spin_unlock_irqrestore(phys_enc->enc_spinlock, lock_flags); Loading
drivers/gpu/drm/msm/sde/sde_plane.c +18 −18 Original line number Diff line number Diff line Loading @@ -1368,33 +1368,31 @@ static struct sde_crtc_res_ops fbo_res_ops = { static u32 sde_plane_rot_calc_prefill(struct drm_plane *plane) { struct drm_plane_state *state; struct drm_crtc_state *cstate; struct sde_plane_state *pstate; struct sde_plane_rot_state *rstate; struct sde_kms *sde_kms; u32 blocksize = 128; u32 prefill_line = 0; if (!plane || !plane->state || !plane->state->fb || !plane->state->crtc || !plane->state->crtc->state) { if (!plane || !plane->state || !plane->state->fb) { SDE_ERROR("invalid parameters\n"); return 0; } sde_kms = _sde_plane_get_kms(plane); state = plane->state; cstate = state->crtc->state; pstate = to_sde_plane_state(state); rstate = &pstate->rot; if (!rstate->rot_hw || !rstate->rot_hw->caps || !rstate->out_src_h || !sde_kms || !sde_kms->catalog) { SDE_ERROR("invalid parameters\n"); if (!sde_kms || !sde_kms->catalog) { SDE_ERROR("invalid kms\n"); return 0; } sde_format_get_block_size(rstate->out_fb_format, &blocksize, &blocksize); if (rstate->out_fb_format) sde_format_get_block_size(rstate->out_fb_format, &blocksize, &blocksize); prefill_line = blocksize + sde_kms->catalog->sbuf_headroom; SDE_DEBUG("plane%d prefill:%u\n", plane->base.id, prefill_line); Loading @@ -1416,7 +1414,7 @@ bool sde_plane_is_sbuf_mode(struct drm_plane *plane, u32 *prefill) struct sde_plane_rot_state *rstate = pstate ? &pstate->rot : NULL; bool sbuf_mode = rstate ? rstate->out_sbuf : false; if (prefill && sbuf_mode) if (prefill) *prefill = sde_plane_rot_calc_prefill(plane); return sbuf_mode; Loading Loading @@ -2447,16 +2445,16 @@ int sde_plane_validate_multirect_v2(struct sde_multirect_plane_states *plane) * sde_plane_get_ctl_flush - get control flush for the given plane * @plane: Pointer to drm plane structure * @ctl: Pointer to hardware control driver * @flush: Pointer to flush control word * @flush_sspp: Pointer to sspp flush control word * @flush_rot: Pointer to rotator flush control word */ void sde_plane_get_ctl_flush(struct drm_plane *plane, struct sde_hw_ctl *ctl, u32 *flush) u32 *flush_sspp, u32 *flush_rot) { struct sde_plane_state *pstate; struct sde_plane_rot_state *rstate; u32 bitmask; if (!plane || !flush) { if (!plane || !flush_sspp) { SDE_ERROR("invalid parameters\n"); return; } Loading @@ -2464,13 +2462,15 @@ void sde_plane_get_ctl_flush(struct drm_plane *plane, struct sde_hw_ctl *ctl, pstate = to_sde_plane_state(plane->state); rstate = &pstate->rot; bitmask = ctl->ops.get_bitmask_sspp(ctl, sde_plane_pipe(plane)); *flush_sspp = ctl->ops.get_bitmask_sspp(ctl, sde_plane_pipe(plane)); if (!flush_rot) return; *flush_rot = 0x0; if (sde_plane_is_sbuf_mode(plane, NULL) && rstate->rot_hw && ctl->ops.get_bitmask_rot) ctl->ops.get_bitmask_rot(ctl, &bitmask, rstate->rot_hw->idx); *flush = bitmask; ctl->ops.get_bitmask_rot(ctl, flush_rot, rstate->rot_hw->idx); } static int sde_plane_prepare_fb(struct drm_plane *plane, Loading
drivers/gpu/drm/msm/sde/sde_plane.h +3 −2 Original line number Diff line number Diff line Loading @@ -172,10 +172,11 @@ bool is_sde_plane_virtual(struct drm_plane *plane); * sde_plane_get_ctl_flush - get control flush mask * @plane: Pointer to DRM plane object * @ctl: Pointer to control hardware * @flush: Pointer to updated flush mask * @flush_sspp: Pointer to sspp flush control word * @flush_rot: Pointer to rotator flush control word */ void sde_plane_get_ctl_flush(struct drm_plane *plane, struct sde_hw_ctl *ctl, u32 *flush); u32 *flush_sspp, u32 *flush_rot); /** * sde_plane_is_sbuf_mode - return status of stream buffer mode Loading