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

Commit 068d6b16 authored by Linux Build Service Account's avatar Linux Build Service Account Committed by Gerrit - the friendly Code Review server
Browse files

Merge "drm/msm/sde: Add debugfs support for fence info dump" into dev/msm-4.14-display

parents f333564a d9c87b72
Loading
Loading
Loading
Loading
+77 −0
Original line number Diff line number Diff line
@@ -5872,6 +5872,77 @@ static int sde_crtc_debugfs_state_show(struct seq_file *s, void *v)
}
DEFINE_SDE_DEBUGFS_SEQ_FOPS(sde_crtc_debugfs_state);

static int _sde_debugfs_fence_status_show(struct seq_file *s, void *data)
{
	struct drm_crtc *crtc;
	struct drm_plane *plane;
	struct drm_connector *conn;
	struct drm_mode_object *drm_obj;
	struct sde_crtc *sde_crtc;
	struct sde_crtc_state *cstate;
	struct sde_fence_context *ctx;
	struct drm_connector_list_iter conn_iter;
	struct drm_device *dev;

	if (!s || !s->private)
		return -EINVAL;

	sde_crtc = s->private;
	crtc = &sde_crtc->base;
	dev = crtc->dev;
	cstate = to_sde_crtc_state(crtc->state);

	/* Dump input fence info */
	seq_puts(s, "===Input fence===\n");
	drm_atomic_crtc_for_each_plane(plane, crtc) {
		struct sde_plane_state *pstate;
		struct dma_fence *fence;

		pstate = to_sde_plane_state(plane->state);
		if (!pstate)
			continue;

		seq_printf(s, "plane:%u stage:%d\n", plane->base.id,
			pstate->stage);

		fence = pstate->input_fence;
		if (fence)
			sde_fence_list_dump(fence, &s);
	}

	/* Dump release fence info */
	seq_puts(s, "\n");
	seq_puts(s, "===Release fence===\n");
	ctx = &sde_crtc->output_fence;
	drm_obj = &crtc->base;
	sde_debugfs_timeline_dump(ctx, drm_obj, &s);
	seq_puts(s, "\n");

	/* Dump retire fence info */
	seq_puts(s, "===Retire fence===\n");
	drm_connector_list_iter_begin(dev, &conn_iter);
	drm_for_each_connector_iter(conn, &conn_iter)
		if (conn->state && conn->state->crtc == crtc &&
				cstate->num_connectors < MAX_CONNECTORS) {
			struct sde_connector *c_conn;

			c_conn = to_sde_connector(conn);
			ctx = &c_conn->retire_fence;
			drm_obj = &conn->base;
			sde_debugfs_timeline_dump(ctx, drm_obj, &s);
		}
	drm_connector_list_iter_end(&conn_iter);
	seq_puts(s, "\n");

	return 0;
}

static int _sde_debugfs_fence_status(struct inode *inode, struct file *file)
{
	return single_open(file, _sde_debugfs_fence_status_show,
				inode->i_private);
}

static int _sde_crtc_init_debugfs(struct drm_crtc *crtc)
{
	struct sde_crtc *sde_crtc;
@@ -5892,6 +5963,10 @@ static int _sde_crtc_init_debugfs(struct drm_crtc *crtc)
		.open =		_sde_debugfs_fps_status,
		.read =		seq_read,
	};
	static const struct file_operations debugfs_fence_fops = {
		.open =		_sde_debugfs_fence_status,
		.read =		seq_read,
	};

	if (!crtc)
		return -EINVAL;
@@ -5918,6 +5993,8 @@ static int _sde_crtc_init_debugfs(struct drm_crtc *crtc)
					sde_crtc, &debugfs_misr_fops);
	debugfs_create_file("fps", 0400, sde_crtc->debugfs_root,
					sde_crtc, &debugfs_fps_fops);
	debugfs_create_file("fence_status", 0400, sde_crtc->debugfs_root,
					sde_crtc, &debugfs_fence_fops);

	return 0;
}
+52 −0
Original line number Diff line number Diff line
@@ -432,3 +432,55 @@ void sde_fence_timeline_status(struct sde_fence_context *ctx,
		obj_name, drm_obj->id, drm_obj->type, ctx->done_count,
		ctx->commit_count);
}

void sde_fence_list_dump(struct dma_fence *fence, struct seq_file **s)
{
	char timeline_str[TIMELINE_VAL_LENGTH];

	if (fence->ops->timeline_value_str)
		fence->ops->timeline_value_str(fence,
		timeline_str, TIMELINE_VAL_LENGTH);

	seq_printf(*s, "fence name:%s timeline name:%s seqno:0x%x timeline:%s signaled:0x%x\n",
		fence->ops->get_driver_name(fence),
		fence->ops->get_timeline_name(fence),
		fence->seqno, timeline_str,
		fence->ops->signaled ?
		fence->ops->signaled(fence) : 0xffffffff);
}

void sde_debugfs_timeline_dump(struct sde_fence_context *ctx,
		struct drm_mode_object *drm_obj, struct seq_file **s)
{
	char *obj_name;
	struct sde_fence *fc, *next;
	struct dma_fence *fence;

	if (!ctx || !drm_obj) {
		SDE_ERROR("invalid input params\n");
		return;
	}

	switch (drm_obj->type) {
	case DRM_MODE_OBJECT_CRTC:
		obj_name = "crtc";
		break;
	case DRM_MODE_OBJECT_CONNECTOR:
		obj_name = "connector";
		break;
	default:
		obj_name = "unknown";
		break;
	}

	seq_printf(*s, "drm obj:%s id:%d type:0x%x done_count:%d commit_count:%d\n",
		obj_name, drm_obj->id, drm_obj->type, ctx->done_count,
		ctx->commit_count);

	spin_lock(&ctx->list_lock);
	list_for_each_entry_safe(fc, next, &ctx->fence_list_head, fence_list) {
		fence = &fc->base;
		sde_fence_list_dump(fence, s);
	}
	spin_unlock(&ctx->list_lock);
}
+28 −0
Original line number Diff line number Diff line
@@ -153,6 +153,22 @@ void sde_fence_signal(struct sde_fence_context *fence, ktime_t ts,
void sde_fence_timeline_status(struct sde_fence_context *ctx,
					struct drm_mode_object *drm_obj);

/**
 * sde_fence_timeline_dump - utility to dump fence list info in debugfs node
 * @fence: Pointer fence container
 * @drm_obj: Pointer to drm object associated with fence timeline
 * @s: used to writing on debugfs node
 */
void sde_debugfs_timeline_dump(struct sde_fence_context *ctx,
		struct drm_mode_object *drm_obj, struct seq_file **s);

/**
 * sde_fence_timeline_status - dumps fence timeline in debugfs node
 * @fence: Pointer fence container
 * @s: used to writing on debugfs node
 */
void sde_fence_list_dump(struct dma_fence *fence, struct seq_file **s);

#else
static inline void *sde_sync_get(uint64_t fd)
{
@@ -212,6 +228,18 @@ static inline void sde_fence_timeline_status(struct sde_fence_context *ctx,
{
	/* do nothing */
}

void sde_debugfs_timeline_dump(struct sde_fence_context *ctx,
		struct drm_mode_object *drm_obj, struct seq_file **s)
{
	/* do nothing */
}

void sde_fence_list_dump(struct dma_fence *fence, struct seq_file **s)
{
	/* do nothing */
}

#endif /* IS_ENABLED(CONFIG_SW_SYNC) */

#endif /* _SDE_FENCE_H_ */