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

Commit 32c02eeb authored by Rajesh Kemisetti's avatar Rajesh Kemisetti Committed by Gerrit - the friendly Code Review server
Browse files

msm: kgsl: Add support to make use of iommu_unmap_fast



iommu_unmap() generally does two things:
  - Removes the memory entry from pagetable.
  - Triggers TLB invalidation sequence by voting
    respective regulator and clocks of SMMU.

SMMU HW also does invalidation of its caches across
power collapse, so the second step in iommu_unmap()
is redundant if SMMU is already in power collapsed state.

Try to skip TLB invalidation by calling iommu_unmap_fast()
when we know that SMMU regulator is already in OFF state.

Change-Id: Idf93eab51e5db1ac8a1b8d922b3fdae64e5266ca
Signed-off-by: default avatarRajesh Kemisetti <rajeshk@codeaurora.org>
parent 2e7f5378
Loading
Loading
Loading
Loading
+2 −0
Original line number Diff line number Diff line
@@ -36,6 +36,8 @@ Optional properties:
		  for secure buffer allocation
- qcom,secure_align_mask: A mask for determining how secure buffers need to
		  be aligned
- qcom,unmap_fast :  A boolean specifying if iommu unmap fast is supported on
			this target.

- List of sub nodes, one for each of the translation context banks supported.
  The driver uses the names of these nodes to determine how they are used,
+23 −1
Original line number Diff line number Diff line
@@ -405,10 +405,18 @@ static int _iommu_unmap_sync_pc(struct kgsl_pagetable *pt,
		uint64_t addr, uint64_t size)
{
	struct kgsl_iommu_pt *iommu_pt = pt->priv;
	struct kgsl_iommu *iommu = _IOMMU_PRIV(pt->mmu);
	size_t unmapped = 0;

	_iommu_sync_mmu_pc(true);

	/*
	 * Take iommu unmap fast path if CX GDSC is in OFF state.
	 */
	if (iommu->vddcx_regulator &&
			(!regulator_is_enabled(iommu->vddcx_regulator)))
		unmapped = iommu_unmap_fast(iommu_pt->domain, addr, size);
	else
		unmapped = iommu_unmap(iommu_pt->domain, addr, size);

	_iommu_sync_mmu_pc(false);
@@ -2676,6 +2684,7 @@ static int _kgsl_iommu_probe(struct kgsl_device *device,
	u32 reg_val[2];
	int i = 0;
	struct kgsl_iommu *iommu = KGSL_IOMMU_PRIV(device);
	struct kgsl_pwrctrl *pwr = &device->pwrctrl;
	struct device_node *child;
	struct platform_device *pdev = of_find_device_by_node(node);

@@ -2722,6 +2731,19 @@ static int _kgsl_iommu_probe(struct kgsl_device *device,
			device->mmu.features |= kgsl_iommu_features[i].bit;
	}

	/*
	 * Try to preserve the SMMU regulator if HW can support
	 * unmap fast path.
	 */
	if (of_property_read_bool(node, "qcom,unmap_fast")) {
		for (i = 0; i < KGSL_MAX_REGULATORS; i++) {
			if (!strcmp(pwr->regulators[i].name, "vddcx")) {
				iommu->vddcx_regulator =
					pwr->regulators[i].reg;
			}
		}
	}

	if (of_property_read_u32(node, "qcom,micro-mmu-control",
		&iommu->micro_mmu_ctrl))
		iommu->micro_mmu_ctrl = UINT_MAX;
+2 −0
Original line number Diff line number Diff line
@@ -129,6 +129,7 @@ struct kgsl_iommu_context {
 * @setstate: Scratch GPU memory for IOMMU operations
 * @clk_enable_count: The ref count of clock enable calls
 * @clks: Array of pointers to IOMMU clocks
 * @vddcx_regulator: Handle to IOMMU regulator
 * @micro_mmu_ctrl: GPU register offset of this glob al register
 * @smmu_info: smmu info used in a5xx preemption
 * @protect: register protection settings for the iommu.
@@ -143,6 +144,7 @@ struct kgsl_iommu {
	struct kgsl_memdesc setstate;
	atomic_t clk_enable_count;
	struct clk *clks[KGSL_IOMMU_MAX_CLKS];
	struct regulator *vddcx_regulator;
	unsigned int micro_mmu_ctrl;
	struct kgsl_memdesc smmu_info;
	unsigned int version;