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

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

Merge "Merge remote-tracking branch 'quic/dev/msm-4.14-display' into msm-4.14"

parents b9c1f416 0450777a
Loading
Loading
Loading
Loading
+24 −8
Original line number Diff line number Diff line
@@ -492,30 +492,42 @@ static ssize_t dp_aux_transfer_debug(struct drm_dp_aux *drm_aux,
		goto end;
	}

	if ((msg->address + msg->size) > SZ_16K) {
	if ((msg->address + msg->size) > SZ_4K) {
		pr_err("invalid dpcd access: addr=0x%x, size=0x%x\n",
				msg->address + msg->size);
		goto address_error;
	}

	if (aux->native) {
		if (aux->read) {
		aux->dp_aux.reg = msg->address;
		aux->dp_aux.read = aux->read;
		aux->dp_aux.size = msg->size;

		reinit_completion(&aux->comp);

		if (aux->read) {
			timeout = wait_for_completion_timeout(&aux->comp, HZ);
			if (!timeout)
			if (!timeout) {
				pr_err("aux timeout for 0x%x\n", msg->address);

			aux->dp_aux.reg = 0xFFFF;
				ret = -ETIMEDOUT;
				goto end;
			}

			memcpy(msg->buffer, aux->dpcd + msg->address,
				msg->size);
			aux->aux_error_num = DP_AUX_ERR_NONE;
		} else {
			memcpy(aux->dpcd + msg->address, msg->buffer,
				msg->size);

			timeout = wait_for_completion_timeout(&aux->comp, HZ);
			if (!timeout) {
				pr_err("aux timeout for 0x%x\n", msg->address);
				ret = -ETIMEDOUT;
				goto end;
			}
		}

		aux->aux_error_num = DP_AUX_ERR_NONE;
	} else {
		if (aux->read && msg->address == 0x50) {
			memcpy(msg->buffer,
@@ -545,6 +557,10 @@ static ssize_t dp_aux_transfer_debug(struct drm_dp_aux *drm_aux,
	memset(msg->buffer, 0, msg->size);
	ret = msg->size;
end:
	aux->dp_aux.reg = 0xFFFF;
	aux->dp_aux.read = true;
	aux->dp_aux.size = 0;

	mutex_unlock(&aux->mutex);
	return ret;
}
+3 −0
Original line number Diff line number Diff line
@@ -43,8 +43,11 @@ enum dp_aux_error {

struct dp_aux {
	u32 reg;
	u32 size;
	u32 state;

	bool read;

	struct drm_dp_aux *drm_aux;
	int (*drm_aux_register)(struct dp_aux *aux);
	void (*drm_aux_deregister)(struct dp_aux *aux);
+28 −8
Original line number Diff line number Diff line
@@ -74,13 +74,13 @@ static int dp_debug_get_dpcd_buf(struct dp_debug_private *debug)
	int rc = 0;

	if (!debug->dpcd) {
		debug->dpcd = devm_kzalloc(debug->dev, SZ_16K, GFP_KERNEL);
		debug->dpcd = devm_kzalloc(debug->dev, SZ_4K, GFP_KERNEL);
		if (!debug->dpcd) {
			rc = -ENOMEM;
			goto end;
		}

		debug->dpcd_size = SZ_16K;
		debug->dpcd_size = SZ_4K;
	}
end:
	return rc;
@@ -254,21 +254,41 @@ static ssize_t dp_debug_read_dpcd(struct file *file,
		char __user *user_buff, size_t count, loff_t *ppos)
{
	struct dp_debug_private *debug = file->private_data;
	char buf[SZ_8];
	char *buf;
	int const buf_size = SZ_4K;
	u32 offset = 0;
	u32 len = 0;

	if (!debug)
	if (!debug || !debug->aux || !debug->dpcd)
		return -ENODEV;

	if (*ppos)
		return 0;

	len += snprintf(buf, SZ_8, "0x%x\n", debug->aux->reg);
	buf = kzalloc(buf_size, GFP_KERNEL);
	if (!buf)
		return -ENOMEM;

	len += snprintf(buf, buf_size, "0x%x", debug->aux->reg);

	if (copy_to_user(user_buff, buf, len))
		return -EFAULT;
	if (!debug->aux->read) {
		while (1) {
			if (debug->aux->reg + offset >= buf_size ||
			    offset >= debug->aux->size)
				break;

			len += snprintf(buf + len, buf_size - len, "0x%x",
				debug->dpcd[debug->aux->reg + offset++]);
		}

		if (debug->dp_debug.sim_mode && debug->aux->dpcd_updated)
			debug->aux->dpcd_updated(debug->aux);
	}

	if (!copy_to_user(user_buff, buf, len))
		*ppos += len;

	kfree(buf);
	return len;
}

+21 −23
Original line number Diff line number Diff line
@@ -603,10 +603,11 @@ static void dp_display_host_init(struct dp_display_private *dp)
	bool flip = false;
	bool reset;

	if (dp->core_initialized) {
		pr_debug("DP core already initialized\n");
	if (dp->core_initialized)
		return;
	}

	if (!dp->debug->sim_mode && !dp->parser->no_aux_switch)
		dp->aux->aux_switch(dp->aux, true, dp->hpd->orientation);

	if (dp->hpd->orientation == ORIENTATION_CC2)
		flip = true;
@@ -618,38 +619,39 @@ static void dp_display_host_init(struct dp_display_private *dp)
	dp->aux->init(dp->aux, dp->parser->aux_cfg);
	enable_irq(dp->irq);
	dp->core_initialized = true;

	/* log this as it results from user action of cable connection */
	pr_info("[OK]\n");
}

static void dp_display_host_deinit(struct dp_display_private *dp)
{
	if (!dp->core_initialized) {
		pr_debug("DP core already off\n");
	if (!dp->core_initialized)
		return;
	}

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

	if (!dp->debug->sim_mode && !dp->parser->no_aux_switch)
		dp->aux->aux_switch(dp->aux, false, ORIENTATION_NONE);

	dp->aux->deinit(dp->aux);
	dp->ctrl->deinit(dp->ctrl);
	dp->power->deinit(dp->power);
	disable_irq(dp->irq);
	dp->core_initialized = false;
	dp->aux->state = 0;

	/* log this as it results from user action of cable dis-connection */
	pr_info("[OK]\n");
}

static int dp_display_process_hpd_high(struct dp_display_private *dp)
{
	int rc = 0;

	if (!dp->debug->sim_mode && !dp->parser->no_aux_switch) {
		rc = dp->aux->aux_switch(dp->aux, true, dp->hpd->orientation);
		if (rc)
			goto end;
	}

	dp->is_connected = true;

	dp->dp_display.max_pclk_khz = dp->parser->max_pclk_khz;
@@ -727,10 +729,8 @@ static int dp_display_process_hpd_low(struct dp_display_private *dp)

		dp_panel = dp->active_panels[idx];

		if (dp_panel->audio_supported) {
		if (dp_panel->audio_supported)
			dp_panel->audio->off(dp_panel->audio);
			dp_panel->audio_supported = false;
		}
	}

	mutex_unlock(&dp->session_lock);
@@ -767,6 +767,8 @@ static int dp_display_usbpd_configure_cb(struct device *dev)
		goto end;
	}

	dp_display_host_init(dp);

	/* check for hpd high and framework ready */
	if (dp->hpd->hpd_high && dp_display_framework_ready(dp))
		queue_delayed_work(dp->wq, &dp->connect_work, 0);
@@ -860,9 +862,6 @@ static int dp_display_usbpd_disconnect_cb(struct device *dev)
	cancel_work(&dp->attention_work);
	flush_workqueue(dp->wq);

	if (!dp->debug->sim_mode && !dp->parser->no_aux_switch)
		dp->aux->aux_switch(dp->aux, false, ORIENTATION_NONE);

	dp_display_handle_disconnect(dp);

	/* Reset abort value to allow future connections */
@@ -981,7 +980,7 @@ static int dp_display_usbpd_attention_cb(struct device *dev)
		return -ENODEV;
	}

	DP_MST_DEBUG("mst: hpd_irq:%d, hpd_high:%d, power_on:%d\n",
	pr_debug("hpd_irq:%d, hpd_high:%d, power_on:%d\n",
			dp->hpd->hpd_irq, dp->hpd->hpd_high,
			dp->power_on);

@@ -1428,7 +1427,6 @@ static int dp_display_post_enable(struct dp_display *dp_display, void *panel)
{
	struct dp_display_private *dp;
	struct dp_panel *dp_panel;
	struct edid *edid;

	if (!dp_display || !panel) {
		pr_err("invalid input\n");
@@ -1455,9 +1453,6 @@ static int dp_display_post_enable(struct dp_display *dp_display, void *panel)

	dp_display_stream_post_enable(dp, dp_panel);

	edid = dp_panel->edid_ctrl->edid;
	dp_panel->audio_supported = drm_detect_monitor_audio(edid);

	if (dp_panel->audio_supported) {
		dp_panel->audio->bw_code = dp->link->link_params.bw_code;
		dp_panel->audio->lane_count = dp->link->link_params.lane_count;
@@ -1568,6 +1563,9 @@ static int dp_display_disable(struct dp_display *dp_display, void *panel)
	}

	dp->power_on = false;

	/* 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);
+24 −0
Original line number Diff line number Diff line
@@ -34,6 +34,7 @@
#define MAX_DP_MST_DRM_ENCODERS		2
#define MAX_DP_MST_DRM_BRIDGES		2
#define DP_MST_SIM_MAX_PORTS    2
#define HPD_STRING_SIZE			30

struct dp_drm_mst_fw_helper_ops {
	int (*calc_pbn_mode)(int clock, int bpp);
@@ -1330,6 +1331,27 @@ static void dp_mst_hotplug(struct drm_dp_mst_topology_mgr *mgr)
	DP_MST_DEBUG("mst hot plug event\n");
}

static void dp_mst_hpd_event_notify(struct dp_mst_private *mst, bool hpd_status)
{
	struct drm_device *dev = mst->dp_display->drm_dev;
	char event_string[] = "MST_HOTPLUG=1";
	char status[HPD_STRING_SIZE];
	char *envp[3];

	if (hpd_status)
		snprintf(status, HPD_STRING_SIZE, "status=connected");
	else
		snprintf(status, HPD_STRING_SIZE, "status=disconnected");

	envp[0] = event_string;
	envp[1] = status;
	envp[2] = NULL;

	kobject_uevent_env(&dev->primary->kdev->kobj, KOBJ_CHANGE, envp);

	DP_MST_DEBUG("%s finished\n", __func__);
}

/* DP Driver Callback OPs */

static void dp_mst_display_hpd(void *dp_display, bool hpd_status,
@@ -1357,6 +1379,8 @@ static void dp_mst_display_hpd(void *dp_display, bool hpd_status,
		rc = mst->mst_fw_cbs->topology_mgr_set_mst(&mst->mst_mgr,
				hpd_status);

	dp_mst_hpd_event_notify(mst, hpd_status);

	DP_MST_DEBUG("mst display hpd:%d, rc:%d\n", hpd_status, rc);

	DP_MST_DEBUG("exit:\n");
Loading