summaryrefslogtreecommitdiff
path: root/drivers/video/fbdev
diff options
context:
space:
mode:
authorKrishna Manikandan <mkrishn@codeaurora.org>2016-12-28 17:58:39 +0530
committerKrishna Manikandan <mkrishn@codeaurora.org>2017-01-02 10:40:40 +0530
commit90fd65ba93d5c3c767ce58fb1d172d511988976a (patch)
tree7da9945d95aca60523130e5f404bbd9fe2ee3a06 /drivers/video/fbdev
parent134572d905d7dba5acd673fd9594391fd7a93611 (diff)
msm: mdss: Add sysfs node for mdss to give runtime fps
Added sysfs node on mdss to get fps value at runtime. The calculation is time based where in mdss driver counts number of frames transferred for every 1 second. Change-Id: I6f38298d066852d1a41cb90167aa41f594eec9c0 Signed-off-by: Raviteja Tamatam <travitej@codeaurora.org> Signed-off-by: Krishna Manikandan <mkrishn@codeaurora.org>
Diffstat (limited to 'drivers/video/fbdev')
-rw-r--r--drivers/video/fbdev/msm/mdss_fb.c58
-rw-r--r--drivers/video/fbdev/msm/mdss_fb.h12
2 files changed, 70 insertions, 0 deletions
diff --git a/drivers/video/fbdev/msm/mdss_fb.c b/drivers/video/fbdev/msm/mdss_fb.c
index 924ebb97890c..b091f63498c5 100644
--- a/drivers/video/fbdev/msm/mdss_fb.c
+++ b/drivers/video/fbdev/msm/mdss_fb.c
@@ -76,6 +76,12 @@
#define BLANK_FLAG_ULP FB_BLANK_NORMAL
#endif
+/*
+ * Time period for fps calulation in micro seconds.
+ * Default value is set to 1 sec.
+ */
+#define MDP_TIME_PERIOD_CALC_FPS_US 1000000
+
static struct fb_info *fbi_list[MAX_FBI_LIST];
static int fbi_list_index;
@@ -502,6 +508,22 @@ static void __mdss_fb_idle_notify_work(struct work_struct *work)
mfd->idle_state = MDSS_FB_IDLE;
}
+
+static ssize_t mdss_fb_get_fps_info(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ struct fb_info *fbi = dev_get_drvdata(dev);
+ struct msm_fb_data_type *mfd = fbi->par;
+ unsigned int fps_int, fps_float;
+
+ if (mfd->panel_power_state != MDSS_PANEL_POWER_ON)
+ mfd->fps_info.measured_fps = 0;
+ fps_int = (unsigned int) mfd->fps_info.measured_fps;
+ fps_float = do_div(fps_int, 10);
+ return scnprintf(buf, PAGE_SIZE, "%d.%d\n", fps_int, fps_float);
+
+}
+
static ssize_t mdss_fb_get_idle_time(struct device *dev,
struct device_attribute *attr, char *buf)
{
@@ -815,6 +837,8 @@ static DEVICE_ATTR(msm_fb_panel_status, S_IRUGO | S_IWUSR,
mdss_fb_get_panel_status, mdss_fb_force_panel_dead);
static DEVICE_ATTR(msm_fb_dfps_mode, S_IRUGO | S_IWUSR,
mdss_fb_get_dfps_mode, mdss_fb_change_dfps_mode);
+static DEVICE_ATTR(measured_fps, S_IRUGO | S_IWUSR | S_IWGRP,
+ mdss_fb_get_fps_info, NULL);
static struct attribute *mdss_fb_attrs[] = {
&dev_attr_msm_fb_type.attr,
&dev_attr_msm_fb_split.attr,
@@ -826,6 +850,7 @@ static struct attribute *mdss_fb_attrs[] = {
&dev_attr_msm_fb_thermal_level.attr,
&dev_attr_msm_fb_panel_status.attr,
&dev_attr_msm_fb_dfps_mode.attr,
+ &dev_attr_measured_fps.attr,
NULL,
};
@@ -1196,6 +1221,7 @@ static int mdss_fb_probe(struct platform_device *pdev)
return rc;
}
}
+ mdss_fb_init_fps_info(mfd);
rc = pm_runtime_set_active(mfd->fbi->dev);
if (rc < 0)
@@ -2977,6 +3003,7 @@ static int __mdss_fb_sync_buf_done_callback(struct notifier_block *p,
case MDP_NOTIFY_FRAME_DONE:
pr_debug("%s: frame done\n", sync_pt_data->fence_name);
mdss_fb_signal_timeline(sync_pt_data);
+ mdss_fb_calc_fps(mfd);
break;
case MDP_NOTIFY_FRAME_CFG_DONE:
if (sync_pt_data->async_wait_fences)
@@ -5031,3 +5058,34 @@ void mdss_fb_report_panel_dead(struct msm_fb_data_type *mfd)
KOBJ_CHANGE, envp);
pr_err("Panel has gone bad, sending uevent - %s\n", envp[0]);
}
+
+
+/*
+ * mdss_fb_calc_fps() - Calculates fps value.
+ * @mfd : frame buffer structure associated with fb device.
+ *
+ * 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
+ */
+void mdss_fb_calc_fps(struct msm_fb_data_type *mfd)
+{
+ ktime_t current_time_us;
+ u64 fps, diff_us;
+
+ current_time_us = ktime_get();
+ diff_us = (u64)ktime_us_delta(current_time_us,
+ mfd->fps_info.last_sampled_time_us);
+ mfd->fps_info.frame_count++;
+
+ if (diff_us >= MDP_TIME_PERIOD_CALC_FPS_US) {
+ fps = ((u64)mfd->fps_info.frame_count) * 10000000;
+ do_div(fps, diff_us);
+ mfd->fps_info.measured_fps = (unsigned int)fps;
+ pr_debug(" MDP_FPS for fb%d is %d.%d\n",
+ mfd->index, (unsigned int)fps/10, (unsigned int)fps%10);
+ mfd->fps_info.last_sampled_time_us = current_time_us;
+ mfd->fps_info.frame_count = 0;
+ }
+}
diff --git a/drivers/video/fbdev/msm/mdss_fb.h b/drivers/video/fbdev/msm/mdss_fb.h
index 2eb6c6456f29..1487c4e7f6e2 100644
--- a/drivers/video/fbdev/msm/mdss_fb.h
+++ b/drivers/video/fbdev/msm/mdss_fb.h
@@ -253,6 +253,12 @@ struct msm_fb_backup_type {
bool atomic_commit;
};
+struct msm_fb_fps_info {
+ u32 frame_count;
+ ktime_t last_sampled_time_us;
+ u32 measured_fps;
+};
+
struct msm_fb_data_type {
u32 key;
u32 index;
@@ -271,6 +277,7 @@ struct msm_fb_data_type {
int idle_time;
u32 idle_state;
+ struct msm_fb_fps_info fps_info;
struct delayed_work idle_notify_work;
bool atomic_commit_pending;
@@ -426,6 +433,10 @@ static inline bool mdss_fb_is_hdmi_primary(struct msm_fb_data_type *mfd)
(mfd->panel_info->type == DTV_PANEL));
}
+static inline void mdss_fb_init_fps_info(struct msm_fb_data_type *mfd)
+{
+ memset(&mfd->fps_info, 0, sizeof(mfd->fps_info));
+}
int mdss_fb_get_phys_info(dma_addr_t *start, unsigned long *len, int fb_num);
void mdss_fb_set_backlight(struct msm_fb_data_type *mfd, u32 bkl_lvl);
void mdss_fb_update_backlight(struct msm_fb_data_type *mfd);
@@ -449,4 +460,5 @@ u32 mdss_fb_get_mode_switch(struct msm_fb_data_type *mfd);
void mdss_fb_report_panel_dead(struct msm_fb_data_type *mfd);
void mdss_panelinfo_to_fb_var(struct mdss_panel_info *pinfo,
struct fb_var_screeninfo *var);
+void mdss_fb_calc_fps(struct msm_fb_data_type *mfd);
#endif /* MDSS_FB_H */