disp: msm: dp: wait for resources init in case of cont splash

Driver probe has to wait for dp resource initialization,
in case of continuous splash to avoid any resource resets.

Change-Id: Idaa506b14132d22b9bfe558c88ab6d33171b4f3b
Signed-off-by: Nilesh Laad <quic_nlaad@quicinc.com>
This commit is contained in:
Nilesh Laad 2023-06-23 17:42:52 +05:30 • committed by Gerrit - the friendly Code Review server
commit 452e643352
3 changed files with 99 additions and 1 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,42 @@ 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;
@ -1358,6 +1395,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);
@ -3990,6 +4030,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";

View file

@ -168,6 +168,7 @@ 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)
{
@ -194,5 +195,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

@ -1800,7 +1800,7 @@ static int _sde_kms_setup_displays(struct drm_device *dev,
.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,
@ -3381,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;
@ -3531,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;
}