diff options
Diffstat (limited to 'drivers/gpu/drm/msm/disp/dpu1/dpu_hw_ctl.c')
-rw-r--r-- | drivers/gpu/drm/msm/disp/dpu1/dpu_hw_ctl.c | 145 |
1 files changed, 97 insertions, 48 deletions
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 573e42b06ad0..ac834db2e4c1 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,8 @@ #define CTL_INTF_FLUSH 0x110 #define CTL_CDM_FLUSH 0x114 #define CTL_PERIPH_FLUSH 0x128 +#define CTL_PIPE_ACTIVE 0x12c +#define CTL_LAYER_ACTIVE 0x130 #define CTL_INTF_MASTER 0x134 #define CTL_DSPP_n_FLUSH(n) ((0x13C) + ((n) * 4)) @@ -64,6 +66,8 @@ static const u32 fetch_tbl[SSPP_MAX] = {CTL_INVALID_BIT, 16, 17, 18, 19, CTL_INVALID_BIT, CTL_INVALID_BIT, CTL_INVALID_BIT, CTL_INVALID_BIT, 0, 1, 2, 3, 4, 5}; +static const u32 lm_tbl[LM_MAX] = {CTL_INVALID_BIT, 0, 1, 2, 3, 4, 5, 6, 7}; + static int _mixer_stages(const struct dpu_lm_cfg *mixer, int count, enum dpu_lm lm) { @@ -555,7 +559,7 @@ exit: DPU_REG_WRITE(c, CTL_LAYER_EXT(lm), mixercfg[1]); DPU_REG_WRITE(c, CTL_LAYER_EXT2(lm), mixercfg[2]); DPU_REG_WRITE(c, CTL_LAYER_EXT3(lm), mixercfg[3]); - if ((test_bit(DPU_CTL_HAS_LAYER_EXT4, &ctx->caps->features))) + if (ctx->mdss_ver->core_major_ver >= 9) DPU_REG_WRITE(c, CTL_LAYER_EXT4(lm), mixercfg[4]); } @@ -575,7 +579,7 @@ static void dpu_hw_ctl_intf_cfg_v1(struct dpu_hw_ctl *ctx, * per VM. Explicitly disable it until VM support is * added in SW. Power on reset value is not disable. */ - if ((test_bit(DPU_CTL_VM_CFG, &ctx->caps->features))) + if (ctx->mdss_ver->core_major_ver >= 7) mode_sel = CTL_DEFAULT_GROUP_ID << 28; if (cfg->intf_mode_sel == DPU_CTL_MODE_SEL_CMD) @@ -676,11 +680,18 @@ static void dpu_hw_ctl_reset_intf_cfg_v1(struct dpu_hw_ctl *ctx, merge3d_active); } - dpu_hw_ctl_clear_all_blendstages(ctx); + if (ctx->ops.clear_all_blendstages) + ctx->ops.clear_all_blendstages(ctx); + + if (ctx->ops.set_active_lms) + ctx->ops.set_active_lms(ctx, NULL); 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); @@ -737,55 +748,39 @@ 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 _setup_ctl_ops(struct dpu_hw_ctl_ops *ops, - unsigned long cap) +static void dpu_hw_ctl_set_active_pipes(struct dpu_hw_ctl *ctx, + unsigned long *active_pipes) { - if (cap & BIT(DPU_CTL_ACTIVE_CFG)) { - ops->trigger_flush = dpu_hw_ctl_trigger_flush_v1; - ops->setup_intf_cfg = dpu_hw_ctl_intf_cfg_v1; - ops->reset_intf_cfg = dpu_hw_ctl_reset_intf_cfg_v1; - ops->update_pending_flush_intf = - dpu_hw_ctl_update_pending_flush_intf_v1; + int i; + u32 val = 0; - ops->update_pending_flush_periph = - dpu_hw_ctl_update_pending_flush_periph_v1; + 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]); + } + } - ops->update_pending_flush_merge_3d = - dpu_hw_ctl_update_pending_flush_merge_3d_v1; - ops->update_pending_flush_wb = dpu_hw_ctl_update_pending_flush_wb_v1; - ops->update_pending_flush_cwb = dpu_hw_ctl_update_pending_flush_cwb_v1; - ops->update_pending_flush_dsc = - dpu_hw_ctl_update_pending_flush_dsc_v1; - ops->update_pending_flush_cdm = dpu_hw_ctl_update_pending_flush_cdm_v1; - } else { - ops->trigger_flush = dpu_hw_ctl_trigger_flush; - ops->setup_intf_cfg = dpu_hw_ctl_intf_cfg; - ops->update_pending_flush_intf = - dpu_hw_ctl_update_pending_flush_intf; - ops->update_pending_flush_wb = dpu_hw_ctl_update_pending_flush_wb; - ops->update_pending_flush_cdm = dpu_hw_ctl_update_pending_flush_cdm; + DPU_REG_WRITE(&ctx->hw, CTL_PIPE_ACTIVE, val); +} + +static void dpu_hw_ctl_set_active_lms(struct dpu_hw_ctl *ctx, + unsigned long *active_lms) +{ + int i; + u32 val = 0; + + if (active_lms) { + for (i = LM_0; i < LM_MAX; i++) { + if (test_bit(i, active_lms) && + lm_tbl[i] != CTL_INVALID_BIT) + val |= BIT(lm_tbl[i]); + } } - ops->clear_pending_flush = dpu_hw_ctl_clear_pending_flush; - ops->update_pending_flush = dpu_hw_ctl_update_pending_flush; - ops->get_pending_flush = dpu_hw_ctl_get_pending_flush; - ops->get_flush_register = dpu_hw_ctl_get_flush_register; - ops->trigger_start = dpu_hw_ctl_trigger_start; - ops->is_started = dpu_hw_ctl_is_started; - ops->trigger_pending = dpu_hw_ctl_trigger_pending; - ops->reset = dpu_hw_ctl_reset_control; - ops->wait_reset_status = dpu_hw_ctl_wait_reset_status; - ops->clear_all_blendstages = dpu_hw_ctl_clear_all_blendstages; - ops->setup_blendstage = dpu_hw_ctl_setup_blendstage; - ops->update_pending_flush_sspp = dpu_hw_ctl_update_pending_flush_sspp; - ops->update_pending_flush_mixer = dpu_hw_ctl_update_pending_flush_mixer; - if (cap & BIT(DPU_CTL_DSPP_SUB_BLOCK_FLUSH)) - ops->update_pending_flush_dspp = dpu_hw_ctl_update_pending_flush_dspp_sub_blocks; - else - ops->update_pending_flush_dspp = dpu_hw_ctl_update_pending_flush_dspp; - if (cap & BIT(DPU_CTL_FETCH_ACTIVE)) - ops->set_active_fetch_pipes = dpu_hw_ctl_set_active_fetch_pipes; -}; + DPU_REG_WRITE(&ctx->hw, CTL_LAYER_ACTIVE, val); +} /** * dpu_hw_ctl_init() - Initializes the ctl_path hw driver object. @@ -793,12 +788,14 @@ static void _setup_ctl_ops(struct dpu_hw_ctl_ops *ops, * @dev: Corresponding device for devres management * @cfg: ctl_path catalog entry for which driver object is required * @addr: mapped register io address of MDP + * @mdss_ver: dpu core's major and minor versions * @mixer_count: Number of mixers in @mixer * @mixer: Pointer to an array of Layer Mixers defined in the catalog */ struct dpu_hw_ctl *dpu_hw_ctl_init(struct drm_device *dev, const struct dpu_ctl_cfg *cfg, void __iomem *addr, + const struct dpu_mdss_version *mdss_ver, u32 mixer_count, const struct dpu_lm_cfg *mixer) { @@ -812,7 +809,59 @@ struct dpu_hw_ctl *dpu_hw_ctl_init(struct drm_device *dev, c->hw.log_mask = DPU_DBG_MASK_CTL; c->caps = cfg; - _setup_ctl_ops(&c->ops, c->caps->features); + c->mdss_ver = mdss_ver; + + if (mdss_ver->core_major_ver >= 5) { + c->ops.trigger_flush = dpu_hw_ctl_trigger_flush_v1; + c->ops.setup_intf_cfg = dpu_hw_ctl_intf_cfg_v1; + c->ops.reset_intf_cfg = dpu_hw_ctl_reset_intf_cfg_v1; + c->ops.update_pending_flush_intf = + dpu_hw_ctl_update_pending_flush_intf_v1; + + c->ops.update_pending_flush_periph = + dpu_hw_ctl_update_pending_flush_periph_v1; + + c->ops.update_pending_flush_merge_3d = + dpu_hw_ctl_update_pending_flush_merge_3d_v1; + c->ops.update_pending_flush_wb = dpu_hw_ctl_update_pending_flush_wb_v1; + c->ops.update_pending_flush_cwb = dpu_hw_ctl_update_pending_flush_cwb_v1; + c->ops.update_pending_flush_dsc = + dpu_hw_ctl_update_pending_flush_dsc_v1; + c->ops.update_pending_flush_cdm = dpu_hw_ctl_update_pending_flush_cdm_v1; + } else { + c->ops.trigger_flush = dpu_hw_ctl_trigger_flush; + c->ops.setup_intf_cfg = dpu_hw_ctl_intf_cfg; + c->ops.update_pending_flush_intf = + dpu_hw_ctl_update_pending_flush_intf; + c->ops.update_pending_flush_wb = dpu_hw_ctl_update_pending_flush_wb; + c->ops.update_pending_flush_cdm = dpu_hw_ctl_update_pending_flush_cdm; + } + c->ops.clear_pending_flush = dpu_hw_ctl_clear_pending_flush; + c->ops.update_pending_flush = dpu_hw_ctl_update_pending_flush; + c->ops.get_pending_flush = dpu_hw_ctl_get_pending_flush; + c->ops.get_flush_register = dpu_hw_ctl_get_flush_register; + c->ops.trigger_start = dpu_hw_ctl_trigger_start; + c->ops.is_started = dpu_hw_ctl_is_started; + 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; + 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.set_active_lms = dpu_hw_ctl_set_active_lms; + } + 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) + c->ops.update_pending_flush_dspp = dpu_hw_ctl_update_pending_flush_dspp_sub_blocks; + else + c->ops.update_pending_flush_dspp = dpu_hw_ctl_update_pending_flush_dspp; + + if (mdss_ver->core_major_ver >= 7) + c->ops.set_active_fetch_pipes = dpu_hw_ctl_set_active_fetch_pipes; + c->idx = cfg->id; c->mixer_count = mixer_count; c->mixer_hw_caps = mixer; |