techpack: display: Implement doze mode

This commit is contained in:
Demon000 2022-05-29 22:47:37 +01:00 committed by spakkkk
parent f470e80bdf
commit b87a34af2c
3 changed files with 186 additions and 0 deletions

View File

@ -5047,6 +5047,121 @@ error:
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 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 ssize_t sysfs_dynamic_dsi_clk_read(struct device *dev,
struct device_attribute *attr, char *buf)
{
@ -5213,6 +5328,8 @@ static DEVICE_ATTR(dimlayer_exposure, 0644,
#endif
static struct attribute *display_fs_attrs[] = {
&dev_attr_doze_status.attr,
&dev_attr_doze_mode.attr,
&dev_attr_fod_ui.attr,
#ifdef CONFIG_DRM_SDE_EXPO
&dev_attr_dimlayer_exposure.attr,

View File

@ -785,6 +785,50 @@ error:
return rc;
}
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_MI_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_MI_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);
}
bool dc_skip_set_backlight(struct dsi_panel *panel, u32 bl_lvl)
{
struct dsi_panel_mi_cfg *mi_cfg = &panel->mi_cfg;
@ -3867,6 +3911,9 @@ struct dsi_panel *dsi_panel_get(struct device *parent,
if (rc)
DSI_DEBUG("failed to parse mi 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);
panel->drm_panel.dev = &panel->mipi_device.dev;
@ -4484,6 +4531,9 @@ int dsi_panel_set_lp1(struct dsi_panel *panel)
DSI_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);
display_utc_time_marker("DSI_CMD_SET_LP1");
@ -4511,6 +4561,9 @@ int dsi_panel_set_lp2(struct dsi_panel *panel)
DSI_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);
display_utc_time_marker("DSI_CMD_SET_LP2");
@ -4554,6 +4607,10 @@ int dsi_panel_set_nolp(struct dsi_panel *panel)
DSI_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");
mi_cfg->dimming_state = STATE_DIM_RESTORE;
if (mi_cfg->dc_type == 0 && mi_cfg->dc_enable) {
@ -5179,6 +5236,7 @@ int dsi_panel_disable(struct dsi_panel *panel)
}
panel->panel_initialized = false;
panel->power_mode = SDE_MODE_DPMS_OFF;
panel->doze_enabled = false;
host = panel->host;
if (host && mi_cfg->fod_hbm_enabled) {

View File

@ -52,6 +52,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,
@ -235,6 +240,9 @@ struct dsi_panel {
int power_mode;
enum dsi_panel_physical_type panel_type;
bool doze_enabled;
enum dsi_doze_mode_type doze_mode;
struct brightness_alpha_pair *fod_dim_lut;
u32 fod_dim_lut_count;
#ifdef CONFIG_DRM_SDE_EXPO
@ -380,4 +388,7 @@ int dsi_panel_set_fod_hbm(struct dsi_panel *panel, bool status);
u32 dsi_panel_get_fod_dim_alpha(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);
#endif /* _DSI_PANEL_H_ */