diff options
| author | Jayant Shekhar <jshekhar@codeaurora.org> | 2014-04-10 16:15:16 +0530 |
|---|---|---|
| committer | David Keitel <dkeitel@codeaurora.org> | 2016-03-23 20:29:05 -0700 |
| commit | 68e08b6ebcff37130be02108f2730f0dc491a17e (patch) | |
| tree | 1eb5b6794b0b64f9c29b6725d232039c341911c5 | |
| parent | db1bde03865567c8590515f88fe4909ce5ad2237 (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.c | 84 | ||||
| -rw-r--r-- | drivers/video/fbdev/msm/mdss_fb.h | 2 |
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) |
