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

Commit 12590af3 authored by qctecmdr Service's avatar qctecmdr Service Committed by Gerrit - the friendly Code Review server
Browse files

Merge "drm/msm/dp: do not toggle clocks for link maintenance"

parents b55c7e23 3f1e8fa4
Loading
Loading
Loading
Loading
+61 −37
Original line number Diff line number Diff line
@@ -39,8 +39,11 @@ struct dp_audio_private {
	struct completion hpd_comp;
	struct workqueue_struct *notify_workqueue;
	struct delayed_work notify_delayed_work;
	struct mutex ops_lock;

	struct dp_audio dp_audio;

	atomic_t acked;
};

static u32 dp_audio_get_header(struct dp_catalog_audio *catalog,
@@ -416,14 +419,14 @@ static int dp_audio_info_setup(struct platform_device *pdev,
		return rc;
	}

	mutex_lock(&audio->dp_audio.ops_lock);
	mutex_lock(&audio->ops_lock);

	audio->channels = params->num_of_channels;

	if (audio->panel->stream_id >= DP_STREAM_MAX) {
		pr_err("invalid stream id: %d\n", audio->panel->stream_id);
		rc = -EINVAL;
		mutex_unlock(&audio->dp_audio.ops_lock);
		mutex_unlock(&audio->ops_lock);
		return rc;
	}

@@ -432,7 +435,7 @@ static int dp_audio_info_setup(struct platform_device *pdev,
	dp_audio_safe_to_exit_level(audio);
	dp_audio_enable(audio, true);

	mutex_unlock(&audio->dp_audio.ops_lock);
	mutex_unlock(&audio->ops_lock);
	return rc;
}

@@ -506,10 +509,11 @@ static void dp_audio_teardown_done(struct platform_device *pdev)
	if (IS_ERR(audio))
		return;

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

	atomic_set(&audio->acked, 1);
	complete_all(&audio->hpd_comp);

	pr_debug("audio engine disabled\n");
@@ -542,8 +546,10 @@ static int dp_audio_ack_done(struct platform_device *pdev, u32 ack)

	pr_debug("acknowledging audio (%d)\n", ack_hpd);

	if (!audio->engine_on)
	if (!audio->engine_on) {
		atomic_set(&audio->acked, 1);
		complete_all(&audio->hpd_comp);
	}
end:
	return rc;
}
@@ -566,16 +572,13 @@ static int dp_audio_codec_ready(struct platform_device *pdev)
	return rc;
}

static int dp_audio_register_ext_disp(struct dp_audio *dp_audio)
static int dp_audio_register_ext_disp(struct dp_audio_private *audio)
{
	int rc = 0;
	struct device_node *pd = NULL;
	const char *phandle = "qcom,ext-disp";
	struct msm_ext_disp_init_data *ext;
	struct msm_ext_disp_audio_codec_ops *ops;
	struct dp_audio_private *audio;

	audio = container_of(dp_audio, struct dp_audio_private, dp_audio);

	ext = &audio->ext_audio_data;
	ops = &ext->codec_ops;
@@ -624,15 +627,12 @@ static int dp_audio_register_ext_disp(struct dp_audio *dp_audio)
	return rc;
}

static int dp_audio_deregister_ext_disp(struct dp_audio *dp_audio)
static int dp_audio_deregister_ext_disp(struct dp_audio_private *audio)
{
	int rc = 0;
	struct device_node *pd = NULL;
	const char *phandle = "qcom,ext-disp";
	struct msm_ext_disp_init_data *ext;
	struct dp_audio_private *audio;

	audio = container_of(dp_audio, struct dp_audio_private, dp_audio);

	ext = &audio->ext_audio_data;

@@ -669,9 +669,14 @@ static int dp_audio_notify(struct dp_audio_private *audio, u32 state)
	int rc = 0;
	struct msm_ext_disp_init_data *ext = &audio->ext_audio_data;

	if (!ext->intf_ops.audio_notify)
	atomic_set(&audio->acked, 0);

	if (!ext->intf_ops.audio_notify) {
		pr_err("audio notify not defined\n");
		goto end;
	}

	reinit_completion(&audio->hpd_comp);
	rc = ext->intf_ops.audio_notify(audio->ext_pdev,
			&ext->codec, state);
	if (rc) {
@@ -679,8 +684,10 @@ static int dp_audio_notify(struct dp_audio_private *audio, u32 state)
		goto end;
	}

	reinit_completion(&audio->hpd_comp);
	rc = wait_for_completion_timeout(&audio->hpd_comp, HZ * 5);
	if (atomic_read(&audio->acked))
		goto end;

	rc = wait_for_completion_timeout(&audio->hpd_comp, HZ * 4);
	if (!rc) {
		pr_err("timeout. state=%d err=%d\n", state, rc);
		rc = -ETIMEDOUT;
@@ -692,6 +699,30 @@ static int dp_audio_notify(struct dp_audio_private *audio, u32 state)
	return rc;
}

static int dp_audio_config(struct dp_audio_private *audio, u32 state)
{
	int rc = 0;
	struct msm_ext_disp_init_data *ext = &audio->ext_audio_data;

	if (!ext || !ext->intf_ops.audio_config) {
		pr_err("audio_config not defined\n");
		goto end;
	}

	/*
	 * DP Audio sets default STREAM_0 only, other streams are
	 * set by audio driver based on the hardware/software support.
	 */
	if (audio->panel->stream_id == DP_STREAM_0) {
		rc = ext->intf_ops.audio_config(audio->ext_pdev,
				&ext->codec, state);
		if (rc)
			pr_err("failed to config audio, err=%d\n", rc);
	}
end:
	return rc;
}

static int dp_audio_on(struct dp_audio *dp_audio)
{
	int rc = 0;
@@ -713,15 +744,9 @@ static int dp_audio_on(struct dp_audio *dp_audio)

	audio->session_on = true;

	if (ext->intf_ops.audio_config) {
		rc = ext->intf_ops.audio_config(audio->ext_pdev,
				&ext->codec,
				EXT_DISPLAY_CABLE_CONNECT);
		if (rc) {
			pr_err("failed to config audio, err=%d\n", rc);
	rc = dp_audio_config(audio, EXT_DISPLAY_CABLE_CONNECT);
	if (rc)
		goto end;
		}
	}

	rc = dp_audio_notify(audio, EXT_DISPLAY_CABLE_CONNECT);
	if (rc)
@@ -757,13 +782,7 @@ static int dp_audio_off(struct dp_audio *dp_audio)

	pr_debug("success\n");
end:
	if (ext->intf_ops.audio_config) {
		rc = ext->intf_ops.audio_config(audio->ext_pdev,
				&ext->codec,
				EXT_DISPLAY_CABLE_DISCONNECT);
		if (rc)
			pr_err("failed to config audio, err=%d\n", rc);
	}
	dp_audio_config(audio, EXT_DISPLAY_CABLE_DISCONNECT);

	audio->session_on = false;
	audio->engine_on  = false;
@@ -830,17 +849,19 @@ struct dp_audio *dp_audio_get(struct platform_device *pdev,
	audio->panel = panel;
	audio->catalog = catalog;

	atomic_set(&audio->acked, 0);

	dp_audio = &audio->dp_audio;

	mutex_init(&dp_audio->ops_lock);
	mutex_init(&audio->ops_lock);

	dp_audio->on  = dp_audio_on;
	dp_audio->off = dp_audio_off;
	dp_audio->register_ext_disp = dp_audio_register_ext_disp;
	dp_audio->deregister_ext_disp = dp_audio_deregister_ext_disp;

	catalog->init(catalog);

	dp_audio_register_ext_disp(audio);

	return dp_audio;

error_notify_workqueue:
@@ -857,7 +878,10 @@ 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);

	dp_audio_deregister_ext_disp(audio);

	mutex_destroy(&audio->ops_lock);

	dp_audio_destroy_notify_workqueue(audio);

+0 −24
Original line number Diff line number Diff line
@@ -29,8 +29,6 @@ struct dp_audio {
	u32 lane_count;
	u32 bw_code;

	struct mutex ops_lock;

	/**
	 * on()
	 *
@@ -52,28 +50,6 @@ struct dp_audio {
	 * Returns the error code in case of failure, 0 in success case.
	 */
	int (*off)(struct dp_audio *dp_audio);

	/**
	 * register_ext_disp()
	 *
	 * Registers the audio with external display module.
	 *
	 * @dp_audio: an instance of struct dp_audio.
	 *
	 * Returns the error code in case of failure, 0 in success case.
	 */
	int (*register_ext_disp)(struct dp_audio *dp_audio);

	/**
	 * deregister_ext_disp()
	 *
	 * Deregisters the audio with external display module.
	 *
	 * @dp_audio: an instance of struct dp_audio.
	 *
	 * Returns the error code in case of failure, 0 in success case.
	 */
	int (*deregister_ext_disp)(struct dp_audio *dp_audio);
};

/**
+29 −28
Original line number Diff line number Diff line
@@ -128,10 +128,8 @@ static void dp_ctrl_push_idle(struct dp_ctrl_private *ctrl,
	int const idle_pattern_completion_timeout_ms = HZ / 10;
	u32 state = 0x0;

	if (!ctrl->power_on) {
		pr_err("CTRL off, return\n");
	if (!ctrl->power_on)
		return;
	}

	if (!ctrl->mst_mode) {
		state = ST_PUSH_IDLE;
@@ -462,18 +460,14 @@ static int dp_ctrl_link_train(struct dp_ctrl_private *ctrl)
	ctrl->link->phy_params.p_level = 0;
	ctrl->link->phy_params.v_level = 0;

	ctrl->catalog->config_ctrl(ctrl->catalog);

	link_info.num_lanes = ctrl->link->link_params.lane_count;
	link_info.rate = drm_dp_bw_code_to_link_rate(
		ctrl->link->link_params.bw_code);
	link_info.capabilities = ctrl->panel->link_info.capabilities;

	ret = drm_dp_link_configure(ctrl->aux->drm_aux, &link_info);
	if (ret) {
		pr_err_ratelimited("link_configure failed, rc=%d\n", ret);
	if (ret)
		goto end;
	}

	ret = drm_dp_dpcd_write(ctrl->aux->drm_aux,
		DP_MAIN_LINK_CHANNEL_CODING_SET, &encoding, 1);
@@ -513,8 +507,6 @@ static int dp_ctrl_setup_main_link(struct dp_ctrl_private *ctrl)
{
	int ret = 0;

	ctrl->catalog->mainlink_ctrl(ctrl->catalog, true);

	if (ctrl->link->sink_request & DP_TEST_LINK_PHY_TEST_PATTERN)
		goto end;

@@ -588,7 +580,7 @@ static int dp_ctrl_link_setup(struct dp_ctrl_private *ctrl)
	catalog->phy_lane_cfg(catalog, ctrl->orientation,
				link_params->lane_count);

	while (--link_train_max_retries || !atomic_read(&ctrl->aborted)) {
	while (--link_train_max_retries && !atomic_read(&ctrl->aborted)) {
		pr_debug("bw_code=%d, lane_count=%d\n",
			link_params->bw_code, link_params->lane_count);

@@ -715,6 +707,11 @@ static void dp_ctrl_host_deinit(struct dp_ctrl *dp_ctrl)
	pr_debug("Host deinitialized successfully\n");
}

static void dp_ctrl_send_video(struct dp_ctrl_private *ctrl)
{
	ctrl->catalog->state_ctrl(ctrl->catalog, ST_SEND_VIDEO);
}

static int dp_ctrl_link_maintenance(struct dp_ctrl *dp_ctrl)
{
	int ret = 0;
@@ -727,25 +724,31 @@ static int dp_ctrl_link_maintenance(struct dp_ctrl *dp_ctrl)

	ctrl = container_of(dp_ctrl, struct dp_ctrl_private, dp_ctrl);

	if (!ctrl->power_on || atomic_read(&ctrl->aborted)) {
		pr_err("CTRL off, return\n");
	ctrl->aux->state &= ~DP_STATE_LINK_MAINTENANCE_COMPLETED;
	ctrl->aux->state &= ~DP_STATE_LINK_MAINTENANCE_FAILED;

	if (!ctrl->power_on) {
		pr_err("ctrl off\n");
		ret = -EINVAL;
		goto end;
	}

	ctrl->aux->state &= ~DP_STATE_LINK_MAINTENANCE_COMPLETED;
	ctrl->aux->state &= ~DP_STATE_LINK_MAINTENANCE_FAILED;
	ctrl->aux->state |= DP_STATE_LINK_MAINTENANCE_STARTED;

	ctrl->catalog->reset(ctrl->catalog);
	dp_ctrl_disable_link_clock(ctrl);
	ret = dp_ctrl_link_setup(ctrl);
	if (atomic_read(&ctrl->aborted))
		goto end;

	ctrl->aux->state |= DP_STATE_LINK_MAINTENANCE_STARTED;
	ret = dp_ctrl_setup_main_link(ctrl);
	ctrl->aux->state &= ~DP_STATE_LINK_MAINTENANCE_STARTED;
	if (ret)

	if (ret) {
		ctrl->aux->state |= DP_STATE_LINK_MAINTENANCE_FAILED;
	else
		goto end;
	}

	ctrl->aux->state |= DP_STATE_LINK_MAINTENANCE_COMPLETED;

	dp_ctrl_send_video(ctrl);
	ret = dp_ctrl_wait4video_ready(ctrl);
end:
	return ret;
}
@@ -842,11 +845,6 @@ 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_send_video(struct dp_ctrl_private *ctrl)
{
	ctrl->catalog->state_ctrl(ctrl->catalog, ST_SEND_VIDEO);
}

static void dp_ctrl_mst_calculate_rg(struct dp_ctrl_private *ctrl,
		struct dp_panel *panel, u32 *p_x_int, u32 *p_y_frac_enum)
{
@@ -1078,6 +1076,9 @@ static void dp_ctrl_stream_off(struct dp_ctrl *dp_ctrl, struct dp_panel *panel)

	ctrl = container_of(dp_ctrl, struct dp_ctrl_private, dp_ctrl);

	if (!ctrl->power_on)
		return;

	panel->hw_cfg(panel, false);

	dp_ctrl_disable_stream_clocks(ctrl, panel);
+29 −89
Original line number Diff line number Diff line
@@ -98,7 +98,6 @@ struct dp_display_private {
	struct delayed_work hdcp_cb_work;
	struct delayed_work connect_work;
	struct work_struct attention_work;
	struct mutex hdcp_mutex;
	struct mutex session_lock;

	u32 active_stream_cnt;
@@ -293,7 +292,6 @@ static void dp_display_deinitialize_hdcp(struct dp_display_private *dp)
	}

	sde_dp_hdcp2p2_deinit(dp->hdcp.data);
	mutex_destroy(&dp->hdcp_mutex);
}

static int dp_display_initialize_hdcp(struct dp_display_private *dp)
@@ -309,8 +307,6 @@ static int dp_display_initialize_hdcp(struct dp_display_private *dp)

	parser = dp->parser;

	mutex_init(&dp->hdcp_mutex);

	hdcp_init_data.client_id     = HDCP_CLIENT_DP;
	hdcp_init_data.drm_aux       = dp->aux->drm_aux;
	hdcp_init_data.cb_data       = (void *)dp;
@@ -852,45 +848,40 @@ static int dp_display_usbpd_disconnect_cb(struct device *dev)
	return rc;
}

static void dp_display_handle_maintenance_req(struct dp_display_private *dp)
static void dp_display_stream_disable(struct dp_display_private *dp,
			struct dp_panel *dp_panel)
{
	int idx;
	struct dp_panel *dp_panel;

	mutex_lock(&dp->session_lock);

	for (idx = DP_STREAM_0; idx < DP_STREAM_MAX; idx++) {
		if (!dp->active_panels[idx])
			continue;
	if (!dp->active_stream_cnt) {
		pr_err("invalid active_stream_cnt (%d)\n");
		return;
	}

		dp_panel = dp->active_panels[idx];
	pr_debug("stream_id=%d, active_stream_cnt=%d\n",
			dp_panel->stream_id, dp->active_stream_cnt);

		dp->ctrl->stream_pre_off(dp->ctrl, dp_panel);
	dp->ctrl->stream_off(dp->ctrl, dp_panel);

		mutex_lock(&dp_panel->audio->ops_lock);

		if (dp_panel->audio_supported)
			dp_panel->audio->off(dp_panel->audio);
	dp->active_panels[dp_panel->stream_id] = NULL;
	dp->active_stream_cnt--;
}

	dp->ctrl->link_maintenance(dp->ctrl);

	for (idx = DP_STREAM_0; idx < DP_STREAM_MAX; idx++) {
		if (!dp->active_panels[idx])
			continue;

		dp_panel = dp->active_panels[idx];
static int dp_display_stream_enable(struct dp_display_private *dp,
			struct dp_panel *dp_panel)
{
	int rc = 0;

		dp->ctrl->stream_on(dp->ctrl, dp_panel);
	rc = dp->ctrl->stream_on(dp->ctrl, dp_panel);

		if (dp_panel->audio_supported)
			dp_panel->audio->on(dp_panel->audio);
	if (dp->debug->tpg_state)
		dp_panel->tpg_config(dp_panel, true);

		mutex_unlock(&dp_panel->audio->ops_lock);
	if (!rc) {
		dp->active_panels[dp_panel->stream_id] = dp_panel;
		dp->active_stream_cnt++;
	}

	mutex_unlock(&dp->session_lock);
	pr_debug("dp active_stream_cnt:%d\n", dp->active_stream_cnt);

	return rc;
}

static void dp_display_mst_attention(struct dp_display_private *dp)
@@ -934,12 +925,12 @@ static void dp_display_attention_work(struct work_struct *work)

	if (dp->link->sink_request & DP_TEST_LINK_TRAINING) {
		dp->link->send_test_response(dp->link);
		dp_display_handle_maintenance_req(dp);
		dp->ctrl->link_maintenance(dp->ctrl);
		goto mst_attention;
	}

	if (dp->link->sink_request & DP_LINK_STATUS_UPDATED)
		dp_display_handle_maintenance_req(dp);
		dp->ctrl->link_maintenance(dp->ctrl);

	if (dp_display_is_hdcp_enabled(dp) && dp->hdcp.ops->cp_irq)
		dp->hdcp.ops->cp_irq(dp->hdcp.data);
@@ -1352,26 +1343,6 @@ static int dp_display_set_stream_info(struct dp_display *dp_display,
	return rc;
}

static int dp_display_stream_enable(struct dp_display_private *dp,
			struct dp_panel *dp_panel)
{
	int rc = 0;

	rc = dp->ctrl->stream_on(dp->ctrl, dp_panel);

	if (dp->debug->tpg_state)
		dp_panel->tpg_config(dp_panel, true);

	if (!rc) {
		dp->active_panels[dp_panel->stream_id] = dp_panel;
		dp->active_stream_cnt++;
	}

	pr_debug("dp active_stream_cnt:%d\n", dp->active_stream_cnt);

	return rc;
}

static int dp_display_enable(struct dp_display *dp_display, void *panel)
{
	int rc = 0;
@@ -1386,13 +1357,8 @@ static int dp_display_enable(struct dp_display *dp_display, void *panel)

	mutex_lock(&dp->session_lock);

	if (atomic_read(&dp->aborted)) {
		pr_err("aborted\n");
		goto end;
	}

	if (!dp_display_is_ready(dp) || !dp->core_initialized) {
		pr_err("display not ready\n");
	if (!dp->core_initialized) {
		pr_err("host not initialized\n");
		goto end;
	}

@@ -1411,8 +1377,6 @@ static void dp_display_stream_post_enable(struct dp_display_private *dp,
{
	dp_panel->spd_config(dp_panel);
	dp_panel->setup_hdr(dp_panel, NULL);

	dp_panel->audio->register_ext_disp(dp_panel->audio);
}

static int dp_display_post_enable(struct dp_display *dp_display, void *panel)
@@ -1436,10 +1400,8 @@ static int dp_display_post_enable(struct dp_display *dp_display, void *panel)
		goto end;
	}

	if (atomic_read(&dp->aborted)) {
		pr_err("aborted\n");
	if (atomic_read(&dp->aborted))
		goto end;
	}

	if (!dp_display_is_ready(dp) || !dp->core_initialized) {
		pr_err("display not ready\n");
@@ -1479,7 +1441,6 @@ static int dp_display_post_enable(struct dp_display *dp_display, void *panel)
static int dp_display_stream_pre_disable(struct dp_display_private *dp,
			struct dp_panel *dp_panel)
{
	dp_panel->audio->deregister_ext_disp(dp_panel->audio);
	dp->ctrl->stream_pre_off(dp->ctrl, dp_panel);

	return 0;
@@ -1528,22 +1489,6 @@ static int dp_display_pre_disable(struct dp_display *dp_display, void *panel)
	return 0;
}

static void dp_display_stream_disable(struct dp_display_private *dp,
			struct dp_panel *dp_panel)
{
	if (!dp->active_stream_cnt) {
		pr_err("invalid active_stream_cnt (%d)\n");
		return;
	}

	pr_debug("stream_id=%d, active_stream_cnt=%d\n",
			dp_panel->stream_id, dp->active_stream_cnt);

	dp->ctrl->stream_off(dp->ctrl, dp_panel);
	dp->active_panels[dp_panel->stream_id] = NULL;
	dp->active_stream_cnt--;
}

static int dp_display_disable(struct dp_display *dp_display, void *panel)
{
	struct dp_display_private *dp = NULL;
@@ -1770,13 +1715,8 @@ static void dp_display_convert_to_dp_mode(struct dp_display *dp_display,
	dp = container_of(dp_display, struct dp_display_private, dp_display);
	dp_panel = panel;

	mutex_lock(&dp->session_lock);

	memset(dp_mode, 0, sizeof(*dp_mode));

	dp_panel->convert_to_dp_mode(dp_panel, drm_mode, dp_mode);

	mutex_unlock(&dp->session_lock);
}

static int dp_display_config_hdr(struct dp_display *dp_display, void *panel,
+0 −1
Original line number Diff line number Diff line
@@ -1683,7 +1683,6 @@ struct dp_panel *dp_panel_get(struct dp_panel_in *in)
	dp_panel->spd_enabled = true;
	memcpy(panel->spd_vendor_name, vendor_name, (sizeof(u8) * 8));
	memcpy(panel->spd_product_description, product_desc, (sizeof(u8) * 16));
	dp_panel->stream_id = DP_STREAM_MAX;
	dp_panel->connector = in->connector;

	if (in->base_panel) {
Loading