Merge "SMMUv3: refactor the driver code" into integration

This commit is contained in:
Soby Mathew 2019-05-03 11:09:02 +00:00 committed by TrustedFirmware Code Review
commit b9c1d185bb
3 changed files with 40 additions and 38 deletions

View File

@ -1,60 +1,55 @@
/* /*
* Copyright (c) 2017-2018, ARM Limited and Contributors. All rights reserved. * Copyright (c) 2017-2019, ARM Limited and Contributors. All rights reserved.
* *
* SPDX-License-Identifier: BSD-3-Clause * SPDX-License-Identifier: BSD-3-Clause
*/ */
#include <common/debug.h>
#include <cdefs.h> #include <cdefs.h>
#include <stdbool.h>
#include <drivers/arm/smmu_v3.h> #include <drivers/arm/smmu_v3.h>
#include <lib/mmio.h> #include <lib/mmio.h>
static inline uint32_t __init smmuv3_read_s_idr1(uintptr_t base) /* SMMU poll number of retries */
{ #define SMMU_POLL_RETRY 1000000
return mmio_read_32(base + SMMU_S_IDR1);
}
static inline uint32_t __init smmuv3_read_s_init(uintptr_t base) static int __init smmuv3_poll(uintptr_t smmu_reg, uint32_t mask,
uint32_t value)
{ {
return mmio_read_32(base + SMMU_S_INIT); uint32_t reg_val, retries = SMMU_POLL_RETRY;
}
static inline void __init smmuv3_write_s_init(uintptr_t base, uint32_t value) do {
{ reg_val = mmio_read_32(smmu_reg);
mmio_write_32(base + SMMU_S_INIT, value); if ((reg_val & mask) == value)
} return 0;
} while (--retries != 0U);
/* Test for pending invalidate */ ERROR("Failed to poll SMMUv3 register @%p\n", (void *)smmu_reg);
static inline bool smmuv3_inval_pending(uintptr_t base) ERROR("Read value 0x%x, expected 0x%x\n", reg_val,
{ value == 0U ? reg_val & ~mask : reg_val | mask);
return (smmuv3_read_s_init(base) & SMMU_S_INIT_INV_ALL_MASK) != 0U; return -1;
} }
/* /*
* Initialize the SMMU by invalidating all secure caches and TLBs. * Initialize the SMMU by invalidating all secure caches and TLBs.
* * Abort all incoming transactions in order to implement a default
* Returns 0 on success, and -1 on failure. * deny policy on reset
*/ */
int __init smmuv3_init(uintptr_t smmu_base) int __init smmuv3_init(uintptr_t smmu_base)
{ {
uint32_t idr1_reg;
/* /*
* Invalidation of secure caches and TLBs is required only if the SMMU * Invalidation of secure caches and TLBs is required only if the SMMU
* supports secure state. If not, it's implementation defined as to how * supports secure state. If not, it's implementation defined as to how
* SMMU_S_INIT register is accessed. * SMMU_S_INIT register is accessed.
*/ */
idr1_reg = smmuv3_read_s_idr1(smmu_base); if ((mmio_read_32(smmu_base + SMMU_S_IDR1) &
if (((idr1_reg >> SMMU_S_IDR1_SECURE_IMPL_SHIFT) & SMMU_S_IDR1_SECURE_IMPL) != 0U) {
SMMU_S_IDR1_SECURE_IMPL_MASK) == 0U) {
return -1; /* Initiate invalidation */
mmio_write_32(smmu_base + SMMU_S_INIT, SMMU_S_INIT_INV_ALL);
/* Wait for global invalidation operation to finish */
return smmuv3_poll(smmu_base + SMMU_S_INIT,
SMMU_S_INIT_INV_ALL, 0U);
} }
/* Initiate invalidation, and wait for it to finish */
smmuv3_write_s_init(smmu_base, SMMU_S_INIT_INV_ALL_MASK);
while (smmuv3_inval_pending(smmu_base))
;
return 0; return 0;
} }

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2017-2018, ARM Limited and Contributors. All rights reserved. * Copyright (c) 2017-2019, ARM Limited and Contributors. All rights reserved.
* *
* SPDX-License-Identifier: BSD-3-Clause * SPDX-License-Identifier: BSD-3-Clause
*/ */
@ -8,20 +8,27 @@
#define SMMU_V3_H #define SMMU_V3_H
#include <stdint.h> #include <stdint.h>
#include <lib/utils_def.h> #include <lib/utils_def.h>
/* SMMUv3 register offsets from device base */ /* SMMUv3 register offsets from device base */
#define SMMU_GBPA U(0x0044)
#define SMMU_S_IDR1 U(0x8004) #define SMMU_S_IDR1 U(0x8004)
#define SMMU_S_INIT U(0x803c) #define SMMU_S_INIT U(0x803c)
#define SMMU_S_GBPA U(0x8044)
/* SMMU_GBPA register fields */
#define SMMU_GBPA_UPDATE (1UL << 31)
#define SMMU_GBPA_ABORT (1UL << 20)
/* SMMU_S_IDR1 register fields */ /* SMMU_S_IDR1 register fields */
#define SMMU_S_IDR1_SECURE_IMPL_SHIFT 31 #define SMMU_S_IDR1_SECURE_IMPL (1UL << 31)
#define SMMU_S_IDR1_SECURE_IMPL_MASK U(0x1)
/* SMMU_S_INIT register fields */ /* SMMU_S_INIT register fields */
#define SMMU_S_INIT_INV_ALL_MASK U(0x1) #define SMMU_S_INIT_INV_ALL (1UL << 0)
/* SMMU_S_GBPA register fields */
#define SMMU_S_GBPA_UPDATE (1UL << 31)
#define SMMU_S_GBPA_ABORT (1UL << 20)
int smmuv3_init(uintptr_t smmu_base); int smmuv3_init(uintptr_t smmu_base);

View File

@ -34,7 +34,7 @@ void __init bl31_early_platform_setup2(u_register_t arg0,
*/ */
fvp_interconnect_enable(); fvp_interconnect_enable();
/* On FVP RevC, intialize SMMUv3 */ /* On FVP RevC, initialize SMMUv3 */
if ((arm_config.flags & ARM_CONFIG_FVP_HAS_SMMUV3) != 0U) if ((arm_config.flags & ARM_CONFIG_FVP_HAS_SMMUV3) != 0U)
smmuv3_init(PLAT_FVP_SMMUV3_BASE); smmuv3_init(PLAT_FVP_SMMUV3_BASE);
} }