summaryrefslogtreecommitdiff
path: root/drivers/video/fbdev
diff options
context:
space:
mode:
authorAdrian Salido <salidoa@google.com>2017-05-16 20:08:29 -0700
committerDavide Garberi <dade.garberi@gmail.com>2022-07-27 19:23:20 +0200
commita9130326b9f76ea72de064d65a9c49d9c8dcfe38 (patch)
treef6f6a0f12284b97b5573c036dd8ef74443e45df3 /drivers/video/fbdev
parente940fc1a6d8bddb1c016f6763b8982e040cf3eed (diff)
msm: mdss: add idle state node
Add a helper node that can be used to notify user space through sysfs node when fb device has not had any activity for a specified amount of time (through idle_time node). Bug: 62110101 Change-Id: I4dfa4b1a376149aa55a940dad7ac336ec99f1af8 Signed-off-by: Adrian Salido <salidoa@google.com>
Diffstat (limited to 'drivers/video/fbdev')
-rw-r--r--drivers/video/fbdev/msm/mdss_fb.c45
1 files changed, 38 insertions, 7 deletions
diff --git a/drivers/video/fbdev/msm/mdss_fb.c b/drivers/video/fbdev/msm/mdss_fb.c
index 8a45081d3a13..ee5f15664fd3 100644
--- a/drivers/video/fbdev/msm/mdss_fb.c
+++ b/drivers/video/fbdev/msm/mdss_fb.c
@@ -527,12 +527,17 @@ static void __mdss_fb_idle_notify_work(struct work_struct *work)
/* Notify idle-ness here */
pr_debug("Idle timeout %dms expired!\n", mfd->idle_time);
- if (mfd->idle_time)
- sysfs_notify(&mfd->fbi->dev->kobj, NULL, "idle_notify");
+
mfd->idle_state = MDSS_FB_IDLE;
+ /*
+ * idle_notify node events are used to reduce MDP load when idle,
+ * this is not needed for command mode panels.
+ */
+ if (mfd->idle_time && mfd->panel.type != MIPI_CMD_PANEL)
+ sysfs_notify(&mfd->fbi->dev->kobj, NULL, "idle_notify");
+ sysfs_notify(&mfd->fbi->dev->kobj, NULL, "idle_state");
}
-
static ssize_t mdss_fb_get_fps_info(struct device *dev,
struct device_attribute *attr, char *buf)
{
@@ -593,6 +598,26 @@ static ssize_t mdss_fb_get_idle_notify(struct device *dev,
return ret;
}
+static ssize_t mdss_fb_get_idle_state(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;
+ const char *state_strs[] = {
+ [MDSS_FB_NOT_IDLE] = "active",
+ [MDSS_FB_IDLE_TIMER_RUNNING] = "pending",
+ [MDSS_FB_IDLE] = "idle",
+ };
+ int state = mfd->idle_state;
+ const char *s;
+ if (state < ARRAY_SIZE(state_strs) && state_strs[state])
+ s = state_strs[state];
+ else
+ s = "invalid";
+
+ return scnprintf(buf, PAGE_SIZE, "%s\n", s);
+}
+
static ssize_t mdss_fb_get_panel_info(struct device *dev,
struct device_attribute *attr, char *buf)
{
@@ -929,6 +954,7 @@ static DEVICE_ATTR(show_blank_event, S_IRUGO, mdss_mdp_show_blank_event, NULL);
static DEVICE_ATTR(idle_time, S_IRUGO | S_IWUSR | S_IWGRP,
mdss_fb_get_idle_time, mdss_fb_set_idle_time);
static DEVICE_ATTR(idle_notify, S_IRUGO, mdss_fb_get_idle_notify, NULL);
+static DEVICE_ATTR(idle_state, S_IRUGO, mdss_fb_get_idle_state, NULL);
static DEVICE_ATTR(msm_fb_panel_info, S_IRUGO, mdss_fb_get_panel_info, NULL);
static DEVICE_ATTR(msm_fb_src_split_info, S_IRUGO, mdss_fb_get_src_split_info,
NULL);
@@ -950,6 +976,7 @@ static struct attribute *mdss_fb_attrs[] = {
&dev_attr_show_blank_event.attr,
&dev_attr_idle_time.attr,
&dev_attr_idle_notify.attr,
+ &dev_attr_idle_state.attr,
&dev_attr_msm_fb_panel_info.attr,
&dev_attr_msm_fb_src_split_info.attr,
&dev_attr_msm_fb_thermal_level.attr,
@@ -3143,14 +3170,18 @@ static int __mdss_fb_sync_buf_done_callback(struct notifier_block *p,
ret = __mdss_fb_wait_for_fence_sub(sync_pt_data,
sync_pt_data->temp_fen, fence_cnt);
}
- if (mfd->idle_time && !mod_delayed_work(system_wq,
+ if (mfd->idle_time) {
+ if (!mod_delayed_work(system_wq,
&mfd->idle_notify_work,
msecs_to_jiffies(mfd->idle_time)))
- pr_debug("fb%d: restarted idle work\n",
- mfd->index);
+ pr_debug("fb%d: restarted idle work\n",
+ mfd->index);
+ mfd->idle_state = MDSS_FB_IDLE_TIMER_RUNNING;
+ } else {
+ mfd->idle_state = MDSS_FB_IDLE;
+ }
if (ret == -ETIME)
ret = NOTIFY_BAD;
- mfd->idle_state = MDSS_FB_IDLE_TIMER_RUNNING;
break;
case MDP_NOTIFY_FRAME_FLUSHED:
pr_debug("%s: frame flushed\n", sync_pt_data->fence_name);