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

Commit 9c22a285 authored by Ajay Singh Parmar's avatar Ajay Singh Parmar Committed by Sandeep Panda
Browse files

msm: mdss: hdmi: schedule link work from isr



Do not schedule link work periodically to check for new message
or authentication status. Hardware automatically poll sink for
the same. Once new message is available or sink indicates
re-authentication required, isr is triggered. Queue link check
work from isr to avoid unnecessary software polling.

Change-Id: I83c71f5151aa077e863b6578a89f6515f6497159
Signed-off-by: default avatarAjay Singh Parmar <aparmar@codeaurora.org>
parent 032961da
Loading
Loading
Loading
Loading
+19 −23
Original line number Diff line number Diff line
@@ -74,8 +74,6 @@ struct hdmi_hdcp2p2_ctrl {
	struct kthread_work send_msg;
	struct kthread_work recv_msg;
	struct kthread_work link;

	struct delayed_work link_check_work;
};

static int hdmi_hdcp2p2_auth(struct hdmi_hdcp2p2_ctrl *ctrl);
@@ -777,8 +775,9 @@ static void hdmi_hdcp2p2_recv_msg(struct hdmi_hdcp2p2_ctrl *ctrl)
	ddc_data->timeout_hsync = timeout_hsync;
	ddc_data->periodic_timer_hsync = timeout_hsync / 20;
	ddc_data->read_method = HDCP2P2_RXSTATUS_HW_DDC_SW_TRIGGER;
	ddc_data->wait = true;

	rc = hdmi_hdcp2p2_ddc_read_rxstatus(ddc_ctrl, true);
	rc = hdmi_hdcp2p2_ddc_read_rxstatus(ddc_ctrl);
	if (rc) {
		pr_err("error reading rxstatus %d\n", rc);
		goto exit;
@@ -831,6 +830,19 @@ static void hdmi_hdcp2p2_recv_msg_work(struct kthread_work *work)
	hdmi_hdcp2p2_recv_msg(ctrl);
}

static void hdmi_hdcp2p2_link_cb(void *data)
{
	struct hdmi_hdcp2p2_ctrl *ctrl = data;

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

	if (atomic_read(&ctrl->auth_state) != HDCP_STATE_INACTIVE)
		queue_kthread_work(&ctrl->worker, &ctrl->link);
}

static int hdmi_hdcp2p2_link_check(struct hdmi_hdcp2p2_ctrl *ctrl)
{
	struct hdmi_tx_ddc_ctrl *ddc_ctrl;
@@ -862,8 +874,10 @@ static int hdmi_hdcp2p2_link_check(struct hdmi_hdcp2p2_ctrl *ctrl)
	ddc_data->timeout_hsync = timeout_hsync;
	ddc_data->periodic_timer_hsync = timeout_hsync;
	ddc_data->read_method = HDCP2P2_RXSTATUS_HW_DDC_SW_TRIGGER;
	ddc_data->link_cb = hdmi_hdcp2p2_link_cb;
	ddc_data->link_data = ctrl;

	return hdmi_hdcp2p2_ddc_read_rxstatus(ddc_ctrl, false);
	return hdmi_hdcp2p2_ddc_read_rxstatus(ddc_ctrl);
}

static void hdmi_hdcp2p2_auth_status(struct hdmi_hdcp2p2_ctrl *ctrl)
@@ -884,8 +898,7 @@ static void hdmi_hdcp2p2_auth_status(struct hdmi_hdcp2p2_ctrl *ctrl)
		ctrl->init_data.notify_status(ctrl->init_data.cb_data,
			HDCP_STATE_AUTHENTICATED);

		if (!hdmi_hdcp2p2_link_check(ctrl))
			queue_kthread_work(&ctrl->worker, &ctrl->link);
		hdmi_hdcp2p2_link_check(ctrl);
	}
}

@@ -897,16 +910,6 @@ static void hdmi_hdcp2p2_auth_status_work(struct kthread_work *work)
	hdmi_hdcp2p2_auth_status(ctrl);
}


static void hdmi_hdcp2p2_link_schedule_work(struct work_struct *work)
{
	struct hdmi_hdcp2p2_ctrl *ctrl = container_of(to_delayed_work(work),
		struct hdmi_hdcp2p2_ctrl, link_check_work);

	if (atomic_read(&ctrl->auth_state) != HDCP_STATE_INACTIVE)
		queue_kthread_work(&ctrl->worker, &ctrl->link);
}

static void hdmi_hdcp2p2_link_work(struct kthread_work *work)
{
	int rc = 0;
@@ -980,10 +983,6 @@ exit:
		hdmi_hdcp2p2_auth_failed(ctrl);
		return;
	}

	/* recheck within 1sec as per hdcp 2.2 standard */
	schedule_delayed_work(&ctrl->link_check_work,
		msecs_to_jiffies(HDCP2P2_LINK_CHECK_TIME_MS));
}

static int hdmi_hdcp2p2_auth(struct hdmi_hdcp2p2_ctrl *ctrl)
@@ -1122,9 +1121,6 @@ void *hdmi_hdcp2p2_init(struct hdmi_hdcp_init_data *init_data)
	ctrl->thread = kthread_run(kthread_worker_fn,
		&ctrl->worker, "hdmi_hdcp2p2");

	INIT_DELAYED_WORK(&ctrl->link_check_work,
		hdmi_hdcp2p2_link_schedule_work);

	if (IS_ERR(ctrl->thread)) {
		pr_err("unable to start hdcp2p2 thread\n");
		rc = PTR_ERR(ctrl->thread);
+14 −5
Original line number Diff line number Diff line
@@ -919,6 +919,7 @@ static int hdmi_ddc_hdcp2p2_isr(struct hdmi_tx_ddc_ctrl *ddc_ctrl)
	struct hdmi_tx_hdcp2p2_ddc_data *data;
	u32 intr0, intr2, intr5;
	u32 msg_size;
	int rc = 0;

	if (!ddc_ctrl || !ddc_ctrl->io) {
		pr_err("invalid input\n");
@@ -1041,10 +1042,18 @@ static int hdmi_ddc_hdcp2p2_isr(struct hdmi_tx_ddc_ctrl *ddc_ctrl)
	}
	DSS_REG_W_ND(io, HDMI_DDC_INT_CTRL5, intr5);

	if (data->message_size || data->ready || data->reauth_req)
	if (data->message_size || data->ready || data->reauth_req) {
		if (data->wait) {
			atomic_set(&ddc_ctrl->rxstatus_busy_wait_done, 1);
		} else if (data->link_cb && data->link_data) {
			data->link_cb(data->link_data);
		} else {
			pr_err("new msg/reauth not handled\n");
			rc = -EINVAL;
		}
	}

	return 0;
	return rc;
}

static int hdmi_ddc_scrambling_isr(struct hdmi_tx_ddc_ctrl *ddc_ctrl)
@@ -1605,7 +1614,7 @@ void hdmi_hdcp2p2_ddc_disable(struct hdmi_tx_ddc_ctrl *ctrl)
	DSS_REG_W(ctrl->io, HDMI_HW_DDC_CTRL, reg_val);
}

int hdmi_hdcp2p2_ddc_read_rxstatus(struct hdmi_tx_ddc_ctrl *ctrl, bool wait)
int hdmi_hdcp2p2_ddc_read_rxstatus(struct hdmi_tx_ddc_ctrl *ctrl)
{
	u32 reg_val;
	u32 intr_en_mask;
@@ -1704,7 +1713,7 @@ int hdmi_hdcp2p2_ddc_read_rxstatus(struct hdmi_tx_ddc_ctrl *ctrl, bool wait)
	DSS_REG_W(ctrl->io, HDMI_HW_DDC_CTRL, reg_val);
	DSS_REG_W(ctrl->io, HDMI_HDCP2P2_DDC_SW_TRIGGER, 1);

	if (wait) {
	if (data->wait) {
		while (busy_wait_us > 0 &&
			!atomic_read(&ctrl->rxstatus_busy_wait_done)) {
			udelay(HDMI_BUSY_WAIT_DELAY_US);
+4 −1
Original line number Diff line number Diff line
@@ -433,7 +433,10 @@ struct hdmi_tx_hdcp2p2_ddc_data {
	bool ddc_done;
	bool ddc_read_req;
	bool ddc_timeout;
	bool wait;
	int irq_wait_count;
	void (*link_cb)(void *data);
	void *link_data;
};

struct hdmi_tx_ddc_ctrl {
@@ -500,8 +503,8 @@ int hdmi_setup_ddc_timers(struct hdmi_tx_ddc_ctrl *ctrl,
			  u32 type, u32 to_in_num_lines);
void hdmi_scrambler_ddc_disable(struct hdmi_tx_ddc_ctrl *ctrl);
void hdmi_hdcp2p2_ddc_disable(struct hdmi_tx_ddc_ctrl *ctrl);
int hdmi_hdcp2p2_ddc_read_rxstatus(struct hdmi_tx_ddc_ctrl *ctrl, bool wait);
int hdmi_hdcp2p2_ddc_check_status(struct hdmi_tx_ddc_ctrl *ctrl);
int hdmi_hdcp2p2_ddc_read_rxstatus(struct hdmi_tx_ddc_ctrl *ctrl);
int hdmi_utils_get_timeout_in_hysnc(struct msm_hdmi_mode_timing_info *timing,
	u32 timeout_ms);