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

Commit 4a053c13 authored by Sarangdhar Joshi's avatar Sarangdhar Joshi Committed by Gerrit - the friendly Code Review server
Browse files

coresight: add element size support for dataset types



Add support for setting up the element size value per TPDA port for various
dataset types as this is necessary for TPDA functionality.

Change-Id: I36e7d849634d1576b5591337479cc92b77b3f395
Signed-off-by: default avatarSarangdhar Joshi <spjoshi@codeaurora.org>
parent d5dd0bba
Loading
Loading
Loading
Loading
+12 −3
Original line number Diff line number Diff line
@@ -194,6 +194,15 @@ Optional properties:
			    funnel component.
-qcom,tmc-flush-powerdown : boolean, indicating trace data needs to be flushed before
			    powering down CPU. Used for TMC component.
- qcom,bc-elem-size : specifies the BC element size supported by each monitor
		      connected to the aggregator on each port. Should be specified
		      in pairs (port, bc element size).
- qcom,tc-elem-size : specifies the TC element size supported by each monitor
		      connected to the aggregator on each port. Should be specified
		      in pairs (port, tc element size).
- qcom,dsb-elem-size : specifies the DSB element size supported by each monitor
		       connected to the aggregator on each port. Should be specified
		       in pairs (port, dsb element size).
- qcom,cmb-elem-size : specifies the CMB element size supported by each monitor
		       connected to the aggregator on each port. Should be specified
		       in pairs (port, cmb element size).
+111 −33
Original line number Diff line number Diff line
@@ -58,6 +58,9 @@ struct tpda_drvdata {
	struct clk		*clk;
	struct mutex		lock;
	bool			enable;
	uint32_t		bc_esize[TPDA_MAX_INPORTS];
	uint32_t		tc_esize[TPDA_MAX_INPORTS];
	uint32_t		dsb_esize[TPDA_MAX_INPORTS];
	uint32_t		cmb_esize[TPDA_MAX_INPORTS];
	bool			trig_async;
	bool			trig_flag_ts;
@@ -107,6 +110,21 @@ static void __tpda_enable_port(struct tpda_drvdata *drvdata, int port)
	uint32_t val;

	val = tpda_readl(drvdata, TPDA_Pn_CR(port));
	if (drvdata->bc_esize[port] == 32)
		val = val | BIT(4);
	else if (drvdata->bc_esize[port] == 64)
		val = val & ~BIT(4);

	if (drvdata->tc_esize[port] == 32)
		val = val | BIT(5);
	else if (drvdata->tc_esize[port] == 64)
		val = val & ~BIT(5);

	if (drvdata->dsb_esize[port] == 32)
		val = val | BIT(8);
	else if (drvdata->dsb_esize[port] == 64)
		val = val & ~BIT(8);

	val = val & ~(0x3 << 6);
	if (drvdata->cmb_esize[port] == 8)
		val &= ~(0x3 << 6);
@@ -114,6 +132,7 @@ static void __tpda_enable_port(struct tpda_drvdata *drvdata, int port)
		val |= (0x1 << 6);
	else if (drvdata->cmb_esize[port] == 64)
		val |= (0x2 << 6);

	/* Set the hold time */
	val = val & ~(0x7 << 1);
	val |= (0x5 << 1);
@@ -525,6 +544,94 @@ static const struct attribute_group *tpda_attr_grps[] = {
	NULL,
};

static int tpda_parse_of_data(struct tpda_drvdata *drvdata)
{
	int len, port, i;
	const __be32 *prop;
	struct device_node *node = drvdata->dev->of_node;

	prop = of_get_property(node, "qcom,bc-elem-size", &len);
	if (prop) {
		len /= sizeof(__be32);
		if (len < 2 || len > 63 || len % 2 != 0) {
			dev_err(drvdata->dev,
				"Dataset BC width entries are wrong\n");
			return -EINVAL;
		}

		for (i = 0; i < len; i++) {
			port = be32_to_cpu(prop[i++]);
			if (port >= TPDA_MAX_INPORTS) {
				dev_err(drvdata->dev,
					"Wrong port specified for BC\n");
				return -EINVAL;
			}
			drvdata->bc_esize[port] = be32_to_cpu(prop[i]);
		}
	}

	prop = of_get_property(node, "qcom,tc-elem-size", &len);
	if (prop) {
		len /= sizeof(__be32);
		if (len < 2 || len > 63 || len % 2 != 0) {
			dev_err(drvdata->dev,
				"Dataset TC width entries are wrong\n");
			return -EINVAL;
		}

		for (i = 0; i < len; i++) {
			port = be32_to_cpu(prop[i++]);
			if (port >= TPDA_MAX_INPORTS) {
				dev_err(drvdata->dev,
					"Wrong port specified for TC\n");
				return -EINVAL;
			}
			drvdata->tc_esize[port] = be32_to_cpu(prop[i]);
		}
	}

	prop = of_get_property(node, "qcom,dsb-elem-size", &len);
	if (prop) {
		len /= sizeof(__be32);
		if (len < 2 || len > 63 || len % 2 != 0) {
			dev_err(drvdata->dev,
				"Dataset DSB width entries are wrong\n");
			return -EINVAL;
		}

		for (i = 0; i < len; i++) {
			port = be32_to_cpu(prop[i++]);
			if (port >= TPDA_MAX_INPORTS) {
				dev_err(drvdata->dev,
					"Wrong port specified for DSB\n");
				return -EINVAL;
			}
			drvdata->dsb_esize[port] = be32_to_cpu(prop[i]);
		}
	}

	prop = of_get_property(node, "qcom,cmb-elem-size", &len);
	if (prop) {
		len /= sizeof(__be32);
		if (len < 2 || len > 63 || len % 2 != 0) {
			dev_err(drvdata->dev,
				"Dataset CMB width entries are wrong\n");
			return -EINVAL;
		}

		for (i = 0; i < len; i++) {
			port = be32_to_cpu(prop[i++]);
			if (port >= TPDA_MAX_INPORTS) {
				dev_err(drvdata->dev,
					"Wrong port specified for CMB\n");
				return -EINVAL;
			}
			drvdata->cmb_esize[port] = be32_to_cpu(prop[i]);
		}
	}
	return 0;
}

static void tpda_init_default_data(struct tpda_drvdata *drvdata)
{
	drvdata->freq_ts = true;
@@ -532,9 +639,7 @@ static void tpda_init_default_data(struct tpda_drvdata *drvdata)

static int tpda_probe(struct platform_device *pdev)
{
	int ret, i;
	uint32_t port, cmb_esize_len = 0;
	uint32_t *cmb_esize = 0;
	int ret;
	struct device *dev = &pdev->dev;
	struct coresight_platform_data *pdata;
	struct tpda_drvdata *drvdata;
@@ -565,36 +670,9 @@ static int tpda_probe(struct platform_device *pdev)

	mutex_init(&drvdata->lock);

	if (of_get_property(pdev->dev.of_node, "qcom,cmb-elem-size",
			    &cmb_esize_len))
		cmb_esize_len /= sizeof(u32);

	if (cmb_esize_len) {
		cmb_esize = devm_kzalloc(drvdata->dev, cmb_esize_len *
					 sizeof(*cmb_esize), GFP_KERNEL);
		if (!cmb_esize)
			return -ENOMEM;

		if (cmb_esize_len % 2 == 0) {
			ret = of_property_read_u32_array(pdev->dev.of_node,
							 "qcom,cmb-elem-size",
							 (u32 *)cmb_esize,
							 cmb_esize_len);
			if (ret) {
				dev_err(dev, "Failed to get CMB width\n");
	ret = tpda_parse_of_data(drvdata);
	if (ret)
		return ret;
			}
			for (i = 0; i < cmb_esize_len; i++) {
				port = cmb_esize[i++];
				drvdata->cmb_esize[port] = cmb_esize[i];
			}
			devm_kfree(drvdata->dev, cmb_esize);
		} else {
			devm_kfree(drvdata->dev, cmb_esize);
			dev_err(dev, "Dataset CMB width entries are wrong\n");
			return -EINVAL;
		}
	}

	drvdata->clk = devm_clk_get(dev, "core_clk");
	if (IS_ERR(drvdata->clk))