Merge pull request #1783 from thloh85-intel/integration_v2
plat: intel: Add BL2 support for Stratix 10 SoC
diff --git a/Makefile b/Makefile
index 3de7b3f..0169f3f 100644
--- a/Makefile
+++ b/Makefile
@@ -1,5 +1,5 @@
#
-# Copyright (c) 2013-2018, ARM Limited and Contributors. All rights reserved.
+# Copyright (c) 2013-2019, ARM Limited and Contributors. All rights reserved.
#
# SPDX-License-Identifier: BSD-3-Clause
#
@@ -242,6 +242,7 @@
TF_LDFLAGS += $(TF_LDFLAGS_$(ARCH))
DTC_FLAGS += -I dts -O dtb
+DTC_CPPFLAGS += -nostdinc -Iinclude -undef -x assembler-with-cpp
################################################################################
# Common sources and include directories
@@ -431,16 +432,6 @@
$(error "BL2_IN_XIP_MEM is only supported when BL2_AT_EL3 is enabled")
endif
-# SMC Calling Convention checks
-ifneq (${SMCCC_MAJOR_VERSION},1)
- ifneq (${SPD},none)
- $(error "SMC Calling Convention 1.X must be used with SPDs")
- endif
- ifeq (${ARCH},aarch32)
- $(error "Only SMCCC 1.X is supported in AArch32 mode.")
- endif
-endif
-
# For RAS_EXTENSION, require that EAs are handled in EL3 first
ifeq ($(RAS_EXTENSION),1)
ifneq ($(HANDLE_EA_EL3_FIRST),1)
@@ -584,7 +575,6 @@
$(eval $(call assert_boolean,CTX_INCLUDE_AARCH32_REGS))
$(eval $(call assert_boolean,CTX_INCLUDE_FPREGS))
$(eval $(call assert_boolean,DEBUG))
-$(eval $(call assert_boolean,DISABLE_PEDANTIC))
$(eval $(call assert_boolean,DYN_DISABLE_AUTH))
$(eval $(call assert_boolean,EL3_EXCEPTION_HANDLING))
$(eval $(call assert_boolean,ENABLE_AMU))
@@ -613,7 +603,7 @@
$(eval $(call assert_boolean,SAVE_KEYS))
$(eval $(call assert_boolean,SEPARATE_CODE_AND_RODATA))
$(eval $(call assert_boolean,SPIN_ON_BL1_EXIT))
-$(eval $(call assert_boolean,SPM_DEPRECATED))
+$(eval $(call assert_boolean,SPM_MM))
$(eval $(call assert_boolean,TRUSTED_BOARD_BOOT))
$(eval $(call assert_boolean,USE_COHERENT_MEM))
$(eval $(call assert_boolean,USE_ROMLIB))
@@ -624,7 +614,6 @@
$(eval $(call assert_numeric,ARM_ARCH_MAJOR))
$(eval $(call assert_numeric,ARM_ARCH_MINOR))
-$(eval $(call assert_numeric,SMCCC_MAJOR_VERSION))
################################################################################
# Add definitions to the cpp preprocessor based on the current build options.
@@ -664,10 +653,9 @@
$(eval $(call add_define,RESET_TO_BL31))
$(eval $(call add_define,SEPARATE_CODE_AND_RODATA))
$(eval $(call add_define,RECLAIM_INIT_CODE))
-$(eval $(call add_define,SMCCC_MAJOR_VERSION))
$(eval $(call add_define,SPD_${SPD}))
$(eval $(call add_define,SPIN_ON_BL1_EXIT))
-$(eval $(call add_define,SPM_DEPRECATED))
+$(eval $(call add_define,SPM_MM))
$(eval $(call add_define,TRUSTED_BOARD_BOOT))
$(eval $(call add_define,USE_COHERENT_MEM))
$(eval $(call add_define,USE_ROMLIB))
diff --git a/bl31/aarch64/runtime_exceptions.S b/bl31/aarch64/runtime_exceptions.S
index e7abd50..4f53b8e 100644
--- a/bl31/aarch64/runtime_exceptions.S
+++ b/bl31/aarch64/runtime_exceptions.S
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2013-2018, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2013-2019, ARM Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -303,38 +303,6 @@
b enter_lower_el_async_ea
end_vector_entry serror_aarch32
-
- /* ---------------------------------------------------------------------
- * This macro takes an argument in x16 that is the index in the
- * 'rt_svc_descs_indices' array, checks that the value in the array is
- * valid, and loads in x15 the pointer to the handler of that service.
- * ---------------------------------------------------------------------
- */
- .macro load_rt_svc_desc_pointer
- /* Load descriptor index from array of indices */
- adr x14, rt_svc_descs_indices
- ldrb w15, [x14, x16]
-
-#if SMCCC_MAJOR_VERSION == 1
- /* Any index greater than 127 is invalid. Check bit 7. */
- tbnz w15, 7, smc_unknown
-#elif SMCCC_MAJOR_VERSION == 2
- /* Verify that the top 3 bits of the loaded index are 0 (w15 <= 31) */
- cmp w15, #31
- b.hi smc_unknown
-#endif /* SMCCC_MAJOR_VERSION */
-
- /*
- * Get the descriptor using the index
- * x11 = (base + off), w15 = index
- *
- * handler = (base + off) + (index << log2(size))
- */
- adr x11, (__RT_SVC_DESCS_START__ + RT_SVC_DESC_HANDLE)
- lsl w10, w15, #RT_SVC_SIZE_LOG2
- ldr x15, [x11, w10, uxtw]
- .endm
-
/* ---------------------------------------------------------------------
* The following code handles secure monitor calls.
* Depending upon the execution state from where the SMC has been
@@ -363,56 +331,27 @@
mov x5, xzr
mov x6, sp
-#if SMCCC_MAJOR_VERSION == 1
-
/* Get the unique owning entity number */
ubfx x16, x0, #FUNCID_OEN_SHIFT, #FUNCID_OEN_WIDTH
ubfx x15, x0, #FUNCID_TYPE_SHIFT, #FUNCID_TYPE_WIDTH
orr x16, x16, x15, lsl #FUNCID_OEN_WIDTH
- load_rt_svc_desc_pointer
+ /* Load descriptor index from array of indices */
+ adr x14, rt_svc_descs_indices
+ ldrb w15, [x14, x16]
-#elif SMCCC_MAJOR_VERSION == 2
-
- /* Bit 31 must be set */
- tbz x0, #FUNCID_TYPE_SHIFT, smc_unknown
+ /* Any index greater than 127 is invalid. Check bit 7. */
+ tbnz w15, 7, smc_unknown
/*
- * Check MSB of namespace to decide between compatibility/vendor and
- * SPCI/SPRT
- */
- tbz x0, #(FUNCID_NAMESPACE_SHIFT + 1), compat_or_vendor
-
- /* Namespace is b'10 (SPRT) or b'11 (SPCI) */
-#if ENABLE_SPM
- tst x0, #(1 << FUNCID_NAMESPACE_SHIFT)
- adr x15, spci_smc_handler
- adr x16, sprt_smc_handler
- csel x15, x15, x16, ne
- b prepare_enter_handler
-#else
- b smc_unknown
-#endif
-
-compat_or_vendor:
-
- /* Namespace is b'00 (compatibility) or b'01 (vendor) */
-
- /*
- * Add the LSB of the namespace (bit [28]) to the OEN [27:24] to create
- * a 5-bit index into the rt_svc_descs_indices array.
+ * Get the descriptor using the index
+ * x11 = (base + off), w15 = index
*
- * The low 16 entries of the rt_svc_descs_indices array correspond to
- * OENs of the compatibility namespace and the top 16 entries of the
- * array are assigned to the vendor namespace descriptor.
+ * handler = (base + off) + (index << log2(size))
*/
- ubfx x16, x0, #FUNCID_OEN_SHIFT, #(FUNCID_OEN_WIDTH + 1)
-
- load_rt_svc_desc_pointer
-
-prepare_enter_handler:
-
-#endif /* SMCCC_MAJOR_VERSION */
+ adr x11, (__RT_SVC_DESCS_START__ + RT_SVC_DESC_HANDLE)
+ lsl w10, w15, #RT_SVC_SIZE_LOG2
+ ldr x15, [x11, w10, uxtw]
/*
* Restore the saved C runtime stack value which will become the new
diff --git a/bl31/bl31.mk b/bl31/bl31.mk
index eddd164..89f5896 100644
--- a/bl31/bl31.mk
+++ b/bl31/bl31.mk
@@ -1,5 +1,5 @@
#
-# Copyright (c) 2013-2018, ARM Limited and Contributors. All rights reserved.
+# Copyright (c) 2013-2019, ARM Limited and Contributors. All rights reserved.
#
# SPDX-License-Identifier: BSD-3-Clause
#
@@ -8,12 +8,12 @@
# Include SPM Makefile
################################################################################
ifeq (${ENABLE_SPM},1)
- ifeq (${SPM_DEPRECATED},1)
+ ifeq (${SPM_MM},1)
ifeq (${EL3_EXCEPTION_HANDLING},0)
$(error EL3_EXCEPTION_HANDLING must be 1 for SPM support)
endif
- $(info Including deprecated SPM makefile)
- include services/std_svc/spm_deprecated/spm.mk
+ $(info Including makefile of SPM based on MM)
+ include services/std_svc/spm_mm/spm.mk
else
$(info Including SPM makefile)
include services/std_svc/spm/spm.mk
diff --git a/common/bl_common.c b/common/bl_common.c
index b2d22c1..84ff99c 100644
--- a/common/bl_common.c
+++ b/common/bl_common.c
@@ -58,92 +58,6 @@
return value;
}
-/******************************************************************************
- * Determine whether the memory region delimited by 'addr' and 'size' is free,
- * given the extents of free memory.
- * Return 1 if it is free, 0 if it is not free or if the input values are
- * invalid.
- *****************************************************************************/
-int is_mem_free(uintptr_t free_base, size_t free_size,
- uintptr_t addr, size_t size)
-{
- uintptr_t free_end, requested_end;
-
- /*
- * Handle corner cases first.
- *
- * The order of the 2 tests is important, because if there's no space
- * left (i.e. free_size == 0) but we don't ask for any memory
- * (i.e. size == 0) then we should report that the memory is free.
- */
- if (size == 0)
- return 1; /* A zero-byte region is always free */
- if (free_size == 0)
- return 0;
-
- /*
- * Check that the end addresses don't overflow.
- * If they do, consider that this memory region is not free, as this
- * is an invalid scenario.
- */
- if (check_uptr_overflow(free_base, free_size - 1))
- return 0;
- free_end = free_base + (free_size - 1);
-
- if (check_uptr_overflow(addr, size - 1))
- return 0;
- requested_end = addr + (size - 1);
-
- /*
- * Finally, check that the requested memory region lies within the free
- * region.
- */
- return (addr >= free_base) && (requested_end <= free_end);
-}
-
-/* Generic function to return the size of an image */
-size_t get_image_size(unsigned int image_id)
-{
- uintptr_t dev_handle;
- uintptr_t image_handle;
- uintptr_t image_spec;
- size_t image_size = 0U;
- int io_result;
-
- /* Obtain a reference to the image by querying the platform layer */
- io_result = plat_get_image_source(image_id, &dev_handle, &image_spec);
- if (io_result != 0) {
- WARN("Failed to obtain reference to image id=%u (%i)\n",
- image_id, io_result);
- return 0;
- }
-
- /* Attempt to access the image */
- io_result = io_open(dev_handle, image_spec, &image_handle);
- if (io_result != 0) {
- WARN("Failed to access image id=%u (%i)\n",
- image_id, io_result);
- return 0;
- }
-
- /* Find the size of the image */
- io_result = io_size(image_handle, &image_size);
- if ((io_result != 0) || (image_size == 0U)) {
- WARN("Failed to determine the size of the image id=%u (%i)\n",
- image_id, io_result);
- }
- io_result = io_close(image_handle);
- /* Ignore improbable/unrecoverable error in 'close' */
-
- /* TODO: Consider maintaining open device connection from this
- * bootloader stage
- */
- io_result = io_dev_close(dev_handle);
- /* Ignore improbable/unrecoverable error in 'dev_close' */
-
- return image_size;
-}
-
/*******************************************************************************
* Internal function to load an image at a specific address given
* an image ID and extents of free memory.
diff --git a/common/desc_image_load.c b/common/desc_image_load.c
index ada02f8..405bb83 100644
--- a/common/desc_image_load.c
+++ b/common/desc_image_load.c
@@ -20,11 +20,28 @@
******************************************************************************/
void flush_bl_params_desc(void)
{
- flush_dcache_range((uintptr_t)bl_mem_params_desc_ptr,
- sizeof(*bl_mem_params_desc_ptr) * bl_mem_params_desc_num);
+ flush_bl_params_desc_args(bl_mem_params_desc_ptr,
+ bl_mem_params_desc_num,
+ &next_bl_params);
+}
- flush_dcache_range((uintptr_t)&next_bl_params,
- sizeof(next_bl_params));
+/*******************************************************************************
+ * This function flushes the data structures specified as arguments so that they
+ * are visible in memory for the next BL image.
+ ******************************************************************************/
+void flush_bl_params_desc_args(bl_mem_params_node_t *mem_params_desc_ptr,
+ unsigned int mem_params_desc_num,
+ bl_params_t *next_bl_params_ptr)
+{
+ assert(mem_params_desc_ptr != NULL);
+ assert(mem_params_desc_num != 0U);
+ assert(next_bl_params_ptr != NULL);
+
+ flush_dcache_range((uintptr_t)mem_params_desc_ptr,
+ sizeof(*mem_params_desc_ptr) * mem_params_desc_num);
+
+ flush_dcache_range((uintptr_t)next_bl_params_ptr,
+ sizeof(*next_bl_params_ptr));
}
/*******************************************************************************
diff --git a/common/runtime_svc.c b/common/runtime_svc.c
index 09ce787..a2c0c09 100644
--- a/common/runtime_svc.c
+++ b/common/runtime_svc.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2013-2018, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2013-2019, ARM Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -29,7 +29,6 @@
* Function to invoke the registered `handle` corresponding to the smc_fid in
* AArch32 mode.
******************************************************************************/
-#if SMCCC_MAJOR_VERSION == 1
uintptr_t handle_runtime_svc(uint32_t smc_fid,
void *cookie,
void *handle,
@@ -55,7 +54,6 @@
return rt_svc_descs[index].handle(smc_fid, x1, x2, x3, x4, cookie,
handle, flags);
}
-#endif /* SMCCC_MAJOR_VERSION */
/*******************************************************************************
* Simple routine to sanity check a runtime service descriptor before using it
@@ -71,14 +69,9 @@
if (desc->end_oen >= OEN_LIMIT)
return -EINVAL;
-#if SMCCC_MAJOR_VERSION == 1
if ((desc->call_type != SMC_TYPE_FAST) &&
(desc->call_type != SMC_TYPE_YIELD))
return -EINVAL;
-#elif SMCCC_MAJOR_VERSION == 2
- if (desc->is_vendor > 1U)
- return -EINVAL;
-#endif /* SMCCC_MAJOR_VERSION */
/* A runtime service having no init or handle function doesn't make sense */
if ((desc->init == NULL) && (desc->handle == NULL))
@@ -149,17 +142,10 @@
* descriptor which will handle the SMCs for this owning
* entity range.
*/
-#if SMCCC_MAJOR_VERSION == 1
start_idx = (uint8_t)get_unique_oen(service->start_oen,
service->call_type);
end_idx = (uint8_t)get_unique_oen(service->end_oen,
service->call_type);
-#elif SMCCC_MAJOR_VERSION == 2
- start_idx = (uint8_t)get_rt_desc_idx(service->start_oen,
- service->is_vendor);
- end_idx = (uint8_t)get_rt_desc_idx(service->end_oen,
- service->is_vendor);
-#endif
assert(start_idx <= end_idx);
assert(end_idx < MAX_RT_SVCS);
for (; start_idx <= end_idx; start_idx++)
diff --git a/docs/coding-guidelines.rst b/docs/coding-guidelines.rst
new file mode 100644
index 0000000..d5ac978
--- /dev/null
+++ b/docs/coding-guidelines.rst
@@ -0,0 +1,556 @@
+Trusted Firmware-A Coding Guidelines
+====================================
+
+.. section-numbering::
+ :suffix: .
+
+.. contents::
+
+The following sections contain TF coding guidelines. They are continually
+evolving and should not be considered "set in stone". Feel free to question them
+and provide feedback.
+
+Some of the guidelines may also apply to other codebases.
+
+**Note:** the existing TF codebase does not necessarily comply with all the
+below guidelines but the intent is for it to do so eventually.
+
+Checkpatch overrides
+--------------------
+
+Some checkpatch warnings in the TF codebase are deliberately ignored. These
+include:
+
+- ``**WARNING: line over 80 characters**``: Although the codebase should
+ generally conform to the 80 character limit this is overly restrictive in some
+ cases.
+
+- ``**WARNING: Use of volatile is usually wrong``: see
+ `Why the “volatile” type class should not be used`_ . Although this document
+ contains some very useful information, there are several legimate uses of the
+ volatile keyword within the TF codebase.
+
+Headers and inclusion
+---------------------
+
+Header guards
+^^^^^^^^^^^^^
+
+For a header file called "some_driver.h" the style used by the Trusted Firmware
+is:
+
+.. code:: c
+
+ #ifndef SOME_DRIVER_H
+ #define SOME_DRIVER_H
+
+ <header content>
+
+ #endif /* SOME_DRIVER_H */
+
+Include statement ordering
+^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+All header files that are included by a source file must use the following,
+grouped ordering. This is to improve readability (by making it easier to quickly
+read through the list of headers) and maintainability.
+
+#. *System* includes: Header files from the standard *C* library, such as
+ ``stddef.h`` and ``string.h``.
+
+#. *Project* includes: Header files under the ``include/`` directory within TF
+ are *project* includes.
+
+#. *Platform* includes: Header files relating to a single, specific platform,
+ and which are located under the ``plat/<platform_name>`` directory within TF,
+ are *platform* includes.
+
+Within each group, ``#include`` statements must be in alphabetical order,
+taking both the file and directory names into account.
+
+Groups must be separated by a single blank line for clarity.
+
+The example below illustrates the ordering rules using some contrived header
+file names; this type of name reuse should be otherwise avoided.
+
+.. code:: c
+
+ #include <string.h>
+
+ #include <a_dir/example/a_header.h>
+ #include <a_dir/example/b_header.h>
+ #include <a_dir/test/a_header.h>
+ #include <b_dir/example/a_header.h>
+
+ #include "./a_header.h"
+
+Include statement variants
+^^^^^^^^^^^^^^^^^^^^^^^^^
+
+Two variants of the ``#include`` directive are acceptable in the TF codebase.
+Correct use of the two styles improves readability by suggesting the location
+of the included header and reducing ambiguity in cases where generic and
+platform-specific headers share a name.
+
+For header files that are in the same directory as the source file that is
+including them, use the ``"..."`` variant.
+
+For header files that are **not** in the same directory as the source file that
+is including them, use the ``<...>`` variant.
+
+Example (bl1_fwu.c):
+
+.. code:: c
+
+ #include <assert.h>
+ #include <errno.h>
+ #include <string.h>
+
+ #include "bl1_private.h"
+
+Platform include paths
+^^^^^^^^^^^^^^^^^^^^^^
+
+Platforms are allowed to add more include paths to be passed to the compiler.
+The ``PLAT_INCLUDES`` variable is used for this purpose. This is needed in
+particular for the file ``platform_def.h``.
+
+Example:
+
+.. code:: c
+
+ PLAT_INCLUDES += -Iinclude/plat/myplat/include
+
+Types and typedefs
+------------------
+
+Use of built-in *C* and *libc* data types
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+The TF codebase should be kept as portable as possible, especially since both
+64-bit and 32-bit platforms are supported. To help with this, the following data
+type usage guidelines should be followed:
+
+- Where possible, use the built-in *C* data types for variable storage (for
+ example, ``char``, ``int``, ``long long``, etc) instead of the standard *C99*
+ types. Most code is typically only concerned with the minimum size of the
+ data stored, which the built-in *C* types guarantee.
+
+- Avoid using the exact-size standard *C99* types in general (for example,
+ ``uint16_t``, ``uint32_t``, ``uint64_t``, etc) since they can prevent the
+ compiler from making optimizations. There are legitimate uses for them,
+ for example to represent data of a known structure. When using them in struct
+ definitions, consider how padding in the struct will work across architectures.
+ For example, extra padding may be introduced in AArch32 systems if a struct
+ member crosses a 32-bit boundary.
+
+- Use ``int`` as the default integer type - it's likely to be the fastest on all
+ systems. Also this can be assumed to be 32-bit as a consequence of the
+ `Procedure Call Standard for the Arm Architecture`_ and the `Procedure Call
+ Standard for the Arm 64-bit Architecture`_ .
+
+- Avoid use of ``short`` as this may end up being slower than ``int`` in some
+ systems. If a variable must be exactly 16-bit, use ``int16_t`` or
+ ``uint16_t``.
+
+- Avoid use of ``long``. This is guaranteed to be at least 32-bit but, given
+ that `int` is 32-bit on Arm platforms, there is no use for it. For integers of
+ at least 64-bit, use ``long long``.
+
+- Use ``char`` for storing text. Use ``uint8_t`` for storing other 8-bit data.
+
+- Use ``unsigned`` for integers that can never be negative (counts,
+ indices, sizes, etc). TF intends to comply with MISRA "essential type" coding
+ rules (10.X), where signed and unsigned types are considered different
+ essential types. Choosing the correct type will aid this. MISRA static
+ analysers will pick up any implicit signed/unsigned conversions that may lead
+ to unexpected behaviour.
+
+- For pointer types:
+
+ - If an argument in a function declaration is pointing to a known type then
+ simply use a pointer to that type (for example: ``struct my_struct *``).
+
+ - If a variable (including an argument in a function declaration) is pointing
+ to a general, memory-mapped address, an array of pointers or another
+ structure that is likely to require pointer arithmetic then use
+ ``uintptr_t``. This will reduce the amount of casting required in the code.
+ Avoid using ``unsigned long`` or ``unsigned long long`` for this purpose; it
+ may work but is less portable.
+
+ - For other pointer arguments in a function declaration, use ``void *``. This
+ includes pointers to types that are abstracted away from the known API and
+ pointers to arbitrary data. This allows the calling function to pass a
+ pointer argument to the function without any explicit casting (the cast to
+ ``void *`` is implicit). The function implementation can then do the
+ appropriate casting to a specific type.
+
+ - Use ``ptrdiff_t`` to compare the difference between 2 pointers.
+
+- Use ``size_t`` when storing the ``sizeof()`` something.
+
+- Use ``ssize_t`` when returning the ``sizeof()`` something from a function that
+ can also return an error code; the signed type allows for a negative return
+ code in case of error. This practice should be used sparingly.
+
+- Use ``u_register_t`` when it's important to store the contents of a register
+ in its native size (32-bit in AArch32 and 64-bit in AArch64). This is not a
+ standard *C99* type but is widely available in libc implementations,
+ including the FreeBSD version included with the TF codebase. Where possible,
+ cast the variable to a more appropriate type before interpreting the data. For
+ example, the following struct in ``ep_info.h`` could use this type to minimize
+ the storage required for the set of registers:
+
+.. code:: c
+
+ typedef struct aapcs64_params {
+ u_register_t arg0;
+ u_register_t arg1;
+ u_register_t arg2;
+ u_register_t arg3;
+ u_register_t arg4;
+ u_register_t arg5;
+ u_register_t arg6;
+ u_register_t arg7;
+ } aapcs64_params_t;
+
+
+ If some code wants to operate on ``arg0`` and knows that it represents a
+ 32-bit unsigned integer on all systems, cast it to ``unsigned int``.
+
+These guidelines should be updated if additional types are needed.
+
+Avoid anonymous typedefs of structs/enums in headers
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+For example, the following definition:
+
+.. code:: c
+
+ typedef struct {
+ int arg1;
+ int arg2;
+ } my_struct_t;
+
+
+is better written as:
+
+.. code:: c
+
+ struct my_struct {
+ int arg1;
+ int arg2;
+ };
+
+This allows function declarations in other header files that depend on the
+struct/enum to forward declare the struct/enum instead of including the
+entire header:
+
+.. code:: c
+
+ #include <my_struct.h>
+ void my_func(my_struct_t *arg);
+
+instead of:
+
+.. code:: c
+
+ struct my_struct;
+ void my_func(struct my_struct *arg);
+
+Some TF definitions use both a struct/enum name **and** a typedef name. This
+is discouraged for new definitions as it makes it difficult for TF to comply
+with MISRA rule 8.3, which states that "All declarations of an object or
+function shall use the same names and type qualifiers".
+
+The Linux coding standards also discourage new typedefs and checkpatch emits
+a warning for this.
+
+Existing typedefs will be retained for compatibility.
+
+Error handling and robustness
+-----------------------------
+
+Using CASSERT to check for compile time data errors
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+Where possible, use the ``CASSERT`` macro to check the validity of data known at
+compile time instead of checking validity at runtime, to avoid unnecessary
+runtime code.
+
+For example, this can be used to check that the assembler's and compiler's views
+of the size of an array is the same.
+
+.. code:: c
+
+ #include <cassert.h>
+
+ define MY_STRUCT_SIZE 8 /* Used by assembler source files */
+
+ struct my_struct {
+ uint32_t arg1;
+ uint32_t arg2;
+ };
+
+ CASSERT(MY_STRUCT_SIZE == sizeof(struct my_struct), assert_my_struct_size_mismatch);
+
+
+If ``MY_STRUCT_SIZE`` in the above example were wrong then the compiler would
+emit an error like this:
+
+.. code:: c
+
+ my_struct.h:10:1: error: size of array ‘assert_my_struct_size_mismatch’ is negative
+
+
+Using assert() to check for programming errors
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+In general, each secure world TF image (BL1, BL2, BL31 and BL32) should be
+treated as a tightly integrated package; the image builder should be aware of
+and responsible for all functionality within the image, even if code within that
+image is provided by multiple entities. This allows us to be more aggressive in
+interpreting invalid state or bad function arguments as programming errors using
+``assert()``, including arguments passed across platform porting interfaces.
+This is in contrast to code in a Linux environment, which is less tightly
+integrated and may attempt to be more defensive by passing the error back up the
+call stack.
+
+Where possible, badly written TF code should fail early using ``assert()``. This
+helps reduce the amount of untested conditional code. By default these
+statements are not compiled into release builds, although this can be overridden
+using the ``ENABLE_ASSERTIONS`` build flag.
+
+Examples:
+
+- Bad argument supplied to library function
+- Bad argument provided by platform porting function
+- Internal secure world image state is inconsistent
+
+
+Handling integration errors
+^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+Each secure world image may be provided by a different entity (for example, a
+Trusted Boot vendor may provide the BL2 image, a TEE vendor may provide the BL32
+image and the OEM/SoC vendor may provide the other images).
+
+An image may contain bugs that are only visible when the images are integrated.
+The system integrator may not even have access to the debug variants of all the
+images in order to check if asserts are firing. For example, the release variant
+of BL1 may have already been burnt into the SoC. Therefore, TF code that detects
+an integration error should _not_ consider this a programming error, and should
+always take action, even in release builds.
+
+If an integration error is considered non-critical it should be treated as a
+recoverable error. If the error is considered critical it should be treated as
+an unexpected unrecoverable error.
+
+Handling recoverable errors
+^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+The secure world **must not** crash when supplied with bad data from an external
+source. For example, data from the normal world or a hardware device. Similarly,
+the secure world **must not** crash if it detects a non-critical problem within
+itself or the system. It must make every effort to recover from the problem by
+emitting a ``WARN`` message, performing any necessary error handling and
+continuing.
+
+Examples:
+
+- Secure world receives SMC from normal world with bad arguments.
+- Secure world receives SMC from normal world at an unexpected time.
+- BL31 receives SMC from BL32 with bad arguments.
+- BL31 receives SMC from BL32 at unexpected time.
+- Secure world receives recoverable error from hardware device. Retrying the
+ operation may help here.
+- Non-critical secure world service is not functioning correctly.
+- BL31 SPD discovers minor configuration problem with corresponding SP.
+
+Handling unrecoverable errors
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+In some cases it may not be possible for the secure world to recover from an
+error. This situation should be handled in one of the following ways:
+
+1. If the unrecoverable error is unexpected then emit an ``ERROR`` message and
+ call ``panic()``. This will end up calling the platform-specific function
+ ``plat_panic_handler()``.
+2. If the unrecoverable error is expected to occur in certain circumstances,
+ then emit an ``ERROR`` message and call the platform-specific function
+ ``plat_error_handler()``.
+
+Cases 1 and 2 are subtly different. A platform may implement ``plat_panic_handler``
+and ``plat_error_handler`` in the same way (for example, by waiting for a secure
+watchdog to time-out or by invoking an interface on the platform's power
+controller to reset the platform). However, ``plat_error_handler`` may take
+additional action for some errors (for example, it may set a flag so the
+platform resets into a different mode). Also, ``plat_panic_handler()`` may
+implement additional debug functionality (for example, invoking a hardware
+breakpoint).
+
+Examples of unexpected unrecoverable errors:
+
+- BL32 receives an unexpected SMC response from BL31 that it is unable to
+ recover from.
+- BL31 Trusted OS SPD code discovers that BL2 has not loaded the corresponding
+ Trusted OS, which is critical for platform operation.
+- Secure world discovers that a critical hardware device is an unexpected and
+ unrecoverable state.
+- Secure world receives an unexpected and unrecoverable error from a critical
+ hardware device.
+- Secure world discovers that it is running on unsupported hardware.
+
+Examples of expected unrecoverable errors:
+
+- BL1/BL2 fails to load the next image due to missing/corrupt firmware on disk.
+- BL1/BL2 fails to authenticate the next image due to an invalid certificate.
+- Secure world continuously receives recoverable errors from a hardware device
+ but is unable to proceed without a valid response.
+
+Handling critical unresponsiveness
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+If the secure world is waiting for a response from an external source (for
+example, the normal world or a hardware device) which is critical for continued
+operation, it must not wait indefinitely. It must have a mechanism (for example,
+a secure watchdog) for resetting itself and/or the external source to prevent
+the system from executing in this state indefinitely.
+
+Examples:
+
+- BL1 is waiting for the normal world to raise an SMC to proceed to the next
+ stage of the secure firmware update process.
+- A Trusted OS is waiting for a response from a proxy in the normal world that
+ is critical for continued operation.
+- Secure world is waiting for a hardware response that is critical for continued
+ operation.
+
+Security considerations
+-----------------------
+
+Part of the security of a platform is handling errors correctly, as described in
+the previous section. There are several other security considerations covered in
+this section.
+
+Do not leak secrets to the normal world
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+The secure world **must not** leak secrets to the normal world, for example in
+response to an SMC.
+
+Handling Denial of Service attacks
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+The secure world **should never** crash or become unusable due to receiving too
+many normal world requests (a *Denial of Service* or *DoS* attack). It should
+have a mechanism for throttling or ignoring normal world requests.
+
+Performance considerations
+--------------------------
+
+Avoid printf and use logging macros
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+``debug.h`` provides logging macros (for example, ``WARN`` and ``ERROR``)
+which wrap ``tf_log`` and which allow the logging call to be compiled-out
+depending on the ``make`` command. Use these macros to avoid print statements
+being compiled unconditionally into the binary.
+
+Each logging macro has a numerical log level:
+
+.. code:: c
+
+ #define LOG_LEVEL_NONE 0
+ #define LOG_LEVEL_ERROR 10
+ #define LOG_LEVEL_NOTICE 20
+ #define LOG_LEVEL_WARNING 30
+ #define LOG_LEVEL_INFO 40
+ #define LOG_LEVEL_VERBOSE 50
+
+
+By default, all logging statements with a log level ``<= LOG_LEVEL_INFO`` will
+be compiled into debug builds and all statements with a log level
+``<= LOG_LEVEL_NOTICE`` will be compiled into release builds. This can be
+overridden from the command line or by the platform makefile (although it may be
+necessary to clean the build directory first). For example, to enable
+``VERBOSE`` logging on FVP:
+
+``make PLAT=fvp LOG_LEVEL=50 all``
+
+Use const data where possible
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+For example, the following code:
+
+.. code:: c
+
+ struct my_struct {
+ int arg1;
+ int arg2;
+ };
+
+ void init(struct my_struct *ptr);
+
+ void main(void)
+ {
+ struct my_struct x;
+ x.arg1 = 1;
+ x.arg2 = 2;
+ init(&x);
+ }
+
+is better written as:
+
+.. code:: c
+
+ struct my_struct {
+ int arg1;
+ int arg2;
+ };
+
+ void init(const struct my_struct *ptr);
+
+ void main(void)
+ {
+ const struct my_struct x = { 1, 2 };
+ init(&x);
+ }
+
+This allows the linker to put the data in a read-only data section instead of a
+writeable data section, which may result in a smaller and faster binary. Note
+that this may require dependent functions (``init()`` in the above example) to
+have ``const`` arguments, assuming they don't need to modify the data.
+
+Library and driver code
+-----------------------
+
+TF library code (under ``lib/`` and ``include/lib``) is any code that provides a
+reusable interface to other code, potentially even to code outside of TF.
+
+In some systems drivers must conform to a specific driver framework to provide
+services to the rest of the system. TF has no driver framework and the
+distinction between a driver and library is somewhat subjective.
+
+A driver (under ``drivers/`` and ``include/drivers/``) is defined as code that
+interfaces with hardware via a memory mapped interface.
+
+Some drivers (for example, the Arm CCI driver in ``include/drivers/arm/cci.h``)
+provide a general purpose API to that specific hardware. Other drivers (for
+example, the Arm PL011 console driver in ``drivers/arm/pl011/pl011_console.S``)
+provide a specific hardware implementation of a more abstract library API. In
+the latter case there may potentially be multiple drivers for the same hardware
+device.
+
+Neither libraries nor drivers should depend on platform-specific code. If they
+require platform-specific data (for example, a base address) to operate then
+they should provide an initialization function that takes the platform-specific
+data as arguments.
+
+TF common code (under ``common/`` and ``include/common/``) is code that is re-used
+by other generic (non-platform-specific) TF code. It is effectively internal
+library code.
+
+.. _`Why the “volatile” type class should not be used`: https://www.kernel.org/doc/html/latest/process/volatile-considered-harmful.html
+.. _`Procedure Call Standard for the Arm Architecture`: http://infocenter.arm.com/help/topic/com.arm.doc.ihi0042f/IHI0042F_aapcs.pdf
+.. _`Procedure Call Standard for the Arm 64-bit Architecture`: http://infocenter.arm.com/help/topic/com.arm.doc.ihi0055b/IHI0055B_aapcs64.pdf
diff --git a/docs/firmware-design.rst b/docs/firmware-design.rst
index c79f03d..06fdbac 100644
--- a/docs/firmware-design.rst
+++ b/docs/firmware-design.rst
@@ -1684,6 +1684,21 @@
Note: Loading the BL32 image in TZC secured DRAM doesn't change the memory
layout of the other images in Trusted SRAM.
+CONFIG section in memory layouts shown below contains:
+
+::
+
+ +--------------------+
+ |bl2_mem_params_descs|
+ |--------------------|
+ | fw_configs |
+ +--------------------+
+
+``bl2_mem_params_descs`` contains parameters passed from BL2 to next the
+BL image during boot.
+
+``fw_configs`` includes soc_fw_config, tos_fw_config and tb_fw_config.
+
**FVP with TSP in Trusted SRAM with firmware configs :**
(These diagrams only cover the AArch64 case)
@@ -1708,7 +1723,7 @@
| | <<<<<<<<<<<<< |----------------|
| | <<<<<<<<<<<<< | BL32 |
0x04002000 +----------+ +----------------+
- |fw_configs|
+ | CONFIG |
0x04001000 +----------+
| Shared |
0x04000000 +----------+
@@ -1745,7 +1760,7 @@
| | <<<<<<<<<<<<< | BL31 PROGBITS |
| | +----------------+
+--------------+
- | fw_configs |
+ | CONFIG |
0x04001000 +--------------+
| Shared |
0x04000000 +--------------+
@@ -1779,7 +1794,7 @@
| | <<<<<<<<<<<<< | BL31 PROGBITS |
| | +----------------+
0x04002000 +----------+
- |fw_configs|
+ | CONFIG |
0x04001000 +----------+
| Shared |
0x04000000 +----------+
diff --git a/docs/plat/nvidia-tegra.rst b/docs/plat/nvidia-tegra.rst
index e244c1c..90d2ae1 100644
--- a/docs/plat/nvidia-tegra.rst
+++ b/docs/plat/nvidia-tegra.rst
@@ -82,6 +82,8 @@
int uart\_id;
/* L2 ECC parity protection disable flag \*/
int l2\_ecc\_parity\_prot\_dis;
+/* SHMEM base address for storing the boot logs \*/
+uint64\_t boot\_profiler\_shmem\_base;
} plat\_params\_from\_bl2\_t;
Power Management
diff --git a/docs/plat/warp7.rst b/docs/plat/warp7.rst
index 51c2609..6c04d91 100644
--- a/docs/plat/warp7.rst
+++ b/docs/plat/warp7.rst
@@ -31,15 +31,6 @@
make warp7_bl33_defconfig;
make u-boot.imx arch=ARM CROSS_COMPILE=arm-linux-gnueabihf-
-## TF-A:
-
-https://github.com/ARM-software/arm-trusted-firmware.git
-
-.. code:: shell
-
- make CROSS_COMPILE=arm-linux-gnueabihf- PLAT=warp7 ARCH=aarch32 ARM_ARCH_MAJOR=7 ARM_CORTEX_A7=yes AARCH32_SP=optee all
- /path/to/u-boot/tools/mkimage -n /path/to/u-boot/u-boot.cfgout -T imximage -e 0x9df00000 -d ./build/warp7/debug/bl2.bin ./build/warp7/debug/bl2.bin.imx
-
## OP-TEE:
https://github.com/OP-TEE/optee_os.git
@@ -48,19 +39,76 @@
make ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf- PLATFORM=imx PLATFORM_FLAVOR=mx7swarp7 ARCH=arm CFG_PAGEABLE_ADDR=0 CFG_DT_ADDR=0x83000000 CFG_NS_ENTRY_ADDR=0x87800000
+## TF-A:
+
+https://github.com/ARM-software/arm-trusted-firmware.git
+
+The following commands assume that a directory exits in the top-level TFA build
+directory "fiptool_images". "fiptool_images" contains
+
+- u-boot.bin
+ The binary output from the u-boot instructions above
+
+- tee-header_v2.bin
+- tee-pager_v2.bin
+- tee-pageable_v2.bin
+ Binary outputs from the previous OPTEE build steps
+
+It is also assumed copy of mbedtls is available on the path path ../mbedtls
+ https://github.com/ARMmbed/mbedtls.git
+ At the time of writing HEAD points to 0592ea772aee48ca1e6d9eb84eca8e143033d973
+
+.. code:: shell
+
+ mkdir fiptool_images
+ cp /path/to/optee/out/arm-plat-imx/core/tee-header_v2.bin fiptool_images
+ cp /path/to/optee/out/arm-plat-imx/core/tee-pager_v2.bin fiptool_images
+ cp /path/to/optee/out/arm-plat-imx/core/tee-pageable_v2.bin fiptool_images
+
+ make CROSS_COMPILE=${CROSS_COMPILE} PLAT=warp7 ARCH=aarch32 ARM_ARCH_MAJOR=7 \
+ ARM_CORTEX_A7=yes AARCH32_SP=optee PLAT_WARP7_UART=1 GENERATE_COT=1 \
+ TRUSTED_BOARD_BOOT=1 USE_TBBR_DEFS=1 MBEDTLS_DIR=../mbedtls \
+ NEED_BL32=yes BL32=fiptool_images/tee-header_v2.bin \
+ BL32_EXTRA1=fiptool_images/tee-pager_v2.bin \
+ BL32_EXTRA2=fiptool_images/tee-pageable_v2.bin \
+ BL33=fiptool_images/u-boot.bin certificates all
+
+ /path/to/u-boot/tools/mkimage -n /path/to/u-boot/u-boot.cfgout -T imximage -e 0x9df00000 -d ./build/warp7/debug/bl2.bin ./build/warp7/debug/bl2.bin.imx
## FIP:
.. code:: shell
- mkdir fiptool_images
cp /path/to/uboot/u-boot.bin fiptool_images
- cp /path/to/optee/out/arm-plat-imx/core/tee-header_v2.bin fiptool_images
- cp /path/to/optee/out/arm-plat-imx/core/tee-pager_v2.bin fiptool_images
- cp /path/to/optee/out/arm-plat-imx/core/tee-pageable_v2.bin fiptool_images
cp /path/to/linux/arch/boot/dts/imx7s-warp.dtb fiptool_images
- tools/fiptool/fiptool create --tos-fw fiptool_images/tee-header_v2.bin --tos-fw-extra1 fiptool_images/tee-pager_v2.bin --tos-fw-extra2 fiptool_images/tee-pageable_v2.bin --nt-fw fiptool_images/u-boot.bin --hw-config fiptool_images/imx7s-warp.dtb warp7.fip
+ tools/cert_create/cert_create -n --rot-key "build/warp7/debug/rot_key.pem" \
+ --tfw-nvctr 0 \
+ --ntfw-nvctr 0 \
+ --trusted-key-cert fiptool_images/trusted-key-cert.key-crt \
+ --tb-fw=build/warp7/debug/bl2.bin \
+ --tb-fw-cert fiptool_images/trusted-boot-fw.key-crt\
+ --tos-fw fiptool_images/tee-header_v2.bin \
+ --tos-fw-cert fiptool_images/tee-header_v2.bin.crt \
+ --tos-fw-key-cert fiptool_images/tee-header_v2.bin.key-crt \
+ --tos-fw-extra1 fiptool_images/tee-pager_v2.bin \
+ --tos-fw-extra2 fiptool_images/tee-pageable_v2.bin \
+ --nt-fw fiptool_images/u-boot.bin \
+ --nt-fw-cert fiptool_images/u-boot.bin.crt \
+ --nt-fw-key-cert fiptool_images/u-boot.bin.key-crt \
+ --hw-config fiptool_images/imx7s-warp.dtb
+
+ tools/fiptool/fiptool create --tos-fw fiptool_images/tee-header_v2.bin \
+ --tos-fw-extra1 fiptool_images/tee-pager_v2.bin \
+ --tos-fw-extra2 fiptool_images/tee-pageable_v2.bin \
+ --nt-fw fiptool_images/u-boot.bin \
+ --hw-config fiptool_images/imx7s-warp.dtb \
+ --tos-fw-cert fiptool_images/tee-header_v2.bin.crt \
+ --tos-fw-key-cert fiptool_images/tee-header_v2.bin.key-crt \
+ --nt-fw-cert fiptool_images/u-boot.bin.crt \
+ --nt-fw-key-cert fiptool_images/u-boot.bin.key-crt \
+ --trusted-key-cert fiptool_images/trusted-key-cert.key-crt \
+ --tb-fw-cert fiptool_images/trusted-boot-fw.key-crt warp7.fip
# Deploy Images
diff --git a/docs/porting-guide.rst b/docs/porting-guide.rst
index 7fc5297..716d446 100644
--- a/docs/porting-guide.rst
+++ b/docs/porting-guide.rst
@@ -1198,9 +1198,6 @@
meminfo.total_base = Base address of secure RAM visible to BL1
meminfo.total_size = Size of secure RAM visible to BL1
- meminfo.free_base = Base address of secure RAM available for allocation
- to BL1
- meminfo.free_size = Size of secure RAM available for allocation to BL1
This information is used by BL1 to load the BL2 image in secure RAM. BL1 also
populates a similar structure to tell BL2 the extents of memory available for
diff --git a/docs/user-guide.rst b/docs/user-guide.rst
index b50de37..320bb1d 100644
--- a/docs/user-guide.rst
+++ b/docs/user-guide.rst
@@ -86,6 +86,46 @@
git clone https://github.com/ARM-software/arm-trusted-firmware.git
+Checking source code style
+~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Trusted Firmware follows the `Linux Coding Style`_ . When making changes to the
+source, for submission to the project, the source must be in compliance with
+this style guide.
+
+Additional, project-specific guidelines are defined in the `Trusted Firmware-A
+Coding Guidelines`_ document.
+
+To assist with coding style compliance, the project Makefile contains two
+targets which both utilise the `checkpatch.pl` script that ships with the Linux
+source tree. The project also defines certain *checkpatch* options in the
+``.checkpatch.conf`` file in the top-level directory.
+
+**Note:** Checkpatch errors will gate upstream merging of pull requests.
+Checkpatch warnings will not gate merging but should be reviewed and fixed if
+possible.
+
+To check the entire source tree, you must first download copies of
+``checkpatch.pl``, ``spelling.txt`` and ``const_structs.checkpatch`` available
+in the `Linux master tree`_ *scripts* directory, then set the ``CHECKPATCH``
+environment variable to point to ``checkpatch.pl`` (with the other 2 files in
+the same directory) and build the `checkcodebase` target:
+
+::
+
+ make CHECKPATCH=<path-to-linux>/linux/scripts/checkpatch.pl checkcodebase
+
+To just check the style on the files that differ between your local branch and
+the remote master, use:
+
+::
+
+ make CHECKPATCH=<path-to-linux>/linux/scripts/checkpatch.pl checkpatch
+
+If you wish to check your patch against something other than the remote master,
+set the ``BASE_COMMIT`` variable to your desired branch. By default, ``BASE_COMMIT``
+is set to ``origin/master``.
+
Building TF-A
-------------
@@ -234,12 +274,6 @@
compiling TF-A. Its value must be a numeric, and defaults to 0. See also,
*Armv8 Architecture Extensions* in `Firmware Design`_.
-- ``ARM_PLAT_MT``: This flag determines whether the Arm platform layer has to
- cater for the multi-threading ``MT`` bit when accessing MPIDR. When this flag
- is set, the functions which deal with MPIDR assume that the ``MT`` bit in
- MPIDR is set and access the bit-fields in MPIDR accordingly. Default value of
- this flag is 0. Note that this option is not used on FVP platforms.
-
- ``BL2``: This is an optional build option which specifies the path to BL2
image for the ``fip`` target. In this case, the BL2 in the TF-A will not be
built.
@@ -628,11 +662,6 @@
pages" section in `Firmware Design`_. This flag is disabled by default and
affects all BL images.
-- ``SMCCC_MAJOR_VERSION``: Numeric value that indicates the major version of
- the SMC Calling Convention that the Trusted Firmware supports. The only two
- allowed values are 1 and 2, and it defaults to 1. The minor version is
- determined using this value.
-
- ``SPD``: Choose a Secure Payload Dispatcher component to be built into TF-A.
This build option is only valid if ``ARCH=aarch64``. The value should be
the path to the directory containing the SPD source, relative to
@@ -735,6 +764,12 @@
Linux Image address must be specified using the ``PRELOADED_BL33_BASE``
option.
+- ``ARM_PLAT_MT``: This flag determines whether the Arm platform layer has to
+ cater for the multi-threading ``MT`` bit when accessing MPIDR. When this flag
+ is set, the functions which deal with MPIDR assume that the ``MT`` bit in
+ MPIDR is set and access the bit-fields in MPIDR accordingly. Default value of
+ this flag is 0. Note that this option is not used on FVP platforms.
+
- ``ARM_RECOM_STATE_ID_ENC``: The PSCI1.0 specification recommends an encoding
for the construction of composite state-ID in the power-state parameter.
The existing PSCI clients currently do not support this encoding of
@@ -930,34 +965,6 @@
build/<platform>/<build-type>/bl32.bin
-Checking source code style
-~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-When making changes to the source for submission to the project, the source
-must be in compliance with the Linux style guide, and to assist with this check
-the project Makefile contains two targets, which both utilise the
-``checkpatch.pl`` script that ships with the Linux source tree.
-
-To check the entire source tree, you must first download copies of
-``checkpatch.pl``, ``spelling.txt`` and ``const_structs.checkpatch`` available
-in the `Linux master tree`_ scripts directory, then set the ``CHECKPATCH``
-environment variable to point to ``checkpatch.pl`` (with the other 2 files in
-the same directory) and build the target checkcodebase:
-
-::
-
- make CHECKPATCH=<path-to-linux>/linux/scripts/checkpatch.pl checkcodebase
-
-To just check the style on the files that differ between your local branch and
-the remote master, use:
-
-::
-
- make CHECKPATCH=<path-to-linux>/linux/scripts/checkpatch.pl checkpatch
-
-If you wish to check your patch against something other than the remote master,
-set the ``BASE_COMMIT`` variable to your desired branch. By default, ``BASE_COMMIT``
-is set to ``origin/master``.
Building and using the FIP tool
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
@@ -2045,7 +2052,7 @@
--------------
-*Copyright (c) 2013-2018, Arm Limited and Contributors. All rights reserved.*
+*Copyright (c) 2013-2019, Arm Limited and Contributors. All rights reserved.*
.. _Linaro: `Linaro Release Notes`_
.. _Linaro Release: `Linaro Release Notes`_
@@ -2054,6 +2061,7 @@
.. _Instructions for using Linaro's deliverables on Juno: https://community.arm.com/dev-platforms/w/docs/303/juno
.. _Arm Platforms Portal: https://community.arm.com/dev-platforms/
.. _Development Studio 5 (DS-5): http://www.arm.com/products/tools/software-tools/ds-5/index.php
+.. _`Linux Coding Style`: https://www.kernel.org/doc/html/latest/process/coding-style.html
.. _Linux master tree: https://github.com/torvalds/linux/tree/master/
.. _Dia: https://wiki.gnome.org/Apps/Dia/Download
.. _here: psci-lib-integration-guide.rst
@@ -2069,3 +2077,4 @@
.. _Juno Getting Started Guide: http://infocenter.arm.com/help/topic/com.arm.doc.dui0928e/DUI0928E_juno_arm_development_platform_gsg.pdf
.. _PSCI: http://infocenter.arm.com/help/topic/com.arm.doc.den0022d/Power_State_Coordination_Interface_PDD_v1_1_DEN0022D.pdf
.. _Secure Partition Manager Design guide: secure-partition-manager-design.rst
+.. _`Trusted Firmware-A Coding Guidelines`: coding-guidelines.rst
diff --git a/plat/arm/css/drivers/mhu/css_mhu.c b/drivers/arm/css/mhu/css_mhu.c
similarity index 96%
rename from plat/arm/css/drivers/mhu/css_mhu.c
rename to drivers/arm/css/mhu/css_mhu.c
index 981df9c..b7faf7e 100644
--- a/plat/arm/css/drivers/mhu/css_mhu.c
+++ b/drivers/arm/css/mhu/css_mhu.c
@@ -9,12 +9,10 @@
#include <platform_def.h>
#include <arch_helpers.h>
+#include <drivers/arm/css/css_mhu.h>
#include <lib/bakery_lock.h>
#include <lib/mmio.h>
-
-#include <plat_arm.h>
-
-#include "css_mhu.h"
+#include <plat/arm/common/plat_arm.h>
/* SCP MHU secure channel registers */
#define SCP_INTR_S_STAT 0x200
diff --git a/plat/arm/css/drivers/mhu/css_mhu_doorbell.c b/drivers/arm/css/mhu/css_mhu_doorbell.c
similarity index 90%
rename from plat/arm/css/drivers/mhu/css_mhu_doorbell.c
rename to drivers/arm/css/mhu/css_mhu_doorbell.c
index 964428b..8858742 100644
--- a/plat/arm/css/drivers/mhu/css_mhu_doorbell.c
+++ b/drivers/arm/css/mhu/css_mhu_doorbell.c
@@ -7,9 +7,8 @@
#include <platform_def.h>
#include <arch_helpers.h>
-
-#include "css_mhu_doorbell.h"
-#include "../scmi/scmi.h"
+#include <drivers/arm/css/css_mhu_doorbell.h>
+#include <drivers/arm/css/scmi.h>
void mhu_ring_doorbell(struct scmi_channel_plat_info *plat_info)
{
diff --git a/plat/arm/css/drivers/scmi/scmi_ap_core_proto.c b/drivers/arm/css/scmi/scmi_ap_core_proto.c
similarity index 97%
rename from plat/arm/css/drivers/scmi/scmi_ap_core_proto.c
rename to drivers/arm/css/scmi/scmi_ap_core_proto.c
index e495dcc..2caccc2 100644
--- a/plat/arm/css/drivers/scmi/scmi_ap_core_proto.c
+++ b/drivers/arm/css/scmi/scmi_ap_core_proto.c
@@ -8,8 +8,8 @@
#include <arch_helpers.h>
#include <common/debug.h>
+#include <drivers/arm/css/scmi.h>
-#include "scmi.h"
#include "scmi_private.h"
/*
diff --git a/plat/arm/css/drivers/scmi/scmi_common.c b/drivers/arm/css/scmi/scmi_common.c
similarity index 98%
rename from plat/arm/css/drivers/scmi/scmi_common.c
rename to drivers/arm/css/scmi/scmi_common.c
index 1b4ecb2..e2c353d 100644
--- a/plat/arm/css/drivers/scmi/scmi_common.c
+++ b/drivers/arm/css/scmi/scmi_common.c
@@ -8,8 +8,8 @@
#include <arch_helpers.h>
#include <common/debug.h>
+#include <drivers/arm/css/scmi.h>
-#include "scmi.h"
#include "scmi_private.h"
#if HW_ASSISTED_COHERENCY
diff --git a/plat/arm/css/drivers/scmi/scmi_private.h b/drivers/arm/css/scmi/scmi_private.h
similarity index 100%
rename from plat/arm/css/drivers/scmi/scmi_private.h
rename to drivers/arm/css/scmi/scmi_private.h
diff --git a/plat/arm/css/drivers/scmi/scmi_pwr_dmn_proto.c b/drivers/arm/css/scmi/scmi_pwr_dmn_proto.c
similarity index 97%
rename from plat/arm/css/drivers/scmi/scmi_pwr_dmn_proto.c
rename to drivers/arm/css/scmi/scmi_pwr_dmn_proto.c
index f315621..70165de 100644
--- a/plat/arm/css/drivers/scmi/scmi_pwr_dmn_proto.c
+++ b/drivers/arm/css/scmi/scmi_pwr_dmn_proto.c
@@ -8,8 +8,8 @@
#include <arch_helpers.h>
#include <common/debug.h>
+#include <drivers/arm/css/scmi.h>
-#include "scmi.h"
#include "scmi_private.h"
/*
diff --git a/plat/arm/css/drivers/scmi/scmi_sys_pwr_proto.c b/drivers/arm/css/scmi/scmi_sys_pwr_proto.c
similarity index 97%
rename from plat/arm/css/drivers/scmi/scmi_sys_pwr_proto.c
rename to drivers/arm/css/scmi/scmi_sys_pwr_proto.c
index 03c3c06..a27c4a5 100644
--- a/plat/arm/css/drivers/scmi/scmi_sys_pwr_proto.c
+++ b/drivers/arm/css/scmi/scmi_sys_pwr_proto.c
@@ -8,8 +8,8 @@
#include <arch_helpers.h>
#include <common/debug.h>
+#include <drivers/arm/css/scmi.h>
-#include "scmi.h"
#include "scmi_private.h"
/*
diff --git a/plat/arm/css/drivers/scp/css_bom_bootloader.c b/drivers/arm/css/scp/css_bom_bootloader.c
similarity index 97%
rename from plat/arm/css/drivers/scp/css_bom_bootloader.c
rename to drivers/arm/css/scp/css_bom_bootloader.c
index ca40c30..1fc1270 100644
--- a/plat/arm/css/drivers/scp/css_bom_bootloader.c
+++ b/drivers/arm/css/scp/css_bom_bootloader.c
@@ -9,13 +9,12 @@
#include <arch_helpers.h>
#include <common/debug.h>
+#include <drivers/arm/css/css_mhu.h>
+#include <drivers/arm/css/css_scp.h>
+#include <drivers/arm/css/css_scpi.h>
#include <plat/common/platform.h>
#include <platform_def.h>
-#include "../mhu/css_mhu.h"
-#include "../scpi/css_scpi.h"
-#include "css_scp.h"
-
/* ID of the MHU slot used for the BOM protocol */
#define BOM_MHU_SLOT_ID 0
diff --git a/plat/arm/css/drivers/scp/css_pm_scmi.c b/drivers/arm/css/scp/css_pm_scmi.c
similarity index 98%
rename from plat/arm/css/drivers/scp/css_pm_scmi.c
rename to drivers/arm/css/scp/css_pm_scmi.c
index fa4dd8a..1966c44 100644
--- a/plat/arm/css/drivers/scp/css_pm_scmi.c
+++ b/drivers/arm/css/scp/css_pm_scmi.c
@@ -9,15 +9,13 @@
#include <arch_helpers.h>
#include <common/debug.h>
+#include <drivers/arm/css/css_scp.h>
+#include <drivers/arm/css/scmi.h>
+#include <plat/arm/common/plat_arm.h>
+#include <plat/arm/css/common/css_pm.h>
#include <plat/common/platform.h>
#include <platform_def.h>
-#include <css_pm.h>
-#include <plat_arm.h>
-
-#include "../scmi/scmi.h"
-#include "css_scp.h"
-
/*
* This file implements the SCP helper functions using SCMI protocol.
*/
diff --git a/plat/arm/css/drivers/scp/css_pm_scpi.c b/drivers/arm/css/scp/css_pm_scpi.c
similarity index 96%
rename from plat/arm/css/drivers/scp/css_pm_scpi.c
rename to drivers/arm/css/scp/css_pm_scpi.c
index f53ac30..b4019ce 100644
--- a/plat/arm/css/drivers/scp/css_pm_scpi.c
+++ b/drivers/arm/css/scp/css_pm_scpi.c
@@ -8,12 +8,10 @@
#include <arch_helpers.h>
#include <common/debug.h>
-
-#include <css_pm.h>
-#include <plat_arm.h>
-
-#include "../scpi/css_scpi.h"
-#include "css_scp.h"
+#include <drivers/arm/css/css_scp.h>
+#include <drivers/arm/css/css_scpi.h>
+#include <plat/arm/common/plat_arm.h>
+#include <plat/arm/css/common/css_pm.h>
/*
* This file implements the SCP power management functions using SCPI protocol.
diff --git a/plat/arm/css/drivers/scp/css_sds.c b/drivers/arm/css/scp/css_sds.c
similarity index 96%
rename from plat/arm/css/drivers/scp/css_sds.c
rename to drivers/arm/css/scp/css_sds.c
index e3f6102..e42ee10 100644
--- a/plat/arm/css/drivers/scp/css_sds.c
+++ b/drivers/arm/css/scp/css_sds.c
@@ -9,13 +9,12 @@
#include <arch_helpers.h>
#include <common/debug.h>
+#include <drivers/arm/css/css_scp.h>
+#include <drivers/arm/css/sds.h>
#include <drivers/delay_timer.h>
#include <plat/common/platform.h>
#include <platform_def.h>
-#include "css_scp.h"
-#include "../sds/sds.h"
-
int css_scp_boot_image_xfer(void *image, unsigned int image_size)
{
int ret;
diff --git a/plat/arm/css/drivers/scpi/css_scpi.c b/drivers/arm/css/scpi/css_scpi.c
similarity index 98%
rename from plat/arm/css/drivers/scpi/css_scpi.c
rename to drivers/arm/css/scpi/css_scpi.c
index d64bfa2..4b73265 100644
--- a/plat/arm/css/drivers/scpi/css_scpi.c
+++ b/drivers/arm/css/scpi/css_scpi.c
@@ -9,13 +9,12 @@
#include <arch_helpers.h>
#include <common/debug.h>
+#include <drivers/arm/css/css_mhu.h>
+#include <drivers/arm/css/css_scpi.h>
#include <lib/utils.h>
#include <plat/common/platform.h>
#include <platform_def.h>
-#include "../mhu/css_mhu.h"
-#include "css_scpi.h"
-
#define SCPI_SHARED_MEM_SCP_TO_AP PLAT_CSS_SCP_COM_SHARED_MEM_BASE
#define SCPI_SHARED_MEM_AP_TO_SCP (PLAT_CSS_SCP_COM_SHARED_MEM_BASE \
+ 0x100)
diff --git a/plat/arm/css/drivers/sds/aarch32/sds_helpers.S b/drivers/arm/css/sds/aarch32/sds_helpers.S
similarity index 97%
rename from plat/arm/css/drivers/sds/aarch32/sds_helpers.S
rename to drivers/arm/css/sds/aarch32/sds_helpers.S
index f68cb35..13ff0e1 100644
--- a/plat/arm/css/drivers/sds/aarch32/sds_helpers.S
+++ b/drivers/arm/css/sds/aarch32/sds_helpers.S
@@ -6,8 +6,9 @@
#include <arch.h>
#include <asm_macros.S>
+#include <drivers/arm/css/sds.h>
#include <platform_def.h>
-#include "../sds.h"
+
#include "../sds_private.h"
.globl sds_get_primary_cpu_id
diff --git a/plat/arm/css/drivers/sds/aarch64/sds_helpers.S b/drivers/arm/css/sds/aarch64/sds_helpers.S
similarity index 97%
rename from plat/arm/css/drivers/sds/aarch64/sds_helpers.S
rename to drivers/arm/css/sds/aarch64/sds_helpers.S
index 3b9c562..3256c2b 100644
--- a/plat/arm/css/drivers/sds/aarch64/sds_helpers.S
+++ b/drivers/arm/css/sds/aarch64/sds_helpers.S
@@ -6,8 +6,9 @@
#include <arch.h>
#include <asm_macros.S>
+#include <drivers/arm/css/sds.h>
#include <platform_def.h>
-#include "../sds.h"
+
#include "../sds_private.h"
.globl sds_get_primary_cpu_id
diff --git a/plat/arm/css/drivers/sds/sds.c b/drivers/arm/css/sds/sds.c
similarity index 99%
rename from plat/arm/css/drivers/sds/sds.c
rename to drivers/arm/css/sds/sds.c
index eb2f48e..1fb196c 100644
--- a/plat/arm/css/drivers/sds/sds.c
+++ b/drivers/arm/css/sds/sds.c
@@ -10,9 +10,9 @@
#include <arch_helpers.h>
#include <common/debug.h>
+#include <drivers/arm/css/sds.h>
#include <platform_def.h>
-#include "sds.h"
#include "sds_private.h"
/*
diff --git a/plat/arm/css/drivers/sds/sds_private.h b/drivers/arm/css/sds/sds_private.h
similarity index 100%
rename from plat/arm/css/drivers/sds/sds_private.h
rename to drivers/arm/css/sds/sds_private.h
diff --git a/plat/arm/board/fvp/drivers/pwrc/fvp_pwrc.c b/drivers/arm/fvp/fvp_pwrc.c
similarity index 95%
rename from plat/arm/board/fvp/drivers/pwrc/fvp_pwrc.c
rename to drivers/arm/fvp/fvp_pwrc.c
index cae9827..75a2b66 100644
--- a/plat/arm/board/fvp/drivers/pwrc/fvp_pwrc.c
+++ b/drivers/arm/fvp/fvp_pwrc.c
@@ -4,14 +4,12 @@
* SPDX-License-Identifier: BSD-3-Clause
*/
+#include <drivers/arm/fvp/fvp_pwrc.h>
#include <lib/bakery_lock.h>
#include <lib/mmio.h>
+#include <plat/arm/common/plat_arm.h>
#include <platform_def.h>
-#include <plat_arm.h>
-#include "../../fvp_private.h"
-#include "fvp_pwrc.h"
-
/*
* TODO: Someday there will be a generic power controller api. At the moment
* each platform has its own pwrc so just exporting functions is fine.
diff --git a/drivers/console/multi_console.c b/drivers/console/multi_console.c
index e94de35..a135959 100644
--- a/drivers/console/multi_console.c
+++ b/drivers/console/multi_console.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2018, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2018-2019, ARM Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -76,7 +76,7 @@
console_t *console;
for (console = console_list; console != NULL; console = console->next)
- if (console->flags & console_state) {
+ if ((console->flags & console_state) && console->putc) {
int ret = console->putc(c, console);
if ((err == ERROR_NO_VALID_CONSOLE) || (ret < err))
err = ret;
@@ -93,7 +93,7 @@
do { /* Keep polling while at least one console works correctly. */
for (console = console_list; console != NULL;
console = console->next)
- if (console->flags & console_state) {
+ if ((console->flags & console_state) && console->getc) {
int ret = console->getc(console);
if (ret >= 0)
return ret;
@@ -111,7 +111,7 @@
console_t *console;
for (console = console_list; console != NULL; console = console->next)
- if (console->flags & console_state) {
+ if ((console->flags & console_state) && console->flush) {
int ret = console->flush(console);
if ((err == ERROR_NO_VALID_CONSOLE) || (ret < err))
err = ret;
diff --git a/drivers/mmc/mmc.c b/drivers/mmc/mmc.c
index 450bd0b..77d683c 100644
--- a/drivers/mmc/mmc.c
+++ b/drivers/mmc/mmc.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2018, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2018-2019, ARM Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -300,7 +300,7 @@
break;
}
- if (ret != 0) {
+ if (ret < 0) {
return ret;
}
diff --git a/drivers/partition/partition.c b/drivers/partition/partition.c
index 630c1d8..6fa3df0 100644
--- a/drivers/partition/partition.c
+++ b/drivers/partition/partition.c
@@ -16,7 +16,7 @@
#include <plat/common/platform.h>
static uint8_t mbr_sector[PARTITION_BLOCK_SIZE];
-partition_entry_list_t list;
+static partition_entry_list_t list;
#if LOG_LEVEL >= LOG_LEVEL_VERBOSE
static void dump_entries(int num)
diff --git a/drivers/renesas/rcar/cpld/ulcb_cpld.c b/drivers/renesas/rcar/cpld/ulcb_cpld.c
index 6b03614..4830853 100644
--- a/drivers/renesas/rcar/cpld/ulcb_cpld.c
+++ b/drivers/renesas/rcar/cpld/ulcb_cpld.c
@@ -24,6 +24,9 @@
#define GPIO_INOUTSEL2 0xE6052004
#define GPIO_INOUTSEL6 0xE6055404
+/* General IO/Interrupt Switching Register */
+#define GPIO_IOINTSEL6 0xE6055400
+
/* GPIO/perihperal function select */
#define PFC_GPSR2 0xE6060108
#define PFC_GPSR6 0xE6060118
@@ -93,6 +96,7 @@
gpio_pfc(PFC_GPSR2, SSTBZ);
gpio_pfc(PFC_GPSR6, MOSI);
+ gpio_set_value(GPIO_IOINTSEL6, SCLK, 0);
gpio_set_value(GPIO_OUTDT6, SCLK, 0);
gpio_set_value(GPIO_OUTDT2, SSTBZ, 1);
gpio_set_value(GPIO_OUTDT6, MOSI, 0);
diff --git a/drivers/renesas/rcar/pwrc/pwrc.c b/drivers/renesas/rcar/pwrc/pwrc.c
index b005caf..d7f0880 100644
--- a/drivers/renesas/rcar/pwrc/pwrc.c
+++ b/drivers/renesas/rcar/pwrc/pwrc.c
@@ -768,3 +768,43 @@
done:
return count;
}
+
+int32_t rcar_pwrc_cpu_on_check(uint64_t mpidr)
+{
+ uint64_t i;
+ uint64_t j;
+ uint64_t cpu_count;
+ uintptr_t reg_PSTR;
+ uint32_t status;
+ uint64_t my_cpu;
+ int32_t rtn;
+ uint32_t my_cluster_type;
+
+ const uint32_t cluster_type[PLATFORM_CLUSTER_COUNT] = {
+ RCAR_CLUSTER_CA53,
+ RCAR_CLUSTER_CA57
+ };
+ const uintptr_t registerPSTR[PLATFORM_CLUSTER_COUNT] = {
+ RCAR_CA53PSTR,
+ RCAR_CA57PSTR
+ };
+
+ my_cluster_type = rcar_pwrc_get_cluster();
+
+ rtn = 0;
+ my_cpu = mpidr & ((uint64_t)(MPIDR_CPU_MASK));
+ for (i = 0U; i < ((uint64_t)(PLATFORM_CLUSTER_COUNT)); i++) {
+ cpu_count = rcar_pwrc_get_cpu_num(cluster_type[i]);
+ reg_PSTR = registerPSTR[i];
+ for (j = 0U; j < cpu_count; j++) {
+ if ((my_cluster_type != cluster_type[i]) || (my_cpu != j)) {
+ status = mmio_read_32(reg_PSTR) >> (j * 4U);
+ if ((status & 0x00000003U) == 0U) {
+ rtn--;
+ }
+ }
+ }
+ }
+ return (rtn);
+
+}
diff --git a/drivers/renesas/rcar/pwrc/pwrc.h b/drivers/renesas/rcar/pwrc/pwrc.h
index 3cdac69..d4d6fc4 100644
--- a/drivers/renesas/rcar/pwrc/pwrc.h
+++ b/drivers/renesas/rcar/pwrc/pwrc.h
@@ -44,6 +44,7 @@
void rcar_pwrc_clusteroff(uint64_t mpidr);
void rcar_pwrc_cpuoff(uint64_t mpidr);
void rcar_pwrc_cpuon(uint64_t mpidr);
+int32_t rcar_pwrc_cpu_on_check(uint64_t mpidr);
void rcar_pwrc_setup(void);
uint32_t rcar_pwrc_get_cpu_wkr(uint64_t mpidr);
diff --git a/drivers/rpi3/gpio/rpi3_gpio.c b/drivers/rpi3/gpio/rpi3_gpio.c
new file mode 100644
index 0000000..b39808f
--- /dev/null
+++ b/drivers/rpi3/gpio/rpi3_gpio.c
@@ -0,0 +1,169 @@
+/*
+ * Copyright (c) 2019, Linaro Limited
+ * Copyright (c) 2019, Ying-Chun Liu (PaulLiu) <paul.liu@linaro.org>
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <string.h>
+#include <assert.h>
+#include <lib/mmio.h>
+#include <drivers/delay_timer.h>
+#include <drivers/rpi3/gpio/rpi3_gpio.h>
+
+static struct rpi3_gpio_params rpi3_gpio_params;
+
+static int rpi3_gpio_get_direction(int gpio);
+static void rpi3_gpio_set_direction(int gpio, int direction);
+static int rpi3_gpio_get_value(int gpio);
+static void rpi3_gpio_set_value(int gpio, int value);
+static void rpi3_gpio_set_pull(int gpio, int pull);
+
+static const gpio_ops_t rpi3_gpio_ops = {
+ .get_direction = rpi3_gpio_get_direction,
+ .set_direction = rpi3_gpio_set_direction,
+ .get_value = rpi3_gpio_get_value,
+ .set_value = rpi3_gpio_set_value,
+ .set_pull = rpi3_gpio_set_pull,
+};
+
+/**
+ * Get selection of GPIO pinmux settings.
+ *
+ * @param gpio The pin number of GPIO. From 0 to 53.
+ * @return The selection of pinmux. RPI3_GPIO_FUNC_INPUT: input,
+ * RPI3_GPIO_FUNC_OUTPUT: output,
+ * RPI3_GPIO_FUNC_ALT0: alt-0,
+ * RPI3_GPIO_FUNC_ALT1: alt-1,
+ * RPI3_GPIO_FUNC_ALT2: alt-2,
+ * RPI3_GPIO_FUNC_ALT3: alt-3,
+ * RPI3_GPIO_FUNC_ALT4: alt-4,
+ * RPI3_GPIO_FUNC_ALT5: alt-5
+ */
+int rpi3_gpio_get_select(int gpio)
+{
+ int ret;
+ uintptr_t reg_base = rpi3_gpio_params.reg_base;
+ int regN = gpio / 10;
+ int shift = 3 * (gpio % 10);
+ uintptr_t reg_sel = reg_base + RPI3_GPIO_GPFSEL(regN);
+ uint32_t sel = mmio_read_32(reg_sel);
+
+ ret = (sel >> shift) & 0x07;
+
+ return ret;
+}
+
+/**
+ * Set selection of GPIO pinmux settings.
+ *
+ * @param gpio The pin number of GPIO. From 0 to 53.
+ * @param fsel The selection of pinmux. RPI3_GPIO_FUNC_INPUT: input,
+ * RPI3_GPIO_FUNC_OUTPUT: output,
+ * RPI3_GPIO_FUNC_ALT0: alt-0,
+ * RPI3_GPIO_FUNC_ALT1: alt-1,
+ * RPI3_GPIO_FUNC_ALT2: alt-2,
+ * RPI3_GPIO_FUNC_ALT3: alt-3,
+ * RPI3_GPIO_FUNC_ALT4: alt-4,
+ * RPI3_GPIO_FUNC_ALT5: alt-5
+ */
+void rpi3_gpio_set_select(int gpio, int fsel)
+{
+ uintptr_t reg_base = rpi3_gpio_params.reg_base;
+ int regN = gpio / 10;
+ int shift = 3 * (gpio % 10);
+ uintptr_t reg_sel = reg_base + RPI3_GPIO_GPFSEL(regN);
+ uint32_t sel = mmio_read_32(reg_sel);
+ uint32_t mask = U(0x07) << shift;
+
+ sel = (sel & (~mask)) | ((fsel << shift) & mask);
+ mmio_write_32(reg_sel, sel);
+}
+
+static int rpi3_gpio_get_direction(int gpio)
+{
+ int result = rpi3_gpio_get_select(gpio);
+
+ if (result == RPI3_GPIO_FUNC_INPUT)
+ return GPIO_DIR_IN;
+ else if (result == RPI3_GPIO_FUNC_OUTPUT)
+ return GPIO_DIR_OUT;
+
+ return GPIO_DIR_IN;
+}
+
+static void rpi3_gpio_set_direction(int gpio, int direction)
+{
+ switch (direction) {
+ case GPIO_DIR_IN:
+ rpi3_gpio_set_select(gpio, RPI3_GPIO_FUNC_INPUT);
+ break;
+ case GPIO_DIR_OUT:
+ rpi3_gpio_set_select(gpio, RPI3_GPIO_FUNC_OUTPUT);
+ break;
+ }
+}
+
+static int rpi3_gpio_get_value(int gpio)
+{
+ uintptr_t reg_base = rpi3_gpio_params.reg_base;
+ int regN = gpio / 32;
+ int shift = gpio % 32;
+ uintptr_t reg_lev = reg_base + RPI3_GPIO_GPLEV(regN);
+ uint32_t value = mmio_read_32(reg_lev);
+
+ if ((value >> shift) & 0x01)
+ return GPIO_LEVEL_HIGH;
+ return GPIO_LEVEL_LOW;
+}
+
+static void rpi3_gpio_set_value(int gpio, int value)
+{
+ uintptr_t reg_base = rpi3_gpio_params.reg_base;
+ int regN = gpio / 32;
+ int shift = gpio % 32;
+ uintptr_t reg_set = reg_base + RPI3_GPIO_GPSET(regN);
+ uintptr_t reg_clr = reg_base + RPI3_GPIO_GPSET(regN);
+
+ switch (value) {
+ case GPIO_LEVEL_LOW:
+ mmio_write_32(reg_clr, U(1) << shift);
+ break;
+ case GPIO_LEVEL_HIGH:
+ mmio_write_32(reg_set, U(1) << shift);
+ break;
+ }
+}
+
+static void rpi3_gpio_set_pull(int gpio, int pull)
+{
+ uintptr_t reg_base = rpi3_gpio_params.reg_base;
+ int regN = gpio / 32;
+ int shift = gpio % 32;
+ uintptr_t reg_pud = reg_base + RPI3_GPIO_GPPUD;
+ uintptr_t reg_clk = reg_base + RPI3_GPIO_GPPUDCLK(regN);
+
+ switch (pull) {
+ case GPIO_PULL_NONE:
+ mmio_write_32(reg_pud, 0x0);
+ break;
+ case GPIO_PULL_UP:
+ mmio_write_32(reg_pud, 0x2);
+ break;
+ case GPIO_PULL_DOWN:
+ mmio_write_32(reg_pud, 0x1);
+ break;
+ }
+ mdelay(150);
+ mmio_write_32(reg_clk, U(1) << shift);
+ mdelay(150);
+ mmio_write_32(reg_clk, 0x0);
+ mmio_write_32(reg_pud, 0x0);
+}
+
+void rpi3_gpio_init(struct rpi3_gpio_params *params)
+{
+ assert(params != 0);
+ memcpy(&rpi3_gpio_params, params, sizeof(struct rpi3_gpio_params));
+ gpio_init(&rpi3_gpio_ops);
+}
diff --git a/drivers/rpi3/sdhost/rpi3_sdhost.c b/drivers/rpi3/sdhost/rpi3_sdhost.c
new file mode 100644
index 0000000..efcd6db
--- /dev/null
+++ b/drivers/rpi3/sdhost/rpi3_sdhost.c
@@ -0,0 +1,689 @@
+/*
+ * Copyright (c) 2019, Linaro Limited
+ * Copyright (c) 2019, Ying-Chun Liu (PaulLiu) <paul.liu@linaro.org>
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <arch.h>
+#include <arch_helpers.h>
+#include <assert.h>
+#include <common/debug.h>
+#include <lib/mmio.h>
+#include <drivers/delay_timer.h>
+#include <drivers/rpi3/sdhost/rpi3_sdhost.h>
+#include <drivers/mmc.h>
+#include <drivers/rpi3/gpio/rpi3_gpio.h>
+#include <errno.h>
+#include <string.h>
+
+static void rpi3_sdhost_initialize(void);
+static int rpi3_sdhost_send_cmd(struct mmc_cmd *cmd);
+static int rpi3_sdhost_set_ios(unsigned int clk, unsigned int width);
+static int rpi3_sdhost_prepare(int lba, uintptr_t buf, size_t size);
+static int rpi3_sdhost_read(int lba, uintptr_t buf, size_t size);
+static int rpi3_sdhost_write(int lba, uintptr_t buf, size_t size);
+
+static const struct mmc_ops rpi3_sdhost_ops = {
+ .init = rpi3_sdhost_initialize,
+ .send_cmd = rpi3_sdhost_send_cmd,
+ .set_ios = rpi3_sdhost_set_ios,
+ .prepare = rpi3_sdhost_prepare,
+ .read = rpi3_sdhost_read,
+ .write = rpi3_sdhost_write,
+};
+
+static struct rpi3_sdhost_params rpi3_sdhost_params;
+
+/**
+ * Wait for command being processed.
+ *
+ * This function waits the command being processed. It compares
+ * the ENABLE flag of the HC_COMMAND register. When ENABLE flag disappeared
+ * it means the command is processed by the SDHOST.
+ * The timeout is currently 1000*100 us = 100 ms.
+ *
+ * @return 0: command finished. 1: command timed out.
+ */
+static int rpi3_sdhost_waitcommand(void)
+{
+ uintptr_t reg_base = rpi3_sdhost_params.reg_base;
+
+ volatile int timeout = 1000;
+
+ while ((mmio_read_32(reg_base + HC_COMMAND) & HC_CMD_ENABLE)
+ && (--timeout > 0)) {
+ udelay(100);
+ }
+
+ return ((timeout > 0) ? 0 : (-(ETIMEDOUT)));
+}
+
+/**
+ * Send the command and argument to the SDHOST
+ *
+ * This function will wait for the previous command finished. And then
+ * clear any error status of previous command. And then
+ * send out the command and args. The command will be turned on the ENABLE
+ * flag before sending out.
+ */
+static void send_command_raw(unsigned int cmd, unsigned int arg)
+{
+ unsigned int status;
+ uintptr_t reg_base = rpi3_sdhost_params.reg_base;
+
+ /* wait for previous command finish */
+ rpi3_sdhost_waitcommand();
+
+ /* clean error status */
+ status = mmio_read_32(reg_base + HC_HOSTSTATUS);
+ if (status & HC_HSTST_MASK_ERROR_ALL)
+ mmio_write_32(reg_base + HC_HOSTSTATUS, status);
+
+ /* recording the command */
+ rpi3_sdhost_params.current_cmd = cmd & HC_CMD_COMMAND_MASK;
+
+ /* send the argument and command */
+ mmio_write_32(reg_base + HC_ARGUMENT, arg);
+ mmio_write_32(reg_base + HC_COMMAND, cmd | HC_CMD_ENABLE);
+}
+
+/**
+ * Send the command and argument to the SDHOST, decorated with control
+ * flags.
+ *
+ * This function will use send_command_raw to send the commands to SDHOST.
+ * But before sending it will decorate the command with control flags specific
+ * to SDHOST.
+ */
+static void send_command_decorated(unsigned int cmd, unsigned int arg)
+{
+ unsigned int cmd_flags = 0;
+
+ switch (cmd & HC_CMD_COMMAND_MASK) {
+ case MMC_CMD(0):
+ cmd_flags |= HC_CMD_RESPONSE_NONE;
+ break;
+ case MMC_ACMD(51):
+ cmd_flags |= HC_CMD_READ;
+ break;
+ case MMC_CMD(8):
+ case MMC_CMD(11):
+ case MMC_CMD(17):
+ case MMC_CMD(18):
+ cmd_flags |= HC_CMD_READ;
+ break;
+ case MMC_CMD(20):
+ case MMC_CMD(24):
+ case MMC_CMD(25):
+ cmd_flags |= HC_CMD_WRITE;
+ break;
+ case MMC_CMD(12):
+ cmd_flags |= HC_CMD_BUSY;
+ break;
+ default:
+ break;
+ }
+ send_command_raw(cmd | cmd_flags, arg);
+}
+
+/**
+ * drains the FIFO on DATA port
+ *
+ * This function drains any data left in the DATA port.
+ */
+static void rpi3_drain_fifo(void)
+{
+ uintptr_t reg_base = rpi3_sdhost_params.reg_base;
+ volatile int timeout = 100000;
+
+ rpi3_sdhost_waitcommand();
+
+ while (mmio_read_32(reg_base + HC_HOSTSTATUS) & HC_HSTST_HAVEDATA) {
+ mmio_read_32(reg_base + HC_DATAPORT);
+ udelay(100);
+ }
+
+ while (1) {
+ uint32_t edm, fsm;
+
+ edm = mmio_read_32(reg_base + HC_DEBUG);
+ fsm = edm & HC_DBG_FSM_MASK;
+
+ if ((fsm == HC_DBG_FSM_IDENTMODE) ||
+ (fsm == HC_DBG_FSM_DATAMODE))
+ break;
+
+ if ((fsm == HC_DBG_FSM_READWAIT) ||
+ (fsm == HC_DBG_FSM_WRITESTART1) ||
+ (fsm == HC_DBG_FSM_READDATA)) {
+ mmio_write_32(reg_base + HC_DEBUG,
+ edm | HC_DBG_FORCE_DATA_MODE);
+ break;
+ }
+
+ if (--timeout <= 0) {
+ ERROR("rpi3_sdhost: %s cannot recover stat\n",
+ __func__);
+ return;
+ }
+ }
+}
+
+/**
+ * Dump SDHOST registers
+ */
+static void rpi3_sdhost_print_regs(void)
+{
+ uintptr_t reg_base = rpi3_sdhost_params.reg_base;
+
+ INFO("rpi3_sdhost: HC_COMMAND: 0x%08x\n",
+ mmio_read_32(reg_base + HC_COMMAND));
+ INFO("rpi3_sdhost: HC_ARGUMENT: 0x%08x\n",
+ mmio_read_32(reg_base + HC_ARGUMENT));
+ INFO("rpi3_sdhost: HC_TIMEOUTCOUNTER: 0x%08x\n",
+ mmio_read_32(reg_base + HC_TIMEOUTCOUNTER));
+ INFO("rpi3_sdhost: HC_CLOCKDIVISOR: 0x%08x\n",
+ mmio_read_32(reg_base + HC_CLOCKDIVISOR));
+ INFO("rpi3_sdhost: HC_RESPONSE_0: 0x%08x\n",
+ mmio_read_32(reg_base + HC_RESPONSE_0));
+ INFO("rpi3_sdhost: HC_RESPONSE_1: 0x%08x\n",
+ mmio_read_32(reg_base + HC_RESPONSE_1));
+ INFO("rpi3_sdhost: HC_RESPONSE_2: 0x%08x\n",
+ mmio_read_32(reg_base + HC_RESPONSE_2));
+ INFO("rpi3_sdhost: HC_RESPONSE_3: 0x%08x\n",
+ mmio_read_32(reg_base + HC_RESPONSE_3));
+ INFO("rpi3_sdhost: HC_HOSTSTATUS: 0x%08x\n",
+ mmio_read_32(reg_base + HC_HOSTSTATUS));
+ INFO("rpi3_sdhost: HC_POWER: 0x%08x\n",
+ mmio_read_32(reg_base + HC_POWER));
+ INFO("rpi3_sdhost: HC_DEBUG: 0x%08x\n",
+ mmio_read_32(reg_base + HC_DEBUG));
+ INFO("rpi3_sdhost: HC_HOSTCONFIG: 0x%08x\n",
+ mmio_read_32(reg_base + HC_HOSTCONFIG));
+ INFO("rpi3_sdhost: HC_BLOCKSIZE: 0x%08x\n",
+ mmio_read_32(reg_base + HC_BLOCKSIZE));
+ INFO("rpi3_sdhost: HC_BLOCKCOUNT: 0x%08x\n",
+ mmio_read_32(reg_base + HC_BLOCKCOUNT));
+}
+
+/**
+ * Reset SDHOST
+ */
+static void rpi3_sdhost_reset(void)
+{
+ uintptr_t reg_base = rpi3_sdhost_params.reg_base;
+ unsigned int dbg;
+ uint32_t tmp1;
+
+ mmio_write_32(reg_base + HC_POWER, 0);
+ mmio_write_32(reg_base + HC_COMMAND, 0);
+ mmio_write_32(reg_base + HC_ARGUMENT, 0);
+
+ mmio_write_32(reg_base + HC_TIMEOUTCOUNTER, HC_TIMEOUT_DEFAULT);
+ mmio_write_32(reg_base + HC_CLOCKDIVISOR, 0);
+ mmio_write_32(reg_base + HC_HOSTSTATUS, HC_HSTST_RESET);
+ mmio_write_32(reg_base + HC_HOSTCONFIG, 0);
+ mmio_write_32(reg_base + HC_BLOCKSIZE, 0);
+ mmio_write_32(reg_base + HC_BLOCKCOUNT, 0);
+
+ dbg = mmio_read_32(reg_base + HC_DEBUG);
+ dbg &= ~((HC_DBG_FIFO_THRESH_MASK << HC_DBG_FIFO_THRESH_READ_SHIFT) |
+ (HC_DBG_FIFO_THRESH_MASK << HC_DBG_FIFO_THRESH_WRITE_SHIFT));
+ dbg |= (HC_FIFO_THRESH_READ << HC_DBG_FIFO_THRESH_READ_SHIFT) |
+ (HC_FIFO_THRESH_WRITE << HC_DBG_FIFO_THRESH_WRITE_SHIFT);
+ mmio_write_32(reg_base + HC_DEBUG, dbg);
+ mdelay(250);
+ mmio_write_32(reg_base + HC_POWER, 1);
+ mdelay(250);
+ rpi3_sdhost_params.clk_rate = 0;
+
+ mmio_write_32(reg_base + HC_CLOCKDIVISOR, HC_CLOCKDIVISOR_MAXVAL);
+ tmp1 = mmio_read_32(reg_base + HC_HOSTCONFIG);
+ mmio_write_32(reg_base + HC_HOSTCONFIG, tmp1 | HC_HSTCF_INT_BUSY);
+}
+
+static void rpi3_sdhost_initialize(void)
+{
+ uintptr_t reg_base = rpi3_sdhost_params.reg_base;
+
+ assert((rpi3_sdhost_params.reg_base & MMC_BLOCK_MASK) == 0);
+
+ rpi3_sdhost_reset();
+
+ mmio_write_32(reg_base + HC_CLOCKDIVISOR, HC_CLOCKDIVISOR_PREFERVAL);
+ udelay(300);
+}
+
+static int rpi3_sdhost_send_cmd(struct mmc_cmd *cmd)
+{
+ uintptr_t reg_base = rpi3_sdhost_params.reg_base;
+ int err = 0;
+ uint32_t cmd_idx;
+ uint32_t cmd_arg;
+ uint32_t cmd_flags = 0;
+ uint32_t intmask;
+
+ /* Wait for the command done */
+ err = rpi3_sdhost_waitcommand();
+ if (err != 0) {
+ WARN("previous command not done yet\n");
+ return err;
+ }
+
+ cmd_idx = cmd->cmd_idx & HC_CMD_COMMAND_MASK;
+ if (cmd_idx == MMC_CMD(17))
+ cmd_idx = MMC_CMD(18);
+
+ cmd_arg = cmd->cmd_arg;
+ if (cmd_idx == MMC_ACMD(51)) {
+ /* if previous cmd send to SDHOST is not MMC_CMD(55).
+ * It means this MMC_ACMD(51) is a resend.
+ * And we must also resend MMC_CMD(55) in this case
+ */
+ if (rpi3_sdhost_params.current_cmd != MMC_CMD(55)) {
+ send_command_decorated(
+ MMC_CMD(55),
+ rpi3_sdhost_params.sdcard_rca <<
+ RCA_SHIFT_OFFSET);
+ rpi3_sdhost_params.mmc_app_cmd = 1;
+ rpi3_sdhost_waitcommand();
+
+ /* Also we need to call prepare to clean the buffer */
+ rpi3_sdhost_prepare(0, (uintptr_t)NULL, 8);
+ }
+ }
+
+ /* We ignore MMC_CMD(12) sending from the TF-A's MMC driver
+ * because we send MMC_CMD(12) by ourselves.
+ */
+ if (cmd_idx == MMC_CMD(12))
+ return 0;
+
+ if ((cmd->resp_type & MMC_RSP_136) &&
+ (cmd->resp_type & MMC_RSP_BUSY)) {
+ ERROR("rpi3_sdhost: unsupported response type!\n");
+ return -(EOPNOTSUPP);
+ }
+
+ if (cmd->resp_type & MMC_RSP_48 && cmd->resp_type != MMC_RESPONSE_R2) {
+ /* 48-bit command
+ * We don't need to set any flags here because it is default.
+ */
+ } else if (cmd->resp_type & MMC_RSP_136) {
+ /* 136-bit command */
+ cmd_flags |= HC_CMD_RESPONSE_LONG;
+ } else {
+ /* no respond command */
+ cmd_flags |= HC_CMD_RESPONSE_NONE;
+ }
+
+ rpi3_sdhost_params.cmdbusy = 0;
+ if (cmd->resp_type & MMC_RSP_BUSY) {
+ cmd_flags |= HC_CMD_BUSY;
+ rpi3_sdhost_params.cmdbusy = 1;
+ }
+
+ if (rpi3_sdhost_params.mmc_app_cmd) {
+ switch (cmd_idx) {
+ case MMC_ACMD(41):
+ if (cmd_arg == OCR_HCS)
+ cmd_arg |= OCR_3_3_3_4;
+ break;
+ default:
+ break;
+ }
+ rpi3_sdhost_params.mmc_app_cmd = 0;
+ }
+
+ if (cmd_idx == MMC_CMD(55))
+ rpi3_sdhost_params.mmc_app_cmd = 1;
+
+ send_command_decorated(cmd_idx | cmd_flags, cmd_arg);
+
+ intmask = mmio_read_32(reg_base + HC_HOSTSTATUS);
+ if (rpi3_sdhost_params.cmdbusy && (intmask & HC_HSTST_INT_BUSY)) {
+ mmio_write_32(reg_base + HC_HOSTSTATUS, HC_HSTST_INT_BUSY);
+ rpi3_sdhost_params.cmdbusy = 0;
+ }
+
+ if (!(cmd_flags & HC_CMD_RESPONSE_NONE)) {
+ err = rpi3_sdhost_waitcommand();
+ if (err != 0)
+ ERROR("rpi3_sdhost: cmd cannot be finished\n");
+ }
+
+ cmd->resp_data[0] = mmio_read_32(reg_base + HC_RESPONSE_0);
+ cmd->resp_data[1] = mmio_read_32(reg_base + HC_RESPONSE_1);
+ cmd->resp_data[2] = mmio_read_32(reg_base + HC_RESPONSE_2);
+ cmd->resp_data[3] = mmio_read_32(reg_base + HC_RESPONSE_3);
+
+ if (mmio_read_32(reg_base + HC_COMMAND) & HC_CMD_FAILED) {
+ uint32_t sdhsts = mmio_read_32(reg_base + HC_HOSTSTATUS);
+
+ mmio_write_32(reg_base + HC_HOSTSTATUS,
+ HC_HSTST_MASK_ERROR_ALL);
+
+ if (!(sdhsts & HC_HSTST_ERROR_CRC7)
+ || (cmd_idx != MMC_ACMD(51))) {
+ if (sdhsts & HC_HSTST_TIMEOUT_CMD) {
+ ERROR("rpi3_sdhost: timeout status 0x%x\n",
+ sdhsts);
+ err = -(ETIMEDOUT);
+ } else {
+ ERROR("rpi3_sdhost: unknown err, cmd = 0x%x\n",
+ mmio_read_32(reg_base + HC_COMMAND));
+ ERROR("rpi3_sdhost status: 0x%x\n", sdhsts);
+ err = -(EILSEQ);
+ }
+ }
+ }
+
+ if ((!err) && (cmd_idx == MMC_CMD(3))) {
+ /* we keep the RCA in case to send MMC_CMD(55) ourselves */
+ rpi3_sdhost_params.sdcard_rca = (cmd->resp_data[0]
+ & 0xFFFF0000U) >> 16;
+ }
+
+ return err;
+}
+
+static int rpi3_sdhost_set_clock(unsigned int clk)
+{
+ uintptr_t reg_base = rpi3_sdhost_params.reg_base;
+ uint32_t max_clk = 250000000;
+ uint32_t div;
+
+ if (clk < 100000) {
+ mmio_write_32(reg_base + HC_CLOCKDIVISOR,
+ HC_CLOCKDIVISOR_MAXVAL);
+ return 0;
+ }
+
+ div = max_clk / clk;
+ if (div < 2)
+ div = 2;
+
+ if ((max_clk / div) > clk)
+ div++;
+
+ div -= 2;
+ if (div > HC_CLOCKDIVISOR_MAXVAL)
+ div = HC_CLOCKDIVISOR_MAXVAL;
+
+ rpi3_sdhost_params.clk_rate = max_clk / (div + 2);
+ rpi3_sdhost_params.ns_per_fifo_word = (1000000000 /
+ rpi3_sdhost_params.clk_rate)
+ * 8;
+
+ mmio_write_32(reg_base + HC_CLOCKDIVISOR, div);
+ return 0;
+}
+
+static int rpi3_sdhost_set_ios(unsigned int clk, unsigned int width)
+{
+ uintptr_t reg_base = rpi3_sdhost_params.reg_base;
+ uint32_t tmp1;
+
+ rpi3_sdhost_set_clock(clk);
+ VERBOSE("rpi3_sdhost: Changing clock to %dHz for data mode\n", clk);
+
+ if (width != MMC_BUS_WIDTH_4 && width != MMC_BUS_WIDTH_1) {
+ ERROR("rpi3_sdhost: width %d not supported\n", width);
+ return -(EOPNOTSUPP);
+ }
+ rpi3_sdhost_params.bus_width = width;
+
+ tmp1 = mmio_read_32(reg_base + HC_HOSTCONFIG);
+ tmp1 &= ~(HC_HSTCF_EXTBUS_4BIT);
+ if (rpi3_sdhost_params.bus_width == MMC_BUS_WIDTH_4)
+ tmp1 |= HC_HSTCF_EXTBUS_4BIT;
+
+ mmio_write_32(reg_base + HC_HOSTCONFIG, tmp1);
+ tmp1 = mmio_read_32(reg_base + HC_HOSTCONFIG);
+ mmio_write_32(reg_base + HC_HOSTCONFIG, tmp1 |
+ HC_HSTCF_SLOW_CARD | HC_HSTCF_INTBUS_WIDE);
+
+ return 0;
+}
+
+static int rpi3_sdhost_prepare(int lba, uintptr_t buf, size_t size)
+{
+ uintptr_t reg_base = rpi3_sdhost_params.reg_base;
+ size_t blocks;
+ size_t blocksize;
+
+ if (size < 512) {
+ blocksize = size;
+ blocks = 1;
+ } else {
+ blocksize = 512;
+ blocks = size / blocksize;
+ if (size % blocksize != 0)
+ blocks++;
+ }
+
+ rpi3_drain_fifo();
+
+ mmio_write_32(reg_base + HC_BLOCKSIZE, blocksize);
+ mmio_write_32(reg_base + HC_BLOCKCOUNT, blocks);
+ udelay(100);
+ return 0;
+}
+
+static int rpi3_sdhost_read(int lba, uintptr_t buf, size_t size)
+{
+ int err = 0;
+ uint32_t *buf1 = ((uint32_t *) buf);
+ uintptr_t reg_base = rpi3_sdhost_params.reg_base;
+ int timeout = 100000;
+ int remaining_words = 0;
+
+ for (int i = 0; i < size / 4; i++) {
+ volatile int t = timeout;
+ uint32_t hsts_err;
+
+ while ((mmio_read_32(reg_base + HC_HOSTSTATUS)
+ & HC_HSTST_HAVEDATA) == 0) {
+ if (t == 0) {
+ ERROR("rpi3_sdhost: fifo timeout after %dus\n",
+ timeout);
+ err = -(ETIMEDOUT);
+ break;
+ }
+ t--;
+ udelay(10);
+ }
+ if (t == 0)
+ break;
+
+ uint32_t data = mmio_read_32(reg_base + HC_DATAPORT);
+
+ hsts_err = mmio_read_32(reg_base + HC_HOSTSTATUS)
+ & HC_HSTST_MASK_ERROR_ALL;
+ if (hsts_err) {
+ ERROR("rpi3_sdhost: transfer FIFO word %d: 0x%x\n",
+ i,
+ mmio_read_32(reg_base + HC_HOSTSTATUS));
+ rpi3_sdhost_print_regs();
+
+ err = -(EILSEQ);
+
+ /* clean the error status */
+ mmio_write_32(reg_base + HC_HOSTSTATUS, hsts_err);
+ }
+
+ if (buf1)
+ buf1[i] = data;
+
+ /* speeding up if the remaining words are still a lot */
+ remaining_words = (mmio_read_32(reg_base + HC_DEBUG) >> 4)
+ & HC_DBG_FIFO_THRESH_MASK;
+ if (remaining_words >= 7)
+ continue;
+
+ /* delay. slowing down the read process */
+ udelay(100);
+ }
+
+ /* We decide to stop by ourselves.
+ * It is because MMC_CMD(18) -> MMC_CMD(13) -> MMC_CMD(12)
+ * doesn't work for RPi3 SDHost.
+ */
+ if (rpi3_sdhost_params.current_cmd == MMC_CMD(18))
+ send_command_decorated(MMC_CMD(12), 0);
+
+ if (err == -(EILSEQ)) {
+ const int max_retries = 20;
+ int r;
+
+ rpi3_sdhost_params.crc_err_retries++;
+ if (rpi3_sdhost_params.crc_err_retries < max_retries) {
+ /* retries if there's an CRC error */
+ r = rpi3_sdhost_prepare(lba, buf, size);
+ send_command_decorated(MMC_CMD(18), lba);
+ r = rpi3_sdhost_read(lba, buf, size);
+ if (r == 0)
+ err = 0;
+ }
+ }
+
+ return err;
+}
+
+static int rpi3_sdhost_write(int lba, uintptr_t buf, size_t size)
+{
+ uint32_t *buf1 = ((uint32_t *) buf);
+ uintptr_t reg_base = rpi3_sdhost_params.reg_base;
+ int err = 0;
+ int remaining_words = 0;
+
+ for (int i = 0; i < size / 4; i++) {
+ uint32_t hsts_err;
+ uint32_t data = buf1[i];
+ uint32_t dbg;
+ uint32_t fsm_state;
+
+ mmio_write_32(reg_base + HC_DATAPORT, data);
+
+ dbg = mmio_read_32(reg_base + HC_DEBUG);
+ fsm_state = dbg & HC_DBG_FSM_MASK;
+ if (fsm_state != HC_DBG_FSM_WRITEDATA
+ && fsm_state != HC_DBG_FSM_WRITESTART1
+ && fsm_state != HC_DBG_FSM_WRITESTART2
+ && fsm_state != HC_DBG_FSM_WRITECRC
+ && fsm_state != HC_DBG_FSM_WRITEWAIT1
+ && fsm_state != HC_DBG_FSM_WRITEWAIT2) {
+ hsts_err = mmio_read_32(reg_base + HC_HOSTSTATUS)
+ & HC_HSTST_MASK_ERROR_ALL;
+ if (hsts_err)
+ err = -(EILSEQ);
+ }
+
+ /* speeding up if the remaining words are not many */
+ remaining_words = (mmio_read_32(reg_base + HC_DEBUG) >> 4)
+ & HC_DBG_FIFO_THRESH_MASK;
+ if (remaining_words <= 4)
+ continue;
+
+ udelay(100);
+ }
+
+ /* We decide to stop by ourselves.
+ * It is because MMC_CMD(25) -> MMC_CMD(13) -> MMC_CMD(12)
+ * doesn't work for RPi3 SDHost.
+ */
+ if (rpi3_sdhost_params.current_cmd == MMC_CMD(25))
+ send_command_decorated(MMC_CMD(12), 0);
+
+ return err;
+}
+
+void rpi3_sdhost_init(struct rpi3_sdhost_params *params,
+ struct mmc_device_info *mmc_dev_info)
+{
+ assert((params != 0) &&
+ ((params->reg_base & MMC_BLOCK_MASK) == 0));
+
+ memcpy(&rpi3_sdhost_params, params, sizeof(struct rpi3_sdhost_params));
+
+ /* backup GPIO 48 to 53 configurations */
+ for (int i = 48; i <= 53; i++) {
+ rpi3_sdhost_params.gpio48_pinselect[i - 48]
+ = rpi3_gpio_get_select(i);
+ VERBOSE("rpi3_sdhost: Original GPIO state %d: %d\n",
+ i,
+ rpi3_sdhost_params.gpio48_pinselect[i - 48]);
+ }
+
+ /* setting pull resistors for 48 to 53.
+ * GPIO 48 (SD_CLK) to GPIO_PULL_UP
+ * GPIO 49 (SD_CMD) to GPIO_PULL_NONE
+ * GPIO 50 (SD_D0) to GPIO_PULL_NONE
+ * GPIO 51 (SD_D1) to GPIO_PULL_NONE
+ * GPIO 52 (SD_D2) to GPIO_PULL_NONE
+ * GPIO 53 (SD_D3) to GPIO_PULL_NONE
+ */
+ gpio_set_pull(48, GPIO_PULL_UP);
+ for (int i = 49; i <= 53; i++)
+ gpio_set_pull(i, GPIO_PULL_NONE);
+
+ /* Set pin 48-53 to alt-0. It means route SDHOST to card slot */
+ for (int i = 48; i <= 53; i++)
+ rpi3_gpio_set_select(i, RPI3_GPIO_FUNC_ALT0);
+
+ mmc_init(&rpi3_sdhost_ops, params->clk_rate, params->bus_width,
+ params->flags, mmc_dev_info);
+}
+
+void rpi3_sdhost_stop(void)
+{
+ uintptr_t reg_base = rpi3_sdhost_params.reg_base;
+
+ VERBOSE("rpi3_sdhost: Shutting down: drain FIFO out\n");
+ rpi3_drain_fifo();
+
+ VERBOSE("rpi3_sdhost: Shutting down: slowing down the clock\n");
+ mmio_write_32(reg_base+HC_CLOCKDIVISOR, HC_CLOCKDIVISOR_SLOWVAL);
+ udelay(500);
+
+ VERBOSE("rpi3_sdhost: Shutting down: put SDHost into idle state\n");
+ send_command_decorated(MMC_CMD(0), 0);
+ udelay(500);
+
+ mmio_write_32(reg_base + HC_COMMAND, 0);
+ mmio_write_32(reg_base + HC_ARGUMENT, 0);
+ mmio_write_32(reg_base + HC_TIMEOUTCOUNTER, HC_TIMEOUT_IDLE);
+ mmio_write_32(reg_base + HC_CLOCKDIVISOR, HC_CLOCKDIVISOR_STOPVAL);
+
+ udelay(100);
+
+ mmio_write_32(reg_base + HC_POWER, 0);
+ mmio_write_32(reg_base + HC_HOSTCONFIG, 0);
+ mmio_write_32(reg_base + HC_BLOCKSIZE, 0x400);
+ mmio_write_32(reg_base + HC_BLOCKCOUNT, 0);
+ mmio_write_32(reg_base + HC_HOSTSTATUS, 0x7f8);
+
+ mmio_write_32(reg_base + HC_COMMAND, 0);
+ mmio_write_32(reg_base + HC_ARGUMENT, 0);
+
+ udelay(100);
+
+ /* Restore the pinmux to original state */
+ for (int i = 48; i <= 53; i++) {
+ rpi3_gpio_set_select(i,
+ rpi3_sdhost_params.gpio48_pinselect[i-48]);
+ }
+
+ /* Must reset the pull resistors for u-boot to work.
+ * GPIO 48 (SD_CLK) to GPIO_PULL_NONE
+ * GPIO 49 (SD_CMD) to GPIO_PULL_UP
+ * GPIO 50 (SD_D0) to GPIO_PULL_UP
+ * GPIO 51 (SD_D1) to GPIO_PULL_UP
+ * GPIO 52 (SD_D2) to GPIO_PULL_UP
+ * GPIO 53 (SD_D3) to GPIO_PULL_UP
+ */
+ gpio_set_pull(48, GPIO_PULL_NONE);
+ for (int i = 49; i <= 53; i++)
+ gpio_set_pull(i, GPIO_PULL_UP);
+}
diff --git a/drivers/st/bsec/bsec.c b/drivers/st/bsec/bsec.c
new file mode 100644
index 0000000..aaecf1f
--- /dev/null
+++ b/drivers/st/bsec/bsec.c
@@ -0,0 +1,913 @@
+/*
+ * Copyright (c) 2017-2019, STMicroelectronics - All Rights Reserved
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <assert.h>
+#include <limits.h>
+
+#include <libfdt.h>
+
+#include <platform_def.h>
+
+#include <arch_helpers.h>
+#include <common/debug.h>
+#include <drivers/st/bsec.h>
+#include <lib/mmio.h>
+#include <lib/spinlock.h>
+
+#define BSEC_IP_VERSION_1_0 0x10
+#define BSEC_COMPAT "st,stm32mp15-bsec"
+
+#define OTP_ACCESS_SIZE (round_up(OTP_MAX_SIZE, __WORD_BIT) / __WORD_BIT)
+
+static uint32_t otp_nsec_access[OTP_ACCESS_SIZE] __unused;
+
+static uint32_t bsec_power_safmem(bool power);
+
+/* BSEC access protection */
+static spinlock_t bsec_spinlock;
+static uintptr_t bsec_base;
+
+static void bsec_lock(void)
+{
+ const uint32_t mask = SCTLR_M_BIT | SCTLR_C_BIT;
+
+ /* Lock is currently required only when MMU and cache are enabled */
+ if ((read_sctlr() & mask) == mask) {
+ spin_lock(&bsec_spinlock);
+ }
+}
+
+static void bsec_unlock(void)
+{
+ const uint32_t mask = SCTLR_M_BIT | SCTLR_C_BIT;
+
+ /* Unlock is required only when MMU and cache are enabled */
+ if ((read_sctlr() & mask) == mask) {
+ spin_unlock(&bsec_spinlock);
+ }
+}
+
+static int bsec_get_dt_node(struct dt_node_info *info)
+{
+ int node;
+
+ node = dt_get_node(info, -1, BSEC_COMPAT);
+ if (node < 0) {
+ return -FDT_ERR_NOTFOUND;
+ }
+
+ return node;
+}
+
+#if defined(IMAGE_BL32)
+static void enable_non_secure_access(uint32_t otp)
+{
+ otp_nsec_access[otp / __WORD_BIT] |= BIT(otp % __WORD_BIT);
+
+ if (bsec_shadow_register(otp) != BSEC_OK) {
+ panic();
+ }
+}
+
+static bool non_secure_can_access(uint32_t otp)
+{
+ return (otp_nsec_access[otp / __WORD_BIT] &
+ BIT(otp % __WORD_BIT)) != 0;
+}
+
+static int bsec_dt_otp_nsec_access(void *fdt, int bsec_node)
+{
+ int bsec_subnode;
+
+ fdt_for_each_subnode(bsec_subnode, fdt, bsec_node) {
+ const fdt32_t *cuint;
+ uint32_t reg;
+ uint32_t i;
+ uint32_t size;
+ uint8_t status;
+
+ cuint = fdt_getprop(fdt, bsec_subnode, "reg", NULL);
+ if (cuint == NULL) {
+ panic();
+ }
+
+ reg = fdt32_to_cpu(*cuint) / sizeof(uint32_t);
+ if (reg < STM32MP1_UPPER_OTP_START) {
+ continue;
+ }
+
+ status = fdt_get_status(bsec_subnode);
+ if ((status & DT_NON_SECURE) == 0U) {
+ continue;
+ }
+
+ size = fdt32_to_cpu(*(cuint + 1)) / sizeof(uint32_t);
+
+ if ((fdt32_to_cpu(*(cuint + 1)) % sizeof(uint32_t)) != 0) {
+ size++;
+ }
+
+ for (i = reg; i < (reg + size); i++) {
+ enable_non_secure_access(i);
+ }
+ }
+
+ return 0;
+}
+#endif
+
+static uint32_t otp_bank_offset(uint32_t otp)
+{
+ assert(otp <= STM32MP1_OTP_MAX_ID);
+
+ return ((otp & ~BSEC_OTP_MASK) >> BSEC_OTP_BANK_SHIFT) *
+ sizeof(uint32_t);
+}
+
+static uint32_t bsec_check_error(uint32_t otp)
+{
+ uint32_t bit = BIT(otp & BSEC_OTP_MASK);
+ uint32_t bank = otp_bank_offset(otp);
+
+ if ((mmio_read_32(bsec_base + BSEC_DISTURBED_OFF + bank) & bit) != 0U) {
+ return BSEC_DISTURBED;
+ }
+
+ if ((mmio_read_32(bsec_base + BSEC_ERROR_OFF + bank) & bit) != 0U) {
+ return BSEC_ERROR;
+ }
+
+ return BSEC_OK;
+}
+
+/*
+ * bsec_probe: initialize BSEC driver.
+ * return value: BSEC_OK if no error.
+ */
+uint32_t bsec_probe(void)
+{
+ void *fdt;
+ int node;
+ struct dt_node_info bsec_info;
+
+ if (fdt_get_address(&fdt) == 0) {
+ panic();
+ }
+
+ node = bsec_get_dt_node(&bsec_info);
+ if (node < 0) {
+ panic();
+ }
+
+ bsec_base = bsec_info.base;
+
+#if defined(IMAGE_BL32)
+ bsec_dt_otp_nsec_access(fdt, node);
+#endif
+ return BSEC_OK;
+}
+
+/*
+ * bsec_get_base: return BSEC base address.
+ */
+uint32_t bsec_get_base(void)
+{
+ return bsec_base;
+}
+
+/*
+ * bsec_set_config: enable and configure BSEC.
+ * cfg: pointer to param structure used to set register.
+ * return value: BSEC_OK if no error.
+ */
+uint32_t bsec_set_config(struct bsec_config *cfg)
+{
+ uint32_t value;
+ int32_t result;
+
+ value = ((((uint32_t)cfg->freq << BSEC_CONF_FRQ_SHIFT) &
+ BSEC_CONF_FRQ_MASK) |
+ (((uint32_t)cfg->pulse_width << BSEC_CONF_PRG_WIDTH_SHIFT) &
+ BSEC_CONF_PRG_WIDTH_MASK) |
+ (((uint32_t)cfg->tread << BSEC_CONF_TREAD_SHIFT) &
+ BSEC_CONF_TREAD_MASK));
+
+ bsec_lock();
+
+ mmio_write_32(bsec_base + BSEC_OTP_CONF_OFF, value);
+
+ bsec_unlock();
+
+ result = bsec_power_safmem((bool)cfg->power &
+ BSEC_CONF_POWER_UP_MASK);
+ if (result != BSEC_OK) {
+ return result;
+ }
+
+ value = ((((uint32_t)cfg->upper_otp_lock << UPPER_OTP_LOCK_SHIFT) &
+ UPPER_OTP_LOCK_MASK) |
+ (((uint32_t)cfg->den_lock << DENREG_LOCK_SHIFT) &
+ DENREG_LOCK_MASK) |
+ (((uint32_t)cfg->prog_lock << GPLOCK_LOCK_SHIFT) &
+ GPLOCK_LOCK_MASK));
+
+ bsec_lock();
+
+ mmio_write_32(bsec_base + BSEC_OTP_LOCK_OFF, value);
+
+ bsec_unlock();
+
+ return BSEC_OK;
+}
+
+/*
+ * bsec_get_config: return config parameters set in BSEC registers.
+ * cfg: config param return.
+ * return value: BSEC_OK if no error.
+ */
+uint32_t bsec_get_config(struct bsec_config *cfg)
+{
+ uint32_t value;
+
+ if (cfg == NULL) {
+ return BSEC_INVALID_PARAM;
+ }
+
+ value = mmio_read_32(bsec_base + BSEC_OTP_CONF_OFF);
+ cfg->power = (uint8_t)((value & BSEC_CONF_POWER_UP_MASK) >>
+ BSEC_CONF_POWER_UP_SHIFT);
+ cfg->freq = (uint8_t)((value & BSEC_CONF_FRQ_MASK) >>
+ BSEC_CONF_FRQ_SHIFT);
+ cfg->pulse_width = (uint8_t)((value & BSEC_CONF_PRG_WIDTH_MASK) >>
+ BSEC_CONF_PRG_WIDTH_SHIFT);
+ cfg->tread = (uint8_t)((value & BSEC_CONF_TREAD_MASK) >>
+ BSEC_CONF_TREAD_SHIFT);
+
+ value = mmio_read_32(bsec_base + BSEC_OTP_LOCK_OFF);
+ cfg->upper_otp_lock = (uint8_t)((value & UPPER_OTP_LOCK_MASK) >>
+ UPPER_OTP_LOCK_SHIFT);
+ cfg->den_lock = (uint8_t)((value & DENREG_LOCK_MASK) >>
+ DENREG_LOCK_SHIFT);
+ cfg->prog_lock = (uint8_t)((value & GPLOCK_LOCK_MASK) >>
+ GPLOCK_LOCK_SHIFT);
+
+ return BSEC_OK;
+}
+
+/*
+ * bsec_shadow_register: copy SAFMEM OTP to BSEC data.
+ * otp: OTP number.
+ * return value: BSEC_OK if no error.
+ */
+uint32_t bsec_shadow_register(uint32_t otp)
+{
+ uint32_t result;
+ bool power_up = false;
+
+ if (otp > STM32MP1_OTP_MAX_ID) {
+ return BSEC_INVALID_PARAM;
+ }
+
+ /* Check if shadowing of OTP is locked */
+ if (bsec_read_sr_lock(otp)) {
+ VERBOSE("BSEC: OTP %i is locked and will not be refreshed\n",
+ otp);
+ }
+
+ if ((bsec_get_status() & BSEC_MODE_PWR_MASK) == 0U) {
+ result = bsec_power_safmem(true);
+
+ if (result != BSEC_OK) {
+ return result;
+ }
+
+ power_up = true;
+ }
+
+ bsec_lock();
+
+ /* Set BSEC_OTP_CTRL_OFF and set ADDR with the OTP value */
+ mmio_write_32(bsec_base + BSEC_OTP_CTRL_OFF, otp | BSEC_READ);
+
+ while ((bsec_get_status() & BSEC_MODE_BUSY_MASK) != 0U) {
+ ;
+ }
+
+ result = bsec_check_error(otp);
+
+ bsec_unlock();
+
+ if (power_up) {
+ if (bsec_power_safmem(false) != BSEC_OK) {
+ panic();
+ }
+ }
+
+ return result;
+}
+
+/*
+ * bsec_read_otp: read an OTP data value.
+ * val: read value.
+ * otp: OTP number.
+ * return value: BSEC_OK if no error.
+ */
+uint32_t bsec_read_otp(uint32_t *val, uint32_t otp)
+{
+ uint32_t result;
+
+ if (otp > STM32MP1_OTP_MAX_ID) {
+ return BSEC_INVALID_PARAM;
+ }
+
+ bsec_lock();
+
+ *val = mmio_read_32(bsec_base + BSEC_OTP_DATA_OFF +
+ (otp * sizeof(uint32_t)));
+
+ result = bsec_check_error(otp);
+
+ bsec_unlock();
+
+ return result;
+}
+
+/*
+ * bsec_write_otp: write value in BSEC data register.
+ * val: value to write.
+ * otp: OTP number.
+ * return value: BSEC_OK if no error.
+ */
+uint32_t bsec_write_otp(uint32_t val, uint32_t otp)
+{
+ uint32_t result;
+
+ if (otp > STM32MP1_OTP_MAX_ID) {
+ return BSEC_INVALID_PARAM;
+ }
+
+ /* Check if programming of OTP is locked */
+ if (bsec_read_sw_lock(otp)) {
+ VERBOSE("BSEC: OTP %i is locked and write will be ignored\n",
+ otp);
+ }
+
+ bsec_lock();
+
+ mmio_write_32(bsec_base + BSEC_OTP_DATA_OFF +
+ (otp * sizeof(uint32_t)), val);
+
+ result = bsec_check_error(otp);
+
+ bsec_unlock();
+
+ return result;
+}
+
+/*
+ * bsec_program_otp: program a bit in SAFMEM after the prog.
+ * The OTP data is not refreshed.
+ * val: value to program.
+ * otp: OTP number.
+ * return value: BSEC_OK if no error.
+ */
+uint32_t bsec_program_otp(uint32_t val, uint32_t otp)
+{
+ uint32_t result;
+ bool power_up = false;
+
+ if (otp > STM32MP1_OTP_MAX_ID) {
+ return BSEC_INVALID_PARAM;
+ }
+
+ /* Check if programming of OTP is locked */
+ if (bsec_read_sp_lock(otp)) {
+ WARN("BSEC: OTP locked, prog will be ignored\n");
+ }
+
+ if ((mmio_read_32(bsec_base + BSEC_OTP_LOCK_OFF) &
+ BIT(BSEC_LOCK_PROGRAM)) != 0U) {
+ WARN("BSEC: GPLOCK activated, prog will be ignored\n");
+ }
+
+ if ((bsec_get_status() & BSEC_MODE_PWR_MASK) == 0U) {
+ result = bsec_power_safmem(true);
+
+ if (result != BSEC_OK) {
+ return result;
+ }
+
+ power_up = true;
+ }
+
+ bsec_lock();
+
+ /* Set value in write register */
+ mmio_write_32(bsec_base + BSEC_OTP_WRDATA_OFF, val);
+
+ /* Set BSEC_OTP_CTRL_OFF and set ADDR with the OTP value */
+ mmio_write_32(bsec_base + BSEC_OTP_CTRL_OFF, otp | BSEC_WRITE);
+
+ while ((bsec_get_status() & BSEC_MODE_BUSY_MASK) != 0U) {
+ ;
+ }
+
+ if ((bsec_get_status() & BSEC_MODE_PROGFAIL_MASK) != 0U) {
+ result = BSEC_PROG_FAIL;
+ } else {
+ result = bsec_check_error(otp);
+ }
+
+ bsec_unlock();
+
+ if (power_up) {
+ if (bsec_power_safmem(false) != BSEC_OK) {
+ panic();
+ }
+ }
+
+ return result;
+}
+
+/*
+ * bsec_permanent_lock_otp: permanent lock of OTP in SAFMEM.
+ * otp: OTP number.
+ * return value: BSEC_OK if no error.
+ */
+uint32_t bsec_permanent_lock_otp(uint32_t otp)
+{
+ uint32_t result;
+ bool power_up = false;
+ uint32_t data;
+ uint32_t addr;
+
+ if (otp > STM32MP1_OTP_MAX_ID) {
+ return BSEC_INVALID_PARAM;
+ }
+
+ if ((bsec_get_status() & BSEC_MODE_PWR_MASK) == 0U) {
+ result = bsec_power_safmem(true);
+
+ if (result != BSEC_OK) {
+ return result;
+ }
+
+ power_up = true;
+ }
+
+ if (otp < STM32MP1_UPPER_OTP_START) {
+ addr = otp >> ADDR_LOWER_OTP_PERLOCK_SHIFT;
+ data = DATA_LOWER_OTP_PERLOCK_BIT <<
+ ((otp & DATA_LOWER_OTP_PERLOCK_MASK) << 1U);
+ } else {
+ addr = (otp >> ADDR_UPPER_OTP_PERLOCK_SHIFT) + 2U;
+ data = DATA_UPPER_OTP_PERLOCK_BIT <<
+ (otp & DATA_UPPER_OTP_PERLOCK_MASK);
+ }
+
+ bsec_lock();
+
+ /* Set value in write register */
+ mmio_write_32(bsec_base + BSEC_OTP_WRDATA_OFF, data);
+
+ /* Set BSEC_OTP_CTRL_OFF and set ADDR with the OTP value */
+ mmio_write_32(bsec_base + BSEC_OTP_CTRL_OFF,
+ addr | BSEC_WRITE | BSEC_LOCK);
+
+ while ((bsec_get_status() & BSEC_MODE_BUSY_MASK) != 0U) {
+ ;
+ }
+
+ if ((bsec_get_status() & BSEC_MODE_PROGFAIL_MASK) != 0U) {
+ result = BSEC_PROG_FAIL;
+ } else {
+ result = bsec_check_error(otp);
+ }
+
+ bsec_unlock();
+
+ if (power_up) {
+ if (bsec_power_safmem(false) != BSEC_OK) {
+ panic();
+ }
+ }
+
+ return result;
+}
+
+/*
+ * bsec_write_debug_conf: write value in debug feature
+ * to enable/disable debug service.
+ * val: value to write.
+ * return value: BSEC_OK if no error.
+ */
+uint32_t bsec_write_debug_conf(uint32_t val)
+{
+ uint32_t result = BSEC_ERROR;
+ uint32_t masked_val = val & BSEC_DEN_ALL_MSK;
+
+ bsec_lock();
+
+ mmio_write_32(bsec_base + BSEC_DEN_OFF, masked_val);
+
+ if ((mmio_read_32(bsec_base + BSEC_DEN_OFF) ^ masked_val) == 0U) {
+ result = BSEC_OK;
+ }
+
+ bsec_unlock();
+
+ return result;
+}
+
+/*
+ * bsec_read_debug_conf: read debug configuration.
+ */
+uint32_t bsec_read_debug_conf(void)
+{
+ return mmio_read_32(bsec_base + BSEC_DEN_OFF);
+}
+
+/*
+ * bsec_get_status: return status register value.
+ */
+uint32_t bsec_get_status(void)
+{
+ return mmio_read_32(bsec_base + BSEC_OTP_STATUS_OFF);
+}
+
+/*
+ * bsec_get_hw_conf: return hardware configuration.
+ */
+uint32_t bsec_get_hw_conf(void)
+{
+ return mmio_read_32(bsec_base + BSEC_IPHW_CFG_OFF);
+}
+
+/*
+ * bsec_get_version: return BSEC version.
+ */
+uint32_t bsec_get_version(void)
+{
+ return mmio_read_32(bsec_base + BSEC_IPVR_OFF);
+}
+
+/*
+ * bsec_get_id: return BSEC ID.
+ */
+uint32_t bsec_get_id(void)
+{
+ return mmio_read_32(bsec_base + BSEC_IP_ID_OFF);
+}
+
+/*
+ * bsec_get_magic_id: return BSEC magic number.
+ */
+uint32_t bsec_get_magic_id(void)
+{
+ return mmio_read_32(bsec_base + BSEC_IP_MAGIC_ID_OFF);
+}
+
+/*
+ * bsec_write_sr_lock: write shadow-read lock.
+ * otp: OTP number.
+ * value: value to write in the register.
+ * Must be always 1.
+ * return: true if OTP is locked, else false.
+ */
+bool bsec_write_sr_lock(uint32_t otp, uint32_t value)
+{
+ bool result = false;
+ uint32_t bank = otp_bank_offset(otp);
+ uint32_t bank_value;
+ uint32_t otp_mask = BIT(otp & BSEC_OTP_MASK);
+
+ bsec_lock();
+
+ bank_value = mmio_read_32(bsec_base + BSEC_SRLOCK_OFF + bank);
+
+ if ((bank_value & otp_mask) == value) {
+ /*
+ * In case of write don't need to write,
+ * the lock is already set.
+ */
+ if (value != 0U) {
+ result = true;
+ }
+ } else {
+ if (value != 0U) {
+ bank_value = bank_value | otp_mask;
+ } else {
+ bank_value = bank_value & ~otp_mask;
+ }
+
+ /*
+ * We can write 0 in all other OTP
+ * if the lock is activated in one of other OTP.
+ * Write 0 has no effect.
+ */
+ mmio_write_32(bsec_base + BSEC_SRLOCK_OFF + bank, bank_value);
+ result = true;
+ }
+
+ bsec_unlock();
+
+ return result;
+}
+
+/*
+ * bsec_read_sr_lock: read shadow-read lock.
+ * otp: OTP number.
+ * return: true if otp is locked, else false.
+ */
+bool bsec_read_sr_lock(uint32_t otp)
+{
+ uint32_t bank = otp_bank_offset(otp);
+ uint32_t otp_mask = BIT(otp & BSEC_OTP_MASK);
+ uint32_t bank_value = mmio_read_32(bsec_base + BSEC_SRLOCK_OFF + bank);
+
+ return (bank_value & otp_mask) != 0U;
+}
+
+/*
+ * bsec_write_sw_lock: write shadow-write lock.
+ * otp: OTP number.
+ * value: Value to write in the register.
+ * Must be always 1.
+ * return: true if OTP is locked, else false.
+ */
+bool bsec_write_sw_lock(uint32_t otp, uint32_t value)
+{
+ bool result = false;
+ uint32_t bank = otp_bank_offset(otp);
+ uint32_t otp_mask = BIT(otp & BSEC_OTP_MASK);
+ uint32_t bank_value;
+
+ bsec_lock();
+
+ bank_value = mmio_read_32(bsec_base + BSEC_SWLOCK_OFF + bank);
+
+ if ((bank_value & otp_mask) == value) {
+ /*
+ * In case of write don't need to write,
+ * the lock is already set.
+ */
+ if (value != 0U) {
+ result = true;
+ }
+ } else {
+ if (value != 0U) {
+ bank_value = bank_value | otp_mask;
+ } else {
+ bank_value = bank_value & ~otp_mask;
+ }
+
+ /*
+ * We can write 0 in all other OTP
+ * if the lock is activated in one of other OTP.
+ * Write 0 has no effect.
+ */
+ mmio_write_32(bsec_base + BSEC_SWLOCK_OFF + bank, bank_value);
+ result = true;
+ }
+
+ bsec_unlock();
+
+ return result;
+}
+
+/*
+ * bsec_read_sw_lock: read shadow-write lock.
+ * otp: OTP number.
+ * return: true if OTP is locked, else false.
+ */
+bool bsec_read_sw_lock(uint32_t otp)
+{
+ uint32_t bank = otp_bank_offset(otp);
+ uint32_t otp_mask = BIT(otp & BSEC_OTP_MASK);
+ uint32_t bank_value = mmio_read_32(bsec_base + BSEC_SWLOCK_OFF + bank);
+
+ return (bank_value & otp_mask) != 0U;
+}
+
+/*
+ * bsec_write_sp_lock: write shadow-program lock.
+ * otp: OTP number.
+ * value: Value to write in the register.
+ * Must be always 1.
+ * return: true if OTP is locked, else false.
+ */
+bool bsec_write_sp_lock(uint32_t otp, uint32_t value)
+{
+ bool result = false;
+ uint32_t bank = otp_bank_offset(otp);
+ uint32_t bank_value;
+ uint32_t otp_mask = BIT(otp & BSEC_OTP_MASK);
+
+ bsec_lock();
+
+ bank_value = mmio_read_32(bsec_base + BSEC_SPLOCK_OFF + bank);
+
+ if ((bank_value & otp_mask) == value) {
+ /*
+ * In case of write don't need to write,
+ * the lock is already set.
+ */
+ if (value != 0U) {
+ result = true;
+ }
+ } else {
+ if (value != 0U) {
+ bank_value = bank_value | otp_mask;
+ } else {
+ bank_value = bank_value & ~otp_mask;
+ }
+
+ /*
+ * We can write 0 in all other OTP
+ * if the lock is activated in one of other OTP.
+ * Write 0 has no effect.
+ */
+ mmio_write_32(bsec_base + BSEC_SPLOCK_OFF + bank, bank_value);
+ result = true;
+ }
+
+ bsec_unlock();
+
+ return result;
+}
+
+/*
+ * bsec_read_sp_lock: read shadow-program lock.
+ * otp: OTP number.
+ * return: true if OTP is locked, else false.
+ */
+bool bsec_read_sp_lock(uint32_t otp)
+{
+ uint32_t bank = otp_bank_offset(otp);
+ uint32_t otp_mask = BIT(otp & BSEC_OTP_MASK);
+ uint32_t bank_value = mmio_read_32(bsec_base + BSEC_SPLOCK_OFF + bank);
+
+ return (bank_value & otp_mask) != 0U;
+}
+
+/*
+ * bsec_wr_lock: Read permanent lock status.
+ * otp: OTP number.
+ * return: true if OTP is locked, else false.
+ */
+bool bsec_wr_lock(uint32_t otp)
+{
+ uint32_t bank = otp_bank_offset(otp);
+ uint32_t lock_bit = BIT(otp & BSEC_OTP_MASK);
+
+ if ((mmio_read_32(bsec_base + BSEC_WRLOCK_OFF + bank) &
+ lock_bit) != 0U) {
+ /*
+ * In case of write don't need to write,
+ * the lock is already set.
+ */
+ return true;
+ }
+
+ return false;
+}
+
+/*
+ * bsec_otp_lock: Lock Upper OTP or Global programming or debug enable
+ * service: Service to lock see header file.
+ * value: Value to write must always set to 1 (only use for debug purpose).
+ * return: BSEC_OK if succeed.
+ */
+uint32_t bsec_otp_lock(uint32_t service, uint32_t value)
+{
+ uintptr_t reg = bsec_base + BSEC_OTP_LOCK_OFF;
+
+ switch (service) {
+ case BSEC_LOCK_UPPER_OTP:
+ mmio_write_32(reg, value << BSEC_LOCK_UPPER_OTP);
+ break;
+ case BSEC_LOCK_DEBUG:
+ mmio_write_32(reg, value << BSEC_LOCK_DEBUG);
+ break;
+ case BSEC_LOCK_PROGRAM:
+ mmio_write_32(reg, value << BSEC_LOCK_PROGRAM);
+ break;
+ default:
+ return BSEC_INVALID_PARAM;
+ }
+
+ return BSEC_OK;
+}
+
+/*
+ * bsec_power_safmem: Activate or deactivate SAFMEM power.
+ * power: true to power up, false to power down.
+ * return: BSEC_OK if succeed.
+ */
+static uint32_t bsec_power_safmem(bool power)
+{
+ uint32_t register_val;
+ uint32_t timeout = BSEC_TIMEOUT_VALUE;
+
+ bsec_lock();
+
+ register_val = mmio_read_32(bsec_base + BSEC_OTP_CONF_OFF);
+
+ if (power) {
+ register_val |= BSEC_CONF_POWER_UP_MASK;
+ } else {
+ register_val &= ~BSEC_CONF_POWER_UP_MASK;
+ }
+
+ mmio_write_32(bsec_base + BSEC_OTP_CONF_OFF, register_val);
+
+ /* Waiting loop */
+ if (power) {
+ while (((bsec_get_status() & BSEC_MODE_PWR_MASK) == 0U) &&
+ (timeout != 0U)) {
+ timeout--;
+ }
+ } else {
+ while (((bsec_get_status() & BSEC_MODE_PWR_MASK) != 0U) &&
+ (timeout != 0U)) {
+ timeout--;
+ }
+ }
+
+ bsec_unlock();
+
+ if (timeout == 0U) {
+ return BSEC_TIMEOUT;
+ }
+
+ return BSEC_OK;
+}
+
+/*
+ * bsec_mode_is_closed_device: read OTP secure sub-mode.
+ * return: false if open_device and true of closed_device.
+ */
+bool bsec_mode_is_closed_device(void)
+{
+ uint32_t value;
+
+ if ((bsec_shadow_register(DATA0_OTP) != BSEC_OK) ||
+ (bsec_read_otp(&value, DATA0_OTP) != BSEC_OK)) {
+ return true;
+ }
+
+ return (value & DATA0_OTP_SECURED) == DATA0_OTP_SECURED;
+}
+
+/*
+ * bsec_shadow_read_otp: Load OTP from SAFMEM and provide its value
+ * otp_value: read value.
+ * word: OTP number.
+ * return value: BSEC_OK if no error.
+ */
+uint32_t bsec_shadow_read_otp(uint32_t *otp_value, uint32_t word)
+{
+ uint32_t result;
+
+ result = bsec_shadow_register(word);
+ if (result != BSEC_OK) {
+ ERROR("BSEC: %u Shadowing Error %i\n", word, result);
+ return result;
+ }
+
+ result = bsec_read_otp(otp_value, word);
+ if (result != BSEC_OK) {
+ ERROR("BSEC: %u Read Error %i\n", word, result);
+ }
+
+ return result;
+}
+
+/*
+ * bsec_check_nsec_access_rights: check non-secure access rights to target OTP.
+ * otp: OTP number.
+ * return: BSEC_OK if authorized access.
+ */
+uint32_t bsec_check_nsec_access_rights(uint32_t otp)
+{
+#if defined(IMAGE_BL32)
+ if (otp > STM32MP1_OTP_MAX_ID) {
+ return BSEC_INVALID_PARAM;
+ }
+
+ if (otp >= STM32MP1_UPPER_OTP_START) {
+ /* Check if BSEC is in OTP-SECURED closed_device state. */
+ if (bsec_mode_is_closed_device()) {
+ if (!non_secure_can_access(otp)) {
+ return BSEC_ERROR;
+ }
+ }
+ }
+#endif
+
+ return BSEC_OK;
+}
+
diff --git a/drivers/st/clk/stm32mp1_clkfunc.c b/drivers/st/clk/stm32mp1_clkfunc.c
index 1d92271..19dfe1b 100644
--- a/drivers/st/clk/stm32mp1_clkfunc.c
+++ b/drivers/st/clk/stm32mp1_clkfunc.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2017-2018, STMicroelectronics - All Rights Reserved
+ * Copyright (c) 2017-2019, STMicroelectronics - All Rights Reserved
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -32,10 +32,18 @@
};
/*******************************************************************************
+ * This function returns the RCC node in the device tree.
+ ******************************************************************************/
+static int fdt_get_rcc_node(void *fdt)
+{
+ return fdt_node_offset_by_compatible(fdt, -1, DT_RCC_CLK_COMPAT);
+}
+
+/*******************************************************************************
* This function reads the frequency of an oscillator from its name.
* It reads the value indicated inside the device tree.
- * Returns 0 if success, and a negative value else.
- * If success, value is stored in the second parameter.
+ * Returns 0 on success, and a negative FDT/ERRNO error code on failure.
+ * On success, value is stored in the second parameter.
******************************************************************************/
int fdt_osc_read_freq(const char *name, uint32_t *freq)
{
@@ -127,7 +135,7 @@
/*******************************************************************************
* This function reads a value of a oscillator property from its id.
- * Returns value if success, and a default value if property not found.
+ * Returns value on success, and a default value if property not found.
* Default value is passed as parameter.
******************************************************************************/
uint32_t fdt_osc_read_uint32_default(enum stm32mp_osc_id osc_id,
@@ -240,7 +248,7 @@
/*******************************************************************************
* This function gets the subnode offset in rcc-clk section from its name.
* It reads the values indicated inside the device tree.
- * Returns offset if success, and a negative value else.
+ * Returns offset on success, and a negative FDT/ERRNO error code on failure.
******************************************************************************/
int fdt_rcc_subnode_offset(const char *name)
{
@@ -251,7 +259,7 @@
return -ENOENT;
}
- node = fdt_node_offset_by_compatible(fdt, -1, DT_RCC_CLK_COMPAT);
+ node = fdt_get_rcc_node(fdt);
if (node < 0) {
return -FDT_ERR_NOTFOUND;
}
@@ -280,7 +288,7 @@
return NULL;
}
- node = fdt_node_offset_by_compatible(fdt, -1, DT_RCC_CLK_COMPAT);
+ node = fdt_get_rcc_node(fdt);
if (node < 0) {
return NULL;
}
@@ -297,7 +305,7 @@
/*******************************************************************************
* This function gets the secure status for rcc node.
* It reads secure-status in device tree.
- * Returns 1 if rcc is available from secure world, 0 else.
+ * Returns true if rcc is available from secure world, false if not.
******************************************************************************/
bool fdt_get_rcc_secure_status(void)
{
@@ -308,18 +316,18 @@
return false;
}
- node = fdt_node_offset_by_compatible(fdt, -1, DT_RCC_COMPAT);
+ node = fdt_get_rcc_node(fdt);
if (node < 0) {
return false;
}
- return fdt_check_secure_status(node);
+ return (fdt_get_status(node) & DT_SECURE) != 0U;
}
/*******************************************************************************
* This function reads the stgen base address.
* It reads the value indicated inside the device tree.
- * Returns address if success, and NULL value else.
+ * Returns address on success, and NULL value on failure.
******************************************************************************/
uintptr_t fdt_get_stgen_base(void)
{
@@ -347,7 +355,7 @@
/*******************************************************************************
* This function gets the clock ID of the given node.
* It reads the value indicated inside the device tree.
- * Returns ID if success, and a negative value else.
+ * Returns ID on success, and a negative FDT/ERRNO error code on failure.
******************************************************************************/
int fdt_get_clock_id(int node)
{
diff --git a/drivers/st/ddr/stm32mp1_ddr.c b/drivers/st/ddr/stm32mp1_ddr.c
index aca0450..79aff6e 100644
--- a/drivers/st/ddr/stm32mp1_ddr.c
+++ b/drivers/st/ddr/stm32mp1_ddr.c
@@ -1,9 +1,10 @@
/*
- * Copyright (C) 2018, STMicroelectronics - All Rights Reserved
+ * Copyright (C) 2018-2019, STMicroelectronics - All Rights Reserved
*
* SPDX-License-Identifier: GPL-2.0+ OR BSD-3-Clause
*/
+#include <errno.h>
#include <stddef.h>
#include <platform_def.h>
@@ -12,10 +13,10 @@
#include <arch_helpers.h>
#include <common/debug.h>
#include <drivers/delay_timer.h>
+#include <drivers/st/stm32mp_pmic.h>
#include <drivers/st/stm32mp1_clk.h>
#include <drivers/st/stm32mp1_ddr.h>
#include <drivers/st/stm32mp1_ddr_regs.h>
-#include <drivers/st/stm32mp1_pmic.h>
#include <drivers/st/stm32mp1_pwr.h>
#include <drivers/st/stm32mp1_ram.h>
#include <drivers/st/stm32mp1_rcc.h>
@@ -233,40 +234,67 @@
static const struct ddr_reg_info ddr_registers[REG_TYPE_NB] = {
[REG_REG] = {
- "static", ddr_reg, ARRAY_SIZE(ddr_reg), DDR_BASE
+ .name = "static",
+ .desc = ddr_reg,
+ .size = ARRAY_SIZE(ddr_reg),
+ .base = DDR_BASE
},
[REG_TIMING] = {
- "timing", ddr_timing, ARRAY_SIZE(ddr_timing), DDR_BASE
+ .name = "timing",
+ .desc = ddr_timing,
+ .size = ARRAY_SIZE(ddr_timing),
+ .base = DDR_BASE
},
[REG_PERF] = {
- "perf", ddr_perf, ARRAY_SIZE(ddr_perf), DDR_BASE
+ .name = "perf",
+ .desc = ddr_perf,
+ .size = ARRAY_SIZE(ddr_perf),
+ .base = DDR_BASE
},
[REG_MAP] = {
- "map", ddr_map, ARRAY_SIZE(ddr_map), DDR_BASE
+ .name = "map",
+ .desc = ddr_map,
+ .size = ARRAY_SIZE(ddr_map),
+ .base = DDR_BASE
},
[REGPHY_REG] = {
- "static", ddrphy_reg, ARRAY_SIZE(ddrphy_reg), DDRPHY_BASE
+ .name = "static",
+ .desc = ddrphy_reg,
+ .size = ARRAY_SIZE(ddrphy_reg),
+ .base = DDRPHY_BASE
},
[REGPHY_TIMING] = {
- "timing", ddrphy_timing, ARRAY_SIZE(ddrphy_timing), DDRPHY_BASE
+ .name = "timing",
+ .desc = ddrphy_timing,
+ .size = ARRAY_SIZE(ddrphy_timing),
+ .base = DDRPHY_BASE
},
[REGPHY_CAL] = {
- "cal", ddrphy_cal, ARRAY_SIZE(ddrphy_cal), DDRPHY_BASE
+ .name = "cal",
+ .desc = ddrphy_cal,
+ .size = ARRAY_SIZE(ddrphy_cal),
+ .base = DDRPHY_BASE
},
[REG_DYN] = {
- "dyn", ddr_dyn, ARRAY_SIZE(ddr_dyn), DDR_BASE
+ .name = "dyn",
+ .desc = ddr_dyn,
+ .size = ARRAY_SIZE(ddr_dyn),
+ .base = DDR_BASE
},
[REGPHY_DYN] = {
- "dyn", ddrphy_dyn, ARRAY_SIZE(ddrphy_dyn), DDRPHY_BASE
+ .name = "dyn",
+ .desc = ddrphy_dyn,
+ .size = ARRAY_SIZE(ddrphy_dyn),
+ .base = DDRPHY_BASE
},
};
-static uint32_t get_base_addr(const struct ddr_info *priv, enum base_type base)
+static uintptr_t get_base_addr(const struct ddr_info *priv, enum base_type base)
{
if (base == DDRPHY_BASE) {
- return (uint32_t)priv->phy;
+ return (uintptr_t)priv->phy;
} else {
- return (uint32_t)priv->ctl;
+ return (uintptr_t)priv->ctl;
}
}
@@ -275,21 +303,22 @@
const void *param)
{
unsigned int i;
- unsigned int *ptr, value;
+ unsigned int value;
enum base_type base = ddr_registers[type].base;
- uint32_t base_addr = get_base_addr(priv, base);
+ uintptr_t base_addr = get_base_addr(priv, base);
const struct reg_desc *desc = ddr_registers[type].desc;
VERBOSE("init %s\n", ddr_registers[type].name);
for (i = 0; i < ddr_registers[type].size; i++) {
- ptr = (unsigned int *)(base_addr + desc[i].offset);
+ uintptr_t ptr = base_addr + desc[i].offset;
+
if (desc[i].par_offset == INVALID_OFFSET) {
ERROR("invalid parameter offset for %s", desc[i].name);
panic();
} else {
- value = *((uint32_t *)((uint32_t)param +
+ value = *((uint32_t *)((uintptr_t)param +
desc[i].par_offset));
- mmio_write_32((uint32_t)ptr, value);
+ mmio_write_32(ptr, value);
}
}
}
@@ -305,15 +334,15 @@
time0 = start;
do {
- pgsr = mmio_read_32((uint32_t)&phy->pgsr);
+ pgsr = mmio_read_32((uintptr_t)&phy->pgsr);
time = get_timer(start);
if (time != time0) {
- VERBOSE(" > [0x%x] pgsr = 0x%x &\n",
- (uint32_t)&phy->pgsr, pgsr);
- VERBOSE(" [0x%x] pir = 0x%x (time=%x)\n",
- (uint32_t)&phy->pir,
- mmio_read_32((uint32_t)&phy->pir),
- (uint32_t)time);
+ VERBOSE(" > [0x%lx] pgsr = 0x%x &\n",
+ (uintptr_t)&phy->pgsr, pgsr);
+ VERBOSE(" [0x%lx] pir = 0x%x (time=%lx)\n",
+ (uintptr_t)&phy->pir,
+ mmio_read_32((uintptr_t)&phy->pir),
+ time);
}
time0 = time;
@@ -341,18 +370,18 @@
error++;
}
} while ((pgsr & DDRPHYC_PGSR_IDONE) == 0U && error == 0);
- VERBOSE("\n[0x%x] pgsr = 0x%x\n",
- (uint32_t)&phy->pgsr, pgsr);
+ VERBOSE("\n[0x%lx] pgsr = 0x%x\n",
+ (uintptr_t)&phy->pgsr, pgsr);
}
static void stm32mp1_ddrphy_init(struct stm32mp1_ddrphy *phy, uint32_t pir)
{
uint32_t pir_init = pir | DDRPHYC_PIR_INIT;
- mmio_write_32((uint32_t)&phy->pir, pir_init);
- VERBOSE("[0x%x] pir = 0x%x -> 0x%x\n",
- (uint32_t)&phy->pir, pir_init,
- mmio_read_32((uint32_t)&phy->pir));
+ mmio_write_32((uintptr_t)&phy->pir, pir_init);
+ VERBOSE("[0x%lx] pir = 0x%x -> 0x%x\n",
+ (uintptr_t)&phy->pir, pir_init,
+ mmio_read_32((uintptr_t)&phy->pir));
/* Need to wait 10 configuration clock before start polling */
udelay(10);
@@ -364,9 +393,9 @@
/* Start quasi dynamic register update */
static void stm32mp1_start_sw_done(struct stm32mp1_ddrctl *ctl)
{
- mmio_clrbits_32((uint32_t)&ctl->swctl, DDRCTRL_SWCTL_SW_DONE);
- VERBOSE("[0x%x] swctl = 0x%x\n",
- (uint32_t)&ctl->swctl, mmio_read_32((uint32_t)&ctl->swctl));
+ mmio_clrbits_32((uintptr_t)&ctl->swctl, DDRCTRL_SWCTL_SW_DONE);
+ VERBOSE("[0x%lx] swctl = 0x%x\n",
+ (uintptr_t)&ctl->swctl, mmio_read_32((uintptr_t)&ctl->swctl));
}
/* Wait quasi dynamic register update */
@@ -375,15 +404,15 @@
unsigned long start;
uint32_t swstat;
- mmio_setbits_32((uint32_t)&ctl->swctl, DDRCTRL_SWCTL_SW_DONE);
- VERBOSE("[0x%x] swctl = 0x%x\n",
- (uint32_t)&ctl->swctl, mmio_read_32((uint32_t)&ctl->swctl));
+ mmio_setbits_32((uintptr_t)&ctl->swctl, DDRCTRL_SWCTL_SW_DONE);
+ VERBOSE("[0x%lx] swctl = 0x%x\n",
+ (uintptr_t)&ctl->swctl, mmio_read_32((uintptr_t)&ctl->swctl));
start = get_timer(0);
do {
- swstat = mmio_read_32((uint32_t)&ctl->swstat);
- VERBOSE("[0x%x] swstat = 0x%x ",
- (uint32_t)&ctl->swstat, swstat);
+ swstat = mmio_read_32((uintptr_t)&ctl->swstat);
+ VERBOSE("[0x%lx] swstat = 0x%x ",
+ (uintptr_t)&ctl->swstat, swstat);
VERBOSE("timer in ms 0x%x = start 0x%lx\r",
get_timer(0), start);
if (get_timer(start) > plat_get_syscnt_freq2()) {
@@ -391,8 +420,8 @@
}
} while ((swstat & DDRCTRL_SWSTAT_SW_DONE_ACK) == 0U);
- VERBOSE("[0x%x] swstat = 0x%x\n",
- (uint32_t)&ctl->swstat, swstat);
+ VERBOSE("[0x%lx] swstat = 0x%x\n",
+ (uintptr_t)&ctl->swstat, swstat);
}
/* Wait quasi dynamic register update */
@@ -406,11 +435,11 @@
start = get_timer(0);
for ( ; ; ) {
- stat = mmio_read_32((uint32_t)&priv->ctl->stat);
+ stat = mmio_read_32((uintptr_t)&priv->ctl->stat);
operating_mode = stat & DDRCTRL_STAT_OPERATING_MODE_MASK;
selref_type = stat & DDRCTRL_STAT_SELFREF_TYPE_MASK;
- VERBOSE("[0x%x] stat = 0x%x\n",
- (uint32_t)&priv->ctl->stat, stat);
+ VERBOSE("[0x%lx] stat = 0x%x\n",
+ (uintptr_t)&priv->ctl->stat, stat);
VERBOSE("timer in ms 0x%x = start 0x%lx\r",
get_timer(0), start);
if (get_timer(start) > plat_get_syscnt_freq2()) {
@@ -441,8 +470,8 @@
}
}
- VERBOSE("[0x%x] stat = 0x%x\n",
- (uint32_t)&priv->ctl->stat, stat);
+ VERBOSE("[0x%lx] stat = 0x%x\n",
+ (uintptr_t)&priv->ctl->stat, stat);
}
/* Mode Register Writes (MRW or MRS) */
@@ -459,7 +488,7 @@
* No write should be performed to MRCTRL0 and MRCTRL1
* if MRSTAT.mr_wr_busy = 1.
*/
- while ((mmio_read_32((uint32_t)&priv->ctl->mrstat) &
+ while ((mmio_read_32((uintptr_t)&priv->ctl->mrstat) &
DDRCTRL_MRSTAT_MR_WR_BUSY) != 0U) {
;
}
@@ -472,14 +501,14 @@
DDRCTRL_MRCTRL0_MR_RANK_ALL |
(((uint32_t)addr << DDRCTRL_MRCTRL0_MR_ADDR_SHIFT) &
DDRCTRL_MRCTRL0_MR_ADDR_MASK);
- mmio_write_32((uint32_t)&priv->ctl->mrctrl0, mrctrl0);
- VERBOSE("[0x%x] mrctrl0 = 0x%x (0x%x)\n",
- (uint32_t)&priv->ctl->mrctrl0,
- mmio_read_32((uint32_t)&priv->ctl->mrctrl0), mrctrl0);
- mmio_write_32((uint32_t)&priv->ctl->mrctrl1, data);
- VERBOSE("[0x%x] mrctrl1 = 0x%x\n",
- (uint32_t)&priv->ctl->mrctrl1,
- mmio_read_32((uint32_t)&priv->ctl->mrctrl1));
+ mmio_write_32((uintptr_t)&priv->ctl->mrctrl0, mrctrl0);
+ VERBOSE("[0x%lx] mrctrl0 = 0x%x (0x%x)\n",
+ (uintptr_t)&priv->ctl->mrctrl0,
+ mmio_read_32((uintptr_t)&priv->ctl->mrctrl0), mrctrl0);
+ mmio_write_32((uintptr_t)&priv->ctl->mrctrl1, data);
+ VERBOSE("[0x%lx] mrctrl1 = 0x%x\n",
+ (uintptr_t)&priv->ctl->mrctrl1,
+ mmio_read_32((uintptr_t)&priv->ctl->mrctrl1));
/*
* 3. In a separate APB transaction, write the MRCTRL0.mr_wr to 1. This
@@ -489,22 +518,22 @@
* initiated until it is deasserted.
*/
mrctrl0 |= DDRCTRL_MRCTRL0_MR_WR;
- mmio_write_32((uint32_t)&priv->ctl->mrctrl0, mrctrl0);
+ mmio_write_32((uintptr_t)&priv->ctl->mrctrl0, mrctrl0);
- while ((mmio_read_32((uint32_t)&priv->ctl->mrstat) &
+ while ((mmio_read_32((uintptr_t)&priv->ctl->mrstat) &
DDRCTRL_MRSTAT_MR_WR_BUSY) != 0U) {
;
}
- VERBOSE("[0x%x] mrctrl0 = 0x%x\n",
- (uint32_t)&priv->ctl->mrctrl0, mrctrl0);
+ VERBOSE("[0x%lx] mrctrl0 = 0x%x\n",
+ (uintptr_t)&priv->ctl->mrctrl0, mrctrl0);
}
/* Switch DDR3 from DLL-on to DLL-off */
static void stm32mp1_ddr3_dll_off(struct ddr_info *priv)
{
- uint32_t mr1 = mmio_read_32((uint32_t)&priv->phy->mr1);
- uint32_t mr2 = mmio_read_32((uint32_t)&priv->phy->mr2);
+ uint32_t mr1 = mmio_read_32((uintptr_t)&priv->phy->mr1);
+ uint32_t mr2 = mmio_read_32((uintptr_t)&priv->phy->mr2);
uint32_t dbgcam;
VERBOSE("mr1: 0x%x\n", mr1);
@@ -514,10 +543,10 @@
* 1. Set the DBG1.dis_hif = 1.
* This prevents further reads/writes being received on the HIF.
*/
- mmio_setbits_32((uint32_t)&priv->ctl->dbg1, DDRCTRL_DBG1_DIS_HIF);
- VERBOSE("[0x%x] dbg1 = 0x%x\n",
- (uint32_t)&priv->ctl->dbg1,
- mmio_read_32((uint32_t)&priv->ctl->dbg1));
+ mmio_setbits_32((uintptr_t)&priv->ctl->dbg1, DDRCTRL_DBG1_DIS_HIF);
+ VERBOSE("[0x%lx] dbg1 = 0x%x\n",
+ (uintptr_t)&priv->ctl->dbg1,
+ mmio_read_32((uintptr_t)&priv->ctl->dbg1));
/*
* 2. Ensure all commands have been flushed from the uMCTL2 by polling
@@ -528,9 +557,9 @@
* DBGCAM.dbg_hpr_q_depth = 0.
*/
do {
- dbgcam = mmio_read_32((uint32_t)&priv->ctl->dbgcam);
- VERBOSE("[0x%x] dbgcam = 0x%x\n",
- (uint32_t)&priv->ctl->dbgcam, dbgcam);
+ dbgcam = mmio_read_32((uintptr_t)&priv->ctl->dbgcam);
+ VERBOSE("[0x%lx] dbgcam = 0x%x\n",
+ (uintptr_t)&priv->ctl->dbgcam, dbgcam);
} while ((((dbgcam & DDRCTRL_DBGCAM_DATA_PIPELINE_EMPTY) ==
DDRCTRL_DBGCAM_DATA_PIPELINE_EMPTY)) &&
((dbgcam & DDRCTRL_DBGCAM_DBG_Q_DEPTH) == 0U));
@@ -574,11 +603,11 @@
* PWRCTL.selfref_sw = 1, and polling STAT.operating_mode to ensure
* the DDRC has entered self-refresh.
*/
- mmio_setbits_32((uint32_t)&priv->ctl->pwrctl,
+ mmio_setbits_32((uintptr_t)&priv->ctl->pwrctl,
DDRCTRL_PWRCTL_SELFREF_SW);
- VERBOSE("[0x%x] pwrctl = 0x%x\n",
- (uint32_t)&priv->ctl->pwrctl,
- mmio_read_32((uint32_t)&priv->ctl->pwrctl));
+ VERBOSE("[0x%lx] pwrctl = 0x%x\n",
+ (uintptr_t)&priv->ctl->pwrctl,
+ mmio_read_32((uintptr_t)&priv->ctl->pwrctl));
/*
* 8. Wait until STAT.operating_mode[1:0]==11 indicating that the
@@ -594,10 +623,10 @@
*/
stm32mp1_start_sw_done(priv->ctl);
- mmio_setbits_32((uint32_t)&priv->ctl->mstr, DDRCTRL_MSTR_DLL_OFF_MODE);
- VERBOSE("[0x%x] mstr = 0x%x\n",
- (uint32_t)&priv->ctl->mstr,
- mmio_read_32((uint32_t)&priv->ctl->mstr));
+ mmio_setbits_32((uintptr_t)&priv->ctl->mstr, DDRCTRL_MSTR_DLL_OFF_MODE);
+ VERBOSE("[0x%lx] mstr = 0x%x\n",
+ (uintptr_t)&priv->ctl->mstr,
+ mmio_read_32((uintptr_t)&priv->ctl->mstr));
stm32mp1_wait_sw_done_ack(priv->ctl);
@@ -611,26 +640,26 @@
/* Change Bypass Mode Frequency Range */
if (stm32mp1_clk_get_rate(DDRPHYC) < 100000000U) {
- mmio_clrbits_32((uint32_t)&priv->phy->dllgcr,
+ mmio_clrbits_32((uintptr_t)&priv->phy->dllgcr,
DDRPHYC_DLLGCR_BPS200);
} else {
- mmio_setbits_32((uint32_t)&priv->phy->dllgcr,
+ mmio_setbits_32((uintptr_t)&priv->phy->dllgcr,
DDRPHYC_DLLGCR_BPS200);
}
- mmio_setbits_32((uint32_t)&priv->phy->acdllcr, DDRPHYC_ACDLLCR_DLLDIS);
+ mmio_setbits_32((uintptr_t)&priv->phy->acdllcr, DDRPHYC_ACDLLCR_DLLDIS);
- mmio_setbits_32((uint32_t)&priv->phy->dx0dllcr,
+ mmio_setbits_32((uintptr_t)&priv->phy->dx0dllcr,
DDRPHYC_DXNDLLCR_DLLDIS);
- mmio_setbits_32((uint32_t)&priv->phy->dx1dllcr,
+ mmio_setbits_32((uintptr_t)&priv->phy->dx1dllcr,
DDRPHYC_DXNDLLCR_DLLDIS);
- mmio_setbits_32((uint32_t)&priv->phy->dx2dllcr,
+ mmio_setbits_32((uintptr_t)&priv->phy->dx2dllcr,
DDRPHYC_DXNDLLCR_DLLDIS);
- mmio_setbits_32((uint32_t)&priv->phy->dx3dllcr,
+ mmio_setbits_32((uintptr_t)&priv->phy->dx3dllcr,
DDRPHYC_DXNDLLCR_DLLDIS);
/* 12. Exit the self-refresh state by setting PWRCTL.selfref_sw = 0. */
- mmio_clrbits_32((uint32_t)&priv->ctl->pwrctl,
+ mmio_clrbits_32((uintptr_t)&priv->ctl->pwrctl,
DDRCTRL_PWRCTL_SELFREF_SW);
stm32mp1_wait_operating_mode(priv, DDRCTRL_STAT_OPERATING_MODE_NORMAL);
@@ -646,20 +675,20 @@
*/
/* 15. Write DBG1.dis_hif = 0 to re-enable reads and writes. */
- mmio_clrbits_32((uint32_t)&priv->ctl->dbg1, DDRCTRL_DBG1_DIS_HIF);
- VERBOSE("[0x%x] dbg1 = 0x%x\n",
- (uint32_t)&priv->ctl->dbg1,
- mmio_read_32((uint32_t)&priv->ctl->dbg1));
+ mmio_clrbits_32((uintptr_t)&priv->ctl->dbg1, DDRCTRL_DBG1_DIS_HIF);
+ VERBOSE("[0x%lx] dbg1 = 0x%x\n",
+ (uintptr_t)&priv->ctl->dbg1,
+ mmio_read_32((uintptr_t)&priv->ctl->dbg1));
}
static void stm32mp1_refresh_disable(struct stm32mp1_ddrctl *ctl)
{
stm32mp1_start_sw_done(ctl);
/* Quasi-dynamic register update*/
- mmio_setbits_32((uint32_t)&ctl->rfshctl3,
+ mmio_setbits_32((uintptr_t)&ctl->rfshctl3,
DDRCTRL_RFSHCTL3_DIS_AUTO_REFRESH);
- mmio_clrbits_32((uint32_t)&ctl->pwrctl, DDRCTRL_PWRCTL_POWERDOWN_EN);
- mmio_clrbits_32((uint32_t)&ctl->dfimisc,
+ mmio_clrbits_32((uintptr_t)&ctl->pwrctl, DDRCTRL_PWRCTL_POWERDOWN_EN);
+ mmio_clrbits_32((uintptr_t)&ctl->dfimisc,
DDRCTRL_DFIMISC_DFI_INIT_COMPLETE_EN);
stm32mp1_wait_sw_done_ack(ctl);
}
@@ -669,14 +698,14 @@
{
stm32mp1_start_sw_done(ctl);
if ((rfshctl3 & DDRCTRL_RFSHCTL3_DIS_AUTO_REFRESH) == 0U) {
- mmio_clrbits_32((uint32_t)&ctl->rfshctl3,
+ mmio_clrbits_32((uintptr_t)&ctl->rfshctl3,
DDRCTRL_RFSHCTL3_DIS_AUTO_REFRESH);
}
if ((pwrctl & DDRCTRL_PWRCTL_POWERDOWN_EN) != 0U) {
- mmio_setbits_32((uint32_t)&ctl->pwrctl,
+ mmio_setbits_32((uintptr_t)&ctl->pwrctl,
DDRCTRL_PWRCTL_POWERDOWN_EN);
}
- mmio_setbits_32((uint32_t)&ctl->dfimisc,
+ mmio_setbits_32((uintptr_t)&ctl->dfimisc,
DDRCTRL_DFIMISC_DFI_INIT_COMPLETE_EN);
stm32mp1_wait_sw_done_ack(ctl);
}
@@ -694,12 +723,14 @@
struct stm32mp1_ddr_config *config)
{
uint32_t pir;
- int ret;
+ int ret = -EINVAL;
if ((config->c_reg.mstr & DDRCTRL_MSTR_DDR3) != 0U) {
ret = board_ddr_power_init(STM32MP_DDR3);
- } else {
+ } else if ((config->c_reg.mstr & DDRCTRL_MSTR_LPDDR2) != 0U) {
ret = board_ddr_power_init(STM32MP_LPDDR2);
+ } else {
+ ERROR("DDR type not supported\n");
}
if (ret != 0) {
@@ -707,7 +738,7 @@
}
VERBOSE("name = %s\n", config->info.name);
- VERBOSE("speed = %d MHz\n", config->info.speed);
+ VERBOSE("speed = %d kHz\n", config->info.speed);
VERBOSE("size = 0x%x\n", config->info.size);
/* DDR INIT SEQUENCE */
@@ -746,11 +777,11 @@
/* 1.5. initialize registers ddr_umctl2 */
/* Stop uMCTL2 before PHY is ready */
- mmio_clrbits_32((uint32_t)&priv->ctl->dfimisc,
+ mmio_clrbits_32((uintptr_t)&priv->ctl->dfimisc,
DDRCTRL_DFIMISC_DFI_INIT_COMPLETE_EN);
- VERBOSE("[0x%x] dfimisc = 0x%x\n",
- (uint32_t)&priv->ctl->dfimisc,
- mmio_read_32((uint32_t)&priv->ctl->dfimisc));
+ VERBOSE("[0x%lx] dfimisc = 0x%x\n",
+ (uintptr_t)&priv->ctl->dfimisc,
+ mmio_read_32((uintptr_t)&priv->ctl->dfimisc));
set_reg(priv, REG_REG, &config->c_reg);
@@ -759,23 +790,23 @@
(DDRCTRL_MSTR_DDR3 | DDRCTRL_MSTR_DLL_OFF_MODE))
== (DDRCTRL_MSTR_DDR3 | DDRCTRL_MSTR_DLL_OFF_MODE)) {
VERBOSE("deactivate DLL OFF in mstr\n");
- mmio_clrbits_32((uint32_t)&priv->ctl->mstr,
+ mmio_clrbits_32((uintptr_t)&priv->ctl->mstr,
DDRCTRL_MSTR_DLL_OFF_MODE);
- VERBOSE("[0x%x] mstr = 0x%x\n",
- (uint32_t)&priv->ctl->mstr,
- mmio_read_32((uint32_t)&priv->ctl->mstr));
+ VERBOSE("[0x%lx] mstr = 0x%x\n",
+ (uintptr_t)&priv->ctl->mstr,
+ mmio_read_32((uintptr_t)&priv->ctl->mstr));
}
set_reg(priv, REG_TIMING, &config->c_timing);
set_reg(priv, REG_MAP, &config->c_map);
/* Skip CTRL init, SDRAM init is done by PHY PUBL */
- mmio_clrsetbits_32((uint32_t)&priv->ctl->init0,
+ mmio_clrsetbits_32((uintptr_t)&priv->ctl->init0,
DDRCTRL_INIT0_SKIP_DRAM_INIT_MASK,
DDRCTRL_INIT0_SKIP_DRAM_INIT_NORMAL);
- VERBOSE("[0x%x] init0 = 0x%x\n",
- (uint32_t)&priv->ctl->init0,
- mmio_read_32((uint32_t)&priv->ctl->init0));
+ VERBOSE("[0x%lx] init0 = 0x%x\n",
+ (uintptr_t)&priv->ctl->init0,
+ mmio_read_32((uintptr_t)&priv->ctl->init0));
set_reg(priv, REG_PERF, &config->c_perf);
@@ -797,10 +828,10 @@
(DDRCTRL_MSTR_DDR3 | DDRCTRL_MSTR_DLL_OFF_MODE))
== (DDRCTRL_MSTR_DDR3 | DDRCTRL_MSTR_DLL_OFF_MODE)) {
VERBOSE("deactivate DLL OFF in mr1\n");
- mmio_clrbits_32((uint32_t)&priv->phy->mr1, BIT(0));
- VERBOSE("[0x%x] mr1 = 0x%x\n",
- (uint32_t)&priv->phy->mr1,
- mmio_read_32((uint32_t)&priv->phy->mr1));
+ mmio_clrbits_32((uintptr_t)&priv->phy->mr1, BIT(0));
+ VERBOSE("[0x%lx] mr1 = 0x%x\n",
+ (uintptr_t)&priv->phy->mr1,
+ mmio_read_32((uintptr_t)&priv->phy->mr1));
}
/*
@@ -830,11 +861,11 @@
*/
stm32mp1_start_sw_done(priv->ctl);
- mmio_setbits_32((uint32_t)&priv->ctl->dfimisc,
+ mmio_setbits_32((uintptr_t)&priv->ctl->dfimisc,
DDRCTRL_DFIMISC_DFI_INIT_COMPLETE_EN);
- VERBOSE("[0x%x] dfimisc = 0x%x\n",
- (uint32_t)&priv->ctl->dfimisc,
- mmio_read_32((uint32_t)&priv->ctl->dfimisc));
+ VERBOSE("[0x%lx] dfimisc = 0x%x\n",
+ (uintptr_t)&priv->ctl->dfimisc,
+ mmio_read_32((uintptr_t)&priv->ctl->dfimisc));
stm32mp1_wait_sw_done_ack(priv->ctl);
@@ -884,14 +915,16 @@
config->c_reg.pwrctl);
/* Enable uMCTL2 AXI port 0 */
- mmio_setbits_32((uint32_t)&priv->ctl->pctrl_0, DDRCTRL_PCTRL_N_PORT_EN);
- VERBOSE("[0x%x] pctrl_0 = 0x%x\n",
- (uint32_t)&priv->ctl->pctrl_0,
- mmio_read_32((uint32_t)&priv->ctl->pctrl_0));
+ mmio_setbits_32((uintptr_t)&priv->ctl->pctrl_0,
+ DDRCTRL_PCTRL_N_PORT_EN);
+ VERBOSE("[0x%lx] pctrl_0 = 0x%x\n",
+ (uintptr_t)&priv->ctl->pctrl_0,
+ mmio_read_32((uintptr_t)&priv->ctl->pctrl_0));
/* Enable uMCTL2 AXI port 1 */
- mmio_setbits_32((uint32_t)&priv->ctl->pctrl_1, DDRCTRL_PCTRL_N_PORT_EN);
- VERBOSE("[0x%x] pctrl_1 = 0x%x\n",
- (uint32_t)&priv->ctl->pctrl_1,
- mmio_read_32((uint32_t)&priv->ctl->pctrl_1));
+ mmio_setbits_32((uintptr_t)&priv->ctl->pctrl_1,
+ DDRCTRL_PCTRL_N_PORT_EN);
+ VERBOSE("[0x%lx] pctrl_1 = 0x%x\n",
+ (uintptr_t)&priv->ctl->pctrl_1,
+ mmio_read_32((uintptr_t)&priv->ctl->pctrl_1));
}
diff --git a/drivers/st/ddr/stm32mp1_ram.c b/drivers/st/ddr/stm32mp1_ram.c
index 127b6c7..e65fbea 100644
--- a/drivers/st/ddr/stm32mp1_ram.c
+++ b/drivers/st/ddr/stm32mp1_ram.c
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2018, STMicroelectronics - All Rights Reserved
+ * Copyright (C) 2018-2019, STMicroelectronics - All Rights Reserved
*
* SPDX-License-Identifier: GPL-2.0+ OR BSD-3-Clause
*/
@@ -25,7 +25,7 @@
static struct ddr_info ddr_priv_data;
-int stm32mp1_ddr_clk_enable(struct ddr_info *priv, uint16_t mem_speed)
+int stm32mp1_ddr_clk_enable(struct ddr_info *priv, uint32_t mem_speed)
{
unsigned long ddrphy_clk, ddr_clk, mem_speed_hz;
@@ -33,10 +33,10 @@
ddrphy_clk = stm32mp1_clk_get_rate(DDRPHYC);
- VERBOSE("DDR: mem_speed (%d MHz), RCC %ld MHz\n",
- mem_speed, ddrphy_clk / 1000U / 1000U);
+ VERBOSE("DDR: mem_speed (%d kHz), RCC %ld kHz\n",
+ mem_speed, ddrphy_clk / 1000U);
- mem_speed_hz = (uint32_t)mem_speed * 1000U * 1000U;
+ mem_speed_hz = mem_speed * 1000U;
/* Max 10% frequency delta */
if (ddrphy_clk > mem_speed_hz) {
@@ -44,9 +44,9 @@
} else {
ddr_clk = mem_speed_hz - ddrphy_clk;
}
- if (ddr_clk > mem_speed_hz) {
- ERROR("DDR expected freq %d MHz, current is %ld MHz\n",
- mem_speed, ddrphy_clk / 1000U / 1000U);
+ if (ddr_clk > (mem_speed_hz / 10)) {
+ ERROR("DDR expected freq %d kHz, current is %ld kHz\n",
+ mem_speed, ddrphy_clk / 1000U);
return -1;
}
return 0;
@@ -208,11 +208,16 @@
return -EINVAL;
}
- config.info.speed =
- (uint16_t)fdt_read_uint32_default(node, "st,mem-speed",
- STM32MP1_DDR_SPEED_DFLT);
- config.info.size = fdt_read_uint32_default(node, "st,mem-size",
- STM32MP1_DDR_SIZE_DFLT);
+ config.info.speed = fdt_read_uint32_default(node, "st,mem-speed", 0);
+ if (!config.info.speed) {
+ VERBOSE("%s: no st,mem-speed\n", __func__);
+ return -EINVAL;
+ }
+ config.info.size = fdt_read_uint32_default(node, "st,mem-size", 0);
+ if (!config.info.size) {
+ VERBOSE("%s: no st,mem-size\n", __func__);
+ return -EINVAL;
+ }
config.info.name = fdt_getprop(fdt, node, "st,mem-name", &len);
if (config.info.name == NULL) {
VERBOSE("%s: no st,mem-name\n", __func__);
@@ -222,7 +227,7 @@
for (idx = 0; idx < ARRAY_SIZE(param); idx++) {
ret = fdt_read_uint32_array(node, param[idx].name,
- (void *)((uint32_t)&config +
+ (void *)((uintptr_t)&config +
param[idx].offset),
param[idx].size);
@@ -261,8 +266,8 @@
VERBOSE("%s : ram size(%x, %x)\n", __func__,
(uint32_t)priv->info.base, (uint32_t)priv->info.size);
- dcsw_op_all(DC_OP_CISW);
write_sctlr(read_sctlr() & ~SCTLR_C_BIT);
+ dcsw_op_all(DC_OP_CISW);
uret = ddr_test_data_bus();
if (uret != 0U) {
diff --git a/drivers/st/gpio/stm32_gpio.c b/drivers/st/gpio/stm32_gpio.c
index 9591e37..d217c45 100644
--- a/drivers/st/gpio/stm32_gpio.c
+++ b/drivers/st/gpio/stm32_gpio.c
@@ -1,87 +1,276 @@
/*
- * Copyright (c) 2016-2018, STMicroelectronics - All Rights Reserved
+ * Copyright (c) 2016-2019, STMicroelectronics - All Rights Reserved
*
* SPDX-License-Identifier: BSD-3-Clause
*/
+#include <assert.h>
+#include <errno.h>
#include <stdbool.h>
+#include <libfdt.h>
+
+#include <platform_def.h>
+
#include <common/bl_common.h>
#include <common/debug.h>
#include <drivers/st/stm32_gpio.h>
+#include <drivers/st/stm32mp1_clk.h>
+#include <drivers/st/stm32mp1_clkfunc.h>
#include <lib/mmio.h>
+#include <lib/utils_def.h>
-static bool check_gpio(uint32_t bank, uint32_t pin)
+#define DT_GPIO_BANK_SHIFT 12
+#define DT_GPIO_BANK_MASK GENMASK(16, 12)
+#define DT_GPIO_PIN_SHIFT 8
+#define DT_GPIO_PIN_MASK GENMASK(11, 8)
+#define DT_GPIO_MODE_MASK GENMASK(7, 0)
+
+/*******************************************************************************
+ * This function gets GPIO bank node in DT.
+ * Returns node offset if status is okay in DT, else return 0
+ ******************************************************************************/
+static int ckeck_gpio_bank(void *fdt, uint32_t bank, int pinctrl_node)
{
- if (pin > GPIO_PIN_MAX) {
- ERROR("%s: wrong pin number (%d)\n", __func__, pin);
- return false;
+ int pinctrl_subnode;
+ uint32_t bank_offset = stm32_get_gpio_bank_offset(bank);
+
+ fdt_for_each_subnode(pinctrl_subnode, fdt, pinctrl_node) {
+ const fdt32_t *cuint;
+
+ if (fdt_getprop(fdt, pinctrl_subnode,
+ "gpio-controller", NULL) == NULL) {
+ continue;
+ }
+
+ cuint = fdt_getprop(fdt, pinctrl_subnode, "reg", NULL);
+ if (cuint == NULL) {
+ continue;
+ }
+
+ if ((fdt32_to_cpu(*cuint) == bank_offset) &&
+ (fdt_get_status(pinctrl_subnode) != DT_DISABLED)) {
+ return pinctrl_subnode;
+ }
}
- if ((bank > GPIO_BANK_K) && (bank != GPIO_BANK_Z)) {
- ERROR("%s: wrong GPIO bank number (%d)\n", __func__, bank);
- return false;
+ return 0;
+}
+
+/*******************************************************************************
+ * This function gets the pin settings from DT information.
+ * When analyze and parsing is done, set the GPIO registers.
+ * Returns 0 on success and a negative FDT error code on failure.
+ ******************************************************************************/
+static int dt_set_gpio_config(void *fdt, int node, uint8_t status)
+{
+ const fdt32_t *cuint, *slewrate;
+ int len;
+ int pinctrl_node;
+ uint32_t i;
+ uint32_t speed = GPIO_SPEED_LOW;
+ uint32_t pull = GPIO_NO_PULL;
+
+ cuint = fdt_getprop(fdt, node, "pinmux", &len);
+ if (cuint == NULL) {
+ return -FDT_ERR_NOTFOUND;
}
- return true;
+ pinctrl_node = fdt_parent_offset(fdt, fdt_parent_offset(fdt, node));
+ if (pinctrl_node < 0) {
+ return -FDT_ERR_NOTFOUND;
+ }
+
+ slewrate = fdt_getprop(fdt, node, "slew-rate", NULL);
+ if (slewrate != NULL) {
+ speed = fdt32_to_cpu(*slewrate);
+ }
+
+ if (fdt_getprop(fdt, node, "bias-pull-up", NULL) != NULL) {
+ pull = GPIO_PULL_UP;
+ } else if (fdt_getprop(fdt, node, "bias-pull-down", NULL) != NULL) {
+ pull = GPIO_PULL_DOWN;
+ } else {
+ VERBOSE("No bias configured in node %d\n", node);
+ }
+
+ for (i = 0U; i < ((uint32_t)len / sizeof(uint32_t)); i++) {
+ uint32_t pincfg;
+ uint32_t bank;
+ uint32_t pin;
+ uint32_t mode;
+ uint32_t alternate = GPIO_ALTERNATE_(0);
+ int bank_node;
+ int clk;
+
+ pincfg = fdt32_to_cpu(*cuint);
+ cuint++;
+
+ bank = (pincfg & DT_GPIO_BANK_MASK) >> DT_GPIO_BANK_SHIFT;
+
+ pin = (pincfg & DT_GPIO_PIN_MASK) >> DT_GPIO_PIN_SHIFT;
+
+ mode = pincfg & DT_GPIO_MODE_MASK;
+
+ switch (mode) {
+ case 0:
+ mode = GPIO_MODE_INPUT;
+ break;
+ case 1 ... 16:
+ alternate = mode - 1U;
+ mode = GPIO_MODE_ALTERNATE;
+ break;
+ case 17:
+ mode = GPIO_MODE_ANALOG;
+ break;
+ default:
+ mode = GPIO_MODE_OUTPUT;
+ break;
+ }
+
+ if (fdt_getprop(fdt, node, "drive-open-drain", NULL) != NULL) {
+ mode |= GPIO_OPEN_DRAIN;
+ }
+
+ bank_node = ckeck_gpio_bank(fdt, bank, pinctrl_node);
+ if (bank_node == 0) {
+ ERROR("PINCTRL inconsistent in DT\n");
+ panic();
+ }
+
+ clk = fdt_get_clock_id(bank_node);
+ if (clk < 0) {
+ return -FDT_ERR_NOTFOUND;
+ }
+
+ /* Platform knows the clock: assert it is okay */
+ assert((unsigned long)clk == stm32_get_gpio_bank_clock(bank));
+
+ set_gpio(bank, pin, mode, speed, pull, alternate, status);
+ }
+
+ return 0;
+}
+
+/*******************************************************************************
+ * This function gets the pin settings from DT information.
+ * When analyze and parsing is done, set the GPIO registers.
+ * Returns 0 on success and a negative FDT/ERRNO error code on failure.
+ ******************************************************************************/
+int dt_set_pinctrl_config(int node)
+{
+ const fdt32_t *cuint;
+ int lenp = 0;
+ uint32_t i;
+ uint8_t status = fdt_get_status(node);
+ void *fdt;
+
+ if (fdt_get_address(&fdt) == 0) {
+ return -ENOENT;
+ }
+
+ if (status == DT_DISABLED) {
+ return -FDT_ERR_NOTFOUND;
+ }
+
+ cuint = fdt_getprop(fdt, node, "pinctrl-0", &lenp);
+ if (cuint == NULL) {
+ return -FDT_ERR_NOTFOUND;
+ }
+
+ for (i = 0; i < ((uint32_t)lenp / 4U); i++) {
+ int p_node, p_subnode;
+
+ p_node = fdt_node_offset_by_phandle(fdt, fdt32_to_cpu(*cuint));
+ if (p_node < 0) {
+ return -FDT_ERR_NOTFOUND;
+ }
+
+ fdt_for_each_subnode(p_subnode, fdt, p_node) {
+ int ret = dt_set_gpio_config(fdt, p_subnode, status);
+
+ if (ret < 0) {
+ return ret;
+ }
+ }
+
+ cuint++;
+ }
+
+ return 0;
}
void set_gpio(uint32_t bank, uint32_t pin, uint32_t mode, uint32_t speed,
- uint32_t pull, uint32_t alternate)
+ uint32_t pull, uint32_t alternate, uint8_t status)
{
- volatile uint32_t bank_address;
+ uintptr_t base = stm32_get_gpio_bank_base(bank);
+ unsigned long clock = stm32_get_gpio_bank_clock(bank);
- if (!check_gpio(bank, pin)) {
- return;
- }
+ assert(pin <= GPIO_PIN_MAX);
- if (bank == GPIO_BANK_Z) {
- bank_address = STM32_GPIOZ_BANK;
- } else {
- bank_address = STM32_GPIOA_BANK +
- (bank * STM32_GPIO_BANK_OFFSET);
- }
+ stm32mp1_clk_enable(clock);
- mmio_clrbits_32(bank_address + GPIO_MODE_OFFSET,
+ mmio_clrbits_32(base + GPIO_MODE_OFFSET,
((uint32_t)GPIO_MODE_MASK << (pin << 1)));
- mmio_setbits_32(bank_address + GPIO_MODE_OFFSET,
+ mmio_setbits_32(base + GPIO_MODE_OFFSET,
(mode & ~GPIO_OPEN_DRAIN) << (pin << 1));
if ((mode & GPIO_OPEN_DRAIN) != 0U) {
- mmio_setbits_32(bank_address + GPIO_TYPE_OFFSET,
- BIT(pin));
+ mmio_setbits_32(base + GPIO_TYPE_OFFSET, BIT(pin));
+ } else {
+ mmio_clrbits_32(base + GPIO_TYPE_OFFSET, BIT(pin));
}
- mmio_clrbits_32(bank_address + GPIO_SPEED_OFFSET,
+ mmio_clrbits_32(base + GPIO_SPEED_OFFSET,
((uint32_t)GPIO_SPEED_MASK << (pin << 1)));
- mmio_setbits_32(bank_address + GPIO_SPEED_OFFSET, speed << (pin << 1));
+ mmio_setbits_32(base + GPIO_SPEED_OFFSET, speed << (pin << 1));
- mmio_clrbits_32(bank_address + GPIO_PUPD_OFFSET,
+ mmio_clrbits_32(base + GPIO_PUPD_OFFSET,
((uint32_t)GPIO_PULL_MASK << (pin << 1)));
- mmio_setbits_32(bank_address + GPIO_PUPD_OFFSET, pull << (pin << 1));
+ mmio_setbits_32(base + GPIO_PUPD_OFFSET, pull << (pin << 1));
if (pin < GPIO_ALT_LOWER_LIMIT) {
- mmio_clrbits_32(bank_address + GPIO_AFRL_OFFSET,
+ mmio_clrbits_32(base + GPIO_AFRL_OFFSET,
((uint32_t)GPIO_ALTERNATE_MASK << (pin << 2)));
- mmio_setbits_32(bank_address + GPIO_AFRL_OFFSET,
+ mmio_setbits_32(base + GPIO_AFRL_OFFSET,
alternate << (pin << 2));
} else {
- mmio_clrbits_32(bank_address + GPIO_AFRH_OFFSET,
+ mmio_clrbits_32(base + GPIO_AFRH_OFFSET,
((uint32_t)GPIO_ALTERNATE_MASK <<
((pin - GPIO_ALT_LOWER_LIMIT) << 2)));
- mmio_setbits_32(bank_address + GPIO_AFRH_OFFSET,
+ mmio_setbits_32(base + GPIO_AFRH_OFFSET,
alternate << ((pin - GPIO_ALT_LOWER_LIMIT) <<
2));
}
VERBOSE("GPIO %u mode set to 0x%x\n", bank,
- mmio_read_32(bank_address + GPIO_MODE_OFFSET));
+ mmio_read_32(base + GPIO_MODE_OFFSET));
VERBOSE("GPIO %u speed set to 0x%x\n", bank,
- mmio_read_32(bank_address + GPIO_SPEED_OFFSET));
+ mmio_read_32(base + GPIO_SPEED_OFFSET));
VERBOSE("GPIO %u mode pull to 0x%x\n", bank,
- mmio_read_32(bank_address + GPIO_PUPD_OFFSET));
+ mmio_read_32(base + GPIO_PUPD_OFFSET));
VERBOSE("GPIO %u mode alternate low to 0x%x\n", bank,
- mmio_read_32(bank_address + GPIO_AFRL_OFFSET));
+ mmio_read_32(base + GPIO_AFRL_OFFSET));
VERBOSE("GPIO %u mode alternate high to 0x%x\n", bank,
- mmio_read_32(bank_address + GPIO_AFRH_OFFSET));
+ mmio_read_32(base + GPIO_AFRH_OFFSET));
+
+ stm32mp1_clk_disable((unsigned long)clock);
+}
+
+void set_gpio_secure_cfg(uint32_t bank, uint32_t pin, bool secure)
+{
+ uintptr_t base = stm32_get_gpio_bank_base(bank);
+ int clock = stm32_get_gpio_bank_clock(bank);
+
+ assert(pin <= GPIO_PIN_MAX);
+
+ stm32mp1_clk_enable((unsigned long)clock);
+
+ if (secure) {
+ mmio_setbits_32(base + GPIO_SECR_OFFSET, BIT(pin));
+ } else {
+ mmio_clrbits_32(base + GPIO_SECR_OFFSET, BIT(pin));
+ }
+
+ stm32mp1_clk_disable((unsigned long)clock);
}
diff --git a/drivers/st/pmic/stm32_i2c.c b/drivers/st/i2c/stm32_i2c.c
similarity index 99%
rename from drivers/st/pmic/stm32_i2c.c
rename to drivers/st/i2c/stm32_i2c.c
index f861ba2..2be7afe 100644
--- a/drivers/st/pmic/stm32_i2c.c
+++ b/drivers/st/i2c/stm32_i2c.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2016-2018, STMicroelectronics - All Rights Reserved
+ * Copyright (c) 2016-2019, STMicroelectronics - All Rights Reserved
*
* SPDX-License-Identifier: BSD-3-Clause
*/
diff --git a/drivers/st/io/io_stm32image.c b/drivers/st/io/io_stm32image.c
index 0164a2d..dc2977d 100644
--- a/drivers/st/io/io_stm32image.c
+++ b/drivers/st/io/io_stm32image.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2018, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2018-2019, ARM Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -94,6 +94,8 @@
for (i = 0; i < STM32_PART_NUM; i++) {
memcpy(stm32image_dev.part_info[i].name,
device_info->part_info[i].name, MAX_PART_NAME_SIZE);
+ stm32image_dev.part_info[i].binary_type =
+ device_info->part_info[i].binary_type;
stm32image_dev.part_info[i].part_offset =
device_info->part_info[i].part_offset;
stm32image_dev.part_info[i].bkp_offset =
@@ -193,21 +195,29 @@
result = io_read(backend_handle, (uintptr_t)header,
MAX_LBA_SIZE, (size_t *)&bytes_read);
if (result != 0) {
- ERROR("%s: io_read (%i)\n", __func__, result);
- break;
+ if (current_part->bkp_offset == 0U) {
+ ERROR("%s: io_read (%i)\n", __func__, result);
+ }
+ header->magic = 0;
}
if ((header->magic != BOOT_API_IMAGE_HEADER_MAGIC_NB) ||
(header->binary_type != current_part->binary_type) ||
(header->image_length >= stm32image_dev.device_size)) {
- WARN("%s: partition %s wrong header\n",
- __func__, current_part->name);
+ VERBOSE("%s: partition %s not found at %x\n",
+ __func__, current_part->name, *stm32_img);
+
+ if (current_part->bkp_offset == 0U) {
+ result = -ENOMEM;
+ break;
+ }
/* Header not correct, check next offset for backup */
*stm32_img += current_part->bkp_offset;
if (*stm32_img > stm32image_dev.device_size) {
/* No backup found, end of device reached */
- WARN("Out of memory\n");
+ WARN("%s : partition %s not found\n",
+ __func__, current_part->name);
result = -ENOMEM;
break;
}
@@ -221,9 +231,13 @@
return result;
}
- *length = header->image_length;
+ if (header->image_length < stm32image_dev.lba_size) {
+ *length = stm32image_dev.lba_size;
+ } else {
+ *length = header->image_length;
+ }
- INFO("STM32 Image size : %i\n", *length);
+ INFO("STM32 Image size : %lu\n", (unsigned long)*length);
return 0;
}
@@ -266,11 +280,10 @@
static int stm32image_partition_read(io_entity_t *entity, uintptr_t buffer,
size_t length, size_t *length_read)
{
- int result = 0, offset, local_length = 0;
+ int result = 0;
uint8_t *local_buffer = (uint8_t *)buffer;
boot_api_image_header_t *header =
(boot_api_image_header_t *)first_lba_buffer;
- uintptr_t backend_handle;
assert(entity != NULL);
assert(buffer != 0U);
@@ -279,8 +292,17 @@
*length_read = 0U;
while (*length_read == 0U) {
+ int offset;
+ int local_length;
+ uintptr_t backend_handle;
+
if (header->magic != BOOT_API_IMAGE_HEADER_MAGIC_NB) {
/* Check for backup as image is corrupted */
+ if (current_part->bkp_offset == 0U) {
+ result = -ENOMEM;
+ break;
+ }
+
*stm32_img += current_part->bkp_offset;
if (*stm32_img >= stm32image_dev.device_size) {
/* End of device reached */
@@ -342,8 +364,8 @@
if (result != 0) {
ERROR("%s: io_read (%i)\n", __func__, result);
*length_read = 0;
- io_close(backend_handle);
- break;
+ header->magic = 0;
+ continue;
}
result = check_header(header, buffer);
@@ -351,8 +373,6 @@
ERROR("Header check failed\n");
*length_read = 0;
header->magic = 0;
- io_close(backend_handle);
- break;
}
io_close(backend_handle);
diff --git a/drivers/st/mmc/stm32_sdmmc2.c b/drivers/st/mmc/stm32_sdmmc2.c
index 05f5ae1..57812d8 100644
--- a/drivers/st/mmc/stm32_sdmmc2.c
+++ b/drivers/st/mmc/stm32_sdmmc2.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2018, STMicroelectronics - All Rights Reserved
+ * Copyright (c) 2018-2019, STMicroelectronics - All Rights Reserved
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -17,6 +17,7 @@
#include <common/debug.h>
#include <drivers/delay_timer.h>
#include <drivers/mmc.h>
+#include <drivers/st/stm32_gpio.h>
#include <drivers/st/stm32_sdmmc2.h>
#include <drivers/st/stm32mp1_clk.h>
#include <drivers/st/stm32mp1_rcc.h>
@@ -470,12 +471,11 @@
}
/* Prepare CMD 16*/
- mmio_write_32(base + SDMMC_DTIMER, UINT32_MAX);
+ mmio_write_32(base + SDMMC_DTIMER, 0);
mmio_write_32(base + SDMMC_DLENR, 0);
- mmio_clrsetbits_32(base + SDMMC_DCTRLR,
- SDMMC_DCTRLR_CLEAR_MASK, SDMMC_DCTRLR_DTDIR);
+ mmio_write_32(base + SDMMC_DCTRLR, 0);
zeromem(&cmd, sizeof(struct mmc_cmd));
@@ -643,7 +643,7 @@
return -FDT_ERR_NOTFOUND;
}
- if (fdt_check_status(sdmmc_node) == 0) {
+ if (fdt_get_status(sdmmc_node) == DT_DISABLED) {
return -FDT_ERR_NOTFOUND;
}
@@ -667,15 +667,15 @@
cuint++;
sdmmc2_params.reset_id = fdt32_to_cpu(*cuint);
- if ((fdt_getprop(fdt, sdmmc_node, "st,pin-ckin", NULL)) != NULL) {
+ if ((fdt_getprop(fdt, sdmmc_node, "st,use-ckin", NULL)) != NULL) {
sdmmc2_params.pin_ckin = SDMMC_CLKCR_SELCLKRX_0;
}
- if ((fdt_getprop(fdt, sdmmc_node, "st,dirpol", NULL)) != NULL) {
+ if ((fdt_getprop(fdt, sdmmc_node, "st,sig-dir", NULL)) != NULL) {
sdmmc2_params.dirpol = SDMMC_POWER_DIRPOL;
}
- if ((fdt_getprop(fdt, sdmmc_node, "st,negedge", NULL)) != NULL) {
+ if ((fdt_getprop(fdt, sdmmc_node, "st,neg-edge", NULL)) != NULL) {
sdmmc2_params.negedge = SDMMC_CLKCR_NEGEDGE;
}
diff --git a/drivers/st/pmic/stm32mp1_pmic.c b/drivers/st/pmic/stm32mp_pmic.c
similarity index 69%
rename from drivers/st/pmic/stm32mp1_pmic.c
rename to drivers/st/pmic/stm32mp_pmic.c
index c5bdfc0..6beabc1 100644
--- a/drivers/st/pmic/stm32mp1_pmic.c
+++ b/drivers/st/pmic/stm32mp_pmic.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2017-2018, STMicroelectronics - All Rights Reserved
+ * Copyright (c) 2017-2019, STMicroelectronics - All Rights Reserved
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -13,10 +13,10 @@
#include <common/debug.h>
#include <drivers/delay_timer.h>
+#include <drivers/st/stm32mp_pmic.h>
#include <drivers/st/stm32_gpio.h>
#include <drivers/st/stm32mp1_clk.h>
-#include <drivers/st/stm32mp1_pmic.h>
-#include <drivers/st/stpmu1.h>
+#include <drivers/st/stpmic1.h>
#include <lib/mmio.h>
#include <lib/utils_def.h>
@@ -27,23 +27,23 @@
#define MASK_RESET_BUCK3 BIT(2)
-#define STPMU1_LDO12356_OUTPUT_MASK (uint8_t)(GENMASK(6, 2))
-#define STPMU1_LDO12356_OUTPUT_SHIFT 2
-#define STPMU1_LDO3_MODE (uint8_t)(BIT(7))
-#define STPMU1_LDO3_DDR_SEL 31U
-#define STPMU1_LDO3_1800000 (9U << STPMU1_LDO12356_OUTPUT_SHIFT)
+#define STPMIC1_LDO12356_OUTPUT_MASK (uint8_t)(GENMASK(6, 2))
+#define STPMIC1_LDO12356_OUTPUT_SHIFT 2
+#define STPMIC1_LDO3_MODE (uint8_t)(BIT(7))
+#define STPMIC1_LDO3_DDR_SEL 31U
+#define STPMIC1_LDO3_1800000 (9U << STPMIC1_LDO12356_OUTPUT_SHIFT)
-#define STPMU1_BUCK_OUTPUT_SHIFT 2
-#define STPMU1_BUCK3_1V8 (39U << STPMU1_BUCK_OUTPUT_SHIFT)
+#define STPMIC1_BUCK_OUTPUT_SHIFT 2
+#define STPMIC1_BUCK3_1V8 (39U << STPMIC1_BUCK_OUTPUT_SHIFT)
-#define STPMU1_DEFAULT_START_UP_DELAY_MS 1
+#define STPMIC1_DEFAULT_START_UP_DELAY_MS 1
static struct i2c_handle_s i2c_handle;
static uint32_t pmic_i2c_addr;
static int dt_get_pmic_node(void *fdt)
{
- return fdt_node_offset_by_compatible(fdt, -1, "st,stpmu1");
+ return fdt_node_offset_by_compatible(fdt, -1, "st,stpmic1");
}
bool dt_check_pmic(void)
@@ -61,7 +61,7 @@
return false;
}
- return fdt_check_status(node);
+ return fdt_get_status(node);
}
static int dt_pmic_i2c_config(struct dt_node_info *i2c_info)
@@ -138,16 +138,16 @@
voltage = (uint16_t)(fdt32_to_cpu(*cuint) / 1000U);
node_name = fdt_get_name(fdt, regulator_node, NULL);
- if (stpmu1_is_regulator_enabled(node_name) == 0U) {
+ if (stpmic1_is_regulator_enabled(node_name) == 0U) {
int status;
- status = stpmu1_regulator_voltage_set(node_name,
- voltage);
+ status = stpmic1_regulator_voltage_set(node_name,
+ voltage);
if (status != 0) {
return status;
}
- status = stpmu1_regulator_enable(node_name);
+ status = stpmic1_regulator_enable(node_name);
if (status != 0) {
return status;
}
@@ -204,7 +204,7 @@
panic();
}
- stpmu1_bind_i2c(&i2c_handle, (uint16_t)pmic_i2c_addr);
+ stpmic1_bind_i2c(&i2c_handle, (uint16_t)pmic_i2c_addr);
}
void initialize_pmic(void)
@@ -214,7 +214,7 @@
initialize_pmic_i2c();
- status = stpmu1_register_read(VERSION_STATUS_REG, &read_val);
+ status = stpmic1_register_read(VERSION_STATUS_REG, &read_val);
if (status != 0) {
panic();
}
@@ -222,7 +222,7 @@
INFO("PMIC version = 0x%x\n", read_val);
/* Keep VDD on during the reset cycle */
- status = stpmu1_register_update(MASK_RESET_BUCK_REG,
+ status = stpmic1_register_update(MASK_RESET_BUCK_REG,
MASK_RESET_BUCK3,
MASK_RESET_BUCK3);
if (status != 0) {
@@ -239,45 +239,46 @@
switch (ddr_type) {
case STM32MP_DDR3:
/* Set LDO3 to sync mode */
- status = stpmu1_register_read(LDO3_CONTROL_REG, &read_val);
+ status = stpmic1_register_read(LDO3_CONTROL_REG, &read_val);
if (status != 0) {
return status;
}
- read_val &= ~STPMU1_LDO3_MODE;
- read_val &= ~STPMU1_LDO12356_OUTPUT_MASK;
- read_val |= STPMU1_LDO3_DDR_SEL << STPMU1_LDO12356_OUTPUT_SHIFT;
+ read_val &= ~STPMIC1_LDO3_MODE;
+ read_val &= ~STPMIC1_LDO12356_OUTPUT_MASK;
+ read_val |= STPMIC1_LDO3_DDR_SEL <<
+ STPMIC1_LDO12356_OUTPUT_SHIFT;
- status = stpmu1_register_write(LDO3_CONTROL_REG, read_val);
+ status = stpmic1_register_write(LDO3_CONTROL_REG, read_val);
if (status != 0) {
return status;
}
- status = stpmu1_regulator_voltage_set("buck2", 1350);
+ status = stpmic1_regulator_voltage_set("buck2", 1350);
if (status != 0) {
return status;
}
- status = stpmu1_regulator_enable("buck2");
+ status = stpmic1_regulator_enable("buck2");
if (status != 0) {
return status;
}
- mdelay(STPMU1_DEFAULT_START_UP_DELAY_MS);
+ mdelay(STPMIC1_DEFAULT_START_UP_DELAY_MS);
- status = stpmu1_regulator_enable("vref_ddr");
+ status = stpmic1_regulator_enable("vref_ddr");
if (status != 0) {
return status;
}
- mdelay(STPMU1_DEFAULT_START_UP_DELAY_MS);
+ mdelay(STPMIC1_DEFAULT_START_UP_DELAY_MS);
- status = stpmu1_regulator_enable("ldo3");
+ status = stpmic1_regulator_enable("ldo3");
if (status != 0) {
return status;
}
- mdelay(STPMU1_DEFAULT_START_UP_DELAY_MS);
+ mdelay(STPMIC1_DEFAULT_START_UP_DELAY_MS);
break;
case STM32MP_LPDDR2:
@@ -286,57 +287,57 @@
* Set LDO3 to bypass mode if BUCK3 = 1.8V
* Set LDO3 to normal mode if BUCK3 != 1.8V
*/
- status = stpmu1_register_read(BUCK3_CONTROL_REG, &read_val);
+ status = stpmic1_register_read(BUCK3_CONTROL_REG, &read_val);
if (status != 0) {
return status;
}
- if ((read_val & STPMU1_BUCK3_1V8) == STPMU1_BUCK3_1V8) {
+ if ((read_val & STPMIC1_BUCK3_1V8) == STPMIC1_BUCK3_1V8) {
buck3_at_1v8 = true;
}
- status = stpmu1_register_read(LDO3_CONTROL_REG, &read_val);
+ status = stpmic1_register_read(LDO3_CONTROL_REG, &read_val);
if (status != 0) {
return status;
}
- read_val &= ~STPMU1_LDO3_MODE;
- read_val &= ~STPMU1_LDO12356_OUTPUT_MASK;
- read_val |= STPMU1_LDO3_1800000;
+ read_val &= ~STPMIC1_LDO3_MODE;
+ read_val &= ~STPMIC1_LDO12356_OUTPUT_MASK;
+ read_val |= STPMIC1_LDO3_1800000;
if (buck3_at_1v8) {
- read_val |= STPMU1_LDO3_MODE;
+ read_val |= STPMIC1_LDO3_MODE;
}
- status = stpmu1_register_write(LDO3_CONTROL_REG, read_val);
+ status = stpmic1_register_write(LDO3_CONTROL_REG, read_val);
if (status != 0) {
return status;
}
- status = stpmu1_regulator_voltage_set("buck2", 1200);
+ status = stpmic1_regulator_voltage_set("buck2", 1200);
if (status != 0) {
return status;
}
- status = stpmu1_regulator_enable("ldo3");
+ status = stpmic1_regulator_enable("ldo3");
if (status != 0) {
return status;
}
- mdelay(STPMU1_DEFAULT_START_UP_DELAY_MS);
+ mdelay(STPMIC1_DEFAULT_START_UP_DELAY_MS);
- status = stpmu1_regulator_enable("buck2");
+ status = stpmic1_regulator_enable("buck2");
if (status != 0) {
return status;
}
- mdelay(STPMU1_DEFAULT_START_UP_DELAY_MS);
+ mdelay(STPMIC1_DEFAULT_START_UP_DELAY_MS);
- status = stpmu1_regulator_enable("vref_ddr");
+ status = stpmic1_regulator_enable("vref_ddr");
if (status != 0) {
return status;
}
- mdelay(STPMU1_DEFAULT_START_UP_DELAY_MS);
+ mdelay(STPMIC1_DEFAULT_START_UP_DELAY_MS);
break;
default:
diff --git a/drivers/st/pmic/stpmic1.c b/drivers/st/pmic/stpmic1.c
new file mode 100644
index 0000000..465996d
--- /dev/null
+++ b/drivers/st/pmic/stpmic1.c
@@ -0,0 +1,762 @@
+/*
+ * Copyright (c) 2016-2019, STMicroelectronics - All Rights Reserved
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <string.h>
+
+#include <common/debug.h>
+#include <drivers/st/stpmic1.h>
+#include <plat/common/platform.h>
+
+struct regul_struct {
+ const char *dt_node_name;
+ const uint16_t *voltage_table;
+ uint8_t voltage_table_size;
+ uint8_t control_reg;
+ uint8_t low_power_reg;
+ uint8_t pull_down_reg;
+ uint8_t pull_down;
+ uint8_t mask_reset_reg;
+ uint8_t mask_reset;
+};
+
+static struct i2c_handle_s *pmic_i2c_handle;
+static uint16_t pmic_i2c_addr;
+
+/* Voltage tables in mV */
+static const uint16_t buck1_voltage_table[] = {
+ 725,
+ 725,
+ 725,
+ 725,
+ 725,
+ 725,
+ 750,
+ 775,
+ 800,
+ 825,
+ 850,
+ 875,
+ 900,
+ 925,
+ 950,
+ 975,
+ 1000,
+ 1025,
+ 1050,
+ 1075,
+ 1100,
+ 1125,
+ 1150,
+ 1175,
+ 1200,
+ 1225,
+ 1250,
+ 1275,
+ 1300,
+ 1325,
+ 1350,
+ 1375,
+ 1400,
+ 1425,
+ 1450,
+ 1475,
+ 1500,
+ 1500,
+ 1500,
+ 1500,
+ 1500,
+ 1500,
+ 1500,
+ 1500,
+ 1500,
+ 1500,
+ 1500,
+ 1500,
+ 1500,
+ 1500,
+ 1500,
+ 1500,
+ 1500,
+ 1500,
+ 1500,
+ 1500,
+ 1500,
+ 1500,
+ 1500,
+ 1500,
+ 1500,
+ 1500,
+ 1500,
+ 1500,
+};
+
+static const uint16_t buck2_voltage_table[] = {
+ 1000,
+ 1000,
+ 1000,
+ 1000,
+ 1000,
+ 1000,
+ 1000,
+ 1000,
+ 1000,
+ 1000,
+ 1000,
+ 1000,
+ 1000,
+ 1000,
+ 1000,
+ 1000,
+ 1000,
+ 1000,
+ 1050,
+ 1050,
+ 1100,
+ 1100,
+ 1150,
+ 1150,
+ 1200,
+ 1200,
+ 1250,
+ 1250,
+ 1300,
+ 1300,
+ 1350,
+ 1350,
+ 1400,
+ 1400,
+ 1450,
+ 1450,
+ 1500,
+};
+
+static const uint16_t buck3_voltage_table[] = {
+ 1000,
+ 1000,
+ 1000,
+ 1000,
+ 1000,
+ 1000,
+ 1000,
+ 1000,
+ 1000,
+ 1000,
+ 1000,
+ 1000,
+ 1000,
+ 1000,
+ 1000,
+ 1000,
+ 1000,
+ 1000,
+ 1000,
+ 1000,
+ 1100,
+ 1100,
+ 1100,
+ 1100,
+ 1200,
+ 1200,
+ 1200,
+ 1200,
+ 1300,
+ 1300,
+ 1300,
+ 1300,
+ 1400,
+ 1400,
+ 1400,
+ 1400,
+ 1500,
+ 1600,
+ 1700,
+ 1800,
+ 1900,
+ 2000,
+ 2100,
+ 2200,
+ 2300,
+ 2400,
+ 2500,
+ 2600,
+ 2700,
+ 2800,
+ 2900,
+ 3000,
+ 3100,
+ 3200,
+ 3300,
+ 3400,
+};
+
+static const uint16_t buck4_voltage_table[] = {
+ 600,
+ 625,
+ 650,
+ 675,
+ 700,
+ 725,
+ 750,
+ 775,
+ 800,
+ 825,
+ 850,
+ 875,
+ 900,
+ 925,
+ 950,
+ 975,
+ 1000,
+ 1025,
+ 1050,
+ 1075,
+ 1100,
+ 1125,
+ 1150,
+ 1175,
+ 1200,
+ 1225,
+ 1250,
+ 1275,
+ 1300,
+ 1300,
+ 1350,
+ 1350,
+ 1400,
+ 1400,
+ 1450,
+ 1450,
+ 1500,
+ 1600,
+ 1700,
+ 1800,
+ 1900,
+ 2000,
+ 2100,
+ 2200,
+ 2300,
+ 2400,
+ 2500,
+ 2600,
+ 2700,
+ 2800,
+ 2900,
+ 3000,
+ 3100,
+ 3200,
+ 3300,
+ 3400,
+ 3500,
+ 3600,
+ 3700,
+ 3800,
+ 3900,
+};
+
+static const uint16_t ldo1_voltage_table[] = {
+ 1700,
+ 1700,
+ 1700,
+ 1700,
+ 1700,
+ 1700,
+ 1700,
+ 1700,
+ 1700,
+ 1800,
+ 1900,
+ 2000,
+ 2100,
+ 2200,
+ 2300,
+ 2400,
+ 2500,
+ 2600,
+ 2700,
+ 2800,
+ 2900,
+ 3000,
+ 3100,
+ 3200,
+ 3300,
+};
+
+static const uint16_t ldo2_voltage_table[] = {
+ 1700,
+ 1700,
+ 1700,
+ 1700,
+ 1700,
+ 1700,
+ 1700,
+ 1700,
+ 1700,
+ 1800,
+ 1900,
+ 2000,
+ 2100,
+ 2200,
+ 2300,
+ 2400,
+ 2500,
+ 2600,
+ 2700,
+ 2800,
+ 2900,
+ 3000,
+ 3100,
+ 3200,
+ 3300,
+};
+
+static const uint16_t ldo3_voltage_table[] = {
+ 1700,
+ 1700,
+ 1700,
+ 1700,
+ 1700,
+ 1700,
+ 1700,
+ 1700,
+ 1700,
+ 1800,
+ 1900,
+ 2000,
+ 2100,
+ 2200,
+ 2300,
+ 2400,
+ 2500,
+ 2600,
+ 2700,
+ 2800,
+ 2900,
+ 3000,
+ 3100,
+ 3200,
+ 3300,
+ 3300,
+ 3300,
+ 3300,
+ 3300,
+ 3300,
+ 3300,
+ 500,
+ 0xFFFF, /* VREFDDR */
+};
+
+static const uint16_t ldo5_voltage_table[] = {
+ 1700,
+ 1700,
+ 1700,
+ 1700,
+ 1700,
+ 1700,
+ 1700,
+ 1700,
+ 1700,
+ 1800,
+ 1900,
+ 2000,
+ 2100,
+ 2200,
+ 2300,
+ 2400,
+ 2500,
+ 2600,
+ 2700,
+ 2800,
+ 2900,
+ 3000,
+ 3100,
+ 3200,
+ 3300,
+ 3400,
+ 3500,
+ 3600,
+ 3700,
+ 3800,
+ 3900,
+};
+
+static const uint16_t ldo6_voltage_table[] = {
+ 900,
+ 1000,
+ 1100,
+ 1200,
+ 1300,
+ 1400,
+ 1500,
+ 1600,
+ 1700,
+ 1800,
+ 1900,
+ 2000,
+ 2100,
+ 2200,
+ 2300,
+ 2400,
+ 2500,
+ 2600,
+ 2700,
+ 2800,
+ 2900,
+ 3000,
+ 3100,
+ 3200,
+ 3300,
+};
+
+static const uint16_t ldo4_voltage_table[] = {
+ 3300,
+};
+
+static const uint16_t vref_ddr_voltage_table[] = {
+ 3300,
+};
+
+/* Table of Regulators in PMIC SoC */
+static const struct regul_struct regulators_table[] = {
+ {
+ .dt_node_name = "buck1",
+ .voltage_table = buck1_voltage_table,
+ .voltage_table_size = ARRAY_SIZE(buck1_voltage_table),
+ .control_reg = BUCK1_CONTROL_REG,
+ .low_power_reg = BUCK1_PWRCTRL_REG,
+ .pull_down_reg = BUCK_PULL_DOWN_REG,
+ .pull_down = BUCK1_PULL_DOWN_SHIFT,
+ .mask_reset_reg = MASK_RESET_BUCK_REG,
+ .mask_reset = BUCK1_MASK_RESET,
+ },
+ {
+ .dt_node_name = "buck2",
+ .voltage_table = buck2_voltage_table,
+ .voltage_table_size = ARRAY_SIZE(buck2_voltage_table),
+ .control_reg = BUCK2_CONTROL_REG,
+ .low_power_reg = BUCK2_PWRCTRL_REG,
+ .pull_down_reg = BUCK_PULL_DOWN_REG,
+ .pull_down = BUCK2_PULL_DOWN_SHIFT,
+ .mask_reset_reg = MASK_RESET_BUCK_REG,
+ .mask_reset = BUCK2_MASK_RESET,
+ },
+ {
+ .dt_node_name = "buck3",
+ .voltage_table = buck3_voltage_table,
+ .voltage_table_size = ARRAY_SIZE(buck3_voltage_table),
+ .control_reg = BUCK3_CONTROL_REG,
+ .low_power_reg = BUCK3_PWRCTRL_REG,
+ .pull_down_reg = BUCK_PULL_DOWN_REG,
+ .pull_down = BUCK3_PULL_DOWN_SHIFT,
+ .mask_reset_reg = MASK_RESET_BUCK_REG,
+ .mask_reset = BUCK3_MASK_RESET,
+ },
+ {
+ .dt_node_name = "buck4",
+ .voltage_table = buck4_voltage_table,
+ .voltage_table_size = ARRAY_SIZE(buck4_voltage_table),
+ .control_reg = BUCK4_CONTROL_REG,
+ .low_power_reg = BUCK4_PWRCTRL_REG,
+ .pull_down_reg = BUCK_PULL_DOWN_REG,
+ .pull_down = BUCK4_PULL_DOWN_SHIFT,
+ .mask_reset_reg = MASK_RESET_BUCK_REG,
+ .mask_reset = BUCK4_MASK_RESET,
+ },
+ {
+ .dt_node_name = "ldo1",
+ .voltage_table = ldo1_voltage_table,
+ .voltage_table_size = ARRAY_SIZE(ldo1_voltage_table),
+ .control_reg = LDO1_CONTROL_REG,
+ .low_power_reg = LDO1_PWRCTRL_REG,
+ .mask_reset_reg = MASK_RESET_LDO_REG,
+ .mask_reset = LDO1_MASK_RESET,
+ },
+ {
+ .dt_node_name = "ldo2",
+ .voltage_table = ldo2_voltage_table,
+ .voltage_table_size = ARRAY_SIZE(ldo2_voltage_table),
+ .control_reg = LDO2_CONTROL_REG,
+ .low_power_reg = LDO2_PWRCTRL_REG,
+ .mask_reset_reg = MASK_RESET_LDO_REG,
+ .mask_reset = LDO2_MASK_RESET,
+ },
+ {
+ .dt_node_name = "ldo3",
+ .voltage_table = ldo3_voltage_table,
+ .voltage_table_size = ARRAY_SIZE(ldo3_voltage_table),
+ .control_reg = LDO3_CONTROL_REG,
+ .low_power_reg = LDO3_PWRCTRL_REG,
+ .mask_reset_reg = MASK_RESET_LDO_REG,
+ .mask_reset = LDO3_MASK_RESET,
+ },
+ {
+ .dt_node_name = "ldo4",
+ .voltage_table = ldo4_voltage_table,
+ .voltage_table_size = ARRAY_SIZE(ldo4_voltage_table),
+ .control_reg = LDO4_CONTROL_REG,
+ .low_power_reg = LDO4_PWRCTRL_REG,
+ .mask_reset_reg = MASK_RESET_LDO_REG,
+ .mask_reset = LDO4_MASK_RESET,
+ },
+ {
+ .dt_node_name = "ldo5",
+ .voltage_table = ldo5_voltage_table,
+ .voltage_table_size = ARRAY_SIZE(ldo5_voltage_table),
+ .control_reg = LDO5_CONTROL_REG,
+ .low_power_reg = LDO5_PWRCTRL_REG,
+ .mask_reset_reg = MASK_RESET_LDO_REG,
+ .mask_reset = LDO5_MASK_RESET,
+ },
+ {
+ .dt_node_name = "ldo6",
+ .voltage_table = ldo6_voltage_table,
+ .voltage_table_size = ARRAY_SIZE(ldo6_voltage_table),
+ .control_reg = LDO6_CONTROL_REG,
+ .low_power_reg = LDO6_PWRCTRL_REG,
+ .mask_reset_reg = MASK_RESET_LDO_REG,
+ .mask_reset = LDO6_MASK_RESET,
+ },
+ {
+ .dt_node_name = "vref_ddr",
+ .voltage_table = vref_ddr_voltage_table,
+ .voltage_table_size = ARRAY_SIZE(vref_ddr_voltage_table),
+ .control_reg = VREF_DDR_CONTROL_REG,
+ .low_power_reg = VREF_DDR_PWRCTRL_REG,
+ .mask_reset_reg = MASK_RESET_LDO_REG,
+ .mask_reset = VREF_DDR_MASK_RESET,
+ },
+};
+
+#define MAX_REGUL ARRAY_SIZE(regulators_table)
+
+static const struct regul_struct *get_regulator_data(const char *name)
+{
+ uint8_t i;
+
+ for (i = 0 ; i < MAX_REGUL ; i++) {
+ if (strncmp(name, regulators_table[i].dt_node_name,
+ strlen(regulators_table[i].dt_node_name)) == 0) {
+ return ®ulators_table[i];
+ }
+ }
+
+ /* Regulator not found */
+ panic();
+ return NULL;
+}
+
+static uint8_t voltage_to_index(const char *name, uint16_t millivolts)
+{
+ const struct regul_struct *regul = get_regulator_data(name);
+ uint8_t i;
+
+ for (i = 0 ; i < regul->voltage_table_size ; i++) {
+ if (regul->voltage_table[i] == millivolts) {
+ return i;
+ }
+ }
+
+ /* Voltage not found */
+ panic();
+
+ return 0;
+}
+
+int stpmic1_powerctrl_on(void)
+{
+ return stpmic1_register_update(MAIN_CONTROL_REG, PWRCTRL_PIN_VALID,
+ PWRCTRL_PIN_VALID);
+}
+
+int stpmic1_switch_off(void)
+{
+ return stpmic1_register_update(MAIN_CONTROL_REG, 1,
+ SOFTWARE_SWITCH_OFF_ENABLED);
+}
+
+int stpmic1_regulator_enable(const char *name)
+{
+ const struct regul_struct *regul = get_regulator_data(name);
+
+ return stpmic1_register_update(regul->control_reg, BIT(0), BIT(0));
+}
+
+int stpmic1_regulator_disable(const char *name)
+{
+ const struct regul_struct *regul = get_regulator_data(name);
+
+ return stpmic1_register_update(regul->control_reg, 0, BIT(0));
+}
+
+uint8_t stpmic1_is_regulator_enabled(const char *name)
+{
+ uint8_t val;
+ const struct regul_struct *regul = get_regulator_data(name);
+
+ if (stpmic1_register_read(regul->control_reg, &val) != 0) {
+ panic();
+ }
+
+ return (val & 0x1U);
+}
+
+int stpmic1_regulator_voltage_set(const char *name, uint16_t millivolts)
+{
+ uint8_t voltage_index = voltage_to_index(name, millivolts);
+ const struct regul_struct *regul = get_regulator_data(name);
+ uint8_t mask;
+
+ /* Voltage can be set for buck<N> or ldo<N> (except ldo4) regulators */
+ if (strncmp(name, "buck", 4) == 0) {
+ mask = BUCK_VOLTAGE_MASK;
+ } else if ((strncmp(name, "ldo", 3) == 0) &&
+ (strncmp(name, "ldo4", 4) != 0)) {
+ mask = LDO_VOLTAGE_MASK;
+ } else {
+ return 0;
+ }
+
+ return stpmic1_register_update(regul->control_reg,
+ voltage_index << LDO_BUCK_VOLTAGE_SHIFT,
+ mask);
+}
+
+int stpmic1_regulator_pull_down_set(const char *name)
+{
+ const struct regul_struct *regul = get_regulator_data(name);
+
+ if (regul->pull_down_reg != 0) {
+ return stpmic1_register_update(regul->pull_down_reg,
+ BIT(regul->pull_down),
+ LDO_BUCK_PULL_DOWN_MASK <<
+ regul->pull_down);
+ }
+
+ return 0;
+}
+
+int stpmic1_regulator_mask_reset_set(const char *name)
+{
+ const struct regul_struct *regul = get_regulator_data(name);
+
+ return stpmic1_register_update(regul->mask_reset_reg,
+ BIT(regul->mask_reset),
+ LDO_BUCK_RESET_MASK <<
+ regul->mask_reset);
+}
+
+int stpmic1_regulator_voltage_get(const char *name)
+{
+ const struct regul_struct *regul = get_regulator_data(name);
+ uint8_t value;
+ uint8_t mask;
+
+ /* Voltage can be set for buck<N> or ldo<N> (except ldo4) regulators */
+ if (strncmp(name, "buck", 4) == 0) {
+ mask = BUCK_VOLTAGE_MASK;
+ } else if ((strncmp(name, "ldo", 3) == 0) &&
+ (strncmp(name, "ldo4", 4) != 0)) {
+ mask = LDO_VOLTAGE_MASK;
+ } else {
+ return 0;
+ }
+
+ if (stpmic1_register_read(regul->control_reg, &value))
+ return -1;
+
+ value = (value & mask) >> LDO_BUCK_VOLTAGE_SHIFT;
+
+ if (value > regul->voltage_table_size)
+ return -1;
+
+ return (int)regul->voltage_table[value];
+}
+
+int stpmic1_register_read(uint8_t register_id, uint8_t *value)
+{
+ return stm32_i2c_mem_read(pmic_i2c_handle, pmic_i2c_addr,
+ (uint16_t)register_id, I2C_MEMADD_SIZE_8BIT,
+ value, 1, 100000);
+}
+
+int stpmic1_register_write(uint8_t register_id, uint8_t value)
+{
+ int status;
+
+ status = stm32_i2c_mem_write(pmic_i2c_handle, pmic_i2c_addr,
+ (uint16_t)register_id,
+ I2C_MEMADD_SIZE_8BIT, &value, 1, 100000);
+
+#if ENABLE_ASSERTIONS
+ if (status != 0) {
+ return status;
+ }
+
+ if ((register_id != WATCHDOG_CONTROL_REG) && (register_id <= 0x40U)) {
+ uint8_t readval;
+
+ status = stpmic1_register_read(register_id, &readval);
+ if (status != 0) {
+ return status;
+ }
+
+ if (readval != value) {
+ return -1;
+ }
+ }
+#endif
+
+ return status;
+}
+
+int stpmic1_register_update(uint8_t register_id, uint8_t value, uint8_t mask)
+{
+ int status;
+ uint8_t val;
+
+ status = stpmic1_register_read(register_id, &val);
+ if (status != 0) {
+ return status;
+ }
+
+ val = (val & ~mask) | (value & mask);
+
+ return stpmic1_register_write(register_id, val);
+}
+
+void stpmic1_bind_i2c(struct i2c_handle_s *i2c_handle, uint16_t i2c_addr)
+{
+ pmic_i2c_handle = i2c_handle;
+ pmic_i2c_addr = i2c_addr;
+}
+
+void stpmic1_dump_regulators(void)
+{
+ uint32_t i;
+
+ for (i = 0U; i < MAX_REGUL; i++) {
+ const char *name __unused = regulators_table[i].dt_node_name;
+
+ VERBOSE("PMIC regul %s: %sable, %dmV",
+ name,
+ stpmic1_is_regulator_enabled(name) ? "en" : "dis",
+ stpmic1_regulator_voltage_get(name));
+ }
+}
+
+int stpmic1_get_version(unsigned long *version)
+{
+ int rc;
+ uint8_t read_val;
+
+ rc = stpmic1_register_read(VERSION_STATUS_REG, &read_val);
+ if (rc) {
+ return -1;
+ }
+
+ *version = (unsigned long)read_val;
+
+ return 0;
+}
diff --git a/drivers/st/pmic/stpmu1.c b/drivers/st/pmic/stpmu1.c
deleted file mode 100644
index 9c36bf6..0000000
--- a/drivers/st/pmic/stpmu1.c
+++ /dev/null
@@ -1,601 +0,0 @@
-/*
- * Copyright (c) 2016-2018, STMicroelectronics - All Rights Reserved
- *
- * SPDX-License-Identifier: BSD-3-Clause
- */
-
-#include <string.h>
-
-#include <common/debug.h>
-#include <drivers/st/stpmu1.h>
-#include <plat/common/platform.h>
-
-struct regul_struct {
- const char *dt_node_name;
- const uint16_t *voltage_table;
- uint8_t voltage_table_size;
- uint8_t control_reg;
- uint8_t low_power_reg;
-};
-
-static struct i2c_handle_s *stpmu_i2c_handle;
-static uint16_t stpmu_i2c_addr;
-
-/* Voltage tables in mV */
-static const uint16_t buck1_voltage_table[] = {
- 600,
- 625,
- 650,
- 675,
- 700,
- 725,
- 750,
- 775,
- 800,
- 825,
- 850,
- 875,
- 900,
- 925,
- 950,
- 975,
- 1000,
- 1025,
- 1050,
- 1075,
- 1100,
- 1125,
- 1150,
- 1175,
- 1200,
- 1225,
- 1250,
- 1275,
- 1300,
- 1325,
- 1350,
- 1350,
-};
-
-static const uint16_t buck2_voltage_table[] = {
- 1000,
- 1000,
- 1000,
- 1000,
- 1000,
- 1000,
- 1000,
- 1000,
- 1000,
- 1000,
- 1000,
- 1000,
- 1000,
- 1000,
- 1000,
- 1000,
- 1000,
- 1000,
- 1050,
- 1050,
- 1100,
- 1100,
- 1150,
- 1150,
- 1200,
- 1200,
- 1250,
- 1250,
- 1300,
- 1300,
- 1350,
- 1350,
- 1400,
- 1400,
- 1450,
- 1450,
- 1500,
-};
-
-static const uint16_t buck3_voltage_table[] = {
- 1000,
- 1000,
- 1000,
- 1000,
- 1000,
- 1000,
- 1000,
- 1000,
- 1000,
- 1000,
- 1000,
- 1000,
- 1000,
- 1000,
- 1000,
- 1000,
- 1000,
- 1000,
- 1000,
- 1000,
- 1100,
- 1100,
- 1100,
- 1100,
- 1200,
- 1200,
- 1200,
- 1200,
- 1300,
- 1300,
- 1300,
- 1300,
- 1400,
- 1400,
- 1400,
- 1400,
- 1500,
- 1600,
- 1700,
- 1800,
- 1900,
- 2000,
- 2100,
- 2200,
- 2300,
- 2400,
- 2500,
- 2600,
- 2700,
- 2800,
- 2900,
- 3000,
- 3100,
- 3200,
- 3300,
- 3400,
-};
-
-static const uint16_t buck4_voltage_table[] = {
- 600,
- 625,
- 650,
- 675,
- 700,
- 725,
- 750,
- 775,
- 800,
- 825,
- 850,
- 875,
- 900,
- 925,
- 950,
- 975,
- 1000,
- 1025,
- 1050,
- 1075,
- 1100,
- 1125,
- 1150,
- 1175,
- 1200,
- 1225,
- 1250,
- 1275,
- 1300,
- 1300,
- 1350,
- 1350,
- 1400,
- 1400,
- 1450,
- 1450,
- 1500,
- 1600,
- 1700,
- 1800,
- 1900,
- 2000,
- 2100,
- 2200,
- 2300,
- 2400,
- 2500,
- 2600,
- 2700,
- 2800,
- 2900,
- 3000,
- 3100,
- 3200,
- 3300,
- 3400,
- 3500,
- 3600,
- 3700,
- 3800,
- 3900,
-};
-
-static const uint16_t ldo1_voltage_table[] = {
- 1700,
- 1700,
- 1700,
- 1700,
- 1700,
- 1700,
- 1700,
- 1700,
- 1700,
- 1800,
- 1900,
- 2000,
- 2100,
- 2200,
- 2300,
- 2400,
- 2500,
- 2600,
- 2700,
- 2800,
- 2900,
- 3000,
- 3100,
- 3200,
- 3300,
-};
-
-static const uint16_t ldo2_voltage_table[] = {
- 1700,
- 1700,
- 1700,
- 1700,
- 1700,
- 1700,
- 1700,
- 1700,
- 1700,
- 1800,
- 1900,
- 2000,
- 2100,
- 2200,
- 2300,
- 2400,
- 2500,
- 2600,
- 2700,
- 2800,
- 2900,
- 3000,
- 3100,
- 3200,
- 3300,
-};
-
-static const uint16_t ldo3_voltage_table[] = {
- 1700,
- 1700,
- 1700,
- 1700,
- 1700,
- 1700,
- 1700,
- 1700,
- 1700,
- 1800,
- 1900,
- 2000,
- 2100,
- 2200,
- 2300,
- 2400,
- 2500,
- 2600,
- 2700,
- 2800,
- 2900,
- 3000,
- 3100,
- 3200,
- 3300,
- 3300,
- 3300,
- 3300,
- 3300,
- 3300,
- 3300,
- 0xFFFF, /* VREFDDR */
-};
-
-static const uint16_t ldo5_voltage_table[] = {
- 1700,
- 1700,
- 1700,
- 1700,
- 1700,
- 1700,
- 1700,
- 1700,
- 1700,
- 1800,
- 1900,
- 2000,
- 2100,
- 2200,
- 2300,
- 2400,
- 2500,
- 2600,
- 2700,
- 2800,
- 2900,
- 3000,
- 3100,
- 3200,
- 3300,
- 3400,
- 3500,
- 3600,
- 3700,
- 3800,
- 3900,
-};
-
-static const uint16_t ldo6_voltage_table[] = {
- 900,
- 1000,
- 1100,
- 1200,
- 1300,
- 1400,
- 1500,
- 1600,
- 1700,
- 1800,
- 1900,
- 2000,
- 2100,
- 2200,
- 2300,
- 2400,
- 2500,
- 2600,
- 2700,
- 2800,
- 2900,
- 3000,
- 3100,
- 3200,
- 3300,
-};
-
-static const uint16_t ldo4_voltage_table[] = {
- 3300,
-};
-
-static const uint16_t vref_ddr_voltage_table[] = {
- 3300,
-};
-
-/* Table of Regulators in PMIC SoC */
-static const struct regul_struct regulators_table[] = {
- {
- .dt_node_name = "buck1",
- .voltage_table = buck1_voltage_table,
- .voltage_table_size = ARRAY_SIZE(buck1_voltage_table),
- .control_reg = BUCK1_CONTROL_REG,
- .low_power_reg = BUCK1_PWRCTRL_REG,
- },
- {
- .dt_node_name = "buck2",
- .voltage_table = buck2_voltage_table,
- .voltage_table_size = ARRAY_SIZE(buck2_voltage_table),
- .control_reg = BUCK2_CONTROL_REG,
- .low_power_reg = BUCK2_PWRCTRL_REG,
- },
- {
- .dt_node_name = "buck3",
- .voltage_table = buck3_voltage_table,
- .voltage_table_size = ARRAY_SIZE(buck3_voltage_table),
- .control_reg = BUCK3_CONTROL_REG,
- .low_power_reg = BUCK3_PWRCTRL_REG,
- },
- {
- .dt_node_name = "buck4",
- .voltage_table = buck4_voltage_table,
- .voltage_table_size = ARRAY_SIZE(buck4_voltage_table),
- .control_reg = BUCK4_CONTROL_REG,
- .low_power_reg = BUCK4_PWRCTRL_REG,
- },
- {
- .dt_node_name = "ldo1",
- .voltage_table = ldo1_voltage_table,
- .voltage_table_size = ARRAY_SIZE(ldo1_voltage_table),
- .control_reg = LDO1_CONTROL_REG,
- .low_power_reg = LDO1_PWRCTRL_REG,
- },
- {
- .dt_node_name = "ldo2",
- .voltage_table = ldo2_voltage_table,
- .voltage_table_size = ARRAY_SIZE(ldo2_voltage_table),
- .control_reg = LDO2_CONTROL_REG,
- .low_power_reg = LDO2_PWRCTRL_REG,
- },
- {
- .dt_node_name = "ldo3",
- .voltage_table = ldo3_voltage_table,
- .voltage_table_size = ARRAY_SIZE(ldo3_voltage_table),
- .control_reg = LDO3_CONTROL_REG,
- .low_power_reg = LDO3_PWRCTRL_REG,
- },
- {
- .dt_node_name = "ldo4",
- .voltage_table = ldo4_voltage_table,
- .voltage_table_size = ARRAY_SIZE(ldo4_voltage_table),
- .control_reg = LDO4_CONTROL_REG,
- .low_power_reg = LDO4_PWRCTRL_REG,
- },
- {
- .dt_node_name = "ldo5",
- .voltage_table = ldo5_voltage_table,
- .voltage_table_size = ARRAY_SIZE(ldo5_voltage_table),
- .control_reg = LDO5_CONTROL_REG,
- .low_power_reg = LDO5_PWRCTRL_REG,
- },
- {
- .dt_node_name = "ldo6",
- .voltage_table = ldo6_voltage_table,
- .voltage_table_size = ARRAY_SIZE(ldo6_voltage_table),
- .control_reg = LDO6_CONTROL_REG,
- .low_power_reg = LDO6_PWRCTRL_REG,
- },
- {
- .dt_node_name = "vref_ddr",
- .voltage_table = vref_ddr_voltage_table,
- .voltage_table_size = ARRAY_SIZE(vref_ddr_voltage_table),
- .control_reg = VREF_DDR_CONTROL_REG,
- .low_power_reg = VREF_DDR_PWRCTRL_REG,
- },
-};
-
-#define MAX_REGUL ARRAY_SIZE(regulators_table)
-
-static const struct regul_struct *stpmu1_get_regulator_data(const char *name)
-{
- uint8_t i;
-
- for (i = 0 ; i < MAX_REGUL ; i++) {
- if (strncmp(name, regulators_table[i].dt_node_name,
- strlen(regulators_table[i].dt_node_name)) == 0) {
- return ®ulators_table[i];
- }
- }
-
- /* Regulator not found */
- panic();
- return NULL;
-}
-
-static uint8_t stpmu1_voltage_find_index(const char *name,
- uint16_t millivolts)
-{
- const struct regul_struct *regul = stpmu1_get_regulator_data(name);
- uint8_t i;
-
- for (i = 0 ; i < regul->voltage_table_size ; i++) {
- if (regul->voltage_table[i] == millivolts) {
- return i;
- }
- }
-
- /* Voltage not found */
- panic();
-
- return 0;
-}
-
-int stpmu1_switch_off(void)
-{
- return stpmu1_register_update(MAIN_CONTROL_REG, 1,
- SOFTWARE_SWITCH_OFF_ENABLED);
-}
-
-int stpmu1_regulator_enable(const char *name)
-{
- const struct regul_struct *regul = stpmu1_get_regulator_data(name);
-
- return stpmu1_register_update(regul->control_reg, BIT(0), BIT(0));
-}
-
-int stpmu1_regulator_disable(const char *name)
-{
- const struct regul_struct *regul = stpmu1_get_regulator_data(name);
-
- return stpmu1_register_update(regul->control_reg, 0, BIT(0));
-}
-
-uint8_t stpmu1_is_regulator_enabled(const char *name)
-{
- uint8_t val;
- const struct regul_struct *regul = stpmu1_get_regulator_data(name);
-
- if (stpmu1_register_read(regul->control_reg, &val) != 0) {
- panic();
- }
-
- return (val & 0x1U);
-}
-
-int stpmu1_regulator_voltage_set(const char *name, uint16_t millivolts)
-{
- uint8_t voltage_index = stpmu1_voltage_find_index(name, millivolts);
- const struct regul_struct *regul = stpmu1_get_regulator_data(name);
-
- return stpmu1_register_update(regul->control_reg, voltage_index << 2,
- 0xFC);
-}
-
-int stpmu1_register_read(uint8_t register_id, uint8_t *value)
-{
- return stm32_i2c_mem_read(stpmu_i2c_handle, stpmu_i2c_addr,
- (uint16_t)register_id, I2C_MEMADD_SIZE_8BIT,
- value, 1, 100000);
-}
-
-int stpmu1_register_write(uint8_t register_id, uint8_t value)
-{
- int status;
-
- status = stm32_i2c_mem_write(stpmu_i2c_handle, stpmu_i2c_addr,
- (uint16_t)register_id,
- I2C_MEMADD_SIZE_8BIT, &value, 1, 100000);
-
- if (status != 0) {
- return status;
- }
-
- if ((register_id != WATCHDOG_CONTROL_REG) && (register_id <= 0x40U)) {
- uint8_t readval;
-
- status = stpmu1_register_read(register_id, &readval);
- if (status != 0) {
- return status;
- }
-
- if (readval != value) {
- return -1;
- }
- }
-
- return 0;
-}
-
-int stpmu1_register_update(uint8_t register_id, uint8_t value, uint8_t mask)
-{
- int status;
- uint8_t val;
-
- status = stpmu1_register_read(register_id, &val);
- if (status != 0) {
- return status;
- }
-
- /* Clear bits to update */
- val &= ~mask;
-
- /* Update appropriate bits*/
- val |= (value & mask);
-
- /* Send new value on I2C Bus */
- return stpmu1_register_write(register_id, val);
-}
-
-void stpmu1_bind_i2c(struct i2c_handle_s *i2c_handle, uint16_t i2c_addr)
-{
- stpmu_i2c_handle = i2c_handle;
- stpmu_i2c_addr = i2c_addr;
-}
diff --git a/drivers/staging/renesas/rcar/ddr/ddr_a/ddr_init_e3.c b/drivers/staging/renesas/rcar/ddr/ddr_a/ddr_init_e3.c
index 62997bc..c289c88 100644
--- a/drivers/staging/renesas/rcar/ddr/ddr_a/ddr_init_e3.c
+++ b/drivers/staging/renesas/rcar/ddr/ddr_a/ddr_init_e3.c
@@ -1137,13 +1137,13 @@
/* ddr backupmode end */
if (ddrBackup) {
- NOTICE("[WARM_BOOT]");
+ NOTICE("BL2: [WARM_BOOT]\n");
} else {
- NOTICE("[COLD_BOOT]");
+ NOTICE("BL2: [COLD_BOOT]\n");
} /* ddrBackup */
err = rcar_dram_update_boot_status(ddrBackup);
if (err) {
- NOTICE("[BOOT_STATUS_UPDATE_ERROR]");
+ NOTICE("BL2: [BOOT_STATUS_UPDATE_ERROR]\n");
return INITDRAM_ERR_I;
} /* err */
@@ -1672,9 +1672,9 @@
md = *((volatile uint32_t*)RST_MODEMR);
ddr = (md & 0x00080000) >> 19;
if (ddr == 0x0) {
- NOTICE("BL2: DDR1584(%s)", RCAR_E3_DDR_VERSION);
+ NOTICE("BL2: DDR1584(%s)\n", RCAR_E3_DDR_VERSION);
} else if(ddr == 0x1){
- NOTICE("BL2: DDR1856(%s)", RCAR_E3_DDR_VERSION);
+ NOTICE("BL2: DDR1856(%s)\n", RCAR_E3_DDR_VERSION);
} /* ddr */
rcar_dram_get_boot_status(&ddrBackup);
@@ -1691,8 +1691,6 @@
failcount = 1;
} /* dataL */
- NOTICE("..%d\n", failcount); /* rev.0.05 */
-
if (failcount == 0) {
return INITDRAM_OK;
} else {
diff --git a/drivers/staging/renesas/rcar/ddr/ddr_b/boot_init_dram.c b/drivers/staging/renesas/rcar/ddr/ddr_b/boot_init_dram.c
index 78f0f11..f4bfdde 100644
--- a/drivers/staging/renesas/rcar/ddr/ddr_b/boot_init_dram.c
+++ b/drivers/staging/renesas/rcar/ddr/ddr_b/boot_init_dram.c
@@ -2826,7 +2826,7 @@
set_freqchgack(0);
if (timeout) {
- FATAL_MSG("Time out[2]");
+ FATAL_MSG("BL2: Time out[2]\n");
return (1);
}
return (0);
@@ -3012,13 +3012,13 @@
***********************************************************************/
#ifdef DDR_BACKUPMODE
if (ddrBackup) {
- NOTICE("[WARM_BOOT]");
+ NOTICE("BL2: [WARM_BOOT]\n");
} else {
- NOTICE("[COLD_BOOT]");
+ NOTICE("BL2: [COLD_BOOT]\n");
}
err = rcar_dram_update_boot_status(ddrBackup);
if (err) {
- NOTICE("[BOOT_STATUS_UPDATE_ERROR]");
+ NOTICE("BL2: [BOOT_STATUS_UPDATE_ERROR]\n");
return INITDRAM_ERR_I;
}
#endif
diff --git a/drivers/synopsys/ufs/dw_ufs.c b/drivers/synopsys/ufs/dw_ufs.c
index c7c8fc2..6bed981 100644
--- a/drivers/synopsys/ufs/dw_ufs.c
+++ b/drivers/synopsys/ufs/dw_ufs.c
@@ -183,7 +183,7 @@
return 0;
}
-const ufs_ops_t dw_ufs_ops = {
+static const ufs_ops_t dw_ufs_ops = {
.phy_init = dwufs_phy_init,
.phy_set_pwr_mode = dwufs_phy_set_pwr_mode,
};
diff --git a/drivers/ufs/ufs.c b/drivers/ufs/ufs.c
index 2351c9b..b2c1046 100644
--- a/drivers/ufs/ufs.c
+++ b/drivers/ufs/ufs.c
@@ -591,7 +591,7 @@
ufs_query(QUERY_WRITE_DESC, idn, index, 0, buf, size);
}
-void ufs_read_capacity(int lun, unsigned int *num, unsigned int *size)
+static void ufs_read_capacity(int lun, unsigned int *num, unsigned int *size)
{
utp_utrd_t utrd;
resp_upiu_t *resp;
diff --git a/fdts/stm32mp15-ddr.dtsi b/fdts/stm32mp15-ddr.dtsi
index be4e2c3..1a5c51c 100644
--- a/fdts/stm32mp15-ddr.dtsi
+++ b/fdts/stm32mp15-ddr.dtsi
@@ -5,7 +5,7 @@
/ {
soc {
- ddr: ddr@0x5A003000{
+ ddr: ddr@5A003000{
compatible = "st,stm32mp1-ddr";
diff --git a/fdts/stm32mp15-ddr3-2x4Gb-1066-binG.dtsi b/fdts/stm32mp15-ddr3-2x4Gb-1066-binG.dtsi
index 58a4cdc..82e7104 100644
--- a/fdts/stm32mp15-ddr3-2x4Gb-1066-binG.dtsi
+++ b/fdts/stm32mp15-ddr3-2x4Gb-1066-binG.dtsi
@@ -3,7 +3,7 @@
* Copyright (C) 2018, STMicroelectronics - All Rights Reserved
*/
-/* STM32MP157C ED1 and ED2 BOARD configuration
+/* STM32MP157C ED1 BOARD configuration
* 2x DDR3L 4Gb each, 16-bit, 533MHz, Single Die Package in flyby topology.
* Reference used NT5CC256M16DP-DI from NANYA
*
@@ -15,10 +15,11 @@
* timing mode optimized
* Scheduling/QoS options : type = 2
* address mapping : RBC
+ * Tc > + 85C : N
*/
-#define DDR_MEM_NAME "DDR3-1066 bin G 2x4Gb 533MHz v1.39"
-#define DDR_MEM_SPEED 533
+#define DDR_MEM_NAME "DDR3-1066/888 bin G 2x4Gb 533MHz v1.41"
+#define DDR_MEM_SPEED 533000
#define DDR_MEM_SIZE 0x40000000
#define DDR_MSTR 0x00040401
@@ -62,7 +63,7 @@
#define DDR_ADDRMAP11 0x00000000
#define DDR_ODTCFG 0x06000600
#define DDR_ODTMAP 0x00000001
-#define DDR_SCHED 0x00001201
+#define DDR_SCHED 0x00000C01
#define DDR_SCHED1 0x00000000
#define DDR_PERFHPR1 0x01000001
#define DDR_PERFLPR1 0x08000200
@@ -74,15 +75,15 @@
#define DDR_PCCFG 0x00000010
#define DDR_PCFGR_0 0x00010000
#define DDR_PCFGW_0 0x00000000
-#define DDR_PCFGQOS0_0 0x02100B03
+#define DDR_PCFGQOS0_0 0x02100C03
#define DDR_PCFGQOS1_0 0x00800100
-#define DDR_PCFGWQOS0_0 0x01100B03
+#define DDR_PCFGWQOS0_0 0x01100C03
#define DDR_PCFGWQOS1_0 0x01000200
#define DDR_PCFGR_1 0x00010000
#define DDR_PCFGW_1 0x00000000
-#define DDR_PCFGQOS0_1 0x02100B03
-#define DDR_PCFGQOS1_1 0x00800000
-#define DDR_PCFGWQOS0_1 0x01100B03
+#define DDR_PCFGQOS0_1 0x02100C03
+#define DDR_PCFGQOS1_1 0x00800040
+#define DDR_PCFGWQOS0_1 0x01100C03
#define DDR_PCFGWQOS1_1 0x01000200
#define DDR_PGCR 0x01442E02
#define DDR_PTR0 0x0022AA5B
diff --git a/fdts/stm32mp157-pinctrl.dtsi b/fdts/stm32mp157-pinctrl.dtsi
index 21bd34e..9dcd7b5 100644
--- a/fdts/stm32mp157-pinctrl.dtsi
+++ b/fdts/stm32mp157-pinctrl.dtsi
@@ -3,13 +3,14 @@
* Copyright (C) STMicroelectronics 2017 - All Rights Reserved
* Author: Ludovic Barre <ludovic.barre@st.com> for STMicroelectronics.
*/
-
#include <dt-bindings/pinctrl/stm32-pinfunc.h>
+
/ {
soc {
- pinctrl: pin-controller {
+ pinctrl: pin-controller@50002000 {
#address-cells = <1>;
#size-cells = <1>;
+ compatible = "st,stm32mp157-pinctrl";
ranges = <0 0x50002000 0xa400>;
pins-are-numbered;
@@ -134,7 +135,132 @@
status = "disabled";
};
- uart4_pins_a: uart4@0 {
+ qspi_bk1_pins_a: qspi-bk1-0 {
+ pins1 {
+ pinmux = <STM32_PINMUX('F', 8, AF10)>, /* QSPI_BK1_IO0 */
+ <STM32_PINMUX('F', 9, AF10)>, /* QSPI_BK1_IO1 */
+ <STM32_PINMUX('F', 7, AF9)>, /* QSPI_BK1_IO2 */
+ <STM32_PINMUX('F', 6, AF9)>; /* QSPI_BK1_IO3 */
+ bias-disable;
+ drive-push-pull;
+ slew-rate = <1>;
+ };
+ pins2 {
+ pinmux = <STM32_PINMUX('B', 6, AF10)>; /* QSPI_BK1_NCS */
+ bias-pull-up;
+ drive-push-pull;
+ slew-rate = <1>;
+ };
+ };
+
+ qspi_bk2_pins_a: qspi-bk2-0 {
+ pins1 {
+ pinmux = <STM32_PINMUX('H', 2, AF9)>, /* QSPI_BK2_IO0 */
+ <STM32_PINMUX('H', 3, AF9)>, /* QSPI_BK2_IO1 */
+ <STM32_PINMUX('G', 10, AF11)>, /* QSPI_BK2_IO2 */
+ <STM32_PINMUX('G', 7, AF11)>; /* QSPI_BK2_IO3 */
+ bias-disable;
+ drive-push-pull;
+ slew-rate = <1>;
+ };
+ pins2 {
+ pinmux = <STM32_PINMUX('C', 0, AF10)>; /* QSPI_BK2_NCS */
+ bias-pull-up;
+ drive-push-pull;
+ slew-rate = <1>;
+ };
+ };
+
+ qspi_clk_pins_a: qspi-clk-0 {
+ pins {
+ pinmux = <STM32_PINMUX('F', 10, AF9)>; /* QSPI_CLK */
+ bias-disable;
+ drive-push-pull;
+ slew-rate = <3>;
+ };
+ };
+
+ sdmmc1_b4_pins_a: sdmmc1-b4-0 {
+ pins1 {
+ pinmux = <STM32_PINMUX('C', 8, AF12)>, /* SDMMC1_D0 */
+ <STM32_PINMUX('C', 9, AF12)>, /* SDMMC1_D1 */
+ <STM32_PINMUX('C', 10, AF12)>, /* SDMMC1_D2 */
+ <STM32_PINMUX('C', 11, AF12)>, /* SDMMC1_D3 */
+ <STM32_PINMUX('D', 2, AF12)>; /* SDMMC1_CMD */
+ slew-rate = <1>;
+ drive-push-pull;
+ bias-disable;
+ };
+ pins2 {
+ pinmux = <STM32_PINMUX('C', 12, AF12)>; /* SDMMC1_CK */
+ slew-rate = <2>;
+ drive-push-pull;
+ bias-disable;
+ };
+ };
+
+ sdmmc1_dir_pins_a: sdmmc1-dir-0 {
+ pins1 {
+ pinmux = <STM32_PINMUX('F', 2, AF11)>, /* SDMMC1_D0DIR */
+ <STM32_PINMUX('C', 7, AF8)>, /* SDMMC1_D123DIR */
+ <STM32_PINMUX('B', 9, AF11)>; /* SDMMC1_CDIR */
+ slew-rate = <1>;
+ drive-push-pull;
+ bias-pull-up;
+ };
+ pins2{
+ pinmux = <STM32_PINMUX('E', 4, AF8)>; /* SDMMC1_CKIN */
+ bias-pull-up;
+ };
+ };
+
+ sdmmc1_dir_pins_b: sdmmc1-dir-1 {
+ pins1 {
+ pinmux = <STM32_PINMUX('E', 12, AF8)>, /* SDMMC1_D0DIR */
+ <STM32_PINMUX('E', 14, AF11)>, /* SDMMC1_D123DIR */
+ <STM32_PINMUX('B', 9, AF11)>; /* SDMMC1_CDIR */
+ slew-rate = <3>;
+ drive-push-pull;
+ bias-pull-up;
+ };
+ pins2 {
+ pinmux = <STM32_PINMUX('E', 4, AF8)>; /* SDMMC1_CKIN */
+ bias-pull-up;
+ };
+ };
+
+ sdmmc2_b4_pins_a: sdmmc2-b4-0 {
+ pins1 {
+ pinmux = <STM32_PINMUX('B', 14, AF9)>, /* SDMMC2_D0 */
+ <STM32_PINMUX('B', 15, AF9)>, /* SDMMC2_D1 */
+ <STM32_PINMUX('B', 3, AF9)>, /* SDMMC2_D2 */
+ <STM32_PINMUX('B', 4, AF9)>, /* SDMMC2_D3 */
+ <STM32_PINMUX('G', 6, AF10)>; /* SDMMC2_CMD */
+ slew-rate = <1>;
+ drive-push-pull;
+ bias-pull-up;
+ };
+ pins2 {
+ pinmux = <STM32_PINMUX('E', 3, AF9)>; /* SDMMC2_CK */
+ slew-rate = <2>;
+ drive-push-pull;
+ bias-pull-up;
+ };
+ };
+
+ sdmmc2_d47_pins_a: sdmmc2-d47-0 {
+ pins {
+ pinmux = <STM32_PINMUX('A', 8, AF9)>, /* SDMMC2_D4 */
+ <STM32_PINMUX('A', 9, AF10)>, /* SDMMC2_D5 */
+ <STM32_PINMUX('E', 5, AF9)>, /* SDMMC2_D6 */
+ <STM32_PINMUX('D', 3, AF9)>; /* SDMMC2_D7 */
+ slew-rate = <1>;
+ drive-push-pull;
+ bias-pull-up;
+ };
+ };
+
+ uart4_pins_a: uart4-0 {
pins1 {
pinmux = <STM32_PINMUX('G', 11, AF6)>; /* UART4_TX */
bias-disable;
@@ -147,7 +273,7 @@
};
};
- usart3_pins_a: usart3@0 {
+ usart3_pins_a: usart3-0 {
pins1 {
pinmux = <STM32_PINMUX('B', 10, AF7)>, /* USART3_TX */
<STM32_PINMUX('G', 8, AF8)>; /* USART3_RTS */
@@ -161,66 +287,12 @@
bias-disable;
};
};
-
- sdmmc1_b4_pins_a: sdmmc1-b4@0 {
- pins {
- pinmux = <STM32_PINMUX('C', 8, AF12)>, /* SDMMC1_D0 */
- <STM32_PINMUX('C', 9, AF12)>, /* SDMMC1_D1 */
- <STM32_PINMUX('C', 10, AF12)>, /* SDMMC1_D2 */
- <STM32_PINMUX('C', 11, AF12)>, /* SDMMC1_D3 */
- <STM32_PINMUX('C', 12, AF12)>, /* SDMMC1_CK */
- <STM32_PINMUX('D', 2, AF12)>; /* SDMMC1_CMD */
- slew-rate = <3>;
- drive-push-pull;
- bias-disable;
- };
- };
-
- sdmmc1_dir_pins_a: sdmmc1-dir@0 {
- pins1 {
- pinmux = <STM32_PINMUX('F', 2, AF11)>, /* SDMMC1_D0DIR */
- <STM32_PINMUX('C', 7, AF8)>, /* SDMMC1_D123DIR */
- <STM32_PINMUX('B', 9, AF11)>; /* SDMMC1_CDIR */
- slew-rate = <3>;
- drive-push-pull;
- bias-pull-up;
- };
- pins2{
- pinmux = <STM32_PINMUX('E', 4, AF8)>; /* SDMMC1_CKIN */
- bias-pull-up;
- };
- };
-
- sdmmc2_b4_pins_a: sdmmc2-b4@0 {
- pins {
- pinmux = <STM32_PINMUX('B', 14, AF9)>, /* SDMMC2_D0 */
- <STM32_PINMUX('B', 15, AF9)>, /* SDMMC2_D1 */
- <STM32_PINMUX('B', 3, AF9)>, /* SDMMC2_D2 */
- <STM32_PINMUX('B', 4, AF9)>, /* SDMMC2_D3 */
- <STM32_PINMUX('E', 3, AF9)>, /* SDMMC2_CK */
- <STM32_PINMUX('G', 6, AF10)>; /* SDMMC2_CMD */
- slew-rate = <3>;
- drive-push-pull;
- bias-pull-up;
- };
- };
-
- sdmmc2_d47_pins_a: sdmmc2-d47@0 {
- pins {
- pinmux = <STM32_PINMUX('A', 8, AF9)>, /* SDMMC2_D4 */
- <STM32_PINMUX('A', 9, AF10)>, /* SDMMC2_D5 */
- <STM32_PINMUX('E', 5, AF9)>, /* SDMMC2_D6 */
- <STM32_PINMUX('D', 3, AF9)>; /* SDMMC2_D7 */
- slew-rate = <3>;
- drive-push-pull;
- bias-pull-up;
- };
- };
};
- pinctrl_z: pin-controller-z {
+ pinctrl_z: pin-controller-z@54004000 {
#address-cells = <1>;
#size-cells = <1>;
+ compatible = "st,stm32mp157-z-pinctrl";
ranges = <0 0x54004000 0x400>;
pins-are-numbered;
@@ -236,7 +308,7 @@
status = "disabled";
};
- i2c4_pins_a: i2c4@0 {
+ i2c4_pins_a: i2c4-0 {
pins {
pinmux = <STM32_PINMUX('Z', 4, AF6)>, /* I2C4_SCL */
<STM32_PINMUX('Z', 5, AF6)>; /* I2C4_SDA */
diff --git a/fdts/stm32mp157c-ed1.dts b/fdts/stm32mp157c-ed1.dts
index e3dabe8..a97e805 100644
--- a/fdts/stm32mp157c-ed1.dts
+++ b/fdts/stm32mp157c-ed1.dts
@@ -3,20 +3,26 @@
* Copyright (C) STMicroelectronics 2017 - All Rights Reserved
* Author: Ludovic Barre <ludovic.barre@st.com> for STMicroelectronics.
*/
-
/dts-v1/;
#include "stm32mp157c.dtsi"
#include "stm32mp157caa-pinctrl.dtsi"
/ {
- model = "STMicroelectronics STM32MP157C-ED1 pmic eval daughter";
+ model = "STMicroelectronics STM32MP157C eval daughter";
compatible = "st,stm32mp157c-ed1", "st,stm32mp157";
chosen {
- bootargs = "earlyprintk console=ttyS3,115200 root=/dev/ram";
- stdout-path = "serial3:115200n8";
+ stdout-path = "serial0:115200n8";
};
+
+ aliases {
+ serial0 = &uart4;
+ };
+};
+
+&clk_hse {
+ st,digbypass;
};
&i2c4 {
@@ -26,37 +32,88 @@
i2c-scl-falling-time-ns = <20>;
status = "okay";
- pmic: stpmu1@33 {
- compatible = "st,stpmu1";
+ pmic: stpmic@33 {
+ compatible = "st,stpmic1";
reg = <0x33>;
+ interrupts-extended = <&exti_pwr 55 IRQ_TYPE_EDGE_FALLING>;
+ interrupt-controller;
+ #interrupt-cells = <2>;
status = "okay";
- st,main_control_register = <0x04>;
- st,vin_control_register = <0xc0>;
- st,usb_control_register = <0x30>;
+ st,main-control-register = <0x04>;
+ st,vin-control-register = <0xc0>;
+ st,usb-control-register = <0x30>;
regulators {
- compatible = "st,stpmu1-regulators";
+ compatible = "st,stpmic1-regulators";
+
+ ldo1-supply = <&v3v3>;
+ ldo2-supply = <&v3v3>;
+ ldo3-supply = <&vdd_ddr>;
+ ldo5-supply = <&v3v3>;
+ ldo6-supply = <&v3v3>;
+
+ vddcore: buck1 {
+ regulator-name = "vddcore";
+ regulator-min-microvolt = <800000>;
+ regulator-max-microvolt = <1350000>;
+ regulator-always-on;
+ regulator-initial-mode = <0>;
+ regulator-over-current-protection;
+ };
+
+ vdd_ddr: buck2 {
+ regulator-name = "vdd_ddr";
+ regulator-min-microvolt = <1350000>;
+ regulator-max-microvolt = <1350000>;
+ regulator-always-on;
+ regulator-initial-mode = <0>;
+ regulator-over-current-protection;
+ };
+
+ vdd: buck3 {
+ regulator-name = "vdd";
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ regulator-always-on;
+ st,mask-reset;
+ regulator-initial-mode = <0>;
+ regulator-over-current-protection;
+ };
v3v3: buck4 {
regulator-name = "v3v3";
regulator-min-microvolt = <3300000>;
regulator-max-microvolt = <3300000>;
- regulator-boot-on;
+ regulator-always-on;
regulator-over-current-protection;
- regulator-initial-mode = <8>;
+ regulator-initial-mode = <0>;
+ };
- regulator-state-standby {
- regulator-suspend-microvolt = <3300000>;
- regulator-unchanged-in-suspend;
- regulator-mode = <8>;
- };
- regulator-state-mem {
- regulator-off-in-suspend;
- };
- regulator-state-disk {
- regulator-off-in-suspend;
- };
+ vdda: ldo1 {
+ regulator-name = "vdda";
+ regulator-min-microvolt = <2900000>;
+ regulator-max-microvolt = <2900000>;
+ };
+
+ v2v8: ldo2 {
+ regulator-name = "v2v8";
+ regulator-min-microvolt = <2800000>;
+ regulator-max-microvolt = <2800000>;
+ };
+
+ vtt_ddr: ldo3 {
+ regulator-name = "vtt_ddr";
+ regulator-min-microvolt = <500000>;
+ regulator-max-microvolt = <750000>;
+ regulator-always-on;
+ regulator-over-current-protection;
+ };
+
+ vdd_usb: ldo4 {
+ regulator-name = "vdd_usb";
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
};
vdd_sd: ldo5 {
@@ -64,24 +121,24 @@
regulator-min-microvolt = <2900000>;
regulator-max-microvolt = <2900000>;
regulator-boot-on;
+ };
- regulator-state-standby {
- regulator-suspend-microvolt = <2900000>;
- regulator-unchanged-in-suspend;
- };
- regulator-state-mem {
- regulator-off-in-suspend;
- };
- regulator-state-disk {
- regulator-off-in-suspend;
- };
+ v1v8: ldo6 {
+ regulator-name = "v1v8";
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+ };
+
+ vref_ddr: vref_ddr {
+ regulator-name = "vref_ddr";
+ regulator-always-on;
+ regulator-over-current-protection;
};
};
};
};
&iwdg2 {
- instance = <2>;
timeout-sec = <32>;
status = "okay";
};
@@ -90,14 +147,19 @@
status = "okay";
};
+&rtc {
+ status = "okay";
+};
+
&sdmmc1 {
pinctrl-names = "default";
pinctrl-0 = <&sdmmc1_b4_pins_a &sdmmc1_dir_pins_a>;
broken-cd;
- st,dirpol;
- st,negedge;
- st,pin-ckin;
+ st,sig-dir;
+ st,neg-edge;
+ st,use-ckin;
bus-width = <4>;
+ vmmc-supply = <&vdd_sd>;
sd-uhs-sdr12;
sd-uhs-sdr25;
sd-uhs-sdr50;
@@ -112,16 +174,17 @@
non-removable;
no-sd;
no-sdio;
- st,dirpol;
- st,negedge;
+ st,neg-edge;
bus-width = <8>;
+ vmmc-supply = <&v3v3>;
+ vqmmc-supply = <&v3v3>;
+ mmc-ddr-3_3v;
status = "okay";
};
&uart4 {
pinctrl-names = "default";
pinctrl-0 = <&uart4_pins_a>;
- resets = <&rcc UART4_R>;
status = "okay";
};
@@ -157,6 +220,7 @@
/* CLOCK init */
&rcc {
+ secure-status = "disabled";
st,clksrc = <
CLK_MPU_PLL1P
CLK_AXI_PLL2P
@@ -186,7 +250,7 @@
CLK_FMC_ACLK
CLK_QSPI_ACLK
CLK_ETH_DISABLED
- CLK_SDMMC12_PLL3R
+ CLK_SDMMC12_PLL4P
CLK_DSI_DSIPLL
CLK_STGEN_HSE
CLK_USBPHY_HSE
@@ -195,7 +259,7 @@
CLK_SPI45_HSI
CLK_SPI6_HSI
CLK_I2C46_HSI
- CLK_SDMMC3_PLL3R
+ CLK_SDMMC3_PLL4P
CLK_USBO_USBPHY
CLK_ADC_CKPER
CLK_CEC_LSE
@@ -206,17 +270,17 @@
CLK_UART35_HSI
CLK_UART6_HSI
CLK_UART78_HSI
- CLK_SPDIF_PLL3Q
+ CLK_SPDIF_PLL4P
CLK_FDCAN_PLL4Q
CLK_SAI1_PLL3Q
CLK_SAI2_PLL3Q
CLK_SAI3_PLL3Q
CLK_SAI4_PLL3Q
- CLK_RNG1_CSI
- CLK_RNG2_CSI
+ CLK_RNG1_LSI
+ CLK_RNG2_LSI
CLK_LPTIM1_PCLK1
CLK_LPTIM23_PCLK3
- CLK_LPTIM45_PCLK3
+ CLK_LPTIM45_LSE
>;
/* VCO = 1300.0 MHz => P = 650 (CPU) */
@@ -231,15 +295,15 @@
frac = < 0x1400 >;
};
- /* VCO = 786.4 MHz => P = 197, Q = 49, R = 98 */
+ /* VCO = 417.8 MHz => P = 209, Q = 24, R = 11 */
pll3: st,pll@2 {
- cfg = < 2 97 3 15 7 PQR(1,1,1) >;
- frac = < 0x9ba >;
+ cfg = < 1 33 1 16 36 PQR(1,1,1) >;
+ frac = < 0x1a04 >;
};
- /* VCO = 508.0 MHz => P = 56, Q = 56, R = 56 */
+ /* VCO = 594.0 MHz => P = 99, Q = 74, R = 74 */
pll4: st,pll@3 {
- cfg = < 5 126 8 8 8 PQR(1,1,1) >;
+ cfg = < 3 98 5 7 7 PQR(1,1,1) >;
};
};
diff --git a/fdts/stm32mp157c-ev1.dts b/fdts/stm32mp157c-ev1.dts
index 98a9d35..cfde8ed 100644
--- a/fdts/stm32mp157c-ev1.dts
+++ b/fdts/stm32mp157c-ev1.dts
@@ -3,23 +3,65 @@
* Copyright (C) STMicroelectronics 2017 - All Rights Reserved
* Author: Ludovic Barre <ludovic.barre@st.com> for STMicroelectronics.
*/
-
/dts-v1/;
+
#include "stm32mp157c-ed1.dts"
/ {
- model = "STMicroelectronics STM32MP157C-EV1 pmic eval daughter on eval mother";
+ model = "STMicroelectronics STM32MP157C eval daughter on eval mother";
compatible = "st,stm32mp157c-ev1", "st,stm32mp157c-ed1", "st,stm32mp157";
chosen {
- bootargs = "earlyprintk console=ttyS3,115200 root=/dev/ram";
- stdout-path = "serial3:115200n8";
+ stdout-path = "serial0:115200n8";
+ };
+
+ aliases {
+ serial1 = &usart3;
+ };
+};
+
+&fmc {
+ status = "okay";
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ nand: nand@0 {
+ reg = <0>;
+ nand-on-flash-bbt;
+ #address-cells = <1>;
+ #size-cells = <1>;
+ };
+};
+
+&qspi {
+ pinctrl-names = "default";
+ pinctrl-0 = <&qspi_clk_pins_a &qspi_bk1_pins_a &qspi_bk2_pins_a>;
+ reg = <0x58003000 0x1000>, <0x70000000 0x4000000>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ status = "okay";
+
+ flash0: mx66l51235l@0 {
+ compatible = "jedec,spi-nor";
+ reg = <0>;
+ spi-rx-bus-width = <4>;
+ spi-max-frequency = <108000000>;
+ #address-cells = <1>;
+ #size-cells = <1>;
+ };
+
+ flash1: mx66l51235l@1 {
+ compatible = "jedec,spi-nor";
+ reg = <1>;
+ spi-rx-bus-width = <4>;
+ spi-max-frequency = <108000000>;
+ #address-cells = <1>;
+ #size-cells = <1>;
};
};
&usart3 {
pinctrl-names = "default";
pinctrl-0 = <&usart3_pins_a>;
- resets = <&rcc USART3_R>;
status = "disabled";
};
diff --git a/fdts/stm32mp157c.dtsi b/fdts/stm32mp157c.dtsi
index 8b13c0e..0ec7ecb 100644
--- a/fdts/stm32mp157c.dtsi
+++ b/fdts/stm32mp157c.dtsi
@@ -3,7 +3,7 @@
* Copyright (C) STMicroelectronics 2017 - All Rights Reserved
* Author: Ludovic Barre <ludovic.barre@st.com> for STMicroelectronics.
*/
-
+#include <dt-bindings/interrupt-controller/arm-gic.h>
#include <dt-bindings/clock/stm32mp1-clks.h>
#include <dt-bindings/reset/stm32mp1-resets.h>
@@ -11,15 +11,12 @@
#address-cells = <1>;
#size-cells = <1>;
- aliases {
- serial0 = &usart1;
- serial1 = &usart2;
- serial2 = &usart3;
- serial3 = &uart4;
- serial4 = &uart5;
- serial5 = &usart6;
- serial6 = &uart7;
- serial7 = &uart8;
+ intc: interrupt-controller@a0021000 {
+ compatible = "arm,cortex-a7-gic";
+ #interrupt-cells = <3>;
+ interrupt-controller;
+ reg = <0xa0021000 0x1000>,
+ <0xa0022000 0x2000>;
};
clocks {
@@ -56,7 +53,7 @@
clk_i2s_ckin: i2s_ckin {
#clock-cells = <0>;
compatible = "fixed-clock";
- clock-frequency = <64000000>;
+ clock-frequency = <0>;
};
clk_dsi_phy: ck_dsi_phy {
@@ -64,31 +61,28 @@
compatible = "fixed-clock";
clock-frequency = <0>;
};
-
- clk_usbo_48m: ck_usbo_48m {
- #clock-cells = <0>;
- compatible = "fixed-clock";
- clock-frequency = <48000000>;
- };
};
soc {
compatible = "simple-bus";
#address-cells = <1>;
#size-cells = <1>;
+ interrupt-parent = <&intc>;
ranges;
usart2: serial@4000e000 {
- compatible = "st,stm32h7-usart";
+ compatible = "st,stm32h7-uart";
reg = <0x4000e000 0x400>;
clocks = <&rcc USART2_K>;
+ resets = <&rcc USART2_R>;
status = "disabled";
};
usart3: serial@4000f000 {
- compatible = "st,stm32h7-usart";
+ compatible = "st,stm32h7-uart";
reg = <0x4000f000 0x400>;
clocks = <&rcc USART3_K>;
+ resets = <&rcc USART3_R>;
status = "disabled";
};
@@ -96,6 +90,7 @@
compatible = "st,stm32h7-uart";
reg = <0x40010000 0x400>;
clocks = <&rcc UART4_K>;
+ resets = <&rcc UART4_R>;
status = "disabled";
};
@@ -103,6 +98,7 @@
compatible = "st,stm32h7-uart";
reg = <0x40011000 0x400>;
clocks = <&rcc UART5_K>;
+ resets = <&rcc UART5_R>;
status = "disabled";
};
@@ -111,6 +107,7 @@
compatible = "st,stm32h7-uart";
reg = <0x40018000 0x400>;
clocks = <&rcc UART7_K>;
+ resets = <&rcc UART7_R>;
status = "disabled";
};
@@ -118,21 +115,23 @@
compatible = "st,stm32h7-uart";
reg = <0x40019000 0x400>;
clocks = <&rcc UART8_K>;
+ resets = <&rcc UART8_R>;
status = "disabled";
};
usart6: serial@44003000 {
- compatible = "st,stm32h7-usart";
+ compatible = "st,stm32h7-uart";
reg = <0x44003000 0x400>;
clocks = <&rcc USART6_K>;
+ resets = <&rcc USART6_R>;
status = "disabled";
};
sdmmc3: sdmmc@48004000 {
compatible = "st,stm32-sdmmc2";
reg = <0x48004000 0x400>, <0x48005000 0x400>;
- reg-names = "sdmmc", "delay";
clocks = <&rcc SDMMC3_K>;
+ clock-names = "apb_pclk";
resets = <&rcc SDMMC3_R>;
cap-sd-highspeed;
cap-mmc-highspeed;
@@ -141,17 +140,34 @@
};
rcc: rcc@50000000 {
- compatible = "syscon", "st,stm32mp1-rcc";
+ compatible = "st,stm32mp1-rcc", "syscon";
+ reg = <0x50000000 0x1000>;
#clock-cells = <1>;
#reset-cells = <1>;
- reg = <0x50000000 0x1000>;
+ interrupts = <GIC_SPI 5 IRQ_TYPE_LEVEL_HIGH>;
};
- rcc_reboot: rcc-reboot@50000000 {
- compatible = "syscon-reboot";
- regmap = <&rcc>;
- offset = <0x404>;
- mask = <0x1>;
+ pwr: pwr@50001000 {
+ compatible = "st,stm32mp1-pwr", "syscon", "simple-mfd";
+ reg = <0x50001000 0x400>;
+ };
+
+ exti: interrupt-controller@5000d000 {
+ compatible = "st,stm32mp1-exti", "syscon";
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ reg = <0x5000d000 0x400>;
+
+ /* exti_pwr is an extra interrupt controller used for
+ * EXTI 55 to 60. It's mapped on pwr interrupt
+ * controller.
+ */
+ exti_pwr: exti-pwr {
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ interrupt-parent = <&pwr>;
+ st,irq-number = <6>;
+ };
};
rng1: rng@54003000 {
@@ -162,13 +178,15 @@
status = "disabled";
};
- fmc_nand: fmc_nand@58002000 {
- compatible = "st,stm32mp1-fmc";
+ fmc: nand-controller@58002000 {
+ compatible = "st,stm32mp15-fmc2";
reg = <0x58002000 0x1000>,
- <0x80000000 0x40000>,
- <0x81000000 0x40000>,
- <0x88000000 0x40000>,
- <0x89000000 0x40000>;
+ <0x80000000 0x1000>,
+ <0x88010000 0x1000>,
+ <0x88020000 0x1000>,
+ <0x81000000 0x1000>,
+ <0x89010000 0x1000>,
+ <0x89020000 0x1000>;
clocks = <&rcc FMC_K>;
resets = <&rcc FMC_R>;
status = "disabled";
@@ -177,15 +195,17 @@
qspi: qspi@58003000 {
compatible = "st,stm32f469-qspi";
reg = <0x58003000 0x1000>, <0x70000000 0x10000000>;
+ reg-names = "qspi", "qspi_mm";
clocks = <&rcc QSPI_K>;
+ resets = <&rcc QSPI_R>;
status = "disabled";
};
sdmmc1: sdmmc@58005000 {
compatible = "st,stm32-sdmmc2";
reg = <0x58005000 0x1000>, <0x58006000 0x1000>;
- reg-names = "sdmmc", "delay";
clocks = <&rcc SDMMC1_K>;
+ clock-names = "apb_pclk";
resets = <&rcc SDMMC1_R>;
cap-sd-highspeed;
cap-mmc-highspeed;
@@ -196,8 +216,8 @@
sdmmc2: sdmmc@58007000 {
compatible = "st,stm32-sdmmc2";
reg = <0x58007000 0x1000>, <0x58008000 0x1000>;
- reg-names = "sdmmc", "delay";
clocks = <&rcc SDMMC2_K>;
+ clock-names = "apb_pclk";
resets = <&rcc SDMMC2_R>;
cap-sd-highspeed;
cap-mmc-highspeed;
@@ -205,7 +225,7 @@
status = "disabled";
};
- iwdg2: iwdg@5a002000 {
+ iwdg2: watchdog@5a002000 {
compatible = "st,stm32mp1-iwdg";
reg = <0x5a002000 0x400>;
clocks = <&rcc IWDG2>, <&rcc CK_LSI>;
@@ -214,15 +234,34 @@
};
usart1: serial@5c000000 {
- compatible = "st,stm32h7-usart";
+ compatible = "st,stm32h7-uart";
reg = <0x5c000000 0x400>;
+ interrupt-names = "event", "wakeup";
+ interrupts-extended = <&intc GIC_SPI 37 IRQ_TYPE_LEVEL_HIGH>,
+ <&exti 26 1>;
clocks = <&rcc USART1_K>;
+ resets = <&rcc USART1_R>;
+ status = "disabled";
+ };
+
+ spi6: spi@5c001000 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ compatible = "st,stm32h7-spi";
+ reg = <0x5c001000 0x400>;
+ interrupts = <GIC_SPI 86 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&rcc SPI6_K>;
+ resets = <&rcc SPI6_R>;
status = "disabled";
};
i2c4: i2c@5c002000 {
compatible = "st,stm32f7-i2c";
reg = <0x5c002000 0x400>;
+ interrupt-names = "event", "error", "wakeup";
+ interrupts-extended = <&intc GIC_SPI 95 IRQ_TYPE_LEVEL_HIGH>,
+ <&intc GIC_SPI 96 IRQ_TYPE_LEVEL_HIGH>,
+ <&exti 24 1>;
clocks = <&rcc I2C4_K>;
resets = <&rcc I2C4_R>;
#address-cells = <1>;
@@ -235,6 +274,36 @@
reg = <0x5c004000 0x400>;
clocks = <&rcc RTCAPB>, <&rcc RTC>;
clock-names = "pclk", "rtc_ck";
+ interrupts-extended = <&intc GIC_SPI 3 IRQ_TYPE_LEVEL_HIGH>,
+ <&exti 19 1>;
+ status = "disabled";
+ };
+
+ bsec: nvmem@5c005000 {
+ compatible = "st,stm32mp15-bsec";
+ reg = <0x5c005000 0x400>;
+ #address-cells = <1>;
+ #size-cells = <1>;
+ ts_cal1: calib@5c {
+ reg = <0x5c 0x2>;
+ };
+ ts_cal2: calib@5e {
+ reg = <0x5e 0x2>;
+ };
+ };
+
+ i2c6: i2c@5c009000 {
+ compatible = "st,stm32f7-i2c";
+ reg = <0x5c009000 0x400>;
+ interrupt-names = "event", "error", "wakeup";
+ interrupts-extended = <&intc GIC_SPI 135 IRQ_TYPE_LEVEL_HIGH>,
+ <&intc GIC_SPI 136 IRQ_TYPE_LEVEL_HIGH>,
+ <&exti 54 1>;
+ clocks = <&rcc I2C6_K>;
+ resets = <&rcc I2C6_R>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ status = "disabled";
};
};
};
diff --git a/fdts/stm32mp157caa-pinctrl.dtsi b/fdts/stm32mp157caa-pinctrl.dtsi
index 774561a..9b9cd08 100644
--- a/fdts/stm32mp157caa-pinctrl.dtsi
+++ b/fdts/stm32mp157caa-pinctrl.dtsi
@@ -7,8 +7,8 @@
#include "stm32mp157-pinctrl.dtsi"
/ {
soc {
- pinctrl: pin-controller {
- compatible = "st,stm32mp157caa-pinctrl";
+ pinctrl: pin-controller@50002000 {
+ st,package = <STM32MP157CAA>;
gpioa: gpio@50002000 {
status = "okay";
@@ -77,8 +77,8 @@
};
};
- pinctrl_z: pin-controller-z {
- compatible = "st,stm32mp157caa-z-pinctrl";
+ pinctrl_z: pin-controller-z@54004000 {
+ st,package = <STM32MP157CAA>;
gpioz: gpio@54004000 {
status = "okay";
diff --git a/include/arch/aarch64/arch.h b/include/arch/aarch64/arch.h
index 9e2bffa..76c3e27 100644
--- a/include/arch/aarch64/arch.h
+++ b/include/arch/aarch64/arch.h
@@ -204,6 +204,10 @@
/* ID_AA64MMFR2_EL1 definitions */
#define ID_AA64MMFR2_EL1 S3_0_C0_C7_2
+
+#define ID_AA64MMFR2_EL1_ST_SHIFT U(28)
+#define ID_AA64MMFR2_EL1_ST_MASK ULL(0xf)
+
#define ID_AA64MMFR2_EL1_CNP_SHIFT U(0)
#define ID_AA64MMFR2_EL1_CNP_MASK ULL(0xf)
@@ -427,6 +431,7 @@
#define TCR_TxSZ_MIN ULL(16)
#define TCR_TxSZ_MAX ULL(39)
+#define TCR_TxSZ_MAX_TTST ULL(48)
/* (internal) physical address size bits in EL3/EL1 */
#define TCR_PS_BITS_4GB ULL(0x0)
diff --git a/include/arch/aarch64/arch_features.h b/include/arch/aarch64/arch_features.h
index 2b09ba0..9bf43bf 100644
--- a/include/arch/aarch64/arch_features.h
+++ b/include/arch/aarch64/arch_features.h
@@ -17,4 +17,10 @@
ID_AA64MMFR2_EL1_CNP_MASK) != 0U;
}
+static inline bool is_armv8_4_ttst_present(void)
+{
+ return ((read_id_aa64mmfr2_el1() >> ID_AA64MMFR2_EL1_ST_SHIFT) &
+ ID_AA64MMFR2_EL1_ST_MASK) == 1U;
+}
+
#endif /* ARCH_FEATURES_H */
diff --git a/include/arch/aarch64/arch_helpers.h b/include/arch/aarch64/arch_helpers.h
index d3f0df7..4e459bb 100644
--- a/include/arch/aarch64/arch_helpers.h
+++ b/include/arch/aarch64/arch_helpers.h
@@ -185,6 +185,7 @@
DEFINE_SYSREG_READ_FUNC(id_aa64isar1_el1)
DEFINE_SYSREG_READ_FUNC(id_aa64pfr0_el1)
DEFINE_SYSREG_READ_FUNC(id_aa64dfr0_el1)
+DEFINE_SYSREG_READ_FUNC(id_afr0_el1)
DEFINE_SYSREG_READ_FUNC(CurrentEl)
DEFINE_SYSREG_READ_FUNC(ctr_el0)
DEFINE_SYSREG_RW_FUNCS(daif)
diff --git a/include/common/bl_common.h b/include/common/bl_common.h
index f7b3b9c..57c1174 100644
--- a/include/common/bl_common.h
+++ b/include/common/bl_common.h
@@ -189,11 +189,6 @@
/*******************************************************************************
* Function & variable prototypes
******************************************************************************/
-size_t get_image_size(unsigned int image_id);
-
-int is_mem_free(uintptr_t free_base, size_t free_size,
- uintptr_t addr, size_t size);
-
int load_auth_image(unsigned int image_id, image_info_t *image_data);
#if TRUSTED_BOARD_BOOT && defined(DYN_DISABLE_AUTH)
diff --git a/include/common/desc_image_load.h b/include/common/desc_image_load.h
index f2f26ea..e46eb27 100644
--- a/include/common/desc_image_load.h
+++ b/include/common/desc_image_load.h
@@ -31,6 +31,9 @@
/* BL image loading utility functions */
void flush_bl_params_desc(void);
+void flush_bl_params_desc_args(bl_mem_params_node_t *mem_params_desc_ptr,
+ unsigned int mem_params_desc_num,
+ bl_params_t *next_bl_params_ptr);
int get_bl_params_node_index(unsigned int image_id);
bl_mem_params_node_t *get_bl_mem_params_node(unsigned int image_id);
bl_load_info_t *get_bl_load_info_from_mem_params_desc(void);
diff --git a/include/common/runtime_svc.h b/include/common/runtime_svc.h
index 59bf158..e5e36c7 100644
--- a/include/common/runtime_svc.h
+++ b/include/common/runtime_svc.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2013-2018, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2013-2019, ARM Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -36,17 +36,8 @@
* In SMCCC 1.X, the function identifier has 6 bits for the owning entity number
* and a single bit for the type of smc call. When taken together, those values
* limit the maximum number of runtime services to 128.
- *
- * In SMCCC 2.X the type bit is always 1 and there are only 4 OEN bits in the
- * compatibility namespace, so the total number of services is 16. The LSB of
- * namespace is also added to these 4 bits to make space for the vendor service
- * handler and so the total number of runtime services is 32.
*/
-#if SMCCC_MAJOR_VERSION == 1
#define MAX_RT_SVCS U(128)
-#elif SMCCC_MAJOR_VERSION == 2
-#define MAX_RT_SVCS U(32)
-#endif
#ifndef __ASSEMBLY__
@@ -70,11 +61,7 @@
typedef struct rt_svc_desc {
uint8_t start_oen;
uint8_t end_oen;
-#if SMCCC_MAJOR_VERSION == 1
uint8_t call_type;
-#elif SMCCC_MAJOR_VERSION == 2
- uint8_t is_vendor;
-#endif
const char *name;
rt_svc_init_t init;
rt_svc_handle_t handle;
@@ -83,8 +70,6 @@
/*
* Convenience macros to declare a service descriptor
*/
-#if SMCCC_MAJOR_VERSION == 1
-
#define DECLARE_RT_SVC(_name, _start, _end, _type, _setup, _smch) \
static const rt_svc_desc_t __svc_desc_ ## _name \
__section("rt_svc_descs") __used = { \
@@ -96,37 +81,6 @@
.handle = (_smch) \
}
-#elif SMCCC_MAJOR_VERSION == 2
-
-#define DECLARE_RT_SVC(_name, _start, _end, _type, _setup, _smch) \
- static const rt_svc_desc_t __svc_desc_ ## _name \
- __section("rt_svc_descs") __used = { \
- .start_oen = (_start), \
- .end_oen = (_end), \
- .is_vendor = 0, \
- .name = #_name, \
- .init = (_setup), \
- .handle = (_smch), \
- }; \
- CASSERT((_type) == SMC_TYPE_FAST, rt_svc_type_check_ ## _name)
-
-/*
- * The higher 16 entries of the runtime services are used for the vendor
- * specific descriptor.
- */
-#define DECLARE_RT_SVC_VENDOR(_setup, _smch) \
- static const rt_svc_desc_t __svc_desc_vendor \
- __section("rt_svc_descs") __used = { \
- .start_oen = 0, \
- .end_oen = 15, \
- .is_vendor = 1, \
- .name = "vendor_rt_svc", \
- .init = _setup, \
- .handle = _smch, \
- }
-
-#endif /* SMCCC_MAJOR_VERSION */
-
/*
* Compile time assertions related to the 'rt_svc_desc' structure to:
* 1. ensure that the assembler and the compiler view of the size
@@ -144,7 +98,6 @@
assert_rt_svc_desc_handle_offset_mismatch);
-#if SMCCC_MAJOR_VERSION == 1
/*
* This function combines the call type and the owning entity number
* corresponding to a runtime service to generate a unique owning entity number.
@@ -169,22 +122,6 @@
return get_unique_oen(GET_SMC_OEN(fid), GET_SMC_TYPE(fid));
}
-#elif SMCCC_MAJOR_VERSION == 2
-
-/*
- * This function combines the owning entity number corresponding to a runtime
- * service with one extra bit for the vendor namespace to generate an index into
- * the 'rt_svc_descs_indices' array. The entry contains the index of the service
- * descriptor in the 'rt_svc_descs' array.
- */
-static inline uint32_t get_rt_desc_idx(uint32_t oen, uint32_t is_vendor)
-{
- return ((is_vendor & 1U) << FUNCID_OEN_WIDTH) |
- (oen & FUNCID_OEN_MASK);
-}
-
-#endif
-
/*******************************************************************************
* Function & variable prototypes
******************************************************************************/
diff --git a/plat/arm/css/drivers/mhu/css_mhu.h b/include/drivers/arm/css/css_mhu.h
similarity index 100%
rename from plat/arm/css/drivers/mhu/css_mhu.h
rename to include/drivers/arm/css/css_mhu.h
diff --git a/plat/arm/css/drivers/mhu/css_mhu_doorbell.h b/include/drivers/arm/css/css_mhu_doorbell.h
similarity index 100%
rename from plat/arm/css/drivers/mhu/css_mhu_doorbell.h
rename to include/drivers/arm/css/css_mhu_doorbell.h
diff --git a/plat/arm/css/drivers/scp/css_scp.h b/include/drivers/arm/css/css_scp.h
similarity index 100%
rename from plat/arm/css/drivers/scp/css_scp.h
rename to include/drivers/arm/css/css_scp.h
diff --git a/plat/arm/css/drivers/scpi/css_scpi.h b/include/drivers/arm/css/css_scpi.h
similarity index 100%
rename from plat/arm/css/drivers/scpi/css_scpi.h
rename to include/drivers/arm/css/css_scpi.h
diff --git a/plat/arm/css/drivers/scmi/scmi.h b/include/drivers/arm/css/scmi.h
similarity index 100%
rename from plat/arm/css/drivers/scmi/scmi.h
rename to include/drivers/arm/css/scmi.h
diff --git a/plat/arm/css/drivers/sds/sds.h b/include/drivers/arm/css/sds.h
similarity index 100%
rename from plat/arm/css/drivers/sds/sds.h
rename to include/drivers/arm/css/sds.h
diff --git a/plat/arm/board/fvp/drivers/pwrc/fvp_pwrc.h b/include/drivers/arm/fvp/fvp_pwrc.h
similarity index 98%
rename from plat/arm/board/fvp/drivers/pwrc/fvp_pwrc.h
rename to include/drivers/arm/fvp/fvp_pwrc.h
index 324f3e2..ca173f3 100644
--- a/plat/arm/board/fvp/drivers/pwrc/fvp_pwrc.h
+++ b/include/drivers/arm/fvp/fvp_pwrc.h
@@ -37,6 +37,8 @@
#ifndef __ASSEMBLY__
+#include <stdint.h>
+
/*******************************************************************************
* Function & variable prototypes
******************************************************************************/
diff --git a/include/drivers/arm/gicv3.h b/include/drivers/arm/gicv3.h
index 2382697..72221ac 100644
--- a/include/drivers/arm/gicv3.h
+++ b/include/drivers/arm/gicv3.h
@@ -84,6 +84,7 @@
#define GICR_PCPUBASE_SHIFT 0x11
#define GICR_SGIBASE_OFFSET U(65536) /* 64 KB */
#define GICR_CTLR U(0x0)
+#define GICR_IIDR U(0x04)
#define GICR_TYPER U(0x08)
#define GICR_WAKER U(0x14)
#define GICR_PROPBASER U(0x70)
diff --git a/include/drivers/rpi3/gpio/rpi3_gpio.h b/include/drivers/rpi3/gpio/rpi3_gpio.h
new file mode 100644
index 0000000..159a2e0
--- /dev/null
+++ b/include/drivers/rpi3/gpio/rpi3_gpio.h
@@ -0,0 +1,38 @@
+/*
+ * Copyright (c) 2019, Linaro Limited
+ * Copyright (c) 2019, Ying-Chun Liu (PaulLiu) <paul.liu@linaro.org>
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef RPI3_GPIO_H
+#define RPI3_GPIO_H
+
+#include <stdint.h>
+#include <drivers/gpio.h>
+
+struct rpi3_gpio_params {
+ uintptr_t reg_base;
+};
+
+void rpi3_gpio_init(struct rpi3_gpio_params *params);
+int rpi3_gpio_get_select(int gpio);
+void rpi3_gpio_set_select(int gpio, int fsel);
+
+#define RPI3_GPIO_GPFSEL(n) ((n) * U(0x04))
+#define RPI3_GPIO_GPSET(n) (((n) * U(0x04)) + U(0x1C))
+#define RPI3_GPIO_GPCLR(n) (((n) * U(0x04)) + U(0x28))
+#define RPI3_GPIO_GPLEV(n) (((n) * U(0x04)) + U(0x34))
+#define RPI3_GPIO_GPPUD U(0x94)
+#define RPI3_GPIO_GPPUDCLK(n) (((n) * U(0x04)) + U(0x98))
+
+#define RPI3_GPIO_FUNC_INPUT U(0)
+#define RPI3_GPIO_FUNC_OUTPUT U(1)
+#define RPI3_GPIO_FUNC_ALT0 U(4)
+#define RPI3_GPIO_FUNC_ALT1 U(5)
+#define RPI3_GPIO_FUNC_ALT2 U(6)
+#define RPI3_GPIO_FUNC_ALT3 U(7)
+#define RPI3_GPIO_FUNC_ALT4 U(3)
+#define RPI3_GPIO_FUNC_ALT5 U(2)
+
+#endif /* RPI3_GPIO_H */
diff --git a/include/drivers/rpi3/sdhost/rpi3_sdhost.h b/include/drivers/rpi3/sdhost/rpi3_sdhost.h
new file mode 100644
index 0000000..bc906e3
--- /dev/null
+++ b/include/drivers/rpi3/sdhost/rpi3_sdhost.h
@@ -0,0 +1,124 @@
+/*
+ * Copyright (c) 2019, Linaro Limited
+ * Copyright (c) 2019, Ying-Chun Liu (PaulLiu) <paul.liu@linaro.org>
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef RPI3_SDHOST_H
+#define RPI3_SDHOST_H
+
+#include <drivers/mmc.h>
+#include <stdint.h>
+#include <platform_def.h>
+
+struct rpi3_sdhost_params {
+ uintptr_t reg_base;
+ uint32_t clk_rate;
+ uint32_t bus_width;
+ uint32_t flags;
+ uint32_t current_cmd;
+ uint8_t cmdbusy;
+ uint8_t mmc_app_cmd;
+ uint32_t ns_per_fifo_word;
+ uint32_t crc_err_retries;
+
+ uint32_t sdcard_rca;
+ uint32_t gpio48_pinselect[6];
+};
+
+void rpi3_sdhost_init(struct rpi3_sdhost_params *params,
+ struct mmc_device_info *mmc_dev_info);
+void rpi3_sdhost_stop(void);
+
+/* Registers */
+#define HC_COMMAND 0x00 /* Command and flags */
+#define HC_ARGUMENT 0x04
+#define HC_TIMEOUTCOUNTER 0x08
+#define HC_CLOCKDIVISOR 0x0c
+#define HC_RESPONSE_0 0x10
+#define HC_RESPONSE_1 0x14
+#define HC_RESPONSE_2 0x18
+#define HC_RESPONSE_3 0x1c
+#define HC_HOSTSTATUS 0x20
+#define HC_POWER 0x30
+#define HC_DEBUG 0x34
+#define HC_HOSTCONFIG 0x38
+#define HC_BLOCKSIZE 0x3c
+#define HC_DATAPORT 0x40
+#define HC_BLOCKCOUNT 0x50
+
+/* Flags for HC_COMMAND register */
+#define HC_CMD_ENABLE 0x8000
+#define HC_CMD_FAILED 0x4000
+#define HC_CMD_BUSY 0x0800
+#define HC_CMD_RESPONSE_NONE 0x0400
+#define HC_CMD_RESPONSE_LONG 0x0200
+#define HC_CMD_WRITE 0x0080
+#define HC_CMD_READ 0x0040
+#define HC_CMD_COMMAND_MASK 0x003f
+
+#define HC_CLOCKDIVISOR_MAXVAL 0x07ff
+#define HC_CLOCKDIVISOR_PREFERVAL 0x027b
+#define HC_CLOCKDIVISOR_SLOWVAL 0x0148
+#define HC_CLOCKDIVISOR_STOPVAL 0x01fb
+
+/* Flags for HC_HOSTSTATUS register */
+#define HC_HSTST_HAVEDATA 0x0001
+#define HC_HSTST_ERROR_FIFO 0x0008
+#define HC_HSTST_ERROR_CRC7 0x0010
+#define HC_HSTST_ERROR_CRC16 0x0020
+#define HC_HSTST_TIMEOUT_CMD 0x0040
+#define HC_HSTST_TIMEOUT_DATA 0x0080
+#define HC_HSTST_INT_BLOCK 0x0200
+#define HC_HSTST_INT_BUSY 0x0400
+
+#define HC_HSTST_RESET 0xffff
+
+#define HC_HSTST_MASK_ERROR_DATA (HC_HSTST_ERROR_FIFO | \
+ HC_HSTST_ERROR_CRC7 | \
+ HC_HSTST_ERROR_CRC16 | \
+ HC_HSTST_TIMEOUT_DATA)
+
+#define HC_HSTST_MASK_ERROR_ALL (HC_HSTST_MASK_ERROR_DATA | \
+ HC_HSTST_TIMEOUT_CMD)
+
+/* Flags for HC_HOSTCONFIG register */
+#define HC_HSTCF_INTBUS_WIDE 0x0002
+#define HC_HSTCF_EXTBUS_4BIT 0x0004
+#define HC_HSTCF_SLOW_CARD 0x0008
+#define HC_HSTCF_INT_DATA 0x0010
+#define HC_HSTCF_INT_BLOCK 0x0100
+#define HC_HSTCF_INT_BUSY 0x0400
+
+/* Flags for HC_DEBUG register */
+#define HC_DBG_FIFO_THRESH_WRITE_SHIFT 9
+#define HC_DBG_FIFO_THRESH_READ_SHIFT 14
+#define HC_DBG_FIFO_THRESH_MASK 0x001f
+#define HC_DBG_FSM_MASK 0xf
+#define HC_DBG_FSM_IDENTMODE 0x0
+#define HC_DBG_FSM_DATAMODE 0x1
+#define HC_DBG_FSM_READDATA 0x2
+#define HC_DBG_FSM_WRITEDATA 0x3
+#define HC_DBG_FSM_READWAIT 0x4
+#define HC_DBG_FSM_READCRC 0x5
+#define HC_DBG_FSM_WRITECRC 0x6
+#define HC_DBG_FSM_WRITEWAIT1 0x7
+#define HC_DBG_FSM_POWERDOWN 0x8
+#define HC_DBG_FSM_POWERUP 0x9
+#define HC_DBG_FSM_WRITESTART1 0xa
+#define HC_DBG_FSM_WRITESTART2 0xb
+#define HC_DBG_FSM_GENPULSES 0xc
+#define HC_DBG_FSM_WRITEWAIT2 0xd
+#define HC_DBG_FSM_STARTPOWDOWN 0xf
+#define HC_DBG_FORCE_DATA_MODE 0x40000
+
+/* Settings */
+#define HC_FIFO_SIZE 16
+#define HC_FIFO_THRESH_READ 4
+#define HC_FIFO_THRESH_WRITE 4
+
+#define HC_TIMEOUT_DEFAULT 0x00f00000
+#define HC_TIMEOUT_IDLE 0x00a00000
+
+#endif /* RPI3_SDHOST_H */
diff --git a/include/drivers/st/bsec.h b/include/drivers/st/bsec.h
new file mode 100644
index 0000000..2171550
--- /dev/null
+++ b/include/drivers/st/bsec.h
@@ -0,0 +1,206 @@
+/*
+ * Copyright (c) 2017-2019, STMicroelectronics - All Rights Reserved
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef BSEC_H
+#define BSEC_H
+
+#include <stdbool.h>
+#include <stdint.h>
+
+#include <lib/utils_def.h>
+
+/*
+ * IP configuration
+ */
+#define BSEC_OTP_MASK GENMASK(4, 0)
+#define BSEC_OTP_BANK_SHIFT 5
+#define BSEC_TIMEOUT_VALUE 0xFFFF
+
+#define ADDR_LOWER_OTP_PERLOCK_SHIFT 0x03
+#define DATA_LOWER_OTP_PERLOCK_BIT 0x03U /* 2 significants bits are used */
+#define DATA_LOWER_OTP_PERLOCK_MASK GENMASK(2, 0)
+#define ADDR_UPPER_OTP_PERLOCK_SHIFT 0x04
+#define DATA_UPPER_OTP_PERLOCK_BIT 0x01U /* 1 significants bits are used */
+#define DATA_UPPER_OTP_PERLOCK_MASK GENMASK(3, 0)
+
+/*
+ * Return status
+ */
+#define BSEC_OK 0U
+#define BSEC_ERROR 0xFFFFFFFFU
+#define BSEC_DISTURBED 0xFFFFFFFEU
+#define BSEC_INVALID_PARAM 0xFFFFFFFCU
+#define BSEC_PROG_FAIL 0xFFFFFFFBU
+#define BSEC_LOCK_FAIL 0xFFFFFFFAU
+#define BSEC_WRITE_FAIL 0xFFFFFFF9U
+#define BSEC_SHADOW_FAIL 0xFFFFFFF8U
+#define BSEC_TIMEOUT 0xFFFFFFF7U
+
+/*
+ * BSEC REGISTER OFFSET (base relative)
+ */
+#define BSEC_OTP_CONF_OFF 0x000U
+#define BSEC_OTP_CTRL_OFF 0x004U
+#define BSEC_OTP_WRDATA_OFF 0x008U
+#define BSEC_OTP_STATUS_OFF 0x00CU
+#define BSEC_OTP_LOCK_OFF 0x010U
+#define BSEC_DEN_OFF 0x014U
+#define BSEC_DISTURBED_OFF 0x01CU
+#define BSEC_DISTURBED1_OFF 0x020U
+#define BSEC_DISTURBED2_OFF 0x024U
+#define BSEC_ERROR_OFF 0x034U
+#define BSEC_ERROR1_OFF 0x038U
+#define BSEC_ERROR2_OFF 0x03CU
+#define BSEC_WRLOCK_OFF 0x04CU /* Safmem permanent lock */
+#define BSEC_WRLOCK1_OFF 0x050U
+#define BSEC_WRLOCK2_OFF 0x054U
+#define BSEC_SPLOCK_OFF 0x064U /* Program safmem sticky lock */
+#define BSEC_SPLOCK1_OFF 0x068U
+#define BSEC_SPLOCK2_OFF 0x06CU
+#define BSEC_SWLOCK_OFF 0x07CU /* Write in OTP sticky lock */
+#define BSEC_SWLOCK1_OFF 0x080U
+#define BSEC_SWLOCK2_OFF 0x084U
+#define BSEC_SRLOCK_OFF 0x094U /* Shadowing sticky lock */
+#define BSEC_SRLOCK1_OFF 0x098U
+#define BSEC_SRLOCK2_OFF 0x09CU
+#define BSEC_JTAG_IN_OFF 0x0ACU
+#define BSEC_JTAG_OUT_OFF 0x0B0U
+#define BSEC_SCRATCH_OFF 0x0B4U
+#define BSEC_OTP_DATA_OFF 0x200U
+#define BSEC_IPHW_CFG_OFF 0xFF0U
+#define BSEC_IPVR_OFF 0xFF4U
+#define BSEC_IP_ID_OFF 0xFF8U
+#define BSEC_IP_MAGIC_ID_OFF 0xFFCU
+
+/*
+ * BSEC_CONFIGURATION Register
+ */
+#define BSEC_CONF_POWER_UP_MASK BIT(0)
+#define BSEC_CONF_POWER_UP_SHIFT 0
+#define BSEC_CONF_FRQ_MASK GENMASK(2, 1)
+#define BSEC_CONF_FRQ_SHIFT 1
+#define BSEC_CONF_PRG_WIDTH_MASK GENMASK(6, 3)
+#define BSEC_CONF_PRG_WIDTH_SHIFT 3
+#define BSEC_CONF_TREAD_MASK GENMASK(8, 7)
+#define BSEC_CONF_TREAD_SHIFT 7
+
+/*
+ * BSEC_CONTROL Register
+ */
+#define BSEC_READ 0x000U
+#define BSEC_WRITE 0x100U
+#define BSEC_LOCK 0x200U
+
+/*
+ * BSEC_OTP_LOCK register
+ */
+#define UPPER_OTP_LOCK_MASK BIT(0)
+#define UPPER_OTP_LOCK_SHIFT 0
+#define DENREG_LOCK_MASK BIT(2)
+#define DENREG_LOCK_SHIFT 2
+#define GPLOCK_LOCK_MASK BIT(4)
+#define GPLOCK_LOCK_SHIFT 4
+
+/*
+ * BSEC_OTP_STATUS Register
+ */
+#define BSEC_MODE_STATUS_MASK GENMASK(2, 0)
+#define BSEC_MODE_BUSY_MASK BIT(3)
+#define BSEC_MODE_PROGFAIL_MASK BIT(4)
+#define BSEC_MODE_PWR_MASK BIT(5)
+#define BSEC_MODE_BIST1_LOCK_MASK BIT(6)
+#define BSEC_MODE_BIST2_LOCK_MASK BIT(7)
+
+/* OTP MODE*/
+#define BSEC_MODE_OPEN1 0x00
+#define BSEC_MODE_SECURED 0x01
+#define BSEC_MODE_OPEN2 0x02
+#define BSEC_MODE_INVALID 0x04
+
+/* BSEC_DENABLE Register */
+#define BSEC_HDPEN BIT(4)
+#define BSEC_SPIDEN BIT(5)
+#define BSEC_SPINDEN BIT(6)
+#define BSEC_DBGSWGEN BIT(10)
+#define BSEC_DEN_ALL_MSK GENMASK(10, 0)
+
+/* BSEC_FENABLE Register */
+#define BSEC_FEN_ALL_MSK GENMASK(14, 0)
+
+/*
+ * OTP Lock services definition
+ * Value must corresponding to the bit number in the register
+ */
+#define BSEC_LOCK_UPPER_OTP 0x00
+#define BSEC_LOCK_DEBUG 0x02
+#define BSEC_LOCK_PROGRAM 0x03
+
+/* Values for struct bsec_config::freq */
+#define FREQ_10_20_MHZ 0x0
+#define FREQ_20_30_MHZ 0x1
+#define FREQ_30_45_MHZ 0x2
+#define FREQ_45_67_MHZ 0x3
+
+/*
+ * Device info structure, providing device-specific functions and a means of
+ * adding driver-specific state
+ */
+struct bsec_config {
+ uint8_t tread; /* SAFMEM Reading current level default 0 */
+ uint8_t pulse_width; /* SAFMEM Programming pulse width default 1 */
+ uint8_t freq; /* SAFMEM CLOCK see freq value define
+ * default FREQ_45_67_MHZ
+ */
+ uint8_t power; /* Power up SAFMEM. 1 power up, 0 power off */
+ uint8_t prog_lock; /* Programming Sticky lock
+ * 1 programming is locked until next reset
+ */
+ uint8_t den_lock; /* Debug enable sticky lock
+ * 1 debug enable is locked until next reset
+ */
+ uint8_t upper_otp_lock; /* Shadowing of upper OTP sticky lock
+ * 1 shadowing of upper OTP is locked
+ * until next reset
+ */
+};
+
+uint32_t bsec_probe(void);
+uint32_t bsec_get_base(void);
+
+uint32_t bsec_set_config(struct bsec_config *cfg);
+uint32_t bsec_get_config(struct bsec_config *cfg);
+
+uint32_t bsec_shadow_register(uint32_t otp);
+uint32_t bsec_read_otp(uint32_t *val, uint32_t otp);
+uint32_t bsec_write_otp(uint32_t val, uint32_t otp);
+uint32_t bsec_program_otp(uint32_t val, uint32_t otp);
+uint32_t bsec_permanent_lock_otp(uint32_t otp);
+
+uint32_t bsec_write_debug_conf(uint32_t val);
+uint32_t bsec_read_debug_conf(void);
+uint32_t bsec_write_feature_conf(uint32_t val);
+uint32_t bsec_read_feature_conf(uint32_t *val);
+
+uint32_t bsec_get_status(void);
+uint32_t bsec_get_hw_conf(void);
+uint32_t bsec_get_version(void);
+uint32_t bsec_get_id(void);
+uint32_t bsec_get_magic_id(void);
+
+bool bsec_write_sr_lock(uint32_t otp, uint32_t value);
+bool bsec_read_sr_lock(uint32_t otp);
+bool bsec_write_sw_lock(uint32_t otp, uint32_t value);
+bool bsec_read_sw_lock(uint32_t otp);
+bool bsec_write_sp_lock(uint32_t otp, uint32_t value);
+bool bsec_read_sp_lock(uint32_t otp);
+bool bsec_wr_lock(uint32_t otp);
+uint32_t bsec_otp_lock(uint32_t service, uint32_t value);
+
+bool bsec_mode_is_closed_device(void);
+uint32_t bsec_shadow_read_otp(uint32_t *otp_value, uint32_t word);
+uint32_t bsec_check_nsec_access_rights(uint32_t otp);
+
+#endif /* BSEC_H */
diff --git a/include/drivers/st/stm32_gpio.h b/include/drivers/st/stm32_gpio.h
index acd95ec..4320eaf 100644
--- a/include/drivers/st/stm32_gpio.h
+++ b/include/drivers/st/stm32_gpio.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2015-2018, STMicroelectronics - All Rights Reserved
+ * Copyright (c) 2015-2019, STMicroelectronics - All Rights Reserved
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -9,10 +9,6 @@
#include <lib/utils_def.h>
-#define STM32_GPIOA_BANK U(0x50002000)
-#define STM32_GPIOZ_BANK U(0x54004000)
-#define STM32_GPIO_BANK_OFFSET U(0x1000)
-
#define GPIO_MODE_OFFSET U(0x00)
#define GPIO_TYPE_OFFSET U(0x04)
#define GPIO_SPEED_OFFSET U(0x08)
@@ -20,56 +16,14 @@
#define GPIO_BSRR_OFFSET U(0x18)
#define GPIO_AFRL_OFFSET U(0x20)
#define GPIO_AFRH_OFFSET U(0x24)
+#define GPIO_SECR_OFFSET U(0x30)
#define GPIO_ALT_LOWER_LIMIT U(0x08)
-#define GPIO_BANK_A U(0x00)
-#define GPIO_BANK_B U(0x01)
-#define GPIO_BANK_C U(0x02)
-#define GPIO_BANK_D U(0x03)
-#define GPIO_BANK_E U(0x04)
-#define GPIO_BANK_F U(0x05)
-#define GPIO_BANK_G U(0x06)
-#define GPIO_BANK_H U(0x07)
-#define GPIO_BANK_I U(0x08)
-#define GPIO_BANK_J U(0x09)
-#define GPIO_BANK_K U(0x0A)
-#define GPIO_BANK_Z U(0x19)
+#define GPIO_PIN_(_x) U(_x)
+#define GPIO_PIN_MAX GPIO_PIN_(15)
-#define GPIO_PIN_0 U(0x00)
-#define GPIO_PIN_1 U(0x01)
-#define GPIO_PIN_2 U(0x02)
-#define GPIO_PIN_3 U(0x03)
-#define GPIO_PIN_4 U(0x04)
-#define GPIO_PIN_5 U(0x05)
-#define GPIO_PIN_6 U(0x06)
-#define GPIO_PIN_7 U(0x07)
-#define GPIO_PIN_8 U(0x08)
-#define GPIO_PIN_9 U(0x09)
-#define GPIO_PIN_10 U(0x0A)
-#define GPIO_PIN_11 U(0x0B)
-#define GPIO_PIN_12 U(0x0C)
-#define GPIO_PIN_13 U(0x0D)
-#define GPIO_PIN_14 U(0x0E)
-#define GPIO_PIN_15 U(0x0F)
-#define GPIO_PIN_MAX GPIO_PIN_15
-
-#define GPIO_ALTERNATE_0 0x00
-#define GPIO_ALTERNATE_1 0x01
-#define GPIO_ALTERNATE_2 0x02
-#define GPIO_ALTERNATE_3 0x03
-#define GPIO_ALTERNATE_4 0x04
-#define GPIO_ALTERNATE_5 0x05
-#define GPIO_ALTERNATE_6 0x06
-#define GPIO_ALTERNATE_7 0x07
-#define GPIO_ALTERNATE_8 0x08
-#define GPIO_ALTERNATE_9 0x09
-#define GPIO_ALTERNATE_10 0x0A
-#define GPIO_ALTERNATE_11 0x0B
-#define GPIO_ALTERNATE_12 0x0C
-#define GPIO_ALTERNATE_13 0x0D
-#define GPIO_ALTERNATE_14 0x0E
-#define GPIO_ALTERNATE_15 0x0F
+#define GPIO_ALTERNATE_(_x) U(_x)
#define GPIO_ALTERNATE_MASK U(0x0F)
#define GPIO_MODE_INPUT 0x00
@@ -82,8 +36,8 @@
#define GPIO_SPEED_LOW 0x00
#define GPIO_SPEED_MEDIUM 0x01
-#define GPIO_SPEED_FAST 0x02
-#define GPIO_SPEED_HIGH 0x03
+#define GPIO_SPEED_HIGH 0x02
+#define GPIO_SPEED_VERY_HIGH 0x03
#define GPIO_SPEED_MASK U(0x03)
#define GPIO_NO_PULL 0x00
@@ -94,8 +48,10 @@
#ifndef __ASSEMBLY__
#include <stdint.h>
+int dt_set_pinctrl_config(int node);
void set_gpio(uint32_t bank, uint32_t pin, uint32_t mode, uint32_t speed,
- uint32_t pull, uint32_t alternate);
+ uint32_t pull, uint32_t alternate, uint8_t status);
+void set_gpio_secure_cfg(uint32_t bank, uint32_t pin, bool secure);
#endif /*__ASSEMBLY__*/
#endif /* STM32_GPIO_H */
diff --git a/include/drivers/st/stm32mp1_ddr.h b/include/drivers/st/stm32mp1_ddr.h
index 363e302..4ab37d6 100644
--- a/include/drivers/st/stm32mp1_ddr.h
+++ b/include/drivers/st/stm32mp1_ddr.h
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2018, STMicroelectronics - All Rights Reserved
+ * Copyright (C) 2018-2019, STMicroelectronics - All Rights Reserved
*
* SPDX-License-Identifier: GPL-2.0+ OR BSD-3-Clause
*/
@@ -153,7 +153,7 @@
struct stm32mp1_ddr_info {
const char *name;
- uint16_t speed; /* in MHZ */
+ uint32_t speed; /* in kHZ */
uint32_t size; /* Memory size in byte = col * row * width */
};
@@ -168,7 +168,7 @@
struct stm32mp1_ddrphy_cal p_cal;
};
-int stm32mp1_ddr_clk_enable(struct ddr_info *priv, uint16_t mem_speed);
+int stm32mp1_ddr_clk_enable(struct ddr_info *priv, uint32_t mem_speed);
void stm32mp1_ddr_init(struct ddr_info *priv,
struct stm32mp1_ddr_config *config);
#endif /* STM32MP1_DDR_H */
diff --git a/include/drivers/st/stm32mp1_ddr_regs.h b/include/drivers/st/stm32mp1_ddr_regs.h
index bfcd5e2..342239a 100644
--- a/include/drivers/st/stm32mp1_ddr_regs.h
+++ b/include/drivers/st/stm32mp1_ddr_regs.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2017-2018, STMicroelectronics - All Rights Reserved
+ * Copyright (c) 2017-2019, STMicroelectronics - All Rights Reserved
*
* SPDX-License-Identifier: GPL-2.0+ OR BSD-3-Clause
*/
@@ -247,11 +247,14 @@
#define DDRCTRL_DBGSTAT 0x310
#define DDRCTRL_SWCTL 0x320
#define DDRCTRL_SWSTAT 0x324
+#define DDRCTRL_PSTAT 0x3FC
#define DDRCTRL_PCTRL_0 0x490
#define DDRCTRL_PCTRL_1 0x540
/* DDR Controller Register fields */
#define DDRCTRL_MSTR_DDR3 BIT(0)
+#define DDRCTRL_MSTR_LPDDR2 BIT(2)
+#define DDRCTRL_MSTR_LPDDR3 BIT(3)
#define DDRCTRL_MSTR_DATA_BUS_WIDTH_MASK GENMASK(13, 12)
#define DDRCTRL_MSTR_DATA_BUS_WIDTH_FULL 0
#define DDRCTRL_MSTR_DATA_BUS_WIDTH_HALF BIT(12)
@@ -269,7 +272,7 @@
/* Only one rank supported */
#define DDRCTRL_MRCTRL0_MR_RANK_SHIFT 4
#define DDRCTRL_MRCTRL0_MR_RANK_ALL \
- (0x1U << DDRCTRL_MRCTRL0_MR_RANK_SHIFT)
+ BIT(DDRCTRL_MRCTRL0_MR_RANK_SHIFT)
#define DDRCTRL_MRCTRL0_MR_ADDR_SHIFT 12
#define DDRCTRL_MRCTRL0_MR_ADDR_MASK GENMASK(15, 12)
#define DDRCTRL_MRCTRL0_MR_WR BIT(31)
@@ -367,6 +370,7 @@
#define DDRPHYC_DLLGCR_BPS200 BIT(23)
+#define DDRPHYC_ACDLLCR_DLLSRST BIT(30)
#define DDRPHYC_ACDLLCR_DLLDIS BIT(31)
#define DDRPHYC_PTR0_TDLLSRST_OFFSET 0
diff --git a/include/drivers/st/stm32mp1_rcc.h b/include/drivers/st/stm32mp1_rcc.h
index fd406c5..2f29e84 100644
--- a/include/drivers/st/stm32mp1_rcc.h
+++ b/include/drivers/st/stm32mp1_rcc.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2015-2018, STMicroelectronics - All Rights Reserved
+ * Copyright (c) 2015-2019, STMicroelectronics - All Rights Reserved
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -68,6 +68,14 @@
#define RCC_MP_AHB6ENCLRR U(0x21C)
#define RCC_MP_TZAHB6ENSETR U(0x220)
#define RCC_MP_TZAHB6ENCLRR U(0x224)
+#define RCC_MC_APB4ENSETR U(0x280)
+#define RCC_MC_APB4ENCLRR U(0x284)
+#define RCC_MC_APB5ENSETR U(0x288)
+#define RCC_MC_APB5ENCLRR U(0x28C)
+#define RCC_MC_AHB5ENSETR U(0x290)
+#define RCC_MC_AHB5ENCLRR U(0x294)
+#define RCC_MC_AHB6ENSETR U(0x298)
+#define RCC_MC_AHB6ENCLRR U(0x29C)
#define RCC_MP_APB4LPENSETR U(0x300)
#define RCC_MP_APB4LPENCLRR U(0x304)
#define RCC_MP_APB5LPENSETR U(0x308)
@@ -78,6 +86,14 @@
#define RCC_MP_AHB6LPENCLRR U(0x31C)
#define RCC_MP_TZAHB6LPENSETR U(0x320)
#define RCC_MP_TZAHB6LPENCLRR U(0x324)
+#define RCC_MC_APB4LPENSETR U(0x380)
+#define RCC_MC_APB4LPENCLRR U(0x384)
+#define RCC_MC_APB5LPENSETR U(0x388)
+#define RCC_MC_APB5LPENCLRR U(0x38C)
+#define RCC_MC_AHB5LPENSETR U(0x390)
+#define RCC_MC_AHB5LPENCLRR U(0x394)
+#define RCC_MC_AHB6LPENSETR U(0x398)
+#define RCC_MC_AHB6LPENCLRR U(0x39C)
#define RCC_BR_RSTSCLRR U(0x400)
#define RCC_MP_GRSTCSETR U(0x404)
#define RCC_MP_RSTSCLRR U(0x408)
@@ -162,6 +178,22 @@
#define RCC_MP_AHB4ENCLRR U(0xA2C)
#define RCC_MP_MLAHBENSETR U(0xA38)
#define RCC_MP_MLAHBENCLRR U(0xA3C)
+#define RCC_MC_APB1ENSETR U(0xA80)
+#define RCC_MC_APB1ENCLRR U(0xA84)
+#define RCC_MC_APB2ENSETR U(0xA88)
+#define RCC_MC_APB2ENCLRR U(0xA8C)
+#define RCC_MC_APB3ENSETR U(0xA90)
+#define RCC_MC_APB3ENCLRR U(0xA94)
+#define RCC_MC_AHB2ENSETR U(0xA98)
+#define RCC_MC_AHB2ENCLRR U(0xA9C)
+#define RCC_MC_AHB3ENSETR U(0xAA0)
+#define RCC_MC_AHB3ENCLRR U(0xAA4)
+#define RCC_MC_AHB4ENSETR U(0xAA8)
+#define RCC_MC_AHB4ENCLRR U(0xAAC)
+#define RCC_MC_AXIMENSETR U(0xAB0)
+#define RCC_MC_AXIMENCLRR U(0xAB4)
+#define RCC_MC_MLAHBENSETR U(0xAB8)
+#define RCC_MC_MLAHBENCLRR U(0xABC)
#define RCC_MP_APB1LPENSETR U(0xB00)
#define RCC_MP_APB1LPENCLRR U(0xB04)
#define RCC_MP_APB2LPENSETR U(0xB08)
@@ -178,10 +210,31 @@
#define RCC_MP_AXIMLPENCLRR U(0xB34)
#define RCC_MP_MLAHBLPENSETR U(0xB38)
#define RCC_MP_MLAHBLPENCLRR U(0xB3C)
+#define RCC_MC_APB1LPENSETR U(0xB80)
+#define RCC_MC_APB1LPENCLRR U(0xB84)
+#define RCC_MC_APB2LPENSETR U(0xB88)
+#define RCC_MC_APB2LPENCLRR U(0xB8C)
+#define RCC_MC_APB3LPENSETR U(0xB90)
+#define RCC_MC_APB3LPENCLRR U(0xB94)
+#define RCC_MC_AHB2LPENSETR U(0xB98)
+#define RCC_MC_AHB2LPENCLRR U(0xB9C)
+#define RCC_MC_AHB3LPENSETR U(0xBA0)
+#define RCC_MC_AHB3LPENCLRR U(0xBA4)
+#define RCC_MC_AHB4LPENSETR U(0xBA8)
+#define RCC_MC_AHB4LPENCLRR U(0xBAC)
+#define RCC_MC_AXIMLPENSETR U(0xBB0)
+#define RCC_MC_AXIMLPENCLRR U(0xBB4)
+#define RCC_MC_MLAHBLPENSETR U(0xBB8)
+#define RCC_MC_MLAHBLPENCLRR U(0xBBC)
+#define RCC_MC_RSTSCLRR U(0xC00)
+#define RCC_MC_CIER U(0xC14)
+#define RCC_MC_CIFR U(0xC18)
#define RCC_VERR U(0xFF4)
#define RCC_IDR U(0xFF8)
#define RCC_SIDR U(0xFFC)
+#define RCC_OFFSET_MASK GENMASK(11, 0)
+
/* Values for RCC_TZCR register */
#define RCC_TZCR_TZEN BIT(0)
@@ -221,6 +274,9 @@
#define RCC_MPUDIV_MASK GENMASK(2, 0)
#define RCC_AXIDIV_MASK GENMASK(2, 0)
+/* Used for TIMER Prescaler */
+#define RCC_TIMGXPRER_TIMGXPRE BIT(0)
+
/* Offset between RCC_MP_xxxENSETR and RCC_MP_xxxENCLRR registers */
#define RCC_MP_ENCLRR_OFFSET U(4)
@@ -228,6 +284,7 @@
#define RCC_BDCR_LSEON BIT(0)
#define RCC_BDCR_LSEBYP BIT(1)
#define RCC_BDCR_LSERDY BIT(2)
+#define RCC_BDCR_DIGBYP BIT(3)
#define RCC_BDCR_LSEDRV_MASK GENMASK(5, 4)
#define RCC_BDCR_LSEDRV_SHIFT 4
#define RCC_BDCR_LSECSSON BIT(8)
@@ -243,6 +300,7 @@
/* Used for all RCC_PLL<n>CR registers */
#define RCC_PLLNCR_PLLON BIT(0)
#define RCC_PLLNCR_PLLRDY BIT(1)
+#define RCC_PLLNCR_SSCG_CTRL BIT(2)
#define RCC_PLLNCR_DIVPEN BIT(4)
#define RCC_PLLNCR_DIVQEN BIT(5)
#define RCC_PLLNCR_DIVREN BIT(6)
@@ -281,8 +339,12 @@
/* Used for RCC_OCENSETR and RCC_OCENCLRR registers */
#define RCC_OCENR_HSION BIT(0)
+#define RCC_OCENR_HSIKERON BIT(1)
#define RCC_OCENR_CSION BIT(4)
+#define RCC_OCENR_CSIKERON BIT(5)
+#define RCC_OCENR_DIGBYP BIT(7)
#define RCC_OCENR_HSEON BIT(8)
+#define RCC_OCENR_HSEKERON BIT(9)
#define RCC_OCENR_HSEBYP BIT(10)
#define RCC_OCENR_HSECSSON BIT(11)
@@ -319,6 +381,16 @@
/* Fields of RCC_HSICFGR register */
#define RCC_HSICFGR_HSIDIV_MASK GENMASK(1, 0)
+#define RCC_HSICFGR_HSITRIM_SHIFT 8
+#define RCC_HSICFGR_HSITRIM_MASK GENMASK(14, 8)
+#define RCC_HSICFGR_HSICAL_SHIFT 16
+#define RCC_HSICFGR_HSICAL_MASK GENMASK(27, 16)
+
+/* Fields of RCC_CSICFGR register */
+#define RCC_CSICFGR_CSITRIM_SHIFT 8
+#define RCC_CSICFGR_CSITRIM_MASK GENMASK(12, 8)
+#define RCC_CSICFGR_CSICAL_SHIFT 16
+#define RCC_CSICFGR_CSICAL_MASK GENMASK(23, 16)
/* Used for RCC_MCO related operations */
#define RCC_MCOCFG_MCOON BIT(12)
@@ -330,22 +402,36 @@
#define RCC_DBGCFGR_DBGCKEN BIT(8)
/* RCC register fields for reset reasons */
-#define RCC_MP_RSTSCLRR_PORRSTF BIT(0)
-#define RCC_MP_RSTSCLRR_BORRSTF BIT(1)
-#define RCC_MP_RSTSCLRR_PADRSTF BIT(2)
-#define RCC_MP_RSTSCLRR_HCSSRSTF BIT(3)
-#define RCC_MP_RSTSCLRR_VCORERSTF BIT(4)
-#define RCC_MP_RSTSCLRR_MPSYSRSTF BIT(6)
-#define RCC_MP_RSTSCLRR_IWDG1RSTF BIT(8)
-#define RCC_MP_RSTSCLRR_IWDG2RSTF BIT(9)
-#define RCC_MP_RSTSCLRR_STDBYRSTF BIT(11)
-#define RCC_MP_RSTSCLRR_CSTDBYRSTF BIT(12)
+#define RCC_MP_RSTSCLRR_PORRSTF BIT(0)
+#define RCC_MP_RSTSCLRR_BORRSTF BIT(1)
+#define RCC_MP_RSTSCLRR_PADRSTF BIT(2)
+#define RCC_MP_RSTSCLRR_HCSSRSTF BIT(3)
+#define RCC_MP_RSTSCLRR_VCORERSTF BIT(4)
+#define RCC_MP_RSTSCLRR_MPSYSRSTF BIT(6)
+#define RCC_MP_RSTSCLRR_MCSYSRSTF BIT(7)
+#define RCC_MP_RSTSCLRR_IWDG1RSTF BIT(8)
+#define RCC_MP_RSTSCLRR_IWDG2RSTF BIT(9)
+#define RCC_MP_RSTSCLRR_STDBYRSTF BIT(11)
+#define RCC_MP_RSTSCLRR_CSTDBYRSTF BIT(12)
+#define RCC_MP_RSTSCLRR_MPUP0RSTF BIT(13)
+#define RCC_MP_RSTSCLRR_MPUP1RSTF BIT(14)
/* Global Reset Register */
#define RCC_MP_GRSTCSETR_MPSYSRST BIT(0)
+#define RCC_MP_GRSTCSETR_MPUP0RST BIT(4)
+#define RCC_MP_GRSTCSETR_MPUP1RST BIT(5)
/* Clock Source Interrupt Flag Register */
#define RCC_MP_CIFR_MASK U(0x110F1F)
+#define RCC_MP_CIFR_LSIRDYF BIT(0)
+#define RCC_MP_CIFR_LSERDYF BIT(1)
+#define RCC_MP_CIFR_HSIRDYF BIT(2)
+#define RCC_MP_CIFR_HSERDYF BIT(3)
+#define RCC_MP_CIFR_CSIRDYF BIT(4)
+#define RCC_MP_CIFR_PLL1DYF BIT(8)
+#define RCC_MP_CIFR_PLL2DYF BIT(9)
+#define RCC_MP_CIFR_PLL3DYF BIT(10)
+#define RCC_MP_CIFR_PLL4DYF BIT(11)
#define RCC_MP_CIFR_WKUPF BIT(20)
/* Stop Request Set Register */
@@ -362,7 +448,29 @@
/* Values of RCC_MP_APB1ENSETR register */
#define RCC_MP_APB1ENSETR_UART4EN BIT(16)
+/* Values of RCC_MP_APB5ENSETR register */
+#define RCC_MP_APB5ENSETR_SPI6EN BIT(0)
+#define RCC_MP_APB5ENSETR_I2C4EN BIT(2)
+#define RCC_MP_APB5ENSETR_I2C6EN BIT(3)
+#define RCC_MP_APB5ENSETR_USART1EN BIT(4)
+#define RCC_MP_APB5ENSETR_RTCAPBEN BIT(8)
+#define RCC_MP_APB5ENSETR_IWDG1APBEN BIT(15)
+
/* Values of RCC_MP_AHB4ENSETR register */
#define RCC_MP_AHB4ENSETR_GPIOGEN BIT(6)
+#define RCC_MP_AHB4ENSETR_GPIOHEN BIT(7)
+
+/* Values of RCC_MP_AHB5ENSETR register */
+#define RCC_MP_AHB5ENSETR_GPIOZEN BIT(0)
+#define RCC_MP_AHB5ENSETR_CRYP1EN BIT(4)
+#define RCC_MP_AHB5ENSETR_HASH1EN BIT(5)
+#define RCC_MP_AHB5ENSETR_RNG1EN BIT(6)
+
+/* Values of RCC_MP_IWDGFZSETR register */
+#define RCC_MP_IWDGFZSETR_IWDG1 BIT(0)
+#define RCC_MP_IWDGFZSETR_IWDG2 BIT(1)
+
+/* Values of RCC_PWRLPDLYCR register */
+#define RCC_PWRLPDLYCR_PWRLP_DLY_MASK GENMASK(21, 0)
#endif /* STM32MP1_RCC_H */
diff --git a/include/drivers/st/stm32mp1_pmic.h b/include/drivers/st/stm32mp_pmic.h
similarity index 67%
rename from include/drivers/st/stm32mp1_pmic.h
rename to include/drivers/st/stm32mp_pmic.h
index 75f8e61..700039b 100644
--- a/include/drivers/st/stm32mp1_pmic.h
+++ b/include/drivers/st/stm32mp_pmic.h
@@ -1,11 +1,11 @@
/*
- * Copyright (c) 2017-2018, STMicroelectronics - All Rights Reserved
+ * Copyright (c) 2017-2019, STMicroelectronics - All Rights Reserved
*
* SPDX-License-Identifier: BSD-3-Clause
*/
-#ifndef STM32MP1_PMIC_H
-#define STM32MP1_PMIC_H
+#ifndef STM32MP_PMIC_H
+#define STM32MP_PMIC_H
#include <stdbool.h>
@@ -17,4 +17,4 @@
void initialize_pmic(void);
int pmic_ddr_power_init(enum ddr_type ddr_type);
-#endif /* STM32MP1_PMIC_H */
+#endif /* STM32MP_PMIC_H */
diff --git a/include/drivers/st/stpmu1.h b/include/drivers/st/stpmic1.h
similarity index 70%
rename from include/drivers/st/stpmu1.h
rename to include/drivers/st/stpmic1.h
index e75d9a6..f7e293b 100644
--- a/include/drivers/st/stpmu1.h
+++ b/include/drivers/st/stpmic1.h
@@ -1,11 +1,11 @@
/*
- * Copyright (c) 2016-2018, STMicroelectronics - All Rights Reserved
+ * Copyright (c) 2016-2019, STMicroelectronics - All Rights Reserved
*
* SPDX-License-Identifier: BSD-3-Clause
*/
-#ifndef STPMU1_H
-#define STPMU1_H
+#ifndef STPMIC1_H
+#define STPMIC1_H
#include <drivers/st/stm32_i2c.h>
#include <lib/utils_def.h>
@@ -84,18 +84,40 @@
#define ITSOURCE2_REG 0xB1U
#define ITSOURCE3_REG 0xB2U
#define ITSOURCE4_REG 0xB3U
+
+/* Registers masks */
#define LDO_VOLTAGE_MASK 0x7CU
#define BUCK_VOLTAGE_MASK 0xFCU
#define LDO_BUCK_VOLTAGE_SHIFT 2
-#define LDO_ENABLE_MASK 0x01U
-#define BUCK_ENABLE_MASK 0x01U
-#define BUCK_HPLP_ENABLE_MASK 0x02U
-#define LDO_HPLP_ENABLE_MASK 0x02U
+#define LDO_BUCK_ENABLE_MASK 0x01U
+#define LDO_BUCK_HPLP_ENABLE_MASK 0x02U
#define LDO_BUCK_HPLP_SHIFT 1
#define LDO_BUCK_RANK_MASK 0x01U
#define LDO_BUCK_RESET_MASK 0x01U
#define LDO_BUCK_PULL_DOWN_MASK 0x03U
+/* Pull down register */
+#define BUCK1_PULL_DOWN_SHIFT 0
+#define BUCK2_PULL_DOWN_SHIFT 2
+#define BUCK3_PULL_DOWN_SHIFT 4
+#define BUCK4_PULL_DOWN_SHIFT 6
+#define VREF_DDR_PULL_DOWN_SHIFT 4
+
+/* Buck Mask reset register */
+#define BUCK1_MASK_RESET 0
+#define BUCK2_MASK_RESET 1
+#define BUCK3_MASK_RESET 2
+#define BUCK4_MASK_RESET 3
+
+/* LDO Mask reset register */
+#define LDO1_MASK_RESET 0
+#define LDO2_MASK_RESET 1
+#define LDO3_MASK_RESET 2
+#define LDO4_MASK_RESET 3
+#define LDO5_MASK_RESET 4
+#define LDO6_MASK_RESET 5
+#define VREF_DDR_MASK_RESET 6
+
/* Main PMIC Control Register (MAIN_CONTROL_REG) */
#define ICC_EVENT_ENABLED BIT(4)
#define PWRCTRL_POLARITY_HIGH BIT(3)
@@ -127,14 +149,21 @@
#define SWIN_SWOUT_ENABLED BIT(2)
#define USBSW_OTG_SWITCH_ENABLED BIT(1)
-int stpmu1_switch_off(void);
-int stpmu1_register_read(uint8_t register_id, uint8_t *value);
-int stpmu1_register_write(uint8_t register_id, uint8_t value);
-int stpmu1_register_update(uint8_t register_id, uint8_t value, uint8_t mask);
-int stpmu1_regulator_enable(const char *name);
-int stpmu1_regulator_disable(const char *name);
-uint8_t stpmu1_is_regulator_enabled(const char *name);
-int stpmu1_regulator_voltage_set(const char *name, uint16_t millivolts);
-void stpmu1_bind_i2c(struct i2c_handle_s *i2c_handle, uint16_t i2c_addr);
+int stpmic1_powerctrl_on(void);
+int stpmic1_switch_off(void);
+int stpmic1_register_read(uint8_t register_id, uint8_t *value);
+int stpmic1_register_write(uint8_t register_id, uint8_t value);
+int stpmic1_register_update(uint8_t register_id, uint8_t value, uint8_t mask);
+int stpmic1_regulator_enable(const char *name);
+int stpmic1_regulator_disable(const char *name);
+uint8_t stpmic1_is_regulator_enabled(const char *name);
+int stpmic1_regulator_voltage_set(const char *name, uint16_t millivolts);
+int stpmic1_regulator_voltage_get(const char *name);
+int stpmic1_regulator_pull_down_set(const char *name);
+int stpmic1_regulator_mask_reset_set(const char *name);
+void stpmic1_bind_i2c(struct i2c_handle_s *i2c_handle, uint16_t i2c_addr);
-#endif /* STPMU1_H */
+int stpmic1_get_version(unsigned long *version);
+void stpmic1_dump_regulators(void);
+
+#endif /* STPMIC1_H */
diff --git a/include/dt-bindings/interrupt-controller/arm-gic.h b/include/dt-bindings/interrupt-controller/arm-gic.h
new file mode 100644
index 0000000..aa9158c
--- /dev/null
+++ b/include/dt-bindings/interrupt-controller/arm-gic.h
@@ -0,0 +1,21 @@
+/* SPDX-License-Identifier: GPL-2.0 or BSD-3-Clause */
+/*
+ * This header provides constants for the ARM GIC.
+ */
+
+#ifndef _DT_BINDINGS_INTERRUPT_CONTROLLER_ARM_GIC_H
+#define _DT_BINDINGS_INTERRUPT_CONTROLLER_ARM_GIC_H
+
+/* interrupt specifier cell 0 */
+
+#define GIC_SPI 0
+#define GIC_PPI 1
+
+#define IRQ_TYPE_NONE 0
+#define IRQ_TYPE_EDGE_RISING 1
+#define IRQ_TYPE_EDGE_FALLING 2
+#define IRQ_TYPE_EDGE_BOTH (IRQ_TYPE_EDGE_FALLING | IRQ_TYPE_EDGE_RISING)
+#define IRQ_TYPE_LEVEL_HIGH 4
+#define IRQ_TYPE_LEVEL_LOW 8
+
+#endif
diff --git a/include/dt-bindings/pinctrl/stm32-pinfunc.h b/include/dt-bindings/pinctrl/stm32-pinfunc.h
index e2f1f1b..7f6e4b9 100644
--- a/include/dt-bindings/pinctrl/stm32-pinfunc.h
+++ b/include/dt-bindings/pinctrl/stm32-pinfunc.h
@@ -32,4 +32,10 @@
#define STM32_PINMUX(port, line, mode) (((PIN_NO(port, line)) << 8) | (mode))
+/* package information */
+#define STM32MP157CAA 0x1
+#define STM32MP157CAB 0x2
+#define STM32MP157CAC 0x4
+#define STM32MP157CAD 0x8
+
#endif /* _DT_BINDINGS_STM32_PINFUNC_H */
diff --git a/include/lib/smccc.h b/include/lib/smccc.h
index b10c52c..94c39d2 100644
--- a/include/lib/smccc.h
+++ b/include/lib/smccc.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2016-2018, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2016-2019, ARM Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -19,15 +19,69 @@
| (((uint32_t)(_minor) & SMCCC_VERSION_MINOR_MASK) << \
SMCCC_VERSION_MINOR_SHIFT))
-#if SMCCC_MAJOR_VERSION == 1
-# define SMCCC_MINOR_VERSION U(1)
-# include <lib/smccc_v1.h>
-#elif SMCCC_MAJOR_VERSION == 2
-# define SMCCC_MINOR_VERSION U(0)
-# include <lib/smccc_v2.h>
-#else
-# error "Unsupported version of SMCCC."
-#endif
+#define SMCCC_MAJOR_VERSION U(1)
+#define SMCCC_MINOR_VERSION U(1)
+
+/*******************************************************************************
+ * Bit definitions inside the function id as per the SMC calling convention
+ ******************************************************************************/
+#define FUNCID_TYPE_SHIFT U(31)
+#define FUNCID_TYPE_MASK U(0x1)
+#define FUNCID_TYPE_WIDTH U(1)
+
+#define FUNCID_CC_SHIFT U(30)
+#define FUNCID_CC_MASK U(0x1)
+#define FUNCID_CC_WIDTH U(1)
+
+#define FUNCID_OEN_SHIFT U(24)
+#define FUNCID_OEN_MASK U(0x3f)
+#define FUNCID_OEN_WIDTH U(6)
+
+#define FUNCID_NUM_SHIFT U(0)
+#define FUNCID_NUM_MASK U(0xffff)
+#define FUNCID_NUM_WIDTH U(16)
+
+#define GET_SMC_TYPE(id) (((id) >> FUNCID_TYPE_SHIFT) & \
+ FUNCID_TYPE_MASK)
+#define GET_SMC_CC(id) (((id) >> FUNCID_CC_SHIFT) & \
+ FUNCID_CC_MASK)
+#define GET_SMC_OEN(id) (((id) >> FUNCID_OEN_SHIFT) & \
+ FUNCID_OEN_MASK)
+
+/*******************************************************************************
+ * Owning entity number definitions inside the function id as per the SMC
+ * calling convention
+ ******************************************************************************/
+#define OEN_ARM_START U(0)
+#define OEN_ARM_END U(0)
+#define OEN_CPU_START U(1)
+#define OEN_CPU_END U(1)
+#define OEN_SIP_START U(2)
+#define OEN_SIP_END U(2)
+#define OEN_OEM_START U(3)
+#define OEN_OEM_END U(3)
+#define OEN_STD_START U(4) /* Standard Service Calls */
+#define OEN_STD_END U(4)
+#define OEN_STD_HYP_START U(5) /* Standard Hypervisor Service calls */
+#define OEN_STD_HYP_END U(5)
+#define OEN_VEN_HYP_START U(6) /* Vendor Hypervisor Service calls */
+#define OEN_VEN_HYP_END U(6)
+#define OEN_TAP_START U(48) /* Trusted Applications */
+#define OEN_TAP_END U(49)
+#define OEN_TOS_START U(50) /* Trusted OS */
+#define OEN_TOS_END U(63)
+#define OEN_LIMIT U(64)
+
+/* Flags and error codes */
+#define SMC_64 U(1)
+#define SMC_32 U(0)
+
+#define SMC_TYPE_FAST ULL(1)
+#define SMC_TYPE_YIELD ULL(0)
+
+#define SMC_OK ULL(0)
+#define SMC_UNK -1
+#define SMC_PREEMPTED -2 /* Not defined by the SMCCC */
/* Various flags passed to SMC handlers */
#define SMC_FROM_SECURE (U(0) << 0)
diff --git a/include/lib/smccc_v1.h b/include/lib/smccc_v1.h
deleted file mode 100644
index 2b8bd8b..0000000
--- a/include/lib/smccc_v1.h
+++ /dev/null
@@ -1,75 +0,0 @@
-/*
- * Copyright (c) 2016-2018, ARM Limited and Contributors. All rights reserved.
- *
- * SPDX-License-Identifier: BSD-3-Clause
- */
-
-#ifndef SMCCC_V1_H
-#define SMCCC_V1_H
-
-#ifndef SMCCC_H
-#error "This file must only be included from smccc.h"
-#endif
-
-/*******************************************************************************
- * Bit definitions inside the function id as per the SMC calling convention
- ******************************************************************************/
-#define FUNCID_TYPE_SHIFT U(31)
-#define FUNCID_TYPE_MASK U(0x1)
-#define FUNCID_TYPE_WIDTH U(1)
-
-#define FUNCID_CC_SHIFT U(30)
-#define FUNCID_CC_MASK U(0x1)
-#define FUNCID_CC_WIDTH U(1)
-
-#define FUNCID_OEN_SHIFT U(24)
-#define FUNCID_OEN_MASK U(0x3f)
-#define FUNCID_OEN_WIDTH U(6)
-
-#define FUNCID_NUM_SHIFT U(0)
-#define FUNCID_NUM_MASK U(0xffff)
-#define FUNCID_NUM_WIDTH U(16)
-
-#define GET_SMC_TYPE(id) (((id) >> FUNCID_TYPE_SHIFT) & \
- FUNCID_TYPE_MASK)
-#define GET_SMC_CC(id) (((id) >> FUNCID_CC_SHIFT) & \
- FUNCID_CC_MASK)
-#define GET_SMC_OEN(id) (((id) >> FUNCID_OEN_SHIFT) & \
- FUNCID_OEN_MASK)
-
-/*******************************************************************************
- * Owning entity number definitions inside the function id as per the SMC
- * calling convention
- ******************************************************************************/
-#define OEN_ARM_START U(0)
-#define OEN_ARM_END U(0)
-#define OEN_CPU_START U(1)
-#define OEN_CPU_END U(1)
-#define OEN_SIP_START U(2)
-#define OEN_SIP_END U(2)
-#define OEN_OEM_START U(3)
-#define OEN_OEM_END U(3)
-#define OEN_STD_START U(4) /* Standard Service Calls */
-#define OEN_STD_END U(4)
-#define OEN_STD_HYP_START U(5) /* Standard Hypervisor Service calls */
-#define OEN_STD_HYP_END U(5)
-#define OEN_VEN_HYP_START U(6) /* Vendor Hypervisor Service calls */
-#define OEN_VEN_HYP_END U(6)
-#define OEN_TAP_START U(48) /* Trusted Applications */
-#define OEN_TAP_END U(49)
-#define OEN_TOS_START U(50) /* Trusted OS */
-#define OEN_TOS_END U(63)
-#define OEN_LIMIT U(64)
-
-/* Flags and error codes */
-#define SMC_64 U(1)
-#define SMC_32 U(0)
-
-#define SMC_TYPE_FAST ULL(1)
-#define SMC_TYPE_YIELD ULL(0)
-
-#define SMC_OK ULL(0)
-#define SMC_UNK -1
-#define SMC_PREEMPTED -2 /* Not defined by the SMCCC */
-
-#endif /* SMCCC_V1_H */
diff --git a/include/lib/smccc_v2.h b/include/lib/smccc_v2.h
deleted file mode 100644
index 22bf458..0000000
--- a/include/lib/smccc_v2.h
+++ /dev/null
@@ -1,85 +0,0 @@
-/*
- * Copyright (c) 2016-2018, ARM Limited and Contributors. All rights reserved.
- *
- * SPDX-License-Identifier: BSD-3-Clause
- */
-
-#ifndef SMCCC_V2_H
-#define SMCCC_V2_H
-
-#ifndef SMCCC_H
-#error "This file must only be included from smccc.h"
-#endif
-
-/*******************************************************************************
- * Bit definitions inside the function id as per the SMC calling convention
- ******************************************************************************/
-#define FUNCID_TYPE_SHIFT U(31)
-#define FUNCID_TYPE_MASK U(0x1)
-#define FUNCID_TYPE_WIDTH U(1)
-
-#define FUNCID_CC_SHIFT U(30)
-#define FUNCID_CC_MASK U(0x1)
-#define FUNCID_CC_WIDTH U(1)
-
-#define FUNCID_NAMESPACE_SHIFT U(28)
-#define FUNCID_NAMESPACE_MASK U(0x3)
-#define FUNCID_NAMESPACE_WIDTH U(2)
-
-#define FUNCID_OEN_SHIFT U(24)
-#define FUNCID_OEN_MASK U(0xf)
-#define FUNCID_OEN_WIDTH U(4)
-
-#define FUNCID_NUM_SHIFT U(0)
-#define FUNCID_NUM_MASK U(0xffff)
-#define FUNCID_NUM_WIDTH U(16)
-
-#define GET_SMC_TYPE(id) (((id) >> FUNCID_TYPE_SHIFT) & \
- FUNCID_TYPE_MASK)
-#define GET_SMC_CC(id) (((id) >> FUNCID_CC_SHIFT) & \
- FUNCID_CC_MASK)
-#define GET_SMC_NAMESPACE(id) (((id) >> FUNCID_NAMESPACE_SHIFT) & \
- FUNCID_NAMESPACE_MASK)
-#define GET_SMC_OEN(id) (((id) >> FUNCID_OEN_SHIFT) & \
- FUNCID_OEN_MASK)
-
-/*******************************************************************************
- * Owning entity number definitions inside the function id as per the SMC
- * calling convention
- ******************************************************************************/
-#define OEN_ARM_START U(0)
-#define OEN_ARM_END U(0)
-#define OEN_CPU_START U(1)
-#define OEN_CPU_END U(1)
-#define OEN_SIP_START U(2)
-#define OEN_SIP_END U(2)
-#define OEN_OEM_START U(3)
-#define OEN_OEM_END U(3)
-#define OEN_STD_START U(4) /* Standard Service Calls */
-#define OEN_STD_END U(4)
-#define OEN_STD_HYP_START U(5) /* Standard Hypervisor Service calls */
-#define OEN_STD_HYP_END U(5)
-#define OEN_VEN_HYP_START U(6) /* Vendor Hypervisor Service calls */
-#define OEN_VEN_HYP_END U(6)
-#define OEN_LIMIT U(16)
-
-/*******************************************************************************
- * Service namespaces as per the SMC Calling Convention v2.X
- ******************************************************************************/
-#define FUNCID_NAMESPACE_START U(0)
-#define FUNCID_NAMESPACE_COMPAT U(0)
-#define FUNCID_NAMESPACE_VENDOR U(1)
-#define FUNCID_NAMESPACE_SPRT U(2)
-#define FUNCID_NAMESPACE_SPCI U(3)
-#define FUNCID_NAMESPACE_LIMIT U(4)
-
-/* Flags and error codes */
-#define SMC_64 U(1)
-#define SMC_32 U(0)
-
-#define SMC_TYPE_FAST ULL(1)
-
-#define SMC_OK ULL(0)
-#define SMC_UNK -1
-
-#endif /* SMCCC_V2_H */
diff --git a/include/lib/xlat_tables/aarch32/xlat_tables_aarch32.h b/include/lib/xlat_tables/aarch32/xlat_tables_aarch32.h
index a333d1e..30eb5e9 100644
--- a/include/lib/xlat_tables/aarch32/xlat_tables_aarch32.h
+++ b/include/lib/xlat_tables/aarch32/xlat_tables_aarch32.h
@@ -63,8 +63,7 @@
* is 1.
*
* Note that this macro assumes that the given virtual address space size is
- * valid. Therefore, the caller is expected to check it is the case using the
- * CHECK_VIRT_ADDR_SPACE_SIZE() macro first.
+ * valid.
*/
#define GET_XLAT_TABLE_LEVEL_BASE(_virt_addr_space_sz) \
(((_virt_addr_space_sz) > (ULL(1) << L1_XLAT_ADDRESS_SHIFT)) ? \
diff --git a/include/lib/xlat_tables/aarch64/xlat_tables_aarch64.h b/include/lib/xlat_tables/aarch64/xlat_tables_aarch64.h
index cc5624c..3014c8f 100644
--- a/include/lib/xlat_tables/aarch64/xlat_tables_aarch64.h
+++ b/include/lib/xlat_tables/aarch64/xlat_tables_aarch64.h
@@ -43,14 +43,22 @@
* state.
*
* TCR.TxSZ is calculated as 64 minus the width of said address space.
- * The value of TCR.TxSZ must be in the range 16 to 39 [1], which means that
- * the virtual address space width must be in the range 48 to 25 bits.
+ * The value of TCR.TxSZ must be in the range 16 to 39 [1] or 48 [2],
+ * depending on Small Translation Table Support which means that
+ * the virtual address space width must be in the range 48 to 25 or 16 bits.
*
* [1] See the ARMv8-A Architecture Reference Manual (DDI 0487A.j) for more
* information:
* Page 1730: 'Input address size', 'For all translation stages'.
+ * [2] See section 12.2.55 in the ARMv8-A Architecture Reference Manual
+ * (DDI 0487D.a)
*/
+/* Maximum value of TCR_ELx.T(0,1)SZ is 39 */
#define MIN_VIRT_ADDR_SPACE_SIZE (ULL(1) << (U(64) - TCR_TxSZ_MAX))
+
+/* Maximum value of TCR_ELx.T(0,1)SZ is 48 */
+#define MIN_VIRT_ADDR_SPACE_SIZE_TTST \
+ (ULL(1) << (U(64) - TCR_TxSZ_MAX_TTST))
#define MAX_VIRT_ADDR_SPACE_SIZE (ULL(1) << (U(64) - TCR_TxSZ_MIN))
/*
@@ -58,9 +66,13 @@
* virtual address space size. For a 4 KB page size,
* - level 0 supports virtual address spaces of widths 48 to 40 bits;
* - level 1 from 39 to 31;
- * - level 2 from 30 to 25.
+ * - level 2 from 30 to 22.
+ * - level 3 from 21 to 16.
*
- * Wider or narrower address spaces are not supported. As a result, level 3
+ * Small Translation Table (Armv8.4-TTST) support allows the starting level
+ * of the translation table from 3 for 4KB granularity. See section 12.2.55 in
+ * the ARMv8-A Architecture Reference Manual (DDI 0487D.a). In Armv8.3 and below
+ * wider or narrower address spaces are not supported. As a result, level 3
* cannot be used as initial lookup level with 4 KB granularity. See section
* D4.2.5 in the ARMv8-A Architecture Reference Manual (DDI 0487A.j) for more
* information.
@@ -71,13 +83,14 @@
* is 1.
*
* Note that this macro assumes that the given virtual address space size is
- * valid. Therefore, the caller is expected to check it is the case using the
- * CHECK_VIRT_ADDR_SPACE_SIZE() macro first.
+ * valid.
*/
#define GET_XLAT_TABLE_LEVEL_BASE(_virt_addr_space_sz) \
(((_virt_addr_space_sz) > (ULL(1) << L0_XLAT_ADDRESS_SHIFT)) \
? 0U \
- : (((_virt_addr_space_sz) > (ULL(1) << L1_XLAT_ADDRESS_SHIFT)) \
- ? 1U : 2U))
+ : (((_virt_addr_space_sz) > (ULL(1) << L1_XLAT_ADDRESS_SHIFT)) \
+ ? 1U \
+ : (((_virt_addr_space_sz) > (ULL(1) << L2_XLAT_ADDRESS_SHIFT)) \
+ ? 2U : 3U)))
#endif /* XLAT_TABLES_AARCH64_H */
diff --git a/include/lib/xlat_tables/xlat_tables_arch.h b/include/lib/xlat_tables/xlat_tables_arch.h
index 251b020..7237534 100644
--- a/include/lib/xlat_tables/xlat_tables_arch.h
+++ b/include/lib/xlat_tables/xlat_tables_arch.h
@@ -14,18 +14,6 @@
#endif
/*
- * Evaluates to 1 if the given virtual address space size is valid, or 0 if it's
- * not.
- *
- * A valid size is one that is a power of 2 and is within the architectural
- * limits. Not that these limits are different for AArch32 and AArch64.
- */
-#define CHECK_VIRT_ADDR_SPACE_SIZE(size) \
- (((unsigned long long)(size) >= MIN_VIRT_ADDR_SPACE_SIZE) && \
- ((unsigned long long)(size) <= MAX_VIRT_ADDR_SPACE_SIZE) && \
- IS_POWER_OF_TWO(size))
-
-/*
* Evaluates to 1 if the given physical address space size is a power of 2,
* or 0 if it's not.
*/
diff --git a/include/lib/xlat_tables/xlat_tables_v2_helpers.h b/include/lib/xlat_tables/xlat_tables_v2_helpers.h
index ce5cf82..6a1be32 100644
--- a/include/lib/xlat_tables/xlat_tables_v2_helpers.h
+++ b/include/lib/xlat_tables/xlat_tables_v2_helpers.h
@@ -125,9 +125,6 @@
#define REGISTER_XLAT_CONTEXT_FULL_SPEC(_ctx_name, _mmap_count, \
_xlat_tables_count, _virt_addr_space_size, \
_phy_addr_space_size, _xlat_regime, _section_name)\
- CASSERT(CHECK_VIRT_ADDR_SPACE_SIZE(_virt_addr_space_size), \
- assert_invalid_virtual_addr_space_size_for_##_ctx_name);\
- \
CASSERT(CHECK_PHY_ADDR_SPACE_SIZE(_phy_addr_space_size), \
assert_invalid_physical_addr_space_sizefor_##_ctx_name);\
\
diff --git a/include/plat/arm/board/common/board_css_def.h b/include/plat/arm/board/common/board_css_def.h
index 6cca389..a77ea96 100644
--- a/include/plat/arm/board/common/board_css_def.h
+++ b/include/plat/arm/board/common/board_css_def.h
@@ -8,11 +8,10 @@
#define BOARD_CSS_DEF_H
#include <lib/utils_def.h>
+#include <plat/arm/board/common/v2m_def.h>
+#include <plat/arm/soc/common/soc_css_def.h>
#include <plat/common/common_def.h>
-#include <soc_css_def.h>
-#include <v2m_def.h>
-
/*
* Definitions common to all ARM CSS-based development platforms
*/
diff --git a/include/plat/arm/board/common/v2m_def.h b/include/plat/arm/board/common/v2m_def.h
index c5de407..6a6979c 100644
--- a/include/plat/arm/board/common/v2m_def.h
+++ b/include/plat/arm/board/common/v2m_def.h
@@ -6,7 +6,7 @@
#ifndef V2M_DEF_H
#define V2M_DEF_H
-#include <lib/xlat_tables/xlat_tables_compat.h>
+#include <lib/utils_def.h>
/* V2M motherboard system registers & offsets */
#define V2M_SYSREGS_BASE UL(0x1c010000)
diff --git a/include/plat/arm/common/arm_def.h b/include/plat/arm/common/arm_def.h
index e27dd80..62623c1 100644
--- a/include/plat/arm/common/arm_def.h
+++ b/include/plat/arm/common/arm_def.h
@@ -348,7 +348,20 @@
* and limit. Leave enough space of BL2 meminfo.
*/
#define ARM_TB_FW_CONFIG_BASE (ARM_BL_RAM_BASE + sizeof(meminfo_t))
-#define ARM_TB_FW_CONFIG_LIMIT (ARM_BL_RAM_BASE + PAGE_SIZE)
+#define ARM_TB_FW_CONFIG_LIMIT (ARM_BL_RAM_BASE + (PAGE_SIZE / 2U))
+
+/*
+ * Boot parameters passed from BL2 to BL31/BL32 are stored here
+ */
+#define ARM_BL2_MEM_DESC_BASE ARM_TB_FW_CONFIG_LIMIT
+#define ARM_BL2_MEM_DESC_LIMIT (ARM_BL2_MEM_DESC_BASE + \
+ (PAGE_SIZE / 2U))
+
+/*
+ * Define limit of firmware configuration memory:
+ * ARM_TB_FW_CONFIG + ARM_BL2_MEM_DESC memory
+ */
+#define ARM_FW_CONFIG_LIMIT (ARM_BL_RAM_BASE + PAGE_SIZE)
/*******************************************************************************
* BL1 specific defines.
@@ -443,7 +456,7 @@
* SP_MIN is the only BL image in SRAM. Allocate the whole of SRAM (excluding
* the page reserved for fw_configs) to BL32
*/
-# define BL32_BASE ARM_TB_FW_CONFIG_LIMIT
+# define BL32_BASE ARM_FW_CONFIG_LIMIT
# define BL32_LIMIT (ARM_BL_RAM_BASE + ARM_BL_RAM_SIZE)
# else
/* Put BL32 below BL2 in the Trusted SRAM.*/
@@ -481,7 +494,7 @@
# define TSP_SEC_MEM_BASE ARM_BL_RAM_BASE
# define TSP_SEC_MEM_SIZE ARM_BL_RAM_SIZE
# define TSP_PROGBITS_LIMIT BL31_BASE
-# define BL32_BASE ARM_TB_FW_CONFIG_LIMIT
+# define BL32_BASE ARM_FW_CONFIG_LIMIT
# define BL32_LIMIT BL31_BASE
# elif ARM_TSP_RAM_LOCATION_ID == ARM_TRUSTED_DRAM_ID
# define TSP_SEC_MEM_BASE PLAT_ARM_TRUSTED_DRAM_BASE
diff --git a/include/plat/arm/common/arm_spm_def.h b/include/plat/arm/common/arm_spm_def.h
index 997e156..16c806b 100644
--- a/include/plat/arm/common/arm_spm_def.h
+++ b/include/plat/arm/common/arm_spm_def.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2017, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2017-2019, ARM Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -32,7 +32,7 @@
#define PLAT_SPM_HEAP_BASE (PLAT_SP_PACKAGE_BASE + PLAT_SP_PACKAGE_SIZE)
#define PLAT_SPM_HEAP_SIZE (BL32_LIMIT - BL32_BASE - PLAT_SP_PACKAGE_SIZE)
-#if SPM_DEPRECATED
+#if SPM_MM
/*
* If BL31 is placed in DRAM, place the Secure Partition in DRAM right after the
@@ -121,7 +121,7 @@
/* Total number of memory regions with distinct properties */
#define ARM_SP_IMAGE_NUM_MEM_REGIONS 6
-#endif /* SPM_DEPRECATED */
+#endif /* SPM_MM */
/* Cookies passed to the Secure Partition at boot. Not used by ARM platforms. */
#define PLAT_SPM_COOKIE_0 ULL(0)
diff --git a/include/plat/arm/common/plat_arm.h b/include/plat/arm/common/plat_arm.h
index d1c03be..9d6786f 100644
--- a/include/plat/arm/common/plat_arm.h
+++ b/include/plat/arm/common/plat_arm.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2015-2018, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2015-2019, ARM Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -38,7 +38,7 @@
* - Region 1 with secure access only;
* - the remaining DRAM regions access from the given Non-Secure masters.
******************************************************************************/
-#if ENABLE_SPM && SPM_DEPRECATED
+#if ENABLE_SPM && SPM_MM
#define ARM_TZC_REGIONS_DEF \
{ARM_AP_TZC_DRAM1_BASE, ARM_EL3_TZC_DRAM1_END, \
TZC_REGION_S_RDWR, 0}, \
@@ -188,6 +188,7 @@
uint32_t arm_get_spsr_for_bl32_entry(void);
uint32_t arm_get_spsr_for_bl33_entry(void);
int arm_bl2_handle_post_image_load(unsigned int image_id);
+struct bl_params *arm_get_next_bl_params(void);
/* BL2 at EL3 functions */
void arm_bl2_el3_early_platform_setup(void);
diff --git a/include/plat/arm/css/common/css_def.h b/include/plat/arm/css/common/css_def.h
index 575db04..ec28db0 100644
--- a/include/plat/arm/css/common/css_def.h
+++ b/include/plat/arm/css/common/css_def.h
@@ -183,7 +183,7 @@
#endif /* CSS_LOAD_SCP_IMAGES */
/* Load address of Non-Secure Image for CSS platform ports */
-#define PLAT_ARM_NS_IMAGE_OFFSET U(0xE0000000)
+#define PLAT_ARM_NS_IMAGE_BASE U(0xE0000000)
/* TZC related constants */
#define PLAT_ARM_TZC_FILTERS TZC_400_REGION_ATTR_FILTER_BIT_ALL
diff --git a/include/services/mm_svc.h b/include/services/mm_svc.h
index c81e904..c111326 100644
--- a/include/services/mm_svc.h
+++ b/include/services/mm_svc.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2018, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2018-2019, ARM Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -7,7 +7,7 @@
#ifndef MM_SVC_H
#define MM_SVC_H
-#if SPM_DEPRECATED
+#if SPM_MM
#include <lib/utils_def.h>
@@ -30,6 +30,6 @@
#define MM_COMMUNICATE_AARCH64 U(0xC4000041)
#define MM_COMMUNICATE_AARCH32 U(0x84000041)
-#endif /* SPM_DEPRECATED */
+#endif /* SPM_MM */
#endif /* MM_SVC_H */
diff --git a/include/services/secure_partition.h b/include/services/secure_partition.h
index 47f6368..0510f80 100644
--- a/include/services/secure_partition.h
+++ b/include/services/secure_partition.h
@@ -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
*/
@@ -7,7 +7,7 @@
#ifndef SECURE_PARTITION_H
#define SECURE_PARTITION_H
-#if SPM_DEPRECATED
+#if SPM_MM
#include <stdint.h>
@@ -49,6 +49,6 @@
secure_partition_mp_info_t *mp_info;
} secure_partition_boot_info_t;
-#endif /* SPM_DEPRECATED */
+#endif /* SPM_MM */
#endif /* SECURE_PARTITION_H */
diff --git a/include/services/spci_svc.h b/include/services/spci_svc.h
index b82cf1e..1d02bfa 100644
--- a/include/services/spci_svc.h
+++ b/include/services/spci_svc.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2018, Arm Limited. All rights reserved.
+ * Copyright (c) 2018-2019, Arm Limited. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -34,7 +34,10 @@
#define SPCI_FID_TUN_SHIFT U(24)
#define SPCI_FID_TUN_MASK U(0x7)
-#define SPCI_SMC(spci_fid) ((FUNCID_NAMESPACE_SPCI << FUNCID_NAMESPACE_SHIFT) | \
+#define OEN_SPCI_START U(0x30)
+#define OEN_SPCI_END U(0x3F)
+
+#define SPCI_SMC(spci_fid) ((OEN_SPCI_START << FUNCID_OEN_SHIFT) | \
(U(1) << 31) | (spci_fid))
#define SPCI_MISC_32(misc_fid) ((SMC_32 << FUNCID_CC_SHIFT) | \
SPCI_FID_MISC_FLAG | \
diff --git a/include/services/spm_svc.h b/include/services/spm_svc.h
index fcb409b..57912e8 100644
--- a/include/services/spm_svc.h
+++ b/include/services/spm_svc.h
@@ -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
*/
@@ -7,7 +7,7 @@
#ifndef SPM_SVC_H
#define SPM_SVC_H
-#if SPM_DEPRECATED
+#if SPM_MM
#include <lib/utils_def.h>
@@ -61,7 +61,7 @@
#define SPM_DENIED -3
#define SPM_NO_MEMORY -5
-#endif /* SPM_DEPRECATED */
+#endif /* SPM_MM */
#ifndef __ASSEMBLY__
@@ -69,7 +69,7 @@
int32_t spm_setup(void);
-#if SPM_DEPRECATED
+#if SPM_MM
uint64_t spm_smc_handler(uint32_t smc_fid,
uint64_t x1,
@@ -83,7 +83,7 @@
/* Helper to enter a Secure Partition */
uint64_t spm_sp_call(uint32_t smc_fid, uint64_t x1, uint64_t x2, uint64_t x3);
-#endif /* SPM_DEPRECATED */
+#endif /* SPM_MM */
#endif /* __ASSEMBLY__ */
diff --git a/include/services/sprt_svc.h b/include/services/sprt_svc.h
index bd695e5..2421ea2 100644
--- a/include/services/sprt_svc.h
+++ b/include/services/sprt_svc.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2018, Arm Limited. All rights reserved.
+ * Copyright (c) 2018-2019, Arm Limited. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -37,10 +37,13 @@
/* Definitions to build the complete SMC ID */
-#define SPRT_SMC_64(sprt_fid) ((FUNCID_NAMESPACE_SPRT << FUNCID_NAMESPACE_SHIFT) | \
+#define OEN_SPRT_START U(0x20)
+#define OEN_SPRT_END U(0x2F)
+
+#define SPRT_SMC_64(sprt_fid) ((OEN_SPRT_START << FUNCID_OEN_SHIFT) | \
(U(1) << 31) | ((sprt_fid) & SPRT_FID_MASK) | \
(SMC_64 << FUNCID_CC_SHIFT))
-#define SPRT_SMC_32(sprt_fid) ((FUNCID_NAMESPACE_SPRT << FUNCID_NAMESPACE_SHIFT) | \
+#define SPRT_SMC_32(sprt_fid) ((OEN_SPRT_START << FUNCID_OEN_SHIFT) | \
(U(1) << 31) | ((sprt_fid) & SPRT_FID_MASK) | \
(SMC_32 << FUNCID_CC_SHIFT))
diff --git a/lib/utils/mem_region.c b/lib/utils/mem_region.c
index 662f6a0..08bccf6 100644
--- a/lib/utils/mem_region.c
+++ b/lib/utils/mem_region.c
@@ -6,7 +6,9 @@
#include <assert.h>
+#include <common/debug.h>
#include <lib/utils.h>
+#include <lib/xlat_tables/xlat_tables_compat.h>
/*
* All the regions defined in mem_region_t must have the following properties
diff --git a/lib/xlat_tables/aarch32/xlat_tables.c b/lib/xlat_tables/aarch32/xlat_tables.c
index 468a9e7..4b01b9b 100644
--- a/lib/xlat_tables/aarch32/xlat_tables.c
+++ b/lib/xlat_tables/aarch32/xlat_tables.c
@@ -55,6 +55,11 @@
{
unsigned long long max_pa;
uintptr_t max_va;
+
+ assert(PLAT_VIRT_ADDR_SPACE_SIZE >= MIN_VIRT_ADDR_SPACE_SIZE);
+ assert(PLAT_VIRT_ADDR_SPACE_SIZE <= MAX_VIRT_ADDR_SPACE_SIZE);
+ assert(IS_POWER_OF_TWO(PLAT_VIRT_ADDR_SPACE_SIZE));
+
print_mmap();
init_xlation_table(0U, base_xlation_table, XLAT_TABLE_LEVEL_BASE,
&max_va, &max_pa);
diff --git a/lib/xlat_tables/aarch64/xlat_tables.c b/lib/xlat_tables/aarch64/xlat_tables.c
index 71f491a..e64fd3e 100644
--- a/lib/xlat_tables/aarch64/xlat_tables.c
+++ b/lib/xlat_tables/aarch64/xlat_tables.c
@@ -10,7 +10,7 @@
#include <platform_def.h>
#include <arch.h>
-#include <arch_helpers.h>
+#include <arch_features.h>
#include <common/bl_common.h>
#include <lib/utils.h>
#include <lib/xlat_tables/xlat_tables.h>
@@ -79,6 +79,21 @@
return (1ULL << pa_range_bits_arr[pa_range]) - 1ULL;
}
+
+/*
+ * Return minimum virtual address space size supported by the architecture
+ */
+static uintptr_t xlat_get_min_virt_addr_space_size(void)
+{
+ uintptr_t ret;
+
+ if (is_armv8_4_ttst_present())
+ ret = MIN_VIRT_ADDR_SPACE_SIZE_TTST;
+ else
+ ret = MIN_VIRT_ADDR_SPACE_SIZE;
+
+ return ret;
+}
#endif /* ENABLE_ASSERTIONS */
unsigned int xlat_arch_current_el(void)
@@ -104,6 +119,12 @@
{
unsigned long long max_pa;
uintptr_t max_va;
+
+ assert(PLAT_VIRT_ADDR_SPACE_SIZE >=
+ (xlat_get_min_virt_addr_space_size() - 1U));
+ assert(PLAT_VIRT_ADDR_SPACE_SIZE <= MAX_VIRT_ADDR_SPACE_SIZE);
+ assert(IS_POWER_OF_TWO(PLAT_VIRT_ADDR_SPACE_SIZE));
+
print_mmap();
init_xlation_table(0U, base_xlation_table, XLAT_TABLE_LEVEL_BASE,
&max_va, &max_pa);
diff --git a/lib/xlat_tables/xlat_tables_private.h b/lib/xlat_tables/xlat_tables_private.h
index 4390f34..82bc70c 100644
--- a/lib/xlat_tables/xlat_tables_private.h
+++ b/lib/xlat_tables/xlat_tables_private.h
@@ -16,9 +16,6 @@
#error xlat tables v2 must be used with HW_ASSISTED_COHERENCY
#endif
-CASSERT(CHECK_VIRT_ADDR_SPACE_SIZE(PLAT_VIRT_ADDR_SPACE_SIZE),
- assert_valid_virt_addr_space_size);
-
CASSERT(CHECK_PHY_ADDR_SPACE_SIZE(PLAT_PHY_ADDR_SPACE_SIZE),
assert_valid_phy_addr_space_size);
diff --git a/lib/xlat_tables_v2/aarch32/xlat_tables_arch.c b/lib/xlat_tables_v2/aarch32/xlat_tables_arch.c
index 913c86d..b69c670 100644
--- a/lib/xlat_tables_v2/aarch32/xlat_tables_arch.c
+++ b/lib/xlat_tables_v2/aarch32/xlat_tables_arch.c
@@ -45,6 +45,14 @@
/* Physical address space size for long descriptor format. */
return (1ULL << 40) - 1ULL;
}
+
+/*
+ * Return minimum virtual address space size supported by the architecture
+ */
+uintptr_t xlat_get_min_virt_addr_space_size(void)
+{
+ return MIN_VIRT_ADDR_SPACE_SIZE;
+}
#endif /* ENABLE_ASSERTIONS*/
bool is_mmu_enabled_ctx(const xlat_ctx_t *ctx)
@@ -193,7 +201,12 @@
if (max_va != UINT32_MAX) {
uintptr_t virtual_addr_space_size = max_va + 1U;
- assert(CHECK_VIRT_ADDR_SPACE_SIZE(virtual_addr_space_size));
+ assert(virtual_addr_space_size >=
+ xlat_get_min_virt_addr_space_size());
+ assert(virtual_addr_space_size <=
+ MAX_VIRT_ADDR_SPACE_SIZE);
+ assert(IS_POWER_OF_TWO(virtual_addr_space_size));
+
/*
* __builtin_ctzll(0) is undefined but here we are guaranteed
* that virtual_addr_space_size is in the range [1, UINT32_MAX].
diff --git a/lib/xlat_tables_v2/aarch64/xlat_tables_arch.c b/lib/xlat_tables_v2/aarch64/xlat_tables_arch.c
index 228f751..e7593dd 100644
--- a/lib/xlat_tables_v2/aarch64/xlat_tables_arch.c
+++ b/lib/xlat_tables_v2/aarch64/xlat_tables_arch.c
@@ -101,6 +101,21 @@
return (1ULL << pa_range_bits_arr[pa_range]) - 1ULL;
}
+
+/*
+ * Return minimum virtual address space size supported by the architecture
+ */
+uintptr_t xlat_get_min_virt_addr_space_size(void)
+{
+ uintptr_t ret;
+
+ if (is_armv8_4_ttst_present())
+ ret = MIN_VIRT_ADDR_SPACE_SIZE_TTST;
+ else
+ ret = MIN_VIRT_ADDR_SPACE_SIZE;
+
+ return ret;
+}
#endif /* ENABLE_ASSERTIONS*/
bool is_mmu_enabled_ctx(const xlat_ctx_t *ctx)
@@ -221,7 +236,11 @@
assert(max_va < ((uint64_t)UINTPTR_MAX));
virtual_addr_space_size = (uintptr_t)max_va + 1U;
- assert(CHECK_VIRT_ADDR_SPACE_SIZE(virtual_addr_space_size));
+
+ assert(virtual_addr_space_size >=
+ xlat_get_min_virt_addr_space_size());
+ assert(virtual_addr_space_size <= MAX_VIRT_ADDR_SPACE_SIZE);
+ assert(IS_POWER_OF_TWO(virtual_addr_space_size));
/*
* __builtin_ctzll(0) is undefined but here we are guaranteed that
diff --git a/lib/xlat_tables_v2/xlat_tables_core.c b/lib/xlat_tables_v2/xlat_tables_core.c
index c49554f..4820b4f 100644
--- a/lib/xlat_tables_v2/xlat_tables_core.c
+++ b/lib/xlat_tables_v2/xlat_tables_core.c
@@ -1146,6 +1146,11 @@
mmap_region_t *mm = ctx->mmap;
+ assert(ctx->va_max_address >=
+ (xlat_get_min_virt_addr_space_size() - 1U));
+ assert(ctx->va_max_address <= (MAX_VIRT_ADDR_SPACE_SIZE - 1U));
+ assert(IS_POWER_OF_TWO(ctx->va_max_address + 1U));
+
xlat_mmap_print(mm);
/* All tables must be zeroed before mapping any region. */
diff --git a/lib/xlat_tables_v2/xlat_tables_private.h b/lib/xlat_tables_v2/xlat_tables_private.h
index fc70955..70ef395 100644
--- a/lib/xlat_tables_v2/xlat_tables_private.h
+++ b/lib/xlat_tables_v2/xlat_tables_private.h
@@ -102,4 +102,9 @@
/* Returns true if the data cache is enabled at the current EL. */
bool is_dcache_enabled(void);
+/*
+ * Returns minimum virtual address space size supported by the architecture
+ */
+uintptr_t xlat_get_min_virt_addr_space_size(void);
+
#endif /* XLAT_TABLES_PRIVATE_H */
diff --git a/maintainers.rst b/maintainers.rst
index 1f7d03e..5bbaf3b 100644
--- a/maintainers.rst
+++ b/maintainers.rst
@@ -175,8 +175,12 @@
----------------------------
:M: Antonio Niño Díaz <antonio.ninodiaz@arm.com>
:G: `antonio-nino-diaz-arm`_
+:M: Ying-Chun Liu (PaulLiu) <paul.liu@linaro.org>
+:G: `grandpaul`_
:F: docs/plat/rpi3.rst
:F: plat/rpi3/
+:F: drivers/rpi3/
+:F: include/drivers/rpi3/
Renesas rcar-gen3 platform port
-------------------------------
diff --git a/make_helpers/build_macros.mk b/make_helpers/build_macros.mk
index 961cabf..73b84c3 100644
--- a/make_helpers/build_macros.mk
+++ b/make_helpers/build_macros.mk
@@ -464,7 +464,7 @@
$(DOBJ): $(2) $(filter-out %.d,$(MAKEFILE_LIST)) | fdt_dirs
$${ECHO} " CPP $$<"
$(eval DTBS := $(addprefix $(1)/,$(call SOURCES_TO_DTBS,$(2))))
- $$(Q)$$(CPP) $$(CPPFLAGS) -x assembler-with-cpp -MT $(DTBS) -MMD -MF $(DTSDEP) -o $(DPRE) $$<
+ $$(Q)$$(PP) $$(DTC_CPPFLAGS) -MT $(DTBS) -MMD -MF $(DTSDEP) -o $(DPRE) $$<
$${ECHO} " DTC $$<"
$$(Q)$$(DTC) $$(DTC_FLAGS) -i fdts -d $(DTBDEP) -o $$@ $(DPRE)
diff --git a/make_helpers/defaults.mk b/make_helpers/defaults.mk
index a55e729..c1aa320 100644
--- a/make_helpers/defaults.mk
+++ b/make_helpers/defaults.mk
@@ -1,5 +1,5 @@
#
-# Copyright (c) 2016-2018, ARM Limited and Contributors. All rights reserved.
+# Copyright (c) 2016-2019, ARM Limited and Contributors. All rights reserved.
#
# SPDX-License-Identifier: BSD-3-Clause
#
@@ -153,17 +153,14 @@
# cores stack
RECLAIM_INIT_CODE := 0
-# Default to SMCCC Version 1.X
-SMCCC_MAJOR_VERSION := 1
-
# SPD choice
SPD := none
# For including the Secure Partition Manager
ENABLE_SPM := 0
-# Use the deprecated SPM based on MM
-SPM_DEPRECATED := 1
+# Use the SPM based on MM
+SPM_MM := 1
# Flag to introduce an infinite loop in BL1 just before it exits into the next
# image. This is meant to help debugging the post-BL2 phase.
diff --git a/plat/arm/board/common/board_common.mk b/plat/arm/board/common/board_common.mk
index 487aad7..b98dfd4 100644
--- a/plat/arm/board/common/board_common.mk
+++ b/plat/arm/board/common/board_common.mk
@@ -4,8 +4,6 @@
# SPDX-License-Identifier: BSD-3-Clause
#
-PLAT_INCLUDES += -Iinclude/plat/arm/board/common/
-
PLAT_BL_COMMON_SOURCES += drivers/arm/pl011/${ARCH}/pl011_console.S \
plat/arm/board/common/${ARCH}/board_arm_helpers.S
diff --git a/plat/arm/board/fvp/aarch32/fvp_helpers.S b/plat/arm/board/fvp/aarch32/fvp_helpers.S
index f689557..9985c1d 100644
--- a/plat/arm/board/fvp/aarch32/fvp_helpers.S
+++ b/plat/arm/board/fvp/aarch32/fvp_helpers.S
@@ -6,10 +6,9 @@
#include <arch.h>
#include <asm_macros.S>
+#include <drivers/arm/fvp/fvp_pwrc.h>
#include <platform_def.h>
-#include "../drivers/pwrc/fvp_pwrc.h"
-
.globl plat_secondary_cold_boot_setup
.globl plat_get_my_entrypoint
.globl plat_is_my_cpu_primary
diff --git a/plat/arm/board/fvp/aarch64/fvp_helpers.S b/plat/arm/board/fvp/aarch64/fvp_helpers.S
index 02a3c7c..09f19f6 100644
--- a/plat/arm/board/fvp/aarch64/fvp_helpers.S
+++ b/plat/arm/board/fvp/aarch64/fvp_helpers.S
@@ -8,10 +8,9 @@
#include <asm_macros.S>
#include <drivers/arm/gicv2.h>
#include <drivers/arm/gicv3.h>
+#include <drivers/arm/fvp/fvp_pwrc.h>
#include <platform_def.h>
-#include "../drivers/pwrc/fvp_pwrc.h"
-
.globl plat_secondary_cold_boot_setup
.globl plat_get_my_entrypoint
.globl plat_is_my_cpu_primary
diff --git a/plat/arm/board/fvp/fvp_bl1_setup.c b/plat/arm/board/fvp/fvp_bl1_setup.c
index d6e82f5..75090e8 100644
--- a/plat/arm/board/fvp/fvp_bl1_setup.c
+++ b/plat/arm/board/fvp/fvp_bl1_setup.c
@@ -5,10 +5,9 @@
*/
#include <common/tbbr/tbbr_img_def.h>
+#include <plat/arm/common/plat_arm.h>
#include <plat/common/platform.h>
-#include <plat_arm.h>
-
#include "fvp_private.h"
/*******************************************************************************
diff --git a/plat/arm/board/fvp/fvp_bl2_el3_setup.c b/plat/arm/board/fvp/fvp_bl2_el3_setup.c
index 69f2f7a..7def56a 100644
--- a/plat/arm/board/fvp/fvp_bl2_el3_setup.c
+++ b/plat/arm/board/fvp/fvp_bl2_el3_setup.c
@@ -4,7 +4,8 @@
* SPDX-License-Identifier: BSD-3-Clause
*/
-#include <plat_arm.h>
+#include <plat/arm/common/plat_arm.h>
+
#include "fvp_private.h"
void bl2_el3_early_platform_setup(u_register_t arg0 __unused,
diff --git a/plat/arm/board/fvp/fvp_bl2_setup.c b/plat/arm/board/fvp/fvp_bl2_setup.c
index 7aa620b..d280949 100644
--- a/plat/arm/board/fvp/fvp_bl2_setup.c
+++ b/plat/arm/board/fvp/fvp_bl2_setup.c
@@ -7,10 +7,10 @@
#include <drivers/arm/sp804_delay_timer.h>
#include <drivers/generic_delay_timer.h>
#include <lib/mmio.h>
+#include <plat/arm/common/plat_arm.h>
#include <plat/common/platform.h>
#include <platform_def.h>
-#include <plat_arm.h>
#include "fvp_private.h"
void bl2_early_platform_setup2(u_register_t arg0, u_register_t arg1, u_register_t arg2, u_register_t arg3)
diff --git a/plat/arm/board/fvp/fvp_bl2u_setup.c b/plat/arm/board/fvp/fvp_bl2u_setup.c
index 6367be6..a8db055 100644
--- a/plat/arm/board/fvp/fvp_bl2u_setup.c
+++ b/plat/arm/board/fvp/fvp_bl2u_setup.c
@@ -4,10 +4,10 @@
* SPDX-License-Identifier: BSD-3-Clause
*/
+#include <plat/arm/common/plat_arm.h>
#include <plat/common/platform.h>
#include <platform_def.h>
-#include <plat_arm.h>
#include "fvp_private.h"
void bl2u_early_platform_setup(struct meminfo *mem_layout, void *plat_info)
diff --git a/plat/arm/board/fvp/fvp_bl31_setup.c b/plat/arm/board/fvp/fvp_bl31_setup.c
index 5f2121c..7f28b20 100644
--- a/plat/arm/board/fvp/fvp_bl31_setup.c
+++ b/plat/arm/board/fvp/fvp_bl31_setup.c
@@ -5,10 +5,10 @@
*/
#include <drivers/arm/smmu_v3.h>
+#include <plat/arm/common/arm_config.h>
+#include <plat/arm/common/plat_arm.h>
#include <plat/common/platform.h>
-#include <arm_config.h>
-#include <plat_arm.h>
#include "fvp_private.h"
void __init bl31_early_platform_setup2(u_register_t arg0,
diff --git a/plat/arm/board/fvp/fvp_common.c b/plat/arm/board/fvp/fvp_common.c
index 4da807a..b885b47 100644
--- a/plat/arm/board/fvp/fvp_common.c
+++ b/plat/arm/board/fvp/fvp_common.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2013-2018, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2013-2019, ARM Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -12,13 +12,12 @@
#include <drivers/arm/gicv2.h>
#include <lib/mmio.h>
#include <lib/xlat_tables/xlat_tables_compat.h>
+#include <plat/arm/common/arm_config.h>
+#include <plat/arm/common/plat_arm.h>
#include <plat/common/platform.h>
#include <platform_def.h>
#include <services/secure_partition.h>
-#include <arm_config.h>
-#include <plat_arm.h>
-
#include "fvp_private.h"
/* Defines for GIC Driver build time selection */
@@ -95,10 +94,10 @@
ARM_MAP_BL1_RW,
#endif
#endif /* TRUSTED_BOARD_BOOT */
-#if ENABLE_SPM && SPM_DEPRECATED
+#if ENABLE_SPM && SPM_MM
ARM_SP_IMAGE_MMAP,
#endif
-#if ENABLE_SPM && !SPM_DEPRECATED
+#if ENABLE_SPM && !SPM_MM
PLAT_MAP_SP_PACKAGE_MEM_RW,
#endif
#if ARM_BL31_IN_DRAM
@@ -126,16 +125,16 @@
MAP_DEVICE0,
MAP_DEVICE1,
ARM_V2M_MAP_MEM_PROTECT,
-#if ENABLE_SPM && SPM_DEPRECATED
+#if ENABLE_SPM && SPM_MM
ARM_SPM_BUF_EL3_MMAP,
#endif
-#if ENABLE_SPM && !SPM_DEPRECATED
+#if ENABLE_SPM && !SPM_MM
PLAT_MAP_SP_PACKAGE_MEM_RO,
#endif
{0}
};
-#if ENABLE_SPM && defined(IMAGE_BL31) && SPM_DEPRECATED
+#if ENABLE_SPM && defined(IMAGE_BL31) && SPM_MM
const mmap_region_t plat_arm_secure_partition_mmap[] = {
V2M_MAP_IOFPGA_EL0, /* for the UART */
MAP_REGION_FLAT(DEVICE0_BASE, \
@@ -189,7 +188,7 @@
}
#endif
-#if ENABLE_SPM && defined(IMAGE_BL31) && SPM_DEPRECATED
+#if ENABLE_SPM && defined(IMAGE_BL31) && SPM_MM
/*
* Boot information passed to a secure partition during initialisation. Linear
* indices in MP information will be filled at runtime.
diff --git a/plat/arm/board/fvp/fvp_io_storage.c b/plat/arm/board/fvp/fvp_io_storage.c
index e186b30..9c4c1d5 100644
--- a/plat/arm/board/fvp/fvp_io_storage.c
+++ b/plat/arm/board/fvp/fvp_io_storage.c
@@ -11,10 +11,9 @@
#include <drivers/io/io_semihosting.h>
#include <drivers/io/io_storage.h>
#include <lib/semihosting.h>
+#include <plat/arm/common/plat_arm.h>
#include <plat/common/common_def.h>
-#include <plat_arm.h>
-
/* Semihosting filenames */
#define BL2_IMAGE_NAME "bl2.bin"
#define BL31_IMAGE_NAME "bl31.bin"
diff --git a/plat/arm/board/fvp/fvp_pm.c b/plat/arm/board/fvp/fvp_pm.c
index 8ba8281..ecf0b01 100644
--- a/plat/arm/board/fvp/fvp_pm.c
+++ b/plat/arm/board/fvp/fvp_pm.c
@@ -10,17 +10,15 @@
#include <arch_helpers.h>
#include <common/debug.h>
#include <drivers/arm/gicv3.h>
+#include <drivers/arm/fvp/fvp_pwrc.h>
#include <lib/extensions/spe.h>
#include <lib/mmio.h>
#include <lib/psci/psci.h>
+#include <plat/arm/common/arm_config.h>
+#include <plat/arm/common/plat_arm.h>
#include <plat/common/platform.h>
#include <platform_def.h>
-#include <arm_config.h>
-#include <plat_arm.h>
-
-#include "../../../../drivers/arm/gic/v3/gicv3_private.h"
-#include "drivers/pwrc/fvp_pwrc.h"
#include "fvp_private.h"
diff --git a/plat/arm/board/fvp/fvp_private.h b/plat/arm/board/fvp/fvp_private.h
index e7dea99..3d96537 100644
--- a/plat/arm/board/fvp/fvp_private.h
+++ b/plat/arm/board/fvp/fvp_private.h
@@ -7,7 +7,7 @@
#ifndef FVP_PRIVATE_H
#define FVP_PRIVATE_H
-#include <plat_arm.h>
+#include <plat/arm/common/plat_arm.h>
/*******************************************************************************
* Function and variable prototypes
diff --git a/plat/arm/board/fvp/fvp_security.c b/plat/arm/board/fvp/fvp_security.c
index 028522c..80ec217 100644
--- a/plat/arm/board/fvp/fvp_security.c
+++ b/plat/arm/board/fvp/fvp_security.c
@@ -4,8 +4,8 @@
* SPDX-License-Identifier: BSD-3-Clause
*/
-#include <arm_config.h>
-#include <plat_arm.h>
+#include <plat/arm/common/arm_config.h>
+#include <plat/arm/common/plat_arm.h>
/*
* We assume that all security programming is done by the primary core.
diff --git a/plat/arm/board/fvp/fvp_topology.c b/plat/arm/board/fvp/fvp_topology.c
index 3384a2f..9823fb3 100644
--- a/plat/arm/board/fvp/fvp_topology.c
+++ b/plat/arm/board/fvp/fvp_topology.c
@@ -7,13 +7,12 @@
#include <platform_def.h>
#include <arch.h>
+#include <drivers/arm/fvp/fvp_pwrc.h>
#include <lib/cassert.h>
+#include <plat/arm/common/arm_config.h>
+#include <plat/arm/common/plat_arm.h>
#include <plat/common/platform.h>
-#include <plat_arm.h>
-#include <arm_config.h>
-#include "drivers/pwrc/fvp_pwrc.h"
-
/* The FVP power domain tree descriptor */
static unsigned char fvp_power_domain_tree_desc[FVP_CLUSTER_COUNT + 2];
diff --git a/plat/arm/board/fvp/include/plat.ld.S b/plat/arm/board/fvp/include/plat.ld.S
index ad2d46c..f024f55 100644
--- a/plat/arm/board/fvp/include/plat.ld.S
+++ b/plat/arm/board/fvp/include/plat.ld.S
@@ -6,7 +6,7 @@
#ifndef PLAT_LD_S
#define PLAT_LD_S
-#include <arm_tzc_dram.ld.S>
-#include <arm_reclaim_init.ld.S>
+#include <plat/arm/common/arm_tzc_dram.ld.S>
+#include <plat/arm/common/arm_reclaim_init.ld.S>
#endif /* PLAT_LD_S */
diff --git a/plat/arm/board/fvp/include/platform_def.h b/plat/arm/board/fvp/include/platform_def.h
index 31f06a9..1153101 100644
--- a/plat/arm/board/fvp/include/platform_def.h
+++ b/plat/arm/board/fvp/include/platform_def.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2014-2018, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2014-2019, ARM Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -7,25 +7,13 @@
#ifndef PLATFORM_DEF_H
#define PLATFORM_DEF_H
-/* Enable the dynamic translation tables library. */
-#ifdef AARCH32
-# if defined(IMAGE_BL32) && RESET_TO_SP_MIN
-# define PLAT_XLAT_TABLES_DYNAMIC 1
-# endif
-#else
-# if defined(IMAGE_BL31) && (RESET_TO_BL31 || (ENABLE_SPM && !SPM_DEPRECATED))
-# define PLAT_XLAT_TABLES_DYNAMIC 1
-# endif
-#endif /* AARCH32 */
-
#include <drivers/arm/tzc400.h>
#include <lib/utils_def.h>
+#include <plat/arm/board/common/v2m_def.h>
+#include <plat/arm/common/arm_def.h>
+#include <plat/arm/common/arm_spm_def.h>
#include <plat/common/common_def.h>
-#include <arm_def.h>
-#include <arm_spm_def.h>
-#include <v2m_def.h>
-
#include "../fvp_def.h"
/* Required platform porting definitions */
@@ -65,7 +53,7 @@
/*
* Load address of BL33 for this platform port
*/
-#define PLAT_ARM_NS_IMAGE_OFFSET (ARM_DRAM1_BASE + UL(0x8000000))
+#define PLAT_ARM_NS_IMAGE_BASE (ARM_DRAM1_BASE + UL(0x8000000))
/*
* PLAT_ARM_MMAP_ENTRIES depends on the number of entries in the
@@ -125,7 +113,7 @@
* calculated using the current BL31 PROGBITS debug size plus the sizes of
* BL2 and BL1-RW
*/
-#if ENABLE_SPM && !SPM_DEPRECATED
+#if ENABLE_SPM && !SPM_MM
#define PLAT_ARM_MAX_BL31_SIZE UL(0x60000)
#else
#define PLAT_ARM_MAX_BL31_SIZE UL(0x3B000)
diff --git a/plat/arm/board/fvp/platform.mk b/plat/arm/board/fvp/platform.mk
index 3b60daa..f79ac46 100644
--- a/plat/arm/board/fvp/platform.mk
+++ b/plat/arm/board/fvp/platform.mk
@@ -1,5 +1,5 @@
#
-# Copyright (c) 2013-2018, ARM Limited and Contributors. All rights reserved.
+# Copyright (c) 2013-2019, ARM Limited and Contributors. All rights reserved.
#
# SPDX-License-Identifier: BSD-3-Clause
#
@@ -146,14 +146,14 @@
BL2U_SOURCES += plat/arm/board/fvp/fvp_bl2u_setup.c \
${FVP_SECURITY_SOURCES}
-BL31_SOURCES += drivers/arm/smmu/smmu_v3.c \
+BL31_SOURCES += drivers/arm/fvp/fvp_pwrc.c \
+ drivers/arm/smmu/smmu_v3.c \
drivers/cfi/v2m/v2m_flash.c \
lib/utils/mem_region.c \
plat/arm/board/fvp/fvp_bl31_setup.c \
plat/arm/board/fvp/fvp_pm.c \
plat/arm/board/fvp/fvp_topology.c \
plat/arm/board/fvp/aarch64/fvp_helpers.S \
- plat/arm/board/fvp/drivers/pwrc/fvp_pwrc.c \
plat/arm/common/arm_nor_psci_mem_protect.c \
${FVP_CPU_LIBS} \
${FVP_GIC_SOURCES} \
@@ -231,6 +231,22 @@
NEED_BL32 := yes
endif
+# Enable the dynamic translation tables library.
+ifeq (${ARCH},aarch32)
+ ifeq (${RESET_TO_SP_MIN},1)
+ BL32_CFLAGS += -DPLAT_XLAT_TABLES_DYNAMIC=1
+ endif
+else
+ ifeq (${RESET_TO_BL31},1)
+ BL31_CFLAGS += -DPLAT_XLAT_TABLES_DYNAMIC=1
+ endif
+ ifeq (${ENABLE_SPM},1)
+ ifeq (${SPM_MM},0)
+ BL31_CFLAGS += -DPLAT_XLAT_TABLES_DYNAMIC=1
+ endif
+ endif
+endif
+
# Add support for platform supplied linker script for BL31 build
$(eval $(call add_define,PLAT_EXTRA_LD_SCRIPT))
diff --git a/plat/arm/board/fvp/sp_min/fvp_sp_min_setup.c b/plat/arm/board/fvp/sp_min/fvp_sp_min_setup.c
index 7c89c27..88c91e6 100644
--- a/plat/arm/board/fvp/sp_min/fvp_sp_min_setup.c
+++ b/plat/arm/board/fvp/sp_min/fvp_sp_min_setup.c
@@ -4,7 +4,8 @@
* SPDX-License-Identifier: BSD-3-Clause
*/
-#include <plat_arm.h>
+#include <plat/arm/common/plat_arm.h>
+
#include "../fvp_private.h"
void plat_arm_sp_min_early_platform_setup(u_register_t arg0, u_register_t arg1,
diff --git a/plat/arm/board/fvp/sp_min/sp_min-fvp.mk b/plat/arm/board/fvp/sp_min/sp_min-fvp.mk
index 8b17c9b..0250a5f 100644
--- a/plat/arm/board/fvp/sp_min/sp_min-fvp.mk
+++ b/plat/arm/board/fvp/sp_min/sp_min-fvp.mk
@@ -5,10 +5,10 @@
#
# SP_MIN source files specific to FVP platform
-BL32_SOURCES += drivers/cfi/v2m/v2m_flash.c \
+BL32_SOURCES += drivers/arm/fvp/fvp_pwrc.c \
+ drivers/cfi/v2m/v2m_flash.c \
lib/utils/mem_region.c \
plat/arm/board/fvp/aarch32/fvp_helpers.S \
- plat/arm/board/fvp/drivers/pwrc/fvp_pwrc.c \
plat/arm/board/fvp/fvp_pm.c \
plat/arm/board/fvp/fvp_topology.c \
plat/arm/board/fvp/sp_min/fvp_sp_min_setup.c \
diff --git a/plat/arm/board/fvp/tsp/fvp_tsp_setup.c b/plat/arm/board/fvp/tsp/fvp_tsp_setup.c
index 86d265a..3c8a963 100644
--- a/plat/arm/board/fvp/tsp/fvp_tsp_setup.c
+++ b/plat/arm/board/fvp/tsp/fvp_tsp_setup.c
@@ -4,7 +4,8 @@
* SPDX-License-Identifier: BSD-3-Clause
*/
-#include <plat_arm.h>
+#include <plat/arm/common/plat_arm.h>
+
#include "../fvp_private.h"
void tsp_early_platform_setup(void)
diff --git a/plat/arm/board/fvp/tsp/tsp-fvp.mk b/plat/arm/board/fvp/tsp/tsp-fvp.mk
index 861fe72..ab3f225 100644
--- a/plat/arm/board/fvp/tsp/tsp-fvp.mk
+++ b/plat/arm/board/fvp/tsp/tsp-fvp.mk
@@ -5,8 +5,8 @@
#
# TSP source files specific to FVP platform
-BL32_SOURCES += plat/arm/board/fvp/aarch64/fvp_helpers.S \
- plat/arm/board/fvp/drivers/pwrc/fvp_pwrc.c \
+BL32_SOURCES += drivers/arm/fvp/fvp_pwrc.c \
+ plat/arm/board/fvp/aarch64/fvp_helpers.S \
plat/arm/board/fvp/fvp_topology.c \
plat/arm/board/fvp/tsp/fvp_tsp_setup.c \
${FVP_GIC_SOURCES}
diff --git a/plat/arm/board/juno/include/platform_def.h b/plat/arm/board/juno/include/platform_def.h
index ed82879..ddbc9b7 100644
--- a/plat/arm/board/juno/include/platform_def.h
+++ b/plat/arm/board/juno/include/platform_def.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2014-2018, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2014-2019, ARM Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -7,29 +7,17 @@
#ifndef PLATFORM_DEF_H
#define PLATFORM_DEF_H
-/* Enable the dynamic translation tables library. */
-#ifdef AARCH32
-# if defined(IMAGE_BL32) && RESET_TO_SP_MIN
-# define PLAT_XLAT_TABLES_DYNAMIC 1
-# endif
-#else
-# if defined(IMAGE_BL31) && RESET_TO_BL31
-# define PLAT_XLAT_TABLES_DYNAMIC 1
-# endif
-#endif /* AARCH32 */
-
-
#include <drivers/arm/tzc400.h>
#if TRUSTED_BOARD_BOOT
#include <drivers/auth/mbedtls/mbedtls_config.h>
#endif
+#include <plat/arm/board/common/board_css_def.h>
+#include <plat/arm/board/common/v2m_def.h>
+#include <plat/arm/common/arm_def.h>
+#include <plat/arm/css/common/css_def.h>
+#include <plat/arm/soc/common/soc_css_def.h>
#include <plat/common/common_def.h>
-#include <arm_def.h>
-#include <board_css_def.h>
-#include <css_def.h>
-#include <soc_css_def.h>
-#include <v2m_def.h>
#include "../juno_def.h"
/* Required platform porting definitions */
@@ -143,7 +131,7 @@
#elif TF_MBEDTLS_KEY_ALG_ID == TF_MBEDTLS_ECDSA
# define PLAT_ARM_MAX_BL2_SIZE UL(0x1D000)
#else
-# define PLAT_ARM_MAX_BL2_SIZE UL(0x1C000)
+# define PLAT_ARM_MAX_BL2_SIZE UL(0x1D000)
#endif
#else
# define PLAT_ARM_MAX_BL2_SIZE UL(0xF000)
diff --git a/plat/arm/board/juno/juno_bl1_setup.c b/plat/arm/board/juno/juno_bl1_setup.c
index 383409d..f72a6ff 100644
--- a/plat/arm/board/juno/juno_bl1_setup.c
+++ b/plat/arm/board/juno/juno_bl1_setup.c
@@ -9,13 +9,12 @@
#include <common/bl_common.h>
#include <common/debug.h>
#include <common/tbbr/tbbr_img_def.h>
+#include <drivers/arm/css/sds.h>
#include <drivers/arm/sp805.h>
+#include <plat/arm/common/plat_arm.h>
#include <plat/common/platform.h>
#include <platform_def.h>
-#include <plat_arm.h>
-#include <sds.h>
-
void juno_reset_to_aarch32_state(void);
static int is_watchdog_reset(void)
diff --git a/plat/arm/board/juno/juno_bl2_setup.c b/plat/arm/board/juno/juno_bl2_setup.c
index 56f05eb..95ef77c 100644
--- a/plat/arm/board/juno/juno_bl2_setup.c
+++ b/plat/arm/board/juno/juno_bl2_setup.c
@@ -8,8 +8,7 @@
#include <common/bl_common.h>
#include <common/desc_image_load.h>
-
-#include <plat_arm.h>
+#include <plat/arm/common/plat_arm.h>
#if JUNO_AARCH32_EL3_RUNTIME
/*******************************************************************************
diff --git a/plat/arm/board/juno/juno_common.c b/plat/arm/board/juno/juno_common.c
index e134108..118c19a 100644
--- a/plat/arm/board/juno/juno_common.c
+++ b/plat/arm/board/juno/juno_common.c
@@ -5,7 +5,7 @@
*/
#include <platform_def.h>
-#include <plat_arm.h>
+#include <plat/arm/common/plat_arm.h>
/*
* Table of memory regions for different BL stages to map using the MMU.
diff --git a/plat/arm/board/juno/juno_pm.c b/plat/arm/board/juno/juno_pm.c
index dbf7b6c..cc80651 100644
--- a/plat/arm/board/juno/juno_pm.c
+++ b/plat/arm/board/juno/juno_pm.c
@@ -4,8 +4,8 @@
* SPDX-License-Identifier: BSD-3-Clause
*/
-#include <plat_arm.h>
-#include <scmi.h>
+#include <drivers/arm/css/scmi.h>
+#include <plat/arm/common/plat_arm.h>
const plat_psci_ops_t *plat_arm_psci_override_pm_ops(plat_psci_ops_t *ops)
{
diff --git a/plat/arm/board/juno/juno_security.c b/plat/arm/board/juno/juno_security.c
index 51c8669..9d7f0e4 100644
--- a/plat/arm/board/juno/juno_security.c
+++ b/plat/arm/board/juno/juno_security.c
@@ -8,9 +8,9 @@
#include <drivers/arm/nic_400.h>
#include <lib/mmio.h>
#include <platform_def.h>
+#include <plat/arm/common/plat_arm.h>
+#include <plat/arm/soc/common/soc_css.h>
-#include <plat_arm.h>
-#include <soc_css.h>
#include "juno_tzmp1_def.h"
#ifdef JUNO_TZMP1
diff --git a/plat/arm/board/juno/juno_topology.c b/plat/arm/board/juno/juno_topology.c
index e70cbdc..ca5c344 100644
--- a/plat/arm/board/juno/juno_topology.c
+++ b/plat/arm/board/juno/juno_topology.c
@@ -4,14 +4,13 @@
* SPDX-License-Identifier: BSD-3-Clause
*/
+#include <drivers/arm/css/css_mhu_doorbell.h>
+#include <drivers/arm/css/scmi.h>
+#include <plat/arm/common/plat_arm.h>
+#include <plat/arm/css/common/css_pm.h>
#include <plat/common/platform.h>
#include <platform_def.h>
-#include <css_pm.h>
-#include <plat_arm.h>
-#include "../../css/drivers/scmi/scmi.h"
-#include "../../css/drivers/mhu/css_mhu_doorbell.h"
-
#if CSS_USE_SCMI_SDS_DRIVER
static scmi_channel_plat_info_t juno_scmi_plat_info = {
.scmi_mbx_mem = CSS_SCMI_PAYLOAD_BASE,
diff --git a/plat/arm/board/juno/platform.mk b/plat/arm/board/juno/platform.mk
index aec2b9b..6575811 100644
--- a/plat/arm/board/juno/platform.mk
+++ b/plat/arm/board/juno/platform.mk
@@ -1,5 +1,5 @@
#
-# Copyright (c) 2013-2018, ARM Limited and Contributors. All rights reserved.
+# Copyright (c) 2013-2019, ARM Limited and Contributors. All rights reserved.
#
# SPDX-License-Identifier: BSD-3-Clause
#
@@ -26,9 +26,7 @@
# SCP during power management operations and for SCP RAM Firmware transfer.
CSS_USE_SCMI_SDS_DRIVER := 1
-PLAT_INCLUDES := -Iplat/arm/board/juno/include \
- -Iplat/arm/css/drivers/scmi \
- -Iplat/arm/css/drivers/sds
+PLAT_INCLUDES := -Iplat/arm/board/juno/include
PLAT_BL_COMMON_SOURCES := plat/arm/board/juno/${ARCH}/juno_helpers.S \
plat/arm/board/juno/juno_common.c
@@ -88,7 +86,7 @@
${JUNO_SECURITY_SOURCES}
ifeq (${CSS_USE_SCMI_SDS_DRIVER},1)
-BL1_SOURCES += plat/arm/css/drivers/sds/sds.c
+BL1_SOURCES += drivers/arm/css/sds/sds.c
endif
endif
@@ -134,6 +132,17 @@
# Do not enable SVE
ENABLE_SVE_FOR_NS := 0
+# Enable the dynamic translation tables library.
+ifeq (${ARCH},aarch32)
+ ifeq (${RESET_TO_SP_MIN},1)
+ BL32_CFLAGS += -DPLAT_XLAT_TABLES_DYNAMIC=1
+ endif
+else
+ ifeq (${RESET_TO_BL31},1)
+ BL31_CFLAGS += -DPLAT_XLAT_TABLES_DYNAMIC=1
+ endif
+endif
+
include plat/arm/board/common/board_common.mk
include plat/arm/common/arm_common.mk
include plat/arm/soc/common/soc_css.mk
diff --git a/plat/arm/board/n1sdp/include/platform_def.h b/plat/arm/board/n1sdp/include/platform_def.h
index 68d0f93..7b8c367 100644
--- a/plat/arm/board/n1sdp/include/platform_def.h
+++ b/plat/arm/board/n1sdp/include/platform_def.h
@@ -7,9 +7,9 @@
#ifndef PLATFORM_DEF_H
#define PLATFORM_DEF_H
-#include <arm_def.h>
-#include <css_def.h>
-#include <v2m_def.h>
+#include <plat/arm/board/common/v2m_def.h>
+#include <plat/arm/common/arm_def.h>
+#include <plat/arm/css/common/css_def.h>
/* UART related constants */
#define PLAT_ARM_BOOT_UART_BASE 0x2A400000
diff --git a/plat/arm/board/n1sdp/n1sdp_bl31_setup.c b/plat/arm/board/n1sdp/n1sdp_bl31_setup.c
index d044b7c..18a0dea 100644
--- a/plat/arm/board/n1sdp/n1sdp_bl31_setup.c
+++ b/plat/arm/board/n1sdp/n1sdp_bl31_setup.c
@@ -6,9 +6,9 @@
#include <platform_def.h>
-#include "../../css/drivers/scmi/scmi.h"
-#include "../../css/drivers/mhu/css_mhu_doorbell.h"
-#include <plat_arm.h>
+#include <drivers/arm/css/css_mhu_doorbell.h>
+#include <drivers/arm/css/scmi.h>
+#include <plat/arm/common/plat_arm.h>
static scmi_channel_plat_info_t n1sdp_scmi_plat_info = {
.scmi_mbx_mem = N1SDP_SCMI_PAYLOAD_BASE,
diff --git a/plat/arm/board/n1sdp/n1sdp_plat.c b/plat/arm/board/n1sdp/n1sdp_plat.c
index 87e1511..6905896 100644
--- a/plat/arm/board/n1sdp/n1sdp_plat.c
+++ b/plat/arm/board/n1sdp/n1sdp_plat.c
@@ -8,10 +8,9 @@
#include <common/bl_common.h>
#include <common/debug.h>
+#include <plat/arm/common/plat_arm.h>
#include <plat/common/platform.h>
-#include <plat_arm.h>
-
/*
* Table of regions to map using the MMU.
* Replace or extend the below regions as required
diff --git a/plat/arm/board/n1sdp/n1sdp_topology.c b/plat/arm/board/n1sdp/n1sdp_topology.c
index c3b4550..edf1170 100644
--- a/plat/arm/board/n1sdp/n1sdp_topology.c
+++ b/plat/arm/board/n1sdp/n1sdp_topology.c
@@ -4,7 +4,7 @@
* SPDX-License-Identifier: BSD-3-Clause
*/
-#include <plat_arm.h>
+#include <plat/arm/common/plat_arm.h>
/* Topology */
typedef struct n1sdp_topology {
diff --git a/plat/arm/common/aarch32/arm_bl2_mem_params_desc.c b/plat/arm/common/aarch32/arm_bl2_mem_params_desc.c
index e23dd25..7aeeb2a 100644
--- a/plat/arm/common/aarch32/arm_bl2_mem_params_desc.c
+++ b/plat/arm/common/aarch32/arm_bl2_mem_params_desc.c
@@ -75,12 +75,13 @@
SET_STATIC_PARAM_HEAD(image_info, PARAM_EP,
VERSION_2, image_info_t, IMAGE_ATTRIB_SKIP_LOADING),
#else
- .ep_info.pc = PLAT_ARM_NS_IMAGE_OFFSET,
+ .ep_info.pc = PLAT_ARM_NS_IMAGE_BASE,
SET_STATIC_PARAM_HEAD(image_info, PARAM_EP,
VERSION_2, image_info_t, 0),
- .image_info.image_base = PLAT_ARM_NS_IMAGE_OFFSET,
- .image_info.image_max_size = ARM_DRAM1_SIZE,
+ .image_info.image_base = PLAT_ARM_NS_IMAGE_BASE,
+ .image_info.image_max_size = ARM_DRAM1_BASE + ARM_DRAM1_SIZE
+ - PLAT_ARM_NS_IMAGE_BASE,
#endif /* PRELOADED_BL33_BASE */
.next_handoff_image_id = INVALID_IMAGE_ID,
diff --git a/plat/arm/common/aarch64/arm_bl2_mem_params_desc.c b/plat/arm/common/aarch64/arm_bl2_mem_params_desc.c
index c0f42f3..0514b39 100644
--- a/plat/arm/common/aarch64/arm_bl2_mem_params_desc.c
+++ b/plat/arm/common/aarch64/arm_bl2_mem_params_desc.c
@@ -176,12 +176,13 @@
SET_STATIC_PARAM_HEAD(image_info, PARAM_EP,
VERSION_2, image_info_t, IMAGE_ATTRIB_SKIP_LOADING),
# else
- .ep_info.pc = PLAT_ARM_NS_IMAGE_OFFSET,
+ .ep_info.pc = PLAT_ARM_NS_IMAGE_BASE,
SET_STATIC_PARAM_HEAD(image_info, PARAM_EP,
VERSION_2, image_info_t, 0),
- .image_info.image_base = PLAT_ARM_NS_IMAGE_OFFSET,
- .image_info.image_max_size = ARM_DRAM1_SIZE,
+ .image_info.image_base = PLAT_ARM_NS_IMAGE_BASE,
+ .image_info.image_max_size = ARM_DRAM1_BASE + ARM_DRAM1_SIZE
+ - PLAT_ARM_NS_IMAGE_BASE,
# endif /* PRELOADED_BL33_BASE */
.next_handoff_image_id = INVALID_IMAGE_ID,
diff --git a/plat/arm/common/arm_bl1_fwu.c b/plat/arm/common/arm_bl1_fwu.c
index cd92aa8..124c1af 100644
--- a/plat/arm/common/arm_bl1_fwu.c
+++ b/plat/arm/common/arm_bl1_fwu.c
@@ -13,10 +13,9 @@
#include <common/bl_common.h>
#include <common/debug.h>
#include <lib/utils.h>
+#include <plat/arm/common/plat_arm.h>
#include <plat/common/platform.h>
-#include <plat_arm.h>
-
/* Struct to keep track of usable memory */
typedef struct bl1_mem_info {
uintptr_t mem_base;
diff --git a/plat/arm/common/arm_bl1_setup.c b/plat/arm/common/arm_bl1_setup.c
index 3a8b5c2..fd4809c 100644
--- a/plat/arm/common/arm_bl1_setup.c
+++ b/plat/arm/common/arm_bl1_setup.c
@@ -14,10 +14,9 @@
#include <drivers/arm/sp805.h>
#include <lib/utils.h>
#include <lib/xlat_tables/xlat_tables_compat.h>
+#include <plat/arm/common/plat_arm.h>
#include <plat/common/platform.h>
-#include <plat_arm.h>
-
/* Weak definitions may be overridden in specific ARM standard platform */
#pragma weak bl1_early_platform_setup
#pragma weak bl1_plat_arch_setup
diff --git a/plat/arm/common/arm_bl2_el3_setup.c b/plat/arm/common/arm_bl2_el3_setup.c
index c38f2ec..0c01c87 100644
--- a/plat/arm/common/arm_bl2_el3_setup.c
+++ b/plat/arm/common/arm_bl2_el3_setup.c
@@ -7,11 +7,10 @@
#include <assert.h>
#include <drivers/generic_delay_timer.h>
+#include <plat/arm/common/plat_arm.h>
#include <plat/common/platform.h>
#include <platform_def.h>
-#include <plat_arm.h>
-
#pragma weak bl2_el3_early_platform_setup
#pragma weak bl2_el3_plat_arch_setup
#pragma weak bl2_el3_plat_prepare_exit
diff --git a/plat/arm/common/arm_bl2_setup.c b/plat/arm/common/arm_bl2_setup.c
index b661eb1..32617f6 100644
--- a/plat/arm/common/arm_bl2_setup.c
+++ b/plat/arm/common/arm_bl2_setup.c
@@ -18,10 +18,9 @@
#include <lib/optee_utils.h>
#endif
#include <lib/utils.h>
+#include <plat/arm/common/plat_arm.h>
#include <plat/common/platform.h>
-#include <plat_arm.h>
-
/* Data structure which holds the extents of the trusted SRAM for BL2 */
static meminfo_t bl2_tzram_layout __aligned(CACHE_WRITEBACK_GRANULE);
diff --git a/plat/arm/common/arm_bl2u_setup.c b/plat/arm/common/arm_bl2u_setup.c
index 332ed14..9f44b9e 100644
--- a/plat/arm/common/arm_bl2u_setup.c
+++ b/plat/arm/common/arm_bl2u_setup.c
@@ -12,10 +12,9 @@
#include <arch_helpers.h>
#include <common/bl_common.h>
#include <drivers/generic_delay_timer.h>
+#include <plat/arm/common/plat_arm.h>
#include <plat/common/platform.h>
-#include <plat_arm.h>
-
/* Weak definitions may be overridden in specific ARM standard platform */
#pragma weak bl2u_platform_setup
#pragma weak bl2u_early_platform_setup
diff --git a/plat/arm/common/arm_bl31_setup.c b/plat/arm/common/arm_bl31_setup.c
index dacefc4..8e1a263 100644
--- a/plat/arm/common/arm_bl31_setup.c
+++ b/plat/arm/common/arm_bl31_setup.c
@@ -15,11 +15,10 @@
#include <lib/mmio.h>
#include <lib/utils.h>
#include <lib/xlat_tables/xlat_tables_compat.h>
+#include <plat/arm/common/plat_arm.h>
#include <plat/common/platform.h>
#include <platform_def.h>
-#include <plat_arm.h>
-
/*
* Placeholder variables for copying the arguments that have been passed to
* BL31 from BL2.
diff --git a/plat/arm/common/arm_cci.c b/plat/arm/common/arm_cci.c
index 7ee997e..3795fc5 100644
--- a/plat/arm/common/arm_cci.c
+++ b/plat/arm/common/arm_cci.c
@@ -9,8 +9,7 @@
#include <arch.h>
#include <drivers/arm/cci.h>
#include <lib/utils.h>
-
-#include <plat_arm.h>
+#include <plat/arm/common/plat_arm.h>
static const int cci_map[] = {
PLAT_ARM_CCI_CLUSTER0_SL_IFACE_IX,
diff --git a/plat/arm/common/arm_ccn.c b/plat/arm/common/arm_ccn.c
index 6aa56f2..2e681ca 100644
--- a/plat/arm/common/arm_ccn.c
+++ b/plat/arm/common/arm_ccn.c
@@ -8,8 +8,7 @@
#include <arch.h>
#include <drivers/arm/ccn.h>
-
-#include <plat_arm.h>
+#include <plat/arm/common/plat_arm.h>
static const unsigned char master_to_rn_id_map[] = {
PLAT_ARM_CLUSTER_TO_CCN_ID_MAP
diff --git a/plat/arm/common/arm_common.c b/plat/arm/common/arm_common.c
index 4cd2ce3..0442945 100644
--- a/plat/arm/common/arm_common.c
+++ b/plat/arm/common/arm_common.c
@@ -14,11 +14,10 @@
#include <common/romlib.h>
#include <lib/mmio.h>
#include <lib/xlat_tables/xlat_tables_compat.h>
+#include <plat/arm/common/plat_arm.h>
#include <plat/common/platform.h>
#include <services/secure_partition.h>
-#include <plat_arm.h>
-
/* Weak definitions may be overridden in specific ARM standard platform */
#pragma weak plat_get_ns_image_entrypoint
#pragma weak plat_arm_get_mmap
@@ -41,7 +40,7 @@
#ifdef PRELOADED_BL33_BASE
return PRELOADED_BL33_BASE;
#else
- return PLAT_ARM_NS_IMAGE_OFFSET;
+ return PLAT_ARM_NS_IMAGE_BASE;
#endif
}
diff --git a/plat/arm/common/arm_common.mk b/plat/arm/common/arm_common.mk
index a8ac286..f18a9af 100644
--- a/plat/arm/common/arm_common.mk
+++ b/plat/arm/common/arm_common.mk
@@ -1,5 +1,5 @@
#
-# Copyright (c) 2015-2018, ARM Limited and Contributors. All rights reserved.
+# Copyright (c) 2015-2019, ARM Limited and Contributors. All rights reserved.
#
# SPDX-License-Identifier: BSD-3-Clause
#
@@ -141,9 +141,6 @@
endif
endif
-PLAT_INCLUDES += -Iinclude/common/tbbr \
- -Iinclude/plat/arm/common
-
ifeq (${ARCH}, aarch64)
PLAT_INCLUDES += -Iinclude/plat/arm/common/aarch64
endif
@@ -240,7 +237,7 @@
endif
# SPM uses libfdt in Arm platforms
-ifeq (${SPM_DEPRECATED},0)
+ifeq (${SPM_MM},0)
ifeq (${ENABLE_SPM},1)
BL31_SOURCES += common/fdt_wrappers.c \
plat/common/plat_spm_rd.c \
@@ -257,8 +254,6 @@
drivers/auth/img_parser_mod.c \
drivers/auth/tbbr/tbbr_cot.c \
- PLAT_INCLUDES += -Iinclude/bl1/tbbr
-
BL1_SOURCES += ${AUTH_SOURCES} \
bl1/tbbr/tbbr_img_desc.c \
plat/arm/common/arm_bl1_fwu.c \
diff --git a/plat/arm/common/arm_console.c b/plat/arm/common/arm_console.c
index 29cb378..0367085 100644
--- a/plat/arm/common/arm_console.c
+++ b/plat/arm/common/arm_console.c
@@ -11,8 +11,7 @@
#include <common/debug.h>
#include <drivers/arm/pl011.h>
#include <drivers/console.h>
-
-#include <plat_arm.h>
+#include <plat/arm/common/plat_arm.h>
/*******************************************************************************
* Functions that set up the console
diff --git a/plat/arm/common/arm_dyn_cfg.c b/plat/arm/common/arm_dyn_cfg.c
index 6c6dc56..1c58649 100644
--- a/plat/arm/common/arm_dyn_cfg.c
+++ b/plat/arm/common/arm_dyn_cfg.c
@@ -15,11 +15,10 @@
#if TRUSTED_BOARD_BOOT
#include <drivers/auth/mbedtls/mbedtls_config.h>
#endif
+#include <plat/arm/common/arm_dyn_cfg_helpers.h>
+#include <plat/arm/common/plat_arm.h>
#include <plat/common/platform.h>
-#include <arm_dyn_cfg_helpers.h>
-#include <plat_arm.h>
-
/* Variable to store the address to TB_FW_CONFIG passed from BL1 */
static void *tb_fw_cfg_dtb;
static size_t tb_fw_cfg_dtb_size;
diff --git a/plat/arm/common/arm_dyn_cfg_helpers.c b/plat/arm/common/arm_dyn_cfg_helpers.c
index bf2f156..36d37f8 100644
--- a/plat/arm/common/arm_dyn_cfg_helpers.c
+++ b/plat/arm/common/arm_dyn_cfg_helpers.c
@@ -10,9 +10,8 @@
#include <common/desc_image_load.h>
#include <common/fdt_wrappers.h>
-
-#include <arm_dyn_cfg_helpers.h>
-#include <plat_arm.h>
+#include <plat/arm/common/arm_dyn_cfg_helpers.h>
+#include <plat/arm/common/plat_arm.h>
#define DTB_PROP_MBEDTLS_HEAP_ADDR "mbedtls_heap_addr"
#define DTB_PROP_MBEDTLS_HEAP_SIZE "mbedtls_heap_size"
diff --git a/plat/arm/common/arm_err.c b/plat/arm/common/arm_err.c
index 8650d48..e77f5dc 100644
--- a/plat/arm/common/arm_err.c
+++ b/plat/arm/common/arm_err.c
@@ -13,10 +13,9 @@
#include <common/debug.h>
#include <drivers/cfi/v2m_flash.h>
#include <drivers/console.h>
+#include <plat/arm/common/plat_arm.h>
#include <plat/common/platform.h>
-#include <plat_arm.h>
-
#pragma weak plat_arm_error_handler
/*
diff --git a/plat/arm/common/arm_gicv2.c b/plat/arm/common/arm_gicv2.c
index fc848c1..80a845f 100644
--- a/plat/arm/common/arm_gicv2.c
+++ b/plat/arm/common/arm_gicv2.c
@@ -7,10 +7,9 @@
#include <platform_def.h>
#include <drivers/arm/gicv2.h>
+#include <plat/arm/common/plat_arm.h>
#include <plat/common/platform.h>
-#include <plat_arm.h>
-
/******************************************************************************
* The following functions are defined as weak to allow a platform to override
* the way the GICv2 driver is initialised and used.
diff --git a/plat/arm/common/arm_gicv3.c b/plat/arm/common/arm_gicv3.c
index e16e13d..93bebf3 100644
--- a/plat/arm/common/arm_gicv3.c
+++ b/plat/arm/common/arm_gicv3.c
@@ -9,10 +9,9 @@
#include <common/interrupt_props.h>
#include <drivers/arm/gicv3.h>
#include <lib/utils.h>
+#include <plat/arm/common/plat_arm.h>
#include <plat/common/platform.h>
-#include <plat_arm.h>
-
/******************************************************************************
* The following functions are defined as weak to allow a platform to override
* the way the GICv3 driver is initialised and used.
diff --git a/plat/arm/common/arm_image_load.c b/plat/arm/common/arm_image_load.c
index bf1fbfd..2faaa76 100644
--- a/plat/arm/common/arm_image_load.c
+++ b/plat/arm/common/arm_image_load.c
@@ -4,16 +4,17 @@
* SPDX-License-Identifier: BSD-3-Clause
*/
+#include <assert.h>
#include <common/bl_common.h>
#include <common/desc_image_load.h>
+#include <plat/arm/common/plat_arm.h>
#include <plat/common/platform.h>
-#include <plat_arm.h>
-
#pragma weak plat_flush_next_bl_params
#pragma weak plat_get_bl_image_load_info
#pragma weak plat_get_next_bl_params
+static bl_params_t *next_bl_params_cpy_ptr;
/*******************************************************************************
* This function flushes the data structures so that they are visible
@@ -21,7 +22,11 @@
******************************************************************************/
void plat_flush_next_bl_params(void)
{
- flush_bl_params_desc();
+ assert(next_bl_params_cpy_ptr != NULL);
+
+ flush_bl_params_desc_args(bl_mem_params_desc_ptr,
+ bl_mem_params_desc_num,
+ next_bl_params_cpy_ptr);
}
/*******************************************************************************
@@ -33,12 +38,53 @@
}
/*******************************************************************************
- * This function returns the list of executable images.
+ * ARM helper function to return the list of executable images.Since the default
+ * descriptors are allocated within BL2 RW memory, this prevents BL31/BL32
+ * overlay of BL2 memory. Hence this function also copies the descriptors to a
+ * pre-allocated memory indicated by ARM_BL2_MEM_DESC_BASE.
+ ******************************************************************************/
+struct bl_params *arm_get_next_bl_params(void)
+{
+ bl_mem_params_node_t *bl2_mem_params_descs_cpy
+ = (bl_mem_params_node_t *)ARM_BL2_MEM_DESC_BASE;
+ const bl_params_t *next_bl_params;
+
+ next_bl_params_cpy_ptr =
+ (bl_params_t *)(ARM_BL2_MEM_DESC_BASE +
+ (bl_mem_params_desc_num * sizeof(bl_mem_params_node_t)));
+
+ /*
+ * Copy the memory descriptors to ARM_BL2_MEM_DESC_BASE area.
+ */
+ (void) memcpy(bl2_mem_params_descs_cpy, bl_mem_params_desc_ptr,
+ (bl_mem_params_desc_num * sizeof(bl_mem_params_node_t)));
+
+ /*
+ * Modify the global 'bl_mem_params_desc_ptr' to point to the
+ * copied location.
+ */
+ bl_mem_params_desc_ptr = bl2_mem_params_descs_cpy;
+
+ next_bl_params = get_next_bl_params_from_mem_params_desc();
+ assert(next_bl_params != NULL);
+
+ /*
+ * Copy 'next_bl_params' to the reserved location after the copied
+ * memory descriptors.
+ */
+ (void) memcpy(next_bl_params_cpy_ptr, next_bl_params,
+ (sizeof(bl_params_t)));
+
+ populate_next_bl_params_config(next_bl_params_cpy_ptr);
+
+ return next_bl_params_cpy_ptr;
+}
+
+/*******************************************************************************
+ * This function returns the list of executable images
******************************************************************************/
struct bl_params *plat_get_next_bl_params(void)
{
- bl_params_t *next_bl_params = get_next_bl_params_from_mem_params_desc();
-
- populate_next_bl_params_config(next_bl_params);
- return next_bl_params;
+ return arm_get_next_bl_params();
}
+
diff --git a/plat/arm/common/arm_io_storage.c b/plat/arm/common/arm_io_storage.c
index d7c5cac..fc1eb49 100644
--- a/plat/arm/common/arm_io_storage.c
+++ b/plat/arm/common/arm_io_storage.c
@@ -15,11 +15,10 @@
#include <drivers/io/io_memmap.h>
#include <drivers/io/io_storage.h>
#include <lib/utils.h>
+#include <plat/arm/common/plat_arm.h>
#include <plat/common/platform.h>
#include <tools_share/firmware_image_package.h>
-#include <plat_arm.h>
-
/* IO devices */
static const io_dev_connector_t *fip_dev_con;
static uintptr_t fip_dev_handle;
diff --git a/plat/arm/common/arm_nor_psci_mem_protect.c b/plat/arm/common/arm_nor_psci_mem_protect.c
index 4ae57e5..3a70059 100644
--- a/plat/arm/common/arm_nor_psci_mem_protect.c
+++ b/plat/arm/common/arm_nor_psci_mem_protect.c
@@ -11,8 +11,7 @@
#include <lib/psci/psci.h>
#include <lib/mmio.h>
#include <lib/utils.h>
-
-#include <plat_arm.h>
+#include <plat/arm/common/plat_arm.h>
/*
* DRAM1 is used also to load the NS boot loader. For this reason we
@@ -22,7 +21,7 @@
* until the end of DRAM1.
* We limit the size of DRAM2 to 1 GB to avoid big delays while booting
*/
-#define DRAM1_NS_IMAGE_LIMIT (PLAT_ARM_NS_IMAGE_OFFSET + (32 << TWO_MB_SHIFT))
+#define DRAM1_NS_IMAGE_LIMIT (PLAT_ARM_NS_IMAGE_BASE + (32 << TWO_MB_SHIFT))
#define DRAM1_PROTECTED_SIZE (ARM_NS_DRAM1_END+1u - DRAM1_NS_IMAGE_LIMIT)
static mem_region_t arm_ram_ranges[] = {
diff --git a/plat/arm/common/arm_pm.c b/plat/arm/common/arm_pm.c
index 4ce13aa..cb87baf 100644
--- a/plat/arm/common/arm_pm.c
+++ b/plat/arm/common/arm_pm.c
@@ -11,10 +11,9 @@
#include <arch_helpers.h>
#include <lib/psci/psci.h>
+#include <plat/arm/common/plat_arm.h>
#include <plat/common/platform.h>
-#include <plat_arm.h>
-
/* Allow ARM Standard platforms to override these functions */
#pragma weak plat_arm_program_trusted_mailbox
diff --git a/plat/arm/common/arm_sip_svc.c b/plat/arm/common/arm_sip_svc.c
index 6b0f7e7..3d308a3 100644
--- a/plat/arm/common/arm_sip_svc.c
+++ b/plat/arm/common/arm_sip_svc.c
@@ -9,11 +9,10 @@
#include <common/debug.h>
#include <common/runtime_svc.h>
#include <lib/pmf/pmf.h>
+#include <plat/arm/common/arm_sip_svc.h>
+#include <plat/arm/common/plat_arm.h>
#include <tools_share/uuid.h>
-#include <arm_sip_svc.h>
-#include <plat_arm.h>
-
/* ARM SiP Service UUID */
DEFINE_SVC_UUID2(arm_sip_svc_uid,
0x556d75e2, 0x6033, 0xb54b, 0xb5, 0x75,
diff --git a/plat/arm/common/arm_topology.c b/plat/arm/common/arm_topology.c
index 6986e52..37047bc 100644
--- a/plat/arm/common/arm_topology.c
+++ b/plat/arm/common/arm_topology.c
@@ -7,8 +7,7 @@
#include <platform_def.h>
#include <arch.h>
-
-#include <plat_arm.h>
+#include <plat/arm/common/plat_arm.h>
/*******************************************************************************
* This function validates an MPIDR by checking whether it falls within the
diff --git a/plat/arm/common/arm_tzc400.c b/plat/arm/common/arm_tzc400.c
index 322713b..34e650f 100644
--- a/plat/arm/common/arm_tzc400.c
+++ b/plat/arm/common/arm_tzc400.c
@@ -8,8 +8,7 @@
#include <common/debug.h>
#include <drivers/arm/tzc400.h>
-
-#include <plat_arm.h>
+#include <plat/arm/common/plat_arm.h>
/* Weak definitions may be overridden in specific ARM standard platform */
#pragma weak plat_arm_security_setup
diff --git a/plat/arm/common/arm_tzc_dmc500.c b/plat/arm/common/arm_tzc_dmc500.c
index 07260a7..e9f897f 100644
--- a/plat/arm/common/arm_tzc_dmc500.c
+++ b/plat/arm/common/arm_tzc_dmc500.c
@@ -10,8 +10,7 @@
#include <common/debug.h>
#include <drivers/arm/tzc_dmc500.h>
-
-#include <plat_arm.h>
+#include <plat/arm/common/plat_arm.h>
/*******************************************************************************
* Initialize the DMC500-TrustZone Controller for ARM standard platforms.
diff --git a/plat/arm/common/execution_state_switch.c b/plat/arm/common/execution_state_switch.c
index e313410..d471130 100644
--- a/plat/arm/common/execution_state_switch.c
+++ b/plat/arm/common/execution_state_switch.c
@@ -12,11 +12,10 @@
#include <lib/el3_runtime/context_mgmt.h>
#include <lib/psci/psci.h>
#include <lib/utils.h>
+#include <plat/arm/common/arm_sip_svc.h>
+#include <plat/arm/common/plat_arm.h>
#include <smccc_helpers.h>
-#include <arm_sip_svc.h>
-#include <plat_arm.h>
-
/*
* Handle SMC from a lower exception level to switch its execution state
* (either from AArch64 to AArch32, or vice versa).
diff --git a/plat/arm/common/sp_min/arm_sp_min_setup.c b/plat/arm/common/sp_min/arm_sp_min_setup.c
index 967b551..c0ea027 100644
--- a/plat/arm/common/sp_min/arm_sp_min_setup.c
+++ b/plat/arm/common/sp_min/arm_sp_min_setup.c
@@ -14,10 +14,9 @@
#include <drivers/arm/pl011.h>
#include <drivers/console.h>
#include <lib/mmio.h>
+#include <plat/arm/common/plat_arm.h>
#include <plat/common/platform.h>
-#include <plat_arm.h>
-
static entry_point_info_t bl33_image_ep_info;
/* Weak definitions may be overridden in specific ARM standard platform */
diff --git a/plat/arm/common/tsp/arm_tsp_setup.c b/plat/arm/common/tsp/arm_tsp_setup.c
index 2937697..2965ccd 100644
--- a/plat/arm/common/tsp/arm_tsp_setup.c
+++ b/plat/arm/common/tsp/arm_tsp_setup.c
@@ -13,8 +13,7 @@
#include <common/debug.h>
#include <drivers/arm/pl011.h>
#include <drivers/console.h>
-
-#include <plat_arm.h>
+#include <plat/arm/common/plat_arm.h>
#define BL32_END (unsigned long)(&__BL32_END__)
diff --git a/plat/arm/css/common/css_bl1_setup.c b/plat/arm/css/common/css_bl1_setup.c
index ae0f011..596cc3d 100644
--- a/plat/arm/css/common/css_bl1_setup.c
+++ b/plat/arm/css/common/css_bl1_setup.c
@@ -6,11 +6,10 @@
#include <common/bl_common.h>
#include <common/debug.h>
+#include <plat/arm/common/plat_arm.h>
+#include <plat/arm/soc/common/soc_css.h>
#include <plat/common/platform.h>
-#include <plat_arm.h>
-#include <soc_css.h>
-
void bl1_platform_setup(void)
{
arm_bl1_platform_setup();
diff --git a/plat/arm/css/common/css_bl2_setup.c b/plat/arm/css/common/css_bl2_setup.c
index 6aefe03..002c6eb 100644
--- a/plat/arm/css/common/css_bl2_setup.c
+++ b/plat/arm/css/common/css_bl2_setup.c
@@ -8,14 +8,12 @@
#include <common/bl_common.h>
#include <common/debug.h>
+#include <drivers/arm/css/css_scp.h>
#include <lib/mmio.h>
#include <lib/utils.h>
+#include <plat/arm/common/plat_arm.h>
#include <platform_def.h>
-#include <plat_arm.h>
-
-#include "../drivers/scp/css_scp.h"
-
/* Weak definition may be overridden in specific CSS based platform */
#pragma weak plat_arm_bl2_handle_scp_bl2
diff --git a/plat/arm/css/common/css_bl2u_setup.c b/plat/arm/css/common/css_bl2u_setup.c
index 564e98f..15cf4f6 100644
--- a/plat/arm/css/common/css_bl2u_setup.c
+++ b/plat/arm/css/common/css_bl2u_setup.c
@@ -6,12 +6,10 @@
#include <common/bl_common.h>
#include <common/debug.h>
+#include <drivers/arm/css/css_scp.h>
+#include <plat/arm/common/plat_arm.h>
#include <plat/common/platform.h>
-#include <plat_arm.h>
-
-#include "../drivers/scp/css_scp.h"
-
/* Weak definition may be overridden in specific CSS based platform */
#pragma weak bl2u_plat_handle_scp_bl2u
diff --git a/plat/arm/css/common/css_common.mk b/plat/arm/css/common/css_common.mk
index ca1edab..2fbbe45 100644
--- a/plat/arm/css/common/css_common.mk
+++ b/plat/arm/css/common/css_common.mk
@@ -11,8 +11,7 @@
# By default, SCMI driver is disabled for CSS platforms
CSS_USE_SCMI_SDS_DRIVER ?= 0
-PLAT_INCLUDES += -Iinclude/plat/arm/css/common \
- -Iinclude/plat/arm/css/common/aarch64
+PLAT_INCLUDES += -Iinclude/plat/arm/css/common/aarch64
PLAT_BL_COMMON_SOURCES += plat/arm/css/common/${ARCH}/css_helpers.S
@@ -27,16 +26,16 @@
plat/arm/css/common/css_topology.c
ifeq (${CSS_USE_SCMI_SDS_DRIVER},0)
-BL31_SOURCES += plat/arm/css/drivers/scp/css_pm_scpi.c \
- plat/arm/css/drivers/mhu/css_mhu.c \
- plat/arm/css/drivers/scpi/css_scpi.c
+BL31_SOURCES += drivers/arm/css/mhu/css_mhu.c \
+ drivers/arm/css/scp/css_pm_scpi.c \
+ drivers/arm/css/scpi/css_scpi.c
else
-BL31_SOURCES += plat/arm/css/drivers/scp/css_pm_scmi.c \
- plat/arm/css/drivers/scmi/scmi_ap_core_proto.c \
- plat/arm/css/drivers/scmi/scmi_common.c \
- plat/arm/css/drivers/scmi/scmi_pwr_dmn_proto.c \
- plat/arm/css/drivers/scmi/scmi_sys_pwr_proto.c \
- plat/arm/css/drivers/mhu/css_mhu_doorbell.c
+BL31_SOURCES += drivers/arm/css/mhu/css_mhu_doorbell.c \
+ drivers/arm/css/scmi/scmi_ap_core_proto.c \
+ drivers/arm/css/scmi/scmi_common.c \
+ drivers/arm/css/scmi/scmi_pwr_dmn_proto.c \
+ drivers/arm/css/scmi/scmi_sys_pwr_proto.c \
+ drivers/arm/css/scp/css_pm_scmi.c
endif
# Process CSS_LOAD_SCP_IMAGES flag
@@ -50,19 +49,19 @@
endif
ifeq (${CSS_USE_SCMI_SDS_DRIVER},1)
- BL2U_SOURCES += plat/arm/css/drivers/scp/css_sds.c \
- plat/arm/css/drivers/sds/sds.c
+ BL2U_SOURCES += drivers/arm/css/scp/css_sds.c \
+ drivers/arm/css/sds/sds.c
- BL2_SOURCES += plat/arm/css/drivers/scp/css_sds.c \
- plat/arm/css/drivers/sds/sds.c
+ BL2_SOURCES += drivers/arm/css/scp/css_sds.c \
+ drivers/arm/css/sds/sds.c
else
- BL2U_SOURCES += plat/arm/css/drivers/scp/css_bom_bootloader.c \
- plat/arm/css/drivers/mhu/css_mhu.c \
- plat/arm/css/drivers/scpi/css_scpi.c
+ BL2U_SOURCES += drivers/arm/css/mhu/css_mhu.c \
+ drivers/arm/css/scp/css_bom_bootloader.c \
+ drivers/arm/css/scpi/css_scpi.c
- BL2_SOURCES += plat/arm/css/drivers/scp/css_bom_bootloader.c \
- plat/arm/css/drivers/mhu/css_mhu.c \
- plat/arm/css/drivers/scpi/css_scpi.c
+ BL2_SOURCES += drivers/arm/css/mhu/css_mhu.c \
+ drivers/arm/css/scp/css_bom_bootloader.c \
+ drivers/arm/css/scpi/css_scpi.c
# Enable option to detect whether the SCP ROM firmware in use predates version
# 1.7.0 and therefore, is incompatible.
CSS_DETECT_PRE_1_7_0_SCP := 1
@@ -74,7 +73,7 @@
endif
ifeq (${CSS_USE_SCMI_SDS_DRIVER},1)
- PLAT_BL_COMMON_SOURCES += plat/arm/css/drivers/sds/${ARCH}/sds_helpers.S
+ PLAT_BL_COMMON_SOURCES += drivers/arm/css/sds/${ARCH}/sds_helpers.S
endif
# Process CSS_USE_SCMI_SDS_DRIVER flag
diff --git a/plat/arm/css/common/css_pm.c b/plat/arm/css/common/css_pm.c
index 8a156e6..f6fc6aa 100644
--- a/plat/arm/css/common/css_pm.c
+++ b/plat/arm/css/common/css_pm.c
@@ -11,14 +11,12 @@
#include <arch_helpers.h>
#include <common/debug.h>
+#include <drivers/arm/css/css_scp.h>
#include <lib/cassert.h>
+#include <plat/arm/common/plat_arm.h>
+#include <plat/arm/css/common/css_pm.h>
#include <plat/common/platform.h>
-#include <css_pm.h>
-#include <plat_arm.h>
-
-#include "../drivers/scp/css_scp.h"
-
/* Allow CSS platforms to override `plat_arm_psci_pm_ops` */
#pragma weak plat_arm_psci_pm_ops
diff --git a/plat/arm/css/common/css_topology.c b/plat/arm/css/common/css_topology.c
index 8ac2232..8aca744 100644
--- a/plat/arm/css/common/css_topology.c
+++ b/plat/arm/css/common/css_topology.c
@@ -6,10 +6,9 @@
#include <assert.h>
+#include <plat/arm/common/plat_arm.h>
#include <plat/common/platform.h>
-#include <plat_arm.h>
-
#if ARM_PLAT_MT
#pragma weak plat_arm_get_cpu_pe_count
#endif
diff --git a/plat/arm/css/common/sp_min/css_sp_min.mk b/plat/arm/css/common/sp_min/css_sp_min.mk
index 9fb280c..6523a16 100644
--- a/plat/arm/css/common/sp_min/css_sp_min.mk
+++ b/plat/arm/css/common/sp_min/css_sp_min.mk
@@ -9,13 +9,13 @@
plat/arm/css/common/css_topology.c
ifeq (${CSS_USE_SCMI_SDS_DRIVER},0)
-BL32_SOURCES += plat/arm/css/drivers/scp/css_pm_scpi.c \
- plat/arm/css/drivers/mhu/css_mhu.c \
- plat/arm/css/drivers/scpi/css_scpi.c
+BL32_SOURCES += drivers/arm/css/mhu/css_mhu.c \
+ drivers/arm/css/scp/css_pm_scpi.c \
+ drivers/arm/css/scpi/css_scpi.c
else
-BL32_SOURCES += plat/arm/css/drivers/scp/css_pm_scmi.c \
- plat/arm/css/drivers/scmi/scmi_common.c \
- plat/arm/css/drivers/scmi/scmi_pwr_dmn_proto.c \
- plat/arm/css/drivers/scmi/scmi_sys_pwr_proto.c \
- plat/arm/css/drivers/mhu/css_mhu_doorbell.c
+BL32_SOURCES += drivers/arm/css/mhu/css_mhu_doorbell.c \
+ drivers/arm/css/scp/css_pm_scmi.c \
+ drivers/arm/css/scmi/scmi_common.c \
+ drivers/arm/css/scmi/scmi_pwr_dmn_proto.c \
+ drivers/arm/css/scmi/scmi_sys_pwr_proto.c
endif
diff --git a/plat/arm/css/sgi/include/sgi_base_platform_def.h b/plat/arm/css/sgi/include/sgi_base_platform_def.h
index 4afaae1..c0e6555 100644
--- a/plat/arm/css/sgi/include/sgi_base_platform_def.h
+++ b/plat/arm/css/sgi/include/sgi_base_platform_def.h
@@ -9,15 +9,14 @@
#include <lib/utils_def.h>
#include <lib/xlat_tables/xlat_tables_defs.h>
+#include <plat/arm/board/common/board_css_def.h>
+#include <plat/arm/board/common/v2m_def.h>
+#include <plat/arm/common/arm_def.h>
+#include <plat/arm/common/arm_spm_def.h>
+#include <plat/arm/css/common/css_def.h>
+#include <plat/arm/soc/common/soc_css_def.h>
#include <plat/common/common_def.h>
-#include <arm_def.h>
-#include <arm_spm_def.h>
-#include <board_css_def.h>
-#include <css_def.h>
-#include <soc_css_def.h>
-#include <v2m_def.h>
-
#define PLATFORM_CORE_COUNT (PLAT_ARM_CLUSTER_COUNT * \
CSS_SGI_MAX_CPUS_PER_CLUSTER * \
CSS_SGI_MAX_PE_PER_CPU)
diff --git a/plat/arm/css/sgi/sgi_bl31_setup.c b/plat/arm/css/sgi/sgi_bl31_setup.c
index 617a62b..bfcb521 100644
--- a/plat/arm/css/sgi/sgi_bl31_setup.c
+++ b/plat/arm/css/sgi/sgi_bl31_setup.c
@@ -10,14 +10,13 @@
#include <common/bl_common.h>
#include <common/debug.h>
+#include <drivers/arm/css/css_mhu_doorbell.h>
+#include <drivers/arm/css/scmi.h>
+#include <plat/arm/common/plat_arm.h>
-#include <plat_arm.h>
#include <sgi_ras.h>
#include <sgi_variant.h>
-#include "../../css/drivers/scmi/scmi.h"
-#include "../../css/drivers/mhu/css_mhu_doorbell.h"
-
sgi_platform_info_t sgi_plat_info;
static scmi_channel_plat_info_t sgi575_scmi_plat_info = {
diff --git a/plat/arm/css/sgi/sgi_image_load.c b/plat/arm/css/sgi/sgi_image_load.c
index 1ed219d..a2f10dc 100644
--- a/plat/arm/css/sgi/sgi_image_load.c
+++ b/plat/arm/css/sgi/sgi_image_load.c
@@ -9,6 +9,7 @@
#include <arch_helpers.h>
#include <common/debug.h>
#include <common/desc_image_load.h>
+#include <plat/arm/common/plat_arm.h>
#include <plat/common/platform.h>
#include <sgi_variant.h>
@@ -72,14 +73,11 @@
bl_params_t *plat_get_next_bl_params(void)
{
int ret;
- bl_params_t *next_bl_params;
ret = plat_sgi_append_config_node();
if (ret != 0)
panic();
- next_bl_params = get_next_bl_params_from_mem_params_desc();
- populate_next_bl_params_config(next_bl_params);
-
- return next_bl_params;
+ return arm_get_next_bl_params();
}
+
diff --git a/plat/arm/css/sgi/sgi_plat.c b/plat/arm/css/sgi/sgi_plat.c
index 72cda7f..83ca30c 100644
--- a/plat/arm/css/sgi/sgi_plat.c
+++ b/plat/arm/css/sgi/sgi_plat.c
@@ -11,11 +11,10 @@
#include <common/bl_common.h>
#include <common/debug.h>
#include <drivers/arm/ccn.h>
+#include <plat/arm/common/plat_arm.h>
#include <plat/common/platform.h>
#include <services/secure_partition.h>
-#include <plat_arm.h>
-
#if USE_COHERENT_MEM
/*
* The next 2 constants identify the extents of the coherent memory region.
diff --git a/plat/arm/css/sgi/sgi_ras.c b/plat/arm/css/sgi/sgi_ras.c
index a6a32d1..0001ffd 100644
--- a/plat/arm/css/sgi/sgi_ras.c
+++ b/plat/arm/css/sgi/sgi_ras.c
@@ -10,12 +10,12 @@
#include <bl31/interrupt_mgmt.h>
#include <lib/el3_runtime/context_mgmt.h>
#include <lib/extensions/ras.h>
+#include <plat/arm/common/arm_spm_def.h>
#include <plat/common/platform.h>
#include <services/mm_svc.h>
#include <services/sdei.h>
#include <services/spm_svc.h>
-#include <arm_spm_def.h>
#include <sgi_ras.h>
static int sgi_ras_intr_handler(const struct err_record_info *err_rec,
diff --git a/plat/arm/css/sgi/sgi_topology.c b/plat/arm/css/sgi/sgi_topology.c
index 2921c0c..dafaf40 100644
--- a/plat/arm/css/sgi/sgi_topology.c
+++ b/plat/arm/css/sgi/sgi_topology.c
@@ -4,7 +4,8 @@
* SPDX-License-Identifier: BSD-3-Clause
*/
-#include <plat_arm.h>
+#include <plat/arm/common/plat_arm.h>
+
#include <sgi_variant.h>
/* Topology */
diff --git a/plat/arm/css/sgm/include/platform_oid.h b/plat/arm/css/sgm/include/platform_oid.h
index 18d41e3..fd1854a 100644
--- a/plat/arm/css/sgm/include/platform_oid.h
+++ b/plat/arm/css/sgm/include/platform_oid.h
@@ -3,7 +3,8 @@
*
* SPDX-License-Identifier: BSD-3-Clause
*/
-#include "../../../../../include/plat/arm/board/common/board_arm_oid.h"
+
+#include <plat/arm/board/common/board_arm_oid.h>
/*
* Required platform OIDs
diff --git a/plat/arm/css/sgm/include/sgm_base_platform_def.h b/plat/arm/css/sgm/include/sgm_base_platform_def.h
index e3fa3f3..4647e74 100644
--- a/plat/arm/css/sgm/include/sgm_base_platform_def.h
+++ b/plat/arm/css/sgm/include/sgm_base_platform_def.h
@@ -9,14 +9,13 @@
#include <drivers/arm/tzc400.h>
#include <drivers/arm/tzc_common.h>
+#include <plat/arm/board/common/board_css_def.h>
+#include <plat/arm/board/common/v2m_def.h>
+#include <plat/arm/common/arm_def.h>
+#include <plat/arm/css/common/css_def.h>
+#include <plat/arm/soc/common/soc_css_def.h>
#include <plat/common/common_def.h>
-#include <arm_def.h>
-#include <board_css_def.h>
-#include <css_def.h>
-#include <soc_css_def.h>
-#include <v2m_def.h>
-
/* CPU topology */
#define PLAT_ARM_CLUSTER_COUNT 1
#define PLAT_ARM_CLUSTER_CORE_COUNT 8
diff --git a/plat/arm/css/sgm/sgm_bl1_setup.c b/plat/arm/css/sgm/sgm_bl1_setup.c
index 8b7c5da..2036515 100644
--- a/plat/arm/css/sgm/sgm_bl1_setup.c
+++ b/plat/arm/css/sgm/sgm_bl1_setup.c
@@ -6,10 +6,10 @@
#include <common/bl_common.h>
#include <common/debug.h>
+#include <plat/arm/common/plat_arm.h>
+#include <plat/arm/soc/common/soc_css.h>
-#include <plat_arm.h>
#include <sgm_plat_config.h>
-#include <soc_css.h>
void bl1_early_platform_setup(void)
{
diff --git a/plat/arm/css/sgm/sgm_bl31_setup.c b/plat/arm/css/sgm/sgm_bl31_setup.c
index 7967cb5..7e92ac8 100644
--- a/plat/arm/css/sgm/sgm_bl31_setup.c
+++ b/plat/arm/css/sgm/sgm_bl31_setup.c
@@ -6,13 +6,12 @@
#include <common/bl_common.h>
#include <common/debug.h>
+#include <drivers/arm/css/css_mhu_doorbell.h>
+#include <drivers/arm/css/scmi.h>
+#include <plat/arm/common/plat_arm.h>
-#include <plat_arm.h>
#include <sgm_plat_config.h>
-#include "../../css/drivers/scmi/scmi.h"
-#include "../../css/drivers/mhu/css_mhu_doorbell.h"
-
static scmi_channel_plat_info_t sgm775_scmi_plat_info = {
.scmi_mbx_mem = CSS_SCMI_PAYLOAD_BASE,
.db_reg_addr = PLAT_CSS_MHU_BASE + CSS_SCMI_MHU_DB_REG_OFF,
diff --git a/plat/arm/css/sgm/sgm_mmap_config.c b/plat/arm/css/sgm/sgm_mmap_config.c
index 763f36a..e5b4b03 100644
--- a/plat/arm/css/sgm/sgm_mmap_config.c
+++ b/plat/arm/css/sgm/sgm_mmap_config.c
@@ -8,8 +8,8 @@
#include <common/bl_common.h>
#include <common/debug.h>
+#include <plat/arm/common/plat_arm.h>
-#include <plat_arm.h>
#include <sgm_variant.h>
/*
diff --git a/plat/arm/css/sgm/sgm_plat_config.c b/plat/arm/css/sgm/sgm_plat_config.c
index 2a43487..d9e65c5 100644
--- a/plat/arm/css/sgm/sgm_plat_config.c
+++ b/plat/arm/css/sgm/sgm_plat_config.c
@@ -10,8 +10,8 @@
#include <platform_def.h>
#include <common/debug.h>
+#include <plat/arm/common/plat_arm.h>
-#include <plat_arm.h>
#include <sgm_plat_config.h>
#include <sgm_variant.h>
diff --git a/plat/arm/css/sgm/sgm_security.c b/plat/arm/css/sgm/sgm_security.c
index 548ec7b..21d5306 100644
--- a/plat/arm/css/sgm/sgm_security.c
+++ b/plat/arm/css/sgm/sgm_security.c
@@ -6,10 +6,10 @@
#include <common/debug.h>
#include <drivers/arm/tzc_dmc500.h>
+#include <plat/arm/common/plat_arm.h>
+#include <plat/arm/soc/common/soc_css.h>
-#include <plat_arm.h>
#include <sgm_variant.h>
-#include <soc_css.h>
/* Is populated with the DMC-500 controllers base addresses */
static tzc_dmc500_driver_data_t plat_driver_data;
diff --git a/plat/arm/css/sgm/sgm_topology.c b/plat/arm/css/sgm/sgm_topology.c
index ce72464..2d9552d 100644
--- a/plat/arm/css/sgm/sgm_topology.c
+++ b/plat/arm/css/sgm/sgm_topology.c
@@ -4,7 +4,8 @@
* SPDX-License-Identifier: BSD-3-Clause
*/
-#include <plat_arm.h>
+#include <plat/arm/common/plat_arm.h>
+
#include <sgm_plat_config.h>
/*******************************************************************************
diff --git a/plat/arm/css/sgm/tsp/sgm_tsp_setup.c b/plat/arm/css/sgm/tsp/sgm_tsp_setup.c
index 39bba94..5f40c4c 100644
--- a/plat/arm/css/sgm/tsp/sgm_tsp_setup.c
+++ b/plat/arm/css/sgm/tsp/sgm_tsp_setup.c
@@ -4,7 +4,8 @@
* SPDX-License-Identifier: BSD-3-Clause
*/
-#include <plat_arm.h>
+#include <plat/arm/common/plat_arm.h>
+
#include <sgm_plat_config.h>
void tsp_early_platform_setup(void)
diff --git a/plat/arm/soc/common/soc_css.mk b/plat/arm/soc/common/soc_css.mk
index e009467..8cad2a5 100644
--- a/plat/arm/soc/common/soc_css.mk
+++ b/plat/arm/soc/common/soc_css.mk
@@ -4,8 +4,6 @@
# SPDX-License-Identifier: BSD-3-Clause
#
-PLAT_INCLUDES += -Iinclude/plat/arm/soc/common/
-
#PLAT_BL_COMMON_SOURCES +=
BL1_SOURCES += plat/arm/soc/common/soc_css_security.c
diff --git a/plat/arm/soc/common/soc_css_security.c b/plat/arm/soc/common/soc_css_security.c
index b48357a..4f6bf61 100644
--- a/plat/arm/soc/common/soc_css_security.c
+++ b/plat/arm/soc/common/soc_css_security.c
@@ -8,8 +8,7 @@
#include <drivers/arm/nic_400.h>
#include <lib/mmio.h>
-
-#include <soc_css.h>
+#include <plat/arm/soc/common/soc_css.h>
void soc_css_init_nic400(void)
{
diff --git a/plat/hisilicon/hikey960/hikey960_bl31_setup.c b/plat/hisilicon/hikey960/hikey960_bl31_setup.c
index 67b06f4..c3fcc38 100644
--- a/plat/hisilicon/hikey960/hikey960_bl31_setup.c
+++ b/plat/hisilicon/hikey960/hikey960_bl31_setup.c
@@ -154,7 +154,8 @@
non_secure = EDMAC_SEC_CTRL_INTR_SEC | EDMAC_SEC_CTRL_GLOBAL_SEC;
mmio_write_32(EDMAC_SEC_CTRL, non_secure);
- for (i = 0; i < EDMAC_CHANNEL_NUMS; i++) {
+ /* Channel 0 is reserved for LPM3, keep secure */
+ for (i = 1; i < EDMAC_CHANNEL_NUMS; i++) {
mmio_write_32(EDMAC_AXI_CONF(i), (1 << 6) | (1 << 18));
}
}
diff --git a/plat/imx/common/imx8_psci.c b/plat/imx/common/imx8_psci.c
index 588d8b4..91d3370 100644
--- a/plat/imx/common/imx8_psci.c
+++ b/plat/imx/common/imx8_psci.c
@@ -32,8 +32,22 @@
int imx_validate_power_state(unsigned int power_state,
psci_power_state_t *req_state)
{
- /* TODO */
- return PSCI_E_INVALID_PARAMS;
+ int pwr_lvl = psci_get_pstate_pwrlvl(power_state);
+ int pwr_type = psci_get_pstate_type(power_state);
+ int state_id = psci_get_pstate_id(power_state);
+
+ if (pwr_lvl > PLAT_MAX_PWR_LVL)
+ return PSCI_E_INVALID_PARAMS;
+
+ if (pwr_type == PSTATE_TYPE_POWERDOWN) {
+ req_state->pwr_domain_state[MPIDR_AFFLVL0] = PLAT_MAX_OFF_STATE;
+ if (!state_id)
+ req_state->pwr_domain_state[MPIDR_AFFLVL1] = PLAT_MAX_RET_STATE;
+ else
+ req_state->pwr_domain_state[MPIDR_AFFLVL1] = PLAT_MAX_OFF_STATE;
+ }
+
+ return PSCI_E_SUCCESS;
}
void imx_get_sys_suspend_power_state(psci_power_state_t *req_state)
diff --git a/plat/imx/common/imx_sip_handler.c b/plat/imx/common/imx_sip_handler.c
index 22a7f2b..55639cd 100644
--- a/plat/imx/common/imx_sip_handler.c
+++ b/plat/imx/common/imx_sip_handler.c
@@ -7,6 +7,7 @@
#include <stdlib.h>
#include <stdint.h>
#include <std_svc.h>
+#include <string.h>
#include <platform_def.h>
#include <common/debug.h>
#include <common/runtime_svc.h>
@@ -76,3 +77,107 @@
return 0;
}
+
+static bool wakeup_src_irqsteer;
+
+bool imx_is_wakeup_src_irqsteer(void)
+{
+ return wakeup_src_irqsteer;
+}
+
+int imx_wakeup_src_handler(uint32_t smc_fid,
+ u_register_t x1,
+ u_register_t x2,
+ u_register_t x3)
+{
+ switch (x1) {
+ case IMX_SIP_WAKEUP_SRC_IRQSTEER:
+ wakeup_src_irqsteer = true;
+ break;
+ case IMX_SIP_WAKEUP_SRC_SCU:
+ wakeup_src_irqsteer = false;
+ break;
+ default:
+ return SMC_UNK;
+ }
+
+ return SMC_OK;
+}
+
+int imx_otp_handler(uint32_t smc_fid,
+ void *handle,
+ u_register_t x1,
+ u_register_t x2)
+{
+ int ret;
+ uint32_t fuse;
+
+ switch (smc_fid) {
+ case IMX_SIP_OTP_READ:
+ ret = sc_misc_otp_fuse_read(ipc_handle, x1, &fuse);
+ SMC_RET2(handle, ret, fuse);
+ break;
+ case IMX_SIP_OTP_WRITE:
+ ret = sc_misc_otp_fuse_write(ipc_handle, x1, x2);
+ SMC_RET1(handle, ret);
+ break;
+ default:
+ ret = SMC_UNK;
+ SMC_RET1(handle, ret);
+ break;
+ }
+
+ return ret;
+}
+
+int imx_misc_set_temp_handler(uint32_t smc_fid,
+ u_register_t x1,
+ u_register_t x2,
+ u_register_t x3,
+ u_register_t x4)
+{
+ return sc_misc_set_temp(ipc_handle, x1, x2, x3, x4);
+}
+
+static uint64_t imx_get_commit_hash(u_register_t x2,
+ u_register_t x3,
+ u_register_t x4)
+{
+ /* Parse the version_string */
+ char *parse = (char *)version_string;
+ uint64_t hash = 0;
+
+ do {
+ parse = strchr(parse, '-');
+ if (parse) {
+ parse += 1;
+ if (*(parse) == 'g') {
+ /* Default is 7 hexadecimal digits */
+ memcpy((void *)&hash, (void *)(parse + 1), 7);
+ break;
+ }
+ }
+
+ } while (parse != NULL);
+
+ return hash;
+}
+
+uint64_t imx_buildinfo_handler(uint32_t smc_fid,
+ u_register_t x1,
+ u_register_t x2,
+ u_register_t x3,
+ u_register_t x4)
+{
+ uint64_t ret;
+
+ switch (x1) {
+ case IMX_SIP_BUILDINFO_GET_COMMITHASH:
+ ret = imx_get_commit_hash(x2, x3, x4);
+ break;
+ default:
+ return SMC_UNK;
+ }
+
+ return ret;
+}
diff --git a/plat/imx/common/imx_sip_svc.c b/plat/imx/common/imx_sip_svc.c
index 89b9df8..c27fbf2 100644
--- a/plat/imx/common/imx_sip_svc.c
+++ b/plat/imx/common/imx_sip_svc.c
@@ -32,7 +32,16 @@
case IMX_SIP_CPUFREQ:
SMC_RET1(handle, imx_cpufreq_handler(smc_fid, x1, x2, x3));
break;
+ case IMX_SIP_WAKEUP_SRC:
+ SMC_RET1(handle, imx_wakeup_src_handler(smc_fid, x1, x2, x3));
+ case IMX_SIP_OTP_READ:
+ case IMX_SIP_OTP_WRITE:
+ return imx_otp_handler(smc_fid, handle, x1, x2);
+ case IMX_SIP_MISC_SET_TEMP:
+ SMC_RET1(handle, imx_misc_set_temp_handler(smc_fid, x1, x2, x3, x4));
#endif
+ case IMX_SIP_BUILDINFO:
+ SMC_RET1(handle, imx_buildinfo_handler(smc_fid, x1, x2, x3, x4));
default:
WARN("Unimplemented i.MX SiP Service Call: 0x%x\n", smc_fid);
SMC_RET1(handle, SMC_UNK);
diff --git a/plat/imx/common/include/imx_sip_svc.h b/plat/imx/common/include/imx_sip_svc.h
index 4ba7b87..648be37 100644
--- a/plat/imx/common/include/imx_sip_svc.h
+++ b/plat/imx/common/include/imx_sip_svc.h
@@ -14,11 +14,33 @@
#define IMX_SIP_SRTC 0xC2000002
#define IMX_SIP_SRTC_SET_TIME 0x00
+#define IMX_SIP_BUILDINFO 0xC2000003
+#define IMX_SIP_BUILDINFO_GET_COMMITHASH 0x00
+
+#define IMX_SIP_WAKEUP_SRC 0xC2000009
+#define IMX_SIP_WAKEUP_SRC_SCU 0x1
+#define IMX_SIP_WAKEUP_SRC_IRQSTEER 0x2
+
+#define IMX_SIP_OTP_READ 0xC200000A
+#define IMX_SIP_OTP_WRITE 0xC200000B
+
+#define IMX_SIP_MISC_SET_TEMP 0xC200000C
+
#if (defined(PLAT_IMX8QM) || defined(PLAT_IMX8QX))
int imx_cpufreq_handler(uint32_t smc_fid, u_register_t x1,
u_register_t x2, u_register_t x3);
int imx_srtc_handler(uint32_t smc_fid, void *handle, u_register_t x1,
u_register_t x2, u_register_t x3, u_register_t x4);
+int imx_wakeup_src_handler(uint32_t smc_fid, u_register_t x1,
+ u_register_t x2, u_register_t x3);
+int imx_otp_handler(uint32_t smc_fid, void *handle,
+ u_register_t x1, u_register_t x2);
+int imx_misc_set_temp_handler(uint32_t smc_fid, u_register_t x1,
+ u_register_t x2, u_register_t x3,
+ u_register_t x4);
+uint64_t imx_buildinfo_handler(uint32_t smc_fid, u_register_t x1,
+ u_register_t x2, u_register_t x3,
+ u_register_t x4);
#endif
#endif /* __IMX_SIP_SVC_H__ */
diff --git a/plat/imx/common/include/plat_imx8.h b/plat/imx/common/include/plat_imx8.h
index 8d83173..be99b97 100644
--- a/plat/imx/common/include/plat_imx8.h
+++ b/plat/imx/common/include/plat_imx8.h
@@ -10,6 +10,11 @@
#include <drivers/arm/gicv3.h>
#include <lib/psci/psci.h>
+struct plat_gic_ctx {
+ gicv3_redist_ctx_t rdist_ctx[PLATFORM_CORE_COUNT];
+ gicv3_dist_ctx_t dist_ctx;
+};
+
unsigned int plat_calc_core_pos(uint64_t mpidr);
void imx_mailbox_init(uintptr_t base_addr);
void plat_gic_driver_init(void);
@@ -23,5 +28,8 @@
int imx_validate_power_state(unsigned int power_state,
psci_power_state_t *req_state);
void imx_get_sys_suspend_power_state(psci_power_state_t *req_state);
+bool imx_is_wakeup_src_irqsteer(void);
+void plat_gic_save(unsigned int proc_num, struct plat_gic_ctx *ctx);
+void plat_gic_restore(unsigned int proc_num, struct plat_gic_ctx *ctx);
#endif /* PLAT_IMX8_H */
diff --git a/plat/imx/common/include/sci/sci.h b/plat/imx/common/include/sci/sci.h
index 1b2f699..2c45bb8 100644
--- a/plat/imx/common/include/sci/sci.h
+++ b/plat/imx/common/include/sci/sci.h
@@ -16,5 +16,6 @@
#include <sci/svc/pm/sci_pm_api.h>
#include <sci/svc/rm/sci_rm_api.h>
#include <sci/svc/timer/sci_timer_api.h>
+#include <sci/svc/misc/sci_misc_api.h>
#endif /* SCI_H */
diff --git a/plat/imx/common/include/sci/svc/misc/sci_misc_api.h b/plat/imx/common/include/sci/svc/misc/sci_misc_api.h
new file mode 100644
index 0000000..d9dd49d
--- /dev/null
+++ b/plat/imx/common/include/sci/svc/misc/sci_misc_api.h
@@ -0,0 +1,539 @@
+/*
+ * Copyright (C) 2016 Freescale Semiconductor, Inc.
+ * Copyright 2017-2019 NXP
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+/*!
+ * Header file containing the public API for the System Controller (SC)
+ * Miscellaneous (MISC) function.
+ *
+ * @addtogroup MISC_SVC (SVC) Miscellaneous Service
+ *
+ * Module for the Miscellaneous (MISC) service.
+ *
+ * @{
+ */
+
+#ifndef SC_MISC_API_H
+#define SC_MISC_API_H
+
+/* Includes */
+
+#include <sci/svc/rm/sci_rm_api.h>
+#include <sci/sci_types.h>
+
+/* Defines */
+
+/*!
+ * @name Defines for type widths
+ */
+/*@{*/
+#define SC_MISC_DMA_GRP_W 5U /* Width of sc_misc_dma_group_t */
+/*@}*/
+
+/*! Max DMA channel priority group */
+#define SC_MISC_DMA_GRP_MAX 31U
+
+/*!
+ * @name Defines for sc_misc_boot_status_t
+ */
+/*@{*/
+#define SC_MISC_BOOT_STATUS_SUCCESS 0U /* Success */
+#define SC_MISC_BOOT_STATUS_SECURITY 1U /* Security violation */
+/*@}*/
+
+/*!
+ * @name Defines for sc_misc_seco_auth_cmd_t
+ */
+/*@{*/
+#define SC_MISC_SECO_AUTH_SECO_FW 0U /* SECO Firmware */
+#define SC_MISC_SECO_AUTH_HDMI_TX_FW 1U /* HDMI TX Firmware */
+#define SC_MISC_SECO_AUTH_HDMI_RX_FW 2U /* HDMI RX Firmware */
+/*@}*/
+
+/*!
+ * @name Defines for sc_misc_temp_t
+ */
+/*@{*/
+#define SC_MISC_TEMP 0U /* Temp sensor */
+#define SC_MISC_TEMP_HIGH 1U /* Temp high alarm */
+#define SC_MISC_TEMP_LOW 2U /* Temp low alarm */
+/*@}*/
+
+/*!
+ * @name Defines for sc_misc_seco_auth_cmd_t
+ */
+/*@{*/
+#define SC_MISC_AUTH_CONTAINER 0U /* Authenticate container */
+#define SC_MISC_VERIFY_IMAGE 1U /* Verify image */
+#define SC_MISC_REL_CONTAINER 2U /* Release container */
+/*@}*/
+
+/* Types */
+
+/*!
+ * This type is used to store a DMA channel priority group.
+ */
+typedef uint8_t sc_misc_dma_group_t;
+
+/*!
+ * This type is used report boot status.
+ */
+typedef uint8_t sc_misc_boot_status_t;
+
+/*!
+ * This type is used to issue SECO authenticate commands.
+ */
+typedef uint8_t sc_misc_seco_auth_cmd_t;
+
+/*!
+ * This type is used report boot status.
+ */
+typedef uint8_t sc_misc_temp_t;
+
+/* Functions */
+
+/*!
+ * @name Control Functions
+ * @{
+ */
+
+/*!
+ * This function sets a miscellaneous control value.
+ *
+ * @param[in] ipc IPC handle
+ * @param[in] resource resource the control is associated with
+ * @param[in] ctrl control to change
+ * @param[in] val value to apply to the control
+ *
+ * @return Returns an error code (SC_ERR_NONE = success).
+ *
+ * Return errors:
+ * - SC_PARM if arguments out of range or invalid,
+ * - SC_ERR_NOACCESS if caller's partition is not the resource owner or parent
+ * of the owner
+ *
+ * Refer to the [Control List](@ref CONTROLS) for valid control values.
+ */
+sc_err_t sc_misc_set_control(sc_ipc_t ipc, sc_rsrc_t resource,
+ sc_ctrl_t ctrl, uint32_t val);
+
+/*!
+ * This function gets a miscellaneous control value.
+ *
+ * @param[in] ipc IPC handle
+ * @param[in] resource resource the control is associated with
+ * @param[in] ctrl control to get
+ * @param[out] val pointer to return the control value
+ *
+ * @return Returns an error code (SC_ERR_NONE = success).
+ *
+ * Return errors:
+ * - SC_PARM if arguments out of range or invalid,
+ * - SC_ERR_NOACCESS if caller's partition is not the resource owner or parent
+ * of the owner
+ *
+ * Refer to the [Control List](@ref CONTROLS) for valid control values.
+ */
+sc_err_t sc_misc_get_control(sc_ipc_t ipc, sc_rsrc_t resource,
+ sc_ctrl_t ctrl, uint32_t *val);
+
+/* @} */
+
+/*!
+ * @name DMA Functions
+ * @{
+ */
+
+/*!
+ * This function configures the max DMA channel priority group for a
+ * partition.
+ *
+ * @param[in] ipc IPC handle
+ * @param[in] pt handle of partition to assign \a max
+ * @param[in] max max priority group (0-31)
+ *
+ * @return Returns an error code (SC_ERR_NONE = success).
+ *
+ * Return errors:
+ * - SC_PARM if arguments out of range or invalid,
+ * - SC_ERR_NOACCESS if caller's partition is not the parent
+ * of the affected partition
+ *
+ * Valid \a max range is 0-31 with 0 being the lowest and 31 the highest.
+ * Default is the max priority group for the parent partition of \a pt.
+ */
+sc_err_t sc_misc_set_max_dma_group(sc_ipc_t ipc, sc_rm_pt_t pt,
+ sc_misc_dma_group_t max);
+
+/*!
+ * This function configures the priority group for a DMA channel.
+ *
+ * @param[in] ipc IPC handle
+ * @param[in] resource DMA channel resource
+ * @param[in] group priority group (0-31)
+ *
+ * @return Returns an error code (SC_ERR_NONE = success).
+ *
+ * Return errors:
+ * - SC_PARM if arguments out of range or invalid,
+ * - SC_ERR_NOACCESS if caller's partition is not the owner or parent
+ * of the owner of the DMA channel
+ *
+ * Valid \a group range is 0-31 with 0 being the lowest and 31 the highest.
+ * The max value of \a group is limited by the partition max set using
+ * sc_misc_set_max_dma_group().
+ */
+sc_err_t sc_misc_set_dma_group(sc_ipc_t ipc, sc_rsrc_t resource,
+ sc_misc_dma_group_t group);
+
+/* @} */
+
+/*!
+ * @name Security Functions
+ * @{
+ */
+
+/*!
+ * This function loads a SECO image.
+ *
+ * @param[in] ipc IPC handle
+ * @param[in] addr_src address of image source
+ * @param[in] addr_dst address of image destination
+ * @param[in] len length of image to load
+ * @param[in] fw SC_TRUE = firmware load
+ *
+ * @return Returns an error code (SC_ERR_NONE = success).
+ *
+ * Return errors codes:
+ * - SC_ERR_PARM if word fuse index param out of range or invalid
+ * - SC_ERR_UNAVAILABLE if SECO not available
+ *
+ * This is used to load images via the SECO. Examples include SECO
+ * Firmware and IVT/CSF data used for authentication. These are usually
+ * loaded into SECO TCM. \a addr_src is in secure memory.
+ *
+ * See the Security Reference Manual (SRM) for more info.
+ */
+sc_err_t sc_misc_seco_image_load(sc_ipc_t ipc, sc_faddr_t addr_src,
+ sc_faddr_t addr_dst, uint32_t len,
+ sc_bool_t fw);
+
+/*!
+ * This function is used to authenticate a SECO image or command.
+ *
+ * @param[in] ipc IPC handle
+ * @param[in] cmd authenticate command
+ * @param[in] addr address of/or metadata
+ *
+ * @return Returns an error code (SC_ERR_NONE = success).
+ *
+ * Return errors codes:
+ * - SC_ERR_PARM if word fuse index param out of range or invalid
+ * - SC_ERR_UNAVAILABLE if SECO not available
+ *
+ * This is used to authenticate a SECO image or issue a security
+ * command. \a addr often points to an container. It is also
+ * just data (or even unused) for some commands.
+ *
+ * See the Security Reference Manual (SRM) for more info.
+ */
+sc_err_t sc_misc_seco_authenticate(sc_ipc_t ipc,
+ sc_misc_seco_auth_cmd_t cmd,
+ sc_faddr_t addr);
+
+/*!
+ * This function securely writes a group of fuse words.
+ *
+ * @param[in] ipc IPC handle
+ * @param[in] addr address of message block
+ *
+ * @return Returns and error code (SC_ERR_NONE = success).
+ *
+ * Return errors codes:
+ * - SC_ERR_UNAVAILABLE if SECO not available
+ *
+ * Note \a addr must be a pointer to a signed message block.
+ *
+ * See the Security Reference Manual (SRM) for more info.
+ */
+sc_err_t sc_misc_seco_fuse_write(sc_ipc_t ipc, sc_faddr_t addr);
+
+/*!
+ * This function securely enables debug.
+ *
+ * @param[in] ipc IPC handle
+ * @param[in] addr address of message block
+ *
+ * @return Returns and error code (SC_ERR_NONE = success).
+ *
+ * Return errors codes:
+ * - SC_ERR_UNAVAILABLE if SECO not available
+ *
+ * Note \a addr must be a pointer to a signed message block.
+ *
+ * See the Security Reference Manual (SRM) for more info.
+ */
+sc_err_t sc_misc_seco_enable_debug(sc_ipc_t ipc, sc_faddr_t addr);
+
+/*!
+ * This function updates the lifecycle of the device.
+ *
+ * @param[in] ipc IPC handle
+ * @param[in] lifecycle new lifecycle
+ *
+ * @return Returns and error code (SC_ERR_NONE = success).
+ *
+ * Return errors codes:
+ * - SC_ERR_UNAVAILABLE if SECO not available
+ *
+ * This message is used for going from Open to NXP Closed to OEM Closed.
+ *
+ * See the Security Reference Manual (SRM) for more info.
+ */
+sc_err_t sc_misc_seco_forward_lifecycle(sc_ipc_t ipc, uint32_t lifecycle);
+
+/*!
+ * This function updates the lifecycle to one of the return lifecycles.
+ *
+ * @param[in] ipc IPC handle
+ * @param[in] addr address of message block
+ *
+ * @return Returns and error code (SC_ERR_NONE = success).
+ *
+ * Return errors codes:
+ * - SC_ERR_UNAVAILABLE if SECO not available
+ *
+ * Note \a addr must be a pointer to a signed message block.
+ *
+ * To switch back to NXP states (Full Field Return), message must be signed
+ * by NXP SRK. For OEM States (Partial Field Return), must be signed by OEM
+ * SRK.
+ *
+ * See the Security Reference Manual (SRM) for more info.
+ */
+sc_err_t sc_misc_seco_return_lifecycle(sc_ipc_t ipc, sc_faddr_t addr);
+
+/*!
+ * This function is used to return the SECO FW build info.
+ *
+ * @param[in] ipc IPC handle
+ * @param[out] version pointer to return build number
+ * @param[out] commit pointer to return commit ID (git SHA-1)
+ */
+void sc_misc_seco_build_info(sc_ipc_t ipc, uint32_t *version, uint32_t *commit);
+
+/*!
+ * This function is used to return SECO chip info.
+ *
+ * @param[in] ipc IPC handle
+ * @param[out] lc pointer to return lifecycle
+ * @param[out] monotonic pointer to return monotonic counter
+ * @param[out] uid_l pointer to return UID (lower 32 bits)
+ * @param[out] uid_h pointer to return UID (upper 32 bits)
+ */
+sc_err_t sc_misc_seco_chip_info(sc_ipc_t ipc, uint16_t *lc,
+ uint16_t *monotonic, uint32_t *uid_l,
+ uint32_t *uid_h);
+
+/* @} */
+
+/*!
+ * @name Debug Functions
+ * @{
+ */
+
+/*!
+ * This function is used output a debug character from the SCU UART.
+ *
+ * @param[in] ipc IPC handle
+ * @param[in] ch character to output
+ */
+void sc_misc_debug_out(sc_ipc_t ipc, uint8_t ch);
+
+/*!
+ * This function starts/stops emulation waveform capture.
+ *
+ * @param[in] ipc IPC handle
+ * @param[in] enable flag to enable/disable capture
+ *
+ * @return Returns an error code (SC_ERR_NONE = success).
+ *
+ * Return errors:
+ * - SC_ERR_UNAVAILABLE if not running on emulation
+ */
+sc_err_t sc_misc_waveform_capture(sc_ipc_t ipc, sc_bool_t enable);
+
+/*!
+ * This function is used to return the SCFW build info.
+ *
+ * @param[in] ipc IPC handle
+ * @param[out] build pointer to return build number
+ * @param[out] commit pointer to return commit ID (git SHA-1)
+ */
+void sc_misc_build_info(sc_ipc_t ipc, uint32_t *build, uint32_t *commit);
+
+/*!
+ * This function is used to return the device's unique ID.
+ *
+ * @param[in] ipc IPC handle
+ * @param[out] id_l pointer to return lower 32-bit of ID [31:0]
+ * @param[out] id_h pointer to return upper 32-bits of ID [63:32]
+ */
+void sc_misc_unique_id(sc_ipc_t ipc, uint32_t *id_l, uint32_t *id_h);
+
+/* @} */
+
+/*!
+ * @name Other Functions
+ * @{
+ */
+
+/*!
+ * This function configures the ARI match value for PCIe/SATA resources.
+ *
+ * @param[in] ipc IPC handle
+ * @param[in] resource match resource
+ * @param[in] resource_mst PCIe/SATA master to match
+ * @param[in] ari ARI to match
+ * @param[in] enable enable match or not
+ *
+ * @return Returns an error code (SC_ERR_NONE = success).
+ *
+ * Return errors:
+ * - SC_PARM if arguments out of range or invalid,
+ * - SC_ERR_NOACCESS if caller's partition is not the owner or parent
+ * of the owner of the resource and translation
+ *
+ * For PCIe, the ARI is the 16-bit value that includes the bus number,
+ * device number, and function number. For SATA, this value includes the
+ * FISType and PM_Port.
+ */
+sc_err_t sc_misc_set_ari(sc_ipc_t ipc, sc_rsrc_t resource,
+ sc_rsrc_t resource_mst, uint16_t ari,
+ sc_bool_t enable);
+
+/*!
+ * This function reports boot status.
+ *
+ * @param[in] ipc IPC handle
+ * @param[in] status boot status
+ *
+ * This is used by SW partitions to report status of boot. This is
+ * normally used to report a boot failure.
+ */
+void sc_misc_boot_status(sc_ipc_t ipc, sc_misc_boot_status_t status);
+
+/*!
+ * This function tells the SCFW that a CPU is done booting.
+ *
+ * @param[in] ipc IPC handle
+ * @param[in] cpu CPU that is done booting
+ *
+ * This is called by early booting CPUs to report they are done with
+ * initialization. After starting early CPUs, the SCFW halts the
+ * booting process until they are done. During this time, early
+ * CPUs can call the SCFW with lower latency as the SCFW is idle.
+ *
+ * @return Returns an error code (SC_ERR_NONE = success).
+ *
+ * Return errors:
+ * - SC_PARM if arguments out of range or invalid,
+ * - SC_ERR_NOACCESS if caller's partition is not the CPU owner
+ */
+sc_err_t sc_misc_boot_done(sc_ipc_t ipc, sc_rsrc_t cpu);
+
+/*!
+ * This function reads a given fuse word index.
+ *
+ * @param[in] ipc IPC handle
+ * @param[in] word fuse word index
+ * @param[out] val fuse read value
+ *
+ * @return Returns and error code (SC_ERR_NONE = success).
+ *
+ * Return errors codes:
+ * - SC_ERR_PARM if word fuse index param out of range or invalid
+ * - SC_ERR_NOACCESS if read operation failed
+ * - SC_ERR_LOCKED if read operation is locked
+ */
+sc_err_t sc_misc_otp_fuse_read(sc_ipc_t ipc, uint32_t word, uint32_t *val);
+
+/*!
+ * This function writes a given fuse word index.
+ *
+ * @param[in] ipc IPC handle
+ * @param[in] word fuse word index
+ * @param[in] val fuse write value
+ *
+ * @return Returns and error code (SC_ERR_NONE = success).
+ *
+ * Return errors codes:
+ * - SC_ERR_PARM if word fuse index param out of range or invalid
+ * - SC_ERR_NOACCESS if write operation failed
+ * - SC_ERR_LOCKED if write operation is locked
+ */
+sc_err_t sc_misc_otp_fuse_write(sc_ipc_t ipc, uint32_t word, uint32_t val);
+
+/*!
+ * This function sets a temp sensor alarm.
+ *
+ * @param[in] ipc IPC handle
+ * @param[in] resource resource with sensor
+ * @param[in] temp alarm to set
+ * @param[in] celsius whole part of temp to set
+ * @param[in] tenths fractional part of temp to set
+ *
+ * @return Returns and error code (SC_ERR_NONE = success).
+ *
+ * This function will enable the alarm interrupt if the temp requested is
+ * not the min/max temp. This enable automatically clears when the alarm
+ * occurs and this function has to be called again to re-enable.
+ *
+ * Return errors codes:
+ * - SC_ERR_PARM if parameters invalid
+ */
+sc_err_t sc_misc_set_temp(sc_ipc_t ipc, sc_rsrc_t resource,
+ sc_misc_temp_t temp, int16_t celsius, int8_t tenths);
+
+/*!
+ * This function gets a temp sensor value.
+ *
+ * @param[in] ipc IPC handle
+ * @param[in] resource resource with sensor
+ * @param[in] temp value to get (sensor or alarm)
+ * @param[out] celsius whole part of temp to get
+ * @param[out] tenths fractional part of temp to get
+ *
+ * @return Returns and error code (SC_ERR_NONE = success).
+ *
+ * Return errors codes:
+ * - SC_ERR_PARM if parameters invalid
+ */
+sc_err_t sc_misc_get_temp(sc_ipc_t ipc, sc_rsrc_t resource,
+ sc_misc_temp_t temp, int16_t *celsius,
+ int8_t *tenths);
+
+/*!
+ * This function returns the boot device.
+ *
+ * @param[in] ipc IPC handle
+ * @param[out] dev pointer to return boot device
+ */
+void sc_misc_get_boot_dev(sc_ipc_t ipc, sc_rsrc_t *dev);
+
+/*!
+ * This function returns the current status of the ON/OFF button.
+ *
+ * @param[in] ipc IPC handle
+ * @param[out] status pointer to return button status
+ */
+void sc_misc_get_button_status(sc_ipc_t ipc, sc_bool_t *status);
+
+/* @} */
+
+#endif /* SC_MISC_API_H */
+
+/**@}*/
diff --git a/plat/imx/common/plat_imx8_gic.c b/plat/imx/common/plat_imx8_gic.c
index aec0b6c..27c525b 100644
--- a/plat/imx/common/plat_imx8_gic.c
+++ b/plat/imx/common/plat_imx8_gic.c
@@ -73,3 +73,19 @@
{
gicv3_rdistif_init(plat_my_core_pos());
}
+
+void plat_gic_save(unsigned int proc_num, struct plat_gic_ctx *ctx)
+{
+ /* save the gic rdist/dist context */
+ for (int i = 0; i < PLATFORM_CORE_COUNT; i++)
+ gicv3_rdistif_save(i, &ctx->rdist_ctx[i]);
+ gicv3_distif_save(&ctx->dist_ctx);
+}
+
+void plat_gic_restore(unsigned int proc_num, struct plat_gic_ctx *ctx)
+{
+ /* restore the gic rdist/dist context */
+ gicv3_distif_init_restore(&ctx->dist_ctx);
+ for (int i = 0; i < PLATFORM_CORE_COUNT; i++)
+ gicv3_rdistif_init_restore(i, &ctx->rdist_ctx[i]);
+}
diff --git a/plat/imx/common/sci/imx8_mu.c b/plat/imx/common/sci/imx8_mu.c
index 26d9bdf..66e956d 100644
--- a/plat/imx/common/sci/imx8_mu.c
+++ b/plat/imx/common/sci/imx8_mu.c
@@ -8,6 +8,21 @@
#include "imx8_mu.h"
+void MU_Resume(uint32_t base)
+{
+ uint32_t reg, i;
+
+ reg = mmio_read_32(base + MU_ACR_OFFSET1);
+ /* Clear GIEn, RIEn, TIEn, GIRn and ABFn. */
+ reg &= ~(MU_CR_GIEn_MASK1 | MU_CR_RIEn_MASK1 | MU_CR_TIEn_MASK1
+ | MU_CR_GIRn_MASK1 | MU_CR_Fn_MASK1);
+ mmio_write_32(base + MU_ACR_OFFSET1, reg);
+
+ /* Enable all RX interrupts */
+ for (i = 0; i < MU_RR_COUNT; i++)
+ MU_EnableRxFullInt(base, i);
+}
+
void MU_EnableRxFullInt(uint32_t base, uint32_t index)
{
uint32_t reg = mmio_read_32(base + MU_ACR_OFFSET1);
diff --git a/plat/imx/common/sci/imx8_mu.h b/plat/imx/common/sci/imx8_mu.h
index 8c78877..edcac7b 100644
--- a/plat/imx/common/sci/imx8_mu.h
+++ b/plat/imx/common/sci/imx8_mu.h
@@ -33,3 +33,4 @@
void MU_ReceiveMsg(uint32_t base, uint32_t regIndex, uint32_t *msg);
void MU_EnableGeneralInt(uint32_t base, uint32_t index);
void MU_EnableRxFullInt(uint32_t base, uint32_t index);
+void MU_Resume(uint32_t base);
diff --git a/plat/imx/common/sci/sci_api.mk b/plat/imx/common/sci/sci_api.mk
index edaef4d..92c7190 100644
--- a/plat/imx/common/sci/sci_api.mk
+++ b/plat/imx/common/sci/sci_api.mk
@@ -9,4 +9,5 @@
plat/imx/common/sci/svc/pad/pad_rpc_clnt.c \
plat/imx/common/sci/svc/pm/pm_rpc_clnt.c \
plat/imx/common/sci/svc/rm/rm_rpc_clnt.c \
- plat/imx/common/sci/svc/timer/timer_rpc_clnt.c
+ plat/imx/common/sci/svc/timer/timer_rpc_clnt.c \
+ plat/imx/common/sci/svc/misc/misc_rpc_clnt.c
diff --git a/plat/imx/common/sci/svc/misc/misc_rpc_clnt.c b/plat/imx/common/sci/svc/misc/misc_rpc_clnt.c
new file mode 100644
index 0000000..080de6a
--- /dev/null
+++ b/plat/imx/common/sci/svc/misc/misc_rpc_clnt.c
@@ -0,0 +1,506 @@
+/*
+ * Copyright (C) 2016 Freescale Semiconductor, Inc.
+ * Copyright 2017-2018 NXP
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+/*!
+ * File containing client-side RPC functions for the MISC service. These
+ * functions are ported to clients that communicate to the SC.
+ *
+ * @addtogroup MISC_SVC
+ * @{
+ */
+
+/* Includes */
+
+#include <sci/sci_types.h>
+#include <sci/svc/rm/sci_rm_api.h>
+#include <sci/svc/misc/sci_misc_api.h>
+#include <sci/sci_rpc.h>
+#include <stdlib.h>
+#include "sci_misc_rpc.h"
+
+/* Local Defines */
+
+/* Local Types */
+
+/* Local Functions */
+
+sc_err_t sc_misc_set_control(sc_ipc_t ipc, sc_rsrc_t resource,
+ sc_ctrl_t ctrl, uint32_t val)
+{
+ sc_rpc_msg_t msg;
+ uint8_t result;
+
+ RPC_VER(&msg) = SC_RPC_VERSION;
+ RPC_SVC(&msg) = (uint8_t)SC_RPC_SVC_MISC;
+ RPC_FUNC(&msg) = (uint8_t)MISC_FUNC_SET_CONTROL;
+ RPC_U32(&msg, 0U) = (uint32_t)ctrl;
+ RPC_U32(&msg, 4U) = (uint32_t)val;
+ RPC_U16(&msg, 8U) = (uint16_t)resource;
+ RPC_SIZE(&msg) = 4U;
+
+ sc_call_rpc(ipc, &msg, SC_FALSE);
+
+ result = RPC_R8(&msg);
+ return (sc_err_t)result;
+}
+
+sc_err_t sc_misc_get_control(sc_ipc_t ipc, sc_rsrc_t resource,
+ sc_ctrl_t ctrl, uint32_t *val)
+{
+ sc_rpc_msg_t msg;
+ uint8_t result;
+
+ RPC_VER(&msg) = SC_RPC_VERSION;
+ RPC_SVC(&msg) = (uint8_t)SC_RPC_SVC_MISC;
+ RPC_FUNC(&msg) = (uint8_t)MISC_FUNC_GET_CONTROL;
+ RPC_U32(&msg, 0U) = (uint32_t)ctrl;
+ RPC_U16(&msg, 4U) = (uint16_t)resource;
+ RPC_SIZE(&msg) = 3U;
+
+ sc_call_rpc(ipc, &msg, SC_FALSE);
+
+ if (val != NULL)
+ *val = RPC_U32(&msg, 0U);
+
+ result = RPC_R8(&msg);
+ return (sc_err_t)result;
+}
+
+sc_err_t sc_misc_set_max_dma_group(sc_ipc_t ipc, sc_rm_pt_t pt,
+ sc_misc_dma_group_t max)
+{
+ sc_rpc_msg_t msg;
+ uint8_t result;
+
+ RPC_VER(&msg) = SC_RPC_VERSION;
+ RPC_SVC(&msg) = (uint8_t)SC_RPC_SVC_MISC;
+ RPC_FUNC(&msg) = (uint8_t)MISC_FUNC_SET_MAX_DMA_GROUP;
+ RPC_U8(&msg, 0U) = (uint8_t)pt;
+ RPC_U8(&msg, 1U) = (uint8_t)max;
+ RPC_SIZE(&msg) = 2U;
+
+ sc_call_rpc(ipc, &msg, SC_FALSE);
+
+ result = RPC_R8(&msg);
+ return (sc_err_t)result;
+}
+
+sc_err_t sc_misc_set_dma_group(sc_ipc_t ipc, sc_rsrc_t resource,
+ sc_misc_dma_group_t group)
+{
+ sc_rpc_msg_t msg;
+ uint8_t result;
+
+ RPC_VER(&msg) = SC_RPC_VERSION;
+ RPC_SVC(&msg) = (uint8_t)SC_RPC_SVC_MISC;
+ RPC_FUNC(&msg) = (uint8_t)MISC_FUNC_SET_DMA_GROUP;
+ RPC_U16(&msg, 0U) = (uint16_t)resource;
+ RPC_U8(&msg, 2U) = (uint8_t)group;
+ RPC_SIZE(&msg) = 2U;
+
+ sc_call_rpc(ipc, &msg, SC_FALSE);
+
+ result = RPC_R8(&msg);
+ return (sc_err_t)result;
+}
+
+sc_err_t sc_misc_seco_image_load(sc_ipc_t ipc, sc_faddr_t addr_src,
+ sc_faddr_t addr_dst, uint32_t len,
+ sc_bool_t fw)
+{
+ sc_rpc_msg_t msg;
+ uint8_t result;
+
+ RPC_VER(&msg) = SC_RPC_VERSION;
+ RPC_SVC(&msg) = (uint8_t)SC_RPC_SVC_MISC;
+ RPC_FUNC(&msg) = (uint8_t)MISC_FUNC_SECO_IMAGE_LOAD;
+ RPC_U32(&msg, 0U) = (uint32_t)(addr_src >> 32U);
+ RPC_U32(&msg, 4U) = (uint32_t)addr_src;
+ RPC_U32(&msg, 8U) = (uint32_t)(addr_dst >> 32U);
+ RPC_U32(&msg, 12U) = (uint32_t)addr_dst;
+ RPC_U32(&msg, 16U) = (uint32_t)len;
+ RPC_U8(&msg, 20U) = (uint8_t)fw;
+ RPC_SIZE(&msg) = 7U;
+
+ sc_call_rpc(ipc, &msg, SC_FALSE);
+
+ result = RPC_R8(&msg);
+ return (sc_err_t)result;
+}
+
+sc_err_t sc_misc_seco_authenticate(sc_ipc_t ipc,
+ sc_misc_seco_auth_cmd_t cmd, sc_faddr_t addr)
+{
+ sc_rpc_msg_t msg;
+ uint8_t result;
+
+ RPC_VER(&msg) = SC_RPC_VERSION;
+ RPC_SVC(&msg) = (uint8_t)SC_RPC_SVC_MISC;
+ RPC_FUNC(&msg) = (uint8_t)MISC_FUNC_SECO_AUTHENTICATE;
+ RPC_U32(&msg, 0U) = (uint32_t)(addr >> 32U);
+ RPC_U32(&msg, 4U) = (uint32_t)addr;
+ RPC_U8(&msg, 8U) = (uint8_t)cmd;
+ RPC_SIZE(&msg) = 4U;
+
+ sc_call_rpc(ipc, &msg, SC_FALSE);
+
+ result = RPC_R8(&msg);
+ return (sc_err_t)result;
+}
+
+sc_err_t sc_misc_seco_fuse_write(sc_ipc_t ipc, sc_faddr_t addr)
+{
+ sc_rpc_msg_t msg;
+ uint8_t result;
+
+ RPC_VER(&msg) = SC_RPC_VERSION;
+ RPC_SVC(&msg) = (uint8_t)SC_RPC_SVC_MISC;
+ RPC_FUNC(&msg) = (uint8_t)MISC_FUNC_SECO_FUSE_WRITE;
+ RPC_U32(&msg, 0U) = (uint32_t)(addr >> 32U);
+ RPC_U32(&msg, 4U) = (uint32_t)addr;
+ RPC_SIZE(&msg) = 3U;
+
+ sc_call_rpc(ipc, &msg, SC_FALSE);
+
+ result = RPC_R8(&msg);
+ return (sc_err_t)result;
+}
+
+sc_err_t sc_misc_seco_enable_debug(sc_ipc_t ipc, sc_faddr_t addr)
+{
+ sc_rpc_msg_t msg;
+ uint8_t result;
+
+ RPC_VER(&msg) = SC_RPC_VERSION;
+ RPC_SVC(&msg) = (uint8_t)SC_RPC_SVC_MISC;
+ RPC_FUNC(&msg) = (uint8_t)MISC_FUNC_SECO_ENABLE_DEBUG;
+ RPC_U32(&msg, 0U) = (uint32_t)(addr >> 32U);
+ RPC_U32(&msg, 4U) = (uint32_t)addr;
+ RPC_SIZE(&msg) = 3U;
+
+ sc_call_rpc(ipc, &msg, SC_FALSE);
+
+ result = RPC_R8(&msg);
+ return (sc_err_t)result;
+}
+
+sc_err_t sc_misc_seco_forward_lifecycle(sc_ipc_t ipc, uint32_t lifecycle)
+{
+ sc_rpc_msg_t msg;
+ uint8_t result;
+
+ RPC_VER(&msg) = SC_RPC_VERSION;
+ RPC_SVC(&msg) = (uint8_t)SC_RPC_SVC_MISC;
+ RPC_FUNC(&msg) = (uint8_t)MISC_FUNC_SECO_FORWARD_LIFECYCLE;
+ RPC_U32(&msg, 0U) = (uint32_t)lifecycle;
+ RPC_SIZE(&msg) = 2U;
+
+ sc_call_rpc(ipc, &msg, SC_FALSE);
+
+ result = RPC_R8(&msg);
+ return (sc_err_t)result;
+}
+
+sc_err_t sc_misc_seco_return_lifecycle(sc_ipc_t ipc, sc_faddr_t addr)
+{
+ sc_rpc_msg_t msg;
+ uint8_t result;
+
+ RPC_VER(&msg) = SC_RPC_VERSION;
+ RPC_SVC(&msg) = (uint8_t)SC_RPC_SVC_MISC;
+ RPC_FUNC(&msg) = (uint8_t)MISC_FUNC_SECO_RETURN_LIFECYCLE;
+ RPC_U32(&msg, 0U) = (uint32_t)(addr >> 32U);
+ RPC_U32(&msg, 4U) = (uint32_t)addr;
+ RPC_SIZE(&msg) = 3U;
+
+ sc_call_rpc(ipc, &msg, SC_FALSE);
+
+ result = RPC_R8(&msg);
+ return (sc_err_t)result;
+}
+
+void sc_misc_seco_build_info(sc_ipc_t ipc, uint32_t *version, uint32_t *commit)
+{
+ sc_rpc_msg_t msg;
+
+ RPC_VER(&msg) = SC_RPC_VERSION;
+ RPC_SVC(&msg) = (uint8_t)SC_RPC_SVC_MISC;
+ RPC_FUNC(&msg) = (uint8_t)MISC_FUNC_SECO_BUILD_INFO;
+ RPC_SIZE(&msg) = 1U;
+
+ sc_call_rpc(ipc, &msg, SC_FALSE);
+
+ if (version != NULL)
+ *version = RPC_U32(&msg, 0U);
+
+ if (commit != NULL)
+ *commit = RPC_U32(&msg, 4U);
+}
+
+sc_err_t sc_misc_seco_chip_info(sc_ipc_t ipc, uint16_t *lc,
+ uint16_t *monotonic, uint32_t *uid_l,
+ uint32_t *uid_h)
+{
+ sc_rpc_msg_t msg;
+ uint8_t result;
+
+ RPC_VER(&msg) = SC_RPC_VERSION;
+ RPC_SVC(&msg) = (uint8_t)SC_RPC_SVC_MISC;
+ RPC_FUNC(&msg) = (uint8_t)MISC_FUNC_SECO_CHIP_INFO;
+ RPC_SIZE(&msg) = 1U;
+
+ sc_call_rpc(ipc, &msg, SC_FALSE);
+
+ if (uid_l != NULL)
+ *uid_l = RPC_U32(&msg, 0U);
+
+ if (uid_h != NULL)
+ *uid_h = RPC_U32(&msg, 4U);
+
+ if (lc != NULL)
+ *lc = RPC_U16(&msg, 8U);
+
+ if (monotonic != NULL)
+ *monotonic = RPC_U16(&msg, 10U);
+
+ result = RPC_R8(&msg);
+ return (sc_err_t)result;
+}
+
+void sc_misc_debug_out(sc_ipc_t ipc, uint8_t ch)
+{
+ sc_rpc_msg_t msg;
+
+ RPC_VER(&msg) = SC_RPC_VERSION;
+ RPC_SVC(&msg) = (uint8_t)SC_RPC_SVC_MISC;
+ RPC_FUNC(&msg) = (uint8_t)MISC_FUNC_DEBUG_OUT;
+ RPC_U8(&msg, 0U) = (uint8_t)ch;
+ RPC_SIZE(&msg) = 2U;
+
+ sc_call_rpc(ipc, &msg, SC_FALSE);
+}
+
+sc_err_t sc_misc_waveform_capture(sc_ipc_t ipc, sc_bool_t enable)
+{
+ sc_rpc_msg_t msg;
+ uint8_t result;
+
+ RPC_VER(&msg) = SC_RPC_VERSION;
+ RPC_SVC(&msg) = (uint8_t)SC_RPC_SVC_MISC;
+ RPC_FUNC(&msg) = (uint8_t)MISC_FUNC_WAVEFORM_CAPTURE;
+ RPC_U8(&msg, 0U) = (uint8_t)enable;
+ RPC_SIZE(&msg) = 2U;
+
+ sc_call_rpc(ipc, &msg, SC_FALSE);
+
+ result = RPC_R8(&msg);
+ return (sc_err_t)result;
+}
+
+void sc_misc_build_info(sc_ipc_t ipc, uint32_t *build, uint32_t *commit)
+{
+ sc_rpc_msg_t msg;
+
+ RPC_VER(&msg) = SC_RPC_VERSION;
+ RPC_SVC(&msg) = (uint8_t)SC_RPC_SVC_MISC;
+ RPC_FUNC(&msg) = (uint8_t)MISC_FUNC_BUILD_INFO;
+ RPC_SIZE(&msg) = 1U;
+
+ sc_call_rpc(ipc, &msg, SC_FALSE);
+
+ if (build != NULL)
+ *build = RPC_U32(&msg, 0U);
+
+ if (commit != NULL)
+ *commit = RPC_U32(&msg, 4U);
+}
+
+void sc_misc_unique_id(sc_ipc_t ipc, uint32_t *id_l, uint32_t *id_h)
+{
+ sc_rpc_msg_t msg;
+
+ RPC_VER(&msg) = SC_RPC_VERSION;
+ RPC_SVC(&msg) = (uint8_t)SC_RPC_SVC_MISC;
+ RPC_FUNC(&msg) = (uint8_t)MISC_FUNC_UNIQUE_ID;
+ RPC_SIZE(&msg) = 1U;
+
+ sc_call_rpc(ipc, &msg, SC_FALSE);
+
+ if (id_l != NULL)
+ *id_l = RPC_U32(&msg, 0U);
+
+ if (id_h != NULL)
+ *id_h = RPC_U32(&msg, 4U);
+}
+
+sc_err_t sc_misc_set_ari(sc_ipc_t ipc, sc_rsrc_t resource,
+ sc_rsrc_t resource_mst, uint16_t ari, sc_bool_t enable)
+{
+ sc_rpc_msg_t msg;
+ uint8_t result;
+
+ RPC_VER(&msg) = SC_RPC_VERSION;
+ RPC_SVC(&msg) = (uint8_t)SC_RPC_SVC_MISC;
+ RPC_FUNC(&msg) = (uint8_t)MISC_FUNC_SET_ARI;
+ RPC_U16(&msg, 0U) = (uint16_t)resource;
+ RPC_U16(&msg, 2U) = (uint16_t)resource_mst;
+ RPC_U16(&msg, 4U) = (uint16_t)ari;
+ RPC_U8(&msg, 6U) = (uint8_t)enable;
+ RPC_SIZE(&msg) = 3U;
+
+ sc_call_rpc(ipc, &msg, SC_FALSE);
+
+ result = RPC_R8(&msg);
+ return (sc_err_t)result;
+}
+
+void sc_misc_boot_status(sc_ipc_t ipc, sc_misc_boot_status_t status)
+{
+ sc_rpc_msg_t msg;
+
+ RPC_VER(&msg) = SC_RPC_VERSION;
+ RPC_SVC(&msg) = (uint8_t)SC_RPC_SVC_MISC;
+ RPC_FUNC(&msg) = (uint8_t)MISC_FUNC_BOOT_STATUS;
+ RPC_U8(&msg, 0U) = (uint8_t)status;
+ RPC_SIZE(&msg) = 2U;
+
+ sc_call_rpc(ipc, &msg, SC_TRUE);
+}
+
+sc_err_t sc_misc_boot_done(sc_ipc_t ipc, sc_rsrc_t cpu)
+{
+ sc_rpc_msg_t msg;
+ uint8_t result;
+
+ RPC_VER(&msg) = SC_RPC_VERSION;
+ RPC_SVC(&msg) = (uint8_t)SC_RPC_SVC_MISC;
+ RPC_FUNC(&msg) = (uint8_t)MISC_FUNC_BOOT_DONE;
+ RPC_U16(&msg, 0U) = (uint16_t)cpu;
+ RPC_SIZE(&msg) = 2U;
+
+ sc_call_rpc(ipc, &msg, SC_FALSE);
+
+ result = RPC_R8(&msg);
+ return (sc_err_t)result;
+}
+
+sc_err_t sc_misc_otp_fuse_read(sc_ipc_t ipc, uint32_t word, uint32_t *val)
+{
+ sc_rpc_msg_t msg;
+ uint8_t result;
+
+ RPC_VER(&msg) = SC_RPC_VERSION;
+ RPC_SVC(&msg) = (uint8_t)SC_RPC_SVC_MISC;
+ RPC_FUNC(&msg) = (uint8_t)MISC_FUNC_OTP_FUSE_READ;
+ RPC_U32(&msg, 0U) = (uint32_t)word;
+ RPC_SIZE(&msg) = 2U;
+
+ sc_call_rpc(ipc, &msg, SC_FALSE);
+
+ if (val != NULL)
+ *val = RPC_U32(&msg, 0U);
+
+ result = RPC_R8(&msg);
+ return (sc_err_t)result;
+}
+
+sc_err_t sc_misc_otp_fuse_write(sc_ipc_t ipc, uint32_t word, uint32_t val)
+{
+ sc_rpc_msg_t msg;
+ uint8_t result;
+
+ RPC_VER(&msg) = SC_RPC_VERSION;
+ RPC_SVC(&msg) = (uint8_t)SC_RPC_SVC_MISC;
+ RPC_FUNC(&msg) = (uint8_t)MISC_FUNC_OTP_FUSE_WRITE;
+ RPC_U32(&msg, 0U) = (uint32_t)word;
+ RPC_U32(&msg, 4U) = (uint32_t)val;
+ RPC_SIZE(&msg) = 3U;
+
+ sc_call_rpc(ipc, &msg, SC_FALSE);
+
+ result = RPC_R8(&msg);
+ return (sc_err_t)result;
+}
+
+sc_err_t sc_misc_set_temp(sc_ipc_t ipc, sc_rsrc_t resource,
+ sc_misc_temp_t temp, int16_t celsius, int8_t tenths)
+{
+ sc_rpc_msg_t msg;
+ uint8_t result;
+
+ RPC_VER(&msg) = SC_RPC_VERSION;
+ RPC_SVC(&msg) = (uint8_t)SC_RPC_SVC_MISC;
+ RPC_FUNC(&msg) = (uint8_t)MISC_FUNC_SET_TEMP;
+ RPC_U16(&msg, 0U) = (uint16_t)resource;
+ RPC_I16(&msg, 2U) = (int16_t) celsius;
+ RPC_U8(&msg, 4U) = (uint8_t)temp;
+ RPC_I8(&msg, 5U) = (int8_t) tenths;
+ RPC_SIZE(&msg) = 3U;
+
+ sc_call_rpc(ipc, &msg, SC_FALSE);
+
+ result = RPC_R8(&msg);
+ return (sc_err_t)result;
+}
+
+sc_err_t sc_misc_get_temp(sc_ipc_t ipc, sc_rsrc_t resource,
+ sc_misc_temp_t temp, int16_t *celsius,
+ int8_t *tenths)
+{
+ sc_rpc_msg_t msg;
+ uint8_t result;
+
+ RPC_VER(&msg) = SC_RPC_VERSION;
+ RPC_SVC(&msg) = (uint8_t)SC_RPC_SVC_MISC;
+ RPC_FUNC(&msg) = (uint8_t)MISC_FUNC_GET_TEMP;
+ RPC_U16(&msg, 0U) = (uint16_t)resource;
+ RPC_U8(&msg, 2U) = (uint8_t)temp;
+ RPC_SIZE(&msg) = 2U;
+
+ sc_call_rpc(ipc, &msg, SC_FALSE);
+
+ if (celsius != NULL)
+ *celsius = RPC_I16(&msg, 0U);
+
+ result = RPC_R8(&msg);
+ if (tenths != NULL)
+ *tenths = RPC_I8(&msg, 2U);
+
+ return (sc_err_t)result;
+}
+
+void sc_misc_get_boot_dev(sc_ipc_t ipc, sc_rsrc_t *dev)
+{
+ sc_rpc_msg_t msg;
+
+ RPC_VER(&msg) = SC_RPC_VERSION;
+ RPC_SVC(&msg) = (uint8_t)SC_RPC_SVC_MISC;
+ RPC_FUNC(&msg) = (uint8_t)MISC_FUNC_GET_BOOT_DEV;
+ RPC_SIZE(&msg) = 1U;
+
+ sc_call_rpc(ipc, &msg, SC_FALSE);
+
+ if (dev != NULL)
+ *dev = RPC_U16(&msg, 0U);
+}
+
+void sc_misc_get_button_status(sc_ipc_t ipc, sc_bool_t *status)
+{
+ sc_rpc_msg_t msg;
+
+ RPC_VER(&msg) = SC_RPC_VERSION;
+ RPC_SVC(&msg) = (uint8_t)SC_RPC_SVC_MISC;
+ RPC_FUNC(&msg) = (uint8_t)MISC_FUNC_GET_BUTTON_STATUS;
+ RPC_SIZE(&msg) = 1U;
+
+ sc_call_rpc(ipc, &msg, SC_FALSE);
+
+ if (status != NULL)
+ *status = RPC_U8(&msg, 0U);
+}
+
+/**@}*/
diff --git a/plat/imx/common/sci/svc/misc/sci_misc_rpc.h b/plat/imx/common/sci/svc/misc/sci_misc_rpc.h
new file mode 100644
index 0000000..03b1a51
--- /dev/null
+++ b/plat/imx/common/sci/svc/misc/sci_misc_rpc.h
@@ -0,0 +1,76 @@
+/*
+ * Copyright (C) 2016 Freescale Semiconductor, Inc.
+ * Copyright 2017-2019 NXP
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+/*!
+ * Header file for the MISC RPC implementation.
+ *
+ * @addtogroup MISC_SVC
+ * @{
+ */
+
+#ifndef SC_MISC_RPC_H
+#define SC_MISC_RPC_H
+
+/* Includes */
+
+/* Defines */
+
+/*!
+ * @name Defines for RPC MISC function calls
+ */
+/*@{*/
+#define MISC_FUNC_UNKNOWN 0 /* Unknown function */
+#define MISC_FUNC_SET_CONTROL 1U /* Index for misc_set_control() RPC call */
+#define MISC_FUNC_GET_CONTROL 2U /* Index for misc_get_control() RPC call */
+#define MISC_FUNC_SET_MAX_DMA_GROUP 4U /* Index for misc_set_max_dma_group() RPC call */
+#define MISC_FUNC_SET_DMA_GROUP 5U /* Index for misc_set_dma_group() RPC call */
+#define MISC_FUNC_SECO_IMAGE_LOAD 8U /* Index for misc_seco_image_load() RPC call */
+#define MISC_FUNC_SECO_AUTHENTICATE 9U /* Index for misc_seco_authenticate() RPC call */
+#define MISC_FUNC_SECO_FUSE_WRITE 20U /* Index for misc_seco_fuse_write() RPC call */
+#define MISC_FUNC_SECO_ENABLE_DEBUG 21U /* Index for misc_seco_enable_debug() RPC call */
+#define MISC_FUNC_SECO_FORWARD_LIFECYCLE 22U /* Index for misc_seco_forward_lifecycle() RPC call */
+#define MISC_FUNC_SECO_RETURN_LIFECYCLE 23U /* Index for misc_seco_return_lifecycle() RPC call */
+#define MISC_FUNC_SECO_BUILD_INFO 24U /* Index for misc_seco_build_info() RPC call */
+#define MISC_FUNC_SECO_CHIP_INFO 25U /* Index for misc_seco_chip_info() RPC call */
+#define MISC_FUNC_DEBUG_OUT 10U /* Index for misc_debug_out() RPC call */
+#define MISC_FUNC_WAVEFORM_CAPTURE 6U /* Index for misc_waveform_capture() RPC call */
+#define MISC_FUNC_BUILD_INFO 15U /* Index for misc_build_info() RPC call */
+#define MISC_FUNC_UNIQUE_ID 19U /* Index for misc_unique_id() RPC call */
+#define MISC_FUNC_SET_ARI 3U /* Index for misc_set_ari() RPC call */
+#define MISC_FUNC_BOOT_STATUS 7U /* Index for misc_boot_status() RPC call */
+#define MISC_FUNC_BOOT_DONE 14U /* Index for misc_boot_done() RPC call */
+#define MISC_FUNC_OTP_FUSE_READ 11U /* Index for misc_otp_fuse_read() RPC call */
+#define MISC_FUNC_OTP_FUSE_WRITE 17U /* Index for misc_otp_fuse_write() RPC call */
+#define MISC_FUNC_SET_TEMP 12U /* Index for misc_set_temp() RPC call */
+#define MISC_FUNC_GET_TEMP 13U /* Index for misc_get_temp() RPC call */
+#define MISC_FUNC_GET_BOOT_DEV 16U /* Index for misc_get_boot_dev() RPC call */
+#define MISC_FUNC_GET_BUTTON_STATUS 18U /* Index for misc_get_button_status() RPC call */
+/*@}*/
+
+/* Types */
+
+/* Functions */
+
+/*!
+ * This function dispatches an incoming MISC RPC request.
+ *
+ * @param[in] caller_pt caller partition
+ * @param[in] msg pointer to RPC message
+ */
+void misc_dispatch(sc_rm_pt_t caller_pt, sc_rpc_msg_t *msg);
+
+/*!
+ * This function translates and dispatches an MISC RPC request.
+ *
+ * @param[in] ipc IPC handle
+ * @param[in] msg pointer to RPC message
+ */
+void misc_xlate(sc_ipc_t ipc, sc_rpc_msg_t *msg);
+
+#endif /* SC_MISC_RPC_H */
+
+/**@}*/
diff --git a/plat/imx/imx7/warp7/include/platform_def.h b/plat/imx/imx7/warp7/include/platform_def.h
index a931c80..d58382f 100644
--- a/plat/imx/imx7/warp7/include/platform_def.h
+++ b/plat/imx/imx7/warp7/include/platform_def.h
@@ -106,6 +106,12 @@
#define WARP7_DTB_BASE (DRAM_BASE + 0x03000000)
#define WARP7_DTB_LIMIT (WARP7_DTB_BASE + WARP7_DTB_SIZE)
+/* Define the absolute location of DTB Overlay 0x83100000 - 0x83101000 */
+#define WARP7_DTB_OVERLAY_SIZE 0x00001000
+#define WARP7_DTB_OVERLAY_BASE WARP7_DTB_LIMIT
+#define WARP7_DTB_OVERLAY_LIMIT (WARP7_DTB_OVERLAY_BASE + \
+ WARP7_DTB_OVERLAY_SIZE)
+
/*
* BL2 specific defines.
*
@@ -142,6 +148,8 @@
* | DDR | BL33/U-BOOT
* 0x87800000 +-----------------+
* | DDR | Unallocated
+ * 0x83101000 +-----------------+
+ * | DDR | DTB Overlay
* 0x83100000 +-----------------+
* | DDR | DTB
* 0x83000000 +-----------------+
diff --git a/plat/imx/imx7/warp7/platform.mk b/plat/imx/imx7/warp7/platform.mk
index a771865..f7bd4ae 100644
--- a/plat/imx/imx7/warp7/platform.mk
+++ b/plat/imx/imx7/warp7/platform.mk
@@ -62,6 +62,43 @@
plat/imx/imx7/warp7/warp7_image_load.c \
${XLAT_TABLES_LIB_SRCS}
+ifneq (${TRUSTED_BOARD_BOOT},0)
+
+include drivers/auth/mbedtls/mbedtls_crypto.mk
+include drivers/auth/mbedtls/mbedtls_x509.mk
+
+AUTH_SOURCES := drivers/auth/auth_mod.c \
+ drivers/auth/crypto_mod.c \
+ drivers/auth/img_parser_mod.c \
+ drivers/auth/tbbr/tbbr_cot.c
+
+BL2_SOURCES += ${AUTH_SOURCES} \
+ plat/common/tbbr/plat_tbbr.c \
+ plat/imx/imx7/warp7/warp7_trusted_boot.c \
+ plat/imx/imx7/warp7/warp7_rotpk.S
+
+ROT_KEY = $(BUILD_PLAT)/rot_key.pem
+ROTPK_HASH = $(BUILD_PLAT)/rotpk_sha256.bin
+
+$(eval $(call add_define_val,ROTPK_HASH,'"$(ROTPK_HASH)"'))
+$(eval $(call MAKE_LIB_DIRS))
+
+$(BUILD_PLAT)/bl2/warp7_rotpk.o: $(ROTPK_HASH)
+
+certificates: $(ROT_KEY)
+
+$(ROT_KEY): | $(BUILD_PLAT)
+ @echo " OPENSSL $@"
+ @if [ ! -f $(ROT_KEY) ]; then \
+ openssl genrsa 2048 > $@ 2>/dev/null; \
+ fi
+
+$(ROTPK_HASH): $(ROT_KEY)
+ @echo " OPENSSL $@"
+ $(Q)openssl rsa -in $< -pubout -outform DER 2>/dev/null |\
+ openssl dgst -sha256 -binary > $@ 2>/dev/null
+endif
+
# Build config flags
# ------------------
@@ -86,6 +123,21 @@
PLAT_WARP7_UART :=1
$(eval $(call add_define,PLAT_WARP7_UART))
+# Add the build options to pack BLx images and kernel device tree
+# in the FIP if the platform requires.
+ifneq ($(BL2),)
+$(eval $(call TOOL_ADD_PAYLOAD,${BUILD_PLAT}/tb_fw.crt,--tb-fw-cert))
+endif
+ifneq ($(BL32_EXTRA1),)
+$(eval $(call TOOL_ADD_IMG,BL32_EXTRA1,--tos-fw-extra1))
+endif
+ifneq ($(BL32_EXTRA2),)
+$(eval $(call TOOL_ADD_IMG,BL32_EXTRA2,--tos-fw-extra2))
+endif
+ifneq ($(HW_CONFIG),)
+$(eval $(call TOOL_ADD_IMG,HW_CONFIG,--hw-config))
+endif
+
# Verify build config
# -------------------
diff --git a/plat/imx/imx7/warp7/warp7_bl2_el3_setup.c b/plat/imx/imx7/warp7/warp7_bl2_el3_setup.c
index 032ed7b..08baf19 100644
--- a/plat/imx/imx7/warp7/warp7_bl2_el3_setup.c
+++ b/plat/imx/imx7/warp7/warp7_bl2_el3_setup.c
@@ -290,12 +290,13 @@
imx_wdog_init();
/* Print out the expected memory map */
- VERBOSE("\tOPTEE 0x%08x-0x%08x\n", WARP7_OPTEE_BASE, WARP7_OPTEE_LIMIT);
- VERBOSE("\tATF/BL2 0x%08x-0x%08x\n", BL2_RAM_BASE, BL2_RAM_LIMIT);
- VERBOSE("\tSHRAM 0x%08x-0x%08x\n", SHARED_RAM_BASE, SHARED_RAM_LIMIT);
- VERBOSE("\tFIP 0x%08x-0x%08x\n", WARP7_FIP_BASE, WARP7_FIP_LIMIT);
- VERBOSE("\tDTB 0x%08x-0x%08x\n", WARP7_DTB_BASE, WARP7_DTB_LIMIT);
- VERBOSE("\tUBOOT/BL33 0x%08x-0x%08x\n", WARP7_UBOOT_BASE, WARP7_UBOOT_LIMIT);
+ VERBOSE("\tOPTEE 0x%08x-0x%08x\n", WARP7_OPTEE_BASE, WARP7_OPTEE_LIMIT);
+ VERBOSE("\tATF/BL2 0x%08x-0x%08x\n", BL2_RAM_BASE, BL2_RAM_LIMIT);
+ VERBOSE("\tSHRAM 0x%08x-0x%08x\n", SHARED_RAM_BASE, SHARED_RAM_LIMIT);
+ VERBOSE("\tFIP 0x%08x-0x%08x\n", WARP7_FIP_BASE, WARP7_FIP_LIMIT);
+ VERBOSE("\tDTB-OVERLAY 0x%08x-0x%08x\n", WARP7_DTB_OVERLAY_BASE, WARP7_DTB_OVERLAY_LIMIT);
+ VERBOSE("\tDTB 0x%08x-0x%08x\n", WARP7_DTB_BASE, WARP7_DTB_LIMIT);
+ VERBOSE("\tUBOOT/BL33 0x%08x-0x%08x\n", WARP7_UBOOT_BASE, WARP7_UBOOT_LIMIT);
}
/*
diff --git a/plat/imx/imx7/warp7/warp7_bl2_mem_params_desc.c b/plat/imx/imx7/warp7/warp7_bl2_mem_params_desc.c
index a29e141..c670d42 100644
--- a/plat/imx/imx7/warp7/warp7_bl2_mem_params_desc.c
+++ b/plat/imx/imx7/warp7/warp7_bl2_mem_params_desc.c
@@ -28,16 +28,6 @@
.next_handoff_image_id = BL33_IMAGE_ID,
},
{
- .image_id = HW_CONFIG_ID,
- SET_STATIC_PARAM_HEAD(ep_info, PARAM_IMAGE_BINARY,
- VERSION_2, entry_point_info_t, SECURE | NON_EXECUTABLE),
- SET_STATIC_PARAM_HEAD(image_info, PARAM_IMAGE_BINARY,
- VERSION_2, image_info_t, 0),
- .image_info.image_base = WARP7_DTB_BASE,
- .image_info.image_max_size = WARP7_DTB_SIZE,
- .next_handoff_image_id = INVALID_IMAGE_ID,
- },
- {
.image_id = BL32_EXTRA1_IMAGE_ID,
SET_STATIC_PARAM_HEAD(ep_info, PARAM_EP, VERSION_2,
diff --git a/plat/imx/imx7/warp7/warp7_io_storage.c b/plat/imx/imx7/warp7/warp7_io_storage.c
index b9cace0..fcfb503 100644
--- a/plat/imx/imx7/warp7/warp7_io_storage.c
+++ b/plat/imx/imx7/warp7/warp7_io_storage.c
@@ -60,10 +60,6 @@
.uuid = UUID_SECURE_PAYLOAD_BL32,
};
-static const io_uuid_spec_t hw_config_uuid_spec = {
- .uuid = UUID_HW_CONFIG,
-};
-
static const io_uuid_spec_t bl32_extra1_uuid_spec = {
.uuid = UUID_SECURE_PAYLOAD_BL32_EXTRA1,
};
@@ -76,6 +72,32 @@
.uuid = UUID_NON_TRUSTED_FIRMWARE_BL33,
};
+#if TRUSTED_BOARD_BOOT
+static const io_uuid_spec_t tb_fw_cert_uuid_spec = {
+ .uuid = UUID_TRUSTED_BOOT_FW_CERT,
+};
+
+static const io_uuid_spec_t trusted_key_cert_uuid_spec = {
+ .uuid = UUID_TRUSTED_KEY_CERT,
+};
+
+static const io_uuid_spec_t tos_fw_key_cert_uuid_spec = {
+ .uuid = UUID_TRUSTED_OS_FW_KEY_CERT,
+};
+
+static const io_uuid_spec_t tos_fw_cert_uuid_spec = {
+ .uuid = UUID_TRUSTED_OS_FW_CONTENT_CERT,
+};
+
+static const io_uuid_spec_t nt_fw_key_cert_uuid_spec = {
+ .uuid = UUID_NON_TRUSTED_FW_KEY_CERT,
+};
+
+static const io_uuid_spec_t nt_fw_cert_uuid_spec = {
+ .uuid = UUID_NON_TRUSTED_FW_CONTENT_CERT,
+};
+#endif /* TRUSTED_BOARD_BOOT */
+
/* TODO: this structure is replicated multiple times. rationalize it ! */
struct plat_io_policy {
uintptr_t *dev_handle;
@@ -112,16 +134,43 @@
(uintptr_t)&bl32_extra2_uuid_spec,
open_fip
},
- [HW_CONFIG_ID] = {
- &fip_dev_handle,
- (uintptr_t)&hw_config_uuid_spec,
- open_fip
- },
[BL33_IMAGE_ID] = {
&fip_dev_handle,
(uintptr_t)&bl33_uuid_spec,
open_fip
- }
+ },
+#if TRUSTED_BOARD_BOOT
+ [TRUSTED_BOOT_FW_CERT_ID] = {
+ &fip_dev_handle,
+ (uintptr_t)&tb_fw_cert_uuid_spec,
+ open_fip
+ },
+ [TRUSTED_KEY_CERT_ID] = {
+ &fip_dev_handle,
+ (uintptr_t)&trusted_key_cert_uuid_spec,
+ open_fip
+ },
+ [TRUSTED_OS_FW_KEY_CERT_ID] = {
+ &fip_dev_handle,
+ (uintptr_t)&tos_fw_key_cert_uuid_spec,
+ open_fip
+ },
+ [NON_TRUSTED_FW_KEY_CERT_ID] = {
+ &fip_dev_handle,
+ (uintptr_t)&nt_fw_key_cert_uuid_spec,
+ open_fip
+ },
+ [TRUSTED_OS_FW_CONTENT_CERT_ID] = {
+ &fip_dev_handle,
+ (uintptr_t)&tos_fw_cert_uuid_spec,
+ open_fip
+ },
+ [NON_TRUSTED_FW_CONTENT_CERT_ID] = {
+ &fip_dev_handle,
+ (uintptr_t)&nt_fw_cert_uuid_spec,
+ open_fip
+ },
+#endif /* TRUSTED_BOARD_BOOT */
};
static int open_fip(const uintptr_t spec)
diff --git a/plat/imx/imx7/warp7/warp7_rotpk.S b/plat/imx/imx7/warp7/warp7_rotpk.S
new file mode 100644
index 0000000..f74b6d25b
--- /dev/null
+++ b/plat/imx/imx7/warp7/warp7_rotpk.S
@@ -0,0 +1,15 @@
+/*
+ * Copyright (c) 2018, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+ .global warp7_rotpk_hash
+ .global warp7_rotpk_hash_end
+warp7_rotpk_hash:
+ /* DER header */
+ .byte 0x30, 0x31, 0x30, 0x0D, 0x06, 0x09, 0x60, 0x86, 0x48
+ .byte 0x01, 0x65, 0x03, 0x04, 0x02, 0x01, 0x05, 0x00, 0x04, 0x20
+ /* SHA256 */
+ .incbin ROTPK_HASH
+warp7_rotpk_hash_end:
diff --git a/plat/imx/imx7/warp7/warp7_trusted_boot.c b/plat/imx/imx7/warp7/warp7_trusted_boot.c
new file mode 100644
index 0000000..8157cd5
--- /dev/null
+++ b/plat/imx/imx7/warp7/warp7_trusted_boot.c
@@ -0,0 +1,31 @@
+/*
+ * Copyright (c) 2018, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <plat/common/platform.h>
+
+extern char warp7_rotpk_hash[], warp7_rotpk_hash_end[];
+
+int plat_get_rotpk_info(void *cookie, void **key_ptr, unsigned int *key_len,
+ unsigned int *flags)
+{
+ *key_ptr = warp7_rotpk_hash;
+ *key_len = warp7_rotpk_hash_end - warp7_rotpk_hash;
+ *flags = ROTPK_IS_HASH;
+
+ return 0;
+}
+
+int plat_get_nv_ctr(void *cookie, unsigned int *nv_ctr)
+{
+ *nv_ctr = 0;
+
+ return 0;
+}
+
+int plat_set_nv_ctr(void *cookie, unsigned int nv_ctr)
+{
+ return 1;
+}
diff --git a/plat/imx/imx8m/imx8mq/platform.mk b/plat/imx/imx8m/imx8mq/platform.mk
index 0255268..2681e57 100644
--- a/plat/imx/imx8m/imx8mq/platform.mk
+++ b/plat/imx/imx8m/imx8mq/platform.mk
@@ -34,3 +34,7 @@
RESET_TO_BL31 := 1
A53_DISABLE_NON_TEMPORAL_HINT := 0
MULTI_CONSOLE_API := 1
+
+ERRATA_A53_835769 := 1
+ERRATA_A53_843419 := 1
+ERRATA_A53_855873 := 1
diff --git a/plat/imx/imx8qm/imx8qm_bl31_setup.c b/plat/imx/imx8qm/imx8qm_bl31_setup.c
index a00695c..c76de64 100644
--- a/plat/imx/imx8qm/imx8qm_bl31_setup.c
+++ b/plat/imx/imx8qm/imx8qm_bl31_setup.c
@@ -49,11 +49,7 @@
};
static const mmap_region_t imx_mmap[] = {
- MAP_REGION_FLAT(IMX_BOOT_UART_BASE, IMX_BOOT_UART_SIZE, MT_DEVICE | MT_RW),
- MAP_REGION_FLAT(SC_IPC_BASE, SC_IPC_SIZE, MT_DEVICE | MT_RW),
- MAP_REGION_FLAT(PLAT_GICD_BASE, PLAT_GICD_SIZE, MT_DEVICE | MT_RW),
- MAP_REGION_FLAT(PLAT_GICR_BASE, PLAT_GICR_SIZE, MT_DEVICE | MT_RW),
- MAP_REGION_FLAT(PLAT_CCI_BASE, PLAT_CCI_SIZE, MT_DEVICE | MT_RW),
+ MAP_REGION_FLAT(IMX_REG_BASE, IMX_REG_SIZE, MT_DEVICE | MT_RW),
{0}
};
@@ -324,6 +320,10 @@
/* turn on MU1 for non-secure OS/Hypervisor */
sc_pm_set_resource_power_mode(ipc_handle, SC_R_MU_1A, SC_PM_PW_MODE_ON);
+ /* Turn on GPT_0's power & clock for non-secure OS/Hypervisor */
+ sc_pm_set_resource_power_mode(ipc_handle, SC_R_GPT_0, SC_PM_PW_MODE_ON);
+ sc_pm_clock_enable(ipc_handle, SC_R_GPT_0, SC_PM_CLK_PER, true, 0);
+ mmio_write_32(IMX_GPT_LPCG_BASE, mmio_read_32(IMX_GPT_LPCG_BASE) | (1 << 25));
/*
* create new partition for non-secure OS/Hypervisor
diff --git a/plat/imx/imx8qm/imx8qm_psci.c b/plat/imx/imx8qm/imx8qm_psci.c
index 833048d..bdba37c 100644
--- a/plat/imx/imx8qm/imx8qm_psci.c
+++ b/plat/imx/imx8qm/imx8qm_psci.c
@@ -17,6 +17,8 @@
#include <plat_imx8.h>
#include <sci/sci.h>
+#include "../../common/sci/imx8_mu.h"
+
#define CORE_PWR_STATE(state) \
((state)->pwr_domain_state[MPIDR_AFFLVL0])
#define CLUSTER_PWR_STATE(state) \
@@ -29,44 +31,70 @@
SC_R_A53_3, SC_R_A72_0, SC_R_A72_1,
};
+/* save gic dist/redist context when GIC is poewr down */
+static struct plat_gic_ctx imx_gicv3_ctx;
+static unsigned int gpt_lpcg, gpt_reg[2];
+
+static void imx_enable_irqstr_wakeup(void)
+{
+ uint32_t irq_mask;
+ gicv3_dist_ctx_t *dist_ctx = &imx_gicv3_ctx.dist_ctx;
+
+ /* put IRQSTR into ON mode */
+ sc_pm_set_resource_power_mode(ipc_handle, SC_R_IRQSTR_SCU2, SC_PM_PW_MODE_ON);
+
+ /* enable the irqsteer to handle wakeup irq */
+ mmio_write_32(IMX_WUP_IRQSTR_BASE, 0x1);
+ for (int i = 0; i < 15; i++) {
+ irq_mask = dist_ctx->gicd_isenabler[i];
+ mmio_write_32(IMX_WUP_IRQSTR_BASE + 0x3c - 0x4 * i, irq_mask);
+ }
+
+ /* set IRQSTR low power mode */
+ if (imx_is_wakeup_src_irqsteer())
+ sc_pm_set_resource_power_mode(ipc_handle, SC_R_IRQSTR_SCU2, SC_PM_PW_MODE_STBY);
+ else
+ sc_pm_set_resource_power_mode(ipc_handle, SC_R_IRQSTR_SCU2, SC_PM_PW_MODE_OFF);
+}
+
+static void imx_disable_irqstr_wakeup(void)
+{
+ /* put IRQSTR into ON from STBY mode */
+ sc_pm_set_resource_power_mode(ipc_handle, SC_R_IRQSTR_SCU2, SC_PM_PW_MODE_ON);
+
+ /* disable the irqsteer */
+ mmio_write_32(IMX_WUP_IRQSTR_BASE, 0x0);
+ for (int i = 0; i < 16; i++)
+ mmio_write_32(IMX_WUP_IRQSTR_BASE + 0x4 + 0x4 * i, 0x0);
+
+ /* put IRQSTR into OFF mode */
+ sc_pm_set_resource_power_mode(ipc_handle, SC_R_IRQSTR_SCU2, SC_PM_PW_MODE_OFF);
+}
+
int imx_pwr_domain_on(u_register_t mpidr)
{
int ret = PSCI_E_SUCCESS;
- unsigned int cluster_id, cpu_id;
+ unsigned int cluster_id = MPIDR_AFFLVL1_VAL(mpidr);
+ unsigned int cpu_id = MPIDR_AFFLVL0_VAL(mpidr);
- cluster_id = MPIDR_AFFLVL1_VAL(mpidr);
- cpu_id = MPIDR_AFFLVL0_VAL(mpidr);
+ sc_pm_set_resource_power_mode(ipc_handle, cluster_id == 0 ?
+ SC_R_A53 : SC_R_A72, SC_PM_PW_MODE_ON);
- printf("imx_pwr_domain_on cluster_id %d, cpu_id %d\n", cluster_id, cpu_id);
+ if (cluster_id == 1)
+ sc_pm_req_low_power_mode(ipc_handle, SC_R_A72, SC_PM_PW_MODE_ON);
- if (cluster_id == 0) {
- sc_pm_set_resource_power_mode(ipc_handle, SC_R_A53,
- SC_PM_PW_MODE_ON);
- if (sc_pm_set_resource_power_mode(ipc_handle, ap_core_index[cpu_id],
- SC_PM_PW_MODE_ON) != SC_ERR_NONE) {
- ERROR("cluster0 core %d power on failed!\n", cpu_id);
- ret = PSCI_E_INTERN_FAIL;
- }
+ if (sc_pm_set_resource_power_mode(ipc_handle,
+ ap_core_index[cpu_id + PLATFORM_CLUSTER0_CORE_COUNT * cluster_id],
+ SC_PM_PW_MODE_ON) != SC_ERR_NONE) {
+ ERROR("core %d power on failed!\n", cpu_id + PLATFORM_CLUSTER0_CORE_COUNT * cluster_id);
+ ret = PSCI_E_INTERN_FAIL;
+ }
- if (sc_pm_cpu_start(ipc_handle, ap_core_index[cpu_id],
- true, BL31_BASE) != SC_ERR_NONE) {
- ERROR("boot cluster0 core %d failed!\n", cpu_id);
- ret = PSCI_E_INTERN_FAIL;
- }
- } else {
- sc_pm_set_resource_power_mode(ipc_handle, SC_R_A72,
- SC_PM_PW_MODE_ON);
- if (sc_pm_set_resource_power_mode(ipc_handle, ap_core_index[cpu_id + 4],
- SC_PM_PW_MODE_ON) != SC_ERR_NONE) {
- ERROR(" cluster1 core %d power on failed!\n", cpu_id);
- ret = PSCI_E_INTERN_FAIL;
- }
-
- if (sc_pm_cpu_start(ipc_handle, ap_core_index[cpu_id + 4],
- true, BL31_BASE) != SC_ERR_NONE) {
- ERROR("boot cluster1 core %d failed!\n", cpu_id);
- ret = PSCI_E_INTERN_FAIL;
- }
+ if (sc_pm_cpu_start(ipc_handle,
+ ap_core_index[cpu_id + PLATFORM_CLUSTER0_CORE_COUNT * cluster_id],
+ true, BL31_BASE) != SC_ERR_NONE) {
+ ERROR("boot core %d failed!\n", cpu_id + PLATFORM_CLUSTER0_CORE_COUNT * cluster_id);
+ ret = PSCI_E_INTERN_FAIL;
}
return ret;
@@ -91,11 +119,14 @@
plat_gic_cpuif_disable();
sc_pm_req_cpu_low_power_mode(ipc_handle,
- ap_core_index[cpu_id + cluster_id * 4],
- SC_PM_PW_MODE_OFF,
- SC_PM_WAKE_SRC_NONE);
- if (CLUSTER_PWR_STATE(target_state) == PLAT_MAX_OFF_STATE)
- cci_disable_snoop_dvm_reqs(MPIDR_AFFLVL1_VAL(mpidr));
+ ap_core_index[cpu_id + PLATFORM_CLUSTER0_CORE_COUNT * cluster_id],
+ SC_PM_PW_MODE_OFF, SC_PM_WAKE_SRC_NONE);
+
+ if (is_local_state_off(CLUSTER_PWR_STATE(target_state))) {
+ cci_disable_snoop_dvm_reqs(cluster_id);
+ if (cluster_id == 1)
+ sc_pm_req_low_power_mode(ipc_handle, SC_R_A72, SC_PM_PW_MODE_OFF);
+ }
printf("turn off cluster:%d core:%d\n", cluster_id, cpu_id);
}
@@ -105,24 +136,148 @@
unsigned int cluster_id = MPIDR_AFFLVL1_VAL(mpidr);
unsigned int cpu_id = MPIDR_AFFLVL0_VAL(mpidr);
- plat_gic_cpuif_disable();
+ if (is_local_state_off(CORE_PWR_STATE(target_state))) {
+ plat_gic_cpuif_disable();
+ sc_pm_set_cpu_resume(ipc_handle,
+ ap_core_index[cpu_id + PLATFORM_CLUSTER0_CORE_COUNT * cluster_id],
+ true, BL31_BASE);
+ sc_pm_req_cpu_low_power_mode(ipc_handle,
+ ap_core_index[cpu_id + PLATFORM_CLUSTER0_CORE_COUNT * cluster_id],
+ SC_PM_PW_MODE_OFF, SC_PM_WAKE_SRC_GIC);
+ } else {
+ dsb();
+ write_scr_el3(read_scr_el3() | SCR_FIQ_BIT);
+ isb();
+ }
- cci_disable_snoop_dvm_reqs(MPIDR_AFFLVL1_VAL(mpidr));
+ if (is_local_state_off(CLUSTER_PWR_STATE(target_state))) {
+ cci_disable_snoop_dvm_reqs(MPIDR_AFFLVL1_VAL(mpidr));
+ if (cluster_id == 1)
+ sc_pm_req_low_power_mode(ipc_handle, SC_R_A72, SC_PM_PW_MODE_OFF);
+ }
- sc_pm_set_cpu_resume_addr(ipc_handle,
- ap_core_index[cpu_id + cluster_id * 4], BL31_BASE);
- sc_pm_req_cpu_low_power_mode(ipc_handle,
- ap_core_index[cpu_id + cluster_id * 4],
- SC_PM_PW_MODE_OFF, SC_PM_WAKE_SRC_GIC);
+ if (is_local_state_retn(SYSTEM_PWR_STATE(target_state))) {
+ plat_gic_cpuif_disable();
+
+ /* save gic context */
+ plat_gic_save(cpu_id, &imx_gicv3_ctx);
+ /* enable the irqsteer for wakeup */
+ imx_enable_irqstr_wakeup();
+
+ cci_disable_snoop_dvm_reqs(MPIDR_AFFLVL1_VAL(mpidr));
+
+ /* Put GIC in LP mode. */
+ sc_pm_set_resource_power_mode(ipc_handle, SC_R_GIC, SC_PM_PW_MODE_OFF);
+ /* Save GPT clock and registers, then turn off its power */
+ gpt_lpcg = mmio_read_32(IMX_GPT_LPCG_BASE);
+ gpt_reg[0] = mmio_read_32(IMX_GPT_BASE);
+ gpt_reg[1] = mmio_read_32(IMX_GPT_BASE + 0x4);
+ sc_pm_set_resource_power_mode(ipc_handle, SC_R_GPT_0, SC_PM_PW_MODE_OFF);
+
+ sc_pm_req_low_power_mode(ipc_handle, SC_R_A53, SC_PM_PW_MODE_OFF);
+ sc_pm_req_low_power_mode(ipc_handle, SC_R_A72, SC_PM_PW_MODE_OFF);
+ sc_pm_req_low_power_mode(ipc_handle, SC_R_CCI, SC_PM_PW_MODE_OFF);
+
+ sc_pm_req_sys_if_power_mode(ipc_handle, SC_R_A53, SC_PM_SYS_IF_DDR,
+ SC_PM_PW_MODE_ON, SC_PM_PW_MODE_OFF);
+ sc_pm_req_sys_if_power_mode(ipc_handle, SC_R_A72, SC_PM_SYS_IF_DDR,
+ SC_PM_PW_MODE_ON, SC_PM_PW_MODE_OFF);
+ sc_pm_req_sys_if_power_mode(ipc_handle, SC_R_A53, SC_PM_SYS_IF_MU,
+ SC_PM_PW_MODE_ON, SC_PM_PW_MODE_OFF);
+ sc_pm_req_sys_if_power_mode(ipc_handle, SC_R_A72, SC_PM_SYS_IF_MU,
+ SC_PM_PW_MODE_ON, SC_PM_PW_MODE_OFF);
+ sc_pm_req_sys_if_power_mode(ipc_handle, SC_R_A53, SC_PM_SYS_IF_INTERCONNECT,
+ SC_PM_PW_MODE_ON, SC_PM_PW_MODE_OFF);
+ sc_pm_req_sys_if_power_mode(ipc_handle, SC_R_A72, SC_PM_SYS_IF_INTERCONNECT,
+ SC_PM_PW_MODE_ON, SC_PM_PW_MODE_OFF);
+ sc_pm_req_low_power_mode(ipc_handle, SC_R_CCI, SC_PM_PW_MODE_OFF);
+
+ sc_pm_set_cpu_resume(ipc_handle,
+ ap_core_index[cpu_id + PLATFORM_CLUSTER0_CORE_COUNT * cluster_id],
+ true, BL31_BASE);
+ if (imx_is_wakeup_src_irqsteer())
+ sc_pm_req_cpu_low_power_mode(ipc_handle,
+ ap_core_index[cpu_id + PLATFORM_CLUSTER0_CORE_COUNT * cluster_id],
+ SC_PM_PW_MODE_OFF, SC_PM_WAKE_SRC_IRQSTEER);
+ else
+ sc_pm_req_cpu_low_power_mode(ipc_handle,
+ ap_core_index[cpu_id + PLATFORM_CLUSTER0_CORE_COUNT * cluster_id],
+ SC_PM_PW_MODE_OFF, SC_PM_WAKE_SRC_SCU);
+ }
}
void imx_domain_suspend_finish(const psci_power_state_t *target_state)
{
u_register_t mpidr = read_mpidr_el1();
+ unsigned int cluster_id = MPIDR_AFFLVL1_VAL(mpidr);
+ unsigned int cpu_id = MPIDR_AFFLVL0_VAL(mpidr);
- cci_enable_snoop_dvm_reqs(MPIDR_AFFLVL1_VAL(mpidr));
+ /* check the system level status */
+ if (is_local_state_retn(SYSTEM_PWR_STATE(target_state))) {
+ MU_Resume(SC_IPC_BASE);
- plat_gic_cpuif_enable();
+ sc_pm_req_cpu_low_power_mode(ipc_handle,
+ ap_core_index[cpu_id + PLATFORM_CLUSTER0_CORE_COUNT * cluster_id],
+ SC_PM_PW_MODE_ON, SC_PM_WAKE_SRC_GIC);
+
+ /* Put GIC/IRQSTR back to high power mode. */
+ sc_pm_set_resource_power_mode(ipc_handle, SC_R_GIC, SC_PM_PW_MODE_ON);
+
+ /* Turn GPT power and restore its clock and registers */
+ sc_pm_set_resource_power_mode(ipc_handle, SC_R_GPT_0, SC_PM_PW_MODE_ON);
+ sc_pm_clock_enable(ipc_handle, SC_R_GPT_0, SC_PM_CLK_PER, true, 0);
+ mmio_write_32(IMX_GPT_BASE, gpt_reg[0]);
+ mmio_write_32(IMX_GPT_BASE + 0x4, gpt_reg[1]);
+ mmio_write_32(IMX_GPT_LPCG_BASE, gpt_lpcg);
+
+ sc_pm_req_low_power_mode(ipc_handle, SC_R_A53, SC_PM_PW_MODE_ON);
+ sc_pm_req_low_power_mode(ipc_handle, SC_R_A72, SC_PM_PW_MODE_ON);
+ sc_pm_req_low_power_mode(ipc_handle, SC_R_CCI, SC_PM_PW_MODE_ON);
+
+ sc_pm_req_sys_if_power_mode(ipc_handle, SC_R_A53, SC_PM_SYS_IF_DDR,
+ SC_PM_PW_MODE_ON, SC_PM_PW_MODE_ON);
+ sc_pm_req_sys_if_power_mode(ipc_handle, SC_R_A72, SC_PM_SYS_IF_DDR,
+ SC_PM_PW_MODE_ON, SC_PM_PW_MODE_ON);
+ sc_pm_req_sys_if_power_mode(ipc_handle, SC_R_A53, SC_PM_SYS_IF_MU,
+ SC_PM_PW_MODE_ON, SC_PM_PW_MODE_ON);
+ sc_pm_req_sys_if_power_mode(ipc_handle, SC_R_A72, SC_PM_SYS_IF_MU,
+ SC_PM_PW_MODE_ON, SC_PM_PW_MODE_ON);
+ sc_pm_req_sys_if_power_mode(ipc_handle, SC_R_A53, SC_PM_SYS_IF_INTERCONNECT,
+ SC_PM_PW_MODE_ON, SC_PM_PW_MODE_ON);
+ sc_pm_req_sys_if_power_mode(ipc_handle, SC_R_A72, SC_PM_SYS_IF_INTERCONNECT,
+ SC_PM_PW_MODE_ON, SC_PM_PW_MODE_ON);
+ sc_pm_req_low_power_mode(ipc_handle, SC_R_CCI, SC_PM_PW_MODE_ON);
+
+ cci_enable_snoop_dvm_reqs(MPIDR_AFFLVL1_VAL(mpidr));
+
+ /* restore gic context */
+ plat_gic_restore(cpu_id, &imx_gicv3_ctx);
+ /* disable the irqsteer wakeup */
+ imx_disable_irqstr_wakeup();
+
+ plat_gic_cpuif_enable();
+ }
+
+ /* check the cluster level power status */
+ if (is_local_state_off(CLUSTER_PWR_STATE(target_state))) {
+ cci_enable_snoop_dvm_reqs(MPIDR_AFFLVL1_VAL(mpidr));
+ if (cluster_id == 1)
+ sc_pm_req_low_power_mode(ipc_handle, SC_R_A72, SC_PM_PW_MODE_ON);
+ }
+
+ /* check the core level power status */
+ if (is_local_state_off(CORE_PWR_STATE(target_state))) {
+ sc_pm_set_cpu_resume(ipc_handle,
+ ap_core_index[cpu_id + PLATFORM_CLUSTER0_CORE_COUNT * cluster_id],
+ false, BL31_BASE);
+ sc_pm_req_cpu_low_power_mode(ipc_handle,
+ ap_core_index[cpu_id + PLATFORM_CLUSTER0_CORE_COUNT * cluster_id],
+ SC_PM_PW_MODE_ON, SC_PM_WAKE_SRC_GIC);
+ plat_gic_cpuif_enable();
+ } else {
+ write_scr_el3(read_scr_el3() & (~SCR_FIQ_BIT));
+ isb();
+ }
}
int imx_validate_ns_entrypoint(uintptr_t ns_entrypoint)
@@ -149,26 +304,23 @@
imx_mailbox_init(sec_entrypoint);
*psci_ops = &imx_plat_psci_ops;
- /* Request low power mode for cluster/cci, only need to do once */
- sc_pm_req_low_power_mode(ipc_handle, SC_R_A72, SC_PM_PW_MODE_OFF);
- sc_pm_req_low_power_mode(ipc_handle, SC_R_A53, SC_PM_PW_MODE_OFF);
- sc_pm_req_low_power_mode(ipc_handle, SC_R_CCI, SC_PM_PW_MODE_OFF);
+ /* make sure system sources power ON in low power mode by default */
+ sc_pm_req_low_power_mode(ipc_handle, SC_R_A53, SC_PM_PW_MODE_ON);
+ sc_pm_req_low_power_mode(ipc_handle, SC_R_A72, SC_PM_PW_MODE_ON);
+ sc_pm_req_low_power_mode(ipc_handle, SC_R_CCI, SC_PM_PW_MODE_ON);
- /* Request RUN and LP modes for DDR, system interconnect etc. */
- sc_pm_req_sys_if_power_mode(ipc_handle, SC_R_A53,
- SC_PM_SYS_IF_DDR, SC_PM_PW_MODE_ON, SC_PM_PW_MODE_STBY);
- sc_pm_req_sys_if_power_mode(ipc_handle, SC_R_A72,
- SC_PM_SYS_IF_DDR, SC_PM_PW_MODE_ON, SC_PM_PW_MODE_STBY);
- sc_pm_req_sys_if_power_mode(ipc_handle, SC_R_A53,
- SC_PM_SYS_IF_MU, SC_PM_PW_MODE_ON, SC_PM_PW_MODE_STBY);
- sc_pm_req_sys_if_power_mode(ipc_handle, SC_R_A72,
- SC_PM_SYS_IF_MU, SC_PM_PW_MODE_ON, SC_PM_PW_MODE_STBY);
- sc_pm_req_sys_if_power_mode(ipc_handle, SC_R_A53,
- SC_PM_SYS_IF_INTERCONNECT, SC_PM_PW_MODE_ON,
- SC_PM_PW_MODE_STBY);
- sc_pm_req_sys_if_power_mode(ipc_handle, SC_R_A72,
- SC_PM_SYS_IF_INTERCONNECT, SC_PM_PW_MODE_ON,
- SC_PM_PW_MODE_STBY);
+ sc_pm_req_sys_if_power_mode(ipc_handle, SC_R_A53, SC_PM_SYS_IF_DDR,
+ SC_PM_PW_MODE_ON, SC_PM_PW_MODE_ON);
+ sc_pm_req_sys_if_power_mode(ipc_handle, SC_R_A72, SC_PM_SYS_IF_DDR,
+ SC_PM_PW_MODE_ON, SC_PM_PW_MODE_ON);
+ sc_pm_req_sys_if_power_mode(ipc_handle, SC_R_A53, SC_PM_SYS_IF_MU,
+ SC_PM_PW_MODE_ON, SC_PM_PW_MODE_ON);
+ sc_pm_req_sys_if_power_mode(ipc_handle, SC_R_A72, SC_PM_SYS_IF_MU,
+ SC_PM_PW_MODE_ON, SC_PM_PW_MODE_ON);
+ sc_pm_req_sys_if_power_mode(ipc_handle, SC_R_A53, SC_PM_SYS_IF_INTERCONNECT,
+ SC_PM_PW_MODE_ON, SC_PM_PW_MODE_ON);
+ sc_pm_req_sys_if_power_mode(ipc_handle, SC_R_A72, SC_PM_SYS_IF_INTERCONNECT,
+ SC_PM_PW_MODE_ON, SC_PM_PW_MODE_ON);
return 0;
}
diff --git a/plat/imx/imx8qm/include/platform_def.h b/plat/imx/imx8qm/include/platform_def.h
index 1d0bdf9..946be76 100644
--- a/plat/imx/imx8qm/include/platform_def.h
+++ b/plat/imx/imx8qm/include/platform_def.h
@@ -36,22 +36,22 @@
#define BL31_LIMIT 0x80020000
#define PLAT_GICD_BASE 0x51a00000
-#define PLAT_GICD_SIZE 0x10000
#define PLAT_GICR_BASE 0x51b00000
-#define PLAT_GICR_SIZE 0xc0000
#define PLAT_CCI_BASE 0x52090000
-#define PLAT_CCI_SIZE 0x10000
#define CLUSTER0_CCI_SLVAE_IFACE 3
#define CLUSTER1_CCI_SLVAE_IFACE 4
#define IMX_BOOT_UART_BASE 0x5a060000
-#define IMX_BOOT_UART_SIZE 0x1000
#define IMX_BOOT_UART_BAUDRATE 115200
#define IMX_BOOT_UART_CLK_IN_HZ 24000000
#define PLAT_CRASH_UART_BASE IMX_BOOT_UART_BASE
#define PLAT__CRASH_UART_CLK_IN_HZ 24000000
#define IMX_CONSOLE_BAUDRATE 115200
#define SC_IPC_BASE 0x5d1b0000
-#define SC_IPC_SIZE 0x10000
+#define IMX_GPT_LPCG_BASE 0x5d540000
+#define IMX_GPT_BASE 0x5d140000
+#define IMX_WUP_IRQSTR_BASE 0x51090000
+#define IMX_REG_BASE 0x50000000
+#define IMX_REG_SIZE 0x10000000
#define COUNTER_FREQUENCY 8000000 /* 8MHz */
diff --git a/plat/imx/imx8qm/include/sec_rsrc.h b/plat/imx/imx8qm/include/sec_rsrc.h
index a623cd3..d16d051 100644
--- a/plat/imx/imx8qm/include/sec_rsrc.h
+++ b/plat/imx/imx8qm/include/sec_rsrc.h
@@ -19,12 +19,14 @@
SC_R_GIC_SMMU,
SC_R_CCI,
SC_R_SYSTEM,
- SC_R_IRQSTR_SCU2
+ SC_R_IRQSTR_SCU2,
+ SC_R_GPT_0
};
/* resources that have register access for non-secure domain */
sc_rsrc_t ns_access_allowed[] = {
SC_R_GIC,
SC_R_GIC_SMMU,
- SC_R_CCI
+ SC_R_CCI,
+ SC_R_GPT_0
};
diff --git a/plat/imx/imx8qm/platform.mk b/plat/imx/imx8qm/platform.mk
index 9113d33..ed6108d 100644
--- a/plat/imx/imx8qm/platform.mk
+++ b/plat/imx/imx8qm/platform.mk
@@ -38,3 +38,7 @@
A53_DISABLE_NON_TEMPORAL_HINT := 0
MULTI_CONSOLE_API := 1
ERRATA_A72_859971 := 1
+
+ERRATA_A53_835769 := 1
+ERRATA_A53_843419 := 1
+ERRATA_A53_855873 := 1
diff --git a/plat/imx/imx8qx/imx8qx_bl31_setup.c b/plat/imx/imx8qx/imx8qx_bl31_setup.c
index c90794a..bfe4052 100644
--- a/plat/imx/imx8qx/imx8qx_bl31_setup.c
+++ b/plat/imx/imx8qx/imx8qx_bl31_setup.c
@@ -44,10 +44,7 @@
(SC_PAD_28FDSOI_PS_PD << PADRING_PULL_SHIFT))
static const mmap_region_t imx_mmap[] = {
- MAP_REGION_FLAT(IMX_BOOT_UART_BASE, IMX_BOOT_UART_SIZE, MT_DEVICE | MT_RW),
- MAP_REGION_FLAT(SC_IPC_BASE, SC_IPC_SIZE, MT_DEVICE | MT_RW),
- MAP_REGION_FLAT(PLAT_GICD_BASE, PLAT_GICD_SIZE, MT_DEVICE | MT_RW),
- MAP_REGION_FLAT(PLAT_GICR_BASE, PLAT_GICR_SIZE, MT_DEVICE | MT_RW),
+ MAP_REGION_FLAT(IMX_REG_BASE, IMX_REG_SIZE, MT_DEVICE | MT_RW),
{0}
};
@@ -281,6 +278,11 @@
/* Turn on MU1 for non-secure OS/Hypervisor */
sc_pm_set_resource_power_mode(ipc_handle, SC_R_MU_1A, SC_PM_PW_MODE_ON);
+ /* Turn on GPT_0's power & clock for non-secure OS/Hypervisor */
+ sc_pm_set_resource_power_mode(ipc_handle, SC_R_GPT_0, SC_PM_PW_MODE_ON);
+ sc_pm_clock_enable(ipc_handle, SC_R_GPT_0, SC_PM_CLK_PER, true, 0);
+ mmio_write_32(IMX_GPT0_LPCG_BASE, mmio_read_32(IMX_GPT0_LPCG_BASE) | (1 << 25));
+
/*
* create new partition for non-secure OS/Hypervisor
* uses global structs defined in sec_rsrc.h
diff --git a/plat/imx/imx8qx/imx8qx_psci.c b/plat/imx/imx8qx/imx8qx_psci.c
index 94c2e2b..aab3a2d 100644
--- a/plat/imx/imx8qx/imx8qx_psci.c
+++ b/plat/imx/imx8qx/imx8qx_psci.c
@@ -16,10 +16,52 @@
#include <plat_imx8.h>
#include <sci/sci.h>
+#include "../../common/sci/imx8_mu.h"
+
const static int ap_core_index[PLATFORM_CORE_COUNT] = {
SC_R_A35_0, SC_R_A35_1, SC_R_A35_2, SC_R_A35_3
};
+/* save gic dist/redist context when GIC is power down */
+static struct plat_gic_ctx imx_gicv3_ctx;
+static unsigned int gpt_lpcg, gpt_reg[2];
+
+static void imx_enable_irqstr_wakeup(void)
+{
+ uint32_t irq_mask;
+ gicv3_dist_ctx_t *dist_ctx = &imx_gicv3_ctx.dist_ctx;
+
+ /* put IRQSTR into ON mode */
+ sc_pm_set_resource_power_mode(ipc_handle, SC_R_IRQSTR_SCU2, SC_PM_PW_MODE_ON);
+
+ /* enable the irqsteer to handle wakeup irq */
+ mmio_write_32(IMX_WUP_IRQSTR_BASE, 0x1);
+ for (int i = 0; i < 15; i++) {
+ irq_mask = dist_ctx->gicd_isenabler[i];
+ mmio_write_32(IMX_WUP_IRQSTR_BASE + 0x3c - 0x4 * i, irq_mask);
+ }
+
+ /* set IRQSTR low power mode */
+ if (imx_is_wakeup_src_irqsteer())
+ sc_pm_set_resource_power_mode(ipc_handle, SC_R_IRQSTR_SCU2, SC_PM_PW_MODE_STBY);
+ else
+ sc_pm_set_resource_power_mode(ipc_handle, SC_R_IRQSTR_SCU2, SC_PM_PW_MODE_OFF);
+}
+
+static void imx_disable_irqstr_wakeup(void)
+{
+ /* Put IRQSTEER back to ON mode */
+ sc_pm_set_resource_power_mode(ipc_handle, SC_R_IRQSTR_SCU2, SC_PM_PW_MODE_ON);
+
+ /* disable the irqsteer */
+ mmio_write_32(IMX_WUP_IRQSTR_BASE, 0x0);
+ for (int i = 0; i < 16; i++)
+ mmio_write_32(IMX_WUP_IRQSTR_BASE + 0x4 + 0x4 * i, 0x0);
+
+ /* Put IRQSTEER into OFF mode */
+ sc_pm_set_resource_power_mode(ipc_handle, SC_R_IRQSTR_SCU2, SC_PM_PW_MODE_OFF);
+}
+
int imx_pwr_domain_on(u_register_t mpidr)
{
int ret = PSCI_E_SUCCESS;
@@ -71,11 +113,52 @@
u_register_t mpidr = read_mpidr_el1();
unsigned int cpu_id = MPIDR_AFFLVL0_VAL(mpidr);
- plat_gic_cpuif_disable();
+ if (is_local_state_off(target_state->pwr_domain_state[MPIDR_AFFLVL0])) {
+ plat_gic_cpuif_disable();
+ sc_pm_set_cpu_resume(ipc_handle, ap_core_index[cpu_id], true, BL31_BASE);
+ sc_pm_req_cpu_low_power_mode(ipc_handle, ap_core_index[cpu_id],
+ SC_PM_PW_MODE_OFF, SC_PM_WAKE_SRC_GIC);
+ } else {
+ dsb();
+ write_scr_el3(read_scr_el3() | SCR_FIQ_BIT);
+ isb();
+ }
- sc_pm_set_cpu_resume_addr(ipc_handle, ap_core_index[cpu_id], BL31_BASE);
- sc_pm_req_cpu_low_power_mode(ipc_handle, ap_core_index[cpu_id],
- SC_PM_PW_MODE_OFF, SC_PM_WAKE_SRC_GIC);
+ if (is_local_state_off(target_state->pwr_domain_state[MPIDR_AFFLVL1]))
+ sc_pm_req_low_power_mode(ipc_handle, SC_R_A35, SC_PM_PW_MODE_OFF);
+
+ if (is_local_state_retn(target_state->pwr_domain_state[PLAT_MAX_PWR_LVL])) {
+ plat_gic_cpuif_disable();
+
+ /* save gic context */
+ plat_gic_save(cpu_id, &imx_gicv3_ctx);
+ /* enable the irqsteer for wakeup */
+ imx_enable_irqstr_wakeup();
+
+ /* Save GPT clock and registers, then turn off its power */
+ gpt_lpcg = mmio_read_32(IMX_GPT0_LPCG_BASE);
+ gpt_reg[0] = mmio_read_32(IMX_GPT0_BASE);
+ gpt_reg[1] = mmio_read_32(IMX_GPT0_BASE + 0x4);
+ sc_pm_set_resource_power_mode(ipc_handle, SC_R_GPT_0, SC_PM_PW_MODE_OFF);
+
+ sc_pm_req_low_power_mode(ipc_handle, SC_R_A35, SC_PM_PW_MODE_OFF);
+ sc_pm_req_sys_if_power_mode(ipc_handle, SC_R_A35, SC_PM_SYS_IF_DDR,
+ SC_PM_PW_MODE_ON, SC_PM_PW_MODE_OFF);
+ sc_pm_req_sys_if_power_mode(ipc_handle, SC_R_A35, SC_PM_SYS_IF_MU,
+ SC_PM_PW_MODE_ON, SC_PM_PW_MODE_OFF);
+ sc_pm_req_sys_if_power_mode(ipc_handle, SC_R_A35, SC_PM_SYS_IF_INTERCONNECT,
+ SC_PM_PW_MODE_ON, SC_PM_PW_MODE_OFF);
+
+ /* Put GIC in OFF mode. */
+ sc_pm_set_resource_power_mode(ipc_handle, SC_R_GIC, SC_PM_PW_MODE_OFF);
+ sc_pm_set_cpu_resume(ipc_handle, ap_core_index[cpu_id], true, BL31_BASE);
+ if (imx_is_wakeup_src_irqsteer())
+ sc_pm_req_cpu_low_power_mode(ipc_handle, ap_core_index[cpu_id],
+ SC_PM_PW_MODE_OFF, SC_PM_WAKE_SRC_IRQSTEER);
+ else
+ sc_pm_req_cpu_low_power_mode(ipc_handle, ap_core_index[cpu_id],
+ SC_PM_PW_MODE_OFF, SC_PM_WAKE_SRC_SCU);
+ }
}
void imx_domain_suspend_finish(const psci_power_state_t *target_state)
@@ -83,10 +166,51 @@
u_register_t mpidr = read_mpidr_el1();
unsigned int cpu_id = MPIDR_AFFLVL0_VAL(mpidr);
- sc_pm_req_low_power_mode(ipc_handle, ap_core_index[cpu_id],
- SC_PM_PW_MODE_ON);
+ if (is_local_state_retn(target_state->pwr_domain_state[PLAT_MAX_PWR_LVL])) {
+ MU_Resume(SC_IPC_BASE);
- plat_gic_cpuif_enable();
+ sc_pm_req_low_power_mode(ipc_handle, ap_core_index[cpu_id], SC_PM_PW_MODE_ON);
+ sc_pm_req_cpu_low_power_mode(ipc_handle, ap_core_index[cpu_id],
+ SC_PM_PW_MODE_ON, SC_PM_WAKE_SRC_GIC);
+
+ /* Put GIC back to high power mode. */
+ sc_pm_set_resource_power_mode(ipc_handle, SC_R_GIC, SC_PM_PW_MODE_ON);
+
+ /* restore gic context */
+ plat_gic_restore(cpu_id, &imx_gicv3_ctx);
+
+ /* Turn on GPT power and restore its clock and registers */
+ sc_pm_set_resource_power_mode(ipc_handle, SC_R_GPT_0, SC_PM_PW_MODE_ON);
+ sc_pm_clock_enable(ipc_handle, SC_R_GPT_0, SC_PM_CLK_PER, true, 0);
+ mmio_write_32(IMX_GPT0_BASE, gpt_reg[0]);
+ mmio_write_32(IMX_GPT0_BASE + 0x4, gpt_reg[1]);
+ mmio_write_32(IMX_GPT0_LPCG_BASE, gpt_lpcg);
+
+ sc_pm_req_low_power_mode(ipc_handle, SC_R_A35, SC_PM_PW_MODE_ON);
+ sc_pm_req_sys_if_power_mode(ipc_handle, SC_R_A35, SC_PM_SYS_IF_DDR,
+ SC_PM_PW_MODE_ON, SC_PM_PW_MODE_ON);
+ sc_pm_req_sys_if_power_mode(ipc_handle, SC_R_A35, SC_PM_SYS_IF_MU,
+ SC_PM_PW_MODE_ON, SC_PM_PW_MODE_ON);
+ sc_pm_req_sys_if_power_mode(ipc_handle, SC_R_A35, SC_PM_SYS_IF_INTERCONNECT,
+ SC_PM_PW_MODE_ON, SC_PM_PW_MODE_ON);
+
+ /* disable the irqsteer wakeup */
+ imx_disable_irqstr_wakeup();
+
+ plat_gic_cpuif_enable();
+ }
+
+ if (is_local_state_off(target_state->pwr_domain_state[MPIDR_AFFLVL1]))
+ sc_pm_req_low_power_mode(ipc_handle, SC_R_A35, SC_PM_PW_MODE_ON);
+
+ if (is_local_state_off(target_state->pwr_domain_state[MPIDR_AFFLVL0])) {
+ sc_pm_req_cpu_low_power_mode(ipc_handle, ap_core_index[cpu_id],
+ SC_PM_PW_MODE_ON, SC_PM_WAKE_SRC_GIC);
+ plat_gic_cpuif_enable();
+ } else {
+ write_scr_el3(read_scr_el3() & (~SCR_FIQ_BIT));
+ isb();
+ }
}
static const plat_psci_ops_t imx_plat_psci_ops = {
@@ -108,17 +232,15 @@
imx_mailbox_init(sec_entrypoint);
*psci_ops = &imx_plat_psci_ops;
- /* Request low power mode for A35 cluster, only need to do once */
- sc_pm_req_low_power_mode(ipc_handle, SC_R_A35, SC_PM_PW_MODE_OFF);
+ /* make sure system sources power ON in low power mode by default */
+ sc_pm_req_low_power_mode(ipc_handle, SC_R_A35, SC_PM_PW_MODE_ON);
- /* Request RUN and LP modes for DDR, system interconnect etc. */
- sc_pm_req_sys_if_power_mode(ipc_handle, SC_R_A35,
- SC_PM_SYS_IF_DDR, SC_PM_PW_MODE_ON, SC_PM_PW_MODE_STBY);
- sc_pm_req_sys_if_power_mode(ipc_handle, SC_R_A35,
- SC_PM_SYS_IF_MU, SC_PM_PW_MODE_ON, SC_PM_PW_MODE_STBY);
- sc_pm_req_sys_if_power_mode(ipc_handle, SC_R_A35,
- SC_PM_SYS_IF_INTERCONNECT, SC_PM_PW_MODE_ON,
- SC_PM_PW_MODE_STBY);
+ sc_pm_req_sys_if_power_mode(ipc_handle, SC_R_A35, SC_PM_SYS_IF_DDR,
+ SC_PM_PW_MODE_ON, SC_PM_PW_MODE_ON);
+ sc_pm_req_sys_if_power_mode(ipc_handle, SC_R_A35, SC_PM_SYS_IF_MU,
+ SC_PM_PW_MODE_ON, SC_PM_PW_MODE_ON);
+ sc_pm_req_sys_if_power_mode(ipc_handle, SC_R_A35, SC_PM_SYS_IF_INTERCONNECT,
+ SC_PM_PW_MODE_ON, SC_PM_PW_MODE_ON);
return 0;
}
diff --git a/plat/imx/imx8qx/include/platform_def.h b/plat/imx/imx8qx/include/platform_def.h
index 1239340..3a3fac8 100644
--- a/plat/imx/imx8qx/include/platform_def.h
+++ b/plat/imx/imx8qx/include/platform_def.h
@@ -37,18 +37,19 @@
#define MAX_MMAP_REGIONS 8
#define PLAT_GICD_BASE 0x51a00000
-#define PLAT_GICD_SIZE 0x10000
#define PLAT_GICR_BASE 0x51b00000
-#define PLAT_GICR_SIZE 0xc0000
#define IMX_BOOT_UART_BASE 0x5a060000
-#define IMX_BOOT_UART_SIZE 0x1000
#define IMX_BOOT_UART_BAUDRATE 115200
#define IMX_BOOT_UART_CLK_IN_HZ 24000000
#define PLAT_CRASH_UART_BASE IMX_BOOT_UART_BASE
#define PLAT__CRASH_UART_CLK_IN_HZ 24000000
#define IMX_CONSOLE_BAUDRATE 115200
#define SC_IPC_BASE 0x5d1b0000
-#define SC_IPC_SIZE 0x10000
+#define IMX_GPT0_LPCG_BASE 0x5d540000
+#define IMX_GPT0_BASE 0x5d140000
+#define IMX_WUP_IRQSTR_BASE 0x51090000
+#define IMX_REG_BASE 0x50000000
+#define IMX_REG_SIZE 0x10000000
#define COUNTER_FREQUENCY 8000000
diff --git a/plat/imx/imx8qx/include/sec_rsrc.h b/plat/imx/imx8qx/include/sec_rsrc.h
index 37c9f66..b7fe0e8 100644
--- a/plat/imx/imx8qx/include/sec_rsrc.h
+++ b/plat/imx/imx8qx/include/sec_rsrc.h
@@ -14,10 +14,12 @@
SC_R_A35_3,
SC_R_GIC,
SC_R_SYSTEM,
- SC_R_IRQSTR_SCU2
+ SC_R_IRQSTR_SCU2,
+ SC_R_GPT_0
};
/* resources that have register access for non-secure domain */
sc_rsrc_t ns_access_allowed[] = {
SC_R_GIC,
+ SC_R_GPT_0
};
diff --git a/plat/marvell/a8k/common/include/a8k_plat_def.h b/plat/marvell/a8k/common/include/a8k_plat_def.h
index 7ed56e0..8b7cd64 100644
--- a/plat/marvell/a8k/common/include/a8k_plat_def.h
+++ b/plat/marvell/a8k/common/include/a8k_plat_def.h
@@ -53,12 +53,12 @@
0x440000 + ((n / 8) << 2))
#define MVEBU_CP_GPIO_DATA_OUT(cp_index, n) \
(MVEBU_CP_REGS_BASE(cp_index) + \
- 0x440100 + ((n > 32) ? 0x40 : 0x00))
+ 0x440100 + ((n > 31) ? 0x40 : 0x00))
#define MVEBU_CP_GPIO_DATA_OUT_EN(cp_index, n) \
(MVEBU_CP_REGS_BASE(cp_index) + \
- 0x440104 + ((n > 32) ? 0x40 : 0x00))
+ 0x440104 + ((n > 31) ? 0x40 : 0x00))
#define MVEBU_CP_GPIO_DATA_IN(cp_index, n) (MVEBU_CP_REGS_BASE(cp_index) + \
- 0x440110 + ((n > 32) ? 0x40 : 0x00))
+ 0x440110 + ((n > 31) ? 0x40 : 0x00))
#define MVEBU_AP_MPP_REGS(n) (MVEBU_RFU_BASE + 0x4000 + ((n) << 2))
#define MVEBU_AP_GPIO_REGS (MVEBU_RFU_BASE + 0x5040)
#define MVEBU_AP_GPIO_DATA_IN (MVEBU_AP_GPIO_REGS + 0x10)
diff --git a/plat/mediatek/mt8173/bl31_plat_setup.c b/plat/mediatek/mt8173/bl31_plat_setup.c
index bd384a1..dd23e63 100644
--- a/plat/mediatek/mt8173/bl31_plat_setup.c
+++ b/plat/mediatek/mt8173/bl31_plat_setup.c
@@ -11,13 +11,13 @@
#include <drivers/console.h>
#include <drivers/generic_delay_timer.h>
#include <lib/mmio.h>
+#include <plat/arm/common/plat_arm.h>
#include <plat/common/common_def.h>
#include <plat/common/platform.h>
#include <mcucfg.h>
#include <mtcmos.h>
#include <mtk_plat_common.h>
-#include <plat_arm.h>
#include <plat_private.h>
#include <spm.h>
diff --git a/plat/mediatek/mt8173/plat_pm.c b/plat/mediatek/mt8173/plat_pm.c
index 9673d2c..1b52470 100644
--- a/plat/mediatek/mt8173/plat_pm.c
+++ b/plat/mediatek/mt8173/plat_pm.c
@@ -15,11 +15,11 @@
#include <lib/bakery_lock.h>
#include <lib/mmio.h>
#include <lib/psci/psci.h>
+#include <plat/arm/common/plat_arm.h>
#include <mcucfg.h>
#include <mt8173_def.h>
#include <mt_cpuxgpt.h> /* generic_timer_backup() */
-#include <plat_arm.h>
#include <plat_private.h>
#include <power_tracer.h>
#include <rtc.h>
diff --git a/plat/mediatek/mt8173/platform.mk b/plat/mediatek/mt8173/platform.mk
index 294aea4..0726efe 100644
--- a/plat/mediatek/mt8173/platform.mk
+++ b/plat/mediatek/mt8173/platform.mk
@@ -9,7 +9,6 @@
PLAT_INCLUDES := -I${MTK_PLAT}/common/ \
-I${MTK_PLAT}/common/drivers/uart/ \
- -Iinclude/plat/arm/common \
-Iinclude/plat/arm/common/aarch64 \
-I${MTK_PLAT_SOC}/drivers/crypt/ \
-I${MTK_PLAT_SOC}/drivers/mtcmos/ \
diff --git a/plat/nvidia/tegra/common/aarch64/tegra_helpers.S b/plat/nvidia/tegra/common/aarch64/tegra_helpers.S
index 2bf9a22..b47be6d 100644
--- a/plat/nvidia/tegra/common/aarch64/tegra_helpers.S
+++ b/plat/nvidia/tegra/common/aarch64/tegra_helpers.S
@@ -18,16 +18,21 @@
/*******************************************************************************
* Implementation defined ACTLR_EL3 bit definitions
******************************************************************************/
-#define ACTLR_EL3_L2ACTLR_BIT (1 << 6)
-#define ACTLR_EL3_L2ECTLR_BIT (1 << 5)
-#define ACTLR_EL3_L2CTLR_BIT (1 << 4)
-#define ACTLR_EL3_CPUECTLR_BIT (1 << 1)
-#define ACTLR_EL3_CPUACTLR_BIT (1 << 0)
+#define ACTLR_EL3_L2ACTLR_BIT (U(1) << 6)
+#define ACTLR_EL3_L2ECTLR_BIT (U(1) << 5)
+#define ACTLR_EL3_L2CTLR_BIT (U(1) << 4)
+#define ACTLR_EL3_CPUECTLR_BIT (U(1) << 1)
+#define ACTLR_EL3_CPUACTLR_BIT (U(1) << 0)
+#define ACTLR_EL3_ENABLE_ALL_MASK (ACTLR_EL3_L2ACTLR_BIT | \
+ ACTLR_EL3_L2ECTLR_BIT | \
+ ACTLR_EL3_L2CTLR_BIT | \
+ ACTLR_EL3_CPUECTLR_BIT | \
+ ACTLR_EL3_CPUACTLR_BIT)
#define ACTLR_EL3_ENABLE_ALL_ACCESS (ACTLR_EL3_L2ACTLR_BIT | \
- ACTLR_EL3_L2ECTLR_BIT | \
- ACTLR_EL3_L2CTLR_BIT | \
- ACTLR_EL3_CPUECTLR_BIT | \
- ACTLR_EL3_CPUACTLR_BIT)
+ ACTLR_EL3_L2ECTLR_BIT | \
+ ACTLR_EL3_L2CTLR_BIT | \
+ ACTLR_EL3_CPUECTLR_BIT | \
+ ACTLR_EL3_CPUACTLR_BIT)
/* Global functions */
.globl plat_is_my_cpu_primary
@@ -87,8 +92,17 @@
* Enable L2 and CPU ECTLR RW access from non-secure world
* -------------------------------------------------------
*/
- mov x0, #ACTLR_EL3_ENABLE_ALL_ACCESS
+ mrs x0, actlr_el3
+ mov x1, #ACTLR_EL3_ENABLE_ALL_MASK
+ bic x0, x0, x1
+ mov x1, #ACTLR_EL3_ENABLE_ALL_ACCESS
+ orr x0, x0, x1
msr actlr_el3, x0
+ mrs x0, actlr_el2
+ mov x1, #ACTLR_EL3_ENABLE_ALL_MASK
+ bic x0, x0, x1
+ mov x1, #ACTLR_EL3_ENABLE_ALL_ACCESS
+ orr x0, x0, x1
msr actlr_el2, x0
isb
@@ -130,17 +144,20 @@
ret
endfunc plat_is_my_cpu_primary
- /* -----------------------------------------------------
+ /* ----------------------------------------------------------
* unsigned int plat_my_core_pos(void);
*
- * result: CorePos = CoreId + (ClusterId << 2)
- * -----------------------------------------------------
+ * result: CorePos = CoreId + (ClusterId * cpus per cluster)
+ * ----------------------------------------------------------
*/
func plat_my_core_pos
mrs x0, mpidr_el1
and x1, x0, #MPIDR_CPU_MASK
and x0, x0, #MPIDR_CLUSTER_MASK
- add x0, x1, x0, LSR #6
+ lsr x0, x0, #MPIDR_AFFINITY_BITS
+ mov x2, #PLATFORM_MAX_CPUS_PER_CLUSTER
+ mul x0, x0, x2
+ add x0, x1, x0
ret
endfunc plat_my_core_pos
@@ -162,14 +179,17 @@
/* -----------------------------------------------------
* int platform_get_core_pos(int mpidr);
*
- * With this function: CorePos = (ClusterId * 4) +
- * CoreId
+ * result: CorePos = (ClusterId * cpus per cluster) +
+ * CoreId
* -----------------------------------------------------
*/
func platform_get_core_pos
and x1, x0, #MPIDR_CPU_MASK
and x0, x0, #MPIDR_CLUSTER_MASK
- add x0, x1, x0, LSR #6
+ lsr x0, x0, #MPIDR_AFFINITY_BITS
+ mov x2, #PLATFORM_MAX_CPUS_PER_CLUSTER
+ mul x0, x0, x2
+ add x0, x1, x0
ret
endfunc platform_get_core_pos
@@ -400,31 +420,6 @@
mov x0, #1
msr oslar_el1, x0
- cpu_init_common
-
- /* ---------------------------------------------------------------------
- * The initial state of the Architectural feature trap register
- * (CPTR_EL3) is unknown and it must be set to a known state. All
- * feature traps are disabled. Some bits in this register are marked as
- * Reserved and should not be modified.
- *
- * CPTR_EL3.TCPAC: This causes a direct access to the CPACR_EL1 from EL1
- * or the CPTR_EL2 from EL2 to trap to EL3 unless it is trapped at EL2.
- * CPTR_EL3.TTA: This causes access to the Trace functionality to trap
- * to EL3 when executed from EL0, EL1, EL2, or EL3. If system register
- * access to trace functionality is not supported, this bit is RES0.
- * CPTR_EL3.TFP: This causes instructions that access the registers
- * associated with Floating Point and Advanced SIMD execution to trap
- * to EL3 when executed from any exception level, unless trapped to EL1
- * or EL2.
- * ---------------------------------------------------------------------
- */
- mrs x1, cptr_el3
- bic w1, w1, #TCPAC_BIT
- bic w1, w1, #TTA_BIT
- bic w1, w1, #TFP_BIT
- msr cptr_el3, x1
-
/* --------------------------------------------------
* Get secure world's entry point and jump to it
* --------------------------------------------------
diff --git a/plat/nvidia/tegra/common/drivers/bpmp/bpmp.c b/plat/nvidia/tegra/common/drivers/bpmp/bpmp.c
index 96e3667..1c5d2e1 100644
--- a/plat/nvidia/tegra/common/drivers/bpmp/bpmp.c
+++ b/plat/nvidia/tegra/common/drivers/bpmp/bpmp.c
@@ -16,7 +16,7 @@
#include <string.h>
#include <tegra_def.h>
-#define BPMP_TIMEOUT_10US 10
+#define BPMP_TIMEOUT 2
static uint32_t channel_base[NR_CHANNELS];
static uint32_t bpmp_init_state = BPMP_INIT_PENDING;
@@ -58,15 +58,15 @@
if (bpmp_init_state == BPMP_INIT_COMPLETE) {
/* loop until BPMP is free */
- for (timeout = 0; timeout < BPMP_TIMEOUT_10US; timeout++) {
+ for (timeout = 0; timeout < BPMP_TIMEOUT; timeout++) {
if (master_free(ch) == true) {
break;
}
- udelay(1);
+ mdelay(1);
}
- if (timeout != BPMP_TIMEOUT_10US) {
+ if (timeout != BPMP_TIMEOUT) {
/* generate the command struct */
p->code = mrq;
@@ -76,18 +76,18 @@
/* signal command ready to the BPMP */
signal_slave(ch);
mmio_write_32(TEGRA_PRI_ICTLR_BASE + CPU_IEP_FIR_SET,
- (1UL << INT_SHR_SEM_OUTBOX_FULL));
+ (1U << INT_SHR_SEM_OUTBOX_FULL));
/* loop until the command is executed */
- for (timeout = 0; timeout < BPMP_TIMEOUT_10US; timeout++) {
+ for (timeout = 0; timeout < BPMP_TIMEOUT; timeout++) {
if (master_acked(ch) == true) {
break;
}
- udelay(1);
+ mdelay(1);
}
- if (timeout != BPMP_TIMEOUT_10US) {
+ if (timeout != BPMP_TIMEOUT) {
/* get the command response */
(void)memcpy(ib_data, (const void *)p->data,
@@ -106,8 +106,8 @@
ret = -EINVAL;
}
- if (timeout == BPMP_TIMEOUT_10US) {
- ERROR("Timed out waiting for bpmp's response");
+ if (timeout == BPMP_TIMEOUT) {
+ ERROR("Timed out waiting for bpmp's response\n");
}
return ret;
@@ -125,7 +125,7 @@
val = mmio_read_32(TEGRA_RES_SEMA_BASE + STA_OFFSET);
if (val != SIGN_OF_LIFE) {
ERROR("BPMP precessor not available\n");
- ret = -ENOTSUP;
+ return -ENOTSUP;
}
/* check if clock for the atomics block is enabled */
@@ -154,12 +154,11 @@
channel_base[ch] = mmio_read_32(base);
/* increment result register offset */
- base += 4UL;
+ base += 4U;
}
/* mark state as "initialized" */
- if (ret == 0)
- bpmp_init_state = BPMP_INIT_COMPLETE;
+ bpmp_init_state = BPMP_INIT_COMPLETE;
/* the channel values have to be visible across all cpus */
flush_dcache_range((uint64_t)channel_base, sizeof(channel_base));
diff --git a/plat/nvidia/tegra/common/drivers/bpmp_ipc/intf.c b/plat/nvidia/tegra/common/drivers/bpmp_ipc/intf.c
new file mode 100644
index 0000000..7faa2f0
--- /dev/null
+++ b/plat/nvidia/tegra/common/drivers/bpmp_ipc/intf.c
@@ -0,0 +1,304 @@
+/*
+ * Copyright (c) 2017, NVIDIA CORPORATION. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <assert.h>
+#include <bpmp_ipc.h>
+#include <debug.h>
+#include <delay_timer.h>
+#include <errno.h>
+#include <mmio.h>
+#include <stdbool.h>
+#include <string.h>
+#include <tegra_def.h>
+#include <utils_def.h>
+
+#include "intf.h"
+#include "ivc.h"
+
+/**
+ * Holds IVC channel data
+ */
+struct ccplex_bpmp_channel_data {
+ /* Buffer for incoming data */
+ struct frame_data *ib;
+
+ /* Buffer for outgoing data */
+ struct frame_data *ob;
+};
+
+static struct ccplex_bpmp_channel_data s_channel;
+static struct ivc ivc_ccplex_bpmp_channel;
+
+/*
+ * Helper functions to access the HSP doorbell registers
+ */
+static inline uint32_t hsp_db_read(uint32_t reg)
+{
+ return mmio_read_32((uint32_t)(TEGRA_HSP_DBELL_BASE + reg));
+}
+
+static inline void hsp_db_write(uint32_t reg, uint32_t val)
+{
+ mmio_write_32((uint32_t)(TEGRA_HSP_DBELL_BASE + reg), val);
+}
+
+/*******************************************************************************
+ * IVC wrappers for CCPLEX <-> BPMP communication.
+ ******************************************************************************/
+
+static void tegra_bpmp_ring_bpmp_doorbell(void);
+
+/*
+ * Get the next frame where data can be written.
+ */
+static struct frame_data *tegra_bpmp_get_next_out_frame(void)
+{
+ struct frame_data *frame;
+ const struct ivc *ch = &ivc_ccplex_bpmp_channel;
+
+ frame = (struct frame_data *)tegra_ivc_write_get_next_frame(ch);
+ if (frame == NULL) {
+ ERROR("%s: Error in getting next frame, exiting\n", __func__);
+ } else {
+ s_channel.ob = frame;
+ }
+
+ return frame;
+}
+
+static void tegra_bpmp_signal_slave(void)
+{
+ (void)tegra_ivc_write_advance(&ivc_ccplex_bpmp_channel);
+ tegra_bpmp_ring_bpmp_doorbell();
+}
+
+static int32_t tegra_bpmp_free_master(void)
+{
+ return tegra_ivc_read_advance(&ivc_ccplex_bpmp_channel);
+}
+
+static bool tegra_bpmp_slave_acked(void)
+{
+ struct frame_data *frame;
+ bool ret = true;
+
+ frame = (struct frame_data *)tegra_ivc_read_get_next_frame(&ivc_ccplex_bpmp_channel);
+ if (frame == NULL) {
+ ret = false;
+ } else {
+ s_channel.ib = frame;
+ }
+
+ return ret;
+}
+
+static struct frame_data *tegra_bpmp_get_cur_in_frame(void)
+{
+ return s_channel.ib;
+}
+
+/*
+ * Enables BPMP to ring CCPlex doorbell
+ */
+static void tegra_bpmp_enable_ccplex_doorbell(void)
+{
+ uint32_t reg;
+
+ reg = hsp_db_read(HSP_DBELL_1_ENABLE);
+ reg |= HSP_MASTER_BPMP_BIT;
+ hsp_db_write(HSP_DBELL_1_ENABLE, reg);
+}
+
+/*
+ * CCPlex rings the BPMP doorbell
+ */
+static void tegra_bpmp_ring_bpmp_doorbell(void)
+{
+ /*
+ * Any writes to this register has the same effect,
+ * uses master ID of the write transaction and set
+ * corresponding flag.
+ */
+ hsp_db_write(HSP_DBELL_3_TRIGGER, HSP_MASTER_CCPLEX_BIT);
+}
+
+/*
+ * Returns true if CCPLex can ring BPMP doorbell, otherwise false.
+ * This also signals that BPMP is up and ready.
+ */
+static bool tegra_bpmp_can_ccplex_ring_doorbell(void)
+{
+ uint32_t reg;
+
+ /* check if ccplex can communicate with bpmp */
+ reg = hsp_db_read(HSP_DBELL_3_ENABLE);
+
+ return ((reg & HSP_MASTER_CCPLEX_BIT) != 0U);
+}
+
+static int32_t tegra_bpmp_wait_for_slave_ack(void)
+{
+ uint32_t timeout = TIMEOUT_RESPONSE_FROM_BPMP_US;
+
+ while (!tegra_bpmp_slave_acked() && (timeout != 0U)) {
+ udelay(1);
+ timeout--;
+ };
+
+ return ((timeout == 0U) ? -ETIMEDOUT : 0);
+}
+
+/*
+ * Notification from the ivc layer
+ */
+static void tegra_bpmp_ivc_notify(const struct ivc *ivc)
+{
+ (void)(ivc);
+
+ tegra_bpmp_ring_bpmp_doorbell();
+}
+
+/*
+ * Atomic send/receive API, which means it waits until slave acks
+ */
+static int32_t tegra_bpmp_ipc_send_req_atomic(uint32_t mrq, void *p_out,
+ uint32_t size_out, void *p_in, uint32_t size_in)
+{
+ struct frame_data *frame = tegra_bpmp_get_next_out_frame();
+ const struct frame_data *f_in = NULL;
+ int32_t ret = 0;
+ void *p_fdata;
+
+ if ((p_out == NULL) || (size_out > IVC_DATA_SZ_BYTES) ||
+ (frame == NULL)) {
+ ERROR("%s: invalid parameters, exiting\n", __func__);
+ ret = -EINVAL;
+ }
+
+ if (ret == 0) {
+
+ /* prepare the command frame */
+ frame->mrq = mrq;
+ frame->flags = FLAG_DO_ACK;
+ p_fdata = frame->data;
+ (void)memcpy(p_fdata, p_out, (size_t)size_out);
+
+ /* signal the slave */
+ tegra_bpmp_signal_slave();
+
+ /* wait for slave to ack */
+ ret = tegra_bpmp_wait_for_slave_ack();
+ if (ret != 0) {
+ ERROR("failed waiting for the slave to ack\n");
+ }
+
+ /* retrieve the response frame */
+ if ((size_in <= IVC_DATA_SZ_BYTES) && (p_in != NULL) &&
+ (ret == 0)) {
+
+ f_in = tegra_bpmp_get_cur_in_frame();
+ if (f_in != NULL) {
+ ERROR("Failed to get next input frame!\n");
+ } else {
+ (void)memcpy(p_in, p_fdata, (size_t)size_in);
+ }
+ }
+
+ if (ret == 0) {
+ ret = tegra_bpmp_free_master();
+ if (ret != 0) {
+ ERROR("Failed to free master\n");
+ }
+ }
+ }
+
+ return ret;
+}
+
+/*
+ * Initializes the BPMP<--->CCPlex communication path.
+ */
+int32_t tegra_bpmp_ipc_init(void)
+{
+ size_t msg_size;
+ uint32_t frame_size, timeout;
+ int32_t error = 0;
+
+ /* allow bpmp to ring CCPLEX's doorbell */
+ tegra_bpmp_enable_ccplex_doorbell();
+
+ /* wait for BPMP to actually ring the doorbell */
+ timeout = TIMEOUT_RESPONSE_FROM_BPMP_US;
+ while ((timeout != 0U) && !tegra_bpmp_can_ccplex_ring_doorbell()) {
+ udelay(1); /* bpmp turn-around time */
+ timeout--;
+ }
+
+ if (timeout == 0U) {
+ ERROR("%s: BPMP firmware is not ready\n", __func__);
+ return -ENOTSUP;
+ }
+
+ INFO("%s: BPMP handshake completed\n", __func__);
+
+ msg_size = tegra_ivc_align(IVC_CMD_SZ_BYTES);
+ frame_size = (uint32_t)tegra_ivc_total_queue_size(msg_size);
+ if (frame_size > TEGRA_BPMP_IPC_CH_MAP_SIZE) {
+ ERROR("%s: carveout size is not sufficient\n", __func__);
+ return -EINVAL;
+ }
+
+ error = tegra_ivc_init(&ivc_ccplex_bpmp_channel,
+ (uint32_t)TEGRA_BPMP_IPC_RX_PHYS_BASE,
+ (uint32_t)TEGRA_BPMP_IPC_TX_PHYS_BASE,
+ 1U, frame_size, tegra_bpmp_ivc_notify);
+ if (error != 0) {
+
+ ERROR("%s: IVC init failed (%d)\n", __func__, error);
+
+ } else {
+
+ /* reset channel */
+ tegra_ivc_channel_reset(&ivc_ccplex_bpmp_channel);
+
+ /* wait for notification from BPMP */
+ while (tegra_ivc_channel_notified(&ivc_ccplex_bpmp_channel) != 0) {
+ /*
+ * Interrupt BPMP with doorbell each time after
+ * tegra_ivc_channel_notified() returns non zero
+ * value.
+ */
+ tegra_bpmp_ring_bpmp_doorbell();
+ }
+
+ INFO("%s: All communication channels initialized\n", __func__);
+ }
+
+ return error;
+}
+
+/* Handler to reset a hardware module */
+int32_t tegra_bpmp_ipc_reset_module(uint32_t rst_id)
+{
+ int32_t ret;
+ struct mrq_reset_request req = {
+ .cmd = (uint32_t)CMD_RESET_MODULE,
+ .reset_id = rst_id
+ };
+
+ /* only GPCDMA/XUSB_PADCTL resets are supported */
+ assert((rst_id == TEGRA_RESET_ID_XUSB_PADCTL) ||
+ (rst_id == TEGRA_RESET_ID_GPCDMA));
+
+ ret = tegra_bpmp_ipc_send_req_atomic(MRQ_RESET, &req,
+ (uint32_t)sizeof(req), NULL, 0);
+ if (ret != 0) {
+ ERROR("%s: failed for module %d with error %d\n", __func__,
+ rst_id, ret);
+ }
+
+ return ret;
+}
diff --git a/plat/nvidia/tegra/common/drivers/bpmp_ipc/intf.h b/plat/nvidia/tegra/common/drivers/bpmp_ipc/intf.h
new file mode 100644
index 0000000..689f8bb
--- /dev/null
+++ b/plat/nvidia/tegra/common/drivers/bpmp_ipc/intf.h
@@ -0,0 +1,74 @@
+/*
+ * Copyright (c) 2017, NVIDIA CORPORATION. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef INTF_H
+#define INTF_H
+
+/**
+ * Flags used in IPC req
+ */
+#define FLAG_DO_ACK (U(1) << 0)
+#define FLAG_RING_DOORBELL (U(1) << 1)
+
+/* Bit 1 is designated for CCPlex in secure world */
+#define HSP_MASTER_CCPLEX_BIT (U(1) << 1)
+/* Bit 19 is designated for BPMP in non-secure world */
+#define HSP_MASTER_BPMP_BIT (U(1) << 19)
+/* Timeout to receive response from BPMP is 1 sec */
+#define TIMEOUT_RESPONSE_FROM_BPMP_US U(1000000) /* in microseconds */
+
+/**
+ * IVC protocol defines and command/response frame
+ */
+
+/**
+ * IVC specific defines
+ */
+#define IVC_CMD_SZ_BYTES U(128)
+#define IVC_DATA_SZ_BYTES U(120)
+
+/**
+ * Holds frame data for an IPC request
+ */
+struct frame_data {
+ /* Identification as to what kind of data is being transmitted */
+ uint32_t mrq;
+
+ /* Flags for slave as to how to respond back */
+ uint32_t flags;
+
+ /* Actual data being sent */
+ uint8_t data[IVC_DATA_SZ_BYTES];
+};
+
+/**
+ * Commands send to the BPMP firmware
+ */
+
+/**
+ * MRQ code to issue a module reset command to BPMP
+ */
+#define MRQ_RESET U(20)
+
+/**
+ * Reset sub-commands
+ */
+#define CMD_RESET_ASSERT U(1)
+#define CMD_RESET_DEASSERT U(2)
+#define CMD_RESET_MODULE U(3)
+
+/**
+ * Used by the sender of an #MRQ_RESET message to request BPMP to
+ * assert or deassert a given reset line.
+ */
+struct __attribute__((packed)) mrq_reset_request {
+ /* reset action to perform (mrq_reset_commands) */
+ uint32_t cmd;
+ /* id of the reset to affected */
+ uint32_t reset_id;
+};
+
+#endif /* INTF_H */
diff --git a/plat/nvidia/tegra/common/drivers/bpmp_ipc/ivc.c b/plat/nvidia/tegra/common/drivers/bpmp_ipc/ivc.c
new file mode 100644
index 0000000..4212eca
--- /dev/null
+++ b/plat/nvidia/tegra/common/drivers/bpmp_ipc/ivc.c
@@ -0,0 +1,653 @@
+/*
+ * Copyright (c) 2017, NVIDIA CORPORATION. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <arch_helpers.h>
+#include <assert.h>
+#include <debug.h>
+#include <errno.h>
+#include <stddef.h>
+#include <string.h>
+
+#include "ivc.h"
+
+/*
+ * IVC channel reset protocol.
+ *
+ * Each end uses its tx_channel.state to indicate its synchronization state.
+ */
+enum {
+ /*
+ * This value is zero for backwards compatibility with services that
+ * assume channels to be initially zeroed. Such channels are in an
+ * initially valid state, but cannot be asynchronously reset, and must
+ * maintain a valid state at all times.
+ *
+ * The transmitting end can enter the established state from the sync or
+ * ack state when it observes the receiving endpoint in the ack or
+ * established state, indicating that has cleared the counters in our
+ * rx_channel.
+ */
+ ivc_state_established = U(0),
+
+ /*
+ * If an endpoint is observed in the sync state, the remote endpoint is
+ * allowed to clear the counters it owns asynchronously with respect to
+ * the current endpoint. Therefore, the current endpoint is no longer
+ * allowed to communicate.
+ */
+ ivc_state_sync = U(1),
+
+ /*
+ * When the transmitting end observes the receiving end in the sync
+ * state, it can clear the w_count and r_count and transition to the ack
+ * state. If the remote endpoint observes us in the ack state, it can
+ * return to the established state once it has cleared its counters.
+ */
+ ivc_state_ack = U(2)
+};
+
+/*
+ * This structure is divided into two-cache aligned parts, the first is only
+ * written through the tx_channel pointer, while the second is only written
+ * through the rx_channel pointer. This delineates ownership of the cache lines,
+ * which is critical to performance and necessary in non-cache coherent
+ * implementations.
+ */
+struct ivc_channel_header {
+ struct {
+ /* fields owned by the transmitting end */
+ uint32_t w_count;
+ uint32_t state;
+ uint32_t w_rsvd[IVC_CHHDR_TX_FIELDS - 2];
+ };
+ struct {
+ /* fields owned by the receiving end */
+ uint32_t r_count;
+ uint32_t r_rsvd[IVC_CHHDR_RX_FIELDS - 1];
+ };
+};
+
+static inline bool ivc_channel_empty(const struct ivc *ivc,
+ volatile const struct ivc_channel_header *ch)
+{
+ /*
+ * This function performs multiple checks on the same values with
+ * security implications, so sample the counters' current values in
+ * shared memory to ensure that these checks use the same values.
+ */
+ uint32_t wr_count = ch->w_count;
+ uint32_t rd_count = ch->r_count;
+ bool ret = false;
+
+ (void)ivc;
+
+ /*
+ * Perform an over-full check to prevent denial of service attacks where
+ * a server could be easily fooled into believing that there's an
+ * extremely large number of frames ready, since receivers are not
+ * expected to check for full or over-full conditions.
+ *
+ * Although the channel isn't empty, this is an invalid case caused by
+ * a potentially malicious peer, so returning empty is safer, because it
+ * gives the impression that the channel has gone silent.
+ */
+ if (((wr_count - rd_count) > ivc->nframes) || (wr_count == rd_count)) {
+ ret = true;
+ }
+
+ return ret;
+}
+
+static inline bool ivc_channel_full(const struct ivc *ivc,
+ volatile const struct ivc_channel_header *ch)
+{
+ uint32_t wr_count = ch->w_count;
+ uint32_t rd_count = ch->r_count;
+
+ (void)ivc;
+
+ /*
+ * Invalid cases where the counters indicate that the queue is over
+ * capacity also appear full.
+ */
+ return ((wr_count - rd_count) >= ivc->nframes);
+}
+
+static inline uint32_t ivc_channel_avail_count(const struct ivc *ivc,
+ volatile const struct ivc_channel_header *ch)
+{
+ uint32_t wr_count = ch->w_count;
+ uint32_t rd_count = ch->r_count;
+
+ (void)ivc;
+
+ /*
+ * This function isn't expected to be used in scenarios where an
+ * over-full situation can lead to denial of service attacks. See the
+ * comment in ivc_channel_empty() for an explanation about special
+ * over-full considerations.
+ */
+ return (wr_count - rd_count);
+}
+
+static inline void ivc_advance_tx(struct ivc *ivc)
+{
+ ivc->tx_channel->w_count++;
+
+ if (ivc->w_pos == (ivc->nframes - (uint32_t)1U)) {
+ ivc->w_pos = 0U;
+ } else {
+ ivc->w_pos++;
+ }
+}
+
+static inline void ivc_advance_rx(struct ivc *ivc)
+{
+ ivc->rx_channel->r_count++;
+
+ if (ivc->r_pos == (ivc->nframes - (uint32_t)1U)) {
+ ivc->r_pos = 0U;
+ } else {
+ ivc->r_pos++;
+ }
+}
+
+static inline int32_t ivc_check_read(const struct ivc *ivc)
+{
+ /*
+ * tx_channel->state is set locally, so it is not synchronized with
+ * state from the remote peer. The remote peer cannot reset its
+ * transmit counters until we've acknowledged its synchronization
+ * request, so no additional synchronization is required because an
+ * asynchronous transition of rx_channel->state to ivc_state_ack is not
+ * allowed.
+ */
+ if (ivc->tx_channel->state != ivc_state_established) {
+ return -ECONNRESET;
+ }
+
+ /*
+ * Avoid unnecessary invalidations when performing repeated accesses to
+ * an IVC channel by checking the old queue pointers first.
+ * Synchronization is only necessary when these pointers indicate empty
+ * or full.
+ */
+ if (!ivc_channel_empty(ivc, ivc->rx_channel)) {
+ return 0;
+ }
+
+ return ivc_channel_empty(ivc, ivc->rx_channel) ? -ENOMEM : 0;
+}
+
+static inline int32_t ivc_check_write(const struct ivc *ivc)
+{
+ if (ivc->tx_channel->state != ivc_state_established) {
+ return -ECONNRESET;
+ }
+
+ if (!ivc_channel_full(ivc, ivc->tx_channel)) {
+ return 0;
+ }
+
+ return ivc_channel_full(ivc, ivc->tx_channel) ? -ENOMEM : 0;
+}
+
+bool tegra_ivc_can_read(const struct ivc *ivc)
+{
+ return ivc_check_read(ivc) == 0;
+}
+
+bool tegra_ivc_can_write(const struct ivc *ivc)
+{
+ return ivc_check_write(ivc) == 0;
+}
+
+bool tegra_ivc_tx_empty(const struct ivc *ivc)
+{
+ return ivc_channel_empty(ivc, ivc->tx_channel);
+}
+
+static inline uintptr_t calc_frame_offset(uint32_t frame_index,
+ uint32_t frame_size, uint32_t frame_offset)
+{
+ return ((uintptr_t)frame_index * (uintptr_t)frame_size) +
+ (uintptr_t)frame_offset;
+}
+
+static void *ivc_frame_pointer(const struct ivc *ivc,
+ volatile const struct ivc_channel_header *ch,
+ uint32_t frame)
+{
+ assert(frame < ivc->nframes);
+ return (void *)((uintptr_t)(&ch[1]) +
+ calc_frame_offset(frame, ivc->frame_size, 0));
+}
+
+int32_t tegra_ivc_read(struct ivc *ivc, void *buf, size_t max_read)
+{
+ const void *src;
+ int32_t result;
+
+ if (buf == NULL) {
+ return -EINVAL;
+ }
+
+ if (max_read > ivc->frame_size) {
+ return -E2BIG;
+ }
+
+ result = ivc_check_read(ivc);
+ if (result != 0) {
+ return result;
+ }
+
+ /*
+ * Order observation of w_pos potentially indicating new data before
+ * data read.
+ */
+ dmbish();
+
+ src = ivc_frame_pointer(ivc, ivc->rx_channel, ivc->r_pos);
+
+ (void)memcpy(buf, src, max_read);
+
+ ivc_advance_rx(ivc);
+
+ /*
+ * Ensure our write to r_pos occurs before our read from w_pos.
+ */
+ dmbish();
+
+ /*
+ * Notify only upon transition from full to non-full.
+ * The available count can only asynchronously increase, so the
+ * worst possible side-effect will be a spurious notification.
+ */
+ if (ivc_channel_avail_count(ivc, ivc->rx_channel) == (ivc->nframes - (uint32_t)1U)) {
+ ivc->notify(ivc);
+ }
+
+ return (int32_t)max_read;
+}
+
+/* directly peek at the next frame rx'ed */
+void *tegra_ivc_read_get_next_frame(const struct ivc *ivc)
+{
+ if (ivc_check_read(ivc) != 0) {
+ return NULL;
+ }
+
+ /*
+ * Order observation of w_pos potentially indicating new data before
+ * data read.
+ */
+ dmbld();
+
+ return ivc_frame_pointer(ivc, ivc->rx_channel, ivc->r_pos);
+}
+
+int32_t tegra_ivc_read_advance(struct ivc *ivc)
+{
+ /*
+ * No read barriers or synchronization here: the caller is expected to
+ * have already observed the channel non-empty. This check is just to
+ * catch programming errors.
+ */
+ int32_t result = ivc_check_read(ivc);
+ if (result != 0) {
+ return result;
+ }
+
+ ivc_advance_rx(ivc);
+
+ /*
+ * Ensure our write to r_pos occurs before our read from w_pos.
+ */
+ dmbish();
+
+ /*
+ * Notify only upon transition from full to non-full.
+ * The available count can only asynchronously increase, so the
+ * worst possible side-effect will be a spurious notification.
+ */
+ if (ivc_channel_avail_count(ivc, ivc->rx_channel) == (ivc->nframes - (uint32_t)1U)) {
+ ivc->notify(ivc);
+ }
+
+ return 0;
+}
+
+int32_t tegra_ivc_write(struct ivc *ivc, const void *buf, size_t size)
+{
+ void *p;
+ int32_t result;
+
+ if ((buf == NULL) || (ivc == NULL)) {
+ return -EINVAL;
+ }
+
+ if (size > ivc->frame_size) {
+ return -E2BIG;
+ }
+
+ result = ivc_check_write(ivc);
+ if (result != 0) {
+ return result;
+ }
+
+ p = ivc_frame_pointer(ivc, ivc->tx_channel, ivc->w_pos);
+
+ (void)memset(p, 0, ivc->frame_size);
+ (void)memcpy(p, buf, size);
+
+ /*
+ * Ensure that updated data is visible before the w_pos counter
+ * indicates that it is ready.
+ */
+ dmbst();
+
+ ivc_advance_tx(ivc);
+
+ /*
+ * Ensure our write to w_pos occurs before our read from r_pos.
+ */
+ dmbish();
+
+ /*
+ * Notify only upon transition from empty to non-empty.
+ * The available count can only asynchronously decrease, so the
+ * worst possible side-effect will be a spurious notification.
+ */
+ if (ivc_channel_avail_count(ivc, ivc->tx_channel) == 1U) {
+ ivc->notify(ivc);
+ }
+
+ return (int32_t)size;
+}
+
+/* directly poke at the next frame to be tx'ed */
+void *tegra_ivc_write_get_next_frame(const struct ivc *ivc)
+{
+ if (ivc_check_write(ivc) != 0) {
+ return NULL;
+ }
+
+ return ivc_frame_pointer(ivc, ivc->tx_channel, ivc->w_pos);
+}
+
+/* advance the tx buffer */
+int32_t tegra_ivc_write_advance(struct ivc *ivc)
+{
+ int32_t result = ivc_check_write(ivc);
+
+ if (result != 0) {
+ return result;
+ }
+
+ /*
+ * Order any possible stores to the frame before update of w_pos.
+ */
+ dmbst();
+
+ ivc_advance_tx(ivc);
+
+ /*
+ * Ensure our write to w_pos occurs before our read from r_pos.
+ */
+ dmbish();
+
+ /*
+ * Notify only upon transition from empty to non-empty.
+ * The available count can only asynchronously decrease, so the
+ * worst possible side-effect will be a spurious notification.
+ */
+ if (ivc_channel_avail_count(ivc, ivc->tx_channel) == (uint32_t)1U) {
+ ivc->notify(ivc);
+ }
+
+ return 0;
+}
+
+void tegra_ivc_channel_reset(const struct ivc *ivc)
+{
+ ivc->tx_channel->state = ivc_state_sync;
+ ivc->notify(ivc);
+}
+
+/*
+ * ===============================================================
+ * IVC State Transition Table - see tegra_ivc_channel_notified()
+ * ===============================================================
+ *
+ * local remote action
+ * ----- ------ -----------------------------------
+ * SYNC EST <none>
+ * SYNC ACK reset counters; move to EST; notify
+ * SYNC SYNC reset counters; move to ACK; notify
+ * ACK EST move to EST; notify
+ * ACK ACK move to EST; notify
+ * ACK SYNC reset counters; move to ACK; notify
+ * EST EST <none>
+ * EST ACK <none>
+ * EST SYNC reset counters; move to ACK; notify
+ *
+ * ===============================================================
+ */
+int32_t tegra_ivc_channel_notified(struct ivc *ivc)
+{
+ uint32_t peer_state;
+
+ /* Copy the receiver's state out of shared memory. */
+ peer_state = ivc->rx_channel->state;
+
+ if (peer_state == (uint32_t)ivc_state_sync) {
+ /*
+ * Order observation of ivc_state_sync before stores clearing
+ * tx_channel.
+ */
+ dmbld();
+
+ /*
+ * Reset tx_channel counters. The remote end is in the SYNC
+ * state and won't make progress until we change our state,
+ * so the counters are not in use at this time.
+ */
+ ivc->tx_channel->w_count = 0U;
+ ivc->rx_channel->r_count = 0U;
+
+ ivc->w_pos = 0U;
+ ivc->r_pos = 0U;
+
+ /*
+ * Ensure that counters appear cleared before new state can be
+ * observed.
+ */
+ dmbst();
+
+ /*
+ * Move to ACK state. We have just cleared our counters, so it
+ * is now safe for the remote end to start using these values.
+ */
+ ivc->tx_channel->state = ivc_state_ack;
+
+ /*
+ * Notify remote end to observe state transition.
+ */
+ ivc->notify(ivc);
+
+ } else if ((ivc->tx_channel->state == (uint32_t)ivc_state_sync) &&
+ (peer_state == (uint32_t)ivc_state_ack)) {
+ /*
+ * Order observation of ivc_state_sync before stores clearing
+ * tx_channel.
+ */
+ dmbld();
+
+ /*
+ * Reset tx_channel counters. The remote end is in the ACK
+ * state and won't make progress until we change our state,
+ * so the counters are not in use at this time.
+ */
+ ivc->tx_channel->w_count = 0U;
+ ivc->rx_channel->r_count = 0U;
+
+ ivc->w_pos = 0U;
+ ivc->r_pos = 0U;
+
+ /*
+ * Ensure that counters appear cleared before new state can be
+ * observed.
+ */
+ dmbst();
+
+ /*
+ * Move to ESTABLISHED state. We know that the remote end has
+ * already cleared its counters, so it is safe to start
+ * writing/reading on this channel.
+ */
+ ivc->tx_channel->state = ivc_state_established;
+
+ /*
+ * Notify remote end to observe state transition.
+ */
+ ivc->notify(ivc);
+
+ } else if (ivc->tx_channel->state == (uint32_t)ivc_state_ack) {
+ /*
+ * At this point, we have observed the peer to be in either
+ * the ACK or ESTABLISHED state. Next, order observation of
+ * peer state before storing to tx_channel.
+ */
+ dmbld();
+
+ /*
+ * Move to ESTABLISHED state. We know that we have previously
+ * cleared our counters, and we know that the remote end has
+ * cleared its counters, so it is safe to start writing/reading
+ * on this channel.
+ */
+ ivc->tx_channel->state = ivc_state_established;
+
+ /*
+ * Notify remote end to observe state transition.
+ */
+ ivc->notify(ivc);
+
+ } else {
+ /*
+ * There is no need to handle any further action. Either the
+ * channel is already fully established, or we are waiting for
+ * the remote end to catch up with our current state. Refer
+ * to the diagram in "IVC State Transition Table" above.
+ */
+ }
+
+ return ((ivc->tx_channel->state == (uint32_t)ivc_state_established) ? 0 : -EAGAIN);
+}
+
+size_t tegra_ivc_align(size_t size)
+{
+ return (size + (IVC_ALIGN - 1U)) & ~(IVC_ALIGN - 1U);
+}
+
+size_t tegra_ivc_total_queue_size(size_t queue_size)
+{
+ if ((queue_size & (IVC_ALIGN - 1U)) != 0U) {
+ ERROR("queue_size (%d) must be %d-byte aligned\n",
+ (int32_t)queue_size, IVC_ALIGN);
+ return 0;
+ }
+ return queue_size + sizeof(struct ivc_channel_header);
+}
+
+static int32_t check_ivc_params(uintptr_t queue_base1, uintptr_t queue_base2,
+ uint32_t nframes, uint32_t frame_size)
+{
+ assert((offsetof(struct ivc_channel_header, w_count)
+ & (IVC_ALIGN - 1U)) == 0U);
+ assert((offsetof(struct ivc_channel_header, r_count)
+ & (IVC_ALIGN - 1U)) == 0U);
+ assert((sizeof(struct ivc_channel_header) & (IVC_ALIGN - 1U)) == 0U);
+
+ if (((uint64_t)nframes * (uint64_t)frame_size) >= 0x100000000ULL) {
+ ERROR("nframes * frame_size overflows\n");
+ return -EINVAL;
+ }
+
+ /*
+ * The headers must at least be aligned enough for counters
+ * to be accessed atomically.
+ */
+ if ((queue_base1 & (IVC_ALIGN - 1U)) != 0U) {
+ ERROR("ivc channel start not aligned: %lx\n", queue_base1);
+ return -EINVAL;
+ }
+ if ((queue_base2 & (IVC_ALIGN - 1U)) != 0U) {
+ ERROR("ivc channel start not aligned: %lx\n", queue_base2);
+ return -EINVAL;
+ }
+
+ if ((frame_size & (IVC_ALIGN - 1U)) != 0U) {
+ ERROR("frame size not adequately aligned: %u\n",
+ frame_size);
+ return -EINVAL;
+ }
+
+ if (queue_base1 < queue_base2) {
+ if ((queue_base1 + ((uint64_t)frame_size * nframes)) > queue_base2) {
+ ERROR("queue regions overlap: %lx + %x, %x\n",
+ queue_base1, frame_size,
+ frame_size * nframes);
+ return -EINVAL;
+ }
+ } else {
+ if ((queue_base2 + ((uint64_t)frame_size * nframes)) > queue_base1) {
+ ERROR("queue regions overlap: %lx + %x, %x\n",
+ queue_base2, frame_size,
+ frame_size * nframes);
+ return -EINVAL;
+ }
+ }
+
+ return 0;
+}
+
+int32_t tegra_ivc_init(struct ivc *ivc, uintptr_t rx_base, uintptr_t tx_base,
+ uint32_t nframes, uint32_t frame_size,
+ ivc_notify_function notify)
+{
+ int32_t result;
+
+ /* sanity check input params */
+ if ((ivc == NULL) || (notify == NULL)) {
+ return -EINVAL;
+ }
+
+ result = check_ivc_params(rx_base, tx_base, nframes, frame_size);
+ if (result != 0) {
+ return result;
+ }
+
+ /*
+ * All sizes that can be returned by communication functions should
+ * fit in a 32-bit integer.
+ */
+ if (frame_size > (1u << 31)) {
+ return -E2BIG;
+ }
+
+ ivc->rx_channel = (struct ivc_channel_header *)rx_base;
+ ivc->tx_channel = (struct ivc_channel_header *)tx_base;
+ ivc->notify = notify;
+ ivc->frame_size = frame_size;
+ ivc->nframes = nframes;
+ ivc->w_pos = 0U;
+ ivc->r_pos = 0U;
+
+ INFO("%s: done\n", __func__);
+
+ return 0;
+}
diff --git a/plat/nvidia/tegra/common/drivers/bpmp_ipc/ivc.h b/plat/nvidia/tegra/common/drivers/bpmp_ipc/ivc.h
new file mode 100644
index 0000000..f34d6cf
--- /dev/null
+++ b/plat/nvidia/tegra/common/drivers/bpmp_ipc/ivc.h
@@ -0,0 +1,51 @@
+/*
+ * Copyright (c) 2017, NVIDIA CORPORATION. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef IVC_H
+#define IVC_H
+
+#include <stdint.h>
+#include <stddef.h>
+#include <utils_def.h>
+
+#define IVC_ALIGN U(64)
+#define IVC_CHHDR_TX_FIELDS U(16)
+#define IVC_CHHDR_RX_FIELDS U(16)
+
+struct ivc;
+struct ivc_channel_header;
+
+/* callback handler for notify on receiving a response */
+typedef void (* ivc_notify_function)(const struct ivc *);
+
+struct ivc {
+ struct ivc_channel_header *rx_channel;
+ struct ivc_channel_header *tx_channel;
+ uint32_t w_pos;
+ uint32_t r_pos;
+ ivc_notify_function notify;
+ uint32_t nframes;
+ uint32_t frame_size;
+};
+
+int32_t tegra_ivc_init(struct ivc *ivc, uintptr_t rx_base, uintptr_t tx_base,
+ uint32_t nframes, uint32_t frame_size,
+ ivc_notify_function notify);
+size_t tegra_ivc_total_queue_size(size_t queue_size);
+size_t tegra_ivc_align(size_t size);
+int32_t tegra_ivc_channel_notified(struct ivc *ivc);
+void tegra_ivc_channel_reset(const struct ivc *ivc);
+int32_t tegra_ivc_write_advance(struct ivc *ivc);
+void *tegra_ivc_write_get_next_frame(const struct ivc *ivc);
+int32_t tegra_ivc_write(struct ivc *ivc, const void *buf, size_t size);
+int32_t tegra_ivc_read_advance(struct ivc *ivc);
+void *tegra_ivc_read_get_next_frame(const struct ivc *ivc);
+int32_t tegra_ivc_read(struct ivc *ivc, void *buf, size_t max_read);
+bool tegra_ivc_tx_empty(const struct ivc *ivc);
+bool tegra_ivc_can_write(const struct ivc *ivc);
+bool tegra_ivc_can_read(const struct ivc *ivc);
+
+#endif /* IVC_H */
diff --git a/plat/nvidia/tegra/common/drivers/gpcdma/gpcdma.c b/plat/nvidia/tegra/common/drivers/gpcdma/gpcdma.c
new file mode 100644
index 0000000..64e84ac
--- /dev/null
+++ b/plat/nvidia/tegra/common/drivers/gpcdma/gpcdma.c
@@ -0,0 +1,188 @@
+/*
+ * Copyright (c) 2017, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <arch_helpers.h>
+#include <common/debug.h>
+#include <delay_timer.h>
+#include <errno.h>
+#include <gpcdma.h>
+#include <mmio.h>
+#include <platform_def.h>
+#include <stdbool.h>
+#include <tegra_def.h>
+#include <utils_def.h>
+
+/* DMA channel registers */
+#define DMA_CH_CSR U(0x0)
+#define DMA_CH_CSR_WEIGHT_SHIFT U(10)
+#define DMA_CH_CSR_XFER_MODE_SHIFT U(21)
+#define DMA_CH_CSR_DMA_MODE_MEM2MEM U(4)
+#define DMA_CH_CSR_DMA_MODE_FIXEDPATTERN U(6)
+#define DMA_CH_CSR_IRQ_MASK_ENABLE (U(1) << 15)
+#define DMA_CH_CSR_RUN_ONCE (U(1) << 27)
+#define DMA_CH_CSR_ENABLE (U(1) << 31)
+
+#define DMA_CH_STAT U(0x4)
+#define DMA_CH_STAT_BUSY (U(1) << 31)
+
+#define DMA_CH_SRC_PTR U(0xC)
+
+#define DMA_CH_DST_PTR U(0x10)
+
+#define DMA_CH_HI_ADR_PTR U(0x14)
+#define DMA_CH_HI_ADR_PTR_SRC_MASK U(0xFF)
+#define DMA_CH_HI_ADR_PTR_DST_SHIFT U(16)
+#define DMA_CH_HI_ADR_PTR_DST_MASK U(0xFF)
+
+#define DMA_CH_MC_SEQ U(0x18)
+#define DMA_CH_MC_SEQ_REQ_CNT_SHIFT U(25)
+#define DMA_CH_MC_SEQ_REQ_CNT_VAL U(0x10)
+#define DMA_CH_MC_SEQ_BURST_SHIFT U(23)
+#define DMA_CH_MC_SEQ_BURST_16_WORDS U(0x3)
+
+#define DMA_CH_WORD_COUNT U(0x20)
+#define DMA_CH_FIXED_PATTERN U(0x34)
+#define DMA_CH_TZ U(0x38)
+#define DMA_CH_TZ_ACCESS_ENABLE U(0)
+#define DMA_CH_TZ_ACCESS_DISABLE U(3)
+
+#define MAX_TRANSFER_SIZE (1U*1024U*1024U*1024U) /* 1GB */
+#define GPCDMA_TIMEOUT_MS U(100)
+#define GPCDMA_RESET_BIT (U(1) << 1)
+
+static bool init_done;
+
+static void tegra_gpcdma_write32(uint32_t offset, uint32_t val)
+{
+ mmio_write_32(TEGRA_GPCDMA_BASE + offset, val);
+}
+
+static uint32_t tegra_gpcdma_read32(uint32_t offset)
+{
+ return mmio_read_32(TEGRA_GPCDMA_BASE + offset);
+}
+
+static void tegra_gpcdma_init(void)
+{
+ /* assert reset for DMA engine */
+ mmio_write_32(TEGRA_CAR_RESET_BASE + TEGRA_GPCDMA_RST_SET_REG_OFFSET,
+ GPCDMA_RESET_BIT);
+
+ udelay(2);
+
+ /* de-assert reset for DMA engine */
+ mmio_write_32(TEGRA_CAR_RESET_BASE + TEGRA_GPCDMA_RST_CLR_REG_OFFSET,
+ GPCDMA_RESET_BIT);
+}
+
+static void tegra_gpcdma_memcpy_priv(uint64_t dst_addr, uint64_t src_addr,
+ uint32_t num_bytes, uint32_t mode)
+{
+ uint32_t val, timeout = 0;
+ int32_t ret = 0;
+
+ /* sanity check byte count */
+ if ((num_bytes > MAX_TRANSFER_SIZE) || ((num_bytes & 0x3U) != U(0))) {
+ ret = -EINVAL;
+ }
+
+ /* initialise GPCDMA block */
+ if (!init_done) {
+ tegra_gpcdma_init();
+ init_done = true;
+ }
+
+ /* make sure channel isn't busy */
+ val = tegra_gpcdma_read32(DMA_CH_STAT);
+ if ((val & DMA_CH_STAT_BUSY) == DMA_CH_STAT_BUSY) {
+ ERROR("DMA channel is busy\n");
+ ret = -EBUSY;
+ }
+
+ if (ret == 0) {
+
+ /* disable any DMA transfers */
+ tegra_gpcdma_write32(DMA_CH_CSR, 0);
+
+ /* enable DMA access to TZDRAM */
+ tegra_gpcdma_write32(DMA_CH_TZ, DMA_CH_TZ_ACCESS_ENABLE);
+
+ /* configure MC sequencer */
+ val = (DMA_CH_MC_SEQ_REQ_CNT_VAL << DMA_CH_MC_SEQ_REQ_CNT_SHIFT) |
+ (DMA_CH_MC_SEQ_BURST_16_WORDS << DMA_CH_MC_SEQ_BURST_SHIFT);
+ tegra_gpcdma_write32(DMA_CH_MC_SEQ, val);
+
+ /* reset fixed pattern */
+ tegra_gpcdma_write32(DMA_CH_FIXED_PATTERN, 0);
+
+ /* populate src and dst address registers */
+ tegra_gpcdma_write32(DMA_CH_SRC_PTR, (uint32_t)src_addr);
+ tegra_gpcdma_write32(DMA_CH_DST_PTR, (uint32_t)dst_addr);
+
+ val = (uint32_t)((src_addr >> 32) & DMA_CH_HI_ADR_PTR_SRC_MASK);
+ val |= (uint32_t)(((dst_addr >> 32) & DMA_CH_HI_ADR_PTR_DST_MASK) <<
+ DMA_CH_HI_ADR_PTR_DST_SHIFT);
+ tegra_gpcdma_write32(DMA_CH_HI_ADR_PTR, val);
+
+ /* transfer size (in words) */
+ tegra_gpcdma_write32(DMA_CH_WORD_COUNT, ((num_bytes >> 2) - 1U));
+
+ /* populate value for CSR */
+ val = (mode << DMA_CH_CSR_XFER_MODE_SHIFT) |
+ DMA_CH_CSR_RUN_ONCE | (U(1) << DMA_CH_CSR_WEIGHT_SHIFT) |
+ DMA_CH_CSR_IRQ_MASK_ENABLE;
+ tegra_gpcdma_write32(DMA_CH_CSR, val);
+
+ /* enable transfer */
+ val = tegra_gpcdma_read32(DMA_CH_CSR);
+ val |= DMA_CH_CSR_ENABLE;
+ tegra_gpcdma_write32(DMA_CH_CSR, val);
+
+ /* wait till transfer completes */
+ do {
+
+ /* read the status */
+ val = tegra_gpcdma_read32(DMA_CH_STAT);
+ if ((val & DMA_CH_STAT_BUSY) != DMA_CH_STAT_BUSY) {
+ break;
+ }
+
+ mdelay(1);
+ timeout++;
+
+ } while (timeout < GPCDMA_TIMEOUT_MS);
+
+ /* flag timeout error */
+ if (timeout == GPCDMA_TIMEOUT_MS) {
+ ERROR("DMA transfer timed out\n");
+ }
+
+ dsbsy();
+
+ /* disable DMA access to TZDRAM */
+ tegra_gpcdma_write32(DMA_CH_TZ, DMA_CH_TZ_ACCESS_DISABLE);
+ isb();
+ }
+}
+
+/*******************************************************************************
+ * Memcpy using GPCDMA block (Mem2Mem copy)
+ ******************************************************************************/
+void tegra_gpcdma_memcpy(uint64_t dst_addr, uint64_t src_addr,
+ uint32_t num_bytes)
+{
+ tegra_gpcdma_memcpy_priv(dst_addr, src_addr, num_bytes,
+ DMA_CH_CSR_DMA_MODE_MEM2MEM);
+}
+
+/*******************************************************************************
+ * Memset using GPCDMA block (Fixed pattern write)
+ ******************************************************************************/
+void tegra_gpcdma_zeromem(uint64_t dst_addr, uint32_t num_bytes)
+{
+ tegra_gpcdma_memcpy_priv(dst_addr, 0, num_bytes,
+ DMA_CH_CSR_DMA_MODE_FIXEDPATTERN);
+}
diff --git a/plat/nvidia/tegra/common/drivers/memctrl/memctrl_v1.c b/plat/nvidia/tegra/common/drivers/memctrl/memctrl_v1.c
index 58f49d0..92fa273 100644
--- a/plat/nvidia/tegra/common/drivers/memctrl/memctrl_v1.c
+++ b/plat/nvidia/tegra/common/drivers/memctrl/memctrl_v1.c
@@ -109,13 +109,16 @@
static void tegra_clear_videomem(uintptr_t non_overlap_area_start,
unsigned long long non_overlap_area_size)
{
+ int ret;
+
/*
* Map the NS memory first, clean it and then unmap it.
*/
- mmap_add_dynamic_region(non_overlap_area_start, /* PA */
+ ret = mmap_add_dynamic_region(non_overlap_area_start, /* PA */
non_overlap_area_start, /* VA */
non_overlap_area_size, /* size */
MT_NS | MT_RW | MT_EXECUTE_NEVER); /* attrs */
+ assert(ret == 0);
zeromem((void *)non_overlap_area_start, non_overlap_area_size);
flush_dcache_range(non_overlap_area_start, non_overlap_area_size);
@@ -206,3 +209,16 @@
/* lock the aperture registers */
tegra_mc_write_32(MC_IRAM_REG_CTRL, MC_DISABLE_IRAM_CFG_WRITES);
}
+
+void tegra_memctrl_clear_pending_interrupts(void)
+{
+ uint32_t mcerr;
+
+ /* check if there are any pending interrupts */
+ mcerr = mmio_read_32(TEGRA_MC_BASE + MC_INTSTATUS);
+
+ if (mcerr != (uint32_t)0U) { /* should not see error here */
+ WARN("MC_INTSTATUS = 0x%x (should be zero)\n", mcerr);
+ mmio_write_32((TEGRA_MC_BASE + MC_INTSTATUS), mcerr);
+ }
+}
diff --git a/plat/nvidia/tegra/common/drivers/memctrl/memctrl_v2.c b/plat/nvidia/tegra/common/drivers/memctrl/memctrl_v2.c
index de431b7..a3ef5e1 100644
--- a/plat/nvidia/tegra/common/drivers/memctrl/memctrl_v2.c
+++ b/plat/nvidia/tegra/common/drivers/memctrl/memctrl_v2.c
@@ -25,316 +25,15 @@
static uint64_t video_mem_base;
static uint64_t video_mem_size_mb;
-static void tegra_memctrl_reconfig_mss_clients(void)
+/*
+ * The following platform setup functions are weakly defined. They
+ * provide typical implementations that will be overridden by a SoC.
+ */
+#pragma weak plat_memctrl_tzdram_setup
+
+void plat_memctrl_tzdram_setup(uint64_t phys_base, uint64_t size_in_bytes)
{
-#if ENABLE_ROC_FOR_ORDERING_CLIENT_REQUESTS
- uint32_t val, wdata_0, wdata_1;
-
- /*
- * Assert Memory Controller's HOTRESET_FLUSH_ENABLE signal for
- * boot and strongly ordered MSS clients to flush existing memory
- * traffic and stall future requests.
- */
- val = tegra_mc_read_32(MC_CLIENT_HOTRESET_CTRL0);
- assert(val == MC_CLIENT_HOTRESET_CTRL0_RESET_VAL);
-
- wdata_0 = MC_CLIENT_HOTRESET_CTRL0_HDA_FLUSH_ENB |
-#if ENABLE_AFI_DEVICE
- MC_CLIENT_HOTRESET_CTRL0_AFI_FLUSH_ENB |
-#endif
- MC_CLIENT_HOTRESET_CTRL0_SATA_FLUSH_ENB |
- MC_CLIENT_HOTRESET_CTRL0_XUSB_HOST_FLUSH_ENB |
- MC_CLIENT_HOTRESET_CTRL0_XUSB_DEV_FLUSH_ENB;
- tegra_mc_write_32(MC_CLIENT_HOTRESET_CTRL0, wdata_0);
-
- /* Wait for HOTRESET STATUS to indicate FLUSH_DONE */
- do {
- val = tegra_mc_read_32(MC_CLIENT_HOTRESET_STATUS0);
- } while ((val & wdata_0) != wdata_0);
-
- /* Wait one more time due to SW WAR for known legacy issue */
- do {
- val = tegra_mc_read_32(MC_CLIENT_HOTRESET_STATUS0);
- } while ((val & wdata_0) != wdata_0);
-
- val = tegra_mc_read_32(MC_CLIENT_HOTRESET_CTRL1);
- assert(val == MC_CLIENT_HOTRESET_CTRL1_RESET_VAL);
-
- wdata_1 = MC_CLIENT_HOTRESET_CTRL1_SDMMC4A_FLUSH_ENB |
- MC_CLIENT_HOTRESET_CTRL1_APE_FLUSH_ENB |
- MC_CLIENT_HOTRESET_CTRL1_SE_FLUSH_ENB |
- MC_CLIENT_HOTRESET_CTRL1_ETR_FLUSH_ENB |
- MC_CLIENT_HOTRESET_CTRL1_AXIS_FLUSH_ENB |
- MC_CLIENT_HOTRESET_CTRL1_EQOS_FLUSH_ENB |
- MC_CLIENT_HOTRESET_CTRL1_UFSHC_FLUSH_ENB |
- MC_CLIENT_HOTRESET_CTRL1_BPMP_FLUSH_ENB |
- MC_CLIENT_HOTRESET_CTRL1_AON_FLUSH_ENB |
- MC_CLIENT_HOTRESET_CTRL1_SCE_FLUSH_ENB;
- tegra_mc_write_32(MC_CLIENT_HOTRESET_CTRL1, wdata_1);
-
- /* Wait for HOTRESET STATUS to indicate FLUSH_DONE */
- do {
- val = tegra_mc_read_32(MC_CLIENT_HOTRESET_STATUS1);
- } while ((val & wdata_1) != wdata_1);
-
- /* Wait one more time due to SW WAR for known legacy issue */
- do {
- val = tegra_mc_read_32(MC_CLIENT_HOTRESET_STATUS1);
- } while ((val & wdata_1) != wdata_1);
-
- /*
- * Change MEMTYPE_OVERRIDE from SO_DEV -> PASSTHRU for boot and
- * strongly ordered MSS clients. ROC needs to be single point
- * of control on overriding the memory type. So, remove TSA's
- * memtype override.
- *
- * MC clients with default SO_DEV override still enabled at TSA:
- * AONW, BPMPW, SCEW, APEW
- */
-#if ENABLE_AFI_DEVICE
- mc_set_tsa_passthrough(AFIW);
-#endif
- mc_set_tsa_passthrough(HDAW);
- mc_set_tsa_passthrough(SATAW);
- mc_set_tsa_passthrough(XUSB_HOSTW);
- mc_set_tsa_passthrough(XUSB_DEVW);
- mc_set_tsa_passthrough(SDMMCWAB);
- mc_set_tsa_passthrough(APEDMAW);
- mc_set_tsa_passthrough(SESWR);
- mc_set_tsa_passthrough(ETRW);
- mc_set_tsa_passthrough(AXISW);
- mc_set_tsa_passthrough(EQOSW);
- mc_set_tsa_passthrough(UFSHCW);
- mc_set_tsa_passthrough(BPMPDMAW);
- mc_set_tsa_passthrough(AONDMAW);
- mc_set_tsa_passthrough(SCEDMAW);
-
- /* Parker has no IO Coherency support and need the following:
- * Ordered MC Clients on Parker are AFI, EQOS, SATA, XUSB.
- * ISO clients(DISP, VI, EQOS) should never snoop caches and
- * don't need ROC/PCFIFO ordering.
- * ISO clients(EQOS) that need ordering should use PCFIFO ordering
- * and bypass ROC ordering by using FORCE_NON_COHERENT path.
- * FORCE_NON_COHERENT/FORCE_COHERENT config take precedence
- * over SMMU attributes.
- * Force all Normal memory transactions from ISO and non-ISO to be
- * non-coherent(bypass ROC, avoid cache snoop to avoid perf hit).
- * Force the SO_DEV transactions from ordered ISO clients(EQOS) to
- * non-coherent path and enable MC PCFIFO interlock for ordering.
- * Force the SO_DEV transactions from ordered non-ISO clients (PCIe,
- * XUSB, SATA) to coherent so that the transactions are
- * ordered by ROC.
- * PCFIFO ensure write ordering.
- * Read after Write ordering is maintained/enforced by MC clients.
- * Clients that need PCIe type write ordering must
- * go through ROC ordering.
- * Ordering enable for Read clients is not necessary.
- * R5's and A9 would get necessary ordering from AXI and
- * don't need ROC ordering enable:
- * - MMIO ordering is through dev mapping and MMIO
- * accesses bypass SMMU.
- * - Normal memory is accessed through SMMU and ordering is
- * ensured by client and AXI.
- * - Ack point for Normal memory is WCAM in MC.
- * - MMIO's can be early acked and AXI ensures dev memory ordering,
- * Client ensures read/write direction change ordering.
- * - See Bug 200312466 for more details.
- *
- * CGID_TAG_ADR is only present from T186 A02. As this code is common
- * between A01 and A02, tegra_memctrl_set_overrides() programs
- * CGID_TAG_ADR for the necessary clients on A02.
- */
- mc_set_txn_override(HDAR, CGID_TAG_DEFAULT, SO_DEV_ZERO, FORCE_NON_COHERENT, FORCE_NON_COHERENT);
- mc_set_txn_override(BPMPW, CGID_TAG_DEFAULT, SO_DEV_ZERO, FORCE_NON_COHERENT, FORCE_NON_COHERENT);
- mc_set_txn_override(PTCR, CGID_TAG_DEFAULT, SO_DEV_ZERO, FORCE_NON_COHERENT, FORCE_NON_COHERENT);
- mc_set_txn_override(NVDISPLAYR, CGID_TAG_DEFAULT, SO_DEV_ZERO, FORCE_NON_COHERENT, FORCE_NON_COHERENT);
- mc_set_txn_override(EQOSW, CGID_TAG_DEFAULT, SO_DEV_ZERO, FORCE_NON_COHERENT, FORCE_NON_COHERENT);
- mc_set_txn_override(NVJPGSWR, CGID_TAG_DEFAULT, SO_DEV_ZERO, FORCE_NON_COHERENT, FORCE_NON_COHERENT);
- mc_set_txn_override(ISPRA, CGID_TAG_DEFAULT, SO_DEV_ZERO, FORCE_NON_COHERENT, FORCE_NON_COHERENT);
- mc_set_txn_override(SDMMCWAA, CGID_TAG_DEFAULT, SO_DEV_ZERO, FORCE_NON_COHERENT, FORCE_NON_COHERENT);
- mc_set_txn_override(VICSRD, CGID_TAG_DEFAULT, SO_DEV_ZERO, FORCE_NON_COHERENT, FORCE_NON_COHERENT);
- mc_set_txn_override(MPCOREW, CGID_TAG_DEFAULT, SO_DEV_ZERO, NO_OVERRIDE, NO_OVERRIDE);
- mc_set_txn_override(GPUSRD, CGID_TAG_DEFAULT, SO_DEV_ZERO, FORCE_NON_COHERENT, FORCE_NON_COHERENT);
- mc_set_txn_override(AXISR, CGID_TAG_DEFAULT, SO_DEV_ZERO, FORCE_NON_COHERENT, FORCE_NON_COHERENT);
- mc_set_txn_override(SCEDMAW, CGID_TAG_DEFAULT, SO_DEV_ZERO, FORCE_NON_COHERENT, FORCE_NON_COHERENT);
- mc_set_txn_override(SDMMCW, CGID_TAG_DEFAULT, SO_DEV_ZERO, FORCE_NON_COHERENT, FORCE_NON_COHERENT);
- mc_set_txn_override(EQOSR, CGID_TAG_DEFAULT, SO_DEV_ZERO, FORCE_NON_COHERENT, FORCE_NON_COHERENT);
- /* See bug 200131110 comment #35*/
- mc_set_txn_override(APEDMAR, CGID_TAG_CLIENT_AXI_ID, SO_DEV_CLIENT_AXI_ID, FORCE_NON_COHERENT, FORCE_NON_COHERENT);
- mc_set_txn_override(NVENCSRD, CGID_TAG_DEFAULT, SO_DEV_ZERO, FORCE_NON_COHERENT, FORCE_NON_COHERENT);
- mc_set_txn_override(SDMMCRAB, CGID_TAG_DEFAULT, SO_DEV_ZERO, FORCE_NON_COHERENT, FORCE_NON_COHERENT);
- mc_set_txn_override(VICSRD1, CGID_TAG_DEFAULT, SO_DEV_ZERO, FORCE_NON_COHERENT, FORCE_NON_COHERENT);
- mc_set_txn_override(BPMPDMAR, CGID_TAG_DEFAULT, SO_DEV_ZERO, FORCE_NON_COHERENT, FORCE_NON_COHERENT);
- mc_set_txn_override(VIW, CGID_TAG_DEFAULT, SO_DEV_ZERO, FORCE_NON_COHERENT, FORCE_NON_COHERENT);
- mc_set_txn_override(SDMMCRAA, CGID_TAG_DEFAULT, SO_DEV_ZERO, FORCE_NON_COHERENT, FORCE_NON_COHERENT);
- mc_set_txn_override(AXISW, CGID_TAG_DEFAULT, SO_DEV_ZERO, FORCE_NON_COHERENT, FORCE_NON_COHERENT);
- mc_set_txn_override(XUSB_DEVR, CGID_TAG_DEFAULT, SO_DEV_ZERO, FORCE_NON_COHERENT, FORCE_NON_COHERENT);
- mc_set_txn_override(UFSHCR, CGID_TAG_DEFAULT, SO_DEV_ZERO, FORCE_NON_COHERENT, FORCE_NON_COHERENT);
- mc_set_txn_override(TSECSWR, CGID_TAG_DEFAULT, SO_DEV_ZERO, FORCE_NON_COHERENT, FORCE_NON_COHERENT);
- mc_set_txn_override(GPUSWR, CGID_TAG_DEFAULT, SO_DEV_ZERO, FORCE_NON_COHERENT, FORCE_NON_COHERENT);
- mc_set_txn_override(SATAR, CGID_TAG_DEFAULT, SO_DEV_ZERO, FORCE_NON_COHERENT, FORCE_NON_COHERENT);
- mc_set_txn_override(XUSB_HOSTW, CGID_TAG_DEFAULT, SO_DEV_ZERO, FORCE_NON_COHERENT, FORCE_COHERENT);
- mc_set_txn_override(TSECSWRB, CGID_TAG_DEFAULT, SO_DEV_ZERO, FORCE_NON_COHERENT, FORCE_NON_COHERENT);
- mc_set_txn_override(GPUSRD2, CGID_TAG_DEFAULT, SO_DEV_ZERO, FORCE_NON_COHERENT, FORCE_NON_COHERENT);
- mc_set_txn_override(SCEDMAR, CGID_TAG_DEFAULT, SO_DEV_ZERO, FORCE_NON_COHERENT, FORCE_NON_COHERENT);
- mc_set_txn_override(GPUSWR2, CGID_TAG_DEFAULT, SO_DEV_ZERO, FORCE_NON_COHERENT, FORCE_NON_COHERENT);
- mc_set_txn_override(AONDMAW, CGID_TAG_DEFAULT, SO_DEV_ZERO, FORCE_NON_COHERENT, FORCE_NON_COHERENT);
- /* See bug 200131110 comment #35*/
- mc_set_txn_override(APEDMAW, CGID_TAG_CLIENT_AXI_ID, SO_DEV_CLIENT_AXI_ID, FORCE_NON_COHERENT, FORCE_NON_COHERENT);
- mc_set_txn_override(AONW, CGID_TAG_DEFAULT, SO_DEV_ZERO, FORCE_NON_COHERENT, FORCE_NON_COHERENT);
- mc_set_txn_override(HOST1XDMAR, CGID_TAG_DEFAULT, SO_DEV_ZERO, FORCE_NON_COHERENT, FORCE_NON_COHERENT);
- mc_set_txn_override(ETRR, CGID_TAG_DEFAULT, SO_DEV_ZERO, FORCE_NON_COHERENT, FORCE_NON_COHERENT);
- mc_set_txn_override(SESWR, CGID_TAG_DEFAULT, SO_DEV_ZERO, FORCE_NON_COHERENT, FORCE_NON_COHERENT);
- mc_set_txn_override(NVJPGSRD, CGID_TAG_DEFAULT, SO_DEV_ZERO, FORCE_NON_COHERENT, FORCE_NON_COHERENT);
- mc_set_txn_override(NVDECSRD, CGID_TAG_DEFAULT, SO_DEV_ZERO, FORCE_NON_COHERENT, FORCE_NON_COHERENT);
- mc_set_txn_override(TSECSRDB, CGID_TAG_DEFAULT, SO_DEV_ZERO, FORCE_NON_COHERENT, FORCE_NON_COHERENT);
- mc_set_txn_override(BPMPDMAW, CGID_TAG_DEFAULT, SO_DEV_ZERO, FORCE_NON_COHERENT, FORCE_NON_COHERENT);
- mc_set_txn_override(APER, CGID_TAG_DEFAULT, SO_DEV_ZERO, FORCE_NON_COHERENT, FORCE_NON_COHERENT);
- mc_set_txn_override(NVDECSRD1, CGID_TAG_DEFAULT, SO_DEV_ZERO, FORCE_NON_COHERENT, FORCE_NON_COHERENT);
- mc_set_txn_override(XUSB_HOSTR, CGID_TAG_DEFAULT, SO_DEV_ZERO, FORCE_NON_COHERENT, FORCE_NON_COHERENT);
- mc_set_txn_override(ISPWA, CGID_TAG_DEFAULT, SO_DEV_ZERO, FORCE_NON_COHERENT, FORCE_NON_COHERENT);
- mc_set_txn_override(SESRD, CGID_TAG_DEFAULT, SO_DEV_ZERO, FORCE_NON_COHERENT, FORCE_NON_COHERENT);
- mc_set_txn_override(SCER, CGID_TAG_DEFAULT, SO_DEV_ZERO, FORCE_NON_COHERENT, FORCE_NON_COHERENT);
- mc_set_txn_override(AONR, CGID_TAG_DEFAULT, SO_DEV_ZERO, FORCE_NON_COHERENT, FORCE_NON_COHERENT);
- mc_set_txn_override(MPCORER, CGID_TAG_DEFAULT, SO_DEV_ZERO, NO_OVERRIDE, NO_OVERRIDE);
- mc_set_txn_override(SDMMCWA, CGID_TAG_DEFAULT, SO_DEV_ZERO, FORCE_NON_COHERENT, FORCE_NON_COHERENT);
- mc_set_txn_override(HDAW, CGID_TAG_DEFAULT, SO_DEV_ZERO, FORCE_NON_COHERENT, FORCE_NON_COHERENT);
- mc_set_txn_override(NVDECSWR, CGID_TAG_DEFAULT, SO_DEV_ZERO, FORCE_NON_COHERENT, FORCE_NON_COHERENT);
- mc_set_txn_override(UFSHCW, CGID_TAG_DEFAULT, SO_DEV_ZERO, FORCE_NON_COHERENT, FORCE_NON_COHERENT);
- mc_set_txn_override(AONDMAR, CGID_TAG_DEFAULT, SO_DEV_ZERO, FORCE_NON_COHERENT, FORCE_NON_COHERENT);
- mc_set_txn_override(SATAW, CGID_TAG_DEFAULT, SO_DEV_ZERO, FORCE_NON_COHERENT, FORCE_COHERENT);
- mc_set_txn_override(ETRW, CGID_TAG_DEFAULT, SO_DEV_ZERO, FORCE_NON_COHERENT, FORCE_NON_COHERENT);
- mc_set_txn_override(VICSWR, CGID_TAG_DEFAULT, SO_DEV_ZERO, FORCE_NON_COHERENT, FORCE_NON_COHERENT);
- mc_set_txn_override(NVENCSWR, CGID_TAG_DEFAULT, SO_DEV_ZERO, FORCE_NON_COHERENT, FORCE_NON_COHERENT);
- /* See bug 200131110 comment #35 */
- mc_set_txn_override(AFIR, CGID_TAG_DEFAULT, SO_DEV_CLIENT_AXI_ID, FORCE_NON_COHERENT, FORCE_NON_COHERENT);
- mc_set_txn_override(SDMMCWAB, CGID_TAG_DEFAULT, SO_DEV_ZERO, FORCE_NON_COHERENT, FORCE_NON_COHERENT);
- mc_set_txn_override(SDMMCRA, CGID_TAG_DEFAULT, SO_DEV_ZERO, FORCE_NON_COHERENT, FORCE_NON_COHERENT);
- mc_set_txn_override(NVDISPLAYR1, CGID_TAG_DEFAULT, SO_DEV_ZERO, FORCE_NON_COHERENT, FORCE_NON_COHERENT);
- mc_set_txn_override(ISPWB, CGID_TAG_DEFAULT, SO_DEV_ZERO, FORCE_NON_COHERENT, FORCE_NON_COHERENT);
- mc_set_txn_override(BPMPR, CGID_TAG_DEFAULT, SO_DEV_ZERO, FORCE_NON_COHERENT, FORCE_NON_COHERENT);
- mc_set_txn_override(APEW, CGID_TAG_DEFAULT, SO_DEV_ZERO, FORCE_NON_COHERENT, FORCE_NON_COHERENT);
- mc_set_txn_override(SDMMCR, CGID_TAG_DEFAULT, SO_DEV_ZERO, FORCE_NON_COHERENT, FORCE_NON_COHERENT);
- mc_set_txn_override(XUSB_DEVW, CGID_TAG_DEFAULT, SO_DEV_ZERO, FORCE_NON_COHERENT, FORCE_COHERENT);
- mc_set_txn_override(TSECSRD, CGID_TAG_DEFAULT, SO_DEV_ZERO, FORCE_NON_COHERENT, FORCE_NON_COHERENT);
- /*
- * See bug 200131110 comment #35 - there are no normal requests
- * and AWID for SO/DEV requests is hardcoded in RTL for a
- * particular PCIE controller
- */
- mc_set_txn_override(AFIW, CGID_TAG_DEFAULT, SO_DEV_CLIENT_AXI_ID, FORCE_NON_COHERENT, FORCE_COHERENT);
- mc_set_txn_override(SCEW, CGID_TAG_DEFAULT, SO_DEV_ZERO, FORCE_NON_COHERENT, FORCE_NON_COHERENT);
-
- /*
- * At this point, ordering can occur at ROC. So, remove PCFIFO's
- * control over ordering requests.
- *
- * Change PCFIFO_*_ORDERED_CLIENT from ORDERED -> UNORDERED for
- * boot and strongly ordered MSS clients
- */
- val = MC_PCFIFO_CLIENT_CONFIG1_RESET_VAL &
-#if ENABLE_AFI_DEVICE
- mc_set_pcfifo_unordered_boot_so_mss(1, AFIW) &
-#endif
- mc_set_pcfifo_unordered_boot_so_mss(1, HDAW) &
- mc_set_pcfifo_unordered_boot_so_mss(1, SATAW);
- tegra_mc_write_32(MC_PCFIFO_CLIENT_CONFIG1, val);
-
- val = MC_PCFIFO_CLIENT_CONFIG2_RESET_VAL &
- mc_set_pcfifo_unordered_boot_so_mss(2, XUSB_HOSTW) &
- mc_set_pcfifo_unordered_boot_so_mss(2, XUSB_DEVW);
- tegra_mc_write_32(MC_PCFIFO_CLIENT_CONFIG2, val);
-
- val = MC_PCFIFO_CLIENT_CONFIG3_RESET_VAL &
- mc_set_pcfifo_unordered_boot_so_mss(3, SDMMCWAB);
- tegra_mc_write_32(MC_PCFIFO_CLIENT_CONFIG3, val);
-
- val = MC_PCFIFO_CLIENT_CONFIG4_RESET_VAL &
- mc_set_pcfifo_unordered_boot_so_mss(4, SESWR) &
- mc_set_pcfifo_unordered_boot_so_mss(4, ETRW) &
- mc_set_pcfifo_unordered_boot_so_mss(4, AXISW) &
- mc_set_pcfifo_unordered_boot_so_mss(4, UFSHCW) &
- mc_set_pcfifo_unordered_boot_so_mss(4, BPMPDMAW) &
- mc_set_pcfifo_unordered_boot_so_mss(4, AONDMAW) &
- mc_set_pcfifo_unordered_boot_so_mss(4, SCEDMAW);
- /* EQOSW is the only client that has PCFIFO order enabled. */
- val |= mc_set_pcfifo_ordered_boot_so_mss(4, EQOSW);
- tegra_mc_write_32(MC_PCFIFO_CLIENT_CONFIG4, val);
-
- val = MC_PCFIFO_CLIENT_CONFIG5_RESET_VAL &
- mc_set_pcfifo_unordered_boot_so_mss(5, APEDMAW);
- tegra_mc_write_32(MC_PCFIFO_CLIENT_CONFIG5, val);
-
- /*
- * Deassert HOTRESET FLUSH_ENABLE for boot and strongly ordered MSS
- * clients to allow memory traffic from all clients to start passing
- * through ROC
- */
- val = tegra_mc_read_32(MC_CLIENT_HOTRESET_CTRL0);
- assert(val == wdata_0);
-
- wdata_0 = MC_CLIENT_HOTRESET_CTRL0_RESET_VAL;
- tegra_mc_write_32(MC_CLIENT_HOTRESET_CTRL0, wdata_0);
-
- val = tegra_mc_read_32(MC_CLIENT_HOTRESET_CTRL1);
- assert(val == wdata_1);
-
- wdata_1 = MC_CLIENT_HOTRESET_CTRL1_RESET_VAL;
- tegra_mc_write_32(MC_CLIENT_HOTRESET_CTRL1, wdata_1);
-
-#endif
-}
-
-static void tegra_memctrl_set_overrides(void)
-{
- tegra_mc_settings_t *plat_mc_settings = tegra_get_mc_settings();
- const mc_txn_override_cfg_t *mc_txn_override_cfgs;
- uint32_t num_txn_override_cfgs;
- uint32_t i, val;
-
- /* Get the settings from the platform */
- assert(plat_mc_settings);
- mc_txn_override_cfgs = plat_mc_settings->txn_override_cfg;
- num_txn_override_cfgs = plat_mc_settings->num_txn_override_cfgs;
-
- /*
- * Set the MC_TXN_OVERRIDE registers for write clients.
- */
- if ((tegra_chipid_is_t186()) &&
- (!tegra_platform_is_silicon() ||
- (tegra_platform_is_silicon() && (tegra_get_chipid_minor() == 1)))) {
-
- /*
- * GPU and NVENC settings for Tegra186 simulation and
- * Silicon rev. A01
- */
- val = tegra_mc_read_32(MC_TXN_OVERRIDE_CONFIG_GPUSWR);
- val &= ~MC_TXN_OVERRIDE_CGID_TAG_MASK;
- tegra_mc_write_32(MC_TXN_OVERRIDE_CONFIG_GPUSWR,
- val | MC_TXN_OVERRIDE_CGID_TAG_ZERO);
-
- val = tegra_mc_read_32(MC_TXN_OVERRIDE_CONFIG_GPUSWR2);
- val &= ~MC_TXN_OVERRIDE_CGID_TAG_MASK;
- tegra_mc_write_32(MC_TXN_OVERRIDE_CONFIG_GPUSWR2,
- val | MC_TXN_OVERRIDE_CGID_TAG_ZERO);
-
- val = tegra_mc_read_32(MC_TXN_OVERRIDE_CONFIG_NVENCSWR);
- val &= ~MC_TXN_OVERRIDE_CGID_TAG_MASK;
- tegra_mc_write_32(MC_TXN_OVERRIDE_CONFIG_NVENCSWR,
- val | MC_TXN_OVERRIDE_CGID_TAG_CLIENT_AXI_ID);
-
- } else {
-
- /*
- * Settings for Tegra186 silicon rev. A02 and onwards.
- */
- for (i = 0; i < num_txn_override_cfgs; i++) {
- val = tegra_mc_read_32(mc_txn_override_cfgs[i].offset);
- val &= ~MC_TXN_OVERRIDE_CGID_TAG_MASK;
- tegra_mc_write_32(mc_txn_override_cfgs[i].offset,
- val | mc_txn_override_cfgs[i].cgid_tag);
- }
- }
+ ; /* do nothing */
}
/*
@@ -347,17 +46,16 @@
uint32_t num_streamid_override_regs;
const mc_streamid_security_cfg_t *mc_streamid_sec_cfgs;
uint32_t num_streamid_sec_cfgs;
- tegra_mc_settings_t *plat_mc_settings = tegra_get_mc_settings();
+ const tegra_mc_settings_t *plat_mc_settings = tegra_get_mc_settings();
uint32_t i;
INFO("Tegra Memory Controller (v2)\n");
-#if ENABLE_SMMU_DEVICE
/* Program the SMMU pagesize */
tegra_smmu_init();
-#endif
+
/* Get the settings from the platform */
- assert(plat_mc_settings);
+ assert(plat_mc_settings != NULL);
mc_streamid_override_regs = plat_mc_settings->streamid_override_cfg;
num_streamid_override_regs = plat_mc_settings->num_streamid_override_cfgs;
mc_streamid_sec_cfgs = plat_mc_settings->streamid_security_cfg;
@@ -398,10 +96,14 @@
* boots with MSS having all control, but ROC provides a performance
* boost as compared to MSS.
*/
- tegra_memctrl_reconfig_mss_clients();
+ if (plat_mc_settings->reconfig_mss_clients != NULL) {
+ plat_mc_settings->reconfig_mss_clients();
+ }
/* Program overrides for MC transactions */
- tegra_memctrl_set_overrides();
+ if (plat_mc_settings->set_txn_overrides != NULL) {
+ plat_mc_settings->set_txn_overrides();
+ }
}
/*
@@ -409,19 +111,27 @@
*/
void tegra_memctrl_restore_settings(void)
{
+ const tegra_mc_settings_t *plat_mc_settings = tegra_get_mc_settings();
+
+ assert(plat_mc_settings != NULL);
+
/*
* Re-configure MSS to allow ROC to deal with ordering of the
* Memory Controller traffic. This is needed as the Memory Controller
* resets during System Suspend with MSS having all control, but ROC
* provides a performance boost as compared to MSS.
*/
- tegra_memctrl_reconfig_mss_clients();
+ if (plat_mc_settings->reconfig_mss_clients != NULL) {
+ plat_mc_settings->reconfig_mss_clients();
+ }
/* Program overrides for MC transactions */
- tegra_memctrl_set_overrides();
+ if (plat_mc_settings->set_txn_overrides != NULL) {
+ plat_mc_settings->set_txn_overrides();
+ }
/* video memory carveout region */
- if (video_mem_base) {
+ if (video_mem_base != 0ULL) {
tegra_mc_write_32(MC_VIDEO_PROTECT_BASE_LO,
(uint32_t)video_mem_base);
tegra_mc_write_32(MC_VIDEO_PROTECT_BASE_HI,
@@ -445,34 +155,9 @@
void tegra_memctrl_tzdram_setup(uint64_t phys_base, uint32_t size_in_bytes)
{
/*
- * Setup the Memory controller to allow only secure accesses to
- * the TZDRAM carveout
+ * Perform platform specific steps.
*/
- INFO("Configuring TrustZone DRAM Memory Carveout\n");
-
- tegra_mc_write_32(MC_SECURITY_CFG0_0, (uint32_t)phys_base);
- tegra_mc_write_32(MC_SECURITY_CFG3_0, (uint32_t)(phys_base >> 32));
- tegra_mc_write_32(MC_SECURITY_CFG1_0, size_in_bytes >> 20);
-
- /*
- * When TZ encryption enabled,
- * We need setup TZDRAM before CPU to access TZ Carveout,
- * otherwise CPU will fetch non-decrypted data.
- * So save TZDRAM setting for retore by SC7 resume FW.
- */
-
- mmio_write_32(TEGRA_SCRATCH_BASE + SECURE_SCRATCH_RSV55_LO,
- tegra_mc_read_32(MC_SECURITY_CFG0_0));
- mmio_write_32(TEGRA_SCRATCH_BASE + SECURE_SCRATCH_RSV55_HI,
- tegra_mc_read_32(MC_SECURITY_CFG3_0));
- mmio_write_32(TEGRA_SCRATCH_BASE + SECURE_SCRATCH_RSV54_HI,
- tegra_mc_read_32(MC_SECURITY_CFG1_0));
-
- /*
- * MCE propagates the security configuration values across the
- * CCPLEX.
- */
- mce_update_gsc_tzdram();
+ plat_memctrl_tzdram_setup(phys_base, size_in_bytes);
}
/*
@@ -494,13 +179,22 @@
* Reset the access configuration registers to restrict access
* to the TZRAM aperture
*/
- for (index = MC_TZRAM_CLIENT_ACCESS_CFG0;
+ for (index = MC_TZRAM_CLIENT_ACCESS0_CFG0;
index < ((uint32_t)MC_TZRAM_CARVEOUT_CFG + (uint32_t)MC_GSC_CONFIG_REGS_SIZE);
index += 4U) {
tegra_mc_write_32(index, 0);
}
/*
+ * Enable CPU access configuration registers to access the TZRAM aperture
+ */
+ if (!tegra_chipid_is_t186()) {
+ val = tegra_mc_read_32(MC_TZRAM_CLIENT_ACCESS1_CFG0);
+ val |= TZRAM_ALLOW_MPCORER | TZRAM_ALLOW_MPCOREW;
+ tegra_mc_write_32(MC_TZRAM_CLIENT_ACCESS1_CFG0, val);
+ }
+
+ /*
* Set the TZRAM base. TZRAM base must be 4k aligned, at least.
*/
assert((phys_base & (uint64_t)0xFFF) == 0U);
@@ -525,8 +219,11 @@
* at all.
*/
val = tegra_mc_read_32(MC_TZRAM_CARVEOUT_CFG);
- val &= ~MC_GSC_ENABLE_TZ_LOCK_BIT;
+ val &= (uint32_t)~MC_GSC_ENABLE_TZ_LOCK_BIT;
val |= MC_GSC_LOCK_CFG_SETTINGS_BIT;
+ if (!tegra_chipid_is_t186()) {
+ val |= MC_GSC_ENABLE_CPU_SECURE_BIT;
+ }
tegra_mc_write_32(MC_TZRAM_CARVEOUT_CFG, val);
/*
@@ -600,18 +297,21 @@
static void tegra_clear_videomem(uintptr_t non_overlap_area_start,
unsigned long long non_overlap_area_size)
{
+ int ret;
+
/*
* Map the NS memory first, clean it and then unmap it.
*/
- mmap_add_dynamic_region(non_overlap_area_start, /* PA */
+ ret = mmap_add_dynamic_region(non_overlap_area_start, /* PA */
non_overlap_area_start, /* VA */
non_overlap_area_size, /* size */
MT_NS | MT_RW | MT_EXECUTE_NEVER); /* attrs */
+ assert(ret == 0);
zero_normalmem((void *)non_overlap_area_start, non_overlap_area_size);
flush_dcache_range(non_overlap_area_start, non_overlap_area_size);
- mmap_remove_dynamic_region(non_overlap_area_start,
+ (void)mmap_remove_dynamic_region(non_overlap_area_start,
non_overlap_area_size);
}
@@ -658,17 +358,19 @@
*/
INFO("Cleaning previous Video Memory Carveout\n");
- if (phys_base > vmem_end_old || video_mem_base > vmem_end_new) {
+ if ((phys_base > vmem_end_old) || (video_mem_base > vmem_end_new)) {
tegra_clear_videomem(video_mem_base,
- (uint64_t)video_mem_size_mb << 20);
+ (uint32_t)video_mem_size_mb << 20U);
} else {
if (video_mem_base < phys_base) {
non_overlap_area_size = phys_base - video_mem_base;
- tegra_clear_videomem(video_mem_base, non_overlap_area_size);
+ tegra_clear_videomem(video_mem_base,
+ (uint32_t)non_overlap_area_size);
}
if (vmem_end_old > vmem_end_new) {
non_overlap_area_size = vmem_end_old - vmem_end_new;
- tegra_clear_videomem(vmem_end_new, non_overlap_area_size);
+ tegra_clear_videomem(vmem_end_new,
+ (uint32_t)non_overlap_area_size);
}
}
@@ -700,3 +402,8 @@
{
; /* do nothing */
}
+
+void tegra_memctrl_clear_pending_interrupts(void)
+{
+ ; /* do nothing */
+}
diff --git a/plat/nvidia/tegra/common/drivers/smmu/smmu.c b/plat/nvidia/tegra/common/drivers/smmu/smmu.c
index 610f32f..8c1b899 100644
--- a/plat/nvidia/tegra/common/drivers/smmu/smmu.c
+++ b/plat/nvidia/tegra/common/drivers/smmu/smmu.c
@@ -19,47 +19,55 @@
/* SMMU IDs currently supported by the driver */
enum {
- TEGRA_SMMU0,
+ TEGRA_SMMU0 = 0U,
TEGRA_SMMU1,
TEGRA_SMMU2
};
static uint32_t tegra_smmu_read_32(uint32_t smmu_id, uint32_t off)
{
+ uint32_t ret = 0U;
+
#if defined(TEGRA_SMMU0_BASE)
- if (smmu_id == TEGRA_SMMU0)
- return mmio_read_32(TEGRA_SMMU0_BASE + off);
+ if (smmu_id == TEGRA_SMMU0) {
+ ret = mmio_read_32(TEGRA_SMMU0_BASE + (uint64_t)off);
+ }
#endif
#if defined(TEGRA_SMMU1_BASE)
- if (smmu_id == TEGRA_SMMU1)
- return mmio_read_32(TEGRA_SMMU1_BASE + off);
+ if (smmu_id == TEGRA_SMMU1) {
+ ret = mmio_read_32(TEGRA_SMMU1_BASE + (uint64_t)off);
+ }
#endif
#if defined(TEGRA_SMMU2_BASE)
- if (smmu_id == TEGRA_SMMU2)
- return mmio_read_32(TEGRA_SMMU2_BASE + off);
+ if (smmu_id == TEGRA_SMMU2) {
+ ret = mmio_read_32(TEGRA_SMMU2_BASE + (uint64_t)off);
+ }
#endif
- return 0;
+ return ret;
}
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);
+ if (smmu_id == TEGRA_SMMU0) {
+ mmio_write_32(TEGRA_SMMU0_BASE + (uint64_t)off, val);
+ }
#endif
#if defined(TEGRA_SMMU1_BASE)
- if (smmu_id == TEGRA_SMMU1)
- mmio_write_32(TEGRA_SMMU1_BASE + off, val);
+ if (smmu_id == TEGRA_SMMU1) {
+ mmio_write_32(TEGRA_SMMU1_BASE + (uint64_t)off, val);
+ }
#endif
#if defined(TEGRA_SMMU2_BASE)
- if (smmu_id == TEGRA_SMMU2)
- mmio_write_32(TEGRA_SMMU2_BASE + off, val);
+ if (smmu_id == TEGRA_SMMU2) {
+ mmio_write_32(TEGRA_SMMU2_BASE + (uint64_t)off, val);
+ }
#endif
}
@@ -70,52 +78,55 @@
{
uint32_t i, num_entries = 0;
smmu_regs_t *smmu_ctx_regs;
- plat_params_from_bl2_t *params_from_bl2 = bl31_get_plat_params();
+ const plat_params_from_bl2_t *params_from_bl2 = bl31_get_plat_params();
uint64_t tzdram_base = params_from_bl2->tzdram_base;
uint64_t tzdram_end = tzdram_base + params_from_bl2->tzdram_size;
uint32_t reg_id1, pgshift, cb_size;
/* sanity check SMMU settings c*/
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));
+ pgshift = ((reg_id1 & ID1_PAGESIZE) != 0U) ? 16U : 12U;
+ cb_size = ((uint32_t)2 << pgshift) * \
+ ((uint32_t)1 << (((reg_id1 >> ID1_NUMPAGENDXB_SHIFT) & ID1_NUMPAGENDXB_MASK) + 1U));
assert(!((pgshift != PGSHIFT) || (cb_size != CB_SIZE)));
assert((smmu_ctx_addr >= tzdram_base) && (smmu_ctx_addr <= tzdram_end));
/* get SMMU context table */
smmu_ctx_regs = plat_get_smmu_ctx();
- assert(smmu_ctx_regs);
+ assert(smmu_ctx_regs != NULL);
/*
* smmu_ctx_regs[0].val contains the size of the context table minus
* the last entry. Sanity check the table size before we start with
* the context save operation.
*/
- while (smmu_ctx_regs[num_entries].val != 0xFFFFFFFFU) {
+ while ((smmu_ctx_regs[num_entries].reg != 0xFFFFFFFFU)) {
num_entries++;
}
/* panic if the sizes do not match */
- if (num_entries != smmu_ctx_regs[0].val)
+ if (num_entries != smmu_ctx_regs[0].val) {
+ ERROR("SMMU context size mismatch!");
panic();
+ }
/* save SMMU register values */
- for (i = 1; i < num_entries; i++)
+ for (i = 1U; i < num_entries; i++) {
smmu_ctx_regs[i].val = mmio_read_32(smmu_ctx_regs[i].reg);
+ }
/* increment by 1 to take care of the last entry */
num_entries++;
/* Save SMMU config settings */
- memcpy16((void *)(uintptr_t)smmu_ctx_addr, (void *)smmu_ctx_regs,
- (sizeof(smmu_regs_t) * num_entries));
+ (void)memcpy16((uint8_t *)smmu_ctx_addr, (uint8_t *)smmu_ctx_regs,
+ (sizeof(smmu_regs_t) * num_entries));
/* save the SMMU table address */
- mmio_write_32(TEGRA_SCRATCH_BASE + SECURE_SCRATCH_RSV11_LO,
+ mmio_write_32(TEGRA_SCRATCH_BASE + SCRATCH_SMMU_TABLE_ADDR_LO,
(uint32_t)smmu_ctx_addr);
- mmio_write_32(TEGRA_SCRATCH_BASE + SECURE_SCRATCH_RSV11_HI,
+ mmio_write_32(TEGRA_SCRATCH_BASE + SCRATCH_SMMU_TABLE_ADDR_HI,
(uint32_t)(smmu_ctx_addr >> 32));
}
@@ -128,17 +139,18 @@
void tegra_smmu_init(void)
{
uint32_t val, cb_idx, smmu_id, ctx_base;
+ uint32_t smmu_counter = plat_get_num_smmu_devices();
- for (smmu_id = 0; smmu_id < NUM_SMMU_DEVICES; smmu_id++) {
+ for (smmu_id = 0U; smmu_id < smmu_counter; 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;
+ val &= (uint32_t)~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_id, SMMU_GNSR_ACR);
- val &= ~SMMU_ACR_CACHE_LOCK_ENABLE_BIT;
+ val &= (uint32_t)~SMMU_ACR_CACHE_LOCK_ENABLE_BIT;
tegra_smmu_write_32(smmu_id, SMMU_GNSR_ACR, val);
/* disable TCU prefetch for all contexts */
@@ -147,19 +159,19 @@
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;
+ val &= (uint32_t)~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;
+ val |= (uint32_t)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;
+ val |= (uint32_t)SMMU_ACR_CACHE_LOCK_ENABLE_BIT;
tegra_smmu_write_32(smmu_id, SMMU_GSR0_SECURE_ACR, val);
}
}
diff --git a/plat/nvidia/tegra/common/drivers/spe/shared_console.S b/plat/nvidia/tegra/common/drivers/spe/shared_console.S
new file mode 100644
index 0000000..a9f0334
--- /dev/null
+++ b/plat/nvidia/tegra/common/drivers/spe/shared_console.S
@@ -0,0 +1,118 @@
+/*
+ * Copyright (c) 2017, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+#include <asm_macros.S>
+
+#define CONSOLE_NUM_BYTES_SHIFT 24
+#define CONSOLE_FLUSH_DATA_TO_PORT (1 << 26)
+#define CONSOLE_RING_DOORBELL (1 << 31)
+#define CONSOLE_IS_BUSY (1 << 31)
+#define CONSOLE_WRITE (CONSOLE_RING_DOORBELL | CONSOLE_FLUSH_DATA_TO_PORT)
+
+ /*
+ * This file contains a driver implementation to make use of the
+ * real console implementation provided by the SPE firmware running
+ * SoCs after Tegra186.
+ *
+ * This console is shared by multiple components and the SPE firmware
+ * finally displays everything on the UART port.
+ */
+
+ .globl console_core_init
+ .globl console_core_putc
+ .globl console_core_getc
+ .globl console_core_flush
+
+ /* -----------------------------------------------
+ * int console_core_init(uintptr_t base_addr,
+ * unsigned int uart_clk, unsigned int baud_rate)
+ * Function to initialize the console without a
+ * C Runtime to print debug information. This
+ * function will be accessed by console_init and
+ * crash reporting.
+ * In: x0 - console base address
+ * w1 - Uart clock in Hz
+ * w2 - Baud rate
+ * Out: return 1 on success else 0 on error
+ * Clobber list : x1, x2
+ * -----------------------------------------------
+ */
+func console_core_init
+ /* Check the input base address */
+ cbz x0, core_init_fail
+ mov w0, #1
+ ret
+core_init_fail:
+ mov w0, wzr
+ ret
+endfunc console_core_init
+
+ /* --------------------------------------------------------
+ * int console_core_putc(int c, uintptr_t base_addr)
+ * Function to output a character over the console. It
+ * returns the character printed on success or -1 on error.
+ * In : w0 - character to be printed
+ * x1 - console base address
+ * Out : return -1 on error else return character.
+ * Clobber list : x2
+ * --------------------------------------------------------
+ */
+func console_core_putc
+ /* Check the input parameter */
+ cbz x1, putc_error
+
+ /* wait until spe is ready */
+1: ldr w2, [x1]
+ and w2, w2, #CONSOLE_IS_BUSY
+ cbnz w2, 1b
+
+ /* spe is ready */
+ mov w2, w0
+ and w2, w2, #0xFF
+ mov w3, #(CONSOLE_WRITE | (1 << CONSOLE_NUM_BYTES_SHIFT))
+ orr w2, w2, w3
+ str w2, [x1]
+
+ ret
+putc_error:
+ mov w0, #-1
+ ret
+endfunc console_core_putc
+
+ /* ---------------------------------------------
+ * int console_core_getc(uintptr_t base_addr)
+ * Function to get a character from the console.
+ * It returns the character grabbed on success
+ * or -1 on error.
+ * In : x0 - console base address
+ * Clobber list : x0, x1
+ * ---------------------------------------------
+ */
+func console_core_getc
+ mov w0, #-1
+ ret
+endfunc console_core_getc
+
+ /* ---------------------------------------------
+ * int console_core_flush(uintptr_t base_addr)
+ * Function to force a write of all buffered
+ * data that hasn't been output.
+ * In : x0 - console base address
+ * Out : return -1 on error else return 0.
+ * Clobber list : x0, x1
+ * ---------------------------------------------
+ */
+func console_core_flush
+ cbz x0, flush_error
+
+ /* flush console */
+ mov w1, #CONSOLE_WRITE
+ str w1, [x0]
+ mov w0, #0
+ ret
+flush_error:
+ mov w0, #-1
+ ret
+endfunc console_core_flush
diff --git a/plat/nvidia/tegra/common/lib/debug/profiler.c b/plat/nvidia/tegra/common/lib/debug/profiler.c
new file mode 100644
index 0000000..d4c3f95
--- /dev/null
+++ b/plat/nvidia/tegra/common/lib/debug/profiler.c
@@ -0,0 +1,144 @@
+/*
+ * Copyright (c) 2017, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+/*******************************************************************************
+ * The profiler stores the timestamps captured during cold boot to the shared
+ * memory for the non-secure world. The non-secure world driver parses the
+ * shared memory block and writes the contents to a file on the device, which
+ * can be later extracted for analysis.
+ *
+ * Profiler memory map
+ *
+ * TOP --------------------------- ---
+ * Trusted OS timestamps 3KB
+ * --------------------------- ---
+ * Trusted Firmware timestamps 1KB
+ * BASE --------------------------- ---
+ *
+ ******************************************************************************/
+
+#include <arch.h>
+#include <arch_helpers.h>
+#include <assert.h>
+#include <mmio.h>
+#include <profiler.h>
+#include <stdbool.h>
+#include <string.h>
+#include <utils_def.h>
+#include <xlat_tables_v2.h>
+
+static uint64_t shmem_base_addr;
+
+#define MAX_PROFILER_RECORDS U(16)
+#define TAG_LEN_BYTES U(56)
+
+/*******************************************************************************
+ * Profiler entry format
+ ******************************************************************************/
+typedef struct {
+ /* text explaining the timestamp location in code */
+ uint8_t tag[TAG_LEN_BYTES];
+ /* timestamp value */
+ uint64_t timestamp;
+} profiler_rec_t;
+
+static profiler_rec_t *head, *cur, *tail;
+static uint32_t tmr;
+static bool is_shmem_buf_mapped;
+
+/*******************************************************************************
+ * Initialise the profiling library
+ ******************************************************************************/
+void boot_profiler_init(uint64_t shmem_base, uint32_t tmr_base)
+{
+ uint64_t shmem_end_base;
+
+ assert(shmem_base != ULL(0));
+ assert(tmr_base != U(0));
+
+ /* store the buffer address */
+ shmem_base_addr = shmem_base;
+
+ /* calculate the base address of the last record */
+ shmem_end_base = shmem_base + (sizeof(profiler_rec_t) *
+ (MAX_PROFILER_RECORDS - U(1)));
+
+ /* calculate the head, tail and cur values */
+ head = (profiler_rec_t *)shmem_base;
+ tail = (profiler_rec_t *)shmem_end_base;
+ cur = head;
+
+ /* timer used to get the current timestamp */
+ tmr = tmr_base;
+}
+
+/*******************************************************************************
+ * Add tag and timestamp to profiler
+ ******************************************************************************/
+void boot_profiler_add_record(const char *str)
+{
+ unsigned int len;
+
+ /* calculate the length of the tag */
+ if (((unsigned int)strlen(str) + U(1)) > TAG_LEN_BYTES) {
+ len = TAG_LEN_BYTES;
+ } else {
+ len = (unsigned int)strlen(str) + U(1);
+ }
+
+ if (head != NULL) {
+
+ /*
+ * The profiler runs with/without MMU enabled. Check
+ * if MMU is enabled and memmap the shmem buffer, in
+ * case it is.
+ */
+ if ((!is_shmem_buf_mapped) &&
+ ((read_sctlr_el3() & SCTLR_M_BIT) != U(0))) {
+
+ (void)mmap_add_dynamic_region(shmem_base_addr,
+ shmem_base_addr,
+ PROFILER_SIZE_BYTES,
+ (MT_NS | MT_RW | MT_EXECUTE_NEVER));
+
+ is_shmem_buf_mapped = true;
+ }
+
+ /* write the tag and timestamp to buffer */
+ (void)snprintf((char *)cur->tag, len, "%s", str);
+ cur->timestamp = mmio_read_32(tmr);
+
+ /* start from head if we reached the end */
+ if (cur == tail) {
+ cur = head;
+ } else {
+ cur++;
+ }
+ }
+}
+
+/*******************************************************************************
+ * Deinint the profiler
+ ******************************************************************************/
+void boot_profiler_deinit(void)
+{
+ if (shmem_base_addr != ULL(0)) {
+
+ /* clean up resources */
+ cur = NULL;
+ head = NULL;
+ tail = NULL;
+
+ /* flush the shmem for it to be visible to the NS world */
+ flush_dcache_range(shmem_base_addr, PROFILER_SIZE_BYTES);
+
+ /* unmap the shmem buffer */
+ if (is_shmem_buf_mapped) {
+ (void)mmap_remove_dynamic_region(shmem_base_addr,
+ PROFILER_SIZE_BYTES);
+ }
+ }
+}
diff --git a/plat/nvidia/tegra/common/tegra_bl31_setup.c b/plat/nvidia/tegra/common/tegra_bl31_setup.c
index 0806307..908e4f2 100644
--- a/plat/nvidia/tegra/common/tegra_bl31_setup.c
+++ b/plat/nvidia/tegra/common/tegra_bl31_setup.c
@@ -26,6 +26,7 @@
#include <plat/common/platform.h>
#include <memctrl.h>
+#include <profiler.h>
#include <tegra_def.h>
#include <tegra_platform.h>
#include <tegra_private.h>
@@ -40,20 +41,19 @@
* of trusted SRAM
******************************************************************************/
-IMPORT_SYM(unsigned long, __RW_START__, BL31_RW_START);
-IMPORT_SYM(unsigned long, __RW_END__, BL31_RW_END);
-IMPORT_SYM(unsigned long, __RODATA_START__, BL31_RODATA_BASE);
-IMPORT_SYM(unsigned long, __RODATA_END__, BL31_RODATA_END);
-IMPORT_SYM(unsigned long, __TEXT_START__, TEXT_START);
-IMPORT_SYM(unsigned long, __TEXT_END__, TEXT_END);
+IMPORT_SYM(uint64_t, __RW_START__, BL31_RW_START);
+IMPORT_SYM(uint64_t, __RW_END__, BL31_RW_END);
+IMPORT_SYM(uint64_t, __RODATA_START__, BL31_RODATA_BASE);
+IMPORT_SYM(uint64_t, __RODATA_END__, BL31_RODATA_END);
+IMPORT_SYM(uint64_t, __TEXT_START__, TEXT_START);
+IMPORT_SYM(uint64_t, __TEXT_END__, TEXT_END);
extern uint64_t tegra_bl31_phys_base;
extern uint64_t tegra_console_base;
-
static entry_point_info_t bl33_image_ep_info, bl32_image_ep_info;
static plat_params_from_bl2_t plat_bl31_params_from_bl2 = {
- .tzdram_size = (uint64_t)TZDRAM_SIZE
+ .tzdram_size = TZDRAM_SIZE
};
static unsigned long bl32_mem_size;
static unsigned long bl32_boot_params;
@@ -70,6 +70,7 @@
#pragma weak plat_early_platform_setup
#pragma weak plat_get_bl31_params
#pragma weak plat_get_bl31_plat_params
+#pragma weak plat_late_platform_setup
void plat_early_platform_setup(void)
{
@@ -86,6 +87,11 @@
return NULL;
}
+void plat_late_platform_setup(void)
+{
+ ; /* do nothing */
+}
+
/*******************************************************************************
* Return a pointer to the 'entry_point_info' structure of the next image for
* security state specified. BL33 corresponds to the non-secure image type
@@ -93,14 +99,16 @@
******************************************************************************/
entry_point_info_t *bl31_plat_get_next_image_ep_info(uint32_t type)
{
- if (type == NON_SECURE)
- return &bl33_image_ep_info;
+ entry_point_info_t *ep = NULL;
/* return BL32 entry point info if it is valid */
- if (type == SECURE && bl32_image_ep_info.pc)
- return &bl32_image_ep_info;
+ if (type == NON_SECURE) {
+ ep = &bl33_image_ep_info;
+ } else if ((type == SECURE) && (bl32_image_ep_info.pc != 0U)) {
+ ep = &bl32_image_ep_info;
+ }
- return NULL;
+ return ep;
}
/*******************************************************************************
@@ -124,6 +132,7 @@
image_info_t bl32_img_info = { {0} };
uint64_t tzdram_start, tzdram_end, bl32_start, bl32_end;
uint32_t console_clock;
+ int32_t ret;
/*
* For RESET_TO_BL31 systems, BL31 is the first bootloader to run so
@@ -131,20 +140,22 @@
* might use custom ways to get arguments, so provide handlers which
* they can override.
*/
- if (arg_from_bl2 == NULL)
+ if (arg_from_bl2 == NULL) {
arg_from_bl2 = plat_get_bl31_params();
- if (plat_params == NULL)
+ }
+ if (plat_params == NULL) {
plat_params = plat_get_bl31_plat_params();
+ }
/*
* Copy BL3-3, BL3-2 entry point information.
* They are stored in Secure RAM, in BL2's address space.
*/
- assert(arg_from_bl2);
- assert(arg_from_bl2->bl33_ep_info);
+ assert(arg_from_bl2 != NULL);
+ assert(arg_from_bl2->bl33_ep_info != NULL);
bl33_image_ep_info = *arg_from_bl2->bl33_ep_info;
- if (arg_from_bl2->bl32_ep_info) {
+ if (arg_from_bl2->bl32_ep_info != NULL) {
bl32_image_ep_info = *arg_from_bl2->bl32_ep_info;
bl32_mem_size = arg_from_bl2->bl32_ep_info->args.arg0;
bl32_boot_params = arg_from_bl2->bl32_ep_info->args.arg2;
@@ -153,7 +164,7 @@
/*
* Parse platform specific parameters - TZDRAM aperture base and size
*/
- assert(plat_params);
+ assert(plat_params != NULL);
plat_bl31_params_from_bl2.tzdram_base = plat_params->tzdram_base;
plat_bl31_params_from_bl2.tzdram_size = plat_params->tzdram_size;
plat_bl31_params_from_bl2.uart_id = plat_params->uart_id;
@@ -163,14 +174,15 @@
* It is very important that we run either from TZDRAM or TZSRAM base.
* Add an explicit check here.
*/
- if ((plat_bl31_params_from_bl2.tzdram_base != BL31_BASE) &&
- (TEGRA_TZRAM_BASE != BL31_BASE))
+ if ((plat_bl31_params_from_bl2.tzdram_base != (uint64_t)BL31_BASE) &&
+ (TEGRA_TZRAM_BASE != BL31_BASE)) {
panic();
+ }
/*
* Reference clock used by the FPGAs is a lot slower.
*/
- if (tegra_platform_is_fpga() == 1U) {
+ if (tegra_platform_is_fpga()) {
console_clock = TEGRA_BOOT_UART_CLK_13_MHZ;
} else {
console_clock = TEGRA_BOOT_UART_CLK_408_MHZ;
@@ -182,31 +194,60 @@
*/
tegra_console_base = plat_get_console_from_id(plat_params->uart_id);
- if (tegra_console_base != (uint64_t)0) {
+ if (tegra_console_base != 0U) {
/*
* Configure the UART port to be used as the console
*/
- console_init(tegra_console_base, console_clock,
+ (void)console_init(tegra_console_base, console_clock,
TEGRA_CONSOLE_BAUDRATE);
}
/*
+ * The previous bootloader passes the base address of the shared memory
+ * location to store the boot profiler logs. Sanity check the
+ * address and initilise the profiler library, if it looks ok.
+ */
+ if (plat_params->boot_profiler_shmem_base != 0ULL) {
+
+ ret = bl31_check_ns_address(plat_params->boot_profiler_shmem_base,
+ PROFILER_SIZE_BYTES);
+ if (ret == (int32_t)0) {
+
+ /* store the membase for the profiler lib */
+ plat_bl31_params_from_bl2.boot_profiler_shmem_base =
+ plat_params->boot_profiler_shmem_base;
+
+ /* initialise the profiler library */
+ boot_profiler_init(plat_params->boot_profiler_shmem_base,
+ TEGRA_TMRUS_BASE);
+ }
+ }
+
+ /*
+ * Add timestamp for platform early setup entry.
+ */
+ boot_profiler_add_record("[TF] early setup entry");
+
+ /*
* Initialize delay timer
*/
tegra_delay_timer_init();
+ /* Early platform setup for Tegra SoCs */
+ plat_early_platform_setup();
+
/*
* Do initial security configuration to allow DRAM/device access.
*/
tegra_memctrl_tzdram_setup(plat_bl31_params_from_bl2.tzdram_base,
- plat_bl31_params_from_bl2.tzdram_size);
+ (uint32_t)plat_bl31_params_from_bl2.tzdram_size);
/*
* The previous bootloader might not have placed the BL32 image
* inside the TZDRAM. We check the BL32 image info to find out
* the base/PC values and relocate the image if necessary.
*/
- if (arg_from_bl2->bl32_image_info) {
+ if (arg_from_bl2->bl32_image_info != NULL) {
bl32_img_info = *arg_from_bl2->bl32_image_info;
@@ -223,11 +264,11 @@
assert(bl32_image_ep_info.pc < tzdram_end);
/* relocate BL32 */
- if (bl32_start >= tzdram_end || bl32_end <= tzdram_start) {
+ if ((bl32_start >= tzdram_end) || (bl32_end <= tzdram_start)) {
INFO("Relocate BL32 to TZDRAM\n");
- memcpy16((void *)(uintptr_t)bl32_image_ep_info.pc,
+ (void)memcpy16((void *)(uintptr_t)bl32_image_ep_info.pc,
(void *)(uintptr_t)bl32_start,
bl32_img_info.image_size);
@@ -237,8 +278,10 @@
}
}
- /* Early platform setup for Tegra SoCs */
- plat_early_platform_setup();
+ /*
+ * Add timestamp for platform early setup exit.
+ */
+ boot_profiler_add_record("[TF] early setup exit");
INFO("BL3-1: Boot CPU: %s Processor [%lx]\n",
(((read_midr() >> MIDR_IMPL_SHIFT) & MIDR_IMPL_MASK)
@@ -256,6 +299,9 @@
if (args->arg4 != 0U) {
args->arg2 = args->arg4;
}
+
+ /* Profiler Carveout Base */
+ args->arg3 = args->arg5;
}
#endif
@@ -264,7 +310,10 @@
******************************************************************************/
void bl31_platform_setup(void)
{
- uint32_t tmp_reg;
+ /*
+ * Add timestamp for platform setup entry.
+ */
+ boot_profiler_add_record("[TF] plat setup entry");
/* Initialize the gic cpu and distributor interfaces */
plat_gic_setup();
@@ -285,9 +334,17 @@
*/
tegra_memctrl_tzram_setup(TEGRA_TZRAM_BASE, TEGRA_TZRAM_SIZE);
- /* Set the next EL to be AArch64 */
- tmp_reg = SCR_RES1_BITS | SCR_RW_BIT;
- write_scr(tmp_reg);
+ /*
+ * Late setup handler to allow platforms to performs additional
+ * functionality.
+ * This handler gets called with MMU enabled.
+ */
+ plat_late_platform_setup();
+
+ /*
+ * Add timestamp for platform setup exit.
+ */
+ boot_profiler_add_record("[TF] plat setup exit");
INFO("BL3-1: Tegra platform setup complete\n");
}
@@ -298,6 +355,15 @@
void bl31_plat_runtime_setup(void)
{
/*
+ * During cold boot, it is observed that the arbitration
+ * bit is set in the Memory controller leading to false
+ * error interrupts in the non-secure world. To avoid
+ * this, clean the interrupt status register before
+ * booting into the non-secure world
+ */
+ tegra_memctrl_clear_pending_interrupts();
+
+ /*
* During boot, USB3 and flash media (SDMMC/SATA) devices need
* access to IRAM. Because these clients connect to the MC and
* do not have a direct path to the IRAM, the MC implements AHB
@@ -307,6 +373,12 @@
* disabled before we jump to the non-secure world.
*/
tegra_memctrl_disable_ahb_redirection();
+
+ /*
+ * Add final timestamp before exiting BL31.
+ */
+ boot_profiler_add_record("[TF] bl31 exit");
+ boot_profiler_deinit();
}
/*******************************************************************************
@@ -315,17 +387,22 @@
******************************************************************************/
void bl31_plat_arch_setup(void)
{
- unsigned long rw_start = BL31_RW_START;
- unsigned long rw_size = BL31_RW_END - BL31_RW_START;
- unsigned long rodata_start = BL31_RODATA_BASE;
- unsigned long rodata_size = BL31_RODATA_END - BL31_RODATA_BASE;
- unsigned long code_base = TEXT_START;
- unsigned long code_size = TEXT_END - TEXT_START;
+ uint64_t rw_start = BL31_RW_START;
+ uint64_t rw_size = BL31_RW_END - BL31_RW_START;
+ uint64_t rodata_start = BL31_RODATA_BASE;
+ uint64_t rodata_size = BL31_RODATA_END - BL31_RODATA_BASE;
+ uint64_t code_base = TEXT_START;
+ uint64_t code_size = TEXT_END - TEXT_START;
const mmap_region_t *plat_mmio_map = NULL;
#if USE_COHERENT_MEM
- unsigned long coh_start, coh_size;
+ uint32_t coh_start, coh_size;
#endif
- plat_params_from_bl2_t *params_from_bl2 = bl31_get_plat_params();
+ const plat_params_from_bl2_t *params_from_bl2 = bl31_get_plat_params();
+
+ /*
+ * Add timestamp for arch setup entry.
+ */
+ boot_profiler_add_record("[TF] arch setup entry");
/* add memory regions */
mmap_add_region(rw_start, rw_start,
@@ -352,21 +429,22 @@
mmap_add_region(coh_start, coh_start,
coh_size,
- MT_DEVICE | MT_RW | MT_SECURE);
+ (uint8_t)MT_DEVICE | (uint8_t)MT_RW | (uint8_t)MT_SECURE);
#endif
/* map on-chip free running uS timer */
- mmap_add_region(page_align((uint64_t)TEGRA_TMRUS_BASE, 0),
- page_align((uint64_t)TEGRA_TMRUS_BASE, 0),
- (uint64_t)TEGRA_TMRUS_SIZE,
- MT_DEVICE | MT_RO | MT_SECURE);
+ mmap_add_region(page_align(TEGRA_TMRUS_BASE, 0),
+ page_align(TEGRA_TMRUS_BASE, 0),
+ TEGRA_TMRUS_SIZE,
+ (uint8_t)MT_DEVICE | (uint8_t)MT_RO | (uint8_t)MT_SECURE);
/* add MMIO space */
plat_mmio_map = plat_get_mmio_map();
- if (plat_mmio_map)
+ if (plat_mmio_map != NULL) {
mmap_add(plat_mmio_map);
- else
+ } else {
WARN("MMIO map not available\n");
+ }
/* set up translation tables */
init_xlat_tables();
@@ -374,33 +452,41 @@
/* enable the MMU */
enable_mmu_el3(0);
+ /*
+ * Add timestamp for arch setup exit.
+ */
+ boot_profiler_add_record("[TF] arch setup exit");
+
INFO("BL3-1: Tegra: MMU enabled\n");
}
/*******************************************************************************
* Check if the given NS DRAM range is valid
******************************************************************************/
-int bl31_check_ns_address(uint64_t base, uint64_t size_in_bytes)
+int32_t bl31_check_ns_address(uint64_t base, uint64_t size_in_bytes)
{
- uint64_t end = base + size_in_bytes;
+ uint64_t end = base + size_in_bytes - U(1);
+ int32_t ret = 0;
/*
* Check if the NS DRAM address is valid
*/
- if ((base < TEGRA_DRAM_BASE) || (end > TEGRA_DRAM_END)) {
+ if ((base < TEGRA_DRAM_BASE) || (base >= TEGRA_DRAM_END) ||
+ (end > TEGRA_DRAM_END)) {
+
ERROR("NS address is out-of-bounds!\n");
- return -EFAULT;
+ ret = -EFAULT;
}
/*
* TZDRAM aperture contains the BL31 and BL32 images, so we need
* to check if the NS DRAM range overlaps the TZDRAM aperture.
*/
- if ((base < TZDRAM_END) && (end > tegra_bl31_phys_base)) {
+ if ((base < (uint64_t)TZDRAM_END) && (end > tegra_bl31_phys_base)) {
ERROR("NS address overlaps TZDRAM!\n");
- return -ENOTSUP;
+ ret = -ENOTSUP;
}
/* valid NS address */
- return 0;
+ return ret;
}
diff --git a/plat/nvidia/tegra/common/tegra_common.mk b/plat/nvidia/tegra/common/tegra_common.mk
index 6a0854e..d9eec4d 100644
--- a/plat/nvidia/tegra/common/tegra_common.mk
+++ b/plat/nvidia/tegra/common/tegra_common.mk
@@ -5,6 +5,7 @@
#
PLAT_INCLUDES := -Iplat/nvidia/tegra/include/drivers \
+ -Iplat/nvidia/tegra/include/lib \
-Iplat/nvidia/tegra/include \
-Iplat/nvidia/tegra/include/${TARGET_SOC}
@@ -21,10 +22,10 @@
BL31_SOURCES += drivers/console/aarch64/console.S \
drivers/delay_timer/delay_timer.c \
- drivers/ti/uart/aarch64/16550_console.S \
${TEGRA_GICv2_SOURCES} \
${COMMON_DIR}/aarch64/tegra_helpers.S \
${COMMON_DIR}/drivers/pmc/pmc.c \
+ ${COMMON_DIR}/lib/debug/profiler.c \
${COMMON_DIR}/tegra_bl31_setup.c \
${COMMON_DIR}/tegra_delay_timer.c \
${COMMON_DIR}/tegra_fiq_glue.c \
diff --git a/plat/nvidia/tegra/common/tegra_fiq_glue.c b/plat/nvidia/tegra/common/tegra_fiq_glue.c
index 9a43f76..cab2e5e 100644
--- a/plat/nvidia/tegra/common/tegra_fiq_glue.c
+++ b/plat/nvidia/tegra/common/tegra_fiq_glue.c
@@ -65,7 +65,7 @@
* Set the new ELR to continue execution in the NS world using the
* FIQ handler registered earlier.
*/
- assert(ns_fiq_handler_addr);
+ assert(ns_fiq_handler_addr != 0ULL);
write_ctx_reg((el3state_ctx), (uint32_t)(CTX_ELR_EL3), (ns_fiq_handler_addr));
/*
diff --git a/plat/nvidia/tegra/common/tegra_platform.c b/plat/nvidia/tegra/common/tegra_platform.c
index 72da126..c1e4209 100644
--- a/plat/nvidia/tegra/common/tegra_platform.c
+++ b/plat/nvidia/tegra/common/tegra_platform.c
@@ -15,7 +15,7 @@
* Tegra platforms
******************************************************************************/
typedef enum tegra_platform {
- TEGRA_PLATFORM_SILICON = 0,
+ TEGRA_PLATFORM_SILICON = 0U,
TEGRA_PLATFORM_QT,
TEGRA_PLATFORM_FPGA,
TEGRA_PLATFORM_EMULATION,
@@ -83,7 +83,7 @@
{
uint32_t chip_id = ((tegra_get_chipid() >> CHIP_ID_SHIFT) & CHIP_ID_MASK);
- return (chip_id == (uint32_t)TEGRA_CHIPID_TEGRA13);
+ return (chip_id == TEGRA_CHIPID_TEGRA13);
}
bool tegra_chipid_is_t186(void)
@@ -97,12 +97,12 @@
{
uint32_t chip_id = (tegra_get_chipid() >> CHIP_ID_SHIFT) & CHIP_ID_MASK;
- return (chip_id == (uint32_t)TEGRA_CHIPID_TEGRA21);
+ return (chip_id == TEGRA_CHIPID_TEGRA21);
}
bool tegra_chipid_is_t210_b01(void)
{
- return (tegra_chipid_is_t210() && (tegra_get_chipid_major() == 0x2UL));
+ return (tegra_chipid_is_t210() && (tegra_get_chipid_major() == 0x2U));
}
/*
diff --git a/plat/nvidia/tegra/common/tegra_pm.c b/plat/nvidia/tegra/common/tegra_pm.c
index ce44983..2805272 100644
--- a/plat/nvidia/tegra/common/tegra_pm.c
+++ b/plat/nvidia/tegra/common/tegra_pm.c
@@ -50,37 +50,42 @@
#pragma weak tegra_soc_prepare_system_off
#pragma weak tegra_soc_get_target_pwr_state
-int tegra_soc_pwr_domain_suspend_pwrdown_early(const psci_power_state_t *target_state)
+int32_t tegra_soc_pwr_domain_suspend_pwrdown_early(const psci_power_state_t *target_state)
{
return PSCI_E_NOT_SUPPORTED;
}
-int tegra_soc_pwr_domain_suspend(const psci_power_state_t *target_state)
+int32_t tegra_soc_pwr_domain_suspend(const psci_power_state_t *target_state)
{
+ (void)target_state;
return PSCI_E_NOT_SUPPORTED;
}
-int tegra_soc_pwr_domain_on(u_register_t mpidr)
+int32_t tegra_soc_pwr_domain_on(u_register_t mpidr)
{
+ (void)mpidr;
return PSCI_E_SUCCESS;
}
-int tegra_soc_pwr_domain_off(const psci_power_state_t *target_state)
+int32_t tegra_soc_pwr_domain_off(const psci_power_state_t *target_state)
{
+ (void)target_state;
return PSCI_E_SUCCESS;
}
-int tegra_soc_pwr_domain_on_finish(const psci_power_state_t *target_state)
+int32_t tegra_soc_pwr_domain_on_finish(const psci_power_state_t *target_state)
{
+ (void)target_state;
return PSCI_E_SUCCESS;
}
-int tegra_soc_pwr_domain_power_down_wfi(const psci_power_state_t *target_state)
+int32_t tegra_soc_pwr_domain_power_down_wfi(const psci_power_state_t *target_state)
{
+ (void)target_state;
return PSCI_E_SUCCESS;
}
-int tegra_soc_prepare_system_reset(void)
+int32_t tegra_soc_prepare_system_reset(void)
{
return PSCI_E_SUCCESS;
}
@@ -91,19 +96,26 @@
panic();
}
-plat_local_state_t tegra_soc_get_target_pwr_state(unsigned int lvl,
+plat_local_state_t tegra_soc_get_target_pwr_state(uint32_t lvl,
const plat_local_state_t *states,
- unsigned int ncpu)
+ uint32_t ncpu)
{
plat_local_state_t target = PLAT_MAX_OFF_STATE, temp;
+ uint32_t num_cpu = ncpu;
+ const plat_local_state_t *local_state = states;
- assert(ncpu);
+ (void)lvl;
+
+ assert(ncpu != 0U);
do {
- temp = *states++;
- if ((temp < target))
+ temp = *local_state;
+ if ((temp < target)) {
target = temp;
- } while (--ncpu);
+ }
+ --num_cpu;
+ local_state++;
+ } while (num_cpu != 0U);
return target;
}
@@ -117,8 +129,9 @@
void tegra_get_sys_suspend_power_state(psci_power_state_t *req_state)
{
/* all affinities use system suspend state id */
- for (uint32_t i = MPIDR_AFFLVL0; i <= PLAT_MAX_PWR_LVL; i++)
+ for (uint32_t i = MPIDR_AFFLVL0; i <= PLAT_MAX_PWR_LVL; i++) {
req_state->pwr_domain_state[i] = PSTATE_ID_SOC_POWERDN;
+ }
}
/*******************************************************************************
@@ -126,6 +139,8 @@
******************************************************************************/
void tegra_cpu_standby(plat_local_state_t cpu_state)
{
+ (void)cpu_state;
+
/*
* Enter standby state
* dsb is good practice before using wfi to enter low power states
@@ -138,7 +153,7 @@
* Handler called when an affinity instance is about to be turned on. The
* level and mpidr determine the affinity instance.
******************************************************************************/
-int tegra_pwr_domain_on(u_register_t mpidr)
+int32_t tegra_pwr_domain_on(u_register_t mpidr)
{
return tegra_soc_pwr_domain_on(mpidr);
}
@@ -149,7 +164,7 @@
******************************************************************************/
void tegra_pwr_domain_off(const psci_power_state_t *target_state)
{
- tegra_soc_pwr_domain_off(target_state);
+ (void)tegra_soc_pwr_domain_off(target_state);
}
/*******************************************************************************
@@ -169,12 +184,13 @@
******************************************************************************/
void tegra_pwr_domain_suspend(const psci_power_state_t *target_state)
{
- tegra_soc_pwr_domain_suspend(target_state);
+ (void)tegra_soc_pwr_domain_suspend(target_state);
/* Disable console if we are entering deep sleep. */
if (target_state->pwr_domain_state[PLAT_MAX_PWR_LVL] ==
- PSTATE_ID_SOC_POWERDN)
- console_uninit();
+ PSTATE_ID_SOC_POWERDN) {
+ (void)console_uninit();
+ }
/* disable GICC */
tegra_gic_cpuif_deactivate();
@@ -191,7 +207,7 @@
uint64_t rmr_el3 = 0;
/* call the chip's power down handler */
- tegra_soc_pwr_domain_power_down_wfi(target_state);
+ (void)tegra_soc_pwr_domain_power_down_wfi(target_state);
/*
* If we are in fake system suspend mode, ensure we start doing
@@ -222,7 +238,7 @@
******************************************************************************/
void tegra_pwr_domain_on_finish(const psci_power_state_t *target_state)
{
- plat_params_from_bl2_t *plat_params;
+ const plat_params_from_bl2_t *plat_params;
uint32_t console_clock;
/*
@@ -239,15 +255,15 @@
/*
* Reference clock used by the FPGAs is a lot slower.
*/
- if (tegra_platform_is_fpga() == 1U) {
+ if (tegra_platform_is_fpga()) {
console_clock = TEGRA_BOOT_UART_CLK_13_MHZ;
} else {
console_clock = TEGRA_BOOT_UART_CLK_408_MHZ;
}
/* Initialize the runtime console */
- if (tegra_console_base != (uint64_t)0) {
- console_init(tegra_console_base, console_clock,
+ if (tegra_console_base != 0ULL) {
+ (void)console_init(tegra_console_base, console_clock,
TEGRA_CONSOLE_BAUDRATE);
}
@@ -262,7 +278,7 @@
*/
plat_params = bl31_get_plat_params();
tegra_memctrl_tzdram_setup(plat_params->tzdram_base,
- plat_params->tzdram_size);
+ (uint32_t)plat_params->tzdram_size);
/*
* Set up the TZRAM memory aperture to allow only secure world
@@ -274,7 +290,7 @@
/*
* Reset hardware settings.
*/
- tegra_soc_pwr_domain_on_finish(target_state);
+ (void)tegra_soc_pwr_domain_on_finish(target_state);
}
/*******************************************************************************
@@ -305,7 +321,7 @@
INFO("Restarting system...\n");
/* per-SoC system reset handler */
- tegra_soc_prepare_system_reset();
+ (void)tegra_soc_prepare_system_reset();
/*
* Program the PMC in order to restart the system.
@@ -316,10 +332,10 @@
/*******************************************************************************
* Handler called to check the validity of the power state parameter.
******************************************************************************/
-int32_t tegra_validate_power_state(unsigned int power_state,
+int32_t tegra_validate_power_state(uint32_t power_state,
psci_power_state_t *req_state)
{
- assert(req_state);
+ assert(req_state != NULL);
return tegra_soc_validate_power_state(power_state, req_state);
}
@@ -327,16 +343,19 @@
/*******************************************************************************
* Platform handler called to check the validity of the non secure entrypoint.
******************************************************************************/
-int tegra_validate_ns_entrypoint(uintptr_t entrypoint)
+int32_t tegra_validate_ns_entrypoint(uintptr_t entrypoint)
{
+ int32_t ret = PSCI_E_INVALID_ADDRESS;
+
/*
* Check if the non secure entrypoint lies within the non
* secure DRAM.
*/
- if ((entrypoint >= TEGRA_DRAM_BASE) && (entrypoint <= TEGRA_DRAM_END))
- return PSCI_E_SUCCESS;
+ if ((entrypoint >= TEGRA_DRAM_BASE) && (entrypoint <= TEGRA_DRAM_END)) {
+ ret = PSCI_E_SUCCESS;
+ }
- return PSCI_E_INVALID_ADDRESS;
+ return ret;
}
/*******************************************************************************
@@ -376,7 +395,7 @@
/*
* Reset hardware settings.
*/
- tegra_soc_pwr_domain_on_finish(&target_state);
+ (void)tegra_soc_pwr_domain_on_finish(&target_state);
/*
* Initialize PSCI ops struct
diff --git a/plat/nvidia/tegra/common/tegra_sip_calls.c b/plat/nvidia/tegra/common/tegra_sip_calls.c
index e7acece..4955b2f 100644
--- a/plat/nvidia/tegra/common/tegra_sip_calls.c
+++ b/plat/nvidia/tegra/common/tegra_sip_calls.c
@@ -69,7 +69,7 @@
void *handle,
u_register_t flags)
{
- uint32_t regval;
+ uint32_t regval, local_x2_32 = (uint32_t)x2;
int32_t err;
/* Check if this is a SoC specific SiP */
@@ -84,14 +84,11 @@
case TEGRA_SIP_NEW_VIDEOMEM_REGION:
- /* clean up the high bits */
- x2 = (uint32_t)x2;
-
/*
* Check if Video Memory overlaps TZDRAM (contains bl31/bl32)
* or falls outside of the valid DRAM range
*/
- err = bl31_check_ns_address(x1, x2);
+ err = bl31_check_ns_address(x1, local_x2_32);
if (err != 0) {
SMC_RET1(handle, (uint64_t)err);
}
@@ -99,9 +96,9 @@
/*
* Check if Video Memory is aligned to 1MB.
*/
- if (((x1 & 0xFFFFFU) != 0U) || ((x2 & 0xFFFFFU) != 0U)) {
+ if (((x1 & 0xFFFFFU) != 0U) || ((local_x2_32 & 0xFFFFFU) != 0U)) {
ERROR("Unaligned Video Memory base address!\n");
- SMC_RET1(handle, -ENOTSUP);
+ SMC_RET1(handle, (uint64_t)-ENOTSUP);
}
/*
@@ -111,13 +108,13 @@
*/
regval = mmio_read_32(TEGRA_CAR_RESET_BASE +
TEGRA_GPU_RESET_REG_OFFSET);
- if ((regval & GPU_RESET_BIT) == 0UL) {
+ if ((regval & GPU_RESET_BIT) == 0U) {
ERROR("GPU not in reset! Video Memory setup failed\n");
- SMC_RET1(handle, -ENOTSUP);
+ SMC_RET1(handle, (uint64_t)-ENOTSUP);
}
/* new video memory carveout settings */
- tegra_memctrl_videomem_setup(x1, (uint32_t)x2);
+ tegra_memctrl_videomem_setup(x1, local_x2_32);
SMC_RET1(handle, 0);
diff --git a/plat/nvidia/tegra/common/tegra_topology.c b/plat/nvidia/tegra/common/tegra_topology.c
index 4f6cf93..14631a7 100644
--- a/plat/nvidia/tegra/common/tegra_topology.c
+++ b/plat/nvidia/tegra/common/tegra_topology.c
@@ -23,10 +23,14 @@
u_register_t cluster_id, cpu_id;
int32_t result;
- cluster_id = (mpidr >> (u_register_t)MPIDR_AFF1_SHIFT) & (u_register_t)MPIDR_AFFLVL_MASK;
- cpu_id = (mpidr >> (u_register_t)MPIDR_AFF0_SHIFT) & (u_register_t)MPIDR_AFFLVL_MASK;
+ cluster_id = (mpidr >> (u_register_t)MPIDR_AFF1_SHIFT) &
+ (u_register_t)MPIDR_AFFLVL_MASK;
+ cpu_id = (mpidr >> (u_register_t)MPIDR_AFF0_SHIFT) &
+ (u_register_t)MPIDR_AFFLVL_MASK;
- result = (int32_t)cpu_id + ((int32_t)cluster_id * 4);
+ /* CorePos = CoreId + (ClusterId * cpus per cluster) */
+ result = (int32_t)cpu_id + ((int32_t)cluster_id *
+ PLATFORM_MAX_CPUS_PER_CLUSTER);
if (cluster_id >= (u_register_t)PLATFORM_CLUSTER_COUNT) {
result = PSCI_E_NOT_PRESENT;
diff --git a/plat/nvidia/tegra/include/drivers/bpmp.h b/plat/nvidia/tegra/include/drivers/bpmp.h
index 27f57df..03da6f6 100644
--- a/plat/nvidia/tegra/include/drivers/bpmp.h
+++ b/plat/nvidia/tegra/include/drivers/bpmp.h
@@ -10,25 +10,25 @@
#include <stdint.h>
/* macro to enable clock to the Atomics block */
-#define CAR_ENABLE_ATOMICS (1UL << 16)
+#define CAR_ENABLE_ATOMICS (1U << 16)
/* command to get the channel base addresses from bpmp */
-#define ATOMIC_CMD_GET 4UL
+#define ATOMIC_CMD_GET 4U
/* Hardware IRQ # used to signal bpmp of an incoming command */
-#define INT_SHR_SEM_OUTBOX_FULL 6UL
+#define INT_SHR_SEM_OUTBOX_FULL 6U
/* macros to decode the bpmp's state */
-#define CH_MASK(ch) (0x3UL << ((ch) * 2UL))
-#define MA_FREE(ch) (0x2UL << ((ch) * 2UL))
-#define MA_ACKD(ch) (0x3UL << ((ch) * 2UL))
+#define CH_MASK(ch) ((uint32_t)0x3 << ((ch) * 2U))
+#define MA_FREE(ch) ((uint32_t)0x2 << ((ch) * 2U))
+#define MA_ACKD(ch) ((uint32_t)0x3 << ((ch) * 2U))
/* response from bpmp to indicate it has powered up */
-#define SIGN_OF_LIFE 0xAAAAAAAAUL
+#define SIGN_OF_LIFE 0xAAAAAAAAU
/* flags to indicate bpmp driver's state */
-#define BPMP_INIT_COMPLETE 0xBEEFF00DUL
-#define BPMP_INIT_PENDING 0xDEADBEEFUL
+#define BPMP_INIT_COMPLETE 0xBEEFF00DU
+#define BPMP_INIT_PENDING 0xDEADBEEFU
/* requests serviced by the bpmp */
#define MRQ_PING 0
@@ -64,14 +64,14 @@
#define TEGRA_PM_SC7 23
/* flag to indicate if entry into a CCx power state is allowed */
-#define BPMP_CCx_ALLOWED 0UL
+#define BPMP_CCx_ALLOWED 0U
/* number of communication channels to interact with the bpmp */
#define NR_CHANNELS 4U
/* flag to ask bpmp to acknowledge command packet */
-#define NO_ACK (0UL << 0UL)
-#define DO_ACK (1UL << 0UL)
+#define NO_ACK (0U << 0U)
+#define DO_ACK (1U << 0U)
/* size of the command/response data */
#define MSG_DATA_MAX_SZ 120U
diff --git a/plat/nvidia/tegra/include/drivers/bpmp_ipc.h b/plat/nvidia/tegra/include/drivers/bpmp_ipc.h
new file mode 100644
index 0000000..9304150
--- /dev/null
+++ b/plat/nvidia/tegra/include/drivers/bpmp_ipc.h
@@ -0,0 +1,30 @@
+/*
+ * Copyright (c) 2017, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef __BPMP_IPC_H__
+#define __BPMP_IPC_H__
+
+#include <stdbool.h>
+#include <stdint.h>
+#include <utils_def.h>
+
+/**
+ * Currently supported reset identifiers
+ */
+#define TEGRA_RESET_ID_XUSB_PADCTL U(114)
+#define TEGRA_RESET_ID_GPCDMA U(70)
+
+/**
+ * Function to initialise the IPC with the bpmp
+ */
+int32_t tegra_bpmp_ipc_init(void);
+
+/**
+ * Handler to reset a module
+ */
+int32_t tegra_bpmp_ipc_reset_module(uint32_t rst_id);
+
+#endif /* __BPMP_IPC_H__ */
diff --git a/plat/nvidia/tegra/include/drivers/gpcdma.h b/plat/nvidia/tegra/include/drivers/gpcdma.h
new file mode 100644
index 0000000..fb5486a
--- /dev/null
+++ b/plat/nvidia/tegra/include/drivers/gpcdma.h
@@ -0,0 +1,16 @@
+/*
+ * Copyright (c) 2017, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef __GPCDMA_H__
+#define __GPCDMA_H__
+
+#include <stdint.h>
+
+void tegra_gpcdma_memcpy(uint64_t dst_addr, uint64_t src_addr,
+ uint32_t num_bytes);
+void tegra_gpcdma_zeromem(uint64_t dst_addr, uint32_t num_bytes);
+
+#endif /* __GPCDMA_H__ */
diff --git a/plat/nvidia/tegra/include/drivers/memctrl.h b/plat/nvidia/tegra/include/drivers/memctrl.h
index 17427cb..d5ef60d 100644
--- a/plat/nvidia/tegra/include/drivers/memctrl.h
+++ b/plat/nvidia/tegra/include/drivers/memctrl.h
@@ -13,5 +13,6 @@
void tegra_memctrl_tzram_setup(uint64_t phys_base, uint32_t size_in_bytes);
void tegra_memctrl_videomem_setup(uint64_t phys_base, uint32_t size_in_bytes);
void tegra_memctrl_disable_ahb_redirection(void);
+void tegra_memctrl_clear_pending_interrupts(void);
#endif /* MEMCTRL_H */
diff --git a/plat/nvidia/tegra/include/drivers/memctrl_v2.h b/plat/nvidia/tegra/include/drivers/memctrl_v2.h
index ffe5269..f5b0ed4 100644
--- a/plat/nvidia/tegra/include/drivers/memctrl_v2.h
+++ b/plat/nvidia/tegra/include/drivers/memctrl_v2.h
@@ -11,185 +11,10 @@
#ifndef __ASSEMBLY__
+#include <mmio.h>
#include <stdint.h>
/*******************************************************************************
- * StreamID to indicate no SMMU translations (requests to be steered on the
- * SMMU bypass path)
- ******************************************************************************/
-#define MC_STREAM_ID_MAX 0x7F
-
-/*******************************************************************************
- * Stream ID Override Config registers
- ******************************************************************************/
-#define MC_STREAMID_OVERRIDE_CFG_PTCR 0x000
-#define MC_STREAMID_OVERRIDE_CFG_AFIR 0x070
-#define MC_STREAMID_OVERRIDE_CFG_HDAR 0x0A8
-#define MC_STREAMID_OVERRIDE_CFG_HOST1XDMAR 0x0B0
-#define MC_STREAMID_OVERRIDE_CFG_NVENCSRD 0x0E0
-#define MC_STREAMID_OVERRIDE_CFG_SATAR 0x0F8
-#define MC_STREAMID_OVERRIDE_CFG_MPCORER 0x138
-#define MC_STREAMID_OVERRIDE_CFG_NVENCSWR 0x158
-#define MC_STREAMID_OVERRIDE_CFG_AFIW 0x188
-#define MC_STREAMID_OVERRIDE_CFG_HDAW 0x1A8
-#define MC_STREAMID_OVERRIDE_CFG_MPCOREW 0x1C8
-#define MC_STREAMID_OVERRIDE_CFG_SATAW 0x1E8
-#define MC_STREAMID_OVERRIDE_CFG_ISPRA 0x220
-#define MC_STREAMID_OVERRIDE_CFG_ISPWA 0x230
-#define MC_STREAMID_OVERRIDE_CFG_ISPWB 0x238
-#define MC_STREAMID_OVERRIDE_CFG_XUSB_HOSTR 0x250
-#define MC_STREAMID_OVERRIDE_CFG_XUSB_HOSTW 0x258
-#define MC_STREAMID_OVERRIDE_CFG_XUSB_DEVR 0x260
-#define MC_STREAMID_OVERRIDE_CFG_XUSB_DEVW 0x268
-#define MC_STREAMID_OVERRIDE_CFG_TSECSRD 0x2A0
-#define MC_STREAMID_OVERRIDE_CFG_TSECSWR 0x2A8
-#define MC_STREAMID_OVERRIDE_CFG_GPUSRD 0x2C0
-#define MC_STREAMID_OVERRIDE_CFG_GPUSWR 0x2C8
-#define MC_STREAMID_OVERRIDE_CFG_SDMMCRA 0x300
-#define MC_STREAMID_OVERRIDE_CFG_SDMMCRAA 0x308
-#define MC_STREAMID_OVERRIDE_CFG_SDMMCR 0x310
-#define MC_STREAMID_OVERRIDE_CFG_SDMMCRAB 0x318
-#define MC_STREAMID_OVERRIDE_CFG_SDMMCWA 0x320
-#define MC_STREAMID_OVERRIDE_CFG_SDMMCWAA 0x328
-#define MC_STREAMID_OVERRIDE_CFG_SDMMCW 0x330
-#define MC_STREAMID_OVERRIDE_CFG_SDMMCWAB 0x338
-#define MC_STREAMID_OVERRIDE_CFG_VICSRD 0x360
-#define MC_STREAMID_OVERRIDE_CFG_VICSWR 0x368
-#define MC_STREAMID_OVERRIDE_CFG_VIW 0x390
-#define MC_STREAMID_OVERRIDE_CFG_NVDECSRD 0x3C0
-#define MC_STREAMID_OVERRIDE_CFG_NVDECSWR 0x3C8
-#define MC_STREAMID_OVERRIDE_CFG_APER 0x3D0
-#define MC_STREAMID_OVERRIDE_CFG_APEW 0x3D8
-#define MC_STREAMID_OVERRIDE_CFG_NVJPGSRD 0x3F0
-#define MC_STREAMID_OVERRIDE_CFG_NVJPGSWR 0x3F8
-#define MC_STREAMID_OVERRIDE_CFG_SESRD 0x400
-#define MC_STREAMID_OVERRIDE_CFG_SESWR 0x408
-#define MC_STREAMID_OVERRIDE_CFG_ETRR 0x420
-#define MC_STREAMID_OVERRIDE_CFG_ETRW 0x428
-#define MC_STREAMID_OVERRIDE_CFG_TSECSRDB 0x430
-#define MC_STREAMID_OVERRIDE_CFG_TSECSWRB 0x438
-#define MC_STREAMID_OVERRIDE_CFG_GPUSRD2 0x440
-#define MC_STREAMID_OVERRIDE_CFG_GPUSWR2 0x448
-#define MC_STREAMID_OVERRIDE_CFG_AXISR 0x460
-#define MC_STREAMID_OVERRIDE_CFG_AXISW 0x468
-#define MC_STREAMID_OVERRIDE_CFG_EQOSR 0x470
-#define MC_STREAMID_OVERRIDE_CFG_EQOSW 0x478
-#define MC_STREAMID_OVERRIDE_CFG_UFSHCR 0x480
-#define MC_STREAMID_OVERRIDE_CFG_UFSHCW 0x488
-#define MC_STREAMID_OVERRIDE_CFG_NVDISPLAYR 0x490
-#define MC_STREAMID_OVERRIDE_CFG_BPMPR 0x498
-#define MC_STREAMID_OVERRIDE_CFG_BPMPW 0x4A0
-#define MC_STREAMID_OVERRIDE_CFG_BPMPDMAR 0x4A8
-#define MC_STREAMID_OVERRIDE_CFG_BPMPDMAW 0x4B0
-#define MC_STREAMID_OVERRIDE_CFG_AONR 0x4B8
-#define MC_STREAMID_OVERRIDE_CFG_AONW 0x4C0
-#define MC_STREAMID_OVERRIDE_CFG_AONDMAR 0x4C8
-#define MC_STREAMID_OVERRIDE_CFG_AONDMAW 0x4D0
-#define MC_STREAMID_OVERRIDE_CFG_SCER 0x4D8
-#define MC_STREAMID_OVERRIDE_CFG_SCEW 0x4E0
-#define MC_STREAMID_OVERRIDE_CFG_SCEDMAR 0x4E8
-#define MC_STREAMID_OVERRIDE_CFG_SCEDMAW 0x4F0
-#define MC_STREAMID_OVERRIDE_CFG_APEDMAR 0x4F8
-#define MC_STREAMID_OVERRIDE_CFG_APEDMAW 0x500
-#define MC_STREAMID_OVERRIDE_CFG_NVDISPLAYR1 0x508
-#define MC_STREAMID_OVERRIDE_CFG_VICSRD1 0x510
-#define MC_STREAMID_OVERRIDE_CFG_NVDECSRD1 0x518
-
-/*******************************************************************************
- * Macro to calculate Security cfg register addr from StreamID Override register
- ******************************************************************************/
-#define MC_STREAMID_OVERRIDE_TO_SECURITY_CFG(addr) (addr + sizeof(uint32_t))
-
-#define MC_TXN_OVERRIDE_CONFIG_COH_PATH_NO_OVERRIDE_SO_DEV (0UL << 4)
-#define MC_TXN_OVERRIDE_CONFIG_COH_PATH_FORCE_NON_COHERENT_SO_DEV (1UL << 4)
-#define MC_TXN_OVERRIDE_CONFIG_COH_PATH_FORCE_COHERENT_SO_DEV (2UL << 4)
-#define MC_TXN_OVERRIDE_CONFIG_COH_PATH_FORCE_COHERENT_SNOOP_SO_DEV (3UL << 4)
-
-#define MC_TXN_OVERRIDE_CONFIG_COH_PATH_NO_OVERRIDE_NORMAL (0UL << 8)
-#define MC_TXN_OVERRIDE_CONFIG_COH_PATH_FORCE_NON_COHERENT_NORMAL (1UL << 8)
-#define MC_TXN_OVERRIDE_CONFIG_COH_PATH_FORCE_COHERENT_NORMAL (2UL << 8)
-#define MC_TXN_OVERRIDE_CONFIG_COH_PATH_FORCE_COHERENT_SNOOP_NORMAL (3UL << 8)
-
-#define MC_TXN_OVERRIDE_CONFIG_CGID_SO_DEV_ZERO (0UL << 12)
-#define MC_TXN_OVERRIDE_CONFIG_CGID_SO_DEV_CLIENT_AXI_ID (1UL << 12)
-
-/*******************************************************************************
- * Memory Controller transaction override config registers
- ******************************************************************************/
-#define MC_TXN_OVERRIDE_CONFIG_HDAR 0x10a8
-#define MC_TXN_OVERRIDE_CONFIG_BPMPW 0x14a0
-#define MC_TXN_OVERRIDE_CONFIG_PTCR 0x1000
-#define MC_TXN_OVERRIDE_CONFIG_NVDISPLAYR 0x1490
-#define MC_TXN_OVERRIDE_CONFIG_EQOSW 0x1478
-#define MC_TXN_OVERRIDE_CONFIG_NVJPGSWR 0x13f8
-#define MC_TXN_OVERRIDE_CONFIG_ISPRA 0x1220
-#define MC_TXN_OVERRIDE_CONFIG_SDMMCWAA 0x1328
-#define MC_TXN_OVERRIDE_CONFIG_VICSRD 0x1360
-#define MC_TXN_OVERRIDE_CONFIG_MPCOREW 0x11c8
-#define MC_TXN_OVERRIDE_CONFIG_GPUSRD 0x12c0
-#define MC_TXN_OVERRIDE_CONFIG_AXISR 0x1460
-#define MC_TXN_OVERRIDE_CONFIG_SCEDMAW 0x14f0
-#define MC_TXN_OVERRIDE_CONFIG_SDMMCW 0x1330
-#define MC_TXN_OVERRIDE_CONFIG_EQOSR 0x1470
-#define MC_TXN_OVERRIDE_CONFIG_APEDMAR 0x14f8
-#define MC_TXN_OVERRIDE_CONFIG_NVENCSRD 0x10e0
-#define MC_TXN_OVERRIDE_CONFIG_SDMMCRAB 0x1318
-#define MC_TXN_OVERRIDE_CONFIG_VICSRD1 0x1510
-#define MC_TXN_OVERRIDE_CONFIG_BPMPDMAR 0x14a8
-#define MC_TXN_OVERRIDE_CONFIG_VIW 0x1390
-#define MC_TXN_OVERRIDE_CONFIG_SDMMCRAA 0x1308
-#define MC_TXN_OVERRIDE_CONFIG_AXISW 0x1468
-#define MC_TXN_OVERRIDE_CONFIG_XUSB_DEVR 0x1260
-#define MC_TXN_OVERRIDE_CONFIG_UFSHCR 0x1480
-#define MC_TXN_OVERRIDE_CONFIG_TSECSWR 0x12a8
-#define MC_TXN_OVERRIDE_CONFIG_GPUSWR 0x12c8
-#define MC_TXN_OVERRIDE_CONFIG_SATAR 0x10f8
-#define MC_TXN_OVERRIDE_CONFIG_XUSB_HOSTW 0x1258
-#define MC_TXN_OVERRIDE_CONFIG_TSECSWRB 0x1438
-#define MC_TXN_OVERRIDE_CONFIG_GPUSRD2 0x1440
-#define MC_TXN_OVERRIDE_CONFIG_SCEDMAR 0x14e8
-#define MC_TXN_OVERRIDE_CONFIG_GPUSWR2 0x1448
-#define MC_TXN_OVERRIDE_CONFIG_AONDMAW 0x14d0
-#define MC_TXN_OVERRIDE_CONFIG_APEDMAW 0x1500
-#define MC_TXN_OVERRIDE_CONFIG_AONW 0x14c0
-#define MC_TXN_OVERRIDE_CONFIG_HOST1XDMAR 0x10b0
-#define MC_TXN_OVERRIDE_CONFIG_ETRR 0x1420
-#define MC_TXN_OVERRIDE_CONFIG_SESWR 0x1408
-#define MC_TXN_OVERRIDE_CONFIG_NVJPGSRD 0x13f0
-#define MC_TXN_OVERRIDE_CONFIG_NVDECSRD 0x13c0
-#define MC_TXN_OVERRIDE_CONFIG_TSECSRDB 0x1430
-#define MC_TXN_OVERRIDE_CONFIG_BPMPDMAW 0x14b0
-#define MC_TXN_OVERRIDE_CONFIG_APER 0x13d0
-#define MC_TXN_OVERRIDE_CONFIG_NVDECSRD1 0x1518
-#define MC_TXN_OVERRIDE_CONFIG_XUSB_HOSTR 0x1250
-#define MC_TXN_OVERRIDE_CONFIG_ISPWA 0x1230
-#define MC_TXN_OVERRIDE_CONFIG_SESRD 0x1400
-#define MC_TXN_OVERRIDE_CONFIG_SCER 0x14d8
-#define MC_TXN_OVERRIDE_CONFIG_AONR 0x14b8
-#define MC_TXN_OVERRIDE_CONFIG_MPCORER 0x1138
-#define MC_TXN_OVERRIDE_CONFIG_SDMMCWA 0x1320
-#define MC_TXN_OVERRIDE_CONFIG_HDAW 0x11a8
-#define MC_TXN_OVERRIDE_CONFIG_NVDECSWR 0x13c8
-#define MC_TXN_OVERRIDE_CONFIG_UFSHCW 0x1488
-#define MC_TXN_OVERRIDE_CONFIG_AONDMAR 0x14c8
-#define MC_TXN_OVERRIDE_CONFIG_SATAW 0x11e8
-#define MC_TXN_OVERRIDE_CONFIG_ETRW 0x1428
-#define MC_TXN_OVERRIDE_CONFIG_VICSWR 0x1368
-#define MC_TXN_OVERRIDE_CONFIG_NVENCSWR 0x1158
-#define MC_TXN_OVERRIDE_CONFIG_AFIR 0x1070
-#define MC_TXN_OVERRIDE_CONFIG_SDMMCWAB 0x1338
-#define MC_TXN_OVERRIDE_CONFIG_SDMMCRA 0x1300
-#define MC_TXN_OVERRIDE_CONFIG_NVDISPLAYR1 0x1508
-#define MC_TXN_OVERRIDE_CONFIG_ISPWB 0x1238
-#define MC_TXN_OVERRIDE_CONFIG_BPMPR 0x1498
-#define MC_TXN_OVERRIDE_CONFIG_APEW 0x13d8
-#define MC_TXN_OVERRIDE_CONFIG_SDMMCR 0x1310
-#define MC_TXN_OVERRIDE_CONFIG_XUSB_DEVW 0x1268
-#define MC_TXN_OVERRIDE_CONFIG_TSECSRD 0x12a0
-#define MC_TXN_OVERRIDE_CONFIG_AFIW 0x1188
-#define MC_TXN_OVERRIDE_CONFIG_SCEW 0x14e0
-
-/*******************************************************************************
* Structure to hold the transaction override settings to use to override
* client inputs
******************************************************************************/
@@ -223,12 +48,31 @@
int override_client_ns_flag;
} mc_streamid_security_cfg_t;
-#define OVERRIDE_DISABLE 1
-#define OVERRIDE_ENABLE 0
-#define CLIENT_FLAG_SECURE 0
-#define CLIENT_FLAG_NON_SECURE 1
-#define CLIENT_INPUTS_OVERRIDE 1
-#define CLIENT_INPUTS_NO_OVERRIDE 0
+#define OVERRIDE_DISABLE 1U
+#define OVERRIDE_ENABLE 0U
+#define CLIENT_FLAG_SECURE 0U
+#define CLIENT_FLAG_NON_SECURE 1U
+#define CLIENT_INPUTS_OVERRIDE 1U
+#define CLIENT_INPUTS_NO_OVERRIDE 0U
+/*******************************************************************************
+ * StreamID to indicate no SMMU translations (requests to be steered on the
+ * SMMU bypass path)
+ ******************************************************************************/
+#define MC_STREAM_ID_MAX 0x7FU
+
+/*******************************************************************************
+ * Memory Controller SMMU Bypass config register
+ ******************************************************************************/
+#define MC_SMMU_BYPASS_CONFIG 0x1820U
+#define MC_SMMU_BYPASS_CTRL_MASK 0x3U
+#define MC_SMMU_BYPASS_CTRL_SHIFT 0U
+#define MC_SMMU_CTRL_TBU_BYPASS_ALL (0U << MC_SMMU_BYPASS_CTRL_SHIFT)
+#define MC_SMMU_CTRL_TBU_RSVD (1U << MC_SMMU_BYPASS_CTRL_SHIFT)
+#define MC_SMMU_CTRL_TBU_BYPASS_SPL_STREAMID (2U << MC_SMMU_BYPASS_CTRL_SHIFT)
+#define MC_SMMU_CTRL_TBU_BYPASS_NONE (3U << MC_SMMU_BYPASS_CTRL_SHIFT)
+#define MC_SMMU_BYPASS_CONFIG_WRITE_ACCESS_BIT (1U << 31)
+#define MC_SMMU_BYPASS_CONFIG_SETTINGS (MC_SMMU_BYPASS_CONFIG_WRITE_ACCESS_BIT | \
+ MC_SMMU_CTRL_TBU_BYPASS_SPL_STREAMID)
#define mc_make_sec_cfg(off, ns, ovrrd, access) \
{ \
@@ -250,131 +94,10 @@
uint32_t num_streamid_security_cfgs;
const mc_txn_override_cfg_t *txn_override_cfg;
uint32_t num_txn_override_cfgs;
+ void (*reconfig_mss_clients)(void);
+ void (*set_txn_overrides)(void);
} tegra_mc_settings_t;
-#endif /* __ASSEMBLY__ */
-
-/*******************************************************************************
- * Memory Controller SMMU Bypass config register
- ******************************************************************************/
-#define MC_SMMU_BYPASS_CONFIG 0x1820
-#define MC_SMMU_BYPASS_CTRL_MASK 0x3
-#define MC_SMMU_BYPASS_CTRL_SHIFT 0
-#define MC_SMMU_CTRL_TBU_BYPASS_ALL (0 << MC_SMMU_BYPASS_CTRL_SHIFT)
-#define MC_SMMU_CTRL_TBU_RSVD (1 << MC_SMMU_BYPASS_CTRL_SHIFT)
-#define MC_SMMU_CTRL_TBU_BYPASS_SPL_STREAMID (2 << MC_SMMU_BYPASS_CTRL_SHIFT)
-#define MC_SMMU_CTRL_TBU_BYPASS_NONE (3 << MC_SMMU_BYPASS_CTRL_SHIFT)
-#define MC_SMMU_BYPASS_CONFIG_WRITE_ACCESS_BIT (1 << 31)
-#define MC_SMMU_BYPASS_CONFIG_SETTINGS (MC_SMMU_BYPASS_CONFIG_WRITE_ACCESS_BIT | \
- MC_SMMU_CTRL_TBU_BYPASS_SPL_STREAMID)
-
-#define MC_TXN_OVERRIDE_CONFIG_AXID_OVERRIDE_CGID (1 << 0)
-#define MC_TXN_OVERRIDE_CONFIG_COH_PATH_OVERRIDE_SO_DEV (2 << 4)
-#define MC_TXN_OVERRIDE_CONFIG_AXID_OVERRIDE_SO_DEV_CGID_SO_DEV_CLIENT (1 << 12)
-
-/*******************************************************************************
- * Non-SO_DEV transactions override values for CGID_TAG bitfield for the
- * MC_TXN_OVERRIDE_CONFIG_{module} registers
- ******************************************************************************/
-#define MC_TXN_OVERRIDE_CGID_TAG_DEFAULT 0
-#define MC_TXN_OVERRIDE_CGID_TAG_CLIENT_AXI_ID 1
-#define MC_TXN_OVERRIDE_CGID_TAG_ZERO 2
-#define MC_TXN_OVERRIDE_CGID_TAG_ADR 3
-#define MC_TXN_OVERRIDE_CGID_TAG_MASK 3
-
-/*******************************************************************************
- * Memory Controller Reset Control registers
- ******************************************************************************/
-#define MC_CLIENT_HOTRESET_CTRL0 0x200
-#define MC_CLIENT_HOTRESET_CTRL0_RESET_VAL 0
-#define MC_CLIENT_HOTRESET_CTRL0_AFI_FLUSH_ENB (1 << 0)
-#define MC_CLIENT_HOTRESET_CTRL0_HC_FLUSH_ENB (1 << 6)
-#define MC_CLIENT_HOTRESET_CTRL0_HDA_FLUSH_ENB (1 << 7)
-#define MC_CLIENT_HOTRESET_CTRL0_ISP2_FLUSH_ENB (1 << 8)
-#define MC_CLIENT_HOTRESET_CTRL0_MPCORE_FLUSH_ENB (1 << 9)
-#define MC_CLIENT_HOTRESET_CTRL0_NVENC_FLUSH_ENB (1 << 11)
-#define MC_CLIENT_HOTRESET_CTRL0_SATA_FLUSH_ENB (1 << 15)
-#define MC_CLIENT_HOTRESET_CTRL0_VI_FLUSH_ENB (1 << 17)
-#define MC_CLIENT_HOTRESET_CTRL0_VIC_FLUSH_ENB (1 << 18)
-#define MC_CLIENT_HOTRESET_CTRL0_XUSB_HOST_FLUSH_ENB (1 << 19)
-#define MC_CLIENT_HOTRESET_CTRL0_XUSB_DEV_FLUSH_ENB (1 << 20)
-#define MC_CLIENT_HOTRESET_CTRL0_TSEC_FLUSH_ENB (1 << 22)
-#define MC_CLIENT_HOTRESET_CTRL0_SDMMC1A_FLUSH_ENB (1 << 29)
-#define MC_CLIENT_HOTRESET_CTRL0_SDMMC2A_FLUSH_ENB (1 << 30)
-#define MC_CLIENT_HOTRESET_CTRL0_SDMMC3A_FLUSH_ENB (1 << 31)
-#define MC_CLIENT_HOTRESET_STATUS0 0x204
-#define MC_CLIENT_HOTRESET_CTRL1 0x970
-#define MC_CLIENT_HOTRESET_CTRL1_RESET_VAL 0
-#define MC_CLIENT_HOTRESET_CTRL1_SDMMC4A_FLUSH_ENB (1 << 0)
-#define MC_CLIENT_HOTRESET_CTRL1_GPU_FLUSH_ENB (1 << 2)
-#define MC_CLIENT_HOTRESET_CTRL1_NVDEC_FLUSH_ENB (1 << 5)
-#define MC_CLIENT_HOTRESET_CTRL1_APE_FLUSH_ENB (1 << 6)
-#define MC_CLIENT_HOTRESET_CTRL1_SE_FLUSH_ENB (1 << 7)
-#define MC_CLIENT_HOTRESET_CTRL1_NVJPG_FLUSH_ENB (1 << 8)
-#define MC_CLIENT_HOTRESET_CTRL1_ETR_FLUSH_ENB (1 << 12)
-#define MC_CLIENT_HOTRESET_CTRL1_TSECB_FLUSH_ENB (1 << 13)
-#define MC_CLIENT_HOTRESET_CTRL1_AXIS_FLUSH_ENB (1 << 18)
-#define MC_CLIENT_HOTRESET_CTRL1_EQOS_FLUSH_ENB (1 << 19)
-#define MC_CLIENT_HOTRESET_CTRL1_UFSHC_FLUSH_ENB (1 << 20)
-#define MC_CLIENT_HOTRESET_CTRL1_NVDISPLAY_FLUSH_ENB (1 << 21)
-#define MC_CLIENT_HOTRESET_CTRL1_BPMP_FLUSH_ENB (1 << 22)
-#define MC_CLIENT_HOTRESET_CTRL1_AON_FLUSH_ENB (1 << 23)
-#define MC_CLIENT_HOTRESET_CTRL1_SCE_FLUSH_ENB (1 << 24)
-#define MC_CLIENT_HOTRESET_STATUS1 0x974
-
-/*******************************************************************************
- * Memory Controller's PCFIFO client configuration registers
- ******************************************************************************/
-#define MC_PCFIFO_CLIENT_CONFIG1 0xdd4UL
-#define MC_PCFIFO_CLIENT_CONFIG1_RESET_VAL 0x20000UL
-#define MC_PCFIFO_CLIENT_CONFIG1_PCFIFO_AFIW_UNORDERED (0UL << 17)
-#define MC_PCFIFO_CLIENT_CONFIG1_PCFIFO_AFIW_MASK (1UL << 17)
-#define MC_PCFIFO_CLIENT_CONFIG1_PCFIFO_HDAW_UNORDERED (0UL << 21)
-#define MC_PCFIFO_CLIENT_CONFIG1_PCFIFO_HDAW_MASK (1UL << 21)
-#define MC_PCFIFO_CLIENT_CONFIG1_PCFIFO_SATAW_UNORDERED (0UL << 29)
-#define MC_PCFIFO_CLIENT_CONFIG1_PCFIFO_SATAW_MASK (1UL << 29)
-
-#define MC_PCFIFO_CLIENT_CONFIG2 0xdd8UL
-#define MC_PCFIFO_CLIENT_CONFIG2_RESET_VAL 0x20000UL
-#define MC_PCFIFO_CLIENT_CONFIG2_PCFIFO_XUSB_HOSTW_UNORDERED (0UL << 11)
-#define MC_PCFIFO_CLIENT_CONFIG2_PCFIFO_XUSB_HOSTW_MASK (1UL << 11)
-#define MC_PCFIFO_CLIENT_CONFIG2_PCFIFO_XUSB_DEVW_UNORDERED (0UL << 13)
-#define MC_PCFIFO_CLIENT_CONFIG2_PCFIFO_XUSB_DEVW_MASK (1UL << 13)
-
-#define MC_PCFIFO_CLIENT_CONFIG3 0xddcUL
-#define MC_PCFIFO_CLIENT_CONFIG3_RESET_VAL 0UL
-#define MC_PCFIFO_CLIENT_CONFIG3_PCFIFO_SDMMCWAB_UNORDERED (0UL << 7)
-#define MC_PCFIFO_CLIENT_CONFIG3_PCFIFO_SDMMCWAB_MASK (1UL << 7)
-
-#define MC_PCFIFO_CLIENT_CONFIG4 0xde0UL
-#define MC_PCFIFO_CLIENT_CONFIG4_RESET_VAL 0UL
-#define MC_PCFIFO_CLIENT_CONFIG4_PCFIFO_SESWR_UNORDERED (0UL << 1)
-#define MC_PCFIFO_CLIENT_CONFIG4_PCFIFO_SESWR_MASK (1UL << 1)
-#define MC_PCFIFO_CLIENT_CONFIG4_PCFIFO_ETRW_UNORDERED (0UL << 5)
-#define MC_PCFIFO_CLIENT_CONFIG4_PCFIFO_ETRW_MASK (1UL << 5)
-#define MC_PCFIFO_CLIENT_CONFIG4_PCFIFO_AXISW_UNORDERED (0UL << 13)
-#define MC_PCFIFO_CLIENT_CONFIG4_PCFIFO_AXISW_MASK (1UL << 13)
-#define MC_PCFIFO_CLIENT_CONFIG4_PCFIFO_EQOSW_UNORDERED (0UL << 15)
-#define MC_PCFIFO_CLIENT_CONFIG4_PCFIFO_EQOSW_ORDERED (1UL << 15)
-#define MC_PCFIFO_CLIENT_CONFIG4_PCFIFO_EQOSW_MASK (1UL << 15)
-#define MC_PCFIFO_CLIENT_CONFIG4_PCFIFO_UFSHCW_UNORDERED (0UL << 17)
-#define MC_PCFIFO_CLIENT_CONFIG4_PCFIFO_UFSHCW_MASK (1UL << 17)
-#define MC_PCFIFO_CLIENT_CONFIG4_PCFIFO_BPMPDMAW_UNORDERED (0UL << 22)
-#define MC_PCFIFO_CLIENT_CONFIG4_PCFIFO_BPMPDMAW_MASK (1UL << 22)
-#define MC_PCFIFO_CLIENT_CONFIG4_PCFIFO_AONDMAW_UNORDERED (0UL << 26)
-#define MC_PCFIFO_CLIENT_CONFIG4_PCFIFO_AONDMAW_MASK (1UL << 26)
-#define MC_PCFIFO_CLIENT_CONFIG4_PCFIFO_SCEDMAW_UNORDERED (0UL << 30)
-#define MC_PCFIFO_CLIENT_CONFIG4_PCFIFO_SCEDMAW_MASK (1UL << 30)
-
-#define MC_PCFIFO_CLIENT_CONFIG5 0xbf4UL
-#define MC_PCFIFO_CLIENT_CONFIG5_RESET_VAL 0UL
-#define MC_PCFIFO_CLIENT_CONFIG5_PCFIFO_APEDMAW_UNORDERED (0UL << 0)
-#define MC_PCFIFO_CLIENT_CONFIG5_PCFIFO_APEDMAW_MASK (1UL << 0)
-
-#ifndef __ASSEMBLY__
-
-#include <lib/mmio.h>
-
static inline uint32_t tegra_mc_read_32(uint32_t off)
{
return mmio_read_32(TEGRA_MC_BASE + off);
@@ -396,7 +119,7 @@
}
#define mc_set_pcfifo_unordered_boot_so_mss(id, client) \
- (~MC_PCFIFO_CLIENT_CONFIG##id##_PCFIFO_##client##_MASK | \
+ ((uint32_t)~MC_PCFIFO_CLIENT_CONFIG##id##_PCFIFO_##client##_MASK | \
MC_PCFIFO_CLIENT_CONFIG##id##_PCFIFO_##client##_UNORDERED)
#define mc_set_pcfifo_ordered_boot_so_mss(id, client) \
@@ -406,8 +129,24 @@
{ \
mmio_write_32(TEGRA_TSA_BASE + TSA_CONFIG_STATIC0_CSW_##client, \
(TSA_CONFIG_STATIC0_CSW_##client##_RESET & \
- ~TSA_CONFIG_CSW_MEMTYPE_OVERRIDE_MASK) | \
- TSA_CONFIG_CSW_MEMTYPE_OVERRIDE_PASTHRU); \
+ (uint32_t)~TSA_CONFIG_CSW_MEMTYPE_OVERRIDE_MASK) | \
+ (uint32_t)TSA_CONFIG_CSW_MEMTYPE_OVERRIDE_PASTHRU); \
+ }
+
+#define mc_set_tsa_w_passthrough(client) \
+ { \
+ mmio_write_32(TEGRA_TSA_BASE + TSA_CONFIG_STATIC0_CSW_##client, \
+ (TSA_CONFIG_STATIC0_CSW_RESET_W & \
+ (uint32_t)~TSA_CONFIG_CSW_MEMTYPE_OVERRIDE_MASK) | \
+ (uint32_t)TSA_CONFIG_CSW_MEMTYPE_OVERRIDE_PASTHRU); \
+ }
+
+#define mc_set_tsa_r_passthrough(client) \
+ { \
+ mmio_write_32(TEGRA_TSA_BASE + TSA_CONFIG_STATIC0_CSR_##client, \
+ (TSA_CONFIG_STATIC0_CSR_RESET_R & \
+ (uint32_t)~TSA_CONFIG_CSW_MEMTYPE_OVERRIDE_MASK) | \
+ (uint32_t)TSA_CONFIG_CSW_MEMTYPE_OVERRIDE_PASTHRU); \
}
#define mc_set_txn_override(client, normal_axi_id, so_dev_axi_id, normal_override, so_dev_override) \
@@ -426,6 +165,14 @@
******************************************************************************/
tegra_mc_settings_t *tegra_get_mc_settings(void);
-#endif /* __ASSMEBLY__ */
+/*******************************************************************************
+ * Handler to program the scratch registers with TZDRAM settings for the
+ * resume firmware.
+ *
+ * Implemented by SoCs under tegra/soc/txxx
+ ******************************************************************************/
+void plat_memctrl_tzdram_setup(uint64_t phys_base, uint64_t size_in_bytes);
+
+#endif /* __ASSEMBLY__ */
#endif /* MEMCTRL_V2_H */
diff --git a/plat/nvidia/tegra/include/drivers/security_engine.h b/plat/nvidia/tegra/include/drivers/security_engine.h
index abfb217..4ab2f9a 100644
--- a/plat/nvidia/tegra/include/drivers/security_engine.h
+++ b/plat/nvidia/tegra/include/drivers/security_engine.h
@@ -38,8 +38,16 @@
tegra_se_io_lst_t *src_ll_buf;
/* pointer to destination linked list buffer */
tegra_se_io_lst_t *dst_ll_buf;
+ /* LP context buffer pointer */
+ uint32_t *ctx_save_buf;
} tegra_se_dev_t;
+/* PKA1 device structure */
+typedef struct tegra_pka_dev {
+ /* PKA1 base address */
+ uint64_t pka_base;
+} tegra_pka_dev_t;
+
/*******************************************************************************
* Public interface
******************************************************************************/
diff --git a/plat/nvidia/tegra/include/drivers/smmu.h b/plat/nvidia/tegra/include/drivers/smmu.h
index 9582a67..41b0c51 100644
--- a/plat/nvidia/tegra/include/drivers/smmu.h
+++ b/plat/nvidia/tegra/include/drivers/smmu.h
@@ -586,12 +586,12 @@
/*******************************************************************************
* SMMU Global Aux. Control Register
******************************************************************************/
-#define SMMU_CBn_ACTLR_CPRE_BIT (1U << 1)
+#define SMMU_CBn_ACTLR_CPRE_BIT (1ULL << 1U)
/*******************************************************************************
* SMMU configuration constants
******************************************************************************/
-#define ID1_PAGESIZE (1U << 31)
+#define ID1_PAGESIZE (1U << 31U)
#define ID1_NUMPAGENDXB_SHIFT 28U
#define ID1_NUMPAGENDXB_MASK 7U
#define ID1_NUMS2CB_SHIFT 16U
@@ -705,5 +705,6 @@
void tegra_smmu_init(void);
void tegra_smmu_save_context(uint64_t smmu_ctx_addr);
smmu_regs_t *plat_get_smmu_ctx(void);
+uint32_t plat_get_num_smmu_devices(void);
#endif /* SMMU_H */
diff --git a/plat/nvidia/tegra/include/lib/profiler.h b/plat/nvidia/tegra/include/lib/profiler.h
new file mode 100644
index 0000000..60f8d80
--- /dev/null
+++ b/plat/nvidia/tegra/include/lib/profiler.h
@@ -0,0 +1,19 @@
+/*
+ * Copyright (c) 2017, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef __PROFILER_H__
+#define __PROFILER_H__
+
+/*******************************************************************************
+ * Number of bytes of memory used by the profiler on Tegra
+ ******************************************************************************/
+#define PROFILER_SIZE_BYTES U(0x1000)
+
+void boot_profiler_init(uint64_t shmem_base, uint32_t tmr_base);
+void boot_profiler_add_record(const char *str);
+void boot_profiler_deinit(void);
+
+#endif /* __PROFILER_H__ */
diff --git a/plat/nvidia/tegra/include/t132/tegra_def.h b/plat/nvidia/tegra/include/t132/tegra_def.h
index 1f58caa..fd75fbc 100644
--- a/plat/nvidia/tegra/include/t132/tegra_def.h
+++ b/plat/nvidia/tegra/include/t132/tegra_def.h
@@ -83,6 +83,9 @@
******************************************************************************/
#define TEGRA_MC_BASE U(0x70019000)
+/* Memory Controller Interrupt Status */
+#define MC_INTSTATUS 0x00U
+
/* TZDRAM carveout configuration registers */
#define MC_SECURITY_CFG0_0 U(0x70)
#define MC_SECURITY_CFG1_0 U(0x74)
diff --git a/plat/nvidia/tegra/include/t186/tegra186_private.h b/plat/nvidia/tegra/include/t186/tegra186_private.h
new file mode 100644
index 0000000..9e2c02b
--- /dev/null
+++ b/plat/nvidia/tegra/include/t186/tegra186_private.h
@@ -0,0 +1,16 @@
+/*
+ * Copyright (c) 2017, NVIDIA CORPORATION. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef TEGRA186_PRIVATE_H
+#define TEGRA186_PRIVATE_H
+
+void tegra186_cpu_reset_handler(void);
+uint64_t tegra186_get_cpu_reset_handler_base(void);
+uint64_t tegra186_get_cpu_reset_handler_size(void);
+uint64_t tegra186_get_smmu_ctx_offset(void);
+void tegra186_set_system_suspend_entry(void);
+
+#endif /* TEGRA186_PRIVATE_H */
diff --git a/plat/nvidia/tegra/include/t186/tegra_def.h b/plat/nvidia/tegra/include/t186/tegra_def.h
index 3abba55..231f93a 100644
--- a/plat/nvidia/tegra/include/t186/tegra_def.h
+++ b/plat/nvidia/tegra/include/t186/tegra_def.h
@@ -112,8 +112,13 @@
#define TSA_CONFIG_STATIC0_CSW_XUSB_HOSTW U(0x15018)
#define TSA_CONFIG_STATIC0_CSW_XUSB_HOSTW_RESET U(0x1100)
-#define TSA_CONFIG_CSW_MEMTYPE_OVERRIDE_MASK (U(0x3) << 11)
-#define TSA_CONFIG_CSW_MEMTYPE_OVERRIDE_PASTHRU (U(0) << 11)
+#define TSA_CONFIG_CSW_MEMTYPE_OVERRIDE_MASK (ULL(0x3) << 11)
+#define TSA_CONFIG_CSW_MEMTYPE_OVERRIDE_PASTHRU (ULL(0) << 11)
+
+/*******************************************************************************
+ * Tegra General Purpose Centralised DMA constants
+ ******************************************************************************/
+#define TEGRA_GPCDMA_BASE ULL(0x2610000)
/*******************************************************************************
* Tegra Memory Controller constants
@@ -124,18 +129,23 @@
/* General Security Carveout register macros */
#define MC_GSC_CONFIG_REGS_SIZE U(0x40)
#define MC_GSC_LOCK_CFG_SETTINGS_BIT (U(1) << 1)
-#define MC_GSC_ENABLE_TZ_LOCK_BIT (U(1) << 0)
+#define MC_GSC_ENABLE_TZ_LOCK_BIT (ULL(1) << 0)
#define MC_GSC_SIZE_RANGE_4KB_SHIFT U(27)
#define MC_GSC_BASE_LO_SHIFT U(12)
#define MC_GSC_BASE_LO_MASK U(0xFFFFF)
#define MC_GSC_BASE_HI_SHIFT U(0)
#define MC_GSC_BASE_HI_MASK U(3)
+#define MC_GSC_ENABLE_CPU_SECURE_BIT (U(1) << 31)
/* TZDRAM carveout configuration registers */
#define MC_SECURITY_CFG0_0 U(0x70)
#define MC_SECURITY_CFG1_0 U(0x74)
#define MC_SECURITY_CFG3_0 U(0x9BC)
+#define MC_SECURITY_BOM_MASK (U(0xFFF) << 20)
+#define MC_SECURITY_SIZE_MB_MASK (U(0x1FFF) << 0)
+#define MC_SECURITY_BOM_HI_MASK (U(0x3) << 0)
+
/* Video Memory carveout configuration registers */
#define MC_VIDEO_PROTECT_BASE_HI U(0x978)
#define MC_VIDEO_PROTECT_BASE_LO U(0x648)
@@ -156,7 +166,10 @@
#define MC_TZRAM_BASE_LO U(0x2194)
#define MC_TZRAM_BASE_HI U(0x2198)
#define MC_TZRAM_SIZE U(0x219C)
-#define MC_TZRAM_CLIENT_ACCESS_CFG0 U(0x21A0)
+#define MC_TZRAM_CLIENT_ACCESS0_CFG0 U(0x21A0)
+#define MC_TZRAM_CLIENT_ACCESS1_CFG0 U(0x21A4)
+#define TZRAM_ALLOW_MPCORER (U(1) << 7)
+#define TZRAM_ALLOW_MPCOREW (U(1) << 25)
/*******************************************************************************
* Tegra UART Controller constants
@@ -198,6 +211,8 @@
#define TEGRA_CAR_RESET_BASE U(0x05000000)
#define TEGRA_GPU_RESET_REG_OFFSET U(0x30)
#define GPU_RESET_BIT (U(1) << 0)
+#define TEGRA_GPCDMA_RST_SET_REG_OFFSET U(0x6A0004)
+#define TEGRA_GPCDMA_RST_CLR_REG_OFFSET U(0x6A0008)
/*******************************************************************************
* Tegra micro-seconds timer constants
@@ -221,10 +236,19 @@
#define SECURE_SCRATCH_RSV11_HI U(0x6AC)
#define SECURE_SCRATCH_RSV53_LO U(0x7F8)
#define SECURE_SCRATCH_RSV53_HI U(0x7FC)
-#define SECURE_SCRATCH_RSV54_HI U(0x804)
#define SECURE_SCRATCH_RSV55_LO U(0x808)
#define SECURE_SCRATCH_RSV55_HI U(0x80C)
+#define SCRATCH_RESET_VECTOR_LO SECURE_SCRATCH_RSV1_LO
+#define SCRATCH_RESET_VECTOR_HI SECURE_SCRATCH_RSV1_HI
+#define SCRATCH_SECURE_BOOTP_FCFG SECURE_SCRATCH_RSV6
+#define SCRATCH_SMMU_TABLE_ADDR_LO SECURE_SCRATCH_RSV11_LO
+#define SCRATCH_SMMU_TABLE_ADDR_HI SECURE_SCRATCH_RSV11_HI
+#define SCRATCH_BL31_PARAMS_ADDR SECURE_SCRATCH_RSV53_LO
+#define SCRATCH_BL31_PLAT_PARAMS_ADDR SECURE_SCRATCH_RSV53_HI
+#define SCRATCH_TZDRAM_ADDR_LO SECURE_SCRATCH_RSV55_LO
+#define SCRATCH_TZDRAM_ADDR_HI SECURE_SCRATCH_RSV55_HI
+
/*******************************************************************************
* Tegra Memory Mapped Control Register Access constants
******************************************************************************/
diff --git a/plat/nvidia/tegra/include/t186/tegra_mc_def.h b/plat/nvidia/tegra/include/t186/tegra_mc_def.h
new file mode 100644
index 0000000..d051a15
--- /dev/null
+++ b/plat/nvidia/tegra/include/t186/tegra_mc_def.h
@@ -0,0 +1,285 @@
+/*
+ * Copyright (c) 2017, NVIDIA CORPORATION. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef TEGRA_MC_DEF_H
+#define TEGRA_MC_DEF_H
+
+/*******************************************************************************
+ * Memory Controller's PCFIFO client configuration registers
+ ******************************************************************************/
+#define MC_PCFIFO_CLIENT_CONFIG0 0xdd0U
+
+#define MC_PCFIFO_CLIENT_CONFIG1 0xdd4U
+#define MC_PCFIFO_CLIENT_CONFIG1_RESET_VAL 0x20000U
+#define MC_PCFIFO_CLIENT_CONFIG1_PCFIFO_AFIW_UNORDERED (0U << 17)
+#define MC_PCFIFO_CLIENT_CONFIG1_PCFIFO_AFIW_MASK (1U << 17)
+#define MC_PCFIFO_CLIENT_CONFIG1_PCFIFO_HDAW_UNORDERED (0U << 21)
+#define MC_PCFIFO_CLIENT_CONFIG1_PCFIFO_HDAW_MASK (1U << 21)
+#define MC_PCFIFO_CLIENT_CONFIG1_PCFIFO_SATAW_UNORDERED (0U << 29)
+#define MC_PCFIFO_CLIENT_CONFIG1_PCFIFO_SATAW_MASK (1U << 29)
+
+#define MC_PCFIFO_CLIENT_CONFIG2 0xdd8U
+#define MC_PCFIFO_CLIENT_CONFIG2_RESET_VAL 0x20000U
+#define MC_PCFIFO_CLIENT_CONFIG2_PCFIFO_XUSB_HOSTW_UNORDERED (0U << 11)
+#define MC_PCFIFO_CLIENT_CONFIG2_PCFIFO_XUSB_HOSTW_MASK (1U << 11)
+#define MC_PCFIFO_CLIENT_CONFIG2_PCFIFO_XUSB_DEVW_UNORDERED (0U << 13)
+#define MC_PCFIFO_CLIENT_CONFIG2_PCFIFO_XUSB_DEVW_MASK (1U << 13)
+
+#define MC_PCFIFO_CLIENT_CONFIG3 0xddcU
+#define MC_PCFIFO_CLIENT_CONFIG3_RESET_VAL 0U
+#define MC_PCFIFO_CLIENT_CONFIG3_PCFIFO_SDMMCWAB_UNORDERED (0U << 7)
+#define MC_PCFIFO_CLIENT_CONFIG3_PCFIFO_SDMMCWAB_MASK (1U << 7)
+
+#define MC_PCFIFO_CLIENT_CONFIG4 0xde0U
+#define MC_PCFIFO_CLIENT_CONFIG4_RESET_VAL 0U
+#define MC_PCFIFO_CLIENT_CONFIG4_PCFIFO_SESWR_UNORDERED (0U << 1)
+#define MC_PCFIFO_CLIENT_CONFIG4_PCFIFO_SESWR_MASK (1U << 1)
+#define MC_PCFIFO_CLIENT_CONFIG4_PCFIFO_ETRW_UNORDERED (0U << 5)
+#define MC_PCFIFO_CLIENT_CONFIG4_PCFIFO_ETRW_MASK (1U << 5)
+#define MC_PCFIFO_CLIENT_CONFIG4_PCFIFO_AXISW_UNORDERED (0U << 13)
+#define MC_PCFIFO_CLIENT_CONFIG4_PCFIFO_AXISW_MASK (1U << 13)
+#define MC_PCFIFO_CLIENT_CONFIG4_PCFIFO_EQOSW_UNORDERED (0U << 15)
+#define MC_PCFIFO_CLIENT_CONFIG4_PCFIFO_EQOSW_ORDERED (1U << 15)
+#define MC_PCFIFO_CLIENT_CONFIG4_PCFIFO_EQOSW_MASK (1U << 15)
+#define MC_PCFIFO_CLIENT_CONFIG4_PCFIFO_UFSHCW_UNORDERED (0U << 17)
+#define MC_PCFIFO_CLIENT_CONFIG4_PCFIFO_UFSHCW_MASK (1U << 17)
+#define MC_PCFIFO_CLIENT_CONFIG4_PCFIFO_BPMPDMAW_UNORDERED (0U << 22)
+#define MC_PCFIFO_CLIENT_CONFIG4_PCFIFO_BPMPDMAW_MASK (1U << 22)
+#define MC_PCFIFO_CLIENT_CONFIG4_PCFIFO_AONDMAW_UNORDERED (0U << 26)
+#define MC_PCFIFO_CLIENT_CONFIG4_PCFIFO_AONDMAW_MASK (1U << 26)
+#define MC_PCFIFO_CLIENT_CONFIG4_PCFIFO_SCEDMAW_UNORDERED (0U << 30)
+#define MC_PCFIFO_CLIENT_CONFIG4_PCFIFO_SCEDMAW_MASK (1U << 30)
+
+#define MC_PCFIFO_CLIENT_CONFIG5 0xbf4U
+#define MC_PCFIFO_CLIENT_CONFIG5_RESET_VAL 0U
+#define MC_PCFIFO_CLIENT_CONFIG5_PCFIFO_APEDMAW_UNORDERED (0U << 0)
+#define MC_PCFIFO_CLIENT_CONFIG5_PCFIFO_APEDMAW_MASK (1U << 0)
+
+/*******************************************************************************
+ * Stream ID Override Config registers
+ ******************************************************************************/
+#define MC_STREAMID_OVERRIDE_CFG_PTCR 0x000U
+#define MC_STREAMID_OVERRIDE_CFG_AFIR 0x070U
+#define MC_STREAMID_OVERRIDE_CFG_HDAR 0x0A8U
+#define MC_STREAMID_OVERRIDE_CFG_HOST1XDMAR 0x0B0U
+#define MC_STREAMID_OVERRIDE_CFG_NVENCSRD 0x0E0U
+#define MC_STREAMID_OVERRIDE_CFG_SATAR 0x0F8U
+#define MC_STREAMID_OVERRIDE_CFG_MPCORER 0x138U
+#define MC_STREAMID_OVERRIDE_CFG_NVENCSWR 0x158U
+#define MC_STREAMID_OVERRIDE_CFG_AFIW 0x188U
+#define MC_STREAMID_OVERRIDE_CFG_HDAW 0x1A8U
+#define MC_STREAMID_OVERRIDE_CFG_MPCOREW 0x1C8U
+#define MC_STREAMID_OVERRIDE_CFG_SATAW 0x1E8U
+#define MC_STREAMID_OVERRIDE_CFG_ISPRA 0x220U
+#define MC_STREAMID_OVERRIDE_CFG_ISPWA 0x230U
+#define MC_STREAMID_OVERRIDE_CFG_ISPWB 0x238U
+#define MC_STREAMID_OVERRIDE_CFG_XUSB_HOSTR 0x250U
+#define MC_STREAMID_OVERRIDE_CFG_XUSB_HOSTW 0x258U
+#define MC_STREAMID_OVERRIDE_CFG_XUSB_DEVR 0x260U
+#define MC_STREAMID_OVERRIDE_CFG_XUSB_DEVW 0x268U
+#define MC_STREAMID_OVERRIDE_CFG_TSECSRD 0x2A0U
+#define MC_STREAMID_OVERRIDE_CFG_TSECSWR 0x2A8U
+#define MC_STREAMID_OVERRIDE_CFG_GPUSRD 0x2C0U
+#define MC_STREAMID_OVERRIDE_CFG_GPUSWR 0x2C8U
+#define MC_STREAMID_OVERRIDE_CFG_SDMMCRA 0x300U
+#define MC_STREAMID_OVERRIDE_CFG_SDMMCRAA 0x308U
+#define MC_STREAMID_OVERRIDE_CFG_SDMMCR 0x310U
+#define MC_STREAMID_OVERRIDE_CFG_SDMMCRAB 0x318U
+#define MC_STREAMID_OVERRIDE_CFG_SDMMCWA 0x320U
+#define MC_STREAMID_OVERRIDE_CFG_SDMMCWAA 0x328U
+#define MC_STREAMID_OVERRIDE_CFG_SDMMCW 0x330U
+#define MC_STREAMID_OVERRIDE_CFG_SDMMCWAB 0x338U
+#define MC_STREAMID_OVERRIDE_CFG_VICSRD 0x360U
+#define MC_STREAMID_OVERRIDE_CFG_VICSWR 0x368U
+#define MC_STREAMID_OVERRIDE_CFG_VIW 0x390U
+#define MC_STREAMID_OVERRIDE_CFG_NVDECSRD 0x3C0U
+#define MC_STREAMID_OVERRIDE_CFG_NVDECSWR 0x3C8U
+#define MC_STREAMID_OVERRIDE_CFG_APER 0x3D0U
+#define MC_STREAMID_OVERRIDE_CFG_APEW 0x3D8U
+#define MC_STREAMID_OVERRIDE_CFG_NVJPGSRD 0x3F0U
+#define MC_STREAMID_OVERRIDE_CFG_NVJPGSWR 0x3F8U
+#define MC_STREAMID_OVERRIDE_CFG_SESRD 0x400U
+#define MC_STREAMID_OVERRIDE_CFG_SESWR 0x408U
+#define MC_STREAMID_OVERRIDE_CFG_ETRR 0x420U
+#define MC_STREAMID_OVERRIDE_CFG_ETRW 0x428U
+#define MC_STREAMID_OVERRIDE_CFG_TSECSRDB 0x430U
+#define MC_STREAMID_OVERRIDE_CFG_TSECSWRB 0x438U
+#define MC_STREAMID_OVERRIDE_CFG_GPUSRD2 0x440U
+#define MC_STREAMID_OVERRIDE_CFG_GPUSWR2 0x448U
+#define MC_STREAMID_OVERRIDE_CFG_AXISR 0x460U
+#define MC_STREAMID_OVERRIDE_CFG_AXISW 0x468U
+#define MC_STREAMID_OVERRIDE_CFG_EQOSR 0x470U
+#define MC_STREAMID_OVERRIDE_CFG_EQOSW 0x478U
+#define MC_STREAMID_OVERRIDE_CFG_UFSHCR 0x480U
+#define MC_STREAMID_OVERRIDE_CFG_UFSHCW 0x488U
+#define MC_STREAMID_OVERRIDE_CFG_NVDISPLAYR 0x490U
+#define MC_STREAMID_OVERRIDE_CFG_BPMPR 0x498U
+#define MC_STREAMID_OVERRIDE_CFG_BPMPW 0x4A0U
+#define MC_STREAMID_OVERRIDE_CFG_BPMPDMAR 0x4A8U
+#define MC_STREAMID_OVERRIDE_CFG_BPMPDMAW 0x4B0U
+#define MC_STREAMID_OVERRIDE_CFG_AONR 0x4B8U
+#define MC_STREAMID_OVERRIDE_CFG_AONW 0x4C0U
+#define MC_STREAMID_OVERRIDE_CFG_AONDMAR 0x4C8U
+#define MC_STREAMID_OVERRIDE_CFG_AONDMAW 0x4D0U
+#define MC_STREAMID_OVERRIDE_CFG_SCER 0x4D8U
+#define MC_STREAMID_OVERRIDE_CFG_SCEW 0x4E0U
+#define MC_STREAMID_OVERRIDE_CFG_SCEDMAR 0x4E8U
+#define MC_STREAMID_OVERRIDE_CFG_SCEDMAW 0x4F0U
+#define MC_STREAMID_OVERRIDE_CFG_APEDMAR 0x4F8U
+#define MC_STREAMID_OVERRIDE_CFG_APEDMAW 0x500U
+#define MC_STREAMID_OVERRIDE_CFG_NVDISPLAYR1 0x508U
+#define MC_STREAMID_OVERRIDE_CFG_VICSRD1 0x510U
+#define MC_STREAMID_OVERRIDE_CFG_NVDECSRD1 0x518U
+
+/*******************************************************************************
+ * Macro to calculate Security cfg register addr from StreamID Override register
+ ******************************************************************************/
+#define MC_STREAMID_OVERRIDE_TO_SECURITY_CFG(addr) ((addr) + (uint32_t)sizeof(uint32_t))
+
+#define MC_TXN_OVERRIDE_CONFIG_COH_PATH_NO_OVERRIDE_SO_DEV (0U << 4)
+#define MC_TXN_OVERRIDE_CONFIG_COH_PATH_FORCE_NON_COHERENT_SO_DEV (1U << 4)
+#define MC_TXN_OVERRIDE_CONFIG_COH_PATH_FORCE_COHERENT_SO_DEV (2U << 4)
+#define MC_TXN_OVERRIDE_CONFIG_COH_PATH_FORCE_COHERENT_SNOOP_SO_DEV (3U << 4)
+
+#define MC_TXN_OVERRIDE_CONFIG_COH_PATH_NO_OVERRIDE_NORMAL (0U << 8)
+#define MC_TXN_OVERRIDE_CONFIG_COH_PATH_FORCE_NON_COHERENT_NORMAL (1U << 8)
+#define MC_TXN_OVERRIDE_CONFIG_COH_PATH_FORCE_COHERENT_NORMAL (2U << 8)
+#define MC_TXN_OVERRIDE_CONFIG_COH_PATH_FORCE_COHERENT_SNOOP_NORMAL (3U << 8)
+
+#define MC_TXN_OVERRIDE_CONFIG_CGID_SO_DEV_ZERO (0U << 12)
+#define MC_TXN_OVERRIDE_CONFIG_CGID_SO_DEV_CLIENT_AXI_ID (1U << 12)
+
+/*******************************************************************************
+ * Memory Controller transaction override config registers
+ ******************************************************************************/
+#define MC_TXN_OVERRIDE_CONFIG_HDAR 0x10a8U
+#define MC_TXN_OVERRIDE_CONFIG_BPMPW 0x14a0U
+#define MC_TXN_OVERRIDE_CONFIG_PTCR 0x1000U
+#define MC_TXN_OVERRIDE_CONFIG_NVDISPLAYR 0x1490U
+#define MC_TXN_OVERRIDE_CONFIG_EQOSW 0x1478U
+#define MC_TXN_OVERRIDE_CONFIG_NVJPGSWR 0x13f8U
+#define MC_TXN_OVERRIDE_CONFIG_ISPRA 0x1220U
+#define MC_TXN_OVERRIDE_CONFIG_SDMMCWAA 0x1328U
+#define MC_TXN_OVERRIDE_CONFIG_VICSRD 0x1360U
+#define MC_TXN_OVERRIDE_CONFIG_MPCOREW 0x11c8U
+#define MC_TXN_OVERRIDE_CONFIG_GPUSRD 0x12c0U
+#define MC_TXN_OVERRIDE_CONFIG_AXISR 0x1460U
+#define MC_TXN_OVERRIDE_CONFIG_SCEDMAW 0x14f0U
+#define MC_TXN_OVERRIDE_CONFIG_SDMMCW 0x1330U
+#define MC_TXN_OVERRIDE_CONFIG_EQOSR 0x1470U
+#define MC_TXN_OVERRIDE_CONFIG_APEDMAR 0x14f8U
+#define MC_TXN_OVERRIDE_CONFIG_NVENCSRD 0x10e0U
+#define MC_TXN_OVERRIDE_CONFIG_SDMMCRAB 0x1318U
+#define MC_TXN_OVERRIDE_CONFIG_VICSRD1 0x1510U
+#define MC_TXN_OVERRIDE_CONFIG_BPMPDMAR 0x14a8U
+#define MC_TXN_OVERRIDE_CONFIG_VIW 0x1390U
+#define MC_TXN_OVERRIDE_CONFIG_SDMMCRAA 0x1308U
+#define MC_TXN_OVERRIDE_CONFIG_AXISW 0x1468U
+#define MC_TXN_OVERRIDE_CONFIG_XUSB_DEVR 0x1260U
+#define MC_TXN_OVERRIDE_CONFIG_UFSHCR 0x1480U
+#define MC_TXN_OVERRIDE_CONFIG_TSECSWR 0x12a8U
+#define MC_TXN_OVERRIDE_CONFIG_GPUSWR 0x12c8U
+#define MC_TXN_OVERRIDE_CONFIG_SATAR 0x10f8U
+#define MC_TXN_OVERRIDE_CONFIG_XUSB_HOSTW 0x1258U
+#define MC_TXN_OVERRIDE_CONFIG_TSECSWRB 0x1438U
+#define MC_TXN_OVERRIDE_CONFIG_GPUSRD2 0x1440U
+#define MC_TXN_OVERRIDE_CONFIG_SCEDMAR 0x14e8U
+#define MC_TXN_OVERRIDE_CONFIG_GPUSWR2 0x1448U
+#define MC_TXN_OVERRIDE_CONFIG_AONDMAW 0x14d0U
+#define MC_TXN_OVERRIDE_CONFIG_APEDMAW 0x1500U
+#define MC_TXN_OVERRIDE_CONFIG_AONW 0x14c0U
+#define MC_TXN_OVERRIDE_CONFIG_HOST1XDMAR 0x10b0U
+#define MC_TXN_OVERRIDE_CONFIG_ETRR 0x1420U
+#define MC_TXN_OVERRIDE_CONFIG_SESWR 0x1408U
+#define MC_TXN_OVERRIDE_CONFIG_NVJPGSRD 0x13f0U
+#define MC_TXN_OVERRIDE_CONFIG_NVDECSRD 0x13c0U
+#define MC_TXN_OVERRIDE_CONFIG_TSECSRDB 0x1430U
+#define MC_TXN_OVERRIDE_CONFIG_BPMPDMAW 0x14b0U
+#define MC_TXN_OVERRIDE_CONFIG_APER 0x13d0U
+#define MC_TXN_OVERRIDE_CONFIG_NVDECSRD1 0x1518U
+#define MC_TXN_OVERRIDE_CONFIG_XUSB_HOSTR 0x1250U
+#define MC_TXN_OVERRIDE_CONFIG_ISPWA 0x1230U
+#define MC_TXN_OVERRIDE_CONFIG_SESRD 0x1400U
+#define MC_TXN_OVERRIDE_CONFIG_SCER 0x14d8U
+#define MC_TXN_OVERRIDE_CONFIG_AONR 0x14b8U
+#define MC_TXN_OVERRIDE_CONFIG_MPCORER 0x1138U
+#define MC_TXN_OVERRIDE_CONFIG_SDMMCWA 0x1320U
+#define MC_TXN_OVERRIDE_CONFIG_HDAW 0x11a8U
+#define MC_TXN_OVERRIDE_CONFIG_NVDECSWR 0x13c8U
+#define MC_TXN_OVERRIDE_CONFIG_UFSHCW 0x1488U
+#define MC_TXN_OVERRIDE_CONFIG_AONDMAR 0x14c8U
+#define MC_TXN_OVERRIDE_CONFIG_SATAW 0x11e8U
+#define MC_TXN_OVERRIDE_CONFIG_ETRW 0x1428U
+#define MC_TXN_OVERRIDE_CONFIG_VICSWR 0x1368U
+#define MC_TXN_OVERRIDE_CONFIG_NVENCSWR 0x1158U
+#define MC_TXN_OVERRIDE_CONFIG_AFIR 0x1070U
+#define MC_TXN_OVERRIDE_CONFIG_SDMMCWAB 0x1338U
+#define MC_TXN_OVERRIDE_CONFIG_SDMMCRA 0x1300U
+#define MC_TXN_OVERRIDE_CONFIG_NVDISPLAYR1 0x1508U
+#define MC_TXN_OVERRIDE_CONFIG_ISPWB 0x1238U
+#define MC_TXN_OVERRIDE_CONFIG_BPMPR 0x1498U
+#define MC_TXN_OVERRIDE_CONFIG_APEW 0x13d8U
+#define MC_TXN_OVERRIDE_CONFIG_SDMMCR 0x1310U
+#define MC_TXN_OVERRIDE_CONFIG_XUSB_DEVW 0x1268U
+#define MC_TXN_OVERRIDE_CONFIG_TSECSRD 0x12a0U
+#define MC_TXN_OVERRIDE_CONFIG_AFIW 0x1188U
+#define MC_TXN_OVERRIDE_CONFIG_SCEW 0x14e0U
+
+#define MC_TXN_OVERRIDE_CONFIG_AXID_OVERRIDE_CGID (1U << 0)
+#define MC_TXN_OVERRIDE_CONFIG_COH_PATH_OVERRIDE_SO_DEV (2U << 4)
+#define MC_TXN_OVERRIDE_CONFIG_AXID_OVERRIDE_SO_DEV_CGID_SO_DEV_CLIENT (1U << 12)
+
+/*******************************************************************************
+ * Non-SO_DEV transactions override values for CGID_TAG bitfield for the
+ * MC_TXN_OVERRIDE_CONFIG_{module} registers
+ ******************************************************************************/
+#define MC_TXN_OVERRIDE_CGID_TAG_DEFAULT 0U
+#define MC_TXN_OVERRIDE_CGID_TAG_CLIENT_AXI_ID 1U
+#define MC_TXN_OVERRIDE_CGID_TAG_ZERO 2U
+#define MC_TXN_OVERRIDE_CGID_TAG_ADR 3U
+#define MC_TXN_OVERRIDE_CGID_TAG_MASK 3ULL
+
+/*******************************************************************************
+ * Memory Controller Reset Control registers
+ ******************************************************************************/
+#define MC_CLIENT_HOTRESET_CTRL0 0x200U
+#define MC_CLIENT_HOTRESET_CTRL0_RESET_VAL 0U
+#define MC_CLIENT_HOTRESET_CTRL0_AFI_FLUSH_ENB (1U << 0)
+#define MC_CLIENT_HOTRESET_CTRL0_HC_FLUSH_ENB (1U << 6)
+#define MC_CLIENT_HOTRESET_CTRL0_HDA_FLUSH_ENB (1U << 7)
+#define MC_CLIENT_HOTRESET_CTRL0_ISP2_FLUSH_ENB (1U << 8)
+#define MC_CLIENT_HOTRESET_CTRL0_MPCORE_FLUSH_ENB (1U << 9)
+#define MC_CLIENT_HOTRESET_CTRL0_NVENC_FLUSH_ENB (1U << 11)
+#define MC_CLIENT_HOTRESET_CTRL0_SATA_FLUSH_ENB (1U << 15)
+#define MC_CLIENT_HOTRESET_CTRL0_VI_FLUSH_ENB (1U << 17)
+#define MC_CLIENT_HOTRESET_CTRL0_VIC_FLUSH_ENB (1U << 18)
+#define MC_CLIENT_HOTRESET_CTRL0_XUSB_HOST_FLUSH_ENB (1U << 19)
+#define MC_CLIENT_HOTRESET_CTRL0_XUSB_DEV_FLUSH_ENB (1U << 20)
+#define MC_CLIENT_HOTRESET_CTRL0_TSEC_FLUSH_ENB (1U << 22)
+#define MC_CLIENT_HOTRESET_CTRL0_SDMMC1A_FLUSH_ENB (1U << 29)
+#define MC_CLIENT_HOTRESET_CTRL0_SDMMC2A_FLUSH_ENB (1U << 30)
+#define MC_CLIENT_HOTRESET_CTRL0_SDMMC3A_FLUSH_ENB (1U << 31)
+#define MC_CLIENT_HOTRESET_STATUS0 0x204U
+#define MC_CLIENT_HOTRESET_CTRL1 0x970U
+#define MC_CLIENT_HOTRESET_CTRL1_RESET_VAL 0U
+#define MC_CLIENT_HOTRESET_CTRL1_SDMMC4A_FLUSH_ENB (1U << 0)
+#define MC_CLIENT_HOTRESET_CTRL1_GPU_FLUSH_ENB (1U << 2)
+#define MC_CLIENT_HOTRESET_CTRL1_NVDEC_FLUSH_ENB (1U << 5)
+#define MC_CLIENT_HOTRESET_CTRL1_APE_FLUSH_ENB (1U << 6)
+#define MC_CLIENT_HOTRESET_CTRL1_SE_FLUSH_ENB (1U << 7)
+#define MC_CLIENT_HOTRESET_CTRL1_NVJPG_FLUSH_ENB (1U << 8)
+#define MC_CLIENT_HOTRESET_CTRL1_ETR_FLUSH_ENB (1U << 12)
+#define MC_CLIENT_HOTRESET_CTRL1_TSECB_FLUSH_ENB (1U << 13)
+#define MC_CLIENT_HOTRESET_CTRL1_AXIS_FLUSH_ENB (1U << 18)
+#define MC_CLIENT_HOTRESET_CTRL1_EQOS_FLUSH_ENB (1U << 19)
+#define MC_CLIENT_HOTRESET_CTRL1_UFSHC_FLUSH_ENB (1U << 20)
+#define MC_CLIENT_HOTRESET_CTRL1_NVDISPLAY_FLUSH_ENB (1U << 21)
+#define MC_CLIENT_HOTRESET_CTRL1_BPMP_FLUSH_ENB (1U << 22)
+#define MC_CLIENT_HOTRESET_CTRL1_AON_FLUSH_ENB (1U << 23)
+#define MC_CLIENT_HOTRESET_CTRL1_SCE_FLUSH_ENB (1U << 24)
+#define MC_CLIENT_HOTRESET_STATUS1 0x974U
+
+#endif /* TEGRA_MC_DEF_H */
diff --git a/plat/nvidia/tegra/include/t210/tegra_def.h b/plat/nvidia/tegra/include/t210/tegra_def.h
index 8d71cae..75919e1 100644
--- a/plat/nvidia/tegra/include/t210/tegra_def.h
+++ b/plat/nvidia/tegra/include/t210/tegra_def.h
@@ -89,6 +89,16 @@
#define TEGRA_RST_DEV_CLR_V U(0x434)
#define TEGRA_CLK_ENB_V U(0x440)
+/* SE Clock Offsets */
+#define TEGRA_RST_DEVICES_V 0x358UL
+#define SE_RESET_BIT (0x1UL << 31)
+#define TEGRA_RST_DEVICES_W 0x35CUL
+#define ENTROPY_CLK_ENB_BIT (0x1UL << 21)
+#define TEGRA_CLK_OUT_ENB_V 0x360UL
+#define SE_CLK_ENB_BIT (0x1UL << 31)
+#define TEGRA_CLK_OUT_ENB_W 0x364UL
+#define ENTROPY_RESET_BIT (0x1UL << 21)
+
/*******************************************************************************
* Tegra Flow Controller constants
******************************************************************************/
@@ -125,6 +135,16 @@
#define TEGRA_UARTE_BASE U(0x70006400)
/*******************************************************************************
+ * Tegra Fuse Controller related constants
+ ******************************************************************************/
+#define TEGRA_FUSE_BASE 0x7000F800UL
+#define FUSE_BOOT_SECURITY_INFO 0x268UL
+#define FUSE_ATOMIC_SAVE_CARVEOUT_EN (0x1U << 7)
+#define FUSE_JTAG_SECUREID_VALID (0x104UL)
+#define ECID_VALID (0x1UL)
+
+
+/*******************************************************************************
* Tegra Power Mgmt Controller constants
******************************************************************************/
#define TEGRA_PMC_BASE U(0x7000E400)
@@ -143,6 +163,9 @@
******************************************************************************/
#define TEGRA_MC_BASE U(0x70019000)
+/* Memory Controller Interrupt Status */
+#define MC_INTSTATUS 0x00U
+
/* TZDRAM carveout configuration registers */
#define MC_SECURITY_CFG0_0 U(0x70)
#define MC_SECURITY_CFG1_0 U(0x74)
@@ -153,6 +176,10 @@
#define MC_VIDEO_PROTECT_BASE_LO U(0x648)
#define MC_VIDEO_PROTECT_SIZE_MB U(0x64c)
+/* SMMU configuration registers*/
+#define MC_SMMU_PPCS_ASID_0 0x270U
+#define PPCS_SMMU_ENABLE (0x1U << 31)
+
/*******************************************************************************
* Tegra SE constants
******************************************************************************/
@@ -168,4 +195,10 @@
#define TEGRA_TZRAM_BASE U(0x7C010000)
#define TEGRA_TZRAM_SIZE U(0x10000)
+/*******************************************************************************
+ * Tegra TZRAM carveout constants
+ ******************************************************************************/
+#define TEGRA_TZRAM_CARVEOUT_BASE U(0x7C04C000)
+#define TEGRA_TZRAM_CARVEOUT_SIZE U(0x4000)
+
#endif /* TEGRA_DEF_H */
diff --git a/plat/nvidia/tegra/include/tegra_platform.h b/plat/nvidia/tegra/include/tegra_platform.h
index 1e7ba16..13c92e0 100644
--- a/plat/nvidia/tegra/include/tegra_platform.h
+++ b/plat/nvidia/tegra/include/tegra_platform.h
@@ -46,7 +46,6 @@
bool tegra_chipid_is_t210(void);
bool tegra_chipid_is_t210_b01(void);
-
/*
* Tegra platform identifiers
*/
diff --git a/plat/nvidia/tegra/include/tegra_private.h b/plat/nvidia/tegra/include/tegra_private.h
index 1682927..68b4624 100644
--- a/plat/nvidia/tegra/include/tegra_private.h
+++ b/plat/nvidia/tegra/include/tegra_private.h
@@ -23,6 +23,16 @@
#define TEGRA_DRAM_END ULL(0x27FFFFFFF)
/*******************************************************************************
+ * Implementation defined ACTLR_EL1 bit definitions
+ ******************************************************************************/
+#define ACTLR_EL1_PMSTATE_MASK (ULL(0xF) << 0)
+
+/*******************************************************************************
+ * Implementation defined ACTLR_EL2 bit definitions
+ ******************************************************************************/
+#define ACTLR_EL2_PMSTATE_MASK (ULL(0xF) << 0)
+
+/*******************************************************************************
* Struct for parameters received from BL2
******************************************************************************/
typedef struct plat_params_from_bl2 {
@@ -31,9 +41,11 @@
/* TZ memory base */
uint64_t tzdram_base;
/* UART port ID */
- int uart_id;
+ int32_t uart_id;
/* L2 ECC parity protection disable flag */
- int l2_ecc_parity_prot_dis;
+ int32_t l2_ecc_parity_prot_dis;
+ /* SHMEM base address for storing the boot logs */
+ uint64_t boot_profiler_shmem_base;
} plat_params_from_bl2_t;
/*******************************************************************************
@@ -63,6 +75,8 @@
void plat_gic_setup(void);
struct tegra_bl31_params *plat_get_bl31_params(void);
plat_params_from_bl2_t *plat_get_bl31_plat_params(void);
+void plat_early_platform_setup(void);
+void plat_late_platform_setup(void);
/* Declarations for plat_secondary.c */
void plat_secondary_setup(void);
@@ -82,7 +96,30 @@
void tegra_pm_system_suspend_entry(void);
void tegra_pm_system_suspend_exit(void);
-int tegra_system_suspended(void);
+int32_t tegra_system_suspended(void);
+int32_t tegra_soc_pwr_domain_suspend(const psci_power_state_t *target_state);
+int32_t tegra_soc_pwr_domain_on(u_register_t mpidr);
+int32_t tegra_soc_pwr_domain_off(const psci_power_state_t *target_state);
+int32_t tegra_soc_pwr_domain_on_finish(const psci_power_state_t *target_state);
+int32_t tegra_soc_pwr_domain_power_down_wfi(const psci_power_state_t *target_state);
+int32_t tegra_soc_prepare_system_reset(void);
+__dead2 void tegra_soc_prepare_system_off(void);
+plat_local_state_t tegra_soc_get_target_pwr_state(uint32_t lvl,
+ const plat_local_state_t *states,
+ uint32_t ncpu);
+void tegra_get_sys_suspend_power_state(psci_power_state_t *req_state);
+void tegra_cpu_standby(plat_local_state_t cpu_state);
+int32_t tegra_pwr_domain_on(u_register_t mpidr);
+void tegra_pwr_domain_off(const psci_power_state_t *target_state);
+void tegra_pwr_domain_suspend(const psci_power_state_t *target_state);
+void __dead2 tegra_pwr_domain_power_down_wfi(const psci_power_state_t *target_state);
+void tegra_pwr_domain_on_finish(const psci_power_state_t *target_state);
+void tegra_pwr_domain_suspend_finish(const psci_power_state_t *target_state);
+__dead2 void tegra_system_off(void);
+__dead2 void tegra_system_reset(void);
+int32_t tegra_validate_power_state(uint32_t power_state,
+ psci_power_state_t *req_state);
+int32_t tegra_validate_ns_entrypoint(uintptr_t entrypoint);
/* Declarations for tegraXXX_pm.c */
int tegra_prepare_cpu_suspend(unsigned int id, unsigned int afflvl);
@@ -90,8 +127,7 @@
/* Declarations for tegra_bl31_setup.c */
plat_params_from_bl2_t *bl31_get_plat_params(void);
-int bl31_check_ns_address(uint64_t base, uint64_t size_in_bytes);
-void plat_early_platform_setup(void);
+int32_t bl31_check_ns_address(uint64_t base, uint64_t size_in_bytes);
/* Declarations for tegra_delay_timer.c */
void tegra_delay_timer_init(void);
diff --git a/plat/nvidia/tegra/platform.mk b/plat/nvidia/tegra/platform.mk
index 33548b7..614d2a2 100644
--- a/plat/nvidia/tegra/platform.mk
+++ b/plat/nvidia/tegra/platform.mk
@@ -12,6 +12,8 @@
# enable assert() for release/debug builds
ENABLE_ASSERTIONS := 1
+PLAT_LOG_LEVEL_ASSERT := 40
+$(eval $(call add_define,PLAT_LOG_LEVEL_ASSERT))
# enable dynamic memory mapping
PLAT_XLAT_TABLES_DYNAMIC := 1
@@ -29,11 +31,14 @@
# do not enable SVE
ENABLE_SVE_FOR_NS := 0
+# enable D-cache early during CPU warmboot
+WARMBOOT_ENABLE_DCACHE_EARLY := 1
+
include plat/nvidia/tegra/common/tegra_common.mk
include ${SOC_DIR}/platform_${TARGET_SOC}.mk
# modify BUILD_PLAT to point to SoC specific build directory
BUILD_PLAT := ${BUILD_BASE}/${PLAT}/${TARGET_SOC}/${BUILD_TYPE}
-# enable signed comparison checks
-TF_CFLAGS += -Wsign-compare
+# platform cflags (enable signed comparisons, disable stdlib)
+TF_CFLAGS += -Wsign-compare -nostdlib
diff --git a/plat/nvidia/tegra/soc/t132/plat_psci_handlers.c b/plat/nvidia/tegra/soc/t132/plat_psci_handlers.c
index 7226120..bd3f46f 100644
--- a/plat/nvidia/tegra/soc/t132/plat_psci_handlers.c
+++ b/plat/nvidia/tegra/soc/t132/plat_psci_handlers.c
@@ -98,19 +98,24 @@
int tegra_soc_pwr_domain_off(const psci_power_state_t *target_state)
{
+ uint64_t val;
+
tegra_fc_cpu_off(read_mpidr() & MPIDR_CPU_MASK);
/* Disable DCO operations */
denver_disable_dco();
/* Power down the CPU */
- write_actlr_el1(DENVER_CPU_STATE_POWER_DOWN);
+ val = read_actlr_el1() & ~ACTLR_EL1_PMSTATE_MASK;
+ write_actlr_el1(val | DENVER_CPU_STATE_POWER_DOWN);
return PSCI_E_SUCCESS;
}
int tegra_soc_pwr_domain_suspend(const psci_power_state_t *target_state)
{
+ uint64_t val;
+
#if ENABLE_ASSERTIONS
int cpu = read_mpidr() & MPIDR_CPU_MASK;
@@ -128,7 +133,8 @@
denver_disable_dco();
/* Program the suspend state ID */
- write_actlr_el1(target_state->pwr_domain_state[PLAT_MAX_PWR_LVL]);
+ val = read_actlr_el1() & ~ACTLR_EL1_PMSTATE_MASK;
+ write_actlr_el1(val | target_state->pwr_domain_state[PLAT_MAX_PWR_LVL]);
return PSCI_E_SUCCESS;
}
diff --git a/plat/nvidia/tegra/soc/t132/platform_t132.mk b/plat/nvidia/tegra/soc/t132/platform_t132.mk
index f15ee74..bb7b7ee 100644
--- a/plat/nvidia/tegra/soc/t132/platform_t132.mk
+++ b/plat/nvidia/tegra/soc/t132/platform_t132.mk
@@ -19,7 +19,8 @@
MAX_MMAP_REGIONS := 8
$(eval $(call add_define,MAX_MMAP_REGIONS))
-BL31_SOURCES += lib/cpus/aarch64/denver.S \
+BL31_SOURCES += drivers/ti/uart/aarch64/16550_console.S \
+ lib/cpus/aarch64/denver.S \
${COMMON_DIR}/drivers/flowctrl/flowctrl.c \
${COMMON_DIR}/drivers/memctrl/memctrl_v1.c \
${SOC_DIR}/plat_psci_handlers.c \
diff --git a/plat/nvidia/tegra/soc/t186/drivers/include/mce_private.h b/plat/nvidia/tegra/soc/t186/drivers/include/mce_private.h
index 96a5525..203f61a 100644
--- a/plat/nvidia/tegra/soc/t186/drivers/include/mce_private.h
+++ b/plat/nvidia/tegra/soc/t186/drivers/include/mce_private.h
@@ -64,19 +64,17 @@
#define MCA_ARG_FINISH_MASK U(0xFF)
/*******************************************************************************
- * Uncore PERFMON ARI struct
+ * Uncore PERFMON ARI macros
******************************************************************************/
#define UNCORE_PERFMON_CMD_READ U(0)
#define UNCORE_PERFMON_CMD_WRITE U(1)
#define UNCORE_PERFMON_CMD_MASK U(0xFF)
-#define UNCORE_PERFMON_CMD_SHIFT U(24)
#define UNCORE_PERFMON_UNIT_GRP_MASK U(0xF)
#define UNCORE_PERFMON_SELECTOR_MASK U(0xF)
#define UNCORE_PERFMON_REG_MASK U(0xFF)
#define UNCORE_PERFMON_CTR_MASK U(0xFF)
#define UNCORE_PERFMON_RESP_STATUS_MASK U(0xFF)
-#define UNCORE_PERFMON_RESP_STATUS_SHIFT U(24)
/*******************************************************************************
* Structure populated by arch specific code to export routines which perform
diff --git a/plat/nvidia/tegra/soc/t186/drivers/mce/ari.c b/plat/nvidia/tegra/soc/t186/drivers/mce/ari.c
index 599e46e..a57bc11 100644
--- a/plat/nvidia/tegra/soc/t186/drivers/mce/ari.c
+++ b/plat/nvidia/tegra/soc/t186/drivers/mce/ari.c
@@ -35,8 +35,8 @@
#define ARI_REQUEST_VALID_BIT (1U << 8)
#define ARI_EVT_MASK_STANDBYWFI_BIT (1U << 7)
-/* default timeout (ms) to wait for ARI completion */
-#define ARI_MAX_RETRY_COUNT 2000
+/* default timeout (us) to wait for ARI completion */
+#define ARI_MAX_RETRY_COUNT U(2000000)
/*******************************************************************************
* ARI helper functions
@@ -80,7 +80,7 @@
static int32_t ari_request_wait(uint32_t ari_base, uint32_t evt_mask, uint32_t req,
uint32_t lo, uint32_t hi)
{
- uint32_t retries = ARI_MAX_RETRY_COUNT;
+ uint32_t retries = (uint32_t)ARI_MAX_RETRY_COUNT;
uint32_t status;
int32_t ret = 0;
@@ -115,8 +115,8 @@
break;
}
- /* delay 1 ms */
- mdelay(1);
+ /* delay 1 us */
+ udelay(1);
/* decrement the retry count */
retries--;
@@ -151,7 +151,7 @@
/* Enter the cstate, to be woken up after wake_time (TSC ticks) */
ret = ari_request_wait(ari_base, ARI_EVT_MASK_STANDBYWFI_BIT,
- TEGRA_ARI_ENTER_CSTATE, state, wake_time);
+ (uint32_t)TEGRA_ARI_ENTER_CSTATE, state, wake_time);
}
return ret;
@@ -191,7 +191,7 @@
}
/* set the updated cstate info */
- return ari_request_wait(ari_base, 0U, TEGRA_ARI_UPDATE_CSTATE_INFO,
+ return ari_request_wait(ari_base, 0U, (uint32_t)TEGRA_ARI_UPDATE_CSTATE_INFO,
(uint32_t)val, wake_mask);
}
@@ -208,8 +208,8 @@
ari_clobber_response(ari_base);
/* update crossover threshold time */
- ret = ari_request_wait(ari_base, 0U, TEGRA_ARI_UPDATE_CROSSOVER,
- type, time);
+ ret = ari_request_wait(ari_base, 0U,
+ (uint32_t)TEGRA_ARI_UPDATE_CROSSOVER, type, time);
}
return ret;
@@ -227,7 +227,8 @@
/* clean the previous response state */
ari_clobber_response(ari_base);
- ret = ari_request_wait(ari_base, 0U, TEGRA_ARI_CSTATE_STATS, state, 0U);
+ ret = ari_request_wait(ari_base, 0U,
+ (uint32_t)TEGRA_ARI_CSTATE_STATS, state, 0U);
if (ret != 0) {
result = EINVAL;
} else {
@@ -243,8 +244,8 @@
ari_clobber_response(ari_base);
/* write the cstate stats */
- return ari_request_wait(ari_base, 0U, TEGRA_ARI_WRITE_CSTATE_STATS, state,
- stats);
+ return ari_request_wait(ari_base, 0U, (uint32_t)TEGRA_ARI_WRITE_CSTATE_STATS,
+ state, stats);
}
uint64_t ari_enumeration_misc(uint32_t ari_base, uint32_t cmd, uint32_t data)
@@ -261,7 +262,7 @@
local_data = 0U;
}
- ret = ari_request_wait(ari_base, 0U, TEGRA_ARI_MISC, cmd, local_data);
+ ret = ari_request_wait(ari_base, 0U, (uint32_t)TEGRA_ARI_MISC, cmd, local_data);
if (ret != 0) {
resp = (uint64_t)ret;
} else {
@@ -281,8 +282,8 @@
/* clean the previous response state */
ari_clobber_response(ari_base);
- ret = ari_request_wait(ari_base, 0U, TEGRA_ARI_IS_CCX_ALLOWED, state & 0x7U,
- wake_time);
+ ret = ari_request_wait(ari_base, 0U, (uint32_t)TEGRA_ARI_IS_CCX_ALLOWED,
+ state & 0x7U, wake_time);
if (ret != 0) {
ERROR("%s: failed (%d)\n", __func__, ret);
result = 0U;
@@ -307,8 +308,8 @@
/* clean the previous response state */
ari_clobber_response(ari_base);
- ret = ari_request_wait(ari_base, 0U, TEGRA_ARI_IS_SC7_ALLOWED, state,
- wake_time);
+ ret = ari_request_wait(ari_base, 0U,
+ (uint32_t)TEGRA_ARI_IS_SC7_ALLOWED, state, wake_time);
if (ret != 0) {
ERROR("%s: failed (%d)\n", __func__, ret);
result = 0;
@@ -346,7 +347,8 @@
} else {
/* clean the previous response state */
ari_clobber_response(ari_base);
- ret = ari_request_wait(ari_base, 0U, TEGRA_ARI_ONLINE_CORE, core, 0U);
+ ret = ari_request_wait(ari_base, 0U,
+ (uint32_t)TEGRA_ARI_ONLINE_CORE, core, 0U);
}
}
@@ -374,7 +376,8 @@
((volt & MCE_AUTO_CC3_VTG_MASK) << MCE_AUTO_CC3_VTG_SHIFT) |\
((enable != 0U) ? MCE_AUTO_CC3_ENABLE_BIT : 0U));
- return ari_request_wait(ari_base, 0U, TEGRA_ARI_CC3_CTRL, val, 0U);
+ return ari_request_wait(ari_base, 0U,
+ (uint32_t)TEGRA_ARI_CC3_CTRL, val, 0U);
}
int32_t ari_reset_vector_update(uint32_t ari_base)
@@ -386,7 +389,8 @@
* Need to program the CPU reset vector one time during cold boot
* and SC7 exit
*/
- (void)ari_request_wait(ari_base, 0U, TEGRA_ARI_COPY_MISCREG_AA64_RST, 0U, 0U);
+ (void)ari_request_wait(ari_base, 0U,
+ (uint32_t)TEGRA_ARI_COPY_MISCREG_AA64_RST, 0U, 0U);
return 0;
}
@@ -396,8 +400,8 @@
/* clean the previous response state */
ari_clobber_response(ari_base);
- return ari_request_wait(ari_base, 0U, TEGRA_ARI_ROC_FLUSH_CACHE_TRBITS,
- 0U, 0U);
+ return ari_request_wait(ari_base, 0U,
+ (uint32_t)TEGRA_ARI_ROC_FLUSH_CACHE_TRBITS, 0U, 0U);
}
int32_t ari_roc_flush_cache(uint32_t ari_base)
@@ -405,8 +409,8 @@
/* clean the previous response state */
ari_clobber_response(ari_base);
- return ari_request_wait(ari_base, 0U, TEGRA_ARI_ROC_FLUSH_CACHE_ONLY,
- 0U, 0U);
+ return ari_request_wait(ari_base, 0U,
+ (uint32_t)TEGRA_ARI_ROC_FLUSH_CACHE_ONLY, 0U, 0U);
}
int32_t ari_roc_clean_cache(uint32_t ari_base)
@@ -414,8 +418,8 @@
/* clean the previous response state */
ari_clobber_response(ari_base);
- return ari_request_wait(ari_base, 0U, TEGRA_ARI_ROC_CLEAN_CACHE_ONLY,
- 0U, 0U);
+ return ari_request_wait(ari_base, 0U,
+ (uint32_t)TEGRA_ARI_ROC_CLEAN_CACHE_ONLY, 0U, 0U);
}
uint64_t ari_read_write_mca(uint32_t ari_base, uint64_t cmd, uint64_t *data)
@@ -432,7 +436,7 @@
ari_write_32(ari_base, (uint32_t)cmd, ARI_RESPONSE_DATA_LO);
ari_write_32(ari_base, (uint32_t)(cmd >> 32U), ARI_RESPONSE_DATA_HI);
- ret = ari_request_wait(ari_base, 0U, TEGRA_ARI_MCA,
+ ret = ari_request_wait(ari_base, 0U, (uint32_t)TEGRA_ARI_MCA,
(uint32_t)mca_arg_data,
(uint32_t)(mca_arg_data >> 32U));
if (ret == 0) {
@@ -473,7 +477,8 @@
* the ID, from the MC registers and update the internal GSC registers
* of the CCPLEX.
*/
- (void)ari_request_wait(ari_base, 0U, TEGRA_ARI_UPDATE_CCPLEX_GSC, gsc_idx, 0U);
+ (void)ari_request_wait(ari_base, 0U,
+ (uint32_t)TEGRA_ARI_UPDATE_CCPLEX_GSC, gsc_idx, 0U);
}
return ret;
@@ -487,7 +492,8 @@
/*
* The MCE will shutdown or restart the entire system
*/
- (void)ari_request_wait(ari_base, 0U, TEGRA_ARI_MISC_CCPLEX, state_idx, 0U);
+ (void)ari_request_wait(ari_base, 0U,
+ (uint32_t)TEGRA_ARI_MISC_CCPLEX, state_idx, 0U);
}
int32_t ari_read_write_uncore_perfmon(uint32_t ari_base, uint64_t req,
@@ -497,7 +503,7 @@
uint32_t val, req_status;
uint8_t req_cmd;
- req_cmd = (uint8_t)(req >> UNCORE_PERFMON_CMD_SHIFT);
+ req_cmd = (uint8_t)(req & UNCORE_PERFMON_CMD_MASK);
/* clean the previous response state */
ari_clobber_response(ari_base);
@@ -514,8 +520,8 @@
val = (req_cmd == UNCORE_PERFMON_CMD_WRITE) ?
(uint32_t)*data : 0U;
- ret = ari_request_wait(ari_base, 0U, TEGRA_ARI_PERFMON, val,
- (uint32_t)req);
+ ret = ari_request_wait(ari_base, 0U,
+ (uint32_t)TEGRA_ARI_PERFMON, val, (uint32_t)req);
if (ret != 0) {
result = ret;
} else {
@@ -527,7 +533,7 @@
* For "read" commands get the data from the uncore
* perfmon registers
*/
- req_status >>= UNCORE_PERFMON_RESP_STATUS_SHIFT;
+ req_status &= UNCORE_PERFMON_RESP_STATUS_MASK;
if ((req_status == 0U) && (req_cmd == UNCORE_PERFMON_CMD_READ)) {
*data = ari_get_response_low(ari_base);
}
@@ -552,6 +558,7 @@
} else {
/* clean the previous response state */
ari_clobber_response(ari_base);
- (void)ari_request_wait(ari_base, 0U, TEGRA_ARI_MISC_CCPLEX, index, value);
+ (void)ari_request_wait(ari_base, 0U,
+ (uint32_t)TEGRA_ARI_MISC_CCPLEX, index, value);
}
}
diff --git a/plat/nvidia/tegra/soc/t186/drivers/mce/mce.c b/plat/nvidia/tegra/soc/t186/drivers/mce/mce.c
index e948e99..9e42b2b 100644
--- a/plat/nvidia/tegra/soc/t186/drivers/mce/mce.c
+++ b/plat/nvidia/tegra/soc/t186/drivers/mce/mce.c
@@ -170,12 +170,12 @@
cpu_ari_base = mce_get_curr_cpu_ari_base();
switch (cmd) {
- case MCE_CMD_ENTER_CSTATE:
+ case (uint64_t)MCE_CMD_ENTER_CSTATE:
ret = ops->enter_cstate(cpu_ari_base, arg0, arg1);
break;
- case MCE_CMD_UPDATE_CSTATE_INFO:
+ case (uint64_t)MCE_CMD_UPDATE_CSTATE_INFO:
/*
* get the parameters required for the update cstate info
* command
@@ -194,12 +194,12 @@
break;
- case MCE_CMD_UPDATE_CROSSOVER_TIME:
+ case (uint64_t)MCE_CMD_UPDATE_CROSSOVER_TIME:
ret = ops->update_crossover_time(cpu_ari_base, arg0, arg1);
break;
- case MCE_CMD_READ_CSTATE_STATS:
+ case (uint64_t)MCE_CMD_READ_CSTATE_STATS:
ret64 = ops->read_cstate_stats(cpu_ari_base, arg0);
/* update context to return cstate stats value */
@@ -208,12 +208,12 @@
break;
- case MCE_CMD_WRITE_CSTATE_STATS:
+ case (uint64_t)MCE_CMD_WRITE_CSTATE_STATS:
ret = ops->write_cstate_stats(cpu_ari_base, arg0, arg1);
break;
- case MCE_CMD_IS_CCX_ALLOWED:
+ case (uint64_t)MCE_CMD_IS_CCX_ALLOWED:
ret = ops->is_ccx_allowed(cpu_ari_base, arg0, arg1);
/* update context to return CCx status value */
@@ -221,7 +221,7 @@
break;
- case MCE_CMD_IS_SC7_ALLOWED:
+ case (uint64_t)MCE_CMD_IS_SC7_ALLOWED:
ret = ops->is_sc7_allowed(cpu_ari_base, arg0, arg1);
/* update context to return SC7 status value */
@@ -230,17 +230,17 @@
break;
- case MCE_CMD_ONLINE_CORE:
+ case (uint64_t)MCE_CMD_ONLINE_CORE:
ret = ops->online_core(cpu_ari_base, arg0);
break;
- case MCE_CMD_CC3_CTRL:
+ case (uint64_t)MCE_CMD_CC3_CTRL:
ret = ops->cc3_ctrl(cpu_ari_base, arg0, arg1, arg2);
break;
- case MCE_CMD_ECHO_DATA:
+ case (uint64_t)MCE_CMD_ECHO_DATA:
ret64 = ops->call_enum_misc(cpu_ari_base, TEGRA_ARI_MISC_ECHO,
arg0);
@@ -252,7 +252,7 @@
break;
- case MCE_CMD_READ_VERSIONS:
+ case (uint64_t)MCE_CMD_READ_VERSIONS:
ret64 = ops->call_enum_misc(cpu_ari_base, TEGRA_ARI_MISC_VERSION,
arg0);
@@ -265,7 +265,7 @@
break;
- case MCE_CMD_ENUM_FEATURES:
+ case (uint64_t)MCE_CMD_ENUM_FEATURES:
ret64 = ops->call_enum_misc(cpu_ari_base,
TEGRA_ARI_MISC_FEATURE_LEAF_0, arg0);
@@ -274,22 +274,22 @@
break;
- case MCE_CMD_ROC_FLUSH_CACHE_TRBITS:
+ case (uint64_t)MCE_CMD_ROC_FLUSH_CACHE_TRBITS:
ret = ops->roc_flush_cache_trbits(cpu_ari_base);
break;
- case MCE_CMD_ROC_FLUSH_CACHE:
+ case (uint64_t)MCE_CMD_ROC_FLUSH_CACHE:
ret = ops->roc_flush_cache(cpu_ari_base);
break;
- case MCE_CMD_ROC_CLEAN_CACHE:
+ case (uint64_t)MCE_CMD_ROC_CLEAN_CACHE:
ret = ops->roc_clean_cache(cpu_ari_base);
break;
- case MCE_CMD_ENUM_READ_MCA:
+ case (uint64_t)MCE_CMD_ENUM_READ_MCA:
ret64 = ops->read_write_mca(cpu_ari_base, arg0, &arg1);
/* update context to return MCA data/error */
@@ -299,7 +299,7 @@
break;
- case MCE_CMD_ENUM_WRITE_MCA:
+ case (uint64_t)MCE_CMD_ENUM_WRITE_MCA:
ret64 = ops->read_write_mca(cpu_ari_base, arg0, &arg1);
/* update context to return MCA error */
@@ -309,7 +309,7 @@
break;
#if ENABLE_CHIP_VERIFICATION_HARNESS
- case MCE_CMD_ENABLE_LATIC:
+ case (uint64_t)MCE_CMD_ENABLE_LATIC:
/*
* This call is not for production use. The constant value,
* 0xFFFF0000, is specific to allowing for enabling LATIC on
@@ -327,14 +327,14 @@
break;
#endif
- case MCE_CMD_UNCORE_PERFMON_REQ:
+ case (uint64_t)MCE_CMD_UNCORE_PERFMON_REQ:
ret = ops->read_write_uncore_perfmon(cpu_ari_base, arg0, &arg1);
/* update context to return data */
write_ctx_reg(gp_regs, CTX_GPREG_X1, (arg1));
break;
- case MCE_CMD_MISC_CCPLEX:
+ case (uint64_t)MCE_CMD_MISC_CCPLEX:
ops->misc_ccplex(cpu_ari_base, arg0, arg1);
break;
diff --git a/plat/nvidia/tegra/soc/t186/drivers/mce/nvg.c b/plat/nvidia/tegra/soc/t186/drivers/mce/nvg.c
index 44ee8fb..cbc9aa3 100644
--- a/plat/nvidia/tegra/soc/t186/drivers/mce/nvg.c
+++ b/plat/nvidia/tegra/soc/t186/drivers/mce/nvg.c
@@ -14,10 +14,12 @@
#include <mce_private.h>
#include <t18x_ari.h>
+#include <tegra_private.h>
int32_t nvg_enter_cstate(uint32_t ari_base, uint32_t state, uint32_t wake_time)
{
int32_t ret = 0;
+ uint64_t val = 0ULL;
(void)ari_base;
@@ -28,10 +30,11 @@
ret = EINVAL;
} else {
/* time (TSC ticks) until the core is expected to get a wake event */
- nvg_set_request_data(TEGRA_NVG_CHANNEL_WAKE_TIME, wake_time);
+ nvg_set_request_data((uint64_t)TEGRA_NVG_CHANNEL_WAKE_TIME, wake_time);
/* set the core cstate */
- write_actlr_el1(state);
+ val = read_actlr_el1() & ~ACTLR_EL1_PMSTATE_MASK;
+ write_actlr_el1(val | (uint64_t)state);
}
return ret;
@@ -78,7 +81,7 @@
val |= ((uint64_t)wake_mask << CSTATE_WAKE_MASK_SHIFT);
/* set the updated cstate info */
- nvg_set_request_data(TEGRA_NVG_CHANNEL_CSTATE_INFO, val);
+ nvg_set_request_data((uint64_t)TEGRA_NVG_CHANNEL_CSTATE_INFO, val);
return 0;
}
@@ -189,7 +192,7 @@
((uint64_t)state & MCE_SC7_ALLOWED_MASK);
/* issue command to check if SC7 is allowed */
- nvg_set_request_data(TEGRA_NVG_CHANNEL_IS_SC7_ALLOWED, val);
+ nvg_set_request_data((uint64_t)TEGRA_NVG_CHANNEL_IS_SC7_ALLOWED, val);
/* 1 = SC7 allowed, 0 = SC7 not allowed */
ret = (nvg_get_result() != 0ULL) ? 1 : 0;
@@ -219,7 +222,7 @@
ret = EINVAL;
} else {
/* get a core online */
- nvg_set_request_data(TEGRA_NVG_CHANNEL_ONLINE_CORE,
+ nvg_set_request_data((uint64_t)TEGRA_NVG_CHANNEL_ONLINE_CORE,
((uint64_t)core & MCE_CORE_ID_MASK));
}
}
@@ -247,7 +250,7 @@
((volt & MCE_AUTO_CC3_VTG_MASK) << MCE_AUTO_CC3_VTG_SHIFT) |\
((enable != 0U) ? MCE_AUTO_CC3_ENABLE_BIT : 0U));
- nvg_set_request_data(TEGRA_NVG_CHANNEL_CC3_CTRL, (uint64_t)val);
+ nvg_set_request_data((uint64_t)TEGRA_NVG_CHANNEL_CC3_CTRL, (uint64_t)val);
return 0;
}
diff --git a/plat/nvidia/tegra/soc/t186/plat_memctrl.c b/plat/nvidia/tegra/soc/t186/plat_memctrl.c
index 38dffb2..376ee86 100644
--- a/plat/nvidia/tegra/soc/t186/plat_memctrl.c
+++ b/plat/nvidia/tegra/soc/t186/plat_memctrl.c
@@ -4,9 +4,13 @@
* SPDX-License-Identifier: BSD-3-Clause
*/
+#include <assert.h>
#include <common/bl_common.h>
+#include <mce.h>
#include <memctrl_v2.h>
+#include <tegra_mc_def.h>
+#include <tegra_platform.h>
/*******************************************************************************
* Array to hold stream_id override config register offsets
@@ -201,16 +205,330 @@
mc_make_txn_override_cfg(SCEW, CGID_TAG_ADR),
};
+static void tegra186_memctrl_reconfig_mss_clients(void)
+{
+#if ENABLE_ROC_FOR_ORDERING_CLIENT_REQUESTS
+ uint32_t val, wdata_0, wdata_1;
+
+ /*
+ * Assert Memory Controller's HOTRESET_FLUSH_ENABLE signal for
+ * boot and strongly ordered MSS clients to flush existing memory
+ * traffic and stall future requests.
+ */
+ val = tegra_mc_read_32(MC_CLIENT_HOTRESET_CTRL0);
+ assert(val == MC_CLIENT_HOTRESET_CTRL0_RESET_VAL);
+
+ wdata_0 = MC_CLIENT_HOTRESET_CTRL0_HDA_FLUSH_ENB |
+#if ENABLE_AFI_DEVICE
+ MC_CLIENT_HOTRESET_CTRL0_AFI_FLUSH_ENB |
+#endif
+ MC_CLIENT_HOTRESET_CTRL0_SATA_FLUSH_ENB |
+ MC_CLIENT_HOTRESET_CTRL0_XUSB_HOST_FLUSH_ENB |
+ MC_CLIENT_HOTRESET_CTRL0_XUSB_DEV_FLUSH_ENB;
+ tegra_mc_write_32(MC_CLIENT_HOTRESET_CTRL0, wdata_0);
+
+ /* Wait for HOTRESET STATUS to indicate FLUSH_DONE */
+ do {
+ val = tegra_mc_read_32(MC_CLIENT_HOTRESET_STATUS0);
+ } while ((val & wdata_0) != wdata_0);
+
+ /* Wait one more time due to SW WAR for known legacy issue */
+ do {
+ val = tegra_mc_read_32(MC_CLIENT_HOTRESET_STATUS0);
+ } while ((val & wdata_0) != wdata_0);
+
+ val = tegra_mc_read_32(MC_CLIENT_HOTRESET_CTRL1);
+ assert(val == MC_CLIENT_HOTRESET_CTRL1_RESET_VAL);
+
+ wdata_1 = MC_CLIENT_HOTRESET_CTRL1_SDMMC4A_FLUSH_ENB |
+ MC_CLIENT_HOTRESET_CTRL1_APE_FLUSH_ENB |
+ MC_CLIENT_HOTRESET_CTRL1_SE_FLUSH_ENB |
+ MC_CLIENT_HOTRESET_CTRL1_ETR_FLUSH_ENB |
+ MC_CLIENT_HOTRESET_CTRL1_AXIS_FLUSH_ENB |
+ MC_CLIENT_HOTRESET_CTRL1_EQOS_FLUSH_ENB |
+ MC_CLIENT_HOTRESET_CTRL1_UFSHC_FLUSH_ENB |
+ MC_CLIENT_HOTRESET_CTRL1_BPMP_FLUSH_ENB |
+ MC_CLIENT_HOTRESET_CTRL1_AON_FLUSH_ENB |
+ MC_CLIENT_HOTRESET_CTRL1_SCE_FLUSH_ENB;
+ tegra_mc_write_32(MC_CLIENT_HOTRESET_CTRL1, wdata_1);
+
+ /* Wait for HOTRESET STATUS to indicate FLUSH_DONE */
+ do {
+ val = tegra_mc_read_32(MC_CLIENT_HOTRESET_STATUS1);
+ } while ((val & wdata_1) != wdata_1);
+
+ /* Wait one more time due to SW WAR for known legacy issue */
+ do {
+ val = tegra_mc_read_32(MC_CLIENT_HOTRESET_STATUS1);
+ } while ((val & wdata_1) != wdata_1);
+
+ /*
+ * Change MEMTYPE_OVERRIDE from SO_DEV -> PASSTHRU for boot and
+ * strongly ordered MSS clients. ROC needs to be single point
+ * of control on overriding the memory type. So, remove TSA's
+ * memtype override.
+ *
+ * MC clients with default SO_DEV override still enabled at TSA:
+ * AONW, BPMPW, SCEW, APEW
+ */
+#if ENABLE_AFI_DEVICE
+ mc_set_tsa_passthrough(AFIW);
+#endif
+ mc_set_tsa_passthrough(HDAW);
+ mc_set_tsa_passthrough(SATAW);
+ mc_set_tsa_passthrough(XUSB_HOSTW);
+ mc_set_tsa_passthrough(XUSB_DEVW);
+ mc_set_tsa_passthrough(SDMMCWAB);
+ mc_set_tsa_passthrough(APEDMAW);
+ mc_set_tsa_passthrough(SESWR);
+ mc_set_tsa_passthrough(ETRW);
+ mc_set_tsa_passthrough(AXISW);
+ mc_set_tsa_passthrough(EQOSW);
+ mc_set_tsa_passthrough(UFSHCW);
+ mc_set_tsa_passthrough(BPMPDMAW);
+ mc_set_tsa_passthrough(AONDMAW);
+ mc_set_tsa_passthrough(SCEDMAW);
+
+ /* Parker has no IO Coherency support and need the following:
+ * Ordered MC Clients on Parker are AFI, EQOS, SATA, XUSB.
+ * ISO clients(DISP, VI, EQOS) should never snoop caches and
+ * don't need ROC/PCFIFO ordering.
+ * ISO clients(EQOS) that need ordering should use PCFIFO ordering
+ * and bypass ROC ordering by using FORCE_NON_COHERENT path.
+ * FORCE_NON_COHERENT/FORCE_COHERENT config take precedence
+ * over SMMU attributes.
+ * Force all Normal memory transactions from ISO and non-ISO to be
+ * non-coherent(bypass ROC, avoid cache snoop to avoid perf hit).
+ * Force the SO_DEV transactions from ordered ISO clients(EQOS) to
+ * non-coherent path and enable MC PCFIFO interlock for ordering.
+ * Force the SO_DEV transactions from ordered non-ISO clients (PCIe,
+ * XUSB, SATA) to coherent so that the transactions are
+ * ordered by ROC.
+ * PCFIFO ensure write ordering.
+ * Read after Write ordering is maintained/enforced by MC clients.
+ * Clients that need PCIe type write ordering must
+ * go through ROC ordering.
+ * Ordering enable for Read clients is not necessary.
+ * R5's and A9 would get necessary ordering from AXI and
+ * don't need ROC ordering enable:
+ * - MMIO ordering is through dev mapping and MMIO
+ * accesses bypass SMMU.
+ * - Normal memory is accessed through SMMU and ordering is
+ * ensured by client and AXI.
+ * - Ack point for Normal memory is WCAM in MC.
+ * - MMIO's can be early acked and AXI ensures dev memory ordering,
+ * Client ensures read/write direction change ordering.
+ * - See Bug 200312466 for more details.
+ *
+ * CGID_TAG_ADR is only present from T186 A02. As this code is common
+ * between A01 and A02, tegra_memctrl_set_overrides() programs
+ * CGID_TAG_ADR for the necessary clients on A02.
+ */
+ mc_set_txn_override(HDAR, CGID_TAG_DEFAULT, SO_DEV_ZERO, FORCE_NON_COHERENT, FORCE_NON_COHERENT);
+ mc_set_txn_override(BPMPW, CGID_TAG_DEFAULT, SO_DEV_ZERO, FORCE_NON_COHERENT, FORCE_NON_COHERENT);
+ mc_set_txn_override(PTCR, CGID_TAG_DEFAULT, SO_DEV_ZERO, FORCE_NON_COHERENT, FORCE_NON_COHERENT);
+ mc_set_txn_override(NVDISPLAYR, CGID_TAG_DEFAULT, SO_DEV_ZERO, FORCE_NON_COHERENT, FORCE_NON_COHERENT);
+ mc_set_txn_override(EQOSW, CGID_TAG_DEFAULT, SO_DEV_ZERO, FORCE_NON_COHERENT, FORCE_NON_COHERENT);
+ mc_set_txn_override(NVJPGSWR, CGID_TAG_DEFAULT, SO_DEV_ZERO, FORCE_NON_COHERENT, FORCE_NON_COHERENT);
+ mc_set_txn_override(ISPRA, CGID_TAG_DEFAULT, SO_DEV_ZERO, FORCE_NON_COHERENT, FORCE_NON_COHERENT);
+ mc_set_txn_override(SDMMCWAA, CGID_TAG_DEFAULT, SO_DEV_ZERO, FORCE_NON_COHERENT, FORCE_NON_COHERENT);
+ mc_set_txn_override(VICSRD, CGID_TAG_DEFAULT, SO_DEV_ZERO, FORCE_NON_COHERENT, FORCE_NON_COHERENT);
+ mc_set_txn_override(MPCOREW, CGID_TAG_DEFAULT, SO_DEV_ZERO, NO_OVERRIDE, NO_OVERRIDE);
+ mc_set_txn_override(GPUSRD, CGID_TAG_DEFAULT, SO_DEV_ZERO, FORCE_NON_COHERENT, FORCE_NON_COHERENT);
+ mc_set_txn_override(AXISR, CGID_TAG_DEFAULT, SO_DEV_ZERO, FORCE_NON_COHERENT, FORCE_NON_COHERENT);
+ mc_set_txn_override(SCEDMAW, CGID_TAG_DEFAULT, SO_DEV_ZERO, FORCE_NON_COHERENT, FORCE_NON_COHERENT);
+ mc_set_txn_override(SDMMCW, CGID_TAG_DEFAULT, SO_DEV_ZERO, FORCE_NON_COHERENT, FORCE_NON_COHERENT);
+ mc_set_txn_override(EQOSR, CGID_TAG_DEFAULT, SO_DEV_ZERO, FORCE_NON_COHERENT, FORCE_NON_COHERENT);
+ /* See bug 200131110 comment #35*/
+ mc_set_txn_override(APEDMAR, CGID_TAG_CLIENT_AXI_ID, SO_DEV_CLIENT_AXI_ID, FORCE_NON_COHERENT, FORCE_NON_COHERENT);
+ mc_set_txn_override(NVENCSRD, CGID_TAG_DEFAULT, SO_DEV_ZERO, FORCE_NON_COHERENT, FORCE_NON_COHERENT);
+ mc_set_txn_override(SDMMCRAB, CGID_TAG_DEFAULT, SO_DEV_ZERO, FORCE_NON_COHERENT, FORCE_NON_COHERENT);
+ mc_set_txn_override(VICSRD1, CGID_TAG_DEFAULT, SO_DEV_ZERO, FORCE_NON_COHERENT, FORCE_NON_COHERENT);
+ mc_set_txn_override(BPMPDMAR, CGID_TAG_DEFAULT, SO_DEV_ZERO, FORCE_NON_COHERENT, FORCE_NON_COHERENT);
+ mc_set_txn_override(VIW, CGID_TAG_DEFAULT, SO_DEV_ZERO, FORCE_NON_COHERENT, FORCE_NON_COHERENT);
+ mc_set_txn_override(SDMMCRAA, CGID_TAG_DEFAULT, SO_DEV_ZERO, FORCE_NON_COHERENT, FORCE_NON_COHERENT);
+ mc_set_txn_override(AXISW, CGID_TAG_DEFAULT, SO_DEV_ZERO, FORCE_NON_COHERENT, FORCE_NON_COHERENT);
+ mc_set_txn_override(XUSB_DEVR, CGID_TAG_DEFAULT, SO_DEV_ZERO, FORCE_NON_COHERENT, FORCE_NON_COHERENT);
+ mc_set_txn_override(UFSHCR, CGID_TAG_DEFAULT, SO_DEV_ZERO, FORCE_NON_COHERENT, FORCE_NON_COHERENT);
+ mc_set_txn_override(TSECSWR, CGID_TAG_DEFAULT, SO_DEV_ZERO, FORCE_NON_COHERENT, FORCE_NON_COHERENT);
+ mc_set_txn_override(GPUSWR, CGID_TAG_DEFAULT, SO_DEV_ZERO, FORCE_NON_COHERENT, FORCE_NON_COHERENT);
+ mc_set_txn_override(SATAR, CGID_TAG_DEFAULT, SO_DEV_ZERO, FORCE_NON_COHERENT, FORCE_NON_COHERENT);
+ mc_set_txn_override(XUSB_HOSTW, CGID_TAG_DEFAULT, SO_DEV_ZERO, FORCE_NON_COHERENT, FORCE_COHERENT);
+ mc_set_txn_override(TSECSWRB, CGID_TAG_DEFAULT, SO_DEV_ZERO, FORCE_NON_COHERENT, FORCE_NON_COHERENT);
+ mc_set_txn_override(GPUSRD2, CGID_TAG_DEFAULT, SO_DEV_ZERO, FORCE_NON_COHERENT, FORCE_NON_COHERENT);
+ mc_set_txn_override(SCEDMAR, CGID_TAG_DEFAULT, SO_DEV_ZERO, FORCE_NON_COHERENT, FORCE_NON_COHERENT);
+ mc_set_txn_override(GPUSWR2, CGID_TAG_DEFAULT, SO_DEV_ZERO, FORCE_NON_COHERENT, FORCE_NON_COHERENT);
+ mc_set_txn_override(AONDMAW, CGID_TAG_DEFAULT, SO_DEV_ZERO, FORCE_NON_COHERENT, FORCE_NON_COHERENT);
+ /* See bug 200131110 comment #35*/
+ mc_set_txn_override(APEDMAW, CGID_TAG_CLIENT_AXI_ID, SO_DEV_CLIENT_AXI_ID, FORCE_NON_COHERENT, FORCE_NON_COHERENT);
+ mc_set_txn_override(AONW, CGID_TAG_DEFAULT, SO_DEV_ZERO, FORCE_NON_COHERENT, FORCE_NON_COHERENT);
+ mc_set_txn_override(HOST1XDMAR, CGID_TAG_DEFAULT, SO_DEV_ZERO, FORCE_NON_COHERENT, FORCE_NON_COHERENT);
+ mc_set_txn_override(ETRR, CGID_TAG_DEFAULT, SO_DEV_ZERO, FORCE_NON_COHERENT, FORCE_NON_COHERENT);
+ mc_set_txn_override(SESWR, CGID_TAG_DEFAULT, SO_DEV_ZERO, FORCE_NON_COHERENT, FORCE_NON_COHERENT);
+ mc_set_txn_override(NVJPGSRD, CGID_TAG_DEFAULT, SO_DEV_ZERO, FORCE_NON_COHERENT, FORCE_NON_COHERENT);
+ mc_set_txn_override(NVDECSRD, CGID_TAG_DEFAULT, SO_DEV_ZERO, FORCE_NON_COHERENT, FORCE_NON_COHERENT);
+ mc_set_txn_override(TSECSRDB, CGID_TAG_DEFAULT, SO_DEV_ZERO, FORCE_NON_COHERENT, FORCE_NON_COHERENT);
+ mc_set_txn_override(BPMPDMAW, CGID_TAG_DEFAULT, SO_DEV_ZERO, FORCE_NON_COHERENT, FORCE_NON_COHERENT);
+ mc_set_txn_override(APER, CGID_TAG_DEFAULT, SO_DEV_ZERO, FORCE_NON_COHERENT, FORCE_NON_COHERENT);
+ mc_set_txn_override(NVDECSRD1, CGID_TAG_DEFAULT, SO_DEV_ZERO, FORCE_NON_COHERENT, FORCE_NON_COHERENT);
+ mc_set_txn_override(XUSB_HOSTR, CGID_TAG_DEFAULT, SO_DEV_ZERO, FORCE_NON_COHERENT, FORCE_NON_COHERENT);
+ mc_set_txn_override(ISPWA, CGID_TAG_DEFAULT, SO_DEV_ZERO, FORCE_NON_COHERENT, FORCE_NON_COHERENT);
+ mc_set_txn_override(SESRD, CGID_TAG_DEFAULT, SO_DEV_ZERO, FORCE_NON_COHERENT, FORCE_NON_COHERENT);
+ mc_set_txn_override(SCER, CGID_TAG_DEFAULT, SO_DEV_ZERO, FORCE_NON_COHERENT, FORCE_NON_COHERENT);
+ mc_set_txn_override(AONR, CGID_TAG_DEFAULT, SO_DEV_ZERO, FORCE_NON_COHERENT, FORCE_NON_COHERENT);
+ mc_set_txn_override(MPCORER, CGID_TAG_DEFAULT, SO_DEV_ZERO, NO_OVERRIDE, NO_OVERRIDE);
+ mc_set_txn_override(SDMMCWA, CGID_TAG_DEFAULT, SO_DEV_ZERO, FORCE_NON_COHERENT, FORCE_NON_COHERENT);
+ mc_set_txn_override(HDAW, CGID_TAG_DEFAULT, SO_DEV_ZERO, FORCE_NON_COHERENT, FORCE_NON_COHERENT);
+ mc_set_txn_override(NVDECSWR, CGID_TAG_DEFAULT, SO_DEV_ZERO, FORCE_NON_COHERENT, FORCE_NON_COHERENT);
+ mc_set_txn_override(UFSHCW, CGID_TAG_DEFAULT, SO_DEV_ZERO, FORCE_NON_COHERENT, FORCE_NON_COHERENT);
+ mc_set_txn_override(AONDMAR, CGID_TAG_DEFAULT, SO_DEV_ZERO, FORCE_NON_COHERENT, FORCE_NON_COHERENT);
+ mc_set_txn_override(SATAW, CGID_TAG_DEFAULT, SO_DEV_ZERO, FORCE_NON_COHERENT, FORCE_COHERENT);
+ mc_set_txn_override(ETRW, CGID_TAG_DEFAULT, SO_DEV_ZERO, FORCE_NON_COHERENT, FORCE_NON_COHERENT);
+ mc_set_txn_override(VICSWR, CGID_TAG_DEFAULT, SO_DEV_ZERO, FORCE_NON_COHERENT, FORCE_NON_COHERENT);
+ mc_set_txn_override(NVENCSWR, CGID_TAG_DEFAULT, SO_DEV_ZERO, FORCE_NON_COHERENT, FORCE_NON_COHERENT);
+ /* See bug 200131110 comment #35 */
+ mc_set_txn_override(AFIR, CGID_TAG_DEFAULT, SO_DEV_CLIENT_AXI_ID, FORCE_NON_COHERENT, FORCE_NON_COHERENT);
+ mc_set_txn_override(SDMMCWAB, CGID_TAG_DEFAULT, SO_DEV_ZERO, FORCE_NON_COHERENT, FORCE_NON_COHERENT);
+ mc_set_txn_override(SDMMCRA, CGID_TAG_DEFAULT, SO_DEV_ZERO, FORCE_NON_COHERENT, FORCE_NON_COHERENT);
+ mc_set_txn_override(NVDISPLAYR1, CGID_TAG_DEFAULT, SO_DEV_ZERO, FORCE_NON_COHERENT, FORCE_NON_COHERENT);
+ mc_set_txn_override(ISPWB, CGID_TAG_DEFAULT, SO_DEV_ZERO, FORCE_NON_COHERENT, FORCE_NON_COHERENT);
+ mc_set_txn_override(BPMPR, CGID_TAG_DEFAULT, SO_DEV_ZERO, FORCE_NON_COHERENT, FORCE_NON_COHERENT);
+ mc_set_txn_override(APEW, CGID_TAG_DEFAULT, SO_DEV_ZERO, FORCE_NON_COHERENT, FORCE_NON_COHERENT);
+ mc_set_txn_override(SDMMCR, CGID_TAG_DEFAULT, SO_DEV_ZERO, FORCE_NON_COHERENT, FORCE_NON_COHERENT);
+ mc_set_txn_override(XUSB_DEVW, CGID_TAG_DEFAULT, SO_DEV_ZERO, FORCE_NON_COHERENT, FORCE_COHERENT);
+ mc_set_txn_override(TSECSRD, CGID_TAG_DEFAULT, SO_DEV_ZERO, FORCE_NON_COHERENT, FORCE_NON_COHERENT);
+ /*
+ * See bug 200131110 comment #35 - there are no normal requests
+ * and AWID for SO/DEV requests is hardcoded in RTL for a
+ * particular PCIE controller
+ */
+ mc_set_txn_override(AFIW, CGID_TAG_DEFAULT, SO_DEV_CLIENT_AXI_ID, FORCE_NON_COHERENT, FORCE_COHERENT);
+ mc_set_txn_override(SCEW, CGID_TAG_DEFAULT, SO_DEV_ZERO, FORCE_NON_COHERENT, FORCE_NON_COHERENT);
+
+ /*
+ * At this point, ordering can occur at ROC. So, remove PCFIFO's
+ * control over ordering requests.
+ *
+ * Change PCFIFO_*_ORDERED_CLIENT from ORDERED -> UNORDERED for
+ * boot and strongly ordered MSS clients
+ */
+ val = MC_PCFIFO_CLIENT_CONFIG1_RESET_VAL &
+#if ENABLE_AFI_DEVICE
+ mc_set_pcfifo_unordered_boot_so_mss(1, AFIW) &
+#endif
+ mc_set_pcfifo_unordered_boot_so_mss(1, HDAW) &
+ mc_set_pcfifo_unordered_boot_so_mss(1, SATAW);
+ tegra_mc_write_32(MC_PCFIFO_CLIENT_CONFIG1, val);
+
+ val = MC_PCFIFO_CLIENT_CONFIG2_RESET_VAL &
+ mc_set_pcfifo_unordered_boot_so_mss(2, XUSB_HOSTW) &
+ mc_set_pcfifo_unordered_boot_so_mss(2, XUSB_DEVW);
+ tegra_mc_write_32(MC_PCFIFO_CLIENT_CONFIG2, val);
+
+ val = MC_PCFIFO_CLIENT_CONFIG3_RESET_VAL &
+ mc_set_pcfifo_unordered_boot_so_mss(3, SDMMCWAB);
+ tegra_mc_write_32(MC_PCFIFO_CLIENT_CONFIG3, val);
+
+ val = MC_PCFIFO_CLIENT_CONFIG4_RESET_VAL &
+ mc_set_pcfifo_unordered_boot_so_mss(4, SESWR) &
+ mc_set_pcfifo_unordered_boot_so_mss(4, ETRW) &
+ mc_set_pcfifo_unordered_boot_so_mss(4, AXISW) &
+ mc_set_pcfifo_unordered_boot_so_mss(4, UFSHCW) &
+ mc_set_pcfifo_unordered_boot_so_mss(4, BPMPDMAW) &
+ mc_set_pcfifo_unordered_boot_so_mss(4, AONDMAW) &
+ mc_set_pcfifo_unordered_boot_so_mss(4, SCEDMAW);
+ /* EQOSW is the only client that has PCFIFO order enabled. */
+ val |= mc_set_pcfifo_ordered_boot_so_mss(4, EQOSW);
+ tegra_mc_write_32(MC_PCFIFO_CLIENT_CONFIG4, val);
+
+ val = MC_PCFIFO_CLIENT_CONFIG5_RESET_VAL &
+ mc_set_pcfifo_unordered_boot_so_mss(5, APEDMAW);
+ tegra_mc_write_32(MC_PCFIFO_CLIENT_CONFIG5, val);
+
+ /*
+ * Deassert HOTRESET FLUSH_ENABLE for boot and strongly ordered MSS
+ * clients to allow memory traffic from all clients to start passing
+ * through ROC
+ */
+ val = tegra_mc_read_32(MC_CLIENT_HOTRESET_CTRL0);
+ assert(val == wdata_0);
+
+ wdata_0 = MC_CLIENT_HOTRESET_CTRL0_RESET_VAL;
+ tegra_mc_write_32(MC_CLIENT_HOTRESET_CTRL0, wdata_0);
+
+ val = tegra_mc_read_32(MC_CLIENT_HOTRESET_CTRL1);
+ assert(val == wdata_1);
+
+ wdata_1 = MC_CLIENT_HOTRESET_CTRL1_RESET_VAL;
+ tegra_mc_write_32(MC_CLIENT_HOTRESET_CTRL1, wdata_1);
+
+#endif
+}
+
+static void tegra186_memctrl_set_overrides(void)
+{
+ const tegra_mc_settings_t *plat_mc_settings = tegra_get_mc_settings();
+ const mc_txn_override_cfg_t *mc_txn_override_cfgs;
+ uint32_t num_txn_override_cfgs;
+ uint32_t i, val;
+
+ /* Get the settings from the platform */
+ assert(plat_mc_settings != NULL);
+ mc_txn_override_cfgs = plat_mc_settings->txn_override_cfg;
+ num_txn_override_cfgs = plat_mc_settings->num_txn_override_cfgs;
+
+ /*
+ * Set the MC_TXN_OVERRIDE registers for write clients.
+ */
+ if ((tegra_chipid_is_t186()) &&
+ (!tegra_platform_is_silicon() ||
+ (tegra_platform_is_silicon() && (tegra_get_chipid_minor() == 1U)))) {
+
+ /*
+ * GPU and NVENC settings for Tegra186 simulation and
+ * Silicon rev. A01
+ */
+ val = tegra_mc_read_32(MC_TXN_OVERRIDE_CONFIG_GPUSWR);
+ val &= (uint32_t)~MC_TXN_OVERRIDE_CGID_TAG_MASK;
+ tegra_mc_write_32(MC_TXN_OVERRIDE_CONFIG_GPUSWR,
+ val | MC_TXN_OVERRIDE_CGID_TAG_ZERO);
+
+ val = tegra_mc_read_32(MC_TXN_OVERRIDE_CONFIG_GPUSWR2);
+ val &= (uint32_t)~MC_TXN_OVERRIDE_CGID_TAG_MASK;
+ tegra_mc_write_32(MC_TXN_OVERRIDE_CONFIG_GPUSWR2,
+ val | MC_TXN_OVERRIDE_CGID_TAG_ZERO);
+
+ val = tegra_mc_read_32(MC_TXN_OVERRIDE_CONFIG_NVENCSWR);
+ val &= (uint32_t)~MC_TXN_OVERRIDE_CGID_TAG_MASK;
+ tegra_mc_write_32(MC_TXN_OVERRIDE_CONFIG_NVENCSWR,
+ val | MC_TXN_OVERRIDE_CGID_TAG_CLIENT_AXI_ID);
+
+ } else {
+
+ /*
+ * Settings for Tegra186 silicon rev. A02 and onwards.
+ */
+ for (i = 0; i < num_txn_override_cfgs; i++) {
+ val = tegra_mc_read_32(mc_txn_override_cfgs[i].offset);
+ val &= (uint32_t)~MC_TXN_OVERRIDE_CGID_TAG_MASK;
+ tegra_mc_write_32(mc_txn_override_cfgs[i].offset,
+ val | mc_txn_override_cfgs[i].cgid_tag);
+ }
+ }
+}
+
/*******************************************************************************
* Struct to hold the memory controller settings
******************************************************************************/
static tegra_mc_settings_t tegra186_mc_settings = {
.streamid_override_cfg = tegra186_streamid_override_regs,
- .num_streamid_override_cfgs = ARRAY_SIZE(tegra186_streamid_override_regs),
+ .num_streamid_override_cfgs = (uint32_t)ARRAY_SIZE(tegra186_streamid_override_regs),
.streamid_security_cfg = tegra186_streamid_sec_cfgs,
- .num_streamid_security_cfgs = ARRAY_SIZE(tegra186_streamid_sec_cfgs),
+ .num_streamid_security_cfgs = (uint32_t)ARRAY_SIZE(tegra186_streamid_sec_cfgs),
.txn_override_cfg = tegra186_txn_override_cfgs,
- .num_txn_override_cfgs = ARRAY_SIZE(tegra186_txn_override_cfgs)
+ .num_txn_override_cfgs = (uint32_t)ARRAY_SIZE(tegra186_txn_override_cfgs),
+ .reconfig_mss_clients = tegra186_memctrl_reconfig_mss_clients,
+ .set_txn_overrides = tegra186_memctrl_set_overrides,
};
/*******************************************************************************
@@ -220,3 +538,45 @@
{
return &tegra186_mc_settings;
}
+
+/*******************************************************************************
+ * Handler to program the scratch registers with TZDRAM settings for the
+ * resume firmware
+ ******************************************************************************/
+void plat_memctrl_tzdram_setup(uint64_t phys_base, uint64_t size_in_bytes)
+{
+ uint32_t val;
+
+ /*
+ * Setup the Memory controller to allow only secure accesses to
+ * the TZDRAM carveout
+ */
+ INFO("Configuring TrustZone DRAM Memory Carveout\n");
+
+ tegra_mc_write_32(MC_SECURITY_CFG0_0, (uint32_t)phys_base);
+ tegra_mc_write_32(MC_SECURITY_CFG3_0, (uint32_t)(phys_base >> 32));
+ tegra_mc_write_32(MC_SECURITY_CFG1_0, size_in_bytes >> 20);
+
+ /*
+ * When TZ encryption is enabled, we need to setup TZDRAM
+ * before CPU accesses TZ Carveout, else CPU will fetch
+ * non-decrypted data. So save TZDRAM setting for SC7 resume
+ * FW to restore.
+ *
+ * Scratch registers map:
+ * RSV55_0 = CFG1[12:0] | CFG0[31:20]
+ * RSV55_1 = CFG3[1:0]
+ */
+ val = tegra_mc_read_32(MC_SECURITY_CFG1_0) & MC_SECURITY_SIZE_MB_MASK;
+ val |= tegra_mc_read_32(MC_SECURITY_CFG0_0) & MC_SECURITY_BOM_MASK;
+ mmio_write_32(TEGRA_SCRATCH_BASE + SCRATCH_TZDRAM_ADDR_LO, val);
+
+ val = tegra_mc_read_32(MC_SECURITY_CFG3_0) & MC_SECURITY_BOM_HI_MASK;
+ mmio_write_32(TEGRA_SCRATCH_BASE + SCRATCH_TZDRAM_ADDR_HI, val);
+
+ /*
+ * MCE propagates the security configuration values across the
+ * CCPLEX.
+ */
+ (void)mce_update_gsc_tzdram();
+}
diff --git a/plat/nvidia/tegra/soc/t186/plat_psci_handlers.c b/plat/nvidia/tegra/soc/t186/plat_psci_handlers.c
index 7a9ce28..09e257d 100644
--- a/plat/nvidia/tegra/soc/t186/plat_psci_handlers.c
+++ b/plat/nvidia/tegra/soc/t186/plat_psci_handlers.c
@@ -20,19 +20,13 @@
#include <mce.h>
#include <smmu.h>
+#include <stdbool.h>
#include <t18x_ari.h>
+#include <tegra186_private.h>
#include <tegra_private.h>
extern void memcpy16(void *dest, const void *src, unsigned int length);
-extern void prepare_cpu_pwr_dwn(void);
-extern void tegra186_cpu_reset_handler(void);
-extern uint32_t __tegra186_cpu_reset_handler_end,
- __tegra186_smmu_context;
-
-/* TZDRAM offset for saving SMMU context */
-#define TEGRA186_SMMU_CTX_OFFSET 16UL
-
/* state id mask */
#define TEGRA186_STATE_ID_MASK 0xFU
/* constants to get power state's wake time */
@@ -111,7 +105,7 @@
/* Enter CPU idle/powerdown */
val = (stateid_afflvl0 == PSTATE_ID_CORE_IDLE) ?
- TEGRA_ARI_CORE_C6 : TEGRA_ARI_CORE_C7;
+ (uint32_t)TEGRA_ARI_CORE_C6 : (uint32_t)TEGRA_ARI_CORE_C7;
(void)mce_command_handler((uint64_t)MCE_CMD_ENTER_CSTATE, (uint64_t)val,
tegra_percpu_data[cpu].wake_time, 0U);
@@ -127,32 +121,36 @@
/* save 'Secure Boot' Processor Feature Config Register */
val = mmio_read_32(TEGRA_MISC_BASE + MISCREG_PFCFG);
- mmio_write_32(TEGRA_SCRATCH_BASE + SECURE_SCRATCH_RSV6, val);
+ mmio_write_32(TEGRA_SCRATCH_BASE + SCRATCH_SECURE_BOOTP_FCFG, val);
/* save SMMU context to TZDRAM */
smmu_ctx_base = params_from_bl2->tzdram_base +
- ((uintptr_t)&__tegra186_smmu_context -
- (uintptr_t)tegra186_cpu_reset_handler);
+ tegra186_get_smmu_ctx_offset();
tegra_smmu_save_context((uintptr_t)smmu_ctx_base);
/* Prepare for system suspend */
- cstate_info.cluster = TEGRA_ARI_CLUSTER_CC7;
- cstate_info.system = TEGRA_ARI_SYSTEM_SC7;
+ cstate_info.cluster = (uint32_t)TEGRA_ARI_CLUSTER_CC7;
+ cstate_info.system = (uint32_t)TEGRA_ARI_SYSTEM_SC7;
cstate_info.system_state_force = 1;
cstate_info.update_wake_mask = 1;
mce_update_cstate_info(&cstate_info);
+
/* Loop until system suspend is allowed */
do {
val = (uint32_t)mce_command_handler(
(uint64_t)MCE_CMD_IS_SC7_ALLOWED,
- TEGRA_ARI_CORE_C7,
+ (uint64_t)TEGRA_ARI_CORE_C7,
MCE_CORE_SLEEP_TIME_INFINITE,
0U);
} while (val == 0U);
/* Instruct the MCE to enter system suspend state */
(void)mce_command_handler((uint64_t)MCE_CMD_ENTER_CSTATE,
- TEGRA_ARI_CORE_C7, MCE_CORE_SLEEP_TIME_INFINITE, 0U);
+ (uint64_t)TEGRA_ARI_CORE_C7, MCE_CORE_SLEEP_TIME_INFINITE, 0U);
+
+ /* set system suspend state for house-keeping */
+ tegra186_set_system_suspend_entry();
+
} else {
; /* do nothing */
}
@@ -161,6 +159,87 @@
}
/*******************************************************************************
+ * Helper function to check if this is the last ON CPU in the cluster
+ ******************************************************************************/
+static bool tegra_last_cpu_in_cluster(const plat_local_state_t *states,
+ uint32_t ncpu)
+{
+ plat_local_state_t target;
+ bool last_on_cpu = true;
+ uint32_t num_cpus = ncpu, pos = 0;
+
+ do {
+ target = states[pos];
+ if (target != PLAT_MAX_OFF_STATE) {
+ last_on_cpu = false;
+ }
+ --num_cpus;
+ pos++;
+ } while (num_cpus != 0U);
+
+ return last_on_cpu;
+}
+
+/*******************************************************************************
+ * Helper function to get target power state for the cluster
+ ******************************************************************************/
+static plat_local_state_t tegra_get_afflvl1_pwr_state(const plat_local_state_t *states,
+ uint32_t ncpu)
+{
+ uint32_t core_pos = (uint32_t)read_mpidr() & (uint32_t)MPIDR_CPU_MASK;
+ uint32_t cpu = plat_my_core_pos();
+ int32_t ret;
+ plat_local_state_t target = states[core_pos];
+ mce_cstate_info_t cstate_info = { 0 };
+
+ /* CPU suspend */
+ if (target == PSTATE_ID_CORE_POWERDN) {
+ /* Program default wake mask */
+ cstate_info.wake_mask = TEGRA186_CORE_WAKE_MASK;
+ cstate_info.update_wake_mask = 1;
+ mce_update_cstate_info(&cstate_info);
+
+ /* Check if CCx state is allowed. */
+ ret = mce_command_handler((uint64_t)MCE_CMD_IS_CCX_ALLOWED,
+ (uint64_t)TEGRA_ARI_CORE_C7,
+ tegra_percpu_data[cpu].wake_time,
+ 0U);
+ if (ret == 0) {
+ target = PSCI_LOCAL_STATE_RUN;
+ }
+ }
+
+ /* CPU off */
+ if (target == PLAT_MAX_OFF_STATE) {
+ /* Enable cluster powerdn from last CPU in the cluster */
+ if (tegra_last_cpu_in_cluster(states, ncpu)) {
+ /* Enable CC7 state and turn off wake mask */
+ cstate_info.cluster = (uint32_t)TEGRA_ARI_CLUSTER_CC7;
+ cstate_info.update_wake_mask = 1;
+ mce_update_cstate_info(&cstate_info);
+
+ /* Check if CCx state is allowed. */
+ ret = mce_command_handler((uint64_t)MCE_CMD_IS_CCX_ALLOWED,
+ (uint64_t)TEGRA_ARI_CORE_C7,
+ MCE_CORE_SLEEP_TIME_INFINITE,
+ 0U);
+ if (ret == 0) {
+ target = PSCI_LOCAL_STATE_RUN;
+ }
+
+ } else {
+
+ /* Turn off wake_mask */
+ cstate_info.update_wake_mask = 1;
+ mce_update_cstate_info(&cstate_info);
+ target = PSCI_LOCAL_STATE_RUN;
+ }
+ }
+
+ return target;
+}
+
+/*******************************************************************************
* Platform handler to calculate the proper target power level at the
* specified affinity level
******************************************************************************/
@@ -168,85 +247,22 @@
const plat_local_state_t *states,
uint32_t ncpu)
{
- plat_local_state_t target = *states;
- uint32_t pos = 0;
- plat_local_state_t result = PSCI_LOCAL_STATE_RUN;
- uint32_t cpu = plat_my_core_pos(), num_cpu = ncpu;
- int32_t ret, cluster_powerdn = 1;
- uint64_t core_pos = read_mpidr() & (uint64_t)MPIDR_CPU_MASK;
- mce_cstate_info_t cstate_info = { 0 };
-
- /* get the power state at this level */
- if (lvl == (uint32_t)MPIDR_AFFLVL1) {
- target = states[core_pos];
- }
- if (lvl == (uint32_t)MPIDR_AFFLVL2) {
- target = states[cpu];
- }
-
- /* CPU suspend */
- if ((lvl == (uint32_t)MPIDR_AFFLVL1) && (target == PSTATE_ID_CORE_POWERDN)) {
-
- /* Program default wake mask */
- cstate_info.wake_mask = TEGRA186_CORE_WAKE_MASK;
- cstate_info.update_wake_mask = 1;
- mce_update_cstate_info(&cstate_info);
-
- /* Check if CCx state is allowed. */
- ret = mce_command_handler((uint64_t)MCE_CMD_IS_CCX_ALLOWED,
- TEGRA_ARI_CORE_C7, tegra_percpu_data[cpu].wake_time,
- 0U);
- if (ret != 0) {
- result = PSTATE_ID_CORE_POWERDN;
- }
- }
-
- /* CPU off */
- if ((lvl == (uint32_t)MPIDR_AFFLVL1) && (target == PLAT_MAX_OFF_STATE)) {
-
- /* find out the number of ON cpus in the cluster */
- do {
- target = states[pos];
- if (target != PLAT_MAX_OFF_STATE) {
- cluster_powerdn = 0;
- }
- --num_cpu;
- pos++;
- } while (num_cpu != 0U);
-
- /* Enable cluster powerdn from last CPU in the cluster */
- if (cluster_powerdn != 0) {
-
- /* Enable CC7 state and turn off wake mask */
- cstate_info.cluster = TEGRA_ARI_CLUSTER_CC7;
- cstate_info.update_wake_mask = 1;
- mce_update_cstate_info(&cstate_info);
-
- /* Check if CCx state is allowed. */
- ret = mce_command_handler((uint64_t)MCE_CMD_IS_CCX_ALLOWED,
- TEGRA_ARI_CORE_C7,
- MCE_CORE_SLEEP_TIME_INFINITE,
- 0U);
- if (ret != 0) {
- result = PSTATE_ID_CORE_POWERDN;
- }
-
- } else {
-
- /* Turn off wake_mask */
- cstate_info.update_wake_mask = 1;
- mce_update_cstate_info(&cstate_info);
- }
- }
+ plat_local_state_t target = PSCI_LOCAL_STATE_RUN;
+ uint32_t cpu = plat_my_core_pos();
/* System Suspend */
- if (((lvl == (uint32_t)MPIDR_AFFLVL2) || (lvl == (uint32_t)MPIDR_AFFLVL1)) &&
- (target == PSTATE_ID_SOC_POWERDN)) {
- result = PSTATE_ID_SOC_POWERDN;
+ if ((lvl == (uint32_t)MPIDR_AFFLVL2) &&
+ (states[cpu] == PSTATE_ID_SOC_POWERDN)) {
+ target = PSTATE_ID_SOC_POWERDN;
}
- /* default state */
- return result;
+ /* CPU off, CPU suspend */
+ if (lvl == (uint32_t)MPIDR_AFFLVL1) {
+ target = tegra_get_afflvl1_pwr_state(states, ncpu);
+ }
+
+ /* target cluster/system state */
+ return target;
}
int32_t tegra_soc_pwr_domain_power_down_wfi(const psci_power_state_t *target_state)
@@ -265,8 +281,7 @@
* BL3-1 over to TZDRAM.
*/
val = params_from_bl2->tzdram_base +
- ((uintptr_t)&__tegra186_cpu_reset_handler_end -
- (uintptr_t)&tegra186_cpu_reset_handler);
+ tegra186_get_cpu_reset_handler_size();
memcpy16((void *)(uintptr_t)val, (void *)(uintptr_t)BL31_BASE,
(uintptr_t)&__BL31_END__ - (uintptr_t)BL31_BASE);
}
@@ -276,12 +291,12 @@
int32_t tegra_soc_pwr_domain_on(u_register_t mpidr)
{
- uint32_t target_cpu = mpidr & (uint64_t)MPIDR_CPU_MASK;
- uint32_t target_cluster = (mpidr & MPIDR_CLUSTER_MASK) >>
- (uint64_t)MPIDR_AFFINITY_BITS;
int32_t ret = PSCI_E_SUCCESS;
+ uint64_t target_cpu = mpidr & MPIDR_CPU_MASK;
+ uint64_t target_cluster = (mpidr & MPIDR_CLUSTER_MASK) >>
+ MPIDR_AFFINITY_BITS;
- if (target_cluster > (uint64_t)MPIDR_AFFLVL1) {
+ if (target_cluster > ((uint32_t)PLATFORM_CLUSTER_COUNT - 1U)) {
ERROR("%s: unsupported CPU (0x%lx)\n", __func__, mpidr);
ret = PSCI_E_NOT_PRESENT;
@@ -304,14 +319,13 @@
uint64_t impl, val;
const plat_params_from_bl2_t *plat_params = bl31_get_plat_params();
- impl = (read_midr() >> MIDR_IMPL_SHIFT) & (uint64_t)MIDR_IMPL_MASK;
+ impl = (read_midr() >> MIDR_IMPL_SHIFT) & MIDR_IMPL_MASK;
/*
* Enable ECC and Parity Protection for Cortex-A57 CPUs (Tegra186
* A02p and beyond).
*/
- if ((plat_params->l2_ecc_parity_prot_dis != 1) &&
- (impl != (uint64_t)DENVER_IMPL)) {
+ if ((plat_params->l2_ecc_parity_prot_dis != 1) && (impl != DENVER_IMPL)) {
val = read_l2ctlr_el1();
val |= CORTEX_A57_L2_ECC_PARITY_PROTECTION_BIT;
@@ -327,7 +341,7 @@
*/
if (stateid_afflvl0 == PLAT_MAX_OFF_STATE) {
- cstate_info.cluster = TEGRA_ARI_CLUSTER_CC1;
+ cstate_info.cluster = (uint32_t)TEGRA_ARI_CLUSTER_CC1;
cstate_info.update_wake_mask = 1;
mce_update_cstate_info(&cstate_info);
}
@@ -354,8 +368,8 @@
* and SC7 for SC7 entry which may not be requested by
* non-secure SW which controls idle states.
*/
- cstate_info.cluster = TEGRA_ARI_CLUSTER_CC7;
- cstate_info.system = TEGRA_ARI_SYSTEM_SC1;
+ cstate_info.cluster = (uint32_t)TEGRA_ARI_CLUSTER_CC7;
+ cstate_info.system = (uint32_t)TEGRA_ARI_SYSTEM_SC1;
cstate_info.update_wake_mask = 1;
mce_update_cstate_info(&cstate_info);
}
@@ -375,8 +389,8 @@
}
/* Turn off CPU */
- (void)mce_command_handler((uint64_t)MCE_CMD_ENTER_CSTATE, TEGRA_ARI_CORE_C7,
- MCE_CORE_SLEEP_TIME_INFINITE, 0U);
+ (void)mce_command_handler((uint64_t)MCE_CMD_ENTER_CSTATE,
+ (uint64_t)TEGRA_ARI_CORE_C7, MCE_CORE_SLEEP_TIME_INFINITE, 0U);
return PSCI_E_SUCCESS;
}
@@ -384,7 +398,7 @@
__dead2 void tegra_soc_prepare_system_off(void)
{
/* power off the entire system */
- mce_enter_ccplex_state(TEGRA_ARI_MISC_CCPLEX_SHUTDOWN_POWER_OFF);
+ mce_enter_ccplex_state((uint32_t)TEGRA_ARI_MISC_CCPLEX_SHUTDOWN_POWER_OFF);
wfi();
@@ -396,7 +410,7 @@
int32_t tegra_soc_prepare_system_reset(void)
{
- mce_enter_ccplex_state(TEGRA_ARI_MISC_CCPLEX_SHUTDOWN_REBOOT);
+ mce_enter_ccplex_state((uint32_t)TEGRA_ARI_MISC_CCPLEX_SHUTDOWN_REBOOT);
return PSCI_E_SUCCESS;
}
diff --git a/plat/nvidia/tegra/soc/t186/plat_secondary.c b/plat/nvidia/tegra/soc/t186/plat_secondary.c
index 35a403b..1650809 100644
--- a/plat/nvidia/tegra/soc/t186/plat_secondary.c
+++ b/plat/nvidia/tegra/soc/t186/plat_secondary.c
@@ -11,6 +11,7 @@
#include <lib/mmio.h>
#include <mce.h>
+#include <tegra186_private.h>
#include <tegra_def.h>
#include <tegra_private.h>
@@ -24,9 +25,6 @@
extern void memcpy16(void *dest, const void *src, unsigned int length);
-extern uint64_t tegra_bl31_phys_base;
-extern uint64_t __tegra186_cpu_reset_handler_end;
-
/*******************************************************************************
* Setup secondary CPU vectors
******************************************************************************/
@@ -34,39 +32,33 @@
{
uint32_t addr_low, addr_high;
const plat_params_from_bl2_t *params_from_bl2 = bl31_get_plat_params();
- uint64_t cpu_reset_handler_base;
+ uint64_t cpu_reset_handler_base, cpu_reset_handler_size;
INFO("Setting up secondary CPU boot\n");
- if ((tegra_bl31_phys_base >= TEGRA_TZRAM_BASE) &&
- (tegra_bl31_phys_base <= (TEGRA_TZRAM_BASE + TEGRA_TZRAM_SIZE))) {
+ /*
+ * The BL31 code resides in the TZSRAM which loses state
+ * when we enter System Suspend. Copy the wakeup trampoline
+ * code to TZDRAM to help us exit from System Suspend.
+ */
+ cpu_reset_handler_base = tegra186_get_cpu_reset_handler_base();
+ cpu_reset_handler_size = tegra186_get_cpu_reset_handler_size();
+ (void)memcpy16((void *)(uintptr_t)params_from_bl2->tzdram_base,
+ (const void *)(uintptr_t)cpu_reset_handler_base,
+ cpu_reset_handler_size);
- /*
- * The BL31 code resides in the TZSRAM which loses state
- * when we enter System Suspend. Copy the wakeup trampoline
- * code to TZDRAM to help us exit from System Suspend.
- */
- cpu_reset_handler_base = params_from_bl2->tzdram_base;
- memcpy16((void *)((uintptr_t)cpu_reset_handler_base),
- (void *)(uintptr_t)tegra186_cpu_reset_handler,
- (uintptr_t)&__tegra186_cpu_reset_handler_end -
- (uintptr_t)tegra186_cpu_reset_handler);
-
- } else {
- cpu_reset_handler_base = (uintptr_t)tegra_secure_entrypoint;
- }
-
- addr_low = (uint32_t)cpu_reset_handler_base | CPU_RESET_MODE_AA64;
- addr_high = (uint32_t)((cpu_reset_handler_base >> 32U) & 0x7ffU);
+ /* TZDRAM base will be used as the "resume" address */
+ addr_low = (uint32_t)params_from_bl2->tzdram_base | CPU_RESET_MODE_AA64;
+ addr_high = (uint32_t)((params_from_bl2->tzdram_base >> 32U) & 0x7ffU);
/* write lower 32 bits first, then the upper 11 bits */
mmio_write_32(TEGRA_MISC_BASE + MISCREG_AA64_RST_LOW, addr_low);
mmio_write_32(TEGRA_MISC_BASE + MISCREG_AA64_RST_HIGH, addr_high);
/* save reset vector to be used during SYSTEM_SUSPEND exit */
- mmio_write_32(TEGRA_SCRATCH_BASE + SCRATCH_SECURE_RSV1_SCRATCH_0,
+ mmio_write_32(TEGRA_SCRATCH_BASE + SCRATCH_RESET_VECTOR_LO,
addr_low);
- mmio_write_32(TEGRA_SCRATCH_BASE + SCRATCH_SECURE_RSV1_SCRATCH_1,
+ mmio_write_32(TEGRA_SCRATCH_BASE + SCRATCH_RESET_VECTOR_HI,
addr_high);
/* update reset vector address to the CCPLEX */
diff --git a/plat/nvidia/tegra/soc/t186/plat_setup.c b/plat/nvidia/tegra/soc/t186/plat_setup.c
index bbd19c1..fd109e5 100644
--- a/plat/nvidia/tegra/soc/t186/plat_setup.c
+++ b/plat/nvidia/tegra/soc/t186/plat_setup.c
@@ -40,7 +40,7 @@
* the number of power domains at the highest power level.
*******************************************************************************
*/
-const uint8_t tegra_power_domain_tree_desc[] = {
+static const uint8_t tegra_power_domain_tree_desc[] = {
/* No of root nodes */
1,
/* No of clusters */
@@ -211,7 +211,7 @@
{
uint32_t val;
- val = mmio_read_32(TEGRA_SCRATCH_BASE + SECURE_SCRATCH_RSV53_LO);
+ val = mmio_read_32(TEGRA_SCRATCH_BASE + SCRATCH_BL31_PARAMS_ADDR);
return (struct tegra_bl31_params *)(uintptr_t)val;
}
@@ -223,7 +223,7 @@
{
uint32_t val;
- val = mmio_read_32(TEGRA_SCRATCH_BASE + SECURE_SCRATCH_RSV53_HI);
+ val = mmio_read_32(TEGRA_SCRATCH_BASE + SCRATCH_BL31_PLAT_PARAMS_ADDR);
return (plat_params_from_bl2_t *)(uintptr_t)val;
}
diff --git a/plat/nvidia/tegra/soc/t186/plat_sip_calls.c b/plat/nvidia/tegra/soc/t186/plat_sip_calls.c
index 955029e..4de8a9e 100644
--- a/plat/nvidia/tegra/soc/t186/plat_sip_calls.c
+++ b/plat/nvidia/tegra/soc/t186/plat_sip_calls.c
@@ -23,7 +23,7 @@
/*******************************************************************************
* Offset to read the ref_clk counter value
******************************************************************************/
-#define REF_CLK_OFFSET 4
+#define REF_CLK_OFFSET 4ULL
/*******************************************************************************
* Tegra186 SiP SMCs
@@ -35,7 +35,7 @@
#define TEGRA_SIP_MCE_CMD_READ_CSTATE_STATS 0xC2FFFF03
#define TEGRA_SIP_MCE_CMD_WRITE_CSTATE_STATS 0xC2FFFF04
#define TEGRA_SIP_MCE_CMD_IS_SC7_ALLOWED 0xC2FFFF05
-#define TEGRA_SIP_MCE_CMD_ONLINE_CORE 0xC2FFFF06
+
#define TEGRA_SIP_MCE_CMD_CC3_CTRL 0xC2FFFF07
#define TEGRA_SIP_MCE_CMD_ECHO_DATA 0xC2FFFF08
#define TEGRA_SIP_MCE_CMD_READ_VERSIONS 0xC2FFFF09
@@ -52,7 +52,7 @@
/*******************************************************************************
* This function is responsible for handling all T186 SiP calls
******************************************************************************/
-int plat_sip_handler(uint32_t smc_fid,
+int32_t plat_sip_handler(uint32_t smc_fid,
uint64_t x1,
uint64_t x2,
uint64_t x3,
@@ -61,24 +61,30 @@
void *handle,
uint64_t flags)
{
- int mce_ret;
- int impl, cpu;
+ int32_t mce_ret, ret = 0;
+ uint32_t impl, cpu;
uint32_t base, core_clk_ctr, ref_clk_ctr;
+ uint32_t local_smc_fid = smc_fid;
+ uint64_t local_x1 = x1, local_x2 = x2, local_x3 = x3;
+
+ (void)x4;
+ (void)cookie;
+ (void)flags;
if (((smc_fid >> FUNCID_CC_SHIFT) & FUNCID_CC_MASK) == SMC_32) {
/* 32-bit function, clear top parameter bits */
- x1 = (uint32_t)x1;
- x2 = (uint32_t)x2;
- x3 = (uint32_t)x3;
+ local_x1 = (uint32_t)x1;
+ local_x2 = (uint32_t)x2;
+ local_x3 = (uint32_t)x3;
}
/*
* Convert SMC FID to SMC64, to support SMC32/SMC64 configurations
*/
- smc_fid |= (SMC_64 << FUNCID_CC_SHIFT);
+ local_smc_fid |= (SMC_64 << FUNCID_CC_SHIFT);
- switch (smc_fid) {
+ switch (local_smc_fid) {
/*
* Micro Coded Engine (MCE) commands reside in the 0x82FFFF00 -
* 0x82FFFFFF SiP SMC space
@@ -103,14 +109,13 @@
case TEGRA_SIP_MCE_CMD_MISC_CCPLEX:
/* clean up the high bits */
- smc_fid &= MCE_CMD_MASK;
+ local_smc_fid &= MCE_CMD_MASK;
/* execute the command and store the result */
- mce_ret = mce_command_handler(smc_fid, x1, x2, x3);
- write_ctx_reg(get_gpregs_ctx(handle), CTX_GPREG_X0,
- (uint64_t)mce_ret);
-
- return 0;
+ mce_ret = mce_command_handler(local_smc_fid, local_x1, local_x2, local_x3);
+ write_ctx_reg(get_gpregs_ctx(handle),
+ CTX_GPREG_X0, (uint64_t)(mce_ret));
+ break;
/*
* This function ID reads the Activity monitor's core/ref clock
@@ -125,28 +130,30 @@
impl = ((uint32_t)x2 >> MIDR_IMPL_SHIFT) & MIDR_IMPL_MASK;
/* sanity check target CPU number */
- if (cpu > PLATFORM_MAX_CPUS_PER_CLUSTER)
- return -EINVAL;
+ if (cpu > (uint32_t)PLATFORM_MAX_CPUS_PER_CLUSTER) {
+ ret = -EINVAL;
+ } else {
+ /* get the base address for the current CPU */
+ base = (impl == DENVER_IMPL) ? TEGRA_DENVER_ACTMON_CTR_BASE :
+ TEGRA_ARM_ACTMON_CTR_BASE;
- /* get the base address for the current CPU */
- base = (impl == DENVER_IMPL) ? TEGRA_DENVER_ACTMON_CTR_BASE :
- TEGRA_ARM_ACTMON_CTR_BASE;
+ /* read the clock counter values */
+ core_clk_ctr = mmio_read_32(base + (8ULL * cpu));
+ ref_clk_ctr = mmio_read_32(base + (8ULL * cpu) + REF_CLK_OFFSET);
- /* read the clock counter values */
- core_clk_ctr = mmio_read_32(base + (8 * cpu));
- ref_clk_ctr = mmio_read_32(base + (8 * cpu) + REF_CLK_OFFSET);
+ /* return the counter values as two different parameters */
+ write_ctx_reg(get_gpregs_ctx(handle),
+ CTX_GPREG_X1, (core_clk_ctr));
+ write_ctx_reg(get_gpregs_ctx(handle),
+ CTX_GPREG_X2, (ref_clk_ctr));
+ }
- /* return the counter values as two different parameters */
- write_ctx_reg(get_gpregs_ctx(handle), CTX_GPREG_X1,
- (uint64_t)core_clk_ctr);
- write_ctx_reg(get_gpregs_ctx(handle), CTX_GPREG_X2,
- (uint64_t)ref_clk_ctr);
-
- return 0;
+ break;
default:
+ ret = -ENOTSUP;
break;
}
- return -ENOTSUP;
+ return ret;
}
diff --git a/plat/nvidia/tegra/soc/t186/plat_smmu.c b/plat/nvidia/tegra/soc/t186/plat_smmu.c
index 19e065c..95f6def 100644
--- a/plat/nvidia/tegra/soc/t186/plat_smmu.c
+++ b/plat/nvidia/tegra/soc/t186/plat_smmu.c
@@ -8,6 +8,9 @@
#include <smmu.h>
#include <tegra_def.h>
+#include <tegra_mc_def.h>
+
+#define MAX_NUM_SMMU_DEVICES U(1)
/*******************************************************************************
* Array to hold SMMU context for Tegra186
@@ -305,7 +308,15 @@
smmu_regs_t *plat_get_smmu_ctx(void)
{
/* index of _END_OF_TABLE_ */
- tegra186_smmu_context[0].val = ARRAY_SIZE(tegra186_smmu_context) - 1;
+ tegra186_smmu_context[0].val = (uint32_t)(ARRAY_SIZE(tegra186_smmu_context)) - 1U;
return tegra186_smmu_context;
}
+
+/*******************************************************************************
+ * Handler to return the support SMMU devices number
+ ******************************************************************************/
+uint32_t plat_get_num_smmu_devices(void)
+{
+ return MAX_NUM_SMMU_DEVICES;
+}
diff --git a/plat/nvidia/tegra/soc/t186/plat_trampoline.S b/plat/nvidia/tegra/soc/t186/plat_trampoline.S
index 69ca798..e3393e9 100644
--- a/plat/nvidia/tegra/soc/t186/plat_trampoline.S
+++ b/plat/nvidia/tegra/soc/t186/plat_trampoline.S
@@ -10,23 +10,32 @@
#include <plat/common/common_def.h>
#include <tegra_def.h>
+#define TEGRA186_STATE_SYSTEM_SUSPEND 0x5C7
+#define TEGRA186_STATE_SYSTEM_RESUME 0x600D
#define TEGRA186_SMMU_CTX_SIZE 0x420
.globl tegra186_cpu_reset_handler
/* CPU reset handler routine */
func tegra186_cpu_reset_handler _align=4
- /*
- * The TZRAM loses state during System Suspend. We use this
- * information to decide if the reset handler is running after a
- * System Suspend. Resume from system suspend requires restoring
- * the entire state from TZDRAM to TZRAM.
- */
- mov x0, #BL31_BASE
- ldr x0, [x0]
- cbnz x0, boot_cpu
+ /* check if we are exiting system suspend state */
+ adr x0, __tegra186_system_suspend_state
+ ldr x1, [x0]
+ mov x2, #TEGRA186_STATE_SYSTEM_SUSPEND
+ lsl x2, x2, #16
+ add x2, x2, #TEGRA186_STATE_SYSTEM_SUSPEND
+ cmp x1, x2
+ bne boot_cpu
- /* resume from system suspend */
+ /* set system resume state */
+ mov x1, #TEGRA186_STATE_SYSTEM_RESUME
+ lsl x1, x1, #16
+ mov x2, #TEGRA186_STATE_SYSTEM_RESUME
+ add x1, x1, x2
+ str x1, [x0]
+ dsb sy
+
+ /* prepare to relocate to TZSRAM */
mov x0, #BL31_BASE
adr x1, __tegra186_cpu_reset_handler_end
adr x2, __tegra186_cpu_reset_handler_data
@@ -69,6 +78,12 @@
__tegra186_cpu_reset_handler_data:
.quad tegra_secure_entrypoint
.quad __BL31_END__ - BL31_BASE
+
+ .globl __tegra186_system_suspend_state
+__tegra186_system_suspend_state:
+ .quad 0
+
+ .align 4
.globl __tegra186_smmu_context
__tegra186_smmu_context:
.rept TEGRA186_SMMU_CTX_SIZE
@@ -80,3 +95,50 @@
.align 4
.globl __tegra186_cpu_reset_handler_end
__tegra186_cpu_reset_handler_end:
+
+ .globl tegra186_get_cpu_reset_handler_size
+ .globl tegra186_get_cpu_reset_handler_base
+ .globl tegra186_get_smmu_ctx_offset
+ .globl tegra186_set_system_suspend_entry
+
+/* return size of the CPU reset handler */
+func tegra186_get_cpu_reset_handler_size
+ adr x0, __tegra186_cpu_reset_handler_end
+ adr x1, tegra186_cpu_reset_handler
+ sub x0, x0, x1
+ ret
+endfunc tegra186_get_cpu_reset_handler_size
+
+/* return the start address of the CPU reset handler */
+func tegra186_get_cpu_reset_handler_base
+ adr x0, tegra186_cpu_reset_handler
+ ret
+endfunc tegra186_get_cpu_reset_handler_base
+
+/* return the size of the SMMU context */
+func tegra186_get_smmu_ctx_offset
+ adr x0, __tegra186_smmu_context
+ adr x1, tegra186_cpu_reset_handler
+ sub x0, x0, x1
+ ret
+endfunc tegra186_get_smmu_ctx_offset
+
+/* set system suspend state before SC7 entry */
+func tegra186_set_system_suspend_entry
+ mov x0, #TEGRA_MC_BASE
+ mov x3, #MC_SECURITY_CFG3_0
+ ldr w1, [x0, x3]
+ lsl x1, x1, #32
+ mov x3, #MC_SECURITY_CFG0_0
+ ldr w2, [x0, x3]
+ orr x3, x1, x2 /* TZDRAM base */
+ adr x0, __tegra186_system_suspend_state
+ adr x1, tegra186_cpu_reset_handler
+ sub x2, x0, x1 /* offset in TZDRAM */
+ mov x0, #TEGRA186_STATE_SYSTEM_SUSPEND
+ lsl x0, x0, #16
+ add x0, x0, #TEGRA186_STATE_SYSTEM_SUSPEND
+ str x0, [x3, x2] /* set value in TZDRAM */
+ dsb sy
+ ret
+endfunc tegra186_set_system_suspend_entry
diff --git a/plat/nvidia/tegra/soc/t186/platform_t186.mk b/plat/nvidia/tegra/soc/t186/platform_t186.mk
index c905323..fdeb886 100644
--- a/plat/nvidia/tegra/soc/t186/platform_t186.mk
+++ b/plat/nvidia/tegra/soc/t186/platform_t186.mk
@@ -11,18 +11,9 @@
ENABLE_ROC_FOR_ORDERING_CLIENT_REQUESTS := 1
$(eval $(call add_define,ENABLE_ROC_FOR_ORDERING_CLIENT_REQUESTS))
-RELOCATE_TO_BL31_BASE := 1
-$(eval $(call add_define,RELOCATE_TO_BL31_BASE))
-
ENABLE_CHIP_VERIFICATION_HARNESS := 0
$(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
@@ -48,8 +39,10 @@
# platform files
PLAT_INCLUDES += -I${SOC_DIR}/drivers/include
-BL31_SOURCES += lib/cpus/aarch64/denver.S \
+BL31_SOURCES += drivers/ti/uart/aarch64/16550_console.S \
+ lib/cpus/aarch64/denver.S \
lib/cpus/aarch64/cortex_a57.S \
+ ${COMMON_DIR}/drivers/gpcdma/gpcdma.c \
${COMMON_DIR}/drivers/memctrl/memctrl_v2.c \
${COMMON_DIR}/drivers/smmu/smmu.c \
${SOC_DIR}/drivers/mce/mce.c \
@@ -64,3 +57,13 @@
${SOC_DIR}/plat_smmu.c \
${SOC_DIR}/plat_trampoline.S
+# Enable workarounds for selected Cortex-A57 erratas.
+A57_DISABLE_NON_TEMPORAL_HINT := 1
+ERRATA_A57_806969 := 1
+ERRATA_A57_813419 := 1
+ERRATA_A57_813420 := 1
+ERRATA_A57_826974 := 1
+ERRATA_A57_826977 := 1
+ERRATA_A57_828024 := 1
+ERRATA_A57_829520 := 1
+ERRATA_A57_833471 := 1
diff --git a/plat/nvidia/tegra/soc/t210/drivers/se/se_private.h b/plat/nvidia/tegra/soc/t210/drivers/se/se_private.h
index 0157747..be1f9cc 100644
--- a/plat/nvidia/tegra/soc/t210/drivers/se/se_private.h
+++ b/plat/nvidia/tegra/soc/t210/drivers/se/se_private.h
@@ -16,14 +16,16 @@
*/
/* Secure scratch registers */
-#define PMC_SECURE_SCRATCH4_OFFSET 0xC0U
-#define PMC_SECURE_SCRATCH5_OFFSET 0xC4U
-#define PMC_SECURE_SCRATCH6_OFFSET 0x224U
-#define PMC_SECURE_SCRATCH7_OFFSET 0x228U
-#define PMC_SECURE_SCRATCH120_OFFSET 0xB38U
-#define PMC_SECURE_SCRATCH121_OFFSET 0xB3CU
-#define PMC_SECURE_SCRATCH122_OFFSET 0xB40U
-#define PMC_SECURE_SCRATCH123_OFFSET 0xB44U
+#define PMC_SECURE_SCRATCH4_OFFSET 0xC0U
+#define PMC_SECURE_SCRATCH5_OFFSET 0xC4U
+#define PMC_SECURE_SCRATCH6_OFFSET 0x224U
+#define PMC_SECURE_SCRATCH7_OFFSET 0x228U
+#define PMC_SECURE_SCRATCH116_OFFSET 0xB28U
+#define PMC_SECURE_SCRATCH117_OFFSET 0xB2CU
+#define PMC_SECURE_SCRATCH120_OFFSET 0xB38U
+#define PMC_SECURE_SCRATCH121_OFFSET 0xB3CU
+#define PMC_SECURE_SCRATCH122_OFFSET 0xB40U
+#define PMC_SECURE_SCRATCH123_OFFSET 0xB44U
/*
* AHB arbitration memory write queue
@@ -32,6 +34,12 @@
#define ARAHB_MST_ID_SE2_MASK (0x1U << 13)
#define ARAHB_MST_ID_SE_MASK (0x1U << 14)
+/**
+ * SE registers
+ */
+#define TEGRA_SE_AES_KEYSLOT_COUNT 16
+#define SE_MAX_LAST_BLOCK_SIZE 0xFFFFF
+
/* SE Status register */
#define SE_STATUS_OFFSET 0x800U
#define SE_STATUS_SHIFT 0
@@ -42,8 +50,24 @@
#define SE_STATUS(x) \
((x) & ((0x3U) << SE_STATUS_SHIFT))
+#define SE_MEM_INTERFACE_SHIFT 2
+#define SE_MEM_INTERFACE_IDLE 0
+#define SE_MEM_INTERFACE_BUSY 1
+#define SE_MEM_INTERFACE(x) ((x) << SE_STATUS_SHIFT)
+
+/* SE register definitions */
+#define SE_SECURITY_REG_OFFSET 0x0
+#define SE_SECURITY_TZ_LOCK_SOFT_SHIFT 5
+#define SE_SECURE 0x0
+#define SE_SECURITY_TZ_LOCK_SOFT(x) ((x) << SE_SECURITY_TZ_LOCK_SOFT_SHIFT)
+
+#define SE_SEC_ENG_DIS_SHIFT 1
+#define SE_DISABLE_FALSE 0
+#define SE_DISABLE_TRUE 1
+#define SE_SEC_ENG_DISABLE(x)((x) << SE_SEC_ENG_DIS_SHIFT)
+
/* SE config register */
-#define SE_CONFIG_REG_OFFSET 0x14U
+#define SE_CONFIG_REG_OFFSET 0x14U
#define SE_CONFIG_ENC_ALG_SHIFT 12
#define SE_CONFIG_ENC_ALG_AES_ENC \
((1U) << SE_CONFIG_ENC_ALG_SHIFT)
@@ -66,7 +90,7 @@
#define SE_CONFIG_DEC_ALG(x) \
((x) & ((0xFU) << SE_CONFIG_DEC_ALG_SHIFT))
-#define SE_CONFIG_DST_SHIFT 2
+#define SE_CONFIG_DST_SHIFT 2
#define SE_CONFIG_DST_MEMORY \
((0U) << SE_CONFIG_DST_SHIFT)
#define SE_CONFIG_DST_HASHREG \
@@ -80,33 +104,75 @@
#define SE_CONFIG_DST(x) \
((x) & ((0x7U) << SE_CONFIG_DST_SHIFT))
+#define SE_CONFIG_ENC_MODE_SHIFT 24
+#define SE_CONFIG_ENC_MODE_KEY128 \
+ ((0UL) << SE_CONFIG_ENC_MODE_SHIFT)
+#define SE_CONFIG_ENC_MODE_KEY192 \
+ ((1UL) << SE_CONFIG_ENC_MODE_SHIFT)
+#define SE_CONFIG_ENC_MODE_KEY256 \
+ ((2UL) << SE_CONFIG_ENC_MODE_SHIFT)
+#define SE_CONFIG_ENC_MODE_SHA1 \
+ ((0UL) << SE_CONFIG_ENC_MODE_SHIFT)
+#define SE_CONFIG_ENC_MODE_SHA224 \
+ ((4UL) << SE_CONFIG_ENC_MODE_SHIFT)
+#define SE_CONFIG_ENC_MODE_SHA256 \
+ ((5UL) << SE_CONFIG_ENC_MODE_SHIFT)
+#define SE_CONFIG_ENC_MODE_SHA384 \
+ ((6UL) << SE_CONFIG_ENC_MODE_SHIFT)
+#define SE_CONFIG_ENC_MODE_SHA512 \
+ ((7UL) << SE_CONFIG_ENC_MODE_SHIFT)
+#define SE_CONFIG_ENC_MODE(x)\
+ ((x) & ((0xFFUL) << SE_CONFIG_ENC_MODE_SHIFT))
+
+#define SE_CONFIG_DEC_MODE_SHIFT 16
+#define SE_CONFIG_DEC_MODE_KEY128 \
+ ((0UL) << SE_CONFIG_DEC_MODE_SHIFT)
+#define SE_CONFIG_DEC_MODE_KEY192 \
+ ((1UL) << SE_CONFIG_DEC_MODE_SHIFT)
+#define SE_CONFIG_DEC_MODE_KEY256 \
+ ((2UL) << SE_CONFIG_DEC_MODE_SHIFT)
+#define SE_CONFIG_DEC_MODE_SHA1 \
+ ((0UL) << SE_CONFIG_DEC_MODE_SHIFT)
+#define SE_CONFIG_DEC_MODE_SHA224 \
+ ((4UL) << SE_CONFIG_DEC_MODE_SHIFT)
+#define SE_CONFIG_DEC_MODE_SHA256 \
+ ((5UL) << SE_CONFIG_DEC_MODE_SHIFT)
+#define SE_CONFIG_DEC_MODE_SHA384 \
+ ((6UL) << SE_CONFIG_DEC_MODE_SHIFT)
+#define SE_CONFIG_DEC_MODE_SHA512 \
+ ((7UL) << SE_CONFIG_DEC_MODE_SHIFT)
+#define SE_CONFIG_DEC_MODE(x)\
+ ((x) & ((0xFFUL) << SE_CONFIG_DEC_MODE_SHIFT))
+
+
/* DRBG random number generator config */
#define SE_RNG_CONFIG_REG_OFFSET 0x340
#define DRBG_MODE_SHIFT 0
#define DRBG_MODE_NORMAL \
- ((0UL) << DRBG_MODE_SHIFT)
+ ((0U) << DRBG_MODE_SHIFT)
#define DRBG_MODE_FORCE_INSTANTION \
- ((1UL) << DRBG_MODE_SHIFT)
+ ((1U) << DRBG_MODE_SHIFT)
#define DRBG_MODE_FORCE_RESEED \
- ((2UL) << DRBG_MODE_SHIFT)
+ ((2U) << DRBG_MODE_SHIFT)
#define SE_RNG_CONFIG_MODE(x) \
- ((x) & ((0x3UL) << DRBG_MODE_SHIFT))
+ ((x) & ((0x3U) << DRBG_MODE_SHIFT))
#define DRBG_SRC_SHIFT 2
#define DRBG_SRC_NONE \
- ((0UL) << DRBG_SRC_SHIFT)
+ ((0U) << DRBG_SRC_SHIFT)
#define DRBG_SRC_ENTROPY \
- ((1UL) << DRBG_SRC_SHIFT)
+ ((1U) << DRBG_SRC_SHIFT)
#define DRBG_SRC_LFSR \
- ((2UL) << DRBG_SRC_SHIFT)
+ ((2U) << DRBG_SRC_SHIFT)
#define SE_RNG_SRC_CONFIG_MODE(x) \
- ((x) & ((0x3UL) << DRBG_SRC_SHIFT))
+ ((x) & ((0x3U) << DRBG_SRC_SHIFT))
/* DRBG random number generator entropy config */
+
#define SE_RNG_SRC_CONFIG_REG_OFFSET 0x344U
-#define DRBG_RO_ENT_SRC_SHIFT 1
+#define DRBG_RO_ENT_SRC_SHIFT 1
#define DRBG_RO_ENT_SRC_ENABLE \
((1U) << DRBG_RO_ENT_SRC_SHIFT)
#define DRBG_RO_ENT_SRC_DISABLE \
@@ -114,7 +180,7 @@
#define SE_RNG_SRC_CONFIG_RO_ENT_SRC(x) \
((x) & ((0x1U) << DRBG_RO_ENT_SRC_SHIFT))
-#define DRBG_RO_ENT_SRC_LOCK_SHIFT 0
+#define DRBG_RO_ENT_SRC_LOCK_SHIFT 0
#define DRBG_RO_ENT_SRC_LOCK_ENABLE \
((1U) << DRBG_RO_ENT_SRC_LOCK_SHIFT)
#define DRBG_RO_ENT_SRC_LOCK_DISABLE \
@@ -130,9 +196,97 @@
#define SE_RNG_SRC_CONFIG_RO_ENT_IGNORE_MEM(x) \
((x) & ((0x1U) << DRBG_RO_ENT_IGNORE_MEM_SHIFT))
+#define SE_RNG_RESEED_INTERVAL_REG_OFFSET 0x348
+
+/* SE CRYPTO */
+#define SE_CRYPTO_REG_OFFSET 0x304
+#define SE_CRYPTO_HASH_SHIFT 0
+#define SE_CRYPTO_HASH_DISABLE \
+ ((0U) << SE_CRYPTO_HASH_SHIFT)
+#define SE_CRYPTO_HASH_ENABLE \
+ ((1U) << SE_CRYPTO_HASH_SHIFT)
+
+#define SE_CRYPTO_XOR_POS_SHIFT 1
+#define SE_CRYPTO_XOR_BYPASS \
+ ((0U) << SE_CRYPTO_XOR_POS_SHIFT)
+#define SE_CRYPTO_XOR_TOP \
+ ((2U) << SE_CRYPTO_XOR_POS_SHIFT)
+#define SE_CRYPTO_XOR_BOTTOM \
+ ((3U) << SE_CRYPTO_XOR_POS_SHIFT)
+
+#define SE_CRYPTO_INPUT_SEL_SHIFT 3
+#define SE_CRYPTO_INPUT_AHB \
+ ((0U) << SE_CRYPTO_INPUT_SEL_SHIFT)
+#define SE_CRYPTO_INPUT_RANDOM \
+ ((1U) << SE_CRYPTO_INPUT_SEL_SHIFT)
+#define SE_CRYPTO_INPUT_AESOUT \
+ ((2U) << SE_CRYPTO_INPUT_SEL_SHIFT)
+#define SE_CRYPTO_INPUT_LNR_CTR \
+ ((3U) << SE_CRYPTO_INPUT_SEL_SHIFT)
+
+#define SE_CRYPTO_VCTRAM_SEL_SHIFT 5
+#define SE_CRYPTO_VCTRAM_AHB \
+ ((0U) << SE_CRYPTO_VCTRAM_SEL_SHIFT)
+#define SE_CRYPTO_VCTRAM_AESOUT \
+ ((2U) << SE_CRYPTO_VCTRAM_SEL_SHIFT)
+#define SE_CRYPTO_VCTRAM_PREVAHB \
+ ((3U) << SE_CRYPTO_VCTRAM_SEL_SHIFT)
+
+#define SE_CRYPTO_IV_SEL_SHIFT 7
+#define SE_CRYPTO_IV_ORIGINAL \
+ ((0U) << SE_CRYPTO_IV_SEL_SHIFT)
+#define SE_CRYPTO_IV_UPDATED \
+ ((1U) << SE_CRYPTO_IV_SEL_SHIFT)
+
+#define SE_CRYPTO_CORE_SEL_SHIFT 8
+#define SE_CRYPTO_CORE_DECRYPT \
+ ((0U) << SE_CRYPTO_CORE_SEL_SHIFT)
+#define SE_CRYPTO_CORE_ENCRYPT \
+ ((1U) << SE_CRYPTO_CORE_SEL_SHIFT)
+
+#define SE_CRYPTO_KEY_INDEX_SHIFT 24
+#define SE_CRYPTO_KEY_INDEX(x) (x << SE_CRYPTO_KEY_INDEX_SHIFT)
+
+#define SE_CRYPTO_MEMIF_AHB \
+ ((0U) << SE_CRYPTO_MEMIF_SHIFT)
+#define SE_CRYPTO_MEMIF_MCCIF \
+ ((1U) << SE_CRYPTO_MEMIF_SHIFT)
+#define SE_CRYPTO_MEMIF_SHIFT 31
+
+/* KEY TABLE */
+#define SE_KEYTABLE_REG_OFFSET 0x31C
+
+/* KEYIV PKT - key slot */
+#define SE_KEYTABLE_SLOT_SHIFT 4
+#define SE_KEYTABLE_SLOT(x) (x << SE_KEYTABLE_SLOT_SHIFT)
+
+/* KEYIV PKT - KEYIV select */
+#define SE_KEYIV_PKT_KEYIV_SEL_SHIFT 3
+#define SE_CRYPTO_KEYIV_KEY \
+ ((0U) << SE_KEYIV_PKT_KEYIV_SEL_SHIFT)
+#define SE_CRYPTO_KEYIV_IVS \
+ ((1U) << SE_KEYIV_PKT_KEYIV_SEL_SHIFT)
+
+/* KEYIV PKT - IV select */
+#define SE_KEYIV_PKT_IV_SEL_SHIFT 2
+#define SE_CRYPTO_KEYIV_IVS_OIV \
+ ((0U) << SE_KEYIV_PKT_IV_SEL_SHIFT)
+#define SE_CRYPTO_KEYIV_IVS_UIV \
+ ((1U) << SE_KEYIV_PKT_IV_SEL_SHIFT)
+
+/* KEYIV PKT - key word */
+#define SE_KEYIV_PKT_KEY_WORD_SHIFT 0
+#define SE_KEYIV_PKT_KEY_WORD(x) \
+ ((x) << SE_KEYIV_PKT_KEY_WORD_SHIFT)
+
+/* KEYIV PKT - iv word */
+#define SE_KEYIV_PKT_IV_WORD_SHIFT 0
+#define SE_KEYIV_PKT_IV_WORD(x) \
+ ((x) << SE_KEYIV_PKT_IV_WORD_SHIFT)
+
/* SE OPERATION */
#define SE_OPERATION_REG_OFFSET 0x8U
-#define SE_OPERATION_SHIFT 0
+#define SE_OPERATION_SHIFT 0
#define SE_OP_ABORT \
((0x0U) << SE_OPERATION_SHIFT)
#define SE_OP_START \
@@ -146,11 +300,85 @@
#define SE_OPERATION(x) \
((x) & ((0x7U) << SE_OPERATION_SHIFT))
+/* SE CONTEXT */
+#define SE_CTX_SAVE_CONFIG_REG_OFFSET 0x70
+#define SE_CTX_SAVE_WORD_QUAD_SHIFT 0
+#define SE_CTX_SAVE_WORD_QUAD(x) \
+ (x << SE_CTX_SAVE_WORD_QUAD_SHIFT)
+#define SE_CTX_SAVE_WORD_QUAD_KEYS_0_3 \
+ ((0U) << SE_CTX_SAVE_WORD_QUAD_SHIFT)
+#define SE_CTX_SAVE_WORD_QUAD_KEYS_4_7 \
+ ((1U) << SE_CTX_SAVE_WORD_QUAD_SHIFT)
+#define SE_CTX_SAVE_WORD_QUAD_ORIG_IV \
+ ((2U) << SE_CTX_SAVE_WORD_QUAD_SHIFT)
+#define SE_CTX_SAVE_WORD_QUAD_UPD_IV \
+ ((3U) << SE_CTX_SAVE_WORD_QUAD_SHIFT)
+
+#define SE_CTX_SAVE_KEY_INDEX_SHIFT 8
+#define SE_CTX_SAVE_KEY_INDEX(x) (x << SE_CTX_SAVE_KEY_INDEX_SHIFT)
+
+#define SE_CTX_SAVE_STICKY_WORD_QUAD_SHIFT 24
+#define SE_CTX_SAVE_STICKY_WORD_QUAD_STICKY_0_3 \
+ ((0U) << SE_CTX_SAVE_STICKY_WORD_QUAD_SHIFT)
+#define SE_CTX_SAVE_STICKY_WORD_QUAD_STICKY_4_7 \
+ ((1U) << SE_CTX_SAVE_STICKY_WORD_QUAD_SHIFT)
+#define SE_CTX_SAVE_STICKY_WORD_QUAD(x) \
+ (x << SE_CTX_SAVE_STICKY_WORD_QUAD_SHIFT)
+
+#define SE_CTX_SAVE_SRC_SHIFT 29
+#define SE_CTX_SAVE_SRC_STICKY_BITS \
+ ((0U) << SE_CTX_SAVE_SRC_SHIFT)
+#define SE_CTX_SAVE_SRC_RSA_KEYTABLE \
+ ((1U) << SE_CTX_SAVE_SRC_SHIFT)
+#define SE_CTX_SAVE_SRC_AES_KEYTABLE \
+ ((2U) << SE_CTX_SAVE_SRC_SHIFT)
+#define SE_CTX_SAVE_SRC_PKA1_STICKY_BITS \
+ ((3U) << SE_CTX_SAVE_SRC_SHIFT)
+#define SE_CTX_SAVE_SRC_MEM \
+ ((4U) << SE_CTX_SAVE_SRC_SHIFT)
+#define SE_CTX_SAVE_SRC_SRK \
+ ((6U) << SE_CTX_SAVE_SRC_SHIFT)
+#define SE_CTX_SAVE_SRC_PKA1_KEYTABLE \
+ ((7U) << SE_CTX_SAVE_SRC_SHIFT)
+
+#define SE_CTX_STICKY_WORD_QUAD_SHIFT 24
+#define SE_CTX_STICKY_WORD_QUAD_WORDS_0_3 \
+ ((0U) << SE_CTX_STICKY_WORD_QUAD_SHIFT)
+#define SE_CTX_STICKY_WORD_QUAD_WORDS_4_7 \
+ ((1U) << SE_CTX_STICKY_WORD_QUAD_SHIFT)
+#define SE_CTX_STICKY_WORD_QUAD(x) (x << SE_CTX_STICKY_WORD_QUAD_SHIFT)
+
+#define SE_CTX_SAVE_RSA_KEY_INDEX_SHIFT 16
+#define SE_CTX_SAVE_RSA_KEY_INDEX(x) \
+ (x << SE_CTX_SAVE_RSA_KEY_INDEX_SHIFT)
+
+#define SE_CTX_RSA_WORD_QUAD_SHIFT 12
+#define SE_CTX_RSA_WORD_QUAD(x) \
+ (x << SE_CTX_RSA_WORD_QUAD_SHIFT)
+
+#define SE_CTX_PKA1_WORD_QUAD_L_SHIFT 0
+#define SE_CTX_PKA1_WORD_QUAD_L_SIZE \
+ ((true ? 4:0) - \
+ (false ? 4:0) + 1)
+#define SE_CTX_PKA1_WORD_QUAD_L(x)\
+ (((x) << SE_CTX_PKA1_WORD_QUAD_L_SHIFT) & 0x1f)
+
+#define SE_CTX_PKA1_WORD_QUAD_H_SHIFT 12
+#define SE_CTX_PKA1_WORD_QUAD_H(x)\
+ ((((x) >> SE_CTX_PKA1_WORD_QUAD_L_SIZE) & 0xf) \
+ << SE_CTX_PKA1_WORD_QUAD_H_SHIFT)
+
+#define SE_RSA_KEY_INDEX_SLOT0_EXP 0
+#define SE_RSA_KEY_INDEX_SLOT0_MOD 1
+#define SE_RSA_KEY_INDEX_SLOT1_EXP 2
+#define SE_RSA_KEY_INDEX_SLOT1_MOD 3
+
+
/* SE_CTX_SAVE_AUTO */
#define SE_CTX_SAVE_AUTO_REG_OFFSET 0x74U
/* Enable */
-#define SE_CTX_SAVE_AUTO_ENABLE_SHIFT 0
+#define SE_CTX_SAVE_AUTO_ENABLE_SHIFT 0
#define SE_CTX_SAVE_AUTO_DIS \
((0U) << SE_CTX_SAVE_AUTO_ENABLE_SHIFT)
#define SE_CTX_SAVE_AUTO_EN \
@@ -167,20 +395,22 @@
#define SE_CTX_SAVE_AUTO_LOCK(x) \
((x) & ((0x1U) << SE_CTX_SAVE_AUTO_LOCK_SHIFT))
-/* Current context save number of blocks */
+/* Current context save number of blocks*/
#define SE_CTX_SAVE_AUTO_CURR_CNT_SHIFT 16
#define SE_CTX_SAVE_AUTO_CURR_CNT_MASK 0x3FFU
#define SE_CTX_SAVE_GET_BLK_COUNT(x) \
(((x) >> SE_CTX_SAVE_AUTO_CURR_CNT_SHIFT) & \
SE_CTX_SAVE_AUTO_CURR_CNT_MASK)
-#define SE_CTX_SAVE_SIZE_BLOCKS_SE1 133
-#define SE_CTX_SAVE_SIZE_BLOCKS_SE2 646
+#define SE_CTX_SAVE_SIZE_BLOCKS_SE1 133
+#define SE_CTX_SAVE_SIZE_BLOCKS_SE2 646
/* SE TZRAM OPERATION - only for SE1 */
-#define SE_TZRAM_OPERATION 0x540U
+#define SE_TZRAM_OPERATION 0x540U
-#define SE_TZRAM_OP_MODE_SHIFT 1
+#define SE_TZRAM_OP_MODE_SHIFT 1
+#define SE_TZRAM_OP_COMMAND_INIT 1
+#define SE_TZRAM_OP_COMMAND_SHIFT 0
#define SE_TZRAM_OP_MODE_SAVE \
((0U) << SE_TZRAM_OP_MODE_SHIFT)
#define SE_TZRAM_OP_MODE_RESTORE \
@@ -188,7 +418,7 @@
#define SE_TZRAM_OP_MODE(x) \
((x) & ((0x1U) << SE_TZRAM_OP_MODE_SHIFT))
-#define SE_TZRAM_OP_BUSY_SHIFT 2
+#define SE_TZRAM_OP_BUSY_SHIFT 2
#define SE_TZRAM_OP_BUSY_OFF \
((0U) << SE_TZRAM_OP_BUSY_SHIFT)
#define SE_TZRAM_OP_BUSY_ON \
@@ -196,7 +426,7 @@
#define SE_TZRAM_OP_BUSY(x) \
((x) & ((0x1U) << SE_TZRAM_OP_BUSY_SHIFT))
-#define SE_TZRAM_OP_REQ_SHIFT 0
+#define SE_TZRAM_OP_REQ_SHIFT 0
#define SE_TZRAM_OP_REQ_IDLE \
((0U) << SE_TZRAM_OP_REQ_SHIFT)
#define SE_TZRAM_OP_REQ_INIT \
@@ -206,7 +436,7 @@
/* SE Interrupt */
#define SE_INT_STATUS_REG_OFFSET 0x10U
-#define SE_INT_OP_DONE_SHIFT 4
+#define SE_INT_OP_DONE_SHIFT 4
#define SE_INT_OP_DONE_CLEAR \
((0U) << SE_INT_OP_DONE_SHIFT)
#define SE_INT_OP_DONE_ACTIVE \
@@ -214,19 +444,186 @@
#define SE_INT_OP_DONE(x) \
((x) & ((0x1U) << SE_INT_OP_DONE_SHIFT))
+/* SE TZRAM SECURITY */
+#define SE_TZRAM_SEC_REG_OFFSET 0x4
+
+#define SE_TZRAM_SEC_SETTING_SHIFT 0
+#define SE_TZRAM_SECURE \
+ ((0UL) << SE_TZRAM_SEC_SETTING_SHIFT)
+#define SE_TZRAM_NONSECURE \
+ ((1UL) << SE_TZRAM_SEC_SETTING_SHIFT)
+#define SE_TZRAM_SEC_SETTING(x) \
+ ((x) & ((0x1UL) << SE_TZRAM_SEC_SETTING_SHIFT))
+
+/* PKA1 KEY SLOTS */
+#define TEGRA_SE_PKA1_KEYSLOT_COUNT 4
+
+
/* SE error status */
#define SE_ERR_STATUS_REG_OFFSET 0x804U
+#define SE_CRYPTO_KEYTABLE_DST_REG_OFFSET 0x330
+#define SE_CRYPTO_KEYTABLE_DST_WORD_QUAD_SHIFT 0
+#define SE_CRYPTO_KEYTABLE_DST_WORD_QUAD(x) \
+ (x << SE_CRYPTO_KEYTABLE_DST_WORD_QUAD_SHIFT)
+
+#define SE_KEY_INDEX_SHIFT 8
+#define SE_CRYPTO_KEYTABLE_DST_KEY_INDEX(x) (x << SE_KEY_INDEX_SHIFT)
+
/* SE linked list (LL) register */
#define SE_IN_LL_ADDR_REG_OFFSET 0x18U
-#define SE_OUT_LL_ADDR_REG_OFFSET 0x24U
-#define SE_BLOCK_COUNT_REG_OFFSET 0x318U
+#define SE_OUT_LL_ADDR_REG_OFFSET 0x24U
+#define SE_BLOCK_COUNT_REG_OFFSET 0x318U
/* AES data sizes */
+#define TEGRA_SE_KEY_256_SIZE 32
+#define TEGRA_SE_KEY_192_SIZE 24
+#define TEGRA_SE_KEY_128_SIZE 16
#define TEGRA_SE_AES_BLOCK_SIZE 16
-#define TEGRA_SE_AES_MIN_KEY_SIZE 16
-#define TEGRA_SE_AES_MAX_KEY_SIZE 32
-#define TEGRA_SE_AES_IV_SIZE 16
+#define TEGRA_SE_AES_MIN_KEY_SIZE 16
+#define TEGRA_SE_AES_MAX_KEY_SIZE 32
+#define TEGRA_SE_AES_IV_SIZE 16
+
+#define TEGRA_SE_RNG_IV_SIZE 16
+#define TEGRA_SE_RNG_DT_SIZE 16
+#define TEGRA_SE_RNG_KEY_SIZE 16
+#define TEGRA_SE_RNG_SEED_SIZE (TEGRA_SE_RNG_IV_SIZE + \
+ TEGRA_SE_RNG_KEY_SIZE + \
+ TEGRA_SE_RNG_DT_SIZE)
+#define TEGRA_SE_RSA512_DIGEST_SIZE 64
+#define TEGRA_SE_RSA1024_DIGEST_SIZE 128
+#define TEGRA_SE_RSA1536_DIGEST_SIZE 192
+#define TEGRA_SE_RSA2048_DIGEST_SIZE 256
+
+#define SE_KEY_TABLE_ACCESS_REG_OFFSET 0x284
+#define SE_KEY_READ_DISABLE_SHIFT 0
+
+#define SE_CTX_BUFER_SIZE 1072
+#define SE_CTX_DRBG_BUFER_SIZE 2112
+
+/* SE blobs size in bytes */
+#define SE_CTX_SAVE_RSA_KEY_LENGTH 1024
+#define SE_CTX_SAVE_RANDOM_DATA_SIZE 16
+#define SE_CTX_SAVE_STICKY_BITS_SIZE 16
+#define SE2_CONTEXT_SAVE_PKA1_STICKY_BITS_LENGTH 16
+#define SE2_CONTEXT_SAVE_PKA1_KEYS_LENGTH 8192
+#define SE_CTX_KNOWN_PATTERN_SIZE 16
+#define SE_CTX_KNOWN_PATTERN_SIZE_WORDS (SE_CTX_KNOWN_PATTERN_SIZE/4)
+
+/* SE RSA */
+#define TEGRA_SE_RSA_KEYSLOT_COUNT 2
+#define SE_RSA_KEY_SIZE_REG_OFFSET 0x404
+#define SE_RSA_EXP_SIZE_REG_OFFSET 0x408
+#define SE_RSA_MAX_EXP_BIT_SIZE 2048
+#define SE_RSA_MAX_EXP_SIZE32 \
+ (SE_RSA_MAX_EXP_BIT_SIZE >> 5)
+#define SE_RSA_MAX_MOD_BIT_SIZE 2048
+#define SE_RSA_MAX_MOD_SIZE32 \
+ (SE_RSA_MAX_MOD_BIT_SIZE >> 5)
+
+/* SE_RSA_KEYTABLE_ADDR */
+#define SE_RSA_KEYTABLE_ADDR 0x420
+#define RSA_KEY_PKT_WORD_ADDR_SHIFT 0
+#define RSA_KEY_PKT_EXPMOD_SEL_SHIFT \
+ ((6U) << RSA_KEY_PKT_WORD_ADDR_SHIFT)
+#define RSA_KEY_MOD \
+ ((1U) << RSA_KEY_PKT_EXPMOD_SEL_SHIFT)
+#define RSA_KEY_EXP \
+ ((0U) << RSA_KEY_PKT_EXPMOD_SEL_SHIFT)
+#define RSA_KEY_PKT_SLOT_SHIFT 7
+#define RSA_KEY_SLOT_1 \
+ ((0U) << RSA_KEY_PKT_SLOT_SHIFT)
+#define RSA_KEY_SLOT_2 \
+ ((1U) << RSA_KEY_PKT_SLOT_SHIFT)
+#define RSA_KEY_PKT_INPUT_MODE_SHIFT 8
+#define RSA_KEY_REG_INPUT \
+ ((0U) << RSA_KEY_PKT_INPUT_MODE_SHIFT)
+#define RSA_KEY_DMA_INPUT \
+ ((1U) << RSA_KEY_PKT_INPUT_MODE_SHIFT)
+
+/* SE_RSA_KEYTABLE_DATA */
+#define SE_RSA_KEYTABLE_DATA 0x424
+
+/* SE_RSA_CONFIG register */
+#define SE_RSA_CONFIG 0x400
+#define RSA_KEY_SLOT_SHIFT 24
+#define RSA_KEY_SLOT(x) \
+ ((x) << RSA_KEY_SLOT_SHIFT)
+
+/*******************************************************************************
+ * Structure definition
+ ******************************************************************************/
+
+/* SE context blob */
+#pragma pack(push, 1)
+typedef struct tegra_aes_key_slot {
+ /* 0 - 7 AES key */
+ uint32_t key[8];
+ /* 8 - 11 Original IV */
+ uint32_t oiv[4];
+ /* 12 - 15 Updated IV */
+ uint32_t uiv[4];
+} tegra_se_aes_key_slot_t;
+#pragma pack(pop)
+
+#pragma pack(push, 1)
+typedef struct tegra_se_context {
+ /* random number */
+ unsigned char rand_data[SE_CTX_SAVE_RANDOM_DATA_SIZE];
+ /* Sticky bits */
+ unsigned char sticky_bits[SE_CTX_SAVE_STICKY_BITS_SIZE * 2];
+ /* AES key slots */
+ tegra_se_aes_key_slot_t key_slots[TEGRA_SE_AES_KEYSLOT_COUNT];
+ /* RSA key slots */
+ unsigned char rsa_keys[SE_CTX_SAVE_RSA_KEY_LENGTH];
+} tegra_se_context_t;
+#pragma pack(pop)
+
+/* PKA context blob */
+#pragma pack(push, 1)
+typedef struct tegra_pka_context {
+ unsigned char sticky_bits[SE2_CONTEXT_SAVE_PKA1_STICKY_BITS_LENGTH];
+ unsigned char pka_keys[SE2_CONTEXT_SAVE_PKA1_KEYS_LENGTH];
+} tegra_pka_context_t;
+#pragma pack(pop)
+
+/* SE context blob */
+#pragma pack(push, 1)
+typedef struct tegra_se_context_blob {
+ /* SE context */
+ tegra_se_context_t se_ctx;
+ /* Known Pattern */
+ unsigned char known_pattern[SE_CTX_KNOWN_PATTERN_SIZE];
+} tegra_se_context_blob_t;
+#pragma pack(pop)
+
+/* SE2 and PKA1 context blob */
+#pragma pack(push, 1)
+typedef struct tegra_se2_context_blob {
+ /* SE2 context */
+ tegra_se_context_t se_ctx;
+ /* PKA1 context */
+ tegra_pka_context_t pka_ctx;
+ /* Known Pattern */
+ unsigned char known_pattern[SE_CTX_KNOWN_PATTERN_SIZE];
+} tegra_se2_context_blob_t;
+#pragma pack(pop)
+
+/* SE AES key type 128bit, 192bit, 256bit */
+typedef enum {
+ SE_AES_KEY128,
+ SE_AES_KEY192,
+ SE_AES_KEY256,
+} tegra_se_aes_key_type_t;
+
+/* SE RSA key slot */
+typedef struct tegra_se_rsa_key_slot {
+ /* 0 - 63 exponent key */
+ uint32_t exponent[SE_RSA_MAX_EXP_SIZE32];
+ /* 64 - 127 modulus key */
+ uint32_t modulus[SE_RSA_MAX_MOD_SIZE32];
+} tegra_se_rsa_key_slot_t;
+
/*******************************************************************************
* Inline functions definition
@@ -242,8 +639,21 @@
mmio_write_32(dev->se_base + offset, val);
}
+static inline uint32_t tegra_pka_read_32(tegra_pka_dev_t *dev, uint32_t offset)
+{
+ return mmio_read_32(dev->pka_base + offset);
+}
+
+static inline void tegra_pka_write_32(tegra_pka_dev_t *dev, uint32_t offset,
+uint32_t val)
+{
+ mmio_write_32(dev->pka_base + offset, val);
+}
+
/*******************************************************************************
* Prototypes
******************************************************************************/
+int tegra_se_start_normal_operation(const tegra_se_dev_t *, uint32_t);
+int tegra_se_start_ctx_save_operation(const tegra_se_dev_t *, uint32_t);
#endif /* SE_PRIVATE_H */
diff --git a/plat/nvidia/tegra/soc/t210/drivers/se/security_engine.c b/plat/nvidia/tegra/soc/t210/drivers/se/security_engine.c
index fa99db6..e0a0d6c 100644
--- a/plat/nvidia/tegra/soc/t210/drivers/se/security_engine.c
+++ b/plat/nvidia/tegra/soc/t210/drivers/se/security_engine.c
@@ -20,7 +20,8 @@
* Constants and Macros
******************************************************************************/
-#define TIMEOUT_100MS 100UL // Timeout in 100ms
+#define TIMEOUT_100MS 100U // Timeout in 100ms
+#define RNG_AES_KEY_INDEX 1
/*******************************************************************************
* Data structure and global variables
@@ -67,6 +68,15 @@
* #--------------------------------#
*/
+/* Known pattern data */
+static const uint32_t se_ctx_known_pattern_data[SE_CTX_KNOWN_PATTERN_SIZE_WORDS] = {
+ /* 128 bit AES block */
+ 0x0C0D0E0F,
+ 0x08090A0B,
+ 0x04050607,
+ 0x00010203,
+};
+
/* SE input and output linked list buffers */
static tegra_se_io_lst_t se1_src_ll_buf;
static tegra_se_io_lst_t se1_dst_ll_buf;
@@ -78,7 +88,7 @@
/* SE1 security engine device handle */
static tegra_se_dev_t se_dev_1 = {
.se_num = 1,
- /* setup base address for se */
+ /* Setup base address for se */
.se_base = TEGRA_SE1_BASE,
/* Setup context size in AES blocks */
.ctx_size_blks = SE_CTX_SAVE_SIZE_BLOCKS_SE1,
@@ -86,12 +96,14 @@
.src_ll_buf = &se1_src_ll_buf,
/* Setup DST buffers for SE operations */
.dst_ll_buf = &se1_dst_ll_buf,
+ /* Setup context save destination */
+ .ctx_save_buf = (uint32_t *)(TEGRA_TZRAM_CARVEOUT_BASE),
};
/* SE2 security engine device handle */
static tegra_se_dev_t se_dev_2 = {
.se_num = 2,
- /* setup base address for se */
+ /* Setup base address for se */
.se_base = TEGRA_SE2_BASE,
/* Setup context size in AES blocks */
.ctx_size_blks = SE_CTX_SAVE_SIZE_BLOCKS_SE2,
@@ -99,8 +111,12 @@
.src_ll_buf = &se2_src_ll_buf,
/* Setup DST buffers for SE operations */
.dst_ll_buf = &se2_dst_ll_buf,
+ /* Setup context save destination */
+ .ctx_save_buf = (uint32_t *)(TEGRA_TZRAM_CARVEOUT_BASE + 0x1000),
};
+static bool ecid_valid;
+
/*******************************************************************************
* Functions Definition
******************************************************************************/
@@ -186,35 +202,15 @@
}
/*
- * Verify the SE context save auto has been enabled.
- * SE_CTX_SAVE_AUTO.ENABLE == ENABLE
- * If the SE context save auto is not enabled, then set
- * the context save auto enable and lock the setting.
- * If the SE context save auto is not enabled and the
- * enable setting is locked, then return an error.
+ * Returns true if the SE engine is configured to perform SE context save in
+ * hardware.
*/
-static inline int32_t tegra_se_ctx_save_auto_enable(const tegra_se_dev_t *se_dev)
+static inline bool tegra_se_atomic_save_enabled(const tegra_se_dev_t *se_dev)
{
uint32_t val;
- int32_t ret = 0;
val = tegra_se_read_32(se_dev, SE_CTX_SAVE_AUTO_REG_OFFSET);
- if (SE_CTX_SAVE_AUTO_ENABLE(val) == SE_CTX_SAVE_AUTO_DIS) {
- if (SE_CTX_SAVE_AUTO_LOCK(val) == SE_CTX_SAVE_AUTO_LOCK_EN) {
- ERROR("%s: ERR: Cannot enable atomic. Write locked!\n",
- __func__);
- ret = -EACCES;
- }
-
- /* Program SE_CTX_SAVE_AUTO */
- if (ret == 0) {
- tegra_se_write_32(se_dev, SE_CTX_SAVE_AUTO_REG_OFFSET,
- SE_CTX_SAVE_AUTO_LOCK_EN |
- SE_CTX_SAVE_AUTO_EN);
- }
- }
-
- return ret;
+ return (SE_CTX_SAVE_AUTO_ENABLE(val) == SE_CTX_SAVE_AUTO_EN);
}
/*
@@ -259,14 +255,6 @@
/* Check that previous operation is finalized */
ret = tegra_se_operation_prepare(se_dev);
- /* Ensure HW atomic context save has been enabled
- * This should have been done at boot time.
- * SE_CTX_SAVE_AUTO.ENABLE == ENABLE
- */
- if (ret == 0) {
- ret = tegra_se_ctx_save_auto_enable(se_dev);
- }
-
/* Read the context save progress counter: block_count
* Ensure no previous context save has been triggered
* SE_CTX_SAVE_AUTO.CURR_CNT == 0
@@ -325,7 +313,8 @@
* Security engine primitive operations, including normal operation
* and the context save operation.
*/
-static int tegra_se_perform_operation(const tegra_se_dev_t *se_dev, uint32_t nbytes)
+static int tegra_se_perform_operation(const tegra_se_dev_t *se_dev, uint32_t nbytes,
+ bool context_save)
{
uint32_t nblocks = nbytes / TEGRA_SE_AES_BLOCK_SIZE;
int ret = 0;
@@ -351,7 +340,10 @@
tegra_se_make_data_coherent(se_dev);
/* Start hardware operation */
- tegra_se_write_32(se_dev, SE_OPERATION_REG_OFFSET, SE_OP_START);
+ if (context_save)
+ tegra_se_write_32(se_dev, SE_OPERATION_REG_OFFSET, SE_OP_CTX_SAVE);
+ else
+ tegra_se_write_32(se_dev, SE_OPERATION_REG_OFFSET, SE_OP_START);
/* Wait for operation to finish */
ret = tegra_se_operation_complete(se_dev);
@@ -361,6 +353,22 @@
}
/*
+ * Normal security engine operations other than the context save
+ */
+int tegra_se_start_normal_operation(const tegra_se_dev_t *se_dev, uint32_t nbytes)
+{
+ return tegra_se_perform_operation(se_dev, nbytes, false);
+}
+
+/*
+ * Security engine context save operation
+ */
+int tegra_se_start_ctx_save_operation(const tegra_se_dev_t *se_dev, uint32_t nbytes)
+{
+ return tegra_se_perform_operation(se_dev, nbytes, true);
+}
+
+/*
* Security Engine sequence to generat SRK
* SE and SE2 will generate different SRK by different
* entropy seeds.
@@ -381,7 +389,10 @@
se_dev->dst_ll_buf->last_buff_num = 0;
/* Configure random number generator */
- val = (DRBG_MODE_FORCE_RESEED | DRBG_SRC_ENTROPY);
+ if (ecid_valid)
+ val = (DRBG_MODE_FORCE_INSTANTION | DRBG_SRC_ENTROPY);
+ else
+ val = (DRBG_MODE_FORCE_RESEED | DRBG_SRC_ENTROPY);
tegra_se_write_32(se_dev, SE_RNG_CONFIG_REG_OFFSET, val);
/* Configure output destination = SRK */
@@ -391,25 +402,562 @@
tegra_se_write_32(se_dev, SE_CONFIG_REG_OFFSET, val);
/* Perform hardware operation */
- ret = tegra_se_perform_operation(se_dev, 0);
+ ret = tegra_se_start_normal_operation(se_dev, 0);
return ret;
}
/*
+ * Generate plain text random data to some memory location using
+ * SE/SE2's SP800-90 random number generator. The random data size
+ * must be some multiple of the AES block size (16 bytes).
+ */
+static int tegra_se_lp_generate_random_data(tegra_se_dev_t *se_dev)
+{
+ int ret = 0;
+ uint32_t val;
+
+ /* Set some arbitrary memory location to store the random data */
+ se_dev->dst_ll_buf->last_buff_num = 0;
+ if (!se_dev->ctx_save_buf) {
+ ERROR("%s: ERR: context save buffer NULL pointer!\n", __func__);
+ return PSCI_E_NOT_PRESENT;
+ }
+ se_dev->dst_ll_buf->buffer[0].addr = ((uint64_t)(&(((tegra_se_context_t *)
+ se_dev->ctx_save_buf)->rand_data)));
+ se_dev->dst_ll_buf->buffer[0].data_len = SE_CTX_SAVE_RANDOM_DATA_SIZE;
+
+
+ /* Confgure the following hardware register settings:
+ * SE_CONFIG.DEC_ALG = NOP
+ * SE_CONFIG.ENC_ALG = RNG
+ * SE_CONFIG.ENC_MODE = KEY192
+ * SE_CONFIG.DST = MEMORY
+ */
+ val = (SE_CONFIG_ENC_ALG_RNG |
+ SE_CONFIG_DEC_ALG_NOP |
+ SE_CONFIG_ENC_MODE_KEY192 |
+ SE_CONFIG_DST_MEMORY);
+ tegra_se_write_32(se_dev, SE_CONFIG_REG_OFFSET, val);
+
+ /* Program the RNG options in SE_CRYPTO_CONFIG as follows:
+ * XOR_POS = BYPASS
+ * INPUT_SEL = RANDOM (Entropy or LFSR)
+ * HASH_ENB = DISABLE
+ */
+ val = (SE_CRYPTO_INPUT_RANDOM |
+ SE_CRYPTO_XOR_BYPASS |
+ SE_CRYPTO_CORE_ENCRYPT |
+ SE_CRYPTO_HASH_DISABLE |
+ SE_CRYPTO_KEY_INDEX(RNG_AES_KEY_INDEX) |
+ SE_CRYPTO_IV_ORIGINAL);
+ tegra_se_write_32(se_dev, SE_CRYPTO_REG_OFFSET, val);
+
+ /* Configure RNG */
+ if (ecid_valid)
+ val = (DRBG_MODE_FORCE_INSTANTION | DRBG_SRC_LFSR);
+ else
+ val = (DRBG_MODE_FORCE_RESEED | DRBG_SRC_LFSR);
+ tegra_se_write_32(se_dev, SE_RNG_CONFIG_REG_OFFSET, val);
+
+ /* SE normal operation */
+ ret = tegra_se_start_normal_operation(se_dev, SE_CTX_SAVE_RANDOM_DATA_SIZE);
+
+ return ret;
+}
+
+/*
+ * Encrypt memory blocks with SRK as part of the security engine context.
+ * The data blocks include: random data and the known pattern data, where
+ * the random data is the first block and known pattern is the last block.
+ */
+static int tegra_se_lp_data_context_save(tegra_se_dev_t *se_dev,
+ uint64_t src_addr, uint64_t dst_addr, uint32_t data_size)
+{
+ int ret = 0;
+
+ se_dev->src_ll_buf->last_buff_num = 0;
+ se_dev->dst_ll_buf->last_buff_num = 0;
+ se_dev->src_ll_buf->buffer[0].addr = src_addr;
+ se_dev->src_ll_buf->buffer[0].data_len = data_size;
+ se_dev->dst_ll_buf->buffer[0].addr = dst_addr;
+ se_dev->dst_ll_buf->buffer[0].data_len = data_size;
+
+ /* By setting the context source from memory and calling the context save
+ * operation, the SE encrypts the memory data with SRK.
+ */
+ tegra_se_write_32(se_dev, SE_CTX_SAVE_CONFIG_REG_OFFSET, SE_CTX_SAVE_SRC_MEM);
+
+ ret = tegra_se_start_ctx_save_operation(se_dev, data_size);
+
+ return ret;
+}
+
+/*
+ * Context save the key table access control sticky bits and
+ * security status of each key-slot. The encrypted sticky-bits are
+ * 32 bytes (2 AES blocks) and formatted as the following structure:
+ * { bit in registers bit in context save
+ * SECURITY_0[4] 158
+ * SE_RSA_KEYTABLE_ACCE4SS_1[2:0] 157:155
+ * SE_RSA_KEYTABLE_ACCE4SS_0[2:0] 154:152
+ * SE_RSA_SECURITY_PERKEY_0[1:0] 151:150
+ * SE_CRYPTO_KEYTABLE_ACCESS_15[7:0] 149:142
+ * ...,
+ * SE_CRYPTO_KEYTABLE_ACCESS_0[7:0] 29:22
+ * SE_CRYPTO_SECURITY_PERKEY_0[15:0] 21:6
+ * SE_TZRAM_SECURITY_0[1:0] 5:4
+ * SE_SECURITY_0[16] 3:3
+ * SE_SECURITY_0[2:0] } 2:0
+ */
+static int tegra_se_lp_sticky_bits_context_save(tegra_se_dev_t *se_dev)
+{
+ int ret = PSCI_E_INTERN_FAIL;
+ uint32_t val = 0;
+
+ se_dev->dst_ll_buf->last_buff_num = 0;
+ if (!se_dev->ctx_save_buf) {
+ ERROR("%s: ERR: context save buffer NULL pointer!\n", __func__);
+ return PSCI_E_NOT_PRESENT;
+ }
+ se_dev->dst_ll_buf->buffer[0].addr = ((uint64_t)(&(((tegra_se_context_t *)
+ se_dev->ctx_save_buf)->sticky_bits)));
+ se_dev->dst_ll_buf->buffer[0].data_len = SE_CTX_SAVE_STICKY_BITS_SIZE;
+
+ /*
+ * The 1st AES block save the sticky-bits context 1 - 16 bytes (0 - 3 words).
+ * The 2nd AES block save the sticky-bits context 17 - 32 bytes (4 - 7 words).
+ */
+ for (int i = 0; i < 2; i++) {
+ val = SE_CTX_SAVE_SRC_STICKY_BITS |
+ SE_CTX_SAVE_STICKY_WORD_QUAD(i);
+ tegra_se_write_32(se_dev, SE_CTX_SAVE_CONFIG_REG_OFFSET, val);
+
+ /* SE context save operation */
+ ret = tegra_se_start_ctx_save_operation(se_dev,
+ SE_CTX_SAVE_STICKY_BITS_SIZE);
+ if (ret)
+ break;
+ se_dev->dst_ll_buf->buffer[0].addr += SE_CTX_SAVE_STICKY_BITS_SIZE;
+ }
+
+ return ret;
+}
+
+static int tegra_se_aeskeytable_context_save(tegra_se_dev_t *se_dev)
+{
+ uint32_t val = 0;
+ int ret = 0;
+
+ se_dev->dst_ll_buf->last_buff_num = 0;
+ if (!se_dev->ctx_save_buf) {
+ ERROR("%s: ERR: context save buffer NULL pointer!\n", __func__);
+ ret = -EINVAL;
+ goto aes_keytable_save_err;
+ }
+
+ /* AES key context save */
+ for (int slot = 0; slot < TEGRA_SE_AES_KEYSLOT_COUNT; slot++) {
+ se_dev->dst_ll_buf->buffer[0].addr = ((uint64_t)(&(
+ ((tegra_se_context_t *)se_dev->
+ ctx_save_buf)->key_slots[slot].key)));
+ se_dev->dst_ll_buf->buffer[0].data_len = TEGRA_SE_KEY_128_SIZE;
+ for (int i = 0; i < 2; i++) {
+ val = SE_CTX_SAVE_SRC_AES_KEYTABLE |
+ SE_CTX_SAVE_KEY_INDEX(slot) |
+ SE_CTX_SAVE_WORD_QUAD(i);
+ tegra_se_write_32(se_dev, SE_CTX_SAVE_CONFIG_REG_OFFSET, val);
+
+ /* SE context save operation */
+ ret = tegra_se_start_ctx_save_operation(se_dev,
+ TEGRA_SE_KEY_128_SIZE);
+ if (ret) {
+ ERROR("%s: ERR: AES key CTX_SAVE OP failed, "
+ "slot=%d, word_quad=%d.\n",
+ __func__, slot, i);
+ goto aes_keytable_save_err;
+ }
+ se_dev->dst_ll_buf->buffer[0].addr += TEGRA_SE_KEY_128_SIZE;
+ }
+
+ /* OIV context save */
+ se_dev->dst_ll_buf->last_buff_num = 0;
+ se_dev->dst_ll_buf->buffer[0].addr = ((uint64_t)(&(
+ ((tegra_se_context_t *)se_dev->
+ ctx_save_buf)->key_slots[slot].oiv)));
+ se_dev->dst_ll_buf->buffer[0].data_len = TEGRA_SE_AES_IV_SIZE;
+
+ val = SE_CTX_SAVE_SRC_AES_KEYTABLE |
+ SE_CTX_SAVE_KEY_INDEX(slot) |
+ SE_CTX_SAVE_WORD_QUAD_ORIG_IV;
+ tegra_se_write_32(se_dev, SE_CTX_SAVE_CONFIG_REG_OFFSET, val);
+
+ /* SE context save operation */
+ ret = tegra_se_start_ctx_save_operation(se_dev, TEGRA_SE_AES_IV_SIZE);
+ if (ret) {
+ ERROR("%s: ERR: OIV CTX_SAVE OP failed, slot=%d.\n",
+ __func__, slot);
+ goto aes_keytable_save_err;
+ }
+
+ /* UIV context save */
+ se_dev->dst_ll_buf->last_buff_num = 0;
+ se_dev->dst_ll_buf->buffer[0].addr = ((uint64_t)(&(
+ ((tegra_se_context_t *)se_dev->
+ ctx_save_buf)->key_slots[slot].uiv)));
+ se_dev->dst_ll_buf->buffer[0].data_len = TEGRA_SE_AES_IV_SIZE;
+
+ val = SE_CTX_SAVE_SRC_AES_KEYTABLE |
+ SE_CTX_SAVE_KEY_INDEX(slot) |
+ SE_CTX_SAVE_WORD_QUAD_UPD_IV;
+ tegra_se_write_32(se_dev, SE_CTX_SAVE_CONFIG_REG_OFFSET, val);
+
+ /* SE context save operation */
+ ret = tegra_se_start_ctx_save_operation(se_dev, TEGRA_SE_AES_IV_SIZE);
+ if (ret) {
+ ERROR("%s: ERR: UIV CTX_SAVE OP failed, slot=%d\n",
+ __func__, slot);
+ goto aes_keytable_save_err;
+ }
+ }
+
+aes_keytable_save_err:
+ return ret;
+}
+
+static int tegra_se_lp_rsakeytable_context_save(tegra_se_dev_t *se_dev)
+{
+ uint32_t val = 0;
+ int ret = 0;
+ /* First the modulus and then the exponent must be
+ * encrypted and saved. This is repeated for SLOT 0
+ * and SLOT 1. Hence the order:
+ * SLOT 0 exponent : RSA_KEY_INDEX : 0
+ * SLOT 0 modulus : RSA_KEY_INDEX : 1
+ * SLOT 1 exponent : RSA_KEY_INDEX : 2
+ * SLOT 1 modulus : RSA_KEY_INDEX : 3
+ */
+ const unsigned int key_index_mod[TEGRA_SE_RSA_KEYSLOT_COUNT][2] = {
+ /* RSA key slot 0 */
+ {SE_RSA_KEY_INDEX_SLOT0_EXP, SE_RSA_KEY_INDEX_SLOT0_MOD},
+ /* RSA key slot 1 */
+ {SE_RSA_KEY_INDEX_SLOT1_EXP, SE_RSA_KEY_INDEX_SLOT1_MOD},
+ };
+
+ se_dev->dst_ll_buf->last_buff_num = 0;
+ se_dev->dst_ll_buf->buffer[0].addr = ((uint64_t)(&(
+ ((tegra_se_context_t *)se_dev->
+ ctx_save_buf)->rsa_keys)));
+ se_dev->dst_ll_buf->buffer[0].data_len = TEGRA_SE_KEY_128_SIZE;
+
+ for (int slot = 0; slot < TEGRA_SE_RSA_KEYSLOT_COUNT; slot++) {
+ /* loop for modulus and exponent */
+ for (int index = 0; index < 2; index++) {
+ for (int word_quad = 0; word_quad < 16; word_quad++) {
+ val = SE_CTX_SAVE_SRC_RSA_KEYTABLE |
+ SE_CTX_SAVE_RSA_KEY_INDEX(
+ key_index_mod[slot][index]) |
+ SE_CTX_RSA_WORD_QUAD(word_quad);
+ tegra_se_write_32(se_dev,
+ SE_CTX_SAVE_CONFIG_REG_OFFSET, val);
+
+ /* SE context save operation */
+ ret = tegra_se_start_ctx_save_operation(se_dev,
+ TEGRA_SE_KEY_128_SIZE);
+ if (ret) {
+ ERROR("%s: ERR: slot=%d.\n",
+ __func__, slot);
+ goto rsa_keytable_save_err;
+ }
+
+ /* Update the pointer to the next word quad */
+ se_dev->dst_ll_buf->buffer[0].addr +=
+ TEGRA_SE_KEY_128_SIZE;
+ }
+ }
+ }
+
+rsa_keytable_save_err:
+ return ret;
+}
+
+static int tegra_se_pkakeytable_sticky_bits_save(tegra_se_dev_t *se_dev)
+{
+ int ret = 0;
+
+ se_dev->dst_ll_buf->last_buff_num = 0;
+ se_dev->dst_ll_buf->buffer[0].addr = ((uint64_t)(&(
+ ((tegra_se2_context_blob_t *)se_dev->
+ ctx_save_buf)->pka_ctx.sticky_bits)));
+ se_dev->dst_ll_buf->buffer[0].data_len = TEGRA_SE_AES_BLOCK_SIZE;
+
+ /* PKA1 sticky bits are 1 AES block (16 bytes) */
+ tegra_se_write_32(se_dev, SE_CTX_SAVE_CONFIG_REG_OFFSET,
+ SE_CTX_SAVE_SRC_PKA1_STICKY_BITS |
+ SE_CTX_STICKY_WORD_QUAD_WORDS_0_3);
+
+ /* SE context save operation */
+ ret = tegra_se_start_ctx_save_operation(se_dev, 0);
+ if (ret) {
+ ERROR("%s: ERR: PKA1 sticky bits CTX_SAVE OP failed\n",
+ __func__);
+ goto pka_sticky_bits_save_err;
+ }
+
+pka_sticky_bits_save_err:
+ return ret;
+}
+
+static int tegra_se_pkakeytable_context_save(tegra_se_dev_t *se_dev)
+{
+ uint32_t val = 0;
+ int ret = 0;
+
+ se_dev->dst_ll_buf->last_buff_num = 0;
+ se_dev->dst_ll_buf->buffer[0].addr = ((uint64_t)(&(
+ ((tegra_se2_context_blob_t *)se_dev->
+ ctx_save_buf)->pka_ctx.pka_keys)));
+ se_dev->dst_ll_buf->buffer[0].data_len = TEGRA_SE_KEY_128_SIZE;
+
+ /* for each slot, save word quad 0-127 */
+ for (int slot = 0; slot < TEGRA_SE_PKA1_KEYSLOT_COUNT; slot++) {
+ for (int word_quad = 0; word_quad < 512/4; word_quad++) {
+ val = SE_CTX_SAVE_SRC_PKA1_KEYTABLE |
+ SE_CTX_PKA1_WORD_QUAD_L((slot * 128) +
+ word_quad) |
+ SE_CTX_PKA1_WORD_QUAD_H((slot * 128) +
+ word_quad);
+ tegra_se_write_32(se_dev,
+ SE_CTX_SAVE_CONFIG_REG_OFFSET, val);
+
+ /* SE context save operation */
+ ret = tegra_se_start_ctx_save_operation(se_dev,
+ TEGRA_SE_KEY_128_SIZE);
+ if (ret) {
+ ERROR("%s: ERR: pka1 keytable ctx save error\n",
+ __func__);
+ goto pka_keytable_save_err;
+ }
+
+ /* Update the pointer to the next word quad */
+ se_dev->dst_ll_buf->buffer[0].addr +=
+ TEGRA_SE_KEY_128_SIZE;
+ }
+ }
+
+pka_keytable_save_err:
+ return ret;
+}
+
+static int tegra_se_save_SRK(tegra_se_dev_t *se_dev)
+{
+ tegra_se_write_32(se_dev, SE_CTX_SAVE_CONFIG_REG_OFFSET,
+ SE_CTX_SAVE_SRC_SRK);
+
+ /* SE context save operation */
+ return tegra_se_start_ctx_save_operation(se_dev, 0);
+}
+
+/*
+ * Lock both SE from non-TZ clients.
+ */
+static inline void tegra_se_lock(tegra_se_dev_t *se_dev)
+{
+ uint32_t val;
+
+ assert(se_dev);
+ val = tegra_se_read_32(se_dev, SE_SECURITY_REG_OFFSET);
+ val |= SE_SECURITY_TZ_LOCK_SOFT(SE_SECURE);
+ tegra_se_write_32(se_dev, SE_SECURITY_REG_OFFSET, val);
+}
+
+/*
+ * Use SRK to encrypt SE state and save to TZRAM carveout
+ */
+static int tegra_se_context_save_sw(tegra_se_dev_t *se_dev)
+{
+ int err = 0;
+
+ assert(se_dev);
+
+ /* Lock entire SE/SE2 as TZ protected */
+ tegra_se_lock(se_dev);
+
+ INFO("%s: generate SRK\n", __func__);
+ /* Generate SRK */
+ err = tegra_se_generate_srk(se_dev);
+ if (err) {
+ ERROR("%s: ERR: SRK generation failed\n", __func__);
+ return err;
+ }
+
+ INFO("%s: generate random data\n", __func__);
+ /* Generate random data */
+ err = tegra_se_lp_generate_random_data(se_dev);
+ if (err) {
+ ERROR("%s: ERR: LP random pattern generation failed\n", __func__);
+ return err;
+ }
+
+ INFO("%s: encrypt random data\n", __func__);
+ /* Encrypt the random data block */
+ err = tegra_se_lp_data_context_save(se_dev,
+ ((uint64_t)(&(((tegra_se_context_t *)se_dev->
+ ctx_save_buf)->rand_data))),
+ ((uint64_t)(&(((tegra_se_context_t *)se_dev->
+ ctx_save_buf)->rand_data))),
+ SE_CTX_SAVE_RANDOM_DATA_SIZE);
+ if (err) {
+ ERROR("%s: ERR: random pattern encryption failed\n", __func__);
+ return err;
+ }
+
+ INFO("%s: save SE sticky bits\n", __func__);
+ /* Save AES sticky bits context */
+ err = tegra_se_lp_sticky_bits_context_save(se_dev);
+ if (err) {
+ ERROR("%s: ERR: sticky bits context save failed\n", __func__);
+ return err;
+ }
+
+ INFO("%s: save AES keytables\n", __func__);
+ /* Save AES key table context */
+ err = tegra_se_aeskeytable_context_save(se_dev);
+ if (err) {
+ ERROR("%s: ERR: LP keytable save failed\n", __func__);
+ return err;
+ }
+
+ /* RSA key slot table context save */
+ INFO("%s: save RSA keytables\n", __func__);
+ err = tegra_se_lp_rsakeytable_context_save(se_dev);
+ if (err) {
+ ERROR("%s: ERR: rsa key table context save failed\n", __func__);
+ return err;
+ }
+
+ /* Only SE2 has an interface with PKA1; thus, PKA1's context is saved
+ * via SE2.
+ */
+ if (se_dev->se_num == 2) {
+ /* Encrypt PKA1 sticky bits on SE2 only */
+ INFO("%s: save PKA sticky bits\n", __func__);
+ err = tegra_se_pkakeytable_sticky_bits_save(se_dev);
+ if (err) {
+ ERROR("%s: ERR: PKA sticky bits context save failed\n", __func__);
+ return err;
+ }
+
+ /* Encrypt PKA1 keyslots on SE2 only */
+ INFO("%s: save PKA keytables\n", __func__);
+ err = tegra_se_pkakeytable_context_save(se_dev);
+ if (err) {
+ ERROR("%s: ERR: PKA key table context save failed\n", __func__);
+ return err;
+ }
+ }
+
+ /* Encrypt known pattern */
+ if (se_dev->se_num == 1) {
+ err = tegra_se_lp_data_context_save(se_dev,
+ ((uint64_t)(&se_ctx_known_pattern_data)),
+ ((uint64_t)(&(((tegra_se_context_blob_t *)se_dev->ctx_save_buf)->known_pattern))),
+ SE_CTX_KNOWN_PATTERN_SIZE);
+ } else if (se_dev->se_num == 2) {
+ err = tegra_se_lp_data_context_save(se_dev,
+ ((uint64_t)(&se_ctx_known_pattern_data)),
+ ((uint64_t)(&(((tegra_se2_context_blob_t *)se_dev->ctx_save_buf)->known_pattern))),
+ SE_CTX_KNOWN_PATTERN_SIZE);
+ }
+ if (err) {
+ ERROR("%s: ERR: save LP known pattern failure\n", __func__);
+ return err;
+ }
+
+ /* Write lp context buffer address into PMC scratch register */
+ if (se_dev->se_num == 1) {
+ /* SE context address */
+ mmio_write_32((uint64_t)TEGRA_PMC_BASE + PMC_SECURE_SCRATCH117_OFFSET,
+ ((uint64_t)(se_dev->ctx_save_buf)));
+ } else if (se_dev->se_num == 2) {
+ /* SE2 & PKA1 context address */
+ mmio_write_32((uint64_t)TEGRA_PMC_BASE + PMC_SECURE_SCRATCH116_OFFSET,
+ ((uint64_t)(se_dev->ctx_save_buf)));
+ }
+
+ /* Saves SRK to PMC secure scratch registers for BootROM, which
+ * verifies and restores the security engine context on warm boot.
+ */
+ err = tegra_se_save_SRK(se_dev);
+ if (err < 0) {
+ ERROR("%s: ERR: LP SRK save failure\n", __func__);
+ return err;
+ }
+
+ INFO("%s: SE context save done \n", __func__);
+
+ return err;
+}
+
+/*
* Initialize the SE engine handle
*/
void tegra_se_init(void)
{
+ uint32_t val = 0;
INFO("%s: start SE init\n", __func__);
/* Generate random SRK to initialize DRBG */
tegra_se_generate_srk(&se_dev_1);
tegra_se_generate_srk(&se_dev_2);
+ /* determine if ECID is valid */
+ val = mmio_read_32(TEGRA_FUSE_BASE + FUSE_JTAG_SECUREID_VALID);
+ ecid_valid = (val == ECID_VALID);
+
INFO("%s: SE init done\n", __func__);
}
+static void tegra_se_enable_clocks(void)
+{
+ uint32_t val = 0;
+
+ /* Enable entropy clock */
+ val = mmio_read_32(TEGRA_CAR_RESET_BASE + TEGRA_CLK_OUT_ENB_W);
+ val |= ENTROPY_CLK_ENB_BIT;
+ mmio_write_32(TEGRA_CAR_RESET_BASE + TEGRA_CLK_OUT_ENB_W, val);
+
+ /* De-Assert Entropy Reset */
+ val = mmio_read_32(TEGRA_CAR_RESET_BASE + TEGRA_RST_DEVICES_W);
+ val &= ~ENTROPY_RESET_BIT;
+ mmio_write_32(TEGRA_CAR_RESET_BASE + TEGRA_RST_DEVICES_W, val);
+
+ /* Enable SE clock */
+ val = mmio_read_32(TEGRA_CAR_RESET_BASE + TEGRA_CLK_OUT_ENB_V);
+ val |= SE_CLK_ENB_BIT;
+ mmio_write_32(TEGRA_CAR_RESET_BASE + TEGRA_CLK_OUT_ENB_V, val);
+
+ /* De-Assert SE Reset */
+ val = mmio_read_32(TEGRA_CAR_RESET_BASE + TEGRA_RST_DEVICES_V);
+ val &= ~SE_RESET_BIT;
+ mmio_write_32(TEGRA_CAR_RESET_BASE + TEGRA_RST_DEVICES_V, val);
+}
+
+static void tegra_se_disable_clocks(void)
+{
+ uint32_t val = 0;
+
+ /* Disable entropy clock */
+ val = mmio_read_32(TEGRA_CAR_RESET_BASE + TEGRA_CLK_OUT_ENB_W);
+ val &= ~ENTROPY_CLK_ENB_BIT;
+ mmio_write_32(TEGRA_CAR_RESET_BASE + TEGRA_CLK_OUT_ENB_W, val);
+
+ /* Disable SE clock */
+ val = mmio_read_32(TEGRA_CAR_RESET_BASE + TEGRA_CLK_OUT_ENB_V);
+ val &= ~SE_CLK_ENB_BIT;
+ mmio_write_32(TEGRA_CAR_RESET_BASE + TEGRA_CLK_OUT_ENB_V, val);
+}
+
/*
* Security engine power suspend entry point.
* This function is invoked from PSCI power domain suspend handler.
@@ -417,20 +965,56 @@
int32_t tegra_se_suspend(void)
{
int32_t ret = 0;
+ uint32_t val = 0;
- /* Atomic context save se2 and pka1 */
- INFO("%s: SE2/PKA1 atomic context save\n", __func__);
- ret = tegra_se_context_save_atomic(&se_dev_2);
+ /* SE does not use SMMU in EL3, disable SMMU.
+ * This will be re-enabled by kernel on resume */
+ val = mmio_read_32(TEGRA_MC_BASE + MC_SMMU_PPCS_ASID_0);
+ val &= ~PPCS_SMMU_ENABLE;
+ mmio_write_32(TEGRA_MC_BASE + MC_SMMU_PPCS_ASID_0, val);
- /* Atomic context save se */
- if (ret == 0) {
- INFO("%s: SE1 atomic context save\n", __func__);
- ret = tegra_se_context_save_atomic(&se_dev_1);
+ tegra_se_enable_clocks();
+
+ if (tegra_se_atomic_save_enabled(&se_dev_2) &&
+ tegra_se_atomic_save_enabled(&se_dev_1)) {
+ /* Atomic context save se2 and pka1 */
+ INFO("%s: SE2/PKA1 atomic context save\n", __func__);
+ if (ret == 0) {
+ ret = tegra_se_context_save_atomic(&se_dev_2);
+ }
+
+ /* Atomic context save se */
+ if (ret == 0) {
+ INFO("%s: SE1 atomic context save\n", __func__);
+ ret = tegra_se_context_save_atomic(&se_dev_1);
+ }
+
+ if (ret == 0) {
+ INFO("%s: SE atomic context save done\n", __func__);
+ }
+ } else if (!tegra_se_atomic_save_enabled(&se_dev_2) &&
+ !tegra_se_atomic_save_enabled(&se_dev_1)) {
+ /* SW context save se2 and pka1 */
+ INFO("%s: SE2/PKA1 legacy(SW) context save\n", __func__);
+ if (ret == 0) {
+ ret = tegra_se_context_save_sw(&se_dev_2);
+ }
+
+ /* SW context save se */
+ if (ret == 0) {
+ INFO("%s: SE1 legacy(SW) context save\n", __func__);
+ ret = tegra_se_context_save_sw(&se_dev_1);
+ }
+
+ if (ret == 0) {
+ INFO("%s: SE SW context save done\n", __func__);
+ }
+ } else {
+ ERROR("%s: One SE set for atomic CTX save, the other is not\n",
+ __func__);
}
- if (ret == 0) {
- INFO("%s: SE atomic context save done\n", __func__);
- }
+ tegra_se_disable_clocks();
return ret;
}
@@ -445,6 +1029,7 @@
uint32_t timeout;
INFO("%s: SE TZRAM save start\n", __func__);
+ tegra_se_enable_clocks();
val = (SE_TZRAM_OP_REQ_INIT | SE_TZRAM_OP_MODE_SAVE);
tegra_se_write_32(&se_dev_1, SE_TZRAM_OPERATION, val);
@@ -465,6 +1050,8 @@
INFO("%s: SE TZRAM save done!\n", __func__);
}
+ tegra_se_disable_clocks();
+
return ret;
}
@@ -483,12 +1070,6 @@
DRBG_RO_ENT_SRC_ENABLE;
tegra_se_write_32(se_dev, SE_RNG_SRC_CONFIG_REG_OFFSET, val);
- /* Enable and lock the SE atomic context save setting */
- if (tegra_se_ctx_save_auto_enable(se_dev) != 0) {
- ERROR("%s: ERR: enable SE%d context save auto failed!\n",
- __func__, se_dev->se_num);
- }
-
/* Set a random value to SRK to initialize DRBG */
tegra_se_generate_srk(se_dev);
}
diff --git a/plat/nvidia/tegra/soc/t210/plat_psci_handlers.c b/plat/nvidia/tegra/soc/t210/plat_psci_handlers.c
index ed30ff4..f52d975 100644
--- a/plat/nvidia/tegra/soc/t210/plat_psci_handlers.c
+++ b/plat/nvidia/tegra/soc/t210/plat_psci_handlers.c
@@ -104,41 +104,55 @@
if ((lvl == MPIDR_AFFLVL1) && (target == PSTATE_ID_CLUSTER_IDLE)) {
/* initialize the bpmp interface */
- (void)tegra_bpmp_init();
-
- /* Cluster idle */
- data[0] = (uint32_t)cpu;
- data[1] = TEGRA_PM_CC6;
- data[2] = TEGRA_PM_SC1;
- ret = tegra_bpmp_send_receive_atomic(MRQ_DO_IDLE,
- (void *)&data, (int)sizeof(data),
- (void *)&bpmp_reply, (int)sizeof(bpmp_reply));
-
- /* check if cluster idle entry is allowed */
- if ((ret != 0L) || (bpmp_reply != BPMP_CCx_ALLOWED)) {
+ ret = tegra_bpmp_init();
+ if (ret != 0U) {
/* Cluster idle not allowed */
target = PSCI_LOCAL_STATE_RUN;
+ } else {
+
+ /* Cluster idle */
+ data[0] = (uint32_t)cpu;
+ data[1] = TEGRA_PM_CC6;
+ data[2] = TEGRA_PM_SC1;
+ ret = tegra_bpmp_send_receive_atomic(MRQ_DO_IDLE,
+ (void *)&data, (int)sizeof(data),
+ (void *)&bpmp_reply,
+ (int)sizeof(bpmp_reply));
+
+ /* check if cluster idle entry is allowed */
+ if ((ret != 0L) || (bpmp_reply != BPMP_CCx_ALLOWED)) {
+
+ /* Cluster idle not allowed */
+ target = PSCI_LOCAL_STATE_RUN;
+ }
}
} else if ((lvl == MPIDR_AFFLVL1) && (target == PSTATE_ID_CLUSTER_POWERDN)) {
/* initialize the bpmp interface */
- (void)tegra_bpmp_init();
-
- /* Cluster power-down */
- data[0] = (uint32_t)cpu;
- data[1] = TEGRA_PM_CC7;
- data[2] = TEGRA_PM_SC1;
- ret = tegra_bpmp_send_receive_atomic(MRQ_DO_IDLE,
- (void *)&data, (int)sizeof(data),
- (void *)&bpmp_reply, (int)sizeof(bpmp_reply));
-
- /* check if cluster power down is allowed */
- if ((ret != 0L) || (bpmp_reply != BPMP_CCx_ALLOWED)) {
+ ret = tegra_bpmp_init();
+ if (ret != 0U) {
/* Cluster power down not allowed */
target = PSCI_LOCAL_STATE_RUN;
+ } else {
+
+ /* Cluster power-down */
+ data[0] = (uint32_t)cpu;
+ data[1] = TEGRA_PM_CC7;
+ data[2] = TEGRA_PM_SC1;
+ ret = tegra_bpmp_send_receive_atomic(MRQ_DO_IDLE,
+ (void *)&data, (int)sizeof(data),
+ (void *)&bpmp_reply,
+ (int)sizeof(bpmp_reply));
+
+ /* check if cluster power down is allowed */
+ if ((ret != 0L) || (bpmp_reply != BPMP_CCx_ALLOWED)) {
+
+ /* Cluster power down not allowed */
+ target = PSCI_LOCAL_STATE_RUN;
+ }
}
} else if (((lvl == MPIDR_AFFLVL2) || (lvl == MPIDR_AFFLVL1)) &&
@@ -177,16 +191,6 @@
if (tegra_se_suspend() != 0) {
ret = PSCI_E_INTERN_FAIL;
}
-
- /* Save tzram contents */
- if (tegra_se_save_tzram() != 0) {
- ret = PSCI_E_INTERN_FAIL;
- }
- }
-
- /* enter system suspend */
- if (ret == PSCI_E_SUCCESS) {
- tegra_fc_soc_powerdn(mpidr);
}
} else if (stateid_afflvl1 == PSTATE_ID_CLUSTER_IDLE) {
@@ -217,6 +221,27 @@
return ret;
}
+int tegra_soc_pwr_domain_power_down_wfi(const psci_power_state_t *target_state)
+{
+ u_register_t mpidr = read_mpidr();
+ const plat_local_state_t *pwr_domain_state =
+ target_state->pwr_domain_state;
+ unsigned int stateid_afflvl2 = pwr_domain_state[PLAT_MAX_PWR_LVL];
+
+ if (stateid_afflvl2 == PSTATE_ID_SOC_POWERDN) {
+
+ if (tegra_chipid_is_t210_b01()) {
+ /* Save tzram contents */
+ tegra_se_save_tzram();
+ }
+
+ /* enter system suspend */
+ tegra_fc_soc_powerdn(mpidr);
+ }
+
+ return PSCI_E_SUCCESS;
+}
+
int tegra_soc_pwr_domain_on_finish(const psci_power_state_t *target_state)
{
const plat_params_from_bl2_t *plat_params = bl31_get_plat_params();
diff --git a/plat/nvidia/tegra/soc/t210/platform_t210.mk b/plat/nvidia/tegra/soc/t210/platform_t210.mk
index a9ab0d8..e23d7e3 100644
--- a/plat/nvidia/tegra/soc/t210/platform_t210.mk
+++ b/plat/nvidia/tegra/soc/t210/platform_t210.mk
@@ -19,14 +19,15 @@
MAX_XLAT_TABLES := 10
$(eval $(call add_define,MAX_XLAT_TABLES))
-MAX_MMAP_REGIONS := 10
+MAX_MMAP_REGIONS := 15
$(eval $(call add_define,MAX_MMAP_REGIONS))
PLAT_INCLUDES += -I${SOC_DIR}/drivers/se
-BL31_SOURCES += lib/cpus/aarch64/cortex_a53.S \
+BL31_SOURCES += drivers/ti/uart/aarch64/16550_console.S \
+ lib/cpus/aarch64/cortex_a53.S \
lib/cpus/aarch64/cortex_a57.S \
- ${COMMON_DIR}/drivers/bpmp/bpmp.c \
+ ${COMMON_DIR}/drivers/bpmp/bpmp.c \
${COMMON_DIR}/drivers/flowctrl/flowctrl.c \
${COMMON_DIR}/drivers/memctrl/memctrl_v1.c \
${SOC_DIR}/plat_psci_handlers.c \
diff --git a/plat/renesas/rcar/bl2_cpg_init.c b/plat/renesas/rcar/bl2_cpg_init.c
index 883fc9a..1dff690 100644
--- a/plat/renesas/rcar/bl2_cpg_init.c
+++ b/plat/renesas/rcar/bl2_cpg_init.c
@@ -28,7 +28,7 @@
static void bl2_system_cpg_init_m3n(void);
#endif
-#if (RCAR_LSI == RCAR_E3)
+#if (RCAR_LSI == RCAR_AUTO) || (RCAR_LSI == RCAR_E3)
static void bl2_realtime_cpg_init_e3(void);
static void bl2_system_cpg_init_e3(void);
#endif
@@ -193,7 +193,7 @@
}
#endif
-#if (RCAR_LSI == RCAR_E3)
+#if (RCAR_LSI == RCAR_AUTO) || (RCAR_LSI == RCAR_E3)
static void bl2_realtime_cpg_init_e3(void)
{
/* Realtime Module Stop Control Registers */
@@ -251,6 +251,9 @@
case RCAR_PRODUCT_M3N:
bl2_realtime_cpg_init_m3n();
break;
+ case RCAR_PRODUCT_E3:
+ bl2_realtime_cpg_init_e3();
+ break;
default:
panic();
break;
@@ -284,6 +287,9 @@
case RCAR_PRODUCT_M3N:
bl2_system_cpg_init_m3n();
break;
+ case RCAR_PRODUCT_E3:
+ bl2_system_cpg_init_e3();
+ break;
default:
panic();
break;
diff --git a/plat/renesas/rcar/include/rcar_def.h b/plat/renesas/rcar/include/rcar_def.h
index 1829e59..3bb03f2 100644
--- a/plat/renesas/rcar/include/rcar_def.h
+++ b/plat/renesas/rcar/include/rcar_def.h
@@ -204,8 +204,6 @@
#define EXTAL_MD14_MD13_TYPE_3 U(16666600) /* MD14=1 MD13=1 */
#define EXTAL_SALVATOR_XS U(8320000) /* Salvator-XS */
#define EXTAL_EBISU U(24000000) /* Ebisu */
-/* CPU Auxiliary Control Register */
-#define RCAR_CA57_DIS_LOAD_PASS_STORE (ULL(1) << 55)
/* CPG write protect registers */
#define CPGWPR_PASSWORD (0x5A5AFFFFU)
#define CPGWPCR_PASSWORD (0xA5A50000U)
diff --git a/plat/renesas/rcar/plat_pm.c b/plat/renesas/rcar/plat_pm.c
index 245a45a..47eda9a 100644
--- a/plat/renesas/rcar/plat_pm.c
+++ b/plat/renesas/rcar/plat_pm.c
@@ -175,7 +175,7 @@
uint64_t cpu = read_mpidr_el1() & 0x0000ffff;
int32_t rtn_on;
- rtn_on = cpu_on_check(cpu);
+ rtn_on = rcar_pwrc_cpu_on_check(cpu);
if (cpu == rcar_boot_mpidr)
panic();
diff --git a/plat/renesas/rcar/platform.mk b/plat/renesas/rcar/platform.mk
index b9c0802..629a3cf 100644
--- a/plat/renesas/rcar/platform.mk
+++ b/plat/renesas/rcar/platform.mk
@@ -4,7 +4,7 @@
# SPDX-License-Identifier: BSD-3-Clause
#
-PROGRAMMABLE_RESET_ADDRESS := 1
+PROGRAMMABLE_RESET_ADDRESS := 0
COLD_BOOT_SINGLE_CPU := 1
ARM_CCI_PRODUCT_ID := 500
TRUSTED_BOARD_BOOT := 1
diff --git a/plat/rockchip/common/rockchip_gicv2.c b/plat/rockchip/common/rockchip_gicv2.c
index 222a882..8db2b30 100644
--- a/plat/rockchip/common/rockchip_gicv2.c
+++ b/plat/rockchip/common/rockchip_gicv2.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2016, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2016-2019, ARM Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -22,11 +22,10 @@
#pragma weak plat_rockchip_gic_pcpu_init
/******************************************************************************
- * On a GICv2 system, the Group 1 secure interrupts are treated as Group 0
- * interrupts.
+ * List of interrupts.
*****************************************************************************/
static const interrupt_prop_t g0_interrupt_props[] = {
- PLAT_RK_GICV2_G1S_IRQS
+ PLAT_RK_GICV2_G0_IRQS
};
/*
diff --git a/plat/rockchip/rk3328/rk3328_def.h b/plat/rockchip/rk3328/rk3328_def.h
index 4704a72..0ce13ad 100644
--- a/plat/rockchip/rk3328/rk3328_def.h
+++ b/plat/rockchip/rk3328/rk3328_def.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2017, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2017-2019, ARM Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -131,15 +131,13 @@
#define RK_IRQ_SEC_SGI_7 15
/*
- * Define a list of Group 1 Secure and Group 0 interrupts as per GICv3
- * terminology. On a GICv2 system or mode, the lists will be merged and treated
- * as Group 0 interrupts.
+ * Define a list of Group 0 interrupts.
*/
-#define PLAT_RK_GICV2_G1S_IRQS \
+#define PLAT_RK_GICV2_G0_IRQS \
INTR_PROP_DESC(RK_IRQ_SEC_PHY_TIMER, GIC_HIGHEST_SEC_PRIORITY, \
- GICV2_INTR_GROUP1, GIC_INTR_CFG_LEVEL), \
+ GICV2_INTR_GROUP0, GIC_INTR_CFG_LEVEL), \
INTR_PROP_DESC(RK_IRQ_SEC_SGI_6, GIC_HIGHEST_SEC_PRIORITY, \
- GICV2_INTR_GROUP1, GIC_INTR_CFG_LEVEL)
+ GICV2_INTR_GROUP0, GIC_INTR_CFG_LEVEL)
#define SHARE_MEM_BASE 0x100000/* [1MB, 1MB+60K]*/
#define SHARE_MEM_PAGE_NUM 15
diff --git a/plat/rockchip/rk3368/rk3368_def.h b/plat/rockchip/rk3368/rk3368_def.h
index a7be7c3..10ac77b 100644
--- a/plat/rockchip/rk3368/rk3368_def.h
+++ b/plat/rockchip/rk3368/rk3368_def.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2016, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2016-2019, ARM Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -96,12 +96,10 @@
#define RK_IRQ_SEC_SGI_7 15
/*
- * Define a list of Group 1 Secure and Group 0 interrupts as per GICv3
- * terminology. On a GICv2 system or mode, the lists will be merged and treated
- * as Group 0 interrupts.
+ * Define a list of Group 0 interrupts.
*/
-#define PLAT_RK_GICV2_G1S_IRQS \
+#define PLAT_RK_GICV2_G0_IRQS \
INTR_PROP_DESC(RK_IRQ_SEC_PHY_TIMER, GIC_HIGHEST_SEC_PRIORITY, \
- GICV2_INTR_GROUP1, GIC_INTR_CFG_LEVEL)
+ GICV2_INTR_GROUP0, GIC_INTR_CFG_LEVEL)
#endif /* RK3368_DEF_H */
diff --git a/plat/rpi3/include/platform_def.h b/plat/rpi3/include/platform_def.h
index 69ebdb3..4d90222 100644
--- a/plat/rpi3/include/platform_def.h
+++ b/plat/rpi3/include/platform_def.h
@@ -244,6 +244,8 @@
#define MAX_IO_DEVICES U(3)
#define MAX_IO_HANDLES U(4)
+#define MAX_IO_BLOCK_DEVICES U(1)
+
/*
* Serial-related constants.
*/
diff --git a/plat/rpi3/platform.mk b/plat/rpi3/platform.mk
index 5e76345..ca638d5 100644
--- a/plat/rpi3/platform.mk
+++ b/plat/rpi3/platform.mk
@@ -27,6 +27,13 @@
drivers/io/io_fip.c \
drivers/io/io_memmap.c \
drivers/io/io_storage.c \
+ drivers/gpio/gpio.c \
+ drivers/delay_timer/delay_timer.c \
+ drivers/delay_timer/generic_delay_timer.c \
+ drivers/rpi3/gpio/rpi3_gpio.c \
+ drivers/io/io_block.c \
+ drivers/mmc/mmc.c \
+ drivers/rpi3/sdhost/rpi3_sdhost.c \
plat/common/aarch64/platform_mp_stack.S \
plat/rpi3/aarch64/plat_helpers.S \
plat/rpi3/aarch64/rpi3_bl2_mem_params_desc.c \
diff --git a/plat/rpi3/rpi3_bl2_setup.c b/plat/rpi3/rpi3_bl2_setup.c
index 53a2c72..3d1f8f9 100644
--- a/plat/rpi3/rpi3_bl2_setup.c
+++ b/plat/rpi3/rpi3_bl2_setup.c
@@ -15,12 +15,41 @@
#include <lib/optee_utils.h>
#include <lib/xlat_tables/xlat_mmu_helpers.h>
#include <lib/xlat_tables/xlat_tables_defs.h>
+#include <drivers/generic_delay_timer.h>
+#include <drivers/rpi3/gpio/rpi3_gpio.h>
+#include <drivers/rpi3/sdhost/rpi3_sdhost.h>
#include "rpi3_private.h"
/* Data structure which holds the extents of the trusted SRAM for BL2 */
static meminfo_t bl2_tzram_layout __aligned(CACHE_WRITEBACK_GRANULE);
+/* rpi3 GPIO setup function. */
+static void rpi3_gpio_setup(void)
+{
+ struct rpi3_gpio_params params;
+
+ memset(¶ms, 0, sizeof(struct rpi3_gpio_params));
+ params.reg_base = RPI3_GPIO_BASE;
+
+ rpi3_gpio_init(¶ms);
+}
+
+/* Data structure which holds the MMC info */
+static struct mmc_device_info mmc_info;
+
+static void rpi3_sdhost_setup(void)
+{
+ struct rpi3_sdhost_params params;
+
+ memset(¶ms, 0, sizeof(struct rpi3_sdhost_params));
+ params.reg_base = RPI3_SDHOST_BASE;
+ params.bus_width = MMC_BUS_WIDTH_4;
+ params.clk_rate = 392464;
+ mmc_info.mmc_dev_type = MMC_IS_SD_HC;
+ rpi3_sdhost_init(¶ms, &mmc_info);
+}
+
/*******************************************************************************
* BL1 has passed the extents of the trusted SRAM that should be visible to BL2
* in x0. This memory layout is sitting at the base of the free trusted SRAM.
@@ -35,9 +64,18 @@
/* Initialize the console to provide early debug support */
rpi3_console_init();
+ /* Enable arch timer */
+ generic_delay_timer_init();
+
+ /* Setup GPIO driver */
+ rpi3_gpio_setup();
+
/* Setup the BL2 memory layout */
bl2_tzram_layout = *mem_layout;
+ /* Setup SDHost driver */
+ rpi3_sdhost_setup();
+
plat_rpi3_io_setup();
}
@@ -103,6 +141,9 @@
/* BL33 expects to receive the primary CPU MPID (through r0) */
bl_mem_params->ep_info.args.arg0 = 0xffff & read_mpidr();
bl_mem_params->ep_info.spsr = rpi3_get_spsr_for_bl33_entry();
+
+ /* Shutting down the SDHost driver to let BL33 drives SDHost.*/
+ rpi3_sdhost_stop();
break;
default:
diff --git a/plat/rpi3/rpi3_hw.h b/plat/rpi3/rpi3_hw.h
index 9d86eb8..1a86835 100644
--- a/plat/rpi3/rpi3_hw.h
+++ b/plat/rpi3/rpi3_hw.h
@@ -84,6 +84,18 @@
#define RPI3_MINI_UART_CLK_IN_HZ ULL(500000000)
/*
+ * GPIO controller
+ */
+#define RPI3_IO_GPIO_OFFSET ULL(0x00200000)
+#define RPI3_GPIO_BASE (RPI3_IO_BASE + RPI3_IO_GPIO_OFFSET)
+
+/*
+ * SDHost controller
+ */
+#define RPI3_IO_SDHOST_OFFSET ULL(0x00202000)
+#define RPI3_SDHOST_BASE (RPI3_IO_BASE + RPI3_IO_SDHOST_OFFSET)
+
+/*
* Local interrupt controller
*/
#define RPI3_INTC_BASE_ADDRESS ULL(0x40000000)
diff --git a/plat/rpi3/rpi3_io_storage.c b/plat/rpi3/rpi3_io_storage.c
index 7e66deb..49c6a76 100644
--- a/plat/rpi3/rpi3_io_storage.c
+++ b/plat/rpi3/rpi3_io_storage.c
@@ -133,11 +133,6 @@
(uintptr_t)&bl32_uuid_spec,
open_fip
},
- [BL32_IMAGE_ID] = {
- &fip_dev_handle,
- (uintptr_t)&bl32_uuid_spec,
- open_fip
- },
[BL32_EXTRA1_IMAGE_ID] = {
&fip_dev_handle,
(uintptr_t)&bl32_extra1_uuid_spec,
diff --git a/plat/rpi3/rpi3_pm.c b/plat/rpi3/rpi3_pm.c
index 3a077d3..4f586b5 100644
--- a/plat/rpi3/rpi3_pm.c
+++ b/plat/rpi3/rpi3_pm.c
@@ -140,7 +140,7 @@
* being turned off earlier. The target_state encodes the low power state that
* each level has woken up from.
******************************************************************************/
-void rpi3_pwr_domain_on_finish(const psci_power_state_t *target_state)
+static void rpi3_pwr_domain_on_finish(const psci_power_state_t *target_state)
{
assert(target_state->pwr_domain_state[MPIDR_AFFLVL0] ==
PLAT_LOCAL_STATE_OFF);
diff --git a/plat/socionext/synquacer/sq_bl31_setup.c b/plat/socionext/synquacer/sq_bl31_setup.c
index 2fac80f..fef84ef 100644
--- a/plat/socionext/synquacer/sq_bl31_setup.c
+++ b/plat/socionext/synquacer/sq_bl31_setup.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2018, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2018-2019, ARM Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -160,7 +160,7 @@
void bl31_plat_arch_setup(void)
{
static const mmap_region_t secure_partition_mmap[] = {
-#if ENABLE_SPM && SPM_DEPRECATED
+#if ENABLE_SPM && SPM_MM
MAP_REGION_FLAT(PLAT_SPM_BUF_BASE,
PLAT_SPM_BUF_SIZE,
MT_RW_DATA | MT_SECURE),
@@ -174,7 +174,7 @@
sq_mmap_setup(BL31_BASE, BL31_SIZE, secure_partition_mmap);
enable_mmu_el3(XLAT_TABLE_NC);
-#if ENABLE_SPM && SPM_DEPRECATED
+#if ENABLE_SPM && SPM_MM
memcpy((void *)SPM_SHIM_EXCEPTIONS_START,
(void *)SPM_SHIM_EXCEPTIONS_LMA,
(uintptr_t)SPM_SHIM_EXCEPTIONS_END -
diff --git a/plat/st/stm32mp1/bl2_io_storage.c b/plat/st/stm32mp1/bl2_io_storage.c
index 45a352e..8ccbc24 100644
--- a/plat/st/stm32mp1/bl2_io_storage.c
+++ b/plat/st/stm32mp1/bl2_io_storage.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2015-2018, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2015-2019, ARM Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -58,13 +58,26 @@
static uintptr_t storage_dev_handle;
static const io_dev_connector_t *mmc_dev_con;
-#define IMG_IDX_BL33 0
+static const io_block_spec_t bl32_block_spec = {
+ .offset = BL32_BASE,
+ .length = STM32MP1_BL32_SIZE
+};
+
+static const io_block_spec_t bl2_block_spec = {
+ .offset = BL2_BASE,
+ .length = STM32MP1_BL2_SIZE,
+};
static const struct stm32image_part_info bl33_partition_spec = {
.name = BL33_IMAGE_NAME,
.binary_type = BL33_BINARY_TYPE,
};
+enum {
+ IMG_IDX_BL33,
+ IMG_IDX_NUM
+};
+
static struct stm32image_device_info stm32image_dev_info_spec = {
.lba_size = MMC_BLOCK_SIZE,
.part_info[IMG_IDX_BL33] = {
@@ -73,20 +86,13 @@
},
};
-static io_block_spec_t stm32image_block_spec;
+static io_block_spec_t stm32image_block_spec = {
+ .offset = 0,
+ .length = 0,
+};
static const io_dev_connector_t *stm32image_dev_con;
-static const io_block_spec_t bl32_block_spec = {
- .offset = BL32_BASE,
- .length = STM32MP1_BL32_SIZE
-};
-
-static const io_block_spec_t bl2_block_spec = {
- .offset = BL2_BASE,
- .length = STM32MP1_BL2_SIZE,
-};
-
static int open_dummy(const uintptr_t spec);
static int open_image(const uintptr_t spec);
static int open_storage(const uintptr_t spec);
@@ -160,83 +166,18 @@
}
}
-static void print_reset_reason(void)
-{
- uint32_t rstsr = mmio_read_32(RCC_BASE + RCC_MP_RSTSCLRR);
-
- if (rstsr == 0U) {
- WARN("Reset reason unknown\n");
- return;
- }
-
- INFO("Reset reason (0x%x):\n", rstsr);
-
- if ((rstsr & RCC_MP_RSTSCLRR_PADRSTF) == 0U) {
- if ((rstsr & RCC_MP_RSTSCLRR_STDBYRSTF) != 0U) {
- INFO("System exits from STANDBY\n");
- return;
- }
-
- if ((rstsr & RCC_MP_RSTSCLRR_CSTDBYRSTF) != 0U) {
- INFO("MPU exits from CSTANDBY\n");
- return;
- }
- }
-
- if ((rstsr & RCC_MP_RSTSCLRR_PORRSTF) != 0U) {
- INFO(" Power-on Reset (rst_por)\n");
- return;
- }
-
- if ((rstsr & RCC_MP_RSTSCLRR_BORRSTF) != 0U) {
- INFO(" Brownout Reset (rst_bor)\n");
- return;
- }
-
- if ((rstsr & RCC_MP_RSTSCLRR_MPSYSRSTF) != 0U) {
- INFO(" System reset generated by MPU (MPSYSRST)\n");
- return;
- }
-
- if ((rstsr & RCC_MP_RSTSCLRR_HCSSRSTF) != 0U) {
- INFO(" Reset due to a clock failure on HSE\n");
- return;
- }
-
- if ((rstsr & RCC_MP_RSTSCLRR_IWDG1RSTF) != 0U) {
- INFO(" IWDG1 Reset (rst_iwdg1)\n");
- return;
- }
-
- if ((rstsr & RCC_MP_RSTSCLRR_IWDG2RSTF) != 0U) {
- INFO(" IWDG2 Reset (rst_iwdg2)\n");
- return;
- }
-
- if ((rstsr & RCC_MP_RSTSCLRR_PADRSTF) != 0U) {
- INFO(" Pad Reset from NRST\n");
- return;
- }
-
- if ((rstsr & RCC_MP_RSTSCLRR_VCORERSTF) != 0U) {
- INFO(" Reset due to a failure of VDD_CORE\n");
- return;
- }
-
- ERROR(" Unidentified reset reason\n");
-}
-
void stm32mp1_io_setup(void)
{
int io_result __unused;
+ uint8_t idx;
+ struct stm32image_part_info *part;
struct stm32_sdmmc2_params params;
struct mmc_device_info device_info;
uintptr_t mmc_default_instance;
+ const partition_entry_t *entry;
boot_api_context_t *boot_context =
(boot_api_context_t *)stm32mp1_get_boot_ctx_address();
- print_reset_reason();
-
print_boot_device(boot_context);
if ((boot_context->boot_partition_used_toboot == 1U) ||
@@ -255,7 +196,7 @@
switch (boot_context->boot_interface_selected) {
case BOOT_API_CTX_BOOT_INTERFACE_SEL_FLASH_SD:
case BOOT_API_CTX_BOOT_INTERFACE_SEL_FLASH_EMMC:
- dmb();
+ dmbsy();
memset(¶ms, 0, sizeof(struct stm32_sdmmc2_params));
@@ -309,14 +250,19 @@
stm32image_dev_info_spec.device_size =
stm32_sdmmc2_mmc_get_device_size();
- stm32image_dev_info_spec.part_info[IMG_IDX_BL33].part_offset =
- get_partition_entry(BL33_IMAGE_NAME)->start;
- stm32image_dev_info_spec.part_info[IMG_IDX_BL33].bkp_offset =
- get_partition_entry(BL33_IMAGE_NAME)->length;
- stm32image_block_spec.offset = 0;
- stm32image_block_spec.length =
- get_partition_entry(BL33_IMAGE_NAME)->length;
+ for (idx = 0U; idx < IMG_IDX_NUM; idx++) {
+ part = &stm32image_dev_info_spec.part_info[idx];
+ entry = get_partition_entry(part->name);
+ if (entry == NULL) {
+ ERROR("Partition %s not found\n",
+ part->name);
+ panic();
+ }
+
+ part->part_offset = entry->start;
+ part->bkp_offset = 0U;
+ }
/*
* Re-open MMC with io_mmc, for better perfs compared to
diff --git a/plat/st/stm32mp1/bl2_plat_setup.c b/plat/st/stm32mp1/bl2_plat_setup.c
index 6af65fd..a1ffd5a 100644
--- a/plat/st/stm32mp1/bl2_plat_setup.c
+++ b/plat/st/stm32mp1/bl2_plat_setup.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2015-2018, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2015-2019, ARM Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -16,8 +16,8 @@
#include <drivers/delay_timer.h>
#include <drivers/generic_delay_timer.h>
#include <drivers/st/stm32_console.h>
+#include <drivers/st/stm32mp_pmic.h>
#include <drivers/st/stm32mp1_clk.h>
-#include <drivers/st/stm32mp1_pmic.h>
#include <drivers/st/stm32mp1_pwr.h>
#include <drivers/st/stm32mp1_ram.h>
#include <drivers/st/stm32mp1_rcc.h>
@@ -33,8 +33,95 @@
static struct console_stm32 console;
-void bl2_el3_early_platform_setup(u_register_t arg0, u_register_t arg1,
- u_register_t arg2, u_register_t arg3)
+static void print_reset_reason(void)
+{
+ uint32_t rstsr = mmio_read_32(RCC_BASE + RCC_MP_RSTSCLRR);
+
+ if (rstsr == 0U) {
+ WARN("Reset reason unknown\n");
+ return;
+ }
+
+ INFO("Reset reason (0x%x):\n", rstsr);
+
+ if ((rstsr & RCC_MP_RSTSCLRR_PADRSTF) == 0U) {
+ if ((rstsr & RCC_MP_RSTSCLRR_STDBYRSTF) != 0U) {
+ INFO("System exits from STANDBY\n");
+ return;
+ }
+
+ if ((rstsr & RCC_MP_RSTSCLRR_CSTDBYRSTF) != 0U) {
+ INFO("MPU exits from CSTANDBY\n");
+ return;
+ }
+ }
+
+ if ((rstsr & RCC_MP_RSTSCLRR_PORRSTF) != 0U) {
+ INFO(" Power-on Reset (rst_por)\n");
+ return;
+ }
+
+ if ((rstsr & RCC_MP_RSTSCLRR_BORRSTF) != 0U) {
+ INFO(" Brownout Reset (rst_bor)\n");
+ return;
+ }
+
+ if ((rstsr & RCC_MP_RSTSCLRR_MCSYSRSTF) != 0U) {
+ if ((rstsr & RCC_MP_RSTSCLRR_PADRSTF) != 0U) {
+ INFO(" System reset generated by MCU (MCSYSRST)\n");
+ } else {
+ INFO(" Local reset generated by MCU (MCSYSRST)\n");
+ }
+ return;
+ }
+
+ if ((rstsr & RCC_MP_RSTSCLRR_MPSYSRSTF) != 0U) {
+ INFO(" System reset generated by MPU (MPSYSRST)\n");
+ return;
+ }
+
+ if ((rstsr & RCC_MP_RSTSCLRR_HCSSRSTF) != 0U) {
+ INFO(" Reset due to a clock failure on HSE\n");
+ return;
+ }
+
+ if ((rstsr & RCC_MP_RSTSCLRR_IWDG1RSTF) != 0U) {
+ INFO(" IWDG1 Reset (rst_iwdg1)\n");
+ return;
+ }
+
+ if ((rstsr & RCC_MP_RSTSCLRR_IWDG2RSTF) != 0U) {
+ INFO(" IWDG2 Reset (rst_iwdg2)\n");
+ return;
+ }
+
+ if ((rstsr & RCC_MP_RSTSCLRR_MPUP0RSTF) != 0U) {
+ INFO(" MPU Processor 0 Reset\n");
+ return;
+ }
+
+ if ((rstsr & RCC_MP_RSTSCLRR_MPUP1RSTF) != 0U) {
+ INFO(" MPU Processor 1 Reset\n");
+ return;
+ }
+
+ if ((rstsr & RCC_MP_RSTSCLRR_PADRSTF) != 0U) {
+ INFO(" Pad Reset from NRST\n");
+ return;
+ }
+
+ if ((rstsr & RCC_MP_RSTSCLRR_VCORERSTF) != 0U) {
+ INFO(" Reset due to a failure of VDD_CORE\n");
+ return;
+ }
+
+ ERROR(" Unidentified reset reason\n");
+}
+
+void bl2_el3_early_platform_setup(u_register_t arg0,
+ u_register_t arg1 __unused,
+ u_register_t arg2 __unused,
+ u_register_t arg3 __unused)
{
stm32mp1_save_boot_ctx_address(arg0);
}
@@ -59,12 +146,38 @@
void bl2_el3_plat_arch_setup(void)
{
int32_t result;
- struct dt_node_info dt_dev_info;
+ struct dt_node_info dt_uart_info;
const char *board_model;
boot_api_context_t *boot_context =
(boot_api_context_t *)stm32mp1_get_boot_ctx_address();
uint32_t clk_rate;
+ mmap_add_region(BL_CODE_BASE, BL_CODE_BASE,
+ BL_CODE_END - BL_CODE_BASE,
+ MT_CODE | MT_SECURE);
+
+ /* Prevent corruption of preloaded BL32 */
+ mmap_add_region(BL32_BASE, BL32_BASE,
+ BL32_LIMIT - BL32_BASE,
+ MT_MEMORY | MT_RO | MT_SECURE);
+
+ /* Map non secure DDR for BL33 load and DDR training area restore */
+ mmap_add_region(STM32MP1_DDR_BASE,
+ STM32MP1_DDR_BASE,
+ STM32MP1_DDR_MAX_SIZE,
+ MT_MEMORY | MT_RW | MT_NS);
+
+ /* Prevent corruption of preloaded Device Tree */
+ mmap_add_region(DTB_BASE, DTB_BASE,
+ DTB_LIMIT - DTB_BASE,
+ MT_MEMORY | MT_RO | MT_SECURE);
+
+ configure_mmu();
+
+ if (dt_open_and_check() < 0) {
+ panic();
+ }
+
/*
* Disable the backup domain write protection.
* The protection is enable at each reset by hardware
@@ -88,28 +201,8 @@
mmio_clrbits_32(RCC_BASE + RCC_BDCR, RCC_BDCR_VSWRST);
}
- mmap_add_region(BL_CODE_BASE, BL_CODE_BASE,
- BL_CODE_END - BL_CODE_BASE,
- MT_CODE | MT_SECURE);
-
- /* Prevent corruption of preloaded BL32 */
- mmap_add_region(BL32_BASE, BL32_BASE,
- BL32_LIMIT - BL32_BASE,
- MT_MEMORY | MT_RO | MT_SECURE);
-
- /* Prevent corruption of preloaded Device Tree */
- mmap_add_region(DTB_BASE, DTB_BASE,
- DTB_LIMIT - DTB_BASE,
- MT_MEMORY | MT_RO | MT_SECURE);
-
- configure_mmu();
-
generic_delay_timer_init();
- if (dt_open_and_check() < 0) {
- panic();
- }
-
if (stm32mp1_clk_probe() < 0) {
panic();
}
@@ -118,12 +211,12 @@
panic();
}
- result = dt_get_stdout_uart_info(&dt_dev_info);
+ result = dt_get_stdout_uart_info(&dt_uart_info);
if ((result <= 0) ||
- (dt_dev_info.status == 0U) ||
- (dt_dev_info.clock < 0) ||
- (dt_dev_info.reset < 0)) {
+ (dt_uart_info.status == 0U) ||
+ (dt_uart_info.clock < 0) ||
+ (dt_uart_info.reset < 0)) {
goto skip_console_init;
}
@@ -131,25 +224,25 @@
goto skip_console_init;
}
- if (stm32mp1_clk_enable((unsigned long)dt_dev_info.clock) != 0) {
+ if (stm32mp1_clk_enable((unsigned long)dt_uart_info.clock) != 0) {
goto skip_console_init;
}
- stm32mp1_reset_assert((uint32_t)dt_dev_info.reset);
+ stm32mp1_reset_assert((uint32_t)dt_uart_info.reset);
udelay(2);
- stm32mp1_reset_deassert((uint32_t)dt_dev_info.reset);
+ stm32mp1_reset_deassert((uint32_t)dt_uart_info.reset);
mdelay(1);
- clk_rate = stm32mp1_clk_get_rate((unsigned long)dt_dev_info.clock);
+ clk_rate = stm32mp1_clk_get_rate((unsigned long)dt_uart_info.clock);
- if (console_stm32_register(dt_dev_info.base, clk_rate,
+ if (console_stm32_register(dt_uart_info.base, clk_rate,
STM32MP1_UART_BAUDRATE, &console) == 0) {
panic();
}
board_model = dt_get_board_model();
if (board_model != NULL) {
- NOTICE("%s\n", board_model);
+ NOTICE("Model: %s\n", board_model);
}
skip_console_init:
@@ -162,5 +255,7 @@
stm32mp1_arch_security_setup();
+ print_reset_reason();
+
stm32mp1_io_setup();
}
diff --git a/plat/st/stm32mp1/include/platform_def.h b/plat/st/stm32mp1/include/platform_def.h
index 1b4df16..6d3d36d 100644
--- a/plat/st/stm32mp1/include/platform_def.h
+++ b/plat/st/stm32mp1/include/platform_def.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2015-2018, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2015-2019, ARM Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -30,8 +30,8 @@
#define BL33_BINARY_TYPE U(0x0)
#define STM32MP1_PRIMARY_CPU U(0x0)
+#define STM32MP1_SECONDARY_CPU U(0x1)
-#define PLATFORM_CACHE_LINE_SIZE 64
#define PLATFORM_CLUSTER_COUNT ULL(1)
#define PLATFORM_CLUSTER0_CORE_COUNT U(2)
#define PLATFORM_CLUSTER1_CORE_COUNT U(0)
@@ -39,9 +39,9 @@
PLATFORM_CLUSTER0_CORE_COUNT)
#define PLATFORM_MAX_CPUS_PER_CLUSTER 2
-#define MAX_IO_DEVICES 4
-#define MAX_IO_HANDLES 4
-#define MAX_IO_BLOCK_DEVICES 1
+#define MAX_IO_DEVICES U(4)
+#define MAX_IO_HANDLES U(4)
+#define MAX_IO_BLOCK_DEVICES U(1)
/*******************************************************************************
* BL2 specific defines.
@@ -81,8 +81,8 @@
/*******************************************************************************
* Platform specific page table and MMU setup constants
******************************************************************************/
-#define PLAT_PHY_ADDR_SPACE_SIZE (1ULL << 32)
-#define PLAT_VIRT_ADDR_SPACE_SIZE (1ULL << 32)
+#define PLAT_PHY_ADDR_SPACE_SIZE (ULL(1) << 32)
+#define PLAT_VIRT_ADDR_SPACE_SIZE (ULL(1) << 32)
/*******************************************************************************
* Declarations and constants to access the mailboxes safely. Each mailbox is
@@ -123,9 +123,6 @@
INTR_PROP_DESC(ARM_IRQ_SEC_PHY_TIMER, \
GIC_HIGHEST_SEC_PRIORITY, \
grp, GIC_INTR_CFG_LEVEL), \
- INTR_PROP_DESC(STM32MP1_IRQ_TAMPSERRS, \
- GIC_HIGHEST_SEC_PRIORITY, \
- grp, GIC_INTR_CFG_LEVEL), \
INTR_PROP_DESC(STM32MP1_IRQ_AXIERRIRQ, \
GIC_HIGHEST_SEC_PRIORITY, \
grp, GIC_INTR_CFG_LEVEL), \
diff --git a/plat/st/stm32mp1/include/stm32mp1_dt.h b/plat/st/stm32mp1/include/stm32mp1_dt.h
index 19549ee..d5640c1 100644
--- a/plat/st/stm32mp1/include/stm32mp1_dt.h
+++ b/plat/st/stm32mp1/include/stm32mp1_dt.h
@@ -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
*/
@@ -9,12 +9,16 @@
#include <stdbool.h>
+#define DT_DISABLED U(0)
+#define DT_NON_SECURE U(1)
+#define DT_SECURE U(2)
+#define DT_SHARED (DT_NON_SECURE | DT_SECURE)
+
struct dt_node_info {
uint32_t base;
int32_t clock;
int32_t reset;
- bool status;
- bool sec_status;
+ uint32_t status;
};
/*******************************************************************************
@@ -23,13 +27,11 @@
int dt_open_and_check(void);
int fdt_get_address(void **fdt_addr);
bool fdt_check_node(int node);
-bool fdt_check_status(int node);
-bool fdt_check_secure_status(int node);
+uint32_t fdt_get_status(int node);
uint32_t fdt_read_uint32_default(int node, const char *prop_name,
uint32_t dflt_value);
int fdt_read_uint32_array(int node, const char *prop_name,
uint32_t *array, uint32_t count);
-int dt_set_pinctrl_config(int node);
int dt_set_stdout_pinctrl(void);
void dt_fill_device_info(struct dt_node_info *info, int node);
int dt_get_node(struct dt_node_info *info, int offset, const char *compat);
diff --git a/plat/st/stm32mp1/include/stm32mp1_private.h b/plat/st/stm32mp1/include/stm32mp1_private.h
index 3404bc6..04c9a9a 100644
--- a/plat/st/stm32mp1/include/stm32mp1_private.h
+++ b/plat/st/stm32mp1/include/stm32mp1_private.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2015-2018, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2015-2019, ARM Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -21,4 +21,8 @@
void stm32mp1_gic_pcpu_init(void);
void stm32mp1_gic_init(void);
+uintptr_t stm32_get_gpio_bank_base(unsigned int bank);
+unsigned long stm32_get_gpio_bank_clock(unsigned int bank);
+uint32_t stm32_get_gpio_bank_offset(unsigned int bank);
+
#endif /* STM32MP1_PRIVATE_H */
diff --git a/plat/st/stm32mp1/include/stm32mp1_smc.h b/plat/st/stm32mp1/include/stm32mp1_smc.h
new file mode 100644
index 0000000..b872758
--- /dev/null
+++ b/plat/st/stm32mp1/include/stm32mp1_smc.h
@@ -0,0 +1,51 @@
+/*
+ * Copyright (c) 2016-2019, STMicroelectronics - All Rights Reserved
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef STM32MP1_SMC_H
+#define STM32MP1_SMC_H
+
+/*
+ * SMC function IDs for STM32 Service queries
+ * STM32 SMC services use the space between 0x82000000 and 0x8200FFFF
+ * like this is defined in SMC calling Convention by ARM
+ * for SiP (silicon Partner)
+ * https://developer.arm.com/docs/den0028/latest
+ */
+
+/* Secure Service access from Non-secure */
+
+/*
+ * STM32_SMC_BSEC call API
+ *
+ * Argument a0: (input) SMCC ID
+ * (output) status return code
+ * Argument a1: (input) Service ID (STM32_SMC_BSEC_xxx)
+ * Argument a2: (input) OTP index
+ * (output) OTP read value, if applicable
+ * Argument a3: (input) OTP value if applicable
+ */
+#define STM32_SMC_BSEC 0x82001003
+
+/* SMC function IDs for SiP Service queries */
+#define STM32_SIP_SVC_CALL_COUNT 0x8200ff00
+#define STM32_SIP_SVC_UID 0x8200ff01
+/* 0x8200ff02 is reserved */
+#define STM32_SIP_SVC_VERSION 0x8200ff03
+
+/* STM32 SiP Service Calls version numbers */
+#define STM32_SIP_SVC_VERSION_MAJOR 0x0
+#define STM32_SIP_SVC_VERSION_MINOR 0x1
+
+/* Number of STM32 SiP Calls implemented */
+#define STM32_COMMON_SIP_NUM_CALLS 4
+
+/* Service for BSEC */
+#define STM32_SMC_READ_SHADOW 0x01
+#define STM32_SMC_PROG_OTP 0x02
+#define STM32_SMC_WRITE_SHADOW 0x03
+#define STM32_SMC_READ_OTP 0x04
+
+#endif /* STM32MP1_SMC_H */
diff --git a/plat/st/stm32mp1/platform.mk b/plat/st/stm32mp1/platform.mk
index 60852c6..4288f23 100644
--- a/plat/st/stm32mp1/platform.mk
+++ b/plat/st/stm32mp1/platform.mk
@@ -1,5 +1,5 @@
#
-# Copyright (c) 2015-2018, ARM Limited and Contributors. All rights reserved.
+# Copyright (c) 2015-2019, ARM Limited and Contributors. All rights reserved.
#
# SPDX-License-Identifier: BSD-3-Clause
#
@@ -24,8 +24,8 @@
PLAT_INCLUDES := -Iplat/st/stm32mp1/include/
# Device tree
-STM32_DTB_FILE_NAME ?= stm32mp157c-ev1.dtb
-FDT_SOURCES := $(addprefix fdts/, $(patsubst %.dtb,%.dts,$(STM32_DTB_FILE_NAME)))
+DTB_FILE_NAME ?= stm32mp157c-ev1.dtb
+FDT_SOURCES := $(addprefix fdts/, $(patsubst %.dtb,%.dts,$(DTB_FILE_NAME)))
DTC_FLAGS += -Wno-unit_address_vs_reg
include lib/libfdt/libfdt.mk
@@ -47,13 +47,14 @@
drivers/arm/tzc/tzc400.c \
drivers/delay_timer/delay_timer.c \
drivers/delay_timer/generic_delay_timer.c \
+ drivers/st/bsec/bsec.c \
drivers/st/clk/stm32mp1_clk.c \
drivers/st/clk/stm32mp1_clkfunc.c \
drivers/st/ddr/stm32mp1_ddr_helpers.c \
drivers/st/gpio/stm32_gpio.c \
- drivers/st/pmic/stm32_i2c.c \
- drivers/st/pmic/stm32mp1_pmic.c \
- drivers/st/pmic/stpmu1.c \
+ drivers/st/i2c/stm32_i2c.c \
+ drivers/st/pmic/stm32mp_pmic.c \
+ drivers/st/pmic/stpmic1.c \
drivers/st/reset/stm32mp1_reset.c \
plat/st/stm32mp1/stm32mp1_context.c \
plat/st/stm32mp1/stm32mp1_dt.c \
@@ -82,13 +83,13 @@
# Macros and rules to build TF binary
STM32_TF_ELF_LDFLAGS := --hash-style=gnu --as-needed
-STM32_DT_BASENAME := $(STM32_DTB_FILE_NAME:.dtb=)
+STM32_DT_BASENAME := $(DTB_FILE_NAME:.dtb=)
STM32_TF_STM32 := ${BUILD_PLAT}/tf-a-${STM32_DT_BASENAME}.stm32
STM32_TF_BINARY := $(STM32_TF_STM32:.stm32=.bin)
STM32_TF_MAPFILE := $(STM32_TF_STM32:.stm32=.map)
STM32_TF_LINKERFILE := $(STM32_TF_STM32:.stm32=.ld)
STM32_TF_ELF := $(STM32_TF_STM32:.stm32=.elf)
-STM32_TF_DTBFILE := ${BUILD_PLAT}/fdts/${STM32_DTB_FILE_NAME}
+STM32_TF_DTBFILE := ${BUILD_PLAT}/fdts/${DTB_FILE_NAME}
STM32_TF_OBJS := ${BUILD_PLAT}/stm32mp1.o
# Variables for use with stm32image
@@ -131,7 +132,7 @@
-DDTB_BIN_PATH=\"${STM32_TF_DTBFILE}\" \
-c plat/st/stm32mp1/stm32mp1.S -o $@
-${STM32_TF_LINKERFILE}: plat/st/stm32mp1/stm32mp1.ld.S
+${STM32_TF_LINKERFILE}: plat/st/stm32mp1/stm32mp1.ld.S ${BUILD_PLAT}
@echo " LDS $<"
${Q}${AS} ${ASFLAGS} ${TF_CFLAGS} -P -E $< -o $@
diff --git a/plat/st/stm32mp1/services/bsec_svc.c b/plat/st/stm32mp1/services/bsec_svc.c
new file mode 100644
index 0000000..2a60e43
--- /dev/null
+++ b/plat/st/stm32mp1/services/bsec_svc.c
@@ -0,0 +1,60 @@
+/*
+ * Copyright (c) 2016-2019, STMicroelectronics - All Rights Reserved
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <platform_def.h>
+
+#include <common/debug.h>
+#include <drivers/st/bsec.h>
+
+#include <stm32mp1_smc.h>
+
+#include "bsec_svc.h"
+
+uint32_t bsec_main(uint32_t x1, uint32_t x2, uint32_t x3,
+ uint32_t *ret_otp_value)
+{
+ uint32_t result;
+ uint32_t tmp_data = 0U;
+
+ switch (x1) {
+ case STM32_SMC_READ_SHADOW:
+ result = bsec_read_otp(ret_otp_value, x2);
+ break;
+ case STM32_SMC_PROG_OTP:
+ *ret_otp_value = 0U;
+ result = bsec_program_otp(x3, x2);
+ break;
+ case STM32_SMC_WRITE_SHADOW:
+ *ret_otp_value = 0;
+ result = bsec_write_otp(x3, x2);
+ break;
+ case STM32_SMC_READ_OTP:
+ *ret_otp_value = 0;
+ result = bsec_read_otp(&tmp_data, x2);
+ if (result != BSEC_OK) {
+ break;
+ }
+
+ result = bsec_shadow_register(x2);
+ if (result != BSEC_OK) {
+ break;
+ }
+
+ result = bsec_read_otp(ret_otp_value, x2);
+ if (result != BSEC_OK) {
+ break;
+ }
+
+ result = bsec_write_otp(tmp_data, x2);
+ break;
+
+ default:
+ result = BSEC_ERROR;
+ break;
+ }
+
+ return result;
+}
diff --git a/plat/st/stm32mp1/services/bsec_svc.h b/plat/st/stm32mp1/services/bsec_svc.h
new file mode 100644
index 0000000..06752ef
--- /dev/null
+++ b/plat/st/stm32mp1/services/bsec_svc.h
@@ -0,0 +1,19 @@
+/*
+ * Copyright (c) 2016-2019, STMicroelectronics - All Rights Reserved
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef BSEC_SVC_H
+#define BSEC_SVC_H
+
+#include <stdint.h>
+
+/* version of this service */
+/* must be increase at each structure modification */
+#define BSEC_SERVICE_VERSION 0x01U
+
+uint32_t bsec_main(uint32_t x1, uint32_t x2, uint32_t x3,
+ uint32_t *ret_otp_value);
+
+#endif /* BSEC_SVC_H */
diff --git a/plat/st/stm32mp1/services/stm32mp1_svc_setup.c b/plat/st/stm32mp1/services/stm32mp1_svc_setup.c
new file mode 100644
index 0000000..72af9ff
--- /dev/null
+++ b/plat/st/stm32mp1/services/stm32mp1_svc_setup.c
@@ -0,0 +1,92 @@
+/*
+ * Copyright (c) 2014-2019, STMicroelectronics - All Rights Reserved
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <stdbool.h>
+#include <stdint.h>
+
+#include <common/debug.h>
+#include <common/runtime_svc.h>
+#include <lib/psci/psci.h>
+#include <tools_share/uuid.h>
+
+#include <stm32mp1_smc.h>
+
+#include "bsec_svc.h"
+
+/* STM32 SiP Service UUID */
+DEFINE_SVC_UUID2(stm32_sip_svc_uid,
+ 0xa778aa50, 0xf49b, 0x144a, 0x8a, 0x5e,
+ 0x26, 0x4d, 0x59, 0x94, 0xc2, 0x14);
+
+/* Setup STM32MP1 Standard Services */
+static int32_t stm32mp1_svc_setup(void)
+{
+ /*
+ * PSCI is the only specification implemented as a Standard Service.
+ * Invoke PSCI setup from here.
+ */
+ return 0;
+}
+
+/*
+ * Top-level Standard Service SMC handler. This handler will in turn dispatch
+ * calls to PSCI SMC handler.
+ */
+static uintptr_t stm32mp1_svc_smc_handler(uint32_t smc_fid, u_register_t x1,
+ u_register_t x2, u_register_t x3,
+ u_register_t x4, void *cookie,
+ void *handle, u_register_t flags)
+{
+ uint32_t ret1 = 0U, ret2 = 0U;
+ bool ret_uid = false, ret2_enabled = false;
+
+ switch (smc_fid) {
+ case STM32_SIP_SVC_CALL_COUNT:
+ ret1 = STM32_COMMON_SIP_NUM_CALLS;
+ break;
+
+ case STM32_SIP_SVC_UID:
+ /* Return UUID to the caller */
+ ret_uid = true;
+ break;
+
+ case STM32_SIP_SVC_VERSION:
+ /* Return the version of current implementation */
+ ret1 = STM32_SIP_SVC_VERSION_MAJOR;
+ ret2 = STM32_SIP_SVC_VERSION_MINOR;
+ ret2_enabled = true;
+ break;
+
+ case STM32_SMC_BSEC:
+ ret1 = bsec_main(x1, x2, x3, &ret2);
+ ret2_enabled = true;
+ break;
+
+ default:
+ WARN("Unimplemented STM32MP1 Service Call: 0x%x\n", smc_fid);
+ ret1 = SMC_UNK;
+ break;
+ }
+
+ if (ret_uid) {
+ SMC_UUID_RET(handle, stm32_sip_svc_uid);
+ }
+
+ if (ret2_enabled) {
+ SMC_RET2(handle, ret1, ret2);
+ }
+
+ SMC_RET1(handle, ret1);
+}
+
+/* Register Standard Service Calls as runtime service */
+DECLARE_RT_SVC(stm32mp1_sip_svc,
+ OEN_SIP_START,
+ OEN_SIP_END,
+ SMC_TYPE_FAST,
+ stm32mp1_svc_setup,
+ stm32mp1_svc_smc_handler
+);
diff --git a/plat/st/stm32mp1/sp_min/sp_min-stm32mp1.mk b/plat/st/stm32mp1/sp_min/sp_min-stm32mp1.mk
index 9fde153..4188cc5 100644
--- a/plat/st/stm32mp1/sp_min/sp_min-stm32mp1.mk
+++ b/plat/st/stm32mp1/sp_min/sp_min-stm32mp1.mk
@@ -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
#
@@ -19,3 +19,7 @@
# Generic PSCI
BL32_SOURCES += plat/common/plat_psci_common.c
+
+# stm32mp1 specific services
+BL32_SOURCES += plat/st/stm32mp1/services/bsec_svc.c \
+ plat/st/stm32mp1/services/stm32mp1_svc_setup.c
diff --git a/plat/st/stm32mp1/sp_min/sp_min_setup.c b/plat/st/stm32mp1/sp_min/sp_min_setup.c
index f541379..0d76fb7 100644
--- a/plat/st/stm32mp1/sp_min/sp_min_setup.c
+++ b/plat/st/stm32mp1/sp_min/sp_min_setup.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2015-2018, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2015-2019, ARM Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -13,9 +13,12 @@
#include <common/bl_common.h>
#include <common/debug.h>
#include <context.h>
+#include <drivers/arm/gicv2.h>
#include <drivers/arm/tzc400.h>
#include <drivers/generic_delay_timer.h>
+#include <drivers/st/bsec.h>
#include <drivers/st/stm32_console.h>
+#include <drivers/st/stm32_gpio.h>
#include <drivers/st/stm32mp1_clk.h>
#include <dt-bindings/clock/stm32mp1-clks.h>
#include <lib/el3_runtime/context_mgmt.h>
@@ -40,7 +43,7 @@
******************************************************************************/
void sp_min_plat_fiq_handler(uint32_t id)
{
- switch (id) {
+ switch (id & INT_ID_MASK) {
case STM32MP1_IRQ_TZC400:
ERROR("STM32MP1_IRQ_TZC400 generated\n");
panic();
@@ -50,7 +53,7 @@
panic();
break;
default:
- ERROR("SECURE IT handler not define for it : %i", id);
+ ERROR("SECURE IT handler not define for it : %u", id);
break;
}
}
@@ -80,7 +83,7 @@
void sp_min_early_platform_setup2(u_register_t arg0, u_register_t arg1,
u_register_t arg2, u_register_t arg3)
{
- struct dt_node_info dt_dev_info;
+ struct dt_node_info dt_uart_info;
int result;
bl_params_t *params_from_bl2 = (bl_params_t *)arg0;
@@ -110,14 +113,18 @@
panic();
}
+ if (bsec_probe() != 0) {
+ panic();
+ }
+
if (stm32mp1_clk_probe() < 0) {
panic();
}
- result = dt_get_stdout_uart_info(&dt_dev_info);
+ result = dt_get_stdout_uart_info(&dt_uart_info);
- if ((result > 0) && dt_dev_info.status) {
- if (console_stm32_register(dt_dev_info.base, 0,
+ if ((result > 0) && (dt_uart_info.status != 0U)) {
+ if (console_stm32_register(dt_uart_info.base, 0,
STM32MP1_UART_BAUDRATE, &console) ==
0) {
panic();
@@ -142,6 +149,16 @@
generic_delay_timer_init();
stm32mp1_gic_init();
+
+ /* Unlock ETZPC securable peripherals */
+#define STM32MP1_ETZPC_BASE 0x5C007000U
+#define ETZPC_DECPROT0 0x010U
+ mmio_write_32(STM32MP1_ETZPC_BASE + ETZPC_DECPROT0, 0xFFFFFFFF);
+
+ /* Set GPIO bank Z as non secure */
+ for (uint32_t pin = 0U; pin < STM32MP_GPIOZ_PIN_MAX_COUNT; pin++) {
+ set_gpio_secure_cfg(GPIO_BANK_Z, pin, false);
+ }
}
void sp_min_plat_arch_setup(void)
diff --git a/plat/st/stm32mp1/stm32mp1_common.c b/plat/st/stm32mp1/stm32mp1_common.c
index b54f313..cd93d2e 100644
--- a/plat/st/stm32mp1/stm32mp1_common.c
+++ b/plat/st/stm32mp1/stm32mp1_common.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2015-2018, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2015-2019, ARM Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -12,6 +12,7 @@
#include <common/bl_common.h>
#include <common/debug.h>
#include <drivers/arm/gicv2.h>
+#include <dt-bindings/clock/stm32mp1-clks.h>
#include <lib/mmio.h>
#include <lib/xlat_tables/xlat_tables_v2.h>
#include <plat/common/platform.h>
@@ -39,26 +40,11 @@
MT_SECURE | \
MT_EXECUTE_NEVER)
-#define MAP_DDR MAP_REGION_FLAT(STM32MP1_DDR_BASE, \
- STM32MP1_DDR_MAX_SIZE, \
- MT_MEMORY | \
- MT_RW | \
- MT_SECURE | \
- MT_EXECUTE_NEVER)
-
-#define MAP_DDR_NS MAP_REGION_FLAT(STM32MP1_DDR_BASE, \
- STM32MP1_DDR_MAX_SIZE, \
- MT_MEMORY | \
- MT_RW | \
- MT_NS | \
- MT_EXECUTE_NEVER)
-
#if defined(IMAGE_BL2)
static const mmap_region_t stm32mp1_mmap[] = {
MAP_SRAM,
MAP_DEVICE1,
MAP_DEVICE2,
- MAP_DDR,
{0}
};
#endif
@@ -67,7 +53,6 @@
MAP_SRAM,
MAP_DEVICE1,
MAP_DEVICE2,
- MAP_DDR_NS,
{0}
};
#endif
@@ -102,3 +87,37 @@
{
return boot_ctx_address;
}
+
+uintptr_t stm32_get_gpio_bank_base(unsigned int bank)
+{
+ switch (bank) {
+ case GPIO_BANK_A ... GPIO_BANK_K:
+ return GPIOA_BASE + (bank * GPIO_BANK_OFFSET);
+ case GPIO_BANK_Z:
+ return GPIOZ_BASE;
+ default:
+ panic();
+ }
+}
+
+/* Return clock ID on success, negative value on error */
+unsigned long stm32_get_gpio_bank_clock(unsigned int bank)
+{
+ switch (bank) {
+ case GPIO_BANK_A ... GPIO_BANK_K:
+ return GPIOA + (bank - GPIO_BANK_A);
+ case GPIO_BANK_Z:
+ return GPIOZ;
+ default:
+ panic();
+ }
+}
+
+uint32_t stm32_get_gpio_bank_offset(unsigned int bank)
+{
+ if (bank == GPIO_BANK_Z) {
+ return 0;
+ } else {
+ return bank * GPIO_BANK_OFFSET;
+ }
+}
diff --git a/plat/st/stm32mp1/stm32mp1_def.h b/plat/st/stm32mp1/stm32mp1_def.h
index 15f0432..8cd5aeb 100644
--- a/plat/st/stm32mp1/stm32mp1_def.h
+++ b/plat/st/stm32mp1/stm32mp1_def.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2015-2018, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2015-2019, ARM Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -112,6 +112,39 @@
#define PWR_BASE U(0x50001000)
/*******************************************************************************
+ * STM32MP1 GPIO
+ ******************************************************************************/
+#define GPIOA_BASE U(0x50002000)
+#define GPIOB_BASE U(0x50003000)
+#define GPIOC_BASE U(0x50004000)
+#define GPIOD_BASE U(0x50005000)
+#define GPIOE_BASE U(0x50006000)
+#define GPIOF_BASE U(0x50007000)
+#define GPIOG_BASE U(0x50008000)
+#define GPIOH_BASE U(0x50009000)
+#define GPIOI_BASE U(0x5000A000)
+#define GPIOJ_BASE U(0x5000B000)
+#define GPIOK_BASE U(0x5000C000)
+#define GPIOZ_BASE U(0x54004000)
+#define GPIO_BANK_OFFSET U(0x1000)
+
+/* Bank IDs used in GPIO driver API */
+#define GPIO_BANK_A U(0)
+#define GPIO_BANK_B U(1)
+#define GPIO_BANK_C U(2)
+#define GPIO_BANK_D U(3)
+#define GPIO_BANK_E U(4)
+#define GPIO_BANK_F U(5)
+#define GPIO_BANK_G U(6)
+#define GPIO_BANK_H U(7)
+#define GPIO_BANK_I U(8)
+#define GPIO_BANK_J U(9)
+#define GPIO_BANK_K U(10)
+#define GPIO_BANK_Z U(25)
+
+#define STM32MP_GPIOZ_PIN_MAX_COUNT 8
+
+/*******************************************************************************
* STM32MP1 UART
******************************************************************************/
#define USART1_BASE U(0x5C000000)
@@ -122,16 +155,21 @@
#define USART6_BASE U(0x44003000)
#define UART7_BASE U(0x40018000)
#define UART8_BASE U(0x40019000)
-#define STM32MP1_DEBUG_USART_BASE UART4_BASE
-#define STM32MP1_UART_BAUDRATE 115200
+#define STM32MP1_UART_BAUDRATE U(115200)
-/*******************************************************************************
- * STM32MP1 GIC-400
- ******************************************************************************/
-#define STM32MP1_GICD_BASE U(0xA0021000)
-#define STM32MP1_GICC_BASE U(0xA0022000)
-#define STM32MP1_GICH_BASE U(0xA0024000)
-#define STM32MP1_GICV_BASE U(0xA0026000)
+/* For UART crash console */
+#define STM32MP1_DEBUG_USART_BASE UART4_BASE
+/* UART4 on HSI@64MHz, TX on GPIOG11 Alternate 6 */
+#define STM32MP1_DEBUG_USART_CLK_FRQ 64000000
+#define DEBUG_UART_TX_GPIO_BANK_ADDRESS GPIOG_BASE
+#define DEBUG_UART_TX_GPIO_BANK_CLK_REG RCC_MP_AHB4ENSETR
+#define DEBUG_UART_TX_GPIO_BANK_CLK_EN RCC_MP_AHB4ENSETR_GPIOGEN
+#define DEBUG_UART_TX_GPIO_PORT 11
+#define DEBUG_UART_TX_GPIO_ALTERNATE 6
+#define DEBUG_UART_TX_CLKSRC_REG RCC_UART24CKSELR
+#define DEBUG_UART_TX_CLKSRC RCC_UART24CKSELR_HSI
+#define DEBUG_UART_TX_EN_REG RCC_MP_APB1ENSETR
+#define DEBUG_UART_TX_EN RCC_MP_APB1ENSETR_UART4EN
/*******************************************************************************
* STM32MP1 TZC (TZ400)
@@ -149,10 +187,7 @@
#define STM32MP1_TZC_ETH_ID U(10)
#define STM32MP1_TZC_DAP_ID U(15)
-#define STM32MP1_MEMORY_NS 0
-#define STM32MP1_MEMORY_SECURE 1
-
-#define STM32MP1_FILTER_BIT_ALL 3
+#define STM32MP1_FILTER_BIT_ALL U(3)
/*******************************************************************************
* STM32MP1 SDMMC
@@ -168,6 +203,21 @@
#define STM32MP1_EMMC_HIGH_SPEED_MAX_FREQ 52000000 /*52 MHz*/
/*******************************************************************************
+ * STM32MP1 BSEC / OTP
+ ******************************************************************************/
+#define STM32MP1_OTP_MAX_ID 0x5FU
+#define STM32MP1_UPPER_OTP_START 0x20U
+
+#define OTP_MAX_SIZE (STM32MP1_OTP_MAX_ID + 1U)
+
+/* OTP offsets */
+#define DATA0_OTP U(0)
+
+/* OTP mask */
+/* DATA0 */
+#define DATA0_OTP_SECURED BIT(6)
+
+/*******************************************************************************
* STM32MP1 TAMP
******************************************************************************/
#define TAMP_BASE U(0x5C00A000)
diff --git a/plat/st/stm32mp1/stm32mp1_dt.c b/plat/st/stm32mp1/stm32mp1_dt.c
index 29e936a..8493b87 100644
--- a/plat/st/stm32mp1/stm32mp1_dt.c
+++ b/plat/st/stm32mp1/stm32mp1_dt.c
@@ -1,10 +1,11 @@
/*
- * 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
*/
#include <assert.h>
+#include <errno.h>
#include <libfdt.h>
@@ -17,135 +18,13 @@
#include <drivers/st/stm32mp1_ddr.h>
#include <drivers/st/stm32mp1_ram.h>
-#include <stm32mp1_dt.h>
-
-#define DT_GPIO_BANK_SHIFT 12
-#define DT_GPIO_BANK_MASK 0x1F000U
-#define DT_GPIO_PIN_SHIFT 8
-#define DT_GPIO_PIN_MASK 0xF00U
-#define DT_GPIO_MODE_MASK 0xFFU
-
static int fdt_checked;
static void *fdt = (void *)(uintptr_t)STM32MP1_DTB_BASE;
/*******************************************************************************
- * This function gets the pin settings from DT information.
- * When analyze and parsing is done, set the GPIO registers.
- * Return 0 on success, else return a negative FDT_ERR_xxx error code.
- ******************************************************************************/
-static int dt_set_gpio_config(int node)
-{
- const fdt32_t *cuint, *slewrate;
- int len, pinctrl_node, pinctrl_subnode;
- uint32_t i;
- uint32_t speed = GPIO_SPEED_LOW;
- uint32_t pull = GPIO_NO_PULL;
-
- cuint = fdt_getprop(fdt, node, "pinmux", &len);
- if (cuint == NULL) {
- return -FDT_ERR_NOTFOUND;
- }
-
- pinctrl_node = fdt_parent_offset(fdt, fdt_parent_offset(fdt, node));
- if (pinctrl_node < 0) {
- return -FDT_ERR_NOTFOUND;
- }
-
- slewrate = fdt_getprop(fdt, node, "slew-rate", NULL);
- if (slewrate != NULL) {
- speed = fdt32_to_cpu(*slewrate);
- }
-
- if (fdt_getprop(fdt, node, "bias-pull-up", NULL) != NULL) {
- pull = GPIO_PULL_UP;
- } else if (fdt_getprop(fdt, node, "bias-pull-down", NULL) != NULL) {
- pull = GPIO_PULL_DOWN;
- } else {
- VERBOSE("No bias configured in node %d\n", node);
- }
-
- for (i = 0; i < ((uint32_t)len / sizeof(uint32_t)); i++) {
- uint32_t pincfg;
- uint32_t bank;
- uint32_t pin;
- uint32_t mode;
- uint32_t alternate = GPIO_ALTERNATE_0;
-
- pincfg = fdt32_to_cpu(*cuint);
- cuint++;
-
- bank = (pincfg & DT_GPIO_BANK_MASK) >> DT_GPIO_BANK_SHIFT;
-
- pin = (pincfg & DT_GPIO_PIN_MASK) >> DT_GPIO_PIN_SHIFT;
-
- mode = pincfg & DT_GPIO_MODE_MASK;
-
- switch (mode) {
- case 0:
- mode = GPIO_MODE_INPUT;
- break;
- case 1 ... 16:
- alternate = mode - 1U;
- mode = GPIO_MODE_ALTERNATE;
- break;
- case 17:
- mode = GPIO_MODE_ANALOG;
- break;
- default:
- mode = GPIO_MODE_OUTPUT;
- break;
- }
-
- if (fdt_getprop(fdt, node, "drive-open-drain", NULL) != NULL) {
- mode |= GPIO_OPEN_DRAIN;
- }
-
- fdt_for_each_subnode(pinctrl_subnode, fdt, pinctrl_node) {
- uint32_t bank_offset;
- const fdt32_t *cuint2;
-
- if (fdt_getprop(fdt, pinctrl_subnode,
- "gpio-controller", NULL) == NULL) {
- continue;
- }
-
- cuint2 = fdt_getprop(fdt, pinctrl_subnode, "reg", NULL);
- if (cuint2 == NULL) {
- continue;
- }
-
- if (bank == GPIO_BANK_Z) {
- bank_offset = 0;
- } else {
- bank_offset = bank * STM32_GPIO_BANK_OFFSET;
- }
-
- if (fdt32_to_cpu(*cuint2) == bank_offset) {
- int clk_id = fdt_get_clock_id(pinctrl_subnode);
-
- if (clk_id < 0) {
- return -FDT_ERR_NOTFOUND;
- }
-
- if (stm32mp1_clk_enable((unsigned long)clk_id) <
- 0) {
- return -FDT_ERR_BADVALUE;
- }
-
- break;
- }
- }
-
- set_gpio(bank, pin, mode, speed, pull, alternate);
- }
-
- return 0;
-}
-
-/*******************************************************************************
* This function checks device tree file with its header.
- * Returns 0 if success, and a negative value else.
+ * Returns 0 on success and a negative FDT error code on failure.
******************************************************************************/
int dt_open_and_check(void)
{
@@ -174,7 +53,7 @@
/*******************************************************************************
* This function check the presence of a node (generic use of fdt library).
- * Returns true if present, false else.
+ * Returns true if present, else return false.
******************************************************************************/
bool fdt_check_node(int node)
{
@@ -187,37 +66,30 @@
}
/*******************************************************************************
- * This function check the status of a node (generic use of fdt library).
- * Returns true if "okay" or missing, false else.
+ * This function return global node status (generic use of fdt library).
******************************************************************************/
-bool fdt_check_status(int node)
+uint32_t fdt_get_status(int node)
{
+ uint32_t status = DT_DISABLED;
int len;
const char *cchar;
cchar = fdt_getprop(fdt, node, "status", &len);
- if (cchar == NULL) {
- return true;
+ if ((cchar == NULL) ||
+ (strncmp(cchar, "okay", (size_t)len) == 0)) {
+ status |= DT_NON_SECURE;
}
- return strncmp(cchar, "okay", (size_t)len) == 0;
-}
-
-/*******************************************************************************
- * This function check the secure-status of a node (generic use of fdt library).
- * Returns true if "okay" or missing, false else.
- ******************************************************************************/
-bool fdt_check_secure_status(int node)
-{
- int len;
- const char *cchar;
-
cchar = fdt_getprop(fdt, node, "secure-status", &len);
if (cchar == NULL) {
- return true;
+ if (status == DT_NON_SECURE) {
+ status |= DT_SECURE;
+ }
+ } else if (strncmp(cchar, "okay", (size_t)len) == 0) {
+ status |= DT_SECURE;
}
- return strncmp(cchar, "okay", (size_t)len) == 0;
+ return status;
}
/*******************************************************************************
@@ -245,7 +117,7 @@
* (generic use of fdt library).
* It reads the values inside the device tree, from property name and node.
* The number of parameters is also indicated as entry parameter.
- * Returns 0 if success, and a negative value else.
+ * Returns 0 on success and a negative FDT error code on failure.
* If success, values are stored at the third parameter address.
******************************************************************************/
int fdt_read_uint32_array(int node, const char *prop_name, uint32_t *array,
@@ -274,52 +146,9 @@
}
/*******************************************************************************
- * This function gets the pin settings from DT information.
- * When analyze and parsing is done, set the GPIO registers.
- * Returns 0 if success, and a negative value else.
- ******************************************************************************/
-int dt_set_pinctrl_config(int node)
-{
- const fdt32_t *cuint;
- int lenp = 0;
- uint32_t i;
-
- if (!fdt_check_status(node)) {
- return -FDT_ERR_NOTFOUND;
- }
-
- cuint = fdt_getprop(fdt, node, "pinctrl-0", &lenp);
- if (cuint == NULL) {
- return -FDT_ERR_NOTFOUND;
- }
-
- for (i = 0; i < ((uint32_t)lenp / 4U); i++) {
- int phandle_node, phandle_subnode;
-
- phandle_node =
- fdt_node_offset_by_phandle(fdt, fdt32_to_cpu(*cuint));
- if (phandle_node < 0) {
- return -FDT_ERR_NOTFOUND;
- }
-
- fdt_for_each_subnode(phandle_subnode, fdt, phandle_node) {
- int ret = dt_set_gpio_config(phandle_subnode);
-
- if (ret < 0) {
- return ret;
- }
- }
-
- cuint++;
- }
-
- return 0;
-}
-
-/*******************************************************************************
* This function gets the stdout pin configuration information from the DT.
* And then calls the sub-function to treat it and set GPIO registers.
- * Returns 0 if success, and a negative value else.
+ * Returns 0 on success and a negative FDT error code on failure.
******************************************************************************/
int dt_set_stdout_pinctrl(void)
{
@@ -363,13 +192,12 @@
info->reset = -1;
}
- info->status = fdt_check_status(node);
- info->sec_status = fdt_check_secure_status(node);
+ info->status = fdt_get_status(node);
}
/*******************************************************************************
* This function retrieve the generic information from DT.
- * Returns node if success, and a negative value else.
+ * Returns node on success and a negative FDT error code on failure.
******************************************************************************/
int dt_get_node(struct dt_node_info *info, int offset, const char *compat)
{
@@ -387,7 +215,7 @@
/*******************************************************************************
* This function gets the UART instance info of stdout from the DT.
- * Returns node if success, and a negative value else.
+ * Returns node on success and a negative FDT error code on failure.
******************************************************************************/
int dt_get_stdout_uart_info(struct dt_node_info *info)
{
@@ -448,7 +276,7 @@
/*******************************************************************************
* This function gets DDR size information from the DT.
- * Returns value in bytes if success, and STM32MP1_DDR_SIZE_DFLT else.
+ * Returns value in bytes on success, and 0 on failure.
******************************************************************************/
uint32_t dt_get_ddr_size(void)
{
@@ -457,11 +285,10 @@
node = fdt_node_offset_by_compatible(fdt, -1, DT_DDR_COMPAT);
if (node < 0) {
INFO("%s: Cannot read DDR node in DT\n", __func__);
- return STM32MP1_DDR_SIZE_DFLT;
+ return 0;
}
- return fdt_read_uint32_default(node, "st,mem-size",
- STM32MP1_DDR_SIZE_DFLT);
+ return fdt_read_uint32_default(node, "st,mem-size", 0);
}
/*******************************************************************************
diff --git a/plat/st/stm32mp1/stm32mp1_gic.c b/plat/st/stm32mp1/stm32mp1_gic.c
index fabed37..becb925 100644
--- a/plat/st/stm32mp1/stm32mp1_gic.c
+++ b/plat/st/stm32mp1/stm32mp1_gic.c
@@ -1,18 +1,28 @@
/*
- * Copyright (c) 2016-2018, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2016-2019, ARM Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
+#include <libfdt.h>
+
#include <platform_def.h>
#include <common/bl_common.h>
+#include <common/debug.h>
#include <drivers/arm/gicv2.h>
+#include <dt-bindings/interrupt-controller/arm-gic.h>
#include <lib/utils.h>
#include <plat/common/platform.h>
+#include <stm32mp1_dt.h>
#include <stm32mp1_private.h>
+struct stm32_gic_instance {
+ uint32_t cells;
+ uint32_t phandle_node;
+};
+
/******************************************************************************
* On a GICv2 system, the Group 1 secure interrupts are treated as Group 0
* interrupts.
@@ -22,19 +32,55 @@
PLATFORM_G0_PROPS(GICV2_INTR_GROUP0)
};
-static unsigned int target_mask_array[PLATFORM_CORE_COUNT];
+/* Fix target_mask_array as secondary core is not able to initialize it */
+static unsigned int target_mask_array[PLATFORM_CORE_COUNT] = {1, 2};
-static const gicv2_driver_data_t platform_gic_data = {
- .gicd_base = STM32MP1_GICD_BASE,
- .gicc_base = STM32MP1_GICC_BASE,
+static gicv2_driver_data_t platform_gic_data = {
.interrupt_props = stm32mp1_interrupt_props,
.interrupt_props_num = ARRAY_SIZE(stm32mp1_interrupt_props),
.target_masks = target_mask_array,
.target_masks_num = ARRAY_SIZE(target_mask_array),
};
+static struct stm32_gic_instance stm32_gic;
+
void stm32mp1_gic_init(void)
{
+ int node;
+ void *fdt;
+ const fdt32_t *cuint;
+ struct dt_node_info dt_gic;
+
+ if (fdt_get_address(&fdt) == 0) {
+ panic();
+ }
+
+ node = dt_get_node(&dt_gic, -1, "arm,cortex-a7-gic");
+ if (node < 0) {
+ panic();
+ }
+
+ platform_gic_data.gicd_base = dt_gic.base;
+
+ cuint = fdt_getprop(fdt, node, "reg", NULL);
+ if (cuint == NULL) {
+ panic();
+ }
+
+ platform_gic_data.gicc_base = fdt32_to_cpu(*(cuint + 2));
+
+ cuint = fdt_getprop(fdt, node, "#interrupt-cells", NULL);
+ if (cuint == NULL) {
+ panic();
+ }
+
+ stm32_gic.cells = fdt32_to_cpu(*cuint);
+
+ stm32_gic.phandle_node = fdt_get_phandle(fdt, node);
+ if (stm32_gic.phandle_node == 0U) {
+ panic();
+ }
+
gicv2_driver_init(&platform_gic_data);
gicv2_distif_init();
diff --git a/plat/st/stm32mp1/stm32mp1_helper.S b/plat/st/stm32mp1/stm32mp1_helper.S
index 61c587f..8c2e1b6 100644
--- a/plat/st/stm32mp1/stm32mp1_helper.S
+++ b/plat/st/stm32mp1/stm32mp1_helper.S
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2015-2018, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2015-2019, ARM Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -12,11 +12,8 @@
#include <drivers/st/stm32_gpio.h>
#include <drivers/st/stm32mp1_rcc.h>
-#define GPIO_BANK_G_ADDRESS 0x50008000
-#define GPIO_TX_PORT 11
-#define GPIO_TX_SHIFT (GPIO_TX_PORT << 1)
-#define GPIO_TX_ALT_SHIFT ((GPIO_TX_PORT - GPIO_ALT_LOWER_LIMIT) << 2)
-#define STM32MP1_HSI_CLK 64000000
+#define GPIO_TX_SHIFT (DEBUG_UART_TX_GPIO_PORT << 1)
+#define GPIO_TX_ALT_SHIFT ((DEBUG_UART_TX_GPIO_PORT - GPIO_ALT_LOWER_LIMIT) << 2)
.globl platform_mem_init
.globl plat_report_exception
@@ -112,13 +109,13 @@
* ---------------------------------------------
*/
func plat_crash_console_init
- /* Enable GPIOs for UART4 TX */
- ldr r1, =(RCC_BASE + RCC_MP_AHB4ENSETR)
+ /* Enable GPIOs for UART TX */
+ ldr r1, =(RCC_BASE + DEBUG_UART_TX_GPIO_BANK_CLK_REG)
ldr r2, [r1]
- /* Configure GPIO G11 */
- orr r2, r2, #RCC_MP_AHB4ENSETR_GPIOGEN
+ /* Configure GPIO */
+ orr r2, r2, #DEBUG_UART_TX_GPIO_BANK_CLK_EN
str r2, [r1]
- ldr r1, =GPIO_BANK_G_ADDRESS
+ ldr r1, =DEBUG_UART_TX_GPIO_BANK_ADDRESS
/* Set GPIO mode alternate */
ldr r2, [r1, #GPIO_MODE_OFFSET]
bic r2, r2, #(GPIO_MODE_MASK << GPIO_TX_SHIFT)
@@ -132,23 +129,22 @@
ldr r2, [r1, #GPIO_PUPD_OFFSET]
bic r2, r2, #(GPIO_PULL_MASK << GPIO_TX_SHIFT)
str r2, [r1, #GPIO_PUPD_OFFSET]
- /* Set alternate AF6 */
+ /* Set alternate */
ldr r2, [r1, #GPIO_AFRH_OFFSET]
bic r2, r2, #(GPIO_ALTERNATE_MASK << GPIO_TX_ALT_SHIFT)
- orr r2, r2, #(GPIO_ALTERNATE_6 << GPIO_TX_ALT_SHIFT)
+ orr r2, r2, #(DEBUG_UART_TX_GPIO_ALTERNATE << GPIO_TX_ALT_SHIFT)
str r2, [r1, #GPIO_AFRH_OFFSET]
-
- /* Enable UART clock, with HSI source */
- ldr r1, =(RCC_BASE + RCC_UART24CKSELR)
- mov r2, #RCC_UART24CKSELR_HSI
+ /* Enable UART clock, with its source */
+ ldr r1, =(RCC_BASE + DEBUG_UART_TX_CLKSRC_REG)
+ mov r2, #DEBUG_UART_TX_CLKSRC
str r2, [r1]
- ldr r1, =(RCC_BASE + RCC_MP_APB1ENSETR)
+ ldr r1, =(RCC_BASE + DEBUG_UART_TX_EN_REG)
ldr r2, [r1]
- orr r2, r2, #RCC_MP_APB1ENSETR_UART4EN
+ orr r2, r2, #DEBUG_UART_TX_EN
str r2, [r1]
ldr r0, =STM32MP1_DEBUG_USART_BASE
- ldr r1, =STM32MP1_HSI_CLK
+ ldr r1, =STM32MP1_DEBUG_USART_CLK_FRQ
ldr r2, =STM32MP1_UART_BAUDRATE
b console_stm32_core_init
endfunc plat_crash_console_init
diff --git a/plat/st/stm32mp1/stm32mp1_pm.c b/plat/st/stm32mp1/stm32mp1_pm.c
index 85189ff..c0e9c4e 100644
--- a/plat/st/stm32mp1/stm32mp1_pm.c
+++ b/plat/st/stm32mp1/stm32mp1_pm.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2015-2018, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2015-2019, ARM Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -23,11 +23,9 @@
#include <boot_api.h>
#include <stm32mp1_private.h>
-static uint32_t stm32_sec_entrypoint;
+static uintptr_t stm32_sec_entrypoint;
static uint32_t cntfrq_core0;
-#define SEND_SECURE_IT_TO_CORE_1 0x20000U
-
/*******************************************************************************
* STM32MP1 handler called when a CPU is about to enter standby.
* call by core 1 to enter in wfi
@@ -42,6 +40,7 @@
* Enter standby state
* dsb is good practice before using wfi to enter low power states
*/
+ isb();
dsb();
while (interrupt == GIC_SPURIOUS_INTERRUPT) {
wfi();
@@ -59,7 +58,7 @@
/*******************************************************************************
* STM32MP1 handler called when a power domain is about to be turned on. The
* mpidr determines the CPU to be turned on.
- * call by core 0 to activate core 1
+ * call by core 0 to activate core 1
******************************************************************************/
static int stm32_pwr_domain_on(u_register_t mpidr)
{
@@ -102,8 +101,7 @@
}
/* Generate an IT to core 1 */
- mmio_write_32(STM32MP1_GICD_BASE + GICD_SGIR,
- SEND_SECURE_IT_TO_CORE_1 | ARM_IRQ_SEC_SGI_0);
+ gicv2_raise_sgi(ARM_IRQ_SEC_SGI_0, STM32MP1_SECONDARY_CPU);
return PSCI_E_SUCCESS;
}
diff --git a/plat/st/stm32mp1/stm32mp1_security.c b/plat/st/stm32mp1/stm32mp1_security.c
index 3992704..cfdbf31 100644
--- a/plat/st/stm32mp1/stm32mp1_security.c
+++ b/plat/st/stm32mp1/stm32mp1_security.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2015-2018, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2015-2019, ARM Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -65,22 +65,6 @@
******************************************************************************/
static void early_init_tzc400(void)
{
- uint32_t rstsr, rst_standby;
-
- rstsr = mmio_read_32(RCC_BASE + RCC_MP_RSTSCLRR);
-
- /* No warning if return from (C)STANDBY */
- rst_standby = rstsr &
- (RCC_MP_RSTSCLRR_STDBYRSTF | RCC_MP_RSTSCLRR_CSTDBYRSTF);
-
- if (stm32mp1_clk_is_enabled(TZC1) && (rst_standby == 0U)) {
- WARN("TZC400 port 1 clock already enable\n");
- }
-
- if (stm32mp1_clk_is_enabled(TZC2) && (rst_standby == 0U)) {
- WARN("TZC400 port 2 clock already enable\n");
- }
-
if (stm32mp1_clk_enable(TZC1) != 0) {
ERROR("Cannot enable TZC1 clock\n");
panic();
@@ -103,6 +87,7 @@
STM32MP1_DDR_BASE +
(STM32MP1_DDR_MAX_SIZE - 1U),
TZC_REGION_S_RDWR,
+ TZC_REGION_ACCESS_RDWR(STM32MP1_TZC_A7_ID) |
TZC_REGION_ACCESS_RDWR(STM32MP1_TZC_SDMMC_ID));
/* Raise an exception if a NS device tries to access secure memory */
diff --git a/plat/ti/k3/common/drivers/sec_proxy/sec_proxy.c b/plat/ti/k3/common/drivers/sec_proxy/sec_proxy.c
index 5dd54d4..49cecd4 100644
--- a/plat/ti/k3/common/drivers/sec_proxy/sec_proxy.c
+++ b/plat/ti/k3/common/drivers/sec_proxy/sec_proxy.c
@@ -139,10 +139,10 @@
if ((mmio_read_32(spt->scfg + SCFG_THREAD_CTRL) & SCFG_THREAD_CTRL_DIR_MASK)
!= (dir << SCFG_THREAD_CTRL_DIR_SHIFT)) {
if (dir)
- ERROR("Trying to receive data on tx Thread %d\n",
+ ERROR("Trying to send data on RX Thread %d\n",
spt->id);
else
- ERROR("Trying to send data on rx Thread %d\n",
+ ERROR("Trying to receive data on TX Thread %d\n",
spt->id);
return -EINVAL;
}
@@ -163,6 +163,44 @@
}
/**
+ * k3_sec_proxy_clear_rx_thread() - Clear Secure Proxy thread
+ *
+ * @id: Channel Identifier
+ *
+ * Return: 0 if all goes well, else appropriate error message
+ */
+int k3_sec_proxy_clear_rx_thread(enum k3_sec_proxy_chan_id id)
+{
+ struct k3_sec_proxy_thread *spt = &spm.threads[id];
+
+ /* Check for any errors already available */
+ if (mmio_read_32(spt->rt + RT_THREAD_STATUS) &
+ RT_THREAD_STATUS_ERROR_MASK) {
+ ERROR("Thread %d is corrupted, cannot send data\n", spt->id);
+ return -EINVAL;
+ }
+
+ /* Make sure thread is configured for right direction */
+ if (!(mmio_read_32(spt->scfg + SCFG_THREAD_CTRL) & SCFG_THREAD_CTRL_DIR_MASK)) {
+ ERROR("Cannot clear a transmit thread %d\n", spt->id);
+ return -EINVAL;
+ }
+
+ /* Read off messages from thread until empty */
+ uint32_t try_count = 10;
+ while (mmio_read_32(spt->rt + RT_THREAD_STATUS) & RT_THREAD_STATUS_CUR_CNT_MASK) {
+ if (!(try_count--)) {
+ ERROR("Could not clear all messages from thread %d\n", spt->id);
+ return -ETIMEDOUT;
+ }
+ WARN("Clearing message from thread %d\n", spt->id);
+ mmio_read_32(spt->data + spm.desc.data_end_offset);
+ }
+
+ return 0;
+}
+
+/**
* k3_sec_proxy_send() - Send data over a Secure Proxy thread
* @id: Channel Identifier
* @msg: Pointer to k3_sec_proxy_msg
diff --git a/plat/ti/k3/common/drivers/sec_proxy/sec_proxy.h b/plat/ti/k3/common/drivers/sec_proxy/sec_proxy.h
index 2d987f8..6c4f5df 100644
--- a/plat/ti/k3/common/drivers/sec_proxy/sec_proxy.h
+++ b/plat/ti/k3/common/drivers/sec_proxy/sec_proxy.h
@@ -44,6 +44,15 @@
*
* Return: 0 if all goes well, else appropriate error message
*/
+int k3_sec_proxy_clear_rx_thread(enum k3_sec_proxy_chan_id id);
+
+/**
+ * k3_sec_proxy_send() - Send data over a Secure Proxy thread
+ * @id: Channel Identifier
+ * @msg: Pointer to k3_sec_proxy_msg
+ *
+ * Return: 0 if all goes well, else appropriate error message
+ */
int k3_sec_proxy_send(enum k3_sec_proxy_chan_id id, const struct k3_sec_proxy_msg *msg);
/**
diff --git a/plat/ti/k3/common/drivers/ti_sci/ti_sci.c b/plat/ti/k3/common/drivers/ti_sci/ti_sci.c
index b211bdf..4a33d34 100644
--- a/plat/ti/k3/common/drivers/ti_sci/ti_sci.c
+++ b/plat/ti/k3/common/drivers/ti_sci/ti_sci.c
@@ -158,6 +158,13 @@
struct k3_sec_proxy_msg *msg = &xfer->tx_message;
int ret;
+ /* Clear any spurious messages in receive queue */
+ ret = k3_sec_proxy_clear_rx_thread(SP_RESPONSE);
+ if (ret) {
+ ERROR("Could not clear response queue (%d)\n", ret);
+ return ret;
+ }
+
/* Send the message */
ret = k3_sec_proxy_send(SP_HIGH_PRIORITY, msg);
if (ret) {
@@ -165,6 +172,7 @@
return ret;
}
+ /* Get the response */
ret = ti_sci_get_response(xfer, SP_RESPONSE);
if (ret) {
ERROR("Failed to get response (%d)\n", ret);
@@ -1459,6 +1467,169 @@
}
/**
+ * ti_sci_proc_wait_boot_status() - Wait for a processor boot status
+ *
+ * @proc_id: Processor ID this request is for
+ * @num_wait_iterations Total number of iterations we will check before
+ * we will timeout and give up
+ * @num_match_iterations How many iterations should we have continued
+ * status to account for status bits glitching.
+ * This is to make sure that match occurs for
+ * consecutive checks. This implies that the
+ * worst case should consider that the stable
+ * time should at the worst be num_wait_iterations
+ * num_match_iterations to prevent timeout.
+ * @delay_per_iteration_us Specifies how long to wait (in micro seconds)
+ * between each status checks. This is the minimum
+ * duration, and overhead of register reads and
+ * checks are on top of this and can vary based on
+ * varied conditions.
+ * @delay_before_iterations_us Specifies how long to wait (in micro seconds)
+ * before the very first check in the first
+ * iteration of status check loop. This is the
+ * minimum duration, and overhead of register
+ * reads and checks are.
+ * @status_flags_1_set_all_wait If non-zero, Specifies that all bits of the
+ * status matching this field requested MUST be 1.
+ * @status_flags_1_set_any_wait If non-zero, Specifies that at least one of the
+ * bits matching this field requested MUST be 1.
+ * @status_flags_1_clr_all_wait If non-zero, Specifies that all bits of the
+ * status matching this field requested MUST be 0.
+ * @status_flags_1_clr_any_wait If non-zero, Specifies that at least one of the
+ * bits matching this field requested MUST be 0.
+ *
+ * Return: 0 if all goes well, else appropriate error message
+ */
+int ti_sci_proc_wait_boot_status(uint8_t proc_id, uint8_t num_wait_iterations,
+ uint8_t num_match_iterations,
+ uint8_t delay_per_iteration_us,
+ uint8_t delay_before_iterations_us,
+ uint32_t status_flags_1_set_all_wait,
+ uint32_t status_flags_1_set_any_wait,
+ uint32_t status_flags_1_clr_all_wait,
+ uint32_t status_flags_1_clr_any_wait)
+{
+ struct ti_sci_msg_req_wait_proc_boot_status req;
+ struct ti_sci_msg_hdr resp;
+
+ struct ti_sci_xfer xfer;
+ int ret;
+
+ ret = ti_sci_setup_one_xfer(TISCI_MSG_WAIT_PROC_BOOT_STATUS,
+ TI_SCI_FLAG_REQ_ACK_ON_PROCESSED,
+ &req, sizeof(req),
+ &resp, sizeof(resp),
+ &xfer);
+ if (ret) {
+ ERROR("Message alloc failed (%d)\n", ret);
+ return ret;
+ }
+
+ req.processor_id = proc_id;
+ req.num_wait_iterations = num_wait_iterations;
+ req.num_match_iterations = num_match_iterations;
+ req.delay_per_iteration_us = delay_per_iteration_us;
+ req.delay_before_iterations_us = delay_before_iterations_us;
+ req.status_flags_1_set_all_wait = status_flags_1_set_all_wait;
+ req.status_flags_1_set_any_wait = status_flags_1_set_any_wait;
+ req.status_flags_1_clr_all_wait = status_flags_1_clr_all_wait;
+ req.status_flags_1_clr_any_wait = status_flags_1_clr_any_wait;
+
+ ret = ti_sci_do_xfer(&xfer);
+ if (ret) {
+ ERROR("Transfer send failed (%d)\n", ret);
+ return ret;
+ }
+
+ if (!ti_sci_is_response_ack(&resp))
+ return -ENODEV;
+
+ return 0;
+}
+
+/**
+ * ti_sci_proc_shutdown() - Shutdown Processor without waiting for ACKs
+ *
+ * @proc_id: Processor ID this request is for
+ * @dev_id: Device identifier this request is for
+ *
+ * Return: 0 if all goes well, else appropriate error message
+ */
+int ti_sci_proc_shutdown(uint8_t proc_id, uint32_t dev_id)
+{
+ struct ti_sci_msg_req_wait_proc_boot_status wait_req;
+ struct ti_sci_msg_req_set_device_state set_req;
+ /*
+ * We will not be waiting for this response, but declare one anyway
+ * to pass to the setup function so the checks will still pass
+ */
+ struct ti_sci_msg_hdr resp;
+
+ struct ti_sci_xfer xfer;
+ int ret;
+
+ /* Start by sending wait command */
+
+ /* Setup with NORESPONSE flag to keep response queue clean */
+ ret = ti_sci_setup_one_xfer(TISCI_MSG_WAIT_PROC_BOOT_STATUS,
+ TI_SCI_FLAG_REQ_GENERIC_NORESPONSE,
+ &wait_req, sizeof(wait_req),
+ &resp, sizeof(resp),
+ &xfer);
+ if (ret) {
+ ERROR("Message alloc failed (%d)\n", ret);
+ return ret;
+ }
+
+ wait_req.processor_id = proc_id;
+ /*
+ * Wait maximum time to give us the best chance to get
+ * to WFI before this command timeouts
+ */
+ wait_req.delay_before_iterations_us = UINT8_MAX;
+ wait_req.num_wait_iterations = UINT8_MAX;
+ wait_req.delay_per_iteration_us = UINT8_MAX; /* TODO: optimize time */
+ wait_req.num_match_iterations = 2;
+ wait_req.status_flags_1_set_all_wait = 0;
+ /* Wait for either WFE or WFI */
+ wait_req.status_flags_1_set_any_wait = PROC_BOOT_STATUS_FLAG_ARMV8_WFE |
+ PROC_BOOT_STATUS_FLAG_ARMV8_WFI;
+ wait_req.status_flags_1_clr_all_wait = 0;
+ wait_req.status_flags_1_clr_any_wait = 0;
+
+ /* Send wait message */
+ ret = k3_sec_proxy_send(SP_HIGH_PRIORITY, &xfer.tx_message);
+ if (ret) {
+ ERROR("Message sending failed (%d)\n", ret);
+ return ret;
+ }
+
+ /* Now queue up the shutdown request */
+ ret = ti_sci_setup_one_xfer(TI_SCI_MSG_SET_DEVICE_STATE,
+ TI_SCI_FLAG_REQ_GENERIC_NORESPONSE,
+ &set_req, sizeof(set_req),
+ &resp, sizeof(resp),
+ &xfer);
+ if (ret) {
+ ERROR("Message alloc failed (%d)\n", ret);
+ return ret;
+ }
+
+ set_req.id = dev_id;
+ set_req.state = MSG_DEVICE_SW_STATE_AUTO_OFF;
+
+ /* Send shutdown message */
+ ret = k3_sec_proxy_send(SP_HIGH_PRIORITY, &xfer.tx_message);
+ if (ret) {
+ ERROR("Message sending failed (%d)\n", ret);
+ return ret;
+ }
+
+ /* Return without waiting for responses */
+ return 0;
+}
+
+/**
* ti_sci_init() - Basic initialization
*
* Return: 0 if all goes well, else appropriate error message
diff --git a/plat/ti/k3/common/drivers/ti_sci/ti_sci.h b/plat/ti/k3/common/drivers/ti_sci/ti_sci.h
index 1176b00..d07ee61 100644
--- a/plat/ti/k3/common/drivers/ti_sci/ti_sci.h
+++ b/plat/ti/k3/common/drivers/ti_sci/ti_sci.h
@@ -179,6 +179,7 @@
* and then set the processor configuration flags.
* @cert_addr: Memory address at which payload image certificate is located.
* - ti_sci_proc_get_boot_status - Command to get the processor boot status
+ * - ti_sci_proc_wait_boot_status - Command to wait for a processor boot status
*
* NOTE: for all these functions, the following are generic in nature:
* @proc_id: Processor ID
@@ -197,6 +198,15 @@
uint32_t *cfg_flags,
uint32_t *ctrl_flags,
uint32_t *sts_flags);
+int ti_sci_proc_wait_boot_status(uint8_t proc_id, uint8_t num_wait_iterations,
+ uint8_t num_match_iterations,
+ uint8_t delay_per_iteration_us,
+ uint8_t delay_before_iterations_us,
+ uint32_t status_flags_1_set_all_wait,
+ uint32_t status_flags_1_set_any_wait,
+ uint32_t status_flags_1_clr_all_wait,
+ uint32_t status_flags_1_clr_any_wait);
+int ti_sci_proc_shutdown(uint8_t proc_id, uint32_t dev_id);
/**
* ti_sci_init() - Basic initialization
diff --git a/plat/ti/k3/common/drivers/ti_sci/ti_sci_protocol.h b/plat/ti/k3/common/drivers/ti_sci/ti_sci_protocol.h
index c6d76d7..a921e51 100644
--- a/plat/ti/k3/common/drivers/ti_sci/ti_sci_protocol.h
+++ b/plat/ti/k3/common/drivers/ti_sci/ti_sci_protocol.h
@@ -46,6 +46,7 @@
#define TISCI_MSG_SET_PROC_BOOT_CTRL 0xc101
#define TISCI_MSG_PROC_AUTH_BOOT_IMIAGE 0xc120
#define TISCI_MSG_GET_PROC_BOOT_STATUS 0xc400
+#define TISCI_MSG_WAIT_PROC_BOOT_STATUS 0xc401
/**
* struct ti_sci_msg_hdr - Generic Message Header for All messages and responses
@@ -647,4 +648,52 @@
uint32_t status_flags;
} __packed;
+/**
+ * struct ti_sci_msg_req_wait_proc_boot_status - Wait for a processor boot status
+ * @hdr: Generic Header
+ * @processor_id: ID of processor
+ * @num_wait_iterations Total number of iterations we will check before
+ * we will timeout and give up
+ * @num_match_iterations How many iterations should we have continued
+ * status to account for status bits glitching.
+ * This is to make sure that match occurs for
+ * consecutive checks. This implies that the
+ * worst case should consider that the stable
+ * time should at the worst be num_wait_iterations
+ * num_match_iterations to prevent timeout.
+ * @delay_per_iteration_us Specifies how long to wait (in micro seconds)
+ * between each status checks. This is the minimum
+ * duration, and overhead of register reads and
+ * checks are on top of this and can vary based on
+ * varied conditions.
+ * @delay_before_iterations_us Specifies how long to wait (in micro seconds)
+ * before the very first check in the first
+ * iteration of status check loop. This is the
+ * minimum duration, and overhead of register
+ * reads and checks are.
+ * @status_flags_1_set_all_wait If non-zero, Specifies that all bits of the
+ * status matching this field requested MUST be 1.
+ * @status_flags_1_set_any_wait If non-zero, Specifies that at least one of the
+ * bits matching this field requested MUST be 1.
+ * @status_flags_1_clr_all_wait If non-zero, Specifies that all bits of the
+ * status matching this field requested MUST be 0.
+ * @status_flags_1_clr_any_wait If non-zero, Specifies that at least one of the
+ * bits matching this field requested MUST be 0.
+ *
+ * Request type is TISCI_MSG_WAIT_PROC_BOOT_STATUS, response is appropriate
+ * message, or NACK in case of inability to satisfy request.
+ */
+struct ti_sci_msg_req_wait_proc_boot_status {
+ struct ti_sci_msg_hdr hdr;
+ uint8_t processor_id;
+ uint8_t num_wait_iterations;
+ uint8_t num_match_iterations;
+ uint8_t delay_per_iteration_us;
+ uint8_t delay_before_iterations_us;
+ uint32_t status_flags_1_set_all_wait;
+ uint32_t status_flags_1_set_any_wait;
+ uint32_t status_flags_1_clr_all_wait;
+ uint32_t status_flags_1_clr_any_wait;
+} __packed;
+
#endif /* TI_SCI_PROTOCOL_H */
diff --git a/plat/ti/k3/common/k3_bl31_setup.c b/plat/ti/k3/common/k3_bl31_setup.c
index 3fa11b2..78fb696 100644
--- a/plat/ti/k3/common/k3_bl31_setup.c
+++ b/plat/ti/k3/common/k3_bl31_setup.c
@@ -23,8 +23,7 @@
const mmap_region_t plat_k3_mmap[] = {
MAP_REGION_FLAT(SHARED_RAM_BASE, SHARED_RAM_SIZE, MT_DEVICE | MT_RW | MT_SECURE),
MAP_REGION_FLAT(K3_USART_BASE_ADDRESS, K3_USART_SIZE, MT_DEVICE | MT_RW | MT_SECURE),
- MAP_REGION_FLAT(K3_GICD_BASE, K3_GICD_SIZE, MT_DEVICE | MT_RW | MT_SECURE),
- MAP_REGION_FLAT(K3_GICR_BASE, K3_GICR_SIZE, MT_DEVICE | MT_RW | MT_SECURE),
+ MAP_REGION_FLAT(K3_GIC_BASE, K3_GIC_SIZE, MT_DEVICE | MT_RW | MT_SECURE),
MAP_REGION_FLAT(SEC_PROXY_RT_BASE, SEC_PROXY_RT_SIZE, MT_DEVICE | MT_RW | MT_SECURE),
MAP_REGION_FLAT(SEC_PROXY_SCFG_BASE, SEC_PROXY_SCFG_SIZE, MT_DEVICE | MT_RW | MT_SECURE),
MAP_REGION_FLAT(SEC_PROXY_DATA_BASE, SEC_PROXY_DATA_SIZE, MT_DEVICE | MT_RW | MT_SECURE),
@@ -116,7 +115,7 @@
void bl31_platform_setup(void)
{
- k3_gic_driver_init(K3_GICD_BASE, K3_GICR_BASE);
+ k3_gic_driver_init(K3_GIC_BASE);
k3_gic_init();
ti_sci_init();
diff --git a/plat/ti/k3/common/k3_gicv3.c b/plat/ti/k3/common/k3_gicv3.c
index b7c7880..1932eaa 100644
--- a/plat/ti/k3/common/k3_gicv3.c
+++ b/plat/ti/k3/common/k3_gicv3.c
@@ -6,10 +6,12 @@
#include <platform_def.h>
+#include <assert.h>
#include <common/bl_common.h>
#include <common/interrupt_props.h>
#include <drivers/arm/gicv3.h>
#include <lib/utils.h>
+#include <lib/mmio.h>
#include <plat/common/platform.h>
#include <k3_gicv3.h>
@@ -35,8 +37,25 @@
.mpidr_to_core_pos = k3_mpidr_to_core_pos,
};
-void k3_gic_driver_init(uintptr_t gicd_base, uintptr_t gicr_base)
+void k3_gic_driver_init(uintptr_t gic_base)
{
+ /* GIC Distributor is always at the base of the IP */
+ uintptr_t gicd_base = gic_base;
+ /* GIC Redistributor base is run-time detected */
+ uintptr_t gicr_base = 0;
+
+ for (unsigned int gicr_shift = 18; gicr_shift < 21; gicr_shift++) {
+ uintptr_t gicr_check = gic_base + BIT(gicr_shift);
+ uint32_t iidr = mmio_read_32(gicr_check + GICR_IIDR);
+ if (iidr != 0) {
+ /* Found the GICR base */
+ gicr_base = gicr_check;
+ break;
+ }
+ }
+ /* Assert if we have not found the GICR base */
+ assert(gicr_base != 0);
+
/*
* The GICv3 driver is initialized in EL3 and does not need
* to be initialized again in SEL1. This is because the S-EL1
diff --git a/plat/ti/k3/common/k3_psci.c b/plat/ti/k3/common/k3_psci.c
index cb75bf6..235e639 100644
--- a/plat/ti/k3/common/k3_psci.c
+++ b/plat/ti/k3/common/k3_psci.c
@@ -81,15 +81,16 @@
void k3_pwr_domain_off(const psci_power_state_t *target_state)
{
- int core_id, device, ret;
+ int core_id, proc, device, ret;
/* Prevent interrupts from spuriously waking up this cpu */
k3_gic_cpuif_disable();
core_id = plat_my_core_pos();
+ proc = PLAT_PROC_START_ID + core_id;
device = PLAT_PROC_DEVICE_START_ID + core_id;
- ret = ti_sci_device_put(device);
+ ret = ti_sci_proc_shutdown(proc, device);
if (ret) {
ERROR("Request to stop core failed: %d\n", ret);
return;
diff --git a/plat/ti/k3/common/plat_common.mk b/plat/ti/k3/common/plat_common.mk
index 9b3e7d8..c91a035 100644
--- a/plat/ti/k3/common/plat_common.mk
+++ b/plat/ti/k3/common/plat_common.mk
@@ -30,6 +30,10 @@
TI_16550_MDR_QUIRK := 1
$(eval $(call add_define,TI_16550_MDR_QUIRK))
+# Allow customizing the UART baud rate
+K3_USART_BAUD := 115200
+$(eval $(call add_define,K3_USART_BAUD))
+
# Libraries
include lib/xlat_tables_v2/xlat_tables.mk
diff --git a/plat/ti/k3/include/k3_gicv3.h b/plat/ti/k3/include/k3_gicv3.h
index 52f34ff..2329a16 100644
--- a/plat/ti/k3/include/k3_gicv3.h
+++ b/plat/ti/k3/include/k3_gicv3.h
@@ -9,7 +9,7 @@
#include <stdint.h>
-void k3_gic_driver_init(uintptr_t gicd_base, uintptr_t gicr_base);
+void k3_gic_driver_init(uintptr_t gic_base);
void k3_gic_init(void);
void k3_gic_cpuif_enable(void);
void k3_gic_cpuif_disable(void);
diff --git a/plat/ti/k3/include/platform_def.h b/plat/ti/k3/include/platform_def.h
index 5d563b6..f1511c1 100644
--- a/plat/ti/k3/include/platform_def.h
+++ b/plat/ti/k3/include/platform_def.h
@@ -136,10 +136,6 @@
#define K3_USART_CLK_SPEED 48000000
#endif
-#ifndef K3_USART_BAUD
-#define K3_USART_BAUD 115200
-#endif
-
/* Crash console defaults */
#define CRASH_CONSOLE_BASE K3_USART_BASE_ADDRESS
#define CRASH_CONSOLE_CLK K3_USART_CLK_SPEED
@@ -189,10 +185,8 @@
INTR_PROP_DESC(ARM_IRQ_SEC_SGI_6, GIC_HIGHEST_SEC_PRIORITY, grp, \
GIC_INTR_CFG_EDGE)
-#define K3_GICD_BASE 0x01800000
-#define K3_GICD_SIZE 0x10000
-#define K3_GICR_BASE 0x01880000
-#define K3_GICR_SIZE 0x100000
+#define K3_GIC_BASE 0x01800000
+#define K3_GIC_SIZE 0x200000
#define SEC_PROXY_DATA_BASE 0x32C00000
#define SEC_PROXY_DATA_SIZE 0x80000
diff --git a/plat/xilinx/zynqmp/bl31_zynqmp_setup.c b/plat/xilinx/zynqmp/bl31_zynqmp_setup.c
index 8ecd6d7..b0eb66c 100644
--- a/plat/xilinx/zynqmp/bl31_zynqmp_setup.c
+++ b/plat/xilinx/zynqmp/bl31_zynqmp_setup.c
@@ -11,10 +11,11 @@
#include <common/bl_common.h>
#include <common/debug.h>
#include <drivers/console.h>
-#include <plat_arm.h>
-#include <plat_private.h>
+#include <plat/arm/common/plat_arm.h>
#include <plat/common/platform.h>
+#include <plat_private.h>
+
#define BL31_END (unsigned long)(&__BL31_END__)
static entry_point_info_t bl32_image_ep_info;
diff --git a/plat/xilinx/zynqmp/include/platform_def.h b/plat/xilinx/zynqmp/include/platform_def.h
index fb10411..7b062fc 100644
--- a/plat/xilinx/zynqmp/include/platform_def.h
+++ b/plat/xilinx/zynqmp/include/platform_def.h
@@ -66,9 +66,9 @@
* BL33 specific defines.
******************************************************************************/
#ifndef PRELOADED_BL33_BASE
-# define PLAT_ARM_NS_IMAGE_OFFSET 0x8000000
+# define PLAT_ARM_NS_IMAGE_BASE 0x8000000
#else
-# define PLAT_ARM_NS_IMAGE_OFFSET PRELOADED_BL33_BASE
+# define PLAT_ARM_NS_IMAGE_BASE PRELOADED_BL33_BASE
#endif
/*******************************************************************************
diff --git a/plat/xilinx/zynqmp/plat_psci.c b/plat/xilinx/zynqmp/plat_psci.c
index 8522d3e..a32e089 100644
--- a/plat/xilinx/zynqmp/plat_psci.c
+++ b/plat/xilinx/zynqmp/plat_psci.c
@@ -12,10 +12,10 @@
#include <drivers/arm/gicv2.h>
#include <lib/mmio.h>
#include <lib/psci/psci.h>
-#include <plat_private.h>
+#include <plat/arm/common/plat_arm.h>
#include <plat/common/platform.h>
-#include <plat_arm.h>
+#include <plat_private.h>
#include "pm_api_sys.h"
#include "pm_client.h"
diff --git a/plat/xilinx/zynqmp/platform.mk b/plat/xilinx/zynqmp/platform.mk
index d147916..b2f91cd 100644
--- a/plat/xilinx/zynqmp/platform.mk
+++ b/plat/xilinx/zynqmp/platform.mk
@@ -45,8 +45,7 @@
$(eval $(call add_define,ZYNQMP_WDT_RESTART))
endif
-PLAT_INCLUDES := -Iinclude/plat/arm/common/ \
- -Iinclude/plat/arm/common/aarch64/ \
+PLAT_INCLUDES := -Iinclude/plat/arm/common/aarch64/ \
-Iplat/xilinx/common/include/ \
-Iplat/xilinx/zynqmp/include/ \
-Iplat/xilinx/zynqmp/pm_service/ \
diff --git a/plat/xilinx/zynqmp/tsp/tsp_plat_setup.c b/plat/xilinx/zynqmp/tsp/tsp_plat_setup.c
index 97718d6..902e4b3 100644
--- a/plat/xilinx/zynqmp/tsp/tsp_plat_setup.c
+++ b/plat/xilinx/zynqmp/tsp/tsp_plat_setup.c
@@ -7,8 +7,8 @@
#include <common/bl_common.h>
#include <common/debug.h>
#include <drivers/console.h>
+#include <plat/arm/common/plat_arm.h>
-#include <plat_arm.h>
#include <plat_private.h>
#include <platform_tsp.h>
diff --git a/services/spd/trusty/smcall.h b/services/spd/trusty/smcall.h
index 742c8c4..9c1c38c 100644
--- a/services/spd/trusty/smcall.h
+++ b/services/spd/trusty/smcall.h
@@ -7,69 +7,68 @@
#ifndef SMCALL_H
#define SMCALL_H
-#define SMC_NUM_ENTITIES 64
-#define SMC_NUM_ARGS 4
-#define SMC_NUM_PARAMS (SMC_NUM_ARGS - 1)
+#define SMC_NUM_ENTITIES 64U
+#define SMC_NUM_ARGS 4U
+#define SMC_NUM_PARAMS (SMC_NUM_ARGS - 1U)
-#define SMC_IS_FASTCALL(smc_nr) ((smc_nr) & 0x80000000)
-#define SMC_IS_SMC64(smc_nr) ((smc_nr) & 0x40000000)
-#define SMC_ENTITY(smc_nr) (((smc_nr) & 0x3F000000) >> 24)
-#define SMC_FUNCTION(smc_nr) ((smc_nr) & 0x0000FFFF)
+#define SMC_IS_FASTCALL(smc_nr) ((smc_nr) & 0x80000000U)
+#define SMC_IS_SMC64(smc_nr) ((smc_nr) & 0x40000000U)
+#define SMC_ENTITY(smc_nr) (((smc_nr) & 0x3F000000U) >> 24U)
+#define SMC_FUNCTION(smc_nr) ((smc_nr) & 0x0000FFFFU)
#define SMC_NR(entity, fn, fastcall, smc64) \
- (((((unsigned int) (fastcall)) & 0x1) << 31) | \
- (((smc64) & 0x1) << 30) | \
- (((entity) & 0x3F) << 24) | \
- ((fn) & 0xFFFF) \
- )
+ (((((uint32_t)(fastcall)) & 0x1U) << 31U) | \
+ (((smc64) & 0x1U) << 30U) | \
+ (((entity) & 0x3FU) << 24U) | \
+ ((fn) & 0xFFFFU))
-#define SMC_FASTCALL_NR(entity, fn) SMC_NR((entity), (fn), 1, 0)
-#define SMC_FASTCALL64_NR(entity, fn) SMC_NR((entity), (fn), 1, 1)
-#define SMC_YIELDCALL_NR(entity, fn) SMC_NR((entity), (fn), 0, 0)
-#define SMC_YIELDCALL64_NR(entity, fn) SMC_NR((entity), (fn), 0, 1)
+#define SMC_FASTCALL_NR(entity, fn) SMC_NR((entity), (fn), 1U, 0U)
+#define SMC_FASTCALL64_NR(entity, fn) SMC_NR((entity), (fn), 1U, 1U)
+#define SMC_YIELDCALL_NR(entity, fn) SMC_NR((entity), (fn), 0U, 0U)
+#define SMC_YIELDCALL64_NR(entity, fn) SMC_NR((entity), (fn), 0U, 1U)
-#define SMC_ENTITY_ARCH 0 /* ARM Architecture calls */
-#define SMC_ENTITY_CPU 1 /* CPU Service calls */
-#define SMC_ENTITY_SIP 2 /* SIP Service calls */
-#define SMC_ENTITY_OEM 3 /* OEM Service calls */
-#define SMC_ENTITY_STD 4 /* Standard Service calls */
-#define SMC_ENTITY_RESERVED 5 /* Reserved for future use */
-#define SMC_ENTITY_TRUSTED_APP 48 /* Trusted Application calls */
-#define SMC_ENTITY_TRUSTED_OS 50 /* Trusted OS calls */
-#define SMC_ENTITY_LOGGING 51 /* Used for secure -> nonsecure logging */
-#define SMC_ENTITY_SECURE_MONITOR 60 /* Trusted OS calls internal to secure monitor */
+#define SMC_ENTITY_ARCH 0U /* ARM Architecture calls */
+#define SMC_ENTITY_CPU 1U /* CPU Service calls */
+#define SMC_ENTITY_SIP 2U /* SIP Service calls */
+#define SMC_ENTITY_OEM 3U /* OEM Service calls */
+#define SMC_ENTITY_STD 4U /* Standard Service calls */
+#define SMC_ENTITY_RESERVED 5U /* Reserved for future use */
+#define SMC_ENTITY_TRUSTED_APP 48U /* Trusted Application calls */
+#define SMC_ENTITY_TRUSTED_OS 50U /* Trusted OS calls */
+#define SMC_ENTITY_LOGGING 51U /* Used for secure -> nonsecure logging */
+#define SMC_ENTITY_SECURE_MONITOR 60U /* Trusted OS calls internal to secure monitor */
/* FC = Fast call, YC = Yielding call */
-#define SMC_YC_RESTART_LAST SMC_YIELDCALL_NR (SMC_ENTITY_SECURE_MONITOR, 0)
-#define SMC_YC_NOP SMC_YIELDCALL_NR (SMC_ENTITY_SECURE_MONITOR, 1)
+#define SMC_YC_RESTART_LAST SMC_YIELDCALL_NR (SMC_ENTITY_SECURE_MONITOR, 0U)
+#define SMC_YC_NOP SMC_YIELDCALL_NR (SMC_ENTITY_SECURE_MONITOR, 1U)
/*
* Return from secure os to non-secure os with return value in r1
*/
-#define SMC_YC_NS_RETURN SMC_YIELDCALL_NR (SMC_ENTITY_SECURE_MONITOR, 0)
+#define SMC_YC_NS_RETURN SMC_YIELDCALL_NR (SMC_ENTITY_SECURE_MONITOR, 0U)
-#define SMC_FC_RESERVED SMC_FASTCALL_NR (SMC_ENTITY_SECURE_MONITOR, 0)
-#define SMC_FC_FIQ_EXIT SMC_FASTCALL_NR (SMC_ENTITY_SECURE_MONITOR, 1)
-#define SMC_FC_REQUEST_FIQ SMC_FASTCALL_NR (SMC_ENTITY_SECURE_MONITOR, 2)
-#define SMC_FC_GET_NEXT_IRQ SMC_FASTCALL_NR (SMC_ENTITY_SECURE_MONITOR, 3)
-#define SMC_FC_FIQ_ENTER SMC_FASTCALL_NR (SMC_ENTITY_SECURE_MONITOR, 4)
+#define SMC_FC_RESERVED SMC_FASTCALL_NR (SMC_ENTITY_SECURE_MONITOR, 0U)
+#define SMC_FC_FIQ_EXIT SMC_FASTCALL_NR (SMC_ENTITY_SECURE_MONITOR, 1U)
+#define SMC_FC_REQUEST_FIQ SMC_FASTCALL_NR (SMC_ENTITY_SECURE_MONITOR, 2U)
+#define SMC_FC_GET_NEXT_IRQ SMC_FASTCALL_NR (SMC_ENTITY_SECURE_MONITOR, 3U)
+#define SMC_FC_FIQ_ENTER SMC_FASTCALL_NR (SMC_ENTITY_SECURE_MONITOR, 4U)
-#define SMC_FC64_SET_FIQ_HANDLER SMC_FASTCALL64_NR(SMC_ENTITY_SECURE_MONITOR, 5)
-#define SMC_FC64_GET_FIQ_REGS SMC_FASTCALL64_NR (SMC_ENTITY_SECURE_MONITOR, 6)
+#define SMC_FC64_SET_FIQ_HANDLER SMC_FASTCALL64_NR(SMC_ENTITY_SECURE_MONITOR, 5U)
+#define SMC_FC64_GET_FIQ_REGS SMC_FASTCALL64_NR (SMC_ENTITY_SECURE_MONITOR, 6U)
-#define SMC_FC_CPU_SUSPEND SMC_FASTCALL_NR (SMC_ENTITY_SECURE_MONITOR, 7)
-#define SMC_FC_CPU_RESUME SMC_FASTCALL_NR (SMC_ENTITY_SECURE_MONITOR, 8)
+#define SMC_FC_CPU_SUSPEND SMC_FASTCALL_NR (SMC_ENTITY_SECURE_MONITOR, 7U)
+#define SMC_FC_CPU_RESUME SMC_FASTCALL_NR (SMC_ENTITY_SECURE_MONITOR, 8U)
-#define SMC_FC_AARCH_SWITCH SMC_FASTCALL_NR (SMC_ENTITY_SECURE_MONITOR, 9)
-#define SMC_FC_GET_VERSION_STR SMC_FASTCALL_NR (SMC_ENTITY_SECURE_MONITOR, 10)
+#define SMC_FC_AARCH_SWITCH SMC_FASTCALL_NR (SMC_ENTITY_SECURE_MONITOR, 9U)
+#define SMC_FC_GET_VERSION_STR SMC_FASTCALL_NR (SMC_ENTITY_SECURE_MONITOR, 10U)
/* Trusted OS entity calls */
-#define SMC_YC_VIRTIO_GET_DESCR SMC_YIELDCALL_NR(SMC_ENTITY_TRUSTED_OS, 20)
-#define SMC_YC_VIRTIO_START SMC_YIELDCALL_NR(SMC_ENTITY_TRUSTED_OS, 21)
-#define SMC_YC_VIRTIO_STOP SMC_YIELDCALL_NR(SMC_ENTITY_TRUSTED_OS, 22)
+#define SMC_YC_VIRTIO_GET_DESCR SMC_YIELDCALL_NR(SMC_ENTITY_TRUSTED_OS, 20U)
+#define SMC_YC_VIRTIO_START SMC_YIELDCALL_NR(SMC_ENTITY_TRUSTED_OS, 21U)
+#define SMC_YC_VIRTIO_STOP SMC_YIELDCALL_NR(SMC_ENTITY_TRUSTED_OS, 22U)
-#define SMC_YC_VDEV_RESET SMC_YIELDCALL_NR(SMC_ENTITY_TRUSTED_OS, 23)
-#define SMC_YC_VDEV_KICK_VQ SMC_YIELDCALL_NR(SMC_ENTITY_TRUSTED_OS, 24)
-#define SMC_YC_SET_ROT_PARAMS SMC_YIELDCALL_NR(SMC_ENTITY_TRUSTED_OS, 65535)
+#define SMC_YC_VDEV_RESET SMC_YIELDCALL_NR(SMC_ENTITY_TRUSTED_OS, 23U)
+#define SMC_YC_VDEV_KICK_VQ SMC_YIELDCALL_NR(SMC_ENTITY_TRUSTED_OS, 24U)
+#define SMC_YC_SET_ROT_PARAMS SMC_YIELDCALL_NR(SMC_ENTITY_TRUSTED_OS, 65535U)
#endif /* SMCALL_H */
diff --git a/services/spd/trusty/trusty.c b/services/spd/trusty/trusty.c
index c9d73f0..83c14b4 100644
--- a/services/spd/trusty/trusty.c
+++ b/services/spd/trusty/trusty.c
@@ -21,7 +21,10 @@
#include "smcall.h"
/* macro to check if Hypervisor is enabled in the HCR_EL2 register */
-#define HYP_ENABLE_FLAG 0x286001
+#define HYP_ENABLE_FLAG 0x286001U
+
+/* length of Trusty's input parameters (in bytes) */
+#define TRUSTY_PARAMS_LEN_BYTES (4096U * 2)
struct trusty_stack {
uint8_t space[PLATFORM_STACK_SIZE] __aligned(16);
@@ -32,7 +35,7 @@
cpu_context_t cpu_ctx;
void *saved_sp;
uint32_t saved_security_state;
- int fiq_handler_active;
+ int32_t fiq_handler_active;
uint64_t fiq_handler_pc;
uint64_t fiq_handler_cpsr;
uint64_t fiq_handler_sp;
@@ -43,7 +46,7 @@
struct trusty_stack secure_stack;
};
-struct args {
+struct smc_args {
uint64_t r0;
uint64_t r1;
uint64_t r2;
@@ -56,8 +59,8 @@
static struct trusty_cpu_ctx trusty_cpu_ctx[PLATFORM_CORE_COUNT];
-struct args trusty_init_context_stack(void **sp, void *new_stack);
-struct args trusty_context_switch_helper(void **sp, void *smc_params);
+struct smc_args trusty_init_context_stack(void **sp, void *new_stack);
+struct smc_args trusty_context_switch_helper(void **sp, void *smc_params);
static uint32_t current_vmid;
@@ -66,37 +69,37 @@
return &trusty_cpu_ctx[plat_my_core_pos()];
}
-static uint32_t is_hypervisor_mode(void)
+static bool is_hypervisor_mode(void)
{
uint64_t hcr = read_hcr();
- return !!(hcr & HYP_ENABLE_FLAG);
+ return ((hcr & HYP_ENABLE_FLAG) != 0U) ? true : false;
}
-static struct args trusty_context_switch(uint32_t security_state, uint64_t r0,
+static struct smc_args trusty_context_switch(uint32_t security_state, uint64_t r0,
uint64_t r1, uint64_t r2, uint64_t r3)
{
- struct args ret;
+ struct smc_args args, ret_args;
struct trusty_cpu_ctx *ctx = get_trusty_ctx();
struct trusty_cpu_ctx *ctx_smc;
assert(ctx->saved_security_state != security_state);
- ret.r7 = 0;
+ args.r7 = 0;
if (is_hypervisor_mode()) {
/* According to the ARM DEN0028A spec, VMID is stored in x7 */
ctx_smc = cm_get_context(NON_SECURE);
- assert(ctx_smc);
- ret.r7 = SMC_GET_GP(ctx_smc, CTX_GPREG_X7);
+ assert(ctx_smc != NULL);
+ args.r7 = SMC_GET_GP(ctx_smc, CTX_GPREG_X7);
}
/* r4, r5, r6 reserved for future use. */
- ret.r6 = 0;
- ret.r5 = 0;
- ret.r4 = 0;
- ret.r3 = r3;
- ret.r2 = r2;
- ret.r1 = r1;
- ret.r0 = r0;
+ args.r6 = 0;
+ args.r5 = 0;
+ args.r4 = 0;
+ args.r3 = r3;
+ args.r2 = r2;
+ args.r1 = r1;
+ args.r0 = r0;
/*
* To avoid the additional overhead in PSCI flow, skip FP context
@@ -109,9 +112,9 @@
cm_el1_sysregs_context_save(security_state);
ctx->saved_security_state = security_state;
- ret = trusty_context_switch_helper(&ctx->saved_sp, &ret);
+ ret_args = trusty_context_switch_helper(&ctx->saved_sp, &args);
- assert(ctx->saved_security_state == !security_state);
+ assert(ctx->saved_security_state == ((security_state == 0U) ? 1U : 0U));
cm_el1_sysregs_context_restore(security_state);
if (r0 != SMC_FC_CPU_SUSPEND && r0 != SMC_FC_CPU_RESUME)
@@ -119,7 +122,7 @@
cm_set_next_eret_context(security_state);
- return ret;
+ return ret_args;
}
static uint64_t trusty_fiq_handler(uint32_t id,
@@ -127,29 +130,29 @@
void *handle,
void *cookie)
{
- struct args ret;
+ struct smc_args ret;
struct trusty_cpu_ctx *ctx = get_trusty_ctx();
assert(!is_caller_secure(flags));
ret = trusty_context_switch(NON_SECURE, SMC_FC_FIQ_ENTER, 0, 0, 0);
- if (ret.r0) {
+ if (ret.r0 != 0U) {
SMC_RET0(handle);
}
- if (ctx->fiq_handler_active) {
+ if (ctx->fiq_handler_active != 0) {
INFO("%s: fiq handler already active\n", __func__);
SMC_RET0(handle);
}
ctx->fiq_handler_active = 1;
- memcpy(&ctx->fiq_gpregs, get_gpregs_ctx(handle), sizeof(ctx->fiq_gpregs));
+ (void)memcpy(&ctx->fiq_gpregs, get_gpregs_ctx(handle), sizeof(ctx->fiq_gpregs));
ctx->fiq_pc = SMC_GET_EL3(handle, CTX_ELR_EL3);
ctx->fiq_cpsr = SMC_GET_EL3(handle, CTX_SPSR_EL3);
ctx->fiq_sp_el1 = read_ctx_reg(get_sysregs_ctx(handle), CTX_SP_EL1);
write_ctx_reg(get_sysregs_ctx(handle), CTX_SP_EL1, ctx->fiq_handler_sp);
- cm_set_elr_spsr_el3(NON_SECURE, ctx->fiq_handler_pc, ctx->fiq_handler_cpsr);
+ cm_set_elr_spsr_el3(NON_SECURE, ctx->fiq_handler_pc, (uint32_t)ctx->fiq_handler_cpsr);
SMC_RET0(handle);
}
@@ -159,9 +162,9 @@
{
struct trusty_cpu_ctx *ctx;
- if (cpu >= PLATFORM_CORE_COUNT) {
+ if (cpu >= (uint64_t)PLATFORM_CORE_COUNT) {
ERROR("%s: cpu %lld >= %d\n", __func__, cpu, PLATFORM_CORE_COUNT);
- return SM_ERR_INVALID_PARAMETERS;
+ return (uint64_t)SM_ERR_INVALID_PARAMETERS;
}
ctx = &trusty_cpu_ctx[cpu];
@@ -182,16 +185,16 @@
static uint64_t trusty_fiq_exit(void *handle, uint64_t x1, uint64_t x2, uint64_t x3)
{
- struct args ret;
+ struct smc_args ret;
struct trusty_cpu_ctx *ctx = get_trusty_ctx();
- if (!ctx->fiq_handler_active) {
+ if (ctx->fiq_handler_active == 0) {
NOTICE("%s: fiq handler not active\n", __func__);
- SMC_RET1(handle, SM_ERR_INVALID_PARAMETERS);
+ SMC_RET1(handle, (uint64_t)SM_ERR_INVALID_PARAMETERS);
}
ret = trusty_context_switch(NON_SECURE, SMC_FC_FIQ_EXIT, 0, 0, 0);
- if (ret.r0 != 1) {
+ if (ret.r0 != 1U) {
INFO("%s(%p) SMC_FC_FIQ_EXIT returned unexpected value, %lld\n",
__func__, handle, ret.r0);
}
@@ -205,10 +208,10 @@
* x1-x4 and x8-x17 need to be restored here because smc_handler64
* corrupts them (el1 code also restored them).
*/
- memcpy(get_gpregs_ctx(handle), &ctx->fiq_gpregs, sizeof(ctx->fiq_gpregs));
+ (void)memcpy(get_gpregs_ctx(handle), &ctx->fiq_gpregs, sizeof(ctx->fiq_gpregs));
ctx->fiq_handler_active = 0;
write_ctx_reg(get_sysregs_ctx(handle), CTX_SP_EL1, ctx->fiq_sp_el1);
- cm_set_elr_spsr_el3(NON_SECURE, ctx->fiq_pc, ctx->fiq_cpsr);
+ cm_set_elr_spsr_el3(NON_SECURE, ctx->fiq_pc, (uint32_t)ctx->fiq_cpsr);
SMC_RET0(handle);
}
@@ -222,8 +225,8 @@
void *handle,
u_register_t flags)
{
- struct args ret;
- uint32_t vmid = 0;
+ struct smc_args ret;
+ uint32_t vmid = 0U;
entry_point_info_t *ep_info = bl31_plat_get_next_image_ep_info(SECURE);
/*
@@ -231,10 +234,12 @@
* Verified Boot is not even supported and returning success here
* would not compromise the boot process.
*/
- if (!ep_info && (smc_fid == SMC_YC_SET_ROT_PARAMS)) {
+ if ((ep_info == NULL) && (smc_fid == SMC_YC_SET_ROT_PARAMS)) {
SMC_RET1(handle, 0);
- } else if (!ep_info) {
+ } else if (ep_info == NULL) {
SMC_RET1(handle, SMC_UNK);
+ } else {
+ ; /* do nothing */
}
if (is_caller_secure(flags)) {
@@ -279,12 +284,11 @@
static int32_t trusty_init(void)
{
- void el3_exit(void);
entry_point_info_t *ep_info;
- struct args zero_args = {0};
+ struct smc_args zero_args = {0};
struct trusty_cpu_ctx *ctx = get_trusty_ctx();
uint32_t cpu = plat_my_core_pos();
- int reg_width = GET_RW(read_ctx_reg(get_el3state_ctx(&ctx->cpu_ctx),
+ uint64_t reg_width = GET_RW(read_ctx_reg(get_el3state_ctx(&ctx->cpu_ctx),
CTX_SPSR_EL3));
/*
@@ -292,7 +296,7 @@
* failure.
*/
ep_info = bl31_plat_get_next_image_ep_info(SECURE);
- assert(ep_info);
+ assert(ep_info != NULL);
fpregs_context_save(get_fpregs_ctx(cm_get_context(NON_SECURE)));
cm_el1_sysregs_context_save(NON_SECURE);
@@ -304,7 +308,7 @@
* Adjust secondary cpu entry point for 32 bit images to the
* end of exception vectors
*/
- if ((cpu != 0) && (reg_width == MODE_RW_32)) {
+ if ((cpu != 0U) && (reg_width == MODE_RW_32)) {
INFO("trusty: cpu %d, adjust entry point to 0x%lx\n",
cpu, ep_info->pc + (1U << 5));
cm_set_elr_el3(SECURE, ep_info->pc + (1U << 5));
@@ -314,10 +318,10 @@
fpregs_context_restore(get_fpregs_ctx(cm_get_context(SECURE)));
cm_set_next_eret_context(SECURE);
- ctx->saved_security_state = ~0; /* initial saved state is invalid */
- trusty_init_context_stack(&ctx->saved_sp, &ctx->secure_stack.end);
+ ctx->saved_security_state = ~0U; /* initial saved state is invalid */
+ (void)trusty_init_context_stack(&ctx->saved_sp, &ctx->secure_stack.end);
- trusty_context_switch_helper(&ctx->saved_sp, &zero_args);
+ (void)trusty_context_switch_helper(&ctx->saved_sp, &zero_args);
cm_el1_sysregs_context_restore(NON_SECURE);
fpregs_context_restore(get_fpregs_ctx(cm_get_context(NON_SECURE)));
@@ -328,10 +332,10 @@
static void trusty_cpu_suspend(uint32_t off)
{
- struct args ret;
+ struct smc_args ret;
ret = trusty_context_switch(NON_SECURE, SMC_FC_CPU_SUSPEND, off, 0, 0);
- if (ret.r0 != 0) {
+ if (ret.r0 != 0U) {
INFO("%s: cpu %d, SMC_FC_CPU_SUSPEND returned unexpected value, %lld\n",
__func__, plat_my_core_pos(), ret.r0);
}
@@ -339,10 +343,10 @@
static void trusty_cpu_resume(uint32_t on)
{
- struct args ret;
+ struct smc_args ret;
ret = trusty_context_switch(NON_SECURE, SMC_FC_CPU_RESUME, on, 0, 0);
- if (ret.r0 != 0) {
+ if (ret.r0 != 0U) {
INFO("%s: cpu %d, SMC_FC_CPU_RESUME returned unexpected value, %lld\n",
__func__, plat_my_core_pos(), ret.r0);
}
@@ -359,8 +363,8 @@
{
struct trusty_cpu_ctx *ctx = get_trusty_ctx();
- if (!ctx->saved_sp) {
- trusty_init();
+ if (ctx->saved_sp == NULL) {
+ (void)trusty_init();
} else {
trusty_cpu_resume(1);
}
@@ -398,12 +402,12 @@
entry_point_info_t *ep_info;
uint32_t instr;
uint32_t flags;
- int ret;
+ int32_t ret;
bool aarch32 = false;
/* Get trusty's entry point info */
ep_info = bl31_plat_get_next_image_ep_info(SECURE);
- if (!ep_info) {
+ if (ep_info == NULL) {
INFO("Trusty image missing.\n");
return -1;
}
@@ -416,7 +420,8 @@
} else if (instr >> 8 == 0xd53810U || instr >> 16 == 0x9400U) {
INFO("trusty: Found 64 bit image\n");
} else {
- NOTICE("trusty: Found unknown image, 0x%x\n", instr);
+ ERROR("trusty: Found unknown image, 0x%x\n", instr);
+ return -1;
}
SET_PARAM_HEAD(ep_info, PARAM_EP, VERSION_1, SECURE | EP_ST_ENABLE);
@@ -444,8 +449,9 @@
ret = register_interrupt_type_handler(INTR_TYPE_S_EL1,
trusty_fiq_handler,
flags);
- if (ret)
+ if (ret != 0) {
ERROR("trusty: failed to register fiq handler, ret = %d\n", ret);
+ }
if (aarch32) {
entry_point_info_t *ns_ep_info;
diff --git a/services/std_svc/spm/spci.c b/services/std_svc/spm/spci.c
index 44a0acd..1ee986a 100644
--- a/services/std_svc/spm/spci.c
+++ b/services/std_svc/spm/spci.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2018, Arm Limited. All rights reserved.
+ * Copyright (c) 2018-2019, Arm Limited. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -9,6 +9,7 @@
#include <string.h>
#include <common/debug.h>
+#include <common/runtime_svc.h>
#include <lib/el3_runtime/context_mgmt.h>
#include <lib/smccc.h>
#include <lib/spinlock.h>
@@ -679,9 +680,10 @@
/*******************************************************************************
* This function handles all SMCs in the range reserved for SPCI.
******************************************************************************/
-uint64_t spci_smc_handler(uint32_t smc_fid, uint64_t x1, uint64_t x2,
- uint64_t x3, uint64_t x4, void *cookie, void *handle,
- uint64_t flags)
+static uintptr_t spci_smc_handler(uint32_t smc_fid, u_register_t x1,
+ u_register_t x2, u_register_t x3,
+ u_register_t x4, void *cookie, void *handle,
+ u_register_t flags)
{
uint32_t spci_fid;
@@ -773,3 +775,12 @@
WARN("SPCI: Unsupported call 0x%08x\n", smc_fid);
SMC_RET1(handle, SPCI_NOT_SUPPORTED);
}
+
+DECLARE_RT_SVC(
+ spci_handler,
+ OEN_SPCI_START,
+ OEN_SPCI_END,
+ SMC_TYPE_FAST,
+ NULL,
+ spci_smc_handler
+);
diff --git a/services/std_svc/spm/spm.mk b/services/std_svc/spm/spm.mk
index 4ba9feb..448aba4 100644
--- a/services/std_svc/spm/spm.mk
+++ b/services/std_svc/spm/spm.mk
@@ -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
#
@@ -26,8 +26,5 @@
INCLUDES += ${SPRT_LIB_INCLUDES}
-# Force SMC Calling Convention 2 when using SPM
-SMCCC_MAJOR_VERSION := 2
-
# Let the top-level Makefile know that we intend to include a BL32 image
NEED_BL32 := yes
diff --git a/services/std_svc/spm/sprt.c b/services/std_svc/spm/sprt.c
index f6af49f..8aa2a88 100644
--- a/services/std_svc/spm/sprt.c
+++ b/services/std_svc/spm/sprt.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2018, Arm Limited. All rights reserved.
+ * Copyright (c) 2018-2019, Arm Limited. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -10,6 +10,7 @@
#include <arch_helpers.h>
#include <common/debug.h>
+#include <common/runtime_svc.h>
#include <lib/el3_runtime/context_mgmt.h>
#include <lib/smccc.h>
#include <lib/utils.h>
@@ -154,9 +155,10 @@
/*******************************************************************************
* This function handles all SMCs in the range reserved for SPRT.
******************************************************************************/
-uint64_t sprt_smc_handler(uint32_t smc_fid, uint64_t x1, uint64_t x2,
- uint64_t x3, uint64_t x4, void *cookie, void *handle,
- uint64_t flags)
+static uintptr_t sprt_smc_handler(uint32_t smc_fid, u_register_t x1,
+ u_register_t x2, u_register_t x3,
+ u_register_t x4, void *cookie, void *handle,
+ u_register_t flags)
{
/* SPRT only supported from the Secure world */
if (is_caller_non_secure(flags) == SMC_FROM_NON_SECURE) {
@@ -214,3 +216,12 @@
WARN("SPRT: Unsupported call 0x%08x\n", smc_fid);
SMC_RET1(handle, SPRT_NOT_SUPPORTED);
}
+
+DECLARE_RT_SVC(
+ sprt_handler,
+ OEN_SPRT_START,
+ OEN_SPRT_END,
+ SMC_TYPE_FAST,
+ NULL,
+ sprt_smc_handler
+);
diff --git a/services/std_svc/spm_deprecated/aarch64/spm_helpers.S b/services/std_svc/spm_mm/aarch64/spm_helpers.S
similarity index 100%
rename from services/std_svc/spm_deprecated/aarch64/spm_helpers.S
rename to services/std_svc/spm_mm/aarch64/spm_helpers.S
diff --git a/services/std_svc/spm_deprecated/aarch64/spm_shim_exceptions.S b/services/std_svc/spm_mm/aarch64/spm_shim_exceptions.S
similarity index 100%
rename from services/std_svc/spm_deprecated/aarch64/spm_shim_exceptions.S
rename to services/std_svc/spm_mm/aarch64/spm_shim_exceptions.S
diff --git a/services/std_svc/spm_deprecated/spm.mk b/services/std_svc/spm_mm/spm.mk
similarity index 90%
rename from services/std_svc/spm_deprecated/spm.mk
rename to services/std_svc/spm_mm/spm.mk
index 3503020..3aa10ee 100644
--- a/services/std_svc/spm_deprecated/spm.mk
+++ b/services/std_svc/spm_mm/spm.mk
@@ -11,7 +11,7 @@
$(error "Error: SPM is only supported on aarch64.")
endif
-SPM_SOURCES := $(addprefix services/std_svc/spm_deprecated/, \
+SPM_SOURCES := $(addprefix services/std_svc/spm_mm/, \
${ARCH}/spm_helpers.S \
${ARCH}/spm_shim_exceptions.S \
spm_main.c \
diff --git a/services/std_svc/spm_deprecated/spm_main.c b/services/std_svc/spm_mm/spm_main.c
similarity index 100%
rename from services/std_svc/spm_deprecated/spm_main.c
rename to services/std_svc/spm_mm/spm_main.c
diff --git a/services/std_svc/spm_deprecated/spm_private.h b/services/std_svc/spm_mm/spm_private.h
similarity index 100%
rename from services/std_svc/spm_deprecated/spm_private.h
rename to services/std_svc/spm_mm/spm_private.h
diff --git a/services/std_svc/spm_deprecated/spm_setup.c b/services/std_svc/spm_mm/spm_setup.c
similarity index 100%
rename from services/std_svc/spm_deprecated/spm_setup.c
rename to services/std_svc/spm_mm/spm_setup.c
diff --git a/services/std_svc/spm_deprecated/spm_shim_private.h b/services/std_svc/spm_mm/spm_shim_private.h
similarity index 100%
rename from services/std_svc/spm_deprecated/spm_shim_private.h
rename to services/std_svc/spm_mm/spm_shim_private.h
diff --git a/services/std_svc/spm_deprecated/spm_xlat.c b/services/std_svc/spm_mm/spm_xlat.c
similarity index 100%
rename from services/std_svc/spm_deprecated/spm_xlat.c
rename to services/std_svc/spm_mm/spm_xlat.c
diff --git a/services/std_svc/std_svc_setup.c b/services/std_svc/std_svc_setup.c
index 7a34655..1d80fa3 100644
--- a/services/std_svc/std_svc_setup.c
+++ b/services/std_svc/std_svc_setup.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2014-2018, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2014-2019, ARM Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -103,7 +103,7 @@
SMC_RET1(handle, ret);
}
-#if ENABLE_SPM && SPM_DEPRECATED
+#if ENABLE_SPM && SPM_MM
/*
* Dispatch SPM calls to SPM SMC handler and return its return
* value
diff --git a/tools/fiptool/fiptool.c b/tools/fiptool/fiptool.c
index 0d4f929..80b498e 100644
--- a/tools/fiptool/fiptool.c
+++ b/tools/fiptool/fiptool.c
@@ -271,10 +271,10 @@
&u->node[2], &u->node[3],
&u->node[4], &u->node[5]);
/*
- * Given the format specifier above, we expect 11 items to be scanned
+ * Given the format specifier above, we expect 16 items to be scanned
* for a properly formatted UUID.
*/
- if (n != 11)
+ if (n != 16)
log_errx("Invalid UUID: %s", s);
}