v12.0 DPU on SM8750 comes with new CTL_PIPE_ACTIVE register for selective activation of pipes, which replaces earlier dpu_hw_ctl_setup_blendstage() code path for newer devices. Reviewed-by: Dmitry Baryshkov <dmitry.baryshkov@xxxxxxxxxx> Signed-off-by: Krzysztof Kozlowski <krzysztof.kozlowski@xxxxxxxxxx> --- Changes in v4: 1. Lowercase hex 2. Add Dmitry's tag Changes in v3: 1. New patch, split from previous big DPU v12.0. --- drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c | 9 +++++++++ drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c | 3 +++ drivers/gpu/drm/msm/disp/dpu1/dpu_hw_ctl.c | 29 +++++++++++++++++++++++++++-- drivers/gpu/drm/msm/disp/dpu1/dpu_hw_ctl.h | 8 ++++++++ 4 files changed, 47 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c index 90f47fc15ee5708795701d78a1380f4ab01c1427..3135e5ab9e8121f3dbd93dde9458f007ae45392a 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c @@ -452,8 +452,10 @@ static void _dpu_crtc_blend_setup_mixer(struct drm_crtc *crtc, uint32_t lm_idx; bool bg_alpha_enable = false; DECLARE_BITMAP(active_fetch, SSPP_MAX); + DECLARE_BITMAP(active_pipes, SSPP_MAX); memset(active_fetch, 0, sizeof(active_fetch)); + memset(active_pipes, 0, sizeof(active_pipes)); drm_atomic_crtc_for_each_plane(plane, crtc) { state = plane->state; if (!state) @@ -471,6 +473,7 @@ static void _dpu_crtc_blend_setup_mixer(struct drm_crtc *crtc, bg_alpha_enable = true; set_bit(pstate->pipe.sspp->idx, active_fetch); + set_bit(pstate->pipe.sspp->idx, active_pipes); _dpu_crtc_blend_setup_pipe(crtc, plane, mixer, cstate->num_mixers, pstate->stage, @@ -479,6 +482,7 @@ static void _dpu_crtc_blend_setup_mixer(struct drm_crtc *crtc, if (pstate->r_pipe.sspp) { set_bit(pstate->r_pipe.sspp->idx, active_fetch); + set_bit(pstate->r_pipe.sspp->idx, active_pipes); _dpu_crtc_blend_setup_pipe(crtc, plane, mixer, cstate->num_mixers, pstate->stage, @@ -502,6 +506,9 @@ static void _dpu_crtc_blend_setup_mixer(struct drm_crtc *crtc, if (ctl->ops.set_active_fetch_pipes) ctl->ops.set_active_fetch_pipes(ctl, active_fetch); + if (ctl->ops.set_active_pipes) + ctl->ops.set_active_pipes(ctl, active_pipes); + _dpu_crtc_program_lm_output_roi(crtc); } @@ -528,6 +535,8 @@ static void _dpu_crtc_blend_setup(struct drm_crtc *crtc) mixer[i].lm_ctl); if (mixer[i].lm_ctl->ops.set_active_fetch_pipes) mixer[i].lm_ctl->ops.set_active_fetch_pipes(mixer[i].lm_ctl, NULL); + if (mixer[i].lm_ctl->ops.set_active_pipes) + mixer[i].lm_ctl->ops.set_active_pipes(mixer[i].lm_ctl, NULL); } /* initialize stage cfg */ diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c index ccf492f27140a2841b454d413e885e4bbd9ee497..aec71a86f809afedc2660d66d2cbf4109c302067 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c @@ -2191,6 +2191,9 @@ static void dpu_encoder_helper_reset_mixers(struct dpu_encoder_phys *phys_enc) if (ctl->ops.set_active_fetch_pipes) ctl->ops.set_active_fetch_pipes(ctl, NULL); + + if (ctl->ops.set_active_pipes) + ctl->ops.set_active_pipes(ctl, NULL); } } diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_ctl.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_ctl.c index 3e5e1e09e9d00ade74371489b2b4e50e648e2d16..c9c65d5e9d36d3a4ce2aef9f57da631f2acd9123 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_ctl.c +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_ctl.c @@ -42,6 +42,7 @@ #define CTL_INTF_FLUSH 0x110 #define CTL_CDM_FLUSH 0x114 #define CTL_PERIPH_FLUSH 0x128 +#define CTL_PIPE_ACTIVE 0x12c #define CTL_INTF_MASTER 0x134 #define CTL_DSPP_n_FLUSH(n) ((0x13C) + ((n) * 4)) @@ -676,6 +677,9 @@ static void dpu_hw_ctl_reset_intf_cfg_v1(struct dpu_hw_ctl *ctx, if (ctx->ops.set_active_fetch_pipes) ctx->ops.set_active_fetch_pipes(ctx, NULL); + if (ctx->ops.set_active_pipes) + ctx->ops.set_active_pipes(ctx, NULL); + if (cfg->intf) { intf_active = DPU_REG_READ(c, CTL_INTF_ACTIVE); intf_active &= ~BIT(cfg->intf - INTF_0); @@ -724,6 +728,23 @@ static void dpu_hw_ctl_set_active_fetch_pipes(struct dpu_hw_ctl *ctx, DPU_REG_WRITE(&ctx->hw, CTL_FETCH_PIPE_ACTIVE, val); } +static void dpu_hw_ctl_set_active_pipes(struct dpu_hw_ctl *ctx, + unsigned long *active_pipes) +{ + int i; + u32 val = 0; + + if (active_pipes) { + for (i = 0; i < SSPP_MAX; i++) { + if (test_bit(i, active_pipes) && + fetch_tbl[i] != CTL_INVALID_BIT) + val |= BIT(fetch_tbl[i]); + } + } + + DPU_REG_WRITE(&ctx->hw, CTL_PIPE_ACTIVE, val); +} + /** * dpu_hw_ctl_init() - Initializes the ctl_path hw driver object. * Should be called before accessing any ctl_path register. @@ -786,8 +807,12 @@ struct dpu_hw_ctl *dpu_hw_ctl_init(struct drm_device *dev, c->ops.trigger_pending = dpu_hw_ctl_trigger_pending; c->ops.reset = dpu_hw_ctl_reset_control; c->ops.wait_reset_status = dpu_hw_ctl_wait_reset_status; - c->ops.clear_all_blendstages = dpu_hw_ctl_clear_all_blendstages; - c->ops.setup_blendstage = dpu_hw_ctl_setup_blendstage; + if (mdss_ver->core_major_ver < 12) { + c->ops.clear_all_blendstages = dpu_hw_ctl_clear_all_blendstages; + c->ops.setup_blendstage = dpu_hw_ctl_setup_blendstage; + } else { + c->ops.set_active_pipes = dpu_hw_ctl_set_active_pipes; + } c->ops.update_pending_flush_sspp = dpu_hw_ctl_update_pending_flush_sspp; c->ops.update_pending_flush_mixer = dpu_hw_ctl_update_pending_flush_mixer; if (mdss_ver->core_major_ver >= 7) diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_ctl.h b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_ctl.h index 1b40d8cc92865e31e5ac4a8c3ee8fac8c5499bbd..186c467e1a64e71116b65b19dd8ecdbb09dac114 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_ctl.h +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_ctl.h @@ -256,6 +256,14 @@ struct dpu_hw_ctl_ops { void (*set_active_fetch_pipes)(struct dpu_hw_ctl *ctx, unsigned long *fetch_active); + + /** + * Set active pipes attached to this CTL + * @ctx: ctl path ctx pointer + * @active_pipes: bitmap of enum dpu_sspp + */ + void (*set_active_pipes)(struct dpu_hw_ctl *ctx, + unsigned long *active_pipes); }; /** -- 2.43.0