From 1154586b71c1e0453076a50638f00d4499eb22b0 Mon Sep 17 00:00:00 2001 From: Jeenu Viswambharan Date: Fri, 26 May 2017 14:15:40 +0100 Subject: [PATCH] Add SMMUv3 driver The driver has only one API: to initialize an SMMUv3 device. This operates on a device that implements secure state, by invalidating secure caches and TLBs. Change-Id: Ief32800419ddf0f1fe38c8f0da8f5ba75c72c826 Signed-off-by: Jeenu Viswambharan --- drivers/arm/smmu/smmu_v3.c | 55 +++++++++++++++++++++++++++++++++++ include/drivers/arm/smmu_v3.h | 26 +++++++++++++++++ 2 files changed, 81 insertions(+) create mode 100644 drivers/arm/smmu/smmu_v3.c create mode 100644 include/drivers/arm/smmu_v3.h diff --git a/drivers/arm/smmu/smmu_v3.c b/drivers/arm/smmu/smmu_v3.c new file mode 100644 index 00000000..cfe8c2a4 --- /dev/null +++ b/drivers/arm/smmu/smmu_v3.c @@ -0,0 +1,55 @@ +/* + * Copyright (c) 2017, ARM Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include +#include + +/* Test for pending invalidate */ +#define INVAL_PENDING(base) \ + smmuv3_read_s_init(base) & SMMU_S_INIT_INV_ALL_MASK + +static inline uint32_t smmuv3_read_s_idr1(uintptr_t base) +{ + return mmio_read_32(base + SMMU_S_IDR1); +} + +static inline uint32_t smmuv3_read_s_init(uintptr_t base) +{ + return mmio_read_32(base + SMMU_S_INIT); +} + +static inline void smmuv3_write_s_init(uintptr_t base, uint32_t value) +{ + mmio_write_32(base + SMMU_S_INIT, value); +} + +/* + * Initialize the SMMU by invalidating all secure caches and TLBs. + * + * Returns 0 on success, and -1 on failure. + */ +int smmuv3_init(uintptr_t smmu_base) +{ + uint32_t idr1_reg; + + /* + * Invalidation of secure caches and TLBs is required only if the SMMU + * supports secure state. If not, it's implementation defined as to how + * SMMU_S_INIT register is accessed. + */ + idr1_reg = smmuv3_read_s_idr1(smmu_base); + if (!((idr1_reg >> SMMU_S_IDR1_SECURE_IMPL_SHIFT) & + SMMU_S_IDR1_SECURE_IMPL_MASK)) { + return -1; + } + + /* Initiate invalidation, and wait for it to finish */ + smmuv3_write_s_init(smmu_base, SMMU_S_INIT_INV_ALL_MASK); + while (INVAL_PENDING(smmu_base)) + ; + + return 0; +} diff --git a/include/drivers/arm/smmu_v3.h b/include/drivers/arm/smmu_v3.h new file mode 100644 index 00000000..b7efde46 --- /dev/null +++ b/include/drivers/arm/smmu_v3.h @@ -0,0 +1,26 @@ +/* + * Copyright (c) 2017, ARM Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#ifndef __SMMU_V3_H__ +#define __SMMU_V3_H__ + +#include + +/* SMMUv3 register offsets from device base */ +#define SMMU_S_IDR1 0x8004 +#define SMMU_S_INIT 0x803c + +/* SMMU_S_IDR1 register fields */ +#define SMMU_S_IDR1_SECURE_IMPL_SHIFT 31 +#define SMMU_S_IDR1_SECURE_IMPL_MASK 0x1 + +/* SMMU_S_INIT register fields */ +#define SMMU_S_INIT_INV_ALL_MASK 0x1 + + +int smmuv3_init(uintptr_t smmu_base); + +#endif /* __SMMU_V3_H__ */ -- 2.30.2