Commit b8c149e2 authored by Dmitry Baryshkov's avatar Dmitry Baryshkov
Browse files

drm/msm/dpu: remove struct dpu_encoder_irq



Remove additional indirection: specify IRQ callbacks and IRQ indices
directly rather than through the pointer in the irq structure. For each
IRQ we have a constant IRQ callback. This change simplifies code review
as the reader no longer needs to remember which function is called.

Signed-off-by: default avatarDmitry Baryshkov <dmitry.baryshkov@linaro.org>
Reviewed-by: default avatarStephen Boyd <swboyd@chromium.org>
Patchwork: https://patchwork.freedesktop.org/patch/474700/
Link: https://lore.kernel.org/r/20220217043148.480898-6-dmitry.baryshkov@linaro.org


Signed-off-by: default avatarDmitry Baryshkov <dmitry.baryshkov@linaro.org>
parent 6ee11c41
Loading
Loading
Loading
Loading
+14 −14
Original line number Diff line number Diff line
@@ -278,9 +278,10 @@ static int dpu_encoder_helper_wait_event_timeout(int32_t drm_id,

int dpu_encoder_helper_wait_for_irq(struct dpu_encoder_phys *phys_enc,
		enum dpu_intr_idx intr_idx,
		void (*func)(void *arg, int irq_idx),
		struct dpu_encoder_wait_info *wait_info)
{
	struct dpu_encoder_irq *irq;
	int irq;
	u32 irq_status;
	int ret;

@@ -288,7 +289,7 @@ int dpu_encoder_helper_wait_for_irq(struct dpu_encoder_phys *phys_enc,
		DPU_ERROR("invalid params\n");
		return -EINVAL;
	}
	irq = &phys_enc->irq[intr_idx];
	irq = phys_enc->irq[intr_idx];

	/* note: do master / slave checking outside */

@@ -296,53 +297,52 @@ int dpu_encoder_helper_wait_for_irq(struct dpu_encoder_phys *phys_enc,
	if (phys_enc->enable_state == DPU_ENC_DISABLED) {
		DRM_ERROR("encoder is disabled id=%u, intr=%d, irq=%d\n",
			  DRMID(phys_enc->parent), intr_idx,
			  irq->irq_idx);
			  irq);
		return -EWOULDBLOCK;
	}

	if (irq->irq_idx < 0) {
		DRM_DEBUG_KMS("skip irq wait id=%u, intr=%d, irq=%s\n",
			      DRMID(phys_enc->parent), intr_idx,
			      irq->name);
	if (irq < 0) {
		DRM_DEBUG_KMS("skip irq wait id=%u, intr=%d\n",
			      DRMID(phys_enc->parent), intr_idx);
		return 0;
	}

	DRM_DEBUG_KMS("id=%u, intr=%d, irq=%d, pp=%d, pending_cnt=%d\n",
		      DRMID(phys_enc->parent), intr_idx,
		      irq->irq_idx, phys_enc->hw_pp->idx - PINGPONG_0,
		      irq, phys_enc->hw_pp->idx - PINGPONG_0,
		      atomic_read(wait_info->atomic_cnt));

	ret = dpu_encoder_helper_wait_event_timeout(
			DRMID(phys_enc->parent),
			irq->irq_idx,
			irq,
			wait_info);

	if (ret <= 0) {
		irq_status = dpu_core_irq_read(phys_enc->dpu_kms, irq->irq_idx);
		irq_status = dpu_core_irq_read(phys_enc->dpu_kms, irq);
		if (irq_status) {
			unsigned long flags;

			DRM_DEBUG_KMS("irq not triggered id=%u, intr=%d, irq=%d, pp=%d, atomic_cnt=%d\n",
				      DRMID(phys_enc->parent), intr_idx,
				      irq->irq_idx,
				      irq,
				      phys_enc->hw_pp->idx - PINGPONG_0,
				      atomic_read(wait_info->atomic_cnt));
			local_irq_save(flags);
			irq->func(phys_enc, irq->irq_idx);
			func(phys_enc, irq);
			local_irq_restore(flags);
			ret = 0;
		} else {
			ret = -ETIMEDOUT;
			DRM_DEBUG_KMS("irq timeout id=%u, intr=%d, irq=%d, pp=%d, atomic_cnt=%d\n",
				      DRMID(phys_enc->parent), intr_idx,
				      irq->irq_idx,
				      irq,
				      phys_enc->hw_pp->idx - PINGPONG_0,
				      atomic_read(wait_info->atomic_cnt));
		}
	} else {
		ret = 0;
		trace_dpu_enc_irq_wait_success(DRMID(phys_enc->parent),
			intr_idx, irq->irq_idx,
			intr_idx, irq,
			phys_enc->hw_pp->idx - PINGPONG_0,
			atomic_read(wait_info->atomic_cnt));
	}
+4 −17
Original line number Diff line number Diff line
@@ -153,21 +153,6 @@ enum dpu_intr_idx {
	INTR_IDX_MAX,
};

/**
 * dpu_encoder_irq - tracking structure for interrupts
 * @name:		string name of interrupt
 * @intr_idx:		Encoder interrupt enumeration
 * @irq_idx:		IRQ interface lookup index from DPU IRQ framework
 *			will be -EINVAL if IRQ is not registered
 * @irq_cb:		interrupt callback
 */
struct dpu_encoder_irq {
	const char *name;
	enum dpu_intr_idx intr_idx;
	int irq_idx;
	void (*func)(void *arg, int irq_idx);
};

/**
 * struct dpu_encoder_phys - physical encoder that drives a single INTF block
 *	tied to a specific panel / sub-panel. Abstract type, sub-classed by
@@ -197,7 +182,7 @@ struct dpu_encoder_irq {
 * @pending_ctlstart_cnt:	Atomic counter tracking the number of ctl start
 *                              pending.
 * @pending_kickoff_wq:		Wait queue for blocking until kickoff completes
 * @irq:			IRQ tracking structures
 * @irq:			IRQ indices
 */
struct dpu_encoder_phys {
	struct drm_encoder *parent;
@@ -220,7 +205,7 @@ struct dpu_encoder_phys {
	atomic_t pending_ctlstart_cnt;
	atomic_t pending_kickoff_cnt;
	wait_queue_head_t pending_kickoff_wq;
	struct dpu_encoder_irq irq[INTR_IDX_MAX];
	int irq[INTR_IDX_MAX];
};

static inline int dpu_encoder_phys_inc_pending(struct dpu_encoder_phys *phys)
@@ -356,11 +341,13 @@ void dpu_encoder_helper_report_irq_timeout(struct dpu_encoder_phys *phys_enc,
 *	note: will call dpu_encoder_helper_wait_for_irq on timeout
 * @phys_enc: Pointer to physical encoder structure
 * @intr_idx: encoder interrupt index
 * @func: IRQ callback to be called in case of timeout
 * @wait_info: wait info struct
 * @Return: 0 or -ERROR
 */
int dpu_encoder_helper_wait_for_irq(struct dpu_encoder_phys *phys_enc,
		enum dpu_intr_idx intr_idx,
		void (*func)(void *arg, int irq_idx),
		struct dpu_encoder_wait_info *wait_info);

#endif /* __dpu_encoder_phys_H__ */
+26 −48
Original line number Diff line number Diff line
@@ -140,19 +140,13 @@ static void dpu_encoder_phys_cmd_atomic_mode_set(
		struct drm_crtc_state *crtc_state,
		struct drm_connector_state *conn_state)
{
	struct dpu_encoder_irq *irq;
	phys_enc->irq[INTR_IDX_CTL_START] = phys_enc->hw_ctl->caps->intr_start;

	irq = &phys_enc->irq[INTR_IDX_CTL_START];
	irq->irq_idx = phys_enc->hw_ctl->caps->intr_start;
	phys_enc->irq[INTR_IDX_PINGPONG] = phys_enc->hw_pp->caps->intr_done;

	irq = &phys_enc->irq[INTR_IDX_PINGPONG];
	irq->irq_idx = phys_enc->hw_pp->caps->intr_done;
	phys_enc->irq[INTR_IDX_RDPTR] = phys_enc->hw_pp->caps->intr_rdptr;

	irq = &phys_enc->irq[INTR_IDX_RDPTR];
	irq->irq_idx = phys_enc->hw_pp->caps->intr_rdptr;

	irq = &phys_enc->irq[INTR_IDX_UNDERRUN];
	irq->irq_idx = phys_enc->hw_intf->cap->intr_underrun;
	phys_enc->irq[INTR_IDX_UNDERRUN] = phys_enc->hw_intf->cap->intr_underrun;
}

static int _dpu_encoder_phys_cmd_handle_ppdone_timeout(
@@ -193,7 +187,7 @@ static int _dpu_encoder_phys_cmd_handle_ppdone_timeout(
			  atomic_read(&phys_enc->pending_kickoff_cnt));
		msm_disp_snapshot_state(drm_enc->dev);
		dpu_core_irq_unregister_callback(phys_enc->dpu_kms,
				phys_enc->irq[INTR_IDX_RDPTR].irq_idx);
				phys_enc->irq[INTR_IDX_RDPTR]);
	}

	atomic_add_unless(&phys_enc->pending_kickoff_cnt, -1, 0);
@@ -221,6 +215,7 @@ static int _dpu_encoder_phys_cmd_wait_for_idle(
	wait_info.timeout_ms = KICKOFF_TIMEOUT_MS;

	ret = dpu_encoder_helper_wait_for_irq(phys_enc, INTR_IDX_PINGPONG,
			dpu_encoder_phys_cmd_pp_tx_done_irq,
			&wait_info);
	if (ret == -ETIMEDOUT)
		_dpu_encoder_phys_cmd_handle_ppdone_timeout(phys_enc);
@@ -260,11 +255,12 @@ static int dpu_encoder_phys_cmd_control_vblank_irq(

	if (enable && atomic_inc_return(&phys_enc->vblank_refcount) == 1)
		ret = dpu_core_irq_register_callback(phys_enc->dpu_kms,
				phys_enc->irq[INTR_IDX_RDPTR].irq_idx,
				phys_enc->irq[INTR_IDX_RDPTR].func, phys_enc);
				phys_enc->irq[INTR_IDX_RDPTR],
				dpu_encoder_phys_cmd_pp_rd_ptr_irq,
				phys_enc);
	else if (!enable && atomic_dec_return(&phys_enc->vblank_refcount) == 0)
		ret = dpu_core_irq_unregister_callback(phys_enc->dpu_kms,
				phys_enc->irq[INTR_IDX_RDPTR].irq_idx);
				phys_enc->irq[INTR_IDX_RDPTR]);

end:
	if (ret) {
@@ -286,27 +282,30 @@ static void dpu_encoder_phys_cmd_irq_control(struct dpu_encoder_phys *phys_enc,

	if (enable) {
		dpu_core_irq_register_callback(phys_enc->dpu_kms,
				phys_enc->irq[INTR_IDX_PINGPONG].irq_idx,
				phys_enc->irq[INTR_IDX_PINGPONG].func, phys_enc);
				phys_enc->irq[INTR_IDX_PINGPONG],
				dpu_encoder_phys_cmd_pp_tx_done_irq,
				phys_enc);
		dpu_core_irq_register_callback(phys_enc->dpu_kms,
				phys_enc->irq[INTR_IDX_UNDERRUN].irq_idx,
				phys_enc->irq[INTR_IDX_UNDERRUN].func, phys_enc);
				phys_enc->irq[INTR_IDX_UNDERRUN],
				dpu_encoder_phys_cmd_underrun_irq,
				phys_enc);
		dpu_encoder_phys_cmd_control_vblank_irq(phys_enc, true);

		if (dpu_encoder_phys_cmd_is_master(phys_enc))
			dpu_core_irq_register_callback(phys_enc->dpu_kms,
					phys_enc->irq[INTR_IDX_CTL_START].irq_idx,
					phys_enc->irq[INTR_IDX_CTL_START].func, phys_enc);
					phys_enc->irq[INTR_IDX_CTL_START],
					dpu_encoder_phys_cmd_ctl_start_irq,
					phys_enc);
	} else {
		if (dpu_encoder_phys_cmd_is_master(phys_enc))
			dpu_core_irq_unregister_callback(phys_enc->dpu_kms,
					phys_enc->irq[INTR_IDX_CTL_START].irq_idx);
					phys_enc->irq[INTR_IDX_CTL_START]);

		dpu_core_irq_unregister_callback(phys_enc->dpu_kms,
				phys_enc->irq[INTR_IDX_UNDERRUN].irq_idx);
				phys_enc->irq[INTR_IDX_UNDERRUN]);
		dpu_encoder_phys_cmd_control_vblank_irq(phys_enc, false);
		dpu_core_irq_unregister_callback(phys_enc->dpu_kms,
				phys_enc->irq[INTR_IDX_PINGPONG].irq_idx);
				phys_enc->irq[INTR_IDX_PINGPONG]);
	}
}

@@ -634,6 +633,7 @@ static int _dpu_encoder_phys_cmd_wait_for_ctl_start(
	wait_info.timeout_ms = KICKOFF_TIMEOUT_MS;

	ret = dpu_encoder_helper_wait_for_irq(phys_enc, INTR_IDX_CTL_START,
			dpu_encoder_phys_cmd_ctl_start_irq,
			&wait_info);
	if (ret == -ETIMEDOUT) {
		DPU_ERROR_CMDENC(cmd_enc, "ctl start interrupt wait failed\n");
@@ -692,6 +692,7 @@ static int dpu_encoder_phys_cmd_wait_for_vblank(
	atomic_inc(&cmd_enc->pending_vblank_cnt);

	rc = dpu_encoder_helper_wait_for_irq(phys_enc, INTR_IDX_RDPTR,
			dpu_encoder_phys_cmd_pp_rd_ptr_irq,
			&wait_info);

	return rc;
@@ -741,7 +742,6 @@ struct dpu_encoder_phys *dpu_encoder_phys_cmd_init(
{
	struct dpu_encoder_phys *phys_enc = NULL;
	struct dpu_encoder_phys_cmd *cmd_enc = NULL;
	struct dpu_encoder_irq *irq;
	int i, ret = 0;

	DPU_DEBUG("intf %d\n", p->intf_idx - INTF_0);
@@ -765,30 +765,8 @@ struct dpu_encoder_phys *dpu_encoder_phys_cmd_init(
	phys_enc->enc_spinlock = p->enc_spinlock;
	cmd_enc->stream_sel = 0;
	phys_enc->enable_state = DPU_ENC_DISABLED;
	for (i = 0; i < INTR_IDX_MAX; i++) {
		irq = &phys_enc->irq[i];
		irq->irq_idx = -EINVAL;
	}

	irq = &phys_enc->irq[INTR_IDX_CTL_START];
	irq->name = "ctl_start";
	irq->intr_idx = INTR_IDX_CTL_START;
	irq->func = dpu_encoder_phys_cmd_ctl_start_irq;

	irq = &phys_enc->irq[INTR_IDX_PINGPONG];
	irq->name = "pp_done";
	irq->intr_idx = INTR_IDX_PINGPONG;
	irq->func = dpu_encoder_phys_cmd_pp_tx_done_irq;

	irq = &phys_enc->irq[INTR_IDX_RDPTR];
	irq->name = "pp_rd_ptr";
	irq->intr_idx = INTR_IDX_RDPTR;
	irq->func = dpu_encoder_phys_cmd_pp_rd_ptr_irq;

	irq = &phys_enc->irq[INTR_IDX_UNDERRUN];
	irq->name = "underrun";
	irq->intr_idx = INTR_IDX_UNDERRUN;
	irq->func = dpu_encoder_phys_cmd_underrun_irq;
	for (i = 0; i < ARRAY_SIZE(phys_enc->irq); i++)
		phys_enc->irq[i] = -EINVAL;

	atomic_set(&phys_enc->vblank_refcount, 0);
	atomic_set(&phys_enc->pending_kickoff_cnt, 0);
+14 −28
Original line number Diff line number Diff line
@@ -367,13 +367,9 @@ static void dpu_encoder_phys_vid_atomic_mode_set(
		struct drm_crtc_state *crtc_state,
		struct drm_connector_state *conn_state)
{
	struct dpu_encoder_irq *irq;
	phys_enc->irq[INTR_IDX_VSYNC] = phys_enc->hw_intf->cap->intr_vsync;

	irq = &phys_enc->irq[INTR_IDX_VSYNC];
	irq->irq_idx = phys_enc->hw_intf->cap->intr_vsync;

	irq = &phys_enc->irq[INTR_IDX_UNDERRUN];
	irq->irq_idx = phys_enc->hw_intf->cap->intr_underrun;
	phys_enc->irq[INTR_IDX_UNDERRUN] = phys_enc->hw_intf->cap->intr_underrun;
}

static int dpu_encoder_phys_vid_control_vblank_irq(
@@ -400,11 +396,12 @@ static int dpu_encoder_phys_vid_control_vblank_irq(

	if (enable && atomic_inc_return(&phys_enc->vblank_refcount) == 1)
		ret = dpu_core_irq_register_callback(phys_enc->dpu_kms,
				phys_enc->irq[INTR_IDX_VSYNC].irq_idx,
				phys_enc->irq[INTR_IDX_VSYNC].func, phys_enc);
				phys_enc->irq[INTR_IDX_VSYNC],
				dpu_encoder_phys_vid_vblank_irq,
				phys_enc);
	else if (!enable && atomic_dec_return(&phys_enc->vblank_refcount) == 0)
		ret = dpu_core_irq_unregister_callback(phys_enc->dpu_kms,
				phys_enc->irq[INTR_IDX_VSYNC].irq_idx);
				phys_enc->irq[INTR_IDX_VSYNC]);

end:
	if (ret) {
@@ -478,6 +475,7 @@ static int dpu_encoder_phys_vid_wait_for_vblank(

	/* Wait for kickoff to complete */
	ret = dpu_encoder_helper_wait_for_irq(phys_enc, INTR_IDX_VSYNC,
			dpu_encoder_phys_vid_vblank_irq,
			&wait_info);

	if (ret == -ETIMEDOUT) {
@@ -530,7 +528,7 @@ static void dpu_encoder_phys_vid_prepare_for_kickoff(
				ctl->idx, rc);
		msm_disp_snapshot_state(drm_enc->dev);
		dpu_core_irq_unregister_callback(phys_enc->dpu_kms,
				phys_enc->irq[INTR_IDX_VSYNC].irq_idx);
				phys_enc->irq[INTR_IDX_VSYNC]);
	}
}

@@ -620,12 +618,13 @@ static void dpu_encoder_phys_vid_irq_control(struct dpu_encoder_phys *phys_enc,
			return;

		dpu_core_irq_register_callback(phys_enc->dpu_kms,
				phys_enc->irq[INTR_IDX_UNDERRUN].irq_idx,
				phys_enc->irq[INTR_IDX_UNDERRUN].func, phys_enc);
				phys_enc->irq[INTR_IDX_UNDERRUN],
				dpu_encoder_phys_vid_underrun_irq,
				phys_enc);
	} else {
		dpu_encoder_phys_vid_control_vblank_irq(phys_enc, false);
		dpu_core_irq_unregister_callback(phys_enc->dpu_kms,
				phys_enc->irq[INTR_IDX_UNDERRUN].irq_idx);
				phys_enc->irq[INTR_IDX_UNDERRUN]);
	}
}

@@ -689,7 +688,6 @@ struct dpu_encoder_phys *dpu_encoder_phys_vid_init(
		struct dpu_enc_phys_init_params *p)
{
	struct dpu_encoder_phys *phys_enc = NULL;
	struct dpu_encoder_irq *irq;
	int i;

	if (!p) {
@@ -715,20 +713,8 @@ struct dpu_encoder_phys *dpu_encoder_phys_vid_init(
	phys_enc->split_role = p->split_role;
	phys_enc->intf_mode = INTF_MODE_VIDEO;
	phys_enc->enc_spinlock = p->enc_spinlock;
	for (i = 0; i < INTR_IDX_MAX; i++) {
		irq = &phys_enc->irq[i];
		irq->irq_idx = -EINVAL;
	}

	irq = &phys_enc->irq[INTR_IDX_VSYNC];
	irq->name = "vsync_irq";
	irq->intr_idx = INTR_IDX_VSYNC;
	irq->func = dpu_encoder_phys_vid_vblank_irq;

	irq = &phys_enc->irq[INTR_IDX_UNDERRUN];
	irq->name = "underrun";
	irq->intr_idx = INTR_IDX_UNDERRUN;
	irq->func = dpu_encoder_phys_vid_underrun_irq;
	for (i = 0; i < ARRAY_SIZE(phys_enc->irq); i++)
		phys_enc->irq[i] = -EINVAL;

	atomic_set(&phys_enc->vblank_refcount, 0);
	atomic_set(&phys_enc->pending_kickoff_cnt, 0);