Bläddra i källkod

Merge "disp: msm: sde: update avr mode config during commit prepare"

qctecmdr 5 år sedan
förälder
incheckning
ee16fbb03f

+ 23 - 10
msm/dsi/dsi_display.c

@@ -7019,21 +7019,11 @@ int dsi_display_pre_kickoff(struct drm_connector *connector,
 {
 	int rc = 0;
 	int i;
-	bool enable;
 
 	/* check and setup MISR */
 	if (display->misr_enable)
 		_dsi_display_setup_misr(display);
 
-	if (params->qsync_update) {
-		enable = (params->qsync_mode > 0) ? true : false;
-		rc = dsi_display_qsync(display, enable);
-		if (rc)
-			DSI_ERR("%s failed to send qsync commands\n",
-				__func__);
-		SDE_EVT32(params->qsync_mode, rc);
-	}
-
 	rc = dsi_display_set_roi(display, params->rois);
 
 	/* dynamic DSI clock setting */
@@ -7114,6 +7104,29 @@ error_out:
 	return rc;
 }
 
+int dsi_display_pre_commit(void *display,
+		struct msm_display_conn_params *params)
+{
+	bool enable = false;
+	int rc = 0;
+
+	if (!display || !params) {
+		pr_err("Invalid params\n");
+		return -EINVAL;
+	}
+
+	if (params->qsync_update) {
+		enable = (params->qsync_mode > 0) ? true : false;
+		rc = dsi_display_qsync(display, enable);
+		if (rc)
+			pr_err("%s failed to send qsync commands\n",
+				__func__);
+		SDE_EVT32(params->qsync_mode, rc);
+	}
+
+	return rc;
+}
+
 int dsi_display_enable(struct dsi_display *display)
 {
 	int rc = 0;

+ 10 - 0
msm/dsi/dsi_display.h

@@ -679,6 +679,16 @@ int dsi_display_set_power(struct drm_connector *connector,
 int dsi_display_pre_kickoff(struct drm_connector *connector,
 		struct dsi_display *display,
 		struct msm_display_kickoff_params *params);
+
+/*
+ * dsi_display_pre_commit - program pre commit features
+ * @display: Pointer to private display structure
+ * @params: Parameters for pre commit time programming
+ * Returns: Zero on success
+ */
+int dsi_display_pre_commit(void *display,
+		struct msm_display_conn_params *params);
+
 /**
  * dsi_display_get_dst_format() - get dst_format from DSI display
  * @connector:        Pointer to drm connector structure

+ 20 - 1
msm/dsi/dsi_drm.c

@@ -911,6 +911,17 @@ int dsi_conn_pre_kickoff(struct drm_connector *connector,
 	return dsi_display_pre_kickoff(connector, display, params);
 }
 
+int dsi_conn_prepare_commit(void *display,
+		struct msm_display_conn_params *params)
+{
+	if (!display || !params) {
+		pr_err("Invalid params\n");
+		return -EINVAL;
+	}
+
+	return dsi_display_pre_commit(display, params);
+}
+
 void dsi_conn_enable_event(struct drm_connector *connector,
 		uint32_t event_idx, bool enable, void *display)
 {
@@ -925,7 +936,8 @@ void dsi_conn_enable_event(struct drm_connector *connector,
 			event_idx, &event_info, enable);
 }
 
-int dsi_conn_post_kickoff(struct drm_connector *connector)
+int dsi_conn_post_kickoff(struct drm_connector *connector,
+	struct msm_display_conn_params *params)
 {
 	struct drm_encoder *encoder;
 	struct dsi_bridge *c_bridge;
@@ -933,6 +945,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;
+	bool enable;
 
 	if (!connector || !connector->state) {
 		DSI_ERR("invalid connector or connector state\n");
@@ -978,6 +991,12 @@ int dsi_conn_post_kickoff(struct drm_connector *connector)
 	/* ensure dynamic clk switch flag is reset */
 	c_bridge->dsi_mode.dsi_mode_flags &= ~DSI_MODE_FLAG_DYN_CLK;
 
+	if (params->qsync_update) {
+		enable = (params->qsync_mode > 0) ? true : false;
+		display_for_each_ctrl(i, display)
+			dsi_ctrl_setup_avr(display->ctrl[i].ctrl, enable);
+	}
+
 	return 0;
 }
 

+ 13 - 1
msm/dsi/dsi_drm.h

@@ -120,9 +120,11 @@ int dsi_conn_pre_kickoff(struct drm_connector *connector,
 /**
  * dsi_display_post_kickoff - program post kickoff-time features
  * @connector: Pointer to drm connector structure
+ * @params: Parameters for post kickoff programming
  * Returns: Zero on success
  */
-int dsi_conn_post_kickoff(struct drm_connector *connector);
+int dsi_conn_post_kickoff(struct drm_connector *connector,
+		struct msm_display_conn_params *params);
 
 /**
  * dsi_convert_to_drm_mode - Update drm mode with dsi mode information
@@ -134,4 +136,14 @@ void dsi_convert_to_drm_mode(const struct dsi_display_mode *dsi_mode,
 
 u64 dsi_drm_find_bit_clk_rate(void *display,
 			      const struct drm_display_mode *drm_mode);
+
+/**
+ * dsi_conn_prepare_commit - program pre commit time features
+ * @display: Pointer to private display structure
+ * @params: Parameters for pre commit programming
+ * Returns: Zero on success
+ */
+int dsi_conn_prepare_commit(void *display,
+		struct msm_display_conn_params *params);
+
 #endif /* _DSI_DRM_H_ */

+ 8 - 7
msm/dsi/dsi_panel.c

@@ -3257,13 +3257,14 @@ struct dsi_panel *dsi_panel_get(struct device *parent,
 	if (rc)
 		DSI_ERR("failed to parse dfps configuration, rc=%d\n", rc);
 
-	if (!(panel->dfps_caps.dfps_support)) {
-		/* qsync and dfps are mutually exclusive features */
-		rc = dsi_panel_parse_qsync_caps(panel, of_node);
-		if (rc)
-			DSI_DEBUG("failed to parse qsync features, rc=%d\n",
-					rc);
-	}
+	rc = dsi_panel_parse_qsync_caps(panel, of_node);
+	if (rc)
+		DSI_DEBUG("failed to parse qsync features, rc=%d\n", rc);
+
+	/* allow qsync support only if DFPS is with VFP approach */
+	if ((panel->dfps_caps.dfps_support) &&
+	    !(panel->dfps_caps.type == DSI_DFPS_IMMEDIATE_VFP))
+		panel->qsync_min_fps = 0;
 
 	rc = dsi_panel_parse_dyn_clk_caps(panel);
 	if (rc)

+ 8 - 2
msm/msm_drv.h

@@ -553,12 +553,18 @@ struct msm_roi_list {
 /**
  * struct - msm_display_kickoff_params - info for display features at kickoff
  * @rois: Regions of interest structure for mapping CRTC to Connector output
- * @qsync_mode: Qsync mode, where 0: disabled 1: continuous mode
- * @qsync_update: Qsync settings were changed/updated
  */
 struct msm_display_kickoff_params {
 	struct msm_roi_list *rois;
 	struct drm_msm_ext_hdr_metadata *hdr_meta;
+};
+
+/**
+ * struct - msm_display_conn_params - info of dpu display features
+ * @qsync_mode: Qsync mode, where 0: disabled 1: continuous mode 2: oneshot
+ * @qsync_update: Qsync settings were changed/updated
+ */
+struct msm_display_conn_params {
 	uint32_t qsync_mode;
 	bool qsync_update;
 };

+ 100 - 15
msm/sde/sde_connector.c

@@ -58,6 +58,7 @@ static const struct drm_prop_enum_list e_power_mode[] = {
 static const struct drm_prop_enum_list e_qsync_mode[] = {
 	{SDE_RM_QSYNC_DISABLED,	"none"},
 	{SDE_RM_QSYNC_CONTINUOUS_MODE,	"continuous"},
+	{SDE_RM_QSYNC_ONE_SHOT_MODE,	"one_shot"},
 };
 static const struct drm_prop_enum_list e_frame_trigger_mode[] = {
 	{FRAME_DONE_WAIT_DEFAULT, "default"},
@@ -621,21 +622,51 @@ void sde_connector_set_colorspace(struct sde_connector *c_conn)
 
 void sde_connector_set_qsync_params(struct drm_connector *connector)
 {
-	struct sde_connector *c_conn = to_sde_connector(connector);
-	u32 qsync_propval;
+	struct sde_connector *c_conn;
+	struct sde_connector_state *c_state;
+	u32 qsync_propval = 0;
+	bool prop_dirty;
 
 	if (!connector)
 		return;
 
+	c_conn = to_sde_connector(connector);
+	c_state = to_sde_connector_state(connector->state);
 	c_conn->qsync_updated = false;
-	qsync_propval = sde_connector_get_property(c_conn->base.state,
-			CONNECTOR_PROP_QSYNC_MODE);
 
-	if (qsync_propval != c_conn->qsync_mode) {
-		SDE_DEBUG("updated qsync mode %d -> %d\n", c_conn->qsync_mode,
-				qsync_propval);
-		c_conn->qsync_updated = true;
-		c_conn->qsync_mode = qsync_propval;
+	prop_dirty = msm_property_is_dirty(&c_conn->property_info,
+					&c_state->property_state,
+					CONNECTOR_PROP_QSYNC_MODE);
+	if (prop_dirty) {
+		qsync_propval = sde_connector_get_property(c_conn->base.state,
+						CONNECTOR_PROP_QSYNC_MODE);
+		if (qsync_propval != c_conn->qsync_mode) {
+			SDE_DEBUG("updated qsync mode %d -> %d\n",
+					c_conn->qsync_mode, qsync_propval);
+			c_conn->qsync_updated = true;
+			c_conn->qsync_mode = qsync_propval;
+		}
+	}
+}
+
+void sde_connector_complete_qsync_commit(struct drm_connector *conn,
+				struct msm_display_conn_params *params)
+{
+	struct sde_connector *c_conn;
+
+	if (!conn || !params) {
+		SDE_ERROR("invalid params\n");
+		return;
+	}
+
+	c_conn = to_sde_connector(conn);
+
+	if (c_conn && c_conn->qsync_updated &&
+		(c_conn->qsync_mode == SDE_RM_QSYNC_ONE_SHOT_MODE)) {
+		/* Reset qsync states if mode is one shot */
+		params->qsync_mode = c_conn->qsync_mode = 0;
+		params->qsync_update = true;
+		SDE_EVT32(conn->base.id, c_conn->qsync_mode);
 	}
 }
 
@@ -753,19 +784,49 @@ int sde_connector_pre_kickoff(struct drm_connector *connector)
 
 	params.rois = &c_state->rois;
 	params.hdr_meta = &c_state->hdr_meta;
-	params.qsync_update = false;
+
+	SDE_EVT32_VERBOSE(connector->base.id);
+
+	rc = c_conn->ops.pre_kickoff(connector, c_conn->display, &params);
+
+end:
+	return rc;
+}
+
+int sde_connector_prepare_commit(struct drm_connector *connector)
+{
+	struct sde_connector *c_conn;
+	struct sde_connector_state *c_state;
+	struct msm_display_conn_params params;
+	int rc;
+
+	if (!connector) {
+		SDE_ERROR("invalid argument\n");
+		return -EINVAL;
+	}
+
+	c_conn = to_sde_connector(connector);
+	c_state = to_sde_connector_state(connector->state);
+	if (!c_conn->display) {
+		SDE_ERROR("invalid connector display\n");
+		return -EINVAL;
+	}
+
+	if (!c_conn->ops.prepare_commit)
+		return 0;
+
+	memset(&params, 0, sizeof(params));
 
 	if (c_conn->qsync_updated) {
 		params.qsync_mode = c_conn->qsync_mode;
 		params.qsync_update = true;
-		SDE_EVT32(connector->base.id, params.qsync_mode);
 	}
 
-	SDE_EVT32_VERBOSE(connector->base.id);
+	rc = c_conn->ops.prepare_commit(c_conn->display, &params);
 
-	rc = c_conn->ops.pre_kickoff(connector, c_conn->display, &params);
+	SDE_EVT32(connector->base.id, params.qsync_mode,
+		  params.qsync_update, rc);
 
-end:
 	return rc;
 }
 
@@ -1376,6 +1437,10 @@ static int sde_connector_atomic_set_property(struct drm_connector *connector,
 		if (rc)
 			SDE_ERROR_CONN(c_conn, "cannot set hdr info %d\n", rc);
 		break;
+	case CONNECTOR_PROP_QSYNC_MODE:
+		msm_property_set_dirty(&c_conn->property_info,
+				&c_state->property_state, idx);
+		break;
 	default:
 		break;
 	}
@@ -2027,13 +2092,33 @@ static int sde_connector_atomic_check(struct drm_connector *connector,
 		struct drm_connector_state *new_conn_state)
 {
 	struct sde_connector *c_conn;
+	struct sde_connector_state *c_state;
+	bool qsync_dirty = false, has_modeset = false;
 
 	if (!connector) {
 		SDE_ERROR("invalid connector\n");
-		return 0;
+		return -EINVAL;
+	}
+
+	if (!new_conn_state) {
+		SDE_ERROR("invalid connector state\n");
+		return -EINVAL;
 	}
 
 	c_conn = to_sde_connector(connector);
+	c_state = to_sde_connector_state(new_conn_state);
+
+	has_modeset = sde_crtc_atomic_check_has_modeset(new_conn_state->state,
+						new_conn_state->crtc);
+	qsync_dirty = msm_property_is_dirty(&c_conn->property_info,
+					&c_state->property_state,
+					CONNECTOR_PROP_QSYNC_MODE);
+
+	SDE_DEBUG("has_modeset %d qsync_dirty %d\n", has_modeset, qsync_dirty);
+	if (has_modeset && qsync_dirty) {
+		SDE_ERROR("invalid qsync update during modeset\n");
+		return -EINVAL;
+	}
 
 	if (c_conn->ops.atomic_check)
 		return c_conn->ops.atomic_check(connector,

+ 31 - 1
msm/sde/sde_connector.h

@@ -229,9 +229,12 @@ struct sde_connector_ops {
 	/**
 	 * post_kickoff - display to program post kickoff-time features
 	 * @connector: Pointer to drm connector structure
+	 * @params: Parameter bundle of connector-stored information for
+	 *	post kickoff programming into the display
 	 * Returns: Zero on success
 	 */
-	int (*post_kickoff)(struct drm_connector *connector);
+	int (*post_kickoff)(struct drm_connector *connector,
+		struct msm_display_conn_params *params);
 
 	/**
 	 * post_open - calls connector to process post open functionalities
@@ -325,6 +328,16 @@ struct sde_connector_ops {
 	 * Returns: zero for success, negetive for failure
 	 */
 	int (*get_default_lms)(void *display, u32 *num_lm);
+
+	/**
+	 * prepare_commit - trigger display to program pre-commit time features
+	 * @display: Pointer to private display structure
+	 * @params: Parameter bundle of connector-stored information for
+	 *	pre commit time programming into the display
+	 * Returns: Zero on success
+	 */
+	int (*prepare_commit)(void *display,
+		struct msm_display_conn_params *params);
 };
 
 /**
@@ -732,6 +745,16 @@ int sde_connector_get_dpms(struct drm_connector *connector);
  */
 void sde_connector_set_qsync_params(struct drm_connector *connector);
 
+/**
+ * sde_connector_complete_qsync_commit - callback signalling completion
+ *			of qsync, if modified for the current commit
+ * @conn   - Pointer to drm connector object
+ * @params - Parameter bundle of connector-stored information for
+ *	post kickoff programming into the display
+ */
+void sde_connector_complete_qsync_commit(struct drm_connector *conn,
+			struct msm_display_conn_params *params);
+
 /**
 * sde_connector_get_dyn_hdr_meta - returns pointer to connector state's dynamic
 *				   HDR metadata info
@@ -801,6 +824,13 @@ int sde_connector_register_custom_event(struct sde_kms *kms,
  */
 int sde_connector_pre_kickoff(struct drm_connector *connector);
 
+/**
+ * sde_connector_prepare_commit - trigger commit time feature programming
+ * @connector: Pointer to drm connector object
+ * Returns: Zero on success
+ */
+int sde_connector_prepare_commit(struct drm_connector *connector);
+
 /**
  * sde_connector_needs_offset - adjust the output fence offset based on
  *                              display type

+ 19 - 0
msm/sde/sde_crtc.h

@@ -714,6 +714,25 @@ static inline int sde_crtc_get_secure_level(struct drm_crtc *crtc,
 			CRTC_PROP_SECURITY_LEVEL);
 }
 
+/** sde_crtc_atomic_check_has_modeset - checks if the new_crtc_state in the
+ *	drm_atomic_state has a modeset
+ * @state : pointer to drm_atomic_state
+ * @crtc : Pointer to drm crtc structure
+ * Returns true if crtc has modeset
+ */
+static inline bool sde_crtc_atomic_check_has_modeset(
+	struct drm_atomic_state *state, struct drm_crtc *crtc)
+{
+	struct drm_crtc_state *crtc_state;
+
+	if (!state || !crtc)
+		return false;
+
+	crtc_state = drm_atomic_get_new_crtc_state(state,
+					crtc);
+	return (crtc_state && drm_atomic_crtc_needs_modeset(crtc_state));
+}
+
 /**
  * sde_crtc_get_secure_transition - determines the operations to be
  * performed before transitioning to secure state

+ 16 - 6
msm/sde/sde_encoder.c

@@ -4703,11 +4703,6 @@ int sde_encoder_prepare_for_kickoff(struct drm_encoder *drm_enc,
 	SDE_DEBUG_ENC(sde_enc, "\n");
 	SDE_EVT32(DRMID(drm_enc));
 
-	/* update the qsync parameters for the current frame */
-	if (sde_enc->cur_master)
-		sde_connector_set_qsync_params(
-				sde_enc->cur_master->connector);
-
 	is_cmd_mode = sde_encoder_check_curr_mode(drm_enc,
 				MSM_DISPLAY_CMD_MODE);
 	if (sde_enc->cur_master && sde_enc->cur_master->connector
@@ -4960,7 +4955,7 @@ void sde_encoder_prepare_commit(struct drm_encoder *drm_enc)
 {
 	struct sde_encoder_virt *sde_enc;
 	struct sde_encoder_phys *phys;
-	int i;
+	int i, rc = 0;
 	struct sde_hw_ctl *ctl;
 
 	if (!drm_enc) {
@@ -4969,6 +4964,11 @@ void sde_encoder_prepare_commit(struct drm_encoder *drm_enc)
 	}
 	sde_enc = to_sde_encoder_virt(drm_enc);
 
+	/* update the qsync parameters for the current frame */
+	if (sde_enc->cur_master)
+		sde_connector_set_qsync_params(
+				sde_enc->cur_master->connector);
+
 	for (i = 0; i < sde_enc->num_phys_encs; i++) {
 		phys = sde_enc->phys_encs[i];
 		if (phys && phys->ops.prepare_commit)
@@ -4986,6 +4986,16 @@ void sde_encoder_prepare_commit(struct drm_encoder *drm_enc)
 				ctl->ops.clear_pending_flush(ctl);
 		}
 	}
+
+	if (sde_enc->cur_master && sde_enc->cur_master->connector) {
+		rc = sde_connector_prepare_commit(
+				  sde_enc->cur_master->connector);
+		if (rc)
+			SDE_ERROR_ENC(sde_enc,
+				      "prepare commit failed conn %d rc %d\n",
+				      sde_enc->cur_master->connector->base.id,
+				      rc);
+	}
 }
 
 void sde_encoder_helper_setup_misr(struct sde_encoder_phys *phys_enc,

+ 16 - 4
msm/sde/sde_encoder_phys_vid.c

@@ -332,7 +332,7 @@ static void _sde_encoder_phys_vid_setup_avr(
 			return;
 		}
 
-		if (qsync_min_fps >= default_fps) {
+		if (qsync_min_fps > default_fps) {
 			SDE_ERROR_VIDENC(vid_enc,
 				"qsync fps %d must be less than default %d\n",
 				qsync_min_fps, default_fps);
@@ -977,9 +977,6 @@ static int sde_encoder_phys_vid_prepare_for_kickoff(
 		vid_enc->error_count = 0;
 	}
 
-	if (sde_connector_is_qsync_updated(phys_enc->connector))
-		_sde_encoder_phys_vid_avr_ctrl(phys_enc);
-
 	return rc;
 }
 
@@ -1124,6 +1121,20 @@ static void sde_encoder_phys_vid_handle_post_kickoff(
 	}
 }
 
+static void sde_encoder_phys_vid_prepare_for_commit(
+		struct sde_encoder_phys *phys_enc)
+{
+
+	if (!phys_enc) {
+		SDE_ERROR("invalid encoder parameters\n");
+		return;
+	}
+
+	if (sde_connector_is_qsync_updated(phys_enc->connector))
+		_sde_encoder_phys_vid_avr_ctrl(phys_enc);
+
+}
+
 static void sde_encoder_phys_vid_irq_control(struct sde_encoder_phys *phys_enc,
 		bool enable)
 {
@@ -1258,6 +1269,7 @@ static void sde_encoder_phys_vid_init_ops(struct sde_encoder_phys_ops *ops)
 	ops->get_wr_line_count = sde_encoder_phys_vid_get_line_count;
 	ops->wait_dma_trigger = sde_encoder_phys_vid_wait_dma_trigger;
 	ops->wait_for_active = sde_encoder_phys_vid_wait_for_active;
+	ops->prepare_commit = sde_encoder_phys_vid_prepare_for_commit;
 }
 
 struct sde_encoder_phys *sde_encoder_phys_vid_init(

+ 7 - 6
msm/sde/sde_hw_intf.c

@@ -83,9 +83,6 @@
 #define INTF_TEAR_AUTOREFRESH_CONFIG    0x2B4
 #define INTF_TEAR_TEAR_DETECT_CTRL      0x2B8
 
-#define AVR_CONTINUOUS_MODE   1
-#define AVR_ONE_SHOT_MODE     2
-
 static struct sde_intf_cfg *_intf_offset(enum sde_intf intf,
 		struct sde_mdss_cfg *m,
 		void __iomem *addr,
@@ -129,7 +126,7 @@ static int sde_hw_intf_avr_setup(struct sde_hw_intf *ctx,
 	u32 min_fps, default_fps, diff_fps;
 	u32 vsync_period_slow;
 	u32 avr_vtotal;
-	u32 add_porches;
+	u32 add_porches = 0;
 
 	if (!ctx || !params || !avr_params) {
 		SDE_ERROR("invalid input parameter(s)\n");
@@ -146,7 +143,10 @@ static int sde_hw_intf_avr_setup(struct sde_hw_intf *ctx,
 	vsync_period = params->vsync_pulse_width +
 			params->v_back_porch + params->height +
 			params->v_front_porch;
-	add_porches = mult_frac(vsync_period, diff_fps, min_fps);
+
+	if (diff_fps)
+		add_porches = mult_frac(vsync_period, diff_fps, min_fps);
+
 	vsync_period_slow = vsync_period + add_porches;
 	avr_vtotal = vsync_period_slow * hsync_period;
 
@@ -168,7 +168,8 @@ static void sde_hw_intf_avr_ctrl(struct sde_hw_intf *ctx,
 	c = &ctx->hw;
 	if (avr_params->avr_mode) {
 		avr_ctrl = BIT(0);
-		avr_mode = (avr_params->avr_mode == AVR_ONE_SHOT_MODE) ?
+		avr_mode =
+		(avr_params->avr_mode == SDE_RM_QSYNC_ONE_SHOT_MODE) ?
 			(BIT(0) | BIT(8)) : 0x0;
 	}
 

+ 8 - 1
msm/sde/sde_kms.c

@@ -46,6 +46,7 @@
 #include "sde_plane.h"
 #include "sde_crtc.h"
 #include "sde_reg_dma.h"
+#include "sde_connector.h"
 
 #include <soc/qcom/scm.h>
 #include "soc/qcom/secure_buffer.h"
@@ -992,6 +993,7 @@ static void sde_kms_complete_commit(struct msm_kms *kms,
 	struct drm_crtc_state *old_crtc_state;
 	struct drm_connector *connector;
 	struct drm_connector_state *old_conn_state;
+	struct msm_display_conn_params params;
 	int i, rc = 0;
 
 	if (!kms || !old_state)
@@ -1024,7 +1026,12 @@ static void sde_kms_complete_commit(struct msm_kms *kms,
 		c_conn = to_sde_connector(connector);
 		if (!c_conn->ops.post_kickoff)
 			continue;
-		rc = c_conn->ops.post_kickoff(connector);
+
+		memset(&params, 0, sizeof(params));
+
+		sde_connector_complete_qsync_commit(connector, &params);
+
+		rc = c_conn->ops.post_kickoff(connector, &params);
 		if (rc) {
 			pr_err("Connector Post kickoff failed rc=%d\n",
 					 rc);

+ 3 - 0
msm/sde/sde_rm.h

@@ -67,10 +67,13 @@ enum sde_rm_topology_control {
  *                              disable state.
  * @SDE_RM_QSYNC_CONTINUOUS_MODE: If set, Qsync is enabled in continuous
  *                              mode.
+ * @SDE_RM_QSYNC_ONE_SHOT_MODE: If set, Qsync is enabled in one shot mode.
+ *
  */
 enum sde_rm_qsync_modes {
 	SDE_RM_QSYNC_DISABLED,
 	SDE_RM_QSYNC_CONTINUOUS_MODE,
+	SDE_RM_QSYNC_ONE_SHOT_MODE
 };
 
 /**