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

Commit d4165d14 authored by Shubhashree Dhar's avatar Shubhashree Dhar
Browse files

drm/msm/sde: add debugfs node in dpu driver to give fps



Add debugfs node on crtc to get fps value at runtime.
The calculation is time based where in dpu driver
counts number of frames transferred for every 1 second.

Change-Id: Ic6ba615cc0b394fd09f5953a7d26c9af8be3559d
Signed-off-by: default avatarShubhashree Dhar <dhar@codeaurora.org>
parent a06ed1d7
Loading
Loading
Loading
Loading
+89 −0
Original line number Diff line number Diff line
@@ -79,6 +79,12 @@ static struct sde_crtc_custom_events custom_events[] = {

#define MISR_BUFF_SIZE			256

/*
 * Time period for fps calculation in micro seconds.
 * Default value is set to 1 sec.
 */
#define CRTC_TIME_PERIOD_CALC_FPS_US	1000000

static inline struct sde_kms *_sde_crtc_get_kms(struct drm_crtc *crtc)
{
	struct msm_drm_private *priv;
@@ -125,6 +131,37 @@ static inline int _sde_crtc_power_enable(struct sde_crtc *sde_crtc, bool enable)
									enable);
}

/*
 * sde_crtc_calc_fps() - Calculates fps value.
 * @sde_crtc   : CRTC structure
 *
 * This function is called at frame done. It counts the number
 * of frames done for every 1 sec. Stores the value in measured_fps.
 * measured_fps value is 10 times the calculated fps value.
 * For example, measured_fps= 594 for calculated fps of 59.4
 */
static void sde_crtc_calc_fps(struct sde_crtc *sde_crtc)
{
	ktime_t current_time_us;
	u64 fps, diff_us;

	current_time_us = ktime_get();
	diff_us = (u64)ktime_us_delta(current_time_us,
			sde_crtc->fps_info.last_sampled_time_us);
	sde_crtc->fps_info.frame_count++;

	if (diff_us >= CRTC_TIME_PERIOD_CALC_FPS_US) {
		fps = ((u64)sde_crtc->fps_info.frame_count) * 10000000;
		do_div(fps, diff_us);
		sde_crtc->fps_info.measured_fps = (unsigned int)fps;
		SDE_DEBUG(" FPS for crtc%d is %d.%d\n",
				sde_crtc->base.base.id, (unsigned int)fps/10,
				(unsigned int)fps%10);
		sde_crtc->fps_info.last_sampled_time_us = current_time_us;
		sde_crtc->fps_info.frame_count = 0;
	}
}

/**
 * _sde_crtc_rp_to_crtc - get crtc from resource pool object
 * @rp: Pointer to resource pool
@@ -601,6 +638,50 @@ static void _sde_crtc_deinit_events(struct sde_crtc *sde_crtc)
		return;
}

static int _sde_debugfs_fps_status_show(struct seq_file *s, void *data)
{
	struct sde_crtc *sde_crtc;
	unsigned int fps_int, fps_float;
	ktime_t current_time_us;
	u64 fps, diff_us;

	if (!s || !s->private) {
		SDE_ERROR("invalid input param(s)\n");
		return -EAGAIN;
	}

	sde_crtc = s->private;

	current_time_us = ktime_get();
	diff_us = (u64)ktime_us_delta(current_time_us,
			sde_crtc->fps_info.last_sampled_time_us);

	if (diff_us >= CRTC_TIME_PERIOD_CALC_FPS_US) {
		fps = ((u64)sde_crtc->fps_info.frame_count) * 10000000;
		do_div(fps, diff_us);
		sde_crtc->fps_info.measured_fps = (unsigned int)fps;
		sde_crtc->fps_info.last_sampled_time_us = current_time_us;
		sde_crtc->fps_info.frame_count = 0;
		SDE_DEBUG("Measured FPS for crtc%d is %d.%d\n",
				sde_crtc->base.base.id, (unsigned int)fps/10,
				(unsigned int)fps%10);
	}

	fps_int = (unsigned int) sde_crtc->fps_info.measured_fps;
	fps_float = do_div(fps_int, 10);

	seq_printf(s, "fps: %d.%d\n", fps_int, fps_float);

	return 0;
}


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

static ssize_t vsync_event_show(struct device *device,
	struct device_attribute *attr, char *buf)
{
@@ -3687,6 +3768,8 @@ void sde_crtc_commit_kickoff(struct drm_crtc *crtc,
	SDE_ATRACE_BEGIN("wait_for_frame_done_event");
	ret = _sde_crtc_wait_for_frame_done(crtc);
	SDE_ATRACE_END("wait_for_frame_done_event");
	sde_crtc_calc_fps(sde_crtc);

	if (ret) {
		SDE_ERROR("crtc%d wait for frame done failed;frame_pending%d\n",
				crtc->base.id,
@@ -5779,6 +5862,10 @@ static int _sde_crtc_init_debugfs(struct drm_crtc *crtc)
		.open =		_sde_debugfs_fence_status,
		.read =		seq_read,
	};
	static const struct file_operations debugfs_fps_fops = {
		.open =		_sde_debugfs_fps_status,
		.read =		seq_read,
	};

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

	return 0;
}
+7 −0
Original line number Diff line number Diff line
@@ -136,6 +136,12 @@ struct sde_crtc_event {
	void *usr;
};

struct sde_crtc_fps_info {
	u32 frame_count;
	ktime_t last_sampled_time_us;
	u32 measured_fps;
};

/*
 * Maximum number of free event structures to cache
 */
@@ -232,6 +238,7 @@ struct sde_crtc {
	u64 play_count;
	ktime_t vblank_cb_time;
	ktime_t vblank_last_cb_time;
	struct sde_crtc_fps_info fps_info;
	struct device *sysfs_dev;
	struct kernfs_node *vsync_event_sf;
	bool vblank_requested;