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

Commit 085471b8 authored by Jayant Shekhar's avatar Jayant Shekhar
Browse files

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: default avatarJayant Shekhar <jshekhar@codeaurora.org>
parent 54f3fb1b
Loading
Loading
Loading
Loading
+63 −21
Original line number Diff line number Diff line
@@ -271,10 +271,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,
@@ -283,26 +309,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 (panel_xres == data[0] + data[1]) {
			mfd->split_fb_left = data[0];
			mfd->split_fb_right = data[1];
	if (!mdss_fb_validate_split(data[0], data[1], mfd))
		pr_debug("dt split_left=%d split_right=%d\n", data[0], 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;
@@ -313,6 +342,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)
{
@@ -401,7 +443,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);
@@ -1381,8 +1424,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");

@@ -1462,6 +1503,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)) {
+2 −0
Original line number Diff line number Diff line
@@ -233,6 +233,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)