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

Commit 2a4f2c97 authored by Linux Build Service Account's avatar Linux Build Service Account Committed by Gerrit - the friendly Code Review server
Browse files

Merge "drm/msm/sde: Support PA dither feature"

parents 17e3ca63 49b38f08
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);
@@ -737,6 +740,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;
@@ -1507,6 +1517,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
@@ -116,6 +116,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