Explorar o código

disp: msm: dsi: optimize wait time in DSI timing DB update

Timing DB needs to be disabled after panel vnsyc.
Update the wait time to reflect difference in line time
between MDP and panel vsync.

Change-Id: Ib5282d67995e8379ead928218f31a8f9fe7fa978
Signed-off-by: Shamika Joshi <[email protected]>
Shamika Joshi %!s(int64=2) %!d(string=hai) anos
pai
achega
495a6a8731

+ 9 - 2
msm/dsi/dsi_ctrl.c

@@ -2516,13 +2516,14 @@ exit:
  * dsi_ctrl_timing_db_update() - update only controller Timing DB
  * @dsi_ctrl:          DSI controller handle.
  * @enable:            Enable/disable Timing DB register
+ * @pf_time_in_us:           Programmable fetch time in micro-seconds
  *
  *  Update timing db register value during dfps usecases
  *
  * Return: error code.
  */
 int dsi_ctrl_timing_db_update(struct dsi_ctrl *dsi_ctrl,
-		bool enable)
+		bool enable, u32 pf_time_in_us)
 {
 	int rc = 0;
 
@@ -2550,7 +2551,13 @@ int dsi_ctrl_timing_db_update(struct dsi_ctrl *dsi_ctrl,
 	 * flush is after panel_vsync. So, added the recommended
 	 * delays after dfps update.
 	 */
-	usleep_range(2000, 2010);
+	if (pf_time_in_us > 2000) {
+		DSI_CTRL_ERR(dsi_ctrl, "Programmable fetch time check failed, pf_time_in_us=%u\n",
+				pf_time_in_us);
+		pf_time_in_us = 2000;
+	}
+
+	usleep_range(pf_time_in_us, pf_time_in_us + 10);
 
 	dsi_ctrl->hw.ops.set_timing_db(&dsi_ctrl->hw, enable);
 

+ 2 - 1
msm/dsi/dsi_ctrl.h

@@ -412,13 +412,14 @@ int dsi_ctrl_update_host_config(struct dsi_ctrl *dsi_ctrl,
  * dsi_ctrl_timing_db_update() - update only controller Timing DB
  * @dsi_ctrl:          DSI controller handle.
  * @enable:            Enable/disable Timing DB register
+ * @pf_time_in_us:           Programmable fetch time in micro-seconds
  *
  * Update timing db register value during dfps usecases
  *
  * Return: error code.
  */
 int dsi_ctrl_timing_db_update(struct dsi_ctrl *dsi_ctrl,
-		bool enable);
+		bool enable, u32 pf_time_in_us);
 
 /**
  * dsi_ctrl_async_timing_update() - update only controller timing

+ 6 - 3
msm/dsi/dsi_drm.c

@@ -1,6 +1,6 @@
 // SPDX-License-Identifier: GPL-2.0-only
 /*
- * Copyright (c) 2021-2022 Qualcomm Innovation Center, Inc. All rights reserved.
+ * Copyright (c) 2021-2023 Qualcomm Innovation Center, Inc. All rights reserved.
  * Copyright (c) 2016-2021, The Linux Foundation. All rights reserved.
  */
 
@@ -1292,6 +1292,7 @@ int dsi_conn_post_kickoff(struct drm_connector *connector,
 	struct dsi_display *display;
 	struct dsi_display_ctrl *m_ctrl, *ctrl;
 	int i, rc = 0, ctrl_version;
+	u32 pf_time_in_us = 0;
 	bool enable;
 	struct dsi_dyn_clk_caps *dyn_clk_caps;
 
@@ -1316,10 +1317,12 @@ int dsi_conn_post_kickoff(struct drm_connector *connector,
 	display = c_bridge->display;
 	dyn_clk_caps = &(display->panel->dyn_clk_caps);
 
+	pf_time_in_us = sde_encoder_get_programmed_fetch_time(encoder);
+
 	if (adj_mode.dsi_mode_flags & DSI_MODE_FLAG_VRR) {
 		m_ctrl = &display->ctrl[display->clk_master_idx];
 		ctrl_version = m_ctrl->ctrl->version;
-		rc = dsi_ctrl_timing_db_update(m_ctrl->ctrl, false);
+		rc = dsi_ctrl_timing_db_update(m_ctrl->ctrl, false, pf_time_in_us);
 		if (rc) {
 			DSI_ERR("[%s] failed to dfps update  rc=%d\n",
 				display->name, rc);
@@ -1354,7 +1357,7 @@ int dsi_conn_post_kickoff(struct drm_connector *connector,
 			if (!ctrl->ctrl || (ctrl == m_ctrl))
 				continue;
 
-			rc = dsi_ctrl_timing_db_update(ctrl->ctrl, false);
+			rc = dsi_ctrl_timing_db_update(ctrl->ctrl, false, pf_time_in_us);
 			if (rc) {
 				DSI_ERR("[%s] failed to dfps update rc=%d\n",
 					display->name,  rc);

+ 20 - 1
msm/sde/sde_encoder.c

@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2021-2022 Qualcomm Innovation Center, Inc. All rights reserved.
+ * Copyright (c) 2021-2023 Qualcomm Innovation Center, Inc. All rights reserved.
  * Copyright (c) 2014-2021, The Linux Foundation. All rights reserved.
  * Copyright (C) 2013 Red Hat
  * Author: Rob Clark <[email protected]>
@@ -155,6 +155,25 @@ void sde_encoder_uidle_enable(struct drm_encoder *drm_enc, bool enable)
 	}
 }
 
+u32 sde_encoder_get_programmed_fetch_time(struct drm_encoder *drm_enc)
+{
+	struct sde_encoder_virt *sde_enc;
+	struct sde_encoder_phys *phys;
+	bool is_vid;
+
+	sde_enc = to_sde_encoder_virt(drm_enc);
+
+	if (!sde_enc || !sde_enc->phys_encs[0]) {
+		SDE_ERROR("invalid params\n");
+		return U32_MAX;
+	}
+
+	phys = sde_enc->phys_encs[0];
+	is_vid = sde_encoder_check_curr_mode(drm_enc, MSM_DISPLAY_VIDEO_MODE);
+
+	return is_vid ? phys->pf_time_in_us : 0;
+}
+
 ktime_t sde_encoder_calc_last_vsync_timestamp(struct drm_encoder *drm_enc)
 {
 	struct sde_encoder_virt *sde_enc;

+ 8 - 1
msm/sde/sde_encoder.h

@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2021-2022 Qualcomm Innovation Center, Inc. All rights reserved.
+ * Copyright (c) 2021-2023 Qualcomm Innovation Center, Inc. All rights reserved.
  * Copyright (c) 2015-2021, The Linux Foundation. All rights reserved.
  * Copyright (C) 2013 Red Hat
  * Author: Rob Clark <[email protected]>
@@ -704,6 +704,13 @@ bool sde_encoder_is_line_insertion_supported(struct drm_encoder *drm_enc);
  */
 struct sde_hw_ctl *sde_encoder_get_hw_ctl(struct sde_connector *c_conn);
 
+/*
+ * sde_encoder_get_programmed_fetch_time - gets the programmable fetch time for video encoders
+ * @drm_enc:    Pointer to drm encoder structure
+ * @Return: programmable fetch time in microseconds
+ */
+u32 sde_encoder_get_programmed_fetch_time(struct drm_encoder *encoder);
+
 void sde_encoder_add_data_to_minidump_va(struct drm_encoder *drm_enc);
 
 /**

+ 3 - 1
msm/sde/sde_encoder_phys.h

@@ -1,6 +1,6 @@
 /* SPDX-License-Identifier: GPL-2.0-only */
 /*
- * Copyright (c) 2021-2022 Qualcomm Innovation Center, Inc. All rights reserved.
+ * Copyright (c) 2021-2023 Qualcomm Innovation Center, Inc. All rights reserved.
  * Copyright (c) 2015-2021, The Linux Foundation. All rights reserved.
  */
 
@@ -316,6 +316,7 @@ struct sde_encoder_irq {
  * @in_clone_mode		Indicates if encoder is in clone mode ref@CWB
  * @vfp_cached:			cached vertical front porch to be used for
  *				programming ROT and MDP fetch start
+ * @pf_time_in_us:		Programmable fetch time in micro-seconds
  * @frame_trigger_mode:		frame trigger mode indication for command
  *				mode display
  * @recovered:			flag set to true when recovered from pp timeout
@@ -366,6 +367,7 @@ struct sde_encoder_phys {
 	bool cont_splash_enabled;
 	bool in_clone_mode;
 	int vfp_cached;
+	u32 pf_time_in_us;
 	enum frame_trigger_mode_type frame_trigger_mode;
 	bool recovered;
 	bool autorefresh_disable_trans;

+ 5 - 1
msm/sde/sde_encoder_phys_vid.c

@@ -1,6 +1,6 @@
 // SPDX-License-Identifier: GPL-2.0-only
 /*
- * Copyright (c) 2021-2022 Qualcomm Innovation Center, Inc. All rights reserved.
+ * Copyright (c) 2021-2023 Qualcomm Innovation Center, Inc. All rights reserved.
  * Copyright (c) 2015-2021, The Linux Foundation. All rights reserved.
  */
 
@@ -283,6 +283,7 @@ static void programmable_fetch_config(struct sde_encoder_phys *phys_enc,
 
 	m = phys_enc->sde_kms->catalog;
 
+	phys_enc->pf_time_in_us = 0;
 	vfp_fetch_lines = programmable_fetch_get_num_lines(vid_enc, timing);
 	if (vfp_fetch_lines) {
 		vert_total = get_vertical_total(timing);
@@ -290,6 +291,9 @@ static void programmable_fetch_config(struct sde_encoder_phys *phys_enc,
 		vfp_fetch_start_vsync_counter =
 			(vert_total - vfp_fetch_lines) * horiz_total + 1;
 
+		phys_enc->pf_time_in_us = DIV_ROUND_UP(1000000 * vfp_fetch_lines,
+				vert_total * timing->vrefresh);
+
 		/**
 		 * Check if we need to throttle the fetch to start
 		 * from second line after the active region.