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

Commit 81e87889 authored by Dhaval Patel's avatar Dhaval Patel Committed by Narendra Muppalla
Browse files

drm/msm/sde: update vblank and underrun isr handling



Current sde driver enables the underrun interrupt for
all interfaces during bootup. That's not a desired
behavior. It should be handled through each interface
when it is enabled/disabled. This patch updates the
irq APIs on each interface to handle generic irq request
and uses them for vblank, underrun, etc interrupts.

Change-Id: I890110eef975555a771a0690c5f762b0a3f18737
Signed-off-by: default avatarDhaval Patel <pdhaval@codeaurora.org>
parent 3fbe6bfb
Loading
Loading
Loading
Loading
+1 −36
Original line number Diff line number Diff line
/* Copyright (c) 2015-2016, The Linux Foundation. All rights reserved.
/* Copyright (c) 2015-2017, The Linux Foundation. All rights reserved.
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License version 2 and
@@ -42,11 +42,6 @@ static void sde_core_irq_callback_handler(void *arg, int irq_idx)
			irq_idx);
}

static void sde_core_irq_intf_error_handler(void *arg, int irq_idx)
{
	SDE_ERROR("INTF underrun detected, irq_idx=%d\n", irq_idx);
}

int sde_core_irq_idx_lookup(struct sde_kms *sde_kms,
		enum sde_intr_type intr_type, u32 instance_idx)
{
@@ -191,36 +186,6 @@ void sde_core_irq_preinstall(struct sde_kms *sde_kms)

int sde_core_irq_postinstall(struct sde_kms *sde_kms)
{
	struct msm_drm_private *priv;
	struct sde_irq_callback irq_cb;
	int irq_idx;
	int i;

	if (!sde_kms) {
		SDE_ERROR("invalid sde_kms\n");
		return -EINVAL;
	} else if (!sde_kms->dev) {
		SDE_ERROR("invalid drm device\n");
		return -EINVAL;
	} else if (!sde_kms->dev->dev_private) {
		SDE_ERROR("invalid device private\n");
		return -EINVAL;
	}
	priv = sde_kms->dev->dev_private;

	irq_cb.func = sde_core_irq_intf_error_handler;
	irq_cb.arg  = sde_kms;

	/* Register interface underrun callback */
	sde_power_resource_enable(&priv->phandle, sde_kms->core_client, true);
	for (i = 0; i < sde_kms->catalog->intf_count; i++) {
		irq_idx = sde_core_irq_idx_lookup(sde_kms,
				SDE_IRQ_TYPE_INTF_UNDER_RUN, i+INTF_0);
		sde_core_irq_register_callback(sde_kms, irq_idx, &irq_cb);
		sde_core_irq_enable(sde_kms, &irq_idx, 1);
	}
	sde_power_resource_enable(&priv->phandle, sde_kms->core_client, false);

	return 0;
}

+23 −3
Original line number Diff line number Diff line
@@ -389,6 +389,9 @@ static void sde_encoder_virt_enable(struct drm_encoder *drm_enc)
		struct sde_encoder_phys *phys = sde_enc->phys_encs[i];

		if (phys) {
			atomic_set(&phys->vsync_cnt, 0);
			atomic_set(&phys->underrun_cnt, 0);

			if (phys->ops.enable)
				phys->ops.enable(phys);

@@ -435,8 +438,12 @@ static void sde_encoder_virt_disable(struct drm_encoder *drm_enc)
	for (i = 0; i < sde_enc->num_phys_encs; i++) {
		struct sde_encoder_phys *phys = sde_enc->phys_encs[i];

		if (phys && phys->ops.disable && !phys->ops.is_master(phys))
		if (phys && phys->ops.disable && !phys->ops.is_master(phys)) {
			phys->ops.disable(phys);

			atomic_set(&phys->vsync_cnt, 0);
			atomic_set(&phys->underrun_cnt, 0);
		}
	}

	if (sde_enc->cur_master && sde_enc->cur_master->ops.disable)
@@ -488,12 +495,13 @@ static enum sde_wb sde_encoder_get_wb(struct sde_mdss_cfg *catalog,
	return WB_MAX;
}

static void sde_encoder_vblank_callback(struct drm_encoder *drm_enc)
static void sde_encoder_vblank_callback(struct drm_encoder *drm_enc,
		struct sde_encoder_phys *phy_enc)
{
	struct sde_encoder_virt *sde_enc = NULL;
	unsigned long lock_flags;

	if (!drm_enc)
	if (!drm_enc || !phy_enc)
		return;

	sde_enc = to_sde_encoder_virt(drm_enc);
@@ -502,6 +510,17 @@ static void sde_encoder_vblank_callback(struct drm_encoder *drm_enc)
	if (sde_enc->crtc_vblank_cb)
		sde_enc->crtc_vblank_cb(sde_enc->crtc_vblank_cb_data);
	spin_unlock_irqrestore(&sde_enc->spin_lock, lock_flags);

	atomic_inc(&phy_enc->vsync_cnt);
}

static void sde_encoder_underrun_callback(struct drm_encoder *drm_enc,
		struct sde_encoder_phys *phy_enc)
{
	if (!phy_enc)
		return;

	atomic_inc(&phy_enc->underrun_cnt);
}

void sde_encoder_register_vblank_callback(struct drm_encoder *drm_enc,
@@ -829,6 +848,7 @@ static int sde_encoder_setup_display(struct sde_encoder_virt *sde_enc,
	enum sde_intf_type intf_type;
	struct sde_encoder_virt_ops parent_ops = {
		sde_encoder_vblank_callback,
		sde_encoder_underrun_callback,
		sde_encoder_handle_phys_enc_ready_for_kickoff
	};
	struct sde_enc_phys_init_params phys_params;
+30 −5
Original line number Diff line number Diff line
/*
 * Copyright (c) 2015-2016 The Linux Foundation. All rights reserved.
 * Copyright (c) 2015-2017 The Linux Foundation. All rights reserved.
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License version 2 and
@@ -46,11 +46,16 @@ struct sde_encoder_phys;
 *	provides for the physical encoders to use to callback.
 * @handle_vblank_virt:	Notify virtual encoder of vblank IRQ reception
 *			Note: This is called from IRQ handler context.
 * @handle_underrun_virt: Notify virtual encoder of underrun IRQ reception
 *			Note: This is called from IRQ handler context.
 * @handle_ready_for_kickoff:	Notify virtual encoder that this phys encoder
 *				is now ready for the next kickoff.
 */
struct sde_encoder_virt_ops {
	void (*handle_vblank_virt)(struct drm_encoder *);
	void (*handle_vblank_virt)(struct drm_encoder *,
			struct sde_encoder_phys *phys);
	void (*handle_underrun_virt)(struct drm_encoder *,
			struct sde_encoder_phys *phys);
	void (*handle_ready_for_kickoff)(struct drm_encoder *,
			struct sde_encoder_phys *phys);
};
@@ -122,6 +127,21 @@ enum sde_enc_enable_state {
	SDE_ENC_ENABLED
};

/**
 * enum sde_intr_idx - sde encoder interrupt index
 * @INTR_IDX_VSYNC:    Vsync interrupt for video mode panel
 * @INTR_IDX_PINGPONG: Pingpong done unterrupt for cmd mode panel
 * @INTR_IDX_UNDERRUN: Underrun unterrupt for video and cmd mode panel
 * @INTR_IDX_RDPTR:    Readpointer done unterrupt for cmd mode panel
 */
enum sde_intr_idx {
	INTR_IDX_VSYNC,
	INTR_IDX_PINGPONG,
	INTR_IDX_UNDERRUN,
	INTR_IDX_RDPTR,
	INTR_IDX_MAX,
};

/**
 * struct sde_encoder_phys - physical encoder that drives a single INTF block
 *	tied to a specific panel / sub-panel. Abstract type, sub-classed by
@@ -138,10 +158,13 @@ enum sde_enc_enable_state {
 * @enabled:		Whether the encoder has enabled and running a mode
 * @split_role:		Role to play in a split-panel configuration
 * @intf_mode:		Interface mode
 * @intf_idx:		Interface index on sde hardware
 * @spin_lock:		Lock for IRQ purposes
 * @mode_3d:		3D mux configuration
 * @enable_state:	Enable state tracking
 * @vblank_refcount:	Reference count of vblank request
 * @vsync_cnt:		Vsync count for the physical encoder
 * @underrun_cnt:	Underrun count for the physical encoder
 */
struct sde_encoder_phys {
	struct drm_encoder *parent;
@@ -155,10 +178,13 @@ struct sde_encoder_phys {
	struct drm_display_mode cached_mode;
	enum sde_enc_split_role split_role;
	enum sde_intf_mode intf_mode;
	enum sde_intf intf_idx;
	spinlock_t spin_lock;
	enum sde_3d_blend_mode mode_3d;
	enum sde_enc_enable_state enable_state;
	atomic_t vblank_refcount;
	atomic_t vsync_cnt;
	atomic_t underrun_cnt;
};

/**
@@ -171,7 +197,7 @@ struct sde_encoder_phys {
 */
struct sde_encoder_phys_vid {
	struct sde_encoder_phys base;
	int irq_idx;
	int irq_idx[INTR_IDX_MAX];
	struct sde_hw_intf *hw_intf;
	struct completion vblank_completion;
};
@@ -199,8 +225,7 @@ struct sde_encoder_phys_cmd {
	int intf_idx;
	int stream_sel;
	struct sde_hw_pingpong *hw_pp;
	int pp_rd_ptr_irq_idx;
	int pp_tx_done_irq_idx;
	int irq_idx[INTR_IDX_MAX];
	wait_queue_head_t pp_tx_done_wq;
	atomic_t pending_cnt;
};
+61 −23
Original line number Diff line number Diff line
/*
 * Copyright (c) 2015-2016 The Linux Foundation. All rights reserved.
 * Copyright (c) 2015-2017 The Linux Foundation. All rights reserved.
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License version 2 and
@@ -133,6 +133,7 @@ static void sde_encoder_phys_cmd_pp_tx_done_irq(void *arg, int irq_idx)
	wake_up_all(&cmd_enc->pp_tx_done_wq);

	/* Trigger a pending flush */
	if (phys_enc->parent_ops.handle_ready_for_kickoff)
		phys_enc->parent_ops.handle_ready_for_kickoff(phys_enc->parent,
			phys_enc);
}
@@ -145,15 +146,28 @@ static void sde_encoder_phys_cmd_pp_rd_ptr_irq(void *arg, int irq_idx)
	if (!cmd_enc)
		return;

	phys_enc->parent_ops.handle_vblank_virt(phys_enc->parent);
	if (phys_enc->parent_ops.handle_vblank_virt)
		phys_enc->parent_ops.handle_vblank_virt(phys_enc->parent,
			phys_enc);
}

static int sde_encoder_phys_cmd_register_pp_irq(
		struct sde_encoder_phys *phys_enc,
		enum sde_intr_type intr_type,
		int *irq_idx,
		void (*irq_func)(void *, int),
		const char *irq_name)
static void sde_encoder_phys_cmd_underrun_irq(void *arg, int irq_idx)
{
	struct sde_encoder_phys_cmd *cmd_enc = arg;
	struct sde_encoder_phys *phys_enc;

	if (!cmd_enc)
		return;

	phys_enc = &cmd_enc->base;
	if (phys_enc->parent_ops.handle_underrun_virt)
		phys_enc->parent_ops.handle_underrun_virt(phys_enc->parent,
			phys_enc);
}

static int sde_encoder_phys_cmd_register_irq(struct sde_encoder_phys *phys_enc,
	enum sde_intr_type intr_type, int *irq_idx,
	void (*irq_func)(void *, int), const char *irq_name)
{
	struct sde_encoder_phys_cmd *cmd_enc =
			to_sde_encoder_phys_cmd(phys_enc);
@@ -208,7 +222,7 @@ static int sde_encoder_phys_cmd_register_pp_irq(
	return ret;
}

static int sde_encoder_phys_cmd_unregister_pp_irq(
static int sde_encoder_phys_cmd_unregister_irq(
		struct sde_encoder_phys *phys_enc,
		int irq_idx)
{
@@ -380,7 +394,7 @@ static int sde_encoder_phys_cmd_control_vblank_irq(

	/* Slave encoders don't report vblank */
	if (!sde_encoder_phys_cmd_is_master(phys_enc))
		return 0;
		goto end;

	SDE_DEBUG_CMDENC(cmd_enc, "[%pS] enable=%d/%d\n",
			__builtin_return_address(0),
@@ -390,15 +404,25 @@ static int sde_encoder_phys_cmd_control_vblank_irq(
			atomic_read(&phys_enc->vblank_refcount));

	if (enable && atomic_inc_return(&phys_enc->vblank_refcount) == 1)
		ret = sde_encoder_phys_cmd_register_pp_irq(phys_enc,
		ret = sde_encoder_phys_cmd_register_irq(phys_enc,
				SDE_IRQ_TYPE_PING_PONG_RD_PTR,
				&cmd_enc->pp_rd_ptr_irq_idx,
				&cmd_enc->irq_idx[INTR_IDX_PINGPONG],
				sde_encoder_phys_cmd_pp_rd_ptr_irq,
				"pp_rd_ptr");
	else if (!enable && atomic_dec_return(&phys_enc->vblank_refcount) == 0)
		ret = sde_encoder_phys_cmd_unregister_pp_irq(phys_enc,
				cmd_enc->pp_rd_ptr_irq_idx);
		ret = sde_encoder_phys_cmd_unregister_irq(phys_enc,
				cmd_enc->irq_idx[INTR_IDX_PINGPONG]);

	if (enable)
		ret = sde_encoder_phys_cmd_register_irq(phys_enc,
			SDE_IRQ_TYPE_PING_PONG_RD_PTR,
			&cmd_enc->irq_idx[INTR_IDX_RDPTR],
			sde_encoder_phys_cmd_pp_rd_ptr_irq, "pp_rd_ptr");
	else
		ret = sde_encoder_phys_cmd_unregister_irq(phys_enc,
			cmd_enc->irq_idx[INTR_IDX_RDPTR]);

end:
	if (ret)
		SDE_ERROR_CMDENC(cmd_enc,
				"control vblank irq error %d, enable %d\n",
@@ -436,19 +460,30 @@ static void sde_encoder_phys_cmd_enable(struct sde_encoder_phys *phys_enc)
	sde_encoder_phys_cmd_pingpong_config(phys_enc);

	/* Both master and slave need to register for pp_tx_done */
	ret = sde_encoder_phys_cmd_register_pp_irq(phys_enc,
	ret = sde_encoder_phys_cmd_register_irq(phys_enc,
			SDE_IRQ_TYPE_PING_PONG_COMP,
			&cmd_enc->pp_tx_done_irq_idx,
			&cmd_enc->irq_idx[INTR_IDX_PINGPONG],
			sde_encoder_phys_cmd_pp_tx_done_irq,
			"pp_tx_done");

	if (ret)
		return;

	ret = sde_encoder_phys_cmd_control_vblank_irq(phys_enc, true);
	if (ret) {
		sde_encoder_phys_cmd_unregister_pp_irq(phys_enc,
				cmd_enc->pp_tx_done_irq_idx);
		sde_encoder_phys_cmd_unregister_irq(phys_enc,
				cmd_enc->irq_idx[INTR_IDX_PINGPONG]);
		return;
	}

	ret = sde_encoder_phys_cmd_register_irq(phys_enc,
			SDE_IRQ_TYPE_INTF_UNDER_RUN,
			&cmd_enc->irq_idx[INTR_IDX_UNDERRUN],
			sde_encoder_phys_cmd_underrun_irq,
			"underrun");
	if (ret) {
		sde_encoder_phys_cmd_control_vblank_irq(phys_enc, false);
		sde_encoder_phys_cmd_unregister_irq(phys_enc,
				cmd_enc->irq_idx[INTR_IDX_UNDERRUN]);
		return;
	}

@@ -475,9 +510,11 @@ static void sde_encoder_phys_cmd_disable(struct sde_encoder_phys *phys_enc)
	if (WARN_ON(phys_enc->enable_state == SDE_ENC_DISABLED))
		return;

	sde_encoder_phys_cmd_unregister_pp_irq(phys_enc,
			cmd_enc->pp_tx_done_irq_idx);
	sde_encoder_phys_cmd_unregister_irq(phys_enc,
			cmd_enc->irq_idx[INTR_IDX_UNDERRUN]);
	sde_encoder_phys_cmd_control_vblank_irq(phys_enc, false);
	sde_encoder_phys_cmd_unregister_irq(phys_enc,
			cmd_enc->irq_idx[INTR_IDX_PINGPONG]);

	atomic_set(&cmd_enc->pending_cnt, 0);
	wake_up_all(&cmd_enc->pp_tx_done_wq);
@@ -603,6 +640,7 @@ struct sde_encoder_phys *sde_encoder_phys_cmd_init(
	phys_enc->hw_mdptop = hw_mdp;

	cmd_enc->intf_idx = p->intf_idx;
	phys_enc->intf_idx = p->intf_idx;

	sde_encoder_phys_cmd_init_ops(&phys_enc->ops);
	phys_enc->parent = p->parent;
+69 −29
Original line number Diff line number Diff line
/* Copyright (c) 2015-2016, The Linux Foundation. All rights reserved.
/* Copyright (c) 2015-2017, The Linux Foundation. All rights reserved.
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License version 2 and
@@ -309,12 +309,28 @@ static void sde_encoder_phys_vid_vblank_irq(void *arg, int irq_idx)
		return;

	phys_enc = &vid_enc->base;
	phys_enc->parent_ops.handle_vblank_virt(phys_enc->parent);
	if (phys_enc->parent_ops.handle_vblank_virt)
		phys_enc->parent_ops.handle_vblank_virt(phys_enc->parent,
				phys_enc);

	/* signal VBLANK completion */
	complete_all(&vid_enc->vblank_completion);
}

static void sde_encoder_phys_vid_underrun_irq(void *arg, int irq_idx)
{
	struct sde_encoder_phys_vid *vid_enc = arg;
	struct sde_encoder_phys *phys_enc;

	if (!vid_enc)
		return;

	phys_enc = &vid_enc->base;
	if (phys_enc->parent_ops.handle_underrun_virt)
		phys_enc->parent_ops.handle_underrun_virt(phys_enc->parent,
			phys_enc);
}

static bool sde_encoder_phys_vid_needs_split_flush(
		struct sde_encoder_phys *phys_enc)
{
@@ -347,7 +363,9 @@ static void _sde_encoder_phys_vid_split_config(
	}
}

static int sde_encoder_phys_vid_register_irq(struct sde_encoder_phys *phys_enc)
static int sde_encoder_phys_vid_register_irq(struct sde_encoder_phys *phys_enc,
	enum sde_intr_type intr_type, int *irq_idx,
	void (*irq_func)(void *, int), const char *irq_name)
{
	struct sde_encoder_phys_vid *vid_enc =
			to_sde_encoder_phys_vid(phys_enc);
@@ -359,59 +377,62 @@ static int sde_encoder_phys_vid_register_irq(struct sde_encoder_phys *phys_enc)
		return -EINVAL;
	}

	vid_enc->irq_idx = sde_core_irq_idx_lookup(phys_enc->sde_kms,
			SDE_IRQ_TYPE_INTF_VSYNC, vid_enc->hw_intf->idx);
	if (vid_enc->irq_idx < 0) {
	*irq_idx = sde_core_irq_idx_lookup(phys_enc->sde_kms, intr_type,
			vid_enc->hw_intf->idx);
	if (*irq_idx < 0) {
		SDE_ERROR_VIDENC(vid_enc,
				"failed to lookup IRQ index for INTF_VSYNC\n");
			"failed to lookup IRQ index for %s type:%d\n", irq_name,
			intr_type);
		return -EINVAL;
	}

	irq_cb.func = sde_encoder_phys_vid_vblank_irq;
	irq_cb.func = irq_func;
	irq_cb.arg = vid_enc;
	ret = sde_core_irq_register_callback(phys_enc->sde_kms,
			vid_enc->irq_idx, &irq_cb);
	ret = sde_core_irq_register_callback(phys_enc->sde_kms, *irq_idx,
			&irq_cb);
	if (ret) {
		SDE_ERROR_VIDENC(vid_enc,
				"failed to register IRQ callback INTF_VSYNC");
			"failed to register IRQ callback for %s\n", irq_name);
		return ret;
	}

	ret = sde_core_irq_enable(phys_enc->sde_kms, &vid_enc->irq_idx, 1);
	ret = sde_core_irq_enable(phys_enc->sde_kms, irq_idx, true);
	if (ret) {
		SDE_ERROR_VIDENC(vid_enc,
			"enable IRQ for INTF_VSYNC failed, irq_idx %d\n",
				vid_enc->irq_idx);
		vid_enc->irq_idx = -EINVAL;
			"enable IRQ for intr:%s failed, irq_idx %d\n",
			irq_name, *irq_idx);
		*irq_idx = -EINVAL;

		/* Unregister callback on IRQ enable failure */
		/* unregister callback on IRQ enable failure */
		sde_core_irq_register_callback(phys_enc->sde_kms,
				vid_enc->irq_idx, NULL);
						*irq_idx, NULL);
		return ret;
	}

	SDE_DEBUG_VIDENC(vid_enc, "registered %d\n", vid_enc->irq_idx);
	SDE_DEBUG_VIDENC(vid_enc, "registered irq %s idx: %d\n",
						irq_name, *irq_idx);

	return ret;
}

static int sde_encoder_phys_vid_unregister_irq(
		struct sde_encoder_phys *phys_enc)
	struct sde_encoder_phys *phys_enc, int irq_idx)
{
	struct sde_encoder_phys_vid *vid_enc =
			to_sde_encoder_phys_vid(phys_enc);

	if (!phys_enc) {
		SDE_ERROR("invalid encoder\n");
		return -EINVAL;
		goto end;
	}

	sde_core_irq_register_callback(phys_enc->sde_kms, vid_enc->irq_idx,
			NULL);
	sde_core_irq_disable(phys_enc->sde_kms, &vid_enc->irq_idx, 1);
	sde_core_irq_disable(phys_enc->sde_kms, &irq_idx, 1);

	sde_core_irq_register_callback(phys_enc->sde_kms, irq_idx, NULL);

	SDE_DEBUG_VIDENC(vid_enc, "unregistered %d\n", vid_enc->irq_idx);
	SDE_DEBUG_VIDENC(vid_enc, "unregistered %d\n", irq_idx);

end:
	return 0;
}

@@ -478,9 +499,13 @@ static int sde_encoder_phys_vid_control_vblank_irq(
			atomic_read(&phys_enc->vblank_refcount));

	if (enable && atomic_inc_return(&phys_enc->vblank_refcount) == 1)
		ret = sde_encoder_phys_vid_register_irq(phys_enc);
		ret = sde_encoder_phys_vid_register_irq(phys_enc,
			SDE_IRQ_TYPE_INTF_VSYNC,
			&vid_enc->irq_idx[INTR_IDX_VSYNC],
			sde_encoder_phys_vid_vblank_irq, "vsync_irq");
	else if (!enable && atomic_dec_return(&phys_enc->vblank_refcount) == 0)
		ret = sde_encoder_phys_vid_unregister_irq(phys_enc);
		ret = sde_encoder_phys_vid_unregister_irq(phys_enc,
			vid_enc->irq_idx[INTR_IDX_VSYNC]);

	if (ret)
		SDE_ERROR_VIDENC(vid_enc,
@@ -497,6 +522,7 @@ static void sde_encoder_phys_vid_enable(struct sde_encoder_phys *phys_enc)
	struct sde_hw_intf *intf = vid_enc->hw_intf;
	struct sde_hw_ctl *ctl = phys_enc->hw_ctl;
	u32 flush_mask = 0;
	int ret;

	if (!phys_enc) {
		SDE_ERROR("invalid encoder\n");
@@ -518,7 +544,18 @@ static void sde_encoder_phys_vid_enable(struct sde_encoder_phys *phys_enc)
		_sde_encoder_phys_vid_split_config(phys_enc, false);

	sde_encoder_phys_vid_setup_timing_engine(phys_enc);
	sde_encoder_phys_vid_control_vblank_irq(phys_enc, true);
	ret = sde_encoder_phys_vid_control_vblank_irq(phys_enc, true);
	if (ret)
		goto end;

	ret = sde_encoder_phys_vid_register_irq(phys_enc,
		SDE_IRQ_TYPE_INTF_UNDER_RUN,
		&vid_enc->irq_idx[INTR_IDX_UNDERRUN],
		sde_encoder_phys_vid_underrun_irq, "underrun");
	if (ret) {
		sde_encoder_phys_vid_control_vblank_irq(phys_enc, false);
		goto end;
	}

	ctl->ops.get_bitmask_intf(ctl, &flush_mask, intf->idx);
	ctl->ops.update_pending_flush(ctl, flush_mask);
@@ -529,6 +566,9 @@ static void sde_encoder_phys_vid_enable(struct sde_encoder_phys *phys_enc)
	/* ctl_flush & timing engine enable will be triggered by framework */
	if (phys_enc->enable_state == SDE_ENC_DISABLED)
		phys_enc->enable_state = SDE_ENC_ENABLING;

end:
	return;
}

static void sde_encoder_phys_vid_disable(struct sde_encoder_phys *phys_enc)
@@ -718,7 +758,6 @@ struct sde_encoder_phys *sde_encoder_phys_vid_init(
		ret = -ENOMEM;
		goto fail;
	}
	vid_enc->irq_idx = -EINVAL;
	init_completion(&vid_enc->vblank_completion);

	phys_enc = &vid_enc->base;
@@ -730,6 +769,7 @@ struct sde_encoder_phys *sde_encoder_phys_vid_init(
		goto fail;
	}
	phys_enc->hw_mdptop = hw_mdp;
	phys_enc->intf_idx = p->intf_idx;

	/**
	 * hw_intf resource permanently assigned to this encoder
@@ -769,7 +809,7 @@ struct sde_encoder_phys *sde_encoder_phys_vid_init(

	phys_enc->enable_state = SDE_ENC_DISABLED;

	SDE_DEBUG_VIDENC(vid_enc, "created\n");
	SDE_DEBUG_VIDENC(vid_enc, "created intf idx:%d\n", p->intf_idx);

	return phys_enc;

Loading