techpack: display: Implement doze mode
This commit is contained in:
parent
f470e80bdf
commit
b87a34af2c
@ -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,
|
||||
|
@ -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) {
|
||||
|
@ -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_ */
|
||||
|
Loading…
Reference in New Issue
Block a user