From 7401ef1995fc7cd4f79876a0c782416125ba49ec Mon Sep 17 00:00:00 2001 From: Samantha Tran Date: Thu, 26 Mar 2020 19:47:27 -0700 Subject: [PATCH] disp: msm: sde: correct line time to include compression ratio Current computation of line time does not include compression ratio from either DSC or VDC. This change stores source bpp and target bpp in sde_crtc during sde encoder mode set to be used while calculating line time. Change-Id: Ib1e045dce17fcf006447d4562b402cc3f214ed8c Signed-off-by: Samantha Tran --- msm/sde/sde_crtc.h | 18 ++++++++++++++++++ msm/sde/sde_encoder.c | 2 ++ msm/sde/sde_encoder_dce.c | 40 +++++++++++++++++++++++++++++++++++++++ msm/sde/sde_encoder_dce.h | 8 ++++++++ msm/sde/sde_hw_util.c | 13 +++++++++---- msm/sde/sde_hw_util.h | 3 ++- msm/sde/sde_plane.c | 5 ++++- 7 files changed, 83 insertions(+), 6 deletions(-) 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 572a9323d8..c4571f2d12 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 =