summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJeykumar Sankaran <jsanka@codeaurora.org>2013-09-20 13:47:01 -0700
committerDavid Keitel <dkeitel@codeaurora.org>2016-03-23 20:21:53 -0700
commit29f66ae4688514f4af15fee4893ea3a54e76f32d (patch)
tree0610df6f32afa75a6f67337657f37c30b29336cb
parent6dedcd4fe530436d3c11a3144ddeab4b075d6b71 (diff)
mdss: dsi: Add support to partial update
Add support to send DCS commands to set the partial update region of interest(ROI) size. These commands will set the column/row start and end coordinates based on the ROI size. Change-Id: I3418472d9d622150c3cd7571b0b1e7a3482f5597 Signed-off-by: Jeykumar Sankaran <jsanka@codeaurora.org>
-rw-r--r--drivers/video/fbdev/msm/mdss_dsi.c42
-rw-r--r--drivers/video/fbdev/msm/mdss_dsi.h1
-rw-r--r--drivers/video/fbdev/msm/mdss_dsi_panel.c68
-rw-r--r--drivers/video/fbdev/msm/mdss_mdp_intf_cmd.c21
-rw-r--r--drivers/video/fbdev/msm/mdss_panel.h7
5 files changed, 138 insertions, 1 deletions
diff --git a/drivers/video/fbdev/msm/mdss_dsi.c b/drivers/video/fbdev/msm/mdss_dsi.c
index f1817675e989..24f09496599a 100644
--- a/drivers/video/fbdev/msm/mdss_dsi.c
+++ b/drivers/video/fbdev/msm/mdss_dsi.c
@@ -617,7 +617,7 @@ static int mdss_dsi_dfps_config(struct mdss_panel_data *pdata, int new_fps)
}
ctrl_pdata = container_of(pdata, struct mdss_dsi_ctrl_pdata,
- panel_data);
+ panel_data);
if (!ctrl_pdata->panel_data.panel_info.dynamic_fps) {
pr_err("%s: Dynamic fps not enabled for this panel\n",
@@ -662,6 +662,43 @@ 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)
+{
+ int rc = -EINVAL;
+ u32 data;
+ struct mdss_dsi_ctrl_pdata *ctrl_pdata = NULL;
+
+ 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);
+
+ /* DSI_COMMAND_MODE_MDP_STREAM_CTRL */
+ data = (((pdata->panel_info.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;
+ 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;
+ }
+
+ return rc;
+}
+
static int mdss_dsi_event_handler(struct mdss_panel_data *pdata,
int event, void *arg)
{
@@ -729,6 +766,9 @@ 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);
+ break;
default:
pr_debug("%s: unhandled event=%d\n", __func__, event);
break;
diff --git a/drivers/video/fbdev/msm/mdss_dsi.h b/drivers/video/fbdev/msm/mdss_dsi.h
index 619d6c83a172..64277c3fadc0 100644
--- a/drivers/video/fbdev/msm/mdss_dsi.h
+++ b/drivers/video/fbdev/msm/mdss_dsi.h
@@ -315,6 +315,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);
struct mdss_panel_data panel_data;
unsigned char *ctrl_base;
int reg_size;
diff --git a/drivers/video/fbdev/msm/mdss_dsi_panel.c b/drivers/video/fbdev/msm/mdss_dsi_panel.c
index c2b42ff9d2ef..99490c27f299 100644
--- a/drivers/video/fbdev/msm/mdss_dsi_panel.c
+++ b/drivers/video/fbdev/msm/mdss_dsi_panel.c
@@ -231,6 +231,61 @@ void mdss_dsi_panel_reset(struct mdss_panel_data *pdata, int enable)
}
}
+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},
+ {{DTYPE_DCS_LWRITE, 1, 0, 0, 1, sizeof(paset)}, paset},
+};
+
+static int mdss_dsi_panel_partial_update(struct mdss_panel_data *pdata)
+{
+ struct mipi_panel_info *mipi;
+ struct mdss_dsi_ctrl_pdata *ctrl = NULL;
+ struct dcs_cmd_req cmdreq;
+ int rc = 0;
+
+ if (pdata == NULL) {
+ pr_err("%s: Invalid input data\n", __func__);
+ return -EINVAL;
+ }
+
+ 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);
+
+ 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;
+
+ mdss_dsi_cmdlist_put(ctrl, &cmdreq);
+
+ return rc;
+}
+
static void mdss_dsi_panel_bl_ctrl(struct mdss_panel_data *pdata,
u32 bl_level)
{
@@ -850,6 +905,7 @@ int mdss_dsi_panel_init(struct device_node *node,
int rc = 0;
static const char *panel_name;
bool cont_splash_enabled;
+ bool partial_update_enabled;
if (!node) {
pr_err("%s: no panel node\n", __func__);
@@ -886,6 +942,18 @@ int mdss_dsi_panel_init(struct device_node *node,
ctrl_pdata->panel_data.panel_info.cont_splash_enabled = 1;
}
+ partial_update_enabled = of_property_read_bool(node,
+ "qcom,partial-update-enabled");
+ if (partial_update_enabled) {
+ pr_info("%s: Partial update enabled.\n", __func__);
+ ctrl_pdata->panel_data.panel_info.partial_update_enabled = 1;
+ ctrl_pdata->partial_update_fnc = mdss_dsi_panel_partial_update;
+ } else {
+ pr_info("%s: Partial update disabled.\n", __func__);
+ ctrl_pdata->panel_data.panel_info.partial_update_enabled = 0;
+ ctrl_pdata->partial_update_fnc = NULL;
+ }
+
ctrl_pdata->on = mdss_dsi_panel_on;
ctrl_pdata->off = mdss_dsi_panel_off;
ctrl_pdata->panel_data.set_backlight = mdss_dsi_panel_bl_ctrl;
diff --git a/drivers/video/fbdev/msm/mdss_mdp_intf_cmd.c b/drivers/video/fbdev/msm/mdss_mdp_intf_cmd.c
index 32d3bff1b2c8..fec73b3ac03e 100644
--- a/drivers/video/fbdev/msm/mdss_mdp_intf_cmd.c
+++ b/drivers/video/fbdev/msm/mdss_mdp_intf_cmd.c
@@ -431,10 +431,28 @@ static int mdss_mdp_cmd_wait4pingpong(struct mdss_mdp_ctl *ctl, void *arg)
return rc;
}
+static int mdss_mdp_cmd_set_partial_roi(struct mdss_mdp_ctl *ctl,
+ struct mdss_mdp_img_rect *roi)
+{
+ int rc = 0;
+ if (roi->w && roi->h &&
+ ctl->panel_data->panel_info.partial_update_enabled) {
+ ctl->panel_data->panel_info.roi_x = roi->x;
+ ctl->panel_data->panel_info.roi_y = roi->y;
+ ctl->panel_data->panel_info.roi_w = roi->w;
+ ctl->panel_data->panel_info.roi_h = roi->h;
+
+ rc = mdss_mdp_ctl_intf_event(ctl,
+ MDSS_EVENT_ENABLE_PARTIAL_UPDATE, NULL);
+ }
+ return rc;
+}
+
int mdss_mdp_cmd_kickoff(struct mdss_mdp_ctl *ctl, void *arg)
{
struct mdss_mdp_cmd_ctx *ctx;
unsigned long flags;
+ struct mdss_mdp_img_rect roi;
int rc;
ctx = (struct mdss_mdp_cmd_ctx *) ctl->priv_data;
@@ -453,6 +471,9 @@ int mdss_mdp_cmd_kickoff(struct mdss_mdp_ctl *ctl, void *arg)
WARN(rc, "intf %d panel on error (%d)\n", ctl->intf_num, rc);
}
+ roi = (struct mdss_mdp_img_rect){0, 0, ctl->width, ctl->height};
+ mdss_mdp_cmd_set_partial_roi(ctl, &roi);
+
/*
* tx dcs command if had any
*/
diff --git a/drivers/video/fbdev/msm/mdss_panel.h b/drivers/video/fbdev/msm/mdss_panel.h
index ee53139a30f3..82411153bb86 100644
--- a/drivers/video/fbdev/msm/mdss_panel.h
+++ b/drivers/video/fbdev/msm/mdss_panel.h
@@ -126,6 +126,7 @@ struct mdss_panel_recovery {
- 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.
*/
enum mdss_intf_events {
MDSS_EVENT_RESET = 1,
@@ -143,6 +144,7 @@ enum mdss_intf_events {
MDSS_EVENT_FB_REGISTERED,
MDSS_EVENT_PANEL_CLK_CTRL,
MDSS_EVENT_DSI_CMDLIST_KOFF,
+ MDSS_EVENT_ENABLE_PARTIAL_UPDATE,
};
struct lcd_panel_info {
@@ -294,6 +296,10 @@ 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;
int bklt_ctrl; /* backlight ctrl */
int pwm_pmic_gpio;
int pwm_lpg_chan;
@@ -304,6 +310,7 @@ struct mdss_panel_info {
u32 mode_gpio_state;
u32 cont_splash_enabled;
+ u32 partial_update_enabled;
struct ion_handle *splash_ihdl;
u32 panel_power_on;