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

Commit f0b0a2a8 authored by Sunil Goutham's avatar Sunil Goutham Committed by Patrick Daly
Browse files

iommu/arm-smmu: Fix 16-bit ASID configuration



16-bit ASID should be enabled before initializing TTBR0/1,
otherwise only LSB 8-bit ASID will be considered. Hence
moving configuration of TTBCR register ahead of TTBR0/1
while initializing context bank.

Change-Id: If76f9c3d201289245292d1fab47278eadff6f4db
Signed-off-by: default avatarSunil Goutham <sgoutham@cavium.com>
[will: rewrote comment]
Signed-off-by: default avatarWill Deacon <will.deacon@arm.com>
Git-commit: 125458ab3aefe9cf2f72dcfe7338dc9ad967da0b
Git-repo: git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git


Signed-off-by: default avatarPatrick Daly <pdaly@codeaurora.org>
parent 681e6619
Loading
Loading
Loading
Loading
+23 −19
Original line number Diff line number Diff line
@@ -1667,6 +1667,29 @@ static void arm_smmu_init_context_bank(struct arm_smmu_domain *smmu_domain,
	}
	writel_relaxed(reg, gr1_base + ARM_SMMU_GR1_CBAR(cfg->cbndx));

	/*
	 * TTBCR
	 * We must write this before the TTBRs, since it determines the
	 * access behaviour of some fields (in particular, ASID[15:8]).
	 */
	if (stage1) {
		if (cfg->fmt == ARM_SMMU_CTX_FMT_AARCH32_S) {
			reg = pgtbl_cfg->arm_v7s_cfg.tcr;
			reg2 = 0;
		} else {
			reg = pgtbl_cfg->arm_lpae_s1_cfg.tcr;
			reg2 = pgtbl_cfg->arm_lpae_s1_cfg.tcr >> 32;
			reg2 |= TTBCR2_SEP_UPSTREAM;
			if (cfg->fmt == ARM_SMMU_CTX_FMT_AARCH64)
				reg2 |= TTBCR2_AS;
		}
		if (smmu->version > ARM_SMMU_V1)
			writel_relaxed(reg2, cb_base + ARM_SMMU_CB_TTBCR2);
	} else {
		reg = pgtbl_cfg->arm_lpae_s2_cfg.vtcr;
	}
	writel_relaxed(reg, cb_base + ARM_SMMU_CB_TTBCR);

	/* TTBRs */
	if (stage1) {
		u16 asid = ARM_SMMU_CB_ASID(smmu, cfg);
@@ -1690,25 +1713,6 @@ static void arm_smmu_init_context_bank(struct arm_smmu_domain *smmu_domain,
		writeq_relaxed(reg64, cb_base + ARM_SMMU_CB_TTBR0);
	}

	/* TTBCR */
	if (stage1) {
		if (cfg->fmt == ARM_SMMU_CTX_FMT_AARCH32_S) {
			reg = pgtbl_cfg->arm_v7s_cfg.tcr;
			reg2 = 0;
		} else {
			reg = pgtbl_cfg->arm_lpae_s1_cfg.tcr;
			reg2 = pgtbl_cfg->arm_lpae_s1_cfg.tcr >> 32;
			reg2 |= TTBCR2_SEP_UPSTREAM;
			if (cfg->fmt == ARM_SMMU_CTX_FMT_AARCH64)
				reg2 |= TTBCR2_AS;
		}
		if (smmu->version > ARM_SMMU_V1)
			writel_relaxed(reg2, cb_base + ARM_SMMU_CB_TTBCR2);
	} else {
		reg = pgtbl_cfg->arm_lpae_s2_cfg.vtcr;
	}
	writel_relaxed(reg, cb_base + ARM_SMMU_CB_TTBCR);

	/* MAIRs (stage-1 only) */
	if (stage1) {
		if (cfg->fmt == ARM_SMMU_CTX_FMT_AARCH32_S) {