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

Commit c1e4bfc7 authored by Dhaval Patel's avatar Dhaval Patel
Browse files

drm: msm: update rsc sequence for power collapse



SDE RSC driver should disable the force_idle on
solver mode enable. Encoder should also disable the
vsync_enable state on pingpong before updating rsc
state to clk state.

Change-Id: I8362cceeaa91e853ab0ae047c2bb96427f862dd0
Signed-off-by: default avatarDhaval Patel <pdhaval@codeaurora.org>
parent 037d768f
Loading
Loading
Loading
Loading
+14 −12
Original line number Diff line number Diff line
@@ -1502,29 +1502,31 @@ static void _sde_encoder_resource_control_rsc_update(
{
	struct sde_encoder_virt *sde_enc = to_sde_encoder_virt(drm_enc);
	struct sde_encoder_rsc_config rsc_cfg = { 0 };
	int i;

	if (enable) {
		rsc_cfg.inline_rotate_prefill =
				sde_crtc_get_inline_prefill(drm_enc->crtc);

		/* connect the TE source to actual TE GPIO to drive RSC */
		_sde_encoder_update_vsync_source(sde_enc, &sde_enc->disp_info,
				false);

		_sde_encoder_update_rsc_client(drm_enc, &rsc_cfg, true);
	} else {
		_sde_encoder_update_rsc_client(drm_enc, NULL, false);

		/**
		 * disconnect the TE source from the actual TE GPIO for RSC
		 *
		 * this call is for hardware workaround on sdm845 and should
		 * not be removed without considering the design changes for
		 * sde rsc + command mode concurrency. It may lead to pp
		 * timeout due to vsync from panel for command mode panel.
		 * disable the vsync source after updating the rsc state. rsc
		 * state update might have vsync wait and vsync source must be
		 * disabled after it. It will avoid generating any vsync from
		 * this point till mode-2 entry. It is SW workaround for
		 * HW limitation and should not be removed without checking the
		 * updated design.
		 */
		_sde_encoder_update_vsync_source(sde_enc, &sde_enc->disp_info,
				true);
		for (i = 0; i < sde_enc->num_phys_encs; i++) {
			struct sde_encoder_phys *phys = sde_enc->phys_encs[i];

			if (phys && phys->ops.prepare_idle_pc)
				phys->ops.prepare_idle_pc(phys);
		}

	}
}

+3 −0
Original line number Diff line number Diff line
@@ -125,6 +125,8 @@ struct sde_encoder_virt_ops {
 *				SDE_ENC_ERR_NEEDS_HW_RESET state
 * @irq_control:		Handler to enable/disable all the encoder IRQs
 * @update_split_role:		Update the split role of the phys enc
 * @prepare_idle_pc:		phys encoder can update the vsync_enable status
 *                              on idle power collapse prepare
 * @restore:			Restore all the encoder configs.
 * @is_autorefresh_enabled:	provides the autorefresh current
 *                              enable/disable state.
@@ -167,6 +169,7 @@ struct sde_encoder_phys_ops {
	void (*irq_control)(struct sde_encoder_phys *phys, bool enable);
	void (*update_split_role)(struct sde_encoder_phys *phys_enc,
			enum sde_enc_split_role role);
	void (*prepare_idle_pc)(struct sde_encoder_phys *phys_enc);
	void (*restore)(struct sde_encoder_phys *phys);
	bool (*is_autorefresh_enabled)(struct sde_encoder_phys *phys);
};
+7 −0
Original line number Diff line number Diff line
@@ -897,6 +897,12 @@ static void _sde_encoder_phys_cmd_connect_te(
	phys_enc->hw_pp->ops.connect_external_te(phys_enc->hw_pp, enable);
}

static void sde_encoder_phys_cmd_prepare_idle_pc(
		struct sde_encoder_phys *phys_enc)
{
	_sde_encoder_phys_cmd_connect_te(phys_enc, false);
}

static void sde_encoder_phys_cmd_disable(struct sde_encoder_phys *phys_enc)
{
	struct sde_encoder_phys_cmd *cmd_enc =
@@ -1239,6 +1245,7 @@ static void sde_encoder_phys_cmd_init_ops(
	ops->irq_control = sde_encoder_phys_cmd_irq_control;
	ops->update_split_role = sde_encoder_phys_cmd_update_split_role;
	ops->restore = sde_encoder_phys_cmd_enable_helper;
	ops->prepare_idle_pc = sde_encoder_phys_cmd_prepare_idle_pc;
	ops->is_autorefresh_enabled =
			sde_encoder_phys_cmd_is_autorefresh_enabled;
	ops->handle_post_kickoff = sde_encoder_phys_cmd_handle_post_kickoff;
+1 −1
Original line number Diff line number Diff line
@@ -515,7 +515,7 @@ static int sde_rsc_state_update(struct sde_rsc_priv *rsc,
		reg = dss_reg_r(&rsc->wrapper_io,
			SDE_RSCC_WRAPPER_OVERRIDE_CTRL, rsc->debug_mode);
		reg |= (BIT(0) | BIT(8));
		reg &= ~(BIT(1) | BIT(2) | BIT(3) | BIT(6) | BIT(7));
		reg &= ~(BIT(1) | BIT(2) | BIT(3) | BIT(6) | BIT(7) | BIT(9));
		dss_reg_w(&rsc->wrapper_io, SDE_RSCC_WRAPPER_OVERRIDE_CTRL,
							reg, rsc->debug_mode);
		/* make sure that solver is enabled */