diff --git a/msm/sde/sde_encoder.c b/msm/sde/sde_encoder.c index 55fe39c2..f270c873 100644 --- a/msm/sde/sde_encoder.c +++ b/msm/sde/sde_encoder.c @@ -2733,95 +2733,12 @@ void sde_encoder_virt_restore(struct drm_encoder *drm_enc) _sde_encoder_virt_enable_helper(drm_enc); } -static void sde_encoder_off_work(struct kthread_work *work) +static void sde_encoder_populate_encoder_phys(struct drm_encoder *drm_enc, + struct sde_encoder_virt *sde_enc, struct msm_display_mode *msm_mode) { - struct sde_encoder_virt *sde_enc = container_of(work, - struct sde_encoder_virt, delayed_off_work.work); - struct drm_encoder *drm_enc; - - if (!sde_enc) { - SDE_ERROR("invalid sde encoder\n"); - return; - } - drm_enc = &sde_enc->base; - - SDE_ATRACE_BEGIN("sde_encoder_off_work"); - sde_encoder_idle_request(drm_enc); - SDE_ATRACE_END("sde_encoder_off_work"); -} - -static void sde_encoder_virt_enable(struct drm_encoder *drm_enc) -{ - struct sde_encoder_virt *sde_enc = NULL; - int i, ret = 0; - struct sde_connector_state *c_state; - struct msm_compression_info *comp_info = NULL; - struct drm_display_mode *cur_mode = NULL; - struct msm_display_mode *msm_mode; - struct msm_display_info *disp_info; - - if (!drm_enc || !drm_enc->crtc) { - SDE_ERROR("invalid encoder\n"); - return; - } - sde_enc = to_sde_encoder_virt(drm_enc); - disp_info = &sde_enc->disp_info; - - if (!sde_kms_power_resource_is_enabled(drm_enc->dev)) { - SDE_ERROR("power resource is not enabled\n"); - return; - } - - if (!sde_enc->crtc) - sde_enc->crtc = drm_enc->crtc; - - comp_info = &sde_enc->mode_info.comp_info; - cur_mode = &sde_enc->base.crtc->state->adjusted_mode; - - SDE_DEBUG_ENC(sde_enc, "\n"); - SDE_EVT32(DRMID(drm_enc), cur_mode->hdisplay, cur_mode->vdisplay); - - sde_enc->cur_master = NULL; - for (i = 0; i < sde_enc->num_phys_encs; i++) { - struct sde_encoder_phys *phys = sde_enc->phys_encs[i]; - - if (phys && phys->ops.is_master && phys->ops.is_master(phys)) { - SDE_DEBUG_ENC(sde_enc, "master is now idx %d\n", i); - sde_enc->cur_master = phys; - break; - } - } - - if (!sde_enc->cur_master) { - SDE_ERROR("virt encoder has no master! num_phys %d\n", i); - return; - } - - _sde_encoder_input_handler_register(drm_enc); - c_state = to_sde_connector_state(sde_enc->cur_master->connector->state); - if (!c_state) { - SDE_ERROR("invalid connector state\n"); - return; - } - - msm_mode = &c_state->msm_mode; - if ((drm_enc->crtc->state->connectors_changed && - sde_encoder_in_clone_mode(drm_enc)) || - !(msm_is_mode_seamless_vrr(msm_mode) - || msm_is_mode_seamless_dms(msm_mode) - || msm_is_mode_seamless_dyn_clk(msm_mode))) - kthread_init_delayed_work(&sde_enc->delayed_off_work, - sde_encoder_off_work); - - ret = sde_encoder_resource_control(drm_enc, SDE_ENC_RC_EVENT_KICKOFF); - if (ret) { - SDE_ERROR_ENC(sde_enc, "sde resource control failed: %d\n", - ret); - return; - } - - memset(&sde_enc->cur_master->intf_cfg_v1, 0, - sizeof(sde_enc->cur_master->intf_cfg_v1)); + struct msm_compression_info *comp_info = &sde_enc->mode_info.comp_info; + struct msm_display_info *disp_info = &sde_enc->disp_info; + int i; for (i = 0; i < sde_enc->num_phys_encs; i++) { struct sde_encoder_phys *phys = sde_enc->phys_encs[i]; @@ -2873,6 +2790,95 @@ static void sde_encoder_virt_enable(struct drm_encoder *drm_enc) sde_enc->cur_master->ops.restore(sde_enc->cur_master); else if (sde_enc->cur_master->ops.enable) sde_enc->cur_master->ops.enable(sde_enc->cur_master); +} + +static void sde_encoder_off_work(struct kthread_work *work) +{ + struct sde_encoder_virt *sde_enc = container_of(work, + struct sde_encoder_virt, delayed_off_work.work); + struct drm_encoder *drm_enc; + + if (!sde_enc) { + SDE_ERROR("invalid sde encoder\n"); + return; + } + drm_enc = &sde_enc->base; + + SDE_ATRACE_BEGIN("sde_encoder_off_work"); + sde_encoder_idle_request(drm_enc); + SDE_ATRACE_END("sde_encoder_off_work"); +} + +static void sde_encoder_virt_enable(struct drm_encoder *drm_enc) +{ + struct sde_encoder_virt *sde_enc = NULL; + int i, ret = 0; + struct sde_connector_state *c_state; + struct drm_display_mode *cur_mode = NULL; + struct msm_display_mode *msm_mode; + + if (!drm_enc || !drm_enc->crtc) { + SDE_ERROR("invalid encoder\n"); + return; + } + sde_enc = to_sde_encoder_virt(drm_enc); + + if (!sde_kms_power_resource_is_enabled(drm_enc->dev)) { + SDE_ERROR("power resource is not enabled\n"); + return; + } + + if (!sde_enc->crtc) + sde_enc->crtc = drm_enc->crtc; + + cur_mode = &sde_enc->base.crtc->state->adjusted_mode; + + SDE_DEBUG_ENC(sde_enc, "\n"); + SDE_EVT32(DRMID(drm_enc), cur_mode->hdisplay, cur_mode->vdisplay); + + sde_enc->cur_master = NULL; + for (i = 0; i < sde_enc->num_phys_encs; i++) { + struct sde_encoder_phys *phys = sde_enc->phys_encs[i]; + + if (phys && phys->ops.is_master && phys->ops.is_master(phys)) { + SDE_DEBUG_ENC(sde_enc, "master is now idx %d\n", i); + sde_enc->cur_master = phys; + break; + } + } + + if (!sde_enc->cur_master) { + SDE_ERROR("virt encoder has no master! num_phys %d\n", i); + return; + } + + _sde_encoder_input_handler_register(drm_enc); + c_state = to_sde_connector_state(sde_enc->cur_master->connector->state); + if (!c_state) { + SDE_ERROR("invalid connector state\n"); + return; + } + + msm_mode = &c_state->msm_mode; + if ((drm_enc->crtc->state->connectors_changed && + sde_encoder_in_clone_mode(drm_enc)) || + !(msm_is_mode_seamless_vrr(msm_mode) + || msm_is_mode_seamless_dms(msm_mode) + || msm_is_mode_seamless_dyn_clk(msm_mode))) + kthread_init_delayed_work(&sde_enc->delayed_off_work, + sde_encoder_off_work); + + ret = sde_encoder_resource_control(drm_enc, SDE_ENC_RC_EVENT_KICKOFF); + if (ret) { + SDE_ERROR_ENC(sde_enc, "sde resource control failed: %d\n", + ret); + return; + } + + memset(&sde_enc->cur_master->intf_cfg_v1, 0, + sizeof(sde_enc->cur_master->intf_cfg_v1)); + + sde_encoder_populate_encoder_phys(drm_enc, sde_enc, msm_mode); _sde_encoder_virt_enable_helper(drm_enc); } diff --git a/msm/sde/sde_hw_sspp.c b/msm/sde/sde_hw_sspp.c index 43c873b7..bb721817 100644 --- a/msm/sde/sde_hw_sspp.c +++ b/msm/sde/sde_hw_sspp.c @@ -295,6 +295,36 @@ static void sde_hw_sspp_set_src_split_order(struct sde_hw_pipe *ctx, SDE_REG_WRITE(c, op_mode_off + idx, opmode); } +static void sde_hw_sspp_setup_ubwc(struct sde_hw_pipe *ctx, struct sde_hw_blk_reg_map *c, + const struct sde_format *fmt, bool const_alpha_en, bool const_color_en) +{ + u32 alpha_en_mask = 0, color_en_mask = 0; + + SDE_REG_WRITE(c, SSPP_FETCH_CONFIG, + SDE_FETCH_CONFIG_RESET_VALUE | + ctx->mdp->highest_bank_bit << 18); + + if (IS_UBWC_40_SUPPORTED(ctx->catalog->ubwc_version)) { + SDE_REG_WRITE(c, SSPP_UBWC_STATIC_CTRL, + SDE_FORMAT_IS_YUV(fmt) ? 0 : BIT(30)); + } else if (IS_UBWC_30_SUPPORTED(ctx->catalog->ubwc_version)) { + color_en_mask = const_color_en ? BIT(30) : 0; + SDE_REG_WRITE(c, SSPP_UBWC_STATIC_CTRL, + color_en_mask | (ctx->mdp->ubwc_swizzle) | + (ctx->mdp->highest_bank_bit << 4)); + } else if (IS_UBWC_20_SUPPORTED(ctx->catalog->ubwc_version)) { + alpha_en_mask = const_alpha_en ? BIT(31) : 0; + SDE_REG_WRITE(c, SSPP_UBWC_STATIC_CTRL, + alpha_en_mask | (ctx->mdp->ubwc_swizzle) | + (ctx->mdp->highest_bank_bit << 4)); + } else if (IS_UBWC_10_SUPPORTED(ctx->catalog->ubwc_version)) { + alpha_en_mask = const_alpha_en ? BIT(31) : 0; + SDE_REG_WRITE(c, SSPP_UBWC_STATIC_CTRL, + alpha_en_mask | (ctx->mdp->ubwc_swizzle & 0x1) | + BIT(8) | (ctx->mdp->highest_bank_bit << 4)); + } +} + /** * Setup source pixel format, flip, */ @@ -306,7 +336,6 @@ static void sde_hw_sspp_setup_format(struct sde_hw_pipe *ctx, struct sde_hw_blk_reg_map *c; u32 chroma_samp, unpack, src_format; u32 opmode = 0; - u32 alpha_en_mask = 0, color_en_mask = 0; u32 op_mode_off, unpack_pat_off, format_off; u32 idx; bool const_color_en = true; @@ -377,28 +406,8 @@ static void sde_hw_sspp_setup_format(struct sde_hw_pipe *ctx, if (SDE_FORMAT_IS_UBWC(fmt)) opmode |= MDSS_MDP_OP_BWC_EN; src_format |= (fmt->fetch_mode & 3) << 30; /*FRAME_FORMAT */ - SDE_REG_WRITE(c, SSPP_FETCH_CONFIG, - SDE_FETCH_CONFIG_RESET_VALUE | - ctx->mdp->highest_bank_bit << 18); - if (IS_UBWC_40_SUPPORTED(ctx->catalog->ubwc_version)) { - SDE_REG_WRITE(c, SSPP_UBWC_STATIC_CTRL, - SDE_FORMAT_IS_YUV(fmt) ? 0 : BIT(30)); - } else if (IS_UBWC_10_SUPPORTED(ctx->catalog->ubwc_version)) { - alpha_en_mask = const_alpha_en ? BIT(31) : 0; - SDE_REG_WRITE(c, SSPP_UBWC_STATIC_CTRL, - alpha_en_mask | (ctx->mdp->ubwc_swizzle & 0x1) | - BIT(8) | (ctx->mdp->highest_bank_bit << 4)); - } else if (IS_UBWC_20_SUPPORTED(ctx->catalog->ubwc_version)) { - alpha_en_mask = const_alpha_en ? BIT(31) : 0; - SDE_REG_WRITE(c, SSPP_UBWC_STATIC_CTRL, - alpha_en_mask | (ctx->mdp->ubwc_swizzle) | - (ctx->mdp->highest_bank_bit << 4)); - } else if (IS_UBWC_30_SUPPORTED(ctx->catalog->ubwc_version)) { - color_en_mask = const_color_en ? BIT(30) : 0; - SDE_REG_WRITE(c, SSPP_UBWC_STATIC_CTRL, - color_en_mask | (ctx->mdp->ubwc_swizzle) | - (ctx->mdp->highest_bank_bit << 4)); - } + + sde_hw_sspp_setup_ubwc(ctx, c, fmt, const_alpha_en, const_color_en); } opmode |= MDSS_MDP_OP_PE_OVERRIDE;