/* Copyright (c) 2010-2016, 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
 * only version 2 as published by the Free Software Foundation.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 */

#include <linux/io.h>
#include <linux/types.h>
#include <linux/delay.h>
#include <linux/slab.h>
#include <linux/stat.h>
#include <soc/qcom/scm.h>
#include <linux/hdcp_qseecom.h>
#include "mdss_hdmi_hdcp.h"
#include "video/msm_hdmi_hdcp_mgr.h"

#define HDCP_STATE_NAME (hdcp_state_name(hdcp_ctrl->hdcp_state))

/* HDCP Keys state based on HDMI_HDCP_LINK0_STATUS:KEYS_STATE */
#define HDCP_KEYS_STATE_NO_KEYS		0
#define HDCP_KEYS_STATE_NOT_CHECKED	1
#define HDCP_KEYS_STATE_CHECKING	2
#define HDCP_KEYS_STATE_VALID		3
#define HDCP_KEYS_STATE_AKSV_NOT_VALID	4
#define HDCP_KEYS_STATE_CHKSUM_MISMATCH	5
#define HDCP_KEYS_STATE_PROD_AKSV	6
#define HDCP_KEYS_STATE_RESERVED	7

#define TZ_HDCP_CMD_ID 0x00004401
#define HDCP_REG_ENABLE 0x01
#define HDCP_REG_DISABLE 0x00

#define HDCP_INT_CLR (BIT(1) | BIT(5) | BIT(7) | BIT(9) | BIT(13))

struct hdmi_hdcp_reg_data {
	u32 reg_id;
	u32 off;
	char *name;
	u32 reg_val;
};

struct hdmi_hdcp_ctrl {
	u32 auth_retries;
	u32 tp_msgid;
	u32 tz_hdcp;
	enum hdmi_hdcp_state hdcp_state;
	struct HDCP_V2V1_MSG_TOPOLOGY cached_tp;
	struct HDCP_V2V1_MSG_TOPOLOGY current_tp;
	struct delayed_work hdcp_auth_work;
	struct work_struct hdcp_int_work;
	struct completion r0_checked;
	struct hdmi_hdcp_init_data init_data;
	struct hdmi_hdcp_ops *ops;
	bool hdmi_tx_ver_4;
};

const char *hdcp_state_name(enum hdmi_hdcp_state hdcp_state)
{
	switch (hdcp_state) {
	case HDCP_STATE_INACTIVE:	return "HDCP_STATE_INACTIVE";
	case HDCP_STATE_AUTHENTICATING:	return "HDCP_STATE_AUTHENTICATING";
	case HDCP_STATE_AUTHENTICATED:	return "HDCP_STATE_AUTHENTICATED";
	case HDCP_STATE_AUTH_FAIL:	return "HDCP_STATE_AUTH_FAIL";
	default:			return "???";
	}
} /* hdcp_state_name */

static int hdmi_hdcp_count_one(u8 *array, u8 len)
{
	int i, j, count = 0;

	for (i = 0; i < len; i++)
		for (j = 0; j < 8; j++)
			count += (((array[i] >> j) & 0x1) ? 1 : 0);
	return count;
} /* hdmi_hdcp_count_one */

static void reset_hdcp_ddc_failures(struct hdmi_hdcp_ctrl *hdcp_ctrl)
{
	int hdcp_ddc_ctrl1_reg;
	int hdcp_ddc_status;
	int failure;
	int nack0;
	struct dss_io_data *io;

	if (!hdcp_ctrl || !hdcp_ctrl->init_data.core_io) {
		DEV_ERR("%s: invalid input\n", __func__);
		return;
	}

	io = hdcp_ctrl->init_data.core_io;

	/* Check for any DDC transfer failures */
	hdcp_ddc_status = DSS_REG_R(io, HDMI_HDCP_DDC_STATUS);
	failure = (hdcp_ddc_status >> 16) & 0x1;
	nack0 = (hdcp_ddc_status >> 14) & 0x1;
	DEV_DBG("%s: %s: On Entry: HDCP_DDC_STATUS=0x%x, FAIL=%d, NACK0=%d\n",
		__func__, HDCP_STATE_NAME, hdcp_ddc_status, failure, nack0);

	if (failure == 0x1) {
		/*
		 * Indicates that the last HDCP HW DDC transfer failed.
		 * This occurs when a transfer is attempted with HDCP DDC
		 * disabled (HDCP_DDC_DISABLE=1) or the number of retries
		 * matches HDCP_DDC_RETRY_CNT.
		 * Failure occurred,  let's clear it.
		 */
		DEV_DBG("%s: %s: DDC failure detected.HDCP_DDC_STATUS=0x%08x\n",
			 __func__, HDCP_STATE_NAME, hdcp_ddc_status);

		/* First, Disable DDC */
		DSS_REG_W(io, HDMI_HDCP_DDC_CTRL_0, BIT(0));

		/* ACK the Failure to Clear it */
		hdcp_ddc_ctrl1_reg = DSS_REG_R(io, HDMI_HDCP_DDC_CTRL_1);
		DSS_REG_W(io, HDMI_HDCP_DDC_CTRL_1,
			hdcp_ddc_ctrl1_reg | BIT(0));

		/* Check if the FAILURE got Cleared */
		hdcp_ddc_status = DSS_REG_R(io, HDMI_HDCP_DDC_STATUS);
		hdcp_ddc_status = (hdcp_ddc_status >> 16) & BIT(0);
		if (hdcp_ddc_status == 0x0)
			DEV_DBG("%s: %s: HDCP DDC Failure cleared\n", __func__,
				HDCP_STATE_NAME);
		else
			DEV_WARN("%s: %s: Unable to clear HDCP DDC Failure",
				__func__, HDCP_STATE_NAME);

		/* Re-Enable HDCP DDC */
		DSS_REG_W(io, HDMI_HDCP_DDC_CTRL_0, 0);
	}

	if (nack0 == 0x1) {
		DEV_DBG("%s: %s: Before: HDMI_DDC_SW_STATUS=0x%08x\n", __func__,
			HDCP_STATE_NAME, DSS_REG_R(io, HDMI_DDC_SW_STATUS));
		/* Reset HDMI DDC software status */
		DSS_REG_W_ND(io, HDMI_DDC_CTRL,
			DSS_REG_R(io, HDMI_DDC_CTRL) | BIT(3));
		msleep(20);
		DSS_REG_W_ND(io, HDMI_DDC_CTRL,
			DSS_REG_R(io, HDMI_DDC_CTRL) & ~(BIT(3)));

		/* Reset HDMI DDC Controller */
		DSS_REG_W_ND(io, HDMI_DDC_CTRL,
			DSS_REG_R(io, HDMI_DDC_CTRL) | BIT(1));
		msleep(20);
		DSS_REG_W_ND(io, HDMI_DDC_CTRL,
			DSS_REG_R(io, HDMI_DDC_CTRL) & ~BIT(1));
		DEV_DBG("%s: %s: After: HDMI_DDC_SW_STATUS=0x%08x\n", __func__,
			HDCP_STATE_NAME, DSS_REG_R(io, HDMI_DDC_SW_STATUS));
	}

	hdcp_ddc_status = DSS_REG_R(io, HDMI_HDCP_DDC_STATUS);

	failure = (hdcp_ddc_status >> 16) & BIT(0);
	nack0 = (hdcp_ddc_status >> 14) & BIT(0);
	DEV_DBG("%s: %s: On Exit: HDCP_DDC_STATUS=0x%x, FAIL=%d, NACK0=%d\n",
		__func__, HDCP_STATE_NAME, hdcp_ddc_status, failure, nack0);
} /* reset_hdcp_ddc_failures */

static void hdmi_hdcp_hw_ddc_clean(struct hdmi_hdcp_ctrl *hdcp_ctrl)
{
	struct dss_io_data *io = NULL;
	u32 hdcp_ddc_status, ddc_hw_status;
	u32 ddc_xfer_done, ddc_xfer_req;
	u32 ddc_hw_req, ddc_hw_not_idle;
	bool ddc_hw_not_ready, xfer_not_done, hw_not_done;
	u32 timeout_count;

	if (!hdcp_ctrl || !hdcp_ctrl->init_data.core_io) {
		DEV_ERR("%s: invalid input\n", __func__);
		return;
	}

	io = hdcp_ctrl->init_data.core_io;
	if (!io->base) {
		DEV_ERR("%s: core io not inititalized\n", __func__);
		return;
	}

	/* Wait to be clean on DDC HW engine */
	timeout_count = 100;
	do {
		hdcp_ddc_status = DSS_REG_R(io, HDMI_HDCP_DDC_STATUS);
		ddc_xfer_req    = hdcp_ddc_status & BIT(4);
		ddc_xfer_done   = hdcp_ddc_status & BIT(10);

		ddc_hw_status   = DSS_REG_R(io, HDMI_DDC_HW_STATUS);
		ddc_hw_req      = ddc_hw_status & BIT(16);
		ddc_hw_not_idle = ddc_hw_status & (BIT(0) | BIT(1));

		/* ddc transfer was requested but not completed */
		xfer_not_done = ddc_xfer_req && !ddc_xfer_done;

		/* ddc status is not idle or a hw request pending */
		hw_not_done = ddc_hw_not_idle || ddc_hw_req;

		ddc_hw_not_ready = xfer_not_done || hw_not_done;

		DEV_DBG("%s: %s: timeout count(%d): ddc hw%sready\n",
			__func__, HDCP_STATE_NAME, timeout_count,
				ddc_hw_not_ready ? " not " : " ");
		DEV_DBG("hdcp_ddc_status[0x%x], ddc_hw_status[0x%x]\n",
				hdcp_ddc_status, ddc_hw_status);
		if (ddc_hw_not_ready)
			msleep(20);
		} while (ddc_hw_not_ready && --timeout_count);
} /* hdmi_hdcp_hw_ddc_clean */

static int hdcp_scm_call(struct scm_hdcp_req *req, u32 *resp)
{
	int ret = 0;

	if (!is_scm_armv8()) {
		ret = scm_call(SCM_SVC_HDCP, SCM_CMD_HDCP, (void *) req,
			     SCM_HDCP_MAX_REG * sizeof(struct scm_hdcp_req),
			     &resp, sizeof(*resp));
	} else {
		struct scm_desc desc;

		desc.args[0] = req[0].addr;
		desc.args[1] = req[0].val;
		desc.args[2] = req[1].addr;
		desc.args[3] = req[1].val;
		desc.args[4] = req[2].addr;
		desc.args[5] = req[2].val;
		desc.args[6] = req[3].addr;
		desc.args[7] = req[3].val;
		desc.args[8] = req[4].addr;
		desc.args[9] = req[4].val;
		desc.arginfo = SCM_ARGS(10);

		ret = scm_call2(SCM_SIP_FNID(SCM_SVC_HDCP, SCM_CMD_HDCP),
				&desc);
		*resp = desc.ret[0];
		if (ret)
			return ret;
	}

	return ret;
}

static int hdmi_hdcp_load_keys(void *input)
{
	int rc = 0;
	bool use_sw_keys = false;
	u32 reg_val;
	u32 ksv_lsb_addr, ksv_msb_addr;
	u32 aksv_lsb, aksv_msb;
	u8 aksv[5];
	struct dss_io_data *io;
	struct dss_io_data *qfprom_io;
	struct hdmi_hdcp_ctrl *hdcp_ctrl = input;

	if (!hdcp_ctrl || !hdcp_ctrl->init_data.core_io ||
		!hdcp_ctrl->init_data.qfprom_io) {
		DEV_ERR("%s: invalid input\n", __func__);
		rc = -EINVAL;
		goto end;
	}

	if ((hdcp_ctrl->hdcp_state != HDCP_STATE_INACTIVE) &&
		(hdcp_ctrl->hdcp_state != HDCP_STATE_AUTH_FAIL)) {
		DEV_ERR("%s: %s: invalid state. returning\n", __func__,
			HDCP_STATE_NAME);
		rc = -EINVAL;
		goto end;
	}

	io = hdcp_ctrl->init_data.core_io;
	qfprom_io = hdcp_ctrl->init_data.qfprom_io;

	/* On compatible hardware, use SW keys */
	reg_val = DSS_REG_R(qfprom_io, SEC_CTRL_HW_VERSION);
	if (reg_val >= HDCP_SEL_MIN_SEC_VERSION) {
		reg_val = DSS_REG_R(qfprom_io,
			QFPROM_RAW_FEAT_CONFIG_ROW0_MSB +
			QFPROM_RAW_VERSION_4);

		if (!(reg_val & BIT(23)))
			use_sw_keys = true;
	}

	if (use_sw_keys) {
		if (hdcp1_set_keys(&aksv_msb, &aksv_lsb)) {
			pr_err("%s: setting hdcp SW keys failed\n", __func__);
			rc = -EINVAL;
			goto end;
		}
	} else {
		/* Fetch aksv from QFPROM, this info should be public. */
		ksv_lsb_addr = HDCP_KSV_LSB;
		ksv_msb_addr = HDCP_KSV_MSB;

		if (hdcp_ctrl->hdmi_tx_ver_4) {
			ksv_lsb_addr += HDCP_KSV_VERSION_4_OFFSET;
			ksv_msb_addr += HDCP_KSV_VERSION_4_OFFSET;
		}

		aksv_lsb = DSS_REG_R(qfprom_io, ksv_lsb_addr);
		aksv_msb = DSS_REG_R(qfprom_io, ksv_msb_addr);
	}

	DEV_DBG("%s: %s: AKSV=%02x%08x\n", __func__, HDCP_STATE_NAME,
		aksv_msb, aksv_lsb);

	aksv[0] =  aksv_lsb        & 0xFF;
	aksv[1] = (aksv_lsb >> 8)  & 0xFF;
	aksv[2] = (aksv_lsb >> 16) & 0xFF;
	aksv[3] = (aksv_lsb >> 24) & 0xFF;
	aksv[4] =  aksv_msb        & 0xFF;

	/* check there are 20 ones in AKSV */
	if (hdmi_hdcp_count_one(aksv, 5) != 20) {
		DEV_ERR("%s: AKSV bit count failed\n", __func__);
		rc = -EINVAL;
		goto end;
	}

	DSS_REG_W(io, HDMI_HDCP_SW_LOWER_AKSV, aksv_lsb);
	DSS_REG_W(io, HDMI_HDCP_SW_UPPER_AKSV, aksv_msb);

	/* Setup seed values for random number An */
	DSS_REG_W(io, HDMI_HDCP_ENTROPY_CTRL0, 0xB1FFB0FF);
	DSS_REG_W(io, HDMI_HDCP_ENTROPY_CTRL1, 0xF00DFACE);

	/* Disable the RngCipher state */
	DSS_REG_W(io, HDMI_HDCP_DEBUG_CTRL,
		DSS_REG_R(io, HDMI_HDCP_DEBUG_CTRL) & ~(BIT(2)));

	/* make sure hw is programmed */
	wmb();

	DSS_REG_W(io, HDMI_HDCP_CTRL, BIT(0));

	hdcp_ctrl->hdcp_state = HDCP_STATE_AUTHENTICATING;
end:
	return rc;
}

static int hdmi_hdcp_authentication_part1(struct hdmi_hdcp_ctrl *hdcp_ctrl)
{
	int rc;
	u32 link0_aksv_0, link0_aksv_1;
	u32 link0_bksv_0, link0_bksv_1;
	u32 link0_an_0, link0_an_1;
	u32 timeout_count;
	bool is_match;
	struct dss_io_data *io;
	struct dss_io_data *hdcp_io;
	u8 aksv[5], *bksv = NULL;
	u8 an[8];
	u8 bcaps = 0;
	struct hdmi_tx_ddc_data ddc_data;
	u32 link0_status = 0, an_ready, keys_state;
	u8 buf[0xFF];

	struct scm_hdcp_req scm_buf[SCM_HDCP_MAX_REG];
	u32 phy_addr;
	u32 ret  = 0;
	u32 resp = 0;

	if (!hdcp_ctrl || !hdcp_ctrl->init_data.core_io ||
		!hdcp_ctrl->init_data.qfprom_io) {
		DEV_ERR("%s: invalid input\n", __func__);
		rc = -EINVAL;
		goto error;
	}

	phy_addr = hdcp_ctrl->init_data.phy_addr;
	bksv = hdcp_ctrl->current_tp.bksv;
	io = hdcp_ctrl->init_data.core_io;
	hdcp_io = hdcp_ctrl->init_data.hdcp_io;

	if (hdcp_ctrl->hdcp_state != HDCP_STATE_AUTHENTICATING) {
		DEV_ERR("%s: %s: invalid state. returning\n", __func__,
			HDCP_STATE_NAME);
		rc = -EINVAL;
		goto error;
	}

	/* Clear any DDC failures from previous tries */
	reset_hdcp_ddc_failures(hdcp_ctrl);

	/*
	 * Read BCAPS
	 * We need to first try to read an HDCP register on the sink to see if
	 * the sink is ready for HDCP authentication
	 */
	memset(&ddc_data, 0, sizeof(ddc_data));
	ddc_data.dev_addr = 0x74;
	ddc_data.offset = 0x40;
	ddc_data.data_buf = &bcaps;
	ddc_data.data_len = 1;
	ddc_data.request_len = 1;
	ddc_data.retry = 5;
	ddc_data.what = "Bcaps";

	hdcp_ctrl->init_data.ddc_ctrl->ddc_data = ddc_data;

	rc = hdmi_ddc_read(hdcp_ctrl->init_data.ddc_ctrl);
	if (rc) {
		DEV_ERR("%s: %s: BCAPS read failed\n", __func__,
			HDCP_STATE_NAME);
		goto error;
	}
	DEV_DBG("%s: %s: BCAPS=%02x\n", __func__, HDCP_STATE_NAME, bcaps);

	/* receiver (0), repeater (1) */
	hdcp_ctrl->current_tp.ds_type =
		(bcaps & BIT(6)) >> 6 ? DS_REPEATER : DS_RECEIVER;

	/* Write BCAPS to the hardware */
	if (hdcp_ctrl->tz_hdcp) {
		memset(scm_buf, 0x00, sizeof(scm_buf));

		scm_buf[0].addr = phy_addr + HDMI_HDCP_RCVPORT_DATA12;
		scm_buf[0].val  = bcaps;

		ret = hdcp_scm_call(scm_buf, &resp);
		if (ret || resp) {
			DEV_ERR("%s: error: scm_call ret = %d, resp = %d\n",
				__func__, ret, resp);
			rc = -EINVAL;
			goto error;
		}
	} else if (hdcp_ctrl->hdmi_tx_ver_4) {
		DSS_REG_W(hdcp_io, HDCP_SEC_TZ_HV_HLOS_HDCP_RCVPORT_DATA12,
				bcaps);
	} else {
		DSS_REG_W(io, HDMI_HDCP_RCVPORT_DATA12, bcaps);
	}

	/* Wait for HDCP keys to be checked and validated */
	timeout_count = 100;
	keys_state = (link0_status >> 28) & 0x7;
	while ((keys_state != HDCP_KEYS_STATE_VALID) &&
		--timeout_count) {
		link0_status = DSS_REG_R(io, HDMI_HDCP_LINK0_STATUS);
		keys_state = (link0_status >> 28) & 0x7;
		DEV_DBG("%s: %s: Keys not ready(%d). s=%d\n, l0=%0x08x",
			__func__, HDCP_STATE_NAME, timeout_count,
			keys_state, link0_status);
		msleep(20);
	}

	if (!timeout_count) {
		DEV_ERR("%s: %s: Invalid Keys State: %d\n", __func__,
			HDCP_STATE_NAME, keys_state);
		rc = -EINVAL;
		goto error;
	}

	/*
	 * 1.1_Features turned off by default.
	 * No need to write AInfo since 1.1_Features is disabled.
	 */
	DSS_REG_W(io, HDMI_HDCP_RCVPORT_DATA4, 0);

	/* Wait for An0 and An1 bit to be ready */
	timeout_count = 100;
	do {
		link0_status = DSS_REG_R(io, HDMI_HDCP_LINK0_STATUS);
		an_ready = (link0_status & BIT(8)) && (link0_status & BIT(9));
		if (!an_ready) {
			DEV_DBG("%s: %s: An not ready(%d). l0_status=0x%08x\n",
				__func__, HDCP_STATE_NAME, timeout_count,
				link0_status);
			msleep(20);
		}
	} while (!an_ready && --timeout_count);

	if (!timeout_count) {
		rc = -ETIMEDOUT;
		DEV_ERR("%s: %s: timedout, An0=%ld, An1=%ld\n", __func__,
			HDCP_STATE_NAME, (link0_status & BIT(8)) >> 8,
			(link0_status & BIT(9)) >> 9);
		goto error;
	}

	/* As per hardware recommendations, wait before reading An */
	msleep(20);

	/* Read An0 and An1 */
	link0_an_0 = DSS_REG_R(io, HDMI_HDCP_RCVPORT_DATA5);
	link0_an_1 = DSS_REG_R(io, HDMI_HDCP_RCVPORT_DATA6);

	/* Read AKSV */
	link0_aksv_0 = DSS_REG_R(io, HDMI_HDCP_RCVPORT_DATA3);
	link0_aksv_1 = DSS_REG_R(io, HDMI_HDCP_RCVPORT_DATA4);

	/* Copy An and AKSV to byte arrays for transmission */
	aksv[0] =  link0_aksv_0        & 0xFF;
	aksv[1] = (link0_aksv_0 >> 8)  & 0xFF;
	aksv[2] = (link0_aksv_0 >> 16) & 0xFF;
	aksv[3] = (link0_aksv_0 >> 24) & 0xFF;
	aksv[4] =  link0_aksv_1        & 0xFF;

	an[0] =  link0_an_0        & 0xFF;
	an[1] = (link0_an_0 >> 8)  & 0xFF;
	an[2] = (link0_an_0 >> 16) & 0xFF;
	an[3] = (link0_an_0 >> 24) & 0xFF;
	an[4] =  link0_an_1        & 0xFF;
	an[5] = (link0_an_1 >> 8)  & 0xFF;
	an[6] = (link0_an_1 >> 16) & 0xFF;
	an[7] = (link0_an_1 >> 24) & 0xFF;

	/* Write An to offset 0x18 */
	memset(&ddc_data, 0, sizeof(ddc_data));
	ddc_data.dev_addr = 0x74;
	ddc_data.offset = 0x18;
	ddc_data.data_buf = an;
	ddc_data.data_len = 8;
	ddc_data.what = "An";
	hdcp_ctrl->init_data.ddc_ctrl->ddc_data = ddc_data;

	rc = hdmi_ddc_write(hdcp_ctrl->init_data.ddc_ctrl);
	if (rc) {
		DEV_ERR("%s: %s: An write failed\n", __func__, HDCP_STATE_NAME);
		goto error;
	}

	/* Write AKSV to offset 0x10 */
	memset(&ddc_data, 0, sizeof(ddc_data));
	ddc_data.dev_addr = 0x74;
	ddc_data.offset = 0x10;
	ddc_data.data_buf = aksv;
	ddc_data.data_len = 5;
	ddc_data.what = "Aksv";
	hdcp_ctrl->init_data.ddc_ctrl->ddc_data = ddc_data;

	rc = hdmi_ddc_write(hdcp_ctrl->init_data.ddc_ctrl);
	if (rc) {
		DEV_ERR("%s: %s: AKSV write failed\n", __func__,
			HDCP_STATE_NAME);
		goto error;
	}
	DEV_DBG("%s: %s: Link0-AKSV=%02x%08x\n", __func__,
		HDCP_STATE_NAME, link0_aksv_1 & 0xFF, link0_aksv_0);

	/* Read BKSV at offset 0x00 */
	memset(&ddc_data, 0, sizeof(ddc_data));
	ddc_data.dev_addr = 0x74;
	ddc_data.offset = 0x00;
	ddc_data.data_buf = bksv;
	ddc_data.data_len = 5;
	ddc_data.request_len = 5;
	ddc_data.retry = 5;
	ddc_data.what = "Bksv";

	hdcp_ctrl->init_data.ddc_ctrl->ddc_data = ddc_data;

	rc = hdmi_ddc_read(hdcp_ctrl->init_data.ddc_ctrl);
	if (rc) {
		DEV_ERR("%s: %s: BKSV read failed\n", __func__,
			HDCP_STATE_NAME);
		goto error;
	}

	/* check there are 20 ones in BKSV */
	if (hdmi_hdcp_count_one(bksv, 5) != 20) {
		DEV_ERR("%s: %s: BKSV doesn't have 20 1's and 20 0's\n",
			__func__, HDCP_STATE_NAME);
		DEV_ERR("%s: %s: BKSV chk fail. BKSV=%02x%02x%02x%02x%02x\n",
			__func__, HDCP_STATE_NAME, bksv[4], bksv[3], bksv[2],
			bksv[1], bksv[0]);
		rc = -EINVAL;
		goto error;
	}

	link0_bksv_0 = bksv[3];
	link0_bksv_0 = (link0_bksv_0 << 8) | bksv[2];
	link0_bksv_0 = (link0_bksv_0 << 8) | bksv[1];
	link0_bksv_0 = (link0_bksv_0 << 8) | bksv[0];
	link0_bksv_1 = bksv[4];
	DEV_DBG("%s: %s: BKSV=%02x%08x\n", __func__, HDCP_STATE_NAME,
		link0_bksv_1, link0_bksv_0);

	if (hdcp_ctrl->tz_hdcp) {
		memset(scm_buf, 0x00, sizeof(scm_buf));

		scm_buf[0].addr = phy_addr + HDMI_HDCP_RCVPORT_DATA0;
		scm_buf[0].val  = link0_bksv_0;
		scm_buf[1].addr = phy_addr + HDMI_HDCP_RCVPORT_DATA1;
		scm_buf[1].val  = link0_bksv_1;

		ret = hdcp_scm_call(scm_buf, &resp);

		if (ret || resp) {
			DEV_ERR("%s: error: scm_call ret = %d, resp = %d\n",
				__func__, ret, resp);
			rc = -EINVAL;
			goto error;
		}
	} else if (hdcp_ctrl->hdmi_tx_ver_4) {
		DSS_REG_W(hdcp_io, HDCP_SEC_TZ_HV_HLOS_HDCP_RCVPORT_DATA0,
			link0_bksv_0);
		DSS_REG_W(hdcp_io, HDCP_SEC_TZ_HV_HLOS_HDCP_RCVPORT_DATA1,
			link0_bksv_1);
	} else {
		DSS_REG_W(io, HDMI_HDCP_RCVPORT_DATA0, link0_bksv_0);
		DSS_REG_W(io, HDMI_HDCP_RCVPORT_DATA1, link0_bksv_1);
	}

	/* Enable HDCP interrupts and ack/clear any stale interrupts */
	DSS_REG_W(io, HDMI_HDCP_INT_CTRL, 0xE6);

	/*
	 * HDCP Compliace Test case 1A-01:
	 * Wait here at least 100ms before reading R0'
	 */
	msleep(125);

	/* Read R0' at offset 0x08 */
	memset(buf, 0, sizeof(buf));
	memset(&ddc_data, 0, sizeof(ddc_data));
	ddc_data.dev_addr = 0x74;
	ddc_data.offset = 0x08;
	ddc_data.data_buf = buf;
	ddc_data.data_len = 2;
	ddc_data.request_len = 2;
	ddc_data.retry = 5;
	ddc_data.what = "R0'";

	hdcp_ctrl->init_data.ddc_ctrl->ddc_data = ddc_data;

	rc = hdmi_ddc_read(hdcp_ctrl->init_data.ddc_ctrl);
	if (rc) {
		DEV_ERR("%s: %s: R0' read failed\n", __func__, HDCP_STATE_NAME);
		goto error;
	}
	DEV_DBG("%s: %s: R0'=%02x%02x\n", __func__, HDCP_STATE_NAME,
		buf[1], buf[0]);

	/* Write R0' to HDCP registers and check to see if it is a match */
	reinit_completion(&hdcp_ctrl->r0_checked);
	DSS_REG_W(io, HDMI_HDCP_RCVPORT_DATA2_0, (((u32)buf[1]) << 8) | buf[0]);
	timeout_count = wait_for_completion_timeout(
		&hdcp_ctrl->r0_checked, HZ*2);
	link0_status = DSS_REG_R(io, HDMI_HDCP_LINK0_STATUS);
	is_match = link0_status & BIT(12);
	if (!is_match) {
		DEV_DBG("%s: %s: Link0_Status=0x%08x\n", __func__,
			HDCP_STATE_NAME, link0_status);
		if (!timeout_count) {
			DEV_ERR("%s: %s: Timeout. No R0 mtch. R0'=%02x%02x\n",
				__func__, HDCP_STATE_NAME, buf[1], buf[0]);
			rc = -ETIMEDOUT;
			goto error;
		} else {
			DEV_ERR("%s: %s: R0 mismatch. R0'=%02x%02x\n", __func__,
				HDCP_STATE_NAME, buf[1], buf[0]);
			rc = -EINVAL;
			goto error;
		}
	} else {
		DEV_DBG("%s: %s: R0 matches\n", __func__, HDCP_STATE_NAME);
	}

error:
	if (rc) {
		DEV_ERR("%s: %s: Authentication Part I failed\n", __func__,
			hdcp_ctrl ? HDCP_STATE_NAME : "???");
	} else {
		/* Enable HDCP Encryption */
		DSS_REG_W(io, HDMI_HDCP_CTRL, BIT(0) | BIT(8));
		DEV_INFO("%s: %s: Authentication Part I successful\n",
			__func__, HDCP_STATE_NAME);
	}
	return rc;
} /* hdmi_hdcp_authentication_part1 */

static int read_write_v_h(struct hdmi_hdcp_ctrl *hdcp_ctrl,
			  struct hdmi_tx_ddc_data ddc_data,
			  struct dss_io_data *io, int off, char *name,
			  u32 reg, bool wr)
{
	int rc = 0;

	do {
		ddc_data.offset = off;
		memset(ddc_data.what, 0, 20);
		snprintf(ddc_data.what, 20, name);
		hdcp_ctrl->init_data.ddc_ctrl->ddc_data = ddc_data;
		rc = hdmi_ddc_read(hdcp_ctrl->init_data.ddc_ctrl);
		if (rc) {
			DEV_ERR("%s: %s: Read %s failed\n", __func__,
				HDCP_STATE_NAME, ddc_data.what);
			return rc;
		}
		DEV_DBG("%s: %s: %s: buf[0]=%x, [1]=%x,[2]=%x, [3]=%x\n",
			__func__, HDCP_STATE_NAME, ddc_data.what,
			ddc_data.data_buf[0], ddc_data.data_buf[1],
			ddc_data.data_buf[2], ddc_data.data_buf[3]);
		if (wr) {
			DSS_REG_W((io), (reg),
					(ddc_data.data_buf[3] << 24 |
					 ddc_data.data_buf[2] << 16 |
					 ddc_data.data_buf[1] << 8 |
					 ddc_data.data_buf[0]));
		}
	} while (0);
	return rc;
}

static int hdmi_hdcp_transfer_v_h(struct hdmi_hdcp_ctrl *hdcp_ctrl)
{
	char what[20];
	int rc = 0;
	u8 buf[4];
	struct hdmi_tx_ddc_data ddc_data;
	struct dss_io_data *io;

	struct scm_hdcp_req scm_buf[SCM_HDCP_MAX_REG];
	u32 phy_addr;

	struct hdmi_hdcp_reg_data reg_data[]  = {
		{HDMI_HDCP_RCVPORT_DATA7,  0x20, "V' H0"},
		{HDMI_HDCP_RCVPORT_DATA8,  0x24, "V' H1"},
		{HDMI_HDCP_RCVPORT_DATA9,  0x28, "V' H2"},
		{HDMI_HDCP_RCVPORT_DATA10, 0x2C, "V' H3"},
		{HDMI_HDCP_RCVPORT_DATA11, 0x30, "V' H4"},
	};
	u32 size = ARRAY_SIZE(reg_data)/sizeof(reg_data[0]);
	u32 iter = 0;
	u32 ret  = 0;
	u32 resp = 0;

	memset(&ddc_data, 0, sizeof(ddc_data));
	ddc_data.dev_addr = 0x74;
	ddc_data.data_buf = buf;
	ddc_data.data_len = 4;
	ddc_data.request_len = 4;
	ddc_data.retry = 5;
	ddc_data.what = what;

	if (!hdcp_ctrl || !hdcp_ctrl->init_data.core_io) {
		DEV_ERR("%s: invalid input\n", __func__);
		return -EINVAL;
	}

	phy_addr = hdcp_ctrl->init_data.phy_addr;

	io = hdcp_ctrl->init_data.core_io;

	if (hdcp_ctrl->tz_hdcp) {
		memset(scm_buf, 0x00, sizeof(scm_buf));

		for (iter = 0; iter < size && iter < SCM_HDCP_MAX_REG; iter++) {
			struct hdmi_hdcp_reg_data *rd = reg_data + iter;

			if (read_write_v_h(hdcp_ctrl, ddc_data, io, rd->off,
					   rd->name, 0, false))
				goto error;

			rd->reg_val = buf[3] << 24 | buf[2] << 16 |
				buf[1] << 8 | buf[0];

			scm_buf[iter].addr = phy_addr + reg_data[iter].reg_id;
			scm_buf[iter].val  = reg_data[iter].reg_val;
		}

		ret = hdcp_scm_call(scm_buf, &resp);
		if (ret || resp) {
			DEV_ERR("%s: error: scm_call ret = %d, resp = %d\n",
				__func__, ret, resp);
			rc = -EINVAL;
			goto error;
		}
	} else if (hdcp_ctrl->hdmi_tx_ver_4) {
		struct dss_io_data *hdcp_io = hdcp_ctrl->init_data.hdcp_io;

		/* Read V'.HO 4 Byte at offset 0x20 */
		if (read_write_v_h(hdcp_ctrl, ddc_data, hdcp_io, 0x20, "V' H0",
				HDCP_SEC_TZ_HV_HLOS_HDCP_RCVPORT_DATA7, true))
			goto error;

		/* Read V'.H1 4 Byte at offset 0x24 */
		if (read_write_v_h(hdcp_ctrl, ddc_data, hdcp_io, 0x24, "V' H1",
				HDCP_SEC_TZ_HV_HLOS_HDCP_RCVPORT_DATA8, true))
			goto error;

		/* Read V'.H2 4 Byte at offset 0x28 */
		if (read_write_v_h(hdcp_ctrl, ddc_data, hdcp_io, 0x28, "V' H2",
				HDCP_SEC_TZ_HV_HLOS_HDCP_RCVPORT_DATA9, true))
			goto error;

		/* Read V'.H3 4 Byte at offset 0x2C */
		if (read_write_v_h(hdcp_ctrl, ddc_data, hdcp_io, 0x2C, "V' H3",
				HDCP_SEC_TZ_HV_HLOS_HDCP_RCVPORT_DATA10, true))
			goto error;

		/* Read V'.H4 4 Byte at offset 0x30 */
		if (read_write_v_h(hdcp_ctrl, ddc_data, hdcp_io, 0x30, "V' H4",
				HDCP_SEC_TZ_HV_HLOS_HDCP_RCVPORT_DATA11, true))
			goto error;
	} else {
		/* Read V'.HO 4 Byte at offset 0x20 */
		if (read_write_v_h(hdcp_ctrl, ddc_data, io, 0x20, "V' H0",
				   HDMI_HDCP_RCVPORT_DATA7, true))
			goto error;

		/* Read V'.H1 4 Byte at offset 0x24 */
		if (read_write_v_h(hdcp_ctrl, ddc_data, io, 0x24, "V' H1",
				   HDMI_HDCP_RCVPORT_DATA8, true))
			goto error;

		/* Read V'.H2 4 Byte at offset 0x28 */
		if (read_write_v_h(hdcp_ctrl, ddc_data, io, 0x28, "V' H2",
				   HDMI_HDCP_RCVPORT_DATA9, true))
			goto error;

		/* Read V'.H3 4 Byte at offset 0x2C */
		if (read_write_v_h(hdcp_ctrl, ddc_data, io, 0x2C, "V' H3",
				   HDMI_HDCP_RCVPORT_DATA10, true))
			goto error;

		/* Read V'.H4 4 Byte at offset 0x30 */
		if (read_write_v_h(hdcp_ctrl, ddc_data, io, 0x30, "V' H4",
				   HDMI_HDCP_RCVPORT_DATA11, true))
			goto error;
	}

error:
	return rc;
}

static int hdmi_hdcp_authentication_part2(struct hdmi_hdcp_ctrl *hdcp_ctrl)
{
	int rc, cnt, i;
	struct hdmi_tx_ddc_data ddc_data;
	u32 timeout_count, down_stream_devices = 0;
	u32 repeater_cascade_depth = 0;
	u8 buf[0xFF];
	u8 *ksv_fifo = NULL;
	u8 bcaps;
	u16 bstatus, max_devs_exceeded = 0, max_cascade_exceeded = 0;
	u32 link0_status;
	u32 ksv_bytes;
	struct dss_io_data *io;

	struct scm_hdcp_req scm_buf[SCM_HDCP_MAX_REG];
	u32 phy_addr;
	u32 ret  = 0;
	u32 resp = 0;

	if (!hdcp_ctrl || !hdcp_ctrl->init_data.core_io) {
		DEV_ERR("%s: invalid input\n", __func__);
		rc = -EINVAL;
		goto error;
	}

	phy_addr = hdcp_ctrl->init_data.phy_addr;

	if (hdcp_ctrl->hdcp_state != HDCP_STATE_AUTHENTICATING) {
		DEV_DBG("%s: %s: invalid state. returning\n", __func__,
			HDCP_STATE_NAME);
		rc = -EINVAL;
		goto error;
	}

	ksv_fifo = hdcp_ctrl->current_tp.ksv_list;

	io = hdcp_ctrl->init_data.core_io;

	memset(buf, 0, sizeof(buf));
	memset(ksv_fifo, 0,
		sizeof(hdcp_ctrl->current_tp.ksv_list));

	/*
	 * Wait until READY bit is set in BCAPS, as per HDCP specifications
	 * maximum permitted time to check for READY bit is five seconds.
	 */
	timeout_count = 50;
	do {
		timeout_count--;
		/* Read BCAPS at offset 0x40 */
		memset(&ddc_data, 0, sizeof(ddc_data));
		ddc_data.dev_addr = 0x74;
		ddc_data.offset = 0x40;
		ddc_data.data_buf = &bcaps;
		ddc_data.data_len = 1;
		ddc_data.request_len = 1;
		ddc_data.retry = 5;
		ddc_data.what = "Bcaps";
		ddc_data.retry_align = true;

		hdcp_ctrl->init_data.ddc_ctrl->ddc_data = ddc_data;

		rc = hdmi_ddc_read(hdcp_ctrl->init_data.ddc_ctrl);
		if (rc) {
			DEV_ERR("%s: %s: BCAPS read failed\n", __func__,
				HDCP_STATE_NAME);
			goto error;
		}
		msleep(100);
	} while (!(bcaps & BIT(5)) && timeout_count);

	/* Read BSTATUS at offset 0x41 */
	memset(&ddc_data, 0, sizeof(ddc_data));
	ddc_data.dev_addr = 0x74;
	ddc_data.offset = 0x41;
	ddc_data.data_buf = buf;
	ddc_data.data_len = 2;
	ddc_data.request_len = 2;
	ddc_data.retry = 5;
	ddc_data.what = "Bstatuss";
	ddc_data.retry_align = true;

	hdcp_ctrl->init_data.ddc_ctrl->ddc_data = ddc_data;

	rc = hdmi_ddc_read(hdcp_ctrl->init_data.ddc_ctrl);
	if (rc) {
		DEV_ERR("%s: %s: BSTATUS read failed\n", __func__,
			HDCP_STATE_NAME);
		goto error;
	}
	bstatus = buf[1];
	bstatus = (bstatus << 8) | buf[0];

	if (hdcp_ctrl->tz_hdcp) {
		memset(scm_buf, 0x00, sizeof(scm_buf));

		/* Write BSTATUS and BCAPS to HDCP registers */
		scm_buf[0].addr = phy_addr + HDMI_HDCP_RCVPORT_DATA12;
		scm_buf[0].val  = bcaps | (bstatus << 8);

		ret = hdcp_scm_call(scm_buf, &resp);
		if (ret || resp) {
			DEV_ERR("%s: error: scm_call ret = %d, resp = %d\n",
				__func__, ret, resp);
			rc = -EINVAL;
			goto error;
		}
	} else if (hdcp_ctrl->hdmi_tx_ver_4) {
		DSS_REG_W(hdcp_ctrl->init_data.hdcp_io,
				HDCP_SEC_TZ_HV_HLOS_HDCP_RCVPORT_DATA12,
				bcaps | (bstatus << 8));
	} else {
		DSS_REG_W(io, HDMI_HDCP_RCVPORT_DATA12, bcaps | (bstatus << 8));
	}

	down_stream_devices = bstatus & 0x7F;
	if (down_stream_devices == 0) {
		/*
		 * If no downstream devices are attached to the repeater
		 * then part II fails.
		 * todo: The other approach would be to continue PART II.
		 */
		DEV_ERR("%s: %s: No downstream devices\n", __func__,
			HDCP_STATE_NAME);
		rc = -EINVAL;
		goto error;
	}

	/* Cascaded repeater depth */
	repeater_cascade_depth = (bstatus >> 8) & 0x7;

	/*
	 * HDCP Compliance 1B-05:
	 * Check if no. of devices connected to repeater
	 * exceed max_devices_connected from bit 7 of Bstatus.
	 */
	max_devs_exceeded = (bstatus & BIT(7)) >> 7;
	if (max_devs_exceeded == 0x01) {
		DEV_ERR("%s: %s: no. of devs connected exceeds max allowed",
			__func__, HDCP_STATE_NAME);
		rc = -EINVAL;
		goto error;
	}

	/*
	 * HDCP Compliance 1B-06:
	 * Check if no. of cascade connected to repeater
	 * exceed max_cascade_connected from bit 11 of Bstatus.
	 */
	max_cascade_exceeded = (bstatus & BIT(11)) >> 11;
	if (max_cascade_exceeded == 0x01) {
		DEV_ERR("%s: %s: no. of cascade conn exceeds max allowed",
			__func__, HDCP_STATE_NAME);
		rc = -EINVAL;
		goto error;
	}

	/*
	 * Read KSV FIFO over DDC
	 * Key Slection vector FIFO Used to pull downstream KSVs
	 * from HDCP Repeaters.
	 * All bytes (DEVICE_COUNT * 5) must be read in a single,
	 * auto incrementing access.
	 * All bytes read as 0x00 for HDCP Receivers that are not
	 * HDCP Repeaters (REPEATER == 0).
	 */
	ksv_bytes = 5 * down_stream_devices;
	memset(&ddc_data, 0, sizeof(ddc_data));
	ddc_data.dev_addr = 0x74;
	ddc_data.offset = 0x43;
	ddc_data.data_buf = ksv_fifo;
	ddc_data.data_len = ksv_bytes;
	ddc_data.request_len = ksv_bytes;
	ddc_data.retry = 5;
	ddc_data.what = "KSV FIFO";

	hdcp_ctrl->init_data.ddc_ctrl->ddc_data = ddc_data;

	cnt = 0;
	do {
		rc = hdmi_ddc_read(hdcp_ctrl->init_data.ddc_ctrl);
		if (rc) {
			DEV_ERR("%s: %s: KSV FIFO read failed\n", __func__,
				HDCP_STATE_NAME);
			/*
			 * HDCP Compliace Test case 1B-01:
			 * Wait here until all the ksv bytes have been
			 * read from the KSV FIFO register.
			 */
			msleep(25);
		} else {
			break;
		}
		cnt++;
	} while (cnt != 20);

	if (cnt == 20)
		goto error;

	rc = hdmi_hdcp_transfer_v_h(hdcp_ctrl);
	if (rc)
		goto error;

	/*
	 * Write KSV FIFO to HDCP_SHA_DATA.
	 * This is done 1 byte at time starting with the LSB.
	 * On the very last byte write, the HDCP_SHA_DATA_DONE bit[0]
	 */

	/* First, reset SHA engine */
	/* Next, enable SHA engine, SEL=DIGA_HDCP */
	if (hdcp_ctrl->tz_hdcp) {
		memset(scm_buf, 0x00, sizeof(scm_buf));

		scm_buf[0].addr = phy_addr + HDMI_HDCP_SHA_CTRL;
		scm_buf[0].val  = HDCP_REG_ENABLE;
		scm_buf[1].addr = phy_addr + HDMI_HDCP_SHA_CTRL;
		scm_buf[1].val  = HDCP_REG_DISABLE;

		ret = hdcp_scm_call(scm_buf, &resp);
		if (ret || resp) {
			DEV_ERR("%s: error: scm_call ret = %d, resp = %d\n",
				__func__, ret, resp);
			rc = -EINVAL;
			goto error;
		}
	} else if (hdcp_ctrl->hdmi_tx_ver_4) {
		DSS_REG_W(hdcp_ctrl->init_data.hdcp_io,
				HDCP_SEC_TZ_HV_HLOS_HDCP_SHA_CTRL,
				HDCP_REG_ENABLE);
		DSS_REG_W(hdcp_ctrl->init_data.hdcp_io,
				HDCP_SEC_TZ_HV_HLOS_HDCP_SHA_CTRL,
				HDCP_REG_DISABLE);
	} else {
		DSS_REG_W(io, HDMI_HDCP_SHA_CTRL, HDCP_REG_ENABLE);
		DSS_REG_W(io, HDMI_HDCP_SHA_CTRL, HDCP_REG_DISABLE);
	}

	for (i = 0; i < ksv_bytes - 1; i++) {
		/* Write KSV byte and do not set DONE bit[0] */
		if (hdcp_ctrl->tz_hdcp) {
			memset(scm_buf, 0x00, sizeof(scm_buf));

			scm_buf[0].addr = phy_addr + HDMI_HDCP_SHA_DATA;
			scm_buf[0].val  = ksv_fifo[i] << 16;

			ret = hdcp_scm_call(scm_buf, &resp);
			if (ret || resp) {
				DEV_ERR("%s: scm_call ret = %d, resp = %d\n",
					__func__, ret, resp);
				rc = -EINVAL;
				goto error;
			}
		} else if (hdcp_ctrl->hdmi_tx_ver_4) {
			DSS_REG_W_ND(hdcp_ctrl->init_data.hdcp_io,
					HDCP_SEC_TZ_HV_HLOS_HDCP_SHA_DATA,
					ksv_fifo[i] << 16);
		} else {
			DSS_REG_W_ND(io, HDMI_HDCP_SHA_DATA, ksv_fifo[i] << 16);
		}

		/*
		 * Once 64 bytes have been written, we need to poll for
		 * HDCP_SHA_BLOCK_DONE before writing any further
		 */
		if (i && !((i + 1) % 64)) {
			timeout_count = 100;
			while (!(DSS_REG_R(io, HDMI_HDCP_SHA_STATUS) & BIT(0))
				&& (--timeout_count)) {
				DEV_DBG("%s: %s: Wrote 64 bytes KSV FIFO\n",
					__func__, HDCP_STATE_NAME);
				DEV_DBG("%s: %s: HDCP_SHA_STATUS=%08x\n",
					__func__, HDCP_STATE_NAME,
					DSS_REG_R(io, HDMI_HDCP_SHA_STATUS));
				msleep(20);
			}
			if (!timeout_count) {
				rc = -ETIMEDOUT;
				DEV_ERR("%s: %s: Write KSV FIFO timedout",
					__func__, HDCP_STATE_NAME);
				goto error;
			}
		}

	}

	/* Write l to DONE bit[0] */
	if (hdcp_ctrl->tz_hdcp) {
		memset(scm_buf, 0x00, sizeof(scm_buf));

		scm_buf[0].addr = phy_addr + HDMI_HDCP_SHA_DATA;
		scm_buf[0].val  = (ksv_fifo[ksv_bytes - 1] << 16) | 0x1;

		ret = hdcp_scm_call(scm_buf, &resp);
		if (ret || resp) {
			DEV_ERR("%s: error: scm_call ret = %d, resp = %d\n",
				__func__, ret, resp);
			rc = -EINVAL;
			goto error;
		}
	} else if (hdcp_ctrl->hdmi_tx_ver_4) {
		DSS_REG_W_ND(hdcp_ctrl->init_data.hdcp_io,
				HDCP_SEC_TZ_HV_HLOS_HDCP_SHA_DATA,
				(ksv_fifo[ksv_bytes - 1] << 16) | 0x1);
	} else {
		DSS_REG_W_ND(io, HDMI_HDCP_SHA_DATA,
			(ksv_fifo[ksv_bytes - 1] << 16) | 0x1);
	}

	/* Now wait for HDCP_SHA_COMP_DONE */
	timeout_count = 100;
	while ((0x10 != (DSS_REG_R(io, HDMI_HDCP_SHA_STATUS)
		& 0xFFFFFF10)) && --timeout_count)
		msleep(20);
	if (!timeout_count) {
		rc = -ETIMEDOUT;
		DEV_ERR("%s: %s: SHA computation timedout", __func__,
			HDCP_STATE_NAME);
		goto error;
	}

	/* Wait for V_MATCHES */
	timeout_count = 100;
	link0_status = DSS_REG_R(io, HDMI_HDCP_LINK0_STATUS);
	while (((link0_status & BIT(20)) != BIT(20)) && --timeout_count) {
		DEV_DBG("%s: %s: Waiting for V_MATCHES(%d). l0_status=0x%08x\n",
			__func__, HDCP_STATE_NAME, timeout_count, link0_status);
		msleep(20);
		link0_status = DSS_REG_R(io, HDMI_HDCP_LINK0_STATUS);
	}
	if (!timeout_count) {
		rc = -ETIMEDOUT;
		DEV_ERR("%s: %s: HDCP V Match timedout", __func__,
			HDCP_STATE_NAME);
		goto error;
	}

error:
	if (rc)
		DEV_ERR("%s: %s: Authentication Part II failed\n", __func__,
			hdcp_ctrl ? HDCP_STATE_NAME : "???");
	else
		DEV_INFO("%s: %s: Authentication Part II successful\n",
			__func__, HDCP_STATE_NAME);

	if (!hdcp_ctrl) {
		DEV_ERR("%s: hdcp_ctrl null. Topology not updated\n",
			__func__);
		return rc;
	}
	/* Update topology information */
	hdcp_ctrl->current_tp.dev_count = down_stream_devices;
	hdcp_ctrl->current_tp.max_cascade_exceeded = max_cascade_exceeded;
	hdcp_ctrl->current_tp.max_dev_exceeded = max_devs_exceeded;
	hdcp_ctrl->current_tp.depth = repeater_cascade_depth;

	return rc;
} /* hdmi_hdcp_authentication_part2 */

static void hdmi_hdcp_cache_topology(struct hdmi_hdcp_ctrl *hdcp_ctrl)
{
	if (!hdcp_ctrl || !hdcp_ctrl->init_data.core_io) {
		DEV_ERR("%s: invalid input\n", __func__);
		return;
	}

	memcpy((void *)&hdcp_ctrl->cached_tp,
		(void *) &hdcp_ctrl->current_tp,
		sizeof(hdcp_ctrl->cached_tp));
}

static void hdmi_hdcp_notify_topology(struct hdmi_hdcp_ctrl *hdcp_ctrl)
{
	char a[16], b[16];
	char *envp[] = {
		[0] = "HDCP_MGR_EVENT=MSG_READY",
		[1] = a,
		[2] = b,
		NULL,
		};

	snprintf(envp[1], 16, "%d", (int)DOWN_CHECK_TOPOLOGY);
	snprintf(envp[2], 16, "%d", (int)HDCP_V1_TX);
	kobject_uevent_env(hdcp_ctrl->init_data.sysfs_kobj, KOBJ_CHANGE, envp);

	DEV_DBG("%s Event Sent: %s msgID = %s srcID = %s\n", __func__,
			envp[0], envp[1], envp[2]);
}

static void hdmi_hdcp_int_work(struct work_struct *work)
{
	struct hdmi_hdcp_ctrl *hdcp_ctrl = container_of(work,
		struct hdmi_hdcp_ctrl, hdcp_int_work);

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

	mutex_lock(hdcp_ctrl->init_data.mutex);
	hdcp_ctrl->hdcp_state = HDCP_STATE_AUTH_FAIL;
	mutex_unlock(hdcp_ctrl->init_data.mutex);

	if (hdcp_ctrl->init_data.notify_status) {
		hdcp_ctrl->init_data.notify_status(
			hdcp_ctrl->init_data.cb_data,
			hdcp_ctrl->hdcp_state);
	}
} /* hdmi_hdcp_int_work */

static void hdmi_hdcp_auth_work(struct work_struct *work)
{
	int rc;
	struct delayed_work *dw = to_delayed_work(work);
	struct hdmi_hdcp_ctrl *hdcp_ctrl = container_of(dw,
		struct hdmi_hdcp_ctrl, hdcp_auth_work);
	struct dss_io_data *io;

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

	if (hdcp_ctrl->hdcp_state != HDCP_STATE_AUTHENTICATING) {
		DEV_DBG("%s: %s: invalid state. returning\n", __func__,
			HDCP_STATE_NAME);
		return;
	}

	io = hdcp_ctrl->init_data.core_io;
	/* Enabling Software DDC */
	DSS_REG_W_ND(io, HDMI_DDC_ARBITRATION, DSS_REG_R(io,
				HDMI_DDC_ARBITRATION) & ~(BIT(4)));

	rc = hdmi_hdcp_authentication_part1(hdcp_ctrl);
	if (rc) {
		DEV_DBG("%s: %s: HDCP Auth Part I failed\n", __func__,
			HDCP_STATE_NAME);
		goto error;
	}

	if (hdcp_ctrl->current_tp.ds_type == DS_REPEATER) {
		rc = hdmi_hdcp_authentication_part2(hdcp_ctrl);
		if (rc) {
			DEV_DBG("%s: %s: HDCP Auth Part II failed\n", __func__,
				HDCP_STATE_NAME);
			goto error;
		}
	} else {
		DEV_INFO("%s: Downstream device is not a repeater\n", __func__);
	}
	/* Disabling software DDC before going into part3 to make sure
	 * there is no Arbitration between software and hardware for DDCi
	 */
	DSS_REG_W_ND(io, HDMI_DDC_ARBITRATION, DSS_REG_R(io,
				HDMI_DDC_ARBITRATION) | (BIT(4)));

error:
	/*
	 * Ensure that the state did not change during authentication.
	 * If it did, it means that deauthenticate/reauthenticate was
	 * called. In that case, this function need not notify HDMI Tx
	 * of the result
	 */
	mutex_lock(hdcp_ctrl->init_data.mutex);
	if (hdcp_ctrl->hdcp_state == HDCP_STATE_AUTHENTICATING) {
		if (rc) {
			hdcp_ctrl->hdcp_state = HDCP_STATE_AUTH_FAIL;
		} else {
			hdcp_ctrl->hdcp_state = HDCP_STATE_AUTHENTICATED;
			hdcp_ctrl->auth_retries = 0;
			hdmi_hdcp_cache_topology(hdcp_ctrl);
			hdmi_hdcp_notify_topology(hdcp_ctrl);
		}
		mutex_unlock(hdcp_ctrl->init_data.mutex);

		/* Notify HDMI Tx controller of the result */
		DEV_DBG("%s: %s: Notifying HDMI Tx of auth result\n",
			__func__, HDCP_STATE_NAME);
		if (hdcp_ctrl->init_data.notify_status) {
			hdcp_ctrl->init_data.notify_status(
				hdcp_ctrl->init_data.cb_data,
				hdcp_ctrl->hdcp_state);
		}
	} else {
		DEV_DBG("%s: %s: HDCP state changed during authentication\n",
			__func__, HDCP_STATE_NAME);
		mutex_unlock(hdcp_ctrl->init_data.mutex);
	}
} /* hdmi_hdcp_auth_work */

int hdmi_hdcp_authenticate(void *input)
{
	struct hdmi_hdcp_ctrl *hdcp_ctrl = (struct hdmi_hdcp_ctrl *)input;

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

	if (hdcp_ctrl->hdcp_state != HDCP_STATE_INACTIVE) {
		DEV_DBG("%s: %s: already active or activating. returning\n",
			__func__, HDCP_STATE_NAME);
		return 0;
	}

	DEV_DBG("%s: %s: Queuing work to start HDCP authentication", __func__,
		HDCP_STATE_NAME);

	if (!hdmi_hdcp_load_keys(input))
		queue_delayed_work(hdcp_ctrl->init_data.workq,
			&hdcp_ctrl->hdcp_auth_work, HZ/2);
	else
		queue_work(hdcp_ctrl->init_data.workq,
			&hdcp_ctrl->hdcp_int_work);

	return 0;
} /* hdmi_hdcp_authenticate */

int hdmi_hdcp_reauthenticate(void *input)
{
	struct hdmi_hdcp_ctrl *hdcp_ctrl = (struct hdmi_hdcp_ctrl *)input;
	struct dss_io_data *io;
	u32 hdmi_hw_version;
	u32 ret = 0;

	if (!hdcp_ctrl || !hdcp_ctrl->init_data.core_io) {
		DEV_ERR("%s: invalid input\n", __func__);
		return -EINVAL;
	}

	io = hdcp_ctrl->init_data.core_io;

	if (hdcp_ctrl->hdcp_state != HDCP_STATE_AUTH_FAIL) {
		DEV_DBG("%s: %s: invalid state. returning\n", __func__,
			HDCP_STATE_NAME);
		return 0;
	}

	hdmi_hw_version = DSS_REG_R(io, HDMI_VERSION);
	if (hdmi_hw_version >= 0x30030000) {
		DSS_REG_W(io, HDMI_CTRL_SW_RESET, BIT(1));
		DSS_REG_W(io, HDMI_CTRL_SW_RESET, 0);
	}

	/* Disable HDCP interrupts */
	DSS_REG_W(io, HDMI_HDCP_INT_CTRL, 0);

	DSS_REG_W(io, HDMI_HDCP_RESET, BIT(0));

	/* Wait to be clean on DDC HW engine */
	hdmi_hdcp_hw_ddc_clean(hdcp_ctrl);

	/* Disable encryption and disable the HDCP block */
	DSS_REG_W(io, HDMI_HDCP_CTRL, 0);

	if (!hdmi_hdcp_load_keys(input))
		queue_delayed_work(hdcp_ctrl->init_data.workq,
			&hdcp_ctrl->hdcp_auth_work, HZ/2);
	else
		queue_work(hdcp_ctrl->init_data.workq,
			&hdcp_ctrl->hdcp_int_work);

	return ret;
} /* hdmi_hdcp_reauthenticate */

void hdmi_hdcp_off(void *input)
{
	struct hdmi_hdcp_ctrl *hdcp_ctrl = (struct hdmi_hdcp_ctrl *)input;
	struct dss_io_data *io;
	int rc = 0;

	if (!hdcp_ctrl || !hdcp_ctrl->init_data.core_io) {
		DEV_ERR("%s: invalid input\n", __func__);
		return;
	}

	io = hdcp_ctrl->init_data.core_io;

	if (hdcp_ctrl->hdcp_state == HDCP_STATE_INACTIVE) {
		DEV_DBG("%s: %s: inactive. returning\n", __func__,
			HDCP_STATE_NAME);
		return;
	}

	/*
	 * Disable HDCP interrupts.
	 * Also, need to set the state to inactive here so that any ongoing
	 * reauth works will know that the HDCP session has been turned off.
	 */
	mutex_lock(hdcp_ctrl->init_data.mutex);
	DSS_REG_W(io, HDMI_HDCP_INT_CTRL, 0);
	hdcp_ctrl->hdcp_state = HDCP_STATE_INACTIVE;
	mutex_unlock(hdcp_ctrl->init_data.mutex);

	/*
	 * Cancel any pending auth/reauth attempts.
	 * If one is ongoing, this will wait for it to finish.
	 * No more reauthentiaction attempts will be scheduled since we
	 * set the currect state to inactive.
	 */
	rc = cancel_delayed_work_sync(&hdcp_ctrl->hdcp_auth_work);
	if (rc)
		DEV_DBG("%s: %s: Deleted hdcp auth work\n", __func__,
			HDCP_STATE_NAME);
	rc = cancel_work_sync(&hdcp_ctrl->hdcp_int_work);
	if (rc)
		DEV_DBG("%s: %s: Deleted hdcp int work\n", __func__,
			HDCP_STATE_NAME);

	DSS_REG_W(io, HDMI_HDCP_RESET, BIT(0));

	/* Disable encryption and disable the HDCP block */
	DSS_REG_W(io, HDMI_HDCP_CTRL, 0);

	DEV_DBG("%s: %s: HDCP: Off\n", __func__, HDCP_STATE_NAME);
} /* hdmi_hdcp_off */

int hdmi_hdcp_isr(void *input)
{
	struct hdmi_hdcp_ctrl *hdcp_ctrl = (struct hdmi_hdcp_ctrl *)input;
	int rc = 0;
	struct dss_io_data *io;
	u32 hdcp_int_val;

	if (!hdcp_ctrl || !hdcp_ctrl->init_data.core_io) {
		DEV_ERR("%s: invalid input\n", __func__);
		rc = -EINVAL;
		goto error;
	}

	io = hdcp_ctrl->init_data.core_io;

	hdcp_int_val = DSS_REG_R(io, HDMI_HDCP_INT_CTRL);

	/* Ignore HDCP interrupts if HDCP is disabled */
	if (hdcp_ctrl->hdcp_state == HDCP_STATE_INACTIVE) {
		DSS_REG_W(io, HDMI_HDCP_INT_CTRL, HDCP_INT_CLR);
		return 0;
	}

	if (hdcp_int_val & BIT(0)) {
		/* AUTH_SUCCESS_INT */
		DSS_REG_W(io, HDMI_HDCP_INT_CTRL, (hdcp_int_val | BIT(1)));
		DEV_INFO("%s: %s: AUTH_SUCCESS_INT received\n", __func__,
			HDCP_STATE_NAME);
		if (hdcp_ctrl->hdcp_state == HDCP_STATE_AUTHENTICATING)
			complete_all(&hdcp_ctrl->r0_checked);
	}

	if (hdcp_int_val & BIT(4)) {
		/* AUTH_FAIL_INT */
		u32 link_status = DSS_REG_R(io, HDMI_HDCP_LINK0_STATUS);

		DSS_REG_W(io, HDMI_HDCP_INT_CTRL, (hdcp_int_val | BIT(5)));
		DEV_INFO("%s: %s: AUTH_FAIL_INT rcvd, LINK0_STATUS=0x%08x\n",
			__func__, HDCP_STATE_NAME, link_status);
		if (hdcp_ctrl->hdcp_state == HDCP_STATE_AUTHENTICATED) {
			/* Inform HDMI Tx of the failure */
			queue_work(hdcp_ctrl->init_data.workq,
				&hdcp_ctrl->hdcp_int_work);
			/* todo: print debug log with auth fail reason */
		} else if (hdcp_ctrl->hdcp_state == HDCP_STATE_AUTHENTICATING) {
			complete_all(&hdcp_ctrl->r0_checked);
		}

		/* Clear AUTH_FAIL_INFO as well */
		DSS_REG_W(io, HDMI_HDCP_INT_CTRL, (hdcp_int_val | BIT(7)));
	}

	if (hdcp_int_val & BIT(8)) {
		/* DDC_XFER_REQ_INT */
		DSS_REG_W(io, HDMI_HDCP_INT_CTRL, (hdcp_int_val | BIT(9)));
		DEV_INFO("%s: %s: DDC_XFER_REQ_INT received\n", __func__,
			HDCP_STATE_NAME);
	}

	if (hdcp_int_val & BIT(12)) {
		/* DDC_XFER_DONE_INT */
		DSS_REG_W(io, HDMI_HDCP_INT_CTRL, (hdcp_int_val | BIT(13)));
		DEV_INFO("%s: %s: DDC_XFER_DONE received\n", __func__,
			HDCP_STATE_NAME);
	}

error:
	return rc;
} /* hdmi_hdcp_isr */

static ssize_t hdmi_hdcp_sysfs_rda_status(struct device *dev,
			struct device_attribute *attr, char *buf)
{
	ssize_t ret;
	struct hdmi_hdcp_ctrl *hdcp_ctrl =
		hdmi_get_featuredata_from_sysfs_dev(dev, HDMI_TX_FEAT_HDCP);

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

	mutex_lock(hdcp_ctrl->init_data.mutex);
	ret = snprintf(buf, PAGE_SIZE, "%d\n", hdcp_ctrl->hdcp_state);
	DEV_DBG("%s: '%d'\n", __func__, hdcp_ctrl->hdcp_state);
	mutex_unlock(hdcp_ctrl->init_data.mutex);

	return ret;
} /* hdmi_hdcp_sysfs_rda_hdcp*/

static ssize_t hdmi_hdcp_sysfs_rda_tp(struct device *dev,
			struct device_attribute *attr, char *buf)
{
	ssize_t ret = 0;
	struct hdmi_hdcp_ctrl *hdcp_ctrl =
		hdmi_get_featuredata_from_sysfs_dev(dev, HDMI_TX_FEAT_HDCP);

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

	switch (hdcp_ctrl->tp_msgid) {
	case DOWN_CHECK_TOPOLOGY:
	case DOWN_REQUEST_TOPOLOGY:
		buf[MSG_ID_IDX]   = hdcp_ctrl->tp_msgid;
		buf[RET_CODE_IDX] = HDCP_AUTHED;
		ret = HEADER_LEN;

		memcpy(buf + HEADER_LEN, &hdcp_ctrl->cached_tp,
			sizeof(struct HDCP_V2V1_MSG_TOPOLOGY));

		ret += sizeof(struct HDCP_V2V1_MSG_TOPOLOGY);

		/* clear the flag once data is read back to user space*/
		hdcp_ctrl->tp_msgid = -1;
		break;
	default:
		ret = -EINVAL;
	}

	return ret;
} /* hdmi_hdcp_sysfs_rda_tp*/

static ssize_t hdmi_hdcp_sysfs_wta_tp(struct device *dev,
	struct device_attribute *attr, const char *buf, size_t count)
{
	int msgid = 0;
	ssize_t ret = count;
	struct hdmi_hdcp_ctrl *hdcp_ctrl =
		hdmi_get_featuredata_from_sysfs_dev(dev, HDMI_TX_FEAT_HDCP);

	if (!hdcp_ctrl || !buf) {
		DEV_ERR("%s: invalid input\n", __func__);
		return -EINVAL;
	}

	msgid = buf[0];

	switch (msgid) {
	case DOWN_CHECK_TOPOLOGY:
	case DOWN_REQUEST_TOPOLOGY:
		hdcp_ctrl->tp_msgid = msgid;
		break;
	/* more cases added here */
	default:
		ret = -EINVAL;
	}

	return ret;
} /* hdmi_tx_sysfs_wta_hpd */

static DEVICE_ATTR(status, 0444, hdmi_hdcp_sysfs_rda_status, NULL);
static DEVICE_ATTR(tp, 0644, hdmi_hdcp_sysfs_rda_tp,
	hdmi_hdcp_sysfs_wta_tp);


static struct attribute *hdmi_hdcp_fs_attrs[] = {
	&dev_attr_status.attr,
	&dev_attr_tp.attr,
	NULL,
};

static struct attribute_group hdmi_hdcp_fs_attr_group = {
	.name = "hdcp",
	.attrs = hdmi_hdcp_fs_attrs,
};

void hdmi_hdcp_deinit(void *input)
{
	struct hdmi_hdcp_ctrl *hdcp_ctrl = (struct hdmi_hdcp_ctrl *)input;

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

	sysfs_remove_group(hdcp_ctrl->init_data.sysfs_kobj,
				&hdmi_hdcp_fs_attr_group);

	kfree(hdcp_ctrl);
} /* hdmi_hdcp_deinit */

void *hdmi_hdcp_init(struct hdmi_hdcp_init_data *init_data)
{
	struct hdmi_hdcp_ctrl *hdcp_ctrl = NULL;
	int ret;
	static struct hdmi_hdcp_ops ops = {
		.hdmi_hdcp_isr = hdmi_hdcp_isr,
		.hdmi_hdcp_reauthenticate = hdmi_hdcp_reauthenticate,
		.hdmi_hdcp_authenticate = hdmi_hdcp_authenticate,
		.hdmi_hdcp_off = hdmi_hdcp_off
	};

	if (!init_data || !init_data->core_io || !init_data->qfprom_io ||
		!init_data->mutex || !init_data->ddc_ctrl ||
		!init_data->notify_status || !init_data->workq ||
		!init_data->cb_data) {
		DEV_ERR("%s: invalid input\n", __func__);
		goto error;
	}

	if (init_data->hdmi_tx_ver >= HDMI_TX_VERSION_4
			&& !init_data->hdcp_io) {
		DEV_ERR("%s: hdcp_io required for HDMI Tx Ver 4\n", __func__);
		goto error;
	}

	hdcp_ctrl = kzalloc(sizeof(*hdcp_ctrl), GFP_KERNEL);
	if (!hdcp_ctrl) {
		DEV_ERR("%s: Out of memory\n", __func__);
		goto error;
	}

	hdcp_ctrl->init_data = *init_data;
	hdcp_ctrl->ops = &ops;
	hdcp_ctrl->hdmi_tx_ver_4 =
		(init_data->hdmi_tx_ver >= HDMI_TX_VERSION_4);

	if (sysfs_create_group(init_data->sysfs_kobj,
				&hdmi_hdcp_fs_attr_group)) {
		DEV_ERR("%s: hdcp sysfs group creation failed\n", __func__);
		goto error;
	}

	INIT_DELAYED_WORK(&hdcp_ctrl->hdcp_auth_work, hdmi_hdcp_auth_work);
	INIT_WORK(&hdcp_ctrl->hdcp_int_work, hdmi_hdcp_int_work);

	hdcp_ctrl->hdcp_state = HDCP_STATE_INACTIVE;
	init_completion(&hdcp_ctrl->r0_checked);

	if (!hdcp_ctrl->hdmi_tx_ver_4) {
		ret = scm_is_call_available(SCM_SVC_HDCP, SCM_CMD_HDCP);
		if (ret <= 0) {
			DEV_ERR("%s: secure hdcp service unavailable, ret = %d",
				 __func__, ret);
		} else {
			DEV_DBG("%s: tz_hdcp = 1\n", __func__);
			hdcp_ctrl->tz_hdcp = 1;
		}
	}

	DEV_DBG("%s: HDCP module initialized. HDCP_STATE=%s", __func__,
		HDCP_STATE_NAME);

error:
	return (void *)hdcp_ctrl;
} /* hdmi_hdcp_init */

struct hdmi_hdcp_ops *hdmi_hdcp_start(void *input)
{
	return ((struct hdmi_hdcp_ctrl *)input)->ops;
}

