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

Commit 7b8fbae9 authored by Rajesh Yadav's avatar Rajesh Yadav
Browse files

drm/msm/sde: Add support for dspp pa memcolor features



Change adds support for dspp pa memcolor feature to
color processing module present in CRTC.

Change-Id: Iadff377a9914c1567c0d8329e229380d77555952
Signed-off-by: default avatarRajesh Yadav <ryadav@codeaurora.org>
parent 0a92eead
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -197,6 +197,7 @@
		qcom,sde-dspp-blocks {
			qcom,sde-dspp-igc = <0x0 0x00030001>;
			qcom,sde-dspp-hsic = <0x800 0x00010007>;
			qcom,sde-dspp-memcolor = <0x880 0x00010007>;
			qcom,sde-dspp-sixzone= <0x900 0x00010007>;
			qcom,sde-dspp-vlut = <0xa00 0x00010008>;
			qcom,sde-dspp-gamut = <0x1000 0x00040000>;
+70 −4
Original line number Diff line number Diff line
@@ -52,6 +52,8 @@ static void dspp_pcc_install_property(struct drm_crtc *crtc);

static void dspp_hsic_install_property(struct drm_crtc *crtc);

static void dspp_memcolor_install_property(struct drm_crtc *crtc);

static void dspp_sixzone_install_property(struct drm_crtc *crtc);

static void dspp_ad_install_property(struct drm_crtc *crtc);
@@ -83,6 +85,7 @@ static void sde_cp_ad_set_prop(struct sde_crtc *sde_crtc,
do { \
	func[SDE_DSPP_PCC] = dspp_pcc_install_property; \
	func[SDE_DSPP_HSIC] = dspp_hsic_install_property; \
	func[SDE_DSPP_MEMCOLOR] = dspp_memcolor_install_property; \
	func[SDE_DSPP_SIXZONE] = dspp_sixzone_install_property; \
	func[SDE_DSPP_AD] = dspp_ad_install_property; \
	func[SDE_DSPP_VLUT] = dspp_vlut_install_property; \
@@ -107,7 +110,10 @@ enum {
	SDE_CP_CRTC_DSPP_PCC,
	SDE_CP_CRTC_DSPP_GC,
	SDE_CP_CRTC_DSPP_HSIC,
	SDE_CP_CRTC_DSPP_MEMCOLOR,
	SDE_CP_CRTC_DSPP_MEMCOL_SKIN,
	SDE_CP_CRTC_DSPP_MEMCOL_SKY,
	SDE_CP_CRTC_DSPP_MEMCOL_FOLIAGE,
	SDE_CP_CRTC_DSPP_MEMCOL_PROT,
	SDE_CP_CRTC_DSPP_SIXZONE,
	SDE_CP_CRTC_DSPP_GAMUT,
	SDE_CP_CRTC_DSPP_DITHER,
@@ -590,12 +596,33 @@ static void sde_cp_crtc_setfeature(struct sde_cp_node *prop_node,
			}
			hw_dspp->ops.setup_pa_hsic(hw_dspp, &hw_cfg);
			break;
		case SDE_CP_CRTC_DSPP_MEMCOLOR:
			if (!hw_dspp || !hw_dspp->ops.setup_pa_memcolor) {
		case SDE_CP_CRTC_DSPP_MEMCOL_SKIN:
			if (!hw_dspp || !hw_dspp->ops.setup_pa_memcol_skin) {
				ret = -EINVAL;
				continue;
			}
			hw_dspp->ops.setup_pa_memcol_skin(hw_dspp, &hw_cfg);
			break;
		case SDE_CP_CRTC_DSPP_MEMCOL_SKY:
			if (!hw_dspp || !hw_dspp->ops.setup_pa_memcol_sky) {
				ret = -EINVAL;
				continue;
			}
			hw_dspp->ops.setup_pa_memcolor(hw_dspp, &hw_cfg);
			hw_dspp->ops.setup_pa_memcol_sky(hw_dspp, &hw_cfg);
			break;
		case SDE_CP_CRTC_DSPP_MEMCOL_FOLIAGE:
			if (!hw_dspp || !hw_dspp->ops.setup_pa_memcol_foliage) {
				ret = -EINVAL;
				continue;
			}
			hw_dspp->ops.setup_pa_memcol_foliage(hw_dspp, &hw_cfg);
			break;
		case SDE_CP_CRTC_DSPP_MEMCOL_PROT:
			if (!hw_dspp || !hw_dspp->ops.setup_pa_memcol_prot) {
				ret = -EINVAL;
				continue;
			}
			hw_dspp->ops.setup_pa_memcol_prot(hw_dspp, &hw_cfg);
			break;
		case SDE_CP_CRTC_DSPP_SIXZONE:
			if (!hw_dspp || !hw_dspp->ops.setup_sixzone) {
@@ -1080,6 +1107,45 @@ static void dspp_hsic_install_property(struct drm_crtc *crtc)
	}
}

static void dspp_memcolor_install_property(struct drm_crtc *crtc)
{
	char feature_name[256];
	struct sde_kms *kms = NULL;
	struct sde_mdss_cfg *catalog = NULL;
	u32 version;

	kms = get_kms(crtc);
	catalog = kms->catalog;
	version = catalog->dspp[0].sblk->memcolor.version >> 16;
	switch (version) {
	case 1:
		snprintf(feature_name, ARRAY_SIZE(feature_name), "%s%d",
			"SDE_DSPP_PA_MEMCOL_SKIN_V", version);
		sde_cp_crtc_install_blob_property(crtc, feature_name,
			SDE_CP_CRTC_DSPP_MEMCOL_SKIN,
			sizeof(struct drm_msm_memcol));
		snprintf(feature_name, ARRAY_SIZE(feature_name), "%s%d",
			"SDE_DSPP_PA_MEMCOL_SKY_V", version);
		sde_cp_crtc_install_blob_property(crtc, feature_name,
			SDE_CP_CRTC_DSPP_MEMCOL_SKY,
			sizeof(struct drm_msm_memcol));
		snprintf(feature_name, ARRAY_SIZE(feature_name), "%s%d",
			"SDE_DSPP_PA_MEMCOL_FOLIAGE_V", version);
		sde_cp_crtc_install_blob_property(crtc, feature_name,
			SDE_CP_CRTC_DSPP_MEMCOL_FOLIAGE,
			sizeof(struct drm_msm_memcol));
		snprintf(feature_name, ARRAY_SIZE(feature_name), "%s%d",
			"SDE_DSPP_PA_MEMCOL_PROT_V", version);
		sde_cp_crtc_install_blob_property(crtc, feature_name,
			SDE_CP_CRTC_DSPP_MEMCOL_PROT,
			sizeof(struct drm_msm_memcol));
		break;
	default:
		DRM_ERROR("version %d not supported\n", version);
		break;
	}
}

static void dspp_sixzone_install_property(struct drm_crtc *crtc)
{
	char feature_name[256];
+2 −1
Original line number Diff line number Diff line
@@ -26,7 +26,8 @@ struct sde_irq_callback;
enum sde_memcolor_type {
	MEMCOLOR_SKIN = 0,
	MEMCOLOR_SKY,
	MEMCOLOR_FOLIAGE
	MEMCOLOR_FOLIAGE,
	MEMCOLOR_MAX
};

/**
+235 −0
Original line number Diff line number Diff line
@@ -81,6 +81,27 @@
#define DSPP_SZ_THRESHOLDS_OFF	0x8
#define DSPP_PA_PWL_HOLD_OFF	0x40

#define DSPP_MEMCOL_SIZE0	0x14
#define DSPP_MEMCOL_SIZE1	0x8
#define DSPP_MEMCOL_PWL0_OFF	0x0
#define DSPP_MEMCOL_PWL2_OFF	0x3C
#define DSPP_MEMCOL_HOLD_SIZE	0x4

#define DSPP_MEMCOL_PROT_VAL_EN BIT(24)
#define DSPP_MEMCOL_PROT_SAT_EN BIT(23)
#define DSPP_MEMCOL_PROT_HUE_EN BIT(22)
#define DSPP_MEMCOL_PROT_CONT_EN BIT(18)
#define DSPP_MEMCOL_PROT_SIXZONE_EN BIT(17)
#define DSPP_MEMCOL_PROT_BLEND_EN BIT(3)

#define DSPP_MEMCOL_MASK \
	(DSPP_OP_PA_SKIN_EN | DSPP_OP_PA_SKY_EN | DSPP_OP_PA_FOL_EN)

#define DSPP_MEMCOL_PROT_MASK \
	(DSPP_MEMCOL_PROT_HUE_EN | DSPP_MEMCOL_PROT_SAT_EN | \
	DSPP_MEMCOL_PROT_VAL_EN | DSPP_MEMCOL_PROT_CONT_EN | \
	DSPP_MEMCOL_PROT_SIXZONE_EN | DSPP_MEMCOL_PROT_BLEND_EN)

#define PA_VIG_DISABLE_REQUIRED(x) \
			!((x) & (VIG_OP_PA_SKIN_EN | VIG_OP_PA_SKY_EN | \
			VIG_OP_PA_FOL_EN | VIG_OP_PA_HUE_EN | \
@@ -433,6 +454,220 @@ void sde_setup_pipe_pa_memcol_v1_7(struct sde_hw_pipe *ctx,
	SDE_REG_WRITE(&ctx->hw, base, op);
}

static void __setup_dspp_memcol(struct sde_hw_dspp *ctx,
		enum sde_memcolor_type type,
		struct drm_msm_memcol *memcolor)
{
	u32 addr = 0, offset = 0, idx = 0;
	u32 hold = 0, local_hold = 0, hold_shift = 0;

	switch (type) {
	case MEMCOLOR_SKIN:
		idx = 0;
		break;
	case MEMCOLOR_SKY:
		idx = 1;
		break;
	case MEMCOLOR_FOLIAGE:
		idx = 2;
		break;
	default:
		DRM_ERROR("Invalid memory color type %d\n", type);
		return;
	}

	offset = DSPP_MEMCOL_PWL0_OFF + (idx * DSPP_MEMCOL_SIZE0);
	addr = ctx->cap->sblk->memcolor.base + offset;
	hold_shift = idx * DSPP_MEMCOL_HOLD_SIZE;

	SDE_REG_WRITE(&ctx->hw, addr, memcolor->color_adjust_p0);
	addr += 4;
	SDE_REG_WRITE(&ctx->hw, addr, memcolor->color_adjust_p1);
	addr += 4;
	SDE_REG_WRITE(&ctx->hw, addr, memcolor->hue_region);
	addr += 4;
	SDE_REG_WRITE(&ctx->hw, addr, memcolor->sat_region);
	addr += 4;
	SDE_REG_WRITE(&ctx->hw, addr, memcolor->val_region);

	offset = DSPP_MEMCOL_PWL2_OFF + (idx * DSPP_MEMCOL_SIZE1);
	addr = ctx->cap->sblk->memcolor.base + offset;

	SDE_REG_WRITE(&ctx->hw, addr, memcolor->color_adjust_p2);
	addr += 4;
	SDE_REG_WRITE(&ctx->hw, addr, memcolor->blend_gain);

	addr = ctx->cap->sblk->hsic.base + DSPP_PA_PWL_HOLD_OFF;
	hold = SDE_REG_READ(&ctx->hw, addr);
	local_hold = ((memcolor->sat_hold & REG_MASK(2)) << hold_shift);
	local_hold |=
		((memcolor->val_hold & REG_MASK(2)) << (hold_shift + 2));
	hold &= ~REG_MASK_SHIFT(4, hold_shift);
	hold |= local_hold;
	SDE_REG_WRITE(&ctx->hw, addr, hold);
}

void sde_setup_dspp_memcol_skin_v17(struct sde_hw_dspp *ctx, void *cfg)
{
	struct sde_hw_cp_cfg *hw_cfg = cfg;
	struct drm_msm_memcol *memcolor;
	u32 opcode = 0;

	if (!ctx || !cfg) {
		DRM_ERROR("invalid param ctx %pK cfg %pK\n", ctx, cfg);
		return;
	}

	opcode = SDE_REG_READ(&ctx->hw, ctx->cap->sblk->hsic.base);

	if (!hw_cfg->payload) {
		DRM_DEBUG_DRIVER("disable memcolor skin feature\n");
		opcode &= ~(DSPP_OP_PA_SKIN_EN);
		if (PA_DSPP_DISABLE_REQUIRED(opcode))
			opcode &= ~DSPP_OP_PA_EN;
		SDE_REG_WRITE(&ctx->hw, ctx->cap->sblk->hsic.base, opcode);
		return;
	}

	if (hw_cfg->len != sizeof(struct drm_msm_memcol)) {
		DRM_ERROR("invalid size of payload len %d exp %zd\n",
			hw_cfg->len, sizeof(struct drm_msm_memcol));
		return;
	}

	memcolor = hw_cfg->payload;

	__setup_dspp_memcol(ctx, MEMCOLOR_SKIN, memcolor);

	opcode |= (DSPP_OP_PA_SKIN_EN | DSPP_OP_PA_EN);
	SDE_REG_WRITE(&ctx->hw, ctx->cap->sblk->hsic.base, opcode);
}

void sde_setup_dspp_memcol_sky_v17(struct sde_hw_dspp *ctx, void *cfg)
{
	struct sde_hw_cp_cfg *hw_cfg = cfg;
	struct drm_msm_memcol *memcolor;
	u32 opcode = 0;

	if (!ctx || !cfg) {
		DRM_ERROR("invalid param ctx %pK cfg %pK\n", ctx, cfg);
		return;
	}

	opcode = SDE_REG_READ(&ctx->hw, ctx->cap->sblk->hsic.base);

	if (!hw_cfg->payload) {
		DRM_DEBUG_DRIVER("disable memcolor sky feature\n");
		opcode &= ~(DSPP_OP_PA_SKY_EN);
		if (PA_DSPP_DISABLE_REQUIRED(opcode))
			opcode &= ~DSPP_OP_PA_EN;
		SDE_REG_WRITE(&ctx->hw, ctx->cap->sblk->hsic.base, opcode);
		return;
	}

	if (hw_cfg->len != sizeof(struct drm_msm_memcol)) {
		DRM_ERROR("invalid size of payload len %d exp %zd\n",
			hw_cfg->len, sizeof(struct drm_msm_memcol));
		return;
	}

	memcolor = hw_cfg->payload;

	__setup_dspp_memcol(ctx, MEMCOLOR_SKY, memcolor);

	opcode |= (DSPP_OP_PA_SKY_EN | DSPP_OP_PA_EN);
	SDE_REG_WRITE(&ctx->hw, ctx->cap->sblk->hsic.base, opcode);
}

void sde_setup_dspp_memcol_foliage_v17(struct sde_hw_dspp *ctx, void *cfg)
{
	struct sde_hw_cp_cfg *hw_cfg = cfg;
	struct drm_msm_memcol *memcolor;
	u32 opcode = 0;

	if (!ctx || !cfg) {
		DRM_ERROR("invalid param ctx %pK cfg %pK\n", ctx, cfg);
		return;
	}

	opcode = SDE_REG_READ(&ctx->hw, ctx->cap->sblk->hsic.base);

	if (!hw_cfg->payload) {
		DRM_DEBUG_DRIVER("disable memcolor foliage feature\n");
		opcode &= ~(DSPP_OP_PA_FOL_EN);
		if (PA_DSPP_DISABLE_REQUIRED(opcode))
			opcode &= ~DSPP_OP_PA_EN;
		SDE_REG_WRITE(&ctx->hw, ctx->cap->sblk->hsic.base, opcode);
		return;
	}

	if (hw_cfg->len != sizeof(struct drm_msm_memcol)) {
		DRM_ERROR("invalid size of payload len %d exp %zd\n",
			hw_cfg->len, sizeof(struct drm_msm_memcol));
		return;
	}

	memcolor = hw_cfg->payload;

	__setup_dspp_memcol(ctx, MEMCOLOR_FOLIAGE, memcolor);

	opcode |= (DSPP_OP_PA_FOL_EN | DSPP_OP_PA_EN);
	SDE_REG_WRITE(&ctx->hw, ctx->cap->sblk->hsic.base, opcode);
}

void sde_setup_dspp_memcol_prot_v17(struct sde_hw_dspp *ctx, void *cfg)
{
	struct sde_hw_cp_cfg *hw_cfg = cfg;
	struct drm_msm_memcol *memcolor;
	u32 opcode = 0, local_opcode = 0;

	if (!ctx || !cfg) {
		DRM_ERROR("invalid param ctx %pK cfg %pK\n", ctx, cfg);
		return;
	}

	opcode = SDE_REG_READ(&ctx->hw, ctx->cap->sblk->hsic.base);

	if (!hw_cfg->payload) {
		DRM_DEBUG_DRIVER("disable memcolor prot feature\n");
		opcode &= ~(DSPP_MEMCOL_PROT_MASK);
		if (PA_DSPP_DISABLE_REQUIRED(opcode))
			opcode &= ~DSPP_OP_PA_EN;
		SDE_REG_WRITE(&ctx->hw, ctx->cap->sblk->hsic.base, opcode);
		return;
	}

	if (hw_cfg->len != sizeof(struct drm_msm_memcol)) {
		DRM_ERROR("invalid size of payload len %d exp %zd\n",
			hw_cfg->len, sizeof(struct drm_msm_memcol));
		return;
	}

	memcolor = hw_cfg->payload;

	if (memcolor->prot_flags) {
		if (memcolor->prot_flags & MEMCOL_PROT_HUE)
			local_opcode |= DSPP_MEMCOL_PROT_HUE_EN;
		if (memcolor->prot_flags & MEMCOL_PROT_SAT)
			local_opcode |= DSPP_MEMCOL_PROT_SAT_EN;
		if (memcolor->prot_flags & MEMCOL_PROT_VAL)
			local_opcode |= DSPP_MEMCOL_PROT_VAL_EN;
		if (memcolor->prot_flags & MEMCOL_PROT_CONT)
			local_opcode |= DSPP_MEMCOL_PROT_CONT_EN;
		if (memcolor->prot_flags & MEMCOL_PROT_SIXZONE)
			local_opcode |= DSPP_MEMCOL_PROT_SIXZONE_EN;
		if (memcolor->prot_flags & MEMCOL_PROT_BLEND)
			local_opcode |= DSPP_MEMCOL_PROT_BLEND_EN;
	}

	if (local_opcode) {
		local_opcode |= DSPP_OP_PA_EN;
		opcode &= ~(DSPP_MEMCOL_PROT_MASK);
		opcode |= local_opcode;
		SDE_REG_WRITE(&ctx->hw, ctx->cap->sblk->hsic.base, opcode);
	}
}

void sde_setup_dspp_pcc_v1_7(struct sde_hw_dspp *ctx, void *cfg)
{
	struct sde_hw_cp_cfg *hw_cfg = cfg;
+28 −0
Original line number Diff line number Diff line
@@ -68,6 +68,34 @@ void sde_setup_dspp_pcc_v1_7(struct sde_hw_dspp *ctx, void *cfg);
 */
void sde_setup_dspp_pa_hsic_v17(struct sde_hw_dspp *ctx, void *cfg);

/**
 * sde_setup_dspp_memcol_skin_v17 - setup DSPP memcol skin in v1.7 hardware
 * @ctx: Pointer to DSPP context
 * @cfg: Pointer to memcolor config data
 */
void sde_setup_dspp_memcol_skin_v17(struct sde_hw_dspp *ctx, void *cfg);

/**
 * sde_setup_dspp_memcol_sky_v17 - setup DSPP memcol sky in v1.7 hardware
 * @ctx: Pointer to DSPP context
 * @cfg: Pointer to memcolor config data
 */
void sde_setup_dspp_memcol_sky_v17(struct sde_hw_dspp *ctx, void *cfg);

/**
 * sde_setup_dspp_memcol_foliage_v17 - setup DSPP memcol fol in v1.7 hardware
 * @ctx: Pointer to DSPP context
 * @cfg: Pointer to memcolor config data
 */
void sde_setup_dspp_memcol_foliage_v17(struct sde_hw_dspp *ctx, void *cfg);

/**
 * sde_setup_dspp_memcol_prot_v17 - setup DSPP memcol prot in v1.7 hardware
 * @ctx: Pointer to DSPP context
 * @cfg: Pointer to memcolor config data
 */
void sde_setup_dspp_memcol_prot_v17(struct sde_hw_dspp *ctx, void *cfg);

/**
 * sde_setup_dspp_sixzone_v17 - setup DSPP sixzone feature in v1.7 hardware
 * @ctx: Pointer to DSPP context
Loading