Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 28916c92 authored by Alexander Beykun's avatar Alexander Beykun
Browse files

drm/msm/sde: add inverse pma support



Alpha unmultiply unit (inverse PMA) is used when alpha value already
applied to source content and have to be unmultipled before gamut
conversion. Patch adds inverse PMA support to vig and dma pipes,
exposes "inverse_pma" capabilities to user space.

Change-Id: I5c1ddbac8e943d1d52ee0b49de86c78e9e99728e
Signed-off-by: default avatarAlexander Beykun <abeykun@codeaurora.org>
parent 6f0f0541
Loading
Loading
Loading
Loading
+7 −0
Original line number Diff line number Diff line
@@ -214,6 +214,8 @@ Optional properties:
				-- qcom,sde-vig-memcolor: offset and version of PA memcolor hardware
				-- qcom,sde-vig-gamut: offset and version of 3D LUT Gamut hardware
				-- qcom,sde-vig-igc: offset and version of 1D LUT IGC hardware
				-- qcom,sde-vig-inverse-pma: Boolean property to indicate if
				inverse PMA feature is available on VIG pipe
- qcom,sde-sspp-dma-blocks:	A node that lists the blocks inside the DMA hardware. There
				can be more than one instance of this binding, in which case the
				entry would be appended with dgm entry index. Each entry will
@@ -224,6 +226,8 @@ Optional properties:
				-- dgm@0
				-- qcom,sde-dma-igc: offset and version of DMA IGC
				-- qcom,sde-dma-gc: offset and version of DMA GC
				-- qcom,sde-dma-inverse-pma: Boolean property to indicate if
				inverse PMA feature is available on DMA pipe
- qcom,sde-sspp-rgb-blocks:	A node that lists the blocks inside the RGB hardware. The
				block entries will contain the offset and version (if needed)
				of each feature block. The presence of a block entry
@@ -680,16 +684,19 @@ Example:
        qcom,sde-vig-hsic = <0x200 0x00010000>;
        qcom,sde-vig-memcolor = <0x200 0x00010000>;
        qcom,sde-vig-pcc = <0x1780 0x00010000>;
        qcom,sde-vig-inverse-pma;
    };

    qcom,sde-sspp-dma-blocks {
	dgm@0 {
		qcom,sde-dma-igc = <0x400 0x00050000>;
		qcom,sde-dma-gc = <0x600 0x00050000>;
		qcom,sde-dma-inverse-pma;
	}
	dgm@1 {
		qcom,sde-dma-igc = <0x1400 0x00050000>;
		qcom,sde-dma-gc = <0x600 0x00050000>;
		qcom,sde-dma-inverse-pma;
	}
    };

+1 −0
Original line number Diff line number Diff line
@@ -121,6 +121,7 @@ enum msm_mdp_plane_property {
	PLANE_PROP_SCALER_V1,
	PLANE_PROP_SCALER_V2,
	PLANE_PROP_ROT_OUT_FB,
	PLANE_PROP_INVERSE_PMA,

	/* enum/bitmask properties */
	PLANE_PROP_BLEND_OP,
+17 −2
Original line number Diff line number Diff line
@@ -216,6 +216,7 @@ enum {
	VIG_PCC_PROP,
	VIG_GAMUT_PROP,
	VIG_IGC_PROP,
	VIG_INVERSE_PMA,
	VIG_PROP_MAX,
};

@@ -229,6 +230,7 @@ enum {
enum {
	DMA_IGC_PROP,
	DMA_GC_PROP,
	DMA_DGM_INVERSE_PMA,
	DMA_PROP_MAX,
};

@@ -507,6 +509,7 @@ static struct sde_prop_type vig_prop[] = {
	{VIG_PCC_PROP, "qcom,sde-vig-pcc", false, PROP_TYPE_U32_ARRAY},
	{VIG_GAMUT_PROP, "qcom,sde-vig-gamut", false, PROP_TYPE_U32_ARRAY},
	{VIG_IGC_PROP, "qcom,sde-vig-igc", false, PROP_TYPE_U32_ARRAY},
	{VIG_INVERSE_PMA, "qcom,sde-vig-inverse-pma", false, PROP_TYPE_BOOL},
};

static struct sde_prop_type rgb_prop[] = {
@@ -518,6 +521,8 @@ static struct sde_prop_type rgb_prop[] = {
static struct sde_prop_type dma_prop[] = {
	{DMA_IGC_PROP, "qcom,sde-dma-igc", false, PROP_TYPE_U32_ARRAY},
	{DMA_GC_PROP, "qcom,sde-dma-gc", false, PROP_TYPE_U32_ARRAY},
	{DMA_DGM_INVERSE_PMA, "qcom,sde-dma-inverse-pma", false,
		PROP_TYPE_BOOL},
};

static struct sde_prop_type ctl_prop[] = {
@@ -1064,6 +1069,9 @@ static void _sde_sspp_setup_vig(struct sde_mdss_cfg *sde_cfg,
		set_bit(SDE_SSPP_VIG_IGC, &sspp->features);
	}

	if (PROP_VALUE_ACCESS(prop_value, VIG_INVERSE_PMA, 0))
		set_bit(SDE_SSPP_INVERSE_PMA, &sspp->features);

	sblk->format_list = sde_cfg->vig_formats;
	sblk->virt_format_list = sde_cfg->dma_formats;
}
@@ -1191,6 +1199,11 @@ static void _sde_sspp_setup_dma(struct sde_mdss_cfg *sde_cfg,
			sblk->gc_blk[i].len = 0;
			set_bit(SDE_SSPP_DMA_GC, &sspp->features);
		}

		if (PROP_VALUE_ACCESS(&prop_value[i * DMA_PROP_MAX],
			DMA_DGM_INVERSE_PMA, 0))
			set_bit(SDE_SSPP_DGM_INVERSE_PMA, &sspp->features);

	}
}

@@ -1299,8 +1312,10 @@ static int sde_sspp_parse_dt(struct device_node *np,
			dgm_prop_value = kzalloc(dgm_count * DMA_PROP_MAX *
					sizeof(struct sde_prop_value),
					GFP_KERNEL);
			if (!dgm_prop_value)
				return -ENOMEM;
			if (!dgm_prop_value) {
				rc = -ENOMEM;
				goto end;
			}
			for (i = 0; i < dgm_count; i++)
				sde_dgm_parse_dt(snp, i,
					&dgm_prop_value[i * DMA_PROP_MAX],
+4 −0
Original line number Diff line number Diff line
@@ -142,6 +142,8 @@ enum {
 * @SDE_SSPP_VIG_GAMUT,      VIG 3D LUT Gamut
 * @SDE_SSPP_DMA_IGC,        DMA 1D LUT IGC
 * @SDE_SSPP_DMA_GC,         DMA 1D LUT GC
 * @SDE_SSPP_INVERSE_PMA     Alpha unmultiply (PMA) support
 * @SDE_SSPP_DGM_INVERSE_PMA Alpha unmultiply (PMA) support in DGM block
 * @SDE_SSPP_MAX             maximum value
 */
enum {
@@ -168,6 +170,8 @@ enum {
	SDE_SSPP_VIG_GAMUT,
	SDE_SSPP_DMA_IGC,
	SDE_SSPP_DMA_GC,
	SDE_SSPP_INVERSE_PMA,
	SDE_SSPP_DGM_INVERSE_PMA,
	SDE_SSPP_MAX
};

+46 −0
Original line number Diff line number Diff line
@@ -48,6 +48,11 @@
#define SSPP_EXCL_REC_SIZE_REC1            0x184
#define SSPP_EXCL_REC_XY_REC1              0x188

/* SSPP_DGM */
#define SSPP_DGM_OP_MODE                   0x804
#define SSPP_DGM_OP_MODE_REC1              0x1804
#define SSPP_GAMUT_UNMULT_MODE             0x1EA0

#define MDSS_MDP_OP_DEINTERLACE            BIT(22)
#define MDSS_MDP_OP_DEINTERLACE_ODD        BIT(23)
#define MDSS_MDP_OP_IGC_ROM_1              BIT(18)
@@ -985,6 +990,42 @@ static void _setup_layer_ops_colorproc(struct sde_hw_pipe *c,
	}
}

static void sde_hw_sspp_setup_inverse_pma(struct sde_hw_pipe *ctx,
			enum sde_sspp_multirect_index index, u32 enable)
{
	u32 op_mode = 0;

	if (!ctx || (index == SDE_SSPP_RECT_1))
		return;

	if (enable)
		op_mode |= BIT(0);

	SDE_REG_WRITE(&ctx->hw, SSPP_GAMUT_UNMULT_MODE, op_mode);
}

static void sde_hw_sspp_setup_dgm_inverse_pma(struct sde_hw_pipe *ctx,
			enum sde_sspp_multirect_index index, u32 enable)
{
	u32 offset = SSPP_DGM_OP_MODE;
	u32 op_mode = 0;

	if (!ctx)
		return;

	if (index == SDE_SSPP_RECT_1)
		offset = SSPP_DGM_OP_MODE_REC1;

	op_mode = SDE_REG_READ(&ctx->hw, offset);

	if (enable)
		op_mode |= BIT(0);
	else
		op_mode &= ~BIT(0);

	SDE_REG_WRITE(&ctx->hw, offset, op_mode);
}

static void _setup_layer_ops(struct sde_hw_pipe *c,
		unsigned long features)
{
@@ -1036,6 +1077,11 @@ static void _setup_layer_ops(struct sde_hw_pipe *c,
		c->ops.setup_cdp = sde_hw_sspp_setup_cdp;

	_setup_layer_ops_colorproc(c, features);

	if (test_bit(SDE_SSPP_DGM_INVERSE_PMA, &features))
		c->ops.setup_inverse_pma = sde_hw_sspp_setup_dgm_inverse_pma;
	else if (test_bit(SDE_SSPP_INVERSE_PMA, &features))
		c->ops.setup_inverse_pma = sde_hw_sspp_setup_inverse_pma;
}

static struct sde_sspp_cfg *_sspp_offset(enum sde_sspp sspp,
Loading