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 <sudarame@codeaurora.org>
This commit is contained in:
Sudarsan Ramesh
2021-04-14 14:06:49 -04:00
parent 28e834679a
commit 45877a3be6
3 changed files with 47 additions and 19 deletions

View File

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

View File

@@ -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);

View File

@@ -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_ */