From db39b61a5f06eed2d1d1acbb33c6eb3d99449e23 Mon Sep 17 00:00:00 2001 From: Christopher Braga Date: Mon, 29 Jun 2020 14:36:09 -0400 Subject: [PATCH] disp: msm: sde: populate DRM pipeline setup during cont-splash Declare the continuous splash pipeline setup to userspace by filling in the DRM states for all plane, crtc, encoder, and connector objects in use. This information will be treated as an 'informative' state, and will be cleared at the start of the first commit to maintain the DRM methodology of DRM clients being the only controller of the pipeline. This ensures any configuration provided by userspace is accepted and applied, even if it may already align with the setup done by continuous splash. This DRM state configuration is done via manual modification of the DRM object states. Modification via the exposed DRM UAPI functions is not possible due to no drm_atomic_state object linking the DRM pipeline objects together. Change-Id: I67650e05aafbb4e799cf60939f0595bc3786fc6e Signed-off-by: Christopher Braga --- msm/sde/sde_connector.c | 5 +++++ msm/sde/sde_connector.h | 3 +++ msm/sde/sde_crtc.c | 10 ++++++++++ msm/sde/sde_crtc.h | 2 ++ msm/sde/sde_kms.c | 17 ++++++++++++++++- msm/sde/sde_plane.c | 6 ++++++ msm/sde/sde_plane.h | 5 ++++- 7 files changed, 46 insertions(+), 2 deletions(-) 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; }; /**