Ver Fonte

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 <[email protected]>
Samantha Tran há 5 anos atrás
pai
commit
7401ef1995

+ 18 - 0
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_ */

+ 2 - 0
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) &&

+ 40 - 0
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;

+ 8 - 0
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

+ 9 - 4
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;

+ 2 - 1
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)
 {

+ 4 - 1
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 =