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

Commit f566f926 authored by Linux Build Service Account's avatar Linux Build Service Account Committed by Gerrit - the friendly Code Review server
Browse files

Merge "drm/msm/sde: update auto-refresh disable during cont-spalsh"

parents 6ef2bdd4 8a0b4875
Loading
Loading
Loading
Loading
+7 −0
Original line number Diff line number Diff line
@@ -108,6 +108,10 @@ Optional properties
				<rd_lut, wr_lut> indicating the safe lut
				settings for the inline rotator sspp and
				writeback client.
- qcom,mdss-rot-qos-cpu-mask: A u32 value indicating desired PM QoS CPU
				affine mask.
- qcom,mdss-rot-qos-cpu-dma-latency: A u32 value indicating desired PM QoS CPU DMA
				latency in usec.
- qcom,mdss-rot-mode:		This is integer value indicates operation mode
				of the rotator device
- qcom,mdss-sbuf-headroom:	This integer value indicates stream buffer headroom in lines.
@@ -188,6 +192,9 @@ Example:
		qcom,mdss-rot-danger-lut = <0x0 0x0>;
		qcom,mdss-rot-safe-lut = <0x0000ffff 0x0>;

		qcom,mdss-rot-qos-cpu-mask = <0xf>;
		qcom,mdss-rot-qos-cpu-dma-latency = <75>;

		qcom,mdss-inline-rot-qos-lut = <0x0 0x0 0x00112233 0x44556677>;
		qcom,mdss-inline-rot-danger-lut = <0x0 0x0000ffff>;
		qcom,mdss-inline-rot-safe-lut = <0x0 0x0000ff00>;
+17 −4
Original line number Diff line number Diff line
/*
 * Copyright (c) 2012-2017, The Linux Foundation. All rights reserved.
 * Copyright (c) 2012-2018, The Linux Foundation. All rights reserved.
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License version 2 and
@@ -71,6 +71,8 @@ struct dp_ctrl_private {
	struct completion video_comp;

	bool orientation;
	bool power_on;

	atomic_t aborted;

	u32 pixel_rate;
@@ -128,6 +130,11 @@ static void dp_ctrl_push_idle(struct dp_ctrl *dp_ctrl)

	ctrl = container_of(dp_ctrl, struct dp_ctrl_private, dp_ctrl);

	if (!ctrl->power_on || atomic_read(&ctrl->aborted)) {
		pr_err("CTRL off, return\n");
		return;
	}

	reinit_completion(&ctrl->idle_comp);
	dp_ctrl_state_ctrl(ctrl, ST_PUSH_IDLE);

@@ -833,7 +840,7 @@ static int dp_ctrl_link_train_1(struct dp_ctrl_private *ctrl)

	tries = 0;
	old_v_level = ctrl->link->phy_params.v_level;
	while (1) {
	while (!atomic_read(&ctrl->aborted)) {
		drm_dp_link_train_clock_recovery_delay(ctrl->panel->dpcd);

		ret = dp_ctrl_read_link_status(ctrl, link_status);
@@ -960,7 +967,7 @@ static int dp_ctrl_link_training_2(struct dp_ctrl_private *ctrl)
			ret = -EINVAL;
			break;
		}
	} while (1);
	} while (!atomic_read(&ctrl->aborted));

	return ret;
}
@@ -1180,6 +1187,11 @@ static int dp_ctrl_link_maintenance(struct dp_ctrl *dp_ctrl)

	ctrl = container_of(dp_ctrl, struct dp_ctrl_private, dp_ctrl);

	if (!ctrl->power_on || atomic_read(&ctrl->aborted)) {
		pr_err("CTRL off, return\n");
		return -EINVAL;
	}

	ctrl->dp_ctrl.push_idle(&ctrl->dp_ctrl);
	ctrl->dp_ctrl.reset(&ctrl->dp_ctrl);

@@ -1341,7 +1353,6 @@ static int dp_ctrl_on(struct dp_ctrl *dp_ctrl)
	atomic_set(&ctrl->aborted, 0);
	rate = ctrl->panel->link_info.rate;

	ctrl->power->clk_enable(ctrl->power, DP_CORE_PM, true);
	ctrl->catalog->hpd_config(ctrl->catalog, true);

	if (ctrl->link->sink_request & DP_TEST_LINK_PHY_TEST_PATTERN) {
@@ -1396,6 +1407,7 @@ static int dp_ctrl_on(struct dp_ctrl *dp_ctrl)
	if (ctrl->link->sink_request & DP_TEST_LINK_PHY_TEST_PATTERN)
		dp_ctrl_send_phy_test_pattern(ctrl);

	ctrl->power_on = true;
	pr_debug("End-\n");

end:
@@ -1419,6 +1431,7 @@ static void dp_ctrl_off(struct dp_ctrl *dp_ctrl)

	dp_ctrl_disable_mainlink_clocks(ctrl);

	ctrl->power_on = false;
	pr_debug("DP off done\n");
}

+3 −1
Original line number Diff line number Diff line
/*
 * Copyright (c) 2017, The Linux Foundation. All rights reserved.
 * Copyright (c) 2017-2018, The Linux Foundation. All rights reserved.
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License version 2 and
@@ -665,6 +665,8 @@ static ssize_t dp_debug_write_hdr(struct file *file,
		pr_err("invalid input\n");
		len = -EINVAL;
	}

	debug->panel->setup_hdr(debug->panel, &c_state->hdr_meta);
end:
	return len;
}
+90 −43
Original line number Diff line number Diff line
/*
 * Copyright (c) 2017, The Linux Foundation. All rights reserved.
 * Copyright (c) 2017-2018, The Linux Foundation. All rights reserved.
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License version 2 and
@@ -22,6 +22,8 @@
#include <linux/of_irq.h>
#include <linux/hdcp_qseecom.h>

#include "sde_connector.h"

#include "msm_drv.h"
#include "dp_usbpd.h"
#include "dp_parser.h"
@@ -87,11 +89,12 @@ struct dp_display_private {

	struct workqueue_struct *wq;
	struct delayed_work hdcp_cb_work;
	struct work_struct connect_work;
	struct delayed_work connect_work;
	struct work_struct attention_work;
	struct mutex hdcp_mutex;
	struct mutex session_lock;
	int hdcp_status;
	unsigned long audio_status;
};

static const struct of_device_id dp_dt_match[] = {
@@ -99,6 +102,11 @@ static const struct of_device_id dp_dt_match[] = {
	{}
};

static bool dp_display_framework_ready(struct dp_display_private *dp)
{
	return dp->dp_display.post_open ? false : true;
}

static inline bool dp_display_is_hdcp_enabled(struct dp_display_private *dp)
{
	return dp->hdcp.feature_enabled &&
@@ -447,31 +455,30 @@ static void dp_display_post_open(struct dp_display *dp_display)
	}

	/* if cable is already connected, send notification */
	if (dp_display->is_connected)
		dp_display_send_hpd_event(dp);
	if (dp->usbpd->hpd_high)
		queue_delayed_work(dp->wq, &dp->connect_work, HZ * 10);
	else
		dp_display->post_open = NULL;

}

static int dp_display_send_hpd_notification(struct dp_display_private *dp,
		bool hpd)
{
	u32 timeout_sec;

	dp->dp_display.is_connected = hpd;

	/* in case, framework is not yet up, don't notify hpd */
	if (dp->dp_display.post_open)
		return 0;
	if  (dp_display_framework_ready(dp))
		timeout_sec = 5;
	else
		timeout_sec = 10;

	reinit_completion(&dp->notification_comp);
	dp_display_send_hpd_event(dp);

	if (!wait_for_completion_timeout(&dp->notification_comp, HZ * 5)) {
	if (!wait_for_completion_timeout(&dp->notification_comp,
						HZ * timeout_sec)) {
		pr_warn("%s timeout\n", hpd ? "connect" : "disconnect");
		/* cancel any pending request */
		dp->ctrl->abort(dp->ctrl);
		dp->aux->abort(dp->aux);

		return -EINVAL;
	}

@@ -495,26 +502,21 @@ static int dp_display_process_hpd_high(struct dp_display_private *dp)

	rc = dp->panel->read_sink_caps(dp->panel, dp->dp_display.connector);
	if (rc) {
		if (rc == -ETIMEDOUT) {
			pr_err("Sink cap read failed, skip notification\n");
		/*
		 * ETIMEDOUT --> cable may have been removed
		 * ENOTCONN --> no downstream device connected
		 */
		if (rc == -ETIMEDOUT || rc == -ENOTCONN)
			goto end;
		} else {
		else
			goto notify;
	}
	}

	dp->link->process_request(dp->link);

	if (dp_display_is_sink_count_zero(dp)) {
		pr_debug("no downstream devices connected\n");
		rc = -EINVAL;
		goto end;
	}

	edid = dp->panel->edid_ctrl->edid;

	dp->audio_supported = drm_detect_monitor_audio(edid);

	dp->link->process_request(dp->link);
	dp->panel->handle_sink_request(dp->panel);

	dp->dp_display.max_pclk_khz = dp->parser->max_pclk_khz;
@@ -571,9 +573,9 @@ static int dp_display_process_hpd_low(struct dp_display_private *dp)
	if (dp->audio_supported)
		dp->audio->off(dp->audio);

	rc = dp_display_send_hpd_notification(dp, false);
	dp->audio_status = -ENODEV;

	dp->aux->deinit(dp->aux);
	rc = dp_display_send_hpd_notification(dp, false);

	dp->panel->video_test = false;

@@ -600,8 +602,9 @@ static int dp_display_usbpd_configure_cb(struct device *dev)

	dp_display_host_init(dp);

	if (dp->usbpd->hpd_high)
		queue_work(dp->wq, &dp->connect_work);
	/* check for hpd high and framework ready */
	if  (dp->usbpd->hpd_high && dp_display_framework_ready(dp))
		queue_delayed_work(dp->wq, &dp->connect_work, 0);
end:
	return rc;
}
@@ -618,6 +621,8 @@ static void dp_display_clean(struct dp_display_private *dp)

	dp->ctrl->push_idle(dp->ctrl);
	dp->ctrl->off(dp->ctrl);
	dp->panel->deinit(dp->panel);
	dp->aux->deinit(dp->aux);
	dp->power_on = false;
}

@@ -657,6 +662,13 @@ static int dp_display_usbpd_disconnect_cb(struct device *dev)
		goto end;
	}

	/*
	 * In case cable/dongle is disconnected during adb shell stop,
	 * reset psm_enabled flag to false since it is no more needed
	 */
	if (dp->dp_display.post_open)
		dp->debug->psm_enabled = false;

	if (dp->debug->psm_enabled)
		dp->link->psm_config(dp->link, &dp->panel->link_info, true);

@@ -665,6 +677,7 @@ static int dp_display_usbpd_disconnect_cb(struct device *dev)
	dp->aux->abort(dp->aux);

	/* wait for idle state */
	cancel_delayed_work(&dp->connect_work);
	flush_workqueue(dp->wq);

	dp_display_handle_disconnect(dp);
@@ -676,13 +689,13 @@ static void dp_display_handle_maintenance_req(struct dp_display_private *dp)
{
	mutex_lock(&dp->audio->ops_lock);

	if (dp->audio_supported)
	if (dp->audio_supported && !IS_ERR_VALUE(dp->audio_status))
		dp->audio->off(dp->audio);

	dp->ctrl->link_maintenance(dp->ctrl);

	if (dp->audio_supported)
		dp->audio->on(dp->audio);
	if (dp->audio_supported && !IS_ERR_VALUE(dp->audio_status))
		dp->audio_status = dp->audio->on(dp->audio);

	mutex_unlock(&dp->audio->ops_lock);
}
@@ -705,7 +718,7 @@ static void dp_display_attention_work(struct work_struct *work)
			return;
		}

		queue_work(dp->wq, &dp->connect_work);
		queue_delayed_work(dp->wq, &dp->connect_work, 0);
		return;
	}

@@ -751,17 +764,19 @@ static int dp_display_usbpd_attention_cb(struct device *dev)
		return -ENODEV;
	}

	if (dp->usbpd->hpd_irq && dp->usbpd->hpd_high) {
	if (dp->usbpd->hpd_irq && dp->usbpd->hpd_high &&
	    dp->power_on) {
		dp->link->process_request(dp->link);
		queue_work(dp->wq, &dp->attention_work);
	} else if (dp->usbpd->hpd_high) {
		queue_work(dp->wq, &dp->connect_work);
		queue_delayed_work(dp->wq, &dp->connect_work, 0);
	} else {
		/* cancel any pending request */
		dp->ctrl->abort(dp->ctrl);
		dp->aux->abort(dp->aux);

		/* wait for idle state */
		cancel_delayed_work(&dp->connect_work);
		flush_workqueue(dp->wq);

		dp_display_handle_disconnect(dp);
@@ -772,7 +787,8 @@ static int dp_display_usbpd_attention_cb(struct device *dev)

static void dp_display_connect_work(struct work_struct *work)
{
	struct dp_display_private *dp = container_of(work,
	struct delayed_work *dw = to_delayed_work(work);
	struct dp_display_private *dp = container_of(dw,
			struct dp_display_private, connect_work);

	if (dp->dp_display.is_connected) {
@@ -1068,7 +1084,7 @@ static int dp_display_post_enable(struct dp_display *dp_display)
	if (dp->audio_supported) {
		dp->audio->bw_code = dp->link->link_params.bw_code;
		dp->audio->lane_count = dp->link->link_params.lane_count;
		dp->audio->on(dp->audio);
		dp->audio_status = dp->audio->on(dp->audio);
	}

	dp_display_update_hdcp_info(dp);
@@ -1079,6 +1095,8 @@ static int dp_display_post_enable(struct dp_display *dp_display)
		dp->hdcp_status = HDCP_STATE_AUTHENTICATING;
		queue_delayed_work(dp->wq, &dp->hdcp_cb_work, HZ / 2);
	}

	dp->panel->setup_hdr(dp->panel, NULL);
end:
	/* clear framework event notifier */
	dp_display->post_open = NULL;
@@ -1114,6 +1132,14 @@ static int dp_display_pre_disable(struct dp_display *dp_display)
			dp->hdcp.ops->off(dp->hdcp.data);
	}

	if (dp->usbpd->hpd_high && dp->usbpd->alt_mode_cfg_done) {
		if (dp->audio_supported)
			dp->audio->off(dp->audio);

		dp->link->psm_config(dp->link, &dp->panel->link_info, true);
		dp->debug->psm_enabled = true;
	}

	dp->ctrl->push_idle(dp->ctrl);
end:
	mutex_unlock(&dp->session_lock);
@@ -1123,6 +1149,8 @@ static int dp_display_pre_disable(struct dp_display *dp_display)
static int dp_display_disable(struct dp_display *dp_display)
{
	struct dp_display_private *dp;
	struct drm_connector *connector;
	struct sde_connector_state *c_state;

	if (!dp_display) {
		pr_err("invalid input\n");
@@ -1130,6 +1158,8 @@ static int dp_display_disable(struct dp_display *dp_display)
	}

	dp = container_of(dp_display, struct dp_display_private, dp_display);
	connector = dp->dp_display.connector;
	c_state = to_sde_connector_state(connector->state);

	mutex_lock(&dp->session_lock);

@@ -1140,7 +1170,25 @@ static int dp_display_disable(struct dp_display *dp_display)

	dp->ctrl->off(dp->ctrl);
	dp->panel->deinit(dp->panel);
	dp->aux->deinit(dp->aux);

	connector->hdr_eotf = 0;
	connector->hdr_metadata_type_one = 0;
	connector->hdr_max_luminance = 0;
	connector->hdr_avg_luminance = 0;
	connector->hdr_min_luminance = 0;

	memset(&c_state->hdr_meta, 0, sizeof(c_state->hdr_meta));

	/*
	 * In case of framework reboot, the DP off sequence is executed without
	 * any notification from driver. Initialize post_open callback to notify
	 * DP connection once framework restarts.
	 */
	if (dp->usbpd->hpd_high && dp->usbpd->alt_mode_cfg_done) {
		dp_display->post_open = dp_display_post_open;
		dp->dp_display.is_connected = false;
	}
	dp->power_on = false;

end:
@@ -1250,8 +1298,7 @@ static int dp_display_get_modes(struct dp_display *dp,
	return ret;
}


static int dp_display_pre_kickoff(struct dp_display *dp_display,
static int dp_display_config_hdr(struct dp_display *dp_display,
			struct drm_msm_ext_hdr_metadata *hdr)
{
	int rc = 0;
@@ -1264,7 +1311,6 @@ static int dp_display_pre_kickoff(struct dp_display *dp_display,

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

	if (hdr->hdr_supported && dp->panel->hdr_supported(dp->panel))
	rc = dp->panel->setup_hdr(dp->panel, hdr);

	return rc;
@@ -1279,7 +1325,7 @@ static int dp_display_create_workqueue(struct dp_display_private *dp)
	}

	INIT_DELAYED_WORK(&dp->hdcp_cb_work, dp_display_hdcp_cb_work);
	INIT_WORK(&dp->connect_work, dp_display_connect_work);
	INIT_DELAYED_WORK(&dp->connect_work, dp_display_connect_work);
	INIT_WORK(&dp->attention_work, dp_display_attention_work);

	return 0;
@@ -1306,6 +1352,7 @@ static int dp_display_probe(struct platform_device *pdev)

	dp->pdev = pdev;
	dp->name = "drm_dp";
	dp->audio_status = -ENODEV;

	rc = dp_display_create_workqueue(dp);
	if (rc) {
@@ -1330,7 +1377,7 @@ static int dp_display_probe(struct platform_device *pdev)
	g_dp_display->get_debug     = dp_get_debug;
	g_dp_display->post_open     = dp_display_post_open;
	g_dp_display->post_init     = dp_display_post_init;
	g_dp_display->pre_kickoff   = dp_display_pre_kickoff;
	g_dp_display->config_hdr    = dp_display_config_hdr;

	rc = component_add(&pdev->dev, &dp_display_comp_ops);
	if (rc) {
+2 −2
Original line number Diff line number Diff line
/*
 * Copyright (c) 2017, The Linux Foundation. All rights reserved.
 * Copyright (c) 2017-2018, The Linux Foundation. All rights reserved.
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License version 2 and
@@ -43,7 +43,7 @@ struct dp_display {
	int (*request_irq)(struct dp_display *dp_display);
	struct dp_debug *(*get_debug)(struct dp_display *dp_display);
	void (*post_open)(struct dp_display *dp_display);
	int (*pre_kickoff)(struct dp_display *dp_display,
	int (*config_hdr)(struct dp_display *dp_display,
				struct drm_msm_ext_hdr_metadata *hdr_meta);
	void (*post_init)(struct dp_display *dp_display);
};
Loading