Loading msm/sde/sde_crtc.c +10 −28 Original line number Diff line number Diff line Loading @@ -496,10 +496,6 @@ static void _sde_crtc_setup_blend_cfg(struct sde_crtc_mixer *mixer, } break; case SDE_DRM_BLEND_OP_SKIP: SDE_ERROR("skip the blending for plane\n"); return; default: /* do nothing */ break; Loading Loading @@ -1336,25 +1332,6 @@ static void _sde_crtc_set_src_split_order(struct drm_crtc *crtc, } } static void __sde_crtc_assign_active_cfg(struct sde_crtc *sdecrtc, struct drm_plane *plane) { u8 found = 0; int i; for (i = 0; i < SDE_STAGE_MAX; i++) { if (sdecrtc->active_cfg.stage[i][0] == SSPP_NONE) { found = 1; break; } } if (!found) { SDE_ERROR("All active configs are allocated\n"); return; } sdecrtc->active_cfg.stage[i][0] = sde_plane_pipe(plane); } static void _sde_crtc_setup_blend_cfg_by_stage(struct sde_crtc_mixer *mixer, int num_mixers, struct plane_state *pstates, int cnt) { Loading Loading @@ -1406,6 +1383,7 @@ static void _sde_crtc_blend_setup_mixer(struct drm_crtc *crtc, int i, mode, cnt = 0; bool bg_alpha_enable = false, is_secure = false; u32 blend_type; DECLARE_BITMAP(fetch_active, SSPP_MAX); if (!sde_crtc || !crtc->state || !mixer) { SDE_ERROR("invalid sde_crtc or mixer\n"); Loading @@ -1421,6 +1399,7 @@ static void _sde_crtc_blend_setup_mixer(struct drm_crtc *crtc, if (!pstates) return; memset(fetch_active, 0, sizeof(fetch_active)); drm_atomic_crtc_for_each_plane(plane, crtc) { state = plane->state; if (!state) Loading @@ -1440,6 +1419,7 @@ static void _sde_crtc_blend_setup_mixer(struct drm_crtc *crtc, (mode == SDE_DRM_FB_SEC_DIR_TRANS)) ? true : false; set_bit(sde_plane_pipe(plane), fetch_active); sde_plane_ctl_flush(plane, ctl, true); SDE_DEBUG("crtc %d stage:%d - plane %d sspp %d fb %d\n", Loading @@ -1458,9 +1438,7 @@ static void _sde_crtc_blend_setup_mixer(struct drm_crtc *crtc, blend_type = sde_plane_get_property(pstate, PLANE_PROP_BLEND_OP); if (blend_type == SDE_DRM_BLEND_OP_SKIP) { __sde_crtc_assign_active_cfg(sde_crtc, plane); } else { if (blend_type != SDE_DRM_BLEND_OP_SKIP) { if (pstate->stage == SDE_STAGE_BASE && format->alpha_enable) bg_alpha_enable = true; Loading Loading @@ -1517,6 +1495,9 @@ static void _sde_crtc_blend_setup_mixer(struct drm_crtc *crtc, _sde_crtc_setup_blend_cfg_by_stage(mixer, sde_crtc->num_mixers, pstates, cnt); if (ctl->ops.set_active_pipes) ctl->ops.set_active_pipes(ctl, fetch_active); sort(pstates, cnt, sizeof(pstates[0]), pstate_cmp, NULL); _sde_crtc_set_src_split_order(crtc, pstates, cnt); Loading Loading @@ -1651,7 +1632,6 @@ static void _sde_crtc_blend_setup(struct drm_crtc *crtc, /* initialize stage cfg */ memset(&sde_crtc->stage_cfg, 0, sizeof(struct sde_hw_stage_cfg)); memset(&sde_crtc->active_cfg, 0, sizeof(sde_crtc->active_cfg)); if (add_planes) _sde_crtc_blend_setup_mixer(crtc, old_state, sde_crtc, mixer); Loading Loading @@ -1683,7 +1663,7 @@ static void _sde_crtc_blend_setup(struct drm_crtc *crtc, cfg.pending_flush_mask); ctl->ops.setup_blendstage(ctl, mixer[i].hw_lm->idx, &sde_crtc->stage_cfg, &sde_crtc->active_cfg); &sde_crtc->stage_cfg); } _sde_crtc_program_lm_output_roi(crtc); Loading Loading @@ -3179,6 +3159,8 @@ static void _sde_crtc_clear_all_blend_stages(struct sde_crtc *sde_crtc) mixer = sde_crtc->mixers[0]; if (mixer.hw_ctl && mixer.hw_ctl->ops.clear_all_blendstages) mixer.hw_ctl->ops.clear_all_blendstages(mixer.hw_ctl); if (mixer.hw_ctl && mixer.hw_ctl->ops.set_active_pipes) mixer.hw_ctl->ops.set_active_pipes(mixer.hw_ctl, NULL); } } Loading msm/sde/sde_crtc.h +0 −2 Original line number Diff line number Diff line Loading @@ -225,7 +225,6 @@ struct sde_crtc_misr_info { * @property_defaults : Array of default values for generic property support * @output_fence : output release fence context * @stage_cfg : H/w mixer stage configuration * @active_cfg : H/w pipes active that shouldn't be staged * @debugfs_root : Parent of debugfs node * @priv_handle : Pointer to external private handle, if present * @vblank_cb_count : count of vblank callback since last reset Loading Loading @@ -298,7 +297,6 @@ struct sde_crtc { struct sde_fence_context *output_fence; struct sde_hw_stage_cfg stage_cfg; struct sde_hw_stage_cfg active_cfg; struct dentry *debugfs_root; void *priv_handle; Loading msm/sde/sde_encoder.c +1 −1 Original line number Diff line number Diff line Loading @@ -4237,7 +4237,7 @@ int sde_encoder_helper_reset_mixers(struct sde_encoder_phys *phys_enc, /* only enable border color on LM */ if (phys_enc->hw_ctl->ops.setup_blendstage) phys_enc->hw_ctl->ops.setup_blendstage( phys_enc->hw_ctl, hw_lm->idx, NULL, NULL); phys_enc->hw_ctl, hw_lm->idx, NULL); } if (!lm_valid) { Loading msm/sde/sde_hw_ctl.c +87 −77 Original line number Diff line number Diff line Loading @@ -266,6 +266,13 @@ static const struct ctl_hw_flush_cfg intf_flush_tbl } /* SDE_HW_FLUSH_INTF */ }; struct sde_ctl_mixer_cfg { u32 cfg; u32 ext; u32 ext2; u32 ext3; }; static struct sde_ctl_cfg *_ctl_offset(enum sde_ctl ctl, struct sde_mdss_cfg *m, void __iomem *addr, Loading Loading @@ -625,6 +632,23 @@ static inline int sde_hw_ctl_update_bitmask_dspp_subblk(struct sde_hw_ctl *ctx, return 0; } static void sde_hw_ctl_set_fetch_pipe_active(struct sde_hw_ctl *ctx, unsigned long *fetch_active) { int i; u32 val = 0; if (fetch_active) { for (i = 0; i < SSPP_MAX; i++) { if (test_bit(i, fetch_active) && fetch_tbl[i] != CTL_INVALID_BIT) val |= BIT(fetch_tbl[i]); } } SDE_REG_WRITE(&ctx->hw, CTL_FETCH_PIPE_ACTIVE, val); } static inline void _sde_hw_ctl_write_dspp_flushes(struct sde_hw_ctl *ctx) { int i; bool has_dspp_flushes = ctx->caps->features & Loading Loading @@ -815,35 +839,18 @@ static void sde_hw_ctl_clear_all_blendstages(struct sde_hw_ctl *ctx) SDE_REG_WRITE(c, CTL_FETCH_PIPE_ACTIVE, 0); } static void sde_hw_ctl_setup_blendstage(struct sde_hw_ctl *ctx, enum sde_lm lm, struct sde_hw_stage_cfg *stage_cfg, struct sde_hw_stage_cfg *active_cfg) static void _sde_hw_ctl_get_mixer_cfg(struct sde_hw_ctl *ctx, struct sde_hw_stage_cfg *stage_cfg, int stages, struct sde_ctl_mixer_cfg *cfg) { struct sde_hw_blk_reg_map *c; u32 mixercfg = 0, mixercfg_ext = 0, mix, ext; u32 mixercfg_ext2 = 0, mixercfg_ext3 = 0; u32 active_fetch_pipes = 0; int i, j; u8 stages; int pipes_per_stage; if (!ctx) return; int i, j, pipes_per_stage; u32 mix, ext; c = &ctx->hw; stages = _mixer_stages(ctx->mixer_hw_caps, ctx->mixer_count, lm); if ((int)stages < 0) return; if (test_bit(SDE_MIXER_SOURCESPLIT, &ctx->mixer_hw_caps->features)) if (test_bit(SDE_MIXER_SOURCESPLIT, &ctx->mixer_hw_caps->features)) pipes_per_stage = PIPES_PER_STAGE; else pipes_per_stage = 1; if (!stage_cfg) goto exit; for (i = 0; i <= stages; i++) { /* overflow to ext register if 'i + 1 > 7' */ mix = (i + 1) & 0x7; Loading @@ -853,125 +860,127 @@ static void sde_hw_ctl_setup_blendstage(struct sde_hw_ctl *ctx, enum sde_sspp pipe = stage_cfg->stage[i][j]; enum sde_sspp_multirect_index rect_index = stage_cfg->multirect_index[i][j]; switch (pipe) { case SSPP_VIG0: if (rect_index == SDE_SSPP_RECT_1) { mixercfg_ext3 |= ((i + 1) & 0xF) << 0; cfg->ext3 |= ((i + 1) & 0xF) << 0; } else { mixercfg |= mix << 0; mixercfg_ext |= ext << 0; cfg->cfg |= mix << 0; cfg->ext |= ext << 0; } break; case SSPP_VIG1: if (rect_index == SDE_SSPP_RECT_1) { mixercfg_ext3 |= ((i + 1) & 0xF) << 4; cfg->ext3 |= ((i + 1) & 0xF) << 4; } else { mixercfg |= mix << 3; mixercfg_ext |= ext << 2; cfg->cfg |= mix << 3; cfg->ext |= ext << 2; } break; case SSPP_VIG2: if (rect_index == SDE_SSPP_RECT_1) { mixercfg_ext3 |= ((i + 1) & 0xF) << 8; cfg->ext3 |= ((i + 1) & 0xF) << 8; } else { mixercfg |= mix << 6; mixercfg_ext |= ext << 4; cfg->cfg |= mix << 6; cfg->ext |= ext << 4; } break; case SSPP_VIG3: if (rect_index == SDE_SSPP_RECT_1) { mixercfg_ext3 |= ((i + 1) & 0xF) << 12; cfg->ext3 |= ((i + 1) & 0xF) << 12; } else { mixercfg |= mix << 26; mixercfg_ext |= ext << 6; cfg->cfg |= mix << 26; cfg->ext |= ext << 6; } break; case SSPP_RGB0: mixercfg |= mix << 9; mixercfg_ext |= ext << 8; cfg->cfg |= mix << 9; cfg->ext |= ext << 8; break; case SSPP_RGB1: mixercfg |= mix << 12; mixercfg_ext |= ext << 10; cfg->cfg |= mix << 12; cfg->ext |= ext << 10; break; case SSPP_RGB2: mixercfg |= mix << 15; mixercfg_ext |= ext << 12; cfg->cfg |= mix << 15; cfg->ext |= ext << 12; break; case SSPP_RGB3: mixercfg |= mix << 29; mixercfg_ext |= ext << 14; cfg->cfg |= mix << 29; cfg->ext |= ext << 14; break; case SSPP_DMA0: if (rect_index == SDE_SSPP_RECT_1) { mixercfg_ext2 |= ((i + 1) & 0xF) << 8; cfg->ext2 |= ((i + 1) & 0xF) << 8; } else { mixercfg |= mix << 18; mixercfg_ext |= ext << 16; cfg->cfg |= mix << 18; cfg->ext |= ext << 16; } break; case SSPP_DMA1: if (rect_index == SDE_SSPP_RECT_1) { mixercfg_ext2 |= ((i + 1) & 0xF) << 12; cfg->ext2 |= ((i + 1) & 0xF) << 12; } else { mixercfg |= mix << 21; mixercfg_ext |= ext << 18; cfg->cfg |= mix << 21; cfg->ext |= ext << 18; } break; case SSPP_DMA2: if (rect_index == SDE_SSPP_RECT_1) { mixercfg_ext2 |= ((i + 1) & 0xF) << 16; cfg->ext2 |= ((i + 1) & 0xF) << 16; } else { mix |= (i + 1) & 0xF; mixercfg_ext2 |= mix << 0; cfg->ext2 |= mix << 0; } break; case SSPP_DMA3: if (rect_index == SDE_SSPP_RECT_1) { mixercfg_ext2 |= ((i + 1) & 0xF) << 20; cfg->ext2 |= ((i + 1) & 0xF) << 20; } else { mix |= (i + 1) & 0xF; mixercfg_ext2 |= mix << 4; cfg->ext2 |= mix << 4; } break; case SSPP_CURSOR0: mixercfg_ext |= ((i + 1) & 0xF) << 20; cfg->ext |= ((i + 1) & 0xF) << 20; break; case SSPP_CURSOR1: mixercfg_ext |= ((i + 1) & 0xF) << 26; cfg->ext |= ((i + 1) & 0xF) << 26; break; default: break; } if (fetch_tbl[pipe] != CTL_INVALID_BIT) active_fetch_pipes |= BIT(fetch_tbl[pipe]); } } } for (i = 0; i <= stages && active_cfg; i++) { enum sde_sspp pipe = active_cfg->stage[i][0]; static void sde_hw_ctl_setup_blendstage(struct sde_hw_ctl *ctx, enum sde_lm lm, struct sde_hw_stage_cfg *stage_cfg) { struct sde_hw_blk_reg_map *c; struct sde_ctl_mixer_cfg cfg = { 0 }; int stages; if (pipe == SSPP_NONE) break; if (fetch_tbl[pipe] != CTL_INVALID_BIT) { active_fetch_pipes |= BIT(fetch_tbl[pipe]); SDE_DEBUG("fetch pipe %d active pipes %x\n", pipe, active_fetch_pipes); } } if (!ctx) return; stages = _mixer_stages(ctx->mixer_hw_caps, ctx->mixer_count, lm); if (stages < 0) return; c = &ctx->hw; if (stage_cfg) _sde_hw_ctl_get_mixer_cfg(ctx, stage_cfg, stages, &cfg); exit: if ((!mixercfg && !mixercfg_ext && !mixercfg_ext2 && !mixercfg_ext3) || if ((!cfg.cfg && !cfg.ext && !cfg.ext2 && !cfg.ext3) || (stage_cfg && !stage_cfg->stage[0][0])) mixercfg |= CTL_MIXER_BORDER_OUT; cfg.cfg |= CTL_MIXER_BORDER_OUT; SDE_REG_WRITE(c, CTL_LAYER(lm), mixercfg); SDE_REG_WRITE(c, CTL_LAYER_EXT(lm), mixercfg_ext); SDE_REG_WRITE(c, CTL_LAYER_EXT2(lm), mixercfg_ext2); SDE_REG_WRITE(c, CTL_LAYER_EXT3(lm), mixercfg_ext3); SDE_REG_WRITE(c, CTL_FETCH_PIPE_ACTIVE, active_fetch_pipes); SDE_REG_WRITE(c, CTL_LAYER(lm), cfg.cfg); SDE_REG_WRITE(c, CTL_LAYER_EXT(lm), cfg.ext); SDE_REG_WRITE(c, CTL_LAYER_EXT2(lm), cfg.ext2); SDE_REG_WRITE(c, CTL_LAYER_EXT3(lm), cfg.ext3); } static u32 sde_hw_ctl_get_staged_sspp(struct sde_hw_ctl *ctx, enum sde_lm lm, Loading Loading @@ -1352,6 +1361,7 @@ static void _setup_ctl_ops(struct sde_hw_ctl_ops *ops, ops->reset_post_disable = sde_hw_ctl_reset_post_disable; ops->get_scheduler_status = sde_hw_ctl_get_scheduler_status; ops->read_active_status = sde_hw_ctl_read_active_status; ops->set_active_pipes = sde_hw_ctl_set_fetch_pipe_active; } else { ops->update_pending_flush = sde_hw_ctl_update_pending_flush; ops->trigger_flush = sde_hw_ctl_trigger_flush; Loading msm/sde/sde_hw_ctl.h +9 −3 Original line number Diff line number Diff line Loading @@ -433,11 +433,9 @@ struct sde_hw_ctl_ops { * @ctx : ctl path ctx pointer * @lm : layer mixer enumeration * @cfg : blend stage configuration * @active_cfg: active no blend stage configuration */ void (*setup_blendstage)(struct sde_hw_ctl *ctx, enum sde_lm lm, struct sde_hw_stage_cfg *cfg, struct sde_hw_stage_cfg *active_cfg); enum sde_lm lm, struct sde_hw_stage_cfg *cfg); /** * Get all the sspp staged on a layer mixer Loading Loading @@ -465,6 +463,14 @@ struct sde_hw_ctl_ops { * @Return: error code */ int (*get_start_state)(struct sde_hw_ctl *ctx); /** * set the active fetch pipes attached to this CTL * @ctx : ctl path ctx pointer * @fetch_active: bitmap of enum sde_sspp pipes attached */ void (*set_active_pipes)(struct sde_hw_ctl *ctx, unsigned long *fetch_active); }; /** Loading Loading
msm/sde/sde_crtc.c +10 −28 Original line number Diff line number Diff line Loading @@ -496,10 +496,6 @@ static void _sde_crtc_setup_blend_cfg(struct sde_crtc_mixer *mixer, } break; case SDE_DRM_BLEND_OP_SKIP: SDE_ERROR("skip the blending for plane\n"); return; default: /* do nothing */ break; Loading Loading @@ -1336,25 +1332,6 @@ static void _sde_crtc_set_src_split_order(struct drm_crtc *crtc, } } static void __sde_crtc_assign_active_cfg(struct sde_crtc *sdecrtc, struct drm_plane *plane) { u8 found = 0; int i; for (i = 0; i < SDE_STAGE_MAX; i++) { if (sdecrtc->active_cfg.stage[i][0] == SSPP_NONE) { found = 1; break; } } if (!found) { SDE_ERROR("All active configs are allocated\n"); return; } sdecrtc->active_cfg.stage[i][0] = sde_plane_pipe(plane); } static void _sde_crtc_setup_blend_cfg_by_stage(struct sde_crtc_mixer *mixer, int num_mixers, struct plane_state *pstates, int cnt) { Loading Loading @@ -1406,6 +1383,7 @@ static void _sde_crtc_blend_setup_mixer(struct drm_crtc *crtc, int i, mode, cnt = 0; bool bg_alpha_enable = false, is_secure = false; u32 blend_type; DECLARE_BITMAP(fetch_active, SSPP_MAX); if (!sde_crtc || !crtc->state || !mixer) { SDE_ERROR("invalid sde_crtc or mixer\n"); Loading @@ -1421,6 +1399,7 @@ static void _sde_crtc_blend_setup_mixer(struct drm_crtc *crtc, if (!pstates) return; memset(fetch_active, 0, sizeof(fetch_active)); drm_atomic_crtc_for_each_plane(plane, crtc) { state = plane->state; if (!state) Loading @@ -1440,6 +1419,7 @@ static void _sde_crtc_blend_setup_mixer(struct drm_crtc *crtc, (mode == SDE_DRM_FB_SEC_DIR_TRANS)) ? true : false; set_bit(sde_plane_pipe(plane), fetch_active); sde_plane_ctl_flush(plane, ctl, true); SDE_DEBUG("crtc %d stage:%d - plane %d sspp %d fb %d\n", Loading @@ -1458,9 +1438,7 @@ static void _sde_crtc_blend_setup_mixer(struct drm_crtc *crtc, blend_type = sde_plane_get_property(pstate, PLANE_PROP_BLEND_OP); if (blend_type == SDE_DRM_BLEND_OP_SKIP) { __sde_crtc_assign_active_cfg(sde_crtc, plane); } else { if (blend_type != SDE_DRM_BLEND_OP_SKIP) { if (pstate->stage == SDE_STAGE_BASE && format->alpha_enable) bg_alpha_enable = true; Loading Loading @@ -1517,6 +1495,9 @@ static void _sde_crtc_blend_setup_mixer(struct drm_crtc *crtc, _sde_crtc_setup_blend_cfg_by_stage(mixer, sde_crtc->num_mixers, pstates, cnt); if (ctl->ops.set_active_pipes) ctl->ops.set_active_pipes(ctl, fetch_active); sort(pstates, cnt, sizeof(pstates[0]), pstate_cmp, NULL); _sde_crtc_set_src_split_order(crtc, pstates, cnt); Loading Loading @@ -1651,7 +1632,6 @@ static void _sde_crtc_blend_setup(struct drm_crtc *crtc, /* initialize stage cfg */ memset(&sde_crtc->stage_cfg, 0, sizeof(struct sde_hw_stage_cfg)); memset(&sde_crtc->active_cfg, 0, sizeof(sde_crtc->active_cfg)); if (add_planes) _sde_crtc_blend_setup_mixer(crtc, old_state, sde_crtc, mixer); Loading Loading @@ -1683,7 +1663,7 @@ static void _sde_crtc_blend_setup(struct drm_crtc *crtc, cfg.pending_flush_mask); ctl->ops.setup_blendstage(ctl, mixer[i].hw_lm->idx, &sde_crtc->stage_cfg, &sde_crtc->active_cfg); &sde_crtc->stage_cfg); } _sde_crtc_program_lm_output_roi(crtc); Loading Loading @@ -3179,6 +3159,8 @@ static void _sde_crtc_clear_all_blend_stages(struct sde_crtc *sde_crtc) mixer = sde_crtc->mixers[0]; if (mixer.hw_ctl && mixer.hw_ctl->ops.clear_all_blendstages) mixer.hw_ctl->ops.clear_all_blendstages(mixer.hw_ctl); if (mixer.hw_ctl && mixer.hw_ctl->ops.set_active_pipes) mixer.hw_ctl->ops.set_active_pipes(mixer.hw_ctl, NULL); } } Loading
msm/sde/sde_crtc.h +0 −2 Original line number Diff line number Diff line Loading @@ -225,7 +225,6 @@ struct sde_crtc_misr_info { * @property_defaults : Array of default values for generic property support * @output_fence : output release fence context * @stage_cfg : H/w mixer stage configuration * @active_cfg : H/w pipes active that shouldn't be staged * @debugfs_root : Parent of debugfs node * @priv_handle : Pointer to external private handle, if present * @vblank_cb_count : count of vblank callback since last reset Loading Loading @@ -298,7 +297,6 @@ struct sde_crtc { struct sde_fence_context *output_fence; struct sde_hw_stage_cfg stage_cfg; struct sde_hw_stage_cfg active_cfg; struct dentry *debugfs_root; void *priv_handle; Loading
msm/sde/sde_encoder.c +1 −1 Original line number Diff line number Diff line Loading @@ -4237,7 +4237,7 @@ int sde_encoder_helper_reset_mixers(struct sde_encoder_phys *phys_enc, /* only enable border color on LM */ if (phys_enc->hw_ctl->ops.setup_blendstage) phys_enc->hw_ctl->ops.setup_blendstage( phys_enc->hw_ctl, hw_lm->idx, NULL, NULL); phys_enc->hw_ctl, hw_lm->idx, NULL); } if (!lm_valid) { Loading
msm/sde/sde_hw_ctl.c +87 −77 Original line number Diff line number Diff line Loading @@ -266,6 +266,13 @@ static const struct ctl_hw_flush_cfg intf_flush_tbl } /* SDE_HW_FLUSH_INTF */ }; struct sde_ctl_mixer_cfg { u32 cfg; u32 ext; u32 ext2; u32 ext3; }; static struct sde_ctl_cfg *_ctl_offset(enum sde_ctl ctl, struct sde_mdss_cfg *m, void __iomem *addr, Loading Loading @@ -625,6 +632,23 @@ static inline int sde_hw_ctl_update_bitmask_dspp_subblk(struct sde_hw_ctl *ctx, return 0; } static void sde_hw_ctl_set_fetch_pipe_active(struct sde_hw_ctl *ctx, unsigned long *fetch_active) { int i; u32 val = 0; if (fetch_active) { for (i = 0; i < SSPP_MAX; i++) { if (test_bit(i, fetch_active) && fetch_tbl[i] != CTL_INVALID_BIT) val |= BIT(fetch_tbl[i]); } } SDE_REG_WRITE(&ctx->hw, CTL_FETCH_PIPE_ACTIVE, val); } static inline void _sde_hw_ctl_write_dspp_flushes(struct sde_hw_ctl *ctx) { int i; bool has_dspp_flushes = ctx->caps->features & Loading Loading @@ -815,35 +839,18 @@ static void sde_hw_ctl_clear_all_blendstages(struct sde_hw_ctl *ctx) SDE_REG_WRITE(c, CTL_FETCH_PIPE_ACTIVE, 0); } static void sde_hw_ctl_setup_blendstage(struct sde_hw_ctl *ctx, enum sde_lm lm, struct sde_hw_stage_cfg *stage_cfg, struct sde_hw_stage_cfg *active_cfg) static void _sde_hw_ctl_get_mixer_cfg(struct sde_hw_ctl *ctx, struct sde_hw_stage_cfg *stage_cfg, int stages, struct sde_ctl_mixer_cfg *cfg) { struct sde_hw_blk_reg_map *c; u32 mixercfg = 0, mixercfg_ext = 0, mix, ext; u32 mixercfg_ext2 = 0, mixercfg_ext3 = 0; u32 active_fetch_pipes = 0; int i, j; u8 stages; int pipes_per_stage; if (!ctx) return; int i, j, pipes_per_stage; u32 mix, ext; c = &ctx->hw; stages = _mixer_stages(ctx->mixer_hw_caps, ctx->mixer_count, lm); if ((int)stages < 0) return; if (test_bit(SDE_MIXER_SOURCESPLIT, &ctx->mixer_hw_caps->features)) if (test_bit(SDE_MIXER_SOURCESPLIT, &ctx->mixer_hw_caps->features)) pipes_per_stage = PIPES_PER_STAGE; else pipes_per_stage = 1; if (!stage_cfg) goto exit; for (i = 0; i <= stages; i++) { /* overflow to ext register if 'i + 1 > 7' */ mix = (i + 1) & 0x7; Loading @@ -853,125 +860,127 @@ static void sde_hw_ctl_setup_blendstage(struct sde_hw_ctl *ctx, enum sde_sspp pipe = stage_cfg->stage[i][j]; enum sde_sspp_multirect_index rect_index = stage_cfg->multirect_index[i][j]; switch (pipe) { case SSPP_VIG0: if (rect_index == SDE_SSPP_RECT_1) { mixercfg_ext3 |= ((i + 1) & 0xF) << 0; cfg->ext3 |= ((i + 1) & 0xF) << 0; } else { mixercfg |= mix << 0; mixercfg_ext |= ext << 0; cfg->cfg |= mix << 0; cfg->ext |= ext << 0; } break; case SSPP_VIG1: if (rect_index == SDE_SSPP_RECT_1) { mixercfg_ext3 |= ((i + 1) & 0xF) << 4; cfg->ext3 |= ((i + 1) & 0xF) << 4; } else { mixercfg |= mix << 3; mixercfg_ext |= ext << 2; cfg->cfg |= mix << 3; cfg->ext |= ext << 2; } break; case SSPP_VIG2: if (rect_index == SDE_SSPP_RECT_1) { mixercfg_ext3 |= ((i + 1) & 0xF) << 8; cfg->ext3 |= ((i + 1) & 0xF) << 8; } else { mixercfg |= mix << 6; mixercfg_ext |= ext << 4; cfg->cfg |= mix << 6; cfg->ext |= ext << 4; } break; case SSPP_VIG3: if (rect_index == SDE_SSPP_RECT_1) { mixercfg_ext3 |= ((i + 1) & 0xF) << 12; cfg->ext3 |= ((i + 1) & 0xF) << 12; } else { mixercfg |= mix << 26; mixercfg_ext |= ext << 6; cfg->cfg |= mix << 26; cfg->ext |= ext << 6; } break; case SSPP_RGB0: mixercfg |= mix << 9; mixercfg_ext |= ext << 8; cfg->cfg |= mix << 9; cfg->ext |= ext << 8; break; case SSPP_RGB1: mixercfg |= mix << 12; mixercfg_ext |= ext << 10; cfg->cfg |= mix << 12; cfg->ext |= ext << 10; break; case SSPP_RGB2: mixercfg |= mix << 15; mixercfg_ext |= ext << 12; cfg->cfg |= mix << 15; cfg->ext |= ext << 12; break; case SSPP_RGB3: mixercfg |= mix << 29; mixercfg_ext |= ext << 14; cfg->cfg |= mix << 29; cfg->ext |= ext << 14; break; case SSPP_DMA0: if (rect_index == SDE_SSPP_RECT_1) { mixercfg_ext2 |= ((i + 1) & 0xF) << 8; cfg->ext2 |= ((i + 1) & 0xF) << 8; } else { mixercfg |= mix << 18; mixercfg_ext |= ext << 16; cfg->cfg |= mix << 18; cfg->ext |= ext << 16; } break; case SSPP_DMA1: if (rect_index == SDE_SSPP_RECT_1) { mixercfg_ext2 |= ((i + 1) & 0xF) << 12; cfg->ext2 |= ((i + 1) & 0xF) << 12; } else { mixercfg |= mix << 21; mixercfg_ext |= ext << 18; cfg->cfg |= mix << 21; cfg->ext |= ext << 18; } break; case SSPP_DMA2: if (rect_index == SDE_SSPP_RECT_1) { mixercfg_ext2 |= ((i + 1) & 0xF) << 16; cfg->ext2 |= ((i + 1) & 0xF) << 16; } else { mix |= (i + 1) & 0xF; mixercfg_ext2 |= mix << 0; cfg->ext2 |= mix << 0; } break; case SSPP_DMA3: if (rect_index == SDE_SSPP_RECT_1) { mixercfg_ext2 |= ((i + 1) & 0xF) << 20; cfg->ext2 |= ((i + 1) & 0xF) << 20; } else { mix |= (i + 1) & 0xF; mixercfg_ext2 |= mix << 4; cfg->ext2 |= mix << 4; } break; case SSPP_CURSOR0: mixercfg_ext |= ((i + 1) & 0xF) << 20; cfg->ext |= ((i + 1) & 0xF) << 20; break; case SSPP_CURSOR1: mixercfg_ext |= ((i + 1) & 0xF) << 26; cfg->ext |= ((i + 1) & 0xF) << 26; break; default: break; } if (fetch_tbl[pipe] != CTL_INVALID_BIT) active_fetch_pipes |= BIT(fetch_tbl[pipe]); } } } for (i = 0; i <= stages && active_cfg; i++) { enum sde_sspp pipe = active_cfg->stage[i][0]; static void sde_hw_ctl_setup_blendstage(struct sde_hw_ctl *ctx, enum sde_lm lm, struct sde_hw_stage_cfg *stage_cfg) { struct sde_hw_blk_reg_map *c; struct sde_ctl_mixer_cfg cfg = { 0 }; int stages; if (pipe == SSPP_NONE) break; if (fetch_tbl[pipe] != CTL_INVALID_BIT) { active_fetch_pipes |= BIT(fetch_tbl[pipe]); SDE_DEBUG("fetch pipe %d active pipes %x\n", pipe, active_fetch_pipes); } } if (!ctx) return; stages = _mixer_stages(ctx->mixer_hw_caps, ctx->mixer_count, lm); if (stages < 0) return; c = &ctx->hw; if (stage_cfg) _sde_hw_ctl_get_mixer_cfg(ctx, stage_cfg, stages, &cfg); exit: if ((!mixercfg && !mixercfg_ext && !mixercfg_ext2 && !mixercfg_ext3) || if ((!cfg.cfg && !cfg.ext && !cfg.ext2 && !cfg.ext3) || (stage_cfg && !stage_cfg->stage[0][0])) mixercfg |= CTL_MIXER_BORDER_OUT; cfg.cfg |= CTL_MIXER_BORDER_OUT; SDE_REG_WRITE(c, CTL_LAYER(lm), mixercfg); SDE_REG_WRITE(c, CTL_LAYER_EXT(lm), mixercfg_ext); SDE_REG_WRITE(c, CTL_LAYER_EXT2(lm), mixercfg_ext2); SDE_REG_WRITE(c, CTL_LAYER_EXT3(lm), mixercfg_ext3); SDE_REG_WRITE(c, CTL_FETCH_PIPE_ACTIVE, active_fetch_pipes); SDE_REG_WRITE(c, CTL_LAYER(lm), cfg.cfg); SDE_REG_WRITE(c, CTL_LAYER_EXT(lm), cfg.ext); SDE_REG_WRITE(c, CTL_LAYER_EXT2(lm), cfg.ext2); SDE_REG_WRITE(c, CTL_LAYER_EXT3(lm), cfg.ext3); } static u32 sde_hw_ctl_get_staged_sspp(struct sde_hw_ctl *ctx, enum sde_lm lm, Loading Loading @@ -1352,6 +1361,7 @@ static void _setup_ctl_ops(struct sde_hw_ctl_ops *ops, ops->reset_post_disable = sde_hw_ctl_reset_post_disable; ops->get_scheduler_status = sde_hw_ctl_get_scheduler_status; ops->read_active_status = sde_hw_ctl_read_active_status; ops->set_active_pipes = sde_hw_ctl_set_fetch_pipe_active; } else { ops->update_pending_flush = sde_hw_ctl_update_pending_flush; ops->trigger_flush = sde_hw_ctl_trigger_flush; Loading
msm/sde/sde_hw_ctl.h +9 −3 Original line number Diff line number Diff line Loading @@ -433,11 +433,9 @@ struct sde_hw_ctl_ops { * @ctx : ctl path ctx pointer * @lm : layer mixer enumeration * @cfg : blend stage configuration * @active_cfg: active no blend stage configuration */ void (*setup_blendstage)(struct sde_hw_ctl *ctx, enum sde_lm lm, struct sde_hw_stage_cfg *cfg, struct sde_hw_stage_cfg *active_cfg); enum sde_lm lm, struct sde_hw_stage_cfg *cfg); /** * Get all the sspp staged on a layer mixer Loading Loading @@ -465,6 +463,14 @@ struct sde_hw_ctl_ops { * @Return: error code */ int (*get_start_state)(struct sde_hw_ctl *ctx); /** * set the active fetch pipes attached to this CTL * @ctx : ctl path ctx pointer * @fetch_active: bitmap of enum sde_sspp pipes attached */ void (*set_active_pipes)(struct sde_hw_ctl *ctx, unsigned long *fetch_active); }; /** Loading