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

Commit 49b38f08 authored by Xu Yang's avatar Xu Yang Committed by Gerrit - the friendly Code Review server
Browse files

drm/msm/sde: Support PA dither feature



Support PA dither feature in DSPP to add more precision to the
original integral LUTV value, which improves quality for ABA
features. Change adds property for the feature and implements
AHB path with version 1.7.

Change-Id: I7d4a7816d91691af440366b156ddff941a669c59
Signed-off-by: default avatarXu Yang <yangxu@codeaurora.org>
parent c9ab2da3
Loading
Loading
Loading
Loading
+35 −0
Original line number Diff line number Diff line
@@ -69,6 +69,8 @@ static void dspp_igc_install_property(struct drm_crtc *crtc);

static void dspp_hist_install_property(struct drm_crtc *crtc);

static void dspp_dither_install_property(struct drm_crtc *crtc);

typedef void (*dspp_prop_install_func_t)(struct drm_crtc *crtc);

static dspp_prop_install_func_t dspp_prop_install_func[SDE_DSPP_MAX];
@@ -98,6 +100,7 @@ do { \
	func[SDE_DSPP_GC] = dspp_gc_install_property; \
	func[SDE_DSPP_IGC] = dspp_igc_install_property; \
	func[SDE_DSPP_HIST] = dspp_hist_install_property; \
	func[SDE_DSPP_DITHER] = dspp_dither_install_property; \
} while (0)

typedef void (*lm_prop_install_func_t)(struct drm_crtc *crtc);
@@ -734,6 +737,13 @@ static void sde_cp_crtc_setfeature(struct sde_cp_node *prop_node,
			}
			hw_lm->ops.setup_gc(hw_lm, &hw_cfg);
			break;
		case SDE_CP_CRTC_DSPP_DITHER:
			if (!hw_dspp || !hw_dspp->ops.setup_pa_dither) {
				ret = -EINVAL;
				continue;
			}
			hw_dspp->ops.setup_pa_dither(hw_dspp, &hw_cfg);
			break;
		case SDE_CP_CRTC_DSPP_HIST_CTRL:
			if (!hw_dspp || !hw_dspp->ops.setup_histogram) {
				ret = -EINVAL;
@@ -1492,6 +1502,31 @@ static void dspp_hist_install_property(struct drm_crtc *crtc)
	}
}

static void dspp_dither_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->dither.version >> 16;
	snprintf(feature_name, ARRAY_SIZE(feature_name), "%s%d",
		"SDE_DSPP_PA_DITHER_V", version);
	switch (version) {
	case 1:
		sde_cp_crtc_install_blob_property(crtc, feature_name,
			SDE_CP_CRTC_DSPP_DITHER,
			sizeof(struct drm_msm_pa_dither));
		break;
	default:
		DRM_ERROR("version %d not supported\n", version);
		break;
	}
}

static void sde_cp_update_list(struct sde_cp_node *prop_node,
		struct sde_crtc *crtc, bool dirty_list)
{
+44 −0
Original line number Diff line number Diff line
@@ -35,6 +35,8 @@
#define PA_LUTV_DSPP_CTRL_OFF	0x4c
#define PA_LUTV_DSPP_SWAP_OFF	0x18

#define PA_DITH_DSPP_MATRIX_OFF	0x4

#define PA_HUE_MASK		0xFFF
#define PA_SAT_MASK		0xFFFF
#define PA_VAL_MASK		0xFF
@@ -967,3 +969,45 @@ void sde_lock_dspp_hist_v1_7(struct sde_hw_dspp *ctx, void *cfg)
	/* lock hist buffer */
	SDE_REG_WRITE(&ctx->hw, offset_ctl, 1);
}

void sde_setup_dspp_dither_v1_7(struct sde_hw_dspp *ctx, void *cfg)
{
	struct sde_hw_cp_cfg *hw_cfg = cfg;
	struct drm_msm_pa_dither *dither;
	u32 ctrl_off, matrix_off;
	u32 opmode, data, i;

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

	ctrl_off = ctx->cap->sblk->dither.base;
	matrix_off = ctrl_off + PA_DITH_DSPP_MATRIX_OFF;

	/* Turn off feature */
	if (!hw_cfg->payload) {
		DRM_DEBUG_DRIVER("Disable DSPP dither feature\n");
		SDE_REG_WRITE(&ctx->hw, ctrl_off, 0);
		return;
	}
	DRM_DEBUG_DRIVER("Enable DSPP Dither feature\n");
	dither = hw_cfg->payload;

	for (i = 0; i < DITHER_MATRIX_SZ; i += 4) {
		data = (dither->matrix[i] & REG_MASK(4)) |
			((dither->matrix[i + 1] & REG_MASK(4)) << 4) |
			((dither->matrix[i + 2] & REG_MASK(4)) << 8) |
			((dither->matrix[i + 3] & REG_MASK(4)) << 12);
		SDE_REG_WRITE(&ctx->hw, matrix_off + i, data);
	}

	opmode = BIT(0);
	opmode |= (dither->offset_en) ? BIT(1) : 0;
	opmode |= ((dither->strength) & REG_MASK(4)) << 4;
	SDE_REG_WRITE(&ctx->hw, ctrl_off, opmode);
}
+8 −1
Original line number Diff line number Diff line
/* Copyright (c) 2016-2017, The Linux Foundation. All rights reserved.
/* Copyright (c) 2016-2018, The Linux Foundation. All rights reserved.
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License version 2 and
@@ -143,4 +143,11 @@ void sde_read_dspp_hist_v1_7(struct sde_hw_dspp *ctx, void *cfg);
 * @ctx: Pointer to DSPP context
 */
void sde_lock_dspp_hist_v1_7(struct sde_hw_dspp *ctx, void *cfg);

/**
 * sde_setup_dspp_dither_v1_7 - setup DSPP dither feature in v1.7 hardware
 * @ctx: Pointer to DSPP context
 * @cfg: Pointer to dither data
 */
void sde_setup_dspp_dither_v1_7(struct sde_hw_dspp *ctx, void *cfg);
#endif
+6 −0
Original line number Diff line number Diff line
@@ -104,6 +104,12 @@ static void _setup_dspp_ops(struct sde_hw_dspp *c, unsigned long features)
					c->ops.setup_sixzone =
						sde_setup_dspp_sixzone_v17;
			break;
		case SDE_DSPP_DITHER:
			if (c->cap->sblk->dither.version ==
				SDE_COLOR_PROCESS_VER(0x1, 0x7))
				c->ops.setup_pa_dither =
					sde_setup_dspp_dither_v1_7;
			break;
		case SDE_DSPP_VLUT:
			if (c->cap->sblk->vlut.version ==
				(SDE_COLOR_PROCESS_VER(0x1, 0x7))) {
+3 −3
Original line number Diff line number Diff line
/* Copyright (c) 2015-2017, The Linux Foundation. All rights reserved.
/* Copyright (c) 2015-2018, The Linux Foundation. All rights reserved.
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License version 2 and
@@ -115,11 +115,11 @@ struct sde_hw_dspp_ops {
	void (*setup_danger_safe)(struct sde_hw_dspp *ctx, void *cfg);

	/**
	 * setup_dither - setup dspp dither
	 * setup_pa_dither - setup dspp PA dither
	 * @ctx: Pointer to dspp context
	 * @cfg: Pointer to configuration
	 */
	void (*setup_dither)(struct sde_hw_dspp *ctx, void *cfg);
	void (*setup_pa_dither)(struct sde_hw_dspp *ctx, void *cfg);

	/**
	 * setup_vlut - setup dspp PA VLUT
Loading