Merge changes Ib1c0cc58,I23635b43 into display-kernel.lnx.5.4.4

* changes:
  disp: msm: sde: Remove pm vote at time of handoff
  disp: msm: eDP continuous splash implementation
This commit is contained in:
Linux Build Service Account 2023-06-28 02:41:26 -07:00 • committed by Gerrit - the friendly Code Review server
commit a3b00b3487
10 changed files with 187 additions and 45 deletions

View file

@ -1,5 +1,6 @@
// SPDX-License-Identifier: GPL-2.0-only
/*
* Copyright (c) 2023 Qualcomm Innovation Center, Inc. All rights reserved.
* Copyright (c) 2012-2020, The Linux Foundation. All rights reserved.
*/
@ -631,7 +632,7 @@ static void dp_aux_reset_phy_config_indices(struct dp_aux_cfg *aux_cfg)
aux_cfg[i].current_index = 0;
}
static void dp_aux_init(struct dp_aux *dp_aux, struct dp_aux_cfg *aux_cfg)
static void dp_aux_init(struct dp_aux *dp_aux, struct dp_aux_cfg *aux_cfg, bool skip_op)
{
struct dp_aux_private *aux;
@ -645,10 +646,16 @@ static void dp_aux_init(struct dp_aux *dp_aux, struct dp_aux_cfg *aux_cfg)
if (aux->enabled)
return;
/*skip aux init when cont. splash is enabled*/
if (skip_op)
goto skip_init;
dp_aux_reset_phy_config_indices(aux_cfg);
aux->catalog->setup(aux->catalog, aux_cfg);
aux->catalog->reset(aux->catalog);
aux->catalog->enable(aux->catalog, true);
skip_init:
atomic_set(&aux->aborted, 0);
aux->retry_cnt = 0;
aux->enabled = true;

View file

@ -1,5 +1,6 @@
/* SPDX-License-Identifier: GPL-2.0-only */
/*
* Copyright (c) 2023 Qualcomm Innovation Center, Inc. All rights reserved.
* Copyright (c) 2012-2020, The Linux Foundation. All rights reserved.
*/
@ -47,7 +48,7 @@ struct dp_aux {
int (*drm_aux_register)(struct dp_aux *aux);
void (*drm_aux_deregister)(struct dp_aux *aux);
void (*isr)(struct dp_aux *aux);
void (*init)(struct dp_aux *aux, struct dp_aux_cfg *aux_cfg);
void (*init)(struct dp_aux *aux, struct dp_aux_cfg *aux_cfg, bool skip_op);
void (*deinit)(struct dp_aux *aux);
void (*reconfig)(struct dp_aux *aux);
void (*abort)(struct dp_aux *aux, bool abort);

View file

@ -165,8 +165,13 @@ trigger_idle:
* configuration, output format and sink/panel timing information.
*/
static void dp_ctrl_configure_source_link_params(struct dp_ctrl_private *ctrl,
bool enable)
bool enable, bool skip_op)
{
if (skip_op) {
DP_DEBUG("configuring source link params skipped\n");
return;
}
if (enable) {
ctrl->catalog->lane_mapping(ctrl->catalog, ctrl->orientation,
ctrl->parser->l_map);
@ -533,7 +538,7 @@ skip_training:
return ret;
}
static int dp_ctrl_link_train(struct dp_ctrl_private *ctrl)
static int dp_ctrl_link_train(struct dp_ctrl_private *ctrl, bool skip_op)
{
int ret = 0;
u8 const encoding = 0x1, downspread = 0x00;
@ -547,6 +552,11 @@ static int dp_ctrl_link_train(struct dp_ctrl_private *ctrl)
ctrl->link->link_params.bw_code);
link_info.capabilities = ctrl->panel->link_info.capabilities;
if (skip_op) {
DP_DEBUG("link training skipped\n");
return 0;
}
ret = drm_dp_link_configure(ctrl->aux->drm_aux, &link_info);
if (ret)
goto end;
@ -592,7 +602,7 @@ end:
return ret;
}
static int dp_ctrl_setup_main_link(struct dp_ctrl_private *ctrl)
static int dp_ctrl_setup_main_link(struct dp_ctrl_private *ctrl, bool skip_op)
{
int ret = 0;
@ -604,13 +614,15 @@ static int dp_ctrl_setup_main_link(struct dp_ctrl_private *ctrl)
* transitioned to PUSH_IDLE. In order to start transmitting a link
* training pattern, we have to first to a DP software reset.
*/
ctrl->catalog->reset(ctrl->catalog);
if (!skip_op)
ctrl->catalog->reset(ctrl->catalog);
if (ctrl->fec_mode)
drm_dp_dpcd_writeb(ctrl->aux->drm_aux, DP_FEC_CONFIGURATION,
0x01);
ret = dp_ctrl_link_train(ctrl);
ret = dp_ctrl_link_train(ctrl, skip_op);
end:
return ret;
@ -720,7 +732,7 @@ end:
ctrl->training_2_pattern = pattern;
}
static int dp_ctrl_link_setup(struct dp_ctrl_private *ctrl, bool shallow)
static int dp_ctrl_link_setup(struct dp_ctrl_private *ctrl, bool shallow, bool skip_op)
{
int rc = -EINVAL;
bool downgrade = false;
@ -746,7 +758,7 @@ static int dp_ctrl_link_setup(struct dp_ctrl_private *ctrl, bool shallow)
ctrl->link->link_params.lane_count,
ctrl->orientation);
dp_ctrl_configure_source_link_params(ctrl, true);
dp_ctrl_configure_source_link_params(ctrl, true, skip_op);
if (!(--link_train_max_retries % 10)) {
struct dp_link_params *link = &ctrl->link->link_params;
@ -758,7 +770,7 @@ static int dp_ctrl_link_setup(struct dp_ctrl_private *ctrl, bool shallow)
dp_ctrl_select_training_pattern(ctrl, downgrade);
rc = dp_ctrl_setup_main_link(ctrl);
rc = dp_ctrl_setup_main_link(ctrl, skip_op);
if (!rc)
break;
@ -782,7 +794,7 @@ static int dp_ctrl_link_setup(struct dp_ctrl_private *ctrl, bool shallow)
if (rc != -EAGAIN)
dp_ctrl_link_rate_down_shift(ctrl);
dp_ctrl_configure_source_link_params(ctrl, false);
dp_ctrl_configure_source_link_params(ctrl, false, skip_op);
dp_ctrl_disable_link_clock(ctrl);
/* hw recommended delays before retrying link training */
@ -852,7 +864,7 @@ static int dp_ctrl_disable_stream_clocks(struct dp_ctrl_private *ctrl,
}
return ret;
}
static int dp_ctrl_host_init(struct dp_ctrl *dp_ctrl, bool flip, bool reset)
static int dp_ctrl_host_init(struct dp_ctrl *dp_ctrl, bool flip, bool reset, bool skip_op)
{
struct dp_ctrl_private *ctrl;
struct dp_catalog_ctrl *catalog;
@ -867,7 +879,7 @@ static int dp_ctrl_host_init(struct dp_ctrl *dp_ctrl, bool flip, bool reset)
ctrl->orientation = flip;
catalog = ctrl->catalog;
if (reset) {
if (reset && !skip_op) {
catalog->usb_reset(ctrl->catalog, flip);
catalog->phy_reset(ctrl->catalog);
}
@ -906,7 +918,7 @@ static void dp_ctrl_send_video(struct dp_ctrl_private *ctrl)
ctrl->catalog->state_ctrl(ctrl->catalog, ST_SEND_VIDEO);
}
static int dp_ctrl_link_maintenance(struct dp_ctrl *dp_ctrl)
static int dp_ctrl_link_maintenance(struct dp_ctrl *dp_ctrl, bool skip_op)
{
int ret = 0;
struct dp_ctrl_private *ctrl;
@ -931,7 +943,7 @@ static int dp_ctrl_link_maintenance(struct dp_ctrl *dp_ctrl)
goto end;
ctrl->aux->state |= DP_STATE_LINK_MAINTENANCE_STARTED;
ret = dp_ctrl_setup_main_link(ctrl);
ret = dp_ctrl_setup_main_link(ctrl, skip_op);
ctrl->aux->state &= ~DP_STATE_LINK_MAINTENANCE_STARTED;
if (ret) {
@ -949,7 +961,7 @@ end:
return ret;
}
static void dp_ctrl_process_phy_test_request(struct dp_ctrl *dp_ctrl)
static void dp_ctrl_process_phy_test_request(struct dp_ctrl *dp_ctrl, bool skip_op)
{
int ret = 0;
struct dp_ctrl_private *ctrl;
@ -978,14 +990,14 @@ static void dp_ctrl_process_phy_test_request(struct dp_ctrl *dp_ctrl)
ctrl->dp_ctrl.stream_off(&ctrl->dp_ctrl, ctrl->panel);
ctrl->dp_ctrl.off(&ctrl->dp_ctrl);
ctrl->aux->init(ctrl->aux, ctrl->parser->aux_cfg);
ctrl->aux->init(ctrl->aux, ctrl->parser->aux_cfg, skip_op);
ret = ctrl->dp_ctrl.on(&ctrl->dp_ctrl, ctrl->mst_mode,
ctrl->fec_mode, ctrl->dsc_mode, false);
ctrl->fec_mode, ctrl->dsc_mode, false, skip_op);
if (ret)
DP_ERR("failed to enable DP controller\n");
ctrl->dp_ctrl.stream_on(&ctrl->dp_ctrl, ctrl->panel);
ctrl->dp_ctrl.stream_on(&ctrl->dp_ctrl, ctrl->panel, skip_op);
DP_DEBUG("end\n");
}
@ -1228,7 +1240,7 @@ static void dp_ctrl_fec_dsc_setup(struct dp_ctrl_private *ctrl)
DP_WARN("failed to enable sink dsc\n");
}
static int dp_ctrl_stream_on(struct dp_ctrl *dp_ctrl, struct dp_panel *panel)
static int dp_ctrl_stream_on(struct dp_ctrl *dp_ctrl, struct dp_panel *panel, bool skip_op)
{
int rc = 0;
bool link_ready = false;
@ -1250,9 +1262,12 @@ static int dp_ctrl_stream_on(struct dp_ctrl *dp_ctrl, struct dp_panel *panel)
return rc;
}
rc = panel->hw_cfg(panel, true);
if (rc)
return rc;
/*Skip panel config when cont. splash is enabled*/
if (!skip_op) {
rc = panel->hw_cfg(panel, true);
if (rc)
return rc;
}
if (ctrl->link->sink_request & DP_TEST_LINK_PHY_TEST_PATTERN) {
dp_ctrl_send_phy_test_pattern(ctrl);
@ -1343,7 +1358,7 @@ static void dp_ctrl_stream_off(struct dp_ctrl *dp_ctrl, struct dp_panel *panel)
}
static int dp_ctrl_on(struct dp_ctrl *dp_ctrl, bool mst_mode,
bool fec_mode, bool dsc_mode, bool shallow)
bool fec_mode, bool dsc_mode, bool shallow, bool skip_op)
{
int rc = 0;
struct dp_ctrl_private *ctrl;
@ -1389,9 +1404,13 @@ static int dp_ctrl_on(struct dp_ctrl *dp_ctrl, bool mst_mode,
ctrl->initial_lane_count = ctrl->link->link_params.lane_count;
ctrl->initial_bw_code = ctrl->link->link_params.bw_code;
rc = dp_ctrl_link_setup(ctrl, shallow);
rc = dp_ctrl_link_setup(ctrl, shallow, skip_op);
if (!rc)
ctrl->power_on = true;
/*enable stream clocks when cont. splash is enabled*/
if (skip_op)
dp_ctrl_enable_stream_clocks(ctrl, ctrl->panel);
end:
return rc;
}
@ -1399,6 +1418,7 @@ end:
static void dp_ctrl_off(struct dp_ctrl *dp_ctrl)
{
struct dp_ctrl_private *ctrl;
bool skip_op = false;
if (!dp_ctrl)
return;
@ -1409,7 +1429,7 @@ static void dp_ctrl_off(struct dp_ctrl *dp_ctrl)
return;
ctrl->catalog->fec_config(ctrl->catalog, false);
dp_ctrl_configure_source_link_params(ctrl, false);
dp_ctrl_configure_source_link_params(ctrl, false, skip_op);
ctrl->catalog->reset(ctrl->catalog);
/* Make sure DP is disabled before clk disable */

View file

@ -16,17 +16,17 @@
#include "dp_debug.h"
struct dp_ctrl {
int (*init)(struct dp_ctrl *dp_ctrl, bool flip, bool reset);
int (*init)(struct dp_ctrl *dp_ctrl, bool flip, bool reset, bool skip_op);
void (*deinit)(struct dp_ctrl *dp_ctrl);
int (*on)(struct dp_ctrl *dp_ctrl, bool mst_mode, bool fec_en,
bool dsc_en, bool shallow);
bool dsc_en, bool shallow, bool skip_op);
void (*off)(struct dp_ctrl *dp_ctrl);
void (*abort)(struct dp_ctrl *dp_ctrl, bool abort);
void (*isr)(struct dp_ctrl *dp_ctrl);
bool (*handle_sink_request)(struct dp_ctrl *dp_ctrl);
void (*process_phy_test_request)(struct dp_ctrl *dp_ctrl);
int (*link_maintenance)(struct dp_ctrl *dp_ctrl);
int (*stream_on)(struct dp_ctrl *dp_ctrl, struct dp_panel *panel);
void (*process_phy_test_request)(struct dp_ctrl *dp_ctrl, bool skip_op);
int (*link_maintenance)(struct dp_ctrl *dp_ctrl, bool skip_op);
int (*stream_on)(struct dp_ctrl *dp_ctrl, struct dp_panel *panel, bool skip_op);
void (*stream_off)(struct dp_ctrl *dp_ctrl, struct dp_panel *panel);
void (*stream_pre_off)(struct dp_ctrl *dp_ctrl, struct dp_panel *panel);
void (*set_mst_channel_info)(struct dp_ctrl *dp_ctrl,

View file

@ -136,6 +136,12 @@ static char *dp_display_state_name(enum dp_display_states state)
static struct dp_display *g_dp_display[MAX_DP_ACTIVE_DISPLAY];
#define HPD_STRING_SIZE 30
static char edp_display_primary[MAX_CMDLINE_PARAM_LEN];
static struct dp_display_boot_param boot_displays[MAX_DP_ACTIVE_BOOT_DISPLAY] = {
{.boot_param = edp_display_primary},
};
struct dp_hdcp_dev {
void *fd;
struct sde_hdcp_ops *ops;
@ -229,6 +235,13 @@ static const struct of_device_id dp_dt_match[] = {
{}
};
bool is_skip_required(struct dp_display *display)
{
if (!display)
return false;
return display->cont_splash_enabled;
}
static inline bool dp_display_is_hdcp_enabled(struct dp_display_private *dp)
{
return dp->link->hdcp_status.hdcp_version && dp->hdcp.ops;
@ -304,6 +317,35 @@ static void dp_audio_enable(struct dp_display_private *dp, bool enable)
}
}
static int dp_display_parse_boot_display_selection(void)
{
char *pos = NULL;
char disp_buf[MAX_CMDLINE_PARAM_LEN] = {'\0'};
int i, j;
for (i = 0; i < MAX_DP_ACTIVE_BOOT_DISPLAY; i++) {
strlcpy(disp_buf, boot_displays[i].boot_param,
MAX_CMDLINE_PARAM_LEN);
pos = strnstr(disp_buf, ":", strlen(disp_buf));
/* Use ':' as a delimiter to retrieve the display name */
if (!pos) {
DP_DEBUG("display name[%s]is not valid\n", disp_buf);
continue;
}
for (j = 0; (disp_buf + j) < pos; j++)
boot_displays[i].name[j] = *(disp_buf + j);
boot_displays[i].name[j] = '\0';
boot_displays[i].boot_disp_en = true;
}
return 0;
}
static void dp_display_update_hdcp_status(struct dp_display_private *dp,
bool reset)
{
@ -1060,6 +1102,8 @@ static int dp_display_host_init(struct dp_display_private *dp)
bool flip = false;
bool reset;
int rc = 0;
bool skip_op = is_skip_required(&dp->dp_display);
if (dp_display_state_is(DP_STATE_INITIALIZED)) {
dp_display_state_log("[already initialized]");
@ -1079,7 +1123,7 @@ static int dp_display_host_init(struct dp_display_private *dp)
}
dp->hpd->host_init(dp->hpd, &dp->catalog->hpd);
rc = dp->ctrl->init(dp->ctrl, flip, reset);
rc = dp->ctrl->init(dp->ctrl, flip, reset, skip_op);
if (rc) {
DP_WARN("Ctrl init Failed.\n");
SDE_EVT32_EXTERNAL(SDE_EVTLOG_FUNC_CASE2, dp->state);
@ -1122,7 +1166,8 @@ static int dp_display_panel_ready(struct dp_display_private *dp)
return -ETIMEDOUT;
}
}
dp->panel->init(dp->panel);
if (!dp->dp_display.cont_splash_enabled)
dp->panel->init(dp->panel);
return 0;
}
@ -1130,6 +1175,7 @@ static int dp_display_panel_ready(struct dp_display_private *dp)
static int dp_display_host_ready(struct dp_display_private *dp)
{
int rc = 0;
bool skip_op;
if (!dp_display_state_is(DP_STATE_INITIALIZED)) {
rc = dp_display_host_init(dp);
@ -1160,11 +1206,11 @@ static int dp_display_host_ready(struct dp_display_private *dp)
* the connect/disconnect notifications do not currently have any
* sessions IDs.
*/
skip_op = dp->dp_display.cont_splash_enabled;
dp->aux->abort(dp->aux, false);
dp->ctrl->abort(dp->ctrl, false);
dp->aux->init(dp->aux, dp->parser->aux_cfg);
dp->aux->init(dp->aux, dp->parser->aux_cfg, skip_op);
dp_display_state_add(DP_STATE_READY);
/* log this as it results from user action of cable connection */
DP_INFO("[OK]\n");
@ -1220,6 +1266,7 @@ static int dp_display_process_hpd_high(struct dp_display_private *dp)
int rc = -EINVAL;
unsigned long wait_timeout_ms;
unsigned long t;
bool skip_op = is_skip_required(&dp->dp_display);
SDE_EVT32_EXTERNAL(SDE_EVTLOG_FUNC_ENTRY, dp->state);
mutex_lock(&dp->session_lock);
@ -1302,7 +1349,7 @@ static int dp_display_process_hpd_high(struct dp_display_private *dp)
dp_display_mst_init(dp);
rc = dp->ctrl->on(dp->ctrl, dp->mst.mst_active,
dp->panel->fec_en, dp->panel->dsc_en, false);
dp->panel->fec_en, dp->panel->dsc_en, false, skip_op);
if (rc) {
dp_display_state_remove(DP_STATE_CONNECTED);
goto end;
@ -1702,8 +1749,9 @@ static int dp_display_stream_enable(struct dp_display_private *dp,
struct dp_panel *dp_panel)
{
int rc = 0;
bool skip_op = is_skip_required(&dp->dp_display);
rc = dp->ctrl->stream_on(dp->ctrl, dp_panel);
rc = dp->ctrl->stream_on(dp->ctrl, dp_panel, skip_op);
if (dp->debug->tpg_state)
dp_panel->tpg_config(dp_panel, true);
@ -1742,6 +1790,7 @@ static void dp_display_attention_work(struct work_struct *work)
struct dp_display_private *dp = container_of(work,
struct dp_display_private, attention_work);
int rc = 0;
bool skip_op = is_skip_required(&dp->dp_display);
SDE_EVT32_EXTERNAL(SDE_EVTLOG_FUNC_ENTRY, dp->state);
mutex_lock(&dp->session_lock);
@ -1805,18 +1854,18 @@ static void dp_display_attention_work(struct work_struct *work)
if (dp->link->sink_request & DP_TEST_LINK_PHY_TEST_PATTERN) {
SDE_EVT32_EXTERNAL(dp->state,
DP_TEST_LINK_PHY_TEST_PATTERN);
dp->ctrl->process_phy_test_request(dp->ctrl);
dp->ctrl->process_phy_test_request(dp->ctrl, skip_op);
}
if (dp->link->sink_request & DP_TEST_LINK_TRAINING) {
SDE_EVT32_EXTERNAL(dp->state, DP_TEST_LINK_TRAINING);
dp->link->send_test_response(dp->link);
rc = dp->ctrl->link_maintenance(dp->ctrl);
rc = dp->ctrl->link_maintenance(dp->ctrl, skip_op);
}
if (dp->link->sink_request & DP_LINK_STATUS_UPDATED) {
SDE_EVT32_EXTERNAL(dp->state, DP_LINK_STATUS_UPDATED);
rc = dp->ctrl->link_maintenance(dp->ctrl);
rc = dp->ctrl->link_maintenance(dp->ctrl, skip_op);
}
if (!rc)
@ -2066,6 +2115,9 @@ static int dp_init_sub_modules(struct dp_display_private *dp)
goto error_pll;
}
if (dp->dp_display.cont_splash_enabled)
dp->pll->cont_splash_enabled = 1;
dp->power = dp_power_get(dp->parser, dp->pll);
if (IS_ERR(dp->power)) {
rc = PTR_ERR(dp->power);
@ -2283,6 +2335,7 @@ static int dp_display_prepare(struct dp_display *dp_display, void *panel)
struct dp_panel *dp_panel;
int rc = 0;
bool shallow_mode = true;
bool skip_op = is_skip_required(dp_display);
if (!dp_display || !panel) {
DP_ERR("invalid input\n");
@ -2385,7 +2438,7 @@ static int dp_display_prepare(struct dp_display *dp_display, void *panel)
* and required things.
*/
rc = dp->ctrl->on(dp->ctrl, dp->mst.mst_active, dp_panel->fec_en,
dp_panel->dsc_en, shallow_mode);
dp_panel->dsc_en, shallow_mode, skip_op);
if (rc)
goto end;
@ -2573,6 +2626,11 @@ end:
static void dp_display_stream_post_enable(struct dp_display_private *dp,
struct dp_panel *dp_panel)
{
if (dp->dp_display.cont_splash_enabled) {
dp->dp_display.cont_splash_enabled = false;
dp->pll->cont_splash_enabled = false;
}
dp_panel->spd_config(dp_panel);
dp_panel->setup_hdr(dp_panel, NULL, false, 0, true);
}
@ -3953,6 +4011,10 @@ static int dp_display_probe(struct platform_device *pdev)
dp_display->is_edp = (info->display_type == DRM_MODE_CONNECTOR_eDP) ? true : false;
dp_display->edp_detect = dp_display_edp_detect;
if (dp_display->is_edp) {
if (dp_display_get_num_of_boot_displays())
dp_display->cont_splash_enabled = 1;
}
rc = component_add(&pdev->dev, &dp_display_comp_ops);
if (rc) {
DP_ERR("component add failed, rc=%d\n", rc);
@ -3985,6 +4047,17 @@ int dp_display_get_displays(void **displays, int count)
return i;
}
int dp_display_get_num_of_boot_displays(void)
{
int i;
int count = 0;
for (i = 0; i < MAX_DP_ACTIVE_BOOT_DISPLAY; i++) {
if (boot_displays[i].boot_disp_en == true)
count++;
}
return count;
}
int dp_display_get_num_of_displays(void)
{
int i;
@ -4151,7 +4224,7 @@ static struct platform_driver dp_display_driver = {
void __init dp_display_register(void)
{
dp_display_parse_boot_display_selection();
platform_driver_register(&dp_display_driver);
}
@ -4159,3 +4232,7 @@ void __exit dp_display_unregister(void)
{
platform_driver_unregister(&dp_display_driver);
}
module_param_string(edp_display0, edp_display_primary, MAX_CMDLINE_PARAM_LEN,
0600);
MODULE_PARM_DESC(edp_display0,
"msm_drm.edp_display0=<display node>: where <display node> is 'primary dp display node name' ");

View file

@ -16,6 +16,9 @@
#define DP_MST_SIM_MAX_PORTS 8
#define MAX_DP_ACTIVE_DISPLAY 8
#define MAX_DP_ACTIVE_BOOT_DISPLAY 1
#define MAX_CMDLINE_PARAM_LEN 512
enum dp_drv_state {
PM_DEFAULT,
@ -39,6 +42,13 @@ struct dp_display_info {
u32 stream_cnt;
};
struct dp_display_boot_param {
char name[MAX_CMDLINE_PARAM_LEN];
char *boot_param;
bool boot_disp_en;
void *disp;
};
struct dp_mst_drm_cbs {
void (*hpd)(void *display, bool hpd_status);
void (*hpd_irq)(void *display, struct dp_mst_hpd_info *info);
@ -86,6 +96,7 @@ struct dp_display {
void *dp_mst_prv_info;
u32 max_mixer_count;
u32 max_dsc_count;
bool cont_splash_enabled;
int (*enable)(struct dp_display *dp_display, void *panel);
int (*post_enable)(struct dp_display *dp_display, void *panel);
@ -149,9 +160,9 @@ struct dp_display {
u32 strm_id, const char **display_type);
int (*edp_detect)(struct dp_display *dp_display);
};
#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);
@ -160,6 +171,10 @@ 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;

View file

@ -463,6 +463,7 @@ int dp_connector_get_info(struct drm_connector *connector,
if (display && display->is_edp) {
info->intf_type = DRM_MODE_CONNECTOR_eDP;
info->display_type = SDE_CONNECTOR_PRIMARY;
info->is_connected = true;
} else {
info->capabilities |= MSM_DISPLAY_CAP_HOT_PLUG;
}

View file

@ -127,7 +127,7 @@ struct dp_pll {
bool ssc_en;
bool bonding_en;
bool cont_splash_enabled;
void *priv;
struct dp_pll_db pll_db;
struct dp_pll_vco_clk pll_clks[DP_PLL_NUM_CLKS];

View file

@ -277,6 +277,8 @@ static int edp_config_vco_rate_7nm(struct dp_pll *pll,
DP_ERR("VCO Init DB failed\n");
return rc;
}
if (pll->cont_splash_enabled)
return 0;
dp_pll_write(dp_phy, DP_PHY_PD_CTL, 0x7d);
/* Make sure the PLL register writes are done */
@ -460,6 +462,11 @@ static int edp_pll_enable_7nm(struct dp_pll *pll)
pll->aux->state &= ~DP_STATE_PLL_LOCKED;
if (pll->cont_splash_enabled) {
pll->aux->state |= DP_STATE_PLL_LOCKED;
return rc;
}
dp_pll_write(dp_phy, DP_PHY_CFG, 0x01);
dp_pll_write(dp_phy, DP_PHY_CFG, 0x05);
dp_pll_write(dp_phy, DP_PHY_CFG, 0x01);
@ -790,6 +797,9 @@ static int edp_pll_vco_div_clk_set_rate(struct clk_hw *hw, unsigned long rate,
pll_link = to_dp_vco_hw(hw);
pll = pll_link->priv;
if (pll->cont_splash_enabled)
return rc;
if (rate != edp_pll_vco_div_clk_get_rate(pll)) {
DP_ERR("unsupported rate %lu failed\n", rate);
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 &&
@ -4426,7 +4436,8 @@ static int _sde_kms_get_splash_data(struct sde_kms *sde_kms,
* cont_splash_region should be collection of all memory regions
* Ex: <r1.start r1.end r2.start r2.end ... rn.start, rn.end>
*/
num_displays = dsi_display_get_num_of_displays();
num_displays = dsi_display_get_num_of_displays()
+ dp_display_get_num_of_boot_displays();
num_regions = of_property_count_u64_elems(node, "reg") / 2;
data->num_splash_displays = num_displays;