From 73f16f7298019e9f296e6f943c0d2b44090fd9f4 Mon Sep 17 00:00:00 2001 From: tanhua1 Date: Wed, 30 Mar 2022 10:43:18 +0800 Subject: [PATCH] display: support local hbm alpha configuration of panel The configuration of the mask aplha of the local hbm is based on the DBV level to ensure that the brightness of local hbm on or off is consistent. Change-Id: I68a7a233a27549db0582a6f07d7a421ed400f3d2 Signed-off-by: tanhua1 Reviewed-on: https://gerrit.mot.com/2238455 SME-Granted: SME Approvals Granted SLTApproved: Slta Waiver Tested-by: Jira Key Submit-Approved: Jira Key --- msm/dsi/dsi_panel.c | 158 +++++++++++++++++++++++++++++++++++++++++++- msm/dsi/dsi_panel.h | 10 +++ 2 files changed, 167 insertions(+), 1 deletion(-) diff --git a/msm/dsi/dsi_panel.c b/msm/dsi/dsi_panel.c index d871ba0d5bcd..dcb08e054124 100644 --- a/msm/dsi/dsi_panel.c +++ b/msm/dsi/dsi_panel.c @@ -885,6 +885,11 @@ int dsi_panel_set_backlight(struct dsi_panel *panel, u32 bl_lvl) if (dsi_panel_set_hbm_backlight(panel, &bl_lvl)) return 0; + if(panel->lhbm_config.enable) { + panel->lhbm_config.dbv_level = bl_lvl; + DSI_INFO("backlight type:%d dbv lvl:%d\n", bl->type, bl_lvl); + } + DSI_DEBUG("backlight type:%d lvl:%d\n", bl->type, bl_lvl); switch (bl->type) { case DSI_BACKLIGHT_WLED: @@ -1054,10 +1059,89 @@ end: return rc; }; +static int dsi_panel_set_local_hbm_param(struct dsi_panel *panel, + struct msm_param_info *param_info, + struct dsi_panel_lhbm_config *lhbm_config) +{ + int rc = 0, count = 0, i; + int alpha = 0; + u8 *payload; + struct panel_param_val_map *param_map; + struct panel_param_val_map *param_map_state; + struct panel_param *panel_param; + struct dsi_cmd_desc *cmds; + + + panel_param = &panel->param_cmds[param_info->param_idx]; + if (!panel_param) { + DSI_ERR("%s: invalid panel_param.\n", __func__); + return -EINVAL; + } + + param_map = panel_param->val_map; + + mutex_lock(&panel->panel_lock); + + if (param_info->value >= panel_param->val_max) + param_info->value = panel_param->val_max - 1; + + if (panel_param->value == param_info->value) + { + rc = 0; + goto end; + } else { + param_map = panel->param_cmds[param_info->param_idx].val_map; + param_map_state = ¶m_map[param_info->value]; + if (!param_map_state->cmds || !param_map_state->cmds->cmds) { + DSI_ERR("Invalid cmds or cmds->cmds\n"); + rc = -EINVAL; + goto end; + } + + cmds = param_map_state->cmds->cmds; + count = param_map_state->cmds->count; + + for (i =0; i < count; i++) { + payload = (u8 *)cmds->msg.tx_buf; + if(param_info->value == HBM_FOD_ON_STATE && + payload[0] == lhbm_config->alpha_reg) { + if(lhbm_config->dbv_level >lhbm_config->alpha_size) { + DSI_ERR("unsupport dbv level %d on local hbm\n", lhbm_config->dbv_level); + rc = -EINVAL; + goto end; + } + + alpha = lhbm_config->alpha[lhbm_config->dbv_level]; + payload[1] = (alpha&0xff00)>>8; + payload[2] = alpha&0xff; + DSI_INFO("%s: alpha [%x]=%x%x\n", + __func__, payload[0], payload[1], payload[2]); + rc = 0; + goto end; + } else if(param_info->value == HBM_OFF_STATE && + payload[0] == 0x51) { + payload[1] = (lhbm_config->dbv_level&0xff00)>>8; + payload[2] = lhbm_config->dbv_level&0xff; + DSI_INFO("%s: restore backlight level=%d\n", + __func__, lhbm_config->dbv_level); + rc = 0; + goto end; + } + cmds++; + } + } + +end: + mutex_unlock(&panel->panel_lock); + return rc; +}; + static int dsi_panel_set_hbm(struct dsi_panel *panel, struct msm_param_info *param_info) { int rc = 0; + u32 bl_lvl; + struct dsi_panel_lhbm_config *lhbm_config = &panel->lhbm_config; pr_info("Set HBM to (%d)\n", param_info->value); @@ -1084,11 +1168,19 @@ static int dsi_panel_set_hbm(struct dsi_panel *panel, rc = -EINVAL; } } else { + if(lhbm_config->enable && param_info->value != HBM_ON_STATE) { + dsi_panel_set_local_hbm_param(panel, param_info, lhbm_config); + } + 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); } else { - rc = dsi_panel_set_backlight(panel, HBM_BRIGHTNESS(param_info->value)); + if(lhbm_config->enable) + bl_lvl = lhbm_config->dbv_level; + else + bl_lvl = HBM_BRIGHTNESS(param_info->value); + rc = dsi_panel_set_backlight(panel, bl_lvl); if (rc) DSI_ERR("unable to set backlight\n"); } @@ -4085,6 +4177,66 @@ error: return rc; } +static int dsi_panel_parse_local_hbm_config(struct dsi_panel *panel) +{ + int rc = 0; + u32 size; + struct dsi_panel_lhbm_config *lhbm_config; + struct dsi_parser_utils *utils = &panel->utils; + + lhbm_config = &panel->lhbm_config; + lhbm_config->enable = utils->read_bool(utils->data, + "qcom,mdss-dsi-panel-local-hbm-enabled"); + + if (lhbm_config->enable) { + rc = utils->read_u32(utils->data, + "qcom,mdss-dsi-panel-local-hbm-alpha-size", + &(lhbm_config->alpha_size)); + if (rc) { + DSI_ERR("%s:%d, Unable to read local hbm alpha size, rc:%u\n", + __func__, __LINE__, rc); + lhbm_config->enable = false; + return rc; + } + + size = lhbm_config->alpha_size * sizeof(u32); + + lhbm_config->alpha = kzalloc(size, GFP_KERNEL); + if (!lhbm_config->alpha) { + rc = -ENOMEM; + DSI_ERR("%s:%d, no memory for local hbm alpha table, rc:%u\n", + __func__, __LINE__, rc); + lhbm_config->enable = false; + return rc; + } + + rc = utils->read_u32_array(utils->data, + "qcom,mdss-dsi-panel-local-hbm-alpha-table", + lhbm_config->alpha, + lhbm_config->alpha_size); + if (rc) { + DSI_ERR("%s:%d, Unable to read local hbm alpha table,rc:%u\n", + __func__, __LINE__, rc); + lhbm_config->enable = false; + return rc; + } + + rc = utils->read_u32(utils->data, + "qcom,mdss-dsi-panel-local-hbm-alpha-register", + &(lhbm_config->alpha_reg)); + if (rc) { + DSI_ERR("%s:%d, Unable to read local hbm register, rc:%u\n", + __func__, __LINE__, rc); + lhbm_config->enable = false; + return rc; + } + } else { + DSI_INFO("%s:%d, no local hbm config\n", + __func__, __LINE__); + } + return 0; +} + static void dsi_panel_update_util(struct dsi_panel *panel, struct device_node *parser_node) { @@ -4446,6 +4598,10 @@ struct dsi_panel *dsi_panel_get(struct device *parent, if (rc) DSI_DEBUG("failed to parse esd config, rc=%d\n", rc); + rc = dsi_panel_parse_local_hbm_config(panel); + if (rc) + DSI_DEBUG("failed to parse local hbm config, rc=%d\n", rc); + rc = dsi_panel_vreg_get(panel); if (rc) { DSI_ERR("[%s] failed to get panel regulators, rc=%d\n", diff --git a/msm/dsi/dsi_panel.h b/msm/dsi/dsi_panel.h index e98564ed5321..26066cd5ca80 100644 --- a/msm/dsi/dsi_panel.h +++ b/msm/dsi/dsi_panel.h @@ -223,6 +223,14 @@ struct dsi_panel_spr_info { enum msm_display_spr_pack_type pack_type; }; +struct dsi_panel_lhbm_config { + bool enable; + u32 dbv_level; + u32 alpha_reg; + u32 alpha_size; + u32 *alpha; +}; + enum panel_idx { MAIN_IDX = 0, SEC_INX, @@ -327,6 +335,8 @@ struct dsi_panel { struct drm_panel_hdr_properties hdr_props; struct drm_panel_esd_config esd_config; + struct dsi_panel_lhbm_config lhbm_config; + struct dsi_parser_utils utils; bool lp11_init;