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

Commit ec93afba authored by Rajesh Yadav's avatar Rajesh Yadav
Browse files

drm/msm/sde: Add support for dspp igc feature



Change adds the LutDMA based igc feature support
to color processing module present in CRTC.
Change also adds multiple opcode support in single
command descriptor for LutDMA.

Change-Id: I87e43ce82b9b33a29d30bef7f3187d3df36e6e9e
Signed-off-by: default avatarRajesh Yadav <ryadav@codeaurora.org>
parent b89a6539
Loading
Loading
Loading
Loading
+7 −0
Original line number Diff line number Diff line
@@ -52,6 +52,9 @@ Required properties
				The number of offsets defined should reflect the
				amount of mixers that can drive data to a panel
				interface.
- qcom,sde-dspp-top-off:		Offset address for the dspp top block.
				The offset is calculated from register "mdp_phys"
				defined in reg property.
- qcom,sde-dspp-off: 		Array of offset addresses for the available dspp
				blocks. These offsets are calculated from
				register "mdp_phys" defined in reg property.
@@ -207,6 +210,7 @@ Optional properties:
				e.g. qcom,sde-dspp-blocks
				-- qcom,sde-dspp-pcc: offset and version of PCC hardware
				-- qcom,sde-dspp-gc: offset and version of GC hardware
				-- qcom,sde-dspp-igc: offset and version of IGC hardware
				-- qcom,sde-dspp-hsic: offset and version of global PA adjustment
				-- qcom,sde-dspp-memcolor: offset and version of PA memcolor hardware
				-- qcom,sde-dspp-sixzone: offset and version of PA sixzone hardware
@@ -424,6 +428,7 @@ Example:
		     0x00002600 0x00002800>;
    qcom,sde-mixer-off = <0x00045000 0x00046000
			0x00047000 0x0004a000>;
    qcom,sde-dspp-top-off = <0x1300>;
    qcom,sde-dspp-off = <0x00055000 0x00057000>;
    qcom,sde-dspp-ad-off = <0x24000 0x22800>;
    qcom,sde-dspp-ad-version = <0x00030000>;
@@ -481,6 +486,7 @@ Example:
    qcom,sde-sspp-src-size = <0x100>;
    qcom,sde-mixer-size = <0x100>;
    qcom,sde-ctl-size = <0x100>;
    qcom,sde-dspp-top-size = <0xc>;
    qcom,sde-dspp-size = <0x100>;
    qcom,sde-intf-size = <0x100>;
    qcom,sde-dsc-size = <0x100>;
@@ -599,6 +605,7 @@ Example:
    };

    qcom,sde-dspp-blocks {
        qcom,sde-dspp-igc = <0x0 0x00010000>;
        qcom,sde-dspp-pcc = <0x1700 0x00010000>;
        qcom,sde-dspp-gc = <0x17c0 0x00010000>;
        qcom,sde-dspp-hsic = <0x0 0x00010000>;
+4 −0
Original line number Diff line number Diff line
@@ -57,6 +57,9 @@
				      0x48000 0x49000 0x4a000>;
		qcom,sde-mixer-size = <0x320>;

		qcom,sde-dspp-top-off = <0x1300>;
		qcom,sde-dspp-top-size = <0xc>;

		qcom,sde-dspp-off = <0x55000 0x57000 0x59000 0x5b000>;
		qcom,sde-dspp-size = <0x17e0>;

@@ -188,6 +191,7 @@
		};

		qcom,sde-dspp-blocks {
			qcom,sde-dspp-igc = <0x0 0x00030001>;
			qcom,sde-dspp-vlut = <0xa00 0x00010008>;
			qcom,sde-dspp-gamut = <0x1000 0x00040000>;
			qcom,sde-dspp-gc = <0x17c0 0x00010008>;
+27 −0
Original line number Diff line number Diff line
@@ -60,6 +60,8 @@ static void dspp_gamut_install_property(struct drm_crtc *crtc);

static void dspp_gc_install_property(struct drm_crtc *crtc);

static void dspp_igc_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];
@@ -80,6 +82,7 @@ do { \
	func[SDE_DSPP_VLUT] = dspp_vlut_install_property; \
	func[SDE_DSPP_GAMUT] = dspp_gamut_install_property; \
	func[SDE_DSPP_GC] = dspp_gc_install_property; \
	func[SDE_DSPP_IGC] = dspp_igc_install_property; \
} while (0)

typedef void (*lm_prop_install_func_t)(struct drm_crtc *crtc);
@@ -1241,6 +1244,30 @@ static void dspp_gc_install_property(struct drm_crtc *crtc)
	}
}

static void dspp_igc_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->igc.version >> 16;
	snprintf(feature_name, ARRAY_SIZE(feature_name), "%s%d",
		"SDE_DSPP_IGC_V", version);
	switch (version) {
	case 3:
		sde_cp_crtc_install_blob_property(crtc, feature_name,
			SDE_CP_CRTC_DSPP_IGC, sizeof(struct drm_msm_igc_lut));
		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)
{
+63 −0
Original line number Diff line number Diff line
@@ -229,6 +229,12 @@ enum {
	DSC_PROP_MAX,
};

enum {
	DSPP_TOP_OFF,
	DSPP_TOP_SIZE,
	DSPP_TOP_PROP_MAX,
};

enum {
	DSPP_OFF,
	DSPP_SIZE,
@@ -463,6 +469,11 @@ static struct sde_prop_type mixer_blocks_prop[] = {
	{MIXER_GC_PROP, "qcom,sde-mixer-gc", false, PROP_TYPE_U32_ARRAY},
};

static struct sde_prop_type dspp_top_prop[] = {
	{DSPP_TOP_OFF, "qcom,sde-dspp-top-off", true, PROP_TYPE_U32},
	{DSPP_TOP_SIZE, "qcom,sde-dspp-top-size", false, PROP_TYPE_U32},
};

static struct sde_prop_type dspp_prop[] = {
	{DSPP_OFF, "qcom,sde-dspp-off", true, PROP_TYPE_U32_ARRAY},
	{DSPP_SIZE, "qcom,sde-dspp-size", false, PROP_TYPE_U32},
@@ -1859,6 +1870,54 @@ static int sde_rot_parse_dt(struct device_node *np,
	return rc;
}

static int sde_dspp_top_parse_dt(struct device_node *np,
		struct sde_mdss_cfg *sde_cfg)
{
	int rc, prop_count[DSPP_TOP_PROP_MAX];
	bool prop_exists[DSPP_TOP_PROP_MAX];
	struct sde_prop_value *prop_value = NULL;
	u32 off_count;

	if (!sde_cfg) {
		SDE_ERROR("invalid argument\n");
		rc = -EINVAL;
		goto end;
	}

	prop_value = kzalloc(DSPP_TOP_PROP_MAX *
			sizeof(struct sde_prop_value), GFP_KERNEL);
	if (!prop_value) {
		rc = -ENOMEM;
		goto end;
	}

	rc = _validate_dt_entry(np, dspp_top_prop, ARRAY_SIZE(dspp_top_prop),
		prop_count, &off_count);
	if (rc)
		goto end;

	rc = _read_dt_entry(np, dspp_top_prop, ARRAY_SIZE(dspp_top_prop),
		prop_count, prop_exists, prop_value);
	if (rc)
		goto end;

	if (off_count != 1) {
		SDE_ERROR("invalid dspp_top off_count:%d\n", off_count);
		rc = -EINVAL;
		goto end;
	}

	sde_cfg->dspp_top.base =
		PROP_VALUE_ACCESS(prop_value, DSPP_TOP_OFF, 0);
	sde_cfg->dspp_top.len =
		PROP_VALUE_ACCESS(prop_value, DSPP_TOP_SIZE, 0);
	snprintf(sde_cfg->dspp_top.name, SDE_HW_BLK_NAME_LEN, "dspp_top");

end:
	kfree(prop_value);
	return rc;
}

static int sde_dspp_parse_dt(struct device_node *np,
						struct sde_mdss_cfg *sde_cfg)
{
@@ -2992,6 +3051,10 @@ struct sde_mdss_cfg *sde_hw_catalog_init(struct drm_device *dev, u32 hw_rev)
	if (rc)
		goto end;

	rc = sde_dspp_top_parse_dt(np, sde_cfg);
	if (rc)
		goto end;

	rc = sde_dspp_parse_dt(np, sde_cfg);
	if (rc)
		goto end;
+13 −0
Original line number Diff line number Diff line
@@ -567,6 +567,17 @@ struct sde_lm_cfg {
	unsigned long lm_pair_mask;
};

/**
 * struct sde_dspp_cfg - information of DSPP top block
 * @id                 enum identifying this block
 * @base               register offset of this block
 * @features           bit mask identifying sub-blocks/features
 *                     supported by this block
 */
struct sde_dspp_top_cfg  {
	SDE_HW_BLK_INFO;
};

/**
 * struct sde_dspp_cfg - information of DSPP blocks
 * @id                 enum identifying this block
@@ -891,6 +902,8 @@ struct sde_mdss_cfg {
	u32 mixer_count;
	struct sde_lm_cfg mixer[MAX_BLOCKS];

	struct sde_dspp_top_cfg dspp_top;

	u32 dspp_count;
	struct sde_dspp_cfg dspp[MAX_BLOCKS];

Loading