From c459206d21ac71baca6f742565b6248298872622 Mon Sep 17 00:00:00 2001 From: Pritesh Raithatha Date: Tue, 24 Jan 2017 13:49:46 +0530 Subject: [PATCH] Tegra: smmu: support for multiple devices This patch adds flexibility to the code to initialise multiple SMMU devices. The base address macro name has been changed to make it explicit that we support multiple SMMUs. Change-Id: Id4854fb010ebeb699512d79c769de24050c2ad69 Signed-off-by: Pritesh Raithatha Signed-off-by: Krishna Reddy Signed-off-by: Varun Wadekar --- plat/nvidia/tegra/common/drivers/smmu/smmu.c | 105 ++++++++++++++----- plat/nvidia/tegra/include/drivers/smmu.h | 14 +-- plat/nvidia/tegra/include/t186/tegra_def.h | 2 +- plat/nvidia/tegra/soc/t186/plat_setup.c | 4 +- plat/nvidia/tegra/soc/t186/platform_t186.mk | 3 + 5 files changed, 90 insertions(+), 38 deletions(-) diff --git a/plat/nvidia/tegra/common/drivers/smmu/smmu.c b/plat/nvidia/tegra/common/drivers/smmu/smmu.c index abb3408f6..a57db8b1d 100644 --- a/plat/nvidia/tegra/common/drivers/smmu/smmu.c +++ b/plat/nvidia/tegra/common/drivers/smmu/smmu.c @@ -36,6 +36,52 @@ #include #include +/* SMMU IDs currently supported by the driver */ +enum { + TEGRA_SMMU0, + TEGRA_SMMU1, + TEGRA_SMMU2 +}; + +static uint32_t tegra_smmu_read_32(uint32_t smmu_id, uint32_t off) +{ +#if defined(TEGRA_SMMU0_BASE) + if (smmu_id == TEGRA_SMMU0) + return mmio_read_32(TEGRA_SMMU0_BASE + off); +#endif + +#if defined(TEGRA_SMMU1_BASE) + if (smmu_id == TEGRA_SMMU1) + return mmio_read_32(TEGRA_SMMU1_BASE + off); +#endif + +#if defined(TEGRA_SMMU2_BASE) + if (smmu_id == TEGRA_SMMU2) + return mmio_read_32(TEGRA_SMMU2_BASE + off); +#endif + + return 0; +} + +static void tegra_smmu_write_32(uint32_t smmu_id, + uint32_t off, uint32_t val) +{ +#if defined(TEGRA_SMMU0_BASE) + if (smmu_id == TEGRA_SMMU0) + mmio_write_32(TEGRA_SMMU0_BASE + off, val); +#endif + +#if defined(TEGRA_SMMU1_BASE) + if (smmu_id == TEGRA_SMMU1) + mmio_write_32(TEGRA_SMMU1_BASE + off, val); +#endif + +#if defined(TEGRA_SMMU2_BASE) + if (smmu_id == TEGRA_SMMU2) + mmio_write_32(TEGRA_SMMU2_BASE + off, val); +#endif +} + /* * Save SMMU settings before "System Suspend" to TZDRAM */ @@ -50,7 +96,7 @@ void tegra_smmu_save_context(uint64_t smmu_ctx_addr) uint32_t reg_id1, pgshift, cb_size; /* sanity check SMMU settings c*/ - reg_id1 = mmio_read_32((TEGRA_SMMU_BASE + SMMU_GNSR0_IDR1)); + reg_id1 = mmio_read_32((TEGRA_SMMU0_BASE + SMMU_GNSR0_IDR1)); pgshift = (reg_id1 & ID1_PAGESIZE) ? 16 : 12; cb_size = (2 << pgshift) * \ (1 << (((reg_id1 >> ID1_NUMPAGENDXB_SHIFT) & ID1_NUMPAGENDXB_MASK) + 1)); @@ -87,34 +133,39 @@ void tegra_smmu_save_context(uint64_t smmu_ctx_addr) */ void tegra_smmu_init(void) { - uint32_t val, i, ctx_base; + uint32_t val, cb_idx, smmu_id, ctx_base; - /* Program the SMMU pagesize and reset CACHE_LOCK bit */ - val = tegra_smmu_read_32(SMMU_GSR0_SECURE_ACR); - val |= SMMU_GSR0_PGSIZE_64K; - val &= ~SMMU_ACR_CACHE_LOCK_ENABLE_BIT; - tegra_smmu_write_32(SMMU_GSR0_SECURE_ACR, val); + for (smmu_id = 0; smmu_id < NUM_SMMU_DEVICES; smmu_id++) { + /* Program the SMMU pagesize and reset CACHE_LOCK bit */ + val = tegra_smmu_read_32(smmu_id, SMMU_GSR0_SECURE_ACR); + val |= SMMU_GSR0_PGSIZE_64K; + val &= ~SMMU_ACR_CACHE_LOCK_ENABLE_BIT; + tegra_smmu_write_32(smmu_id, SMMU_GSR0_SECURE_ACR, val); - /* reset CACHE LOCK bit for NS Aux. Config. Register */ - val = tegra_smmu_read_32(SMMU_GNSR_ACR); - val &= ~SMMU_ACR_CACHE_LOCK_ENABLE_BIT; - tegra_smmu_write_32(SMMU_GNSR_ACR, val); + /* reset CACHE LOCK bit for NS Aux. Config. Register */ + val = tegra_smmu_read_32(smmu_id, SMMU_GNSR_ACR); + val &= ~SMMU_ACR_CACHE_LOCK_ENABLE_BIT; + tegra_smmu_write_32(smmu_id, SMMU_GNSR_ACR, val); - /* disable TCU prefetch for all contexts */ - ctx_base = (SMMU_GSR0_PGSIZE_64K * SMMU_NUM_CONTEXTS) + SMMU_CBn_ACTLR; - for (i = 0; i < SMMU_CONTEXT_BANK_MAX_IDX; i++) { - val = tegra_smmu_read_32(ctx_base + (SMMU_GSR0_PGSIZE_64K * i)); - val &= ~SMMU_CBn_ACTLR_CPRE_BIT; - tegra_smmu_write_32(ctx_base + (SMMU_GSR0_PGSIZE_64K * i), val); + /* disable TCU prefetch for all contexts */ + ctx_base = (SMMU_GSR0_PGSIZE_64K * SMMU_NUM_CONTEXTS) + + SMMU_CBn_ACTLR; + for (cb_idx = 0; cb_idx < SMMU_CONTEXT_BANK_MAX_IDX; cb_idx++) { + val = tegra_smmu_read_32(smmu_id, + ctx_base + (SMMU_GSR0_PGSIZE_64K * cb_idx)); + val &= ~SMMU_CBn_ACTLR_CPRE_BIT; + tegra_smmu_write_32(smmu_id, ctx_base + + (SMMU_GSR0_PGSIZE_64K * cb_idx), val); + } + + /* set CACHE LOCK bit for NS Aux. Config. Register */ + val = tegra_smmu_read_32(smmu_id, SMMU_GNSR_ACR); + val |= SMMU_ACR_CACHE_LOCK_ENABLE_BIT; + tegra_smmu_write_32(smmu_id, SMMU_GNSR_ACR, val); + + /* set CACHE LOCK bit for S Aux. Config. Register */ + val = tegra_smmu_read_32(smmu_id, SMMU_GSR0_SECURE_ACR); + val |= SMMU_ACR_CACHE_LOCK_ENABLE_BIT; + tegra_smmu_write_32(smmu_id, SMMU_GSR0_SECURE_ACR, val); } - - /* set CACHE LOCK bit for NS Aux. Config. Register */ - val = tegra_smmu_read_32(SMMU_GNSR_ACR); - val |= SMMU_ACR_CACHE_LOCK_ENABLE_BIT; - tegra_smmu_write_32(SMMU_GNSR_ACR, val); - - /* set CACHE LOCK bit for S Aux. Config. Register */ - val = tegra_smmu_read_32(SMMU_GSR0_SECURE_ACR); - val |= SMMU_ACR_CACHE_LOCK_ENABLE_BIT; - tegra_smmu_write_32(SMMU_GSR0_SECURE_ACR, val); } diff --git a/plat/nvidia/tegra/include/drivers/smmu.h b/plat/nvidia/tegra/include/drivers/smmu.h index a59b06bf7..61ad5f060 100644 --- a/plat/nvidia/tegra/include/drivers/smmu.h +++ b/plat/nvidia/tegra/include/drivers/smmu.h @@ -643,7 +643,7 @@ typedef struct smmu_regs { #define smmu_make_gnsr0_sec_cfg(name) \ { \ - .reg = TEGRA_SMMU_BASE + SMMU_GNSR0_ ## name, \ + .reg = TEGRA_SMMU0_BASE + SMMU_GNSR0_ ## name, \ .val = 0x00000000, \ } @@ -653,37 +653,37 @@ typedef struct smmu_regs { */ #define smmu_make_gnsr0_nsec_cfg(name) \ { \ - .reg = TEGRA_SMMU_BASE + 0x400 + SMMU_GNSR0_ ## name, \ + .reg = TEGRA_SMMU0_BASE + 0x400 + SMMU_GNSR0_ ## name, \ .val = 0x00000000, \ } #define smmu_make_gnsr0_smr_cfg(n) \ { \ - .reg = TEGRA_SMMU_BASE + SMMU_GNSR0_SMR ## n, \ + .reg = TEGRA_SMMU0_BASE + SMMU_GNSR0_SMR ## n, \ .val = 0x00000000, \ } #define smmu_make_gnsr0_s2cr_cfg(n) \ { \ - .reg = TEGRA_SMMU_BASE + SMMU_GNSR0_S2CR ## n, \ + .reg = TEGRA_SMMU0_BASE + SMMU_GNSR0_S2CR ## n, \ .val = 0x00000000, \ } #define smmu_make_gnsr1_cbar_cfg(n) \ { \ - .reg = TEGRA_SMMU_BASE + (1 << PGSHIFT) + SMMU_GNSR1_CBAR ## n, \ + .reg = TEGRA_SMMU0_BASE + (1 << PGSHIFT) + SMMU_GNSR1_CBAR ## n, \ .val = 0x00000000, \ } #define smmu_make_gnsr1_cba2r_cfg(n) \ { \ - .reg = TEGRA_SMMU_BASE + (1 << PGSHIFT) + SMMU_GNSR1_CBA2R ## n, \ + .reg = TEGRA_SMMU0_BASE + (1 << PGSHIFT) + SMMU_GNSR1_CBA2R ## n, \ .val = 0x00000000, \ } #define make_smmu_cb_cfg(name, n) \ { \ - .reg = TEGRA_SMMU_BASE + (CB_SIZE >> 1) + (n * (1 << PGSHIFT)) \ + .reg = TEGRA_SMMU0_BASE + (CB_SIZE >> 1) + (n * (1 << PGSHIFT)) \ + SMMU_CBn_ ## name, \ .val = 0x00000000, \ } diff --git a/plat/nvidia/tegra/include/t186/tegra_def.h b/plat/nvidia/tegra/include/t186/tegra_def.h index 8a1dd3f24..ae11d2810 100644 --- a/plat/nvidia/tegra/include/t186/tegra_def.h +++ b/plat/nvidia/tegra/include/t186/tegra_def.h @@ -272,7 +272,7 @@ /******************************************************************************* * Tegra SMMU Controller constants ******************************************************************************/ -#define TEGRA_SMMU_BASE 0x12000000 +#define TEGRA_SMMU0_BASE 0x12000000 /******************************************************************************* * Tegra TZRAM constants diff --git a/plat/nvidia/tegra/soc/t186/plat_setup.c b/plat/nvidia/tegra/soc/t186/plat_setup.c index 13f867e21..e165df1a8 100644 --- a/plat/nvidia/tegra/soc/t186/plat_setup.c +++ b/plat/nvidia/tegra/soc/t186/plat_setup.c @@ -111,10 +111,8 @@ static const mmap_region_t tegra_mmap[] = { MT_DEVICE | MT_RW | MT_SECURE), MAP_REGION_FLAT(TEGRA_ARM_ACTMON_CTR_BASE, 0x20000, /* 128KB - ARM/Denver */ MT_DEVICE | MT_RW | MT_SECURE), -#if ENABLE_SMMU_DEVICE - MAP_REGION_FLAT(TEGRA_SMMU_BASE, 0x1000000, /* 64KB */ + MAP_REGION_FLAT(TEGRA_SMMU0_BASE, 0x1000000, /* 64KB */ MT_DEVICE | MT_RW | MT_SECURE), -#endif {0} }; diff --git a/plat/nvidia/tegra/soc/t186/platform_t186.mk b/plat/nvidia/tegra/soc/t186/platform_t186.mk index 85c924b98..979dcb129 100644 --- a/plat/nvidia/tegra/soc/t186/platform_t186.mk +++ b/plat/nvidia/tegra/soc/t186/platform_t186.mk @@ -44,6 +44,9 @@ $(eval $(call add_define,ENABLE_CHIP_VERIFICATION_HARNESS)) ENABLE_SMMU_DEVICE := 1 $(eval $(call add_define,ENABLE_SMMU_DEVICE)) +NUM_SMMU_DEVICES := 1 +$(eval $(call add_define,NUM_SMMU_DEVICES)) + RESET_TO_BL31 := 1 PROGRAMMABLE_RESET_ADDRESS := 1