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 =