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

Commit db14789c authored by Ajay Singh Parmar's avatar Ajay Singh Parmar
Browse files

drm/msm/dp: protect audio functionality during link maintenance



Link maintenance request from sink can be issued asynchronously
along with audio on/off functionalities. Link maintenance may
switch off and on the clocks needed for audio functionalities.
Protect the audio functionalities using lock to make sure the
required clocks are on.

CRs-Fixed: 2123895
Change-Id: I33e977b1e18feb205427a76171fd9b41fe463262
Signed-off-by: default avatarAjay Singh Parmar <aparmar@codeaurora.org>
parent 45c3e5c2
Loading
Loading
Loading
Loading
+9 −0
Original line number Diff line number Diff line
@@ -465,12 +465,16 @@ static int dp_audio_info_setup(struct platform_device *pdev,
		goto end;
	}

	mutex_lock(&audio->dp_audio.ops_lock);

	audio->channels = params->num_of_channels;

	dp_audio_setup_sdp(audio);
	dp_audio_setup_acr(audio);
	dp_audio_safe_to_exit_level(audio);
	dp_audio_enable(audio, true);

	mutex_unlock(&audio->dp_audio.ops_lock);
end:
	return rc;
}
@@ -545,7 +549,9 @@ static void dp_audio_teardown_done(struct platform_device *pdev)
	if (IS_ERR(audio))
		return;

	mutex_lock(&audio->dp_audio.ops_lock);
	dp_audio_enable(audio, false);
	mutex_unlock(&audio->dp_audio.ops_lock);

	complete_all(&audio->hpd_comp);

@@ -756,6 +762,8 @@ struct dp_audio *dp_audio_get(struct platform_device *pdev,

	dp_audio = &audio->dp_audio;

	mutex_init(&dp_audio->ops_lock);

	dp_audio->on  = dp_audio_on;
	dp_audio->off = dp_audio_off;

@@ -780,6 +788,7 @@ void dp_audio_put(struct dp_audio *dp_audio)
		return;

	audio = container_of(dp_audio, struct dp_audio_private, dp_audio);
	mutex_destroy(&dp_audio->ops_lock);

	devm_kfree(&audio->pdev->dev, audio);
}
+2 −0
Original line number Diff line number Diff line
@@ -29,6 +29,8 @@ struct dp_audio {
	u32 lane_count;
	u32 bw_code;

	struct mutex ops_lock;

	/**
	 * on()
	 *
+16 −4
Original line number Diff line number Diff line
@@ -1256,31 +1256,43 @@ static void dp_ctrl_send_phy_test_pattern(struct dp_ctrl_private *ctrl)
			dp_link_get_phy_test_pattern(pattern_requested));
}

static void dp_ctrl_handle_sink_request(struct dp_ctrl *dp_ctrl)
static bool dp_ctrl_handle_sink_request(struct dp_ctrl *dp_ctrl)
{
	struct dp_ctrl_private *ctrl;
	u32 sink_request = 0x0;
	bool req_handled = false;

	if (!dp_ctrl) {
		pr_err("invalid input\n");
		return;
		goto end;
	}

	ctrl = container_of(dp_ctrl, struct dp_ctrl_private, dp_ctrl);
	sink_request = ctrl->link->sink_request;

	if (sink_request & DP_TEST_LINK_PHY_TEST_PATTERN) {
		pr_info("PHY_TEST_PATTERN request\n");
		pr_info("PHY_TEST_PATTERN\n");
		dp_ctrl_process_phy_test_request(ctrl);

		req_handled = true;
	}

	if (sink_request & DP_LINK_STATUS_UPDATED)
	if (sink_request & DP_LINK_STATUS_UPDATED) {
		pr_info("DP_LINK_STATUS_UPDATED\n");
		dp_ctrl_link_maintenance(ctrl);

		req_handled = true;
	}

	if (sink_request & DP_TEST_LINK_TRAINING) {
		pr_info("DP_TEST_LINK_TRAINING\n");
		ctrl->link->send_test_response(ctrl->link);
		dp_ctrl_link_maintenance(ctrl);

		req_handled = true;
	}
end:
	return req_handled;
}

static void dp_ctrl_reset(struct dp_ctrl *dp_ctrl)
+1 −1
Original line number Diff line number Diff line
@@ -31,7 +31,7 @@ struct dp_ctrl {
	void (*push_idle)(struct dp_ctrl *dp_ctrl);
	void (*abort)(struct dp_ctrl *dp_ctrl);
	void (*isr)(struct dp_ctrl *dp_ctrl);
	void (*handle_sink_request)(struct dp_ctrl *dp_ctrl);
	bool (*handle_sink_request)(struct dp_ctrl *dp_ctrl);
};

struct dp_ctrl_in {
+14 −1
Original line number Diff line number Diff line
@@ -671,6 +671,8 @@ static void dp_display_handle_video_request(struct dp_display_private *dp)

static int dp_display_handle_hpd_irq(struct dp_display_private *dp)
{
	bool req_handled;

	if (dp->link->sink_request & DS_PORT_STATUS_CHANGED) {
		dp_display_send_hpd_notification(dp, false);

@@ -682,7 +684,18 @@ static int dp_display_handle_hpd_irq(struct dp_display_private *dp)
		return dp_display_process_hpd_high(dp);
	}

	dp->ctrl->handle_sink_request(dp->ctrl);
	mutex_lock(&dp->audio->ops_lock);
	req_handled = dp->ctrl->handle_sink_request(dp->ctrl);
	mutex_unlock(&dp->audio->ops_lock);

	/*
	 * reconfigure audio if test was executed
	 * which could have changed the contoller's state
	 */
	if (req_handled && dp->audio_supported) {
		dp->audio->off(dp->audio);
		dp->audio->on(dp->audio);
	}

	dp_display_handle_video_request(dp);