Browse Source

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 <[email protected]>
Christopher Braga 5 years ago
parent
commit
db39b61a5f
7 changed files with 46 additions and 2 deletions
  1. 5 0
      msm/sde/sde_connector.c
  2. 3 0
      msm/sde/sde_connector.h
  3. 10 0
      msm/sde/sde_crtc.c
  4. 2 0
      msm/sde/sde_crtc.h
  5. 16 1
      msm/sde/sde_kms.c
  6. 6 0
      msm/sde/sde_plane.c
  7. 4 1
      msm/sde/sde_plane.h

+ 5 - 0
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");

+ 3 - 0
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;
 };
 
 /**

+ 10 - 0
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");

+ 2 - 0
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 {

+ 16 - 1
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) {

+ 6 - 0
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");

+ 4 - 1
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 <[email protected]>
  *
@@ -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;
 };
 
 /**