From d67e46e138eb9e61359cd90b92786417152d8dea Mon Sep 17 00:00:00 2001 From: tinno64 Date: Mon, 22 May 2023 17:01:04 +0800 Subject: [PATCH] gpu/msm: check fps value before enable lhbm Don't allow lhbm enable under specific fps, such 48hz. If enable lhbm when fps is 48hz, screen will flicker due to hardware limitation. So check fps value before enable lhbm. refer to https://gerrit.mot.com/#/c/2383010/ Change-Id: I0c9b6bc3a42c7eb83c0df73c9453892098e9c0cf Signed-off-by: tinno64 Reviewed-on: https://gerrit.mot.com/2616578 SME-Granted: SME Approvals Granted SLTApproved: Slta Waiver Tested-by: Jira Key Reviewed-by: Xiangpo Zhao Submit-Approved: Jira Key --- msm/dsi/dsi_panel.c | 75 +++++++++++++++++++++++++++++++++++++++++++++ msm/dsi/dsi_panel.h | 5 +++ 2 files changed, 80 insertions(+) diff --git a/msm/dsi/dsi_panel.c b/msm/dsi/dsi_panel.c index c4cc9a4f50f3..cb547af2b512 100644 --- a/msm/dsi/dsi_panel.c +++ b/msm/dsi/dsi_panel.c @@ -1241,6 +1241,48 @@ end: return rc; }; +static bool dsi_panel_lhbm_not_allowed_list(struct dsi_panel *panel) +{ + int i; + + for (i = 0; i < panel->lhbm_config.lhbm_not_allowed_fps_list_len; i++) { + if (panel->lhbm_config.lhbm_not_allowed_fps_list[i] == + panel->cur_mode->timing.refresh_rate) + return true; + } + + return false; +} + +static int dsi_panel_lhbm_waitfor_fps_valid(struct dsi_panel *panel) +{ + u32 count = 30; + u32 poll_interval = 1; + + count = panel->lhbm_config.lhbm_wait_for_fps_count; + if (count == 0) + return 0; + + if (panel->lhbm_config.lhbm_wait_for_fps_interval) + poll_interval = panel->lhbm_config.lhbm_wait_for_fps_interval; + + pr_info("%s count %d, interval %d\n", __func__, count, poll_interval); + while(dsi_panel_lhbm_not_allowed_list(panel)) { + if (!count) { + pr_warn("%s: it is timeout, and current_fps = %d\n", __func__, + panel->cur_mode->timing.refresh_rate); + break; + } else if (count > poll_interval) { + usleep_range(poll_interval * 1000, poll_interval *1000); + count -= poll_interval; + } else { + usleep_range(count * 1000, count *1000); + count = 0; + } + } + return 0; +} + static int dsi_panel_set_hbm(struct dsi_panel *panel, struct msm_param_info *param_info) { @@ -1277,6 +1319,9 @@ static int dsi_panel_set_hbm(struct dsi_panel *panel, dsi_panel_set_local_hbm_param(panel, param_info, lhbm_config); } + if (panel->lhbm_config.lhbm_wait_for_fps_valid && param_info->value == HBM_FOD_ON_STATE) + dsi_panel_lhbm_waitfor_fps_valid(panel); + rc = dsi_panel_send_param_cmd(panel, param_info); if (rc < 0) { DSI_ERR("%s: failed to send param cmds. ret=%d\n", __func__, rc); @@ -4416,6 +4461,36 @@ static int dsi_panel_parse_local_hbm_config(struct dsi_panel *panel) lhbm_config->resend_lbhm_off = utils->read_bool(utils->data, "qcom,mdss-dsi-panel-resend-local-hbm-off"); + + lhbm_config->lhbm_wait_for_fps_valid = utils->read_bool(utils->data, + "qcom,mdss-dsi-panel-lhbm-wait-fps-valid"); + + utils->read_u32(utils->data, + "qcom,mdss-dsi-panel-local-hbm-wait-fps-count", + &(lhbm_config->lhbm_wait_for_fps_count)); + + utils->read_u32(utils->data, + "qcom,mdss-dsi-panel-local-hbm-wait-fps-interval", + &(lhbm_config->lhbm_wait_for_fps_interval)); + + lhbm_config->lhbm_not_allowed_fps_list_len = utils->count_u32_elems(utils->data, + "qcom,mdss-dsi-panel-lhbm-not-allowed-fps-list"); + if (lhbm_config->lhbm_not_allowed_fps_list_len >= 1) { + lhbm_config->lhbm_not_allowed_fps_list = kcalloc(lhbm_config->lhbm_not_allowed_fps_list_len, + sizeof(u32), GFP_KERNEL); + if (!lhbm_config->lhbm_not_allowed_fps_list ) + return -ENOMEM; + + rc = utils->read_u32_array(utils->data, + "qcom,mdss-dsi-panel-lhbm-not-allowed-fps-list", + lhbm_config->lhbm_not_allowed_fps_list, + lhbm_config->lhbm_not_allowed_fps_list_len); + if (rc) { + DSI_ERR("[%s] lhbm not allowed fps list parse failed\n", panel->name); + return -EINVAL; + } + } + } else { DSI_INFO("%s:%d, no local hbm config\n", __func__, __LINE__); diff --git a/msm/dsi/dsi_panel.h b/msm/dsi/dsi_panel.h index cea0cc403c7c..802cf867df4c 100644 --- a/msm/dsi/dsi_panel.h +++ b/msm/dsi/dsi_panel.h @@ -243,6 +243,11 @@ struct dsi_panel_lhbm_config { u32 alpha_reg; u32 alpha_size; u32 *alpha; + bool lhbm_wait_for_fps_valid; + u32 lhbm_wait_for_fps_count; + u32 lhbm_wait_for_fps_interval; + u32 *lhbm_not_allowed_fps_list; + u32 lhbm_not_allowed_fps_list_len; }; enum panel_idx {