From 2ec044eec31dade2be625368488a0a524bc439a2 Mon Sep 17 00:00:00 2001 From: Samantha Tran Date: Thu, 19 Mar 2020 11:36:39 -0700 Subject: [PATCH] disp: msm: sde: correct line time to include DSC Current computation of line time does not include compression ratio from DSC. This change computes compression ratio during any mode change and stores it in sde_crtc. Change-Id: Ib1e045dce17fcf006447d4562b402cc3f214ed8c Signed-off-by: Samantha Tran --- msm/sde/sde_crtc.h | 31 +++++++++++++++++++++++++++++++ msm/sde/sde_encoder.c | 2 ++ msm/sde/sde_hw_util.c | 10 ++++++---- msm/sde/sde_hw_util.h | 2 +- msm/sde/sde_plane.c | 5 ++++- 5 files changed, 44 insertions(+), 6 deletions(-) diff --git a/msm/sde/sde_crtc.h b/msm/sde/sde_crtc.h index 0f66455b92e8..85f7174c1e96 100644 --- a/msm/sde/sde_crtc.h +++ b/msm/sde/sde_crtc.h @@ -29,6 +29,7 @@ #include "sde_hw_ds.h" #define SDE_CRTC_NAME_SIZE 12 +#define RGB_NUM_COMPONENTS 3 /* define the maximum number of in-flight frame events */ /* Expand it to 2x for handling atleast 2 connectors safely */ @@ -263,6 +264,7 @@ 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 + * @comp_ratio : Compression ratio */ struct sde_crtc { struct drm_crtc base; @@ -342,6 +344,8 @@ struct sde_crtc { struct mutex ltm_buffer_lock; spinlock_t ltm_lock; bool needs_hw_reset; + + int comp_ratio; }; #define to_sde_crtc(x) container_of(x, struct sde_crtc, base) @@ -832,4 +836,31 @@ void sde_crtc_get_misr_info(struct drm_crtc *crtc, int sde_crtc_get_num_datapath(struct drm_crtc *crtc, struct drm_connector *connector); +/* + * sde_crtc_set_compression_ratio - set compression ratio src_bpp/target_bpp + * @msm_mode_info: Mode info + * @crtc: Pointer to drm crtc structure + */ +static inline void sde_crtc_set_compression_ratio( + struct msm_mode_info mode_info, struct drm_crtc *crtc) +{ + int target_bpp, src_bpp; + struct sde_crtc *sde_crtc = to_sde_crtc(crtc); + + /** + * In cases where DSC compression type is not found, set + * compression value to default value of 1. + */ + if (mode_info.comp_info.comp_type != MSM_DISPLAY_COMPRESSION_DSC) { + sde_crtc->comp_ratio = 1; + goto end; + } + + target_bpp = mode_info.comp_info.dsc_info.bpp; + src_bpp = mode_info.comp_info.dsc_info.bpc * RGB_NUM_COMPONENTS; + sde_crtc->comp_ratio = mult_frac(1, src_bpp, target_bpp); +end: + SDE_DEBUG("sde_crtc comp ratio: %d\n", sde_crtc->comp_ratio); +} + #endif /* _SDE_CRTC_H_ */ diff --git a/msm/sde/sde_encoder.c b/msm/sde/sde_encoder.c index 30067a6c849a..b3e60de70467 100644 --- a/msm/sde/sde_encoder.c +++ b/msm/sde/sde_encoder.c @@ -2915,6 +2915,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_crtc_set_compression_ratio(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_hw_util.c b/msm/sde/sde_hw_util.c index 819af9e22f84..ff4b5dfd08f0 100644 --- a/msm/sde/sde_hw_util.c +++ b/msm/sde/sde_hw_util.c @@ -1,6 +1,6 @@ // SPDX-License-Identifier: GPL-2.0-only /* - * Copyright (c) 2015-2019, The Linux Foundation. All rights reserved. + * Copyright (c) 2015-2020, The Linux Foundation. All rights reserved. */ #define pr_fmt(fmt) "[drm:%s:%d] " fmt, __func__, __LINE__ @@ -549,9 +549,10 @@ 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 + * @comp_ratio: compression ratio * 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 comp_ratio) { u64 pclk_rate; u32 pclk_period; @@ -570,10 +571,11 @@ uint32_t sde_get_linetime(struct drm_display_mode *mode) } /* - * Line time calculation based on Pixel clock and HTOTAL. + * Line time calculation based on Pixel clock, HTOTAL, and comp_ratio. * Final unit is in ns. */ - line_time = (pclk_period * mode->htotal) / 1000; + line_time = DIV_ROUND_UP(mult_frac(pclk_period, mode->htotal, + comp_ratio), 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 d9e8d28cdfe5..84b16336c591 100644 --- a/msm/sde/sde_hw_util.h +++ b/msm/sde/sde_hw_util.h @@ -217,7 +217,7 @@ 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 comp_ratio); 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 874dc4e28e00..3062b7a57472 100644 --- a/msm/sde/sde_plane.c +++ b/msm/sde/sde_plane.c @@ -2843,7 +2843,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->comp_ratio); /* nS */ u32 fal1_target_idle_time_ns = psde->catalog->uidle_cfg.fal1_target_idle_time * 1000; /* nS */ u32 fal10_target_idle_time_ns =