浏览代码

disp: msm: dp: clear cache upon writing to edid debugfs node

Currently, any edids read by the driver are cached in the
sde_connector object. In the event that subsequent edids are written,
the cached edid is used instead of the newly written edid.

In the event a new edid is written to the edid debugfs node over
dpsim, this change clears the current cached edid before overwriting
the new one.

Change-Id: I53f870e97c3b9ac5954d193f74e4b272386f67a8
Signed-off-by: Sudarsan Ramesh <[email protected]>
Sudarsan Ramesh 4 年之前
父节点
当前提交
45877a3be6
共有 3 个文件被更改,包括 47 次插入19 次删除
  1. 2 0
      msm/dp/dp_debug.c
  2. 34 18
      msm/dp/dp_mst_drm.c
  3. 11 1
      msm/dp/dp_mst_drm.h

+ 2 - 0
msm/dp/dp_debug.c

@@ -18,6 +18,7 @@
 #include "dp_pll.h"
 #include "dp_hpd.h"
 #include "dp_mst_sim.h"
+#include "dp_mst_drm.h"
 
 #define DEBUG_NAME "drm_dp"
 
@@ -178,6 +179,7 @@ static ssize_t dp_debug_write_edid(struct file *file,
 	}
 
 	dp_debug_enable_sim_mode(debug, DP_SIM_MODE_EDID);
+	dp_mst_clear_edid_cache(debug->display);
 	dp_sim_update_port_edid(debug->sim_bridge, debug->mst_edid_idx,
 			edid, edid_size);
 bail:

+ 34 - 18
msm/dp/dp_mst_drm.c

@@ -927,6 +927,38 @@ dp_mst_connector_detect(struct drm_connector *connector, bool force,
 	return status;
 }
 
+void dp_mst_clear_edid_cache(void *dp_display) {
+	struct dp_display *dp = dp_display;
+	struct drm_connector_list_iter conn_iter;
+	struct drm_connector *conn;
+	struct sde_connector *c_conn;
+
+	DP_MST_DEBUG("enter:\n");
+	SDE_EVT32_EXTERNAL(SDE_EVTLOG_FUNC_ENTRY);
+
+	if (!dp) {
+		DP_ERR("invalid input\n");
+		return;
+	}
+
+	drm_connector_list_iter_begin(dp->drm_dev, &conn_iter);
+	drm_for_each_connector_iter(conn, &conn_iter) {
+		c_conn = to_sde_connector(conn);
+		if (!c_conn->mst_port)
+			continue;
+
+		mutex_lock(&dp_mst.edid_lock);
+		kfree(c_conn->cached_edid);
+		c_conn->cached_edid = NULL;
+		mutex_unlock(&dp_mst.edid_lock);
+	}
+
+	drm_connector_list_iter_end(&conn_iter);
+
+	DP_MST_DEBUG("exit:\n");
+	SDE_EVT32_EXTERNAL(SDE_EVTLOG_FUNC_EXIT);
+}
+
 static int dp_mst_connector_get_modes(struct drm_connector *connector,
 		void *display, const struct msm_resource_caps_info *avail_res)
 {
@@ -1768,9 +1800,6 @@ static void dp_mst_display_hpd_irq(void *dp_display)
 	u8 esi[14];
 	unsigned int esi_res = DP_SINK_COUNT_ESI + 1;
 	bool handled;
-	struct drm_connector_list_iter conn_iter;
-	struct drm_connector *conn;
-	struct sde_connector *c_conn;
 
 	if (!mst->mst_session_state) {
 		DP_ERR("mst_hpd_irq received before mst session start\n");
@@ -1793,21 +1822,8 @@ static void dp_mst_display_hpd_irq(void *dp_display)
 	if (handled) {
 		rc = drm_dp_dpcd_write(mst->caps.drm_aux, esi_res, &esi[1], 3);
 
-		if (esi[1] & DP_UP_REQ_MSG_RDY) {
-			drm_connector_list_iter_begin(dp->drm_dev, &conn_iter);
-			drm_for_each_connector_iter(conn, &conn_iter) {
-
-				c_conn = to_sde_connector(conn);
-				if (!c_conn->mst_port)
-					continue;
-
-				mutex_lock(&mst->edid_lock);
-				kfree(c_conn->cached_edid);
-				c_conn->cached_edid = NULL;
-				mutex_unlock(&mst->edid_lock);
-			}
-			drm_connector_list_iter_end(&conn_iter);
-		}
+		if (esi[1] & DP_UP_REQ_MSG_RDY)
+			dp_mst_clear_edid_cache(dp);
 
 		if (rc != 3)
 			DP_ERR("dpcd esi_res failed. rlen=%d\n", rc);

+ 11 - 1
msm/dp/dp_mst_drm.h

@@ -1,6 +1,6 @@
 /* SPDX-License-Identifier: GPL-2.0-only */
 /*
- * Copyright (c) 2017-2020, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2017-2021, The Linux Foundation. All rights reserved.
  */
 
 #ifndef _DP_MST_DRM_H_
@@ -39,6 +39,12 @@ int dp_mst_init(struct dp_display *dp_display);
  * @display: Pointer to private display structure
  */
 void dp_mst_deinit(struct dp_display *dp_display);
+
+/**
+ * dp_mst_clear_edid_cache - clear mst edid cache for the given display
+ * @display: Pointer to private display structure
+ */
+void dp_mst_clear_edid_cache(void *dp_display);
 #else
 
 static inline int dp_mst_drm_bridge_init(void *display,
@@ -60,6 +66,10 @@ static inline int dp_mst_deinit(struct dp_display *dp_display)
 {
 	return 0;
 }
+
+static inline void dp_mst_clear_edid_cache(void *display)
+{
+}
 #endif /* CONFIG_DRM_MSM_DP_MST */
 
 #endif /* _DP_MST_DRM_H_ */