summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKuogee Hsieh <khsieh@codeaurora.org>2014-05-01 16:02:48 -0700
committerDavid Keitel <dkeitel@codeaurora.org>2016-03-23 20:30:06 -0700
commit3a28acf18f5bfb8d2ac6f1d421d7691d55dd595a (patch)
tree262739944ea514196281992dd1882bf2d3fa3a11
parent903eef82014c1a6988b5203878eb0af11c0d89d6 (diff)
mdss: display: add support of dual dsi partial update.
This patch adds l_roi and r_roi fields to display commit struct to support partial update for dual DSI panels. Panel side frame buffer's column, page address and DSI controller's stream size are updated based on the ROI requested. Change-Id: I70957c9ee1546448416441a8d0608fb00c3b92ca Signed-off-by: Jeykumar Sankaran <jsanka@codeaurora.org> Signed-off-by: Siddhartha Agrawal <agrawals@codeaurora.org> Signed-off-by: Kuogee Hsieh <khsieh@codeaurora.org>
-rw-r--r--drivers/video/fbdev/msm/mdss_dsi.c70
-rw-r--r--drivers/video/fbdev/msm/mdss_dsi.h15
-rw-r--r--drivers/video/fbdev/msm/mdss_dsi_host.c10
-rw-r--r--drivers/video/fbdev/msm/mdss_dsi_panel.c242
-rw-r--r--drivers/video/fbdev/msm/mdss_fb.c6
-rw-r--r--drivers/video/fbdev/msm/mdss_mdp.h1
-rw-r--r--drivers/video/fbdev/msm/mdss_mdp_ctl.c139
-rw-r--r--drivers/video/fbdev/msm/mdss_mdp_intf_cmd.c78
-rw-r--r--drivers/video/fbdev/msm/mdss_mdp_overlay.c16
-rw-r--r--drivers/video/fbdev/msm/mdss_mdp_pipe.c11
-rw-r--r--drivers/video/fbdev/msm/mdss_panel.h17
-rw-r--r--include/uapi/linux/msm_mdp.h3
12 files changed, 488 insertions, 120 deletions
diff --git a/drivers/video/fbdev/msm/mdss_dsi.c b/drivers/video/fbdev/msm/mdss_dsi.c
index 38d46d0dba8d..64fec36fc3fc 100644
--- a/drivers/video/fbdev/msm/mdss_dsi.c
+++ b/drivers/video/fbdev/msm/mdss_dsi.c
@@ -1122,11 +1122,33 @@ static int mdss_dsi_dfps_config(struct mdss_panel_data *pdata, int new_fps)
return rc;
}
-static int mdss_dsi_ctl_partial_update(struct mdss_panel_data *pdata)
+static int mdss_dsi_ctl_partial_roi(struct mdss_panel_data *pdata)
{
+ struct mdss_dsi_ctrl_pdata *ctrl_pdata = NULL;
int rc = -EINVAL;
- u32 data;
+
+ if (pdata == NULL) {
+ pr_err("%s: Invalid input data\n", __func__);
+ return -EINVAL;
+ }
+
+ ctrl_pdata = container_of(pdata, struct mdss_dsi_ctrl_pdata,
+ panel_data);
+
+ if (ctrl_pdata->set_col_page_addr)
+ rc = ctrl_pdata->set_col_page_addr(pdata);
+
+ return rc;
+}
+
+static int mdss_dsi_set_stream_size(struct mdss_panel_data *pdata)
+{
+ u32 data, idle;
struct mdss_dsi_ctrl_pdata *ctrl_pdata = NULL;
+ struct mdss_panel_info *pinfo;
+ struct mdss_rect *roi;
+ struct panel_horizontal_idle *pidle;
+ int i;
if (pdata == NULL) {
pr_err("%s: Invalid input data\n", __func__);
@@ -1136,27 +1158,44 @@ static int mdss_dsi_ctl_partial_update(struct mdss_panel_data *pdata)
ctrl_pdata = container_of(pdata, struct mdss_dsi_ctrl_pdata,
panel_data);
+ pinfo = &pdata->panel_info;
+
+ if (!pinfo->partial_update_enabled)
+ return -EINVAL;
+
+ roi = &pinfo->roi;
+
/* DSI_COMMAND_MODE_MDP_STREAM_CTRL */
- data = (((pdata->panel_info.roi_w * 3) + 1) << 16) |
+ data = (((roi->w * 3) + 1) << 16) |
(pdata->panel_info.mipi.vc << 8) | DTYPE_DCS_LWRITE;
MIPI_OUTP((ctrl_pdata->ctrl_base) + 0x60, data);
MIPI_OUTP((ctrl_pdata->ctrl_base) + 0x58, data);
/* DSI_COMMAND_MODE_MDP_STREAM_TOTAL */
- data = pdata->panel_info.roi_h << 16 | pdata->panel_info.roi_w;
+ data = roi->h << 16 | roi->w;
MIPI_OUTP((ctrl_pdata->ctrl_base) + 0x64, data);
MIPI_OUTP((ctrl_pdata->ctrl_base) + 0x5C, data);
- if (ctrl_pdata->partial_update_fnc)
- rc = ctrl_pdata->partial_update_fnc(pdata);
-
- if (rc) {
- pr_err("%s: unable to initialize the panel\n",
- __func__);
- return rc;
+ /* set idle control -- dsi clk cycle */
+ idle = 0;
+ pidle = ctrl_pdata->line_idle;
+ for (i = 0; i < ctrl_pdata->horizontal_idle_cnt; i++) {
+ if (roi->w > pidle->min && roi->w <= pidle->max) {
+ idle = pidle->idle;
+ pr_debug("%s: ndx=%d w=%d range=%d-%d idle=%d\n",
+ __func__, ctrl_pdata->ndx, roi->w,
+ pidle->min, pidle->max, pidle->idle);
+ break;
+ }
+ pidle++;
}
- return rc;
+ if (idle)
+ idle |= BIT(12); /* enable */
+
+ MIPI_OUTP((ctrl_pdata->ctrl_base) + 0x194, idle);
+
+ return 0;
}
static int mdss_dsi_event_handler(struct mdss_panel_data *pdata,
@@ -1225,8 +1264,11 @@ static int mdss_dsi_event_handler(struct mdss_panel_data *pdata,
rc = mdss_dsi_blank(pdata);
}
break;
- case MDSS_EVENT_ENABLE_PARTIAL_UPDATE:
- rc = mdss_dsi_ctl_partial_update(pdata);
+ case MDSS_EVENT_ENABLE_PARTIAL_ROI:
+ rc = mdss_dsi_ctl_partial_roi(pdata);
+ break;
+ case MDSS_EVENT_DSI_STREAM_SIZE:
+ rc = mdss_dsi_set_stream_size(pdata);
break;
case MDSS_EVENT_DSI_ULPS_CTRL:
rc = mdss_dsi_ulps_config(ctrl_pdata, (int)(unsigned long) arg);
diff --git a/drivers/video/fbdev/msm/mdss_dsi.h b/drivers/video/fbdev/msm/mdss_dsi.h
index d97ac9399192..c36a4853ece0 100644
--- a/drivers/video/fbdev/msm/mdss_dsi.h
+++ b/drivers/video/fbdev/msm/mdss_dsi.h
@@ -232,12 +232,21 @@ struct dsi_pinctrl_res {
struct pinctrl_state *gpio_state_suspend;
};
+struct panel_horizontal_idle {
+ int min;
+ int max;
+ int idle;
+};
+
enum {
DSI_CTRL_0,
DSI_CTRL_1,
DSI_CTRL_MAX,
};
+#define DSI_CTRL_LEFT DSI_CTRL_0
+#define DSI_CTRL_RIGHT DSI_CTRL_1
+
/* DSI controller #0 is always treated as a master in broadcast mode */
#define DSI_CTRL_MASTER DSI_CTRL_0
#define DSI_CTRL_SLAVE DSI_CTRL_1
@@ -254,7 +263,7 @@ struct mdss_dsi_ctrl_pdata {
int ndx; /* panel_num */
int (*on) (struct mdss_panel_data *pdata);
int (*off) (struct mdss_panel_data *pdata);
- int (*partial_update_fnc) (struct mdss_panel_data *pdata);
+ int (*set_col_page_addr) (struct mdss_panel_data *pdata);
int (*check_status) (struct mdss_dsi_ctrl_pdata *pdata);
int (*cmdlist_commit)(struct mdss_dsi_ctrl_pdata *ctrl, int from_mdp);
void (*switch_mode) (struct mdss_panel_data *pdata, int mode);
@@ -288,6 +297,7 @@ struct mdss_dsi_ctrl_pdata {
int bklt_max;
int new_fps;
int pwm_enabled;
+ struct mdss_rect roi;
struct pwm_device *pwm_bl;
struct dsi_drv_cm_data shared_pdata;
u32 pclk_rate;
@@ -324,6 +334,9 @@ struct mdss_dsi_ctrl_pdata {
int status_mode;
struct dsi_pinctrl_res pin_res;
+
+ int horizontal_idle_cnt;
+ struct panel_horizontal_idle *line_idle;
};
struct dsi_status_data {
diff --git a/drivers/video/fbdev/msm/mdss_dsi_host.c b/drivers/video/fbdev/msm/mdss_dsi_host.c
index dea677b90a33..d856a5f92dae 100644
--- a/drivers/video/fbdev/msm/mdss_dsi_host.c
+++ b/drivers/video/fbdev/msm/mdss_dsi_host.c
@@ -1331,7 +1331,8 @@ int mdss_dsi_cmdlist_commit(struct mdss_dsi_ctrl_pdata *ctrl, int from_mdp)
/* make sure dsi_cmd_mdp is idle */
mdss_dsi_cmd_mdp_busy(ctrl);
- pr_debug("%s: from_mdp=%d pid=%d\n", __func__, from_mdp, current->pid);
+ pr_debug("%s: ctrl=%d from_mdp=%d pid=%d\n", __func__,
+ ctrl->ndx, from_mdp, current->pid);
if (req == NULL)
goto need_lock;
@@ -1363,8 +1364,11 @@ int mdss_dsi_cmdlist_commit(struct mdss_dsi_ctrl_pdata *ctrl, int from_mdp)
need_lock:
- if (from_mdp) /* from pipe_commit */
- mdss_dsi_cmd_mdp_start(ctrl);
+ if (from_mdp) { /* from pipe_commit */
+ /* acquire lock only has new frame update */
+ if (ctrl->roi.w != 0 || ctrl->roi.h != 0)
+ mdss_dsi_cmd_mdp_start(ctrl);
+ }
MDSS_XLOG(ctrl->ndx, from_mdp, ctrl->mdp_busy, current->pid,
XLOG_FUNC_EXIT);
diff --git a/drivers/video/fbdev/msm/mdss_dsi_panel.c b/drivers/video/fbdev/msm/mdss_dsi_panel.c
index 6b204337a52b..5653ebc50c7b 100644
--- a/drivers/video/fbdev/msm/mdss_dsi_panel.c
+++ b/drivers/video/fbdev/msm/mdss_dsi_panel.c
@@ -91,6 +91,13 @@ u32 mdss_dsi_panel_cmd_read(struct mdss_dsi_ctrl_pdata *ctrl, char cmd0,
char cmd1, void (*fxn)(int), char *rbuf, int len)
{
struct dcs_cmd_req cmdreq;
+ struct mdss_panel_info *pinfo;
+
+ pinfo = &(ctrl->panel_data.panel_info);
+ if (pinfo->partial_update_dcs_cmd_by_left) {
+ if (ctrl->ndx != DSI_CTRL_LEFT)
+ return -EINVAL;
+ }
dcs_cmd[0] = cmd0;
dcs_cmd[1] = cmd1;
@@ -113,6 +120,13 @@ static void mdss_dsi_panel_cmds_send(struct mdss_dsi_ctrl_pdata *ctrl,
struct dsi_panel_cmds *pcmds)
{
struct dcs_cmd_req cmdreq;
+ struct mdss_panel_info *pinfo;
+
+ pinfo = &(ctrl->panel_data.panel_info);
+ if (pinfo->partial_update_dcs_cmd_by_left) {
+ if (ctrl->ndx != DSI_CTRL_LEFT)
+ return;
+ }
memset(&cmdreq, 0, sizeof(cmdreq));
cmdreq.cmds = pcmds->cmds;
@@ -138,6 +152,13 @@ static struct dsi_cmd_desc backlight_cmd = {
static void mdss_dsi_panel_bklt_dcs(struct mdss_dsi_ctrl_pdata *ctrl, int level)
{
struct dcs_cmd_req cmdreq;
+ struct mdss_panel_info *pinfo;
+
+ pinfo = &(ctrl->panel_data.panel_info);
+ if (pinfo->partial_update_dcs_cmd_by_left) {
+ if (ctrl->ndx != DSI_CTRL_LEFT)
+ return;
+ }
pr_debug("%s: level=%d\n", __func__, level);
@@ -281,20 +302,69 @@ int mdss_dsi_panel_reset(struct mdss_panel_data *pdata, int enable)
return rc;
}
+/**
+ * mdss_dsi_roi_merge() - merge two roi into single roi
+ *
+ * Function used by partial update with only one dsi intf take 2A/2B
+ * (column/page) dcs commands.
+ */
+static int mdss_dsi_roi_merge(struct mdss_dsi_ctrl_pdata *ctrl,
+ struct mdss_rect *roi)
+{
+ struct mdss_panel_info *l_pinfo;
+ struct mdss_rect *l_roi;
+ struct mdss_rect *r_roi;
+ struct mdss_dsi_ctrl_pdata *other = NULL;
+ int ans = 0;
+
+ if (ctrl->ndx == DSI_CTRL_LEFT) {
+ other = mdss_dsi_get_ctrl_by_index(DSI_CTRL_RIGHT);
+ if (!other)
+ return ans;
+ l_pinfo = &(ctrl->panel_data.panel_info);
+ l_roi = &(ctrl->panel_data.panel_info.roi);
+ r_roi = &(other->panel_data.panel_info.roi);
+ } else {
+ other = mdss_dsi_get_ctrl_by_index(DSI_CTRL_LEFT);
+ if (!other)
+ return ans;
+ l_pinfo = &(other->panel_data.panel_info);
+ l_roi = &(other->panel_data.panel_info.roi);
+ r_roi = &(ctrl->panel_data.panel_info.roi);
+ }
+
+ if (l_roi->w == 0 && l_roi->h == 0) {
+ /* right only */
+ *roi = *r_roi;
+ roi->x += l_pinfo->xres;/* add left full width to x-offset */
+ } else {
+ /* left only and left+righ */
+ *roi = *l_roi;
+ roi->w += r_roi->w; /* add right width */
+ ans = 1;
+ }
+
+ return ans;
+}
+
static char caset[] = {0x2a, 0x00, 0x00, 0x03, 0x00}; /* DTYPE_DCS_LWRITE */
static char paset[] = {0x2b, 0x00, 0x00, 0x05, 0x00}; /* DTYPE_DCS_LWRITE */
-static struct dsi_cmd_desc partial_update_enable_cmd[] = {
- {{DTYPE_DCS_LWRITE, 1, 0, 0, 1, sizeof(caset)}, caset},
+/* pack into one frame before sent */
+static struct dsi_cmd_desc set_col_page_addr_cmd[] = {
+ {{DTYPE_DCS_LWRITE, 0, 0, 0, 1, sizeof(caset)}, caset}, /* packed */
{{DTYPE_DCS_LWRITE, 1, 0, 0, 1, sizeof(paset)}, paset},
};
-static int mdss_dsi_panel_partial_update(struct mdss_panel_data *pdata)
+static int mdss_dsi_set_col_page_addr(struct mdss_panel_data *pdata)
{
- struct mipi_panel_info *mipi;
+ struct mdss_panel_info *pinfo;
+ struct mdss_rect roi;
+ struct mdss_rect *p_roi;
+ struct mdss_rect *c_roi;
struct mdss_dsi_ctrl_pdata *ctrl = NULL;
struct dcs_cmd_req cmdreq;
- int rc = 0;
+ int left_or_both = 0;
if (pdata == NULL) {
pr_err("%s: Invalid input data\n", __func__);
@@ -303,37 +373,62 @@ static int mdss_dsi_panel_partial_update(struct mdss_panel_data *pdata)
ctrl = container_of(pdata, struct mdss_dsi_ctrl_pdata,
panel_data);
- mipi = &pdata->panel_info.mipi;
- pr_debug("%s: ctrl=%p ndx=%d\n", __func__, ctrl, ctrl->ndx);
+ pinfo = &pdata->panel_info;
+ p_roi = &pinfo->roi;
+ c_roi = &ctrl->roi;
+
+ if (!mdss_rect_cmp(c_roi, p_roi)) {
+ pr_debug("%s: ndx=%d x=%d y=%d w=%d h=%d\n",
+ __func__, ctrl->ndx, p_roi->x,
+ p_roi->y, p_roi->w, p_roi->h);
+
+ *c_roi = *p_roi; /* keep to ctrl */
+ if (c_roi->w == 0 || c_roi->h == 0) {
+ /* no new frame update */
+ pr_debug("%s: ctrl=%d, no partial roi set\n",
+ __func__, ctrl->ndx);
+ return 0;
+ }
- caset[1] = (((pdata->panel_info.roi_x) & 0xFF00) >> 8);
- caset[2] = (((pdata->panel_info.roi_x) & 0xFF));
- caset[3] = (((pdata->panel_info.roi_x - 1 + pdata->panel_info.roi_w)
- & 0xFF00) >> 8);
- caset[4] = (((pdata->panel_info.roi_x - 1 + pdata->panel_info.roi_w)
- & 0xFF));
- partial_update_enable_cmd[0].payload = caset;
-
- paset[1] = (((pdata->panel_info.roi_y) & 0xFF00) >> 8);
- paset[2] = (((pdata->panel_info.roi_y) & 0xFF));
- paset[3] = (((pdata->panel_info.roi_y - 1 + pdata->panel_info.roi_h)
- & 0xFF00) >> 8);
- paset[4] = (((pdata->panel_info.roi_y - 1 + pdata->panel_info.roi_h)
- & 0xFF));
- partial_update_enable_cmd[1].payload = paset;
-
- pr_debug("%s: enabling partial update\n", __func__);
- memset(&cmdreq, 0, sizeof(cmdreq));
- cmdreq.cmds = partial_update_enable_cmd;
- cmdreq.cmds_cnt = 2;
- cmdreq.flags = CMD_REQ_COMMIT | CMD_CLK_CTRL;
- cmdreq.rlen = 0;
- cmdreq.cb = NULL;
+ roi = *c_roi;
- mdss_dsi_cmdlist_put(ctrl, &cmdreq);
+ if (pinfo->partial_update_roi_merge)
+ left_or_both = mdss_dsi_roi_merge(ctrl, &roi);
- return rc;
+ if (pinfo->partial_update_dcs_cmd_by_left) {
+ if (left_or_both && ctrl->ndx == DSI_CTRL_RIGHT) {
+ /* 2A/2B sent by left already */
+ return 0;
+ }
+ }
+
+ caset[1] = (((roi.x) & 0xFF00) >> 8);
+ caset[2] = (((roi.x) & 0xFF));
+ caset[3] = (((roi.x - 1 + roi.w) & 0xFF00) >> 8);
+ caset[4] = (((roi.x - 1 + roi.w) & 0xFF));
+ set_col_page_addr_cmd[0].payload = caset;
+
+ paset[1] = (((roi.y) & 0xFF00) >> 8);
+ paset[2] = (((roi.y) & 0xFF));
+ paset[3] = (((roi.y - 1 + roi.h) & 0xFF00) >> 8);
+ paset[4] = (((roi.y - 1 + roi.h) & 0xFF));
+ set_col_page_addr_cmd[1].payload = paset;
+
+ memset(&cmdreq, 0, sizeof(cmdreq));
+ cmdreq.cmds = set_col_page_addr_cmd;
+ cmdreq.cmds_cnt = 2;
+ cmdreq.flags = CMD_REQ_COMMIT | CMD_CLK_CTRL;
+ cmdreq.rlen = 0;
+ cmdreq.cb = NULL;
+
+ if (pinfo->partial_update_dcs_cmd_by_left)
+ ctrl = mdss_dsi_get_ctrl_by_index(DSI_CTRL_LEFT);
+
+ mdss_dsi_cmdlist_put(ctrl, &cmdreq);
+ }
+
+ return 0;
}
static void mdss_dsi_panel_switch_mode(struct mdss_panel_data *pdata,
@@ -419,18 +514,27 @@ static int mdss_dsi_panel_on(struct mdss_panel_data *pdata)
{
struct mipi_panel_info *mipi;
struct mdss_dsi_ctrl_pdata *ctrl = NULL;
+ struct mdss_panel_info *pinfo;
if (pdata == NULL) {
pr_err("%s: Invalid input data\n", __func__);
return -EINVAL;
}
+ pinfo = &pdata->panel_info;
+
ctrl = container_of(pdata, struct mdss_dsi_ctrl_pdata,
panel_data);
mipi = &pdata->panel_info.mipi;
+ if (pinfo->partial_update_dcs_cmd_by_left) {
+ if (ctrl->ndx != DSI_CTRL_LEFT)
+ return 0;
+ }
+
pr_debug("%s: ctrl=%p ndx=%d\n", __func__, ctrl, ctrl->ndx);
+
if (ctrl->on_cmds.cmd_cnt)
mdss_dsi_panel_cmds_send(ctrl, &ctrl->on_cmds);
@@ -442,15 +546,23 @@ static int mdss_dsi_panel_off(struct mdss_panel_data *pdata)
{
struct mipi_panel_info *mipi;
struct mdss_dsi_ctrl_pdata *ctrl = NULL;
+ struct mdss_panel_info *pinfo;
if (pdata == NULL) {
pr_err("%s: Invalid input data\n", __func__);
return -EINVAL;
}
+ pinfo = &pdata->panel_info;
+
ctrl = container_of(pdata, struct mdss_dsi_ctrl_pdata,
panel_data);
+ if (pinfo->partial_update_dcs_cmd_by_left) {
+ if (ctrl->ndx != DSI_CTRL_LEFT)
+ return 0;
+ }
+
pr_debug("%s: ctrl=%p ndx=%d\n", __func__, ctrl, ctrl->ndx);
mipi = &pdata->panel_info.mipi;
@@ -830,12 +942,21 @@ static int mdss_dsi_parse_panel_features(struct device_node *np,
pinfo->cont_splash_enabled = of_property_read_bool(np,
"qcom,cont-splash-enabled");
- pinfo->partial_update_enabled = of_property_read_bool(np,
- "qcom,partial-update-enabled");
- pr_info("%s:%d Partial update %s\n", __func__, __LINE__,
- (pinfo->partial_update_enabled ? "enabled" : "disabled"));
- if (pinfo->partial_update_enabled)
- ctrl->partial_update_fnc = mdss_dsi_panel_partial_update;
+ if (pinfo->mipi.mode == DSI_CMD_MODE) {
+ pinfo->partial_update_enabled = of_property_read_bool(np,
+ "qcom,partial-update-enabled");
+ pr_info("%s: partial_update_enabled=%d\n", __func__,
+ pinfo->partial_update_enabled);
+ if (pinfo->partial_update_enabled) {
+ ctrl->set_col_page_addr = mdss_dsi_set_col_page_addr;
+ pinfo->partial_update_dcs_cmd_by_left =
+ of_property_read_bool(np,
+ "qcom,partial-update-dcs-cmd-by-left");
+ pinfo->partial_update_roi_merge =
+ of_property_read_bool(np,
+ "qcom,partial-update-roi-merge");
+ }
+ }
pinfo->ulps_feature_enabled = of_property_read_bool(np,
"qcom,ulps-enabled");
@@ -866,6 +987,49 @@ static int mdss_dsi_parse_panel_features(struct device_node *np,
return 0;
}
+static void mdss_dsi_parse_panel_horizintal_line_idle(struct device_node *np,
+ struct mdss_dsi_ctrl_pdata *ctrl)
+{
+ const u32 *src;
+ int i, len, cnt;
+ struct panel_horizontal_idle *kp;
+
+ if (!np || !ctrl) {
+ pr_err("%s: Invalid arguments\n", __func__);
+ return;
+ }
+
+ src = of_get_property(np, "qcom,mdss-dsi-hor-line-idle", &len);
+ if (!src || len == 0)
+ return;
+
+ cnt = len % 3; /* 3 fields per entry */
+ if (cnt) {
+ pr_err("%s: invalid horizontal idle len=%d\n", __func__, len);
+ return;
+ }
+
+ cnt = len / sizeof(u32);
+
+ kp = kzalloc(sizeof(*kp) * (cnt / 3), GFP_KERNEL);
+ if (kp == NULL) {
+ pr_err("%s: No memory\n", __func__);
+ return;
+ }
+
+ ctrl->line_idle = kp;
+ for (i = 0; i < cnt; i += 3) {
+ kp->min = be32_to_cpu(src[i]);
+ kp->max = be32_to_cpu(src[i+1]);
+ kp->idle = be32_to_cpu(src[i+2]);
+ kp++;
+ ctrl->horizontal_idle_cnt++;
+ }
+
+ pr_debug("%s: horizontal_idle_cnt=%d\n", __func__,
+ ctrl->horizontal_idle_cnt);
+}
+
static int mdss_panel_parse_dt(struct device_node *np,
struct mdss_dsi_ctrl_pdata *ctrl_pdata)
{
@@ -1176,6 +1340,8 @@ static int mdss_panel_parse_dt(struct device_node *np,
goto error;
}
+ mdss_dsi_parse_panel_horizintal_line_idle(np, ctrl_pdata);
+
return 0;
error:
diff --git a/drivers/video/fbdev/msm/mdss_fb.c b/drivers/video/fbdev/msm/mdss_fb.c
index af3a0e5dbd48..fe2dd93da88c 100644
--- a/drivers/video/fbdev/msm/mdss_fb.c
+++ b/drivers/video/fbdev/msm/mdss_fb.c
@@ -431,12 +431,12 @@ static ssize_t mdss_fb_get_panel_info(struct device *dev,
int ret;
ret = scnprintf(buf, PAGE_SIZE,
- "pu_en=%d\nxalign=%d\nwalign=%d\nystart=%d\nhalign=%d\n"
- "min_w=%d\nmin_h=%d",
+ "pu_en=%d\nxstart=%d\nwalign=%d\nystart=%d\nhalign=%d\n"
+ "min_w=%d\nmin_h=%d\nroi_merge=%d",
pinfo->partial_update_enabled, pinfo->xstart_pix_align,
pinfo->width_pix_align, pinfo->ystart_pix_align,
pinfo->height_pix_align, pinfo->min_width,
- pinfo->min_height);
+ pinfo->min_height, pinfo->partial_update_roi_merge);
return ret;
}
diff --git a/drivers/video/fbdev/msm/mdss_mdp.h b/drivers/video/fbdev/msm/mdss_mdp.h
index f295ef070691..9cd61b5f80e1 100644
--- a/drivers/video/fbdev/msm/mdss_mdp.h
+++ b/drivers/video/fbdev/msm/mdss_mdp.h
@@ -186,6 +186,7 @@ struct mdss_mdp_ctl {
struct mdss_rect roi;
struct mdss_rect roi_bkup;
u8 roi_changed;
+ u8 valid_roi;
int (*start_fnc) (struct mdss_mdp_ctl *ctl);
int (*stop_fnc) (struct mdss_mdp_ctl *ctl);
diff --git a/drivers/video/fbdev/msm/mdss_mdp_ctl.c b/drivers/video/fbdev/msm/mdss_mdp_ctl.c
index a80658996b3b..42ca5a3a6f59 100644
--- a/drivers/video/fbdev/msm/mdss_mdp_ctl.c
+++ b/drivers/video/fbdev/msm/mdss_mdp_ctl.c
@@ -1722,6 +1722,7 @@ int mdss_mdp_ctl_split_display_setup(struct mdss_mdp_ctl *ctl,
sctl->width = pdata->panel_info.xres;
sctl->height = pdata->panel_info.yres;
+ sctl->roi = (struct mdss_rect){0, 0, sctl->width, sctl->height};
ctl->mixer_left = mdss_mdp_mixer_alloc(ctl, MDSS_MDP_MIXER_TYPE_INTF,
false, 0);
@@ -2071,43 +2072,26 @@ int mdss_mdp_ctl_reset(struct mdss_mdp_ctl *ctl)
return 0;
}
-void mdss_mdp_set_roi(struct mdss_mdp_ctl *ctl,
- struct mdp_display_commit *data)
+void mdss_mdp_set_mixer_roi(struct mdss_mdp_ctl *ctl, struct mdss_rect *roi)
{
- struct mdss_rect temp_roi, mixer_roi;
-
- temp_roi.x = data->roi.x;
- temp_roi.y = data->roi.y;
- temp_roi.w = data->roi.w;
- temp_roi.h = data->roi.h;
-
- /*
- * No Partial Update for:
- * 1) dual DSI panels
- * 2) non-cmd mode panels
- */
- if (!temp_roi.w || !temp_roi.h || ctl->mixer_right ||
- (ctl->panel_data->panel_info.type != MIPI_CMD_PANEL) ||
- !ctl->panel_data->panel_info.partial_update_enabled) {
- temp_roi = (struct mdss_rect)
- {0, 0, ctl->mixer_left->width,
- ctl->mixer_left->height};
- }
+ struct mdss_rect mixer_roi;
+ ctl->valid_roi = (roi->w && roi->h);
ctl->roi_changed = 0;
- if (!mdss_rect_cmp(&temp_roi, &ctl->roi)) {
- ctl->roi = temp_roi;
+ if (!mdss_rect_cmp(roi, &ctl->roi)) {
+ ctl->roi = *roi;
ctl->roi_changed++;
mixer_roi = ctl->mixer_left->roi;
- if ((mixer_roi.w != temp_roi.w) ||
- (mixer_roi.h != temp_roi.h)) {
- ctl->mixer_left->roi = temp_roi;
+ if ((mixer_roi.w != roi->w) ||
+ (mixer_roi.h != roi->h)) {
+ ctl->mixer_left->roi = *roi;
ctl->mixer_left->params_changed++;
}
}
- pr_debug("ROI requested: [%d, %d, %d, %d]\n",
- ctl->roi.x, ctl->roi.y, ctl->roi.w, ctl->roi.h);
+
+ pr_debug("ROI requested: [%d]: [%d, %d, %d, %d]\n",
+ ctl->num, ctl->roi.x, ctl->roi.y, ctl->roi.w, ctl->roi.h);
}
static inline u32 mdss_mdp_mpq_pipe_num_map(u32 pipe_num)
@@ -2124,6 +2108,41 @@ static inline u32 mdss_mdp_mpq_pipe_num_map(u32 pipe_num)
return mpq_num;
}
+void mdss_mdp_set_roi(struct mdss_mdp_ctl *ctl,
+ struct mdp_display_commit *data)
+{
+ struct mdss_rect l_roi, r_roi;
+
+ l_roi.x = data->l_roi.x;
+ l_roi.y = data->l_roi.y;
+ l_roi.w = data->l_roi.w;
+ l_roi.h = data->l_roi.h;
+
+ r_roi.x = data->r_roi.x;
+ r_roi.y = data->r_roi.y;
+ r_roi.w = data->r_roi.w;
+ r_roi.h = data->r_roi.h;
+
+ /* Reset ROI when we have (1) invalid ROI (2) feature disabled */
+ if ((!l_roi.w && l_roi.h) || (l_roi.w && !l_roi.h) ||
+ (!r_roi.w && r_roi.h) || (r_roi.w && !r_roi.h) ||
+ !ctl->panel_data->panel_info.partial_update_enabled) {
+ l_roi = (struct mdss_rect)
+ {0, 0, ctl->mixer_left->width, ctl->mixer_left->height};
+
+ if (ctl->mixer_right) {
+ r_roi = (struct mdss_rect)
+ {0, 0, ctl->mixer_right->width,
+ ctl->mixer_right->height};
+ }
+ }
+
+ mdss_mdp_set_mixer_roi(ctl, &l_roi);
+
+ if (ctl->mixer_right)
+ mdss_mdp_set_mixer_roi(ctl->mixer_right->ctl, &r_roi);
+}
+
static void mdss_mdp_mixer_setup(struct mdss_mdp_ctl *master_ctl,
int mixer_mux)
{
@@ -2723,6 +2742,7 @@ int mdss_mdp_display_commit(struct mdss_mdp_ctl *ctl, void *arg)
struct mdss_mdp_ctl *sctl = NULL;
int ret = 0;
bool is_bw_released;
+ int split_enable;
if (!ctl) {
pr_err("display function not set\n");
@@ -2745,8 +2765,23 @@ int mdss_mdp_display_commit(struct mdss_mdp_ctl *ctl, void *arg)
* pending, so we want to re-calculate the bandwidth in this situation
*/
is_bw_released = !mdss_mdp_ctl_perf_get_transaction_status(ctl);
- mdss_mdp_ctl_perf_set_transaction_status(ctl, PERF_SW_COMMIT_STATE,
- PERF_STATUS_BUSY);
+ if (is_bw_released) {
+ if (sctl)
+ is_bw_released =
+ !mdss_mdp_ctl_perf_get_transaction_status(sctl);
+ }
+
+ if (sctl && !ctl->valid_roi && sctl->valid_roi) {
+ /*
+ * Seperate kickoff on DSI1 is needed only when we have
+ * ONLY right half updating on a dual DSI panel
+ */
+ mdss_mdp_ctl_perf_set_transaction_status(sctl,
+ PERF_SW_COMMIT_STATE, PERF_STATUS_BUSY);
+ } else {
+ mdss_mdp_ctl_perf_set_transaction_status(ctl,
+ PERF_SW_COMMIT_STATE, PERF_STATUS_BUSY);
+ }
if (is_bw_released || ctl->force_screen_state ||
(ctl->mixer_left && ctl->mixer_left->params_changed) ||
@@ -2791,6 +2826,18 @@ int mdss_mdp_display_commit(struct mdss_mdp_ctl *ctl, void *arg)
ctl->roi_bkup.h = ctl->roi.h;
ATRACE_BEGIN("postproc_programming");
+ if (sctl && sctl->wait_pingpong)
+ sctl->wait_pingpong(sctl, NULL);
+
+ /*
+ * With partial frame update, enable split display bit only
+ * when validity of ROI's on both the DSI's are identical
+ */
+ if (sctl) {
+ split_enable = (ctl->valid_roi == sctl->valid_roi);
+ mdss_mdp_ctl_split_display_enable(split_enable, ctl, sctl);
+ }
+
if (ctl->mfd && ctl->mfd->dcm_state != DTM_ENTER)
/* postprocessing setup, including dspp */
mdss_mdp_pp_setup_locked(ctl);
@@ -2814,8 +2861,23 @@ int mdss_mdp_display_commit(struct mdss_mdp_ctl *ctl, void *arg)
mdss_mdp_xlog_mixer_reg(ctl);
- if (ctl->display_fnc)
- ret = ctl->display_fnc(ctl, arg); /* kickoff */
+ if (sctl && !ctl->valid_roi && sctl->valid_roi) {
+ /*
+ * Seperate kickoff on DSI1 is needed only when we have
+ * ONLY right half updating on a dual DSI panel
+ */
+ if (sctl->display_fnc)
+ ret = sctl->display_fnc(sctl, arg); /* DSI1 kickoff */
+ } else {
+ if (ctl->display_fnc)
+ ret = ctl->display_fnc(ctl, arg); /* DSI0 kickoff */
+ }
+
+ if (sctl)
+ sctl->valid_roi = 0;
+
+ ctl->valid_roi = 0;
+
if (ret)
pr_warn("error displaying frame\n");
@@ -2833,13 +2895,26 @@ done:
void mdss_mdp_ctl_notifier_register(struct mdss_mdp_ctl *ctl,
struct notifier_block *notifier)
{
+ struct mdss_mdp_ctl *sctl;
+
blocking_notifier_chain_register(&ctl->notifier_head, notifier);
+
+ sctl = mdss_mdp_get_split_ctl(ctl);
+ if (sctl)
+ blocking_notifier_chain_register(&sctl->notifier_head,
+ notifier);
}
void mdss_mdp_ctl_notifier_unregister(struct mdss_mdp_ctl *ctl,
struct notifier_block *notifier)
{
+ struct mdss_mdp_ctl *sctl;
blocking_notifier_chain_unregister(&ctl->notifier_head, notifier);
+
+ sctl = mdss_mdp_get_split_ctl(ctl);
+ if (sctl)
+ blocking_notifier_chain_unregister(&sctl->notifier_head,
+ notifier);
}
int mdss_mdp_ctl_notify(struct mdss_mdp_ctl *ctl, int event)
diff --git a/drivers/video/fbdev/msm/mdss_mdp_intf_cmd.c b/drivers/video/fbdev/msm/mdss_mdp_intf_cmd.c
index cd7bda9b3576..864ab730c6c6 100644
--- a/drivers/video/fbdev/msm/mdss_mdp_intf_cmd.c
+++ b/drivers/video/fbdev/msm/mdss_mdp_intf_cmd.c
@@ -413,7 +413,8 @@ static void __mdss_mdp_cmd_ulps_work(struct work_struct *work)
static int mdss_mdp_cmd_add_vsync_handler(struct mdss_mdp_ctl *ctl,
struct mdss_mdp_vsync_handler *handle)
{
- struct mdss_mdp_cmd_ctx *ctx;
+ struct mdss_mdp_ctl *sctl = NULL;
+ struct mdss_mdp_cmd_ctx *ctx, *sctx = NULL;
unsigned long flags;
bool enable_rdptr = false;
@@ -425,6 +426,9 @@ static int mdss_mdp_cmd_add_vsync_handler(struct mdss_mdp_ctl *ctl,
MDSS_XLOG(ctl->num, ctx->koff_cnt, ctx->clk_enabled,
ctx->rdptr_enabled);
+ sctl = mdss_mdp_get_split_ctl(ctl);
+ if (sctl)
+ sctx = (struct mdss_mdp_cmd_ctx *) sctl->priv_data;
spin_lock_irqsave(&ctx->clk_lock, flags);
if (!handle->enabled) {
@@ -432,13 +436,19 @@ static int mdss_mdp_cmd_add_vsync_handler(struct mdss_mdp_ctl *ctl,
list_add(&handle->list, &ctx->vsync_handlers);
enable_rdptr = !handle->cmd_post_flush;
- if (enable_rdptr)
+ if (enable_rdptr) {
ctx->vsync_enabled++;
+ if (sctx)
+ sctx->vsync_enabled++;
+ }
}
spin_unlock_irqrestore(&ctx->clk_lock, flags);
- if (enable_rdptr)
+ if (enable_rdptr) {
mdss_mdp_cmd_clk_on(ctx);
+ if (sctx)
+ mdss_mdp_cmd_clk_on(sctx);
+ }
return 0;
}
@@ -446,7 +456,8 @@ static int mdss_mdp_cmd_add_vsync_handler(struct mdss_mdp_ctl *ctl,
static int mdss_mdp_cmd_remove_vsync_handler(struct mdss_mdp_ctl *ctl,
struct mdss_mdp_vsync_handler *handle)
{
- struct mdss_mdp_cmd_ctx *ctx;
+ struct mdss_mdp_ctl *sctl;
+ struct mdss_mdp_cmd_ctx *ctx, *sctx = NULL;
unsigned long flags;
ctx = (struct mdss_mdp_cmd_ctx *) ctl->priv_data;
@@ -457,6 +468,9 @@ static int mdss_mdp_cmd_remove_vsync_handler(struct mdss_mdp_ctl *ctl,
MDSS_XLOG(ctl->num, ctx->koff_cnt, ctx->clk_enabled,
ctx->rdptr_enabled, 0x88888);
+ sctl = mdss_mdp_get_split_ctl(ctl);
+ if (sctl)
+ sctx = (struct mdss_mdp_cmd_ctx *) sctl->priv_data;
spin_lock_irqsave(&ctx->clk_lock, flags);
if (handle->enabled) {
@@ -464,8 +478,11 @@ static int mdss_mdp_cmd_remove_vsync_handler(struct mdss_mdp_ctl *ctl,
list_del_init(&handle->list);
if (!handle->cmd_post_flush) {
- if (ctx->vsync_enabled)
+ if (ctx->vsync_enabled) {
ctx->vsync_enabled--;
+ if (sctx)
+ sctx->vsync_enabled--;
+ }
else
WARN(1, "unbalanced vsync disable");
}
@@ -544,23 +561,48 @@ static int mdss_mdp_cmd_wait4pingpong(struct mdss_mdp_ctl *ctl, void *arg)
static int mdss_mdp_cmd_set_partial_roi(struct mdss_mdp_ctl *ctl)
{
+ struct mdss_mdp_ctl *sctl = NULL;
+ struct mdss_rect *roi;
int rc = 0;
- if (ctl->roi.w && ctl->roi.h && ctl->roi_changed &&
- ctl->panel_data->panel_info.partial_update_enabled) {
- ctl->panel_data->panel_info.roi_x = ctl->roi.x;
- ctl->panel_data->panel_info.roi_y = ctl->roi.y;
- ctl->panel_data->panel_info.roi_w = ctl->roi.w;
- ctl->panel_data->panel_info.roi_h = ctl->roi.h;
- rc = mdss_mdp_ctl_intf_event(ctl,
- MDSS_EVENT_ENABLE_PARTIAL_UPDATE, NULL);
+ if (!ctl->panel_data->panel_info.partial_update_enabled)
+ return rc;
+
+ sctl = mdss_mdp_get_split_ctl(ctl);
+
+ /* save roi to pinfo which used by dsi controller */
+ roi = &ctl->panel_data->panel_info.roi;
+ *roi = ctl->roi;
+
+ if (sctl) {
+ /* save roi to pinfo whcih used by dsi controller */
+ roi = &sctl->panel_data->panel_info.roi;
+ *roi = sctl->roi;
}
+
+ /* set panel col and page addr */
+ rc = mdss_mdp_ctl_intf_event(ctl,
+ MDSS_EVENT_ENABLE_PARTIAL_ROI, NULL);
+ return rc;
+}
+
+static int mdss_mdp_cmd_set_stream_size(struct mdss_mdp_ctl *ctl)
+{
+ int rc = 0;
+
+ if (!ctl->panel_data->panel_info.partial_update_enabled)
+ return rc;
+
+ /* set dsi controller stream size */
+ rc = mdss_mdp_ctl_intf_event(ctl,
+ MDSS_EVENT_DSI_STREAM_SIZE, NULL);
return rc;
}
int mdss_mdp_cmd_kickoff(struct mdss_mdp_ctl *ctl, void *arg)
{
- struct mdss_mdp_cmd_ctx *ctx;
+ struct mdss_mdp_ctl *sctl;
+ struct mdss_mdp_cmd_ctx *ctx, *sctx = NULL;
unsigned long flags;
int rc;
@@ -570,6 +612,10 @@ int mdss_mdp_cmd_kickoff(struct mdss_mdp_ctl *ctl, void *arg)
return -ENODEV;
}
+ sctl = mdss_mdp_get_split_ctl(ctl);
+ if (sctl)
+ sctx = (struct mdss_mdp_cmd_ctx *) sctl->priv_data;
+
mdss_mdp_ctl_perf_set_transaction_status(ctl,
PERF_HW_MDP_STATE, PERF_STATUS_BUSY);
@@ -578,6 +624,8 @@ int mdss_mdp_cmd_kickoff(struct mdss_mdp_ctl *ctl, void *arg)
WARN(rc, "intf %d unblank error (%d)\n", ctl->intf_num, rc);
ctx->panel_on++;
+ if (sctx)
+ sctx->panel_on++;
rc = mdss_mdp_ctl_intf_event(ctl, MDSS_EVENT_PANEL_ON, NULL);
WARN(rc, "intf %d panel on error (%d)\n", ctl->intf_num, rc);
@@ -600,6 +648,8 @@ int mdss_mdp_cmd_kickoff(struct mdss_mdp_ctl *ctl, void *arg)
*/
mdss_mdp_ctl_intf_event(ctl, MDSS_EVENT_DSI_CMDLIST_KOFF,
(void *)&ctx->recovery);
+ mdss_mdp_cmd_set_stream_size(ctl);
+
INIT_COMPLETION(ctx->pp_comp);
mdss_mdp_irq_enable(MDSS_MDP_IRQ_PING_PONG_COMP, ctx->pp_num);
mdss_mdp_ctl_write(ctl, MDSS_MDP_REG_CTL_START, 1);
diff --git a/drivers/video/fbdev/msm/mdss_mdp_overlay.c b/drivers/video/fbdev/msm/mdss_mdp_overlay.c
index 233b3d06b737..28532054b546 100644
--- a/drivers/video/fbdev/msm/mdss_mdp_overlay.c
+++ b/drivers/video/fbdev/msm/mdss_mdp_overlay.c
@@ -1290,6 +1290,7 @@ int mdss_mdp_overlay_kickoff(struct msm_fb_data_type *mfd,
struct mdss_overlay_private *mdp5_data = mfd_to_mdp5_data(mfd);
struct mdss_mdp_pipe *pipe;
struct mdss_mdp_ctl *ctl = mfd_to_ctl(mfd);
+ struct mdp_display_commit temp_data;
int ret = 0;
int sd_in_pipe = 0;
bool need_cleanup = false;
@@ -1328,8 +1329,18 @@ int mdss_mdp_overlay_kickoff(struct msm_fb_data_type *mfd,
mdss_mdp_clk_ctrl(MDP_BLOCK_POWER_ON, false);
- if (data)
+ if (data) {
mdss_mdp_set_roi(ctl, data);
+ } else {
+ temp_data.l_roi = (struct mdp_rect){0, 0,
+ ctl->mixer_left->width, ctl->mixer_left->height};
+ if (ctl->mixer_right) {
+ temp_data.r_roi = (struct mdp_rect) {0, 0,
+ ctl->mixer_right->width, ctl->mixer_right->height};
+ }
+ mdss_mdp_set_roi(ctl, &temp_data);
+ }
+
/*
* Setup pipe in solid fill before unstaging,
@@ -3500,6 +3511,9 @@ int mdss_mdp_overlay_init(struct msm_fb_data_type *mfd)
mfd->mdp.private1 = mdp5_data;
mfd->wait_for_kickoff = true;
+ if (mfd->panel_info->partial_update_enabled && mfd->split_display)
+ mdp5_data->mdata->has_src_split = false;
+
rc = mdss_mdp_overlay_fb_parse_dt(mfd);
if (rc)
return rc;
diff --git a/drivers/video/fbdev/msm/mdss_mdp_pipe.c b/drivers/video/fbdev/msm/mdss_mdp_pipe.c
index cd6f1dee03a9..65ee2a082c94 100644
--- a/drivers/video/fbdev/msm/mdss_mdp_pipe.c
+++ b/drivers/video/fbdev/msm/mdss_mdp_pipe.c
@@ -1060,8 +1060,9 @@ static int mdss_mdp_image_setup(struct mdss_mdp_pipe *pipe,
struct mdss_rect sci, dst, src;
bool rotation = false;
- pr_debug("pnum=%d wh=%dx%d src={%d,%d,%d,%d} dst={%d,%d,%d,%d}\n",
- pipe->num, pipe->img_width, pipe->img_height,
+ pr_debug("ctl: %d pnum=%d wh=%dx%d src={%d,%d,%d,%d} dst={%d,%d,%d,%d}\n",
+ pipe->mixer_left->ctl->num, pipe->num,
+ pipe->img_width, pipe->img_height,
pipe->src.x, pipe->src.y, pipe->src.w, pipe->src.h,
pipe->dst.x, pipe->dst.y, pipe->dst.w, pipe->dst.h);
@@ -1100,9 +1101,9 @@ static int mdss_mdp_image_setup(struct mdss_mdp_pipe *pipe,
src = pipe->src;
if ((pipe->mixer_left->type != MDSS_MDP_MIXER_TYPE_WRITEBACK) &&
- !pipe->mixer_left->ctl->is_video_mode &&
- !pipe->src_split_req)
- mdss_mdp_crop_rect(&src, &dst, &sci);
+ !pipe->mixer_left->ctl->is_video_mode &&
+ !pipe->src_split_req)
+ mdss_mdp_crop_rect(&src, &dst, &sci);
src_size = (src.h << 16) | src.w;
src_xy = (src.y << 16) | src.x;
diff --git a/drivers/video/fbdev/msm/mdss_panel.h b/drivers/video/fbdev/msm/mdss_panel.h
index 9bdcaff99062..8ced70aa7509 100644
--- a/drivers/video/fbdev/msm/mdss_panel.h
+++ b/drivers/video/fbdev/msm/mdss_panel.h
@@ -130,10 +130,11 @@ struct mdss_panel_recovery {
* panel driver gets ptr to struct fb_info which
* holds fb dev information.
* @MDSS_EVENT_PANEL_CLK_CTRL: panel clock control
- - 0 clock disable
- - 1 clock enable
+ * - 0 clock disable
+ * - 1 clock enable
* @MDSS_EVENT_DSI_CMDLIST_KOFF: acquire dsi_mdp_busy lock before kickoff.
- * @MDSS_EVENT_ENABLE_PARTIAL_UPDATE: Event to update ROI of the panel.
+ * @MDSS_EVENT_ENABLE_PARTIAL_ROI: Event to update ROI of the panel.
+ * @MDSS_EVENT_DSI_STREAM_SIZE: Event to update DSI controller's stream size
* @MDSS_EVENT_DSI_ULPS_CTRL: Event to configure Ultra Lower Power Saving
* mode for the DSI data and clock lanes. The
* event arguments can have one of these values:
@@ -160,7 +161,8 @@ enum mdss_intf_events {
MDSS_EVENT_FB_REGISTERED,
MDSS_EVENT_PANEL_CLK_CTRL,
MDSS_EVENT_DSI_CMDLIST_KOFF,
- MDSS_EVENT_ENABLE_PARTIAL_UPDATE,
+ MDSS_EVENT_ENABLE_PARTIAL_ROI,
+ MDSS_EVENT_DSI_STREAM_SIZE,
MDSS_EVENT_DSI_ULPS_CTRL,
MDSS_EVENT_DSI_DYNAMIC_SWITCH,
};
@@ -324,10 +326,7 @@ struct mdss_panel_info {
u32 rst_seq[MDSS_DSI_RST_SEQ_LEN];
u32 rst_seq_len;
u32 vic; /* video identification code */
- u32 roi_x;
- u32 roi_y;
- u32 roi_w;
- u32 roi_h;
+ struct mdss_rect roi;
int bklt_ctrl; /* backlight ctrl */
int pwm_pmic_gpio;
int pwm_lpg_chan;
@@ -347,6 +346,8 @@ struct mdss_panel_info {
u32 cont_splash_enabled;
u32 partial_update_enabled;
+ u32 partial_update_dcs_cmd_by_left;
+ u32 partial_update_roi_merge;
struct ion_handle *splash_ihdl;
u32 panel_power_on;
diff --git a/include/uapi/linux/msm_mdp.h b/include/uapi/linux/msm_mdp.h
index 2075a285622a..8a289a3d9a54 100644
--- a/include/uapi/linux/msm_mdp.h
+++ b/include/uapi/linux/msm_mdp.h
@@ -1042,7 +1042,8 @@ struct mdp_display_commit {
uint32_t flags;
uint32_t wait_for_finish;
struct fb_var_screeninfo var;
- struct mdp_rect roi;
+ struct mdp_rect l_roi;
+ struct mdp_rect r_roi;
};
/**