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

Commit bbcd7572 authored by Abhijith Desai's avatar Abhijith Desai
Browse files

Merge commit '7be8c9d2' into msm-4.14



* commit '7be8c9d2':
  drm/msm/sde: fix mixer width for validating plane dest roi
  drm/msm/sde: validate plane ROI to be within layer mixer boundary
  drm/sde/hdcp: Update sink sync check to be disabled by default
  drm/msm/hdcp: Prevent disconnect from stopping HDCP
  drm/msm/hdcp:  Avoid double authentication if first is still in progress
  drm/msm/hdcp: Account for in progress stream management
  drm/msm/hdcp: update hdcp 2.2 stream management sequence
  drm/msm/dp: change mdss_dp_active and mdss_dp_sleep to optional

Change-Id: I0301295b153cbce094c7c48a05f5cb886a82926a
Signed-off-by: default avatarAbhijith Desai <desaia@codeaurora.org>
parents d131eb25 7be8c9d2
Loading
Loading
Loading
Loading
+11 −0
Original line number Diff line number Diff line
@@ -1946,6 +1946,17 @@ static int dp_debug_init(struct dp_debug *dp_debug)
		goto error_remove_dir;
	}

	file = debugfs_create_bool("hdcp_wait_sink_sync", 0644, dir,
			&debug->dp_debug.hdcp_wait_sink_sync);

	if (IS_ERR_OR_NULL(file)) {
		rc = PTR_ERR(file);
		pr_err("[%s] debugfs hdcp_wait_sink_sync failed, rc=%d\n",
		       DEBUG_NAME, rc);
		goto error_remove_dir;
	}


	file = debugfs_create_bool("dsc_feature_enable", 0644, dir,
			&debug->parser->dsc_feature_enable);
	if (IS_ERR_OR_NULL(file)) {
+2 −0
Original line number Diff line number Diff line
@@ -25,6 +25,7 @@
/**
 * struct dp_debug
 * @debug_en: specifies whether debug mode enabled
 * @hdcp_wait_sink_sync: used to wait for sink synchronization before HDCP auth
 * @vdisplay: used to filter out vdisplay value
 * @hdisplay: used to filter out hdisplay value
 * @vrefresh: used to filter out vrefresh value
@@ -37,6 +38,7 @@ struct dp_debug {
	bool sim_mode;
	bool psm_enabled;
	bool hdcp_disabled;
	bool hdcp_wait_sink_sync;
	int aspect_ratio;
	int vdisplay;
	int hdisplay;
+40 −17
Original line number Diff line number Diff line
@@ -107,6 +107,7 @@ struct dp_display_private {
	struct mutex session_lock;
	bool suspended;
	bool hdcp_delayed_off;
	bool hdcp_abort;

	u32 active_stream_cnt;
	struct dp_mst mst;
@@ -339,7 +340,8 @@ static void dp_display_hdcp_cb_work(struct work_struct *work)

	dp = container_of(dw, struct dp_display_private, hdcp_cb_work);

	if (!dp->power_on || !dp->is_connected || atomic_read(&dp->aborted))
	if (!dp->power_on || !dp->is_connected || atomic_read(&dp->aborted) ||
			dp->hdcp_abort)
		return;

	if (dp->suspended) {
@@ -355,13 +357,17 @@ static void dp_display_hdcp_cb_work(struct work_struct *work)
		dp->hdcp_delayed_off = false;
	}

	drm_dp_dpcd_readb(dp->aux->drm_aux, DP_SINK_STATUS, &sink_status);
	sink_status &= (DP_RECEIVE_PORT_0_STATUS | DP_RECEIVE_PORT_1_STATUS);
	if (dp->debug->hdcp_wait_sink_sync) {
		drm_dp_dpcd_readb(dp->aux->drm_aux, DP_SINK_STATUS,
				&sink_status);
		sink_status &= (DP_RECEIVE_PORT_0_STATUS |
				DP_RECEIVE_PORT_1_STATUS);
		if (sink_status < 1) {
			pr_debug("Sink not synchronized. Queuing again then exiting\n");
			queue_delayed_work(dp->wq, &dp->hdcp_cb_work, HZ);
			return;
		}
	}

	status = &dp->link->hdcp_status;

@@ -375,7 +381,6 @@ static void dp_display_hdcp_cb_work(struct work_struct *work)
				dp_display_update_hdcp_status(dp, true);
				return;
			}
			status->hdcp_state = HDCP_STATE_AUTHENTICATING;
		} else {
			dp_display_update_hdcp_status(dp, true);
			return;
@@ -400,10 +405,12 @@ static void dp_display_hdcp_cb_work(struct work_struct *work)
		ops->force_encryption(data, dp->debug->force_encryption);

	switch (status->hdcp_state) {
	case HDCP_STATE_AUTHENTICATING:
	case HDCP_STATE_INACTIVE:
		dp_display_hdcp_register_streams(dp);
		if (dp->hdcp.ops && dp->hdcp.ops->authenticate)
			rc = dp->hdcp.ops->authenticate(data);
		if (!rc)
			status->hdcp_state = HDCP_STATE_AUTHENTICATING;
		break;
	case HDCP_STATE_AUTH_FAIL:
		if (dp_display_is_ready(dp) && dp->power_on) {
@@ -1730,16 +1737,18 @@ static int dp_display_pre_disable(struct dp_display *dp_display, void *panel)
		goto end;
	}

	dp->hdcp_abort = true;
	cancel_delayed_work_sync(&dp->hdcp_cb_work);
	if (dp_display_is_hdcp_enabled(dp) &&
			status->hdcp_state != HDCP_STATE_INACTIVE) {
		bool off = true;

		if (dp->suspended) {
			pr_debug("Can't perform HDCP cleanup while suspended. Defer\n");
			dp->hdcp_delayed_off = true;
			goto stream;
			goto clean;
		}

		flush_delayed_work(&dp->hdcp_cb_work);
		if (dp->mst.mst_active) {
			dp_display_hdcp_deregister_stream(dp,
				dp_panel->stream_id);
@@ -1747,18 +1756,19 @@ static int dp_display_pre_disable(struct dp_display *dp_display, void *panel)
				if (i != dp_panel->stream_id &&
						dp->active_panels[i]) {
					pr_debug("Streams are still active. Skip disabling HDCP\n");
					goto stream;
					off = false;
				}
			}
		}

		if (off) {
			if (dp->hdcp.ops->off)
				dp->hdcp.ops->off(dp->hdcp.data);

			dp_display_update_hdcp_status(dp, true);
		}
	}

stream:
clean:
	if (dp_panel->audio_supported)
		dp_panel->audio->off(dp_panel->audio);

@@ -1771,8 +1781,10 @@ static int dp_display_pre_disable(struct dp_display *dp_display, void *panel)

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

	if (!dp_display || !panel) {
		pr_err("invalid input\n");
@@ -1781,6 +1793,7 @@ 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;
	status = &dp->link->hdcp_status;

	mutex_lock(&dp->session_lock);

@@ -1791,6 +1804,16 @@ static int dp_display_disable(struct dp_display *dp_display, void *panel)

	dp_display_stream_disable(dp, dp_panel);
	dp_display_update_dsc_resources(dp, dp_panel, false);

	dp->hdcp_abort = false;
	for (i = DP_STREAM_0; i < DP_STREAM_MAX; i++) {
		if (dp->active_panels[i]) {
			if (status->hdcp_state != HDCP_STATE_AUTHENTICATED)
				queue_delayed_work(dp->wq, &dp->hdcp_cb_work,
						HZ/4);
			break;
		}
	}
end:
	mutex_unlock(&dp->session_lock);
	return 0;
+8 −11
Original line number Diff line number Diff line
@@ -205,14 +205,13 @@ static int dp_parser_msm_hdcp_dev(struct dp_parser *parser)

static int dp_parser_pinctrl(struct dp_parser *parser)
{
	int rc = 0;
	struct dp_pinctrl *pinctrl = &parser->pinctrl;

	pinctrl->pin = devm_pinctrl_get(&parser->pdev->dev);

	if (IS_ERR_OR_NULL(pinctrl->pin)) {
		pr_debug("failed to get pinctrl, rc=%d\n", rc);
		goto error;
		pr_debug("failed to get pinctrl\n");
		return 0;
	}

	if (parser->no_aux_switch && parser->lphw_hpd) {
@@ -235,20 +234,18 @@ static int dp_parser_pinctrl(struct dp_parser *parser)
	pinctrl->state_active = pinctrl_lookup_state(pinctrl->pin,
					"mdss_dp_active");
	if (IS_ERR_OR_NULL(pinctrl->state_active)) {
		rc = PTR_ERR(pinctrl->state_active);
		pr_err("failed to get pinctrl active state, rc=%d\n", rc);
		goto error;
		pinctrl->state_active = NULL;
		pr_debug("failed to get pinctrl active state\n");
	}

	pinctrl->state_suspend = pinctrl_lookup_state(pinctrl->pin,
					"mdss_dp_sleep");
	if (IS_ERR_OR_NULL(pinctrl->state_suspend)) {
		rc = PTR_ERR(pinctrl->state_suspend);
		pr_err("failed to get pinctrl suspend state, rc=%d\n", rc);
		goto error;
		pinctrl->state_suspend = NULL;
		pr_debug("failed to get pinctrl suspend state\n");
	}
error:
	return rc;

	return 0;
}

static int dp_parser_gpio(struct dp_parser *parser)
+1 −8
Original line number Diff line number Diff line
@@ -117,7 +117,7 @@ static int dp_power_regulator_ctrl(struct dp_power_private *power, bool enable)

static int dp_power_pinctrl_set(struct dp_power_private *power, bool active)
{
	int rc = -EFAULT;
	int rc = 0;
	struct pinctrl_state *pin_state;
	struct dp_parser *parser;

@@ -140,9 +140,6 @@ static int dp_power_pinctrl_set(struct dp_power_private *power, bool active)
		}
	}

	if (parser->no_aux_switch)
		return 0;

	pin_state = active ? parser->pinctrl.state_active
				: parser->pinctrl.state_suspend;
	if (!IS_ERR_OR_NULL(pin_state)) {
@@ -152,10 +149,6 @@ static int dp_power_pinctrl_set(struct dp_power_private *power, bool active)
			pr_err("can not set %s pins\n",
			       active ? "dp_active"
			       : "dp_sleep");
	} else {
		pr_err("invalid '%s' pinstate\n",
		       active ? "dp_active"
		       : "dp_sleep");
	}

	return rc;
Loading