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

Commit 8ffa6450 authored by Isaac J. Manjarres's avatar Isaac J. Manjarres
Browse files

iommu/arm-smmu: Add support for not removing SMMU power votes



The SMMU driver will vote for the resources it needs before performing
a particular operation, and will remove its votes after the operation
is complete.

When power resources are not currently enabled by other drivers,
the SMMU driver's requests to enable its devices' power resources
go through the slow paths where the hardware power resources
get turned on. So, in a scenario where the SMMU driver is constantly
performing work and having to toggle the state of the power resources,
the SMMU driver operations take more time.

On GKI, the upstream implementation of the IOMMU page table management
code is used, which doesn't have the optimizations we have downstream,
which improve the performance of the SMMU driver when unmapping memory.

The GPU can go into slumber if it is not active, and can relinquish its
votes for the power resources that the SMMU driver votes for when
unmapping memory. This requires the SMMU driver to take the slowpath
of enabling all of these power resources and then disabling them
on every call to unmap memory, which can incur a considerable amount
of delay.

This delay, along with the usage of the unoptimized IOMMU page table
management code in GKI results in slow unmap calls.

Thus, add support for the SMMU driver to never remove its power votes,
so that it doesn't have to spend time voting for power resources while
it is operating.

Change-Id: Id93aafef18f69e377391875e2a7b340b34b4b3e8
Signed-off-by: default avatarIsaac J. Manjarres <isaacm@codeaurora.org>
parent be81ead7
Loading
Loading
Loading
Loading
+12 −0
Original line number Diff line number Diff line
@@ -548,6 +548,18 @@ config ARM_SMMU_SKIP_MAP_POWER_ON

	  If unsure, say N here.

config ARM_SMMU_POWER_ALWAYS_ON
	bool "Never remove SMMU power resource votes"
	depends on ARM_SMMU && !QGKI
	help
	  Support for never removing SMMU power resource votes (i.e.
	  regulator, clocks, and interconnect votes). Never removing the
	  power resource votes allows for less time to be spent by the SMMU
	  driver in voting for power resources when it is actively working for
	  an extended period of time.

	  If unsure, say N here.

config ARM_SMMU_V3
	tristate "ARM Ltd. System MMU Version 3 (SMMUv3) Support"
	depends on ARM64
+27 −0
Original line number Diff line number Diff line
@@ -5049,6 +5049,28 @@ static int arm_smmu_device_dt_probe(struct platform_device *pdev)
	arm_smmu_interrupt_selftest(smmu);
	arm_smmu_power_off(smmu, smmu->pwr);

	/*
	 * On GKI, we use the upstream implementation of the IOMMU page table
	 * management code, which lacks all of the optimizations that we have
	 * downstream to speed up calls into the SMMU driver to unmap memory.
	 *
	 * When the GPU goes into slumber, it relinquishes its votes for
	 * the regulators and clocks that the SMMU driver votes for. This
	 * means that when the SMMU driver adds/removes votes for the
	 * power resources required to access the GPU SMMU registers for
	 * TLB invalidations while unmapping memory, the SMMU driver has to
	 * wait for the resources to actually turn on/off, which incurs a
	 * considerable amount of delay.
	 *
	 * This delay, coupled with the use of the unoptimized IOMMU page table
	 * management code in GKI results in slow unmap calls. To alleviate
	 * that, we can remove the latency incurred by enabling/disabling the
	 * power resources, by always keeping them on.
	 */
	if (IS_ENABLED(CONFIG_ARM_SMMU_POWER_ALWAYS_ON) &&
	    of_property_read_bool(dev->of_node, "qcom,power-always-on"))
		arm_smmu_power_on(smmu->pwr);

	/*
	 * We want to avoid touching dev->power.lock in fastpaths unless
	 * it's really going to do something useful - pm_runtime_enabled()
@@ -5104,6 +5126,11 @@ static int arm_smmu_device_remove(struct platform_device *pdev)
	arm_smmu_gr0_write(smmu, ARM_SMMU_GR0_sCR0, sCR0_CLIENTPD);
	arm_smmu_power_off(smmu, smmu->pwr);

	/* Remove the extra reference that was taken in the probe function */
	if (IS_ENABLED(CONFIG_ARM_SMMU_POWER_ALWAYS_ON) &&
	    of_property_read_bool(pdev->dev.of_node, "qcom,power-always-on"))
		arm_smmu_power_off(smmu, smmu->pwr);

	arm_smmu_exit_power_resources(smmu->pwr);

	return 0;