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

Commit e9b20774 authored by Xu Yang's avatar Xu Yang
Browse files

drm/msm/sde: add support for PA VLUT version 1.8



VLUT in PA block is used by ABA features to adjust the
contrast. Change adds support for PA VLUT 1.8 AHB path
to enable/disable VLUT control, set VLUT data, and enable
VLUT flush bit.

Change-Id: I80167f866d051f43341f6272312bfc74195dd46d
Signed-off-by: default avatarXu Yang <yangxu@codeaurora.org>
parent 1d9aee75
Loading
Loading
Loading
Loading
+60 −0
Original line number Diff line number Diff line
@@ -12,6 +12,7 @@

#include <drm/msm_drm_pp.h>
#include "sde_hw_color_processing_v1_7.h"
#include "sde_hw_ctl.h"

#define PA_HUE_VIG_OFF		0x110
#define PA_SAT_VIG_OFF		0x114
@@ -26,6 +27,9 @@
#define PA_LUTV_DSPP_OFF	0x1400
#define PA_LUT_SWAP_OFF		0x234

#define PA_LUTV_DSPP_CTRL_OFF	0x4c
#define PA_LUTV_DSPP_SWAP_OFF	0x18

#define PA_HUE_MASK		0xFFF
#define PA_SAT_MASK		0xFFFF
#define PA_VAL_MASK		0xFF
@@ -458,6 +462,62 @@ void sde_setup_dspp_pa_vlut_v1_7(struct sde_hw_dspp *ctx, void *cfg)
	SDE_REG_WRITE(&ctx->hw, base, op_mode);
}

void sde_setup_dspp_pa_vlut_v1_8(struct sde_hw_dspp *ctx, void *cfg)
{
	struct drm_msm_pa_vlut *payload = NULL;
	struct sde_hw_cp_cfg *hw_cfg = cfg;
	struct sde_hw_ctl *ctl = NULL;
	u32 vlut_base, pa_hist_base;
	u32 ctrl_off, swap_off;
	u32 tmp = 0;
	int i = 0, j = 0;
	u32 flush_mask = 0;

	if (!ctx) {
		DRM_ERROR("invalid input parameter NULL ctx\n");
		return;
	}

	if (!hw_cfg || (hw_cfg->payload && hw_cfg->len !=
			sizeof(struct drm_msm_pa_vlut))) {
		DRM_ERROR("hw %pK payload %pK payloadsize %d exp size %zd\n",
			  hw_cfg, ((hw_cfg) ? hw_cfg->payload : NULL),
			  ((hw_cfg) ? hw_cfg->len : 0),
			  sizeof(struct drm_msm_pa_vlut));
		return;
	}

	ctl = hw_cfg->ctl;
	vlut_base = ctx->cap->sblk->vlut.base;
	pa_hist_base = ctx->cap->sblk->hist.base;
	ctrl_off = pa_hist_base + PA_LUTV_DSPP_CTRL_OFF;
	swap_off = pa_hist_base + PA_LUTV_DSPP_SWAP_OFF;

	if (!hw_cfg->payload) {
		DRM_DEBUG_DRIVER("Disable vlut feature\n");
		SDE_REG_WRITE(&ctx->hw, ctrl_off, 0);
		goto exit;
	}

	payload = hw_cfg->payload;
	DRM_DEBUG_DRIVER("Enable vlut feature flags %llx\n", payload->flags);
	for (i = 0, j = 0; i < ARRAY_SIZE(payload->val); i += 2, j += 4) {
		tmp = (payload->val[i] & REG_MASK(10)) |
			((payload->val[i + 1] & REG_MASK(10)) << 16);
		SDE_REG_WRITE(&ctx->hw, (vlut_base + j), tmp);
	}
	SDE_REG_WRITE(&ctx->hw, ctrl_off, 1);
	SDE_REG_WRITE(&ctx->hw, swap_off, 1);

exit:
	/* update flush bit */
	if (ctl && ctl->ops.get_bitmask_dspp_pavlut) {
		ctl->ops.get_bitmask_dspp_pavlut(ctl, &flush_mask, ctx->idx);
		if (ctl->ops.update_pending_flush)
			ctl->ops.update_pending_flush(ctl, flush_mask);
	}
}

void sde_setup_dspp_gc_v1_7(struct sde_hw_dspp *ctx, void *cfg)
{
	struct drm_msm_pgc_lut *payload = NULL;
+7 −0
Original line number Diff line number Diff line
@@ -75,6 +75,13 @@ void sde_setup_dspp_pa_hue_v1_7(struct sde_hw_dspp *ctx, void *cfg);
 */
void sde_setup_dspp_pa_vlut_v1_7(struct sde_hw_dspp *ctx, void *cfg);

/**
 * sde_setup_dspp_pa_vlut_v1_8 - setup DSPP PA vLUT feature in v1.8 hardware
 * @ctx: Pointer to DSPP context
 * @cfg: Pointer to vLUT data
 */
void sde_setup_dspp_pa_vlut_v1_8(struct sde_hw_dspp *ctx, void *cfg);

/**
 * sde_setup_dspp_gc_v1_7 - setup DSPP gc feature in v1.7 hardware
 * @ctx: Pointer to DSPP context
+17 −0
Original line number Diff line number Diff line
@@ -239,6 +239,22 @@ static inline int sde_hw_ctl_get_bitmask_dspp(struct sde_hw_ctl *ctx,
	return 0;
}

static inline int sde_hw_ctl_get_bitmask_dspp_pavlut(struct sde_hw_ctl *ctx,
		u32 *flushbits, enum sde_dspp dspp)
{
	switch (dspp) {
	case DSPP_0:
		*flushbits |= BIT(3);
		break;
	case DSPP_1:
		*flushbits |= BIT(4);
		break;
	default:
		return -EINVAL;
	}
	return 0;
}

static inline int sde_hw_ctl_get_bitmask_intf(struct sde_hw_ctl *ctx,
		u32 *flushbits, enum sde_intf intf)
{
@@ -565,6 +581,7 @@ static void _setup_ctl_ops(struct sde_hw_ctl_ops *ops,
	ops->get_bitmask_sspp = sde_hw_ctl_get_bitmask_sspp;
	ops->get_bitmask_mixer = sde_hw_ctl_get_bitmask_mixer;
	ops->get_bitmask_dspp = sde_hw_ctl_get_bitmask_dspp;
	ops->get_bitmask_dspp_pavlut = sde_hw_ctl_get_bitmask_dspp_pavlut;
	ops->get_bitmask_intf = sde_hw_ctl_get_bitmask_intf;
	ops->get_bitmask_cdm = sde_hw_ctl_get_bitmask_cdm;
	ops->get_bitmask_wb = sde_hw_ctl_get_bitmask_wb;
+4 −0
Original line number Diff line number Diff line
@@ -173,6 +173,10 @@ struct sde_hw_ctl_ops {
		u32 *flushbits,
		enum sde_dspp blk);

	int (*get_bitmask_dspp_pavlut)(struct sde_hw_ctl *ctx,
		u32 *flushbits,
		enum sde_dspp blk);

	int (*get_bitmask_intf)(struct sde_hw_ctl *ctx,
		u32 *flushbits,
		enum sde_intf blk);
+4 −1
Original line number Diff line number Diff line
@@ -82,9 +82,12 @@ static void _setup_dspp_ops(struct sde_hw_dspp *c, unsigned long features)
			} else if (c->cap->sblk->vlut.version ==
					(SDE_COLOR_PROCESS_VER(0x1, 0x8))) {
				ret = reg_dmav1_init_dspp_op_v4(i, c->idx);
				if (ret)
				if (!ret)
					c->ops.setup_vlut =
					reg_dmav1_setup_dspp_vlutv18;
				else
					c->ops.setup_vlut =
					sde_setup_dspp_pa_vlut_v1_8;
			}
			break;
		case SDE_DSPP_GAMUT:
Loading