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

Commit b59a48c6 authored by Abhijit Kulkarni's avatar Abhijit Kulkarni Committed by Gerrit - the friendly Code Review server
Browse files

drm/msm/sde: cleanup encoder implementation



This code cleans up video and cmd mode encoders by moving
the implementation of identifying single ctrl into common
header file and waits for LUTDMA flush only once for single
control path configuration with two interfaces.

Change-Id: Ib1978540dc3ebc7e4866fb4844456b171a830c3b
Signed-off-by: default avatarAbhijit Kulkarni <kabhijit@codeaurora.org>
parent ca44a271
Loading
Loading
Loading
Loading
+13 −23
Original line number Diff line number Diff line
@@ -3060,6 +3060,8 @@ static inline void _sde_encoder_trigger_flush(struct drm_encoder *drm_enc,
{
	struct sde_hw_ctl *ctl;
	int pending_kickoff_cnt;
	unsigned long lock_flags;
	struct sde_encoder_virt *sde_enc;

	if (!drm_enc || !phys) {
		SDE_ERROR("invalid argument(s), drm_enc %d, phys_enc %d\n",
@@ -3067,6 +3069,8 @@ static inline void _sde_encoder_trigger_flush(struct drm_encoder *drm_enc,
		return;
	}

	sde_enc = to_sde_encoder_virt(drm_enc);

	if (!phys->hw_pp) {
		SDE_ERROR("invalid pingpong hw\n");
		return;
@@ -3086,6 +3090,9 @@ static inline void _sde_encoder_trigger_flush(struct drm_encoder *drm_enc,
		return;
	}

	/* update pending counts and trigger kickoff ctl flush atomically */
	spin_lock_irqsave(&sde_enc->enc_spinlock, lock_flags);

	pending_kickoff_cnt = sde_encoder_phys_inc_pending(phys);

	if (phys->ops.is_master && phys->ops.is_master(phys))
@@ -3097,6 +3104,8 @@ static inline void _sde_encoder_trigger_flush(struct drm_encoder *drm_enc,

	phys->ops.trigger_flush(phys);

	spin_unlock_irqrestore(&sde_enc->enc_spinlock, lock_flags);

	if (ctl->ops.get_pending_flush) {
		struct sde_ctl_flush_cfg pending_flush = {0,};

@@ -3268,7 +3277,6 @@ static void _sde_encoder_kickoff_phys(struct sde_encoder_virt *sde_enc)
{
	struct sde_hw_ctl *ctl;
	uint32_t i;
	unsigned long lock_flags;
	struct sde_ctl_flush_cfg pending_flush = {0,};

	if (!sde_enc) {
@@ -3276,12 +3284,10 @@ static void _sde_encoder_kickoff_phys(struct sde_encoder_virt *sde_enc)
		return;
	}

	/*
	 * Trigger LUT DMA flush, this might need a wait, so we need
	 * to do this outside of the atomic context
	 */
	/* don't perform flush/start operations for slave encoders */
	for (i = 0; i < sde_enc->num_phys_encs; i++) {
		struct sde_encoder_phys *phys = sde_enc->phys_encs[i];
		enum sde_rm_topology_name topology = SDE_RM_TOPOLOGY_NONE;
		bool wait_for_dma = false;

		if (!phys || phys->enable_state == SDE_ENC_DISABLED)
@@ -3292,27 +3298,12 @@ static void _sde_encoder_kickoff_phys(struct sde_encoder_virt *sde_enc)
			continue;

		if (phys->ops.wait_dma_trigger)
			wait_for_dma = phys->ops.wait_dma_trigger(phys);
			wait_for_dma = phys->ops.wait_dma_trigger(
					phys);

		if (phys->hw_ctl->ops.reg_dma_flush)
			phys->hw_ctl->ops.reg_dma_flush(phys->hw_ctl,
					wait_for_dma);
	}

	/* update pending counts and trigger kickoff ctl flush atomically */
	spin_lock_irqsave(&sde_enc->enc_spinlock, lock_flags);

	/* don't perform flush/start operations for slave encoders */
	for (i = 0; i < sde_enc->num_phys_encs; i++) {
		struct sde_encoder_phys *phys = sde_enc->phys_encs[i];
		enum sde_rm_topology_name topology = SDE_RM_TOPOLOGY_NONE;

		if (!phys || phys->enable_state == SDE_ENC_DISABLED)
			continue;

		ctl = phys->hw_ctl;
		if (!ctl)
			continue;

		if (phys->connector)
			topology = sde_connector_get_topology_name(
@@ -3344,7 +3335,6 @@ static void _sde_encoder_kickoff_phys(struct sde_encoder_virt *sde_enc)

	_sde_encoder_trigger_start(sde_enc->cur_master);

	spin_unlock_irqrestore(&sde_enc->enc_spinlock, lock_flags);
}

static void _sde_encoder_ppsplit_swap_intf_for_right_only_update(
+50 −0
Original line number Diff line number Diff line
@@ -604,4 +604,54 @@ int sde_encoder_helper_unregister_irq(struct sde_encoder_phys *phys_enc,
void sde_encoder_helper_update_intf_cfg(
		struct sde_encoder_phys *phys_enc);

/**
 * _sde_encoder_phys_is_dual_ctl - check if encoder needs dual ctl path.
 * @phys_enc: Pointer to physical encoder structure
 * @Return: true if dual ctl paths else false
 */
static inline bool _sde_encoder_phys_is_dual_ctl(
		struct sde_encoder_phys *phys_enc)
{
	enum sde_rm_topology_name topology;

	if (!phys_enc)
		return false;

	topology = sde_connector_get_topology_name(phys_enc->connector);
	if ((topology == SDE_RM_TOPOLOGY_DUALPIPE_DSC) ||
		(topology == SDE_RM_TOPOLOGY_DUALPIPE))
		return true;

	return false;
}

/**
 * _sde_encoder_phys_is_ppsplit - check if pp_split is enabled
 * @phys_enc: Pointer to physical encoder structure
 * @Return: true or false
 */
static inline bool _sde_encoder_phys_is_ppsplit(
		struct sde_encoder_phys *phys_enc)
{
	enum sde_rm_topology_name topology;

	if (!phys_enc)
		return false;

	topology = sde_connector_get_topology_name(phys_enc->connector);
	if (topology == SDE_RM_TOPOLOGY_PPSPLIT)
		return true;

	return false;
}

static inline bool sde_encoder_phys_needs_single_flush(
		struct sde_encoder_phys *phys_enc)
{
	if (!phys_enc)
		return false;

	return phys_enc && (_sde_encoder_phys_is_ppsplit(phys_enc) ||
		_sde_encoder_phys_is_dual_ctl(phys_enc));
}
#endif /* __sde_encoder_phys_H__ */
+1 −24
Original line number Diff line number Diff line
@@ -457,20 +457,6 @@ static void sde_encoder_phys_cmd_mode_set(
	_sde_encoder_phys_cmd_setup_irq_hw_idx(phys_enc);
}

static bool _sde_encoder_phys_is_ppsplit(struct sde_encoder_phys *phys_enc)
{
	enum sde_rm_topology_name topology;

	if (!phys_enc)
		return false;

	topology = sde_connector_get_topology_name(phys_enc->connector);
	if (topology == SDE_RM_TOPOLOGY_PPSPLIT)
		return true;

	return false;
}

static int _sde_encoder_phys_cmd_handle_ppdone_timeout(
		struct sde_encoder_phys *phys_enc)
{
@@ -882,15 +868,6 @@ static void _sde_encoder_phys_cmd_pingpong_config(
	sde_encoder_phys_cmd_tearcheck_config(phys_enc);
}

static bool sde_encoder_phys_cmd_needs_single_flush(
		struct sde_encoder_phys *phys_enc)
{
	if (!phys_enc)
		return false;

	return _sde_encoder_phys_is_ppsplit(phys_enc);
}

static void sde_encoder_phys_cmd_enable_helper(
		struct sde_encoder_phys *phys_enc)
{
@@ -1349,7 +1326,7 @@ static void sde_encoder_phys_cmd_init_ops(
	ops->wait_for_vblank = sde_encoder_phys_cmd_wait_for_vblank;
	ops->trigger_flush = sde_encoder_helper_trigger_flush;
	ops->trigger_start = sde_encoder_phys_cmd_trigger_start;
	ops->needs_single_flush = sde_encoder_phys_cmd_needs_single_flush;
	ops->needs_single_flush = sde_encoder_phys_needs_single_flush;
	ops->hw_reset = sde_encoder_helper_hw_reset;
	ops->irq_control = sde_encoder_phys_cmd_irq_control;
	ops->update_split_role = sde_encoder_phys_cmd_update_split_role;
+2 −38
Original line number Diff line number Diff line
@@ -484,42 +484,6 @@ static void sde_encoder_phys_vid_underrun_irq(void *arg, int irq_idx)
			phys_enc);
}

static bool _sde_encoder_phys_is_ppsplit(struct sde_encoder_phys *phys_enc)
{
	enum sde_rm_topology_name topology;

	if (!phys_enc)
		return false;

	topology = sde_connector_get_topology_name(phys_enc->connector);
	if (topology == SDE_RM_TOPOLOGY_PPSPLIT)
		return true;

	return false;
}

static bool _sde_encoder_phys_is_dual_ctl(struct sde_encoder_phys *phys_enc)
{
	enum sde_rm_topology_name topology;

	if (!phys_enc)
		return false;

	topology = sde_connector_get_topology_name(phys_enc->connector);
	if ((topology == SDE_RM_TOPOLOGY_DUALPIPE_DSC) ||
		(topology == SDE_RM_TOPOLOGY_DUALPIPE))
		return true;

	return false;
}

static bool sde_encoder_phys_vid_needs_single_flush(
		struct sde_encoder_phys *phys_enc)
{
	return phys_enc && (_sde_encoder_phys_is_ppsplit(phys_enc) ||
		_sde_encoder_phys_is_dual_ctl(phys_enc));
}

static void _sde_encoder_phys_vid_setup_irq_hw_idx(
		struct sde_encoder_phys *phys_enc)
{
@@ -742,7 +706,7 @@ static void sde_encoder_phys_vid_enable(struct sde_encoder_phys *phys_enc)
	 * flush bit for the slave intf, since both intfs use same ctl
	 * and HW will only flush the master.
	 */
	if (sde_encoder_phys_vid_needs_single_flush(phys_enc) &&
	if (sde_encoder_phys_needs_single_flush(phys_enc) &&
		!sde_encoder_phys_vid_is_master(phys_enc))
		goto skip_flush;

@@ -1160,7 +1124,7 @@ static void sde_encoder_phys_vid_init_ops(struct sde_encoder_phys_ops *ops)
	ops->irq_control = sde_encoder_phys_vid_irq_control;
	ops->prepare_for_kickoff = sde_encoder_phys_vid_prepare_for_kickoff;
	ops->handle_post_kickoff = sde_encoder_phys_vid_handle_post_kickoff;
	ops->needs_single_flush = sde_encoder_phys_vid_needs_single_flush;
	ops->needs_single_flush = sde_encoder_phys_needs_single_flush;
	ops->setup_misr = sde_encoder_phys_vid_setup_misr;
	ops->collect_misr = sde_encoder_phys_vid_collect_misr;
	ops->trigger_flush = sde_encoder_helper_trigger_flush;