diff --git a/msm/sde/sde_connector.c b/msm/sde/sde_connector.c index daf048a9eb..f8cb79cc24 100644 --- a/msm/sde/sde_connector.c +++ b/msm/sde/sde_connector.c @@ -1166,6 +1166,11 @@ sde_connector_atomic_duplicate_state(struct drm_connector *connector) c_conn = to_sde_connector(connector); c_oldstate = to_sde_connector_state(connector->state); + if (c_oldstate->cont_splash_populated) { + connector->state->crtc = NULL; + c_oldstate->cont_splash_populated = false; + } + c_state = msm_property_alloc_state(&c_conn->property_info); if (!c_state) { SDE_ERROR("state alloc failed\n"); diff --git a/msm/sde/sde_connector.h b/msm/sde/sde_connector.h index 1dbb6ca631..0d266a5b43 100644 --- a/msm/sde/sde_connector.h +++ b/msm/sde/sde_connector.h @@ -618,6 +618,7 @@ struct sde_connector { * @msm_mode: struct containing drm_mode and downstream private variables * @old_topology_name: topology of previous atomic state. remove this in later * kernel versions which provide drm_atomic_state old_state pointers + * @cont_splash_populated: State was populated as part of cont. splash */ struct sde_connector_state { struct drm_connector_state base; @@ -632,6 +633,8 @@ struct sde_connector_state { struct sde_connector_dyn_hdr_metadata dyn_hdr_meta; struct msm_display_mode msm_mode; enum sde_rm_topology_name old_topology_name; + + bool cont_splash_populated; }; /** diff --git a/msm/sde/sde_crtc.c b/msm/sde/sde_crtc.c index b394cfc8a7..0db31587d9 100644 --- a/msm/sde/sde_crtc.c +++ b/msm/sde/sde_crtc.c @@ -4005,6 +4005,16 @@ static struct drm_crtc_state *sde_crtc_duplicate_state(struct drm_crtc *crtc) sde_crtc = to_sde_crtc(crtc); old_cstate = to_sde_crtc_state(crtc->state); + + if (old_cstate->cont_splash_populated) { + crtc->state->plane_mask = 0; + crtc->state->connector_mask = 0; + crtc->state->encoder_mask = 0; + + crtc->state->enable = false; + old_cstate->cont_splash_populated = false; + } + cstate = msm_property_alloc_state(&sde_crtc->property_info); if (!cstate) { SDE_ERROR("failed to allocate state\n"); diff --git a/msm/sde/sde_crtc.h b/msm/sde/sde_crtc.h index 3862fdc1b5..05291137e7 100644 --- a/msm/sde/sde_crtc.h +++ b/msm/sde/sde_crtc.h @@ -431,6 +431,7 @@ enum sde_crtc_dirty_flags { * @cp_prop_values: array of cp property values * @cp_dirty_list: array tracking features that are dirty * @cp_range_payload: array storing state user_data passed via range props + * @cont_splash_populated: State was populated as part of cont. splash */ struct sde_crtc_state { struct drm_crtc_state base; @@ -468,6 +469,7 @@ struct sde_crtc_state { uint32_t cp_dirty_list[SDE_CP_CRTC_MAX_FEATURES]; struct sde_cp_crtc_range_prop_payload cp_range_payload[SDE_CP_CRTC_MAX_FEATURES]; + bool cont_splash_populated; }; enum sde_crtc_irq_state { diff --git a/msm/sde/sde_kms.c b/msm/sde/sde_kms.c index 8703a0a5c2..f3d0e8169d 100644 --- a/msm/sde/sde_kms.c +++ b/msm/sde/sde_kms.c @@ -2889,6 +2889,7 @@ static int _sde_kms_update_planes_for_cont_splash(struct sde_kms *sde_kms, struct msm_drm_private *priv; struct drm_plane *plane; struct sde_splash_mem *splash; + struct sde_plane_state *pstate; enum sde_sspp plane_id; bool is_virtual; int i, j; @@ -2918,6 +2919,10 @@ static int _sde_kms_update_planes_for_cont_splash(struct sde_kms *sde_kms, plane_id, crtc->base.id); } + plane->state->crtc = crtc; + crtc->state->plane_mask |= drm_plane_mask(plane); + pstate = to_sde_plane_state(plane->state); + pstate->cont_splash_populated = true; SDE_DEBUG("set crtc:%d for plane:%d rect:%d\n", crtc->base.id, plane_id, is_virtual); } @@ -3115,6 +3120,9 @@ static int sde_kms_cont_splash_config(struct msm_kms *kms, /* dsi */ for (i = 0; i < sde_kms->dsi_display_count; ++i) { + struct sde_crtc_state *cstate; + struct sde_connector_state *conn_state; + display = sde_kms->dsi_displays[i]; dsi_display = (struct dsi_display *)display; splash_display = &sde_kms->splash_data.splash_display[i]; @@ -3189,7 +3197,9 @@ static int sde_kms_cont_splash_config(struct msm_kms *kms, } mutex_unlock(&dev->mode_config.mutex); - crtc->state->encoder_mask = (1 << drm_encoder_index(encoder)); + crtc->state->encoder_mask = drm_encoder_mask(encoder); + crtc->state->connector_mask = drm_connector_mask(connector); + connector->state->crtc = crtc; drm_mode = _sde_kms_get_splash_mode(sde_kms, connector, state); if (!drm_mode) { @@ -3211,6 +3221,8 @@ static int sde_kms_cont_splash_config(struct msm_kms *kms, } drm_mode_copy(&crtc->state->adjusted_mode, drm_mode); drm_mode_copy(&crtc->mode, drm_mode); + cstate = to_sde_crtc_state(crtc->state); + cstate->cont_splash_populated = true; /* Update encoder structure */ sde_encoder_update_caps_for_cont_splash(encoder, @@ -3222,6 +3234,9 @@ static int sde_kms_cont_splash_config(struct msm_kms *kms, if (sde_conn && sde_conn->ops.cont_splash_config) sde_conn->ops.cont_splash_config(sde_conn->display); + conn_state = to_sde_connector_state(connector->state); + conn_state->cont_splash_populated = true; + rc = _sde_kms_update_planes_for_cont_splash(sde_kms, splash_display, crtc); if (rc) { diff --git a/msm/sde/sde_plane.c b/msm/sde/sde_plane.c index 1639c67523..5b28672f17 100644 --- a/msm/sde/sde_plane.c +++ b/msm/sde/sde_plane.c @@ -4294,6 +4294,12 @@ sde_plane_duplicate_state(struct drm_plane *plane) old_state = to_sde_plane_state(plane->state); psde = to_sde_plane(plane); + + if (old_state->cont_splash_populated) { + plane->state->crtc = NULL; + old_state->cont_splash_populated = false; + } + pstate = msm_property_alloc_state(&psde->property_info); if (!pstate) { SDE_ERROR_PLANE(psde, "failed to allocate state\n"); diff --git a/msm/sde/sde_plane.h b/msm/sde/sde_plane.h index 86c3fdb199..f2ce03a6a3 100644 --- a/msm/sde/sde_plane.h +++ b/msm/sde/sde_plane.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015-2020, The Linux Foundation. All rights reserved. + * Copyright (c) 2015-2021, The Linux Foundation. All rights reserved. * Copyright (C) 2013 Red Hat * Author: Rob Clark * @@ -110,6 +110,7 @@ enum sde_plane_sclcheck_state { * @rotation: rotation cache state * @static_cache_state: plane cache state for static image * @cdp_cfg: CDP configuration + * @cont_splash_populated: State was populated as part of cont. splash */ struct sde_plane_state { struct drm_plane_state base; @@ -141,6 +142,8 @@ struct sde_plane_state { uint32_t static_cache_state; struct sde_hw_pipe_cdp_cfg cdp_cfg; + + bool cont_splash_populated; }; /**