Commit c459206d authored by Pritesh Raithatha's avatar Pritesh Raithatha Committed by Varun Wadekar
Browse files

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: default avatarPritesh Raithatha <praithatha@nvidia.com>
Signed-off-by: default avatarKrishna Reddy <vdumpa@nvidia.com>
Signed-off-by: default avatarVarun Wadekar <vwadekar@nvidia.com>
parent 986e333d
...@@ -36,6 +36,52 @@ ...@@ -36,6 +36,52 @@
#include <string.h> #include <string.h>
#include <tegra_private.h> #include <tegra_private.h>
/* 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 * Save SMMU settings before "System Suspend" to TZDRAM
*/ */
...@@ -50,7 +96,7 @@ void tegra_smmu_save_context(uint64_t smmu_ctx_addr) ...@@ -50,7 +96,7 @@ void tegra_smmu_save_context(uint64_t smmu_ctx_addr)
uint32_t reg_id1, pgshift, cb_size; uint32_t reg_id1, pgshift, cb_size;
/* sanity check SMMU settings c*/ /* 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; pgshift = (reg_id1 & ID1_PAGESIZE) ? 16 : 12;
cb_size = (2 << pgshift) * \ cb_size = (2 << pgshift) * \
(1 << (((reg_id1 >> ID1_NUMPAGENDXB_SHIFT) & ID1_NUMPAGENDXB_MASK) + 1)); (1 << (((reg_id1 >> ID1_NUMPAGENDXB_SHIFT) & ID1_NUMPAGENDXB_MASK) + 1));
...@@ -87,34 +133,39 @@ void tegra_smmu_save_context(uint64_t smmu_ctx_addr) ...@@ -87,34 +133,39 @@ void tegra_smmu_save_context(uint64_t smmu_ctx_addr)
*/ */
void tegra_smmu_init(void) 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 */ for (smmu_id = 0; smmu_id < NUM_SMMU_DEVICES; smmu_id++) {
val = tegra_smmu_read_32(SMMU_GSR0_SECURE_ACR); /* Program the SMMU pagesize and reset CACHE_LOCK bit */
val |= SMMU_GSR0_PGSIZE_64K; val = tegra_smmu_read_32(smmu_id, SMMU_GSR0_SECURE_ACR);
val &= ~SMMU_ACR_CACHE_LOCK_ENABLE_BIT; val |= SMMU_GSR0_PGSIZE_64K;
tegra_smmu_write_32(SMMU_GSR0_SECURE_ACR, val); 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); /* reset CACHE LOCK bit for NS Aux. Config. Register */
val &= ~SMMU_ACR_CACHE_LOCK_ENABLE_BIT; val = tegra_smmu_read_32(smmu_id, SMMU_GNSR_ACR);
tegra_smmu_write_32(SMMU_GNSR_ACR, val); 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; /* disable TCU prefetch for all contexts */
for (i = 0; i < SMMU_CONTEXT_BANK_MAX_IDX; i++) { ctx_base = (SMMU_GSR0_PGSIZE_64K * SMMU_NUM_CONTEXTS)
val = tegra_smmu_read_32(ctx_base + (SMMU_GSR0_PGSIZE_64K * i)); + SMMU_CBn_ACTLR;
val &= ~SMMU_CBn_ACTLR_CPRE_BIT; for (cb_idx = 0; cb_idx < SMMU_CONTEXT_BANK_MAX_IDX; cb_idx++) {
tegra_smmu_write_32(ctx_base + (SMMU_GSR0_PGSIZE_64K * i), val); 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);
} }
...@@ -643,7 +643,7 @@ typedef struct smmu_regs { ...@@ -643,7 +643,7 @@ typedef struct smmu_regs {
#define smmu_make_gnsr0_sec_cfg(name) \ #define smmu_make_gnsr0_sec_cfg(name) \
{ \ { \
.reg = TEGRA_SMMU_BASE + SMMU_GNSR0_ ## name, \ .reg = TEGRA_SMMU0_BASE + SMMU_GNSR0_ ## name, \
.val = 0x00000000, \ .val = 0x00000000, \
} }
...@@ -653,37 +653,37 @@ typedef struct smmu_regs { ...@@ -653,37 +653,37 @@ typedef struct smmu_regs {
*/ */
#define smmu_make_gnsr0_nsec_cfg(name) \ #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, \ .val = 0x00000000, \
} }
#define smmu_make_gnsr0_smr_cfg(n) \ #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, \ .val = 0x00000000, \
} }
#define smmu_make_gnsr0_s2cr_cfg(n) \ #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, \ .val = 0x00000000, \
} }
#define smmu_make_gnsr1_cbar_cfg(n) \ #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, \ .val = 0x00000000, \
} }
#define smmu_make_gnsr1_cba2r_cfg(n) \ #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, \ .val = 0x00000000, \
} }
#define make_smmu_cb_cfg(name, n) \ #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, \ + SMMU_CBn_ ## name, \
.val = 0x00000000, \ .val = 0x00000000, \
} }
......
...@@ -272,7 +272,7 @@ ...@@ -272,7 +272,7 @@
/******************************************************************************* /*******************************************************************************
* Tegra SMMU Controller constants * Tegra SMMU Controller constants
******************************************************************************/ ******************************************************************************/
#define TEGRA_SMMU_BASE 0x12000000 #define TEGRA_SMMU0_BASE 0x12000000
/******************************************************************************* /*******************************************************************************
* Tegra TZRAM constants * Tegra TZRAM constants
......
...@@ -111,10 +111,8 @@ static const mmap_region_t tegra_mmap[] = { ...@@ -111,10 +111,8 @@ static const mmap_region_t tegra_mmap[] = {
MT_DEVICE | MT_RW | MT_SECURE), MT_DEVICE | MT_RW | MT_SECURE),
MAP_REGION_FLAT(TEGRA_ARM_ACTMON_CTR_BASE, 0x20000, /* 128KB - ARM/Denver */ MAP_REGION_FLAT(TEGRA_ARM_ACTMON_CTR_BASE, 0x20000, /* 128KB - ARM/Denver */
MT_DEVICE | MT_RW | MT_SECURE), MT_DEVICE | MT_RW | MT_SECURE),
#if ENABLE_SMMU_DEVICE MAP_REGION_FLAT(TEGRA_SMMU0_BASE, 0x1000000, /* 64KB */
MAP_REGION_FLAT(TEGRA_SMMU_BASE, 0x1000000, /* 64KB */
MT_DEVICE | MT_RW | MT_SECURE), MT_DEVICE | MT_RW | MT_SECURE),
#endif
{0} {0}
}; };
......
...@@ -44,6 +44,9 @@ $(eval $(call add_define,ENABLE_CHIP_VERIFICATION_HARNESS)) ...@@ -44,6 +44,9 @@ $(eval $(call add_define,ENABLE_CHIP_VERIFICATION_HARNESS))
ENABLE_SMMU_DEVICE := 1 ENABLE_SMMU_DEVICE := 1
$(eval $(call add_define,ENABLE_SMMU_DEVICE)) $(eval $(call add_define,ENABLE_SMMU_DEVICE))
NUM_SMMU_DEVICES := 1
$(eval $(call add_define,NUM_SMMU_DEVICES))
RESET_TO_BL31 := 1 RESET_TO_BL31 := 1
PROGRAMMABLE_RESET_ADDRESS := 1 PROGRAMMABLE_RESET_ADDRESS := 1
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment