mirror of
https://github.com/BobTheBlinker/android_kernel_motorola_sm6375.git
synced 2026-10-08 12:58:12 -04:00
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:
commit
a3b00b3487
10 changed files with 187 additions and 45 deletions
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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 */
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
|
|
|
|||
|
|
@ -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' ");
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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];
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
Loading…
Reference in a new issue