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 <praithatha@nvidia.com>
Signed-off-by: Krishna Reddy <vdumpa@nvidia.com>
Signed-off-by: Varun Wadekar <vwadekar@nvidia.com>
This commit is contained in:
Pritesh Raithatha 2017-01-24 13:49:46 +05:30 committed by Varun Wadekar
parent 986e333dc3
commit c459206d21
5 changed files with 90 additions and 38 deletions

View File

@ -36,6 +36,52 @@
#include <string.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
*/
@ -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);
}

View File

@ -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, \
}

View File

@ -272,7 +272,7 @@
/*******************************************************************************
* Tegra SMMU Controller constants
******************************************************************************/
#define TEGRA_SMMU_BASE 0x12000000
#define TEGRA_SMMU0_BASE 0x12000000
/*******************************************************************************
* Tegra TZRAM constants

View File

@ -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}
};

View File

@ -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