Browse Source

disp: msm: populate submode blob information

Mode information apart from the fields in
drm_mode_modeinfo that can trigger a modeset like
dsc-nondsc, video-cmd are defined in sub mode.
For each mode in connector->modes there can be
multiple submodes.

Change-Id: Ib8697d3fa4ea5261d9ac4943b1a4149e22c4da2f
Signed-off-by: Raviteja Tamatam <[email protected]>
Raviteja Tamatam 4 năm trước cách đây
mục cha
commit
b89a3f739a

+ 1 - 1
msm/dsi/dsi_display.c

@@ -7150,7 +7150,7 @@ end:
 	return is_matching;
 }
 
-static bool dsi_display_mode_match(const struct dsi_display_mode *mode1,
+bool dsi_display_mode_match(const struct dsi_display_mode *mode1,
 		struct dsi_display_mode *mode2, unsigned int match_flags)
 {
 	if (!mode1 && !mode2)

+ 9 - 0
msm/dsi/dsi_display.h

@@ -814,5 +814,14 @@ int dsi_display_update_dyn_bit_clk(struct dsi_display *display, struct dsi_displ
  */
 int dsi_display_restore_bit_clk(struct dsi_display *display, struct dsi_display_mode *mode);
 
+/**
+ * dsi_display_mode_match() - compares two dsi mode structures
+ * @mode1:       dsi_display_mode to be compared
+ * @mode2:       dsi_display_mode to be compared
+ * @match_flags: Values to compare
+ * Return: True if mode matches
+ */
+bool dsi_display_mode_match(const struct dsi_display_mode *mode1,
+		struct dsi_display_mode *mode2, unsigned int match_flags);
 
 #endif /* _DSI_DISPLAY_H_ */

+ 61 - 0
msm/dsi/dsi_drm.c

@@ -803,6 +803,67 @@ end:
 	return 0;
 }
 
+void dsi_conn_set_submode_blob_info(struct drm_connector *conn,
+		void *info, void *display, struct drm_display_mode *drm_mode)
+{
+	struct dsi_display *dsi_display = display;
+	struct dsi_display_mode partial_dsi_mode;
+	int count, i;
+	int preferred_submode_idx = -EINVAL;
+
+	if (!conn || !display || !drm_mode) {
+		DSI_ERR("Invalid params\n");
+		return;
+	}
+
+	convert_to_dsi_mode(drm_mode, &partial_dsi_mode);
+
+	mutex_lock(&dsi_display->display_lock);
+	count = dsi_display->panel->num_display_modes;
+	for (i = 0; i < count; i++) {
+		struct dsi_display_mode *dsi_mode = &dsi_display->modes[i];
+
+		u32 panel_mode_caps = 0;
+		const char *topo_name = NULL;
+
+		if (dsi_display_mode_match(&partial_dsi_mode, dsi_mode,
+				DSI_MODE_MATCH_FULL_TIMINGS)) {
+
+			sde_kms_info_add_keyint(info, "submode_idx", i);
+
+			if (dsi_mode->is_preferred)
+				preferred_submode_idx = i;
+
+			if (dsi_mode->panel_mode_caps & DSI_OP_CMD_MODE)
+				panel_mode_caps |= DRM_MODE_FLAG_CMD_MODE_PANEL;
+			if (dsi_mode->panel_mode_caps & DSI_OP_VIDEO_MODE)
+				panel_mode_caps |= DRM_MODE_FLAG_VID_MODE_PANEL;
+
+			sde_kms_info_add_keyint(info, "panel_mode_capabilities",
+				panel_mode_caps);
+
+			sde_kms_info_add_keyint(info, "dsc_mode",
+				dsi_mode->priv_info->dsc_enabled ? MSM_DISPLAY_DSC_MODE_ENABLED :
+					MSM_DISPLAY_DSC_MODE_DISABLED);
+			topo_name = sde_conn_get_topology_name(conn,
+				dsi_mode->priv_info->topology);
+			if (topo_name)
+				sde_kms_info_add_keystr(info, "topology", topo_name);
+
+			if (dsi_mode->priv_info->bit_clk_list.count > 0)
+				sde_kms_info_add_list(info, "dyn_bitclk_list",
+						dsi_mode->priv_info->bit_clk_list.rates,
+						dsi_mode->priv_info->bit_clk_list.count);
+		}
+	}
+
+	if (preferred_submode_idx >= 0)
+		sde_kms_info_add_keyint(info, "preferred_submode_idx",
+			preferred_submode_idx);
+
+	mutex_unlock(&dsi_display->display_lock);
+}
+
 enum drm_connector_status dsi_conn_detect(struct drm_connector *conn,
 		bool force,
 		void *display)

+ 10 - 0
msm/dsi/dsi_drm.h

@@ -162,4 +162,14 @@ void dsi_conn_set_allowed_mode_switch(struct drm_connector *connector,
 int dsi_conn_set_dyn_bit_clk(struct drm_connector *connector,
 		uint64_t value);
 
+/**
+ * dsi_conn_set_submode_blob_info - populate given sub mode blob
+ * @connector: Pointer to drm connector structure
+ * @info: Pointer to sde connector info structure
+ * @display: Pointer to private display handle
+ * @drm_mode: Pointer to drm_display_mode structure
+ */
+void dsi_conn_set_submode_blob_info(struct drm_connector *conn,
+		void *info, void *display, struct drm_display_mode *drm_mode);
+
 #endif /* _DSI_DRM_H_ */

+ 5 - 0
msm/dsi/dsi_panel.c

@@ -3025,6 +3025,11 @@ static int dsi_panel_parse_topology(
 		goto parse_fail;
 	}
 
+	if (priv_info->dsc_enabled)
+		topology[top_sel].comp_type = MSM_DISPLAY_COMPRESSION_DSC;
+	else if (priv_info->vdc_enabled)
+		topology[top_sel].comp_type = MSM_DISPLAY_COMPRESSION_VDC;
+
 	DSI_INFO("default topology: lm: %d comp_enc:%d intf: %d\n",
 		topology[top_sel].num_lm,
 		topology[top_sel].num_enc,

+ 29 - 23
msm/sde/sde_connector.c

@@ -2512,6 +2512,29 @@ static void _sde_connector_report_panel_dead(struct sde_connector *conn,
 			conn->base.base.id, conn->encoder->base.id);
 }
 
+const char *sde_conn_get_topology_name(struct drm_connector *conn,
+		struct msm_display_topology topology)
+{
+	struct sde_kms *sde_kms;
+	int topology_idx = 0;
+
+	sde_kms = _sde_connector_get_kms(conn);
+	if (!sde_kms) {
+		SDE_ERROR("invalid kms\n");
+		return NULL;
+	}
+
+	topology_idx = (int)sde_rm_get_topology_name(&sde_kms->rm,
+				topology);
+
+	if (topology_idx >= SDE_RM_TOPOLOGY_MAX) {
+		SDE_ERROR("invalid topology\n");
+		return NULL;
+	}
+
+	return e_topology_name[topology_idx].name;
+}
+
 int sde_connector_esd_status(struct drm_connector *conn)
 {
 	struct sde_connector *sde_conn = NULL;
@@ -2617,6 +2640,7 @@ static int sde_connector_populate_mode_info(struct drm_connector *conn,
 	struct sde_connector *c_conn = NULL;
 	struct drm_display_mode *mode;
 	struct msm_mode_info mode_info;
+	const char *topo_name = NULL;
 	int rc = 0;
 
 	sde_kms = _sde_connector_get_kms(conn);
@@ -2632,8 +2656,6 @@ static int sde_connector_populate_mode_info(struct drm_connector *conn,
 	}
 
 	list_for_each_entry(mode, &conn->modes, head) {
-		int topology_idx = 0;
-		u32 panel_mode_caps = 0;
 
 		memset(&mode_info, 0, sizeof(mode_info));
 
@@ -2651,20 +2673,12 @@ static int sde_connector_populate_mode_info(struct drm_connector *conn,
 		sde_kms_info_add_keyint(info, "bit_clk_rate",
 					mode_info.clk_rate);
 
-		if (mode_info.bit_clk_count > 0)
-			sde_kms_info_add_list(info, "dyn_bitclk_list",
-					mode_info.bit_clk_rates,
-					mode_info.bit_clk_count);
-
-
-		topology_idx = (int)sde_rm_get_topology_name(&sde_kms->rm,
-					mode_info.topology);
-		if (topology_idx < SDE_RM_TOPOLOGY_MAX) {
-			sde_kms_info_add_keystr(info, "topology",
-					e_topology_name[topology_idx].name);
+		if (c_conn->ops.set_submode_info) {
+			c_conn->ops.set_submode_info(conn, info, c_conn->display, mode);
 		} else {
-			SDE_ERROR_CONN(c_conn, "invalid topology\n");
-			continue;
+			topo_name = sde_conn_get_topology_name(conn, mode_info.topology);
+			if (topo_name)
+				sde_kms_info_add_keystr(info, "topology", topo_name);
 		}
 
 		sde_kms_info_add_keyint(info, "has_cwb_crop", sde_kms->catalog->has_cwb_crop);
@@ -2677,14 +2691,6 @@ static int sde_connector_populate_mode_info(struct drm_connector *conn,
 		sde_kms_info_add_keyint(info, "allowed_mode_switch",
 			mode_info.allowed_mode_switches);
 
-		if (mode_info.panel_mode_caps & DSI_OP_CMD_MODE)
-			panel_mode_caps |= DRM_MODE_FLAG_CMD_MODE_PANEL;
-		if (mode_info.panel_mode_caps & DSI_OP_VIDEO_MODE)
-			panel_mode_caps |= DRM_MODE_FLAG_VID_MODE_PANEL;
-
-		sde_kms_info_add_keyint(info, "panel_mode_capabilities",
-			panel_mode_caps);
-
 		if (!mode_info.roi_caps.num_roi)
 			continue;
 

+ 13 - 0
msm/sde/sde_connector.h

@@ -399,6 +399,16 @@ struct sde_connector_ops {
 	 * Returns: AVR step fps value on success
 	 */
 	int (*get_avr_step_req)(void *display, u32 mode_fps);
+
+	/**
+	 * set_submode_info - populate given sub mode blob
+	 * @connector: Pointer to drm connector structure
+	 * @info: Pointer to sde connector info structure
+	 * @display: Pointer to private display handle
+	 * @drm_mode: Pointer to drm_display_mode structure
+	 */
+	void (*set_submode_info)(struct drm_connector *conn,
+		void *info, void *display, struct drm_display_mode *drm_mode);
 };
 
 /**
@@ -1139,4 +1149,7 @@ int sde_connector_get_panel_vfp(struct drm_connector *connector,
  */
 int sde_connector_esd_status(struct drm_connector *connector);
 
+const char *sde_conn_get_topology_name(struct drm_connector *conn,
+		struct msm_display_topology topology);
+
 #endif /* _SDE_CONNECTOR_H_ */

+ 1 - 0
msm/sde/sde_kms.c

@@ -1770,6 +1770,7 @@ static int _sde_kms_setup_displays(struct drm_device *dev,
 		.get_qsync_min_fps = dsi_display_get_qsync_min_fps,
 		.get_avr_step_req = dsi_display_get_avr_step_req_fps,
 		.prepare_commit = dsi_conn_prepare_commit,
+		.set_submode_info = dsi_conn_set_submode_blob_info,
 	};
 	static const struct sde_connector_ops wb_ops = {
 		.post_init =    sde_wb_connector_post_init,