Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

dsi_panel: use Low power mode 1 with AOD #5

Closed
wants to merge 2 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
12 changes: 7 additions & 5 deletions drivers/gpu/drm/msm/dsi-staging/dsi_defs.h
Original file line number Diff line number Diff line change
Expand Up @@ -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
};

Expand Down
117 changes: 117 additions & 0 deletions drivers/gpu/drm/msm/dsi-staging/dsi_display.c
Original file line number Diff line number Diff line change
Expand Up @@ -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)
{
Expand Down Expand Up @@ -5095,13 +5202,23 @@ 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);

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,
Expand Down
92 changes: 90 additions & 2 deletions drivers/gpu/drm/msm/dsi-staging/dsi_panel.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
}
Expand Down Expand Up @@ -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_LP1);
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;
Expand All @@ -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)
Expand Down Expand Up @@ -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",
Expand Down Expand Up @@ -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",
Expand Down Expand Up @@ -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);
Expand Down Expand Up @@ -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);
Expand Down Expand Up @@ -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;
Expand All @@ -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;
Expand Down Expand Up @@ -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;
Expand All @@ -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) {
Expand Down Expand Up @@ -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;
Expand Down
11 changes: 11 additions & 0 deletions drivers/gpu/drm/msm/dsi-staging/dsi_panel.h
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down Expand Up @@ -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;

Expand Down Expand Up @@ -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);
Expand Down