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

Commit 183a0a7e authored by qctecmdr Service's avatar qctecmdr Service Committed by Gerrit - the friendly Code Review server
Browse files

Merge "iommu: arm-smmu: Disable io-coherency in bypass mode"

parents e4d26920 c8f2b610
Loading
Loading
Loading
Loading
+9 −0
Original line number Original line Diff line number Diff line
@@ -37,6 +37,9 @@
#define sCR0_VMID16EN			(1 << 31)
#define sCR0_VMID16EN			(1 << 31)
#define sCR0_BSU_SHIFT			14
#define sCR0_BSU_SHIFT			14
#define sCR0_BSU_MASK			0x3
#define sCR0_BSU_MASK			0x3
#define sCR0_SHCFG_SHIFT		22
#define sCR0_SHCFG_MASK			0x3
#define sCR0_SHCFG_NSH			3


/* Auxiliary Configuration register */
/* Auxiliary Configuration register */
#define ARM_SMMU_GR0_sACR		0x10
#define ARM_SMMU_GR0_sACR		0x10
@@ -114,6 +117,9 @@
#define S2CR_EXIDVALID			(1 << 10)
#define S2CR_EXIDVALID			(1 << 10)
#define S2CR_TYPE_SHIFT			16
#define S2CR_TYPE_SHIFT			16
#define S2CR_TYPE_MASK			0x3
#define S2CR_TYPE_MASK			0x3
#define S2CR_SHCFG_SHIFT		8
#define S2CR_SHCFG_MASK			0x3
#define S2CR_SHCFG_NSH			0x3
enum arm_smmu_s2cr_type {
enum arm_smmu_s2cr_type {
	S2CR_TYPE_TRANS,
	S2CR_TYPE_TRANS,
	S2CR_TYPE_BYPASS,
	S2CR_TYPE_BYPASS,
@@ -184,6 +190,9 @@ enum arm_smmu_s2cr_privcfg {
#define ARM_SMMU_CB_ATS1PR		0x800
#define ARM_SMMU_CB_ATS1PR		0x800
#define ARM_SMMU_CB_ATSR		0x8f0
#define ARM_SMMU_CB_ATSR		0x8f0


#define SCTLR_SHCFG_SHIFT		22
#define SCTLR_SHCFG_MASK		0x3
#define SCTLR_SHCFG_NSH			0x3
#define SCTLR_S1_ASIDPNE		(1 << 12)
#define SCTLR_S1_ASIDPNE		(1 << 12)
#define SCTLR_CFCFG			(1 << 7)
#define SCTLR_CFCFG			(1 << 7)
#define SCTLR_HUPCF			(1 << 8)
#define SCTLR_HUPCF			(1 << 8)
+12 −1
Original line number Original line Diff line number Diff line
@@ -1480,6 +1480,9 @@ static void arm_smmu_write_context_bank(struct arm_smmu_device *smmu, int idx,
	/* SCTLR */
	/* SCTLR */
	reg = SCTLR_CFCFG | SCTLR_CFIE | SCTLR_CFRE | SCTLR_AFE | SCTLR_TRE;
	reg = SCTLR_CFCFG | SCTLR_CFIE | SCTLR_CFRE | SCTLR_AFE | SCTLR_TRE;


	/* Ensure bypass transactions are Non-shareable */
	reg |= SCTLR_SHCFG_NSH << SCTLR_SHCFG_SHIFT;

	if (attributes & (1 << DOMAIN_ATTR_CB_STALL_DISABLE)) {
	if (attributes & (1 << DOMAIN_ATTR_CB_STALL_DISABLE)) {
		reg &= ~SCTLR_CFCFG;
		reg &= ~SCTLR_CFCFG;
		reg |= SCTLR_HUPCF;
		reg |= SCTLR_HUPCF;
@@ -1676,6 +1679,9 @@ static int arm_smmu_init_domain_context(struct iommu_domain *domain,
		quirks |= IO_PGTABLE_QUIRK_QCOM_USE_UPSTREAM_HINT;
		quirks |= IO_PGTABLE_QUIRK_QCOM_USE_UPSTREAM_HINT;
	if (is_iommu_pt_coherent(smmu_domain))
	if (is_iommu_pt_coherent(smmu_domain))
		quirks |= IO_PGTABLE_QUIRK_NO_DMA;
		quirks |= IO_PGTABLE_QUIRK_NO_DMA;
	if ((quirks & IO_PGTABLE_QUIRK_QCOM_USE_UPSTREAM_HINT) &&
		(smmu->model == QCOM_SMMUV500))
		quirks |= IO_PGTABLE_QUIRK_QSMMUV500_NON_SHAREABLE;


	ret = arm_smmu_alloc_cb(domain, smmu, dev);
	ret = arm_smmu_alloc_cb(domain, smmu, dev);
	if (ret < 0)
	if (ret < 0)
@@ -1891,7 +1897,8 @@ static void arm_smmu_write_s2cr(struct arm_smmu_device *smmu, int idx)
	struct arm_smmu_s2cr *s2cr = smmu->s2crs + idx;
	struct arm_smmu_s2cr *s2cr = smmu->s2crs + idx;
	u32 reg = (s2cr->type & S2CR_TYPE_MASK) << S2CR_TYPE_SHIFT |
	u32 reg = (s2cr->type & S2CR_TYPE_MASK) << S2CR_TYPE_SHIFT |
		  (s2cr->cbndx & S2CR_CBNDX_MASK) << S2CR_CBNDX_SHIFT |
		  (s2cr->cbndx & S2CR_CBNDX_MASK) << S2CR_CBNDX_SHIFT |
		  (s2cr->privcfg & S2CR_PRIVCFG_MASK) << S2CR_PRIVCFG_SHIFT;
		  (s2cr->privcfg & S2CR_PRIVCFG_MASK) << S2CR_PRIVCFG_SHIFT |
		  S2CR_SHCFG_NSH << S2CR_SHCFG_SHIFT;


	if (smmu->features & ARM_SMMU_FEAT_EXIDS && smmu->smrs &&
	if (smmu->features & ARM_SMMU_FEAT_EXIDS && smmu->smrs &&
	    smmu->smrs[idx].valid)
	    smmu->smrs[idx].valid)
@@ -3498,6 +3505,10 @@ static void arm_smmu_device_reset(struct arm_smmu_device *smmu)
	if (smmu->features & ARM_SMMU_FEAT_EXIDS)
	if (smmu->features & ARM_SMMU_FEAT_EXIDS)
		reg |= sCR0_EXIDENABLE;
		reg |= sCR0_EXIDENABLE;


	/* Force bypass transaction to be Non-Shareable & not io-coherent */
	reg &= ~(sCR0_SHCFG_MASK << sCR0_SHCFG_SHIFT);
	reg |= sCR0_SHCFG_NSH << sCR0_SHCFG_SHIFT;

	/* Push the button */
	/* Push the button */
	arm_smmu_tlb_sync_global(smmu);
	arm_smmu_tlb_sync_global(smmu);
	writel(reg, ARM_SMMU_GR0_NS(smmu) + ARM_SMMU_GR0_sCR0);
	writel(reg, ARM_SMMU_GR0_NS(smmu) + ARM_SMMU_GR0_sCR0);
+7 −1
Original line number Original line Diff line number Diff line
@@ -1116,7 +1116,8 @@ arm_64_lpae_alloc_pgtable_s1(struct io_pgtable_cfg *cfg, void *cookie)


	if (cfg->quirks & ~(IO_PGTABLE_QUIRK_ARM_NS
	if (cfg->quirks & ~(IO_PGTABLE_QUIRK_ARM_NS
			  | IO_PGTABLE_QUIRK_NO_DMA
			  | IO_PGTABLE_QUIRK_NO_DMA
			  | IO_PGTABLE_QUIRK_QCOM_USE_UPSTREAM_HINT))
			  | IO_PGTABLE_QUIRK_QCOM_USE_UPSTREAM_HINT
			  | IO_PGTABLE_QUIRK_QSMMUV500_NON_SHAREABLE))
		return NULL;
		return NULL;


	data = arm_lpae_alloc_pgtable(cfg);
	data = arm_lpae_alloc_pgtable(cfg);
@@ -1128,6 +1129,11 @@ arm_64_lpae_alloc_pgtable_s1(struct io_pgtable_cfg *cfg, void *cookie)
		reg = (ARM_LPAE_TCR_SH_OS << ARM_LPAE_TCR_SH0_SHIFT) |
		reg = (ARM_LPAE_TCR_SH_OS << ARM_LPAE_TCR_SH0_SHIFT) |
			(ARM_LPAE_TCR_RGN_WBWA << ARM_LPAE_TCR_IRGN0_SHIFT) |
			(ARM_LPAE_TCR_RGN_WBWA << ARM_LPAE_TCR_IRGN0_SHIFT) |
			(ARM_LPAE_TCR_RGN_WBWA << ARM_LPAE_TCR_ORGN0_SHIFT);
			(ARM_LPAE_TCR_RGN_WBWA << ARM_LPAE_TCR_ORGN0_SHIFT);
	else if ((cfg->quirks & IO_PGTABLE_QUIRK_QCOM_USE_UPSTREAM_HINT) &&
		(cfg->quirks & IO_PGTABLE_QUIRK_QSMMUV500_NON_SHAREABLE))
		reg = (ARM_LPAE_TCR_SH_NS << ARM_LPAE_TCR_SH0_SHIFT) |
			(ARM_LPAE_TCR_RGN_NC << ARM_LPAE_TCR_IRGN0_SHIFT) |
			(ARM_LPAE_TCR_RGN_WBWA << ARM_LPAE_TCR_ORGN0_SHIFT);
	else if (cfg->quirks & IO_PGTABLE_QUIRK_QCOM_USE_UPSTREAM_HINT)
	else if (cfg->quirks & IO_PGTABLE_QUIRK_QCOM_USE_UPSTREAM_HINT)
		reg = (ARM_LPAE_TCR_SH_OS << ARM_LPAE_TCR_SH0_SHIFT) |
		reg = (ARM_LPAE_TCR_SH_OS << ARM_LPAE_TCR_SH0_SHIFT) |
			(ARM_LPAE_TCR_RGN_NC << ARM_LPAE_TCR_IRGN0_SHIFT) |
			(ARM_LPAE_TCR_RGN_NC << ARM_LPAE_TCR_IRGN0_SHIFT) |
+8 −0
Original line number Original line Diff line number Diff line
@@ -81,6 +81,13 @@ struct io_pgtable_cfg {
	 *	be accessed by a fully cache-coherent IOMMU or CPU (e.g. for a
	 *	be accessed by a fully cache-coherent IOMMU or CPU (e.g. for a
	 *	software-emulated IOMMU), such that pagetable updates need not
	 *	software-emulated IOMMU), such that pagetable updates need not
	 *	be treated as explicit DMA data.
	 *	be treated as explicit DMA data.
	 *

	 * IO_PGTABLE_QUIRK_QSMMUV500_NON_SHAREABLE:
	 *	Having page tables which are non coherent, but cached in a
	 *	system cache requires SH=Non-Shareable. This applies to the
	 *	qsmmuv500 model. For data buffers SH=Non-Shareable is not
	 *	required.


	 * IO_PGTABLE_QUIRK_QCOM_USE_UPSTREAM_HINT: Override the attributes
	 * IO_PGTABLE_QUIRK_QCOM_USE_UPSTREAM_HINT: Override the attributes
	 *	set in TCR for the page table walker. Use attributes specified
	 *	set in TCR for the page table walker. Use attributes specified
@@ -92,6 +99,7 @@ struct io_pgtable_cfg {
	#define IO_PGTABLE_QUIRK_TLBI_ON_MAP	BIT(2)
	#define IO_PGTABLE_QUIRK_TLBI_ON_MAP	BIT(2)
	#define IO_PGTABLE_QUIRK_ARM_MTK_4GB	BIT(3)
	#define IO_PGTABLE_QUIRK_ARM_MTK_4GB	BIT(3)
	#define IO_PGTABLE_QUIRK_NO_DMA		BIT(4)
	#define IO_PGTABLE_QUIRK_NO_DMA		BIT(4)
	#define IO_PGTABLE_QUIRK_QSMMUV500_NON_SHAREABLE BIT(5)
	#define IO_PGTABLE_QUIRK_QCOM_USE_UPSTREAM_HINT	BIT(6)
	#define IO_PGTABLE_QUIRK_QCOM_USE_UPSTREAM_HINT	BIT(6)
	unsigned long			quirks;
	unsigned long			quirks;
	unsigned long			pgsize_bitmap;
	unsigned long			pgsize_bitmap;