From edd28fa65d534562a14534f4a91b310ed3f7a536 Mon Sep 17 00:00:00 2001 From: SVB22 Date: Fri, 11 Sep 2020 14:55:30 +0300 Subject: [PATCH 1/2] Revert "Revert "drm: msm: dsi-staging: implement doze mode"" This reverts commit e877a752a5fb7eeaecb26495b24ed3adee706910. --- drivers/gpu/drm/msm/dsi-staging/dsi_defs.h | 12 +- drivers/gpu/drm/msm/dsi-staging/dsi_display.c | 117 ++++++++++++++++++ drivers/gpu/drm/msm/dsi-staging/dsi_panel.c | 92 +++++++++++++- drivers/gpu/drm/msm/dsi-staging/dsi_panel.h | 11 ++ 4 files changed, 225 insertions(+), 7 deletions(-) diff --git a/drivers/gpu/drm/msm/dsi-staging/dsi_defs.h b/drivers/gpu/drm/msm/dsi-staging/dsi_defs.h index 7f4db7be6477..4b41e80d73a0 100644 --- a/drivers/gpu/drm/msm/dsi-staging/dsi_defs.h +++ b/drivers/gpu/drm/msm/dsi-staging/dsi_defs.h @@ -308,11 +308,13 @@ enum dsi_cmd_set_type { DSI_CMD_SET_POST_TIMING_SWITCH, DSI_CMD_SET_QSYNC_ON, DSI_CMD_SET_QSYNC_OFF, - DSI_CMD_SET_DISP_HBM_FOD_ON, - DSI_CMD_SET_DISP_HBM_FOD_OFF, - DSI_CMD_SET_DISP_LCD_HBM_L1_ON, - DSI_CMD_SET_DISP_LCD_HBM_L2_ON, - DSI_CMD_SET_DISP_LCD_HBM_OFF, + DSI_CMD_SET_DOZE_HBM, + DSI_CMD_SET_DOZE_LBM, + DSI_CMD_SET_DISP_HBM_FOD_ON, + DSI_CMD_SET_DISP_HBM_FOD_OFF, + DSI_CMD_SET_DISP_LCD_HBM_L1_ON, + DSI_CMD_SET_DISP_LCD_HBM_L2_ON, + DSI_CMD_SET_DISP_LCD_HBM_OFF, DSI_CMD_SET_MAX }; diff --git a/drivers/gpu/drm/msm/dsi-staging/dsi_display.c b/drivers/gpu/drm/msm/dsi-staging/dsi_display.c index cb2ae027a980..f6e03439b8bb 100644 --- a/drivers/gpu/drm/msm/dsi-staging/dsi_display.c +++ b/drivers/gpu/drm/msm/dsi-staging/dsi_display.c @@ -5022,6 +5022,113 @@ static int dsi_display_validate_split_link(struct dsi_display *display) return rc; } +static ssize_t sysfs_doze_status_read(struct device *dev, + struct device_attribute *attr, char *buf) +{ + struct dsi_display *display; + struct dsi_panel *panel; + bool status; + + display = dev_get_drvdata(dev); + if (!display) { + pr_err("Invalid display\n"); + return -EINVAL; + } + + panel = display->panel; + + mutex_lock(&panel->panel_lock); + status = panel->doze_enabled; + mutex_unlock(&panel->panel_lock); + + return snprintf(buf, PAGE_SIZE, "%d\n", status); +} + +static ssize_t sysfs_doze_status_write(struct device *dev, + struct device_attribute *attr, const char *buf, size_t count) +{ + struct dsi_display *display; + struct dsi_panel *panel; + bool status; + int rc = 0; + + display = dev_get_drvdata(dev); + if (!display) { + pr_err("Invalid display\n"); + return -EINVAL; + } + + rc = kstrtobool(buf, &status); + if (rc) { + pr_err("%s: kstrtobool failed. rc=%d\n", __func__, rc); + return rc; + } + + panel = display->panel; + + mutex_lock(&panel->panel_lock); + dsi_panel_set_doze_status(panel, status); + mutex_unlock(&panel->panel_lock); + + return count; +} + +static ssize_t sysfs_doze_mode_read(struct device *dev, + struct device_attribute *attr, char *buf) +{ + enum dsi_doze_mode_type doze_mode; + struct dsi_display *display; + struct dsi_panel *panel; + + display = dev_get_drvdata(dev); + if (!display) { + pr_err("Invalid display\n"); + return -EINVAL; + } + + panel = display->panel; + + mutex_lock(&panel->panel_lock); + doze_mode = panel->doze_mode; + mutex_unlock(&panel->panel_lock); + + return snprintf(buf, PAGE_SIZE, "%d\n", doze_mode); +} + +static ssize_t sysfs_doze_mode_write(struct device *dev, + struct device_attribute *attr, const char *buf, size_t count) +{ + struct dsi_display *display; + struct dsi_panel *panel; + int rc = 0; + int mode; + + display = dev_get_drvdata(dev); + if (!display) { + pr_err("Invalid display\n"); + return -EINVAL; + } + + rc = kstrtoint(buf, 10, &mode); + if (rc) { + pr_err("%s: kstrtoint failed. rc=%d\n", __func__, rc); + return rc; + } + + if (mode < DSI_DOZE_LPM || mode > DSI_DOZE_HBM) { + pr_err("%s: invalid value for doze mode\n", __func__); + return -EINVAL; + } + + panel = display->panel; + + mutex_lock(&panel->panel_lock); + dsi_panel_set_doze_mode(panel, (enum dsi_doze_mode_type) mode); + mutex_unlock(&panel->panel_lock); + + return count; +} + static ssize_t sysfs_fod_ui_read(struct device *dev, struct device_attribute *attr, char *buf) { @@ -5095,6 +5202,14 @@ static ssize_t sysfs_hbm_write(struct device *dev, return ret == 0 ? count : ret; } +static DEVICE_ATTR(doze_status, 0644, + sysfs_doze_status_read, + sysfs_doze_status_write); + +static DEVICE_ATTR(doze_mode, 0644, + sysfs_doze_mode_read, + sysfs_doze_mode_write); + static DEVICE_ATTR(fod_ui, 0444, sysfs_fod_ui_read, NULL); @@ -5102,6 +5217,8 @@ static DEVICE_ATTR(fod_ui, 0444, static DEVICE_ATTR(hbm, 0644, sysfs_hbm_read, sysfs_hbm_write); static struct attribute *display_fs_attrs[] = { + &dev_attr_doze_status.attr, + &dev_attr_doze_mode.attr, &dev_attr_fod_ui.attr, &dev_attr_hbm.attr, NULL, diff --git a/drivers/gpu/drm/msm/dsi-staging/dsi_panel.c b/drivers/gpu/drm/msm/dsi-staging/dsi_panel.c index 21c670fad758..e3d6fd694b29 100644 --- a/drivers/gpu/drm/msm/dsi-staging/dsi_panel.c +++ b/drivers/gpu/drm/msm/dsi-staging/dsi_panel.c @@ -694,7 +694,12 @@ static u32 dsi_panel_get_backlight(struct dsi_panel *panel) { u32 bl_level; - bl_level = panel->bl_config.bl_level; + if (panel->doze_enabled && panel->doze_mode == DSI_DOZE_HBM) + bl_level = panel->bl_config.bl_doze_hbm; + else if (panel->doze_enabled && panel->doze_mode == DSI_DOZE_LPM) + bl_level = panel->bl_config.bl_doze_lpm; + else if (!panel->doze_enabled) + bl_level = panel->bl_config.bl_level; return bl_level; } @@ -727,6 +732,50 @@ u32 dsi_panel_get_fod_dim_alpha(struct dsi_panel *panel) panel->fod_dim_lut[i - 1].alpha, panel->fod_dim_lut[i].alpha); } +int dsi_panel_update_doze(struct dsi_panel *panel) { + int rc = 0; + + if (panel->doze_enabled && panel->doze_mode == DSI_DOZE_HBM) { + rc = dsi_panel_tx_cmd_set(panel, DSI_CMD_SET_DOZE_HBM); + if (rc) + pr_err("[%s] failed to send DSI_CMD_SET_DOZE_HBM cmd, rc=%d\n", + panel->name, rc); + } else if (panel->doze_enabled && panel->doze_mode == DSI_DOZE_LPM) { + rc = dsi_panel_tx_cmd_set(panel, DSI_CMD_SET_DOZE_LBM); + if (rc) + pr_err("[%s] failed to send DSI_CMD_SET_DOZE_LBM cmd, rc=%d\n", + panel->name, rc); + } else if (!panel->doze_enabled) { + rc = dsi_panel_tx_cmd_set(panel, DSI_CMD_SET_NOLP); + if (rc) + pr_err("[%s] failed to send DSI_CMD_SET_NOLP cmd, rc=%d\n", + panel->name, rc); + } + + return rc; +} + +int dsi_panel_set_doze_status(struct dsi_panel *panel, bool status) { + if (panel->doze_enabled == status) + return 0; + + panel->doze_enabled = status; + + return dsi_panel_update_doze(panel); +} + +int dsi_panel_set_doze_mode(struct dsi_panel *panel, enum dsi_doze_mode_type mode) { + if (panel->doze_mode == mode) + return 0; + + panel->doze_mode = mode; + + if (!panel->doze_enabled) + return 0; + + return dsi_panel_update_doze(panel); +} + int dsi_panel_set_fod_hbm(struct dsi_panel *panel, bool status) { int rc = 0; @@ -742,6 +791,8 @@ int dsi_panel_set_fod_hbm(struct dsi_panel *panel, bool status) if (rc) pr_err("[%s] failed to send DSI_CMD_SET_DISP_HBM_FOD_ON cmd, rc=%d\n", panel->name, rc); + } else if (panel->doze_enabled) { + dsi_panel_update_doze(panel); } else { rc = dsi_panel_tx_cmd_set(panel, DSI_CMD_SET_DISP_HBM_FOD_OFF); if (rc) @@ -1835,6 +1886,8 @@ const char *cmd_set_prop_map[DSI_CMD_SET_MAX] = { "qcom,mdss-dsi-post-mode-switch-on-command", "qcom,mdss-dsi-qsync-on-commands", "qcom,mdss-dsi-qsync-off-commands", + "qcom,mdss-dsi-doze-hbm-command", + "qcom,mdss-dsi-doze-lbm-command", "qcom,mdss-dsi-dispparam-hbm-fod-on-command", "qcom,mdss-dsi-dispparam-hbm-fod-off-command", "qcom,mdss-dsi-dispparam-lcd-hbm-l1-on-command", @@ -1866,6 +1919,8 @@ const char *cmd_set_state_map[DSI_CMD_SET_MAX] = { "qcom,mdss-dsi-post-mode-switch-on-command-state", "qcom,mdss-dsi-qsync-on-commands-state", "qcom,mdss-dsi-qsync-off-commands-state", + "qcom,mdss-dsi-doze-hbm-command-state", + "qcom,mdss-dsi-doze-lbm-command-state", "qcom,mdss-dsi-dispparam-hbm-fod-on-command-state", "qcom,mdss-dsi-dispparam-hbm-fod-off-command-state", "qcom,mdss-dsi-dispparam-lcd-hbm-l1-on-command-state", @@ -2488,6 +2543,24 @@ static int dsi_panel_parse_bl_config(struct dsi_panel *panel) panel->bl_config.brightness_default_level = val; } + rc = utils->read_u32(utils->data, + "qcom,disp-doze-lpm-backlight", &val); + if (rc) { + panel->bl_config.bl_doze_lpm = 0; + pr_debug("set doze lpm backlight to 0\n"); + } else { + panel->bl_config.bl_doze_lpm = val; + } + + rc = utils->read_u32(utils->data, + "qcom,disp-doze-hbm-backlight", &val); + if (rc) { + panel->bl_config.bl_doze_hbm = 0; + pr_debug("set doze hbm backlight to 0\n"); + } else { + panel->bl_config.bl_doze_hbm = val; + } + rc = dsi_panel_parse_fod_dim_lut(panel, utils); if (rc) pr_err("[%s failed to parse fod dim lut\n", panel->name); @@ -3539,6 +3612,9 @@ struct dsi_panel *dsi_panel_get(struct device *parent, if (rc) pr_debug("failed to parse esd config, rc=%d\n", rc); + panel->doze_mode = DSI_DOZE_LPM; + panel->doze_enabled = false; + panel->power_mode = SDE_MODE_DPMS_OFF; drm_panel_init(&panel->drm_panel); mutex_init(&panel->panel_lock); @@ -4089,6 +4165,10 @@ int dsi_panel_set_lp1(struct dsi_panel *panel) if (rc) pr_err("[%s] failed to send DSI_CMD_SET_LP1 cmd, rc=%d\n", panel->name, rc); + + rc = dsi_panel_set_doze_status(panel, true); + if (rc) + pr_err("unable to set doze on\n"); exit: mutex_unlock(&panel->panel_lock); return rc; @@ -4111,6 +4191,10 @@ int dsi_panel_set_lp2(struct dsi_panel *panel) if (rc) pr_err("[%s] failed to send DSI_CMD_SET_LP2 cmd, rc=%d\n", panel->name, rc); + + rc = dsi_panel_set_doze_status(panel, true); + if (rc) + pr_err("unable to set doze on\n"); exit: mutex_unlock(&panel->panel_lock); return rc; @@ -4141,6 +4225,10 @@ int dsi_panel_set_nolp(struct dsi_panel *panel) if (rc) pr_err("[%s] failed to send DSI_CMD_SET_NOLP cmd, rc=%d\n", panel->name, rc); + + rc = dsi_panel_set_doze_status(panel, false); + if (rc) + pr_err("unable to set doze on\n"); exit: mutex_unlock(&panel->panel_lock); return rc; @@ -4154,7 +4242,6 @@ int dsi_panel_prepare(struct dsi_panel *panel) pr_err("invalid params\n"); return -EINVAL; } - mutex_lock(&panel->panel_lock); if (panel->lp11_init) { @@ -4566,6 +4653,7 @@ int dsi_panel_disable(struct dsi_panel *panel) } panel->panel_initialized = false; panel->power_mode = SDE_MODE_DPMS_OFF; + panel->doze_enabled = false; mutex_unlock(&panel->panel_lock); return rc; diff --git a/drivers/gpu/drm/msm/dsi-staging/dsi_panel.h b/drivers/gpu/drm/msm/dsi-staging/dsi_panel.h index 3ed8c3a8b420..10bdd76c2d10 100644 --- a/drivers/gpu/drm/msm/dsi-staging/dsi_panel.h +++ b/drivers/gpu/drm/msm/dsi-staging/dsi_panel.h @@ -53,6 +53,11 @@ enum dsi_backlight_type { DSI_BACKLIGHT_MAX, }; +enum dsi_doze_mode_type { + DSI_DOZE_LPM = 0, + DSI_DOZE_HBM, +}; + enum bl_update_flag { BL_UPDATE_DELAY_UNTIL_FIRST_FRAME, BL_UPDATE_NONE, @@ -232,6 +237,8 @@ struct dsi_panel { int power_mode; enum dsi_panel_physical_type panel_type; + bool doze_enabled; + enum dsi_doze_mode_type doze_mode; bool resend_ea; bool resend_ea_hbm; @@ -357,6 +364,10 @@ int dsi_panel_parse_esd_reg_read_configs(struct dsi_panel *panel); void dsi_panel_ext_bridge_put(struct dsi_panel *panel); +int dsi_panel_set_doze_status(struct dsi_panel *panel, bool status); + +int dsi_panel_set_doze_mode(struct dsi_panel *panel, enum dsi_doze_mode_type mode); + int dsi_panel_set_fod_hbm(struct dsi_panel *panel, bool status); u32 dsi_panel_get_fod_dim_alpha(struct dsi_panel *panel); From 56fc0e34f3add7e4ec3d2e5ce443e0199eb09449 Mon Sep 17 00:00:00 2001 From: SVB22 Date: Fri, 11 Sep 2020 15:05:55 +0300 Subject: [PATCH 2/2] dsi_panel: use Low power mode 1 with AOD --- drivers/gpu/drm/msm/dsi-staging/dsi_panel.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/gpu/drm/msm/dsi-staging/dsi_panel.c b/drivers/gpu/drm/msm/dsi-staging/dsi_panel.c index e3d6fd694b29..17d30f3d4ade 100644 --- a/drivers/gpu/drm/msm/dsi-staging/dsi_panel.c +++ b/drivers/gpu/drm/msm/dsi-staging/dsi_panel.c @@ -741,7 +741,7 @@ int dsi_panel_update_doze(struct dsi_panel *panel) { pr_err("[%s] failed to send DSI_CMD_SET_DOZE_HBM cmd, rc=%d\n", panel->name, rc); } else if (panel->doze_enabled && panel->doze_mode == DSI_DOZE_LPM) { - rc = dsi_panel_tx_cmd_set(panel, DSI_CMD_SET_DOZE_LBM); + rc = dsi_panel_tx_cmd_set(panel, DSI_CMD_SET_LP1); if (rc) pr_err("[%s] failed to send DSI_CMD_SET_DOZE_LBM cmd, rc=%d\n", panel->name, rc);