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

Commit 03ec97d5 authored by Shubhashree Dhar's avatar Shubhashree Dhar
Browse files

drm: msm: sde: Add support for Qseed3Lite



Change adds software support for Qseed3Lite. Coefficient register
space is re-defined. Qseed3Lite uses filter coefficients for only 2
filters, namely Y-2D Separable and UV-2D Separable. No coefficient
programming for directional filtering. Blend Config field in Op Mode
register is depricated for Qseed3lite. No LUT coefficient programming
for destination scalar, as it is used for only upscaling, coefficients
are hard-coded inside HW to save area. Additional fields for Directional
Weight and Blend Filter Ratio are added in drm scaler structure.

Change-Id: Icf4cf7af00e94e545e92370d265e2dbb51e84188
Signed-off-by: default avatarShubhashree Dhar <dhar@codeaurora.org>
parent 0db88144
Loading
Loading
Loading
Loading
+17 −0
Original line number Diff line number Diff line
@@ -32,6 +32,8 @@
#include "sde_hw_ctl.h"
#include "sde_crtc.h"
#include "sde_plane.h"
#include "sde_hw_util.h"
#include "sde_hw_catalog.h"
#include "sde_color_processing.h"
#include "sde_encoder.h"
#include "sde_connector.h"
@@ -1918,6 +1920,7 @@ static int _sde_crtc_set_dest_scaler_lut(struct sde_crtc *sde_crtc,
		struct sde_crtc_state *cstate, uint32_t lut_idx)
{
	struct sde_hw_scaler3_lut_cfg *cfg;
	struct sde_kms *sde_kms;
	u32 *lut_data = NULL;
	size_t len = 0;
	int ret = 0;
@@ -1927,6 +1930,13 @@ static int _sde_crtc_set_dest_scaler_lut(struct sde_crtc *sde_crtc,
		return -EINVAL;
	}

	sde_kms = _sde_crtc_get_kms(&sde_crtc->base);
	if (!sde_kms)
		return -EINVAL;

	if (is_qseed3_rev_qseed3lite(sde_kms->catalog))
		return 0;

	lut_data = msm_property_get_blob(&sde_crtc->property_info,
			&cstate->property_state, &len, lut_idx);
	if (!lut_data || !len) {
@@ -5008,6 +5018,8 @@ static void sde_crtc_install_properties(struct drm_crtc *crtc,
		sde_kms_info_add_keystr(info, "qseed_type", "qseed2");
	if (catalog->qseed_type == SDE_SSPP_SCALER_QSEED3)
		sde_kms_info_add_keystr(info, "qseed_type", "qseed3");
	if (catalog->qseed_type == SDE_SSPP_SCALER_QSEED3LITE)
		sde_kms_info_add_keystr(info, "qseed_type", "qseed3lite");

	if (sde_is_custom_client()) {
		/* No support for SMART_DMA_V1 yet */
@@ -5049,6 +5061,11 @@ static void sde_crtc_install_properties(struct drm_crtc *crtc,
			msm_property_install_blob(&sde_crtc->property_info,
					"ds_lut_sep", 0,
					CRTC_PROP_DEST_SCALER_LUT_SEP);
		} else if (catalog->ds[0].features
				& BIT(SDE_SSPP_SCALER_QSEED3LITE)) {
			msm_property_install_volatile_range(
					&sde_crtc->property_info, "dest_scaler",
					0x0, 0, ~0, 0, CRTC_PROP_DEST_SCALER);
		}
	}

+14 −0
Original line number Diff line number Diff line
@@ -1018,6 +1018,15 @@ static void _sde_sspp_setup_vig(struct sde_mdss_cfg *sde_cfg,
			VIG_QSEED_LEN, 0);
		snprintf(sblk->scaler_blk.name, SDE_HW_BLK_NAME_LEN,
			"sspp_scaler%u", sspp->id - SSPP_VIG0);
	} else if (sde_cfg->qseed_type == SDE_SSPP_SCALER_QSEED3LITE) {
		set_bit(SDE_SSPP_SCALER_QSEED3LITE, &sspp->features);
		sblk->scaler_blk.id = SDE_SSPP_SCALER_QSEED3LITE;
		sblk->scaler_blk.base = PROP_VALUE_ACCESS(prop_value,
			VIG_QSEED_OFF, 0);
		sblk->scaler_blk.len = PROP_VALUE_ACCESS(prop_value,
			VIG_QSEED_LEN, 0);
		snprintf(sblk->scaler_blk.name, SDE_HW_BLK_NAME_LEN,
			"sspp_scaler%u", sspp->id - SSPP_VIG0);
	}

	if (sde_cfg->has_sbuf)
@@ -2428,6 +2437,9 @@ static int sde_ds_parse_dt(struct device_node *np,

		if (sde_cfg->qseed_type == SDE_SSPP_SCALER_QSEED3)
			set_bit(SDE_SSPP_SCALER_QSEED3, &ds->features);
		else if (sde_cfg->qseed_type == SDE_SSPP_SCALER_QSEED3LITE)
			set_bit(SDE_SSPP_SCALER_QSEED3LITE, &ds->features);

	}

end:
@@ -2989,6 +3001,8 @@ static int sde_parse_dt(struct device_node *np, struct sde_mdss_cfg *cfg)
	rc = of_property_read_string(np, sde_prop[QSEED_TYPE].prop_name, &type);
	if (!rc && !strcmp(type, "qseedv3")) {
		cfg->qseed_type = SDE_SSPP_SCALER_QSEED3;
	} else if (!rc && !strcmp(type, "qseedv3lite")) {
		cfg->qseed_type = SDE_SSPP_SCALER_QSEED3LITE;
	} else if (!rc && !strcmp(type, "qseedv2")) {
		cfg->qseed_type = SDE_SSPP_SCALER_QSEED2;
	} else if (rc) {
+3 −1
Original line number Diff line number Diff line
@@ -157,6 +157,7 @@ enum {
 * @SDE_SSPP_SEC_UI_ALLOWED   Allows secure-ui layers
 * @SDE_SSPP_BLOCK_SEC_UI    Blocks secure-ui layers
 * @SDE_SSPP_QOS_FL_NOCALC   Avoid fill level calculation for QoS/danger/safe
 * @SDE_SSPP_SCALER_QSEED3LITE Qseed3lite algorithm support
 * @SDE_SSPP_MAX             maximum value
 */
enum {
@@ -190,6 +191,7 @@ enum {
	SDE_SSPP_SEC_UI_ALLOWED,
	SDE_SSPP_BLOCK_SEC_UI,
	SDE_SSPP_QOS_FL_NOCALC,
	SDE_SSPP_SCALER_QSEED3LITE,
	SDE_SSPP_MAX
};

@@ -655,7 +657,7 @@ struct sde_ctl_cfg {
 */
struct sde_sspp_cfg {
	SDE_HW_BLK_INFO;
	const struct sde_sspp_sub_blks *sblk;
	struct sde_sspp_sub_blks *sblk;
	u32 xin_id;
	enum sde_clk_ctrl_type clk_ctrl;
	u32 type;
+18 −4
Original line number Diff line number Diff line
/* Copyright (c) 2017, The Linux Foundation. All rights reserved.
/* Copyright (c)2017-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
@@ -27,6 +27,14 @@ static void sde_hw_ds_setup_opmode(struct sde_hw_ds *hw_ds,
	SDE_REG_WRITE(hw, DEST_SCALER_OP_MODE, op_mode);
}

static u32 _sde_hw_ds_get_scaler3_ver(struct sde_hw_ds *ctx)
{
	if (!ctx)
		return 0;

	return sde_hw_get_scaler3_ver(&ctx->hw, ctx->scl->base);
}

static void sde_hw_ds_setup_scaler3(struct sde_hw_ds *hw_ds,
			void *scaler_cfg, void *scaler_lut_cfg)
{
@@ -48,9 +56,8 @@ static void sde_hw_ds_setup_scaler3(struct sde_hw_ds *hw_ds,
		scl3_cfg->sep_len = scl3_lut_cfg->sep_len;
	}

	sde_hw_setup_scaler3(&hw_ds->hw, scl3_cfg,
	sde_hw_setup_scaler3(&hw_ds->hw, scl3_cfg, hw_ds->scl->version,
			 hw_ds->scl->base,
			 hw_ds->scl->version,
			 sde_get_sde_format(DRM_FORMAT_XBGR2101010));
}

@@ -58,9 +65,12 @@ static void _setup_ds_ops(struct sde_hw_ds_ops *ops, unsigned long features)
{
	ops->setup_opmode = sde_hw_ds_setup_opmode;

	if (test_bit(SDE_SSPP_SCALER_QSEED3, &features))
	if (test_bit(SDE_SSPP_SCALER_QSEED3, &features) ||
			test_bit(SDE_SSPP_SCALER_QSEED3LITE, &features)) {
		ops->get_scaler_ver = _sde_hw_ds_get_scaler3_ver;
		ops->setup_scaler = sde_hw_ds_setup_scaler3;
	}
}

static struct sde_ds_cfg *_ds_offset(enum sde_ds ds,
		struct sde_mdss_cfg *m,
@@ -119,6 +129,10 @@ struct sde_hw_ds *sde_hw_ds_init(enum sde_ds idx,
	hw_ds->scl = cfg;
	_setup_ds_ops(&hw_ds->ops, hw_ds->scl->features);

	if (hw_ds->ops.get_scaler_ver)
		hw_ds->scl->version = hw_ds->ops.get_scaler_ver(hw_ds);


	rc = sde_hw_blk_init(&hw_ds->base, SDE_HW_BLK_DS, idx, &sde_hw_ops);
	if (rc) {
		SDE_ERROR("failed to init hw blk %d\n", rc);
+8 −2
Original line number Diff line number Diff line
/* Copyright (c) 2017, The Linux Foundation. All rights reserved.
/* Copyright (c) 2017-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
@@ -66,6 +66,12 @@ struct sde_hw_ds_ops {
				void *scaler_cfg,
				void *scaler_lut_cfg);

	/**
	 * get_scaler_ver - get scaler h/w version
	 * @ctx: Pointer to ds structure
	 */
	u32 (*get_scaler_ver)(struct sde_hw_ds *ctx);

};

/**
@@ -82,7 +88,7 @@ struct sde_hw_ds {
	struct sde_hw_blk base;
	struct sde_hw_blk_reg_map hw;
	enum sde_ds idx;
	const struct sde_ds_cfg *scl;
	struct sde_ds_cfg *scl;
	struct sde_hw_ds_ops ops;
};

Loading