Эх сурвалжийг харах

disp: msm: dp: fix pbn value for MST RG calculation

The DP MST driver calculates the PBN value for each mode during
mode enumeration. This PBN value is later used to calculate slot
count and also MST RG parameters. But if DSC and/or FEC is enabled,
then the slot calculation needs the PBN with overhead, but
RG calculator needs the one without. But currently, the driver is
using the PBN with overhead for both. This double counting of the
overhead for RG calculation causes MST FIFO overflow for certain
usecases.

This change fixes this by caching both PBN values during mode
enumeration and using the PBN value without overhead as input
to RG calculation.

Change-Id: Id58e91068c25202e6528a793ab736bc51732961f
Signed-off-by: Rajkumar Subbiah <[email protected]>
Rajkumar Subbiah 2 жил өмнө
parent
commit
4e82bfb0fa

+ 1 - 1
msm/dp/dp_ctrl.c

@@ -1122,7 +1122,7 @@ static void dp_ctrl_mst_calculate_rg(struct dp_ctrl_private *ctrl,
 	u64 lclk = 0;
 	u64 lanes = ctrl->link->link_params.lane_count;
 	u64 bpp = panel->pinfo.bpp;
-	u64 pbn = panel->pbn;
+	u64 pbn = panel->pinfo.pbn_no_overhead; // before dsc/fec overhead
 	u64 numerator, denominator, temp, temp1, temp2;
 	u32 x_int = 0, y_frac_enum = 0;
 	u64 target_strm_sym, ts_int_fixp, ts_frac_fixp, y_frac_enum_fixp;

+ 3 - 0
msm/dp/dp_display.c

@@ -2350,6 +2350,9 @@ static int dp_display_set_mode(struct dp_display *dp_display, void *panel,
 	mode->timing.bpp = dp->panel->get_mode_bpp(dp->panel,
 			mode->timing.bpp, mode->timing.pixel_clk_khz, dsc_en);
 
+	if (dp->mst.mst_active)
+		dp->mst.cbs.set_mst_mode_params(&dp->dp_display, mode);
+
 	dp_panel->pinfo = mode->timing;
 	mutex_unlock(&dp->session_lock);
 	SDE_EVT32_EXTERNAL(SDE_EVTLOG_FUNC_EXIT, dp->state);

+ 1 - 0
msm/dp/dp_display.h

@@ -24,6 +24,7 @@ struct dp_mst_drm_cbs {
 	void (*set_drv_state)(void *dp_display,
 			enum dp_drv_state mst_state);
 	int (*set_mgr_state)(void *dp_display, bool state);
+	void (*set_mst_mode_params)(void *dp_display, struct dp_display_mode *mode);
 };
 
 struct dp_mst_drm_install_info {

+ 16 - 8
msm/dp/dp_mst_drm.c

@@ -309,16 +309,14 @@ static int dp_mst_calc_pbn_mode(struct dp_display_mode *dp_mode)
 	int pbn, bpp;
 	bool dsc_en;
 	s64 pbn_fp;
+	struct dp_panel_info *pinfo = &dp_mode->timing;
 
-	dsc_en = dp_mode->timing.comp_info.enabled;
-	bpp = dsc_en ?
-		DSC_BPP(dp_mode->timing.comp_info.dsc_info.config)
-		: dp_mode->timing.bpp;
+	dsc_en = pinfo->comp_info.enabled;
+	bpp = dsc_en ? DSC_BPP(pinfo->comp_info.dsc_info.config) : pinfo->bpp;
 
-	pbn = drm_dp_calc_pbn_mode(dp_mode->timing.pixel_clk_khz, bpp, false);
+	pbn = drm_dp_calc_pbn_mode(pinfo->pixel_clk_khz, bpp, false);
 	pbn_fp = drm_fixp_from_fraction(pbn, 1);
-
-	DP_DEBUG_V("before overhead pbn:%d, bpp:%d\n", pbn, bpp);
+	pinfo->pbn_no_overhead = pbn;
 
 	if (dsc_en)
 		pbn_fp = drm_fixp_mul(pbn_fp, dp_mode->dsc_overhead_fp);
@@ -327,8 +325,11 @@ static int dp_mst_calc_pbn_mode(struct dp_display_mode *dp_mode)
 		pbn_fp = drm_fixp_mul(pbn_fp, dp_mode->fec_overhead_fp);
 
 	pbn = drm_fixp2int(pbn_fp);
+	pinfo->pbn = pbn;
+
+	DP_DEBUG_V("pbn before overhead:%d pbn final:%d, bpp:%d\n", pinfo->pbn_no_overhead, pbn,
+			bpp);
 
-	DP_DEBUG_V("after overhead pbn:%d, bpp:%d\n", pbn, bpp);
 	return pbn;
 }
 
@@ -2024,6 +2025,12 @@ static void dp_mst_set_state(void *dp_display, enum dp_drv_state mst_state)
 	DP_MST_INFO("mst power state:%d\n", mst_state);
 }
 
+static void dp_mst_display_set_mst_mode_params(void *dp_display, struct dp_display_mode *mode)
+{
+	// update pbn values that will later be used for rg calculation
+	dp_mst_calc_pbn_mode(mode);
+}
+
 /* DP MST APIs */
 
 static const struct dp_mst_drm_cbs dp_mst_display_cbs = {
@@ -2031,6 +2038,7 @@ static const struct dp_mst_drm_cbs dp_mst_display_cbs = {
 	.hpd_irq = dp_mst_display_hpd_irq,
 	.set_drv_state = dp_mst_set_state,
 	.set_mgr_state = dp_mst_display_set_mgr_state,
+	.set_mst_mode_params = dp_mst_display_set_mst_mode_params,
 };
 
 static const struct drm_dp_mst_topology_cbs dp_mst_drm_cbs = {

+ 2 - 0
msm/dp/dp_panel.h

@@ -64,6 +64,8 @@ struct dp_panel_info {
 	bool widebus_en;
 	struct msm_compression_info comp_info;
 	s64 dsc_overhead_fp;
+	u32 pbn_no_overhead;
+	u32 pbn;
 };
 
 struct dp_display_mode {