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

Commit 6f1a18e6 authored by Abhinav Kumar's avatar Abhinav Kumar Committed by Gerrit - the friendly Code Review server
Browse files

drm/msm: configure AV mute before disabling encryption



In current implementation, AV mute packet is sent after
disabling the encryption. This can cause artifacts on the
sink when re-authentication is going on.

Send the AV mute packet to the sink before disabling
encryption so that no visual artifacts are observed
during re-authentication.

Change-Id: Ifbe656691b3750a76fbd48a776ba660ebbe5f65a
Signed-off-by: default avatarAbhinav Kumar <abhinavk@codeaurora.org>
parent 32ce34e9
Loading
Loading
Loading
Loading
+18 −5
Original line number Diff line number Diff line
@@ -591,6 +591,22 @@ static void sde_hdmi_tx_hdcp_cb(void *ptr, enum sde_hdcp_states status)
	queue_delayed_work(hdmi->workq, &hdmi_ctrl->hdcp_cb_work, HZ/4);
}

static void sde_hdmi_tx_set_avmute(void *ptr)
{
	struct sde_hdmi *hdmi_ctrl = (struct sde_hdmi *)ptr;
	struct hdmi *hdmi;

	if (!hdmi_ctrl) {
		DEV_ERR("%s: invalid input\n", __func__);
		return;
	}

	pr_err("setting avmute to true\n");

	hdmi = hdmi_ctrl->ctrl.ctrl;
	sde_hdmi_config_avmute(hdmi, true);
}

void sde_hdmi_hdcp_off(struct sde_hdmi *hdmi_ctrl)
{

@@ -645,10 +661,6 @@ static void sde_hdmi_tx_hdcp_cb_work(struct work_struct *work)

		hdmi_ctrl->auth_state = false;

		if (sde_hdmi_tx_is_encryption_set(hdmi_ctrl) ||
			!sde_hdmi_tx_is_stream_shareable(hdmi_ctrl))
			rc = sde_hdmi_config_avmute(hdmi, true);

		if (sde_hdmi_tx_is_panel_on(hdmi_ctrl)) {
			pr_debug("%s: Reauthenticating\n", __func__);
			if (hdmi_ctrl->hdcp_ops && hdmi_ctrl->hdcp_data) {
@@ -2397,6 +2409,7 @@ static int _sde_hdmi_init_hdcp(struct sde_hdmi *hdmi_ctrl)
	hdcp_init_data.mutex         = &hdmi_ctrl->hdcp_mutex;
	hdcp_init_data.workq         = hdmi->workq;
	hdcp_init_data.notify_status = sde_hdmi_tx_hdcp_cb;
	hdcp_init_data.avmute_sink   = sde_hdmi_tx_set_avmute;
	hdcp_init_data.cb_data       = (void *)hdmi_ctrl;
	hdcp_init_data.hdmi_tx_ver   = hdmi_ctrl->hdmi_tx_major_version;
	hdcp_init_data.sec_access    = true;
+20 −3
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
@@ -321,11 +321,27 @@ int min_enc_lvl)

	SDE_HDCP_DEBUG("enc level changed %d\n", min_enc_lvl);

	/* notify the client first about the new level */
	if (enc_notify && ctrl->init_data.notify_status)
		ctrl->init_data.notify_status(ctrl->init_data.cb_data, enc_lvl);

	cdata.context = ctrl->lib_ctx;
	sde_hdmi_hdcp2p2_wakeup_lib(ctrl, &cdata);
}

	if (enc_notify && ctrl->init_data.notify_status)
		ctrl->init_data.notify_status(ctrl->init_data.cb_data, enc_lvl);
static void sde_hdmi_hdcp2p2_mute_sink(void *client_ctx)
{
	struct sde_hdmi_hdcp2p2_ctrl *ctrl =
		(struct sde_hdmi_hdcp2p2_ctrl *)client_ctx;

	if (!ctrl) {
		SDE_ERROR("invalid input\n");
		return;
	}

	/* call into client to send avmute to the sink */
	if (ctrl->init_data.avmute_sink)
		ctrl->init_data.avmute_sink(ctrl->init_data.cb_data);
}

static void sde_hdmi_hdcp2p2_auth_failed(struct sde_hdmi_hdcp2p2_ctrl *ctrl)
@@ -930,6 +946,7 @@ void *sde_hdmi_hdcp2p2_init(struct sde_hdcp_init_data *init_data)
		.wakeup = sde_hdmi_hdcp2p2_wakeup,
		.notify_lvl_change = sde_hdmi_hdcp2p2_min_level_change,
		.srm_cb = sde_hdmi_hdcp2p2_srm_cb,
		.mute_sink = sde_hdmi_hdcp2p2_mute_sink,
	};

	static struct hdcp_txmtr_ops txmtr_ops;
+2 −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
@@ -59,6 +59,7 @@ struct sde_hdcp_init_data {
	struct workqueue_struct *workq;
	void *cb_data;
	void (*notify_status)(void *cb_data, enum sde_hdcp_states status);
	void (*avmute_sink)(void *cb_data);
	struct sde_hdmi_tx_ddc_ctrl *ddc_ctrl;
	u8 sink_rx_status;
	u16 *version;
+6 −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
@@ -1359,6 +1359,9 @@ static void sde_hdcp_1x_notify_topology(void)

static void sde_hdcp_1x_update_auth_status(struct sde_hdcp_1x *hdcp)
{
	if (sde_hdcp_1x_state(HDCP_STATE_AUTH_FAIL))
		hdcp->init_data.avmute_sink(hdcp->init_data.cb_data);

	if (sde_hdcp_1x_state(HDCP_STATE_AUTHENTICATED)) {
		sde_hdcp_1x_cache_topology(hdcp);
		sde_hdcp_1x_notify_topology();
@@ -1853,7 +1856,8 @@ void *sde_hdcp_1x_init(struct sde_hdcp_init_data *init_data)

	if (!init_data || !init_data->core_io || !init_data->qfprom_io ||
		!init_data->mutex || !init_data->notify_status ||
		!init_data->workq || !init_data->cb_data) {
		!init_data->workq || !init_data->cb_data ||
		!init_data->avmute_sink) {
		pr_err("invalid input\n");
		goto error;
	}
+4 −1
Original line number Diff line number Diff line
/* Copyright (c) 2015-2017, The Linux Foundation. All rights reserved.
/* Copyright (c) 2015-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
@@ -2078,6 +2078,9 @@ static void hdcp_lib_clean(struct hdcp_lib_handle *handle)

	handle->authenticated = false;

	/* AV mute the sink first to avoid artifacts */
	handle->client_ops->mute_sink(handle->client_ctx);

	hdcp_lib_txmtr_deinit(handle);
	if (!handle->legacy_app)
		hdcp_lib_session_deinit(handle);
Loading