summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJayant Shekhar <jshekhar@codeaurora.org>2014-04-10 16:15:16 +0530
committerDavid Keitel <dkeitel@codeaurora.org>2016-03-23 20:29:05 -0700
commit68e08b6ebcff37130be02108f2730f0dc491a17e (patch)
tree1eb5b6794b0b64f9c29b6725d232039c341911c5
parentdb1bde03865567c8590515f88fe4909ce5ad2237 (diff)
msm: mdss: change framebuffer split ratio at run time
This is to avoid kernel recompilation when a different framebuffer split ratio is desired at run time. To enable a new ratio, write the desired value to /sys/devices/virtual/graphics/fb0/msm_fb_split. Changes will take effect only after client releases all references to driver. Change-Id: I4764399f80fc22ec5815a8e2818901189b3aaeb5 Signed-off-by: Jayant Shekhar <jshekhar@codeaurora.org>
-rw-r--r--drivers/video/fbdev/msm/mdss_fb.c84
-rw-r--r--drivers/video/fbdev/msm/mdss_fb.h2
2 files changed, 65 insertions, 21 deletions
diff --git a/drivers/video/fbdev/msm/mdss_fb.c b/drivers/video/fbdev/msm/mdss_fb.c
index cbf0d03bd794..b28ffdaa206a 100644
--- a/drivers/video/fbdev/msm/mdss_fb.c
+++ b/drivers/video/fbdev/msm/mdss_fb.c
@@ -309,10 +309,36 @@ static ssize_t mdss_fb_get_type(struct device *dev,
return ret;
}
-static void mdss_fb_parse_dt(struct msm_fb_data_type *mfd)
+static inline int mdss_fb_validate_split(int left, int right,
+ struct msm_fb_data_type *mfd)
+{
+ int rc = -EINVAL;
+ u32 panel_xres = mfd->panel_info->xres;
+ /* more validate condition could be added if needed */
+ if (left && right) {
+ if (mfd->split_display)
+ panel_xres *= 2;
+
+ if (panel_xres == left + right) {
+ mfd->split_fb_left = left;
+ mfd->split_fb_right = right;
+ rc = 0;
+ }
+ } else {
+ if (mfd->split_display) {
+ mfd->split_fb_left = mfd->split_fb_right = panel_xres;
+ rc = 0;
+ } else {
+ mfd->split_fb_left = mfd->split_fb_right = 0;
+ }
+ }
+
+ return rc;
+}
+
+static void mdss_fb_parse_dt_split(struct msm_fb_data_type *mfd)
{
u32 data[2] = {0};
- u32 panel_xres;
struct platform_device *pdev = mfd->pdev;
mfd->splash_logo_enabled = of_property_read_bool(pdev->dev.of_node,
@@ -321,26 +347,29 @@ static void mdss_fb_parse_dt(struct msm_fb_data_type *mfd)
of_property_read_u32_array(pdev->dev.of_node,
"qcom,mdss-fb-split", data, 2);
- panel_xres = mfd->panel_info->xres;
- if (data[0] && data[1]) {
- if (mfd->split_display)
- panel_xres *= 2;
+ if (!mdss_fb_validate_split(data[0], data[1], mfd))
+ pr_debug("dt split_left=%d split_right=%d\n", data[0], data[1]);
+}
- if (panel_xres == data[0] + data[1]) {
- mfd->split_fb_left = data[0];
- mfd->split_fb_right = data[1];
- }
- } else {
- if (mfd->split_display)
- mfd->split_fb_left = mfd->split_fb_right = panel_xres;
- else
- mfd->split_fb_left = mfd->split_fb_right = 0;
+static ssize_t mdss_fb_store_split(struct device *dev,
+ struct device_attribute *attr, const char *buf, size_t len)
+{
+ u32 data[2] = {0};
+ struct fb_info *fbi = dev_get_drvdata(dev);
+ struct msm_fb_data_type *mfd = (struct msm_fb_data_type *)fbi->par;
+
+ if (2 != sscanf(buf, "%d %d", &data[0], &data[1])) {
+ pr_debug("Not able to read split values\n");
+ } else if (!mdss_fb_validate_split(data[0], data[1], mfd)) {
+ mfd->mdss_fb_split_stored = 1;
+ pr_debug("sys split_left=%d split_right=%d\n",
+ data[0], data[1]);
}
- pr_info("split framebuffer left=%d right=%d\n",
- mfd->split_fb_left, mfd->split_fb_right);
+
+ return len;
}
-static ssize_t mdss_fb_get_split(struct device *dev,
+static ssize_t mdss_fb_show_split(struct device *dev,
struct device_attribute *attr, char *buf)
{
ssize_t ret = 0;
@@ -351,6 +380,19 @@ static ssize_t mdss_fb_get_split(struct device *dev,
return ret;
}
+static void mdss_fb_get_split(struct msm_fb_data_type *mfd)
+{
+ if (mfd->index != 0)
+ return;
+
+ if (!mfd->mdss_fb_split_stored)
+ mdss_fb_parse_dt_split(mfd);
+
+ if (mfd->split_fb_left || mfd->split_fb_right)
+ pr_debug("split framebuffer left=%d right=%d\n",
+ mfd->split_fb_left, mfd->split_fb_right);
+}
+
static ssize_t mdss_mdp_show_blank_event(struct device *dev,
struct device_attribute *attr, char *buf)
{
@@ -441,7 +483,8 @@ static ssize_t mdss_fb_get_panel_info(struct device *dev,
}
static DEVICE_ATTR(msm_fb_type, S_IRUGO, mdss_fb_get_type, NULL);
-static DEVICE_ATTR(msm_fb_split, S_IRUGO, mdss_fb_get_split, NULL);
+static DEVICE_ATTR(msm_fb_split, S_IRUGO | S_IWUSR, mdss_fb_show_split,
+ mdss_fb_store_split);
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);
@@ -1422,8 +1465,6 @@ static int mdss_fb_register(struct msm_fb_data_type *mfd)
mfd->panel_power_on = false;
mfd->dcm_state = DCM_UNINIT;
- mdss_fb_parse_dt(mfd);
-
if (mdss_fb_alloc_fbmem(mfd))
pr_warn("unable to allocate fb memory in fb register\n");
@@ -1505,6 +1546,7 @@ static int mdss_fb_open(struct fb_info *info, int user)
}
if (!mfd->ref_cnt) {
+ mdss_fb_get_split(mfd);
mfd->disp_thread = kthread_run(__mdss_fb_display_thread, mfd,
"mdss_fb%d", mfd->index);
if (IS_ERR(mfd->disp_thread)) {
diff --git a/drivers/video/fbdev/msm/mdss_fb.h b/drivers/video/fbdev/msm/mdss_fb.h
index 66330b73d605..f291d5bc094e 100644
--- a/drivers/video/fbdev/msm/mdss_fb.h
+++ b/drivers/video/fbdev/msm/mdss_fb.h
@@ -234,6 +234,8 @@ struct msm_fb_data_type {
struct list_head proc_list;
struct ion_client *fb_ion_client;
struct ion_handle *fb_ion_handle;
+
+ bool mdss_fb_split_stored;
};
static inline void mdss_fb_update_notify_update(struct msm_fb_data_type *mfd)