iommu: add qcom_iommu for early "B" family devices
Subsystems (3)
cover iommu: add qcom_iommu for early "B" family devices
An iommu driver for Qualcomm "B" family devices which do implement the ARM SMMU spec, but not in a way that arm-smmu can support.
(I initially added support to arm-smmu, but it was decided that approach was too intrusive and it would be cleaner to have a separate driver.)
I should note that all the dependencies for this driver have been merged since 4.12, and it is the last thing needed for having another fully- enabled (gpu/display/video codec/etc) ARM device that is fully upstream.
Rob Clark (3):
Docs: dt: document qcom iommu bindings
iommu: arm-smmu: split out register defines
iommu: add qcom_iommu
Stanimir Varbanov (1):
iommu: qcom: initialize secure page table
.../devicetree/bindings/iommu/qcom,iommu.txt | 121 +++ drivers/iommu/Kconfig | 10 + drivers/iommu/Makefile | 1 + drivers/iommu/arm-smmu-regs.h | 227 +++++ drivers/iommu/arm-smmu.c | 203 +---- drivers/iommu/qcom_iommu.c | 932 +++++++++++++++++++++ 6 files changed, 1292 insertions(+), 202 deletions(-) create mode 100644 Documentation/devicetree/bindings/iommu/qcom,iommu.txt create mode 100644 drivers/iommu/arm-smmu-regs.h create mode 100644 drivers/iommu/qcom_iommu.c
Signature · 1 line
2.13.0
A message that is not in the archive (sent off-list or not yet received): 20170713120747.20490-1-robdclark-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org
PATCH RESEND 1/4 Docs: dt: document qcom iommu bindings
--- .../devicetree/bindings/iommu/qcom,iommu.txt | 121 +++++++++++++++++++++ 1 file changed, 121 insertions(+) create mode 100644 Documentation/devicetree/bindings/iommu/qcom,iommu.txt
Documentation/devicetree/bindings/iommu/qcom,iommu.txt new file +121 -0
@@ -0,0 +1,121 @@ +* QCOM IOMMU v1 Implementation + +Qualcomm "B" family devices which are not compatible with arm-smmu have +a similar looking IOMMU but without access to the global register space, +and optionally requiring additional configuration to route context irqs +to non-secure vs secure interrupt line. + +** Required properties: + +- compatible : Should be one of: + + "qcom,msm8916-iommu" + + Followed by "qcom,msm-iommu-v1". + +- clock-names : Should be a pair of "iface" (required for IOMMUs + register group access) and "bus" (required for + the IOMMUs underlying bus access). + +- clocks : Phandles for respective clocks described by + clock-names. + +- #address-cells : must be 1. + +- #size-cells : must be 1. + +- #iommu-cells : Must be 1. Index identifies the context-bank #. + +- ranges : Base address and size of the iommu context banks. + +- qcom,iommu-secure-id : secure-id. + +- List of sub-nodes, one per translation context bank. Each sub-node + has the following required properties: + + - compatible : Should be one of: + - "qcom,msm-iommu-v1-ns" : non-secure context bank + - "qcom,msm-iommu-v1-sec" : secure context bank + - reg : Base address and size of context bank within the iommu + - interrupts : The context fault irq. + +** Optional properties: + +- reg : Base address and size of the SMMU local base, should + be only specified if the iommu requires configuration + for routing of context bank irq's to secure vs non- + secure lines. (Ie. if the iommu contains secure + context banks) + + +** Examples: + + apps_iommu: iommu@1e20000 { + #address-cells = <1>; + #size-cells = <1>; + #iommu-cells = <1>; + compatible = "qcom,msm8916-iommu", "qcom,msm-iommu-v1"; + ranges = <0 0x1e20000 0x40000>; + reg = <0x1ef0000 0x3000>; + clocks = <&gcc GCC_SMMU_CFG_CLK>, + <&gcc GCC_APSS_TCU_CLK>; + clock-names = "iface", "bus"; + qcom,iommu-secure-id = <17>; + + // mdp_0: + iommu-ctx@4000 { + compatible = "qcom,msm-iommu-v1-ns"; + reg = <0x4000 0x1000>; + interrupts = <GIC_SPI 70 IRQ_TYPE_LEVEL_HIGH>; + }; + + // venus_ns: + iommu-ctx@5000 { + compatible = "qcom,msm-iommu-v1-sec"; + reg = <0x5000 0x1000>; + interrupts = <GIC_SPI 70 IRQ_TYPE_LEVEL_HIGH>; + }; + }; + + gpu_iommu: iommu@1f08000 { + #address-cells = <1>; + #size-cells = <1>; + #iommu-cells = <1>; + compatible = "qcom,msm8916-iommu", "qcom,msm-iommu-v1"; + ranges = <0 0x1f08000 0x10000>; + clocks = <&gcc GCC_SMMU_CFG_CLK>, + <&gcc GCC_GFX_TCU_CLK>; + clock-names = "iface", "bus"; + qcom,iommu-secure-id = <18>; + + // gfx3d_user: + iommu-ctx@1000 { + compatible = "qcom,msm-iommu-v1-ns"; + reg = <0x1000 0x1000>; + interrupts = <GIC_SPI 241 IRQ_TYPE_LEVEL_HIGH>; + }; + + // gfx3d_priv: + iommu-ctx@2000 { + compatible = "qcom,msm-iommu-v1-ns"; + reg = <0x2000 0x1000>; + interrupts = <GIC_SPI 242 IRQ_TYPE_LEVEL_HIGH>; + }; + }; + + ... + + venus: video-codec@1d00000 { + ... + iommus = <&apps_iommu 5>; + }; + + mdp: mdp@1a01000 { + ... + iommus = <&apps_iommu 4>; + }; + + gpu@01c00000 { + ... + iommus = <&gpu_iommu 1>, <&gpu_iommu 2>; + };
Signature · 1 line
2.13.0
Archit Taneja
Tested-byQuoted 9 lines · Rob Clark
An iommu driver for Qualcomm "B" family devices which do implement the ARM SMMU spec, but not in a way that arm-smmu can support.
(I initially added support to arm-smmu, but it was decided that approach was too intrusive and it would be cleaner to have a separate driver.)
I should note that all the dependencies for this driver have been merged since 4.12, and it is the last thing needed for having another fully- enabled (gpu/display/video codec/etc) ARM device that is fully upstream.
fwiw:
Quoted 20 lines
Rob Clark (3):
Docs: dt: document qcom iommu bindings
iommu: arm-smmu: split out register defines
iommu: addqcom_iommuStanimir Varbanov (1):
iommu: qcom: initialize secure page table.../devicetree/bindings/iommu/qcom,iommu.txt | 121 +++ drivers/iommu/Kconfig | 10 + drivers/iommu/Makefile | 1 + drivers/iommu/arm-smmu-regs.h | 227 +++++ drivers/iommu/arm-smmu.c | 203 +---- drivers/iommu/qcom_iommu.c | 932 +++++++++++++++++++++ 6 files changed, 1292 insertions(+), 202 deletions(-)create mode 100644
Documentation/devicetree/bindings/iommu/qcom,iommu.txtcreate mode 100644drivers/iommu/arm-smmu-regs.h
create mode 100644drivers/iommu/qcom_iommu.c
Signature · 2 lines
Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum, a Linux Foundation Collaborative Project
PATCH RESEND 2/4 iommu: arm-smmu: split out register defines
In reply to Rob ClarkI want to re-use some of these for qcom_iommu, which has (roughly) the same context-bank registers.
--- drivers/iommu/arm-smmu-regs.h | 227 ++++++++++++++++++++++++++++++++++++++++++ drivers/iommu/arm-smmu.c | 203 +------------------------------------ 2 files changed, 228 insertions(+), 202 deletions(-) create mode 100644 drivers/iommu/arm-smmu-regs.h
drivers/iommu/arm-smmu-regs.h new file +227 -0
@@ -0,0 +1,227 @@ +/* +* IOMMU API for ARM architected SMMU implementations. +* +* This program is free software; you can redistribute it and/or modify +* it under the terms of the GNU General Public License version 2 as +* published by the Free Software Foundation. +* +* This program is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with this program; if not, write to the Free Software +* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +* +* Copyright (C) 2013 ARM Limited +* +* Author: Will Deacon <[email protected]> +*/ + +#ifndef _ARM_SMMU_REGS_H +#define _ARM_SMMU_REGS_H + +/* Configuration registers */ +#define ARM_SMMU_GR0_sCR0 0x0 +#define sCR0_CLIENTPD (1 << 0) +#define sCR0_GFRE (1 << 1) +#define sCR0_GFIE (1 << 2) +#define sCR0_EXIDENABLE (1 << 3) +#define sCR0_GCFGFRE (1 << 4) +#define sCR0_GCFGFIE (1 << 5) +#define sCR0_USFCFG (1 << 10) +#define sCR0_VMIDPNE (1 << 11) +#define sCR0_PTM (1 << 12) +#define sCR0_FB (1 << 13) +#define sCR0_VMID16EN (1 << 31) +#define sCR0_BSU_SHIFT 14 +#define sCR0_BSU_MASK 0x3 + +/* Auxiliary Configuration register */ +#define ARM_SMMU_GR0_sACR 0x10 + +/* Identification registers */ +#define ARM_SMMU_GR0_ID0 0x20 +#define ARM_SMMU_GR0_ID1 0x24 +#define ARM_SMMU_GR0_ID2 0x28 +#define ARM_SMMU_GR0_ID3 0x2c +#define ARM_SMMU_GR0_ID4 0x30 +#define ARM_SMMU_GR0_ID5 0x34 +#define ARM_SMMU_GR0_ID6 0x38 +#define ARM_SMMU_GR0_ID7 0x3c +#define ARM_SMMU_GR0_sGFSR 0x48 +#define ARM_SMMU_GR0_sGFSYNR0 0x50 +#define ARM_SMMU_GR0_sGFSYNR1 0x54 +#define ARM_SMMU_GR0_sGFSYNR2 0x58 + +#define ID0_S1TS (1 << 30) +#define ID0_S2TS (1 << 29) +#define ID0_NTS (1 << 28) +#define ID0_SMS (1 << 27) +#define ID0_ATOSNS (1 << 26) +#define ID0_PTFS_NO_AARCH32 (1 << 25) +#define ID0_PTFS_NO_AARCH32S (1 << 24) +#define ID0_CTTW (1 << 14) +#define ID0_NUMIRPT_SHIFT 16 +#define ID0_NUMIRPT_MASK 0xff +#define ID0_NUMSIDB_SHIFT 9 +#define ID0_NUMSIDB_MASK 0xf +#define ID0_EXIDS (1 << 8) +#define ID0_NUMSMRG_SHIFT 0 +#define ID0_NUMSMRG_MASK 0xff + +#define ID1_PAGESIZE (1 << 31) +#define ID1_NUMPAGENDXB_SHIFT 28 +#define ID1_NUMPAGENDXB_MASK 7 +#define ID1_NUMS2CB_SHIFT 16 +#define ID1_NUMS2CB_MASK 0xff +#define ID1_NUMCB_SHIFT 0 +#define ID1_NUMCB_MASK 0xff + +#define ID2_OAS_SHIFT 4 +#define ID2_OAS_MASK 0xf +#define ID2_IAS_SHIFT 0 +#define ID2_IAS_MASK 0xf +#define ID2_UBS_SHIFT 8 +#define ID2_UBS_MASK 0xf +#define ID2_PTFS_4K (1 << 12) +#define ID2_PTFS_16K (1 << 13) +#define ID2_PTFS_64K (1 << 14) +#define ID2_VMID16 (1 << 15) + +#define ID7_MAJOR_SHIFT 4 +#define ID7_MAJOR_MASK 0xf + +/* Global TLB invalidation */ +#define ARM_SMMU_GR0_TLBIVMID 0x64 +#define ARM_SMMU_GR0_TLBIALLNSNH 0x68 +#define ARM_SMMU_GR0_TLBIALLH 0x6c +#define ARM_SMMU_GR0_sTLBGSYNC 0x70 +#define ARM_SMMU_GR0_sTLBGSTATUS 0x74 +#define sTLBGSTATUS_GSACTIVE (1 << 0) +#define TLB_LOOP_TIMEOUT 1000000/* 1s! */ +#define TLB_SPIN_COUNT 10 + +/* Stream mapping registers */ +#define ARM_SMMU_GR0_SMR (n) (0x800 + ((n) << 2)) +#define SMR_VALID (1 << 31) +#define SMR_MASK_SHIFT 16 +#define SMR_ID_SHIFT 0 + +#define ARM_SMMU_GR0_S2CR (n) (0xc00 + ((n) << 2)) +#define S2CR_CBNDX_SHIFT 0 +#define S2CR_CBNDX_MASK 0xff +#define S2CR_EXIDVALID (1 << 10) +#define S2CR_TYPE_SHIFT 16 +#define S2CR_TYPE_MASK 0x3 +enum arm_smmu_s2cr_type { +S2CR_TYPE_TRANS , +S2CR_TYPE_BYPASS , +S2CR_TYPE_FAULT , +}; + +#define S2CR_PRIVCFG_SHIFT 24 +#define S2CR_PRIVCFG_MASK 0x3 +enum arm_smmu_s2cr_privcfg { +S2CR_PRIVCFG_DEFAULT , +S2CR_PRIVCFG_DIPAN , +S2CR_PRIVCFG_UNPRIV , +S2CR_PRIVCFG_PRIV , +}; + +/* Context bank attribute registers */ +#define ARM_SMMU_GR1_CBAR (n) (0x0 + ((n) << 2)) +#define CBAR_VMID_SHIFT 0 +#define CBAR_VMID_MASK 0xff +#define CBAR_S1_BPSHCFG_SHIFT 8 +#define CBAR_S1_BPSHCFG_MASK 3 +#define CBAR_S1_BPSHCFG_NSH 3 +#define CBAR_S1_MEMATTR_SHIFT 12 +#define CBAR_S1_MEMATTR_MASK 0xf +#define CBAR_S1_MEMATTR_WB 0xf +#define CBAR_TYPE_SHIFT 16 +#define CBAR_TYPE_MASK 0x3 +#define CBAR_TYPE_S2_TRANS (0 << CBAR_TYPE_SHIFT) +#define CBAR_TYPE_S1_TRANS_S2_BYPASS (1 << CBAR_TYPE_SHIFT) +#define CBAR_TYPE_S1_TRANS_S2_FAULT (2 << CBAR_TYPE_SHIFT) +#define CBAR_TYPE_S1_TRANS_S2_TRANS (3 << CBAR_TYPE_SHIFT) +#define CBAR_IRPTNDX_SHIFT 24 +#define CBAR_IRPTNDX_MASK 0xff + +#define ARM_SMMU_GR1_CBA2R (n) (0x800 + ((n) << 2)) +#define CBA2R_RW64_32BIT (0 << 0) +#define CBA2R_RW64_64BIT (1 << 0) +#define CBA2R_VMID_SHIFT 16 +#define CBA2R_VMID_MASK 0xffff + +#define ARM_SMMU_CB_SCTLR 0x0 +#define ARM_SMMU_CB_ACTLR 0x4 +#define ARM_SMMU_CB_RESUME 0x8 +#define ARM_SMMU_CB_TTBCR2 0x10 +#define ARM_SMMU_CB_TTBR0 0x20 +#define ARM_SMMU_CB_TTBR1 0x28 +#define ARM_SMMU_CB_TTBCR 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 ARM_SMMU_CB_FSR 0x58 +#define ARM_SMMU_CB_FAR 0x60 +#define ARM_SMMU_CB_FSYNR0 0x68 +#define ARM_SMMU_CB_S1_TLBIVA 0x600 +#define ARM_SMMU_CB_S1_TLBIASID 0x610 +#define ARM_SMMU_CB_S1_TLBIVAL 0x620 +#define ARM_SMMU_CB_S2_TLBIIPAS2 0x630 +#define ARM_SMMU_CB_S2_TLBIIPAS2L 0x638 +#define ARM_SMMU_CB_TLBSYNC 0x7f0 +#define ARM_SMMU_CB_TLBSTATUS 0x7f4 +#define ARM_SMMU_CB_ATS1PR 0x800 +#define ARM_SMMU_CB_ATSR 0x8f0 + +#define SCTLR_S1_ASIDPNE (1 << 12) +#define SCTLR_CFCFG (1 << 7) +#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 ARM_MMU500_ACTLR_CPRE (1 << 1) + +#define ARM_MMU500_ACR_CACHE_LOCK (1 << 26) +#define ARM_MMU500_ACR_SMTNMB_TLBEN (1 << 8) + +#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) + +#endif /* _ARM_SMMU_REGS_H */
drivers/iommu/arm-smmu.c +1 -202
218 lines not on this page · raw message
Signature · 1 line
2.13.0
A message that is not in the archive (sent off-list or not yet received): 20170713120747.20490-3-robdclark-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org
Re: [RESEND PATCH 2/4] iommu: arm-smmu: split out register defines
Quoted 39 lines · Rob Clark
I want to re-use some of these for
qcom_iommu, which has (roughly) the same context-bank registers.Signed-off-by Rob Clark <[email protected]>--- drivers/iommu/arm-smmu-regs.h | 227 ++++++++++++++++++++++++++++++++++++++++++ drivers/iommu/arm-smmu.c | 203 +------------------------------------ 2 files changed, 228 insertions(+), 202 deletions(-) create mode 100644 drivers/iommu/arm-smmu-regs.hdrivers/iommu/arm-smmu-regs.h new file +23
-0@@ -0,0 +1,227 @@ +/* +* IOMMU API for ARM architected SMMU implementations. +* +* This program is free software; you can redistribute it and/or modify +* it under the terms of the GNU General Public License version 2 as +* published by the Free Software Foundation. +* +* This program is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with this program; if not, write to the Free Software +* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +* +* Copyright (C) 2013 ARM Limited +* +* Author: Will Deacon <[email protected]> +*/ + +#ifndef _ARM_SMMU_REGS_H +#define _ARM_SMMU_REGS_H
[...]
drivers/iommu/arm-smmu-regs.h line 104
Quoted 9 lines
drivers/iommu/arm-smmu-regs.h new file +9
-0+/* Global TLB invalidation */ +#define ARM_SMMU_GR0_TLBIVMID 0x64 +#define ARM_SMMU_GR0_TLBIALLNSNH 0x68 +#define ARM_SMMU_GR0_TLBIALLH 0x6c +#define ARM_SMMU_GR0_sTLBGSYNC 0x70 +#define ARM_SMMU_GR0_sTLBGSTATUS 0x74 +#define sTLBGSTATUS_GSACTIVE (1 << 0) +#define TLB_LOOP_TIMEOUT 1000000/* 1s! */ +#define TLB_SPIN_COUNT 10
Do you need these TLB defines? They're not part of the architected register state.
drivers/iommu/arm-smmu-regs.h line 194
Quoted 13 lines
drivers/iommu/arm-smmu-regs.h new file +13
-0+#define SCTLR_S1_ASIDPNE (1 << 12) +#define SCTLR_CFCFG (1 << 7) +#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 ARM_MMU500_ACTLR_CPRE (1 << 1) + +#define ARM_MMU500_ACR_CACHE_LOCK (1 << 26) +#define ARM_MMU500_ACR_SMTNMB_TLBEN (1 << 8)
The MMU-500 defines can probably stay in arm-smmu.c.
Will
PATCH RESEND 3/4 iommu: add qcom_iommu
In reply to Rob ClarkAn iommu driver for Qualcomm "B" family devices which do implement the ARM SMMU spec, but not in a way that is compatible with how the arm-smmu driver is designed. It seems SMMU_SCR1.GASRAE=1 so the global register space is not accessible. This means it needs to get configuration from devicetree instead of setting it up dynamically.
In the end, other than register definitions, there is not much code to share with arm-smmu (other than what has already been refactored out into the pgtable helpers).
---
v1: original
v2: bindings cleanups and kconfig issues that kbuild robot pointed out
v3: fix issues pointed out by Rob H. and actually make device removal
work
v4: fix WARN_ON() splats reported by Archit
v5: some fixes to build as a module.. note that it cannot actually
be built as a module yet (at minimum a bunch of other iommu syms that are needed are not exported, but there may be more to it than that), but at least qcom_iommu is ready should it become possible to build iommu drivers as modules.
v6: Add additional pm-runtime get/puts around paths that can hit
TLB inv, to avoid unclocked register access if device using the iommu is not powered on. And pre-emptively clear interrupts before registering IRQ handler just in case the bootloader has left us a surpise.
v7: Address review comments from Robin (don't associate iommu_group
with context bank, table lookup instead of list to find context bank, etc)
v8: Fix silly bug on detach. Actually Robin already pointed it out
but I somehow overlooked that comment when preparing v7.
drivers/iommu/Kconfig | 10 + drivers/iommu/Makefile | 1 + drivers/iommu/qcom_iommu.c | 868 +++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 879 insertions(+) create mode 100644 drivers/iommu/qcom_iommu.c
drivers/iommu/Kconfig +10 -0
@@ -367,4 +367,14 @@ config MTK_IOMMU_V1 if unsure, say N here. +config QCOM_IOMMU + # Note: iommu drivers cannot (yet?) be built as modules + bool "Qualcomm IOMMU Support" + depends on ARCH_QCOM || COMPILE_TEST + select IOMMU_API + select IOMMU_IO_PGTABLE_LPAE + select ARM_DMA_USE_IOMMU + help + Support for IOMMU on certain Qualcomm SoCs. + endif # IOMMU_SUPPORT
drivers/iommu/Makefile +1 -0
@@ -27,3 +27,4 @@ obj-$(CONFIG_TEGRA_IOMMU_SMMU) += tegra-smmu.o obj-$(CONFIG_EXYNOS_IOMMU) += exynos-iommu.o obj-$(CONFIG_FSL_PAMU) += fsl_pamu.o fsl_pamu_domain.o obj-$(CONFIG_S390_IOMMU) += s390-iommu.o +obj-$(CONFIG_QCOM_IOMMU) += qcom_iommu.o
drivers/iommu/qcom_iommu.c new file +868 -0
868 lines not on this page · raw message
Signature · 1 line
2.13.0
PATCH RESEND 4/4 iommu: qcom: initialize secure page table
In reply to Rob ClarkFrom: Stanimir Varbanov <[email protected]>
This basically gets the secure page table size, allocates memory for secure pagetables and passes the physical address to the trusted zone.
--- drivers/iommu/qcom_iommu.c | 64 ++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 64 insertions(+)
drivers/iommu/qcom_iommu.c +64 -0
@@ -604,6 +604,51 @@ static void qcom_iommu_disable_clocks(struct qcom_iommu_dev *qcom_iommu)clk_disable_unprepare (qcom_iommu->iface_clk); } +static int qcom_iommu_sec_ptbl_init (struct device *dev) +{ +size_t psize =0 ; +unsigned int spare =0 ; +void *cpu_addr; +dma_addr_t paddr; +unsigned long attrs; +static bool allocated = false; +int ret; + +if (allocated) +return 0 ; + + ret =qcom_scm_iommu_secure_ptbl_size (spare, &psize); +if (ret) { +dev_err (dev,"failed to get iommu secure pgtable size (%d)\n" , + ret); +return ret; + } + +dev_info (dev,"iommu sec: pgtable size: %zu\n" , psize); + + attrs =DMA_ATTR_NO_KERNEL_MAPPING ; + + cpu_addr =dma_alloc_attrs (dev, psize, &paddr,GFP_KERNEL , attrs); +if (!cpu_addr) { +dev_err (dev,"failed to allocate %zu bytes for pgtable\n" , + psize); +return -ENOMEM ; + } + + ret =qcom_scm_iommu_secure_ptbl_init (paddr, psize, spare); +if (ret) { +dev_err (dev,"failed to init iommu pgtable (%d)\n" , ret); + goto free_mem; + } + + allocated = true; +return 0 ; + +free_mem: +dma_free_attrs (dev, psize, cpu_addr, paddr, attrs); +return ret; +} +static int get_asid (const struct device_node *np) {u32 reg;
@@ -700,6 +745,17 @@ static struct platform_driver qcom_iommu_ctx_driver = { .remove = qcom_iommu_ctx_remove, }; +static bool qcom_iommu_has_secure_context (struct qcom_iommu_dev *qcom_iommu) +{ +struct device_node *child; + +for_each_child_of_node (qcom_iommu->dev->of_node, child) +if (of_device_is_compatible (child,"qcom,msm-iommu-v1-sec" )) +return true; + +return false; +} +static int qcom_iommu_device_probe (struct platform_device *pdev) {struct device_node *child;
@@ -744,6 +800,14 @@ static int qcom_iommu_device_probe(struct platform_device *pdev)return -ENODEV ; } +if (qcom_iommu_has_secure_context (qcom_iommu)) { + ret =qcom_iommu_sec_ptbl_init (dev); +if (ret) { +dev_err (dev,"cannot init secure pg table(%d)\n" , ret); +return ret; + } + } +platform_set_drvdata (pdev, qcom_iommu);pm_runtime_enable (dev);
Signature · 1 line
2.13.0