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

Commit 6fa30971 authored by qctecmdr's avatar qctecmdr Committed by Gerrit - the friendly Code Review server
Browse files

Merge "disp: msm: dp: unify hpd event for sst and mst"

parents e09f7466 2fc0439a
Loading
Loading
Loading
Loading
+68 −70
Original line number Diff line number Diff line
@@ -807,7 +807,7 @@ static const struct component_ops dp_display_comp_ops = {
	.unbind = dp_display_unbind,
};

static void dp_display_send_hpd_event(struct dp_display_private *dp)
static bool dp_display_send_hpd_event(struct dp_display_private *dp)
{
	struct drm_device *dev = NULL;
	struct drm_connector *connector;
@@ -816,24 +816,18 @@ static void dp_display_send_hpd_event(struct dp_display_private *dp)
	char *envp[5];
	int rc = 0;

	if (dp->mst.mst_active) {
		DP_DEBUG("skip notification for mst mode\n");
		dp_display_state_remove(DP_STATE_DISCONNECT_NOTIFIED);
		return;
	}

	connector = dp->dp_display.base_connector;

	if (!connector) {
		DP_ERR("connector not set\n");
		return;
		return false;
	}

	connector->status = connector->funcs->detect(connector, false);
	if (dp->cached_connector_status == connector->status) {
		DP_DEBUG("connector status (%d) unchanged, skipping uevent\n",
				dp->cached_connector_status);
		return;
		return false;
	}

	dp->cached_connector_status = connector->status;
@@ -842,7 +836,7 @@ static void dp_display_send_hpd_event(struct dp_display_private *dp)

	if (dp->debug->skip_uevent) {
		DP_INFO("skipping uevent\n");
		goto update_state;
		return false;
	}

	snprintf(name, HPD_STRING_SIZE, "name=%s", connector->name);
@@ -864,14 +858,7 @@ static void dp_display_send_hpd_event(struct dp_display_private *dp)
	rc = kobject_uevent_env(&dev->primary->kdev->kobj, KOBJ_CHANGE, envp);
	DP_INFO("uevent %s: %d\n", rc ? "failure" : "success", rc);

update_state:
	if (connector->status == connector_status_connected) {
		dp_display_state_add(DP_STATE_CONNECT_NOTIFIED);
		dp_display_state_remove(DP_STATE_DISCONNECT_NOTIFIED);
	} else {
		dp_display_state_add(DP_STATE_DISCONNECT_NOTIFIED);
		dp_display_state_remove(DP_STATE_CONNECT_NOTIFIED);
	}
	return true;
}

static int dp_display_send_hpd_notification(struct dp_display_private *dp)
@@ -900,13 +887,29 @@ static int dp_display_send_hpd_notification(struct dp_display_private *dp)

	dp->aux->state |= DP_STATE_NOTIFICATION_SENT;

	if (!dp->mst.mst_active)
	reinit_completion(&dp->notification_comp);

	if (!dp->mst.mst_active) {
		dp->dp_display.is_sst_connected = hpd;
	else

		if (!dp_display_send_hpd_event(dp))
			goto skip_wait;
	} else {
		dp->dp_display.is_sst_connected = false;

	reinit_completion(&dp->notification_comp);
	dp_display_send_hpd_event(dp);
		if (!dp->mst.cbs.hpd)
			goto skip_wait;

		dp->mst.cbs.hpd(&dp->dp_display, true);
	}

	if (hpd) {
		dp_display_state_add(DP_STATE_CONNECT_NOTIFIED);
		dp_display_state_remove(DP_STATE_DISCONNECT_NOTIFIED);
	} else {
		dp_display_state_add(DP_STATE_DISCONNECT_NOTIFIED);
		dp_display_state_remove(DP_STATE_CONNECT_NOTIFIED);
	}

	/*
	 * Skip the wait if TUI is active considering that the user mode will
@@ -942,11 +945,9 @@ static void dp_display_update_mst_state(struct dp_display_private *dp,
	dp->panel->mst_state = state;
}

static void dp_display_process_mst_hpd_high(struct dp_display_private *dp,
						bool mst_probe)
static void dp_display_mst_init(struct dp_display_private *dp)
{
	bool is_mst_receiver;
	struct dp_mst_hpd_info info;
	const unsigned long clear_mstm_ctrl_timeout_us = 100000;
	u8 old_mstm_ctrl;
	int ret;
@@ -957,9 +958,6 @@ static void dp_display_process_mst_hpd_high(struct dp_display_private *dp,
		return;
	}

	DP_MST_DEBUG("mst_hpd_high work. mst_probe:%d\n", mst_probe);

	if (!dp->mst.mst_active) {
	is_mst_receiver = dp->panel->read_mst_cap(dp->panel);

	if (!is_mst_receiver) {
@@ -968,8 +966,7 @@ static void dp_display_process_mst_hpd_high(struct dp_display_private *dp,
	}

	/* clear sink mst state */
		drm_dp_dpcd_readb(dp->aux->drm_aux, DP_MSTM_CTRL,
				&old_mstm_ctrl);
	drm_dp_dpcd_readb(dp->aux->drm_aux, DP_MSTM_CTRL, &old_mstm_ctrl);
	drm_dp_dpcd_writeb(dp->aux->drm_aux, DP_MSTM_CTRL, 0);

	/* add extra delay if MST state is not cleared */
@@ -988,19 +985,26 @@ static void dp_display_process_mst_hpd_high(struct dp_display_private *dp,
	}

	dp_display_update_mst_state(dp, true);
	} else if (dp->mst.mst_active && mst_probe) {
}

static void dp_display_set_mst_mgr_state(struct dp_display_private *dp,
					bool state)
{
	struct dp_mst_hpd_info info = {0};

	if (!dp->mst.mst_active)
		return;

	info.mst_protocol = dp->parser->has_mst_sideband;
	if (state) {
		info.mst_port_cnt = dp->debug->mst_port_cnt;
		info.edid = dp->debug->get_edid(dp->debug);
	}

	if (dp->mst.cbs.set_mgr_state)
			dp->mst.cbs.set_mgr_state(&dp->dp_display, true, &info);

		if (dp->mst.cbs.hpd)
			dp->mst.cbs.hpd(&dp->dp_display, true);
	}
		dp->mst.cbs.set_mgr_state(&dp->dp_display, state, &info);

	DP_MST_DEBUG("mst_hpd_high. mst_active:%d\n", dp->mst.mst_active);
	DP_MST_DEBUG("mst_mgr_state: %d\n", state);
}

static int dp_display_host_init(struct dp_display_private *dp)
@@ -1210,7 +1214,7 @@ static int dp_display_process_hpd_high(struct dp_display_private *dp)
	dp->link->process_request(dp->link);
	dp->panel->handle_sink_request(dp->panel);

	dp_display_process_mst_hpd_high(dp, false);
	dp_display_mst_init(dp);

	rc = dp->ctrl->on(dp->ctrl, dp->mst.mst_active,
			dp->panel->fec_en, dp->panel->dsc_en, false);
@@ -1221,7 +1225,7 @@ static int dp_display_process_hpd_high(struct dp_display_private *dp)

	dp->process_hpd_connect = false;

	dp_display_process_mst_hpd_high(dp, true);
	dp_display_set_mst_mgr_state(dp, true);
end:
	mutex_unlock(&dp->session_lock);

@@ -1270,7 +1274,6 @@ static int dp_display_process_hpd_high(struct dp_display_private *dp)
static void dp_display_process_mst_hpd_low(struct dp_display_private *dp)
{
	int rc = 0;
	struct dp_mst_hpd_info info = {0};

	if (dp->mst.mst_active) {
		DP_MST_DEBUG("mst_hpd_low work\n");
@@ -1286,17 +1289,12 @@ static void dp_display_process_mst_hpd_low(struct dp_display_private *dp)
		if (dp->mst.cbs.hpd)
			dp->mst.cbs.hpd(&dp->dp_display, false);

		dp_display_update_mst_state(dp, false);

		if ((dp_display_state_is(DP_STATE_CONNECT_NOTIFIED) ||
				dp_display_state_is(DP_STATE_ENABLED)))
			rc = dp_display_send_hpd_notification(dp);

		if (dp->mst.cbs.set_mgr_state) {
			info.mst_protocol = dp->parser->has_mst_sideband;
			dp->mst.cbs.set_mgr_state(&dp->dp_display, false,
					&info);
		}
		dp_display_update_mst_state(dp, false);
		dp_display_set_mst_mgr_state(dp, false);
	}

	DP_MST_DEBUG("mst_hpd_low. mst_active:%d\n", dp->mst.mst_active);