summaryrefslogtreecommitdiff
path: root/drivers/video/fbdev
diff options
context:
space:
mode:
authordianlujitao <dianlujitao@lineageos.org>2018-01-28 22:44:39 +0800
committerMichael Bestas <mkbestas@gmail.com>2020-04-18 04:02:31 +0300
commit0829dbf732e158cf6b5b5a6699aa6178282664af (patch)
tree48a63a77f43658f90cc4f8b7877ea032383476d8 /drivers/video/fbdev
parent39825fd47718456a91767000531f76144496c8e7 (diff)
mdss: livedisplay: Allow independent CABC command
* The current CABC/SRE/ACO command is OR'd together from CABC off command and a mode mask. However, on some modern panels, the commands are more complex and can't be simply calculated. Add DT fields to store independent CABC command without runtime calculation. * Try the simple unified CABC commands first, and use the independent one as fallback. Change-Id: I6dcf2db9586d309f3181539bbd6031f5fd0949a7
Diffstat (limited to 'drivers/video/fbdev')
-rw-r--r--drivers/video/fbdev/msm/mdss_livedisplay.c63
-rw-r--r--drivers/video/fbdev/msm/mdss_livedisplay.h7
2 files changed, 58 insertions, 12 deletions
diff --git a/drivers/video/fbdev/msm/mdss_livedisplay.c b/drivers/video/fbdev/msm/mdss_livedisplay.c
index 90d18572166e..32f010b6b64a 100644
--- a/drivers/video/fbdev/msm/mdss_livedisplay.c
+++ b/drivers/video/fbdev/msm/mdss_livedisplay.c
@@ -166,12 +166,22 @@ int mdss_livedisplay_update(struct mdss_dsi_ctrl_pdata *ctrl_pdata,
// The CABC command on most modern panels is also responsible for
// other features such as SRE and ACO. The register fields are bits
// and are OR'd together and sent in a single DSI command.
- if (mlc->cabc_level == CABC_UI)
- cabc_value |= mlc->cabc_ui_value;
- else if (mlc->cabc_level == CABC_IMAGE)
- cabc_value |= mlc->cabc_image_value;
- else if (mlc->cabc_level == CABC_VIDEO)
- cabc_value |= mlc->cabc_video_value;
+ if (mlc->cabc_level == CABC_UI) {
+ if (mlc->unified_cabc_cmds)
+ cabc_value |= mlc->cabc_ui_value;
+ else
+ len += mlc->cabc_ui_cmds_len;
+ } else if (mlc->cabc_level == CABC_IMAGE) {
+ if (mlc->unified_cabc_cmds)
+ cabc_value |= mlc->cabc_image_value;
+ else
+ len += mlc->cabc_image_cmds_len;
+ } else if (mlc->cabc_level == CABC_VIDEO) {
+ if (mlc->unified_cabc_cmds)
+ cabc_value |= mlc->cabc_video_value;
+ else
+ len += mlc->cabc_video_cmds_len;
+ }
if (mlc->sre_level == SRE_WEAK)
cabc_value |= mlc->sre_weak_value;
@@ -183,9 +193,10 @@ int mdss_livedisplay_update(struct mdss_dsi_ctrl_pdata *ctrl_pdata,
if (mlc->aco_enabled)
cabc_value |= mlc->aco_value;
- len += mlc->cabc_cmds_len;
+ if (cabc_value || mlc->cabc_level == CABC_OFF)
+ len += mlc->cabc_cmds_len;
- pr_info("%s cabc=%d sre=%d aco=%d cmd=%d\n", __func__,
+ pr_debug("%s cabc=%d sre=%d aco=%d cmd=%d\n", __func__,
mlc->cabc_level, mlc->sre_level, mlc->aco_enabled,
cabc_value);
}
@@ -230,10 +241,25 @@ int mdss_livedisplay_update(struct mdss_dsi_ctrl_pdata *ctrl_pdata,
// CABC/SRE/ACO features
if (is_cabc_cmd(types) && mlc->cabc_cmds_len) {
- memcpy(cmd_buf + dlen, mlc->cabc_cmds, mlc->cabc_cmds_len);
- dlen += mlc->cabc_cmds_len;
- // The CABC command parameter is the last value in the sequence
- cmd_buf[dlen - 1] = cabc_value;
+ if (cabc_value || mlc->cabc_level == CABC_OFF) {
+ memcpy(cmd_buf + dlen, mlc->cabc_cmds, mlc->cabc_cmds_len);
+ dlen += mlc->cabc_cmds_len;
+ // The CABC command parameter is the last value in the sequence
+ cmd_buf[dlen - 1] = cabc_value;
+ }
+
+ if (!mlc->unified_cabc_cmds) {
+ if (mlc->cabc_level == CABC_UI && mlc->cabc_ui_cmds_len) {
+ memcpy(cmd_buf + dlen, mlc->cabc_ui_cmds, mlc->cabc_ui_cmds_len);
+ dlen += mlc->cabc_ui_cmds_len;
+ } else if (mlc->cabc_level == CABC_IMAGE && mlc->cabc_image_cmds_len) {
+ memcpy(cmd_buf + dlen, mlc->cabc_image_cmds, mlc->cabc_image_cmds_len);
+ dlen += mlc->cabc_image_cmds_len;
+ } else if (mlc->cabc_level == CABC_VIDEO && mlc->cabc_video_cmds_len) {
+ memcpy(cmd_buf + dlen, mlc->cabc_video_cmds, mlc->cabc_video_cmds_len);
+ dlen += mlc->cabc_video_cmds_len;
+ }
+ }
}
// And the post_cmd, can be used to turn on the panel
@@ -496,12 +522,25 @@ int mdss_livedisplay_parse_dt(struct device_node *np, struct mdss_panel_info *pi
if (mlc->cabc_cmds_len > 0) {
rc = of_property_read_u32(np, "cm,mdss-livedisplay-cabc-ui-value", &tmp);
if (rc == 0) {
+ // Read unified CABC cmds first
mlc->caps |= MODE_CABC;
+ mlc->unified_cabc_cmds = true;
mlc->cabc_ui_value = (uint8_t)(tmp & 0xFF);
of_property_read_u32(np, "cm,mdss-livedisplay-cabc-image-value", &tmp);
mlc->cabc_image_value = (uint8_t)(tmp & 0xFF);
of_property_read_u32(np, "cm,mdss-livedisplay-cabc-video-value", &tmp);
mlc->cabc_video_value = (uint8_t)(tmp & 0xFF);
+ } else {
+ // If unified CABC cmds don't exist, try independent cmds
+ mlc->cabc_ui_cmds = of_get_property(np,
+ "cm,mdss-livedisplay-cabc-ui-cmd", &mlc->cabc_ui_cmds_len);
+ if (mlc->cabc_ui_cmds_len > 0) {
+ mlc->caps |= MODE_CABC;
+ mlc->cabc_image_cmds = of_get_property(np,
+ "cm,mdss-livedisplay-cabc-image-cmd", &mlc->cabc_image_cmds_len);
+ mlc->cabc_video_cmds = of_get_property(np,
+ "cm,mdss-livedisplay-cabc-video-cmd", &mlc->cabc_video_cmds_len);
+ }
}
rc = of_property_read_u32(np, "cm,mdss-livedisplay-sre-medium-value", &tmp);
if (rc == 0) {
diff --git a/drivers/video/fbdev/msm/mdss_livedisplay.h b/drivers/video/fbdev/msm/mdss_livedisplay.h
index 099ebe20daf5..58b4f9f6a866 100644
--- a/drivers/video/fbdev/msm/mdss_livedisplay.h
+++ b/drivers/video/fbdev/msm/mdss_livedisplay.h
@@ -45,7 +45,14 @@ struct mdss_livedisplay_ctx {
unsigned int presets_len[MAX_PRESETS];
const uint8_t *cabc_cmds;
+ const uint8_t *cabc_ui_cmds;
+ const uint8_t *cabc_image_cmds;
+ const uint8_t *cabc_video_cmds;
unsigned int cabc_cmds_len;
+ unsigned int cabc_ui_cmds_len;
+ unsigned int cabc_image_cmds_len;
+ unsigned int cabc_video_cmds_len;
+ bool unified_cabc_cmds;
const uint8_t *post_cmds;
unsigned int post_cmds_len;