Browse Source

drm: sde: Remove feature support for IGC/3D LUT for virtual planes

Attempts by virtual planes to set IGC and 3D LUT values are unsupported
and will result in LUTDMA hangs. Update virtual DRM planes capabilities
to disallow these features and make any attempts to set them a NOP.

Change-Id: I50eee7e981208ba53dfae833ab53b8fd0e5cda4e
Signed-off-by: Christopher Braga <[email protected]>
Christopher Braga 6 năm trước cách đây
mục cha
commit
47ecefa419
1 tập tin đã thay đổi với 21 bổ sung5 xóa
  1. 21 5
      msm/sde/sde_hw_sspp.c

+ 21 - 5
msm/sde/sde_hw_sspp.c

@@ -1023,10 +1023,16 @@ static void sde_hw_sspp_setup_uidle(struct sde_hw_pipe *ctx,
 }
 
 static void _setup_layer_ops_colorproc(struct sde_hw_pipe *c,
-		unsigned long features)
+		unsigned long features, bool is_virtual_pipe)
 {
 	int ret = 0;
 
+	if (is_virtual_pipe) {
+		features &=
+			~(BIT(SDE_SSPP_VIG_IGC) | BIT(SDE_SSPP_VIG_GAMUT));
+		c->cap->features = features;
+	}
+
 	if (test_bit(SDE_SSPP_HSIC, &features)) {
 		if (c->cap->sblk->hsic_blk.version ==
 			(SDE_COLOR_PROCESS_VER(0x1, 0x7))) {
@@ -1181,7 +1187,8 @@ static void sde_hw_sspp_setup_dgm_csc(struct sde_hw_pipe *ctx,
 }
 
 static void _setup_layer_ops(struct sde_hw_pipe *c,
-		unsigned long features, unsigned long perf_features)
+		unsigned long features, unsigned long perf_features,
+		bool is_virtual_pipe)
 {
 	int ret;
 
@@ -1247,7 +1254,7 @@ static void _setup_layer_ops(struct sde_hw_pipe *c,
 	if (test_bit(SDE_PERF_SSPP_UIDLE, &perf_features))
 		c->ops.setup_uidle = sde_hw_sspp_setup_uidle;
 
-	_setup_layer_ops_colorproc(c, features);
+	_setup_layer_ops_colorproc(c, features, is_virtual_pipe);
 
 	if (test_bit(SDE_SSPP_DGM_INVERSE_PMA, &features))
 		c->ops.setup_inverse_pma = sde_hw_sspp_setup_dgm_inverse_pma;
@@ -1264,6 +1271,7 @@ static struct sde_sspp_cfg *_sspp_offset(enum sde_sspp sspp,
 		struct sde_hw_blk_reg_map *b)
 {
 	int i;
+	struct sde_sspp_cfg *cfg;
 
 	if ((sspp < SSPP_MAX) && catalog && addr && b) {
 		for (i = 0; i < catalog->sspp_count; i++) {
@@ -1273,7 +1281,14 @@ static struct sde_sspp_cfg *_sspp_offset(enum sde_sspp sspp,
 				b->length = catalog->sspp[i].len;
 				b->hwversion = catalog->hwversion;
 				b->log_mask = SDE_DBG_MASK_SSPP;
-				return &catalog->sspp[i];
+
+				/* Only shallow copy is needed */
+				cfg =  kmemdup(&catalog->sspp[i], sizeof(*cfg),
+					GFP_KERNEL);
+				if (!cfg)
+					return ERR_PTR(-ENOMEM);
+
+				return cfg;
 			}
 		}
 	}
@@ -1313,7 +1328,7 @@ struct sde_hw_pipe *sde_hw_sspp_init(enum sde_sspp idx,
 	hw_pipe->idx = idx;
 	hw_pipe->cap = cfg;
 	_setup_layer_ops(hw_pipe, hw_pipe->cap->features,
-		hw_pipe->cap->perf_features);
+		hw_pipe->cap->perf_features, is_virtual_pipe);
 
 	if (hw_pipe->ops.get_scaler_ver) {
 		sde_init_scaler_blk(&hw_pipe->cap->sblk->scaler_blk,
@@ -1353,6 +1368,7 @@ void sde_hw_sspp_destroy(struct sde_hw_pipe *ctx)
 	if (ctx) {
 		sde_hw_blk_destroy(&ctx->base);
 		reg_dmav1_deinit_sspp_ops(ctx->idx);
+		kfree(ctx->cap);
 	}
 	kfree(ctx);
 }