Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 9f38f045 authored by Ajay Singh Parmar's avatar Ajay Singh Parmar
Browse files

drm/msm/dp: fix panel de-initialization



During source initiated power down sequence which can
be triggered by system suspend or framework reboot,
do not clear the panel parameters as the DisplayPort
cable is still connected and rest of the sub-system
remains in connected mode. On resume, the system expect
the DisplayPort driver to be in same state as before
suspend. De-initializing the panel clears the internal
states which should be done only on hot plug event.

CRs-Fixed: 2327083
Change-Id: I78ca970155191e50166a81e29e94b7bbd82140d3
Signed-off-by: default avatarAjay Singh Parmar <aparmar@codeaurora.org>
parent 4bee6db9
Loading
Loading
Loading
Loading
+16 −7
Original line number Diff line number Diff line
@@ -814,7 +814,7 @@ static void dp_display_clean(struct dp_display_private *dp)

		dp_display_stream_pre_disable(dp, dp_panel);
		dp_display_stream_disable(dp, dp_panel);
		dp_panel->deinit(dp_panel);
		dp_panel->deinit(dp_panel, 0);
	}

	dp->power_on = false;
@@ -1540,11 +1540,7 @@ static int dp_display_disable(struct dp_display *dp_display, void *panel)
	}

	dp_display_stream_disable(dp, dp_panel);

	/* log this as it results from user action of cable dis-connection */
	pr_info("[OK]\n");
end:
	dp_panel->deinit(dp_panel);
	mutex_unlock(&dp->session_lock);
	return 0;
}
@@ -1597,6 +1593,8 @@ static struct dp_debug *dp_get_debug(struct dp_display *dp_display)
static int dp_display_unprepare(struct dp_display *dp_display, void *panel)
{
	struct dp_display_private *dp;
	struct dp_panel *dp_panel = panel;
	u32 flags = 0;

	if (!dp_display || !panel) {
		pr_err("invalid input\n");
@@ -1607,10 +1605,19 @@ static int dp_display_unprepare(struct dp_display *dp_display, void *panel)

	mutex_lock(&dp->session_lock);

	/*
	 * Check if the power off sequence was triggered
	 * by a source initialated action like framework
	 * reboot or suspend-resume but not from normal
	 * hot plug.
	 */
	if (dp_display_is_ready(dp))
		flags |= DP_PANEL_SRC_INITIATED_POWER_DOWN;

	if (dp->active_stream_cnt)
		goto end;

	if (dp_display_is_ready(dp)) {
	if (flags & DP_PANEL_SRC_INITIATED_POWER_DOWN) {
		dp->link->psm_config(dp->link, &dp->panel->link_info, true);
		dp->debug->psm_enabled = true;

@@ -1631,8 +1638,10 @@ static int dp_display_unprepare(struct dp_display *dp_display, void *panel)

	complete_all(&dp->notification_comp);

	pr_debug("[OK]\n");
	/* log this as it results from user action of cable dis-connection */
	pr_info("[OK]\n");
end:
	dp_panel->deinit(dp_panel, flags);
	mutex_unlock(&dp->session_lock);

	return 0;
+6 −1
Original line number Diff line number Diff line
@@ -1449,7 +1449,7 @@ static int dp_panel_init_panel_info(struct dp_panel *dp_panel)
	return rc;
}

static int dp_panel_deinit_panel_info(struct dp_panel *dp_panel)
static int dp_panel_deinit_panel_info(struct dp_panel *dp_panel, u32 flags)
{
	int rc = 0;
	struct dp_panel_private *panel;
@@ -1462,6 +1462,11 @@ static int dp_panel_deinit_panel_info(struct dp_panel *dp_panel)
		return -EINVAL;
	}

	if (flags & DP_PANEL_SRC_INITIATED_POWER_DOWN) {
		pr_debug("retain states in src initiated power down request\n");
		return 0;
	}

	panel = container_of(dp_panel, struct dp_panel_private, dp_panel);
	hdr = &panel->catalog->hdr_data;

+11 −1
Original line number Diff line number Diff line
@@ -23,6 +23,16 @@
#include "sde_edid_parser.h"
#include "sde_connector.h"

/*
 * A source initiated power down flag is set
 * when the DP is powered off while physical
 * DP cable is still connected i.e. without
 * HPD or not initiated by sink like HPD_IRQ.
 * This can happen if framework reboots or
 * device suspends.
 */
#define DP_PANEL_SRC_INITIATED_POWER_DOWN BIT(0)

enum dp_lane_count {
	DP_LANE_COUNT_1	= 1,
	DP_LANE_COUNT_2	= 2,
@@ -102,7 +112,7 @@ struct dp_panel {
	bool widebus_en;

	int (*init)(struct dp_panel *dp_panel);
	int (*deinit)(struct dp_panel *dp_panel);
	int (*deinit)(struct dp_panel *dp_panel, u32 flags);
	int (*hw_cfg)(struct dp_panel *dp_panel, bool enable);
	int (*read_sink_caps)(struct dp_panel *dp_panel,
		struct drm_connector *connector, bool multi_func);