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

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

Merge "iommu: msm: Implement SW PTW for IOMMU mappings"

parents 83085812 e56f129a
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -29,6 +29,7 @@ Optional properties:
- qti,iommu-pmu-ncounters: Number of PMU counters per group.
- qti,iommu-pmu-event-classes: List of event classes supported.
- Bus scaling properties: See msm_bus.txt
- qti,no-atos-support: boolean indicating that IOMMU doesn't have ATS support

- List of sub nodes, one for each of the translation context banks supported.
  Each sub node has the following required properties:
+1 −0
Original line number Diff line number Diff line
@@ -131,6 +131,7 @@ struct msm_iommu_drvdata {
	unsigned int bus_client;
	int needs_rem_spinlock;
	int powered_on;
	int no_atos_support;
};

/**
+6 −0
Original line number Diff line number Diff line
@@ -935,6 +935,12 @@ static phys_addr_t msm_iommu_iova_to_phys(struct iommu_domain *domain,
				 struct msm_iommu_ctx_drvdata, attached_elm);
	iommu_drvdata = dev_get_drvdata(ctx_drvdata->pdev->dev.parent);

	if (iommu_drvdata->no_atos_support) {
		ret = msm_iommu_iova_to_phys_soft(domain, va);
		mutex_unlock(&msm_iommu_lock);
		return ret;
	}

	base = iommu_drvdata->base;
	ctx = ctx_drvdata->num;

+3 −0
Original line number Diff line number Diff line
@@ -340,6 +340,9 @@ static int msm_iommu_probe(struct platform_device *pdev)
			return PTR_ERR(drvdata->aiclk);
	}

	drvdata->no_atos_support = of_property_read_bool(pdev->dev.of_node,
						"qti,no-atos-support");

	if (clk_get_rate(drvdata->clk) == 0) {
		ret = clk_round_rate(drvdata->clk, 1000);
		clk_set_rate(drvdata->clk, ret);
+40 −0
Original line number Diff line number Diff line
@@ -615,6 +615,46 @@ void msm_iommu_pagetable_unmap_range(struct msm_iommu_pt *pt, unsigned int va,
	}
}

phys_addr_t msm_iommu_iova_to_phys_soft(struct iommu_domain *domain,
					  phys_addr_t va)
{
	struct msm_iommu_priv *priv = domain->priv;
	struct msm_iommu_pt *pt = &priv->pt;
	unsigned long *fl_pte;
	unsigned long fl_offset;
	unsigned long *sl_table = NULL;
	unsigned long sl_offset;
	unsigned long *sl_pte;

	if (!pt->fl_table) {
		pr_err("Page table doesn't exist\n");
		return 0;
	}

	fl_offset = FL_OFFSET(va);
	fl_pte = pt->fl_table + fl_offset;

	if (*fl_pte & FL_TYPE_TABLE) {
		sl_table = __va(((*fl_pte) & FL_BASE_MASK));
		sl_offset = SL_OFFSET(va);
		sl_pte = sl_table + sl_offset;
		/* 64 KB section */
		if (*sl_pte & SL_TYPE_LARGE)
			return (*sl_pte & 0xFFFF0000) | (va & ~0xFFFF0000);
		/* 4 KB section */
		if (*sl_pte & SL_TYPE_SMALL)
			return (*sl_pte & 0xFFFFF000) | (va & ~0xFFFFF000);
	} else {
		/* 16 MB section */
		if (*fl_pte & FL_SUPERSECTION)
			return (*fl_pte & 0xFF000000) | (va & ~0xFF000000);
		/* 1 MB section */
		if (*fl_pte & FL_TYPE_SECT)
			return (*fl_pte & 0xFFF00000) | (va & ~0xFFF00000);
	}
	return 0;
}

static int __init get_tex_class(int icp, int ocp, int mt, int nos)
{
	int i = 0;
Loading