Loading drivers/iommu/arm-smmu-regs.h +9 −0 Original line number Original line Diff line number Diff line Loading @@ -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 Loading Loading @@ -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, Loading Loading @@ -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) Loading drivers/iommu/arm-smmu.c +12 −1 Original line number Original line Diff line number Diff line Loading @@ -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; Loading Loading @@ -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) Loading Loading @@ -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) Loading Loading @@ -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); Loading drivers/iommu/io-pgtable-arm.c +7 −1 Original line number Original line Diff line number Diff line Loading @@ -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); Loading @@ -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) | Loading drivers/iommu/io-pgtable.h +8 −0 Original line number Original line Diff line number Diff line Loading @@ -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 Loading @@ -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; Loading Loading
drivers/iommu/arm-smmu-regs.h +9 −0 Original line number Original line Diff line number Diff line Loading @@ -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 Loading Loading @@ -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, Loading Loading @@ -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) Loading
drivers/iommu/arm-smmu.c +12 −1 Original line number Original line Diff line number Diff line Loading @@ -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; Loading Loading @@ -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) Loading Loading @@ -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) Loading Loading @@ -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); Loading
drivers/iommu/io-pgtable-arm.c +7 −1 Original line number Original line Diff line number Diff line Loading @@ -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); Loading @@ -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) | Loading
drivers/iommu/io-pgtable.h +8 −0 Original line number Original line Diff line number Diff line Loading @@ -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 Loading @@ -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; Loading