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

Commit ca166490 authored by Linux Build Service Account's avatar Linux Build Service Account Committed by Gerrit - the friendly Code Review server
Browse files

Merge "msm: mdss: do not turn off interface clocks for doze mode"

parents 4ab0af8b de744a14
Loading
Loading
Loading
Loading
+72 −35
Original line number Diff line number Diff line
@@ -59,11 +59,17 @@ struct mdss_mdp_cmd_ctx mdss_mdp_cmd_ctx_list[MAX_SESSIONS];

static int mdss_mdp_cmd_do_notifier(struct mdss_mdp_cmd_ctx *ctx);

static bool __mdss_mdp_cmd_panel_power_off(struct mdss_mdp_cmd_ctx *ctx)
static bool __mdss_mdp_cmd_is_panel_power_off(struct mdss_mdp_cmd_ctx *ctx)
{
	return mdss_panel_is_power_off(ctx->panel_power_state);
}

static bool __mdss_mdp_cmd_is_panel_power_on_interactive(
		struct mdss_mdp_cmd_ctx *ctx)
{
	return mdss_panel_is_power_on_interactive(ctx->panel_power_state);
}

static inline u32 mdss_mdp_cmd_line_count(struct mdss_mdp_ctl *ctl)
{
	struct mdss_mdp_mixer *mixer;
@@ -216,7 +222,7 @@ static inline void mdss_mdp_cmd_clk_on(struct mdss_mdp_cmd_ctx *ctx)
	struct mdss_data_type *mdata = mdss_mdp_get_mdata();
	int irq_en, rc;

	if (__mdss_mdp_cmd_panel_power_off(ctx))
	if (__mdss_mdp_cmd_is_panel_power_off(ctx))
		return;

	mutex_lock(&ctx->clk_mtx);
@@ -692,6 +698,45 @@ static int mdss_mdp_cmd_set_stream_size(struct mdss_mdp_ctl *ctl)
	return rc;
}

static int mdss_mdp_cmd_panel_on(struct mdss_mdp_ctl *ctl,
	struct mdss_mdp_ctl *sctl)
{
	struct mdss_mdp_cmd_ctx *ctx, *sctx = NULL;
	int rc = 0;

	ctx = (struct mdss_mdp_cmd_ctx *) ctl->priv_data;
	if (!ctx) {
		pr_err("invalid ctx\n");
		return -ENODEV;
	}

	if (sctl)
		sctx = (struct mdss_mdp_cmd_ctx *) sctl->priv_data;

	if (!__mdss_mdp_cmd_is_panel_power_on_interactive(ctx)) {
		rc = mdss_mdp_ctl_intf_event(ctl, MDSS_EVENT_LINK_READY, NULL);
		WARN(rc, "intf %d link ready error (%d)\n", ctl->intf_num, rc);

		rc = mdss_mdp_ctl_intf_event(ctl, MDSS_EVENT_UNBLANK, NULL);
		WARN(rc, "intf %d unblank error (%d)\n", ctl->intf_num, rc);

		rc = mdss_mdp_ctl_intf_event(ctl, MDSS_EVENT_PANEL_ON, NULL);
		WARN(rc, "intf %d panel on error (%d)\n", ctl->intf_num, rc);

		ctx->panel_power_state = MDSS_PANEL_POWER_ON;
		if (sctx)
			sctx->panel_power_state = MDSS_PANEL_POWER_ON;

		mdss_mdp_ctl_intf_event(ctl,
			MDSS_EVENT_REGISTER_RECOVERY_HANDLER,
			(void *)&ctx->intf_recovery);
	} else {
		pr_err("%s: Panel already on\n", __func__);
	}

	return rc;
}

/*
 * There are 3 partial update possibilities
 * left only ==> enable left pingpong_done
@@ -708,7 +753,6 @@ int mdss_mdp_cmd_kickoff(struct mdss_mdp_ctl *ctl, void *arg)
{
	struct mdss_mdp_ctl *sctl = NULL;
	struct mdss_mdp_cmd_ctx *ctx, *sctx = NULL;
	int rc;

	ctx = (struct mdss_mdp_cmd_ctx *) ctl->priv_data;
	if (!ctx) {
@@ -733,24 +777,13 @@ int mdss_mdp_cmd_kickoff(struct mdss_mdp_ctl *ctl, void *arg)
			PERF_HW_MDP_STATE, PERF_STATUS_BUSY);
	}

	if (__mdss_mdp_cmd_panel_power_off(ctx)) {
		rc = mdss_mdp_ctl_intf_event(ctl, MDSS_EVENT_LINK_READY, NULL);
		WARN(rc, "intf %d link ready error (%d)\n", ctl->intf_num, rc);

		rc = mdss_mdp_ctl_intf_event(ctl, MDSS_EVENT_UNBLANK, NULL);
		WARN(rc, "intf %d unblank error (%d)\n", ctl->intf_num, rc);

		rc = mdss_mdp_ctl_intf_event(ctl, MDSS_EVENT_PANEL_ON, NULL);
		WARN(rc, "intf %d panel on error (%d)\n", ctl->intf_num, rc);

		ctx->panel_power_state = MDSS_PANEL_POWER_ON;
		if (sctx)
			sctx->panel_power_state = MDSS_PANEL_POWER_ON;

		mdss_mdp_ctl_intf_event(ctl,
				MDSS_EVENT_REGISTER_RECOVERY_HANDLER,
				(void *)&ctx->intf_recovery);
	}
	/*
	 * Turn on the panel, if not already. This is because the panel is
	 * turned on only when we send the first frame and not during cmd
	 * start. This is to ensure that no artifacts are seen on the panel.
	 */
	if (__mdss_mdp_cmd_is_panel_power_off(ctx))
		mdss_mdp_cmd_panel_on(ctl, sctl);

	MDSS_XLOG(ctl->num, ctl->roi.x, ctl->roi.y, ctl->roi.w,
						ctl->roi.h);
@@ -863,12 +896,7 @@ int mdss_mdp_cmd_intfs_stop(struct mdss_mdp_ctl *ctl, int session,

	mdss_mdp_cmd_clk_off(ctx);
	flush_work(&ctx->pp_done_work);
	ctx->panel_power_state = panel_power_state;

	if (panel_power_state != MDSS_PANEL_POWER_OFF) {
		pr_debug("%s: panel always on\n", __func__);
		goto end;
	}
	mdss_mdp_cmd_tearcheck_setup(ctl, false);

	mdss_mdp_set_intr_callback(MDSS_MDP_IRQ_PING_PONG_RD_PTR,
		ctx->pp_num, NULL, NULL);
@@ -877,7 +905,6 @@ int mdss_mdp_cmd_intfs_stop(struct mdss_mdp_ctl *ctl, int session,

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

end:
	pr_debug("%s:-\n", __func__);

	return 0;
@@ -900,6 +927,13 @@ static int mdss_mdp_cmd_stop_sub(struct mdss_mdp_ctl *ctl,
	if (ctx->panel_power_state == panel_power_state)
		return 0;

	/*
	 * If the panel will be left on, then we do not need to turn off
	 * interface clocks since we may continue to get display updates.
	 */
	if (mdss_panel_is_power_on(panel_power_state))
		return 0;

	list_for_each_entry_safe(handle, tmp, &ctx->vsync_handlers, list)
		mdss_mdp_cmd_remove_vsync_handler(ctl, handle);
	MDSS_XLOG(ctl->num, atomic_read(&ctx->koff_cnt), ctx->clk_enabled,
@@ -945,12 +979,11 @@ int mdss_mdp_cmd_stop(struct mdss_mdp_ctl *ctl, int panel_power_state)
		ret = mdss_mdp_ctl_intf_event(ctl, MDSS_EVENT_PANEL_OFF,
				(void *) (long int) panel_power_state);
		WARN(ret, "intf %d unblank error (%d)\n", ctl->intf_num, ret);

		if (panel_power_state != MDSS_PANEL_POWER_DOZE)
			mdss_mdp_cmd_tearcheck_setup(ctl, false);
	}

	if (panel_power_state != MDSS_PANEL_POWER_OFF) {
	ctx->panel_power_state = panel_power_state;

	if (mdss_panel_is_power_on(panel_power_state)) {
		pr_debug("%s: cmd_stop with panel always on\n", __func__);
		goto end;
	}
@@ -974,6 +1007,7 @@ static int mdss_mdp_cmd_intfs_setup(struct mdss_mdp_ctl *ctl,
			int session)
{
	struct mdss_mdp_cmd_ctx *ctx;
	struct mdss_mdp_ctl *sctl = NULL;
	struct mdss_mdp_mixer *mixer;
	int ret;

@@ -986,10 +1020,11 @@ static int mdss_mdp_cmd_intfs_setup(struct mdss_mdp_ctl *ctl,
			return ret;
	}

	sctl = mdss_mdp_get_split_ctl(ctl);
	ctx = &mdss_mdp_cmd_ctx_list[session];
	if (ctx->ref_cnt) {
		if (ctx->panel_power_state != MDSS_PANEL_POWER_OFF) {
			pr_debug("%s: ctl_start with panel always on\n",
		if (mdss_panel_is_power_on(ctx->panel_power_state)) {
			pr_debug("%s: cmd_start with panel always on\n",
				__func__);
			/*
			 * It is possible that the resume was called from the
@@ -1000,7 +1035,9 @@ static int mdss_mdp_cmd_intfs_setup(struct mdss_mdp_ctl *ctl,
			 * tearcheck logic.
			 */
			mdss_mdp_cmd_restore(ctl);
			return 0;

			/* Turn on panel so that it can exit low power mode */
			return mdss_mdp_cmd_panel_on(ctl, sctl);
		} else {
			pr_err("Intf %d already in use\n", session);
			return -EBUSY;