diff --git a/msm/dp/dp_aux.c b/msm/dp/dp_aux.c index ae00856bb3da..7c4fbc2fbb50 100644 --- a/msm/dp/dp_aux.c +++ b/msm/dp/dp_aux.c @@ -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; diff --git a/msm/dp/dp_aux.h b/msm/dp/dp_aux.h index 850941b1e53d..aa762e91acf7 100644 --- a/msm/dp/dp_aux.h +++ b/msm/dp/dp_aux.h @@ -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); diff --git a/msm/dp/dp_ctrl.c b/msm/dp/dp_ctrl.c index 395d5a7e1cc9..4f935764cc21 100644 --- a/msm/dp/dp_ctrl.c +++ b/msm/dp/dp_ctrl.c @@ -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 */ diff --git a/msm/dp/dp_ctrl.h b/msm/dp/dp_ctrl.h index 225a4bf54daf..0f506d7294d8 100644 --- a/msm/dp/dp_ctrl.h +++ b/msm/dp/dp_ctrl.h @@ -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, diff --git a/msm/dp/dp_display.c b/msm/dp/dp_display.c index 11349989c449..292c6cef76a2 100644 --- a/msm/dp/dp_display.c +++ b/msm/dp/dp_display.c @@ -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=: where is 'primary dp display node name' "); diff --git a/msm/dp/dp_display.h b/msm/dp/dp_display.h index 892322fa2fc2..13181732cf32 100644 --- a/msm/dp/dp_display.h +++ b/msm/dp/dp_display.h @@ -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; diff --git a/msm/dp/dp_drm.c b/msm/dp/dp_drm.c index 6e054af5dc3d..1342726043e8 100644 --- a/msm/dp/dp_drm.c +++ b/msm/dp/dp_drm.c @@ -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; } diff --git a/msm/dp/dp_pll.h b/msm/dp/dp_pll.h index fa56964ab533..780a00c6dbfa 100644 --- a/msm/dp/dp_pll.h +++ b/msm/dp/dp_pll.h @@ -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]; diff --git a/msm/dp/edp_pll_7nm.c b/msm/dp/edp_pll_7nm.c index da26cb657884..1f3b60a1f325 100644 --- a/msm/dp/edp_pll_7nm.c +++ b/msm/dp/edp_pll_7nm.c @@ -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; diff --git a/msm/sde/sde_kms.c b/msm/sde/sde_kms.c index 308200bd8579..b416840b5f7c 100644 --- a/msm/sde/sde_kms.c +++ b/msm/sde/sde_kms.c @@ -4426,7 +4426,8 @@ static int _sde_kms_get_splash_data(struct sde_kms *sde_kms, * cont_splash_region should be collection of all memory regions * Ex: */ - 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;