Unverified Commit 5a346290 authored by openeuler-ci-bot's avatar openeuler-ci-bot Committed by Gitee
Browse files

!5307 drm/msm/dpu: Add mutex lock in control vblank irq

parents 513f709d a4393a1e
Loading
Loading
Loading
Loading
+3 −1
Original line number Diff line number Diff line
@@ -194,6 +194,7 @@ struct dpu_encoder_irq {
 * @hw_intf:		Hardware interface to the intf registers
 * @dpu_kms:		Pointer to the dpu_kms top level
 * @cached_mode:	DRM mode cached at mode_set time, acted on in enable
 * @vblank_ctl_lock:	Vblank ctl mutex lock to protect vblank_refcount
 * @enabled:		Whether the encoder has enabled and running a mode
 * @split_role:		Role to play in a split-panel configuration
 * @intf_mode:		Interface mode
@@ -223,12 +224,13 @@ struct dpu_encoder_phys {
	struct dpu_hw_intf *hw_intf;
	struct dpu_kms *dpu_kms;
	struct drm_display_mode cached_mode;
	struct mutex vblank_ctl_lock;
	enum dpu_enc_split_role split_role;
	enum dpu_intf_mode intf_mode;
	enum dpu_intf intf_idx;
	spinlock_t *enc_spinlock;
	enum dpu_enc_enable_state enable_state;
	atomic_t vblank_refcount;
	int vblank_refcount;
	atomic_t vsync_cnt;
	atomic_t underrun_cnt;
	atomic_t pending_ctlstart_cnt;
+19 −8
Original line number Diff line number Diff line
@@ -263,7 +263,8 @@ static int dpu_encoder_phys_cmd_control_vblank_irq(
		return -EINVAL;
	}

	refcount = atomic_read(&phys_enc->vblank_refcount);
	mutex_lock(&phys_enc->vblank_ctl_lock);
	refcount = phys_enc->vblank_refcount;

	/* Slave encoders don't report vblank */
	if (!dpu_encoder_phys_cmd_is_master(phys_enc))
@@ -279,13 +280,21 @@ static int dpu_encoder_phys_cmd_control_vblank_irq(
		      phys_enc->hw_pp->idx - PINGPONG_0,
		      enable ? "true" : "false", refcount);

	if (enable && atomic_inc_return(&phys_enc->vblank_refcount) == 1)
	if (enable) {
		if (phys_enc->vblank_refcount == 0)
			ret = dpu_encoder_helper_register_irq(phys_enc, INTR_IDX_RDPTR);
	else if (!enable && atomic_dec_return(&phys_enc->vblank_refcount) == 0)
		if (!ret)
			phys_enc->vblank_refcount++;
	} else if (!enable) {
		if (phys_enc->vblank_refcount == 1)
			ret = dpu_encoder_helper_unregister_irq(phys_enc,
					INTR_IDX_RDPTR);
		if (!ret)
			phys_enc->vblank_refcount--;
	}

end:
	mutex_unlock(&phys_enc->vblank_ctl_lock);
	if (ret) {
		DRM_ERROR("vblank irq err id:%u pp:%d ret:%d, enable %s/%d\n",
			  DRMID(phys_enc->parent),
@@ -301,7 +310,7 @@ static void dpu_encoder_phys_cmd_irq_control(struct dpu_encoder_phys *phys_enc,
{
	trace_dpu_enc_phys_cmd_irq_ctrl(DRMID(phys_enc->parent),
			phys_enc->hw_pp->idx - PINGPONG_0,
			enable, atomic_read(&phys_enc->vblank_refcount));
			enable, phys_enc->vblank_refcount);

	if (enable) {
		dpu_encoder_helper_register_irq(phys_enc, INTR_IDX_PINGPONG);
@@ -724,6 +733,9 @@ struct dpu_encoder_phys *dpu_encoder_phys_cmd_init(
	phys_enc->hw_mdptop = p->dpu_kms->hw_mdp;
	phys_enc->intf_idx = p->intf_idx;

	mutex_init(&phys_enc->vblank_ctl_lock);
	phys_enc->vblank_refcount = 0;

	dpu_encoder_phys_cmd_init_ops(&phys_enc->ops);
	phys_enc->parent = p->parent;
	phys_enc->parent_ops = p->parent_ops;
@@ -765,7 +777,6 @@ struct dpu_encoder_phys *dpu_encoder_phys_cmd_init(
	irq->intr_idx = INTR_IDX_UNDERRUN;
	irq->cb.func = dpu_encoder_phys_cmd_underrun_irq;

	atomic_set(&phys_enc->vblank_refcount, 0);
	atomic_set(&phys_enc->pending_kickoff_cnt, 0);
	atomic_set(&phys_enc->pending_ctlstart_cnt, 0);
	atomic_set(&cmd_enc->pending_vblank_cnt, 0);
+21 −10
Original line number Diff line number Diff line
@@ -395,7 +395,8 @@ static int dpu_encoder_phys_vid_control_vblank_irq(
	int ret = 0;
	int refcount;

	refcount = atomic_read(&phys_enc->vblank_refcount);
	mutex_lock(&phys_enc->vblank_ctl_lock);
	refcount = phys_enc->vblank_refcount;

	/* Slave encoders don't report vblank */
	if (!dpu_encoder_phys_vid_is_master(phys_enc))
@@ -407,16 +408,24 @@ static int dpu_encoder_phys_vid_control_vblank_irq(
		goto end;
	}

	DRM_DEBUG_KMS("id:%u enable=%d/%d\n", DRMID(phys_enc->parent), enable,
		      atomic_read(&phys_enc->vblank_refcount));
	DRM_DEBUG_VBL("id:%u enable=%d/%d\n", DRMID(phys_enc->parent), enable,
		      refcount);

	if (enable && atomic_inc_return(&phys_enc->vblank_refcount) == 1)
	if (enable) {
		if (phys_enc->vblank_refcount == 0)
			ret = dpu_encoder_helper_register_irq(phys_enc, INTR_IDX_VSYNC);
	else if (!enable && atomic_dec_return(&phys_enc->vblank_refcount) == 0)
		if (!ret)
			phys_enc->vblank_refcount++;
	} else if (!enable) {
		if (phys_enc->vblank_refcount == 1)
			ret = dpu_encoder_helper_unregister_irq(phys_enc,
					INTR_IDX_VSYNC);
		if (!ret)
			phys_enc->vblank_refcount--;
	}

end:
	mutex_unlock(&phys_enc->vblank_ctl_lock);
	if (ret) {
		DRM_ERROR("failed: id:%u intf:%d ret:%d enable:%d refcnt:%d\n",
			  DRMID(phys_enc->parent),
@@ -631,7 +640,7 @@ static void dpu_encoder_phys_vid_irq_control(struct dpu_encoder_phys *phys_enc,
	trace_dpu_enc_phys_vid_irq_ctrl(DRMID(phys_enc->parent),
			    phys_enc->hw_intf->idx - INTF_0,
			    enable,
			    atomic_read(&phys_enc->vblank_refcount));
			    phys_enc->vblank_refcount);

	if (enable) {
		ret = dpu_encoder_phys_vid_control_vblank_irq(phys_enc, true);
@@ -700,6 +709,9 @@ struct dpu_encoder_phys *dpu_encoder_phys_vid_init(

	DPU_DEBUG_VIDENC(phys_enc, "\n");

	mutex_init(&phys_enc->vblank_ctl_lock);
	phys_enc->vblank_refcount = 0;

	dpu_encoder_phys_vid_init_ops(&phys_enc->ops);
	phys_enc->parent = p->parent;
	phys_enc->parent_ops = p->parent_ops;
@@ -727,7 +739,6 @@ struct dpu_encoder_phys *dpu_encoder_phys_vid_init(
	irq->intr_idx = INTR_IDX_UNDERRUN;
	irq->cb.func = dpu_encoder_phys_vid_underrun_irq;

	atomic_set(&phys_enc->vblank_refcount, 0);
	atomic_set(&phys_enc->pending_kickoff_cnt, 0);
	init_waitqueue_head(&phys_enc->pending_kickoff_wq);
	phys_enc->enable_state = DPU_ENC_DISABLED;