ソースを参照

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

Add changes to support avr mode config update during
prepare commit which happens before gpu fence wait
for the input buffers.

Change-Id: Ib2cb5b7e1f10501914c003f6cf066b85048f79d4
Signed-off-by: Kalyan Thota <[email protected]>
Signed-off-by: Jayaprakash <[email protected]>
Jayaprakash 5 年 前
コミット
aad3dd4525

+ 23 - 10
msm/dsi/dsi_display.c

@@ -7011,21 +7011,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 */
@@ -7106,6 +7096,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

+ 12 - 1
msm/dsi/dsi_drm.c

@@ -901,6 +901,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)
 {
@@ -916,7 +927,7 @@ void dsi_conn_enable_event(struct drm_connector *connector,
 }
 
 int dsi_conn_post_kickoff(struct drm_connector *connector,
-	struct msm_display_kickoff_params *params)
+	struct msm_display_conn_params *params)
 {
 	struct drm_encoder *encoder;
 	struct dsi_bridge *c_bridge;

+ 11 - 1
msm/dsi/dsi_drm.h

@@ -124,7 +124,7 @@ int dsi_conn_pre_kickoff(struct drm_connector *connector,
  * Returns: Zero on success
  */
 int dsi_conn_post_kickoff(struct drm_connector *connector,
-		struct msm_display_kickoff_params *params);
+		struct msm_display_conn_params *params);
 
 /**
  * dsi_convert_to_drm_mode - Update drm mode with dsi mode information
@@ -136,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 - 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;
 };

+ 42 - 10
msm/sde/sde_connector.c

@@ -640,15 +640,17 @@ void sde_connector_set_qsync_params(struct drm_connector *connector)
 	if (prop_dirty) {
 		qsync_propval = sde_connector_get_property(c_conn->base.state,
 						CONNECTOR_PROP_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;
+		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_kickoff_params *params)
+				struct msm_display_conn_params *params)
 {
 	struct sde_connector *c_conn;
 
@@ -782,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;
 }
 

+ 19 - 2
msm/sde/sde_connector.h

@@ -234,7 +234,7 @@ struct sde_connector_ops {
 	 * Returns: Zero on success
 	 */
 	int (*post_kickoff)(struct drm_connector *connector,
-		struct msm_display_kickoff_params *params);
+		struct msm_display_conn_params *params);
 
 	/**
 	 * post_open - calls connector to process post open functionalities
@@ -328,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);
 };
 
 /**
@@ -743,7 +753,7 @@ void sde_connector_set_qsync_params(struct drm_connector *connector);
  *	post kickoff programming into the display
  */
 void sde_connector_complete_qsync_commit(struct drm_connector *conn,
-			struct msm_display_kickoff_params *params);
+			struct msm_display_conn_params *params);
 
 /**
 * sde_connector_get_dyn_hdr_meta - returns pointer to connector state's dynamic
@@ -814,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

+ 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,

+ 15 - 3
msm/sde/sde_encoder_phys_vid.c

@@ -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(

+ 2 - 4
msm/sde/sde_kms.c

@@ -949,7 +949,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_kickoff_params params;
+	struct msm_display_conn_params params;
 	int i, rc = 0;
 
 	if (!kms || !old_state)
@@ -983,9 +983,7 @@ static void sde_kms_complete_commit(struct msm_kms *kms,
 		if (!c_conn->ops.post_kickoff)
 			continue;
 
-		params.rois = NULL;
-		params.hdr_meta = NULL;
-		params.qsync_update = false;
+		memset(&params, 0, sizeof(params));
 
 		sde_connector_complete_qsync_commit(connector, &params);