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

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

msm: mdss: dp: fix hdcp 1.x interrupt and aux issues



Do not reset interrupt in Display Port driver as HDCP
module also uses same register for interrupts. Use proper
parameters for AUX APIs to avoid communication failures.

CRs-Fixed: 1050304
Change-Id: Ib7b046ca5a0071e571758fd656c86a3fd3be51af
Signed-off-by: default avatarAjay Singh Parmar <aparmar@codeaurora.org>
Signed-off-by: default avatarTatenda Chipeperekwa <tatendac@codeaurora.org>
parent ab26d098
Loading
Loading
Loading
Loading
+4 −6
Original line number Diff line number Diff line
@@ -1730,7 +1730,7 @@ irqreturn_t dp_isr(int irq, void *ptr)
{
	struct mdss_dp_drv_pdata *dp = (struct mdss_dp_drv_pdata *)ptr;
	unsigned char *base = dp->base;
	u32 isr1, isr2, mask1, mask2;
	u32 isr1, isr2, mask1;
	u32 ack;

	spin_lock(&dp->lock);
@@ -1738,13 +1738,11 @@ irqreturn_t dp_isr(int irq, void *ptr)
	isr2 = dp_read(base + DP_INTR_STATUS2);

	mask1 = isr1 & dp->mask1;
	mask2 = isr2 & dp->mask2;

	isr1 &= ~mask1;	/* remove masks bit */
	isr2 &= ~mask2;

	pr_debug("isr=%x mask=%x isr2=%x mask2=%x\n",
			isr1, mask1, isr2, mask2);
	pr_debug("isr=%x mask=%x isr2=%x\n",
			isr1, mask1, isr2);

	ack = isr1 & EDP_INTR_STATUS1;
	ack <<= 1;	/* ack bits */
@@ -1753,7 +1751,7 @@ irqreturn_t dp_isr(int irq, void *ptr)

	ack = isr2 & EDP_INTR_STATUS2;
	ack <<= 1;	/* ack bits */
	ack |= mask2;
	ack |= isr2;
	dp_write(base + DP_INTR_STATUS2, ack);
	spin_unlock(&dp->lock);

+6 −2
Original line number Diff line number Diff line
@@ -230,7 +230,9 @@ static int dp_aux_write_cmds(struct mdss_dp_drv_pdata *ep,

int dp_aux_write(void *ep, struct edp_cmd *cmd)
{
	return dp_aux_write_cmds(ep, cmd);
	int rc = dp_aux_write_cmds(ep, cmd);

	return rc < 0 ? -EINVAL : 0;
}

static int dp_aux_read_cmds(struct mdss_dp_drv_pdata *ep,
@@ -291,7 +293,9 @@ static int dp_aux_read_cmds(struct mdss_dp_drv_pdata *ep,

int dp_aux_read(void *ep, struct edp_cmd *cmds)
{
	return dp_aux_read_cmds(ep, cmds);
	int rc = dp_aux_read_cmds(ep, cmds);

	return rc  < 0 ? -EINVAL : 0;
}

void dp_aux_native_handler(struct mdss_dp_drv_pdata *ep, u32 isr)
+0 −2
Original line number Diff line number Diff line
@@ -181,8 +181,6 @@
#define HDCP_SEC_DP_TZ_HV_HLOS_HDCP_RCVPORT_DATA11     (0x01C)
#define HDCP_SEC_DP_TZ_HV_HLOS_HDCP_RCVPORT_DATA12     (0x020)

#define DP_INTERRUPT_STATUS_2                          (0x024)

struct lane_mapping {
	char lane0;
	char lane1;
+20 −19
Original line number Diff line number Diff line
@@ -41,14 +41,14 @@
#define HDCP_INT_CLR (isr->auth_success_ack | isr->auth_fail_ack | \
			isr->auth_fail_info_ack | isr->tx_req_ack | \
			isr->encryption_ready_ack | \
			isr->encryption_not_ready | isr->tx_req_done_ack)
			isr->encryption_not_ready_ack | isr->tx_req_done_ack)

#define HDCP_INT_EN (isr->auth_success_mask | isr->auth_fail_mask | \
			isr->encryption_ready_mask | \
			isr->encryption_not_ready_mask)

#define HDCP_POLL_SLEEP_US   (20 * 1000)
#define HDCP_POLL_TIMEOUT_US (HDCP_POLL_SLEEP_US * 1000)
#define HDCP_POLL_TIMEOUT_US (HDCP_POLL_SLEEP_US * 100)

#define reg_set_data(x) \
	(hdcp_ctrl->init_data.sec_access ? reg_set->sec_data##x : \
@@ -215,7 +215,7 @@ struct hdcp_reg_set {
	 BIT(0), BIT(4), 0, 0, 0, 0}

#define HDCP_DP_INT_SET \
	{DP_INTERRUPT_STATUS_2, \
	{DP_INTR_STATUS2, \
	 BIT(17), BIT(20), BIT(24), BIT(27), 0, 0, \
	 BIT(16), BIT(19), BIT(21), BIT(23), BIT(26), 0, 0, \
	 BIT(15), BIT(18), BIT(22), BIT(25), 0, 0}
@@ -554,7 +554,7 @@ static int hdcp_1x_read(struct hdcp_1x_ctrl *hdcp_ctrl,
		cmd.out_buf = buf;
		cmd.len = sink->len;

		rc = dp_aux_read(hdcp_ctrl->init_data.dp_data, &cmd);
		rc = dp_aux_read(hdcp_ctrl->init_data.cb_data, &cmd);
		if (rc)
			DEV_ERR("%s: %s: %s read failed\n", __func__,
				HDCP_STATE_NAME, sink->name);
@@ -564,7 +564,7 @@ static int hdcp_1x_read(struct hdcp_1x_ctrl *hdcp_ctrl,
}

static int hdcp_1x_write(struct hdcp_1x_ctrl *hdcp_ctrl,
			   u32 offset, u32 len, u8 *buf, char *name)
			   struct hdcp_sink_addr *sink, u8 *buf)
{
	int rc = 0;
	struct hdmi_tx_ddc_data ddc_data;
@@ -573,28 +573,28 @@ static int hdcp_1x_write(struct hdcp_1x_ctrl *hdcp_ctrl,
		memset(&ddc_data, 0, sizeof(ddc_data));

		ddc_data.dev_addr = 0x74;
		ddc_data.offset = offset;
		ddc_data.offset = sink->addr;
		ddc_data.data_buf = buf;
		ddc_data.data_len = len;
		ddc_data.what = name;
		ddc_data.data_len = sink->len;
		ddc_data.what = sink->name;
		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: %s write failed\n", __func__,
				HDCP_STATE_NAME, name);
				HDCP_STATE_NAME, sink->name);
	} else if (IS_ENABLED(CONFIG_FB_MSM_MDSS_DP_PANEL) &&
		hdcp_ctrl->init_data.client_id == HDCP_CLIENT_DP) {
		struct edp_cmd cmd = {0};

		cmd.addr = offset;
		cmd.len = len;
		cmd.addr = sink->addr;
		cmd.len = sink->len;
		cmd.datap = buf;

		rc = dp_aux_write(hdcp_ctrl->init_data.dp_data, &cmd);
		rc = dp_aux_write(hdcp_ctrl->init_data.cb_data, &cmd);
		if (rc)
			DEV_ERR("%s: %s: %s read failed\n", __func__,
				HDCP_STATE_NAME, name);
				HDCP_STATE_NAME, sink->name);
	}

	return rc;
@@ -754,13 +754,13 @@ static int hdcp_1x_authentication_part1(struct hdcp_1x_ctrl *hdcp_ctrl)
	an[6] = (link0_an_1 >> 16) & 0xFF;
	an[7] = (link0_an_1 >> 24) & 0xFF;

	rc = hdcp_1x_write(hdcp_ctrl, 0x18, 8, an, "an");
	rc = hdcp_1x_write(hdcp_ctrl, &hdcp_ctrl->sink_addr.an, an);
	if (IS_ERR_VALUE(rc)) {
		DEV_ERR("%s: error writing an to sink\n", __func__);
		goto error;
	}

	rc = hdcp_1x_write(hdcp_ctrl, 0x10, 5, aksv, "aksv");
	rc = hdcp_1x_write(hdcp_ctrl, &hdcp_ctrl->sink_addr.aksv, aksv);
	if (IS_ERR_VALUE(rc)) {
		DEV_ERR("%s: error writing aksv to sink\n", __func__);
		goto error;
@@ -1325,10 +1325,12 @@ static void hdcp_1x_auth_work(struct work_struct *work)
	}

	io = hdcp_ctrl->init_data.core_io;
	/* Enabling Software DDC */
	/* Enabling Software DDC for HDMI and REF timer for DP */
	if (hdcp_ctrl->init_data.client_id == HDCP_CLIENT_HDMI)
		DSS_REG_W_ND(io, HDMI_DDC_ARBITRATION, DSS_REG_R(io,
				HDMI_DDC_ARBITRATION) & ~(BIT(4)));
	else if (hdcp_ctrl->init_data.client_id == HDCP_CLIENT_DP)
		DSS_REG_W(io, DP_DP_HPD_REFTIMER, 0x10013);

	rc = hdcp_1x_authentication_part1(hdcp_ctrl);
	if (rc) {
@@ -1774,9 +1776,8 @@ void *hdcp_1x_init(struct hdcp_init_data *init_data)
	};

	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) {
		!init_data->mutex || !init_data->notify_status ||
		!init_data->workq || !init_data->cb_data) {
		DEV_ERR("%s: invalid input\n", __func__);
		goto error;
	}
+0 −1
Original line number Diff line number Diff line
@@ -42,7 +42,6 @@ struct hdcp_init_data {
	void *cb_data;
	void (*notify_status)(void *cb_data, enum hdcp_states status);
	struct hdmi_tx_ddc_ctrl *ddc_ctrl;
	void *dp_data;
	u32 phy_addr;
	u32 hdmi_tx_ver;
	struct msm_hdmi_mode_timing_info *timing;