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

Commit f56c77f4 authored by Tatenda Chipeperekwa's avatar Tatenda Chipeperekwa
Browse files

drm/msm/dp: add error handling for stream enable failures



Add error handling in the control and display modules for stream
enable failures. Ensure that the link clock is turned off if
stream enable fails, and validate the active stream count in the
stream disable path. Furthermore, disable the display core only
after the display controller is powered off in order to prevent
potential unclocked register access.

Change-Id: I4be11edbb4014b7c772b78fff871fdb4f31ce456
Signed-off-by: default avatarTatenda Chipeperekwa <tatendac@codeaurora.org>
parent 0db88144
Loading
Loading
Loading
Loading
+7 −3
Original line number Diff line number Diff line
@@ -988,22 +988,26 @@ static int dp_ctrl_stream_on(struct dp_ctrl *dp_ctrl, struct dp_panel *panel)

	rc = panel->hw_cfg(panel);
	if (rc)
		return rc;
		goto error;

	dp_ctrl_send_video(ctrl);

	rc = dp_ctrl_mst_stream_setup(ctrl, panel);
	if (rc)
		return rc;
		goto error;

	rc = dp_ctrl_wait4video_ready(ctrl);
	if (rc)
		return rc;
		goto error;

	link_ready = ctrl->catalog->mainlink_ready(ctrl->catalog);
	pr_debug("mainlink %s\n", link_ready ? "READY" : "NOT READY");

	return rc;

error:
	dp_ctrl_disable_stream_clocks(ctrl, panel);
	return rc;
}

static void dp_ctrl_mst_stream_pre_off(struct dp_ctrl *dp_ctrl,
+29 −10
Original line number Diff line number Diff line
@@ -738,7 +738,14 @@ static int dp_display_handle_disconnect(struct dp_display_private *dp)
	if (rc && dp->power_on)
		dp_display_clean(dp);

	if (!dp->usbpd->alt_mode_cfg_done)
	/*
	 * De-initialize the display core only if the display controller has
	 * been turned off either through the DRM bridge disable call or
	 * through the error handling code. This ensures that the power
	 * resource vote is still present in cases when the bridge disable is
	 * delayed.
	 */
	if (!dp->power_on && !dp->usbpd->alt_mode_cfg_done)
		dp_display_host_deinit(dp);

	mutex_unlock(&dp->session_lock);
@@ -1315,6 +1322,10 @@ static int dp_display_enable(struct dp_display *dp_display, void *panel)

stream_setup:
	rc = dp_display_stream_enable(dp, panel);
	if (rc && (dp->active_stream_cnt == 0)) {
		dp->ctrl->off(dp->ctrl);
		dp->power_on = false;
	}

end:
	mutex_unlock(&dp->session_lock);
@@ -1442,19 +1453,23 @@ static int dp_display_pre_disable(struct dp_display *dp_display, void *panel)
static void dp_display_stream_disable(struct dp_display_private *dp,
			struct dp_panel *dp_panel)
{
	dp->ctrl->stream_off(dp->ctrl, dp_panel);
	if (!dp->active_stream_cnt) {
		pr_err("invalid active_stream_cnt (%d)\n");
		return;
	}

	pr_debug("stream_id=%d, active_stream_cnt=%d\n",
			dp_panel->stream_id, dp->active_stream_cnt);

	dp->ctrl->stream_off(dp->ctrl, dp_panel);
	dp->active_panels[dp_panel->stream_id] = NULL;
	dp->active_stream_cnt--;

	dp_panel->deinit(dp_panel);

	pr_debug("mst stream disabled");
}

static int dp_display_disable(struct dp_display *dp_display, void *panel)
{
	struct dp_display_private *dp;
	struct dp_display_private *dp = NULL;
	struct dp_panel *dp_panel = NULL;

	if (!dp_display || !panel) {
		pr_err("invalid input\n");
@@ -1462,18 +1477,21 @@ static int dp_display_disable(struct dp_display *dp_display, void *panel)
	}

	dp = container_of(dp_display, struct dp_display_private, dp_display);
	dp_panel = panel;

	mutex_lock(&dp->session_lock);

	dp_display_stream_disable(dp, panel);

	if (!dp->power_on || !dp->core_initialized) {
		pr_debug("Link already powered off, return\n");
		goto end;
	}

	if (dp->active_stream_cnt)
	dp_display_stream_disable(dp, dp_panel);

	if (dp->active_stream_cnt) {
		pr_debug("active stream present\n");
		goto end;
	}

	dp->ctrl->off(dp->ctrl);

@@ -1490,6 +1508,7 @@ static int dp_display_disable(struct dp_display *dp_display, void *panel)

	dp->power_on = false;
end:
	dp_panel->deinit(dp_panel);
	mutex_unlock(&dp->session_lock);
	return 0;
}
+1 −1
Original line number Diff line number Diff line
@@ -646,7 +646,7 @@ static int dp_power_deinit(struct dp_power *dp_power)
	rc = sde_power_resource_enable(power->phandle,
			power->dp_core_client, false);
	if (rc) {
		pr_err("Power resource enable failed, rc=%d\n", rc);
		pr_err("Power resource disable failed, rc=%d\n", rc);
		goto exit;
	}
	dp_power_config_gpios(power, false, false);
+1 −0
Original line number Diff line number Diff line
@@ -446,6 +446,7 @@ static int dp_usbpd_simulate_connect(struct dp_usbpd *dp_usbpd, bool hpd,
	dp_usbpd->hpd_high = hpd;
	pd->forced_disconnect = !hpd;
	pd->dp_usbpd.orientation = orientation;
	pd->dp_usbpd.alt_mode_cfg_done = hpd;

	pr_debug("hpd_high=%d, forced_disconnect=%d, orientation=%d\n",
			dp_usbpd->hpd_high, pd->forced_disconnect,