diff --git a/msm/sde/sde_crtc.h b/msm/sde/sde_crtc.h index 01fa624e99..3b5470b4b2 100644 --- a/msm/sde/sde_crtc.h +++ b/msm/sde/sde_crtc.h @@ -255,6 +255,8 @@ struct sde_crtc_misr_info { * @ltm_buffer_lock : muttx to protect ltm_buffers allcation and free * @ltm_lock : Spinlock to protect ltm buffer_cnt, hist_en and ltm lists * @needs_hw_reset : Initiate a hw ctl reset + * @src_bpp : source bpp used to calculate compression ratio + * @target_bpp : target bpp used to calculate compression ratio */ struct sde_crtc { struct drm_crtc base; @@ -337,6 +339,9 @@ struct sde_crtc { struct mutex ltm_buffer_lock; spinlock_t ltm_lock; bool needs_hw_reset; + + int src_bpp; + int target_bpp; }; #define to_sde_crtc(x) container_of(x, struct sde_crtc, base) @@ -830,4 +835,17 @@ void sde_crtc_misr_setup(struct drm_crtc *crtc, bool enable, u32 frame_count); void sde_crtc_get_misr_info(struct drm_crtc *crtc, struct sde_crtc_misr_info *crtc_misr_info); +/** + * sde_crtc_set_bpp - set src and target bpp values + * @sde_crtc: Pointer to sde crtc struct + * @src_bpp: source bpp value to be stored + * @target_bpp: target value to be stored + */ +static inline void sde_crtc_set_bpp(struct sde_crtc *sde_crtc, int src_bpp, + int target_bpp) +{ + sde_crtc->src_bpp = src_bpp; + sde_crtc->target_bpp = target_bpp; +} + #endif /* _SDE_CRTC_H_ */ diff --git a/msm/sde/sde_encoder.c b/msm/sde/sde_encoder.c index 942e02924a..144f2339f9 100644 --- a/msm/sde/sde_encoder.c +++ b/msm/sde/sde_encoder.c @@ -2134,6 +2134,8 @@ static void sde_encoder_virt_mode_set(struct drm_encoder *drm_enc, /* store the mode_info */ sde_connector_state_get_mode_info(conn->state, &sde_enc->mode_info); + sde_encoder_dce_set_bpp(sde_enc->mode_info, sde_enc->crtc); + /* release resources before seamless mode change */ if (msm_is_mode_seamless_dms(adj_mode) || (msm_is_mode_seamless_dyn_clk(adj_mode) && diff --git a/msm/sde/sde_encoder_dce.c b/msm/sde/sde_encoder_dce.c index 0861f89dc4..2fb842e1e5 100644 --- a/msm/sde/sde_encoder_dce.c +++ b/msm/sde/sde_encoder_dce.c @@ -842,6 +842,46 @@ void _dce_helper_flush_vdc(struct sde_encoder_virt *sde_enc) } } +void sde_encoder_dce_set_bpp(struct msm_mode_info mode_info, + struct drm_crtc *crtc) +{ + struct sde_crtc *sde_crtc = to_sde_crtc(crtc); + enum msm_display_compression_type comp_type; + int src_bpp, target_bpp; + + if (!sde_crtc) { + SDE_DEBUG("invalid sde_crtc\n"); + return; + } + + comp_type = mode_info.comp_info.comp_type; + /** + * In cases where DSC or VDC compression type is not found, set + * src and target bpp to get compression ratio 8/8 (default). + */ + if (comp_type == MSM_DISPLAY_COMPRESSION_DSC) { + struct msm_display_dsc_info dsc_info = + mode_info.comp_info.dsc_info; + src_bpp = msm_get_src_bpc(dsc_info.chroma_format, + dsc_info.config.bits_per_component); + target_bpp = dsc_info.config.bits_per_pixel >> 4; + } else if (comp_type == MSM_DISPLAY_COMPRESSION_VDC) { + struct msm_display_vdc_info vdc_info = + mode_info.comp_info.vdc_info; + src_bpp = msm_get_src_bpc(vdc_info.chroma_format, + vdc_info.bits_per_component); + target_bpp = vdc_info.bits_per_pixel >> 4; + } else { + src_bpp = 8; + target_bpp = 8; + } + + sde_crtc_set_bpp(sde_crtc, src_bpp, target_bpp); + + SDE_DEBUG("sde_crtc src_bpp = %d, target_bpp = %d\n", + sde_crtc->src_bpp, sde_crtc->target_bpp); +} + void sde_encoder_dce_disable(struct sde_encoder_virt *sde_enc) { enum msm_display_compression_type comp_type; diff --git a/msm/sde/sde_encoder_dce.h b/msm/sde/sde_encoder_dce.h index d475dfdaf3..b217a03484 100644 --- a/msm/sde/sde_encoder_dce.h +++ b/msm/sde/sde_encoder_dce.h @@ -8,6 +8,14 @@ #include "sde_encoder.h" +/** + * sde_encoder_dce_set_bpp : set src_bpp and target_bpp in sde_crtc + * @msm_mode_info: Mode info + * @crtc: Pointer to drm crtc structure + */ +void sde_encoder_dce_set_bpp( + struct msm_mode_info mode_info, struct drm_crtc *crtc); + /** * sde_encoder_dce_disable : function to disable compression * @sde_enc: pointer to virtual encoder structure diff --git a/msm/sde/sde_hw_util.c b/msm/sde/sde_hw_util.c index 2ba8b237c5..e44b67ceae 100644 --- a/msm/sde/sde_hw_util.c +++ b/msm/sde/sde_hw_util.c @@ -549,9 +549,12 @@ uint32_t sde_copy_formats( /** * sde_get_linetime - returns the line time for a given mode * @mode: pointer to drm mode to calculate the line time + * @src_bpp: source bpp + * @target_bpp: target bpp * Return: line time of display mode in nS */ -uint32_t sde_get_linetime(struct drm_display_mode *mode) +uint32_t sde_get_linetime(struct drm_display_mode *mode, + int src_bpp, int target_bpp) { u64 pclk_rate; u32 pclk_period; @@ -570,10 +573,12 @@ uint32_t sde_get_linetime(struct drm_display_mode *mode) } /* - * Line time calculation based on Pixel clock and HTOTAL. - * Final unit is in ns. + * Line time calculation based on Pixel clock, HTOTAL, and comp_ratio. + * Compression ratio found by src_bpp/target_bpp. Final unit is in ns. */ - line_time = (pclk_period * mode->htotal) / 1000; + line_time = pclk_period * mode->htotal; + line_time = DIV_ROUND_UP(mult_frac(line_time, target_bpp, + src_bpp), 1000); if (line_time == 0) { SDE_ERROR("line time calculation is 0\n"); return 0; diff --git a/msm/sde/sde_hw_util.h b/msm/sde/sde_hw_util.h index 316e739e5e..6e4ae06396 100644 --- a/msm/sde/sde_hw_util.h +++ b/msm/sde/sde_hw_util.h @@ -215,7 +215,8 @@ uint32_t sde_copy_formats( const struct sde_format_extended *src_list, uint32_t src_list_size); -uint32_t sde_get_linetime(struct drm_display_mode *mode); +uint32_t sde_get_linetime(struct drm_display_mode *mode, + int src_bpp, int target_bpp); static inline bool is_qseed3_rev_qseed3lite(struct sde_mdss_cfg *sde_cfg) { diff --git a/msm/sde/sde_plane.c b/msm/sde/sde_plane.c index de7cad87bf..abad3c2151 100644 --- a/msm/sde/sde_plane.c +++ b/msm/sde/sde_plane.c @@ -2813,7 +2813,10 @@ static void _sde_plane_setup_uidle(struct drm_crtc *crtc, struct sde_rect *src, struct sde_rect *dst) { struct sde_hw_pipe_uidle_cfg cfg; - u32 line_time = sde_get_linetime(&crtc->mode); /* nS */ + struct sde_crtc *sde_crtc = to_sde_crtc(crtc); + + u32 line_time = sde_get_linetime(&crtc->mode, + sde_crtc->src_bpp, sde_crtc->target_bpp); /* nS */ u32 fal1_target_idle_time_ns = psde->catalog->uidle_cfg.fal1_target_idle_time * 1000; /* nS */ u32 fal10_target_idle_time_ns =