Merge commit '452e643352' into display-kernel.lnx.5.4.r8-rel

Change-Id: I5e9066dcb3f69b8123621056c60b322af4897a62
Signed-off-by: Venkata Prahlad Valluru <quic_vvalluru@quicinc.com>
This commit is contained in:
Venkata Prahlad Valluru 2023-07-17 16:29:58 +05:30
commit 73d4a4007a
10 changed files with 476 additions and 47 deletions

View file

@ -177,6 +177,7 @@ struct dp_display_private {
struct dentry *root;
struct completion notification_comp;
struct completion attention_comp;
struct completion res_init_comp;
struct dp_hpd *hpd;
struct dp_parser *parser;
@ -317,6 +318,41 @@ static void dp_audio_enable(struct dp_display_private *dp, bool enable)
}
}
/**
* dp_display_cont_splash_config() - Initialize resources for continuous splash
* @dp_display: Pointer to dp display
* Returns: Zero on success
*/
int dp_display_cont_splash_config(void *display)
{
struct dp_display *dp_display = display;
struct dp_display_private *dp;
int rc = 0;
/* Vote for gdsc required to read register address space */
if (!dp_display) {
DP_ERR("invalid input display param\n");
return -EINVAL;
}
dp = container_of(dp_display, struct dp_display_private, dp_display);
if (!dp_display->is_edp) {
DP_ERR("splash handoff for dp not supported\n");
return -EOPNOTSUPP;
}
/* wait for the all the resource initialization and voting to
* complete, before we exit driver probe
*/
if (!wait_for_completion_timeout(&dp->res_init_comp, HZ * 10)) {
DP_WARN("timeout waiting for splash_res_init\n");
rc = -ETIMEDOUT;
}
return rc;
}
static int dp_display_parse_boot_display_selection(void)
{
char *pos = NULL;
@ -1122,10 +1158,14 @@ static int dp_display_host_init(struct dp_display_private *dp)
return rc;
}
<<<<<<< HEAD
/* Skip hpd config when cont. splash is enbaled*/
if (!skip_op)
dp->hpd->host_init(dp->hpd, &dp->catalog->hpd);
=======
dp->hpd->host_init(dp->hpd, &dp->catalog->hpd);
>>>>>>> 452e643352bd41612f5634d8b38d7be9cbc9a875
rc = dp->ctrl->init(dp->ctrl, flip, reset, skip_op);
if (rc) {
DP_WARN("Ctrl init Failed.\n");
@ -1361,6 +1401,9 @@ static int dp_display_process_hpd_high(struct dp_display_private *dp)
dp->process_hpd_connect = false;
dp_display_set_mst_mgr_state(dp, true);
/* all dp resource init are complete */
complete_all(&dp->res_init_comp);
end:
mutex_unlock(&dp->session_lock);
@ -2630,7 +2673,11 @@ static void dp_display_stream_post_enable(struct dp_display_private *dp,
struct dp_panel *dp_panel)
{
<<<<<<< HEAD
if (dp->dp_display.is_edp) {
=======
if (dp->dp_display.cont_splash_enabled) {
>>>>>>> 452e643352bd41612f5634d8b38d7be9cbc9a875
dp->dp_display.cont_splash_enabled = false;
dp->pll->cont_splash_enabled = false;
}
@ -2642,6 +2689,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) {
@ -2687,6 +2737,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);
@ -3344,6 +3403,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)
@ -3950,6 +4040,7 @@ static int dp_display_probe(struct platform_device *pdev)
init_completion(&dp->notification_comp);
init_completion(&dp->attention_comp);
init_completion(&dp->res_init_comp);
dp->pdev = pdev;
dp->name = "drm_dp";
@ -4005,6 +4096,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;
@ -4238,4 +4330,8 @@ void __exit dp_display_unregister(void)
module_param_string(edp_display0, edp_display_primary, MAX_CMDLINE_PARAM_LEN,
0600);
MODULE_PARM_DESC(edp_display0,
<<<<<<< HEAD
"msm_drm.edp_display0=<display node>:<configX> where <display node> is 'primary dp display node name' and <configX> where x represents index in the topology list");
=======
"msm_drm.edp_display0=<display node>: where <display node> is 'primary dp display node name' ");
>>>>>>> 452e643352bd41612f5634d8b38d7be9cbc9a875

View file

@ -121,6 +121,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);
@ -160,17 +162,23 @@ struct dp_display {
u32 strm_id, const char **display_type);
int (*edp_detect)(struct dp_display *dp_display);
};
int dp_display_get_num_of_boot_displays(void);
#if IS_ENABLED(CONFIG_DRM_MSM_DP)
int dp_display_get_num_of_displays(void);
int dp_display_get_num_of_boot_displays(void);
int dp_display_get_displays(void **displays, int count);
int dp_display_get_num_of_streams(void);
int dp_display_get_info(void *dp_display, struct dp_display_info *dp_info);
int dp_display_cont_splash_config(void *display);
#else
static inline int dp_display_get_num_of_displays(void)
{
return 0;
}
static inline int dp_display_get_num_of_boot_displays(void)
{
return 0;
}
static inline int dp_display_get_displays(void **displays, int count)
{
return 0;
@ -188,5 +196,9 @@ static inline int dp_connector_update_pps(struct drm_connector *connector,
{
return 0;
}
static inline int dp_display_cont_splash_config(void *display)
{
return 0;
}
#endif /* CONFIG_DRM_MSM_DP */
#endif /* _DP_DISPLAY_H_ */

View file

@ -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)
{

View file

@ -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

View file

@ -6,6 +6,7 @@
#include "dp_panel.h"
#include <linux/unistd.h>
#include <linux/pwm.h>
#include <drm/drm_fixed.h>
#include "dp_debug.h"
#include <drm/drm_dsc.h>
@ -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;

View file

@ -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);

View file

@ -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);

View file

@ -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];

View file

@ -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 <linux/string.h>
#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;

View file

@ -1255,6 +1255,16 @@ static void _sde_kms_release_splash_resource(struct sde_kms *sde_kms,
SDE_EVT32(DRMID(crtc), crtc->state->active,
sde_kms->splash_data.num_splash_displays);
/*remove all votes if eDP displays are done with splash*/
if (dp_display_get_num_of_boot_displays()) {
for (i = 0; i < SDE_POWER_HANDLE_DBUS_ID_MAX; i++)
sde_power_data_bus_set_quota(phandle, i,
SDE_POWER_HANDLE_ENABLE_BUS_AB_QUOTA,
phandle->ib_quota[i]);
pm_runtime_put_sync(sde_kms->dev->dev);
sde_kms->splash_data.num_splash_displays--;
}
for (i = 0; i < MAX_DSI_DISPLAYS; i++) {
splash_display = &sde_kms->splash_data.splash_display[i];
if (splash_display->encoder &&
@ -1785,11 +1795,12 @@ 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,
.cmd_transfer = NULL,
.cont_splash_config = NULL,
.cont_splash_config = dp_display_cont_splash_config,
.cont_splash_res_disable = NULL,
.get_panel_vfp = NULL,
.update_pps = dp_connector_update_pps,
@ -3370,6 +3381,7 @@ static int sde_kms_cont_splash_config(struct msm_kms *kms,
{
void *display;
struct dsi_display *dsi_display;
struct dp_display *dp_display;
struct msm_display_info info;
struct drm_encoder *encoder = NULL;
struct drm_crtc *crtc = NULL;
@ -3520,6 +3532,57 @@ static int sde_kms_cont_splash_config(struct msm_kms *kms,
}
}
/* dp */
for (i = 0; i < sde_kms->dp_display_count; ++i) {
display = sde_kms->dp_displays[i];
dp_display = (struct dp_display *)display;
if (!dp_display->cont_splash_enabled) {
SDE_DEBUG("DP-%d splash not enabled\n", i);
continue;
}
if (dp_display->bridge->base.encoder) {
encoder = dp_display->bridge->base.encoder;
SDE_DEBUG("encoder name = %s\n", encoder->name);
} else {
SDE_DEBUG("Invalid encoder\n");
break;
}
mutex_lock(&dev->mode_config.mutex);
drm_connector_list_iter_begin(dev, &conn_iter);
drm_for_each_connector_iter(connector, &conn_iter) {
/**
* SDE_KMS doesn't attach more than one encoder to
* a DSI connector. So it is safe to check only with
* the first encoder entry. Revisit this logic if we
* ever have to support continuous splash for
* external displays in MST configuration.
*/
if (connector->encoder_ids[0] == encoder->base.id)
break;
}
drm_connector_list_iter_end(&conn_iter);
if (!connector) {
SDE_ERROR("connector not initialized\n");
mutex_unlock(&dev->mode_config.mutex);
return -EINVAL;
}
mutex_unlock(&dev->mode_config.mutex);
/* Enable all irqs */
sde_irq_update(kms, true);
sde_conn = to_sde_connector(connector);
if (sde_conn && sde_conn->ops.cont_splash_config)
sde_conn->ops.cont_splash_config(sde_conn->display);
/* Disable irqs */
sde_irq_update(kms, false);
}
return rc;
}
@ -4427,7 +4490,7 @@ static int _sde_kms_get_splash_data(struct sde_kms *sde_kms,
* Ex: <r1.start r1.end r2.start r2.end ... rn.start, rn.end>
*/
num_displays = dsi_display_get_num_of_displays()
+dp_display_get_num_of_boot_displays();
+ dp_display_get_num_of_boot_displays();
num_regions = of_property_count_u64_elems(node, "reg") / 2;
data->num_splash_displays = num_displays;