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

Commit f00ab632 authored by Tatenda Chipeperekwa's avatar Tatenda Chipeperekwa
Browse files

drm/msm/hdcp: send type on minimum encryption level change



Send the updated content stream type to the HDCP receiver
when the minimum encryption level changes as this will
enable the receiver to correctly decode and decrypt the
stream.

CRs-Fixed: 2340074
Change-Id: I205f61b2ef30caff947c8b4d37e0f71e05f6da4a
Signed-off-by: default avatarTatenda Chipeperekwa <tatendac@codeaurora.org>
parent afd3c658
Loading
Loading
Loading
Loading
+7 −3
Original line number Diff line number Diff line
@@ -314,20 +314,24 @@ static int dp_hdcp2p2_reauthenticate(void *input)
}

static void dp_hdcp2p2_min_level_change(void *client_ctx,
		int min_enc_level)
		u8 min_enc_level)
{
	struct dp_hdcp2p2_ctrl *ctrl = (struct dp_hdcp2p2_ctrl *)client_ctx;
	struct sde_hdcp_2x_wakeup_data cdata = {
		HDCP_2X_CMD_QUERY_STREAM_TYPE};
		HDCP_2X_CMD_MIN_ENC_LEVEL};

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

	pr_debug("enc level changed %d\n", min_enc_level);
	if (!dp_hdcp2p2_is_valid_state(ctrl)) {
		pr_err("invalid state\n");
		return;
	}

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

+72 −1
Original line number Diff line number Diff line
@@ -73,6 +73,7 @@ struct sde_hdcp_2x_ctrl {
	int last_msg;
	atomic_t hdcp_off;
	enum sde_hdcp_2x_device_type device_type;
	u8 min_enc_level;

	struct task_struct *thread;
	struct completion response_completion;
@@ -85,6 +86,7 @@ struct sde_hdcp_2x_ctrl {
	struct kthread_work wk_clean;
	struct kthread_work wk_stream;
	struct kthread_work wk_wait;
	struct kthread_work wk_send_type;
};

static const char *sde_hdcp_2x_message_name(int msg_id)
@@ -230,6 +232,8 @@ static int sde_hdcp_2x_get_next_message(struct sde_hdcp_2x_ctrl *hdcp,
		if (!hdcp->repeater_flag)
			return SKE_SEND_TYPE_ID;
	case SKE_SEND_TYPE_ID:
		if (!hdcp->repeater_flag)
			return SKE_SEND_TYPE_ID;
	case REP_STREAM_READY:
	case REP_SEND_ACK:
		if (!hdcp->repeater_flag)
@@ -397,6 +401,61 @@ static void sde_hdcp_2x_cleanup_work(struct kthread_work *work)
	sde_hdcp_2x_clean(hdcp);
}

static u8 sde_hdcp_2x_stream_type(u8 min_enc_level)
{
	u8 stream_type = 0;
	u8 const hdcp_min_enc_level_0 = 0, hdcp_min_enc_level_1 = 1,
	   hdcp_min_enc_level_2 = 2;
	u8 const stream_type_0 = 0, stream_type_1 = 1;

	switch (min_enc_level) {
	case hdcp_min_enc_level_0:
	case hdcp_min_enc_level_1:
		stream_type = stream_type_0;
		break;
	case hdcp_min_enc_level_2:
		stream_type = stream_type_1;
		break;
	default:
		stream_type = stream_type_0;
		break;
	}

	pr_debug("min_enc_level = %u, type = %u", min_enc_level, stream_type);

	return stream_type;
}

static void sde_hdcp_2x_send_type(struct sde_hdcp_2x_ctrl *hdcp)
{
	if (atomic_read(&hdcp->hdcp_off)) {
		pr_debug("invalid state, hdcp off\n");
		return;
	}

	if (hdcp->repeater_flag) {
		pr_debug("invalid state, not receiver\n");
		return;
	}

	hdcp->app_data.response.data[0] = SKE_SEND_TYPE_ID;
	hdcp->app_data.response.data[1] =
		sde_hdcp_2x_stream_type(hdcp->min_enc_level);
	hdcp->app_data.response.length = 1;
	hdcp->app_data.timeout = 100;

	if (!atomic_read(&hdcp->hdcp_off))
		sde_hdcp_2x_send_message(hdcp);
}

static void sde_hdcp_2x_send_type_work(struct kthread_work *work)
{
	struct sde_hdcp_2x_ctrl *hdcp =
		container_of(work, struct sde_hdcp_2x_ctrl, wk_send_type);

	sde_hdcp_2x_send_type(hdcp);
}

static void sde_hdcp_2x_stream(struct sde_hdcp_2x_ctrl *hdcp)
{
	int rc = 0;
@@ -476,7 +535,9 @@ static void sde_hdcp_2x_msg_sent(struct sde_hdcp_2x_ctrl *hdcp)
					HDCP_TRANSPORT_CMD_LINK_POLL, &cdata);
		} else {
			hdcp->app_data.response.data[0] = SKE_SEND_TYPE_ID;
			hdcp->app_data.response.length = 2;
			hdcp->app_data.response.data[1] =
				sde_hdcp_2x_stream_type(hdcp->min_enc_level);
			hdcp->app_data.response.length = 1;
			hdcp->app_data.timeout = 100;

			sde_hdcp_2x_send_message(hdcp);
@@ -795,6 +856,15 @@ static int sde_hdcp_2x_wakeup(struct sde_hdcp_2x_wakeup_data *data)
		HDCP_2X_EXECUTE(timeout);
		break;
	case HDCP_2X_CMD_QUERY_STREAM_TYPE:
		HDCP_2X_EXECUTE(stream);
		break;
	case HDCP_2X_CMD_MIN_ENC_LEVEL:
		hdcp->min_enc_level = data->min_enc_level;
		if (!hdcp->repeater_flag) {
			HDCP_2X_EXECUTE(send_type);
			break;
		}

		HDCP_2X_EXECUTE(stream);
		break;
	default:
@@ -861,6 +931,7 @@ int sde_hdcp_2x_register(struct sde_hdcp_2x_register_data *data)
	kthread_init_work(&hdcp->wk_clean,     sde_hdcp_2x_cleanup_work);
	kthread_init_work(&hdcp->wk_stream,    sde_hdcp_2x_query_stream_work);
	kthread_init_work(&hdcp->wk_wait, sde_hdcp_2x_wait_for_response_work);
	kthread_init_work(&hdcp->wk_send_type,    sde_hdcp_2x_send_type_work);

	init_completion(&hdcp->response_completion);

+3 −0
Original line number Diff line number Diff line
@@ -32,6 +32,7 @@
 * @HDCP_2X_CMD_MSG_RECV_TIMEOUT:  receiving message from sink timed out
 * @HDCP_2X_CMD_QUERY_STREAM_TYPE: start content stream processing
 * @HDCP_2X_CMD_LINK_FAILED:       link failure notification
 * @HDCP_2X_CMD_MIN_ENC_LEVEL:     trigger minimum encryption level change
 */
enum sde_hdcp_2x_wakeup_cmd {
	HDCP_2X_CMD_INVALID,
@@ -45,6 +46,7 @@ enum sde_hdcp_2x_wakeup_cmd {
	HDCP_2X_CMD_MSG_RECV_TIMEOUT,
	HDCP_2X_CMD_QUERY_STREAM_TYPE,
	HDCP_2X_CMD_LINK_FAILED,
	HDCP_2X_CMD_MIN_ENC_LEVEL,
};

/**
@@ -85,6 +87,7 @@ struct sde_hdcp_2x_wakeup_data {
	void *context;
	uint32_t total_message_length;
	uint32_t timeout;
	u8 min_enc_level;
};

/**
+3 −3
Original line number Diff line number Diff line
@@ -38,11 +38,11 @@ struct msm_hdcp {
	struct HDCP_V2V1_MSG_TOPOLOGY cached_tp;
	u32 tp_msgid;
	void *client_ctx;
	void (*cb)(void *ctx, int data);
	void (*cb)(void *ctx, u8 data);
};

void msm_hdcp_register_cb(struct device *dev, void *ctx,
		void (*cb)(void *ctx, int data))
		void (*cb)(void *ctx, u8 data))
{
	struct msm_hdcp *hdcp = NULL;

@@ -278,7 +278,7 @@ static int msm_hdcp_probe(struct platform_device *pdev)
	}

	hdcp->device = device_create(hdcp->class, NULL,
		hdcp->dev_num, NULL, DRIVER_NAME);
		hdcp->dev_num, hdcp, DRIVER_NAME);
	if (IS_ERR(hdcp->device)) {
		ret = PTR_ERR(hdcp->device);
		pr_err("device_create failed %d\n", ret);
+1 −1
Original line number Diff line number Diff line
@@ -19,7 +19,7 @@ void msm_hdcp_notify_topology(struct device *dev);
void msm_hdcp_cache_repeater_topology(struct device *dev,
			struct HDCP_V2V1_MSG_TOPOLOGY *tp);
void msm_hdcp_register_cb(struct device *dev, void *ctx,
	void (*cb)(void *ctx, int data));
	void (*cb)(void *ctx, u8 data));

#endif /* __MSM_HDCP_H */