浏览代码

disp: msm: sde: read demura plane status registers on cont-splash boot

Extrapolate the Demura plane configuration from the Demura DSPP block
on cont-splash boot, and pass this information to DRM clients via a
CRTC property. This will allow user-space to be aware of all plane
reservations, and avoid plane mangling in multi display use-cases.

Change-Id: I6d216f555fcddbd19c18b6209dc830c21f6be5a4
Signed-off-by: Christopher Braga <[email protected]>
Christopher Braga 5 年之前
父节点
当前提交
dc1af2c9d5

+ 83 - 0
msm/sde/sde_color_processing.c

@@ -1291,6 +1291,47 @@ static void _sde_cp_crtc_install_immutable_property(struct drm_crtc *crtc,
 				feature, val);
 	_sde_cp_crtc_attach_property(&prop_attach);
 }
+
+static void _sde_cp_crtc_install_bitmask_property(struct drm_crtc *crtc,
+		char *name, u32 feature, bool immutable,
+		const struct drm_prop_enum_list *list, u32 enum_sz,
+		u64 supported_bits)
+{
+	struct drm_property *prop;
+	struct sde_cp_node *prop_node = NULL;
+	struct msm_drm_private *priv;
+	struct sde_cp_prop_attach prop_attach;
+	int flags = immutable ? DRM_MODE_PROP_IMMUTABLE : 0;
+	uint64_t val = 0;
+
+	if (feature >=  SDE_CP_CRTC_MAX_FEATURES) {
+		DRM_ERROR("invalid feature %d max %d\n", feature,
+			  SDE_CP_CRTC_MAX_FEATURES);
+		return;
+	}
+
+	prop_node = kzalloc(sizeof(*prop_node), GFP_KERNEL);
+	if (!prop_node)
+		return;
+
+	priv = crtc->dev->dev_private;
+	prop = priv->cp_property[feature];
+
+	if (!prop) {
+		prop = drm_property_create_bitmask(crtc->dev, flags, name, list,
+				enum_sz, supported_bits);
+		if (!prop) {
+			DRM_ERROR("property create failed: %s\n", name);
+			kfree(prop_node);
+			return;
+		}
+		priv->cp_property[feature] = prop;
+	}
+
+	INIT_PROP_ATTACH(&prop_attach, crtc, prop, prop_node, feature, val);
+	_sde_cp_crtc_attach_property(&prop_attach);
+}
+
 static void _sde_cp_crtc_install_range_property(struct drm_crtc *crtc,
 					     char *name,
 					     u32 feature,
@@ -2184,6 +2225,44 @@ static int _sde_cp_crtc_set_range_prop(
 	return ret;
 }
 
+void sde_cp_crtc_refresh_status_properties(struct drm_crtc *crtc)
+{
+	struct sde_crtc *sde_crtc = NULL;
+	int i = 0;
+	struct sde_hw_dspp *hw_dspp = NULL;
+	struct msm_drm_private *priv;
+	struct drm_property *prop;
+	u64 val = 0;
+
+	if (!crtc) {
+		DRM_ERROR("invalid crtc %pKn", crtc);
+		return;
+	}
+
+	sde_crtc = to_sde_crtc(crtc);
+	if (!sde_crtc) {
+		DRM_ERROR("invalid sde_crtc %pK\n", sde_crtc);
+		return;
+	}
+
+	priv = crtc->dev->dev_private;
+	prop = priv->cp_property[SDE_CP_CRTC_DSPP_DEMURA_BOOT_PLANE];
+	if (!prop)
+		return;
+
+	for (i = 0; i < sde_crtc->num_mixers; i++) {
+		u32 status = 0;
+
+		hw_dspp = sde_crtc->mixers[i].hw_dspp;
+		if (hw_dspp && hw_dspp->ops.demura_read_plane_status) {
+			hw_dspp->ops.demura_read_plane_status(hw_dspp, &status);
+			if (status != DEM_FETCH_DMA_INVALID)
+				val |= 1 << status;
+		}
+	}
+	drm_object_property_set_value(&crtc->base, prop, val);
+}
+
 int sde_cp_crtc_set_property(struct drm_crtc *crtc,
 				struct drm_crtc_state *state,
 				struct drm_property *property,
@@ -3029,6 +3108,10 @@ static  void _dspp_demura_install_property(struct drm_crtc *crtc)
 		_sde_cp_crtc_install_range_property(crtc, "SDE_DEMURA_BACKLIGHT_V1",
 				SDE_CP_CRTC_DSPP_DEMURA_BACKLIGHT,
 				0, 1024, 0);
+		_sde_cp_crtc_install_bitmask_property(crtc, "SDE_DEMURA_BOOT_PLANE_V1",
+				SDE_CP_CRTC_DSPP_DEMURA_BOOT_PLANE, true,
+				sde_demura_fetch_planes,
+				ARRAY_SIZE(sde_demura_fetch_planes), 0xf);
 		break;
 	default:
 		DRM_ERROR("version %d not supported\n", version);

+ 9 - 0
msm/sde/sde_color_processing.h

@@ -104,6 +104,7 @@ enum sde_cp_crtc_features {
 	SDE_CP_CRTC_DSPP_SPR_INIT,
 	SDE_CP_CRTC_DSPP_DEMURA_INIT,
 	SDE_CP_CRTC_DSPP_DEMURA_BACKLIGHT,
+	SDE_CP_CRTC_DSPP_DEMURA_BOOT_PLANE,
 	SDE_CP_CRTC_DSPP_MAX,
 	/* DSPP features end */
 
@@ -161,6 +162,14 @@ void sde_cp_crtc_install_properties(struct drm_crtc *crtc);
  */
 void sde_cp_crtc_destroy_properties(struct drm_crtc *crtc);
 
+/**
+ * sde_cp_crtc_refresh_status_properties(): Updates color processing
+ *                                    properties reflecting the status
+ *                                    of the crtc.
+ * @crtc: Pointer to crtc.
+ */
+void sde_cp_crtc_refresh_status_properties(struct drm_crtc *crtc);
+
 /**
  * sde_cp_crtc_set_property: Set a color processing property
  *                                      for a crtc.

+ 1 - 0
msm/sde/sde_crtc.c

@@ -7228,6 +7228,7 @@ void sde_crtc_update_cont_splash_settings(struct drm_crtc *crtc)
 	}
 
 	_sde_crtc_setup_mixers(crtc);
+	sde_cp_crtc_refresh_status_properties(crtc);
 	crtc->enabled = true;
 
 	/* update core clk value for initial state with cont-splash */

+ 28 - 1
msm/sde/sde_hw_color_proc_common_v4.h

@@ -1,12 +1,39 @@
 /* SPDX-License-Identifier: GPL-2.0-only */
 /*
- * Copyright (c) 2017-2019, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2017-2019, 2021 The Linux Foundation. All rights reserved.
  */
 #ifndef _SDE_HW_COLOR_PROC_COMMON_V4_H_
 #define _SDE_HW_COLOR_PROC_COMMON_V4_H_
 
 #include "sde_hw_mdss.h"
 
+/*
+ * DEMURA fetch planes
+ * @DEM_FETCH_DMA1_RECT0      Demura data fetched from DMA plane 1 rectangle 0
+ * @DEM_FETCH_DMA1_RECT1      Demura data fetched from DMA plane 1 rectangle 1
+ * @DEM_FETCH_DMA3_RECT0      Demura data fetched from DMA plane 3 rectangle 0
+ * @DEM_FETCH_DMA3_RECT1      Demura data fetched from DMA plane 3 rectangle 1
+ * @DEM_FETCH_DMA_INVALID     Invalid DMA plane for fetching Demmura data
+ */
+enum demura_fetch_planes {
+	DEM_FETCH_DMA1_RECT0 = 0,
+	DEM_FETCH_DMA1_RECT1,
+	DEM_FETCH_DMA3_RECT0,
+	DEM_FETCH_DMA3_RECT1,
+	DEM_FETCH_DMA_INVALID,
+};
+
+/**
+ * struct sde_demura_fetch_planes - drm prop enun struct containing bit
+ *     mask enum properties and values
+ */
+static const struct drm_prop_enum_list sde_demura_fetch_planes[] = {
+	{DEM_FETCH_DMA1_RECT0, "demura_dma1_rect0"},
+	{DEM_FETCH_DMA1_RECT1, "demura_dma1_rect1"},
+	{DEM_FETCH_DMA3_RECT0, "demura_dma3_rect0"},
+	{DEM_FETCH_DMA3_RECT1, "demura_dma3_rect1"},
+};
+
 #define GAMUT_TABLE_SEL_OFF 0x4
 #define GAMUT_UPPER_COLOR_OFF 0x8
 #define GAMUT_LOWER_COLOR_OFF 0xc

+ 33 - 5
msm/sde/sde_hw_color_proc_v4.c

@@ -398,19 +398,20 @@ void sde_ltm_read_intr_status(struct sde_hw_dspp *ctx, u32 *status)
 	SDE_REG_WRITE(&ctx->hw, ctx->cap->sblk->ltm.base + 0x58, clear);
 }
 
-void sde_demura_backlight_cfg(struct sde_hw_dspp *dspp, u64 val)
+void sde_demura_backlight_cfg(struct sde_hw_dspp *ctx, u64 val)
 {
 	u32 demura_base;
 	u32 backlight;
 
-	if (!dspp) {
-		DRM_ERROR("invalid parameter ctx %pK", dspp);
+	if (!ctx) {
+		DRM_ERROR("invalid parameter ctx %pK", ctx);
 		return;
 	}
-	demura_base = dspp->cap->sblk->demura.base;
+
+	demura_base = ctx->cap->sblk->demura.base;
 	backlight = (val & REG_MASK(11));
 	backlight |= ((val & REG_MASK_SHIFT(11, 32)) >> 16);
-	SDE_REG_WRITE(&dspp->hw, dspp->cap->sblk->demura.base + 0x8,
+	SDE_REG_WRITE(&ctx->hw, ctx->cap->sblk->demura.base + 0x8,
 			backlight);
 }
 
@@ -608,3 +609,30 @@ void sde_setup_fp16_unmultv1(struct sde_hw_pipe *ctx,
 
 	SDE_REG_WRITE(&ctx->hw, unmult_base, unmult);
 }
+
+void sde_demura_read_plane_status(struct sde_hw_dspp *ctx, u32 *status)
+{
+	u32 demura_base;
+	u32 value;
+
+	if (!ctx) {
+		DRM_ERROR("invalid parameter ctx %pK", ctx);
+		return;
+	}
+
+	demura_base = ctx->cap->sblk->demura.base;
+	value = SDE_REG_READ(&ctx->hw, demura_base + 0x4);
+	if (!(value & 0x4)) {
+		*status = DEM_FETCH_DMA_INVALID;
+	} else if (ctx->idx == DSPP_0) {
+		if (value & 0x80000000)
+			*status = DEM_FETCH_DMA1_RECT0;
+		else
+			*status = DEM_FETCH_DMA3_RECT0;
+	} else {
+		if (value & 0x80000000)
+			*status = DEM_FETCH_DMA1_RECT1;
+		else
+			*status = DEM_FETCH_DMA3_RECT1;
+	}
+}

+ 10 - 3
msm/sde/sde_hw_color_proc_v4.h

@@ -1,6 +1,6 @@
 /* SPDX-License-Identifier: GPL-2.0-only */
 /*
- * Copyright (c) 2017-2021, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2017-2019, 2021 The Linux Foundation. All rights reserved.
  */
 #ifndef _SDE_HW_COLOR_PROC_V4_H_
 #define _SDE_HW_COLOR_PROC_V4_H_
@@ -74,10 +74,17 @@ void sde_ltm_read_intr_status(struct sde_hw_dspp *dspp, u32 *status);
 
 /**
  * sde_demura_backlight_cfg - api to set backlight for demura
- * @dspp: pointer to dspp object
+ * @ctx: pointer to dspp object
  * @val: value of backlight
  */
-void sde_demura_backlight_cfg(struct sde_hw_dspp *dspp, u64 val);
+void sde_demura_backlight_cfg(struct sde_hw_dspp *ctx, u64 val);
+
+/**
+ * sde_demura_read_plane_status - api to read demura plane fetch setup.
+ * @ctx: pointer to dspp object.
+ * @status: Currently present plane. Reported as a demura_fetch_planes value.
+ */
+void sde_demura_read_plane_status(struct sde_hw_dspp *ctx, u32 *status);
 
 /**
  * sde_setup_fp16_cscv1 - api to set FP16 CSC cp block

+ 4 - 2
msm/sde/sde_hw_dspp.c

@@ -1,6 +1,6 @@
 // SPDX-License-Identifier: GPL-2.0-only
 /*
- * Copyright (c) 2015-2020, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2015-2021, The Linux Foundation. All rights reserved.
  */
 
 #include <drm/msm_drm_pp.h>
@@ -328,7 +328,9 @@ static void dspp_demura(struct sde_hw_dspp *c)
 		if (!ret) {
 			c->ops.setup_demura_cfg = reg_dmav1_setup_demurav1;
 			c->ops.setup_demura_backlight_cfg =
-				sde_demura_backlight_cfg;
+					sde_demura_backlight_cfg;
+			c->ops.demura_read_plane_status =
+					sde_demura_read_plane_status;
 		}
 	}
 }

+ 8 - 1
msm/sde/sde_hw_dspp.h

@@ -1,6 +1,6 @@
 /* SPDX-License-Identifier: GPL-2.0-only */
 /*
- * Copyright (c) 2015-2020, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2015-2021, The Linux Foundation. All rights reserved.
  */
 
 #ifndef _SDE_HW_DSPP_H
@@ -276,6 +276,13 @@ struct sde_hw_dspp_ops {
 	 * @status: Pointer to configuration.
 	 */
 	void (*setup_demura_backlight_cfg)(struct sde_hw_dspp *ctx, u64 val);
+
+	/**
+	 * demura_read_plane_status - Query demura plane status
+	 * @ctx: Pointer to dspp context
+	 * @status: Demura plane used by DSPP. demura_fetch_planes enum value.
+	 */
+	void (*demura_read_plane_status)(struct sde_hw_dspp *ctx, u32 *status);
 };
 
 /**