Commit 667e9985 authored by Dmitry Baryshkov's avatar Dmitry Baryshkov Committed by Rob Clark
Browse files

drm/msm/dpu: replace IRQ lookup with the data in hw catalog



The IRQ table in the dpu_hw_interrupts.h is big, ugly, and hard to
maintain. There are only few interrupts used from that table. Newer
generations use different IRQ locations. Move this data to hw catalog.

Signed-off-by: default avatarDmitry Baryshkov <dmitry.baryshkov@linaro.org>
Reviewed-by: default avatarAbhinav Kumar <abhinavk@codeaurora.org>
Link: https://lore.kernel.org/r/20210516202910.2141079-5-dmitry.baryshkov@linaro.org


[fixup tracepoint compile warns/err]
Signed-off-by: default avatarRob Clark <robdclark@chromium.org>
parent 597762d5
Loading
Loading
Loading
Loading
+5 −15
Original line number Diff line number Diff line
@@ -43,16 +43,6 @@ static void dpu_core_irq_callback_handler(void *arg, int irq_idx)
	spin_unlock_irqrestore(&dpu_kms->irq_obj.cb_lock, irq_flags);
}

int dpu_core_irq_idx_lookup(struct dpu_kms *dpu_kms,
		enum dpu_intr_type intr_type, u32 instance_idx)
{
	if (!dpu_kms->hw_intr || !dpu_kms->hw_intr->ops.irq_idx_lookup)
		return -EINVAL;

	return dpu_kms->hw_intr->ops.irq_idx_lookup(dpu_kms->hw_intr,
			intr_type, instance_idx);
}

/**
 * _dpu_core_irq_enable - enable core interrupt given by the index
 * @dpu_kms:		Pointer to dpu kms context
@@ -70,7 +60,7 @@ static int _dpu_core_irq_enable(struct dpu_kms *dpu_kms, int irq_idx)
		return -EINVAL;
	}

	if (irq_idx < 0 || irq_idx >= dpu_kms->hw_intr->irq_idx_tbl_size) {
	if (irq_idx < 0 || irq_idx >= dpu_kms->hw_intr->total_irqs) {
		DPU_ERROR("invalid IRQ index: [%d]\n", irq_idx);
		return -EINVAL;
	}
@@ -133,7 +123,7 @@ static int _dpu_core_irq_disable(struct dpu_kms *dpu_kms, int irq_idx)
		return -EINVAL;
	}

	if (irq_idx < 0 || irq_idx >= dpu_kms->hw_intr->irq_idx_tbl_size) {
	if (irq_idx < 0 || irq_idx >= dpu_kms->hw_intr->total_irqs) {
		DPU_ERROR("invalid IRQ index: [%d]\n", irq_idx);
		return -EINVAL;
	}
@@ -208,7 +198,7 @@ int dpu_core_irq_register_callback(struct dpu_kms *dpu_kms, int irq_idx,
		return -EINVAL;
	}

	if (irq_idx < 0 || irq_idx >= dpu_kms->hw_intr->irq_idx_tbl_size) {
	if (irq_idx < 0 || irq_idx >= dpu_kms->hw_intr->total_irqs) {
		DPU_ERROR("invalid IRQ index: [%d]\n", irq_idx);
		return -EINVAL;
	}
@@ -243,7 +233,7 @@ int dpu_core_irq_unregister_callback(struct dpu_kms *dpu_kms, int irq_idx,
		return -EINVAL;
	}

	if (irq_idx < 0 || irq_idx >= dpu_kms->hw_intr->irq_idx_tbl_size) {
	if (irq_idx < 0 || irq_idx >= dpu_kms->hw_intr->total_irqs) {
		DPU_ERROR("invalid IRQ index: [%d]\n", irq_idx);
		return -EINVAL;
	}
@@ -328,7 +318,7 @@ void dpu_core_irq_preinstall(struct dpu_kms *dpu_kms)
	spin_lock_init(&dpu_kms->irq_obj.cb_lock);

	/* Create irq callbacks for all possible irq_idx */
	dpu_kms->irq_obj.total_irqs = dpu_kms->hw_intr->irq_idx_tbl_size;
	dpu_kms->irq_obj.total_irqs = dpu_kms->hw_intr->total_irqs;
	dpu_kms->irq_obj.irq_cb_tbl = kcalloc(dpu_kms->irq_obj.total_irqs,
			sizeof(struct list_head), GFP_KERNEL);
	dpu_kms->irq_obj.enable_counts = kcalloc(dpu_kms->irq_obj.total_irqs,
+0 −13
Original line number Diff line number Diff line
@@ -29,19 +29,6 @@ void dpu_core_irq_uninstall(struct dpu_kms *dpu_kms);
 */
irqreturn_t dpu_core_irq(struct dpu_kms *dpu_kms);

/**
 * dpu_core_irq_idx_lookup - IRQ helper function for lookup irq_idx from HW
 *                      interrupt mapping table.
 * @dpu_kms:		DPU handle
 * @intr_type:		DPU HW interrupt type for lookup
 * @instance_idx:	DPU HW block instance defined in dpu_hw_mdss.h
 * @return:		irq_idx or -EINVAL when fail to lookup
 */
int dpu_core_irq_idx_lookup(
		struct dpu_kms *dpu_kms,
		enum dpu_intr_type intr_type,
		uint32_t instance_idx);

/**
 * dpu_core_irq_enable - IRQ helper function for enabling one or more IRQs
 * @dpu_kms:		DPU handle
+26 −38
Original line number Diff line number Diff line
@@ -254,7 +254,7 @@ void dpu_encoder_helper_report_irq_timeout(struct dpu_encoder_phys *phys_enc,
}

static int dpu_encoder_helper_wait_event_timeout(int32_t drm_id,
		int32_t hw_id, struct dpu_encoder_wait_info *info);
		u32 irq_idx, struct dpu_encoder_wait_info *info);

int dpu_encoder_helper_wait_for_irq(struct dpu_encoder_phys *phys_enc,
		enum dpu_intr_idx intr_idx,
@@ -274,27 +274,27 @@ int dpu_encoder_helper_wait_for_irq(struct dpu_encoder_phys *phys_enc,

	/* return EWOULDBLOCK since we know the wait isn't necessary */
	if (phys_enc->enable_state == DPU_ENC_DISABLED) {
		DRM_ERROR("encoder is disabled id=%u, intr=%d, hw=%d, irq=%d",
			  DRMID(phys_enc->parent), intr_idx, irq->hw_idx,
		DRM_ERROR("encoder is disabled id=%u, intr=%d, irq=%d",
			  DRMID(phys_enc->parent), intr_idx,
			  irq->irq_idx);
		return -EWOULDBLOCK;
	}

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

	DRM_DEBUG_KMS("id=%u, intr=%d, hw=%d, irq=%d, pp=%d, pending_cnt=%d",
		      DRMID(phys_enc->parent), intr_idx, irq->hw_idx,
	DRM_DEBUG_KMS("id=%u, intr=%d, irq=%d, pp=%d, pending_cnt=%d",
		      DRMID(phys_enc->parent), intr_idx,
		      irq->irq_idx, 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->hw_idx,
			irq->irq_idx,
			wait_info);

	if (ret <= 0) {
@@ -304,9 +304,9 @@ int dpu_encoder_helper_wait_for_irq(struct dpu_encoder_phys *phys_enc,
			unsigned long flags;

			DRM_DEBUG_KMS("irq not triggered id=%u, intr=%d, "
				      "hw=%d, irq=%d, pp=%d, atomic_cnt=%d",
				      "irq=%d, pp=%d, atomic_cnt=%d",
				      DRMID(phys_enc->parent), intr_idx,
				      irq->hw_idx, irq->irq_idx,
				      irq->irq_idx,
				      phys_enc->hw_pp->idx - PINGPONG_0,
				      atomic_read(wait_info->atomic_cnt));
			local_irq_save(flags);
@@ -316,16 +316,16 @@ int dpu_encoder_helper_wait_for_irq(struct dpu_encoder_phys *phys_enc,
		} else {
			ret = -ETIMEDOUT;
			DRM_DEBUG_KMS("irq timeout id=%u, intr=%d, "
				      "hw=%d, irq=%d, pp=%d, atomic_cnt=%d",
				      "irq=%d, pp=%d, atomic_cnt=%d",
				      DRMID(phys_enc->parent), intr_idx,
				      irq->hw_idx, irq->irq_idx,
				      irq->irq_idx,
				      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->hw_idx, irq->irq_idx,
			intr_idx, irq->irq_idx,
			phys_enc->hw_pp->idx - PINGPONG_0,
			atomic_read(wait_info->atomic_cnt));
	}
@@ -345,19 +345,9 @@ int dpu_encoder_helper_register_irq(struct dpu_encoder_phys *phys_enc,
	}
	irq = &phys_enc->irq[intr_idx];

	if (irq->irq_idx >= 0) {
		DPU_DEBUG_PHYS(phys_enc,
				"skipping already registered irq %s type %d\n",
				irq->name, irq->intr_type);
		return 0;
	}

	irq->irq_idx = dpu_core_irq_idx_lookup(phys_enc->dpu_kms,
			irq->intr_type, irq->hw_idx);
	if (irq->irq_idx < 0) {
		DPU_ERROR_PHYS(phys_enc,
			"failed to lookup IRQ index for %s type:%d\n",
			irq->name, irq->intr_type);
			"invalid IRQ index:%d\n", irq->irq_idx);
		return -EINVAL;
	}

@@ -373,8 +363,8 @@ int dpu_encoder_helper_register_irq(struct dpu_encoder_phys *phys_enc,

	ret = dpu_core_irq_enable(phys_enc->dpu_kms, &irq->irq_idx, 1);
	if (ret) {
		DRM_ERROR("enable failed id=%u, intr=%d, hw=%d, irq=%d",
			  DRMID(phys_enc->parent), intr_idx, irq->hw_idx,
		DRM_ERROR("enable failed id=%u, intr=%d, irq=%d",
			  DRMID(phys_enc->parent), intr_idx,
			  irq->irq_idx);
		dpu_core_irq_unregister_callback(phys_enc->dpu_kms,
				irq->irq_idx, &irq->cb);
@@ -383,7 +373,7 @@ int dpu_encoder_helper_register_irq(struct dpu_encoder_phys *phys_enc,
	}

	trace_dpu_enc_irq_register_success(DRMID(phys_enc->parent), intr_idx,
				irq->hw_idx, irq->irq_idx);
				irq->irq_idx);

	return ret;
}
@@ -398,31 +388,29 @@ int dpu_encoder_helper_unregister_irq(struct dpu_encoder_phys *phys_enc,

	/* silently skip irqs that weren't registered */
	if (irq->irq_idx < 0) {
		DRM_ERROR("duplicate unregister id=%u, intr=%d, hw=%d, irq=%d",
			  DRMID(phys_enc->parent), intr_idx, irq->hw_idx,
		DRM_ERROR("duplicate unregister id=%u, intr=%d, irq=%d",
			  DRMID(phys_enc->parent), intr_idx,
			  irq->irq_idx);
		return 0;
	}

	ret = dpu_core_irq_disable(phys_enc->dpu_kms, &irq->irq_idx, 1);
	if (ret) {
		DRM_ERROR("disable failed id=%u, intr=%d, hw=%d, irq=%d ret=%d",
			  DRMID(phys_enc->parent), intr_idx, irq->hw_idx,
		DRM_ERROR("disable failed id=%u, intr=%d, irq=%d ret=%d",
			  DRMID(phys_enc->parent), intr_idx,
			  irq->irq_idx, ret);
	}

	ret = dpu_core_irq_unregister_callback(phys_enc->dpu_kms, irq->irq_idx,
			&irq->cb);
	if (ret) {
		DRM_ERROR("unreg cb fail id=%u, intr=%d, hw=%d, irq=%d ret=%d",
			  DRMID(phys_enc->parent), intr_idx, irq->hw_idx,
		DRM_ERROR("unreg cb fail id=%u, intr=%d, irq=%d ret=%d",
			  DRMID(phys_enc->parent), intr_idx,
			  irq->irq_idx, ret);
	}

	trace_dpu_enc_irq_unregister_success(DRMID(phys_enc->parent), intr_idx,
					     irq->hw_idx, irq->irq_idx);

	irq->irq_idx = -EINVAL;
					     irq->irq_idx);

	return 0;
}
@@ -1543,7 +1531,7 @@ void dpu_encoder_helper_trigger_start(struct dpu_encoder_phys *phys_enc)

static int dpu_encoder_helper_wait_event_timeout(
		int32_t drm_id,
		int32_t hw_id,
		u32 irq_idx,
		struct dpu_encoder_wait_info *info)
{
	int rc = 0;
@@ -1556,7 +1544,7 @@ static int dpu_encoder_helper_wait_event_timeout(
				atomic_read(info->atomic_cnt) == 0, jiffies);
		time = ktime_to_ms(ktime_get());

		trace_dpu_enc_wait_event_timeout(drm_id, hw_id, rc, time,
		trace_dpu_enc_wait_event_timeout(drm_id, irq_idx, rc, time,
						 expected_time,
						 atomic_read(info->atomic_cnt));
	/* If we timed out, counter is valid and time is less, wait again */
+0 −2
Original line number Diff line number Diff line
@@ -167,7 +167,6 @@ enum dpu_intr_idx {
 * @name:		string name of interrupt
 * @intr_type:		Encoder interrupt type
 * @intr_idx:		Encoder interrupt enumeration
 * @hw_idx:		HW Block ID
 * @irq_idx:		IRQ interface lookup index from DPU IRQ framework
 *			will be -EINVAL if IRQ is not registered
 * @irq_cb:		interrupt callback
@@ -176,7 +175,6 @@ struct dpu_encoder_irq {
	const char *name;
	enum dpu_intr_type intr_type;
	enum dpu_intr_idx intr_idx;
	int hw_idx;
	int irq_idx;
	struct dpu_irq_callback cb;
};
+12 −24
Original line number Diff line number Diff line
@@ -144,28 +144,6 @@ static void dpu_encoder_phys_cmd_underrun_irq(void *arg, int irq_idx)
			phys_enc);
}

static void _dpu_encoder_phys_cmd_setup_irq_hw_idx(
		struct dpu_encoder_phys *phys_enc)
{
	struct dpu_encoder_irq *irq;

	irq = &phys_enc->irq[INTR_IDX_CTL_START];
	irq->hw_idx = phys_enc->hw_ctl->idx;
	irq->irq_idx = -EINVAL;

	irq = &phys_enc->irq[INTR_IDX_PINGPONG];
	irq->hw_idx = phys_enc->hw_pp->idx;
	irq->irq_idx = -EINVAL;

	irq = &phys_enc->irq[INTR_IDX_RDPTR];
	irq->hw_idx = phys_enc->hw_pp->idx;
	irq->irq_idx = -EINVAL;

	irq = &phys_enc->irq[INTR_IDX_UNDERRUN];
	irq->hw_idx = phys_enc->intf_idx;
	irq->irq_idx = -EINVAL;
}

static void dpu_encoder_phys_cmd_mode_set(
		struct dpu_encoder_phys *phys_enc,
		struct drm_display_mode *mode,
@@ -173,6 +151,7 @@ static void dpu_encoder_phys_cmd_mode_set(
{
	struct dpu_encoder_phys_cmd *cmd_enc =
		to_dpu_encoder_phys_cmd(phys_enc);
	struct dpu_encoder_irq *irq;

	if (!mode || !adj_mode) {
		DPU_ERROR("invalid args\n");
@@ -182,7 +161,17 @@ static void dpu_encoder_phys_cmd_mode_set(
	DPU_DEBUG_CMDENC(cmd_enc, "caching mode:\n");
	drm_mode_debug_printmodeline(adj_mode);

	_dpu_encoder_phys_cmd_setup_irq_hw_idx(phys_enc);
	irq = &phys_enc->irq[INTR_IDX_CTL_START];
	irq->irq_idx = phys_enc->hw_ctl->caps->intr_start;

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

	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;
}

static int _dpu_encoder_phys_cmd_handle_ppdone_timeout(
@@ -799,7 +788,6 @@ struct dpu_encoder_phys *dpu_encoder_phys_cmd_init(
		irq = &phys_enc->irq[i];
		INIT_LIST_HEAD(&irq->cb.list);
		irq->irq_idx = -EINVAL;
		irq->hw_idx = -EINVAL;
		irq->cb.arg = phys_enc;
	}

Loading