/* Copyright (c) 2010-2015, 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 "hdmi.h"
#include <linux/qcom_scm.h>

#define HDCP_REG_ENABLE 0x01
#define HDCP_REG_DISABLE 0x00
#define HDCP_PORT_ADDR 0x74

#define HDCP_INT_STATUS_MASK ( \
		HDMI_HDCP_INT_CTRL_AUTH_SUCCESS_INT | \
		HDMI_HDCP_INT_CTRL_AUTH_FAIL_INT | \
		HDMI_HDCP_INT_CTRL_AUTH_XFER_REQ_INT | \
		HDMI_HDCP_INT_CTRL_AUTH_XFER_DONE_INT)

#define AUTH_WORK_RETRIES_TIME 100
#define AUTH_RETRIES_TIME 30

/* QFPROM Registers for HDMI/HDCP */
#define QFPROM_RAW_FEAT_CONFIG_ROW0_LSB  0x000000F8
#define QFPROM_RAW_FEAT_CONFIG_ROW0_MSB  0x000000FC
#define HDCP_KSV_LSB                     0x000060D8
#define HDCP_KSV_MSB                     0x000060DC

enum DS_TYPE {  /* type of downstream device */
	DS_UNKNOWN,
	DS_RECEIVER,
	DS_REPEATER,
};

enum hdmi_hdcp_state {
	HDCP_STATE_NO_AKSV,
	HDCP_STATE_INACTIVE,
	HDCP_STATE_AUTHENTICATING,
	HDCP_STATE_AUTHENTICATED,
	HDCP_STATE_AUTH_FAILED
};

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

struct hdmi_hdcp_ctrl {
	struct hdmi *hdmi;
	u32 auth_retries;
	bool tz_hdcp;
	enum hdmi_hdcp_state hdcp_state;
	struct work_struct hdcp_auth_work;
	struct work_struct hdcp_reauth_work;

#define AUTH_ABORT_EV 1
#define AUTH_RESULT_RDY_EV 2
	unsigned long auth_event;
	wait_queue_head_t auth_event_queue;

	u32 ksv_fifo_w_index;
	/*
	 * store aksv from qfprom
	 */
	u32 aksv_lsb;
	u32 aksv_msb;
	bool aksv_valid;
	u32 ds_type;
	u32 bksv_lsb;
	u32 bksv_msb;
	u8 dev_count;
	u8 depth;
	u8 ksv_list[5 * 127];
	bool max_cascade_exceeded;
	bool max_dev_exceeded;
};

static int hdmi_ddc_read(struct hdmi *hdmi, u16 addr, u8 offset,
	u8 *data, u16 data_len)
{
	int rc;
	int retry = 5;
	struct i2c_msg msgs[] = {
		{
			.addr	= addr >> 1,
			.flags	= 0,
			.len	= 1,
			.buf	= &offset,
		}, {
			.addr	= addr >> 1,
			.flags	= I2C_M_RD,
			.len	= data_len,
			.buf	= data,
		}
	};

	DBG("Start DDC read");
retry:
	rc = i2c_transfer(hdmi->i2c, msgs, 2);

	retry--;
	if (rc == 2)
		rc = 0;
	else if (retry > 0)
		goto retry;
	else
		rc = -EIO;

	DBG("End DDC read %d", rc);

	return rc;
}

#define HDCP_DDC_WRITE_MAX_BYTE_NUM 32

static int hdmi_ddc_write(struct hdmi *hdmi, u16 addr, u8 offset,
	u8 *data, u16 data_len)
{
	int rc;
	int retry = 10;
	u8 buf[HDCP_DDC_WRITE_MAX_BYTE_NUM];
	struct i2c_msg msgs[] = {
		{
			.addr	= addr >> 1,
			.flags	= 0,
			.len	= 1,
		}
	};

	DBG("Start DDC write");
	if (data_len > (HDCP_DDC_WRITE_MAX_BYTE_NUM - 1)) {
		pr_err("%s: write size too big\n", __func__);
		return -ERANGE;
	}

	buf[0] = offset;
	memcpy(&buf[1], data, data_len);
	msgs[0].buf = buf;
	msgs[0].len = data_len + 1;
retry:
	rc = i2c_transfer(hdmi->i2c, msgs, 1);

	retry--;
	if (rc == 1)
		rc = 0;
	else if (retry > 0)
		goto retry;
	else
		rc = -EIO;

	DBG("End DDC write %d", rc);

	return rc;
}

static int hdmi_hdcp_scm_wr(struct hdmi_hdcp_ctrl *hdcp_ctrl, u32 *preg,
	u32 *pdata, u32 count)
{
	struct hdmi *hdmi = hdcp_ctrl->hdmi;
	struct qcom_scm_hdcp_req scm_buf[QCOM_SCM_HDCP_MAX_REQ_CNT];
	u32 resp, phy_addr, idx = 0;
	int i, ret = 0;

	WARN_ON(!pdata || !preg || (count == 0));

	if (hdcp_ctrl->tz_hdcp) {
		phy_addr = (u32)hdmi->mmio_phy_addr;

		while (count) {
			memset(scm_buf, 0, sizeof(scm_buf));
			for (i = 0; i < count && i < QCOM_SCM_HDCP_MAX_REQ_CNT;
				i++) {
				scm_buf[i].addr = phy_addr + preg[idx];
				scm_buf[i].val  = pdata[idx];
				idx++;
			}
			ret = qcom_scm_hdcp_req(scm_buf, i, &resp);

			if (ret || resp) {
				pr_err("%s: error: scm_call ret=%d resp=%u\n",
					__func__, ret, resp);
				ret = -EINVAL;
				break;
			}

			count -= i;
		}
	} else {
		for (i = 0; i < count; i++)
			hdmi_write(hdmi, preg[i], pdata[i]);
	}

	return ret;
}

void hdmi_hdcp_irq(struct hdmi_hdcp_ctrl *hdcp_ctrl)
{
	struct hdmi *hdmi = hdcp_ctrl->hdmi;
	u32 reg_val, hdcp_int_status;
	unsigned long flags;

	spin_lock_irqsave(&hdmi->reg_lock, flags);
	reg_val = hdmi_read(hdmi, REG_HDMI_HDCP_INT_CTRL);
	hdcp_int_status = reg_val & HDCP_INT_STATUS_MASK;
	if (!hdcp_int_status) {
		spin_unlock_irqrestore(&hdmi->reg_lock, flags);
		return;
	}
	/* Clear Interrupts */
	reg_val |= hdcp_int_status << 1;
	/* Clear AUTH_FAIL_INFO as well */
	if (hdcp_int_status & HDMI_HDCP_INT_CTRL_AUTH_FAIL_INT)
		reg_val |= HDMI_HDCP_INT_CTRL_AUTH_FAIL_INFO_ACK;
	hdmi_write(hdmi, REG_HDMI_HDCP_INT_CTRL, reg_val);
	spin_unlock_irqrestore(&hdmi->reg_lock, flags);

	DBG("hdcp irq %x", hdcp_int_status);

	if (hdcp_int_status & HDMI_HDCP_INT_CTRL_AUTH_SUCCESS_INT) {
		pr_info("%s:AUTH_SUCCESS_INT received\n", __func__);
		if (HDCP_STATE_AUTHENTICATING == hdcp_ctrl->hdcp_state) {
			set_bit(AUTH_RESULT_RDY_EV, &hdcp_ctrl->auth_event);
			wake_up_all(&hdcp_ctrl->auth_event_queue);
		}
	}

	if (hdcp_int_status & HDMI_HDCP_INT_CTRL_AUTH_FAIL_INT) {
		reg_val = hdmi_read(hdmi, REG_HDMI_HDCP_LINK0_STATUS);
		pr_info("%s: AUTH_FAIL_INT rcvd, LINK0_STATUS=0x%08x\n",
			__func__, reg_val);
		if (HDCP_STATE_AUTHENTICATED == hdcp_ctrl->hdcp_state)
			queue_work(hdmi->workq, &hdcp_ctrl->hdcp_reauth_work);
		else if (HDCP_STATE_AUTHENTICATING ==
				hdcp_ctrl->hdcp_state) {
			set_bit(AUTH_RESULT_RDY_EV, &hdcp_ctrl->auth_event);
			wake_up_all(&hdcp_ctrl->auth_event_queue);
		}
	}
}

static int hdmi_hdcp_msleep(struct hdmi_hdcp_ctrl *hdcp_ctrl, u32 ms, u32 ev)
{
	int rc;

	rc = wait_event_timeout(hdcp_ctrl->auth_event_queue,
		!!test_bit(ev, &hdcp_ctrl->auth_event),
		msecs_to_jiffies(ms));
	if (rc) {
		pr_info("%s: msleep is canceled by event %d\n",
				__func__, ev);
		clear_bit(ev, &hdcp_ctrl->auth_event);
		return -ECANCELED;
	}

	return 0;
}

static int hdmi_hdcp_read_validate_aksv(struct hdmi_hdcp_ctrl *hdcp_ctrl)
{
	struct hdmi *hdmi = hdcp_ctrl->hdmi;

	/* Fetch aksv from QFPROM, this info should be public. */
	hdcp_ctrl->aksv_lsb = hdmi_qfprom_read(hdmi, HDCP_KSV_LSB);
	hdcp_ctrl->aksv_msb = hdmi_qfprom_read(hdmi, HDCP_KSV_MSB);

	/* check there are 20 ones in AKSV */
	if ((hweight32(hdcp_ctrl->aksv_lsb) + hweight32(hdcp_ctrl->aksv_msb))
			!= 20) {
		pr_err("%s: AKSV QFPROM doesn't have 20 1's, 20 0's\n",
			__func__);
		pr_err("%s: QFPROM AKSV chk failed (AKSV=%02x%08x)\n",
			__func__, hdcp_ctrl->aksv_msb,
			hdcp_ctrl->aksv_lsb);
		return -EINVAL;
	}
	DBG("AKSV=%02x%08x", hdcp_ctrl->aksv_msb, hdcp_ctrl->aksv_lsb);

	return 0;
}

static int reset_hdcp_ddc_failures(struct hdmi_hdcp_ctrl *hdcp_ctrl)
{
	struct hdmi *hdmi = hdcp_ctrl->hdmi;
	u32 reg_val, failure, nack0;
	int rc = 0;

	/* Check for any DDC transfer failures */
	reg_val = hdmi_read(hdmi, REG_HDMI_HDCP_DDC_STATUS);
	failure = reg_val & HDMI_HDCP_DDC_STATUS_FAILED;
	nack0 = reg_val & HDMI_HDCP_DDC_STATUS_NACK0;
	DBG("HDCP_DDC_STATUS=0x%x, FAIL=%d, NACK0=%d",
		reg_val, failure, nack0);

	if (failure) {
		/*
		 * 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.
		 */
		DBG("DDC failure detected");

		/* First, Disable DDC */
		hdmi_write(hdmi, REG_HDMI_HDCP_DDC_CTRL_0,
			HDMI_HDCP_DDC_CTRL_0_DISABLE);

		/* ACK the Failure to Clear it */
		reg_val = hdmi_read(hdmi, REG_HDMI_HDCP_DDC_CTRL_1);
		reg_val |= HDMI_HDCP_DDC_CTRL_1_FAILED_ACK;
		hdmi_write(hdmi, REG_HDMI_HDCP_DDC_CTRL_1, reg_val);

		/* Check if the FAILURE got Cleared */
		reg_val = hdmi_read(hdmi, REG_HDMI_HDCP_DDC_STATUS);
		if (reg_val & HDMI_HDCP_DDC_STATUS_FAILED)
			pr_info("%s: Unable to clear HDCP DDC Failure\n",
				__func__);

		/* Re-Enable HDCP DDC */
		hdmi_write(hdmi, REG_HDMI_HDCP_DDC_CTRL_0, 0);
	}

	if (nack0) {
		DBG("Before: HDMI_DDC_SW_STATUS=0x%08x",
			hdmi_read(hdmi, REG_HDMI_DDC_SW_STATUS));
		/* Reset HDMI DDC software status */
		reg_val = hdmi_read(hdmi, REG_HDMI_DDC_CTRL);
		reg_val |= HDMI_DDC_CTRL_SW_STATUS_RESET;
		hdmi_write(hdmi, REG_HDMI_DDC_CTRL, reg_val);

		rc = hdmi_hdcp_msleep(hdcp_ctrl, 20, AUTH_ABORT_EV);

		reg_val = hdmi_read(hdmi, REG_HDMI_DDC_CTRL);
		reg_val &= ~HDMI_DDC_CTRL_SW_STATUS_RESET;
		hdmi_write(hdmi, REG_HDMI_DDC_CTRL, reg_val);

		/* Reset HDMI DDC Controller */
		reg_val = hdmi_read(hdmi, REG_HDMI_DDC_CTRL);
		reg_val |= HDMI_DDC_CTRL_SOFT_RESET;
		hdmi_write(hdmi, REG_HDMI_DDC_CTRL, reg_val);

		/* If previous msleep is aborted, skip this msleep */
		if (!rc)
			rc = hdmi_hdcp_msleep(hdcp_ctrl, 20, AUTH_ABORT_EV);

		reg_val = hdmi_read(hdmi, REG_HDMI_DDC_CTRL);
		reg_val &= ~HDMI_DDC_CTRL_SOFT_RESET;
		hdmi_write(hdmi, REG_HDMI_DDC_CTRL, reg_val);
		DBG("After: HDMI_DDC_SW_STATUS=0x%08x",
			hdmi_read(hdmi, REG_HDMI_DDC_SW_STATUS));
	}

	return rc;
}

static int hdmi_hdcp_hw_ddc_clean(struct hdmi_hdcp_ctrl *hdcp_ctrl)
{
	int rc;
	u32 hdcp_ddc_status, ddc_hw_status;
	u32 xfer_done, xfer_req, hw_done;
	bool hw_not_ready;
	u32 timeout_count;
	struct hdmi *hdmi = hdcp_ctrl->hdmi;

	if (hdmi_read(hdmi, REG_HDMI_DDC_HW_STATUS) == 0)
		return 0;

	/* Wait to be clean on DDC HW engine */
	timeout_count = 100;
	do {
		hdcp_ddc_status = hdmi_read(hdmi, REG_HDMI_HDCP_DDC_STATUS);
		ddc_hw_status = hdmi_read(hdmi, REG_HDMI_DDC_HW_STATUS);

		xfer_done = hdcp_ddc_status & HDMI_HDCP_DDC_STATUS_XFER_DONE;
		xfer_req = hdcp_ddc_status & HDMI_HDCP_DDC_STATUS_XFER_REQ;
		hw_done = ddc_hw_status & HDMI_DDC_HW_STATUS_DONE;
		hw_not_ready = !xfer_done || xfer_req || !hw_done;

		if (hw_not_ready)
			break;

		timeout_count--;
		if (!timeout_count) {
			pr_warn("%s: hw_ddc_clean failed\n", __func__);
			return -ETIMEDOUT;
		}

		rc = hdmi_hdcp_msleep(hdcp_ctrl, 20, AUTH_ABORT_EV);
		if (rc)
			return rc;
	} while (1);

	return 0;
}

static void hdmi_hdcp_reauth_work(struct work_struct *work)
{
	struct hdmi_hdcp_ctrl *hdcp_ctrl = container_of(work,
		struct hdmi_hdcp_ctrl, hdcp_reauth_work);
	struct hdmi *hdmi = hdcp_ctrl->hdmi;
	unsigned long flags;
	u32 reg_val;

	DBG("HDCP REAUTH WORK");
	/*
	 * Disable HPD circuitry.
	 * This is needed to reset the HDCP cipher engine so that when we
	 * attempt a re-authentication, HW would clear the AN0_READY and
	 * AN1_READY bits in HDMI_HDCP_LINK0_STATUS register
	 */
	spin_lock_irqsave(&hdmi->reg_lock, flags);
	reg_val = hdmi_read(hdmi, REG_HDMI_HPD_CTRL);
	reg_val &= ~HDMI_HPD_CTRL_ENABLE;
	hdmi_write(hdmi, REG_HDMI_HPD_CTRL, reg_val);

	/* Disable HDCP interrupts */
	hdmi_write(hdmi, REG_HDMI_HDCP_INT_CTRL, 0);
	spin_unlock_irqrestore(&hdmi->reg_lock, flags);

	hdmi_write(hdmi, REG_HDMI_HDCP_RESET,
		HDMI_HDCP_RESET_LINK0_DEAUTHENTICATE);

	/* Wait to be clean on DDC HW engine */
	if (hdmi_hdcp_hw_ddc_clean(hdcp_ctrl)) {
		pr_info("%s: reauth work aborted\n", __func__);
		return;
	}

	/* Disable encryption and disable the HDCP block */
	hdmi_write(hdmi, REG_HDMI_HDCP_CTRL, 0);

	/* Enable HPD circuitry */
	spin_lock_irqsave(&hdmi->reg_lock, flags);
	reg_val = hdmi_read(hdmi, REG_HDMI_HPD_CTRL);
	reg_val |= HDMI_HPD_CTRL_ENABLE;
	hdmi_write(hdmi, REG_HDMI_HPD_CTRL, reg_val);
	spin_unlock_irqrestore(&hdmi->reg_lock, flags);

	/*
	 * Only retry defined times then abort current authenticating process
	 */
	if (++hdcp_ctrl->auth_retries == AUTH_RETRIES_TIME) {
		hdcp_ctrl->hdcp_state = HDCP_STATE_INACTIVE;
		hdcp_ctrl->auth_retries = 0;
		pr_info("%s: abort reauthentication!\n", __func__);

		return;
	}

	DBG("Queue AUTH WORK");
	hdcp_ctrl->hdcp_state = HDCP_STATE_AUTHENTICATING;
	queue_work(hdmi->workq, &hdcp_ctrl->hdcp_auth_work);
}

static int hdmi_hdcp_auth_prepare(struct hdmi_hdcp_ctrl *hdcp_ctrl)
{
	struct hdmi *hdmi = hdcp_ctrl->hdmi;
	u32 link0_status;
	u32 reg_val;
	unsigned long flags;
	int rc;

	if (!hdcp_ctrl->aksv_valid) {
		rc = hdmi_hdcp_read_validate_aksv(hdcp_ctrl);
		if (rc) {
			pr_err("%s: ASKV validation failed\n", __func__);
			hdcp_ctrl->hdcp_state = HDCP_STATE_NO_AKSV;
			return -ENOTSUPP;
		}
		hdcp_ctrl->aksv_valid = true;
	}

	spin_lock_irqsave(&hdmi->reg_lock, flags);
	/* disable HDMI Encrypt */
	reg_val = hdmi_read(hdmi, REG_HDMI_CTRL);
	reg_val &= ~HDMI_CTRL_ENCRYPTED;
	hdmi_write(hdmi, REG_HDMI_CTRL, reg_val);

	/* Enabling Software DDC */
	reg_val = hdmi_read(hdmi, REG_HDMI_DDC_ARBITRATION);
	reg_val &= ~HDMI_DDC_ARBITRATION_HW_ARBITRATION;
	hdmi_write(hdmi, REG_HDMI_DDC_ARBITRATION, reg_val);
	spin_unlock_irqrestore(&hdmi->reg_lock, flags);

	/*
	 * Write AKSV read from QFPROM to the HDCP registers.
	 * This step is needed for HDCP authentication and must be
	 * written before enabling HDCP.
	 */
	hdmi_write(hdmi, REG_HDMI_HDCP_SW_LOWER_AKSV, hdcp_ctrl->aksv_lsb);
	hdmi_write(hdmi, REG_HDMI_HDCP_SW_UPPER_AKSV, hdcp_ctrl->aksv_msb);

	/*
	 * HDCP setup prior to enabling HDCP_CTRL.
	 * Setup seed values for random number An.
	 */
	hdmi_write(hdmi, REG_HDMI_HDCP_ENTROPY_CTRL0, 0xB1FFB0FF);
	hdmi_write(hdmi, REG_HDMI_HDCP_ENTROPY_CTRL1, 0xF00DFACE);

	/* Disable the RngCipher state */
	reg_val = hdmi_read(hdmi, REG_HDMI_HDCP_DEBUG_CTRL);
	reg_val &= ~HDMI_HDCP_DEBUG_CTRL_RNG_CIPHER;
	hdmi_write(hdmi, REG_HDMI_HDCP_DEBUG_CTRL, reg_val);
	DBG("HDCP_DEBUG_CTRL=0x%08x",
		hdmi_read(hdmi, REG_HDMI_HDCP_DEBUG_CTRL));

	/*
	 * Ensure that all register writes are completed before
	 * enabling HDCP cipher
	 */
	wmb();

	/*
	 * Enable HDCP
	 * This needs to be done as early as possible in order for the
	 * hardware to make An available to read
	 */
	hdmi_write(hdmi, REG_HDMI_HDCP_CTRL, HDMI_HDCP_CTRL_ENABLE);

	/*
	 * If we had stale values for the An ready bit, it should most
	 * likely be cleared now after enabling HDCP cipher
	 */
	link0_status = hdmi_read(hdmi, REG_HDMI_HDCP_LINK0_STATUS);
	DBG("After enabling HDCP Link0_Status=0x%08x", link0_status);
	if (!(link0_status &
		(HDMI_HDCP_LINK0_STATUS_AN_0_READY |
		HDMI_HDCP_LINK0_STATUS_AN_1_READY)))
		DBG("An not ready after enabling HDCP");

	/* Clear any DDC failures from previous tries before enable HDCP*/
	rc = reset_hdcp_ddc_failures(hdcp_ctrl);

	return rc;
}

static void hdmi_hdcp_auth_fail(struct hdmi_hdcp_ctrl *hdcp_ctrl)
{
	struct hdmi *hdmi = hdcp_ctrl->hdmi;
	u32 reg_val;
	unsigned long flags;

	DBG("hdcp auth failed, queue reauth work");
	/* clear HDMI Encrypt */
	spin_lock_irqsave(&hdmi->reg_lock, flags);
	reg_val = hdmi_read(hdmi, REG_HDMI_CTRL);
	reg_val &= ~HDMI_CTRL_ENCRYPTED;
	hdmi_write(hdmi, REG_HDMI_CTRL, reg_val);
	spin_unlock_irqrestore(&hdmi->reg_lock, flags);

	hdcp_ctrl->hdcp_state = HDCP_STATE_AUTH_FAILED;
	queue_work(hdmi->workq, &hdcp_ctrl->hdcp_reauth_work);
}

static void hdmi_hdcp_auth_done(struct hdmi_hdcp_ctrl *hdcp_ctrl)
{
	struct hdmi *hdmi = hdcp_ctrl->hdmi;
	u32 reg_val;
	unsigned long flags;

	/*
	 * Disable software DDC before going into part3 to make sure
	 * there is no Arbitration between software and hardware for DDC
	 */
	spin_lock_irqsave(&hdmi->reg_lock, flags);
	reg_val = hdmi_read(hdmi, REG_HDMI_DDC_ARBITRATION);
	reg_val |= HDMI_DDC_ARBITRATION_HW_ARBITRATION;
	hdmi_write(hdmi, REG_HDMI_DDC_ARBITRATION, reg_val);
	spin_unlock_irqrestore(&hdmi->reg_lock, flags);

	/* enable HDMI Encrypt */
	spin_lock_irqsave(&hdmi->reg_lock, flags);
	reg_val = hdmi_read(hdmi, REG_HDMI_CTRL);
	reg_val |= HDMI_CTRL_ENCRYPTED;
	hdmi_write(hdmi, REG_HDMI_CTRL, reg_val);
	spin_unlock_irqrestore(&hdmi->reg_lock, flags);

	hdcp_ctrl->hdcp_state = HDCP_STATE_AUTHENTICATED;
	hdcp_ctrl->auth_retries = 0;
}

/*
 * hdcp authenticating part 1
 * Wait Key/An ready
 * Read BCAPS from sink
 * Write BCAPS and AKSV into HDCP engine
 * Write An and AKSV to sink
 * Read BKSV from sink and write into HDCP engine
 */
static int hdmi_hdcp_wait_key_an_ready(struct hdmi_hdcp_ctrl *hdcp_ctrl)
{
	int rc;
	struct hdmi *hdmi = hdcp_ctrl->hdmi;
	u32 link0_status, keys_state;
	u32 timeout_count;
	bool an_ready;

	/* Wait for HDCP keys to be checked and validated */
	timeout_count = 100;
	do {
		link0_status = hdmi_read(hdmi, REG_HDMI_HDCP_LINK0_STATUS);
		keys_state = (link0_status >> 28) & 0x7;
		if (keys_state == HDCP_KEYS_STATE_VALID)
			break;

		DBG("Keys not ready(%d). s=%d, l0=%0x08x",
			timeout_count, keys_state, link0_status);

		timeout_count--;
		if (!timeout_count) {
			pr_err("%s: Wait key state timedout", __func__);
			return -ETIMEDOUT;
		}

		rc = hdmi_hdcp_msleep(hdcp_ctrl, 20, AUTH_ABORT_EV);
		if (rc)
			return rc;
	} while (1);

	timeout_count = 100;
	do {
		link0_status = hdmi_read(hdmi, REG_HDMI_HDCP_LINK0_STATUS);
		an_ready = (link0_status & HDMI_HDCP_LINK0_STATUS_AN_0_READY)
			&& (link0_status & HDMI_HDCP_LINK0_STATUS_AN_1_READY);
		if (an_ready)
			break;

		DBG("An not ready(%d). l0_status=0x%08x",
			timeout_count, link0_status);

		timeout_count--;
		if (!timeout_count) {
			pr_err("%s: Wait An timedout", __func__);
			return -ETIMEDOUT;
		}

		rc = hdmi_hdcp_msleep(hdcp_ctrl, 20, AUTH_ABORT_EV);
		if (rc)
			return rc;
	} while (1);

	return 0;
}

static int hdmi_hdcp_send_aksv_an(struct hdmi_hdcp_ctrl *hdcp_ctrl)
{
	int rc = 0;
	struct hdmi *hdmi = hdcp_ctrl->hdmi;
	u32 link0_aksv_0, link0_aksv_1;
	u32 link0_an[2];
	u8 aksv[5];

	/* Read An0 and An1 */
	link0_an[0] = hdmi_read(hdmi, REG_HDMI_HDCP_RCVPORT_DATA5);
	link0_an[1] = hdmi_read(hdmi, REG_HDMI_HDCP_RCVPORT_DATA6);

	/* Read AKSV */
	link0_aksv_0 = hdmi_read(hdmi, REG_HDMI_HDCP_RCVPORT_DATA3);
	link0_aksv_1 = hdmi_read(hdmi, REG_HDMI_HDCP_RCVPORT_DATA4);

	DBG("Link ASKV=%08x%08x", link0_aksv_0, link0_aksv_1);
	/* 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;

	/* Write An to offset 0x18 */
	rc = hdmi_ddc_write(hdmi, HDCP_PORT_ADDR, 0x18, (u8 *)link0_an,
		(u16)sizeof(link0_an));
	if (rc) {
		pr_err("%s:An write failed\n", __func__);
		return rc;
	}
	DBG("Link0-An=%08x%08x", link0_an[0], link0_an[1]);

	/* Write AKSV to offset 0x10 */
	rc = hdmi_ddc_write(hdmi, HDCP_PORT_ADDR, 0x10, aksv, 5);
	if (rc) {
		pr_err("%s:AKSV write failed\n", __func__);
		return rc;
	}
	DBG("Link0-AKSV=%02x%08x", link0_aksv_1 & 0xFF, link0_aksv_0);

	return 0;
}

static int hdmi_hdcp_recv_bksv(struct hdmi_hdcp_ctrl *hdcp_ctrl)
{
	int rc = 0;
	struct hdmi *hdmi = hdcp_ctrl->hdmi;
	u8 bksv[5];
	u32 reg[2], data[2];

	/* Read BKSV at offset 0x00 */
	rc = hdmi_ddc_read(hdmi, HDCP_PORT_ADDR, 0x00, bksv, 5);
	if (rc) {
		pr_err("%s:BKSV read failed\n", __func__);
		return rc;
	}

	hdcp_ctrl->bksv_lsb = bksv[0] | (bksv[1] << 8) |
		(bksv[2] << 16) | (bksv[3] << 24);
	hdcp_ctrl->bksv_msb = bksv[4];
	DBG(":BKSV=%02x%08x", hdcp_ctrl->bksv_msb, hdcp_ctrl->bksv_lsb);

	/* check there are 20 ones in BKSV */
	if ((hweight32(hdcp_ctrl->bksv_lsb) + hweight32(hdcp_ctrl->bksv_msb))
			!= 20) {
		pr_err(": BKSV doesn't have 20 1's and 20 0's\n");
		pr_err(": BKSV chk fail. BKSV=%02x%02x%02x%02x%02x\n",
			bksv[4], bksv[3], bksv[2], bksv[1], bksv[0]);
		return -EINVAL;
	}

	/* Write BKSV read from sink to HDCP registers */
	reg[0] = REG_HDMI_HDCP_RCVPORT_DATA0;
	data[0] = hdcp_ctrl->bksv_lsb;
	reg[1] = REG_HDMI_HDCP_RCVPORT_DATA1;
	data[1] = hdcp_ctrl->bksv_msb;
	rc = hdmi_hdcp_scm_wr(hdcp_ctrl, reg, data, 2);

	return rc;
}

static int hdmi_hdcp_recv_bcaps(struct hdmi_hdcp_ctrl *hdcp_ctrl)
{
	int rc = 0;
	struct hdmi *hdmi = hdcp_ctrl->hdmi;
	u32 reg, data;
	u8 bcaps;

	rc = hdmi_ddc_read(hdmi, HDCP_PORT_ADDR, 0x40, &bcaps, 1);
	if (rc) {
		pr_err("%s:BCAPS read failed\n", __func__);
		return rc;
	}
	DBG("BCAPS=%02x", bcaps);

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

	/* Write BCAPS to the hardware */
	reg = REG_HDMI_HDCP_RCVPORT_DATA12;
	data = (u32)bcaps;
	rc = hdmi_hdcp_scm_wr(hdcp_ctrl, &reg, &data, 1);

	return rc;
}

static int hdmi_hdcp_auth_part1_key_exchange(struct hdmi_hdcp_ctrl *hdcp_ctrl)
{
	struct hdmi *hdmi = hdcp_ctrl->hdmi;
	unsigned long flags;
	int rc;

	/* Wait for AKSV key and An ready */
	rc = hdmi_hdcp_wait_key_an_ready(hdcp_ctrl);
	if (rc) {
		pr_err("%s: wait key and an ready failed\n", __func__);
		return rc;
	};

	/* Read BCAPS and send to HDCP engine */
	rc = hdmi_hdcp_recv_bcaps(hdcp_ctrl);
	if (rc) {
		pr_err("%s: read bcaps error, abort\n", __func__);
		return rc;
	}

	/*
	 * 1.1_Features turned off by default.
	 * No need to write AInfo since 1.1_Features is disabled.
	 */
	hdmi_write(hdmi, REG_HDMI_HDCP_RCVPORT_DATA4, 0);

	/* Send AKSV and An to sink */
	rc = hdmi_hdcp_send_aksv_an(hdcp_ctrl);
	if (rc) {
		pr_err("%s:An/Aksv write failed\n", __func__);
		return rc;
	}

	/* Read BKSV and send to HDCP engine*/
	rc = hdmi_hdcp_recv_bksv(hdcp_ctrl);
	if (rc) {
		pr_err("%s:BKSV Process failed\n", __func__);
		return rc;
	}

	/* Enable HDCP interrupts and ack/clear any stale interrupts */
	spin_lock_irqsave(&hdmi->reg_lock, flags);
	hdmi_write(hdmi, REG_HDMI_HDCP_INT_CTRL,
		HDMI_HDCP_INT_CTRL_AUTH_SUCCESS_ACK |
		HDMI_HDCP_INT_CTRL_AUTH_SUCCESS_MASK |
		HDMI_HDCP_INT_CTRL_AUTH_FAIL_ACK |
		HDMI_HDCP_INT_CTRL_AUTH_FAIL_MASK |
		HDMI_HDCP_INT_CTRL_AUTH_FAIL_INFO_ACK);
	spin_unlock_irqrestore(&hdmi->reg_lock, flags);

	return 0;
}

/* read R0' from sink and pass it to HDCP engine */
static int hdmi_hdcp_auth_part1_recv_r0(struct hdmi_hdcp_ctrl *hdcp_ctrl)
{
	struct hdmi *hdmi = hdcp_ctrl->hdmi;
	int rc = 0;
	u8 buf[2];

	/*
	 * HDCP Compliance Test case 1A-01:
	 * Wait here at least 100ms before reading R0'
	 */
	rc = hdmi_hdcp_msleep(hdcp_ctrl, 125, AUTH_ABORT_EV);
	if (rc)
		return rc;

	/* Read R0' at offset 0x08 */
	rc = hdmi_ddc_read(hdmi, HDCP_PORT_ADDR, 0x08, buf, 2);
	if (rc) {
		pr_err("%s:R0' read failed\n", __func__);
		return rc;
	}
	DBG("R0'=%02x%02x", buf[1], buf[0]);

	/* Write R0' to HDCP registers and check to see if it is a match */
	hdmi_write(hdmi, REG_HDMI_HDCP_RCVPORT_DATA2_0,
		(((u32)buf[1]) << 8) | buf[0]);

	return 0;
}

/* Wait for authenticating result: R0/R0' are matched or not */
static int hdmi_hdcp_auth_part1_verify_r0(struct hdmi_hdcp_ctrl *hdcp_ctrl)
{
	struct hdmi *hdmi = hdcp_ctrl->hdmi;
	u32 link0_status;
	int rc;

	/* wait for hdcp irq, 10 sec should be long enough */
	rc = hdmi_hdcp_msleep(hdcp_ctrl, 10000, AUTH_RESULT_RDY_EV);
	if (!rc) {
		pr_err("%s: Wait Auth IRQ timeout\n", __func__);
		return -ETIMEDOUT;
	}

	link0_status = hdmi_read(hdmi, REG_HDMI_HDCP_LINK0_STATUS);
	if (!(link0_status & HDMI_HDCP_LINK0_STATUS_RI_MATCHES)) {
		pr_err("%s: Authentication Part I failed\n", __func__);
		return -EINVAL;
	}

	/* Enable HDCP Encryption */
	hdmi_write(hdmi, REG_HDMI_HDCP_CTRL,
		HDMI_HDCP_CTRL_ENABLE |
		HDMI_HDCP_CTRL_ENCRYPTION_ENABLE);

	return 0;
}

static int hdmi_hdcp_recv_check_bstatus(struct hdmi_hdcp_ctrl *hdcp_ctrl,
	u16 *pbstatus)
{
	int rc;
	struct hdmi *hdmi = hdcp_ctrl->hdmi;
	bool max_devs_exceeded = false, max_cascade_exceeded = false;
	u32 repeater_cascade_depth = 0, down_stream_devices = 0;
	u16 bstatus;
	u8 buf[2];

	/* Read BSTATUS at offset 0x41 */
	rc = hdmi_ddc_read(hdmi, HDCP_PORT_ADDR, 0x41, buf, 2);
	if (rc) {
		pr_err("%s: BSTATUS read failed\n", __func__);
		goto error;
	}
	*pbstatus = bstatus = (buf[1] << 8) | buf[0];


	down_stream_devices = bstatus & 0x7F;
	repeater_cascade_depth = (bstatus >> 8) & 0x7;
	max_devs_exceeded = (bstatus & BIT(7)) ? true : false;
	max_cascade_exceeded = (bstatus & BIT(11)) ? true : false;

	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.
		 */
		pr_err("%s: No downstream devices\n", __func__);
		rc = -EINVAL;
		goto error;
	}

	/*
	 * HDCP Compliance 1B-05:
	 * Check if no. of devices connected to repeater
	 * exceed max_devices_connected from bit 7 of Bstatus.
	 */
	if (max_devs_exceeded) {
		pr_err("%s: no. of devs connected exceeds max allowed",
			__func__);
		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.
	 */
	if (max_cascade_exceeded) {
		pr_err("%s: no. of cascade conn exceeds max allowed",
			__func__);
		rc = -EINVAL;
		goto error;
	}

error:
	hdcp_ctrl->dev_count = down_stream_devices;
	hdcp_ctrl->max_cascade_exceeded = max_cascade_exceeded;
	hdcp_ctrl->max_dev_exceeded = max_devs_exceeded;
	hdcp_ctrl->depth = repeater_cascade_depth;
	return rc;
}

static int hdmi_hdcp_auth_part2_wait_ksv_fifo_ready(
	struct hdmi_hdcp_ctrl *hdcp_ctrl)
{
	int rc;
	struct hdmi *hdmi = hdcp_ctrl->hdmi;
	u32 reg, data;
	u32 timeout_count;
	u16 bstatus;
	u8 bcaps;

	/*
	 * 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 = 100;
	do {
		/* Read BCAPS at offset 0x40 */
		rc = hdmi_ddc_read(hdmi, HDCP_PORT_ADDR, 0x40, &bcaps, 1);
		if (rc) {
			pr_err("%s: BCAPS read failed\n", __func__);
			return rc;
		}

		if (bcaps & BIT(5))
			break;

		timeout_count--;
		if (!timeout_count) {
			pr_err("%s: Wait KSV fifo ready timedout", __func__);
			return -ETIMEDOUT;
		}

		rc = hdmi_hdcp_msleep(hdcp_ctrl, 20, AUTH_ABORT_EV);
		if (rc)
			return rc;
	} while (1);

	rc = hdmi_hdcp_recv_check_bstatus(hdcp_ctrl, &bstatus);
	if (rc) {
		pr_err("%s: bstatus error\n", __func__);
		return rc;
	}

	/* Write BSTATUS and BCAPS to HDCP registers */
	reg = REG_HDMI_HDCP_RCVPORT_DATA12;
	data = bcaps | (bstatus << 8);
	rc = hdmi_hdcp_scm_wr(hdcp_ctrl, &reg, &data, 1);
	if (rc) {
		pr_err("%s: BSTATUS write failed\n", __func__);
		return rc;
	}

	return 0;
}

/*
 * hdcp authenticating part 2: 2nd
 * read ksv fifo from sink
 * transfer V' from sink to HDCP engine
 * reset SHA engine
 */
static int hdmi_hdcp_transfer_v_h(struct hdmi_hdcp_ctrl *hdcp_ctrl)
{
	struct hdmi *hdmi = hdcp_ctrl->hdmi;
	int rc = 0;
	struct hdmi_hdcp_reg_data reg_data[]  = {
		{REG_HDMI_HDCP_RCVPORT_DATA7,  0x20, "V' H0"},
		{REG_HDMI_HDCP_RCVPORT_DATA8,  0x24, "V' H1"},
		{REG_HDMI_HDCP_RCVPORT_DATA9,  0x28, "V' H2"},
		{REG_HDMI_HDCP_RCVPORT_DATA10, 0x2C, "V' H3"},
		{REG_HDMI_HDCP_RCVPORT_DATA11, 0x30, "V' H4"},
	};
	struct hdmi_hdcp_reg_data *rd;
	u32 size = ARRAY_SIZE(reg_data);
	u32 reg[ARRAY_SIZE(reg_data)];
	u32 data[ARRAY_SIZE(reg_data)];
	int i;

	for (i = 0; i < size; i++) {
		rd = &reg_data[i];
		rc = hdmi_ddc_read(hdmi, HDCP_PORT_ADDR,
			rd->off, (u8 *)&data[i], (u16)sizeof(data[i]));
		if (rc) {
			pr_err("%s: Read %s failed\n", __func__, rd->name);
			goto error;
		}

		DBG("%s =%x", rd->name, data[i]);
		reg[i] = reg_data[i].reg_id;
	}

	rc = hdmi_hdcp_scm_wr(hdcp_ctrl, reg, data, size);

error:
	return rc;
}

static int hdmi_hdcp_recv_ksv_fifo(struct hdmi_hdcp_ctrl *hdcp_ctrl)
{
	int rc;
	struct hdmi *hdmi = hdcp_ctrl->hdmi;
	u32 ksv_bytes;

	ksv_bytes = 5 * hdcp_ctrl->dev_count;

	rc = hdmi_ddc_read(hdmi, HDCP_PORT_ADDR, 0x43,
		hdcp_ctrl->ksv_list, ksv_bytes);
	if (rc)
		pr_err("%s: KSV FIFO read failed\n", __func__);

	return rc;
}

static int hdmi_hdcp_reset_sha_engine(struct hdmi_hdcp_ctrl *hdcp_ctrl)
{
	u32 reg[2], data[2];
	u32 rc  = 0;

	reg[0] = REG_HDMI_HDCP_SHA_CTRL;
	data[0] = HDCP_REG_ENABLE;
	reg[1] = REG_HDMI_HDCP_SHA_CTRL;
	data[1] = HDCP_REG_DISABLE;

	rc = hdmi_hdcp_scm_wr(hdcp_ctrl, reg, data, 2);

	return rc;
}

static int hdmi_hdcp_auth_part2_recv_ksv_fifo(
	struct hdmi_hdcp_ctrl *hdcp_ctrl)
{
	int rc;
	u32 timeout_count;

	/*
	 * Read KSV FIFO over DDC
	 * Key Selection 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).
	 */
	timeout_count = 100;
	do {
		rc = hdmi_hdcp_recv_ksv_fifo(hdcp_ctrl);
		if (!rc)
			break;

		timeout_count--;
		if (!timeout_count) {
			pr_err("%s: Recv ksv fifo timedout", __func__);
			return -ETIMEDOUT;
		}

		rc = hdmi_hdcp_msleep(hdcp_ctrl, 25, AUTH_ABORT_EV);
		if (rc)
			return rc;
	} while (1);

	rc = hdmi_hdcp_transfer_v_h(hdcp_ctrl);
	if (rc) {
		pr_err("%s: transfer V failed\n", __func__);
		return rc;
	}

	/* reset SHA engine before write ksv fifo */
	rc = hdmi_hdcp_reset_sha_engine(hdcp_ctrl);
	if (rc) {
		pr_err("%s: fail to reset sha engine\n", __func__);
		return rc;
	}

	return 0;
}

/*
 * Write KSV FIFO to HDCP_SHA_DATA.
 * This is done 1 byte at time starting with the LSB.
 * Once 64 bytes have been written, we need to poll for
 * HDCP_SHA_BLOCK_DONE before writing any further
 * If the last byte is written, we need to poll for
 * HDCP_SHA_COMP_DONE to wait until HW finish
 */
static int hdmi_hdcp_write_ksv_fifo(struct hdmi_hdcp_ctrl *hdcp_ctrl)
{
	int i;
	struct hdmi *hdmi = hdcp_ctrl->hdmi;
	u32 ksv_bytes, last_byte = 0;
	u8 *ksv_fifo = NULL;
	u32 reg_val, data, reg;
	u32 rc  = 0;

	ksv_bytes  = 5 * hdcp_ctrl->dev_count;

	/* Check if need to wait for HW completion */
	if (hdcp_ctrl->ksv_fifo_w_index) {
		reg_val = hdmi_read(hdmi, REG_HDMI_HDCP_SHA_STATUS);
		DBG("HDCP_SHA_STATUS=%08x", reg_val);
		if (hdcp_ctrl->ksv_fifo_w_index == ksv_bytes) {
			/* check COMP_DONE if last write */
			if (reg_val & HDMI_HDCP_SHA_STATUS_COMP_DONE) {
				DBG("COMP_DONE");
				return 0;
			} else {
				return -EAGAIN;
			}
		} else {
			/* check BLOCK_DONE if not last write */
			if (!(reg_val & HDMI_HDCP_SHA_STATUS_BLOCK_DONE))
				return -EAGAIN;

			DBG("BLOCK_DONE");
		}
	}

	ksv_bytes  -= hdcp_ctrl->ksv_fifo_w_index;
	if (ksv_bytes <= 64)
		last_byte = 1;
	else
		ksv_bytes = 64;

	ksv_fifo = hdcp_ctrl->ksv_list;
	ksv_fifo += hdcp_ctrl->ksv_fifo_w_index;

	for (i = 0; i < ksv_bytes; i++) {
		/* Write KSV byte and set DONE bit[0] for last byte*/
		reg_val = ksv_fifo[i] << 16;
		if ((i == (ksv_bytes - 1)) && last_byte)
			reg_val |= HDMI_HDCP_SHA_DATA_DONE;

		reg = REG_HDMI_HDCP_SHA_DATA;
		data = reg_val;
		rc = hdmi_hdcp_scm_wr(hdcp_ctrl, &reg, &data, 1);

		if (rc)
			return rc;
	}

	hdcp_ctrl->ksv_fifo_w_index += ksv_bytes;

	/*
	 *return -EAGAIN to notify caller to wait for COMP_DONE or BLOCK_DONE
	 */
	return -EAGAIN;
}

/* write ksv fifo into HDCP engine */
static int hdmi_hdcp_auth_part2_write_ksv_fifo(
	struct hdmi_hdcp_ctrl *hdcp_ctrl)
{
	int rc;
	u32 timeout_count;

	hdcp_ctrl->ksv_fifo_w_index = 0;
	timeout_count = 100;
	do {
		rc = hdmi_hdcp_write_ksv_fifo(hdcp_ctrl);
		if (!rc)
			break;

		if (rc != -EAGAIN)
			return rc;

		timeout_count--;
		if (!timeout_count) {
			pr_err("%s: Write KSV fifo timedout", __func__);
			return -ETIMEDOUT;
		}

		rc = hdmi_hdcp_msleep(hdcp_ctrl, 20, AUTH_ABORT_EV);
		if (rc)
			return rc;
	} while (1);

	return 0;
}

static int hdmi_hdcp_auth_part2_check_v_match(struct hdmi_hdcp_ctrl *hdcp_ctrl)
{
	int rc = 0;
	struct hdmi *hdmi = hdcp_ctrl->hdmi;
	u32 link0_status;
	u32 timeout_count = 100;

	do {
		link0_status = hdmi_read(hdmi, REG_HDMI_HDCP_LINK0_STATUS);
		if (link0_status & HDMI_HDCP_LINK0_STATUS_V_MATCHES)
			break;

		timeout_count--;
		if (!timeout_count) {
				pr_err("%s: HDCP V Match timedout", __func__);
				return -ETIMEDOUT;
		}

		rc = hdmi_hdcp_msleep(hdcp_ctrl, 20, AUTH_ABORT_EV);
		if (rc)
			return rc;
	} while (1);

	return 0;
}

static void hdmi_hdcp_auth_work(struct work_struct *work)
{
	struct hdmi_hdcp_ctrl *hdcp_ctrl = container_of(work,
		struct hdmi_hdcp_ctrl, hdcp_auth_work);
	int rc;

	rc = hdmi_hdcp_auth_prepare(hdcp_ctrl);
	if (rc) {
		pr_err("%s: auth prepare failed %d\n", __func__, rc);
		goto end;
	}

	/* HDCP PartI */
	rc = hdmi_hdcp_auth_part1_key_exchange(hdcp_ctrl);
	if (rc) {
		pr_err("%s: key exchange failed %d\n", __func__, rc);
		goto end;
	}

	rc = hdmi_hdcp_auth_part1_recv_r0(hdcp_ctrl);
	if (rc) {
		pr_err("%s: receive r0 failed %d\n", __func__, rc);
		goto end;
	}

	rc = hdmi_hdcp_auth_part1_verify_r0(hdcp_ctrl);
	if (rc) {
		pr_err("%s: verify r0 failed %d\n", __func__, rc);
		goto end;
	}
	pr_info("%s: Authentication Part I successful\n", __func__);
	if (hdcp_ctrl->ds_type == DS_RECEIVER)
		goto end;

	/* HDCP PartII */
	rc = hdmi_hdcp_auth_part2_wait_ksv_fifo_ready(hdcp_ctrl);
	if (rc) {
		pr_err("%s: wait ksv fifo ready failed %d\n", __func__, rc);
		goto end;
	}

	rc = hdmi_hdcp_auth_part2_recv_ksv_fifo(hdcp_ctrl);
	if (rc) {
		pr_err("%s: recv ksv fifo failed %d\n", __func__, rc);
		goto end;
	}

	rc = hdmi_hdcp_auth_part2_write_ksv_fifo(hdcp_ctrl);
	if (rc) {
		pr_err("%s: write ksv fifo failed %d\n", __func__, rc);
		goto end;
	}

	rc = hdmi_hdcp_auth_part2_check_v_match(hdcp_ctrl);
	if (rc)
		pr_err("%s: check v match failed %d\n", __func__, rc);

end:
	if (rc == -ECANCELED) {
		pr_info("%s: hdcp authentication canceled\n", __func__);
	} else if (rc == -ENOTSUPP) {
		pr_info("%s: hdcp is not supported\n", __func__);
	} else if (rc) {
		pr_err("%s: hdcp authentication failed\n", __func__);
		hdmi_hdcp_auth_fail(hdcp_ctrl);
	} else {
		hdmi_hdcp_auth_done(hdcp_ctrl);
	}
}

void hdmi_hdcp_on(struct hdmi_hdcp_ctrl *hdcp_ctrl)
{
	struct hdmi *hdmi = hdcp_ctrl->hdmi;
	u32 reg_val;
	unsigned long flags;

	if ((HDCP_STATE_INACTIVE != hdcp_ctrl->hdcp_state) ||
		(HDCP_STATE_NO_AKSV == hdcp_ctrl->hdcp_state)) {
		DBG("still active or activating or no askv. returning");
		return;
	}

	/* clear HDMI Encrypt */
	spin_lock_irqsave(&hdmi->reg_lock, flags);
	reg_val = hdmi_read(hdmi, REG_HDMI_CTRL);
	reg_val &= ~HDMI_CTRL_ENCRYPTED;
	hdmi_write(hdmi, REG_HDMI_CTRL, reg_val);
	spin_unlock_irqrestore(&hdmi->reg_lock, flags);

	hdcp_ctrl->auth_event = 0;
	hdcp_ctrl->hdcp_state = HDCP_STATE_AUTHENTICATING;
	hdcp_ctrl->auth_retries = 0;
	queue_work(hdmi->workq, &hdcp_ctrl->hdcp_auth_work);
}

void hdmi_hdcp_off(struct hdmi_hdcp_ctrl *hdcp_ctrl)
{
	struct hdmi *hdmi = hdcp_ctrl->hdmi;
	unsigned long flags;
	u32 reg_val;

	if ((HDCP_STATE_INACTIVE == hdcp_ctrl->hdcp_state) ||
		(HDCP_STATE_NO_AKSV == hdcp_ctrl->hdcp_state)) {
		DBG("hdcp inactive or no aksv. returning");
		return;
	}

	/*
	 * Disable HPD circuitry.
	 * This is needed to reset the HDCP cipher engine so that when we
	 * attempt a re-authentication, HW would clear the AN0_READY and
	 * AN1_READY bits in HDMI_HDCP_LINK0_STATUS register
	 */
	spin_lock_irqsave(&hdmi->reg_lock, flags);
	reg_val = hdmi_read(hdmi, REG_HDMI_HPD_CTRL);
	reg_val &= ~HDMI_HPD_CTRL_ENABLE;
	hdmi_write(hdmi, REG_HDMI_HPD_CTRL, reg_val);

	/*
	 * 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.
	 */
	hdmi_write(hdmi, REG_HDMI_HDCP_INT_CTRL, 0);
	spin_unlock_irqrestore(&hdmi->reg_lock, flags);

	/*
	 * Cancel any pending auth/reauth attempts.
	 * If one is ongoing, this will wait for it to finish.
	 * No more reauthentication attempts will be scheduled since we
	 * set the current state to inactive.
	 */
	set_bit(AUTH_ABORT_EV, &hdcp_ctrl->auth_event);
	wake_up_all(&hdcp_ctrl->auth_event_queue);
	cancel_work_sync(&hdcp_ctrl->hdcp_auth_work);
	cancel_work_sync(&hdcp_ctrl->hdcp_reauth_work);

	hdmi_write(hdmi, REG_HDMI_HDCP_RESET,
		HDMI_HDCP_RESET_LINK0_DEAUTHENTICATE);

	/* Disable encryption and disable the HDCP block */
	hdmi_write(hdmi, REG_HDMI_HDCP_CTRL, 0);

	spin_lock_irqsave(&hdmi->reg_lock, flags);
	reg_val = hdmi_read(hdmi, REG_HDMI_CTRL);
	reg_val &= ~HDMI_CTRL_ENCRYPTED;
	hdmi_write(hdmi, REG_HDMI_CTRL, reg_val);

	/* Enable HPD circuitry */
	reg_val = hdmi_read(hdmi, REG_HDMI_HPD_CTRL);
	reg_val |= HDMI_HPD_CTRL_ENABLE;
	hdmi_write(hdmi, REG_HDMI_HPD_CTRL, reg_val);
	spin_unlock_irqrestore(&hdmi->reg_lock, flags);

	hdcp_ctrl->hdcp_state = HDCP_STATE_INACTIVE;

	DBG("HDCP: Off");
}

struct hdmi_hdcp_ctrl *hdmi_hdcp_init(struct hdmi *hdmi)
{
	struct hdmi_hdcp_ctrl *hdcp_ctrl = NULL;

	if (!hdmi->qfprom_mmio) {
		pr_err("%s: HDCP is not supported without qfprom\n",
			__func__);
		return ERR_PTR(-EINVAL);
	}

	hdcp_ctrl = kzalloc(sizeof(*hdcp_ctrl), GFP_KERNEL);
	if (!hdcp_ctrl)
		return ERR_PTR(-ENOMEM);

	INIT_WORK(&hdcp_ctrl->hdcp_auth_work, hdmi_hdcp_auth_work);
	INIT_WORK(&hdcp_ctrl->hdcp_reauth_work, hdmi_hdcp_reauth_work);
	init_waitqueue_head(&hdcp_ctrl->auth_event_queue);
	hdcp_ctrl->hdmi = hdmi;
	hdcp_ctrl->hdcp_state = HDCP_STATE_INACTIVE;
	hdcp_ctrl->aksv_valid = false;

	if (qcom_scm_hdcp_available())
		hdcp_ctrl->tz_hdcp = true;
	else
		hdcp_ctrl->tz_hdcp = false;

	return hdcp_ctrl;
}

void hdmi_hdcp_destroy(struct hdmi *hdmi)
{
	if (hdmi && hdmi->hdcp_ctrl) {
		kfree(hdmi->hdcp_ctrl);
		hdmi->hdcp_ctrl = NULL;
	}
}
