From 228e520fb4e7a8ee321edad60c39f6d261938144 Mon Sep 17 00:00:00 2001 From: Venkata Prahlad Valluru Date: Tue, 13 Jun 2023 12:42:28 +0530 Subject: [PATCH] disp: msm: dp: add backlight for edp Register backlight and cooling devices for eDP interface and reuse connector backlight update functions. Parse and use backlight properties from devicetree. Change-Id: I5d96a8d588d8f7266aa5bffad310718942e7dfe6 Signed-off-by: Venkata Prahlad Valluru --- msm/dp/dp_display.c | 44 +++++++++++++ msm/dp/dp_display.h | 2 + msm/dp/dp_drm.c | 21 ++++++ msm/dp/dp_drm.h | 9 +++ msm/dp/dp_panel.c | 105 ++++++++++++++++++++++++++++++ msm/dp/dp_panel.h | 21 ++++++ msm/dp/dp_parser.c | 42 ++++++++++++ msm/dp/dp_parser.h | 10 ++- msm/sde/sde_connector.c | 140 +++++++++++++++++++++++++++------------- msm/sde/sde_kms.c | 1 + 10 files changed, 350 insertions(+), 45 deletions(-) diff --git a/msm/dp/dp_display.c b/msm/dp/dp_display.c index 11349989c449..f99fd658ec26 100644 --- a/msm/dp/dp_display.c +++ b/msm/dp/dp_display.c @@ -2581,6 +2581,9 @@ static int dp_display_post_enable(struct dp_display *dp_display, void *panel) { struct dp_display_private *dp; struct dp_panel *dp_panel; + struct drm_connector *connector; + struct sde_connector *sde_conn; + struct backlight_device *bl_device; int rc = 0; if (!dp_display || !panel) { @@ -2626,6 +2629,15 @@ static int dp_display_post_enable(struct dp_display *dp_display, void *panel) DP_ERR("Cannot turn edp backlight power on"); goto end; } + connector = dp_display->base_connector; + sde_conn = to_sde_connector(connector); + + sde_conn->allow_bl_update = true; + if (sde_conn->bl_device) { + bl_device = sde_conn->bl_device; + bl_device->props.power = FB_BLANK_UNBLANK; + bl_device->props.state &= ~BL_CORE_FBBLANK; + } } cancel_delayed_work_sync(&dp->hdcp_cb_work); @@ -3283,6 +3295,37 @@ static int dp_display_config_hdr(struct dp_display *dp_display, void *panel, core_clk_rate, flush_hdr); } +static int dp_display_set_backlight(struct dp_display *dp_display, + void *panel, u32 bl_lvl) +{ + struct dp_panel *dp_panel; + struct dp_display_private *dp; + u32 bl_scale, bl_scale_sv; + u64 bl_temp; + + if (!dp_display || !panel) { + DP_ERR("invalid input\n"); + return -EINVAL; + } + + dp = container_of(dp_display, struct dp_display_private, dp_display); + dp_panel = panel; + + dp_panel->bl_config.bl_level = bl_lvl; + + /* scale backlight */ + bl_scale = dp_panel->bl_config.bl_scale; + bl_temp = bl_lvl * bl_scale / MAX_BL_SCALE_LEVEL; + + bl_scale_sv = dp_panel->bl_config.bl_scale_sv; + bl_temp = (u32)bl_temp * bl_scale_sv / MAX_SV_BL_SCALE_LEVEL; + + DP_DEBUG("bl_scale = %u, bl_scale_sv = %u, bl_lvl = %u\n", + bl_scale, bl_scale_sv, (u32)bl_temp); + + return dp_panel->set_backlight(dp_panel, (u32)bl_temp); +} + static int dp_display_setup_colospace(struct dp_display *dp_display, void *panel, u32 colorspace) @@ -3944,6 +3987,7 @@ static int dp_display_probe(struct platform_device *pdev) dp_display->wakeup_phy_layer = dp_display_wakeup_phy_layer; dp_display->set_colorspace = dp_display_setup_colospace; + dp_display->set_backlight = dp_display_set_backlight; dp_display->get_available_dp_resources = dp_display_get_available_dp_resources; dp_display->get_display_type = dp_display_get_display_type; diff --git a/msm/dp/dp_display.h b/msm/dp/dp_display.h index 892322fa2fc2..a49ef045d702 100644 --- a/msm/dp/dp_display.h +++ b/msm/dp/dp_display.h @@ -110,6 +110,8 @@ struct dp_display { bool dhdr_update); int (*set_colorspace)(struct dp_display *dp_display, void *panel, u32 colorspace); + int (*set_backlight)(struct dp_display *dp_display, void *panel, + u32 bl_lvl); int (*post_init)(struct dp_display *dp_display); int (*mst_install)(struct dp_display *dp_display, struct dp_mst_drm_install_info *mst_install_info); diff --git a/msm/dp/dp_drm.c b/msm/dp/dp_drm.c index 6e054af5dc3d..d936aecd7c8c 100644 --- a/msm/dp/dp_drm.c +++ b/msm/dp/dp_drm.c @@ -326,6 +326,27 @@ int dp_connector_config_hdr(struct drm_connector *connector, void *display, c_state->dyn_hdr_meta.dynamic_hdr_update); } +int dp_connector_set_backlight(struct drm_connector *connector, + void *display, u32 bl_lvl) +{ + struct dp_display *dp_display = display; + struct sde_connector *sde_conn; + + if (!dp_display || !connector) { + DP_ERR("invalid dp display\n"); + return -EINVAL; + } + + sde_conn = to_sde_connector(connector); + if (!sde_conn->drv_panel) { + DP_ERR("invalid dp panel\n"); + return -EINVAL; + } + + return dp_display->set_backlight(dp_display, + sde_conn->drv_panel, bl_lvl); +} + int dp_connector_set_colorspace(struct drm_connector *connector, void *display) { diff --git a/msm/dp/dp_drm.h b/msm/dp/dp_drm.h index 647705c2706d..a99ab9c86f9d 100644 --- a/msm/dp/dp_drm.h +++ b/msm/dp/dp_drm.h @@ -49,6 +49,15 @@ int dp_connector_atomic_check(struct drm_connector *connector, void *display, struct drm_atomic_state *state); +/** + * dp_connector_set_backlight - callback to set backlight + * @connector: Pointer to drm connector structure + * @display: Pointer to private display handle + * Returns: Zero on success + */ +int dp_connector_set_backlight(struct drm_connector *connector, + void *display, u32 bl_lvl); + /** * dp_connector_set_colorspace - callback to set new colorspace * @connector: Pointer to drm connector structure diff --git a/msm/dp/dp_panel.c b/msm/dp/dp_panel.c index 6c24c52b0004..8fc1b13c3e32 100644 --- a/msm/dp/dp_panel.c +++ b/msm/dp/dp_panel.c @@ -6,6 +6,7 @@ #include "dp_panel.h" #include +#include #include #include "dp_debug.h" #include @@ -2295,6 +2296,91 @@ static int dp_panel_set_stream_info(struct dp_panel *dp_panel, return 0; } +static int dp_panel_pwm_register(struct dp_panel *dp_panel) +{ + int rc = 0; + struct dp_backlight_config *bl = &dp_panel->bl_config; + struct platform_device *pdev; + struct device *dev; + struct dp_panel_private *panel; + + panel = container_of(dp_panel, struct dp_panel_private, dp_panel); + pdev = panel->parser->pdev; + dev = &pdev->dev; + + bl->pwm_bl = devm_of_pwm_get(dev, dev->of_node, NULL); + if (IS_ERR_OR_NULL(bl->pwm_bl)) { + rc = PTR_ERR(bl->pwm_bl); + DP_ERR("failed to request pwm, rc=%d\n", rc); + return rc; + } + + return 0; +} + +static void dp_panel_pwm_unregister(struct dp_panel *dp_panel) +{ + struct dp_backlight_config *bl = &dp_panel->bl_config; + struct platform_device *pdev; + struct dp_panel_private *panel; + + panel = container_of(dp_panel, struct dp_panel_private, dp_panel); + pdev = panel->parser->pdev; + + if (bl->pwm_bl) + devm_pwm_put(&pdev->dev, bl->pwm_bl); +} + +static int dp_panel_set_backlight(struct dp_panel *panel, u32 bl_lvl) +{ + int rc = 0; + u32 duty = 0; + u32 period_ns = 0; + struct dp_backlight_config *bl; + + if (!panel) { + DP_ERR("Invalid Params\n"); + return -EINVAL; + } + + bl = &panel->bl_config; + if (!bl->pwm_bl) { + DP_ERR("pwm device not found\n"); + return -EINVAL; + } + + DP_DEBUG("backlight lvl:%d\n", bl_lvl); + + period_ns = bl->pwm_period_usecs * NSEC_PER_USEC; + duty = bl_lvl * period_ns; + duty /= bl->bl_max_level; + + rc = pwm_config(bl->pwm_bl, duty, period_ns); + if (rc) { + DP_ERR("failed to change pwm config, rc=\n", rc); + goto error; + } + + if (bl_lvl == 0 && bl->pwm_enabled) { + pwm_disable(bl->pwm_bl); + bl->pwm_enabled = false; + return 0; + } + + if (bl_lvl != 0 && !bl->pwm_enabled) { + rc = pwm_enable(bl->pwm_bl); + if (rc) { + DP_ERR("failed to enable pwm, rc=\n", rc); + goto error; + } + + bl->pwm_enabled = true; + } + +error: + return rc; +} + static int dp_panel_init_panel_info(struct dp_panel *dp_panel) { int rc = 0; @@ -3058,6 +3144,15 @@ struct dp_panel *dp_panel_get(struct dp_panel_in *in) dp_panel->fec_feature_enable = panel->parser->fec_feature_enable; dp_panel->dsc_continuous_pps = panel->parser->dsc_continuous_pps; + /* backlight config for edp */ + dp_panel->bl_config.bl_min_level = panel->parser->bl_min_level; + dp_panel->bl_config.bl_max_level = panel->parser->bl_max_level; + dp_panel->bl_config.brightness_max_level = panel->parser->brightness_max_level; + dp_panel->bl_config.pwm_period_usecs = panel->parser->pwm_period_usecs; + dp_panel->bl_config.bl_scale = MAX_BL_SCALE_LEVEL; + dp_panel->bl_config.bl_scale_sv = MAX_SV_BL_SCALE_LEVEL; + + if (in->base_panel) { memcpy(dp_panel->dpcd, in->base_panel->dpcd, DP_RECEIVER_CAP_SIZE + 1); @@ -3085,6 +3180,7 @@ struct dp_panel *dp_panel_get(struct dp_panel_in *in) dp_panel->spd_config = dp_panel_spd_config; dp_panel->setup_hdr = dp_panel_setup_hdr; dp_panel->set_colorspace = dp_panel_set_colorspace; + dp_panel->set_backlight = dp_panel_set_backlight; dp_panel->hdr_supported = dp_panel_hdr_supported; dp_panel->set_stream_info = dp_panel_set_stream_info; dp_panel->read_sink_status = dp_panel_read_sink_sts; @@ -3115,6 +3211,12 @@ struct dp_panel *dp_panel_get(struct dp_panel_in *in) } } + if (in->is_edp) { + rc = dp_panel_pwm_register(dp_panel); + if (rc) + DP_ERR("Failed to register pwm\n"); + } + return dp_panel; error: return ERR_PTR(rc); @@ -3132,6 +3234,9 @@ void dp_panel_put(struct dp_panel *dp_panel) dp_panel_edid_deregister(panel); sde_conn = to_sde_connector(dp_panel->connector); + + dp_panel_pwm_unregister(dp_panel); + if (sde_conn) sde_conn->drv_panel = NULL; diff --git a/msm/dp/dp_panel.h b/msm/dp/dp_panel.h index 822393143ab8..3abb41297584 100644 --- a/msm/dp/dp_panel.h +++ b/msm/dp/dp_panel.h @@ -18,6 +18,9 @@ #define DP_RECEIVER_DSC_CAP_SIZE 15 #define DP_RECEIVER_FEC_STATUS_SIZE 3 #define DP_RECEIVER_EXT_CAP_SIZE 4 +#define MAX_BL_LEVEL 4096 +#define MAX_BL_SCALE_LEVEL 1024 +#define MAX_SV_BL_SCALE_LEVEL 65535 /* * A source initiated power down flag is set * when the DP is powered off while physical @@ -86,6 +89,22 @@ struct dp_dsc_caps { u8 color_depth; }; +struct dp_backlight_config { + u32 bl_min_level; + u32 bl_max_level; + u32 brightness_max_level; + u32 bl_level; + u32 bl_scale; + u32 bl_scale_sv; + + int en_gpio; + /* PWM params */ + struct pwm_device *pwm_bl; + bool pwm_enabled; + u32 pwm_period_usecs; +}; + + struct dp_audio; #define DP_PANEL_CAPS_DSC BIT(0) @@ -102,6 +121,7 @@ struct dp_panel { struct drm_dp_link link_info; struct sde_edid_ctrl *edid_ctrl; struct dp_panel_info pinfo; + struct dp_backlight_config bl_config; bool video_test; bool spd_enabled; @@ -159,6 +179,7 @@ struct dp_panel { bool dhdr_update, u64 core_clk_rate, bool flush); int (*set_colorspace)(struct dp_panel *dp_panel, u32 colorspace); + int (*set_backlight)(struct dp_panel *dp_panel, u32 bl_lvl); void (*tpg_config)(struct dp_panel *dp_panel, bool enable); int (*spd_config)(struct dp_panel *dp_panel); bool (*hdr_supported)(struct dp_panel *dp_panel); diff --git a/msm/dp/dp_parser.c b/msm/dp/dp_parser.c index 7f5501a136bf..4503df56a81d 100644 --- a/msm/dp/dp_parser.c +++ b/msm/dp/dp_parser.c @@ -256,6 +256,47 @@ error: return rc; } +static void dp_parser_bl_config(struct dp_parser *parser) +{ + int rc = 0; + u32 val = 0; + struct device_node *of_node = parser->pdev->dev.of_node; + + rc = of_property_read_u32(of_node, "qcom,edp-bl-min-level", &val); + if (rc) { + DP_DEBUG("bl-min-level unspecified, defaulting to zero\n"); + parser->bl_min_level = 0; + } else { + parser->bl_min_level = val; + } + + rc = of_property_read_u32(of_node, "qcom,edp-bl-max-level", &val); + if (rc) { + DP_DEBUG("bl-max-level unspecified, defaulting to 4096\n"); + parser->bl_max_level = 4096; + } else { + parser->bl_max_level = val; + } + + rc = of_property_read_u32(of_node, "qcom,edp-brightness-max-level", + &val); + if (rc) { + DP_DEBUG("brigheness-max-level unspecified, defaulting to 255\n"); + parser->brightness_max_level = 255; + } else { + parser->brightness_max_level = val; + } + + rc = of_property_read_u32(of_node, "qcom,bl-pmic-pwm-period-usecs", + &val); + if (rc) { + DP_DEBUG("bl-pmic-pwm-period-usecs unspecified, default 100\n"); + parser->pwm_period_usecs = 100; + } else { + parser->pwm_period_usecs = val; + } +} + static int dp_parser_gpio(struct dp_parser *parser) { int i = 0; @@ -854,6 +895,7 @@ static int dp_parser_parse(struct dp_parser *parser) if (rc) goto err; + dp_parser_bl_config(parser); dp_parser_dsc(parser); dp_parser_fec(parser); dp_parser_widebus(parser); diff --git a/msm/dp/dp_parser.h b/msm/dp/dp_parser.h index 5444ee9e7050..da70b5674d51 100644 --- a/msm/dp/dp_parser.h +++ b/msm/dp/dp_parser.h @@ -235,7 +235,11 @@ static inline char *dp_phy_aux_config_type_to_string(u32 cfg_type) * @fec_feature_enable: FEC feature enable status * @dsc_continuous_pps: PPS sent every frame by HW * @has_widebus: widebus (2PPC) feature eanble status - *@mst_fixed_port: mst port_num reserved for fixed topology + * @bl_min_level: minimum brightness value for backlight + * @bl_max_level: maximum brightness value for backlight + * @brightness_max_level: maximum brightness level for backlight + * @pwm_period_usecs: pwm period in usecs for backlight pwm + * @mst_fixed_port: mst port_num reserved for fixed topology * @parse: function to be called by client to parse device tree. * @get_io: function to be called by client to get io data. * @get_io_buf: function to be called by client to get io buffers. @@ -267,6 +271,10 @@ struct dp_parser { bool gpio_aux_switch; bool lphw_hpd; bool panel_notifier_support; + u32 bl_min_level; + u32 bl_max_level; + u32 brightness_max_level; + u32 pwm_period_usecs; u32 mst_fixed_port[MAX_DP_MST_STREAMS]; u32 pixel_base_off[MAX_DP_MST_STREAMS]; const char *mst_fixed_display_type[MAX_DP_MST_STREAMS]; diff --git a/msm/sde/sde_connector.c b/msm/sde/sde_connector.c index 404e8af8c80f..8c23f622a97b 100644 --- a/msm/sde/sde_connector.c +++ b/msm/sde/sde_connector.c @@ -1,6 +1,6 @@ // SPDX-License-Identifier: GPL-2.0-only /* - * Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved. + * Copyright (c) 2022-2023 Qualcomm Innovation Center, Inc. All rights reserved. * Copyright (c) 2016-2021, The Linux Foundation. All rights reserved. */ @@ -16,6 +16,7 @@ #include #include "dsi_drm.h" #include "dsi_display.h" +#include "dp_panel.h" #include "sde_crtc.h" #include "sde_rm.h" #include "sde_vm.h" @@ -23,6 +24,7 @@ #define BL_NODE_NAME_SIZE 32 #define HDR10_PLUS_VSIF_TYPE_CODE 0x81 +#define MAX_BRIGHTNESS_LEVEL 255 /* Autorefresh will occur after FRAME_CNT frames. Large values are unlikely */ #define AUTOREFRESH_MAX_FRAME_CNT 6 @@ -93,13 +95,16 @@ static inline struct sde_kms *_sde_connector_get_kms(struct drm_connector *conn) static int sde_backlight_device_update_status(struct backlight_device *bd) { int brightness; - struct dsi_display *display; + struct dsi_display *dsi_display; + struct dp_panel *dp_panel; struct sde_connector *c_conn = bl_get_data(bd); int bl_lvl; struct drm_event event; int rc = 0; struct sde_kms *sde_kms; struct sde_vm_ops *vm_ops; + u32 bl_max_level = 0; + u32 brightness_max_level = 0; sde_kms = _sde_connector_get_kms(&c_conn->base); if (!sde_kms) { @@ -114,15 +119,27 @@ static int sde_backlight_device_update_status(struct backlight_device *bd) (bd->props.state & BL_CORE_SUSPENDED)) brightness = 0; - display = (struct dsi_display *) c_conn->display; - if (brightness > display->panel->bl_config.bl_max_level) - brightness = display->panel->bl_config.bl_max_level; + if (c_conn->connector_type == DRM_MODE_CONNECTOR_DSI) { + dsi_display = (struct dsi_display *) c_conn->display; + bl_max_level = dsi_display->panel->bl_config.bl_max_level; + brightness_max_level = + dsi_display->panel->bl_config.brightness_max_level; + } else if (c_conn->connector_type == DRM_MODE_CONNECTOR_eDP) { + dp_panel = (struct dp_panel *) c_conn->drv_panel; + if (dp_panel) { + bl_max_level = dp_panel->bl_config.bl_max_level; + brightness_max_level = + dp_panel->bl_config.brightness_max_level; + } + } + + if (brightness > bl_max_level) + brightness = bl_max_level; if (brightness > c_conn->thermal_max_brightness) brightness = c_conn->thermal_max_brightness; /* map UI brightness into driver backlight level with rounding */ - bl_lvl = mult_frac(brightness, display->panel->bl_config.bl_max_level, - display->panel->bl_config.brightness_max_level); + bl_lvl = mult_frac(brightness, bl_max_level, brightness_max_level); if (!bl_lvl && brightness) bl_lvl = 1; @@ -188,31 +205,46 @@ static int sde_backlight_setup(struct sde_connector *c_conn, { struct backlight_properties props; struct dsi_display *display; - struct dsi_backlight_config *bl_config; + struct dp_panel *dp_panel; + struct dsi_backlight_config *dsi_bl_config; struct sde_kms *sde_kms; static int display_count; char bl_node_name[BL_NODE_NAME_SIZE]; + u32 brightness_max_level = 0; sde_kms = _sde_connector_get_kms(&c_conn->base); if (!sde_kms) { SDE_ERROR("invalid kms\n"); return -EINVAL; - } else if (c_conn->connector_type != DRM_MODE_CONNECTOR_DSI) { + } + + if (c_conn->connector_type == DRM_MODE_CONNECTOR_DSI) { + display = (struct dsi_display *) c_conn->display; + dsi_bl_config = &display->panel->bl_config; + brightness_max_level = dsi_bl_config->brightness_max_level; + if (dsi_bl_config->type != DSI_BACKLIGHT_DCS && + sde_in_trusted_vm(sde_kms)) + return 0; + } else if (c_conn->connector_type == DRM_MODE_CONNECTOR_eDP) { + dp_panel = (struct dp_panel *) c_conn->drv_panel; + if (dp_panel) + brightness_max_level = + dp_panel->bl_config.brightness_max_level; + else { + brightness_max_level = MAX_BRIGHTNESS_LEVEL; + } + } else { + SDE_DEBUG("invalid connector type %d\n", + c_conn->connector_type); return 0; } - display = (struct dsi_display *) c_conn->display; - bl_config = &display->panel->bl_config; - - if (bl_config->type != DSI_BACKLIGHT_DCS && - sde_in_trusted_vm(sde_kms)) - return 0; memset(&props, 0, sizeof(props)); props.type = BACKLIGHT_RAW; props.power = FB_BLANK_UNBLANK; - props.max_brightness = bl_config->brightness_max_level; - props.brightness = bl_config->brightness_max_level; + props.max_brightness = brightness_max_level; + props.brightness = brightness_max_level; snprintf(bl_node_name, BL_NODE_NAME_SIZE, "panel%u-backlight", display_count); c_conn->bl_device = backlight_device_register(bl_node_name, dev->dev, @@ -223,7 +255,7 @@ static int sde_backlight_setup(struct sde_connector *c_conn, c_conn->bl_device = NULL; return -ENODEV; } - c_conn->thermal_max_brightness = bl_config->brightness_max_level; + c_conn->thermal_max_brightness = brightness_max_level; /** * In TVM, thermal cooling device is not enabled. Registering with dummy @@ -639,42 +671,62 @@ static int _sde_connector_update_power_locked(struct sde_connector *c_conn) static int _sde_connector_update_bl_scale(struct sde_connector *c_conn) { struct dsi_display *dsi_display; - struct dsi_backlight_config *bl_config; + struct dp_display *dp_display; + struct dsi_backlight_config *dsi_bl_config; + struct dp_backlight_config *dp_bl_config; + struct dp_panel *dp_panel; int rc = 0; + u32 bl_scale, bl_scale_sv; if (!c_conn) { SDE_ERROR("Invalid params sde_connector null\n"); return -EINVAL; } - dsi_display = c_conn->display; - if (!dsi_display || !dsi_display->panel) { - SDE_ERROR("Invalid params(s) dsi_display %pK, panel %pK\n", - dsi_display, - ((dsi_display) ? dsi_display->panel : NULL)); - return -EINVAL; - } - - bl_config = &dsi_display->panel->bl_config; - - if (!c_conn->allow_bl_update) { - c_conn->unset_bl_level = bl_config->bl_level; - return 0; - } - - if (c_conn->unset_bl_level) - bl_config->bl_level = c_conn->unset_bl_level; - - bl_config->bl_scale = c_conn->bl_scale > MAX_BL_SCALE_LEVEL ? + bl_scale = c_conn->bl_scale > MAX_BL_SCALE_LEVEL ? MAX_BL_SCALE_LEVEL : c_conn->bl_scale; - bl_config->bl_scale_sv = c_conn->bl_scale_sv > MAX_SV_BL_SCALE_LEVEL ? + bl_scale_sv = c_conn->bl_scale_sv > MAX_SV_BL_SCALE_LEVEL ? MAX_SV_BL_SCALE_LEVEL : c_conn->bl_scale_sv; - SDE_DEBUG("bl_scale = %u, bl_scale_sv = %u, bl_level = %u\n", - bl_config->bl_scale, bl_config->bl_scale_sv, - bl_config->bl_level); - rc = c_conn->ops.set_backlight(&c_conn->base, - dsi_display, bl_config->bl_level); + if (c_conn->connector_type == DRM_MODE_CONNECTOR_DSI) { + dsi_display = c_conn->display; + if (!dsi_display || !dsi_display->panel) { + SDE_ERROR("Invalid params dsi_display %pK, panel %pK\n", + dsi_display, + ((dsi_display) ? dsi_display->panel : NULL)); + return -EINVAL; + } + dsi_bl_config = &dsi_display->panel->bl_config; + if (!c_conn->allow_bl_update) { + c_conn->unset_bl_level = dsi_bl_config->bl_level; + return 0; + } + dsi_bl_config->bl_scale = bl_scale; + dsi_bl_config->bl_scale_sv = bl_scale_sv; + if (c_conn->unset_bl_level) + dsi_bl_config->bl_level = c_conn->unset_bl_level; + + rc = c_conn->ops.set_backlight(&c_conn->base, + dsi_display, dsi_bl_config->bl_level); + } else if (c_conn->connector_type == DRM_MODE_CONNECTOR_eDP) { + dp_display = c_conn->display; + dp_panel = (struct dp_panel *) c_conn->drv_panel; + if (dp_panel) { + dp_bl_config = &dp_panel->bl_config; + if (!c_conn->allow_bl_update) { + c_conn->unset_bl_level = dp_bl_config->bl_level; + return 0; + } + dp_bl_config->bl_scale = bl_scale; + dp_bl_config->bl_scale_sv = bl_scale_sv; + if (c_conn->unset_bl_level) + dp_bl_config->bl_level = c_conn->unset_bl_level; + rc = c_conn->ops.set_backlight(&c_conn->base, + dp_display, dp_bl_config->bl_level); + } else + SDE_ERROR("Invalid dp_panel null\n"); + } + c_conn->unset_bl_level = 0; return rc; diff --git a/msm/sde/sde_kms.c b/msm/sde/sde_kms.c index 308200bd8579..00f3d28619ec 100644 --- a/msm/sde/sde_kms.c +++ b/msm/sde/sde_kms.c @@ -1785,6 +1785,7 @@ static int _sde_kms_setup_displays(struct drm_device *dev, .get_info = dp_connector_get_info, .get_mode_info = dp_connector_get_mode_info, .post_open = dp_connector_post_open, + .set_backlight = dp_connector_set_backlight, .check_status = NULL, .set_colorspace = dp_connector_set_colorspace, .config_hdr = dp_connector_config_hdr,