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

Commit 2045ecdb authored by Mitchel Humpherys's avatar Mitchel Humpherys
Browse files

iommu/arm-smmu: Use context bank TLBSTATUS registers



There are TLBSTATUS registers in SMMU global register space as well as
context bank register space.  Currently we're polling the global
TLBSTATUS registers after TLB invalidation, even when using the TLB
invalidation registers from context bank address space.  This violates
the usage model described in the ARM SMMU spec.  Fix this by polling
context bank TLBSTATUS registers for context bank TLB operations, and
global TLBSTATUS registers for global TLB operations.

Change-Id: I8aa916f7bc71793cad4c9224aa85d5310eacec75
Signed-off-by: default avatarMitchel Humpherys <mitchelh@codeaurora.org>
parent c22fe3da
Loading
Loading
Loading
Loading
+6 −6
Original line number Diff line number Diff line
@@ -813,16 +813,16 @@ static void arm_smmu_tlb_sync_cb(struct arm_smmu_device *smmu,
	u32 val;

	writel_relaxed(0, base + ARM_SMMU_CB_TLBSYNC);
	if (readl_poll_timeout(base + ARM_SMMU_CB_TLBSTATUS, val,
	if (readl_poll_timeout_atomic(base + ARM_SMMU_CB_TLBSTATUS, val,
				      !(val & TLBSTATUS_SACTIVE),
				20, TLB_LOOP_TIMEOUT))
				      10, TLB_LOOP_TIMEOUT))
		dev_err(smmu->dev, "TLBSYNC timeout!\n");
}

static void arm_smmu_tlb_sync(void *cookie)
{
	struct arm_smmu_domain *smmu_domain = cookie;
	__arm_smmu_tlb_sync(smmu_domain->smmu);
	arm_smmu_tlb_sync_cb(smmu_domain->smmu, smmu_domain->cfg.cbndx);
}

/* Must be called with clocks/regulators enabled */
@@ -841,14 +841,14 @@ static void arm_smmu_tlb_inv_context(void *cookie)
		base = ARM_SMMU_CB_BASE(smmu) + ARM_SMMU_CB(smmu, cfg->cbndx);
		writel_relaxed(ARM_SMMU_CB_ASID(cfg),
			       base + ARM_SMMU_CB_S1_TLBIASID);
		arm_smmu_tlb_sync_cb(smmu, cfg->cbndx);
	} else {
		base = ARM_SMMU_GR0(smmu);
		writel_relaxed(ARM_SMMU_CB_VMID(cfg),
			       base + ARM_SMMU_GR0_TLBIVMID);
	}

		__arm_smmu_tlb_sync(smmu);
	}
}

static void arm_smmu_tlb_inv_range_nosync(unsigned long iova, size_t size,
					  bool leaf, void *cookie)