Add functions for checking SMMU bypass status and also, matching valid hardware device Stream IDs in SMMU Stream Mapping registers.
Signed-off-by: Naresh Kumar Ravulapalli <nareshkumar.ravulapa...@altera.com> --- arch/arm/mach-socfpga/include/mach/smmu_s10.h | 28 +++++++++++ arch/arm/mach-socfpga/smmu_s10.c | 48 +++++++++++++++++++ 2 files changed, 76 insertions(+) diff --git a/arch/arm/mach-socfpga/include/mach/smmu_s10.h b/arch/arm/mach-socfpga/include/mach/smmu_s10.h index 4a28b109b0d..209caa86e38 100644 --- a/arch/arm/mach-socfpga/include/mach/smmu_s10.h +++ b/arch/arm/mach-socfpga/include/mach/smmu_s10.h @@ -4,7 +4,35 @@ * Copyright (C) 2025 Altera Corporation <www.altera.com> */ +/* SMMU registers */ +#define SMMU_SCR0 0 +#define SMMU_SIDR0 0x20 +#define SMMU_SIDR1 0x24 + +#define SMMU_SCR0_CLIENTPD BIT(0) +#define SMMU_SIDR0_NUMSMRG_MASK GENMASK(7, 0) +#define SMMU_SIDR1_NUMCB_MASK GENMASK(7, 0) + +/* Stream mapping registers */ +#define SMMU_GR0_SMR(n) (0x800 + ((n) << 2)) +#define SMMU_SMR_VALID BIT(31) +#define SMMU_SMR_MASK GENMASK(30, 16) +#define SMMU_SMR_ID GENMASK(14, 0) + +#define SMMU_GR0_S2CR(n) (0xc00 + ((n) << 2)) +#define SMMU_S2CR_TYPE GENMASK(17, 16) +#define SMMU_S2CR_CBNDX GENMASK(7, 0) + +/* Register groups for Context Bank */ +#define SMMU_GR0_CB(n, r) (0x20000 + ((n) << 12) + ((r) << 2)) +#define SMMU_CB_SCTLR 0 +#define SMMU_CB_SCTLR_M BIT(0) + +#define SMMU_SID_SDM2HPS_PSI_BE 0 + void socfpga_init_smmu(void); +int is_smmu_bypass(void); +int is_smmu_stream_id_enabled(u32 stream_id); #define SMMU_SET_STREAMID(x, r, w) (((x) << (r)) | ((x) << (w))) diff --git a/arch/arm/mach-socfpga/smmu_s10.c b/arch/arm/mach-socfpga/smmu_s10.c index 50be049538b..c3230ce860e 100644 --- a/arch/arm/mach-socfpga/smmu_s10.c +++ b/arch/arm/mach-socfpga/smmu_s10.c @@ -75,3 +75,51 @@ void socfpga_init_smmu(void) set_smmu_streamid(); set_smmu_accessible_reg(); } + +int is_smmu_bypass(void) +{ + return readl(SOCFPGA_SMMU_ADDRESS + SMMU_SCR0) & SMMU_SCR0_CLIENTPD; +} + +int is_smmu_stream_id_enabled(u32 stream_id) +{ + int i; + u32 smrg_num; + u32 smr, s2cr, sid_mask; + u32 cb, cb_index, cb_num; + + if (is_smmu_bypass()) + return 0; + + /* Get number of Stream Mapping Register Groups */ + smrg_num = readl(SOCFPGA_SMMU_ADDRESS + SMMU_SIDR0) & + SMMU_SIDR0_NUMSMRG_MASK; + + /* Get number of Context Bank */ + cb_num = readl(SOCFPGA_SMMU_ADDRESS + SMMU_SIDR1) & + SMMU_SIDR1_NUMCB_MASK; + + for (i = 0; i < smrg_num; i++) { + smr = readl(SOCFPGA_SMMU_ADDRESS + SMMU_GR0_SMR((u64)i)); + sid_mask = (smr & SMMU_SMR_MASK) >> 16; + + /* Skip if Stream ID is invalid or not matched */ + if (!(smr & SMMU_SMR_VALID) || (smr & sid_mask) != stream_id) + continue; + + /* Get Context Bank index from valid matching Stream ID */ + s2cr = readl(SOCFPGA_SMMU_ADDRESS + SMMU_GR0_S2CR((u64)i)); + cb_index = s2cr & SMMU_S2CR_CBNDX; + + /* Skip if Context Bank is invalid or not Translation mode */ + if (cb_index >= cb_num || (s2cr & SMMU_S2CR_TYPE)) + continue; + + cb = readl(SOCFPGA_SMMU_ADDRESS + SMMU_GR0_CB((u64)cb_index, + SMMU_CB_SCTLR)); + /* Return MMU enable status for this Context Bank */ + return (cb & SMMU_CB_SCTLR_M); + } + + return 0; +} -- 2.35.3