diff options
author | dianlujitao <dianlujitao@lineageos.org> | 2018-01-28 22:44:39 +0800 |
---|---|---|
committer | Michael Bestas <mkbestas@gmail.com> | 2020-04-18 04:02:31 +0300 |
commit | 0829dbf732e158cf6b5b5a6699aa6178282664af (patch) | |
tree | 48a63a77f43658f90cc4f8b7877ea032383476d8 /drivers/video/fbdev | |
parent | 39825fd47718456a91767000531f76144496c8e7 (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.c | 63 | ||||
-rw-r--r-- | drivers/video/fbdev/msm/mdss_livedisplay.h | 7 |
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; |