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

Commit 352cdae8 authored by Robin Murphy's avatar Robin Murphy Committed by Isaac J. Manjarres
Browse files

iommu/arm-smmu: Convert context bank registers to bitfields



Finish the final part of the job, once again updating some names to
match the current spec.

Change-Id: I405fa064194b5c90b13935fb37b36ba9e8ee35c0
Signed-off-by: default avatarRobin Murphy <robin.murphy@arm.com>
Signed-off-by: default avatarWill Deacon <will@kernel.org>
Git-commit: 620565a7
Git-repo: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git


[isaacm@codeaurora.org: resolved merge conflicts/build time errors]
Signed-off-by: default avatarIsaac J. Manjarres <isaacm@codeaurora.org>
parent 3838623d
Loading
Loading
Loading
Loading
+44 −41
Original line number Diff line number Diff line
@@ -139,20 +139,60 @@ enum arm_smmu_cbar_type {
#define CBA2R_VA64			BIT(0)

#define ARM_SMMU_CB_SCTLR		0x0
#define SCTLR_S1_ASIDPNE		BIT(12)
#define SCTLR_CFCFG			BIT(7)
#define SCTLR_CFIE			BIT(6)
#define SCTLR_CFRE			BIT(5)
#define SCTLR_E				BIT(4)
#define SCTLR_AFE			BIT(2)
#define SCTLR_TRE			BIT(1)
#define SCTLR_M				BIT(0)

#define ARM_SMMU_CB_ACTLR		0x4

#define ARM_SMMU_CB_RESUME		0x8
#define ARM_SMMU_CB_TTBCR2		0x10
#define RESUME_TERMINATE		BIT(0)

#define ARM_SMMU_CB_TCR2		0x10
#define TCR2_SEP			GENMASK(17, 15)
#define TCR2_SEP_UPSTREAM		0x7
#define TCR2_AS				BIT(4)

#define ARM_SMMU_CB_TTBR0		0x20
#define ARM_SMMU_CB_TTBR1		0x28
#define ARM_SMMU_CB_TTBCR		0x30
#define TTBRn_ASID			GENMASK_ULL(63, 48)

#define ARM_SMMU_CB_TCR			0x30
#define ARM_SMMU_CB_CONTEXTIDR		0x34
#define ARM_SMMU_CB_S1_MAIR0		0x38
#define ARM_SMMU_CB_S1_MAIR1		0x3c

#define ARM_SMMU_CB_PAR			0x50
#define CB_PAR_F			BIT(0)

#define ARM_SMMU_CB_FSR			0x58
#define FSR_MULTI			BIT(31)
#define FSR_SS				BIT(30)
#define FSR_UUT				BIT(8)
#define FSR_ASF				BIT(7)
#define FSR_TLBLKF			BIT(6)
#define FSR_TLBMCF			BIT(5)
#define FSR_EF				BIT(4)
#define FSR_PF				BIT(3)
#define FSR_AFF				BIT(2)
#define FSR_TF				BIT(1)

#define FSR_IGN				(FSR_AFF | FSR_ASF | \
					 FSR_TLBMCF | FSR_TLBLKF)
#define FSR_FAULT			(FSR_MULTI | FSR_SS | FSR_UUT | \
					 FSR_EF | FSR_PF | FSR_TF | FSR_IGN)

#define ARM_SMMU_CB_FSRRESTORE		0x5c
#define ARM_SMMU_CB_FAR			0x60

#define ARM_SMMU_CB_FSYNR0		0x68
#define FSYNR0_WNR			BIT(4)

#define ARM_SMMU_CB_FSYNR1		0x6c
#define ARM_SMMU_CB_S1_TLBIVA		0x600
#define ARM_SMMU_CB_S1_TLBIASID		0x610
@@ -164,7 +204,6 @@ enum arm_smmu_cbar_type {
#define ARM_SMMU_CB_TLBSTATUS		0x7f4
#define TLBSTATUS_SACTIVE		(1 << 0)
#define ARM_SMMU_CB_ATS1PR		0x800
#define ARM_SMMU_CB_ATSR		0x8f0
#define ARM_SMMU_STATS_SYNC_INV_TBU_ACK 0x25dc
#define ARM_SMMU_TBU_PWR_STATUS         0x2204
#define ARM_SMMU_MMU2QSS_AND_SAFE_WAIT_CNTR 0x2670
@@ -179,45 +218,9 @@ enum arm_smmu_cbar_type {
#define SCTLR_WACFG_WA			0x2
#define SCTLR_MEM_ATTR_OISH_WB_CACHE	0xf
#define SCTLR_MTCFG			(1 << 20)
#define SCTLR_S1_ASIDPNE		(1 << 12)
#define SCTLR_CFCFG			(1 << 7)
#define SCTLR_HUPCF			(1 << 8)
#define SCTLR_CFIE			(1 << 6)
#define SCTLR_CFRE			(1 << 5)
#define SCTLR_E				(1 << 4)
#define SCTLR_AFE			(1 << 2)
#define SCTLR_TRE			(1 << 1)
#define SCTLR_M				(1 << 0)

#define CB_PAR_F			(1 << 0)

#define ATSR_ACTIVE			(1 << 0)

#define RESUME_RETRY			(0 << 0)
#define RESUME_TERMINATE		(1 << 0)

#define TTBCR2_SEP_SHIFT		15
#define TTBCR2_SEP_UPSTREAM		(0x7 << TTBCR2_SEP_SHIFT)
#define TTBCR2_AS			(1 << 4)

#define TTBRn_ASID_SHIFT		48

#define FSR_MULTI			(1 << 31)
#define FSR_SS				(1 << 30)
#define FSR_UUT				(1 << 8)
#define FSR_ASF				(1 << 7)
#define FSR_TLBLKF			(1 << 6)
#define FSR_TLBMCF			(1 << 5)
#define FSR_EF				(1 << 4)
#define FSR_PF				(1 << 3)
#define FSR_AFF				(1 << 2)
#define FSR_TF				(1 << 1)

#define FSR_IGN				(FSR_AFF | FSR_ASF | \
					 FSR_TLBMCF | FSR_TLBLKF)
#define FSR_FAULT			(FSR_MULTI | FSR_SS | FSR_UUT | \
					 FSR_EF | FSR_PF | FSR_TF | FSR_IGN)

#define FSYNR0_WNR			(1 << 4)
#define ARM_SMMU_CB_ATSR		0x8f0
#define ATSR_ACTIVE			BIT(0)

#endif /* _ARM_SMMU_REGS_H */
+10 −10
Original line number Diff line number Diff line
@@ -1624,16 +1624,16 @@ static void arm_smmu_init_context_bank(struct arm_smmu_domain *smmu_domain,

	cb->cfg = cfg;

	/* TTBCR */
	/* TCR */
	if (stage1) {
		if (cfg->fmt == ARM_SMMU_CTX_FMT_AARCH32_S) {
			cb->tcr[0] = pgtbl_cfg->arm_v7s_cfg.tcr;
		} else {
			cb->tcr[0] = pgtbl_cfg->arm_lpae_s1_cfg.tcr;
			cb->tcr[1] = pgtbl_cfg->arm_lpae_s1_cfg.tcr >> 32;
			cb->tcr[1] |= TTBCR2_SEP_UPSTREAM;
			cb->tcr[1] |= FIELD_PREP(TCR2_SEP, TCR2_SEP_UPSTREAM);
			if (cfg->fmt == ARM_SMMU_CTX_FMT_AARCH64)
				cb->tcr[1] |= TTBCR2_AS;
				cb->tcr[1] |= TCR2_AS;
		}
	} else {
		cb->tcr[0] = pgtbl_cfg->arm_lpae_s2_cfg.vtcr;
@@ -1646,9 +1646,9 @@ static void arm_smmu_init_context_bank(struct arm_smmu_domain *smmu_domain,
			cb->ttbr[1] = pgtbl_cfg->arm_v7s_cfg.ttbr[1];
		} else {
			cb->ttbr[0] = pgtbl_cfg->arm_lpae_s1_cfg.ttbr[0];
			cb->ttbr[0] |= (u64)cfg->asid << TTBRn_ASID_SHIFT;
			cb->ttbr[0] |= FIELD_PREP(TTBRn_ASID, cfg->asid);
			cb->ttbr[1] = pgtbl_cfg->arm_lpae_s1_cfg.ttbr[1];
			cb->ttbr[1] |= (u64)cfg->asid << TTBRn_ASID_SHIFT;
			cb->ttbr[1] |= FIELD_PREP(TTBRn_ASID, cfg->asid);
		}
	} else {
		cb->ttbr[0] = pgtbl_cfg->arm_lpae_s2_cfg.vttbr;
@@ -1719,13 +1719,13 @@ static void arm_smmu_write_context_bank(struct arm_smmu_device *smmu, int idx,
	writel_relaxed(reg, gr1_base + ARM_SMMU_GR1_CBAR(idx));

	/*
	 * TTBCR
	 * TCR
	 * We must write this before the TTBRs, since it determines the
	 * access behaviour of some fields (in particular, ASID[15:8]).
	 */
	if (stage1 && smmu->version > ARM_SMMU_V1)
		writel_relaxed(cb->tcr[1], cb_base + ARM_SMMU_CB_TTBCR2);
	writel_relaxed(cb->tcr[0], cb_base + ARM_SMMU_CB_TTBCR);
		writel_relaxed(cb->tcr[1], cb_base + ARM_SMMU_CB_TCR2);
	writel_relaxed(cb->tcr[0], cb_base + ARM_SMMU_CB_TCR);

	/* TTBRs */
	if (cfg->fmt == ARM_SMMU_CTX_FMT_AARCH32_S) {
@@ -3502,8 +3502,8 @@ static int arm_smmu_domain_get_attr(struct iommu_domain *domain,
		}
		val = pgtbl_cfg->arm_lpae_s1_cfg.ttbr[0];
		if (smmu_domain->cfg.cbar != CBAR_TYPE_S2_TRANS)
			val |= (u64)ARM_SMMU_CB_ASID(smmu, &smmu_domain->cfg)
					<< (TTBRn_ASID_SHIFT);
			val |= FIELD_PREP(TTBRn_ASID, ARM_SMMU_CB_ASID(smmu,
							&smmu_domain->cfg));
		*((u64 *)data) = val;
		ret = 0;
		break;
+7 −6
Original line number Diff line number Diff line
@@ -7,6 +7,7 @@
 */

#include <linux/atomic.h>
#include <linux/bitfield.h>
#include <linux/clk.h>
#include <linux/delay.h>
#include <linux/dma-iommu.h>
@@ -247,16 +248,16 @@ static int qcom_iommu_init_domain(struct iommu_domain *domain,
		/* TTBRs */
		iommu_writeq(ctx, ARM_SMMU_CB_TTBR0,
				pgtbl_cfg.arm_lpae_s1_cfg.ttbr[0] |
				((u64)ctx->asid << TTBRn_ASID_SHIFT));
				FIELD_PREP(TTBRn_ASID, ctx->asid));
		iommu_writeq(ctx, ARM_SMMU_CB_TTBR1,
				pgtbl_cfg.arm_lpae_s1_cfg.ttbr[1] |
				((u64)ctx->asid << TTBRn_ASID_SHIFT));
				FIELD_PREP(TTBRn_ASID, ctx->asid));

		/* TTBCR */
		iommu_writel(ctx, ARM_SMMU_CB_TTBCR2,
		/* TCR */
		iommu_writel(ctx, ARM_SMMU_CB_TCR2,
				(pgtbl_cfg.arm_lpae_s1_cfg.tcr >> 32) |
				TTBCR2_SEP_UPSTREAM);
		iommu_writel(ctx, ARM_SMMU_CB_TTBCR,
				FIELD_PREP(TCR2_SEP, TCR2_SEP_UPSTREAM));
		iommu_writel(ctx, ARM_SMMU_CB_TCR,
				pgtbl_cfg.arm_lpae_s1_cfg.tcr);

		/* MAIRs (stage-1 only) */