diff --git a/drivers/gpu/drm/drm_sysfs.c b/drivers/gpu/drm/drm_sysfs.c index 4799d8c13445..b67531e02011 100644 --- a/drivers/gpu/drm/drm_sysfs.c +++ b/drivers/gpu/drm/drm_sysfs.c @@ -260,6 +260,11 @@ static ssize_t panel_info_show(struct device *device, return written; } +int dsi_bridge_disp_set_doze_backlight(struct drm_connector *connector, + int doze_backlight); +ssize_t dsi_bridge_disp_get_doze_backlight(struct drm_connector *connector, + char *buf); + static ssize_t doze_brightness_show(struct device *device, struct device_attribute *attr, char *buf) @@ -271,6 +276,30 @@ static ssize_t doze_brightness_show(struct device *device, dev->doze_brightness); } +static ssize_t doze_backlight_store(struct device *device, + struct device_attribute *attr, + const char *buf, size_t count) +{ + struct drm_connector *connector = to_drm_connector(device); + int doze_backlight; + int ret; + + ret = kstrtoint(buf, 0, &doze_backlight); + if (ret) + return ret; + + ret = dsi_bridge_disp_set_doze_backlight(connector, doze_backlight); + + return ret ? ret : count; +} + +static ssize_t doze_backlight_show(struct device *dev, + struct device_attribute *attr, char *buf) +{ + struct drm_connector *connector = to_drm_connector(dev); + return dsi_bridge_disp_get_doze_backlight(connector, buf); +} + void drm_bridge_disp_param_set(struct drm_bridge *bridge, int cmd); static ssize_t disp_param_store(struct device *device, struct device_attribute *attr, @@ -458,6 +487,7 @@ static DEVICE_ATTR_RO(modes); static DEVICE_ATTR_RO(panel_info); static DEVICE_ATTR_WO(disp_param); static DEVICE_ATTR_RO(doze_brightness); +static DEVICE_ATTR_RW(doze_backlight); static DEVICE_ATTR_RW(mipi_reg); static DEVICE_ATTR_RW(disp_count); static DEVICE_ATTR_RW(dim_layer_enable); @@ -473,6 +503,7 @@ static struct attribute *connector_dev_attrs[] = { &dev_attr_panel_info.attr, &dev_attr_disp_param.attr, &dev_attr_doze_brightness.attr, + &dev_attr_doze_backlight.attr, &dev_attr_mipi_reg.attr, &dev_attr_disp_count.attr, &dev_attr_dim_layer_enable.attr, diff --git a/drivers/gpu/drm/msm/dsi-staging/dsi_display.c b/drivers/gpu/drm/msm/dsi-staging/dsi_display.c index 91198970d344..79b4230db8f3 100644 --- a/drivers/gpu/drm/msm/dsi-staging/dsi_display.c +++ b/drivers/gpu/drm/msm/dsi-staging/dsi_display.c @@ -236,19 +236,10 @@ int dsi_display_set_backlight(struct drm_connector *connector, goto error; } - if (drm_dev && (drm_dev->doze_state == MSM_DRM_BLANK_LP1 || drm_dev->doze_state == MSM_DRM_BLANK_LP2)) { - rc = dsi_panel_set_doze_backlight(display, (u32)bl_temp); - if (rc) - pr_err("unable to set doze backlight\n"); - rc = dsi_panel_enable_doze_backlight(panel, (u32)bl_temp); - if (rc) - pr_err("unable to enable doze backlight\n"); - } else { - drm_dev->doze_brightness = DOZE_BRIGHTNESS_INVALID; - rc = dsi_panel_set_backlight(panel, (u32)bl_temp); - if (rc) - pr_err("unable to set backlight\n"); - } + rc = dsi_panel_set_backlight(panel, (u32)bl_temp); + if (rc) + pr_err("unable to set backlight\n"); + rc = dsi_display_clk_ctrl(dsi_display->dsi_clk_handle, DSI_CORE_CLK, DSI_CLK_OFF); if (rc) { @@ -1277,6 +1268,8 @@ int dsi_display_set_power(struct drm_connector *connector, case SDE_MODE_DPMS_LP1: msm_drm_notifier_call_chain(MSM_DRM_EARLY_EVENT_BLANK, &g_notify_data); rc = dsi_panel_set_lp1(display->panel); + if (!rc) + dsi_panel_set_doze_backlight(display); msm_drm_notifier_call_chain(MSM_DRM_EVENT_BLANK, &g_notify_data); break; case SDE_MODE_DPMS_LP2: diff --git a/drivers/gpu/drm/msm/dsi-staging/dsi_display.h b/drivers/gpu/drm/msm/dsi-staging/dsi_display.h index bbc3b41c3bc0..5918445b3a6d 100644 --- a/drivers/gpu/drm/msm/dsi-staging/dsi_display.h +++ b/drivers/gpu/drm/msm/dsi-staging/dsi_display.h @@ -653,7 +653,13 @@ void dsi_display_enable_event(struct drm_connector *connector, int dsi_display_set_backlight(struct drm_connector *connector, void *display, u32 bl_lvl); -int dsi_panel_set_doze_backlight(struct dsi_display *display, u32 bl_lvl); +/** + * dsi_display_set_doze_backlight() - set doze backlight + * @display: Handle to display. + */ +int dsi_panel_set_doze_backlight(struct dsi_display *display); + +ssize_t dsi_panel_get_doze_backlight(struct dsi_display *display, char *buf); /** * dsi_display_check_status() - check if panel is dead or alive diff --git a/drivers/gpu/drm/msm/dsi-staging/dsi_drm.c b/drivers/gpu/drm/msm/dsi-staging/dsi_drm.c index 39e4bed9756f..f6772b4f226e 100644 --- a/drivers/gpu/drm/msm/dsi-staging/dsi_drm.c +++ b/drivers/gpu/drm/msm/dsi-staging/dsi_drm.c @@ -364,6 +364,53 @@ static int dsi_bridge_get_panel_info(struct drm_bridge *bridge, char *buf) return rc; } +int dsi_panel_set_doze_backlight(struct dsi_display *display); + +ssize_t dsi_panel_get_doze_backlight(struct dsi_display *display, char *buf); + +int dsi_bridge_disp_set_doze_backlight(struct drm_connector *connector, + int doze_backlight) +{ + struct dsi_display *display = NULL; + struct dsi_bridge *c_bridge = NULL; + + if (!connector || !connector->encoder || !connector->encoder->bridge) { + pr_err("Invalid connector/encoder/bridge ptr\n"); + return -EINVAL; + } + + c_bridge = to_dsi_bridge(connector->encoder->bridge); + display = c_bridge->display; + if (!display || !display->panel || !display->drm_dev) { + pr_err("Invalid display/panel/drm_dev ptr\n"); + return -EINVAL; + } else + display->drm_dev->doze_brightness = doze_backlight; + + return dsi_panel_set_doze_backlight(display); +} + +ssize_t dsi_bridge_disp_get_doze_backlight(struct drm_connector *connector, + char *buf) +{ + struct dsi_display *display = NULL; + struct dsi_bridge *c_bridge = NULL; + + if (!connector || !connector->encoder || !connector->encoder->bridge) { + pr_err("Invalid connector/encoder/bridge ptr\n"); + return -EINVAL; + } + + c_bridge = to_dsi_bridge(connector->encoder->bridge); + display = c_bridge->display; + if (!display || !display->panel) { + pr_err("Invalid display/panel ptr\n"); + return -EINVAL; + } + + return dsi_panel_get_doze_backlight(display, buf); +} + static void dsi_bridge_enable(struct drm_bridge *bridge) { int rc = 0; diff --git a/drivers/gpu/drm/msm/dsi-staging/dsi_panel.c b/drivers/gpu/drm/msm/dsi-staging/dsi_panel.c index 5c1fbe70c2ed..4c516fe328a6 100644 --- a/drivers/gpu/drm/msm/dsi-staging/dsi_panel.c +++ b/drivers/gpu/drm/msm/dsi-staging/dsi_panel.c @@ -740,62 +740,80 @@ static int dsi_panel_update_pwm_backlight(struct dsi_panel *panel, return rc; } -int dsi_panel_set_doze_backlight(struct dsi_display *display, u32 bl_lvl) +int dsi_panel_set_doze_backlight(struct dsi_display *display) { int rc = 0; + struct dsi_display *dsi_display = display; struct dsi_panel *panel = NULL; struct drm_device *drm_dev = NULL; - if (!display || !display->panel || !display->drm_dev) { + if (!dsi_display || !dsi_display->panel || !dsi_display->drm_dev) { pr_err("invalid display/panel/drm_dev\n"); return -EINVAL; } - panel = display->panel; - drm_dev = display->drm_dev; + panel = dsi_display->panel; + drm_dev = dsi_display->drm_dev; + mutex_lock(&panel->panel_lock); - if (panel->fod_hbm_enabled || panel->fod_backlight_flag || panel->fod_dimlayer_hbm_enabled) { - pr_debug("%s FOD HBM open, skip value:%u [hbm=%d][fod_bl=%d][dimlayer_fod=%d]\n", __func__, - bl_lvl, panel->fod_hbm_enabled, panel->fod_backlight_flag, panel->fod_dimlayer_hbm_enabled); - return rc; + if (!dsi_panel_initialized(panel)) { + pr_info("[%s] set doze backlight before panel initialized!\n", dsi_display->name); + goto error; } - if (bl_lvl > panel->doze_backlight_threshold) { - 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); - drm_dev->doze_brightness = DOZE_BRIGHTNESS_HBM; - panel->in_aod = true; - panel->skip_dimmingon = STATE_DIM_BLOCK; - } else if (bl_lvl <= panel->doze_backlight_threshold && bl_lvl > 0) { - 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); - drm_dev->doze_brightness = DOZE_BRIGHTNESS_LBM; - panel->in_aod = true; - panel->skip_dimmingon = STATE_DIM_BLOCK; - } else { - drm_dev->doze_brightness = DOZE_BRIGHTNESS_INVALID; + if (drm_dev && (drm_dev->doze_state == MSM_DRM_BLANK_LP1 || drm_dev->doze_state == MSM_DRM_BLANK_LP2)) { + if (panel->fod_hbm_enabled || panel->fod_dimlayer_hbm_enabled || panel->fod_backlight_flag) { + pr_debug("%s FOD HBM open, skip set doze backlight at: [hbm=%d][dimlayer_fod=%d][fod_bl=%d]\n", + __func__, panel->fod_hbm_enabled, + panel->fod_dimlayer_hbm_enabled, panel->fod_backlight_flag); + goto error; + } + + if (drm_dev->doze_brightness == DOZE_BRIGHTNESS_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); + panel->in_aod = true; + panel->skip_dimmingon = STATE_DIM_BLOCK; + } else if (drm_dev->doze_brightness == DOZE_BRIGHTNESS_LBM) { + 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); + panel->in_aod = true; + panel->skip_dimmingon = STATE_DIM_BLOCK; + } else { + drm_dev->doze_brightness = DOZE_BRIGHTNESS_INVALID; + pr_debug("In %s the doze_brightness value:%u\n", __func__, drm_dev->doze_brightness); + } } - pr_debug("%s value:%u\n", __func__, drm_dev->doze_brightness); +error: + mutex_unlock(&panel->panel_lock); return rc; } -int dsi_panel_enable_doze_backlight(struct dsi_panel *panel, u32 bl_lvl) +ssize_t dsi_panel_get_doze_backlight(struct dsi_display *display, char *buf) { + int rc = 0; - struct dsi_backlight_config *bl = &panel->bl_config; + struct dsi_display *dsi_display = display; + struct dsi_panel *panel = NULL; + struct drm_device *drm_dev = NULL; - if (panel->fod_backlight_flag) { - pr_debug("fod_backlight_flag set\n"); - } else { - pr_debug("enable doze backlight type:%d lvl:%d\n", bl->type, bl_lvl); - rc = dsi_panel_update_backlight(panel, bl_lvl); + if (!dsi_display || !dsi_display->panel || !dsi_display->drm_dev) { + pr_err("invalid display/panel/drm_dev\n"); + return -EINVAL; } + panel = dsi_display->panel; + drm_dev = dsi_display->drm_dev; + + mutex_lock(&panel->panel_lock); + + rc = snprintf(buf, PAGE_SIZE, "%d\n", drm_dev->doze_brightness); + pr_info("In %s the doze_brightness value:%u\n", __func__, drm_dev->doze_brightness); + + mutex_unlock(&panel->panel_lock); - panel->last_bl_lvl = bl_lvl; 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 16d8f6db26f7..38ca0b7554f3 100644 --- a/drivers/gpu/drm/msm/dsi-staging/dsi_panel.h +++ b/drivers/gpu/drm/msm/dsi-staging/dsi_panel.h @@ -358,8 +358,6 @@ int dsi_panel_post_unprepare(struct dsi_panel *panel); int dsi_panel_set_backlight(struct dsi_panel *panel, u32 bl_lvl); -int dsi_panel_enable_doze_backlight(struct dsi_panel *panel, u32 bl_lvl); - int dsi_panel_update_pps(struct dsi_panel *panel); int dsi_panel_send_qsync_on_dcs(struct dsi_panel *panel,