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

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

Merge "drm/msm/dp: maintain the connector to encoder link during suspend/resume"

parents 3e58225c ef6b1f5c
Loading
Loading
Loading
Loading
+33 −0
Original line number Diff line number Diff line
@@ -2333,6 +2333,21 @@ int dp_display_get_num_of_streams(void)
	return DP_STREAM_MAX;
}

static void dp_display_set_mst_state(void *dp_display,
		enum dp_drv_state mst_state)
{
	struct dp_display_private *dp;

	if (!g_dp_display) {
		pr_debug("dp display not initialized\n");
		return;
	}

	dp = container_of(g_dp_display, struct dp_display_private, dp_display);
	if (dp->mst.mst_active && dp->mst.cbs.set_drv_state)
		dp->mst.cbs.set_drv_state(g_dp_display, mst_state);
}

static int dp_display_remove(struct platform_device *pdev)
{
	struct dp_display_private *dp;
@@ -2353,6 +2368,23 @@ static int dp_display_remove(struct platform_device *pdev)
	return 0;
}

static int dp_pm_prepare(struct device *dev)
{
	dp_display_set_mst_state(g_dp_display, PM_SUSPEND);

	return 0;
}

static void dp_pm_complete(struct device *dev)
{
	dp_display_set_mst_state(g_dp_display, PM_DEFAULT);
}

static const struct dev_pm_ops dp_pm_ops = {
	.prepare = dp_pm_prepare,
	.complete = dp_pm_complete,
};

static struct platform_driver dp_display_driver = {
	.probe  = dp_display_probe,
	.remove = dp_display_remove,
@@ -2360,6 +2392,7 @@ static struct platform_driver dp_display_driver = {
		.name = "msm-dp-display",
		.of_match_table = dp_dt_match,
		.suppress_bind_attrs = true,
		.pm = &dp_pm_ops,
	},
};

+7 −0
Original line number Diff line number Diff line
@@ -23,6 +23,11 @@

#define DP_MST_SIM_MAX_PORTS	2

enum dp_drv_state {
	PM_DEFAULT,
	PM_SUSPEND,
};

struct dp_mst_hpd_info {
	bool mst_protocol;
	bool mst_hpd_sim;
@@ -34,6 +39,8 @@ struct dp_mst_drm_cbs {
	void (*hpd)(void *display, bool hpd_status,
			struct dp_mst_hpd_info *info);
	void (*hpd_irq)(void *display, struct dp_mst_hpd_info *info);
	void (*set_drv_state)(void *dp_display,
			enum dp_drv_state mst_state);
};

struct dp_mst_drm_install_info {
+70 −4
Original line number Diff line number Diff line
@@ -118,6 +118,7 @@ struct dp_mst_private {
	const struct dp_drm_mst_fw_helper_ops *mst_fw_cbs;
	struct dp_mst_sim_mode simulator;
	struct mutex mst_lock;
	enum dp_drv_state state;
};

struct dp_mst_encoder_info_cache {
@@ -513,6 +514,27 @@ static void _dp_mst_update_timeslots(struct dp_mst_private *mst,
	}
}

static void _dp_mst_update_single_timeslot(struct dp_mst_private *mst,
		struct dp_mst_bridge *mst_bridge)
{
	int pbn = 0, start_slot = 0, num_slots = 0;

	if (mst->state == PM_SUSPEND) {
		if (mst_bridge->vcpi) {
			mst->mst_fw_cbs->get_vcpi_info(&mst->mst_mgr,
					mst_bridge->vcpi,
					&start_slot, &num_slots);
			pbn = mst_bridge->pbn;
		}

		mst_bridge->num_slots = num_slots;

		mst->dp_display->set_stream_info(mst->dp_display,
				mst_bridge->dp_panel,
				mst_bridge->id, start_slot, num_slots, pbn);
	}
}

static void _dp_mst_bridge_pre_enable_part1(struct dp_mst_bridge *dp_bridge)
{
	struct dp_display *dp_display = dp_bridge->display;
@@ -523,6 +545,12 @@ static void _dp_mst_bridge_pre_enable_part1(struct dp_mst_bridge *dp_bridge)
	bool ret;
	int pbn, slots;

	/* skip mst specific disable operations during suspend */
	if (mst->state == PM_SUSPEND) {
		_dp_mst_update_single_timeslot(mst, dp_bridge);
		return;
	}

	pbn = mst->mst_fw_cbs->calc_pbn_mode(
			dp_bridge->dp_mode.timing.pixel_clk_khz,
			dp_bridge->dp_mode.timing.bpp);
@@ -555,6 +583,10 @@ static void _dp_mst_bridge_pre_enable_part2(struct dp_mst_bridge *dp_bridge)

	DP_MST_DEBUG("enter\n");

	/* skip mst specific disable operations during suspend */
	if (mst->state == PM_SUSPEND)
		return;

	mst->mst_fw_cbs->check_act_status(&mst->mst_mgr);

	mst->mst_fw_cbs->update_payload_part2(&mst->mst_mgr);
@@ -573,6 +605,12 @@ static void _dp_mst_bridge_pre_disable_part1(struct dp_mst_bridge *dp_bridge)

	DP_MST_DEBUG("enter\n");

	/* skip mst specific disable operations during suspend */
	if (mst->state == PM_SUSPEND) {
		_dp_mst_update_single_timeslot(mst, dp_bridge);
		return;
	}

	mst->mst_fw_cbs->reset_vcpi_slots(&mst->mst_mgr, port);

	mst->mst_fw_cbs->update_payload_part1(&mst->mst_mgr);
@@ -593,6 +631,10 @@ static void _dp_mst_bridge_pre_disable_part2(struct dp_mst_bridge *dp_bridge)

	DP_MST_DEBUG("enter\n");

	/* skip mst specific disable operations during suspend */
	if (mst->state == PM_SUSPEND)
		return;

	mst->mst_fw_cbs->check_act_status(&mst->mst_mgr);

	mst->mst_fw_cbs->update_payload_part2(&mst->mst_mgr);
@@ -770,10 +812,13 @@ static void dp_mst_bridge_post_disable(struct drm_bridge *drm_bridge)
		pr_info("[%d] DP display unprepare failed, rc=%d\n",
		       bridge->id, rc);

	/* maintain the connector to encoder link during suspend/resume */
	if (mst->state != PM_SUSPEND) {
		/* Disconnect the connector and panel info from bridge */
		mst->mst_bridge[bridge->id].connector = NULL;
		mst->mst_bridge[bridge->id].dp_panel = NULL;
		mst->mst_bridge[bridge->id].encoder_active_sts = false;
	}

	DP_MST_DEBUG("mst bridge [%d] post disable complete\n", bridge->id);
}
@@ -1089,6 +1134,13 @@ static int dp_mst_connector_atomic_check(struct drm_connector *connector,

	DP_MST_DEBUG("enter:\n");

	/*
	 * Skip atomic check during mst suspend, to avoid mismanagement of
	 * available vcpi slots.
	 */
	if (mst->state == PM_SUSPEND)
		return rc;

	if (!new_conn_state)
		return rc;

@@ -1403,11 +1455,25 @@ static void dp_mst_display_hpd_irq(void *dp_display,
	DP_MST_DEBUG("exit:\n");
}

static void dp_mst_set_state(void *dp_display, enum dp_drv_state mst_state)
{
	struct dp_display *dp = dp_display;
	struct dp_mst_private *mst = dp->dp_mst_prv_info;

	if (!mst) {
		pr_debug("mst not initialized\n");
		return;
	}

	mst->state = mst_state;
}

/* DP MST APIs */

static const struct dp_mst_drm_cbs dp_mst_display_cbs = {
	.hpd = dp_mst_display_hpd,
	.hpd_irq = dp_mst_display_hpd_irq,
	.set_drv_state = dp_mst_set_state,
};

static const struct drm_dp_mst_topology_cbs dp_mst_drm_cbs = {