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

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

Merge "msm: iommu: Add support for alternate iface clocks"

parents 000e1ae8 1d7a8c8a
Loading
Loading
Loading
Loading
+2 −0
Original line number Diff line number Diff line
@@ -47,6 +47,8 @@ Optional properties:
Optional properties:
- qcom,needs-alt-core-clk : boolean to enable the secondary core clock for
  access to the IOMMU configuration registers
- qcom,needs-alt-iface-clk : boolean to enable the secondary iface clock for
  access to the IOMMU configuration registers
- qcom,iommu-bfb-regs : An array of unsigned 32-bit integers corresponding to
  BFB register addresses that need to be configured for performance tuning
  purposes. If this property is present, the qcom,iommu-bfb-data must also be
+3 −1
Original line number Diff line number Diff line
@@ -90,7 +90,8 @@ struct msm_iommu_bfb_settings {
 * @irq:	Interrupt number
 * @clk:	The bus clock for this IOMMU hardware instance
 * @pclk:	The clock for the IOMMU bus interconnect
 * @aclk:	Alternate clock for this IOMMU core, if any
 * @aclk:	Alternate core clock for this IOMMU core, if any
 * @aiclk:	Alternate interface clock for this IOMMU core, if any
 * @name:	Human-readable name of this IOMMU device
 * @gdsc:	Regulator needed to power this HW block (v2 only)
 * @bfb_settings: Optional BFB performance tuning parameters
@@ -113,6 +114,7 @@ struct msm_iommu_drvdata {
	struct clk *clk;
	struct clk *pclk;
	struct clk *aclk;
	struct clk *aiclk;
	const char *name;
	struct regulator *gdsc;
	struct regulator *alt_gdsc;
+20 −5
Original line number Diff line number Diff line
@@ -102,14 +102,18 @@ static int __enable_clocks(struct msm_iommu_drvdata *drvdata)

	ret = clk_prepare_enable(drvdata->clk);
	if (ret)
		clk_disable_unprepare(drvdata->pclk);
		goto fail1;

	if (drvdata->aclk) {
		ret = clk_prepare_enable(drvdata->aclk);
		if (ret) {
			clk_disable_unprepare(drvdata->clk);
			clk_disable_unprepare(drvdata->pclk);
		if (ret)
			goto fail2;
	}

	if (drvdata->aiclk) {
		ret = clk_prepare_enable(drvdata->aiclk);
		if (ret)
			goto fail3;
	}

	if (drvdata->clk_reg_virt) {
@@ -121,12 +125,23 @@ static int __enable_clocks(struct msm_iommu_drvdata *drvdata)
		/* Ensure clock is on before continuing */
		mb();
	}
	return 0;

fail3:
	if (drvdata->aclk)
		clk_disable_unprepare(drvdata->aclk);
fail2:
	clk_disable_unprepare(drvdata->clk);
fail1:
	clk_disable_unprepare(drvdata->pclk);
fail:
	return ret;
}

static void __disable_clocks(struct msm_iommu_drvdata *drvdata)
{
	if (drvdata->aiclk)
		clk_disable_unprepare(drvdata->aiclk);
	if (drvdata->aclk)
		clk_disable_unprepare(drvdata->aclk);
	clk_disable_unprepare(drvdata->clk);
+14 −1
Original line number Diff line number Diff line
@@ -285,7 +285,7 @@ static int msm_iommu_probe(struct platform_device *pdev)
	struct iommu_pmon *pmon_info;
	struct msm_iommu_drvdata *drvdata;
	struct resource *r;
	int ret, needs_alt_core_clk;
	int ret, needs_alt_core_clk, needs_alt_iface_clk;
	int global_cfg_irq, global_client_irq;

	drvdata = devm_kzalloc(&pdev->dev, sizeof(*drvdata), GFP_KERNEL);
@@ -332,6 +332,14 @@ static int msm_iommu_probe(struct platform_device *pdev)
			return PTR_ERR(drvdata->aclk);
	}

	needs_alt_iface_clk = of_property_read_bool(pdev->dev.of_node,
						   "qcom,needs-alt-iface-clk");
	if (needs_alt_iface_clk) {
		drvdata->aiclk = devm_clk_get(&pdev->dev, "alt_iface_clk");
		if (IS_ERR(drvdata->aclk))
			return PTR_ERR(drvdata->aiclk);
	}

	if (clk_get_rate(drvdata->clk) == 0) {
		ret = clk_round_rate(drvdata->clk, 1000);
		clk_set_rate(drvdata->clk, ret);
@@ -342,6 +350,11 @@ static int msm_iommu_probe(struct platform_device *pdev)
		clk_set_rate(drvdata->aclk, ret);
	}

	if (drvdata->aiclk && clk_get_rate(drvdata->aiclk) == 0) {
		ret = clk_round_rate(drvdata->aiclk, 1000);
		clk_set_rate(drvdata->aiclk, ret);
	}

	ret = msm_iommu_parse_dt(pdev, drvdata);
	if (ret)
		return ret;