msm: mdss: dsi: Add support dual roi partial update

Add support for sending multiple roi information via the 2A/2B
command to the panel. This mode is only supported on certain
panels. This change will be help in sending multiple partial
updates that will be merged as a single partial update.

Change-Id: Ib0fb977d86d6293595b62e9f0476615d68b919ac
Signed-off-by: Siddhartha Agrawal <agrawals@codeaurora.org>
This commit is contained in:
Siddhartha Agrawal 2016-10-05 11:59:30 -07:00 committed by Gerrit - the friendly Code Review server
parent bbd8499b43
commit a7d84d65a8
11 changed files with 192 additions and 43 deletions

View file

@ -350,8 +350,13 @@ the fps window.
as below:
--> Reset GPIO value
--> Sleep value (in ms)
- qcom,partial-update-enabled: Boolean used to enable partial
- qcom,partial-update-enabled: String used to enable partial
panel update for command mode panels.
"none": partial update is disabled
"single_roi": default enable mode, only single roi is sent to panel
"dual_roi": two rois are merged into one big roi. Panel ddic should be able
to process two roi's along with the DCS command to send two rois.
disabled if property is not specified.
- qcom,mdss-dsi-horizontal-line-idle: List of width ranges (EC - SC) in pixels indicating
additional idle time in dsi clock cycles that is needed
to compensate for smaller line width.
@ -632,7 +637,7 @@ Example:
qcom,mdss-tear-check-rd-ptr-trigger-intr = <1281>;
qcom,mdss-tear-check-frame-rate = <6000>;
qcom,mdss-dsi-reset-sequence = <1 2>, <0 10>, <1 10>;
qcom,partial-update-enabled;
qcom,partial-update-enabled = "single_roi";
qcom,dcs-cmd-by-left;
qcom,mdss-dsi-lp11-init;
qcom,mdss-dsi-init-delay-us = <100>;

View file

@ -388,7 +388,7 @@
qcom,mdss-dsi-bl-max-level = <4095>;
qcom,cont-splash-enabled;
qcom,panel-supply-entries = <&dsi_panel_pwr_supply>;
qcom,partial-update-enabled;
qcom,partial-update-enabled = "single_roi";
qcom,panel-roi-alignment = <720 128 720 64 720 64>;
};
@ -432,7 +432,7 @@
qcom,5v-boost-gpio = <&pmi8994_gpios 8 0>;
qcom,cont-splash-enabled;
qcom,panel-supply-entries = <&dsi_panel_pwr_supply>;
qcom,partial-update-enabled;
qcom,partial-update-enabled = "single_roi";
qcom,panel-roi-alignment = <4 4 2 2 20 20>;
};

View file

@ -376,7 +376,7 @@
qcom,mdss-dsi-bl-max-level = <4095>;
qcom,cont-splash-enabled;
qcom,panel-supply-entries = <&dsi_panel_pwr_supply>;
qcom,partial-update-enabled;
qcom,partial-update-enabled = "single_roi";
qcom,panel-roi-alignment = <720 128 720 64 720 64>;
};

View file

@ -409,7 +409,7 @@
qcom,mdss-dsi-bl-min-level = <1>;
qcom,mdss-dsi-bl-max-level = <4095>;
qcom,panel-supply-entries = <&dsi_panel_pwr_supply>;
qcom,partial-update-enabled;
qcom,partial-update-enabled = "single_roi";
qcom,panel-roi-alignment = <720 128 720 64 720 64>;
};
@ -432,7 +432,7 @@
qcom,mdss-dsi-bl-min-level = <1>;
qcom,mdss-dsi-bl-max-level = <4095>;
qcom,panel-supply-entries = <&dsi_panel_pwr_supply>;
qcom,partial-update-enabled;
qcom,partial-update-enabled = "single_roi";
/* panel supports slice height of 8/16/32/48/3840 */
qcom,panel-roi-alignment = <1080 8 1080 8 1080 8>;
};
@ -480,7 +480,7 @@
qcom,mdss-dsi-bl-max-level = <4095>;
qcom,5v-boost-gpio = <&pmi8994_gpios 8 0>;
qcom,panel-supply-entries = <&dsi_panel_pwr_supply>;
qcom,partial-update-enabled;
qcom,partial-update-enabled = "single_roi";
qcom,panel-roi-alignment = <4 2 4 2 20 20>;
};

View file

@ -629,7 +629,7 @@
qcom,mdss-dsi-bl-min-level = <1>;
qcom,mdss-dsi-bl-max-level = <4095>;
qcom,panel-supply-entries = <&dsi_panel_pwr_supply>;
qcom,partial-update-enabled;
qcom,partial-update-enabled = "single_roi";
/* panel supports slice height of 8/16/32/48/3840 */
qcom,panel-roi-alignment = <1080 8 1080 8 1080 8>;
};

View file

@ -1,4 +1,4 @@
/* Copyright (c) 2015, The Linux Foundation. All rights reserved.
/* Copyright (c) 2015-2016, The Linux Foundation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and
@ -343,7 +343,7 @@
qcom,mdss-dsi-bl-max-level = <4095>;
qcom,cont-splash-enabled;
qcom,panel-supply-entries = <&dsi_panel_pwr_supply>;
qcom,partial-update-enabled;
qcom,partial-update-enabled = "single_roi";
qcom,panel-roi-alignment = <720 128 720 64 720 64>;
};
@ -387,7 +387,7 @@
qcom,5v-boost-gpio = <&pmi8994_gpios 8 0>;
qcom,cont-splash-enabled;
qcom,panel-supply-entries = <&dsi_panel_pwr_supply>;
qcom,partial-update-enabled;
qcom,partial-update-enabled = "single_roi";
qcom,panel-roi-alignment = <4 4 2 2 20 20>;
};

View file

@ -397,7 +397,7 @@
qcom,mdss-dsi-bl-min-level = <1>;
qcom,mdss-dsi-bl-max-level = <4095>;
qcom,panel-supply-entries = <&dsi_panel_pwr_supply>;
qcom,partial-update-enabled;
qcom,partial-update-enabled = "single_roi";
qcom,panel-roi-alignment = <720 128 720 64 720 64>;
};
@ -420,7 +420,7 @@
qcom,mdss-dsi-bl-min-level = <1>;
qcom,mdss-dsi-bl-max-level = <4095>;
qcom,panel-supply-entries = <&dsi_panel_pwr_supply>;
qcom,partial-update-enabled;
qcom,partial-update-enabled = "single_roi";
/* panel supports slice height of 8/16/32/48/3840 */
qcom,panel-roi-alignment = <1080 8 1080 8 1080 8>;
};
@ -468,7 +468,7 @@
qcom,mdss-dsi-bl-max-level = <4095>;
qcom,5v-boost-gpio = <&pmi8994_gpios 8 0>;
qcom,panel-supply-entries = <&dsi_panel_pwr_supply>;
qcom,partial-update-enabled;
qcom,partial-update-enabled = "single_roi";
qcom,panel-roi-alignment = <4 4 2 2 20 20>;
};

View file

@ -382,7 +382,7 @@
qcom,mdss-dsi-bl-max-level = <4095>;
qcom,5v-boost-gpio = <&tlmm 51 0>;
qcom,panel-supply-entries = <&dsi_panel_pwr_supply>;
qcom,partial-update-enabled;
qcom,partial-update-enabled = "single_roi";
qcom,panel-roi-alignment = <4 2 4 2 20 20>;
};

View file

@ -468,6 +468,7 @@ struct mdss_dsi_ctrl_pdata {
bool cmd_sync_wait_trigger;
struct mdss_rect roi;
struct mdss_dsi_dual_pu_roi dual_roi;
struct pwm_device *pwm_bl;
u32 pclk_rate;
u32 byte_clk_rate;

View file

@ -447,28 +447,82 @@ static int mdss_dsi_roi_merge(struct mdss_dsi_ctrl_pdata *ctrl,
static char caset[] = {0x2a, 0x00, 0x00, 0x03, 0x00}; /* DTYPE_DCS_LWRITE */
static char paset[] = {0x2b, 0x00, 0x00, 0x05, 0x00}; /* DTYPE_DCS_LWRITE */
/*
* Some panels can support multiple ROIs as part of the below commands
*/
static char caset_dual[] = {0x2a, 0x00, 0x00, 0x03, 0x00, 0x03,
0x00, 0x00, 0x00, 0x00};/* DTYPE_DCS_LWRITE */
static char paset_dual[] = {0x2b, 0x00, 0x00, 0x05, 0x00, 0x03,
0x00, 0x00, 0x00, 0x00};/* DTYPE_DCS_LWRITE */
/* 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},
};
/* pack into one frame before sent */
static struct dsi_cmd_desc set_dual_col_page_addr_cmd[] = { /*packed*/
{{DTYPE_DCS_LWRITE, 0, 0, 0, 1, sizeof(caset_dual)}, caset_dual},
{{DTYPE_DCS_LWRITE, 1, 0, 0, 1, sizeof(paset_dual)}, paset_dual},
};
static void __mdss_dsi_send_col_page_addr(struct mdss_dsi_ctrl_pdata *ctrl,
struct mdss_rect *roi, bool dual_roi)
{
if (dual_roi) {
struct mdss_rect *first, *second;
first = &ctrl->panel_data.panel_info.dual_roi.first_roi;
second = &ctrl->panel_data.panel_info.dual_roi.second_roi;
caset_dual[1] = (((first->x) & 0xFF00) >> 8);
caset_dual[2] = (((first->x) & 0xFF));
caset_dual[3] = (((first->x - 1 + first->w) & 0xFF00) >> 8);
caset_dual[4] = (((first->x - 1 + first->w) & 0xFF));
/* skip the MPU setting byte*/
caset_dual[6] = (((second->x) & 0xFF00) >> 8);
caset_dual[7] = (((second->x) & 0xFF));
caset_dual[8] = (((second->x - 1 + second->w) & 0xFF00) >> 8);
caset_dual[9] = (((second->x - 1 + second->w) & 0xFF));
set_dual_col_page_addr_cmd[0].payload = caset_dual;
paset_dual[1] = (((first->y) & 0xFF00) >> 8);
paset_dual[2] = (((first->y) & 0xFF));
paset_dual[3] = (((first->y - 1 + first->h) & 0xFF00) >> 8);
paset_dual[4] = (((first->y - 1 + first->h) & 0xFF));
/* skip the MPU setting byte */
paset_dual[6] = (((second->y) & 0xFF00) >> 8);
paset_dual[7] = (((second->y) & 0xFF));
paset_dual[8] = (((second->y - 1 + second->h) & 0xFF00) >> 8);
paset_dual[9] = (((second->y - 1 + second->h) & 0xFF));
set_dual_col_page_addr_cmd[1].payload = paset_dual;
} else {
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;
}
pr_debug("%s Sending 2A 2B cmnd with dual_roi=%d\n", __func__,
dual_roi);
}
static void mdss_dsi_send_col_page_addr(struct mdss_dsi_ctrl_pdata *ctrl,
struct mdss_rect *roi, int unicast)
{
struct dcs_cmd_req cmdreq;
struct mdss_panel_info *pinfo = &ctrl->panel_data.panel_info;
bool dual_roi = pinfo->dual_roi.enabled;
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;
__mdss_dsi_send_col_page_addr(ctrl, roi, dual_roi);
memset(&cmdreq, 0, sizeof(cmdreq));
cmdreq.cmds_cnt = 2;
@ -478,7 +532,9 @@ static void mdss_dsi_send_col_page_addr(struct mdss_dsi_ctrl_pdata *ctrl,
cmdreq.rlen = 0;
cmdreq.cb = NULL;
cmdreq.cmds = set_col_page_addr_cmd;
/* Send default or dual roi 2A/2B cmd */
cmdreq.cmds = dual_roi ? set_dual_col_page_addr_cmd :
set_col_page_addr_cmd;
mdss_dsi_cmdlist_put(ctrl, &cmdreq);
}
@ -1837,6 +1893,41 @@ error:
pinfo->esd_check_enabled = false;
}
static void mdss_dsi_parse_partial_update_caps(struct device_node *np,
struct mdss_dsi_ctrl_pdata *ctrl)
{
struct mdss_panel_info *pinfo;
const char *data;
pinfo = &ctrl->panel_data.panel_info;
data = of_get_property(np, "qcom,partial-update-enabled", NULL);
if (data && !strcmp(data, "single_roi"))
pinfo->partial_update_supported =
PU_SINGLE_ROI;
else if (data && !strcmp(data, "dual_roi"))
pinfo->partial_update_supported =
PU_DUAL_ROI;
else if (data && !strcmp(data, "none"))
pinfo->partial_update_supported =
PU_NOT_SUPPORTED;
else
pinfo->partial_update_supported =
PU_NOT_SUPPORTED;
if (pinfo->mipi.mode == DSI_CMD_MODE) {
pinfo->partial_update_enabled = pinfo->partial_update_supported;
pr_info("%s: partial_update_enabled=%d\n", __func__,
pinfo->partial_update_enabled);
ctrl->set_col_page_addr = mdss_dsi_set_col_page_addr;
if (pinfo->partial_update_enabled) {
pinfo->partial_update_roi_merge =
of_property_read_bool(np,
"qcom,partial-update-roi-merge");
}
}
}
static int mdss_dsi_parse_panel_features(struct device_node *np,
struct mdss_dsi_ctrl_pdata *ctrl)
{
@ -1849,19 +1940,7 @@ static int mdss_dsi_parse_panel_features(struct device_node *np,
pinfo = &ctrl->panel_data.panel_info;
pinfo->partial_update_supported = of_property_read_bool(np,
"qcom,partial-update-enabled");
if (pinfo->mipi.mode == DSI_CMD_MODE) {
pinfo->partial_update_enabled = pinfo->partial_update_supported;
pr_info("%s: partial_update_enabled=%d\n", __func__,
pinfo->partial_update_enabled);
ctrl->set_col_page_addr = mdss_dsi_set_col_page_addr;
if (pinfo->partial_update_enabled) {
pinfo->partial_update_roi_merge =
of_property_read_bool(np,
"qcom,partial-update-roi-merge");
}
}
mdss_dsi_parse_partial_update_caps(np, ctrl);
pinfo->dcs_cmd_by_left = of_property_read_bool(np,
"qcom,dcs-cmd-by-left");

View file

@ -137,6 +137,25 @@ enum {
SIM_HW_TE_MODE,
};
/*
* enum partial_update_mode - Different modes for partial update feature
*
* @PU_NOT_SUPPORTED: Feature is not supported on target.
* @PU_SINGLE_ROI: Default mode, only one ROI is triggered to the
* panel(one on each DSI in case of split dsi)
* @PU_DUAL_ROI: Support for sending two roi's that are clubbed
* together as one big single ROI. This is only
* supported on certain panels that have this
* capability in their DDIC.
*
*/
enum {
PU_NOT_SUPPORTED = 0,
PU_SINGLE_ROI,
PU_DUAL_ROI,
};
struct mdss_rect {
u16 x;
u16 y;
@ -664,6 +683,50 @@ struct mdss_panel_roi_alignment {
u32 min_height;
};
/*
* Nomeclature used to represent partial ROI in case of
* dual roi when the panel supports it. Region marked (XXX) is
* the extended roi to align with the second roi since LM output
* has to be rectangle.
*
* For single ROI, only the first ROI will be used in the struct.
* DSI driver will merge it based on the partial_update_roi_merge
* property.
*
* -------------------------------
* | DSI0 | DSI1 |
* -------------------------------
* | | |
* | | |
* | =========|=======----+ |
* | | | |XXXX| |
* | | First| Roi |XXXX| |
* | | | |XXXX| |
* | =========|=======----+ |
* | | |
* | | |
* | | |
* | +----================= |
* | |XXXX| | | |
* | |XXXX| Second Roi | |
* | |XXXX| | | |
* | +----====|============ |
* | | |
* | | |
* | | |
* | | |
* | | |
* ------------------------------
*
*/
struct mdss_dsi_dual_pu_roi {
struct mdss_rect first_roi;
struct mdss_rect second_roi;
bool enabled;
};
struct mdss_panel_info {
u32 xres;
u32 yres;
@ -689,6 +752,7 @@ struct mdss_panel_info {
u32 vic; /* video identification code */
u32 deep_color;
struct mdss_rect roi;
struct mdss_dsi_dual_pu_roi dual_roi;
int pwm_pmic_gpio;
int pwm_lpg_chan;
int pwm_period;
@ -723,8 +787,8 @@ struct mdss_panel_info {
u32 cont_splash_enabled;
bool esd_rdy;
bool partial_update_supported; /* value from dts if pu is supported */
bool partial_update_enabled; /* is pu currently allowed */
u32 partial_update_supported; /* value from dts if pu is supported */
u32 partial_update_enabled; /* is pu currently allowed */
u32 dcs_cmd_by_left;
u32 partial_update_roi_merge;
struct ion_handle *splash_ihdl;