Merge pull request #1345 from dbasehore/udelay
rockchip/rk3399: Fix sram_udelay
diff --git a/Makefile b/Makefile
index ef4e5c6..a837846 100644
--- a/Makefile
+++ b/Makefile
@@ -373,6 +373,11 @@
endif
endif
+#For now, BL2_IN_XIP_MEM is only supported when BL2_AT_EL3 is 1.
+ifeq ($(BL2_AT_EL3)-$(BL2_IN_XIP_MEM),0-1)
+$(error "BL2_IN_XIP_MEM is only supported when BL2_AT_EL3 is enabled")
+endif
+
################################################################################
# Process platform overrideable behaviour
################################################################################
@@ -518,6 +523,7 @@
$(eval $(call assert_boolean,USE_TBBR_DEFS))
$(eval $(call assert_boolean,WARMBOOT_ENABLE_DCACHE_EARLY))
$(eval $(call assert_boolean,BL2_AT_EL3))
+$(eval $(call assert_boolean,BL2_IN_XIP_MEM))
$(eval $(call assert_numeric,ARM_ARCH_MAJOR))
$(eval $(call assert_numeric,ARM_ARCH_MINOR))
@@ -564,6 +570,7 @@
$(eval $(call add_define,USE_TBBR_DEFS))
$(eval $(call add_define,WARMBOOT_ENABLE_DCACHE_EARLY))
$(eval $(call add_define,BL2_AT_EL3))
+$(eval $(call add_define,BL2_IN_XIP_MEM))
# Define the EL3_PAYLOAD_BASE flag only if it is provided.
ifdef EL3_PAYLOAD_BASE
diff --git a/acknowledgements.rst b/acknowledgements.rst
index 59f569e..9b81b6c 100644
--- a/acknowledgements.rst
+++ b/acknowledgements.rst
@@ -12,5 +12,7 @@
Xilinx, Inc.
+NXP Semiconductors
+
Individuals
-----------
diff --git a/bl1/bl1_fwu.c b/bl1/bl1_fwu.c
index 49e4e8e..25be577 100644
--- a/bl1/bl1_fwu.c
+++ b/bl1/bl1_fwu.c
@@ -24,12 +24,12 @@
* Function declarations.
*/
static int bl1_fwu_image_copy(unsigned int image_id,
- uintptr_t image_addr,
+ uintptr_t image_src,
unsigned int block_size,
unsigned int image_size,
unsigned int flags);
static int bl1_fwu_image_auth(unsigned int image_id,
- uintptr_t image_addr,
+ uintptr_t image_src,
unsigned int image_size,
unsigned int flags);
static int bl1_fwu_image_execute(unsigned int image_id,
@@ -50,7 +50,7 @@
static unsigned int sec_exec_image_id = INVALID_IMAGE_ID;
/* Authentication status of each image. */
-extern unsigned int auth_img_flags[];
+extern unsigned int auth_img_flags[MAX_NUMBER_IDS];
/*******************************************************************************
* Top level handler for servicing FWU SMCs.
diff --git a/bl1/tbbr/tbbr_img_desc.c b/bl1/tbbr/tbbr_img_desc.c
index f2ed1a1..44f58d3 100644
--- a/bl1/tbbr/tbbr_img_desc.c
+++ b/bl1/tbbr/tbbr_img_desc.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2015-2016, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2015-2018, ARM Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -7,6 +7,7 @@
#include <bl1.h>
#include <bl_common.h>
#include <platform_def.h>
+#include <tbbr/tbbr_img_desc.h>
image_desc_t bl1_tbbr_image_descs[] = {
{
diff --git a/bl2/bl2_el3.ld.S b/bl2/bl2_el3.ld.S
index 3728643..0f91edc 100644
--- a/bl2/bl2_el3.ld.S
+++ b/bl2/bl2_el3.ld.S
@@ -12,15 +12,26 @@
ENTRY(bl2_entrypoint)
MEMORY {
+#if BL2_IN_XIP_MEM
+ ROM (rx): ORIGIN = BL2_RO_BASE, LENGTH = BL2_RO_LIMIT - BL2_RO_BASE
+ RAM (rwx): ORIGIN = BL2_RW_BASE, LENGTH = BL2_RW_LIMIT - BL2_RW_BASE
+#else
RAM (rwx): ORIGIN = BL2_BASE, LENGTH = BL2_LIMIT - BL2_BASE
+#endif
}
SECTIONS
{
+#if BL2_IN_XIP_MEM
+ . = BL2_RO_BASE;
+ ASSERT(. == ALIGN(PAGE_SIZE),
+ "BL2_RO_BASE address is not aligned on a page boundary.")
+#else
. = BL2_BASE;
ASSERT(. == ALIGN(PAGE_SIZE),
"BL2_BASE address is not aligned on a page boundary.")
+#endif
#if SEPARATE_CODE_AND_RODATA
.text . : {
@@ -33,7 +44,11 @@
*(.vectors)
. = NEXT(PAGE_SIZE);
__TEXT_END__ = .;
+#if BL2_IN_XIP_MEM
+ } >ROM
+#else
} >RAM
+#endif
.rodata . : {
__RODATA_START__ = .;
@@ -56,7 +71,11 @@
. = NEXT(PAGE_SIZE);
__RODATA_END__ = .;
+#if BL2_IN_XIP_MEM
+ } >ROM
+#else
} >RAM
+#endif
ASSERT(__TEXT_RESIDENT_END__ - __TEXT_RESIDENT_START__ <= PAGE_SIZE,
"Resident part of BL2 has exceeded its limit.")
@@ -95,12 +114,22 @@
. = NEXT(PAGE_SIZE);
__RO_END__ = .;
+#if BL2_IN_XIP_MEM
+ } >ROM
+#else
} >RAM
#endif
+#endif
ASSERT(__CPU_OPS_END__ > __CPU_OPS_START__,
"cpu_ops not defined for this platform.")
+#if BL2_IN_XIP_MEM
+ . = BL2_RW_BASE;
+ ASSERT(BL2_RW_BASE == ALIGN(PAGE_SIZE),
+ "BL2_RW_BASE address is not aligned on a page boundary.")
+#endif
+
/*
* Define a linker symbol to mark start of the RW memory area for this
* image.
@@ -113,10 +142,14 @@
* section can be placed independently of the main .data section.
*/
.data . : {
- __DATA_START__ = .;
+ __DATA_RAM_START__ = .;
*(.data*)
- __DATA_END__ = .;
+ __DATA_RAM_END__ = .;
+#if BL2_IN_XIP_MEM
+ } >RAM AT>ROM
+#else
} >RAM
+#endif
stacks (NOLOAD) : {
__STACKS_START__ = .;
@@ -174,12 +207,32 @@
__RW_END__ = .;
__BL2_END__ = .;
+#if BL2_IN_XIP_MEM
+ __BL2_RAM_START__ = ADDR(.data);
+ __BL2_RAM_END__ = .;
+
+ __DATA_ROM_START__ = LOADADDR(.data);
+ __DATA_SIZE__ = SIZEOF(.data);
+
+ /*
+ * The .data section is the last PROGBITS section so its end marks the end
+ * of BL2's RO content in XIP memory..
+ */
+ __BL2_ROM_END__ = __DATA_ROM_START__ + __DATA_SIZE__;
+ ASSERT(__BL2_ROM_END__ <= BL2_RO_LIMIT,
+ "BL2's RO content has exceeded its limit.")
+#endif
__BSS_SIZE__ = SIZEOF(.bss);
+
#if USE_COHERENT_MEM
__COHERENT_RAM_UNALIGNED_SIZE__ =
__COHERENT_RAM_END_UNALIGNED__ - __COHERENT_RAM_START__;
#endif
+#if BL2_IN_XIP_MEM
+ ASSERT(. <= BL2_RW_LIMIT, "BL2's RW content has exceeded its limit.")
+#else
ASSERT(. <= BL2_LIMIT, "BL2 image has exceeded its limit.")
+#endif
}
diff --git a/bl2/bl2_image_load.c b/bl2/bl2_image_load.c
index d5d28a5..d22e9ce 100644
--- a/bl2/bl2_image_load.c
+++ b/bl2/bl2_image_load.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2016, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2016-2018, ARM Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -182,7 +182,7 @@
* This function loads SCP_BL2/BL3x images and returns the ep_info for
* the next executable image.
******************************************************************************/
-entry_point_info_t *bl2_load_images(void)
+struct entry_point_info *bl2_load_images(void)
{
bl31_params_t *bl2_to_bl31_params;
entry_point_info_t *bl31_ep_info;
diff --git a/bl2/bl2_image_load_v2.c b/bl2/bl2_image_load_v2.c
index d95c6b2..0f40785 100644
--- a/bl2/bl2_image_load_v2.c
+++ b/bl2/bl2_image_load_v2.c
@@ -21,7 +21,7 @@
* This function loads SCP_BL2/BL3x images and returns the ep_info for
* the next executable image.
******************************************************************************/
-entry_point_info_t *bl2_load_images(void)
+struct entry_point_info *bl2_load_images(void)
{
bl_params_t *bl2_to_next_bl_params;
bl_load_info_t *bl2_load_info;
diff --git a/bl2/bl2_private.h b/bl2/bl2_private.h
index 50295d6..f93a179 100644
--- a/bl2/bl2_private.h
+++ b/bl2/bl2_private.h
@@ -7,6 +7,20 @@
#ifndef __BL2_PRIVATE_H__
#define __BL2_PRIVATE_H__
+#if BL2_IN_XIP_MEM
+/*******************************************************************************
+ * Declarations of linker defined symbols which will tell us where BL2 lives
+ * in Trusted ROM and RAM
+ ******************************************************************************/
+extern uintptr_t __BL2_ROM_END__;
+#define BL2_ROM_END (uintptr_t)(&__BL2_ROM_END__)
+
+extern uintptr_t __BL2_RAM_START__;
+extern uintptr_t __BL2_RAM_END__;
+#define BL2_RAM_BASE (uintptr_t)(&__BL2_RAM_START__)
+#define BL2_RAM_LIMIT (uintptr_t)(&__BL2_RAM_END__)
+#endif
+
/******************************************
* Forward declarations
*****************************************/
diff --git a/bl32/tsp/tsp_private.h b/bl32/tsp/tsp_private.h
index b11570c..dd65a5f 100644
--- a/bl32/tsp/tsp_private.h
+++ b/bl32/tsp/tsp_private.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2014, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2014-2018, ARM Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -62,7 +62,7 @@
void tsp_get_magic(uint64_t args[4]);
-tsp_args_t *tsp_cpu_resume_main(uint64_t arg0,
+tsp_args_t *tsp_cpu_resume_main(uint64_t max_off_pwrlvl,
uint64_t arg1,
uint64_t arg2,
uint64_t arg3,
@@ -106,7 +106,47 @@
/* Vector table of jumps */
extern tsp_vectors_t tsp_vector_table;
+/* functions */
+int32_t tsp_common_int_handler(void);
+int32_t tsp_handle_preemption(void);
+tsp_args_t *tsp_abort_smc_handler(uint64_t func,
+ uint64_t arg1,
+ uint64_t arg2,
+ uint64_t arg3,
+ uint64_t arg4,
+ uint64_t arg5,
+ uint64_t arg6,
+ uint64_t arg7);
+
+tsp_args_t *tsp_smc_handler(uint64_t func,
+ uint64_t arg1,
+ uint64_t arg2,
+ uint64_t arg3,
+ uint64_t arg4,
+ uint64_t arg5,
+ uint64_t arg6,
+ uint64_t arg7);
+
+tsp_args_t *tsp_system_reset_main(uint64_t arg0,
+ uint64_t arg1,
+ uint64_t arg2,
+ uint64_t arg3,
+ uint64_t arg4,
+ uint64_t arg5,
+ uint64_t arg6,
+ uint64_t arg7);
+
+tsp_args_t *tsp_system_off_main(uint64_t arg0,
+ uint64_t arg1,
+ uint64_t arg2,
+ uint64_t arg3,
+ uint64_t arg4,
+ uint64_t arg5,
+ uint64_t arg6,
+ uint64_t arg7);
+
+uint64_t tsp_main(void);
#endif /* __ASSEMBLY__ */
#endif /* __TSP_PRIVATE_H__ */
diff --git a/docs/cpu-specific-build-macros.rst b/docs/cpu-specific-build-macros.rst
index 9e11cdf..65f6adb 100644
--- a/docs/cpu-specific-build-macros.rst
+++ b/docs/cpu-specific-build-macros.rst
@@ -18,7 +18,11 @@
vulnerability workarounds should be applied at runtime.
- ``WORKAROUND_CVE_2017_5715``: Enables the security workaround for
- `CVE-2017-5715`_. Defaults to 1.
+ `CVE-2017-5715`_. This flag can be set to 0 by the platform if none
+ of the PEs in the system need the workaround. Setting this flag to 0 provides
+ no performance benefit for non-affected platforms, it just helps to comply
+ with the recommendation in the spec regarding workaround discovery.
+ Defaults to 1.
CPU Errata Workarounds
----------------------
diff --git a/docs/plat/ls1043a.rst b/docs/plat/ls1043a.rst
new file mode 100644
index 0000000..0d604aa
--- /dev/null
+++ b/docs/plat/ls1043a.rst
@@ -0,0 +1,91 @@
+Description
+===========
+
+The QorIQ® LS1043A processor is NXP's first quad-core, 64-bit Arm®-based
+processor for embedded networking. The LS1023A (two core version) and the
+LS1043A (four core version) deliver greater than 10 Gbps of performance
+in a flexible I/O package supporting fanless designs. This SoC is a
+purpose-built solution for small-form-factor networking and industrial
+applications with BOM optimizations for economic low layer PCB, lower cost
+power supply and single clock design. The new 0.9V versions of the LS1043A
+and LS1023A deliver addition power savings for applications such as Wireless
+LAN and to Power over Ethernet systems.
+
+LS1043ARDB Specification:
+-------------------------
+Memory subsystem:
+ * 2GByte DDR4 SDRAM (32bit bus)
+ * 128 Mbyte NOR flash single-chip memory
+ * 512 Mbyte NAND flash
+ * 16 Mbyte high-speed SPI flash
+ * SD connector to interface with the SD memory card
+
+Ethernet:
+ * XFI 10G port
+ * QSGMII with 4x 1G ports
+ * Two RGMII ports
+
+PCIe:
+ * PCIe2 (Lanes C) to mini-PCIe slot
+ * PCIe3 (Lanes D) to PCIe slot
+
+USB 3.0: two super speed USB 3.0 type A ports
+
+UART: supports two UARTs up to 115200 bps for console
+
+More information are listed in `ls1043`_.
+
+Boot Sequence
+=============
+
+
+Bootrom --> TF-A BL1 --> TF-A BL2 --> TF-A BL1 --> TF-A BL31
+--> BL32(Tee OS) --> TF-A BL31 --> BL33(u-boot) --> Linux kernel
+
+
+How to build
+============
+
+Build Procedure
+---------------
+
+- Prepare AARCH64 toolchain.
+
+- Build u-boot and OPTee firstly, and get binary images: u-boot.bin and tee.bin
+
+- Build TF-A for Nor boot
+
+ Build bl1:
+
+ .. code:: shell
+
+ CROSS_COMPILE=aarch64-linux-gnu- make PLAT=ls1043 bl1
+
+ Build fip:
+
+ .. code:: shell
+
+ CROSS_COMPILE=aarch64-linux-gnu- make PLAT=ls1043 fip \
+ BL33=u-boot.bin NEED_BL32=yes BL32=tee.bin SPD=opteed
+
+Deploy TF-A Images
+-----------------
+
+- Deploy TF-A images on Nor flash Alt Bank.
+
+ .. code:: shell
+
+ => tftp 82000000 bl1.bin
+ => pro off all;era 64100000 +$filesize;cp.b 82000000 64100000 $filesize
+
+ => tftp 82000000 fip.bin
+ => pro off all;era 64120000 +$filesize;cp.b 82000000 64120000 $filesize
+
+ Then change to Alt bank and boot up TF-A:
+
+ .. code:: shell
+
+ => cpld reset altbank
+
+
+.. _ls1043: https://www.nxp.com/products/processors-and-microcontrollers/arm-based-processors-and-mcus/qoriq-layerscape-arm-processors/qoriq-layerscape-1043a-and-1023a-multicore-communications-processors:LS1043A?lang_cd=en
diff --git a/docs/porting-guide.rst b/docs/porting-guide.rst
index ff5bb12..12e135f 100644
--- a/docs/porting-guide.rst
+++ b/docs/porting-guide.rst
@@ -217,11 +217,37 @@
- **#define : BL2\_BASE**
Defines the base address in secure RAM where BL1 loads the BL2 binary image.
- Must be aligned on a page-size boundary.
+ Must be aligned on a page-size boundary. This constant is not applicable
+ when BL2_IN_XIP_MEM is set to '1'.
- **#define : BL2\_LIMIT**
Defines the maximum address in secure RAM that the BL2 image can occupy.
+ This constant is not applicable when BL2_IN_XIP_MEM is set to '1'.
+
+- **#define : BL2\_RO\_BASE**
+
+ Defines the base address in secure XIP memory where BL2 RO section originally
+ lives. Must be aligned on a page-size boundary. This constant is only needed
+ when BL2_IN_XIP_MEM is set to '1'.
+
+- **#define : BL2\_RO\_LIMIT**
+
+ Defines the maximum address in secure XIP memory that BL2's actual content
+ (i.e. excluding any data section allocated at runtime) can occupy. This
+ constant is only needed when BL2_IN_XIP_MEM is set to '1'.
+
+- **#define : BL2\_RW\_BASE**
+
+ Defines the base address in secure RAM where BL2's read-write data will live
+ at runtime. Must be aligned on a page-size boundary. This constant is only
+ needed when BL2_IN_XIP_MEM is set to '1'.
+
+- **#define : BL2\_RW\_LIMIT**
+
+ Defines the maximum address in secure RAM that BL2's read-write data can
+ occupy at runtime. This constant is only needed when BL2_IN_XIP_MEM is set
+ to '1'.
- **#define : BL31\_BASE**
diff --git a/docs/user-guide.rst b/docs/user-guide.rst
index 5794855..f8bc4be 100644
--- a/docs/user-guide.rst
+++ b/docs/user-guide.rst
@@ -246,6 +246,12 @@
- ``BL2_AT_EL3``: This is an optional build option that enables the use of
BL2 at EL3 execution level.
+- ``BL2_IN_XIP_MEM``: In some use-cases BL2 will be stored in eXecute In Place
+ (XIP) memory, like BL1. In these use-cases, it is necessary to initialize
+ the RW sections in RAM, while leaving the RO sections in place. This option
+ enable this use-case. For now, this option is only supported when BL2_AT_EL3
+ is set to '1'.
+
- ``BL31``: This is an optional build option which specifies the path to
BL31 image for the ``fip`` target. In this case, the BL31 in TF-A will not
be built.
@@ -783,6 +789,12 @@
HW_CONFIG blob instead of the DTS file. This option is useful to override
the default HW_CONFIG selected by the build system.
+ARM JUNO platform specific build options
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+- ``JUNO_TZMP1`` : Boolean option to configure Juno to be used for TrustZone
+ Media Protection (TZ-MP1). Default value of this flag is 0.
+
Debugging options
~~~~~~~~~~~~~~~~~
diff --git a/drivers/arm/tzc/tzc_dmc500.c b/drivers/arm/tzc/tzc_dmc500.c
index 7350b2c..8b618e6 100644
--- a/drivers/arm/tzc/tzc_dmc500.c
+++ b/drivers/arm/tzc/tzc_dmc500.c
@@ -25,6 +25,7 @@
/* Pointer to the tzc_dmc500_driver_data structure populated by the platform */
static const tzc_dmc500_driver_data_t *g_driver_data;
+static unsigned int g_sys_if_count;
#define verify_region_attr(region, attr) \
((g_conf_regions[(region)].sec_attr == \
@@ -88,7 +89,7 @@
for (dmc_inst = 0; dmc_inst < g_driver_data->dmc_count; dmc_inst++) {
assert(DMC_INST_BASE_ADDR(dmc_inst));
- for (sys_if = 0; sys_if < MAX_SYS_IF_COUNT; sys_if++)
+ for (sys_if = 0; sys_if < g_sys_if_count; sys_if++)
_tzc_dmc500_write_flush_control(
DMC_INST_SI_BASE(dmc_inst, sys_if));
}
@@ -119,7 +120,7 @@
for (dmc_inst = 0; dmc_inst < g_driver_data->dmc_count;
dmc_inst++) {
assert(DMC_INST_BASE_ADDR(dmc_inst));
- for (sys_if = 0; sys_if < MAX_SYS_IF_COUNT;
+ for (sys_if = 0; sys_if < g_sys_if_count;
sys_if++) {
attr = _tzc_dmc500_read_region_attr_0(
DMC_INST_SI_BASE(dmc_inst, sys_if),
@@ -154,7 +155,7 @@
/* Configure region_0 in all DMC instances */
for (dmc_inst = 0; dmc_inst < g_driver_data->dmc_count; dmc_inst++) {
assert(DMC_INST_BASE_ADDR(dmc_inst));
- for (sys_if = 0; sys_if < MAX_SYS_IF_COUNT; sys_if++)
+ for (sys_if = 0; sys_if < g_sys_if_count; sys_if++)
_tzc_dmc500_configure_region0(
DMC_INST_SI_BASE(dmc_inst, sys_if),
sec_attr, nsaid_permissions);
@@ -195,7 +196,7 @@
for (dmc_inst = 0; dmc_inst < g_driver_data->dmc_count; dmc_inst++) {
assert(DMC_INST_BASE_ADDR(dmc_inst));
- for (sys_if = 0; sys_if < MAX_SYS_IF_COUNT; sys_if++)
+ for (sys_if = 0; sys_if < g_sys_if_count; sys_if++)
_tzc_dmc500_configure_region(
DMC_INST_SI_BASE(dmc_inst, sys_if),
TZC_DMC500_REGION_ATTR_F_EN_MASK,
@@ -272,4 +273,13 @@
/* Validates the information passed by platform */
validate_plat_driver_data(plat_driver_data);
g_driver_data = plat_driver_data;
+
+ /* Check valid system interface count */
+ assert(g_driver_data->sys_if_count <= MAX_SYS_IF_COUNT);
+
+ g_sys_if_count = g_driver_data->sys_if_count;
+
+ /* If interface count is not present then assume max */
+ if (g_sys_if_count == 0U)
+ g_sys_if_count = MAX_SYS_IF_COUNT;
}
diff --git a/drivers/auth/auth_mod.c b/drivers/auth/auth_mod.c
index 1cea60b..eb537b6 100644
--- a/drivers/auth/auth_mod.c
+++ b/drivers/auth/auth_mod.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2015-2016, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2015-2018, ARM Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -30,7 +30,7 @@
/* Pointer to CoT */
extern const auth_img_desc_t *const cot_desc_ptr;
-extern unsigned int auth_img_flags[];
+extern unsigned int auth_img_flags[MAX_NUMBER_IDS];
static int cmp_auth_param_type_desc(const auth_param_type_desc_t *a,
const auth_param_type_desc_t *b)
diff --git a/drivers/auth/crypto_mod.c b/drivers/auth/crypto_mod.c
index 3b3e3ac..4cd0550 100644
--- a/drivers/auth/crypto_mod.c
+++ b/drivers/auth/crypto_mod.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2015, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2015-2018, ARM Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -9,7 +9,6 @@
#include <debug.h>
/* Variable exported by the crypto library through REGISTER_CRYPTO_LIB() */
-extern const crypto_lib_desc_t crypto_lib_desc;
/*
* The crypto module is responsible for verifying digital signatures and hashes.
diff --git a/drivers/auth/mbedtls/mbedtls_common.c b/drivers/auth/mbedtls/mbedtls_common.c
index 205c243..c048d00 100644
--- a/drivers/auth/mbedtls/mbedtls_common.c
+++ b/drivers/auth/mbedtls/mbedtls_common.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2015-2017, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2015-2018, ARM Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -10,6 +10,7 @@
#include <mbedtls/memory_buffer_alloc.h>
#include <mbedtls/platform.h>
#include <mbedtls_config.h>
+#include <mbedtls_common.h>
/*
* mbed TLS heap
diff --git a/include/bl2/bl2.h b/include/bl2/bl2.h
index f2bd07e..89ff06e 100644
--- a/include/bl2/bl2.h
+++ b/include/bl2/bl2.h
@@ -7,9 +7,6 @@
#ifndef BL2_H__
#define BL2_H__
-struct entry_point_info;
-
void bl2_main(void);
-struct entry_point_info *bl2_load_images(void);
#endif /* BL2_H__ */
diff --git a/include/common/aarch64/el3_common_macros.S b/include/common/aarch64/el3_common_macros.S
index 4ebf77b..d5f527a 100644
--- a/include/common/aarch64/el3_common_macros.S
+++ b/include/common/aarch64/el3_common_macros.S
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2015-2017, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2015-2018, ARM Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -278,8 +278,8 @@
* an earlier boot loader stage.
* -------------------------------------------------------------
*/
- adr x0, __RW_START__
- adr x1, __RW_END__
+ ldr x0, =__RW_START__
+ ldr x1, =__RW_END__
sub x1, x1, x0
bl inv_dcache_range
#endif
@@ -294,7 +294,7 @@
bl zeromem
#endif
-#ifdef IMAGE_BL1
+#if defined(IMAGE_BL1) || (defined(IMAGE_BL2) && BL2_IN_XIP_MEM)
ldr x0, =__DATA_RAM_START__
ldr x1, =__DATA_ROM_START__
ldr x2, =__DATA_SIZE__
diff --git a/include/common/runtime_svc.h b/include/common/runtime_svc.h
index 5d9fa39..706c211 100644
--- a/include/common/runtime_svc.h
+++ b/include/common/runtime_svc.h
@@ -102,15 +102,15 @@
* oen is used to access an entry in the 'rt_svc_descs_indices' array. The entry
* contains the index of the service descriptor in the 'rt_svc_descs' array.
*/
-#define get_unique_oen(oen, call_type) ((oen & FUNCID_OEN_MASK) | \
- ((call_type & FUNCID_TYPE_MASK) \
- << FUNCID_OEN_WIDTH))
+#define get_unique_oen(oen, call_type) \
+ (((uint32_t)(oen) & FUNCID_OEN_MASK) | \
+ (((uint32_t)(call_type) & FUNCID_TYPE_MASK) << FUNCID_OEN_WIDTH))
/*
* This macro generates the unique owning entity number from the SMC Function
- * ID. This unique oen is used to access an entry in the
- * 'rt_svc_descs_indices' array to invoke the corresponding runtime service
- * handler during SMC handling.
+ * ID. This unique oen is used to access an entry in the 'rt_svc_descs_indices'
+ * array to invoke the corresponding runtime service handler during SMC
+ * handling.
*/
#define get_unique_oen_from_smc_fid(fid) \
get_unique_oen(((fid) >> FUNCID_OEN_SHIFT), \
diff --git a/include/common/tbbr/tbbr_img_def.h b/include/common/tbbr/tbbr_img_def.h
index 060198b..273abbe 100644
--- a/include/common/tbbr/tbbr_img_def.h
+++ b/include/common/tbbr/tbbr_img_def.h
@@ -75,4 +75,7 @@
/* NT_FW_CONFIG */
#define NT_FW_CONFIG_ID 27
+/* Define size of the array */
+#define MAX_NUMBER_IDS 28
+
#endif /* __TBBR_IMG_DEF_H__ */
diff --git a/include/drivers/arm/tzc_dmc500.h b/include/drivers/arm/tzc_dmc500.h
index 2606d1b..ff58a27 100644
--- a/include/drivers/arm/tzc_dmc500.h
+++ b/include/drivers/arm/tzc_dmc500.h
@@ -130,6 +130,7 @@
typedef struct tzc_dmc500_driver_data {
uintptr_t dmc_base[MAX_DMC_COUNT];
int dmc_count;
+ unsigned int sys_if_count;
} tzc_dmc500_driver_data_t;
void tzc_dmc500_driver_init(const tzc_dmc500_driver_data_t *plat_driver_data);
diff --git a/include/drivers/auth/auth_mod.h b/include/drivers/auth/auth_mod.h
index bd65098..bb3b8f9 100644
--- a/include/drivers/auth/auth_mod.h
+++ b/include/drivers/auth/auth_mod.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2015, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2015-2018, ARM Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -12,6 +12,7 @@
#include <auth_common.h>
#include <cot_def.h>
#include <img_parser_mod.h>
+#include <tbbr_img_def.h>
/*
* Image flags
@@ -41,7 +42,10 @@
#define REGISTER_COT(_cot) \
const auth_img_desc_t *const cot_desc_ptr = \
(const auth_img_desc_t *const)&_cot[0]; \
- unsigned int auth_img_flags[sizeof(_cot)/sizeof(_cot[0])]
+ unsigned int auth_img_flags[MAX_NUMBER_IDS]
+
+extern const auth_img_desc_t *const cot_desc_ptr;
+extern unsigned int auth_img_flags[MAX_NUMBER_IDS];
#endif /* TRUSTED_BOARD_BOOT */
diff --git a/include/drivers/auth/crypto_mod.h b/include/drivers/auth/crypto_mod.h
index 08884ab..f9b44d1 100644
--- a/include/drivers/auth/crypto_mod.h
+++ b/include/drivers/auth/crypto_mod.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2015, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2015-2018, ARM Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -43,7 +43,7 @@
void crypto_mod_init(void);
int crypto_mod_verify_signature(void *data_ptr, unsigned int data_len,
void *sig_ptr, unsigned int sig_len,
- void *sig_alg, unsigned int sig_alg_len,
+ void *sig_alg_ptr, unsigned int sig_alg_len,
void *pk_ptr, unsigned int pk_len);
int crypto_mod_verify_hash(void *data_ptr, unsigned int data_len,
void *digest_info_ptr, unsigned int digest_info_len);
@@ -57,4 +57,6 @@
.verify_hash = _verify_hash \
}
+extern const crypto_lib_desc_t crypto_lib_desc;
+
#endif /* __CRYPTO_MOD_H__ */
diff --git a/include/drivers/auth/img_parser_mod.h b/include/drivers/auth/img_parser_mod.h
index 347ed62..eaf3e6e 100644
--- a/include/drivers/auth/img_parser_mod.h
+++ b/include/drivers/auth/img_parser_mod.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2015, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2015-2018, ARM Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -44,10 +44,10 @@
/* Exported functions */
void img_parser_init(void);
int img_parser_check_integrity(img_type_t img_type,
- void *img, unsigned int img_len);
+ void *img_ptr, unsigned int img_len);
int img_parser_get_auth_param(img_type_t img_type,
const auth_param_type_desc_t *type_desc,
- void *img, unsigned int img_len,
+ void *img_ptr, unsigned int img_len,
void **param_ptr, unsigned int *param_len);
/* Macro to register an image parser library */
diff --git a/include/lib/aarch64/arch.h b/include/lib/aarch64/arch.h
index 91aa484..ff3881e 100644
--- a/include/lib/aarch64/arch.h
+++ b/include/lib/aarch64/arch.h
@@ -442,10 +442,10 @@
#define GET_M32(mode) (((mode) >> MODE32_SHIFT) & MODE32_MASK)
#define SPSR_64(el, sp, daif) \
- (MODE_RW_64 << MODE_RW_SHIFT | \
- ((el) & MODE_EL_MASK) << MODE_EL_SHIFT | \
- ((sp) & MODE_SP_MASK) << MODE_SP_SHIFT | \
- ((daif) & SPSR_DAIF_MASK) << SPSR_DAIF_SHIFT)
+ ((MODE_RW_64 << MODE_RW_SHIFT) | \
+ (((el) & MODE_EL_MASK) << MODE_EL_SHIFT) | \
+ (((sp) & MODE_SP_MASK) << MODE_SP_SHIFT) | \
+ (((daif) & SPSR_DAIF_MASK) << SPSR_DAIF_SHIFT))
#define SPSR_MODE32(mode, isa, endian, aif) \
((MODE_RW_32 << MODE_RW_SHIFT) | \
diff --git a/include/lib/cpus/aarch64/cpu_macros.S b/include/lib/cpus/aarch64/cpu_macros.S
index 8f0a74f..bfe2449 100644
--- a/include/lib/cpus/aarch64/cpu_macros.S
+++ b/include/lib/cpus/aarch64/cpu_macros.S
@@ -230,6 +230,7 @@
/* Check whether errata applies */
mov x0, \_rev_var
+ /* Shall clobber: x0-x7 */
bl check_errata_\_id
.ifeq \_chosen
diff --git a/include/lib/smccc.h b/include/lib/smccc.h
index d683420..b1d4dea 100644
--- a/include/lib/smccc.h
+++ b/include/lib/smccc.h
@@ -76,8 +76,8 @@
#define SMC_FROM_SECURE (U(0) << 0)
#define SMC_FROM_NON_SECURE (U(1) << 0)
-#define is_caller_non_secure(_f) (!!(_f & SMC_FROM_NON_SECURE))
-#define is_caller_secure(_f) (!(is_caller_non_secure(_f)))
+#define is_caller_non_secure(_f) (((_f) & SMC_FROM_NON_SECURE) != U(0))
+#define is_caller_secure(_f) (!is_caller_non_secure(_f))
/* The macro below is used to identify a Standard Service SMC call */
#define is_std_svc_call(_fid) ((((_fid) >> FUNCID_OEN_SHIFT) & \
diff --git a/include/lib/xlat_tables/xlat_tables_v2.h b/include/lib/xlat_tables/xlat_tables_v2.h
index ba3e360..b237945 100644
--- a/include/lib/xlat_tables/xlat_tables_v2.h
+++ b/include/lib/xlat_tables/xlat_tables_v2.h
@@ -299,7 +299,7 @@
* executing.
*/
int change_mem_attributes(xlat_ctx_t *ctx, uintptr_t base_va, size_t size,
- mmap_attr_t attr);
+ uint32_t attr);
/*
* Query the memory attributes of a memory page in a set of translation tables.
@@ -317,7 +317,7 @@
* Output parameter where to store the attributes of the targeted memory page.
*/
int get_mem_attributes(const xlat_ctx_t *ctx, uintptr_t base_va,
- mmap_attr_t *attributes);
+ uint32_t *attributes);
#endif /*__ASSEMBLY__*/
#endif /* __XLAT_TABLES_V2_H__ */
diff --git a/include/plat/arm/common/plat_arm.h b/include/plat/arm/common/plat_arm.h
index b0db8f0..f79450c 100644
--- a/include/plat/arm/common/plat_arm.h
+++ b/include/plat/arm/common/plat_arm.h
@@ -11,6 +11,7 @@
#include <cassert.h>
#include <cpu_data.h>
#include <stdint.h>
+#include <tzc_common.h>
#include <utils_def.h>
/*******************************************************************************
@@ -21,6 +22,43 @@
struct image_info;
struct bl_params;
+typedef struct arm_tzc_regions_info {
+ unsigned long long base;
+ unsigned long long end;
+ tzc_region_attributes_t sec_attr;
+ unsigned int nsaid_permissions;
+} arm_tzc_regions_info_t;
+
+/*******************************************************************************
+ * Default mapping definition of the TrustZone Controller for ARM standard
+ * platforms.
+ * Configure:
+ * - Region 0 with no access;
+ * - Region 1 with secure access only;
+ * - the remaining DRAM regions access from the given Non-Secure masters.
+ ******************************************************************************/
+#if ENABLE_SPM
+#define ARM_TZC_REGIONS_DEF \
+ {ARM_AP_TZC_DRAM1_BASE, ARM_EL3_TZC_DRAM1_END, \
+ TZC_REGION_S_RDWR, 0}, \
+ {ARM_NS_DRAM1_BASE, ARM_NS_DRAM1_END, ARM_TZC_NS_DRAM_S_ACCESS, \
+ PLAT_ARM_TZC_NS_DEV_ACCESS}, \
+ {ARM_DRAM2_BASE, ARM_DRAM2_END, ARM_TZC_NS_DRAM_S_ACCESS, \
+ PLAT_ARM_TZC_NS_DEV_ACCESS}, \
+ {ARM_SP_IMAGE_NS_BUF_BASE, (ARM_SP_IMAGE_NS_BUF_BASE + \
+ ARM_SP_IMAGE_NS_BUF_SIZE) - 1, TZC_REGION_S_NONE, \
+ PLAT_ARM_TZC_NS_DEV_ACCESS}
+
+#else
+#define ARM_TZC_REGIONS_DEF \
+ {ARM_AP_TZC_DRAM1_BASE, ARM_EL3_TZC_DRAM1_END, \
+ TZC_REGION_S_RDWR, 0}, \
+ {ARM_NS_DRAM1_BASE, ARM_NS_DRAM1_END, ARM_TZC_NS_DRAM_S_ACCESS, \
+ PLAT_ARM_TZC_NS_DEV_ACCESS}, \
+ {ARM_DRAM2_BASE, ARM_DRAM2_END, ARM_TZC_NS_DRAM_S_ACCESS, \
+ PLAT_ARM_TZC_NS_DEV_ACCESS}
+#endif
+
#define ARM_CASSERT_MMAP \
CASSERT((ARRAY_SIZE(plat_arm_mmap) + ARM_BL_REGIONS) \
<= MAX_MMAP_REGIONS, \
@@ -110,9 +148,10 @@
void arm_io_setup(void);
/* Security utility functions */
-void arm_tzc400_setup(void);
+void arm_tzc400_setup(const arm_tzc_regions_info_t *tzc_regions);
struct tzc_dmc500_driver_data;
-void arm_tzc_dmc500_setup(struct tzc_dmc500_driver_data *plat_driver_data);
+void arm_tzc_dmc500_setup(struct tzc_dmc500_driver_data *plat_driver_data,
+ const arm_tzc_regions_info_t *tzc_regions);
/* Systimer utility function */
void arm_configure_sys_timer(void);
diff --git a/include/plat/common/common_def.h b/include/plat/common/common_def.h
index 84923b9..827d416 100644
--- a/include/plat/common/common_def.h
+++ b/include/plat/common/common_def.h
@@ -78,9 +78,19 @@
#define BL1_CODE_END BL_CODE_END
#define BL1_RO_DATA_BASE BL_RO_DATA_BASE
#define BL1_RO_DATA_END round_up(BL1_ROM_END, PAGE_SIZE)
+#if BL2_IN_XIP_MEM
+#define BL2_CODE_END BL_CODE_END
+#define BL2_RO_DATA_BASE BL_RO_DATA_BASE
+#define BL2_RO_DATA_END round_up(BL2_ROM_END, PAGE_SIZE)
+#endif /* BL2_IN_XIP_MEM */
#else
#define BL_RO_DATA_BASE 0
#define BL_RO_DATA_END 0
#define BL1_CODE_END round_up(BL1_ROM_END, PAGE_SIZE)
+#if BL2_IN_XIP_MEM
+#define BL2_RO_DATA_BASE 0
+#define BL2_RO_DATA_END 0
+#define BL2_CODE_END round_up(BL2_ROM_END, PAGE_SIZE)
+#endif /* BL2_IN_XIP_MEM */
#endif /* SEPARATE_CODE_AND_RODATA */
#endif /* __COMMON_DEF_H__ */
diff --git a/lib/cpus/aarch64/cortex_a53.S b/lib/cpus/aarch64/cortex_a53.S
index 3e480bc..3a23e02 100644
--- a/lib/cpus/aarch64/cortex_a53.S
+++ b/lib/cpus/aarch64/cortex_a53.S
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2014-2017, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2014-2018, ARM Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -9,6 +9,7 @@
#include <cortex_a53.h>
#include <cpu_macros.S>
#include <debug.h>
+#include <errata_report.h>
#include <plat_macros.S>
#if A53_DISABLE_NON_TEMPORAL_HINT
@@ -144,8 +145,23 @@
* This workaround is statically enabled at build time.
*/
func check_errata_835769
- mov x1, #0x04
- b cpu_rev_var_ls
+ cmp x0, #0x04
+ b.hi errata_not_applies
+ /*
+ * Fix potentially available for revisions r0p2, r0p3 and r0p4.
+ * If r0p2, r0p3 or r0p4; check for fix in REVIDR, else exit.
+ */
+ cmp x0, #0x01
+ mov x0, #ERRATA_APPLIES
+ b.ls exit_check_errata_835769
+ /* Load REVIDR. */
+ mrs x1, revidr_el1
+ /* If REVIDR[7] is set (fix exists) set ERRATA_NOT_APPLIES, else exit. */
+ tbz x1, #7, exit_check_errata_835769
+errata_not_applies:
+ mov x0, #ERRATA_NOT_APPLIES
+exit_check_errata_835769:
+ ret
endfunc check_errata_835769
/*
@@ -154,8 +170,22 @@
* This workaround is statically enabled at build time.
*/
func check_errata_843419
- mov x1, #0x04
- b cpu_rev_var_ls
+ mov x1, #ERRATA_APPLIES
+ mov x2, #ERRATA_NOT_APPLIES
+ cmp x0, #0x04
+ csel x0, x1, x2, ls
+ /*
+ * Fix potentially available for revision r0p4.
+ * If r0p4 check for fix in REVIDR, else exit.
+ */
+ b.ne exit_check_errata_843419
+ /* Load REVIDR. */
+ mrs x3, revidr_el1
+ /* If REVIDR[8] is set (fix exists) set ERRATA_NOT_APPLIES, else exit. */
+ tbz x3, #8, exit_check_errata_843419
+ mov x0, x2
+exit_check_errata_843419:
+ ret
endfunc check_errata_843419
/* -------------------------------------------------
diff --git a/lib/cpus/aarch64/cpu_helpers.S b/lib/cpus/aarch64/cpu_helpers.S
index 5a9226d..9f13ed2 100644
--- a/lib/cpus/aarch64/cpu_helpers.S
+++ b/lib/cpus/aarch64/cpu_helpers.S
@@ -198,6 +198,8 @@
* Compare the CPU's revision-variant (x0) with a given value (x1), for errata
* application purposes. If the revision-variant is less than or same as a given
* value, indicates that errata applies; otherwise not.
+ *
+ * Shall clobber: x0-x3
*/
.globl cpu_rev_var_ls
func cpu_rev_var_ls
@@ -212,6 +214,8 @@
* Compare the CPU's revision-variant (x0) with a given value (x1), for errata
* application purposes. If the revision-variant is higher than or same as a
* given value, indicates that errata applies; otherwise not.
+ *
+ * Shall clobber: x0-x3
*/
.globl cpu_rev_var_hs
func cpu_rev_var_hs
diff --git a/lib/xlat_tables_v2/xlat_tables_internal.c b/lib/xlat_tables_v2/xlat_tables_internal.c
index 653260c..aa13064 100644
--- a/lib/xlat_tables_v2/xlat_tables_internal.c
+++ b/lib/xlat_tables_v2/xlat_tables_internal.c
@@ -115,8 +115,8 @@
/*
* Returns a block/page table descriptor for the given level and attributes.
*/
-static uint64_t xlat_desc(const xlat_ctx_t *ctx, mmap_attr_t attr,
- unsigned long long addr_pa, int level)
+static uint64_t xlat_desc(const xlat_ctx_t *ctx, uint32_t attr,
+ unsigned long long addr_pa, int level)
{
uint64_t desc;
int mem_type;
@@ -561,7 +561,8 @@
if (action == ACTION_WRITE_BLOCK_ENTRY) {
table_base[table_idx] =
- xlat_desc(ctx, mm->attr, table_idx_pa, level);
+ xlat_desc(ctx, (uint32_t)mm->attr, table_idx_pa,
+ level);
} else if (action == ACTION_CREATE_NEW_TABLE) {
@@ -735,7 +736,8 @@
void mmap_add_region_ctx(xlat_ctx_t *ctx, const mmap_region_t *mm)
{
mmap_region_t *mm_cursor = ctx->mmap;
- mmap_region_t *mm_last = mm_cursor + ctx->mmap_num;
+ const mmap_region_t *mm_end = ctx->mmap + ctx->mmap_num;
+ mmap_region_t *mm_last;
unsigned long long end_pa = mm->base_pa + mm->size - 1;
uintptr_t end_va = mm->base_va + mm->size - 1;
int ret;
@@ -786,6 +788,21 @@
&& (mm_cursor->size < mm->size))
++mm_cursor;
+ /*
+ * Find the last entry marker in the mmap
+ */
+ mm_last = ctx->mmap;
+ while ((mm_last->size != 0U) && (mm_last < mm_end)) {
+ ++mm_last;
+ }
+
+ /*
+ * Check if we have enough space in the memory mapping table.
+ * This shouldn't happen as we have checked in mmap_add_region_check
+ * that there is free space.
+ */
+ assert(mm_last->size == 0U);
+
/* Make room for new region by moving other regions up by one place */
memmove(mm_cursor + 1, mm_cursor,
(uintptr_t)mm_last - (uintptr_t)mm_cursor);
@@ -795,7 +812,7 @@
* This shouldn't happen as we have checked in mmap_add_region_check
* that there is free space.
*/
- assert(mm_last->size == 0);
+ assert(mm_end->size == 0U);
*mm_cursor = *mm;
@@ -1411,7 +1428,7 @@
static int get_mem_attributes_internal(const xlat_ctx_t *ctx, uintptr_t base_va,
- mmap_attr_t *attributes, uint64_t **table_entry,
+ uint32_t *attributes, uint64_t **table_entry,
unsigned long long *addr_pa, int *table_level)
{
uint64_t *entry;
@@ -1502,7 +1519,7 @@
int get_mem_attributes(const xlat_ctx_t *ctx, uintptr_t base_va,
- mmap_attr_t *attributes)
+ uint32_t *attributes)
{
return get_mem_attributes_internal(ctx, base_va, attributes,
NULL, NULL, NULL);
@@ -1512,7 +1529,7 @@
int change_mem_attributes(xlat_ctx_t *ctx,
uintptr_t base_va,
size_t size,
- mmap_attr_t attr)
+ uint32_t attr)
{
/* Note: This implementation isn't optimized. */
@@ -1609,7 +1626,7 @@
for (int i = 0; i < pages_count; ++i) {
- mmap_attr_t old_attr, new_attr;
+ uint32_t old_attr, new_attr;
uint64_t *entry;
int level;
unsigned long long addr_pa;
diff --git a/maintainers.rst b/maintainers.rst
index 77b851e..2217cbe 100644
--- a/maintainers.rst
+++ b/maintainers.rst
@@ -83,6 +83,15 @@
- plat/mediatek/\*
+NXP QorIQ Layerscape platform sub-maintainer
+--------------------------------------
+Jiafei Pan (jiafei.pan@nxp.com, `qoriq-open-source`_)
+
+Files:
+
+- docs/plat/ls1043a.rst
+- plat/layerscape/\*
+
Raspberry Pi 3 platform sub-maintainer
--------------------------------------
@@ -141,3 +150,4 @@
.. _sivadur: https://github.com/sivadur
.. _rockchip-linux: https://github.com/rockchip-linux
.. _etienne-lms: https://github.com/etienne-lms
+.. _qoriq-open-source: https://github.com/qoriq-open-source
diff --git a/make_helpers/defaults.mk b/make_helpers/defaults.mk
index 751f834..77eb157 100644
--- a/make_helpers/defaults.mk
+++ b/make_helpers/defaults.mk
@@ -30,6 +30,10 @@
# Execute BL2 at EL3
BL2_AT_EL3 := 0
+# BL2 image is stored in XIP memory, for now, this option is only supported
+# when BL2_AT_EL3 is 1.
+BL2_IN_XIP_MEM := 0
+
# By default, consider that the platform may release several CPUs out of reset.
# The platform Makefile is free to override this value.
COLD_BOOT_SINGLE_CPU := 0
diff --git a/plat/arm/board/fvp/aarch32/fvp_helpers.S b/plat/arm/board/fvp/aarch32/fvp_helpers.S
index 143972d..5d88546 100644
--- a/plat/arm/board/fvp/aarch32/fvp_helpers.S
+++ b/plat/arm/board/fvp/aarch32/fvp_helpers.S
@@ -104,15 +104,20 @@
bx lr
endfunc plat_is_my_cpu_primary
- /* -----------------------------------------------------
+ /* ---------------------------------------------------------------------
* unsigned int plat_arm_calc_core_pos(u_register_t mpidr)
*
* Function to calculate the core position on FVP.
*
- * (ClusterId * FVP_MAX_CPUS_PER_CLUSTER) +
+ * (ClusterId * FVP_MAX_CPUS_PER_CLUSTER * FVP_MAX_PE_PER_CPU) +
* (CPUId * FVP_MAX_PE_PER_CPU) +
* ThreadId
- * -----------------------------------------------------
+ *
+ * which can be simplified as:
+ *
+ * ((ClusterId * FVP_MAX_CPUS_PER_CLUSTER + CPUId) * FVP_MAX_PE_PER_CPU)
+ * + ThreadId
+ * ---------------------------------------------------------------------
*/
func plat_arm_calc_core_pos
mov r3, r0
@@ -125,14 +130,15 @@
lsleq r3, r0, #MPIDR_AFFINITY_BITS
/* Extract individual affinity fields from MPIDR */
- mov r2, #FVP_MAX_PE_PER_CPU
ubfx r0, r3, #MPIDR_AFF0_SHIFT, #MPIDR_AFFINITY_BITS
ubfx r1, r3, #MPIDR_AFF1_SHIFT, #MPIDR_AFFINITY_BITS
- mla r0, r1, r2, r0
-
- mov r1, #FVP_MAX_CPUS_PER_CLUSTER
ubfx r2, r3, #MPIDR_AFF2_SHIFT, #MPIDR_AFFINITY_BITS
- mla r0, r1, r2, r0
+
+ /* Compute linear position */
+ mov r3, #FVP_MAX_CPUS_PER_CLUSTER
+ mla r1, r2, r3, r1
+ mov r3, #FVP_MAX_PE_PER_CPU
+ mla r0, r1, r3, r0
bx lr
endfunc plat_arm_calc_core_pos
diff --git a/plat/arm/board/fvp/fvp_private.h b/plat/arm/board/fvp/fvp_private.h
index c5cd07d..16f10a2 100644
--- a/plat/arm/board/fvp/fvp_private.h
+++ b/plat/arm/board/fvp/fvp_private.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2014-2016, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2014-2018, ARM Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -18,6 +18,7 @@
void fvp_interconnect_init(void);
void fvp_interconnect_enable(void);
void fvp_interconnect_disable(void);
+void tsp_early_platform_setup(void);
#endif /* __FVP_PRIVATE_H__ */
diff --git a/plat/arm/board/fvp/fvp_security.c b/plat/arm/board/fvp/fvp_security.c
index 4559865..a6c9227 100644
--- a/plat/arm/board/fvp/fvp_security.c
+++ b/plat/arm/board/fvp/fvp_security.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2014-2015, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2014-2018, ARM Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -22,5 +22,5 @@
*/
if (get_arm_config()->flags & ARM_CONFIG_HAS_TZC)
- arm_tzc400_setup();
+ arm_tzc400_setup(NULL);
}
diff --git a/plat/arm/board/juno/include/platform_def.h b/plat/arm/board/juno/include/platform_def.h
index 2e2fdd7..b422398 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-2017, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2014-2018, ARM Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -110,12 +110,14 @@
*/
#if TRUSTED_BOARD_BOOT
#if TF_MBEDTLS_KEY_ALG_ID == TF_MBEDTLS_RSA_AND_ECDSA
-# define PLAT_ARM_MAX_BL2_SIZE 0x1F000
+# define PLAT_ARM_MAX_BL2_SIZE 0x20000
+#elif TF_MBEDTLS_KEY_ALG_ID == TF_MBEDTLS_ECDSA
+# define PLAT_ARM_MAX_BL2_SIZE 0x1D000
#else
-# define PLAT_ARM_MAX_BL2_SIZE 0x1B000
+# define PLAT_ARM_MAX_BL2_SIZE 0x1C000
#endif
#else
-# define PLAT_ARM_MAX_BL2_SIZE 0xD000
+# define PLAT_ARM_MAX_BL2_SIZE 0xE000
#endif
/*
diff --git a/plat/arm/board/juno/juno_security.c b/plat/arm/board/juno/juno_security.c
index ce4239b..b6cfe78 100644
--- a/plat/arm/board/juno/juno_security.c
+++ b/plat/arm/board/juno/juno_security.c
@@ -1,15 +1,80 @@
/*
- * Copyright (c) 2014-2015, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2014-2018, ARM Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
+#include <debug.h>
#include <mmio.h>
#include <nic_400.h>
#include <plat_arm.h>
#include <soc_css.h>
-#include "juno_def.h"
+#include "juno_def.h"
+#include "juno_tzmp1_def.h"
+
+#ifdef JUNO_TZMP1
+/*
+ * Protect buffer for VPU/GPU/DPU memory usage with hardware protection
+ * enabled. Propose 224MB video output, 96 MB video input and 32MB video
+ * private.
+ *
+ * Ind Memory Range Caption S_ATTR NS_ATTR
+ * 1 0x080000000 - 0x0E7FFFFFF ARM_NS_DRAM1 NONE RDWR | MEDIA_RW
+ * 2 0x0E8000000 - 0x0F5FFFFFF JUNO_MEDIA_TZC_PROT_DRAM1 NONE MEDIA_RW | AP_WR
+ * 3 0x0F6000000 - 0x0FBFFFFFF JUNO_VPU_TZC_PROT_DRAM1 RDWR VPU_PROT_RW
+ * 4 0x0FC000000 - 0x0FDFFFFFF JUNO_VPU_TZC_PRIV_DRAM1 RDWR VPU_PRIV_RW
+ * 5 0x0FE000000 - 0x0FEFFFFFF JUNO_AP_TZC_SHARE_DRAM1 NONE RDWR | MEDIA_RW
+ * 6 0x0FF000000 - 0x0FFFFFFFF ARM_AP_TZC_DRAM1 RDWR NONE
+ * 7 0x880000000 - 0x9FFFFFFFF ARM_DRAM2 NONE RDWR | MEDIA_RW
+ *
+ * Memory regions are neighbored to save limited TZC regions. Calculation
+ * started from ARM_TZC_SHARE_DRAM1 since it is known and fixed for both
+ * protected-enabled and protected-disabled settings.
+ *
+ * Video private buffer aheads of ARM_TZC_SHARE_DRAM1
+ */
+
+static const arm_tzc_regions_info_t juno_tzmp1_tzc_regions[] = {
+ {ARM_AP_TZC_DRAM1_BASE, ARM_AP_TZC_DRAM1_END, TZC_REGION_S_RDWR, 0},
+ {JUNO_NS_DRAM1_PT1_BASE, JUNO_NS_DRAM1_PT1_END,
+ TZC_REGION_S_NONE, JUNO_MEDIA_TZC_NS_DEV_ACCESS},
+ {JUNO_MEDIA_TZC_PROT_DRAM1_BASE, JUNO_MEDIA_TZC_PROT_DRAM1_END,
+ TZC_REGION_S_NONE, JUNO_MEDIA_TZC_PROT_ACCESS},
+ {JUNO_VPU_TZC_PROT_DRAM1_BASE, JUNO_VPU_TZC_PROT_DRAM1_END,
+ TZC_REGION_S_RDWR, JUNO_VPU_TZC_PROT_ACCESS},
+ {JUNO_VPU_TZC_PRIV_DRAM1_BASE, JUNO_VPU_TZC_PRIV_DRAM1_END,
+ TZC_REGION_S_RDWR, JUNO_VPU_TZC_PRIV_ACCESS},
+ {JUNO_AP_TZC_SHARE_DRAM1_BASE, JUNO_AP_TZC_SHARE_DRAM1_END,
+ TZC_REGION_S_NONE, JUNO_MEDIA_TZC_NS_DEV_ACCESS},
+ {ARM_DRAM2_BASE, ARM_DRAM2_END,
+ TZC_REGION_S_NONE, JUNO_MEDIA_TZC_NS_DEV_ACCESS},
+ {},
+};
+
+/*******************************************************************************
+ * Program dp650 to configure NSAID value for protected mode.
+ ******************************************************************************/
+static void init_dp650(void)
+{
+ mmio_write_32(DP650_BASE + DP650_PROT_NSAID_OFFSET,
+ DP650_PROT_NSAID_CONFIG);
+}
+
+/*******************************************************************************
+ * Program v550 to configure NSAID value for protected mode.
+ ******************************************************************************/
+static void init_v550(void)
+{
+ /*
+ * bits[31:28] is for PRIVATE,
+ * bits[27:24] is for OUTBUF,
+ * bits[23:20] is for PROTECTED.
+ */
+ mmio_write_32(V550_BASE + V550_PROTCTRL_OFFSET, V550_PROTCTRL_CONFIG);
+}
+
+#endif /* JUNO_TZMP1 */
/*******************************************************************************
* Set up the MMU-401 SSD tables. The power-on configuration has all stream IDs
@@ -59,11 +124,23 @@
/* Initialize debug configuration */
init_debug_cfg();
/* Initialize the TrustZone Controller */
- arm_tzc400_setup();
+#ifdef JUNO_TZMP1
+ arm_tzc400_setup(juno_tzmp1_tzc_regions);
+ INFO("TZC protected shared memory base address for TZMP usecase: %p\n",
+ (void *)JUNO_AP_TZC_SHARE_DRAM1_BASE);
+ INFO("TZC protected shared memory end address for TZMP usecase: %p\n",
+ (void *)JUNO_AP_TZC_SHARE_DRAM1_END);
+#else
+ arm_tzc400_setup(NULL);
+#endif
/* Do ARM CSS internal NIC setup */
css_init_nic400();
/* Do ARM CSS SoC security setup */
soc_css_security_setup();
/* Initialize the SMMU SSD tables */
init_mmu401();
+#ifdef JUNO_TZMP1
+ init_dp650();
+ init_v550();
+#endif
}
diff --git a/plat/arm/board/juno/juno_tzmp1_def.h b/plat/arm/board/juno/juno_tzmp1_def.h
new file mode 100644
index 0000000..7055f76
--- /dev/null
+++ b/plat/arm/board/juno/juno_tzmp1_def.h
@@ -0,0 +1,85 @@
+/*
+ * Copyright (c) 2018, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef __JUNO_TZMP1_DEF_H__
+#define __JUNO_TZMP1_DEF_H__
+
+#include <plat_arm.h>
+
+/*
+ * Public memory regions for both protected and non-protected mode
+ *
+ * OPTEE shared memory 0xFEE00000 - 0xFEFFFFFF
+ */
+#define JUNO_AP_TZC_SHARE_DRAM1_SIZE ULL(0x02000000)
+#define JUNO_AP_TZC_SHARE_DRAM1_BASE (ARM_AP_TZC_DRAM1_BASE - \
+ JUNO_AP_TZC_SHARE_DRAM1_SIZE)
+#define JUNO_AP_TZC_SHARE_DRAM1_END (ARM_AP_TZC_DRAM1_BASE - 1)
+
+/* ARM_MEDIA_FEATURES for MEDIA GPU Protect Mode Test */
+#define JUNO_TZC400_NSAID_FPGA_MEDIA_SECURE 8 /* GPU/DPU protected, VPU outbuf */
+#define JUNO_TZC400_NSAID_FPGA_VIDEO_PROTECTED 7 /* VPU protected */
+#define JUNO_TZC400_NSAID_FPGA_VIDEO_PRIVATE 10 /* VPU private (firmware) */
+
+#define JUNO_VPU_TZC_PRIV_DRAM1_SIZE ULL(0x02000000)
+#define JUNO_VPU_TZC_PRIV_DRAM1_BASE (JUNO_AP_TZC_SHARE_DRAM1_BASE - \
+ JUNO_VPU_TZC_PRIV_DRAM1_SIZE)
+#define JUNO_VPU_TZC_PRIV_DRAM1_END (JUNO_AP_TZC_SHARE_DRAM1_BASE - 1)
+
+/* Video input protected buffer follows upper item */
+#define JUNO_VPU_TZC_PROT_DRAM1_SIZE ULL(0x06000000)
+#define JUNO_VPU_TZC_PROT_DRAM1_BASE (JUNO_VPU_TZC_PRIV_DRAM1_BASE - \
+ JUNO_VPU_TZC_PROT_DRAM1_SIZE)
+#define JUNO_VPU_TZC_PROT_DRAM1_END (JUNO_VPU_TZC_PRIV_DRAM1_BASE - 1)
+
+/* Video, graphics and display shares same NSAID and same protected buffer */
+#define JUNO_MEDIA_TZC_PROT_DRAM1_SIZE ULL(0x0e000000)
+#define JUNO_MEDIA_TZC_PROT_DRAM1_BASE (JUNO_VPU_TZC_PROT_DRAM1_BASE - \
+ JUNO_MEDIA_TZC_PROT_DRAM1_SIZE)
+#define JUNO_MEDIA_TZC_PROT_DRAM1_END (JUNO_VPU_TZC_PROT_DRAM1_BASE - 1)
+
+/* Rest of DRAM1 are Non-Secure public buffer */
+#define JUNO_NS_DRAM1_PT1_BASE ARM_DRAM1_BASE
+#define JUNO_NS_DRAM1_PT1_END (JUNO_MEDIA_TZC_PROT_DRAM1_BASE - 1)
+#define JUNO_NS_DRAM1_PT1_SIZE (JUNO_NS_DRAM1_PT1_END - \
+ JUNO_NS_DRAM1_PT1_BASE + 1)
+
+/* TZC filter flags */
+#define JUNO_MEDIA_TZC_NS_DEV_ACCESS (PLAT_ARM_TZC_NS_DEV_ACCESS | \
+ TZC_REGION_ACCESS_RD(JUNO_TZC400_NSAID_FPGA_MEDIA_SECURE))
+
+/* VPU / GPU /DPU protected access */
+#define JUNO_MEDIA_TZC_PROT_ACCESS \
+ (TZC_REGION_ACCESS_RDWR(JUNO_TZC400_NSAID_FPGA_MEDIA_SECURE) | \
+ TZC_REGION_ACCESS_WR(TZC400_NSAID_AP))
+
+#define JUNO_VPU_TZC_PROT_ACCESS \
+ (TZC_REGION_ACCESS_RDWR(JUNO_TZC400_NSAID_FPGA_VIDEO_PROTECTED))
+
+#define JUNO_VPU_TZC_PRIV_ACCESS \
+ (TZC_REGION_ACCESS_RDWR(JUNO_TZC400_NSAID_FPGA_VIDEO_PRIVATE))
+
+/*******************************************************************************
+ * Mali-DP650 related constants
+ ******************************************************************************/
+/* Base address of DP650 */
+#define DP650_BASE 0x6f200000
+/* offset to PROT_NSAID register */
+#define DP650_PROT_NSAID_OFFSET 0x10004
+/* config to PROT_NSAID register */
+#define DP650_PROT_NSAID_CONFIG 0x08008888
+
+/*******************************************************************************
+ * Mali-V550 related constants
+ ******************************************************************************/
+/* Base address of V550 */
+#define V550_BASE 0x6f030000
+/* offset to PROTCTRL register */
+#define V550_PROTCTRL_OFFSET 0x0040
+/* config to PROTCTRL register */
+#define V550_PROTCTRL_CONFIG 0xa8700000
+
+#endif /* __JUNO_TZMP1_DEF_H__ */
diff --git a/plat/arm/board/juno/platform.mk b/plat/arm/board/juno/platform.mk
index 656fc14..3ab99ef 100644
--- a/plat/arm/board/juno/platform.mk
+++ b/plat/arm/board/juno/platform.mk
@@ -1,5 +1,5 @@
#
-# Copyright (c) 2013-2017, ARM Limited and Contributors. All rights reserved.
+# Copyright (c) 2013-2018, ARM Limited and Contributors. All rights reserved.
#
# SPDX-License-Identifier: BSD-3-Clause
#
@@ -31,6 +31,13 @@
$(eval $(call assert_boolean,JUNO_AARCH32_EL3_RUNTIME))
$(eval $(call add_define,JUNO_AARCH32_EL3_RUNTIME))
+# Flag to enable support for TZMP1 on JUNO
+JUNO_TZMP1 := 0
+$(eval $(call assert_boolean,JUNO_TZMP1))
+ifeq (${JUNO_TZMP1}, 1)
+$(eval $(call add_define,JUNO_TZMP1))
+endif
+
ifeq (${JUNO_AARCH32_EL3_RUNTIME}, 1)
# Include BL32 in FIP
NEED_BL32 := yes
diff --git a/plat/arm/common/arm_bl1_fwu.c b/plat/arm/common/arm_bl1_fwu.c
index 1305934..f2be477 100644
--- a/plat/arm/common/arm_bl1_fwu.c
+++ b/plat/arm/common/arm_bl1_fwu.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2015-2016, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2015-2018, ARM Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -9,6 +9,7 @@
#include <debug.h>
#include <errno.h>
#include <plat_arm.h>
+#include <platform.h>
#include <platform_def.h>
#include <tbbr_img_desc.h>
#include <utils.h>
@@ -19,7 +20,7 @@
unsigned int mem_size;
} bl1_mem_info_t;
-bl1_mem_info_t fwu_addr_map_secure[] = {
+static bl1_mem_info_t fwu_addr_map_secure[] = {
{
.mem_base = ARM_SHARED_RAM_BASE,
.mem_size = ARM_SHARED_RAM_SIZE
@@ -29,7 +30,7 @@
}
};
-bl1_mem_info_t fwu_addr_map_non_secure[] = {
+static bl1_mem_info_t fwu_addr_map_non_secure[] = {
{
.mem_base = ARM_NS_DRAM1_BASE,
.mem_size = ARM_NS_DRAM1_SIZE
diff --git a/plat/arm/common/arm_dyn_cfg_helpers.c b/plat/arm/common/arm_dyn_cfg_helpers.c
index cfcbf2a..9ba51a3 100644
--- a/plat/arm/common/arm_dyn_cfg_helpers.c
+++ b/plat/arm/common/arm_dyn_cfg_helpers.c
@@ -4,6 +4,7 @@
* SPDX-License-Identifier: BSD-3-Clause
*/
+#include <arm_dyn_cfg_helpers.h>
#include <assert.h>
#include <desc_image_load.h>
#include <fdt_wrappers.h>
diff --git a/plat/arm/common/arm_tzc400.c b/plat/arm/common/arm_tzc400.c
index 6b706be..a32736c 100644
--- a/plat/arm/common/arm_tzc400.c
+++ b/plat/arm/common/arm_tzc400.c
@@ -18,16 +18,20 @@
/*******************************************************************************
* Initialize the TrustZone Controller for ARM standard platforms.
- * Configure:
- * - Region 0 with no access;
- * - Region 1 with secure access only;
- * - the remaining DRAM regions access from the given Non-Secure masters.
- *
* When booting an EL3 payload, this is simplified: we configure region 0 with
* secure access only and do not enable any other region.
******************************************************************************/
-void arm_tzc400_setup(void)
+void arm_tzc400_setup(const arm_tzc_regions_info_t *tzc_regions)
{
+#ifndef EL3_PAYLOAD_BASE
+ int region_index = 1;
+ const arm_tzc_regions_info_t *p;
+ const arm_tzc_regions_info_t init_tzc_regions[] = {
+ ARM_TZC_REGIONS_DEF,
+ {0}
+ };
+#endif
+
INFO("Configuring TrustZone Controller\n");
tzc400_init(PLAT_ARM_TZC_BASE);
@@ -36,42 +40,22 @@
tzc400_disable_filters();
#ifndef EL3_PAYLOAD_BASE
+ if (tzc_regions == NULL)
+ p = init_tzc_regions;
+ else
+ p = tzc_regions;
/* Region 0 set to no access by default */
tzc400_configure_region0(TZC_REGION_S_NONE, 0);
- /* Region 1 set to cover Secure part of DRAM */
- tzc400_configure_region(PLAT_ARM_TZC_FILTERS, 1,
- ARM_AP_TZC_DRAM1_BASE, ARM_EL3_TZC_DRAM1_END,
- TZC_REGION_S_RDWR,
- 0);
+ /* Rest Regions set according to tzc_regions array */
+ for (; p->base != 0ULL; p++) {
+ tzc400_configure_region(PLAT_ARM_TZC_FILTERS, region_index,
+ p->base, p->end, p->sec_attr, p->nsaid_permissions);
+ region_index++;
+ }
- /* Region 2 set to cover Non-Secure access to 1st DRAM address range.
- * Apply the same configuration to given filters in the TZC. */
- tzc400_configure_region(PLAT_ARM_TZC_FILTERS, 2,
- ARM_NS_DRAM1_BASE, ARM_NS_DRAM1_END,
- ARM_TZC_NS_DRAM_S_ACCESS,
- PLAT_ARM_TZC_NS_DEV_ACCESS);
-
- /* Region 3 set to cover Non-Secure access to 2nd DRAM address range */
- tzc400_configure_region(PLAT_ARM_TZC_FILTERS, 3,
- ARM_DRAM2_BASE, ARM_DRAM2_END,
- ARM_TZC_NS_DRAM_S_ACCESS,
- PLAT_ARM_TZC_NS_DEV_ACCESS);
-
-#if ENABLE_SPM
- /*
- * Region 4 set to cover Non-Secure access to the communication buffer
- * shared with the Secure world.
- */
- tzc400_configure_region(PLAT_ARM_TZC_FILTERS,
- 4,
- ARM_SP_IMAGE_NS_BUF_BASE,
- (ARM_SP_IMAGE_NS_BUF_BASE +
- ARM_SP_IMAGE_NS_BUF_SIZE) - 1,
- TZC_REGION_S_NONE,
- PLAT_ARM_TZC_NS_DEV_ACCESS);
-#endif
+ INFO("Total %d regions set.\n", region_index);
#else /* if defined(EL3_PAYLOAD_BASE) */
@@ -92,5 +76,5 @@
void plat_arm_security_setup(void)
{
- arm_tzc400_setup();
+ arm_tzc400_setup(NULL);
}
diff --git a/plat/arm/common/arm_tzc_dmc500.c b/plat/arm/common/arm_tzc_dmc500.c
index 8e41391..89c502c 100644
--- a/plat/arm/common/arm_tzc_dmc500.c
+++ b/plat/arm/common/arm_tzc_dmc500.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2016, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2016-2018, ARM Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -12,15 +12,21 @@
/*******************************************************************************
* Initialize the DMC500-TrustZone Controller for ARM standard platforms.
- * Configure both the interfaces on Region 0 with no access, Region 1 with
- * secure access only, and the remaining DRAM regions access from the
- * given Non-Secure masters.
- *
* When booting an EL3 payload, this is simplified: we configure region 0 with
* secure access only and do not enable any other region.
******************************************************************************/
-void arm_tzc_dmc500_setup(tzc_dmc500_driver_data_t *plat_driver_data)
+void arm_tzc_dmc500_setup(tzc_dmc500_driver_data_t *plat_driver_data,
+ const arm_tzc_regions_info_t *tzc_regions)
{
+#ifndef EL3_PAYLOAD_BASE
+ int region_index = 1;
+ const arm_tzc_regions_info_t *p;
+ const arm_tzc_regions_info_t init_tzc_regions[] = {
+ ARM_TZC_REGIONS_DEF,
+ {0}
+ };
+#endif
+
assert(plat_driver_data);
INFO("Configuring DMC-500 TZ Settings\n");
@@ -28,28 +34,23 @@
tzc_dmc500_driver_init(plat_driver_data);
#ifndef EL3_PAYLOAD_BASE
+ if (tzc_regions == NULL)
+ p = init_tzc_regions;
+ else
+ p = tzc_regions;
+
/* Region 0 set to no access by default */
tzc_dmc500_configure_region0(TZC_REGION_S_NONE, 0);
- /* Region 1 set to cover Secure part of DRAM */
- tzc_dmc500_configure_region(1, ARM_AP_TZC_DRAM1_BASE,
- ARM_EL3_TZC_DRAM1_END,
- TZC_REGION_S_RDWR,
- 0);
+ /* Rest Regions set according to tzc_regions array */
+ for (; p->base != 0ULL; p++) {
+ tzc_dmc500_configure_region(region_index, p->base, p->end,
+ p->sec_attr, p->nsaid_permissions);
+ region_index++;
+ }
- /* Region 2 set to cover Non-Secure access to 1st DRAM address range.*/
- tzc_dmc500_configure_region(2,
- ARM_NS_DRAM1_BASE,
- ARM_NS_DRAM1_END,
- ARM_TZC_NS_DRAM_S_ACCESS,
- PLAT_ARM_TZC_NS_DEV_ACCESS);
+ INFO("Total %d regions set.\n", region_index);
- /* Region 3 set to cover Non-Secure access to 2nd DRAM address range */
- tzc_dmc500_configure_region(3,
- ARM_DRAM2_BASE,
- ARM_DRAM2_END,
- ARM_TZC_NS_DRAM_S_ACCESS,
- PLAT_ARM_TZC_NS_DEV_ACCESS);
#else
/* Allow secure access only to DRAM for EL3 payloads */
tzc_dmc500_configure_region0(TZC_REGION_S_RDWR, 0);
diff --git a/plat/arm/css/common/css_common.mk b/plat/arm/css/common/css_common.mk
index cfbb3e9..72d5527 100644
--- a/plat/arm/css/common/css_common.mk
+++ b/plat/arm/css/common/css_common.mk
@@ -28,13 +28,14 @@
ifeq (${CSS_USE_SCMI_SDS_DRIVER},0)
BL31_SOURCES += plat/arm/css/drivers/scp/css_pm_scpi.c \
- plat/arm/css/drivers/scpi/css_mhu.c \
+ plat/arm/css/drivers/mhu/css_mhu.c \
plat/arm/css/drivers/scpi/css_scpi.c
else
BL31_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/scmi/scmi_sys_pwr_proto.c \
+ plat/arm/css/drivers/mhu/css_mhu_doorbell.c
endif
ifneq (${RESET_TO_BL31},0)
@@ -60,11 +61,11 @@
plat/arm/css/drivers/sds/sds.c
else
BL2U_SOURCES += plat/arm/css/drivers/scp/css_bom_bootloader.c \
- plat/arm/css/drivers/scpi/css_mhu.c \
+ plat/arm/css/drivers/mhu/css_mhu.c \
plat/arm/css/drivers/scpi/css_scpi.c
BL2_SOURCES += plat/arm/css/drivers/scp/css_bom_bootloader.c \
- plat/arm/css/drivers/scpi/css_mhu.c \
+ plat/arm/css/drivers/mhu/css_mhu.c \
plat/arm/css/drivers/scpi/css_scpi.c
# Enable option to detect whether the SCP ROM firmware in use predates version
# 1.7.0 and therefore, is incompatible.
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 28eb2db..9fb280c 100644
--- a/plat/arm/css/common/sp_min/css_sp_min.mk
+++ b/plat/arm/css/common/sp_min/css_sp_min.mk
@@ -1,5 +1,5 @@
#
-# Copyright (c) 2017, ARM Limited and Contributors. All rights reserved.
+# Copyright (c) 2017-2018, ARM Limited and Contributors. All rights reserved.
#
# SPDX-License-Identifier: BSD-3-Clause
#
@@ -10,11 +10,12 @@
ifeq (${CSS_USE_SCMI_SDS_DRIVER},0)
BL32_SOURCES += plat/arm/css/drivers/scp/css_pm_scpi.c \
- plat/arm/css/drivers/scpi/css_mhu.c \
+ plat/arm/css/drivers/mhu/css_mhu.c \
plat/arm/css/drivers/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/scmi/scmi_sys_pwr_proto.c \
+ plat/arm/css/drivers/mhu/css_mhu_doorbell.c
endif
diff --git a/plat/arm/css/drivers/scpi/css_mhu.c b/plat/arm/css/drivers/mhu/css_mhu.c
similarity index 96%
rename from plat/arm/css/drivers/scpi/css_mhu.c
rename to plat/arm/css/drivers/mhu/css_mhu.c
index 500b8df..30492a6 100644
--- a/plat/arm/css/drivers/scpi/css_mhu.c
+++ b/plat/arm/css/drivers/mhu/css_mhu.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2014-2017, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2014-2018, ARM Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
diff --git a/plat/arm/css/drivers/scpi/css_mhu.h b/plat/arm/css/drivers/mhu/css_mhu.h
similarity index 85%
rename from plat/arm/css/drivers/scpi/css_mhu.h
rename to plat/arm/css/drivers/mhu/css_mhu.h
index 298eee9..0fb00c7 100644
--- a/plat/arm/css/drivers/scpi/css_mhu.h
+++ b/plat/arm/css/drivers/mhu/css_mhu.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2014-2016, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2014-2018, ARM Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
diff --git a/plat/arm/css/drivers/mhu/css_mhu_doorbell.c b/plat/arm/css/drivers/mhu/css_mhu_doorbell.c
new file mode 100644
index 0000000..b9faf67
--- /dev/null
+++ b/plat/arm/css/drivers/mhu/css_mhu_doorbell.c
@@ -0,0 +1,37 @@
+/*
+ * Copyright (c) 2014-2018, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <arch_helpers.h>
+#include <platform_def.h>
+#include "css_mhu_doorbell.h"
+#include "../scmi/scmi.h"
+
+void mhu_ring_doorbell(scmi_channel_plat_info_t *plat_info)
+{
+ MHU_RING_DOORBELL(plat_info->db_reg_addr,
+ plat_info->db_modify_mask,
+ plat_info->db_preserve_mask);
+ return;
+}
+
+void mhuv2_ring_doorbell(scmi_channel_plat_info_t *plat_info)
+{
+ /* wake receiver */
+ MHU_V2_ACCESS_REQUEST(MHUV2_BASE_ADDR);
+
+ /* wait for receiver to acknowledge its ready */
+ while (MHU_V2_IS_ACCESS_READY(MHUV2_BASE_ADDR) == 0)
+ ;
+
+ MHU_RING_DOORBELL(plat_info->db_reg_addr,
+ plat_info->db_modify_mask,
+ plat_info->db_preserve_mask);
+
+ /* clear the access request for the recevier */
+ MHU_V2_CLEAR_REQUEST(MHUV2_BASE_ADDR);
+
+ return;
+}
diff --git a/plat/arm/css/drivers/mhu/css_mhu_doorbell.h b/plat/arm/css/drivers/mhu/css_mhu_doorbell.h
new file mode 100644
index 0000000..3c94536
--- /dev/null
+++ b/plat/arm/css/drivers/mhu/css_mhu_doorbell.h
@@ -0,0 +1,43 @@
+/*
+ * Copyright (c) 2014-2018, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef CSS_MHU_DOORBELL_H
+#define CSS_MHU_DOORBELL_H
+
+#include <mmio.h>
+#include <stdint.h>
+
+/* MHUv2 Base Address */
+#define MHUV2_BASE_ADDR PLAT_CSS_MHU_BASE
+
+/* MHUv2 Control Registers Offsets */
+#define MHU_V2_MSG_NO_CAP_OFFSET 0xF80
+#define MHU_V2_ACCESS_REQ_OFFSET 0xF88
+#define MHU_V2_ACCESS_READY_OFFSET 0xF8C
+
+#define SENDER_REG_STAT(CHANNEL) (0x20 * (CHANNEL))
+#define SENDER_REG_SET(CHANNEL) (0x20 * (CHANNEL)) + 0xC
+
+/* Helper macro to ring doorbell */
+#define MHU_RING_DOORBELL(addr, modify_mask, preserve_mask) do { \
+ uint32_t db = mmio_read_32(addr) & (preserve_mask); \
+ mmio_write_32(addr, db | (modify_mask)); \
+ } while (0)
+
+#define MHU_V2_ACCESS_REQUEST(addr) \
+ mmio_write_32((addr) + MHU_V2_ACCESS_REQ_OFFSET, 0x1)
+
+#define MHU_V2_CLEAR_REQUEST(addr) \
+ mmio_write_32((addr) + MHU_V2_ACCESS_REQ_OFFSET, 0x0)
+
+#define MHU_V2_IS_ACCESS_READY(addr) \
+ (mmio_read_32((addr) + MHU_V2_ACCESS_READY_OFFSET) & 0x1)
+
+struct scmi_channel_plat_info;
+void mhu_ring_doorbell(struct scmi_channel_plat_info *plat_info);
+void mhuv2_ring_doorbell(struct scmi_channel_plat_info *plat_info);
+
+#endif /* CSS_MHU_DOORBELL_H */
diff --git a/plat/arm/css/drivers/scmi/scmi.h b/plat/arm/css/drivers/scmi/scmi.h
index 850402a..cf9ef5e 100644
--- a/plat/arm/css/drivers/scmi/scmi.h
+++ b/plat/arm/css/drivers/scmi/scmi.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2017, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2017-2018, ARM Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -96,6 +96,10 @@
uint32_t db_preserve_mask;
/* The bit mask that need to be set to ring doorbell */
uint32_t db_modify_mask;
+ /* The handler for ringing doorbell */
+ void (*ring_doorbell)(struct scmi_channel_plat_info *plat_info);
+ /* cookie is unused now. But added for future enhancements. */
+ void *cookie;
} scmi_channel_plat_info_t;
/*
diff --git a/plat/arm/css/drivers/scmi/scmi_common.c b/plat/arm/css/drivers/scmi/scmi_common.c
index d0051c7..8482d21 100644
--- a/plat/arm/css/drivers/scmi/scmi_common.c
+++ b/plat/arm/css/drivers/scmi/scmi_common.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2017, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2017-2018, ARM Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -39,9 +39,7 @@
*/
dmbst();
- SCMI_RING_DOORBELL(ch->info->db_reg_addr, ch->info->db_modify_mask,
- ch->info->db_preserve_mask);
-
+ ch->info->ring_doorbell(ch->info);
/*
* Ensure that the write to the doorbell register is ordered prior to
* checking whether the channel is free.
@@ -150,6 +148,7 @@
assert(ch->info->db_reg_addr);
assert(ch->info->db_modify_mask);
assert(ch->info->db_preserve_mask);
+ assert(ch->info->ring_doorbell != NULL);
assert(ch->lock);
diff --git a/plat/arm/css/drivers/scmi/scmi_private.h b/plat/arm/css/drivers/scmi/scmi_private.h
index 20e1e9b..a07841e 100644
--- a/plat/arm/css/drivers/scmi/scmi_private.h
+++ b/plat/arm/css/drivers/scmi/scmi_private.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2017, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2017-2018, ARM Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -113,12 +113,6 @@
(val3) = mmio_read_32((uintptr_t)&payld_arr[2]); \
} while (0)
-/* Helper macro to ring doorbell */
-#define SCMI_RING_DOORBELL(addr, modify_mask, preserve_mask) do { \
- uint32_t db = mmio_read_32(addr) & (preserve_mask); \
- mmio_write_32(addr, db | (modify_mask)); \
- } while (0)
-
/*
* Private data structure for representing the mailbox memory layout. Refer
* the SCMI specification for more details.
diff --git a/plat/arm/css/drivers/scp/css_bom_bootloader.c b/plat/arm/css/drivers/scp/css_bom_bootloader.c
index 08d6fc5..42ed30d 100644
--- a/plat/arm/css/drivers/scp/css_bom_bootloader.c
+++ b/plat/arm/css/drivers/scp/css_bom_bootloader.c
@@ -10,7 +10,7 @@
#include <debug.h>
#include <platform.h>
#include <stdint.h>
-#include "../scpi/css_mhu.h"
+#include "../mhu/css_mhu.h"
#include "../scpi/css_scpi.h"
#include "css_scp.h"
diff --git a/plat/arm/css/drivers/scp/css_pm_scmi.c b/plat/arm/css/drivers/scp/css_pm_scmi.c
index f8bc20c..c0ed487 100644
--- a/plat/arm/css/drivers/scp/css_pm_scmi.c
+++ b/plat/arm/css/drivers/scp/css_pm_scmi.c
@@ -13,6 +13,7 @@
#include <platform.h>
#include <string.h>
#include "../scmi/scmi.h"
+#include "../mhu/css_mhu_doorbell.h"
#include "css_scp.h"
/*
@@ -76,7 +77,7 @@
* Helper function to suspend a CPU power domain and its parent power domains
* if applicable.
*/
-void css_scp_suspend(const psci_power_state_t *target_state)
+void css_scp_suspend(const struct psci_power_state *target_state)
{
int lvl, ret;
uint32_t scmi_pwr_state = 0;
@@ -302,6 +303,7 @@
.db_reg_addr = PLAT_CSS_MHU_BASE + CSS_SCMI_MHU_DB_REG_OFF,
.db_preserve_mask = 0xfffffffe,
.db_modify_mask = 0x1,
+ .ring_doorbell = &mhu_ring_doorbell,
};
void plat_arm_pwrc_setup(void)
diff --git a/plat/arm/css/drivers/scp/css_pm_scpi.c b/plat/arm/css/drivers/scp/css_pm_scpi.c
index 545c3fb..23fd80e 100644
--- a/plat/arm/css/drivers/scp/css_pm_scpi.c
+++ b/plat/arm/css/drivers/scp/css_pm_scpi.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2016, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2016-2018, ARM Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -19,7 +19,7 @@
/*
* Helper function to inform power down state to SCP.
*/
-void css_scp_suspend(const psci_power_state_t *target_state)
+void css_scp_suspend(const struct psci_power_state *target_state)
{
uint32_t cluster_state = scpi_power_on;
uint32_t system_state = scpi_power_on;
diff --git a/plat/arm/css/drivers/scpi/css_scpi.c b/plat/arm/css/drivers/scpi/css_scpi.c
index 3e92c86..2ed5760 100644
--- a/plat/arm/css/drivers/scpi/css_scpi.c
+++ b/plat/arm/css/drivers/scpi/css_scpi.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2014-2017, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2014-2018, ARM Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -11,7 +11,7 @@
#include <platform.h>
#include <string.h>
#include <utils.h>
-#include "css_mhu.h"
+#include "../mhu/css_mhu.h"
#include "css_scpi.h"
#define SCPI_SHARED_MEM_SCP_TO_AP PLAT_CSS_SCP_COM_SHARED_MEM_BASE
diff --git a/plat/arm/css/sgi/sgi-common.mk b/plat/arm/css/sgi/sgi-common.mk
index 9c398b7..659351a 100644
--- a/plat/arm/css/sgi/sgi-common.mk
+++ b/plat/arm/css/sgi/sgi-common.mk
@@ -45,6 +45,7 @@
override CSS_LOAD_SCP_IMAGES := 0
override NEED_BL2U := no
override ARM_BL31_IN_DRAM := 1
+override ARM_PLAT_MT := 1
# System coherency is managed in hardware
HW_ASSISTED_COHERENCY := 1
diff --git a/plat/hisilicon/hikey/hikey_bl2_setup.c b/plat/hisilicon/hikey/hikey_bl2_setup.c
index a78bb1e..a3fc607 100644
--- a/plat/hisilicon/hikey/hikey_bl2_setup.c
+++ b/plat/hisilicon/hikey/hikey_bl2_setup.c
@@ -304,14 +304,12 @@
hikey_gpio_init();
hikey_pmussi_init();
hikey_hi6553_init();
-
- dsb();
- hikey_ddr_init();
- hikey_security_setup();
-
/* Clear SRAM since it'll be used by MCU right now. */
memset((void *)SRAM_BASE, 0, SRAM_SIZE);
- clean_dcache_range(SRAM_BASE, SRAM_SIZE);
+
+ dsb();
+ hikey_ddr_init(DDR_FREQ_800M);
+ hikey_security_setup();
hikey_boardid_init();
init_acpu_dvfs();
@@ -321,6 +319,9 @@
hikey_mmc_pll_init();
+ /* Clean SRAM before MCU used */
+ clean_dcache_range(SRAM_BASE, SRAM_SIZE);
+
reset_dwmmc_clk();
memset(¶ms, 0, sizeof(dw_mmc_params_t));
params.reg_base = DWMMC0_BASE;
diff --git a/plat/hisilicon/hikey/hikey_ddr.c b/plat/hisilicon/hikey/hikey_ddr.c
index ab572eb..43cece0 100644
--- a/plat/hisilicon/hikey/hikey_ddr.c
+++ b/plat/hisilicon/hikey/hikey_ddr.c
@@ -5,17 +5,16 @@
*/
#include <arch_helpers.h>
+#include <assert.h>
#include <debug.h>
#include <errno.h>
#include <hi6220.h>
#include <hi6553.h>
+#include <hisi_sram_map.h>
#include <mmio.h>
#include <sp804_delay_timer.h>
-enum {
- DDR_FREQ_533M = 0,
- DDR_FREQ_800M,
-};
+#include "hikey_private.h"
static void init_pll(void)
{
@@ -24,7 +23,6 @@
data = mmio_read_32((0xf7032000 + 0x000));
data |= 0x1;
mmio_write_32((0xf7032000 + 0x000), data);
- dsb();
do {
data = mmio_read_32((0xf7032000 + 0x000));
} while (!(data & (1 << 28)));
@@ -33,22 +31,45 @@
data &= ~0x007;
data |= 0x004;
mmio_write_32((0xf7800000 + 0x000), data);
- dsb();
do {
data = mmio_read_32((0xf7800000 + 0x014));
data &= 0x007;
} while (data != 0x004);
mmio_write_32(PERI_SC_PERIPH_CTRL14, 0x2101);
- data = mmio_read_32(PERI_SC_PERIPH_STAT1);
+ dsb();
+ isb();
+ udelay(10);
+ mmio_write_32(PERI_SC_PERIPH_CTRL14, 0x2001);
+ dsb();
+ isb();
+ udelay(10);
+ mmio_write_32(PERI_SC_PERIPH_CTRL14, 0x2201);
+ dsb();
+ isb();
+ udelay(10);
mmio_write_32(0xf7032000 + 0x02c, 0x5110103e);
+ dsb();
+ isb();
+ udelay(10);
data = mmio_read_32(0xf7032000 + 0x050);
data |= 1 << 28;
mmio_write_32(0xf7032000 + 0x050, data);
+ dsb();
+ isb();
+ udelay(10);
mmio_write_32(PERI_SC_PERIPH_CTRL14, 0x2101);
- mdelay(1);
- data = mmio_read_32(PERI_SC_PERIPH_STAT1);
- NOTICE("syspll frequency:%dHz\n", data);
+ dsb();
+ isb();
+ udelay(10);
+ mmio_write_32(PERI_SC_PERIPH_CTRL14, 0x2001);
+ dsb();
+ isb();
+ udelay(10);
+ mmio_write_32(PERI_SC_PERIPH_CTRL14, 0x2201);
+ dsb();
+ isb();
+ udelay(10);
}
static void init_freq(void)
@@ -215,7 +236,7 @@
data = mmio_read_32((0xf712c000 + 0x1c8));
data &= 0xfffff0f0;
- data |= 0x100f0f;
+ data |= 0x100f01;
mmio_write_32((0xf712c000 + 0x1c8), data);
for (i = 0; i < 0x20; i++) {
@@ -244,7 +265,7 @@
} while (data & 1);
data = mmio_read_32((0xf712c000 + 0x008));
- if (!(data & 0x400)) {
+ if ((data & 0x400) == 0) {
mdelay(10);
return 0;
}
@@ -489,7 +510,334 @@
INFO("wdet rbs av fail\n");
}
-static void set_ddrc_533mhz(void)
+void set_ddrc_150mhz(void)
+{
+ unsigned int data;
+
+ mmio_write_32((0xf7032000 + 0x580), 0x1);
+ mmio_write_32((0xf7032000 + 0x5a8), 0x7);
+ data = mmio_read_32((0xf7032000 + 0x104));
+ data &= 0xfffffcff;
+ mmio_write_32((0xf7032000 + 0x104), data);
+
+ mmio_write_32((0xf7030000 + 0x050), 0x31);
+ mmio_write_32((0xf7030000 + 0x240), 0x5ffff);
+ mmio_write_32((0xf7030000 + 0x344), 0xf5ff);
+ mmio_write_32((0xf712c000 + 0x00c), 0x80000f0f);
+ mmio_write_32((0xf712c000 + 0x00c), 0xf0f);
+ mmio_write_32((0xf712c000 + 0x018), 0x7);
+ mmio_write_32((0xf712c000 + 0x090), 0x7200000);
+ mmio_write_32((0xf712c000 + 0x258), 0x720);
+ mmio_write_32((0xf712c000 + 0x2d8), 0x720);
+ mmio_write_32((0xf712c000 + 0x358), 0x720);
+ mmio_write_32((0xf712c000 + 0x3d8), 0x720);
+ mmio_write_32((0xf712c000 + 0x018), 0x7);
+ mmio_write_32((0xf712c000 + 0x0b0), 0xf00000f);
+ mmio_write_32((0xf712c000 + 0x0b4), 0xf);
+ mmio_write_32((0xf712c000 + 0x088), 0x3fff801);
+ mmio_write_32((0xf712c000 + 0x070), 0x8940000);
+
+ data = mmio_read_32((0xf712c000 + 0x078));
+ data |= 4;
+ mmio_write_32((0xf712c000 + 0x078), data);
+ mmio_write_32((0xf712c000 + 0x01c), 0x8000080);
+ data = mmio_read_32((0xf712c000 + 0x020));
+ data &= 0xfffffffe;
+ mmio_write_32((0xf712c000 + 0x020), data);
+ mmio_write_32((0xf712c000 + 0x1d4), 0xc0000);
+ mmio_write_32((0xf712c000 + 0x010), 0x500000f);
+ mmio_write_32((0xf712c000 + 0x014), 0x10);
+ data = mmio_read_32((0xf712c000 + 0x1e4));
+ data &= 0xffffff00;
+ mmio_write_32((0xf712c000 + 0x1e4), data);
+ mmio_write_32((0xf712c000 + 0x030), 0x30c82355);
+ mmio_write_32((0xf712c000 + 0x034), 0x62112bb);
+ mmio_write_32((0xf712c000 + 0x038), 0x20041022);
+ mmio_write_32((0xf712c000 + 0x03c), 0x63177497);
+ mmio_write_32((0xf712c000 + 0x040), 0x3008407);
+ mmio_write_32((0xf712c000 + 0x064), 0x10483);
+ mmio_write_32((0xf712c000 + 0x068), 0xff0a0000);
+ data = mmio_read_32((0xf712c000 + 0x070));
+ data &= 0xffff0000;
+ data |= 0x184;
+ mmio_write_32((0xf712c000 + 0x070), data);
+ data = mmio_read_32((0xf712c000 + 0x048));
+ data &= 0xbfffffff;
+ mmio_write_32((0xf712c000 + 0x048), data);
+ data = mmio_read_32((0xf712c000 + 0x020));
+ data &= ~0x10;
+ mmio_write_32((0xf712c000 + 0x020), data);
+ data = mmio_read_32((0xf712c000 + 0x080));
+ data &= ~0x2000;
+ mmio_write_32((0xf712c000 + 0x080), data);
+ mmio_write_32((0xf712c000 + 0x270), 0x3);
+ mmio_write_32((0xf712c000 + 0x2f0), 0x3);
+ mmio_write_32((0xf712c000 + 0x370), 0x3);
+ mmio_write_32((0xf712c000 + 0x3f0), 0x3);
+ mmio_write_32((0xf712c000 + 0x048), 0x90420880);
+
+ mmio_write_32((0xf7128000 + 0x040), 0x0);
+ mmio_write_32((0xf712c000 + 0x004), 0x146d);
+ mmio_write_32((0xf7128000 + 0x050), 0x100123);
+ mmio_write_32((0xf7128000 + 0x060), 0x133);
+ mmio_write_32((0xf7128000 + 0x064), 0x133);
+ mmio_write_32((0xf7128000 + 0x200), 0xa1000);
+
+ mmio_write_32((0xf7128000 + 0x100), 0xb3290d08);
+ mmio_write_32((0xf7128000 + 0x104), 0x9621821);
+ mmio_write_32((0xf7128000 + 0x108), 0x45009023);
+ mmio_write_32((0xf7128000 + 0x10c), 0xaf44c145);
+ mmio_write_32((0xf7128000 + 0x110), 0x10b00000);
+ mmio_write_32((0xf7128000 + 0x114), 0x11080806);
+ mmio_write_32((0xf7128000 + 0x118), 0x44);
+ do {
+ data = mmio_read_32((0xf712c000 + 0x004));
+ } while (data & 1);
+ data = mmio_read_32((0xf712c000 + 0x008));
+ if (data & 8) {
+ NOTICE("fail to init ddr3 rank0\n");
+ return;
+ }
+
+ data = mmio_read_32((0xf712c000 + 0x048));
+ data |= 1;
+ mmio_write_32((0xf712c000 + 0x048), data);
+ mmio_write_32((0xf712c000 + 0x004), 0x21);
+ do {
+ data = mmio_read_32((0xf712c000 + 0x004));
+ } while (data & 1);
+
+ data = mmio_read_32((0xf712c000 + 0x008));
+ if (data & 0x8)
+ NOTICE("ddr3 rank1 init failure\n");
+ else
+ INFO("ddr3 rank1 init pass\n");
+
+ data = mmio_read_32((0xf712c000 + 0x048));
+ data &= ~0xf;
+ mmio_write_32((0xf712c000 + 0x048), data);
+ INFO("succeed to set ddrc 150mhz\n");
+}
+
+void set_ddrc_266mhz(void)
+{
+ unsigned int data;
+
+ mmio_write_32((0xf7032000 + 0x580), 0x3);
+ mmio_write_32((0xf7032000 + 0x5a8), 0x1003);
+ data = mmio_read_32((0xf7032000 + 0x104));
+ data &= 0xfffffcff;
+ mmio_write_32((0xf7032000 + 0x104), data);
+
+ mmio_write_32((0xf7030000 + 0x050), 0x31);
+ mmio_write_32((0xf7030000 + 0x240), 0x5ffff);
+ mmio_write_32((0xf7030000 + 0x344), 0xf5ff);
+ mmio_write_32((0xf712c000 + 0x00c), 0x80000f0f);
+ mmio_write_32((0xf712c000 + 0x00c), 0xf0f);
+ mmio_write_32((0xf712c000 + 0x018), 0x7);
+ mmio_write_32((0xf712c000 + 0x090), 0x7200000);
+ mmio_write_32((0xf712c000 + 0x258), 0x720);
+ mmio_write_32((0xf712c000 + 0x2d8), 0x720);
+ mmio_write_32((0xf712c000 + 0x358), 0x720);
+ mmio_write_32((0xf712c000 + 0x3d8), 0x720);
+ mmio_write_32((0xf712c000 + 0x018), 0x7);
+ mmio_write_32((0xf712c000 + 0x0b0), 0xf00000f);
+ mmio_write_32((0xf712c000 + 0x0b4), 0xf);
+ mmio_write_32((0xf712c000 + 0x088), 0x3fff801);
+ mmio_write_32((0xf712c000 + 0x070), 0x8940000);
+
+ data = mmio_read_32((0xf712c000 + 0x078));
+ data |= 4;
+ mmio_write_32((0xf712c000 + 0x078), data);
+ mmio_write_32((0xf712c000 + 0x01c), 0x8000080);
+ data = mmio_read_32((0xf712c000 + 0x020));
+ data &= 0xfffffffe;
+ mmio_write_32((0xf712c000 + 0x020), data);
+ mmio_write_32((0xf712c000 + 0x1d4), 0xc0000);
+ mmio_write_32((0xf712c000 + 0x010), 0x500000f);
+ mmio_write_32((0xf712c000 + 0x014), 0x10);
+ data = mmio_read_32((0xf712c000 + 0x1e4));
+ data &= 0xffffff00;
+ mmio_write_32((0xf712c000 + 0x1e4), data);
+ mmio_write_32((0xf712c000 + 0x030), 0x510d4455);
+ mmio_write_32((0xf712c000 + 0x034), 0x8391ebb);
+ mmio_write_32((0xf712c000 + 0x038), 0x2005103c);
+ mmio_write_32((0xf712c000 + 0x03c), 0x6329950b);
+ mmio_write_32((0xf712c000 + 0x040), 0x300858c);
+ mmio_write_32((0xf712c000 + 0x064), 0x10483);
+ mmio_write_32((0xf712c000 + 0x068), 0xff0a0000);
+ data = mmio_read_32((0xf712c000 + 0x070));
+ data &= 0xffff0000;
+ data |= 0x184;
+ mmio_write_32((0xf712c000 + 0x070), data);
+ data = mmio_read_32((0xf712c000 + 0x048));
+ data &= 0xbfffffff;
+ mmio_write_32((0xf712c000 + 0x048), data);
+ data = mmio_read_32((0xf712c000 + 0x020));
+ data &= ~0x10;
+ mmio_write_32((0xf712c000 + 0x020), data);
+ data = mmio_read_32((0xf712c000 + 0x080));
+ data &= ~0x2000;
+ mmio_write_32((0xf712c000 + 0x080), data);
+ mmio_write_32((0xf712c000 + 0x270), 0x3);
+ mmio_write_32((0xf712c000 + 0x2f0), 0x3);
+ mmio_write_32((0xf712c000 + 0x370), 0x3);
+ mmio_write_32((0xf712c000 + 0x3f0), 0x3);
+ mmio_write_32((0xf712c000 + 0x048), 0x90420880);
+
+ mmio_write_32((0xf7128000 + 0x040), 0x0);
+ mmio_write_32((0xf712c000 + 0x004), 0x146d);
+ mmio_write_32((0xf7128000 + 0x050), 0x100123);
+ mmio_write_32((0xf7128000 + 0x060), 0x133);
+ mmio_write_32((0xf7128000 + 0x064), 0x133);
+ mmio_write_32((0xf7128000 + 0x200), 0xa1000);
+
+ mmio_write_32((0xf7128000 + 0x100), 0xb441d50d);
+ mmio_write_32((0xf7128000 + 0x104), 0xf721839);
+ mmio_write_32((0xf7128000 + 0x108), 0x5500f03f);
+ mmio_write_32((0xf7128000 + 0x10c), 0xaf486145);
+ mmio_write_32((0xf7128000 + 0x110), 0x10b00000);
+ mmio_write_32((0xf7128000 + 0x114), 0x12080d06);
+ mmio_write_32((0xf7128000 + 0x118), 0x44);
+ do {
+ data = mmio_read_32((0xf712c000 + 0x004));
+ } while (data & 1);
+ data = mmio_read_32((0xf712c000 + 0x008));
+ if (data & 8) {
+ NOTICE("fail to init ddr3 rank0\n");
+ return;
+ }
+
+ data = mmio_read_32((0xf712c000 + 0x048));
+ data |= 1;
+ mmio_write_32((0xf712c000 + 0x048), data);
+ mmio_write_32((0xf712c000 + 0x004), 0x21);
+ do {
+ data = mmio_read_32((0xf712c000 + 0x004));
+ } while (data & 1);
+
+ data = mmio_read_32((0xf712c000 + 0x008));
+ if (data & 0x8)
+ NOTICE("ddr3 rank1 init failure\n");
+ else
+ INFO("ddr3 rank1 init pass\n");
+
+ data = mmio_read_32((0xf712c000 + 0x048));
+ data &= ~0xf;
+ mmio_write_32((0xf712c000 + 0x048), data);
+ INFO("succeed to set ddrc 266mhz\n");
+}
+
+void set_ddrc_400mhz(void)
+{
+ unsigned int data;
+
+ mmio_write_32((0xf7032000 + 0x580), 0x2);
+ mmio_write_32((0xf7032000 + 0x5a8), 0x1003);
+ data = mmio_read_32((0xf7032000 + 0x104));
+ data &= 0xfffffcff;
+ mmio_write_32((0xf7032000 + 0x104), data);
+
+ mmio_write_32((0xf7030000 + 0x050), 0x31);
+ mmio_write_32((0xf7030000 + 0x240), 0x5ffff);
+ mmio_write_32((0xf7030000 + 0x344), 0xf5ff);
+ mmio_write_32((0xf712c000 + 0x00c), 0x80000f0f);
+ mmio_write_32((0xf712c000 + 0x00c), 0xf0f);
+ mmio_write_32((0xf712c000 + 0x018), 0x7);
+ mmio_write_32((0xf712c000 + 0x090), 0x7200000);
+ mmio_write_32((0xf712c000 + 0x258), 0x720);
+ mmio_write_32((0xf712c000 + 0x2d8), 0x720);
+ mmio_write_32((0xf712c000 + 0x358), 0x720);
+ mmio_write_32((0xf712c000 + 0x3d8), 0x720);
+ mmio_write_32((0xf712c000 + 0x018), 0x7);
+ mmio_write_32((0xf712c000 + 0x0b0), 0xf00000f);
+ mmio_write_32((0xf712c000 + 0x0b4), 0xf);
+ mmio_write_32((0xf712c000 + 0x088), 0x3fff801);
+ mmio_write_32((0xf712c000 + 0x070), 0x8940000);
+
+ data = mmio_read_32((0xf712c000 + 0x078));
+ data |= 4;
+ mmio_write_32((0xf712c000 + 0x078), data);
+ mmio_write_32((0xf712c000 + 0x01c), 0x8000080);
+ data = mmio_read_32((0xf712c000 + 0x020));
+ data &= 0xfffffffe;
+ mmio_write_32((0xf712c000 + 0x020), data);
+ mmio_write_32((0xf712c000 + 0x1d4), 0xc0000);
+ mmio_write_32((0xf712c000 + 0x010), 0x500000f);
+ mmio_write_32((0xf712c000 + 0x014), 0x10);
+ data = mmio_read_32((0xf712c000 + 0x1e4));
+ data &= 0xffffff00;
+ mmio_write_32((0xf712c000 + 0x1e4), data);
+ mmio_write_32((0xf712c000 + 0x030), 0x75525655);
+ mmio_write_32((0xf712c000 + 0x034), 0xa552abb);
+ mmio_write_32((0xf712c000 + 0x038), 0x20071059);
+ mmio_write_32((0xf712c000 + 0x03c), 0x633e8591);
+ mmio_write_32((0xf712c000 + 0x040), 0x3008691);
+ mmio_write_32((0xf712c000 + 0x064), 0x10483);
+ mmio_write_32((0xf712c000 + 0x068), 0xff0a0000);
+ data = mmio_read_32((0xf712c000 + 0x070));
+ data &= 0xffff0000;
+ data |= 0x184;
+ mmio_write_32((0xf712c000 + 0x070), data);
+ data = mmio_read_32((0xf712c000 + 0x048));
+ data &= 0xbfffffff;
+ mmio_write_32((0xf712c000 + 0x048), data);
+ data = mmio_read_32((0xf712c000 + 0x020));
+ data &= ~0x10;
+ mmio_write_32((0xf712c000 + 0x020), data);
+ data = mmio_read_32((0xf712c000 + 0x080));
+ data &= ~0x2000;
+ mmio_write_32((0xf712c000 + 0x080), data);
+ mmio_write_32((0xf712c000 + 0x270), 0x3);
+ mmio_write_32((0xf712c000 + 0x2f0), 0x3);
+ mmio_write_32((0xf712c000 + 0x370), 0x3);
+ mmio_write_32((0xf712c000 + 0x3f0), 0x3);
+ mmio_write_32((0xf712c000 + 0x048), 0x90420880);
+
+ mmio_write_32((0xf7128000 + 0x040), 0x0);
+ mmio_write_32((0xf712c000 + 0x004), 0x146d);
+ mmio_write_32((0xf7128000 + 0x050), 0x100123);
+ mmio_write_32((0xf7128000 + 0x060), 0x133);
+ mmio_write_32((0xf7128000 + 0x064), 0x133);
+ mmio_write_32((0xf7128000 + 0x200), 0xa1000);
+
+ mmio_write_32((0xf7128000 + 0x100), 0xb55a9d12);
+ mmio_write_32((0xf7128000 + 0x104), 0x17721855);
+ mmio_write_32((0xf7128000 + 0x108), 0x7501505f);
+ mmio_write_32((0xf7128000 + 0x10c), 0xaf4ca245);
+ mmio_write_32((0xf7128000 + 0x110), 0x10b00000);
+ mmio_write_32((0xf7128000 + 0x114), 0x13081306);
+ mmio_write_32((0xf7128000 + 0x118), 0x44);
+ do {
+ data = mmio_read_32((0xf712c000 + 0x004));
+ } while (data & 1);
+ data = mmio_read_32((0xf712c000 + 0x008));
+ if (data & 8) {
+ NOTICE("fail to init ddr3 rank0\n");
+ return;
+ }
+
+ data = mmio_read_32((0xf712c000 + 0x048));
+ data |= 1;
+ mmio_write_32((0xf712c000 + 0x048), data);
+ mmio_write_32((0xf712c000 + 0x004), 0x21);
+ do {
+ data = mmio_read_32((0xf712c000 + 0x004));
+ } while (data & 1);
+
+ data = mmio_read_32((0xf712c000 + 0x008));
+ if (data & 0x8)
+ NOTICE("ddr3 rank1 init failure\n");
+ else
+ INFO("ddr3 rank1 init pass\n");
+
+ data = mmio_read_32((0xf712c000 + 0x048));
+ data &= ~0xf;
+ mmio_write_32((0xf712c000 + 0x048), data);
+ INFO("succeed to set ddrc 400mhz\n");
+}
+
+void set_ddrc_533mhz(void)
{
unsigned int data;
@@ -503,6 +851,7 @@
mmio_write_32((0xf7030000 + 0x240), 0x5ffff);
mmio_write_32((0xf7030000 + 0x344), 0xf5ff);
mmio_write_32((0xf712c000 + 0x00c), 0x400);
+ mmio_write_32((0xf712c000 + 0x00c), 0x400);
mmio_write_32((0xf712c000 + 0x018), 0x7);
mmio_write_32((0xf712c000 + 0x090), 0x6400000);
mmio_write_32((0xf712c000 + 0x258), 0x640);
@@ -564,10 +913,53 @@
NOTICE("failed to init lpddr3 rank0 dram phy\n");
return;
}
- NOTICE("succeed to init lpddr3 rank0 dram phy\n");
+ cat_533mhz_800mhz();
+
+ mmio_write_32((0xf712c000 + 0x004), 0xf1);
+ mmio_write_32((0xf7128000 + 0x050), 0x100123);
+ mmio_write_32((0xf7128000 + 0x060), 0x133);
+ mmio_write_32((0xf7128000 + 0x064), 0x133);
+ mmio_write_32((0xf7128000 + 0x200), 0xa1000);
+
+ mmio_write_32((0xf7128000 + 0x100), 0xb77b6718);
+ mmio_write_32((0xf7128000 + 0x104), 0x1e82a071);
+ mmio_write_32((0xf7128000 + 0x108), 0x9501c07e);
+ mmio_write_32((0xf7128000 + 0x10c), 0xaf50c255);
+ mmio_write_32((0xf7128000 + 0x110), 0x10b00000);
+ mmio_write_32((0xf7128000 + 0x114), 0x13181908);
+ mmio_write_32((0xf7128000 + 0x118), 0x44);
+ do {
+ data = mmio_read_32((0xf712c000 + 0x004));
+ } while (data & 1);
+ data = mmio_read_32((0xf712c000 + 0x008));
+ if (data & 0x7fe) {
+ NOTICE("fail to init ddr3 rank0\n");
+ return;
+ }
+ ddrx_rdet();
+ ddrx_wdet();
+
+ data = mmio_read_32((0xf712c000 + 0x048));
+ data |= 1;
+ mmio_write_32((0xf712c000 + 0x048), data);
+ mmio_write_32((0xf712c000 + 0x004), 0x21);
+ do {
+ data = mmio_read_32((0xf712c000 + 0x004));
+ } while (data & 1);
+
+ data = mmio_read_32((0xf712c000 + 0x008));
+ if (data & 0x7fe)
+ NOTICE("ddr3 rank1 init failure\n");
+ else
+ INFO("ddr3 rank1 init pass\n");
+
+ data = mmio_read_32((0xf712c000 + 0x048));
+ data &= ~0xf;
+ mmio_write_32((0xf712c000 + 0x048), data);
+ INFO("succeed to set ddrc 533mhz\n");
}
-static void set_ddrc_800mhz(void)
+void set_ddrc_800mhz(void)
{
unsigned int data;
@@ -581,6 +973,7 @@
mmio_write_32((0xf7030000 + 0x240), 0x5ffff);
mmio_write_32((0xf7030000 + 0x344), 0xf5ff);
mmio_write_32((0xf712c000 + 0x00c), 0x400);
+ mmio_write_32((0xf712c000 + 0x00c), 0x400);
mmio_write_32((0xf712c000 + 0x018), 0x7);
mmio_write_32((0xf712c000 + 0x090), 0x5400000);
mmio_write_32((0xf712c000 + 0x258), 0x540);
@@ -642,9 +1035,53 @@
WARN("failed to init lpddr3 rank0 dram phy\n");
return;
}
+ cat_533mhz_800mhz();
+
+ mmio_write_32((0xf712c000 + 0x004), 0xf1);
+ mmio_write_32((0xf7128000 + 0x050), 0x100023);
+ mmio_write_32((0xf7128000 + 0x060), 0x133);
+ mmio_write_32((0xf7128000 + 0x064), 0x133);
+ mmio_write_32((0xf7128000 + 0x200), 0xa1000);
+
+ mmio_write_32((0xf7128000 + 0x100), 0x755a9d12);
+ mmio_write_32((0xf7128000 + 0x104), 0x1753b055);
+ mmio_write_32((0xf7128000 + 0x108), 0x7401505f);
+ mmio_write_32((0xf7128000 + 0x10c), 0x578ca244);
+ mmio_write_32((0xf7128000 + 0x110), 0x10700000);
+ mmio_write_32((0xf7128000 + 0x114), 0x13141306);
+ mmio_write_32((0xf7128000 + 0x118), 0x44);
+ do {
+ data = mmio_read_32((0xf712c000 + 0x004));
+ } while (data & 1);
+ data = mmio_read_32((0xf712c000 + 0x008));
+ if (data & 0x7fe) {
+ NOTICE("fail to init ddr3 rank0\n");
+ return;
+ }
+ ddrx_rdet();
+ ddrx_wdet();
+
+ data = mmio_read_32((0xf712c000 + 0x048));
+ data |= 1;
+ mmio_write_32((0xf712c000 + 0x048), data);
+ mmio_write_32((0xf712c000 + 0x004), 0x21);
+ do {
+ data = mmio_read_32((0xf712c000 + 0x004));
+ } while (data & 1);
+
+ data = mmio_read_32((0xf712c000 + 0x008));
+ if (data & 0x7fe)
+ NOTICE("ddr3 rank1 init failure\n");
+ else
+ INFO("ddr3 rank1 init pass\n");
+
+ data = mmio_read_32((0xf712c000 + 0x048));
+ data &= ~0xf;
+ mmio_write_32((0xf712c000 + 0x048), data);
+ INFO("succeed to set ddrc 800mhz\n");
}
-static void ddrc_common_init(int ddr800)
+static void ddrc_common_init(int freq)
{
unsigned int data;
@@ -653,11 +1090,10 @@
mmio_write_32((0xf7120000 + 0x104), 0x71040004);
mmio_write_32((0xf7121400 + 0x104), 0xf);
mmio_write_32((0xf7121800 + 0x104), 0xf);
- mmio_write_32((0xf7121800 + 0x104), 0xf);
mmio_write_32((0xf7121c00 + 0x104), 0xf);
mmio_write_32((0xf7122000 + 0x104), 0xf);
mmio_write_32((0xf7128000 + 0x02c), 0x6);
- mmio_write_32((0xf7128000 + 0x020), 0x1);
+ mmio_write_32((0xf7128000 + 0x020), 0x30003);
mmio_write_32((0xf7128000 + 0x028), 0x310201);
mmio_write_32((0xf712c000 + 0x1e4), 0xfe007600);
mmio_write_32((0xf7128000 + 0x01c), 0xaf001);
@@ -668,10 +1104,10 @@
mmio_write_32((0xf7128000 + 0x280), data);
mmio_write_32((0xf7128000 + 0x244), 0x3);
- if (ddr800)
- mmio_write_32((0xf7128000 + 0x240), 167 * 400000 / 1024);
+ if (freq == DDR_FREQ_800M)
+ mmio_write_32((0xf7128000 + 0x240), 167 * (freq / 2) / 1024);
else
- mmio_write_32((0xf7128000 + 0x240), 167 * 533000 / 1024);
+ mmio_write_32((0xf7128000 + 0x240), 167 * freq / 1024);
data = mmio_read_32((0xf712c000 + 0x080));
data &= 0xffff;
@@ -702,20 +1138,24 @@
mmio_write_32((0xf7128000 + 0x064), 0x132);
mmio_write_32((0xf7120000 + 0x100), 0x1600);
mmio_write_32((0xf7120000 + 0x104), 0x71040004);
+ mmio_write_32(MEMORY_AXI_DDR_CAPACITY_ADDR, 0x40000000);
break;
case 0x1c:
mmio_write_32((0xf7128000 + 0x060), 0x142);
mmio_write_32((0xf7128000 + 0x064), 0x142);
mmio_write_32((0xf7120000 + 0x100), 0x1700);
mmio_write_32((0xf7120000 + 0x104), 0x71040004);
+ mmio_write_32(MEMORY_AXI_DDR_CAPACITY_ADDR, 0x80000000);
break;
case 0x58:
mmio_write_32((0xf7128000 + 0x060), 0x133);
mmio_write_32((0xf7128000 + 0x064), 0x133);
mmio_write_32((0xf7120000 + 0x100), 0x1700);
mmio_write_32((0xf7120000 + 0x104), 0x71040004);
+ mmio_write_32(MEMORY_AXI_DDR_CAPACITY_ADDR, 0x80000000);
break;
default:
+ mmio_write_32(MEMORY_AXI_DDR_CAPACITY_ADDR, 0x80000000);
break;
}
if (!data)
@@ -772,73 +1212,114 @@
return data;
}
+void ddr_phy_reset(void)
+{
+ mmio_write_32(0xf7030340, 0xa000);
+ mmio_write_32(0xf7030344, 0xa000);
+}
+
+void lpddrx_save_ddl_para_bypass(uint32_t *ddr_ddl_para, unsigned int index)
+{
+ uint32_t value;
+ uint32_t cnt = index;
+ uint32_t i;
+
+ for (i = 0; i < 4; i++) {
+ value = mmio_read_32(0xf712c000 + 0x22c + i * 0x80);
+ ddr_ddl_para[cnt++] = value;
+ value = mmio_read_32(0xf712c000 + 0x23c + i * 0x80);
+ ddr_ddl_para[cnt++] = value;
+ value = mmio_read_32(0xf712c000 + 0x240 + i * 0x80);
+ ddr_ddl_para[cnt++] = value;
+ value = mmio_read_32(0xf712c000 + 0x640 + i * 0x80);
+ ddr_ddl_para[cnt++] = value;
+ }
+}
+
+void lpddrx_save_ddl_para_mission(uint32_t *ddr_ddl_para, unsigned int index)
+{
+ uint32_t value;
+ uint32_t cnt = index;
+ uint32_t i;
+
+ value = mmio_read_32(0xf712c000 + 0x140);
+ ddr_ddl_para[cnt++] = value;
+ value = mmio_read_32(0xf712c000 + 0x144);
+ ddr_ddl_para[cnt++] = value;
+ value = mmio_read_32(0xf712c000 + 0x148);
+ ddr_ddl_para[cnt++] = value;
+ value = mmio_read_32(0xf712c000 + 0x14c);
+ ddr_ddl_para[cnt++] = value;
+ value = mmio_read_32(0xf712c000 + 0x150);
+ ddr_ddl_para[cnt++] = value;
+ value = mmio_read_32(0xf712c000 + 0x1d4);
+ ddr_ddl_para[cnt++] = value;
+ for (i = 0; i < 4; i++) {
+ value = mmio_read_32(0xf712c000 + 0x210 + i * 0x80);
+ ddr_ddl_para[cnt++] = value;
+ value = mmio_read_32(0xf712c000 + 0x214 + i * 0x80);
+ ddr_ddl_para[cnt++] = value;
+ value = mmio_read_32(0xf712c000 + 0x218 + i * 0x80);
+ ddr_ddl_para[cnt++] = value;
+ value = mmio_read_32(0xf712c000 + 0x21c + i * 0x80);
+ ddr_ddl_para[cnt++] = value;
+ value = mmio_read_32(0xf712c000 + 0x220 + i * 0x80);
+ ddr_ddl_para[cnt++] = value;
+ value = mmio_read_32(0xf712c000 + 0x224 + i * 0x80);
+ ddr_ddl_para[cnt++] = value;
+ value = mmio_read_32(0xf712c000 + 0x228 + i * 0x80);
+ ddr_ddl_para[cnt++] = value;
+ value = mmio_read_32(0xf712c000 + 0x22c + i * 0x80);
+ ddr_ddl_para[cnt++] = value;
+ value = mmio_read_32(0xf712c000 + 0x230 + i * 0x80);
+ ddr_ddl_para[cnt++] = value;
+ value = mmio_read_32(0xf712c000 + 0x234 + i * 0x80);
+ ddr_ddl_para[cnt++] = value;
+ value = mmio_read_32(0xf712c000 + 0x238 + i * 0x80);
+ ddr_ddl_para[cnt++] = value;
+ value = mmio_read_32(0xf712c000 + 0x23c + i * 0x80);
+ ddr_ddl_para[cnt++] = value;
+ value = mmio_read_32(0xf712c000 + 0x240 + i * 0x80);
+ ddr_ddl_para[cnt++] = value;
+ value = mmio_read_32(0xf712c000 + 0x640 + i * 0x80);
+ ddr_ddl_para[cnt++] = value;
+ }
+ value = mmio_read_32(0xf712c000 + 0x168);
+ ddr_ddl_para[cnt++] = value;
+ value = mmio_read_32(0xf712c000 + 0x24c + 0 * 0x80);
+ ddr_ddl_para[cnt++] = value;
+ value = mmio_read_32(0xf712c000 + 0x24c + 2 * 0x80);
+ ddr_ddl_para[cnt++] = value;
+}
+
int lpddr3_freq_init(int freq)
{
- unsigned int data;
-
- if (freq == DDR_FREQ_800M) {
- set_ddrc_800mhz();
- INFO("%s, set ddrc 800mhz\n", __func__);
- } else {
+ set_ddrc_150mhz();
+ lpddrx_save_ddl_para_bypass((uint32_t *)MEMORY_AXI_DDR_DDL_ADDR, 0);
+ if (freq > DDR_FREQ_150M) {
+ ddr_phy_reset();
+ set_ddrc_266mhz();
+ lpddrx_save_ddl_para_bypass((uint32_t *)MEMORY_AXI_DDR_DDL_ADDR,
+ 16);
+ }
+ if (freq > DDR_FREQ_266M) {
+ ddr_phy_reset();
+ set_ddrc_400mhz();
+ lpddrx_save_ddl_para_bypass((uint32_t *)MEMORY_AXI_DDR_DDL_ADDR,
+ 16 * 2);
+ }
+ if (freq > DDR_FREQ_400M) {
+ ddr_phy_reset();
set_ddrc_533mhz();
- INFO("%s, set ddrc 533mhz\n", __func__);
+ lpddrx_save_ddl_para_mission((uint32_t *)MEMORY_AXI_DDR_DDL_ADDR,
+ 16 * 3);
}
-
- mmio_write_32((0xf712c000 + 0x004), 0xf1);
- if (freq == DDR_FREQ_800M)
- mmio_write_32((0xf7128000 + 0x050), 0x100023);
- else
- mmio_write_32((0xf7128000 + 0x050), 0x100123);
- mmio_write_32((0xf7128000 + 0x060), 0x133);
- mmio_write_32((0xf7128000 + 0x064), 0x133);
- mmio_write_32((0xf7128000 + 0x200), 0xa1000);
-
- if (freq == DDR_FREQ_800M) {
- mmio_write_32((0xf7128000 + 0x100), 0x755a9d12);
- mmio_write_32((0xf7128000 + 0x104), 0x1753b055);
- mmio_write_32((0xf7128000 + 0x108), 0x7401505f);
- mmio_write_32((0xf7128000 + 0x10c), 0x578ca244);
- mmio_write_32((0xf7128000 + 0x110), 0x10700000);
- mmio_write_32((0xf7128000 + 0x114), 0x13141306);
- } else {
- mmio_write_32((0xf7128000 + 0x100), 0xb77b6718);
- mmio_write_32((0xf7128000 + 0x104), 0x1e82a071);
- mmio_write_32((0xf7128000 + 0x108), 0x9501c07e);
- mmio_write_32((0xf7128000 + 0x10c), 0xaf50c255);
- mmio_write_32((0xf7128000 + 0x110), 0x10b00000);
- mmio_write_32((0xf7128000 + 0x114), 0x13181908);
+ if (freq > DDR_FREQ_533M) {
+ ddr_phy_reset();
+ set_ddrc_800mhz();
+ lpddrx_save_ddl_para_mission((uint32_t *)MEMORY_AXI_DDR_DDL_ADDR,
+ 16 * 3 + 61);
}
- mmio_write_32((0xf7128000 + 0x118), 0x44);
- do {
- data = mmio_read_32((0xf712c000 + 0x004));
- } while (data & 1);
-
- data = mmio_read_32((0xf712c000 + 0x008));
- if (data & 0x7fe) {
- NOTICE("fail to init ddr3 rank0\n");
- return -EFAULT;
- }
- INFO("init ddr3 rank0\n");
- ddrx_rdet();
- ddrx_wdet();
-
- data = mmio_read_32((0xf712c000 + 0x048));
- data |= 1;
- mmio_write_32((0xf712c000 + 0x048), data);
- mmio_write_32((0xf712c000 + 0x004), 0x21);
- do {
- data = mmio_read_32((0xf712c000 + 0x004));
- } while (data & 1);
-
- data = mmio_read_32((0xf712c000 + 0x008));
- if (data & 0x7fe)
- NOTICE("ddr3 rank1 init failure\n");
- else
- INFO("ddr3 rank1 init pass\n");
-
- data = mmio_read_32((0xf712c000 + 0x048));
- data &= ~0xf;
- mmio_write_32((0xf712c000 + 0x048), data);
return 0;
}
@@ -855,7 +1336,7 @@
data |= 1;
mmio_write_32((0xf7032000 + 0x010), data);
- udelay(100);
+ udelay(300);
do {
data = mmio_read_32((0xf7032000 + 0x030));
data &= 3 << 28;
@@ -923,38 +1404,40 @@
mmio_write_32((0xf7124000 + 0x0d0), 0x3020100);
}
-static void ddr_phy_reset(void)
-{
- mmio_write_32(0xf7030340, 0xa000);
- mmio_write_32(0xf7030344, 0xa000);
-}
-
-void hikey_ddr_init(void)
+void hikey_ddr_init(unsigned int ddr_freq)
{
uint32_t data;
+ assert((ddr_freq == DDR_FREQ_150M) || (ddr_freq == DDR_FREQ_266M) ||
+ (ddr_freq == DDR_FREQ_400M) || (ddr_freq == DDR_FREQ_533M) ||
+ (ddr_freq == DDR_FREQ_800M));
init_pll();
init_freq();
- /*
- * Init DDR with 533MHz. Otherwise, DDR initialization
- * may fail on 800MHz on some boards.
- */
- ddr_phy_reset();
- init_ddr(DDR_FREQ_533M);
- /* Init DDR with 800MHz. */
- ddr_phy_reset();
- init_ddr(DDR_FREQ_800M);
+ init_ddr(ddr_freq);
-
- ddrc_common_init(1);
+ ddrc_common_init(ddr_freq);
dienum_det_and_rowcol_cfg();
detect_ddr_chip_info();
- data = mmio_read_32(0xf7032000 + 0x010);
- data &= ~0x1;
- mmio_write_32(0xf7032000 + 0x010, data);
- data = mmio_read_32(0xf7032000 + 0x010);
+ if ((ddr_freq == DDR_FREQ_400M) || (ddr_freq == DDR_FREQ_800M)) {
+ data = mmio_read_32(0xf7032000 + 0x010);
+ data &= ~0x1;
+ mmio_write_32(0xf7032000 + 0x010, data);
+ } else if ((ddr_freq == DDR_FREQ_266M) || (ddr_freq == DDR_FREQ_533M)) {
+ data = mmio_read_32(0xf7032000 + 0x030);
+ data &= ~0x1;
+ mmio_write_32(0xf7032000 + 0x030, data);
+ } else {
+ data = mmio_read_32(0xf7032000 + 0x010);
+ data &= ~0x1;
+ mmio_write_32(0xf7032000 + 0x010, data);
+ data = mmio_read_32(0xf7032000 + 0x030);
+ data &= ~0x1;
+ mmio_write_32(0xf7032000 + 0x030, data);
+ }
+ dsb();
+ isb();
/*
* Test memory access. Do not use address 0x0 because the compiler
diff --git a/plat/hisilicon/hikey/hikey_private.h b/plat/hisilicon/hikey/hikey_private.h
index 7654921..e6d109a 100644
--- a/plat/hisilicon/hikey/hikey_private.h
+++ b/plat/hisilicon/hikey/hikey_private.h
@@ -12,6 +12,14 @@
#define RANDOM_MAX 0x7fffffffffffffff
#define RANDOM_MAGIC 0x9a4dbeaf
+enum {
+ DDR_FREQ_150M = 150 * 1000,
+ DDR_FREQ_266M = 266 * 1000,
+ DDR_FREQ_400M = 400 * 1000,
+ DDR_FREQ_533M = 533 * 1000,
+ DDR_FREQ_800M = 800 * 1000
+};
+
struct random_serial_num {
uint64_t magic;
uint64_t data;
@@ -34,7 +42,7 @@
unsigned long coh_start,
unsigned long coh_limit);
-void hikey_ddr_init(void);
+void hikey_ddr_init(unsigned int ddr_freq);
void hikey_io_setup(void);
void hikey_sp804_init(void);
diff --git a/plat/layerscape/board/ls1043/aarch64/ls1043_helpers.S b/plat/layerscape/board/ls1043/aarch64/ls1043_helpers.S
new file mode 100644
index 0000000..80524fc
--- /dev/null
+++ b/plat/layerscape/board/ls1043/aarch64/ls1043_helpers.S
@@ -0,0 +1,147 @@
+/*
+ * Copyright (c) 2018, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <arch.h>
+#include <asm_macros.S>
+#include <platform_def.h>
+
+ .globl plat_reset_handler
+ .globl plat_my_core_pos
+ .globl platform_mem_init
+
+func plat_my_core_pos
+ mrs x0, mpidr_el1
+ and x1, x0, #MPIDR_CPU_MASK //reserve the last 8 bits
+ and x0, x0, #MPIDR_CLUSTER_MASK
+ add x0, x1, x0, LSR #4 //4 cores
+ ret
+endfunc plat_my_core_pos
+
+func platform_mem_init
+ mov x29, x30
+ bl inv_dcache_range
+
+//SDRAM_CFG
+ ldr w0, =0x1080000
+ ldr w1, =0x0c000c45
+ str w1, [x0, #0x110]
+//CS0_BNDS
+ ldr w1, =0x7f000000
+ str w1, [x0, #0x000]
+//CS0_CONFIG
+ ldr w1, =0x22030480
+ str w1, [x0, #0x080]
+//TIMING_CFG_0
+ ldr w1, =0x18005591
+ str w1, [x0, #0x104]
+//TIMING_CFG_1
+ ldr w1, =0x428cb4bb
+ str w1, [x0, #0x108]
+//TIMING_CFG_2
+ ldr w1, =0x11c14800
+ str w1, [x0, #0x10C]
+//TIMING_CFG_3
+ ldr w1, =0x00100c01
+ str w1, [x0, #0x100]
+//TIMING_CFG_4
+ ldr w1, =0x02000000
+ str w1, [x0, #0x160]
+//TIMING_CFG_5
+ ldr w1, =0x00144003
+ str w1, [x0, #0x164]
+//TIMING_CFG_7
+ ldr w1, =0x00003013
+ str w1, [x0, #0x16C]
+//TIMING_CFG_8
+ ldr w1, =0x00561102
+ str w1, [x0, #0x250]
+//SDRAM_CFG_2
+ ldr w1, =0x00114000
+ str w1, [x0, #0x114]
+//SDRAM_MODE
+ ldr w1, =0x10020103
+ str w1, [x0, #0x118]
+//SDRAM_MODE_2
+ ldr w1, =0x0
+ str w1, [x0, #0x11C]
+//SDRAM_INTERVAL
+ ldr w1, =0x18066018
+ str w1, [x0, #0x124]
+//DDR_WRLVL_CNTL
+ ldr w1, =0x07f675c6
+ str w1, [x0, #0x174]
+//DDR_WRLVL_CNTL_2
+ ldr w1, =0x00080907
+ str w1, [x0, #0x190]
+//DDR_WRLVL_CNTL_3
+ ldr w1, =0x0
+ str w1, [x0, #0x194]
+//DDR_CDR1
+ ldr w1, =0x00000480
+ str w1, [x0, #0xB28]
+//DDR_CDR2
+ ldr w1, =0x81a10000
+ str w1, [x0, #0xB2C]
+//SDRAM_CLK_CNTL
+ ldr w1, =0x00000003
+ str w1, [x0, #0x130]
+//DDR_ZQ_CNTL
+ ldr w1, =0x0507098a
+ str w1, [x0, #0x170]
+//SDRAM_MODE_9
+ ldr w1, =0x00050000
+ str w1, [x0, #0x220]
+//SDRAM_MODE_10
+ ldr w1, =0x00000004
+ str w1, [x0, #0x224]
+//CS0_CONFIG_2
+ ldr w1, =0x0
+ str w1, [x0, #0x0C0]
+//SDRAM_CFG
+ ldr w1, =0x08000cc5
+ str w1, [x0, #0x110]
+
+ mov w3,#0
+ ldr w4,=0xffffff01
+z_loop:
+delay_loop1:
+ sub w4, w4, #1
+ cmp w4, #0
+ b.gt delay_loop1
+
+ ldr w1, [x0, #0x114]
+ add w3, w3, #1
+ cmp w1, #0 //'\n'
+ b.eq 1f
+ cmp w3, #20
+ b.gt 1f
+ b z_loop
+
+1:
+ ldr w4,=0xffffff02
+delay_loop2:
+ sub w4, w4, #1
+ cmp w4, #0
+ b.gt delay_loop2
+
+ ldr w1, =0x00000000
+ str w1, [x0]
+
+ ret x29
+endfunc platform_mem_init
+
+func apply_platform_errata
+ /*TODO if needed*/
+ ret
+endfunc apply_platform_errata
+
+func plat_reset_handler
+ mov x29, x30
+ bl apply_platform_errata
+
+ mov x30, x29
+ ret
+endfunc plat_reset_handler
diff --git a/plat/layerscape/board/ls1043/include/ls_def.h b/plat/layerscape/board/ls1043/include/ls_def.h
new file mode 100644
index 0000000..1015129
--- /dev/null
+++ b/plat/layerscape/board/ls1043/include/ls_def.h
@@ -0,0 +1,107 @@
+/*
+ * Copyright (c) 2018, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef __LS_DEF_H__
+#define __LS_DEF_H__
+
+#include <arch.h>
+#include <common_def.h>
+#include <platform_def.h>
+#include <tbbr_img_def.h>
+#include <utils_def.h>
+#include <xlat_tables_defs.h>
+
+
+/******************************************************************************
+ * Definitions common to all ARM standard platforms
+ *****************************************************************************/
+/* Special value used to verify platform parameters from BL2 to BL31 */
+#define LS_BL31_PLAT_PARAM_VAL 0x0f1e2d3c4b5a6978ULL
+
+#define LS_CACHE_WRITEBACK_SHIFT 6
+
+/*
+ * Macros mapping the MPIDR Affinity levels to Layerscape Platform Power levels. The
+ * power levels have a 1:1 mapping with the MPIDR affinity levels.
+ */
+#define LS_PWR_LVL0 MPIDR_AFFLVL0
+#define LS_PWR_LVL1 MPIDR_AFFLVL1
+#define LS_PWR_LVL2 MPIDR_AFFLVL2
+
+/*
+ * Macros for local power states in Layerscape platforms encoded by State-ID field
+ * within the power-state parameter.
+ */
+/* Local power state for power domains in Run state. */
+#define LS_LOCAL_STATE_RUN 0
+/* Local power state for retention. Valid only for CPU power domains */
+#define LS_LOCAL_STATE_RET 1
+/*
+ * Local power state for OFF/power-down. Valid for CPU and cluster power
+ * domains
+ */
+#define LS_LOCAL_STATE_OFF 2
+
+#define LS_MAP_NS_DRAM MAP_REGION_FLAT( \
+ (LS_NS_DRAM_BASE), \
+ LS_DRAM1_SIZE, \
+ MT_DEVICE | MT_RW | MT_NS)
+
+#define LS_MAP_TSP_SEC_MEM MAP_REGION_FLAT( \
+ TSP_SEC_MEM_BASE, \
+ TSP_SEC_MEM_SIZE, \
+ MT_DEVICE | MT_RW | MT_SECURE)
+
+
+#define LS_MAP_FLASH0_RW MAP_REGION_FLAT(PLAT_LS_FLASH_BASE,\
+ PLAT_LS_FLASH_SIZE, \
+ MT_DEVICE | MT_RW)
+
+#define LS_MAP_CCSR MAP_REGION_FLAT(PLAT_LS_CCSR_BASE, \
+ PLAT_LS_CCSR_SIZE, \
+ MT_DEVICE | MT_RW | MT_SECURE)
+
+
+#define LS_MAP_CONSOLE MAP_REGION_FLAT(PLAT_LS1043_DUART1_BASE, \
+ PLAT_LS1043_DUART_SIZE, \
+ MT_DEVICE | MT_RW | MT_NS)
+
+/*
+ * The number of regions like RO(code), coherent and data required by
+ * different BL stages which need to be mapped in the MMU.
+ */
+/******************************************************************************
+ * Required platform porting definitions common to all ARM standard platforms
+ *****************************************************************************/
+
+#define PLAT_PHY_ADDR_SPACE_SIZE (1ull << 32)
+#define PLAT_VIRT_ADDR_SPACE_SIZE (1ull << 32)
+
+/*
+ * This macro defines the deepest retention state possible. A higher state
+ * id will represent an invalid or a power down state.
+ */
+#define PLAT_MAX_RET_STATE LS_LOCAL_STATE_RET
+
+/*
+ * This macro defines the deepest power down states possible. Any state ID
+ * higher than this is invalid.
+ */
+#define PLAT_MAX_OFF_STATE LS_LOCAL_STATE_OFF
+
+/*
+ * Some data must be aligned on the biggest cache line size in the platform.
+ * This is known only to the platform as it might have a combination of
+ * integrated and external caches.
+ */
+#define CACHE_WRITEBACK_GRANULE (1 << LS_CACHE_WRITEBACK_SHIFT)
+
+/*
+ * One cache line needed for bakery locks on Layerscape platforms
+ */
+#define PLAT_PERCPU_BAKERY_LOCK_SIZE (1 * CACHE_WRITEBACK_GRANULE)
+
+#endif /* __LS_DEF_H__ */
diff --git a/plat/layerscape/board/ls1043/include/ns_access.h b/plat/layerscape/board/ls1043/include/ns_access.h
new file mode 100644
index 0000000..6ed7bc0
--- /dev/null
+++ b/plat/layerscape/board/ls1043/include/ns_access.h
@@ -0,0 +1,174 @@
+/*
+ * Copyright (c) 2018, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef __FSL_NS_ACCESS_H_
+#define __FSL_NS_ACCESS_H_
+
+#include "fsl_csu.h"
+
+enum csu_cslx_ind {
+ CSU_CSLX_PCIE2_IO = 0,
+ CSU_CSLX_PCIE1_IO,
+ CSU_CSLX_MG2TPR_IP,
+ CSU_CSLX_IFC_MEM,
+ CSU_CSLX_OCRAM,
+ CSU_CSLX_GIC,
+ CSU_CSLX_PCIE1,
+ CSU_CSLX_OCRAM2,
+ CSU_CSLX_QSPI_MEM,
+ CSU_CSLX_PCIE2,
+ CSU_CSLX_SATA,
+ CSU_CSLX_USB1,
+ CSU_CSLX_QM_BM_SWPORTAL,
+ CSU_CSLX_PCIE3 = 16,
+ CSU_CSLX_PCIE3_IO,
+ CSU_CSLX_USB3 = 20,
+ CSU_CSLX_USB2,
+ CSU_CSLX_PFE = 23,
+ CSU_CSLX_SERDES = 32,
+ CSU_CSLX_QDMA,
+ CSU_CSLX_LPUART2,
+ CSU_CSLX_LPUART1,
+ CSU_CSLX_LPUART4,
+ CSU_CSLX_LPUART3,
+ CSU_CSLX_LPUART6,
+ CSU_CSLX_LPUART5,
+ CSU_CSLX_DSPI1 = 41,
+ CSU_CSLX_QSPI,
+ CSU_CSLX_ESDHC,
+ CSU_CSLX_IFC = 45,
+ CSU_CSLX_I2C1,
+ CSU_CSLX_USB_2,
+ CSU_CSLX_I2C3 = 48,
+ CSU_CSLX_I2C2,
+ CSU_CSLX_DUART2 = 50,
+ CSU_CSLX_DUART1,
+ CSU_CSLX_WDT2,
+ CSU_CSLX_WDT1,
+ CSU_CSLX_EDMA,
+ CSU_CSLX_SYS_CNT,
+ CSU_CSLX_DMA_MUX2,
+ CSU_CSLX_DMA_MUX1,
+ CSU_CSLX_DDR,
+ CSU_CSLX_QUICC,
+ CSU_CSLX_DCFG_CCU_RCPM = 60,
+ CSU_CSLX_SECURE_BOOTROM,
+ CSU_CSLX_SFP,
+ CSU_CSLX_TMU,
+ CSU_CSLX_SECURE_MONITOR,
+ CSU_CSLX_SCFG,
+ CSU_CSLX_FM = 66,
+ CSU_CSLX_SEC5_5,
+ CSU_CSLX_BM,
+ CSU_CSLX_QM,
+ CSU_CSLX_GPIO2 = 70,
+ CSU_CSLX_GPIO1,
+ CSU_CSLX_GPIO4,
+ CSU_CSLX_GPIO3,
+ CSU_CSLX_PLATFORM_CONT,
+ CSU_CSLX_CSU,
+ CSU_CSLX_IIC4 = 77,
+ CSU_CSLX_WDT4,
+ CSU_CSLX_WDT3,
+ CSU_CSLX_ESDHC2 = 80,
+ CSU_CSLX_WDT5 = 81,
+ CSU_CSLX_SAI2,
+ CSU_CSLX_SAI1,
+ CSU_CSLX_SAI4,
+ CSU_CSLX_SAI3,
+ CSU_CSLX_FTM2 = 86,
+ CSU_CSLX_FTM1,
+ CSU_CSLX_FTM4,
+ CSU_CSLX_FTM3,
+ CSU_CSLX_FTM6 = 90,
+ CSU_CSLX_FTM5,
+ CSU_CSLX_FTM8,
+ CSU_CSLX_FTM7,
+ CSU_CSLX_DSCR = 121,
+};
+
+static struct csu_ns_dev ns_dev[] = {
+ {CSU_CSLX_PCIE2_IO, CSU_ALL_RW},
+ {CSU_CSLX_PCIE1_IO, CSU_ALL_RW},
+ {CSU_CSLX_MG2TPR_IP, CSU_ALL_RW},
+ {CSU_CSLX_IFC_MEM, CSU_ALL_RW},
+ {CSU_CSLX_OCRAM, CSU_ALL_RW},
+ {CSU_CSLX_GIC, CSU_ALL_RW},
+ {CSU_CSLX_PCIE1, CSU_ALL_RW},
+ {CSU_CSLX_OCRAM2, CSU_ALL_RW},
+ {CSU_CSLX_QSPI_MEM, CSU_ALL_RW},
+ {CSU_CSLX_PCIE2, CSU_ALL_RW},
+ {CSU_CSLX_SATA, CSU_ALL_RW},
+ {CSU_CSLX_USB1, CSU_ALL_RW},
+ {CSU_CSLX_QM_BM_SWPORTAL, CSU_ALL_RW},
+ {CSU_CSLX_PCIE3, CSU_ALL_RW},
+ {CSU_CSLX_PCIE3_IO, CSU_ALL_RW},
+ {CSU_CSLX_USB3, CSU_ALL_RW},
+ {CSU_CSLX_USB2, CSU_ALL_RW},
+ {CSU_CSLX_PFE, CSU_ALL_RW},
+ {CSU_CSLX_SERDES, CSU_ALL_RW},
+ {CSU_CSLX_QDMA, CSU_ALL_RW},
+ {CSU_CSLX_LPUART2, CSU_ALL_RW},
+ {CSU_CSLX_LPUART1, CSU_ALL_RW},
+ {CSU_CSLX_LPUART4, CSU_ALL_RW},
+ {CSU_CSLX_LPUART3, CSU_ALL_RW},
+ {CSU_CSLX_LPUART6, CSU_ALL_RW},
+ {CSU_CSLX_LPUART5, CSU_ALL_RW},
+ {CSU_CSLX_DSPI1, CSU_ALL_RW},
+ {CSU_CSLX_QSPI, CSU_ALL_RW},
+ {CSU_CSLX_ESDHC, CSU_ALL_RW},
+ {CSU_CSLX_IFC, CSU_ALL_RW},
+ {CSU_CSLX_I2C1, CSU_ALL_RW},
+ {CSU_CSLX_USB_2, CSU_ALL_RW},
+ {CSU_CSLX_I2C3, CSU_ALL_RW},
+ {CSU_CSLX_I2C2, CSU_ALL_RW},
+ {CSU_CSLX_DUART2, CSU_ALL_RW},
+ {CSU_CSLX_DUART1, CSU_ALL_RW},
+ {CSU_CSLX_WDT2, CSU_ALL_RW},
+ {CSU_CSLX_WDT1, CSU_ALL_RW},
+ {CSU_CSLX_EDMA, CSU_ALL_RW},
+ {CSU_CSLX_SYS_CNT, CSU_ALL_RW},
+ {CSU_CSLX_DMA_MUX2, CSU_ALL_RW},
+ {CSU_CSLX_DMA_MUX1, CSU_ALL_RW},
+ {CSU_CSLX_DDR, CSU_ALL_RW},
+ {CSU_CSLX_QUICC, CSU_ALL_RW},
+ {CSU_CSLX_DCFG_CCU_RCPM, CSU_ALL_RW},
+ {CSU_CSLX_SECURE_BOOTROM, CSU_ALL_RW},
+ {CSU_CSLX_SFP, CSU_ALL_RW},
+ {CSU_CSLX_TMU, CSU_ALL_RW},
+ {CSU_CSLX_SECURE_MONITOR, CSU_ALL_RW},
+ {CSU_CSLX_SCFG, CSU_ALL_RW},
+ {CSU_CSLX_FM, CSU_ALL_RW},
+ {CSU_CSLX_SEC5_5, CSU_ALL_RW},
+ {CSU_CSLX_BM, CSU_ALL_RW},
+ {CSU_CSLX_QM, CSU_ALL_RW},
+ {CSU_CSLX_GPIO2, CSU_ALL_RW},
+ {CSU_CSLX_GPIO1, CSU_ALL_RW},
+ {CSU_CSLX_GPIO4, CSU_ALL_RW},
+ {CSU_CSLX_GPIO3, CSU_ALL_RW},
+ {CSU_CSLX_PLATFORM_CONT, CSU_ALL_RW},
+ {CSU_CSLX_CSU, CSU_ALL_RW},
+ {CSU_CSLX_IIC4, CSU_ALL_RW},
+ {CSU_CSLX_WDT4, CSU_ALL_RW},
+ {CSU_CSLX_WDT3, CSU_ALL_RW},
+ {CSU_CSLX_ESDHC2, CSU_ALL_RW},
+ {CSU_CSLX_WDT5, CSU_ALL_RW},
+ {CSU_CSLX_SAI2, CSU_ALL_RW},
+ {CSU_CSLX_SAI1, CSU_ALL_RW},
+ {CSU_CSLX_SAI4, CSU_ALL_RW},
+ {CSU_CSLX_SAI3, CSU_ALL_RW},
+ {CSU_CSLX_FTM2, CSU_ALL_RW},
+ {CSU_CSLX_FTM1, CSU_ALL_RW},
+ {CSU_CSLX_FTM4, CSU_ALL_RW},
+ {CSU_CSLX_FTM3, CSU_ALL_RW},
+ {CSU_CSLX_FTM6, CSU_ALL_RW},
+ {CSU_CSLX_FTM5, CSU_ALL_RW},
+ {CSU_CSLX_FTM8, CSU_ALL_RW},
+ {CSU_CSLX_FTM7, CSU_ALL_RW},
+ {CSU_CSLX_DSCR, CSU_ALL_RW},
+};
+
+#endif
diff --git a/plat/layerscape/board/ls1043/include/plat_macros.S b/plat/layerscape/board/ls1043/include/plat_macros.S
new file mode 100644
index 0000000..8163dc1
--- /dev/null
+++ b/plat/layerscape/board/ls1043/include/plat_macros.S
@@ -0,0 +1,21 @@
+/*
+ * Copyright (c) 2018, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef __PLAT_MACROS_S__
+#define __PLAT_MACROS_S__
+
+ /* ---------------------------------------------
+ * The below required platform porting macro
+ * prints out relevant GIC and CCI registers
+ * whenever an unhandled exception is taken in
+ * BL31.
+ * Clobbers: x0 - x10, x16, x17, sp
+ * ---------------------------------------------
+ */
+ .macro plat_crash_print_regs
+ .endm
+
+#endif /* __PLAT_MACROS_S__ */
diff --git a/plat/layerscape/board/ls1043/include/platform_def.h b/plat/layerscape/board/ls1043/include/platform_def.h
new file mode 100644
index 0000000..0e1cae6
--- /dev/null
+++ b/plat/layerscape/board/ls1043/include/platform_def.h
@@ -0,0 +1,212 @@
+/*
+ * Copyright (c) 2018, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef __PLATFORM_DEF_H__
+#define __PLATFORM_DEF_H__
+
+#include <common_def.h>
+#include <tzc400.h>
+#include <utils.h>
+#include "ls_def.h"
+
+#define FIRMWARE_WELCOME_STR_LS1043 "Welcome to LS1043 BL1 Phase\n"
+#define FIRMWARE_WELCOME_STR_LS1043_BL2 "Welcome to LS1043 BL2 Phase\n"
+#define FIRMWARE_WELCOME_STR_LS1043_BL31 "Welcome to LS1043 BL31 Phase\n"
+#define FIRMWARE_WELCOME_STR_LS1043_BL32 "Welcome to LS1043 BL32 Phase, TSP\n"
+
+/* Required platform porting definitions */
+#define PLAT_PRIMARY_CPU 0x0
+#define PLAT_MAX_PWR_LVL LS_PWR_LVL1
+#define PLATFORM_CORE_COUNT 4
+#define COUNTER_FREQUENCY 25000000 /* 25MHz */
+
+/*
+ * Required LS standard platform porting definitions
+ */
+#define PLAT_LS_CLUSTER_COUNT 1
+#define PLAT_LS1043_CCI_CLUSTER0_SL_IFACE_IX 4
+#define LS1043_CLUSTER_COUNT 1
+#define LS1043_MAX_CPUS_PER_CLUSTER 4
+
+#define LS_DRAM1_BASE 0x80000000
+#define LS_DRAM2_BASE 0x880000000
+#define LS_DRAM2_SIZE 0x780000000 /* 30G */
+#define LS_DRAM1_SIZE 0x80000000 /* 2G */
+#define LS_NS_DRAM_BASE LS_DRAM1_BASE
+/* 64M Secure Memory, in fact there a 2M non-secure hole on top of it */
+#define LS_SECURE_DRAM_SIZE (64 * 1024 * 1024)
+#define LS_SECURE_DRAM_BASE (LS_NS_DRAM_BASE + LS_DRAM1_SIZE - \
+ LS_SECURE_DRAM_SIZE)
+#define LS_NS_DRAM_SIZE (LS_DRAM1_SIZE - LS_SECURE_DRAM_SIZE)
+
+/*
+ * By default, BL2 is in DDR memory.
+ * If LS_BL2_IN_OCRAM is defined, BL2 will in OCRAM
+ */
+/* #define LS_BL2_IN_OCRAM */
+
+#ifndef LS_BL2_IN_OCRAM
+/*
+ * on top of SECURE memory is 2M non-secure hole for OPTee,
+ * 1M secure memory below this hole will be used for BL2.
+ */
+#define LS_BL2_DDR_BASE (LS_SECURE_DRAM_BASE + \
+ LS_SECURE_DRAM_SIZE \
+ - 3 * 1024 * 1024)
+#endif
+
+#define PLAT_LS_CCSR_BASE 0x1000000
+#define PLAT_LS_CCSR_SIZE 0xF000000
+
+/* Flash base address, currently ROM is not used for TF-A images on LS platforms */
+#define PLAT_LS_TRUSTED_ROM_BASE 0x60100000
+#define PLAT_LS_TRUSTED_ROM_SIZE 0x20000000 /* Flash size */
+#define PLAT_LS_FLASH_SIZE 0x20000000
+#define PLAT_LS_FLASH_BASE 0x60000000
+
+#define LS_SRAM_BASE 0x10000000
+#define LS_SRAM_LIMIT 0x10020000 /* 128K */
+#define LS_SRAM_SHARED_SIZE 0x1000 /* 4K */
+#define LS_SRAM_SIZE (LS_SRAM_LIMIT - LS_SRAM_BASE)
+#define LS_BL_RAM_BASE (LS_SRAM_BASE + LS_SRAM_SHARED_SIZE)
+
+#define PLAT_LS_FIP_MAX_SIZE 0x4000000
+
+/* Memory Layout */
+
+#define BL1_RO_BASE PLAT_LS_TRUSTED_ROM_BASE
+#define BL1_RO_LIMIT (PLAT_LS_TRUSTED_ROM_BASE \
+ + PLAT_LS_TRUSTED_ROM_SIZE)
+#define PLAT_LS_FIP_BASE 0x60120000
+
+#ifdef LS_BL2_IN_OCRAM
+/* BL2 is in OCRAM */
+#define PLAT_LS_MAX_BL1_RW_SIZE (52 * 1024) /* 52K */
+#define PLAT_LS_MAX_BL31_SIZE (64 * 1024) /* 64K */
+#define PLAT_LS_MAX_BL2_SIZE (44 * 1024) /* 44K */
+/* Reserve memory in OCRAM for BL31 Text and ROData segment */
+#define BL31_TEXT_RODATA_SIZE (32 * 1024) /* 32K */
+#else /* LS_BL2_IN_OCRAM */
+/* BL2 in DDR */
+#define PLAT_LS_MAX_BL1_RW_SIZE (64 * 1024) /* 64K */
+#define PLAT_LS_MAX_BL31_SIZE (64 * 1024) /* 64K */
+#define PLAT_LS_MAX_BL2_SIZE (1 * 1024 * 1024) /* 1M */
+#endif /* LS_BL2_IN_OCRAM */
+/*
+ * Put BL31 at the start of OCRAM.
+ */
+#define BL31_BASE LS_SRAM_BASE
+#define BL31_LIMIT (LS_SRAM_BASE + PLAT_LS_MAX_BL31_SIZE)
+
+#ifdef LS_BL2_IN_OCRAM
+/*
+ * BL2 follow BL31 Text and ROData region.
+ */
+#define BL2_BASE (BL31_BASE + BL31_TEXT_RODATA_SIZE)
+#define BL2_LIMIT (BL2_BASE + PLAT_LS_MAX_BL2_SIZE)
+
+#else
+/*
+ * BL2 in DDR memory.
+ */
+#define BL2_BASE LS_BL2_DDR_BASE
+#define BL2_LIMIT (BL2_BASE + PLAT_LS_MAX_BL2_SIZE)
+
+#endif
+
+/*
+ * Put BL1 RW at the top of the Trusted SRAM.
+ */
+#ifdef LS_BL2_IN_OCRAM
+#define BL1_RW_BASE BL2_LIMIT
+#else
+#define BL1_RW_BASE BL31_LIMIT
+#endif
+#define BL1_RW_LIMIT LS_SRAM_LIMIT
+
+/* Put BL32 in secure memory */
+#define BL32_BASE LS_SECURE_DRAM_BASE
+#define BL32_LIMIT (LS_SECURE_DRAM_BASE + LS_SECURE_DRAM_SIZE)
+/* BL33 memory region */
+#define BL33_BASE 0x82000000
+#define BL33_LIMIT (LS_NS_DRAM_BASE + LS_NS_DRAM_SIZE)
+
+/*******************************************************************************
+ * BL32 specific defines.
+ ******************************************************************************/
+/*
+ * On ARM standard platforms, the TSP can execute from Trusted SRAM,
+ * Trusted DRAM (if available) or the DRAM region secured by the TrustZone
+ * controller.
+ */
+
+#define TSP_SEC_MEM_BASE BL32_BASE
+#define TSP_SEC_MEM_SIZE (BL32_LIMIT - BL32_BASE)
+
+/*
+ * ID of the secure physical generic timer interrupt used by the TSP.
+ */
+#define TSP_IRQ_SEC_PHY_TIMER 29
+
+
+/*
+ * GIC related constants
+ */
+#define PLAT_LS1043_CCI_BASE 0x01180000
+#define GICD_BASE 0x01401000
+#define GICC_BASE 0x01402000
+#define GICD_BASE_64K 0x01410000
+#define GICC_BASE_64K 0x01420000
+
+#define DCFG_CCSR_SVR 0x1ee00a4
+#define REV1_0 0x10
+#define REV1_1 0x11
+#define GIC_ADDR_BIT 31
+#define SCFG_GIC400_ALIGN 0x1570188
+
+/* UART related definition */
+
+#define PLAT_LS1043_DUART1_BASE 0x021c0000
+#define PLAT_LS1043_DUART2_BASE 0x021d0000
+#define PLAT_LS1043_DUART_SIZE 0x10000
+
+#define PLAT_LS1043_UART_BASE 0x21c0500
+#define PLAT_LS1043_UART2_BASE 0x21c0600
+#define PLAT_LS1043_UART_CLOCK 400000000
+#define PLAT_LS1043_UART_BAUDRATE 115200
+/* Define UART to be used by TF-A log */
+#define LS_TF_UART_BASE PLAT_LS1043_UART_BASE
+#define LS_TF_UART_CLOCK PLAT_LS1043_UART_CLOCK
+#define LS_TF_UART_BAUDRATE PLAT_LS1043_UART_BAUDRATE
+
+#define LS1043_SYS_CNTCTL_BASE 0x2B00000
+
+#define CONFIG_SYS_IMMR 0x01000000
+#define CONFIG_SYS_FSL_CSU_ADDR (CONFIG_SYS_IMMR + 0x00510000)
+
+/* Size of cacheable stacks */
+#if defined(IMAGE_BL1)
+#define PLATFORM_STACK_SIZE 0x440
+#define MAX_MMAP_REGIONS 6
+#define MAX_XLAT_TABLES 4
+#elif defined(IMAGE_BL2)
+#define PLATFORM_STACK_SIZE 0x400
+#define MAX_MMAP_REGIONS 8
+#define MAX_XLAT_TABLES 6
+#elif defined(IMAGE_BL31)
+#define PLATFORM_STACK_SIZE 0x400
+#define MAX_MMAP_REGIONS 8
+#define MAX_XLAT_TABLES 4
+#elif defined(IMAGE_BL32)
+#define PLATFORM_STACK_SIZE 0x440
+#define MAX_MMAP_REGIONS 8
+#define MAX_XLAT_TABLES 9
+#endif
+
+#define MAX_IO_DEVICES 3
+#define MAX_IO_HANDLES 4
+
+#endif /* __PLATFORM_DEF_H__ */
diff --git a/plat/layerscape/board/ls1043/include/soc_tzasc.h b/plat/layerscape/board/ls1043/include/soc_tzasc.h
new file mode 100644
index 0000000..0039f2d
--- /dev/null
+++ b/plat/layerscape/board/ls1043/include/soc_tzasc.h
@@ -0,0 +1,93 @@
+/*
+ * Copyright (c) 2018, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef _SOC_TZASC_H_
+#define _SOC_TZASC_H_
+
+#include "tzc380.h"
+
+#define MAX_NUM_TZC_REGION 3
+
+/* TZASC related constants */
+#define TZASC_CONFIGURATION_REG 0x000
+#define TZASC_SECURITY_INV_REG 0x034
+#define TZASC_SECURITY_INV_EN 0x1
+#define TZASC_REGIONS_REG 0x100
+/* As region address should address atleast 32KB memory. */
+#define TZASC_REGION_LOWADDR_MASK 0xFFFF8000
+#define TZASC_REGION_LOWADDR_OFFSET 0x0
+#define TZASC_REGION_HIGHADDR_OFFSET 0x4
+#define TZASC_REGION_ATTR_OFFSET 0x8
+#define TZASC_REGION_ENABLED 1
+#define TZASC_REGION_DISABLED 0
+#define TZASC_REGION_SIZE_32KB 0xE
+#define TZASC_REGION_SIZE_64KB 0xF
+#define TZASC_REGION_SIZE_128KB 0x10
+#define TZASC_REGION_SIZE_256KB 0x11
+#define TZASC_REGION_SIZE_512KB 0x12
+#define TZASC_REGION_SIZE_1MB 0x13
+#define TZASC_REGION_SIZE_2MB 0x14
+#define TZASC_REGION_SIZE_4MB 0x15
+#define TZASC_REGION_SIZE_8MB 0x16
+#define TZASC_REGION_SIZE_16MB 0x17
+#define TZASC_REGION_SIZE_32MB 0x18
+#define TZASC_REGION_SIZE_64MB 0x19
+#define TZASC_REGION_SIZE_128MB 0x1A
+#define TZASC_REGION_SIZE_256MB 0x1B
+#define TZASC_REGION_SIZE_512MB 0x1C
+#define TZASC_REGION_SIZE_1GB 0x1D
+#define TZASC_REGION_SIZE_2GB 0x1E
+#define TZASC_REGION_SIZE_4GB 0x1F
+#define TZASC_REGION_SIZE_8GB 0x20
+#define TZASC_REGION_SIZE_16GB 0x21
+#define TZASC_REGION_SIZE_32GB 0x22
+#define TZASC_REGION_SECURITY_SR (1 << 3)
+#define TZASC_REGION_SECURITY_SW (1 << 2)
+#define TZASC_REGION_SECURITY_SRW (TZASC_REGION_SECURITY_SR| \
+ TZASC_REGION_SECURITY_SW)
+#define TZASC_REGION_SECURITY_NSR (1 << 1)
+#define TZASC_REGION_SECURITY_NSW 1
+#define TZASC_REGION_SECURITY_NSRW (TZASC_REGION_SECURITY_NSR| \
+ TZASC_REGION_SECURITY_NSW)
+
+#define CSU_SEC_ACCESS_REG_OFFSET 0x21C
+#define TZASC_BYPASS_MUX_DISABLE 0x4
+#define CCI_TERMINATE_BARRIER_TX 0x8
+#define CONFIG_SYS_FSL_TZASC_ADDR 0x1500000
+
+/* List of MAX_NUM_TZC_REGION TZC regions' boundaries and configurations. */
+
+static const struct tzc380_reg tzc380_reg_list[] = {
+ {
+ TZASC_REGION_SECURITY_NSRW, /* .secure attr */
+ 0x0, /* .enabled */
+ 0x0, /* .lowaddr */
+ 0x0, /* .highaddr */
+ 0x0, /* .size */
+ 0x0, /* .submask */
+ },
+ {
+ TZASC_REGION_SECURITY_SRW,
+ TZASC_REGION_ENABLED,
+ 0xFC000000,
+ 0x0,
+ TZASC_REGION_SIZE_64MB,
+ 0x80, /* Disable region 7 */
+ },
+ /* reserve 2M non-scure memory for OPTEE public memory */
+ {
+ TZASC_REGION_SECURITY_SRW,
+ TZASC_REGION_ENABLED,
+ 0xFF800000,
+ 0x0,
+ TZASC_REGION_SIZE_8MB,
+ 0xC0, /* Disable region 6 & 7 */
+ },
+
+ {}
+};
+
+#endif /* _SOC_TZASC_H_ */
diff --git a/plat/layerscape/board/ls1043/ls1043_bl1_setup.c b/plat/layerscape/board/ls1043/ls1043_bl1_setup.c
new file mode 100644
index 0000000..e82a1fb
--- /dev/null
+++ b/plat/layerscape/board/ls1043/ls1043_bl1_setup.c
@@ -0,0 +1,56 @@
+/*
+ * Copyright (c) 2018, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <cci.h>
+#include <debug.h>
+#include <mmio.h>
+#include "plat_ls.h"
+
+static const int cci_map[] = {
+ PLAT_LS1043_CCI_CLUSTER0_SL_IFACE_IX
+};
+
+void bl1_platform_setup(void)
+{
+ NOTICE(FIRMWARE_WELCOME_STR_LS1043);
+
+ ls_bl1_platform_setup();
+
+ /*
+ * Initialize system level generic timer for Layerscape Socs.
+ */
+ ls_delay_timer_init();
+
+ /* TODO: remove these DDR code */
+ VERBOSE("CS0_BNDS = %x\n", mmio_read_32(0x1080000 + 0x000));
+ mmio_write_32(0x1080000 + 0x000, 0x7f000000);
+ VERBOSE("CS0_BNDS = %x\n", mmio_read_32(0x1080000 + 0x000));
+}
+
+/*******************************************************************************
+ * Perform any BL1 specific platform actions.
+ ******************************************************************************/
+void bl1_early_platform_setup(void)
+{
+ ls_bl1_early_platform_setup();
+
+ /*
+ * Initialize Interconnect for this cluster during cold boot.
+ * No need for locks as no other CPU is active.
+ */
+ cci_init(PLAT_LS1043_CCI_BASE, cci_map, ARRAY_SIZE(cci_map));
+
+ /*
+ * Enable coherency in Interconnect for the primary CPU's cluster.
+ */
+ cci_enable_snoop_dvm_reqs(MPIDR_AFFLVL1_VAL(read_mpidr()));
+
+}
+
+unsigned int bl1_plat_get_next_image_id(void)
+{
+ return BL2_IMAGE_ID;
+}
diff --git a/plat/layerscape/board/ls1043/ls1043_bl2_setup.c b/plat/layerscape/board/ls1043/ls1043_bl2_setup.c
new file mode 100644
index 0000000..b529aa5
--- /dev/null
+++ b/plat/layerscape/board/ls1043/ls1043_bl2_setup.c
@@ -0,0 +1,25 @@
+/*
+ * Copyright (c) 2018, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <mmio.h>
+#include <debug.h>
+#include "plat_ls.h"
+
+void bl2_early_platform_setup2(u_register_t arg0, u_register_t arg1,
+ u_register_t arg2, u_register_t arg3)
+{
+ ls_bl2_early_platform_setup((meminfo_t *)arg1);
+
+ /*
+ * Initialize system level generic timer for Layerscape Socs.
+ */
+ ls_delay_timer_init();
+}
+
+void bl2_platform_setup(void)
+{
+ NOTICE(FIRMWARE_WELCOME_STR_LS1043_BL2);
+}
diff --git a/plat/layerscape/board/ls1043/ls1043_bl31_setup.c b/plat/layerscape/board/ls1043/ls1043_bl31_setup.c
new file mode 100644
index 0000000..3473d98
--- /dev/null
+++ b/plat/layerscape/board/ls1043/ls1043_bl31_setup.c
@@ -0,0 +1,55 @@
+/*
+ * Copyright (c) 2018, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <cci.h>
+#include <debug.h>
+#include "plat_ls.h"
+#include "fsl_csu.h"
+
+/* slave interfaces according to the RM */
+static const int cci_map[] = {
+ 4,
+};
+
+void bl31_early_platform_setup2(u_register_t arg0, u_register_t arg1,
+ u_register_t arg2, u_register_t arg3)
+{
+#ifdef LS_BL2_IN_OCRAM
+ unsigned long romem_base = (unsigned long)(&__TEXT_START__);
+ unsigned long romem_size = (unsigned long)(&__RODATA_END__)
+ - romem_base;
+
+ /* Check the Text and RO-Data region size */
+ if (romem_size > BL31_TEXT_RODATA_SIZE) {
+ ERROR("BL31 Text and RO-Data region size exceed reserved memory size\n");
+ panic();
+ }
+#endif
+
+ /*
+ * Initialize system level generic timer for Layerscape Socs.
+ */
+ ls_delay_timer_init();
+
+ ls_bl31_early_platform_setup((void *)arg0, (void *)arg3);
+
+ /*
+ * Initialize the correct interconnect for this cluster during cold
+ * boot. No need for locks as no other CPU is active.
+ */
+ cci_init(PLAT_LS1043_CCI_BASE, cci_map, ARRAY_SIZE(cci_map));
+
+ /*
+ * Enable coherency in interconnect for the primary CPU's cluster.
+ * Earlier bootloader stages might already do this (e.g. Trusted
+ * Firmware's BL1 does it) but we can't assume so. There is no harm in
+ * executing this code twice anyway.
+ */
+ cci_enable_snoop_dvm_reqs(MPIDR_AFFLVL1_VAL(read_mpidr()));
+
+ /* Init CSU to enable non-secure access to peripherals */
+ enable_layerscape_ns_access();
+}
diff --git a/plat/layerscape/board/ls1043/ls1043_err.c b/plat/layerscape/board/ls1043/ls1043_err.c
new file mode 100644
index 0000000..e4a2cae
--- /dev/null
+++ b/plat/layerscape/board/ls1043/ls1043_err.c
@@ -0,0 +1,30 @@
+/*
+ * Copyright (c) 2018, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <arch_helpers.h>
+#include <debug.h>
+#include <errno.h>
+#include <stdint.h>
+
+/*
+ * Error handler
+ */
+void plat_error_handler(int err)
+{
+ switch (err) {
+ case -ENOENT:
+ case -EAUTH:
+ /* ToDo */
+ break;
+ default:
+ /* Unexpected error */
+ break;
+ }
+
+ /* Loop until the watchdog resets the system */
+ for (;;)
+ wfi();
+}
diff --git a/plat/layerscape/board/ls1043/ls1043_psci.c b/plat/layerscape/board/ls1043/ls1043_psci.c
new file mode 100644
index 0000000..1c83df4
--- /dev/null
+++ b/plat/layerscape/board/ls1043/ls1043_psci.c
@@ -0,0 +1,168 @@
+/*
+ * Copyright (c) 2018, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <arch_helpers.h>
+#include <debug.h>
+#include <errno.h>
+#include <assert.h>
+#include <platform.h>
+#include <psci.h>
+#include <mmio.h>
+#include <sys/endian.h>
+#include <gicv2.h>
+#include <delay_timer.h>
+#include "platform_def.h"
+
+#define LS_SCFG_BASE 0x01570000
+/* register to store warm boot entry, big endian, higher 32bit */
+#define LS_SCFG_SCRATCHRW0_OFFSET 0x600
+/* register to store warm boot entry, big endian, lower 32bit */
+#define LS_SCFG_SCRATCHRW1_OFFSET 0x604
+#define LS_SCFG_COREBCR_OFFSET 0x680
+
+#define LS_DCFG_BASE 0x01EE0000
+#define LS_DCFG_RSTCR_OFFSET 0x0B0
+#define LS_DCFG_RSTRQMR1_OFFSET 0x0C0
+#define LS_DCFG_BRR_OFFSET 0x0E4
+
+#define LS_SCFG_CORE0_SFT_RST_OFFSET 0x130
+#define LS_SCFG_CORE1_SFT_RST_OFFSET 0x134
+#define LS_SCFG_CORE2_SFT_RST_OFFSET 0x138
+#define LS_SCFG_CORE3_SFT_RST_OFFSET 0x13C
+
+#define LS_SCFG_CORESRENCR_OFFSET 0x204
+
+#define LS_SCFG_RVBAR0_0_OFFSET 0x220
+#define LS_SCFG_RVBAR0_1_OFFSET 0x224
+
+#define LS_SCFG_RVBAR1_0_OFFSET 0x228
+#define LS_SCFG_RVBAR1_1_OFFSET 0x22C
+
+#define LS_SCFG_RVBAR2_0_OFFSET 0x230
+#define LS_SCFG_RVBAR2_1_OFFSET 0x234
+
+#define LS_SCFG_RVBAR3_0_OFFSET 0x238
+#define LS_SCFG_RVBAR3_1_OFFSET 0x23C
+
+/* the entry for core warm boot */
+static uintptr_t warmboot_entry;
+
+/* warm reset single core */
+static void ls1043_reset_core(int core_pos)
+{
+ assert(core_pos >= 0 && core_pos < PLATFORM_CORE_COUNT);
+
+ /* set 0 in RVBAR, boot from bootrom at 0x0 */
+ mmio_write_32(LS_SCFG_BASE + LS_SCFG_RVBAR0_0_OFFSET + core_pos * 8,
+ 0);
+ mmio_write_32(LS_SCFG_BASE + LS_SCFG_RVBAR0_1_OFFSET + core_pos * 8,
+ 0);
+
+ dsb();
+ /* enable core soft reset */
+ mmio_write_32(LS_SCFG_BASE + LS_SCFG_CORESRENCR_OFFSET,
+ htobe32(1 << 31));
+ dsb();
+ isb();
+ /* reset core */
+ mmio_write_32(LS_SCFG_BASE + LS_SCFG_CORE0_SFT_RST_OFFSET +
+ core_pos * 4, htobe32(1 << 31));
+ mdelay(10);
+}
+
+static void __dead2 ls1043_system_reset(void)
+{
+ /* clear reset request mask bits */
+ mmio_write_32(LS_DCFG_BASE + LS_DCFG_RSTRQMR1_OFFSET, 0);
+
+ /* set reset request bit */
+ mmio_write_32(LS_DCFG_BASE + LS_DCFG_RSTCR_OFFSET,
+ htobe32((uint32_t)0x2));
+
+ /* system will reset; if fail, enter wfi */
+ dsb();
+ isb();
+ wfi();
+
+ panic();
+}
+
+
+static int ls1043_pwr_domain_on(u_register_t mpidr)
+{
+ int core_pos = plat_core_pos_by_mpidr(mpidr);
+ uint32_t core_mask, brr;
+
+ assert(core_pos >= 0 && core_pos < PLATFORM_CORE_COUNT);
+ core_mask = 1 << core_pos;
+
+ /* set warm boot entry */
+ mmio_write_32(LS_SCFG_BASE + LS_SCFG_SCRATCHRW0_OFFSET,
+ htobe32((uint32_t)(warmboot_entry >> 32)));
+
+ mmio_write_32(LS_SCFG_BASE + LS_SCFG_SCRATCHRW1_OFFSET,
+ htobe32((uint32_t)warmboot_entry));
+
+ dsb();
+
+ brr = be32toh(mmio_read_32(LS_DCFG_BASE + LS_DCFG_BRR_OFFSET));
+ if (brr & core_mask) {
+ /* core has been released, must reset it to restart */
+ ls1043_reset_core(core_pos);
+
+ /* set bit in core boot control register to enable boot */
+ mmio_write_32(LS_SCFG_BASE + LS_SCFG_COREBCR_OFFSET,
+ htobe32(core_mask));
+
+ } else {
+ /* set bit in core boot control register to enable boot */
+ mmio_write_32(LS_SCFG_BASE + LS_SCFG_COREBCR_OFFSET,
+ htobe32(core_mask));
+
+ /* release core */
+ mmio_write_32(LS_DCFG_BASE + LS_DCFG_BRR_OFFSET,
+ htobe32(brr | core_mask));
+ }
+
+ mdelay(20);
+
+ /* wake core in case it is in wfe */
+ dsb();
+ isb();
+ sev();
+
+ return PSCI_E_SUCCESS;
+}
+
+static void ls1043_pwr_domain_on_finish(const psci_power_state_t *target_state)
+{
+ /* Per cpu gic distributor setup */
+ gicv2_pcpu_distif_init();
+
+ /* Enable the gic CPU interface */
+ gicv2_cpuif_enable();
+}
+
+static void ls1043_pwr_domain_off(const psci_power_state_t *target_state)
+{
+ /* Disable the gic CPU interface */
+ gicv2_cpuif_disable();
+}
+
+static plat_psci_ops_t ls1043_psci_pm_ops = {
+ .system_reset = ls1043_system_reset,
+ .pwr_domain_on = ls1043_pwr_domain_on,
+ .pwr_domain_on_finish = ls1043_pwr_domain_on_finish,
+ .pwr_domain_off = ls1043_pwr_domain_off,
+};
+
+int plat_setup_psci_ops(uintptr_t sec_entrypoint,
+ const plat_psci_ops_t **psci_ops)
+{
+ warmboot_entry = sec_entrypoint;
+ *psci_ops = &ls1043_psci_pm_ops;
+ return 0;
+}
diff --git a/plat/layerscape/board/ls1043/ls1043_security.c b/plat/layerscape/board/ls1043/ls1043_security.c
new file mode 100644
index 0000000..18ae56e
--- /dev/null
+++ b/plat/layerscape/board/ls1043/ls1043_security.c
@@ -0,0 +1,15 @@
+/*
+ * Copyright (c) 2018, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include "plat_ls.h"
+
+/*
+ * We assume that all security programming is done by the primary core.
+ */
+void plat_ls_security_setup(void)
+{
+ tzc380_setup();
+}
diff --git a/plat/layerscape/board/ls1043/ls1043_stack_protector.c b/plat/layerscape/board/ls1043/ls1043_stack_protector.c
new file mode 100644
index 0000000..50f463b
--- /dev/null
+++ b/plat/layerscape/board/ls1043/ls1043_stack_protector.c
@@ -0,0 +1,21 @@
+/*
+ * Copyright (c) 2018, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <arch_helpers.h>
+#include <stdint.h>
+
+#define RANDOM_CANARY_VALUE ((u_register_t) 3288484550995823360ULL)
+
+u_register_t plat_get_stack_protector_canary(void)
+{
+ /*
+ * Ideally, a random number should be returned instead of the
+ * combination of a timer's value and a compile-time constant. As the
+ * FVP does not have any random number generator, this is better than
+ * nothing but not necessarily really secure.
+ */
+ return RANDOM_CANARY_VALUE ^ read_cntpct_el0();
+}
diff --git a/plat/layerscape/board/ls1043/ls1043_topology.c b/plat/layerscape/board/ls1043/ls1043_topology.c
new file mode 100644
index 0000000..12d2830
--- /dev/null
+++ b/plat/layerscape/board/ls1043/ls1043_topology.c
@@ -0,0 +1,56 @@
+/*
+ * Copyright (c) 2018, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <arch.h>
+#include <cassert.h>
+#include "plat_ls.h"
+#include "platform_def.h"
+
+unsigned char ls1043_power_domain_tree_desc[LS1043_CLUSTER_COUNT + 1];
+
+
+CASSERT(LS1043_CLUSTER_COUNT && LS1043_CLUSTER_COUNT <= 256,
+ assert_invalid_ls1043_cluster_count);
+
+/*******************************************************************************
+ * This function dynamically constructs the topology according to
+ * LS1043_CLUSTER_COUNT and returns it.
+ ******************************************************************************/
+const unsigned char *plat_get_power_domain_tree_desc(void)
+{
+ int i;
+
+ ls1043_power_domain_tree_desc[0] = LS1043_CLUSTER_COUNT;
+
+ for (i = 0; i < LS1043_CLUSTER_COUNT; i++)
+ ls1043_power_domain_tree_desc[i + 1] =
+ LS1043_MAX_CPUS_PER_CLUSTER;
+
+ return ls1043_power_domain_tree_desc;
+}
+
+/*******************************************************************************
+ * This function returns the core count within the cluster corresponding to
+ * `mpidr`.
+ ******************************************************************************/
+unsigned int plat_ls_get_cluster_core_count(u_register_t mpidr)
+{
+ return LS1043_MAX_CPUS_PER_CLUSTER;
+}
+
+/*******************************************************************************
+ * This function implements a part of the critical interface between the psci
+ * generic layer and the platform that allows the former to query the platform
+ * to convert an MPIDR to a unique linear index. An error code (-1) is returned
+ * in case the MPIDR is invalid.
+ ******************************************************************************/
+int plat_core_pos_by_mpidr(u_register_t mpidr)
+{
+ if (ls_check_mpidr(mpidr) == -1)
+ return -1;
+
+ return plat_ls_calc_core_pos(mpidr);
+}
diff --git a/plat/layerscape/board/ls1043/ls_gic.c b/plat/layerscape/board/ls1043/ls_gic.c
new file mode 100644
index 0000000..3986153
--- /dev/null
+++ b/plat/layerscape/board/ls1043/ls_gic.c
@@ -0,0 +1,46 @@
+/*
+ * Copyright (c) 2018, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <mmio.h>
+#include <debug.h>
+#include <endian.h>
+#include "platform_def.h"
+#include "soc.h"
+
+/*
+ * Get GIC offset
+ * For LS1043a rev1.0, GIC base address align with 4k.
+ * For LS1043a rev1.1, if DCFG_GIC400_ALIGN[GIC_ADDR_BIT]
+ * is set, GIC base address align with 4K, or else align
+ * with 64k.
+ */
+void get_gic_offset(uint32_t *gicc_base, uint32_t *gicd_base)
+{
+
+ uint32_t *ccsr_svr = (uint32_t *)DCFG_CCSR_SVR;
+ uint32_t *gic_align = (uint32_t *)SCFG_GIC400_ALIGN;
+ uint32_t val;
+ uint32_t soc_dev_id;
+
+ val = be32toh(mmio_read_32((uintptr_t)ccsr_svr));
+ soc_dev_id = val & (SVR_WO_E << 8);
+
+ if ((soc_dev_id == (SVR_LS1043A << 8) ||
+ soc_dev_id == (SVR_LS1043AE << 8)) &&
+ ((val & 0xff) == REV1_1)) {
+ val = be32toh(mmio_read_32((uintptr_t)gic_align));
+ if (val & (1 << GIC_ADDR_BIT)) {
+ *gicc_base = GICC_BASE;
+ *gicd_base = GICD_BASE;
+ } else {
+ *gicc_base = GICC_BASE_64K;
+ *gicd_base = GICD_BASE_64K;
+ }
+ } else {
+ *gicc_base = GICC_BASE;
+ *gicd_base = GICD_BASE;
+ }
+}
diff --git a/plat/layerscape/board/ls1043/platform.mk b/plat/layerscape/board/ls1043/platform.mk
new file mode 100644
index 0000000..163d25e
--- /dev/null
+++ b/plat/layerscape/board/ls1043/platform.mk
@@ -0,0 +1,80 @@
+#
+# Copyright (c) 2018, ARM Limited and Contributors. All rights reserved.
+#
+# SPDX-License-Identifier: BSD-3-Clause
+#
+
+# indicate the reset vector address can be programmed
+PROGRAMMABLE_RESET_ADDRESS := 1
+USE_COHERENT_MEM := 0
+RESET_TO_BL31 := 0
+ENABLE_STACK_PROTECTOR := 0
+LS1043_GIC_SOURCES := drivers/arm/gic/common/gic_common.c \
+ drivers/arm/gic/v2/gicv2_main.c \
+ drivers/arm/gic/v2/gicv2_helpers.c \
+ plat/common/plat_gicv2.c \
+ plat/layerscape/board/ls1043/ls_gic.c
+
+
+LS1043_INTERCONNECT_SOURCES := drivers/arm/cci/cci.c
+
+LS1043_SECURITY_SOURCES := plat/layerscape/common/ls_tzc380.c \
+ plat/layerscape/board/ls1043/ls1043_security.c
+
+PLAT_INCLUDES := -Iplat/layerscape/board/ls1043/include \
+ -Iinclude/plat/arm/common \
+ -Iplat/layerscape/common/include \
+ -Iinclude/drivers/arm \
+ -Iinclude/lib \
+ -Iinclude/drivers/io
+
+
+PLAT_BL_COMMON_SOURCES := drivers/console/aarch64/console.S \
+ plat/layerscape/common/aarch64/ls_console.S
+
+LS1043_CPU_LIBS := lib/cpus/${ARCH}/aem_generic.S
+
+LS1043_CPU_LIBS += lib/cpus/aarch64/cortex_a53.S
+
+BL1_SOURCES += plat/layerscape/board/ls1043/ls1043_bl1_setup.c \
+ plat/layerscape/board/ls1043/ls1043_err.c \
+ drivers/delay_timer/delay_timer.c \
+
+BL1_SOURCES += plat/layerscape/board/ls1043/${ARCH}/ls1043_helpers.S \
+ ${LS1043_CPU_LIBS} \
+ ${LS1043_INTERCONNECT_SOURCES} \
+ $(LS1043_SECURITY_SOURCES)
+
+
+BL2_SOURCES += drivers/delay_timer/delay_timer.c \
+ plat/layerscape/board/ls1043/ls1043_bl2_setup.c \
+ plat/layerscape/board/ls1043/ls1043_err.c \
+ ${LS1043_SECURITY_SOURCES}
+
+
+BL31_SOURCES += plat/layerscape/board/ls1043/ls1043_bl31_setup.c \
+ plat/layerscape/board/ls1043/ls1043_topology.c \
+ plat/layerscape/board/ls1043/aarch64/ls1043_helpers.S \
+ plat/layerscape/board/ls1043/ls1043_psci.c \
+ drivers/delay_timer/delay_timer.c \
+ ${LS1043_CPU_LIBS} \
+ ${LS1043_GIC_SOURCES} \
+ ${LS1043_INTERCONNECT_SOURCES} \
+ ${LS1043_SECURITY_SOURCES}
+
+# Disable the PSCI platform compatibility layer
+ENABLE_PLAT_COMPAT := 0
+MULTI_CONSOLE_API := 1
+
+# Enable workarounds for selected Cortex-A53 erratas.
+ERRATA_A53_855873 := 1
+
+ifneq (${ENABLE_STACK_PROTECTOR},0)
+PLAT_BL_COMMON_SOURCES += plat/layerscape/board/ls1043/ls1043_stack_protector.c
+endif
+
+ifeq (${ARCH},aarch32)
+ NEED_BL32 := yes
+endif
+
+include plat/layerscape/common/ls_common.mk
diff --git a/plat/layerscape/board/ls1043/tsp/ls1043_tsp_setup.c b/plat/layerscape/board/ls1043/tsp/ls1043_tsp_setup.c
new file mode 100644
index 0000000..4fc019c
--- /dev/null
+++ b/plat/layerscape/board/ls1043/tsp/ls1043_tsp_setup.c
@@ -0,0 +1,14 @@
+/*
+ * Copyright (c) 2018, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include "plat_ls.h"
+
+void tsp_early_platform_setup(void)
+{
+ ls_tsp_early_platform_setup();
+
+ /*Todo: Initialize the platform config for future decision making */
+}
diff --git a/plat/layerscape/board/ls1043/tsp/tsp-ls1043.mk b/plat/layerscape/board/ls1043/tsp/tsp-ls1043.mk
new file mode 100644
index 0000000..3941427
--- /dev/null
+++ b/plat/layerscape/board/ls1043/tsp/tsp-ls1043.mk
@@ -0,0 +1,12 @@
+#
+# Copyright (c) 2018, ARM Limited and Contributors. All rights reserved.
+#
+# SPDX-License-Identifier: BSD-3-Clause
+#
+
+# TSP source files specific to FVP platform
+BL32_SOURCES += plat/layerscape/board/ls1043/ls1043_topology.c \
+ plat/layerscape/board/ls1043/tsp/ls1043_tsp_setup.c \
+ ${LS1043_GIC_SOURCES}
+
+include plat/layerscape/common/tsp/ls_tsp.mk
diff --git a/plat/layerscape/common/aarch64/ls_bl2_mem_params_desc.c b/plat/layerscape/common/aarch64/ls_bl2_mem_params_desc.c
new file mode 100644
index 0000000..a96e390
--- /dev/null
+++ b/plat/layerscape/common/aarch64/ls_bl2_mem_params_desc.c
@@ -0,0 +1,113 @@
+/*
+ * Copyright (c) 2018, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <bl_common.h>
+#include <desc_image_load.h>
+#include <platform.h>
+#include <platform_def.h>
+#include <debug.h>
+#include <ls_def.h>
+
+/*******************************************************************************
+ * Following descriptor provides BL image/ep information that gets used
+ * by BL2 to load the images and also subset of this information is
+ * passed to next BL image. The image loading sequence is managed by
+ * populating the images in required loading order. The image execution
+ * sequence is managed by populating the `next_handoff_image_id` with
+ * the next executable image id.
+ ******************************************************************************/
+static bl_mem_params_node_t bl2_mem_params_descs[] = {
+#ifdef EL3_PAYLOAD_BASE
+ /* Fill EL3 payload related information (BL31 is EL3 payload)*/
+ {
+ .image_id = BL31_IMAGE_ID,
+
+ SET_STATIC_PARAM_HEAD(ep_info, PARAM_EP,
+ VERSION_2, entry_point_info_t,
+ SECURE | EXECUTABLE | EP_FIRST_EXE),
+ .ep_info.pc = EL3_PAYLOAD_BASE,
+ .ep_info.spsr = SPSR_64(MODE_EL3, MODE_SP_ELX,
+ DISABLE_ALL_EXCEPTIONS),
+
+ SET_STATIC_PARAM_HEAD(image_info, PARAM_EP,
+ VERSION_2, image_info_t,
+ IMAGE_ATTRIB_PLAT_SETUP |
+ IMAGE_ATTRIB_SKIP_LOADING),
+
+ .next_handoff_image_id = INVALID_IMAGE_ID,
+ },
+
+#else /* EL3_PAYLOAD_BASE */
+
+ /* Fill BL31 related information */
+ {
+ .image_id = BL31_IMAGE_ID,
+
+ SET_STATIC_PARAM_HEAD(ep_info, PARAM_EP,
+ VERSION_2, entry_point_info_t,
+ SECURE | EXECUTABLE | EP_FIRST_EXE),
+ .ep_info.pc = BL31_BASE,
+ .ep_info.spsr = SPSR_64(MODE_EL3, MODE_SP_ELX,
+ DISABLE_ALL_EXCEPTIONS),
+#if DEBUG
+ .ep_info.args.arg1 = LS_BL31_PLAT_PARAM_VAL,
+#endif
+
+ SET_STATIC_PARAM_HEAD(image_info, PARAM_EP,
+ VERSION_2, image_info_t, IMAGE_ATTRIB_PLAT_SETUP),
+ .image_info.image_base = BL31_BASE,
+ .image_info.image_max_size = (BL31_LIMIT - BL31_BASE),
+
+# ifdef BL32_BASE
+ .next_handoff_image_id = BL32_IMAGE_ID,
+# else
+ .next_handoff_image_id = BL33_IMAGE_ID,
+# endif
+ },
+# ifdef BL32_BASE
+ /* Fill BL32 related information */
+ {
+ .image_id = BL32_IMAGE_ID,
+
+ SET_STATIC_PARAM_HEAD(ep_info, PARAM_EP,
+ VERSION_2, entry_point_info_t, SECURE | EXECUTABLE),
+ .ep_info.pc = BL32_BASE,
+
+ SET_STATIC_PARAM_HEAD(image_info, PARAM_EP,
+ VERSION_2, image_info_t, 0),
+ .image_info.image_base = BL32_BASE,
+ .image_info.image_max_size = (BL32_LIMIT - BL32_BASE),
+
+ .next_handoff_image_id = BL33_IMAGE_ID,
+ },
+# endif /* BL32_BASE */
+
+ /* Fill BL33 related information */
+ {
+ .image_id = BL33_IMAGE_ID,
+ SET_STATIC_PARAM_HEAD(ep_info, PARAM_EP,
+ VERSION_2, entry_point_info_t, NON_SECURE | EXECUTABLE),
+# ifdef PRELOADED_BL33_BASE
+ .ep_info.pc = PRELOADED_BL33_BASE,
+
+ SET_STATIC_PARAM_HEAD(image_info, PARAM_EP,
+ VERSION_2, image_info_t,
+ IMAGE_ATTRIB_SKIP_LOADING),
+# else
+ .ep_info.pc = BL33_BASE,
+
+ SET_STATIC_PARAM_HEAD(image_info, PARAM_EP,
+ VERSION_2, image_info_t, 0),
+ .image_info.image_base = BL33_BASE,
+ .image_info.image_max_size = LS_NS_DRAM_SIZE,
+# endif /* PRELOADED_BL33_BASE */
+
+ .next_handoff_image_id = INVALID_IMAGE_ID,
+ }
+#endif /* EL3_PAYLOAD_BASE */
+};
+
+REGISTER_BL_IMAGE_DESCS(bl2_mem_params_descs)
diff --git a/plat/layerscape/common/aarch64/ls_console.S b/plat/layerscape/common/aarch64/ls_console.S
new file mode 100644
index 0000000..5c87465
--- /dev/null
+++ b/plat/layerscape/common/aarch64/ls_console.S
@@ -0,0 +1,268 @@
+/*
+ * Copyright (c) 2018, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <arch.h>
+#include <asm_macros.S>
+#include <console_macros.S>
+#include <assert_macros.S>
+#include "ls_16550.h"
+
+ /*
+ * "core" functions are low-level implementations that don't require
+ * writable memory and are thus safe to call in BL1 crash context.
+ */
+ .globl console_ls_16550_core_init
+ .globl console_ls_16550_core_putc
+ .globl console_ls_16550_core_getc
+
+ .globl console_ls_16550_putc
+ .globl console_ls_16550_getc
+ .globl console_ls_16550_flush
+
+ /* -----------------------------------------------
+ * int console_ls_16550_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, 0 on error
+ * Clobber list : x1, x2, x3
+ * -----------------------------------------------
+ */
+func console_ls_16550_core_init
+ /* Check the input base address */
+ cbz x0, init_fail
+ /* Check baud rate and uart clock for sanity */
+ cbz w1, init_fail
+ cbz w2, init_fail
+
+ /* Program the baudrate */
+ /* Divisor = Uart clock / (16 * baudrate) */
+ lsl w2, w2, #4
+ udiv w2, w1, w2
+ and w1, w2, #0xff /* w1 = DLL */
+ lsr w2, w2, #8
+ and w2, w2, #0xff /* w2 = DLLM */
+ ldrb w3, [x0, #UARTLCR]
+ orr w3, w3, #UARTLCR_DLAB
+ strb w3, [x0, #UARTLCR] /* enable DLL, DLLM programming */
+ strb w1, [x0, #UARTDLL] /* program DLL */
+ strb w2, [x0, #UARTDLLM] /* program DLLM */
+ mov w2, #~UARTLCR_DLAB
+ and w3, w3, w2
+ strb w3, [x0, #UARTLCR] /* disable DLL, DLLM programming */
+
+ /* 8n1 */
+ mov w3, #3
+ strb w3, [x0, #UARTLCR]
+ /* no interrupt */
+ mov w3, #0
+ strb w3, [x0, #UARTIER]
+ /* enable fifo, DMA */
+ mov w3, #(UARTFCR_FIFOEN |UARTFCR_TXCLR | UARTFCR_RXCLR)
+ strb w3, [x0, #UARTFCR]
+ /* DTR + RTS */
+ mov w3, #3
+ str w3, [x0, #UARTMCR]
+ mov w0, #1
+ ret
+init_fail:
+ mov w0, #0
+ ret
+endfunc console_ls_16550_core_init
+
+#if MULTI_CONSOLE_API
+ .globl console_ls_16550_register
+
+ /* -----------------------------------------------
+ * int console_ls_16550_register(console_ls_16550_t *console,
+ * uintptr_t base, uint32_t clk, uint32_t baud)
+ * Function to initialize and register a new 16550
+ * console. Storage passed in for the console struct
+ * *must* be persistent (i.e. not from the stack).
+ * In: x0 - UART register base address
+ * w1 - UART clock in Hz
+ * w2 - Baud rate
+ * x3 - pointer to empty console_ls_16550_t struct
+ * Out: return 1 on success, 0 on error
+ * Clobber list : x0, x1, x2, x6, x7, x14
+ * -----------------------------------------------
+ */
+func console_ls_16550_register
+ mov x7, x30
+ mov x6, x3
+ cbz x6, register_fail
+ str x0, [x6, #CONSOLE_T_16550_BASE]
+
+ bl console_ls_16550_core_init
+ cbz x0, register_fail
+
+ mov x0, x6
+ mov x30, x7
+ finish_console_register ls_16550
+
+register_fail:
+ ret x7
+endfunc console_ls_16550_register
+#else
+ .globl console_core_init
+ .globl console_core_putc
+ .globl console_core_getc
+ .globl console_core_flush
+ .equ console_core_init,console_ls_16550_core_init
+ .equ console_core_putc,console_ls_16550_core_putc
+ .equ console_core_getc,console_ls_16550_core_getc
+ .equ console_core_flush,console_ls_16550_core_flush
+#endif
+
+ /* --------------------------------------------------------
+ * int console_ls_16550_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_ls_16550_core_putc
+#if ENABLE_ASSERTIONS
+ cmp x1, #0
+ ASM_ASSERT(ne)
+#endif /* ENABLE_ASSERTIONS */
+
+ /* Prepend '\r' to '\n' */
+ cmp w0, #0xA //'\n'
+ b.ne 2f
+ /* Check if the transmit FIFO is full */
+1: ldrb w2, [x1, #UARTLSR]
+ and w2, w2, #UARTLSR_THRE /* #(UARTLSR_TEMT | UARTLSR_THRE)*/
+ cmp w2, #(UARTLSR_THRE)
+ b.ne 1b
+ mov w2, #0xD /* '\r' */
+ strb w2, [x1, #UARTTX]
+ ldrb w2, [x1, #UARTFCR]
+ orr w2, w2, #UARTFCR_TXCLR
+
+ /* Check if the transmit FIFO is full */
+2: ldrb w2, [x1, #UARTLSR]
+ and w2, w2, #(UARTLSR_THRE)
+ cmp w2, #(UARTLSR_THRE)
+ b.ne 2b
+ strb w0, [x1, #UARTTX]
+ ret
+endfunc console_ls_16550_core_putc
+
+ /* --------------------------------------------------------
+ * int console_16550_putc(int c, console_ls_16550_t *console)
+ * 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 - pointer to console_t structure
+ * Out : return -1 on error else return character.
+ * Clobber list : x2
+ * --------------------------------------------------------
+ */
+func console_ls_16550_putc
+#if ENABLE_ASSERTIONS
+ cmp x1, #0
+ ASM_ASSERT(ne)
+#endif /* ENABLE_ASSERTIONS */
+ ldr x1, [x1, #CONSOLE_T_16550_BASE]
+ b console_ls_16550_core_putc
+endfunc console_ls_16550_putc
+
+ /* ---------------------------------------------
+ * int console_ls_16550_core_getc(uintptr_t base_addr)
+ * Function to get a character from the console.
+ * It returns the character grabbed on success
+ * or -1 on if no character is available.
+ * In : x0 - console base address
+ * Out : w0 - character if available, else -1
+ * Clobber list : x0, x1
+ * ---------------------------------------------
+ */
+func console_ls_16550_core_getc
+#if ENABLE_ASSERTIONS
+ cmp x0, #0
+ ASM_ASSERT(ne)
+#endif /* ENABLE_ASSERTIONS */
+
+ /* Check if the receive FIFO is empty */
+1: ldrb w1, [x0, #UARTLSR]
+ tbz w1, #UARTLSR_RDR, 1b
+ ldrb w0, [x0, #UARTRX]
+ ret
+no_char:
+ mov w0, #ERROR_NO_PENDING_CHAR
+ ret
+endfunc console_ls_16550_core_getc
+
+ /* ---------------------------------------------
+ * int console_ls_16550_getc(console_ls_16550_t *console)
+ * Function to get a character from the console.
+ * It returns the character grabbed on success
+ * or -1 on if no character is available.
+ * In : x0 - pointer to console_t structure
+ * Out : w0 - character if available, else -1
+ * Clobber list : x0, x1
+ * ---------------------------------------------
+ */
+func console_ls_16550_getc
+#if ENABLE_ASSERTIONS
+ cmp x1, #0
+ ASM_ASSERT(ne)
+#endif /* ENABLE_ASSERTIONS */
+ ldr x0, [x0, #CONSOLE_T_16550_BASE]
+ b console_ls_16550_core_getc
+endfunc console_ls_16550_getc
+
+ /* ---------------------------------------------
+ * int console_ls_16550_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_ls_16550_core_flush
+#if ENABLE_ASSERTIONS
+ cmp x0, #0
+ ASM_ASSERT(ne)
+#endif /* ENABLE_ASSERTIONS */
+
+ /* Loop until the transmit FIFO is empty */
+1: ldrb w1, [x0, #UARTLSR]
+ and w1, w1, #(UARTLSR_TEMT | UARTLSR_THRE)
+ cmp w1, #(UARTLSR_TEMT | UARTLSR_THRE)
+ b.ne 1b
+
+ mov w0, #0
+ ret
+endfunc console_ls_16550_core_flush
+
+ /* ---------------------------------------------
+ * int console_ls_16550_flush(console_ls_16550_t *console)
+ * Function to force a write of all buffered
+ * data that hasn't been output.
+ * In : x0 - pointer to console_t structure
+ * Out : return -1 on error else return 0.
+ * Clobber list : x0, x1
+ * ---------------------------------------------
+ */
+func console_ls_16550_flush
+#if ENABLE_ASSERTIONS
+ cmp x0, #0
+ ASM_ASSERT(ne)
+#endif /* ENABLE_ASSERTIONS */
+ ldr x0, [x0, #CONSOLE_T_16550_BASE]
+ b console_ls_16550_core_flush
+endfunc console_ls_16550_flush
diff --git a/plat/layerscape/common/aarch64/ls_helpers.S b/plat/layerscape/common/aarch64/ls_helpers.S
new file mode 100644
index 0000000..7d71f48
--- /dev/null
+++ b/plat/layerscape/common/aarch64/ls_helpers.S
@@ -0,0 +1,150 @@
+/*
+ * Copyright (c) 2018, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <asm_macros.S>
+#include <console.h>
+#include <platform_def.h>
+
+ .weak plat_my_core_pos
+ .globl plat_crash_console_init
+ .globl plat_crash_console_putc
+ .globl plat_crash_console_flush
+ .weak platform_mem_init
+ .globl plat_ls_calc_core_pos
+
+
+ /* -----------------------------------------------------
+ * unsigned int plat_my_core_pos(void)
+ * This function uses the plat_ls_calc_core_pos()
+ * definition to get the index of the calling CPU.
+ * -----------------------------------------------------
+ */
+func plat_my_core_pos
+ mrs x0, mpidr_el1
+ b plat_ls_calc_core_pos
+endfunc plat_my_core_pos
+
+ /* -----------------------------------------------------
+ * unsigned int plat_ls_calc_core_pos(u_register_t mpidr)
+ * Helper function to calculate the core position.
+ * With this function: CorePos = (ClusterId * 4) +
+ * CoreId
+ * -----------------------------------------------------
+ */
+func plat_ls_calc_core_pos
+ and x1, x0, #MPIDR_CPU_MASK
+ and x0, x0, #MPIDR_CLUSTER_MASK
+ add x0, x1, x0, LSR #6
+ ret
+endfunc plat_ls_calc_core_pos
+
+ /* ---------------------------------------------
+ * int plat_crash_console_init(void)
+ * Function to initialize the crash console
+ * without a C Runtime to print crash report.
+ * Clobber list : x0 - x4
+ * ---------------------------------------------
+ */
+
+#if MULTI_CONSOLE_API
+ /* -----------------------------------------------------
+ * int plat_crash_console_init(void)
+ * Use normal console by default. Switch it to crash
+ * mode so serial consoles become active again.
+ * NOTE: This default implementation will only work for
+ * crashes that occur after a normal console (marked
+ * valid for the crash state) has been registered with
+ * the console framework. To debug crashes that occur
+ * earlier, the platform has to override these functions
+ * with an implementation that initializes a console
+ * driver with hardcoded parameters. See
+ * docs/porting-guide.rst for more information.
+ * -----------------------------------------------------
+ */
+func plat_crash_console_init
+#if defined(IMAGE_BL1)
+ /*
+ * BL1 code can possibly crash so early that the data segment is not yet
+ * accessible. Don't risk undefined behavior by trying to run the normal
+ * console framework. Platforms that want to debug BL1 will need to
+ * override this with custom functions that can run from registers only.
+ */
+ mov x0, #0
+ ret
+#else /* IMAGE_BL1 */
+ mov x3, x30
+ mov x0, #CONSOLE_FLAG_CRASH
+ bl console_switch_state
+ mov x0, #1
+ ret x3
+#endif
+endfunc plat_crash_console_init
+
+ /* -----------------------------------------------------
+ * void plat_crash_console_putc(int character)
+ * Output through the normal console by default.
+ * -----------------------------------------------------
+ */
+func plat_crash_console_putc
+ b console_putc
+endfunc plat_crash_console_putc
+
+ /* -----------------------------------------------------
+ * void plat_crash_console_flush(void)
+ * Flush normal console by default.
+ * -----------------------------------------------------
+ */
+func plat_crash_console_flush
+ b console_flush
+endfunc plat_crash_console_flush
+
+#else /* MULTI_CONSOLE_API */
+
+ /* -----------------------------------------------------
+ * In the old API these are all no-op stubs that need to
+ * be overridden by the platform to be useful.
+ * -----------------------------------------------------
+ */
+func plat_crash_console_init
+ mov_imm x0, PLAT_LS1043_UART_BASE
+ mov_imm x1, PLAT_LS1043_UART_CLOCK
+ mov_imm x2, PLAT_LS1043_UART_BAUDRATE
+ b console_core_init
+endfunc plat_crash_console_init
+
+ /* ---------------------------------------------
+ * int plat_crash_console_putc(int c)
+ * Function to print a character on the crash
+ * console without a C Runtime.
+ * Clobber list : x1, x2
+ * ---------------------------------------------
+ */
+func plat_crash_console_putc
+ mov_imm x1, PLAT_LS1043_UART_BASE
+ b console_core_putc
+endfunc plat_crash_console_putc
+
+ /* ---------------------------------------------
+ * int plat_crash_console_flush()
+ * Function to force a write of all buffered
+ * data that hasn't been output.
+ * Out : return -1 on error else return 0.
+ * Clobber list : r0 - r1
+ * ---------------------------------------------
+ */
+func plat_crash_console_flush
+ mov_imm x1, PLAT_LS1043_UART_BASE
+ b console_core_flush
+endfunc plat_crash_console_flush
+#endif
+ /* ---------------------------------------------------------------------
+ * We don't need to carry out any memory initialization on LS
+ * platforms. The Secure SRAM is accessible straight away.
+ * ---------------------------------------------------------------------
+ */
+func platform_mem_init
+ ret
+endfunc platform_mem_init
diff --git a/plat/layerscape/common/include/fsl_csu.h b/plat/layerscape/common/include/fsl_csu.h
new file mode 100644
index 0000000..680911e
--- /dev/null
+++ b/plat/layerscape/common/include/fsl_csu.h
@@ -0,0 +1,33 @@
+/*
+ * Copyright (c) 2018, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef __FSL_CSU_H__
+#define __FSL_CSU_H__
+
+enum csu_cslx_access {
+ CSU_NS_SUP_R = 0x08,
+ CSU_NS_SUP_W = 0x80,
+ CSU_NS_SUP_RW = 0x88,
+ CSU_NS_USER_R = 0x04,
+ CSU_NS_USER_W = 0x40,
+ CSU_NS_USER_RW = 0x44,
+ CSU_S_SUP_R = 0x02,
+ CSU_S_SUP_W = 0x20,
+ CSU_S_SUP_RW = 0x22,
+ CSU_S_USER_R = 0x01,
+ CSU_S_USER_W = 0x10,
+ CSU_S_USER_RW = 0x11,
+ CSU_ALL_RW = 0xff,
+};
+
+struct csu_ns_dev {
+ uintptr_t ind;
+ uint32_t val;
+};
+
+void enable_layerscape_ns_access(void);
+
+#endif
diff --git a/plat/layerscape/common/include/ls_16550.h b/plat/layerscape/common/include/ls_16550.h
new file mode 100644
index 0000000..503a01d
--- /dev/null
+++ b/plat/layerscape/common/include/ls_16550.h
@@ -0,0 +1,86 @@
+/*
+ * Copyright (c) 2018, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef __LS_16550_H__
+#define __LS_16550_H__
+
+#include <console.h>
+
+/* UART16550 Registers */
+#define UARTTX 0x0
+#define UARTRX 0x0
+#define UARTDLL 0x0
+#define UARTIER 0x1
+#define UARTDLLM 0x1
+#define UARTFCR 0x2
+#define UARTLCR 0x3
+#define UARTLSR 0x5
+#define UARTMCR 0x4
+
+/* FIFO Control Register bits */
+#define UARTFCR_FIFOMD_16450 (0 << 6)
+#define UARTFCR_FIFOMD_16550 (1 << 6)
+#define UARTFCR_RXTRIG_1 (0 << 6)
+#define UARTFCR_RXTRIG_4 (1 << 6)
+#define UARTFCR_RXTRIG_8 (2 << 6)
+#define UARTFCR_RXTRIG_16 (3 << 6)
+#define UARTFCR_TXTRIG_1 (0 << 4)
+#define UARTFCR_TXTRIG_4 (1 << 4)
+#define UARTFCR_TXTRIG_8 (2 << 4)
+#define UARTFCR_TXTRIG_16 (3 << 4)
+#define UARTFCR_DMAEN (1 << 3) /* Enable DMA mode */
+#define UARTFCR_TXCLR (1 << 2) /* Clear contents of Tx FIFO */
+#define UARTFCR_RXCLR (1 << 1) /* Clear contents of Rx FIFO */
+#define UARTFCR_FIFOEN (1 << 0) /* Enable the Tx/Rx FIFO */
+#define UARTFCR_64FIFO (1 << 5)
+
+/* Line Control Register bits */
+#define UARTLCR_DLAB (1 << 7) /* Divisor Latch Access */
+#define UARTLCR_SETB (1 << 6) /* Set BREAK Condition */
+#define UARTLCR_SETP (1 << 5) /* Set Parity to LCR[4] */
+#define UARTLCR_EVEN (1 << 4) /* Even Parity Format */
+#define UARTLCR_PAR (1 << 3) /* Parity */
+#define UARTLCR_STOP (1 << 2) /* Stop Bit */
+#define UARTLCR_WORDSZ_5 0 /* Word Length of 5 */
+#define UARTLCR_WORDSZ_6 1 /* Word Length of 6 */
+#define UARTLCR_WORDSZ_7 2 /* Word Length of 7 */
+#define UARTLCR_WORDSZ_8 3 /* Word Length of 8 */
+
+/* Line Status Register bits */
+#define UARTLSR_RXFIFOEMT (1 << 9) /* Rx Fifo Empty */
+#define UARTLSR_TXFIFOFULL (1 << 8) /* Tx Fifo Full */
+#define UARTLSR_RXFIFOERR (1 << 7) /* Rx Fifo Error */
+#define UARTLSR_TEMT (1 << 6) /* Tx Shift Register Empty */
+#define UARTLSR_THRE (1 << 5) /* Tx Holding Register Empty */
+#define UARTLSR_BRK (1 << 4) /* Break Condition Detected */
+#define UARTLSR_FERR (1 << 3) /* Framing Error */
+#define UARTLSR_PERR (1 << 3) /* Parity Error */
+#define UARTLSR_OVRF (1 << 2) /* Rx Overrun Error */
+#define UARTLSR_RDR (1 << 2) /* Rx Data Ready */
+
+#define CONSOLE_T_16550_BASE CONSOLE_T_DRVDATA
+
+#ifndef __ASSEMBLY__
+
+#include <types.h>
+
+typedef struct {
+ console_t console;
+ uintptr_t base;
+} console_ls_16550_t;
+
+/*
+ * Initialize a new 16550 console instance and register it with the console
+ * framework. The |console| pointer must point to storage that will be valid
+ * for the lifetime of the console, such as a global or static local variable.
+ * Its contents will be reinitialized from scratch.
+ */
+int console_ls_16550_register(uintptr_t baseaddr, uint32_t clock, uint32_t baud,
+ console_ls_16550_t *console);
+
+#endif /*__ASSEMBLY__*/
+
+#endif /* __LS_16550_H__ */
diff --git a/plat/layerscape/common/include/plat_ls.h b/plat/layerscape/common/include/plat_ls.h
new file mode 100644
index 0000000..9d5ec14
--- /dev/null
+++ b/plat/layerscape/common/include/plat_ls.h
@@ -0,0 +1,61 @@
+/*
+ * Copyright (c) 2018, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef __PLAT_LS_H__
+#define __PLAT_LS_H__
+
+#include <sys/types.h>
+#include <cpu_data.h>
+
+/* BL1 utility functions */
+void ls_bl1_platform_setup(void);
+void ls_bl1_early_platform_setup(void);
+
+/* BL2 utility functions */
+void ls_bl2_early_platform_setup(meminfo_t *mem_layout);
+uint32_t ls_get_spsr_for_bl32_entry(void);
+uint32_t ls_get_spsr_for_bl33_entry(void);
+
+/* BL3 utility functions */
+void ls_bl31_early_platform_setup(void *from_bl2,
+ void *plat_params_from_bl2);
+
+/* IO storage utility functions */
+void plat_ls_io_setup(void);
+
+
+void ls_setup_page_tables(uintptr_t total_base,
+ size_t total_size,
+ uintptr_t code_start,
+ uintptr_t code_limit,
+ uintptr_t rodata_start,
+ uintptr_t rodata_limit
+#if USE_COHERENT_MEM
+ , uintptr_t coh_start,
+ uintptr_t coh_limit
+#endif
+);
+
+/* PSCI utility functions */
+int ls_check_mpidr(u_register_t mpidr);
+
+/* Security utility functions */
+int tzc380_setup(void);
+
+/* Timer utility functions */
+uint64_t ls_get_timer(uint64_t start);
+void ls_delay_timer_init(void);
+
+/* TSP utility functions */
+void ls_tsp_early_platform_setup(void);
+
+/* Helper functions */
+unsigned int plat_ls_calc_core_pos(u_register_t mpidr);
+
+/* others */
+unsigned int plat_ls_get_cluster_core_count(u_register_t mpidr);
+
+#endif /* __PLAT_LS_H__ */
diff --git a/plat/layerscape/common/include/soc.h b/plat/layerscape/common/include/soc.h
new file mode 100644
index 0000000..72c10cf
--- /dev/null
+++ b/plat/layerscape/common/include/soc.h
@@ -0,0 +1,18 @@
+/*
+ * Copyright (c) 2018, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef __LAYERSCAPE_SOC_H__
+#define __LAYERSCAPE_SOC_H__
+
+#include <stdint.h>
+
+#define SVR_WO_E 0xFFFFFE
+#define SVR_LS1043A 0x879204
+#define SVR_LS1043AE 0x879200
+
+void get_gic_offset(uint32_t *gicc_base, uint32_t *gicd_base);
+
+#endif /* __LAYERSCAPE_SOC_H__ */
diff --git a/plat/layerscape/common/include/tzc380.h b/plat/layerscape/common/include/tzc380.h
new file mode 100644
index 0000000..788c0ed
--- /dev/null
+++ b/plat/layerscape/common/include/tzc380.h
@@ -0,0 +1,19 @@
+/*
+ * Copyright (c) 2018, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef __TZC380_H__
+#define __TZC380_H__
+
+struct tzc380_reg {
+ unsigned int secure;
+ unsigned int enabled;
+ unsigned int low_addr;
+ unsigned int high_addr;
+ unsigned int size;
+ unsigned int sub_mask;
+};
+
+#endif /* __TZC380_H__ */
diff --git a/plat/layerscape/common/ls_bl1_setup.c b/plat/layerscape/common/ls_bl1_setup.c
new file mode 100644
index 0000000..43f7450
--- /dev/null
+++ b/plat/layerscape/common/ls_bl1_setup.c
@@ -0,0 +1,89 @@
+/*
+ * Copyright (c) 2018, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <debug.h>
+#include "ls_16550.h"
+#include "plat_ls.h"
+#include "../../../bl1/bl1_private.h"
+
+/* Data structure which holds the extents of the trusted SRAM for BL1*/
+static meminfo_t bl1_tzram_layout;
+
+meminfo_t *bl1_plat_sec_mem_layout(void)
+{
+ return &bl1_tzram_layout;
+}
+
+/*******************************************************************************
+ * BL1 specific platform actions shared between ARM standard platforms.
+ ******************************************************************************/
+void ls_bl1_early_platform_setup(void)
+{
+ static console_ls_16550_t console;
+
+#if !LS1043_DISABLE_TRUSTED_WDOG
+ /* TODO: Enable watchdog */
+
+#endif
+
+ /* Initialize the console to provide early debug support */
+ console_ls_16550_register(LS_TF_UART_BASE, LS_TF_UART_CLOCK,
+ LS_TF_UART_BAUDRATE, &console);
+
+ /* Allow BL1 to see the whole Trusted RAM */
+ bl1_tzram_layout.total_base = LS_SRAM_BASE;
+ bl1_tzram_layout.total_size = LS_SRAM_SIZE;
+}
+
+/******************************************************************************
+ * Perform the very early platform specific architecture setup shared between
+ * ARM standard platforms. This only does basic initialization. Later
+ * architectural setup (bl1_arch_setup()) does not do anything platform
+ * specific.
+ *****************************************************************************/
+void ls_bl1_plat_arch_setup(void)
+{
+ ls_setup_page_tables(bl1_tzram_layout.total_base,
+ bl1_tzram_layout.total_size,
+ BL_CODE_BASE,
+ BL1_CODE_END,
+ BL1_RO_DATA_BASE,
+ BL1_RO_DATA_END
+#if USE_COHERENT_MEM
+ , BL_COHERENT_RAM_BASE,
+ BL_COHERENT_RAM_END
+#endif
+ );
+ VERBOSE("After setup the page tables\n");
+#ifdef AARCH32
+ enable_mmu_secure(0);
+#else
+ enable_mmu_el3(0);
+#endif /* AARCH32 */
+ VERBOSE("After MMU enabled\n");
+}
+
+void bl1_plat_arch_setup(void)
+{
+ ls_bl1_plat_arch_setup();
+}
+
+/*
+ * Perform the platform specific architecture setup shared between
+ * ARM standard platforms.
+ */
+void ls_bl1_platform_setup(void)
+{
+ /* Initialise the IO layer and register platform IO devices */
+ plat_ls_io_setup();
+}
+
+void bl1_plat_prepare_exit(entry_point_info_t *ep_info)
+{
+#if !LS1043_DISABLE_TRUSTED_WDOG
+ /*TODO: Disable watchdog before leaving BL1 */
+#endif
+}
diff --git a/plat/layerscape/common/ls_bl2_setup.c b/plat/layerscape/common/ls_bl2_setup.c
new file mode 100644
index 0000000..6e6ad6e
--- /dev/null
+++ b/plat/layerscape/common/ls_bl2_setup.c
@@ -0,0 +1,98 @@
+/*
+ * Copyright (c) 2018, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <assert.h>
+#include <bl_common.h>
+#include <desc_image_load.h>
+#include "ls_16550.h"
+#include "plat_ls.h"
+#include "ls_def.h"
+
+/* Data structure which holds the extents of the trusted SRAM for BL2 */
+static meminfo_t bl2_tzram_layout __aligned(CACHE_WRITEBACK_GRANULE);
+
+/*******************************************************************************
+ * 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.
+ * Copy it to a safe location before its reclaimed by later BL2 functionality.
+ ******************************************************************************/
+void ls_bl2_early_platform_setup(meminfo_t *mem_layout)
+{
+ static console_ls_16550_t console;
+
+ /* Initialize the console to provide early debug support */
+ console_ls_16550_register(LS_TF_UART_BASE, LS_TF_UART_CLOCK,
+ LS_TF_UART_BAUDRATE, &console);
+
+ /* Setup the BL2 memory layout */
+ bl2_tzram_layout = *mem_layout;
+
+ /* Initialise the IO layer and register platform IO devices */
+ plat_ls_io_setup();
+}
+
+/*******************************************************************************
+ * Perform the very early platform specific architectural setup here. At the
+ * moment this is only initializes the mmu in a quick and dirty way.
+ ******************************************************************************/
+void ls_bl2_plat_arch_setup(void)
+{
+ ls_setup_page_tables(bl2_tzram_layout.total_base,
+ bl2_tzram_layout.total_size,
+ BL_CODE_BASE,
+ BL_CODE_END,
+ BL_RO_DATA_BASE,
+ BL_RO_DATA_END
+#if USE_COHERENT_MEM
+ , BL_COHERENT_RAM_BASE,
+ BL_COHERENT_RAM_END
+#endif
+ );
+
+#ifdef AARCH32
+ enable_mmu_secure(0);
+#else
+ enable_mmu_el1(0);
+#endif
+}
+
+void bl2_plat_arch_setup(void)
+{
+ ls_bl2_plat_arch_setup();
+}
+
+int ls_bl2_handle_post_image_load(unsigned int image_id)
+{
+ int err = 0;
+ bl_mem_params_node_t *bl_mem_params = get_bl_mem_params_node(image_id);
+
+ assert(bl_mem_params);
+
+ switch (image_id) {
+#ifdef AARCH64
+ case BL32_IMAGE_ID:
+ bl_mem_params->ep_info.spsr = ls_get_spsr_for_bl32_entry();
+ break;
+#endif
+
+ case BL33_IMAGE_ID:
+ /* 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 = ls_get_spsr_for_bl33_entry();
+ break;
+ }
+
+ return err;
+}
+
+/*******************************************************************************
+ * This function can be used by the platforms to update/use image
+ * information for given `image_id`.
+ ******************************************************************************/
+int bl2_plat_handle_post_image_load(unsigned int image_id)
+{
+ return ls_bl2_handle_post_image_load(image_id);
+}
diff --git a/plat/layerscape/common/ls_bl31_setup.c b/plat/layerscape/common/ls_bl31_setup.c
new file mode 100644
index 0000000..3016f58
--- /dev/null
+++ b/plat/layerscape/common/ls_bl31_setup.c
@@ -0,0 +1,224 @@
+/*
+ * Copyright (c) 2018, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <assert.h>
+#include <console.h>
+#include <mmio.h>
+#include <gicv2.h>
+#include "ls_16550.h"
+#include "plat_ls.h"
+#include "soc.h"
+
+#define BL31_END (uintptr_t)(&__BL31_END__)
+
+/*
+ * Placeholder variables for copying the arguments that have been passed to
+ * BL31 from BL2.
+ */
+static entry_point_info_t bl32_image_ep_info;
+static entry_point_info_t bl33_image_ep_info;
+
+const unsigned int g0_interrupt_array1[] = {
+ 9
+};
+
+gicv2_driver_data_t ls_gic_data = {
+ .gicd_base = GICD_BASE,
+ .gicc_base = GICC_BASE,
+ .g0_interrupt_num = ARRAY_SIZE(g0_interrupt_array1),
+ .g0_interrupt_array = g0_interrupt_array1,
+};
+
+
+/*******************************************************************************
+ * Return a pointer to the 'entry_point_info' structure of the next image for the
+ * security state specified. BL33 corresponds to the non-secure image type
+ * while BL32 corresponds to the secure image type. A NULL pointer is returned
+ * if the image does not exist.
+ ******************************************************************************/
+entry_point_info_t *bl31_plat_get_next_image_ep_info(uint32_t type)
+{
+ entry_point_info_t *next_image_info;
+
+ assert(sec_state_is_valid(type));
+ next_image_info = (type == NON_SECURE)
+ ? &bl33_image_ep_info : &bl32_image_ep_info;
+
+ if (next_image_info->pc)
+ return next_image_info;
+ else
+ return NULL;
+}
+
+/*******************************************************************************
+ * Perform any BL31 early platform setup common to Layerscape platforms.
+ * Here is an opportunity to copy parameters passed by the calling EL (S-EL1
+ * in BL2 & S-EL3 in BL1) before they are lost (potentially). This needs to be
+ * done before the MMU is initialized so that the memory layout can be used
+ * while creating page tables. BL2 has flushed this information to memory, so
+ * we are guaranteed to pick up good data.
+ ******************************************************************************/
+void ls_bl31_early_platform_setup(void *from_bl2,
+ void *plat_params_from_bl2)
+{
+ static console_ls_16550_t console;
+
+ /* Initialize the console to provide early debug support */
+ console_ls_16550_register(LS_TF_UART_BASE, LS_TF_UART_CLOCK,
+ LS_TF_UART_BAUDRATE, &console);
+#if RESET_TO_BL31
+ /* There are no parameters from BL2 if BL31 is a reset vector */
+ assert(from_bl2 == NULL);
+ assert(plat_params_from_bl2 == NULL);
+
+#ifdef BL32_BASE
+ /* Populate entry point information for BL32 */
+ SET_PARAM_HEAD(&bl32_image_ep_info,
+ PARAM_EP,
+ VERSION_1,
+ 0);
+ SET_SECURITY_STATE(bl32_image_ep_info.h.attr, SECURE);
+ bl32_image_ep_info.pc = BL32_BASE;
+ bl32_image_ep_info.spsr = ls_get_spsr_for_bl32_entry();
+#endif /* BL32_BASE */
+
+ /* Populate entry point information for BL33 */
+ SET_PARAM_HEAD(&bl33_image_ep_info,
+ PARAM_EP,
+ VERSION_1,
+ 0);
+ /*
+ * Tell BL31 where the non-trusted software image
+ * is located and the entry state information
+ */
+ bl33_image_ep_info.pc = plat_get_ns_image_entrypoint();
+
+ bl33_image_ep_info.spsr = ls_get_spsr_for_bl33_entry();
+ SET_SECURITY_STATE(bl33_image_ep_info.h.attr, NON_SECURE);
+
+#else /* RESET_TO_BL31 */
+
+ /*
+ * In debug builds, we pass a special value in 'plat_params_from_bl2'
+ * to verify platform parameters from BL2 to BL31.
+ * In release builds, it's not used.
+ */
+ assert(((unsigned long long)plat_params_from_bl2) ==
+ LS_BL31_PLAT_PARAM_VAL);
+
+ /*
+ * Check params passed from BL2 should not be NULL,
+ */
+ bl_params_t *params_from_bl2 = (bl_params_t *)from_bl2;
+
+ assert(params_from_bl2 != NULL);
+ assert(params_from_bl2->h.type == PARAM_BL_PARAMS);
+ assert(params_from_bl2->h.version >= VERSION_2);
+
+ bl_params_node_t *bl_params = params_from_bl2->head;
+
+ /*
+ * Copy BL33 and BL32 (if present), entry point information.
+ * They are stored in Secure RAM, in BL2's address space.
+ */
+ while (bl_params) {
+ if (bl_params->image_id == BL32_IMAGE_ID)
+ bl32_image_ep_info = *bl_params->ep_info;
+
+ if (bl_params->image_id == BL33_IMAGE_ID)
+ bl33_image_ep_info = *bl_params->ep_info;
+
+ bl_params = bl_params->next_params_info;
+ }
+
+ if (bl33_image_ep_info.pc == 0)
+ panic();
+
+#endif /* RESET_TO_BL31 */
+}
+
+/*******************************************************************************
+ * Perform any BL31 platform setup common to Layerscape platforms
+ ******************************************************************************/
+void ls_bl31_platform_setup(void)
+{
+ uint32_t gicc_base, gicd_base;
+
+ NOTICE(FIRMWARE_WELCOME_STR_LS1043_BL31);
+ /* Initialize the GIC driver, cpu and distributor interfaces */
+ get_gic_offset(&gicc_base, &gicd_base);
+ ls_gic_data.gicd_base = (uintptr_t)gicd_base;
+ ls_gic_data.gicc_base = (uintptr_t)gicc_base;
+ gicv2_driver_init(&ls_gic_data);
+ gicv2_distif_init();
+ gicv2_pcpu_distif_init();
+ gicv2_cpuif_enable();
+
+#if RESET_TO_BL31
+ /*
+ * Do initial security configuration to allow DRAM/device access
+ * (if earlier BL has not already done so).
+ */
+ plat_ls_security_setup();
+
+#endif /* RESET_TO_BL31 */
+
+ /* Enable and initialize the System level generic timer */
+ mmio_write_32(LS1043_SYS_CNTCTL_BASE + CNTCR_OFF,
+ CNTCR_FCREQ(0) | CNTCR_EN);
+
+ VERBOSE("Leave arm_bl31_platform_setup\n");
+}
+
+/*******************************************************************************
+ * Perform any BL31 platform runtime setup prior to BL31 exit common to Layerscape
+ * platforms
+ ******************************************************************************/
+void ls_bl31_plat_runtime_setup(void)
+{
+ static console_ls_16550_t console;
+
+ /* Initialize the runtime console */
+ console_ls_16550_register(PLAT_LS1043_UART_BASE, PLAT_LS1043_UART_CLOCK,
+ PLAT_LS1043_UART_BAUDRATE, &console);
+}
+
+void bl31_platform_setup(void)
+{
+ ls_bl31_platform_setup();
+}
+
+void bl31_plat_runtime_setup(void)
+{
+ ls_bl31_plat_runtime_setup();
+}
+
+/*******************************************************************************
+ * Perform the very early platform specific architectural setup shared between
+ * Layerscape platforms. This only does basic initialization. Later
+ * architectural setup (bl31_arch_setup()) does not do anything platform
+ * specific.
+ ******************************************************************************/
+void ls_bl31_plat_arch_setup(void)
+{
+ ls_setup_page_tables(BL31_BASE,
+ BL31_END - BL31_BASE,
+ BL_CODE_BASE,
+ BL_CODE_END,
+ BL_RO_DATA_BASE,
+ BL_RO_DATA_END
+#if USE_COHERENT_MEM
+ , BL_COHERENT_RAM_BASE,
+ BL_COHERENT_RAM_END
+#endif
+ );
+ enable_mmu_el3(0);
+}
+
+void bl31_plat_arch_setup(void)
+{
+ ls_bl31_plat_arch_setup();
+}
diff --git a/plat/layerscape/common/ls_common.c b/plat/layerscape/common/ls_common.c
new file mode 100644
index 0000000..abf6525
--- /dev/null
+++ b/plat/layerscape/common/ls_common.c
@@ -0,0 +1,199 @@
+/*
+ * Copyright (c) 2018, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+#include <arch.h>
+#include <arch_helpers.h>
+#include <xlat_tables_v2.h>
+#include <assert.h>
+#include <debug.h>
+#include <mmio.h>
+#include "platform_def.h"
+
+const mmap_region_t *plat_ls_get_mmap(void);
+
+/*
+ * Table of memory regions for various BL stages to map using the MMU.
+ * This doesn't include Trusted SRAM as ls_setup_page_tables() already
+ * takes care of mapping it.
+ *
+ * The flash needs to be mapped as writable in order to erase the FIP's Table of
+ * Contents in case of unrecoverable error (see plat_error_handler()).
+ */
+#ifdef IMAGE_BL1
+const mmap_region_t plat_ls_mmap[] = {
+ LS_MAP_FLASH0_RW,
+ LS_MAP_NS_DRAM,
+ LS_MAP_CCSR,
+ {0}
+};
+#endif
+#ifdef IMAGE_BL2
+const mmap_region_t plat_ls_mmap[] = {
+ LS_MAP_FLASH0_RW,
+ LS_MAP_CCSR,
+ LS_MAP_NS_DRAM,
+ LS_MAP_TSP_SEC_MEM,
+ {0}
+};
+#endif
+#ifdef IMAGE_BL31
+const mmap_region_t plat_ls_mmap[] = {
+ LS_MAP_CCSR,
+ LS_MAP_FLASH0_RW,
+ LS_MAP_NS_DRAM,
+ LS_MAP_TSP_SEC_MEM,
+ {0}
+};
+#endif
+#ifdef IMAGE_BL32
+const mmap_region_t plat_ls_mmap[] = {
+ LS_MAP_CCSR,
+ LS_MAP_FLASH0_RW,
+ LS_MAP_TSP_SEC_MEM,
+ {0}
+};
+#endif
+/*
+ * Set up the page tables for the generic and platform-specific memory regions.
+ * The extents of the generic memory regions are specified by the function
+ * arguments and consist of:
+ * - Trusted SRAM seen by the BL image;
+ * - Code section;
+ * - Read-only data section;
+ * - Coherent memory region, if applicable.
+ */
+void ls_setup_page_tables(uintptr_t total_base,
+ size_t total_size,
+ uintptr_t code_start,
+ uintptr_t code_limit,
+ uintptr_t rodata_start,
+ uintptr_t rodata_limit
+#if USE_COHERENT_MEM
+ ,
+ uintptr_t coh_start,
+ uintptr_t coh_limit
+#endif
+ )
+{
+ /* Now (re-)map the platform-specific memory regions */
+ mmap_add(plat_ls_get_mmap());
+ /*
+ * Map the Trusted SRAM with appropriate memory attributes.
+ * Subsequent mappings will adjust the attributes for specific regions.
+ */
+ VERBOSE("Trusted SRAM seen by this BL image: %p - %p\n",
+ (void *) total_base, (void *) (total_base + total_size));
+ mmap_add_region(total_base, total_base,
+ total_size,
+ MT_MEMORY | MT_RW | MT_SECURE);
+
+ /* Re-map the code section */
+ VERBOSE("Code region: %p - %p\n",
+ (void *) code_start, (void *) code_limit);
+ mmap_add_region(code_start, code_start,
+ code_limit - code_start,
+ MT_CODE | MT_SECURE);
+
+ /* Re-map the read-only data section */
+ VERBOSE("Read-only data region: %p - %p\n",
+ (void *) rodata_start, (void *) rodata_limit);
+ mmap_add_region(rodata_start, rodata_start,
+ rodata_limit - rodata_start,
+ MT_RO_DATA | MT_SECURE);
+
+#if USE_COHERENT_MEM
+ /* Re-map the coherent memory region */
+ VERBOSE("Coherent region: %p - %p\n",
+ (void *) coh_start, (void *) coh_limit);
+ mmap_add_region(coh_start, coh_start,
+ coh_limit - coh_start,
+ MT_DEVICE | MT_RW | MT_SECURE);
+#endif
+
+ /* Create the page tables to reflect the above mappings */
+ init_xlat_tables();
+}
+
+uintptr_t plat_get_ns_image_entrypoint(void)
+{
+#ifdef PRELOADED_BL33_BASE
+ return PRELOADED_BL33_BASE;
+#else
+ return LS_NS_DRAM_BASE;
+#endif
+}
+
+/*******************************************************************************
+ * Gets SPSR for BL32 entry
+ ******************************************************************************/
+uint32_t ls_get_spsr_for_bl32_entry(void)
+{
+ /*
+ * The Secure Payload Dispatcher service is responsible for
+ * setting the SPSR prior to entry into the BL32 image.
+ */
+ return 0;
+}
+
+/*******************************************************************************
+ * Gets SPSR for BL33 entry
+ ******************************************************************************/
+#ifndef AARCH32
+uint32_t ls_get_spsr_for_bl33_entry(void)
+{
+ unsigned int mode;
+ uint32_t spsr;
+
+ /* Figure out what mode we enter the non-secure world in */
+ mode = EL_IMPLEMENTED(2) ? MODE_EL2 : MODE_EL1;
+
+ /*
+ * TODO: Consider the possibility of specifying the SPSR in
+ * the FIP ToC and allowing the platform to have a say as
+ * well.
+ */
+ spsr = SPSR_64(mode, MODE_SP_ELX, DISABLE_ALL_EXCEPTIONS);
+ return spsr;
+}
+#else
+/*******************************************************************************
+ * Gets SPSR for BL33 entry
+ ******************************************************************************/
+uint32_t ls_get_spsr_for_bl33_entry(void)
+{
+ unsigned int hyp_status, mode, spsr;
+
+ hyp_status = GET_VIRT_EXT(read_id_pfr1());
+
+ mode = (hyp_status) ? MODE32_hyp : MODE32_svc;
+
+ /*
+ * TODO: Consider the possibility of specifying the SPSR in
+ * the FIP ToC and allowing the platform to have a say as
+ * well.
+ */
+ spsr = SPSR_MODE32(mode, plat_get_ns_image_entrypoint() & 0x1,
+ SPSR_E_LITTLE, DISABLE_ALL_EXCEPTIONS);
+ return spsr;
+}
+#endif /* AARCH32 */
+
+/*******************************************************************************
+ * Returns Layerscape platform specific memory map regions.
+ ******************************************************************************/
+const mmap_region_t *plat_ls_get_mmap(void)
+{
+ return plat_ls_mmap;
+}
+
+
+unsigned int plat_get_syscnt_freq2(void)
+{
+ unsigned int counter_base_frequency;
+
+ counter_base_frequency = COUNTER_FREQUENCY;
+
+ return counter_base_frequency;
+}
diff --git a/plat/layerscape/common/ls_common.mk b/plat/layerscape/common/ls_common.mk
new file mode 100644
index 0000000..1a80e9f
--- /dev/null
+++ b/plat/layerscape/common/ls_common.mk
@@ -0,0 +1,62 @@
+#
+# Copyright (c) 2018, ARM Limited and Contributors. All rights reserved.
+#
+# SPDX-License-Identifier: BSD-3-Clause
+#
+
+
+# Process LS1043_DISABLE_TRUSTED_WDOG flag
+# TODO:Temparally disabled it on development phase, not implemented yet
+LS1043_DISABLE_TRUSTED_WDOG := 1
+
+# On Layerscape platforms, separate the code and read-only data sections to allow
+# mapping the former as executable and the latter as execute-never.
+SEPARATE_CODE_AND_RODATA := 1
+
+# Enable new version of image loading on Layerscape platforms
+LOAD_IMAGE_V2 := 1
+
+# Use generic OID definition (tbbr_oid.h)
+USE_TBBR_DEFS := 1
+
+
+COLD_BOOT_SINGLE_CPU := 1
+
+PLAT_INCLUDES += -Iinclude/common/tbbr
+
+PLAT_BL_COMMON_SOURCES += plat/layerscape/common/${ARCH}/ls_helpers.S \
+ plat/layerscape/common/ls_common.c
+
+include lib/xlat_tables_v2/xlat_tables.mk
+
+PLAT_BL_COMMON_SOURCES += ${XLAT_TABLES_LIB_SRCS}
+
+BL1_SOURCES += \
+ drivers/io/io_fip.c \
+ drivers/io/io_memmap.c \
+ drivers/io/io_storage.c \
+ plat/layerscape/common/ls_timer.c \
+ plat/layerscape/common/ls_bl1_setup.c \
+ plat/layerscape/common/ls_io_storage.c
+
+BL2_SOURCES += drivers/io/io_fip.c \
+ drivers/io/io_memmap.c \
+ drivers/io/io_storage.c \
+ plat/layerscape/common/ls_timer.c \
+ plat/layerscape/common/ls_bl2_setup.c \
+ plat/layerscape/common/ls_io_storage.c
+BL2_SOURCES += plat/layerscape/common/${ARCH}/ls_bl2_mem_params_desc.c
+BL2_SOURCES += plat/layerscape/common/ls_image_load.c \
+ common/desc_image_load.c
+
+BL31_SOURCES += plat/layerscape/common/ls_bl31_setup.c \
+ plat/layerscape/common/ls_timer.c \
+ plat/layerscape/common/ls_topology.c \
+ plat/layerscape/common/ns_access.c \
+ plat/common/plat_psci_common.c
+# Verify build config
+# -------------------
+
+ifneq (${LOAD_IMAGE_V2}, 1)
+ $(error Error: Layerscape needs LOAD_IMAGE_V2=1)
+endif
diff --git a/plat/layerscape/common/ls_image_load.c b/plat/layerscape/common/ls_image_load.c
new file mode 100644
index 0000000..909bec2
--- /dev/null
+++ b/plat/layerscape/common/ls_image_load.c
@@ -0,0 +1,33 @@
+/*
+ * Copyright (c) 2018, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <desc_image_load.h>
+#include "ls_def.h"
+
+/*******************************************************************************
+ * This function flushes the data structures so that they are visible
+ * in memory for the next BL image.
+ ******************************************************************************/
+void plat_flush_next_bl_params(void)
+{
+ flush_bl_params_desc();
+}
+
+/*******************************************************************************
+ * This function returns the list of loadable images.
+ ******************************************************************************/
+bl_load_info_t *plat_get_bl_image_load_info(void)
+{
+ return get_bl_load_info_from_mem_params_desc();
+}
+
+/*******************************************************************************
+ * This function returns the list of executable images.
+ ******************************************************************************/
+bl_params_t *plat_get_next_bl_params(void)
+{
+ return get_next_bl_params_from_mem_params_desc();
+}
diff --git a/plat/layerscape/common/ls_io_storage.c b/plat/layerscape/common/ls_io_storage.c
new file mode 100644
index 0000000..7402366
--- /dev/null
+++ b/plat/layerscape/common/ls_io_storage.c
@@ -0,0 +1,175 @@
+/*
+ * Copyright (c) 2018, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+#include <assert.h>
+#include <debug.h>
+#include <firmware_image_package.h>
+#include <io_driver.h>
+#include <io_fip.h>
+#include <io_memmap.h>
+#include <io_storage.h>
+#include "platform_def.h"
+
+/* IO devices */
+static const io_dev_connector_t *fip_dev_con;
+static uintptr_t fip_dev_handle;
+static const io_dev_connector_t *memmap_dev_con;
+static uintptr_t memmap_dev_handle;
+
+static const io_block_spec_t fip_block_spec = {
+ .offset = PLAT_LS_FIP_BASE,
+ .length = PLAT_LS_FIP_MAX_SIZE
+};
+
+static const io_uuid_spec_t bl2_uuid_spec = {
+ .uuid = UUID_TRUSTED_BOOT_FIRMWARE_BL2,
+};
+
+static const io_uuid_spec_t bl31_uuid_spec = {
+ .uuid = UUID_EL3_RUNTIME_FIRMWARE_BL31,
+};
+
+static const io_uuid_spec_t bl32_uuid_spec = {
+ .uuid = UUID_SECURE_PAYLOAD_BL32,
+};
+
+static const io_uuid_spec_t bl33_uuid_spec = {
+ .uuid = UUID_NON_TRUSTED_FIRMWARE_BL33,
+};
+
+static int open_fip(const uintptr_t spec);
+static int open_memmap(const uintptr_t spec);
+
+struct plat_io_policy {
+ uintptr_t *dev_handle;
+ uintptr_t image_spec;
+ int (*check)(const uintptr_t spec);
+};
+
+static const struct plat_io_policy policies[] = {
+ [FIP_IMAGE_ID] = {
+ &memmap_dev_handle,
+ (uintptr_t)&fip_block_spec,
+ open_memmap
+ },
+ [BL2_IMAGE_ID] = {
+ &fip_dev_handle,
+ (uintptr_t)&bl2_uuid_spec,
+ open_fip
+ },
+ [BL31_IMAGE_ID] = {
+ &fip_dev_handle,
+ (uintptr_t)&bl31_uuid_spec,
+ open_fip
+ },
+ [BL32_IMAGE_ID] = {
+ &fip_dev_handle,
+ (uintptr_t)&bl32_uuid_spec,
+ open_fip
+ },
+ [BL33_IMAGE_ID] = {
+ &fip_dev_handle,
+ (uintptr_t)&bl33_uuid_spec,
+ open_fip
+ },
+};
+
+static int open_fip(const uintptr_t spec)
+{
+ int result;
+ uintptr_t local_image_handle;
+
+ /* See if a Firmware Image Package is available */
+ result = io_dev_init(fip_dev_handle, (uintptr_t)FIP_IMAGE_ID);
+ if (result == 0) {
+ result = io_open(fip_dev_handle, spec, &local_image_handle);
+ if (result == 0) {
+ VERBOSE("Using FIP\n");
+ io_close(local_image_handle);
+ }
+ }
+ return result;
+}
+
+
+static int open_memmap(const uintptr_t spec)
+{
+ int result;
+ uintptr_t local_image_handle;
+
+ result = io_dev_init(memmap_dev_handle, (uintptr_t)NULL);
+ if (result == 0) {
+ result = io_open(memmap_dev_handle, spec, &local_image_handle);
+ if (result == 0) {
+ VERBOSE("Using Memmap\n");
+ io_close(local_image_handle);
+ }
+ }
+ return result;
+}
+
+
+void ls_io_setup(void)
+{
+ int io_result;
+
+ io_result = register_io_dev_fip(&fip_dev_con);
+ assert(io_result == 0);
+
+ io_result = register_io_dev_memmap(&memmap_dev_con);
+ assert(io_result == 0);
+
+ /* Open connections to devices and cache the handles */
+ io_result = io_dev_open(fip_dev_con, (uintptr_t)NULL,
+ &fip_dev_handle);
+ assert(io_result == 0);
+
+ io_result = io_dev_open(memmap_dev_con, (uintptr_t)NULL,
+ &memmap_dev_handle);
+ assert(io_result == 0);
+
+ /* Ignore improbable errors in release builds */
+ (void)io_result;
+}
+
+void plat_ls_io_setup(void)
+{
+ ls_io_setup();
+}
+
+int plat_ls_get_alt_image_source(
+ unsigned int image_id __unused,
+ uintptr_t *dev_handle __unused,
+ uintptr_t *image_spec __unused)
+{
+ /* By default do not try an alternative */
+ return -ENOENT;
+}
+
+/*
+ * Return an IO device handle and specification which can be used to access
+ * an image. Use this to enforce platform load policy.
+ */
+int plat_get_image_source(unsigned int image_id, uintptr_t *dev_handle,
+ uintptr_t *image_spec)
+{
+ int result;
+ const struct plat_io_policy *policy;
+
+ assert(image_id < ARRAY_SIZE(policies));
+
+ policy = &policies[image_id];
+ result = policy->check(policy->image_spec);
+ if (result == 0) {
+ *image_spec = policy->image_spec;
+ *dev_handle = *(policy->dev_handle);
+ } else {
+ VERBOSE("Trying alternative IO\n");
+ result = plat_ls_get_alt_image_source(image_id, dev_handle,
+ image_spec);
+ }
+
+ return result;
+}
diff --git a/plat/layerscape/common/ls_timer.c b/plat/layerscape/common/ls_timer.c
new file mode 100644
index 0000000..25b5e63
--- /dev/null
+++ b/plat/layerscape/common/ls_timer.c
@@ -0,0 +1,47 @@
+/*
+ * Copyright (c) 2018, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <mmio.h>
+#include <delay_timer.h>
+#include <arch_helpers.h>
+
+#define TIMER_BASE_ADDR 0x02B00000
+
+uint64_t ls_get_timer(uint64_t start)
+{
+ return read_cntpct_el0() * 1000 / read_cntfrq_el0() - start;
+}
+
+static uint32_t ls_timeus_get_value(void)
+{
+ /*
+ * Generic delay timer implementation expects the timer to be a down
+ * counter. We apply bitwise NOT operator to the tick values returned
+ * by read_cntpct_el0() to simulate the down counter. The value is
+ * clipped from 64 to 32 bits.
+ */
+ return (uint32_t)(~read_cntpct_el0());
+}
+
+static const timer_ops_t ls_timer_ops = {
+ .get_timer_value = ls_timeus_get_value,
+ .clk_mult = 1,
+ .clk_div = 25,
+};
+
+
+/*
+ * Initialise the nxp layerscape on-chip free rolling us counter as the delay
+ * timer.
+ */
+void ls_delay_timer_init(void)
+{
+ uintptr_t cntcr = TIMER_BASE_ADDR;
+
+ mmio_write_32(cntcr, 0x1);
+
+ timer_init(&ls_timer_ops);
+}
diff --git a/plat/layerscape/common/ls_topology.c b/plat/layerscape/common/ls_topology.c
new file mode 100644
index 0000000..5b76087
--- /dev/null
+++ b/plat/layerscape/common/ls_topology.c
@@ -0,0 +1,39 @@
+/*
+ * Copyright (c) 2018, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include "plat_ls.h"
+
+/*******************************************************************************
+ * This function validates an MPIDR by checking whether it falls within the
+ * acceptable bounds. An error code (-1) is returned if an incorrect mpidr
+ * is passed.
+ ******************************************************************************/
+int ls_check_mpidr(u_register_t mpidr)
+{
+ unsigned int cluster_id, cpu_id;
+ uint64_t valid_mask;
+
+ valid_mask = ~(MPIDR_CLUSTER_MASK | MPIDR_CPU_MASK);
+ cluster_id = (mpidr >> MPIDR_AFF1_SHIFT) & MPIDR_AFFLVL_MASK;
+ cpu_id = (mpidr >> MPIDR_AFF0_SHIFT) & MPIDR_AFFLVL_MASK;
+
+ mpidr &= MPIDR_AFFINITY_MASK;
+ if (mpidr & valid_mask)
+ return -1;
+
+ if (cluster_id >= PLAT_LS_CLUSTER_COUNT)
+ return -1;
+
+ /*
+ * Validate cpu_id by checking whether it represents a CPU in
+ * one of the two clusters present on the platform.
+ */
+ if (cpu_id >= plat_ls_get_cluster_core_count(mpidr))
+ return -1;
+
+
+ return 0;
+}
diff --git a/plat/layerscape/common/ls_tzc380.c b/plat/layerscape/common/ls_tzc380.c
new file mode 100644
index 0000000..b9f32ac
--- /dev/null
+++ b/plat/layerscape/common/ls_tzc380.c
@@ -0,0 +1,74 @@
+/*
+ * Copyright (c) 2018, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <debug.h>
+#include <mmio.h>
+#include <endian.h>
+#include "platform_def.h"
+#include "soc_tzasc.h"
+
+int tzc380_set_region(unsigned int tzasc_base, unsigned int region_id,
+ unsigned int enabled, unsigned int low_addr,
+ unsigned int high_addr, unsigned int size,
+ unsigned int security, unsigned int subreg_disable_mask)
+{
+ unsigned int reg;
+ unsigned int reg_base;
+ unsigned int attr_value;
+
+ reg_base = (tzasc_base + TZASC_REGIONS_REG + (region_id << 4));
+
+ if (region_id == 0) {
+ reg = (reg_base + TZASC_REGION_ATTR_OFFSET);
+ mmio_write_32((uintptr_t)reg, ((security & 0xF) << 28));
+ } else {
+ reg = reg_base + TZASC_REGION_LOWADDR_OFFSET;
+ mmio_write_32((uintptr_t)reg,
+ (low_addr & TZASC_REGION_LOWADDR_MASK));
+
+ reg = reg_base + TZASC_REGION_HIGHADDR_OFFSET;
+ mmio_write_32((uintptr_t)reg, high_addr);
+
+ reg = reg_base + TZASC_REGION_ATTR_OFFSET;
+ attr_value = ((security & 0xF) << 28) |
+ ((subreg_disable_mask & 0xFF) << 8) |
+ ((size & 0x3F) << 1) | (enabled & 0x1);
+ mmio_write_32((uintptr_t)reg, attr_value);
+
+ }
+ return 0;
+}
+
+int tzc380_setup(void)
+{
+ int reg_id = 0;
+
+ INFO("Configuring TZASC-380\n");
+
+ /*
+ * Configure CCI control override register to terminate all barrier
+ * transactions
+ */
+ mmio_write_32(PLAT_LS1043_CCI_BASE, CCI_TERMINATE_BARRIER_TX);
+
+ /* Configure CSU secure access register to disable TZASC bypass mux */
+ mmio_write_32((uintptr_t)(CONFIG_SYS_FSL_CSU_ADDR +
+ CSU_SEC_ACCESS_REG_OFFSET),
+ bswap32(TZASC_BYPASS_MUX_DISABLE));
+
+ for (reg_id = 0; reg_id < MAX_NUM_TZC_REGION; reg_id++) {
+ tzc380_set_region(CONFIG_SYS_FSL_TZASC_ADDR,
+ reg_id,
+ tzc380_reg_list[reg_id].enabled,
+ tzc380_reg_list[reg_id].low_addr,
+ tzc380_reg_list[reg_id].high_addr,
+ tzc380_reg_list[reg_id].size,
+ tzc380_reg_list[reg_id].secure,
+ tzc380_reg_list[reg_id].sub_mask);
+ }
+
+ return 0;
+}
diff --git a/plat/layerscape/common/ns_access.c b/plat/layerscape/common/ns_access.c
new file mode 100644
index 0000000..e1daaed
--- /dev/null
+++ b/plat/layerscape/common/ns_access.c
@@ -0,0 +1,37 @@
+/*
+ * Copyright (c) 2018, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <mmio.h>
+#include <endian.h>
+#include <debug.h>
+#include "ns_access.h"
+#include "platform_def.h"
+
+static void enable_devices_ns_access(struct csu_ns_dev *ns_dev, uint32_t num)
+{
+ uint32_t *base = (uint32_t *)CONFIG_SYS_FSL_CSU_ADDR;
+ uint32_t *reg;
+ uint32_t val;
+ int i;
+
+ for (i = 0; i < num; i++) {
+ reg = base + ns_dev[i].ind / 2;
+ val = be32toh(mmio_read_32((uintptr_t)reg));
+ if (ns_dev[i].ind % 2 == 0) {
+ val &= 0x0000ffff;
+ val |= ns_dev[i].val << 16;
+ } else {
+ val &= 0xffff0000;
+ val |= ns_dev[i].val;
+ }
+ mmio_write_32((uintptr_t)reg, htobe32(val));
+ }
+}
+
+void enable_layerscape_ns_access(void)
+{
+ enable_devices_ns_access(ns_dev, ARRAY_SIZE(ns_dev));
+}
diff --git a/plat/layerscape/common/tsp/ls_tsp.mk b/plat/layerscape/common/tsp/ls_tsp.mk
new file mode 100644
index 0000000..7cb9781
--- /dev/null
+++ b/plat/layerscape/common/tsp/ls_tsp.mk
@@ -0,0 +1,10 @@
+#
+# Copyright (c) 2018, ARM Limited and Contributors. All rights reserved.
+#
+# SPDX-License-Identifier: BSD-3-Clause
+#
+
+# TSP source files common to ARM standard platforms
+BL32_SOURCES += plat/layerscape/common/ls_topology.c \
+ plat/layerscape/common/tsp/ls_tsp_setup.c \
+ plat/common/aarch64/platform_mp_stack.S
diff --git a/plat/layerscape/common/tsp/ls_tsp_setup.c b/plat/layerscape/common/tsp/ls_tsp_setup.c
new file mode 100644
index 0000000..82ac965
--- /dev/null
+++ b/plat/layerscape/common/tsp/ls_tsp_setup.c
@@ -0,0 +1,76 @@
+/*
+ * Copyright (c) 2018, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <gicv2.h>
+#include <debug.h>
+#include "ls_16550.h"
+#include "plat_ls.h"
+#include "soc.h"
+
+#define BL32_END (unsigned long)(&__BL32_END__)
+
+const unsigned int g0_interrupt_array1[] = {
+ 9
+};
+
+gicv2_driver_data_t ls_gic_data = {
+ .gicd_base = GICD_BASE,
+ .gicc_base = GICC_BASE,
+ .g0_interrupt_num = ARRAY_SIZE(g0_interrupt_array1),
+ .g0_interrupt_array = g0_interrupt_array1,
+};
+
+/*******************************************************************************
+ * Initialize the UART
+ ******************************************************************************/
+void ls_tsp_early_platform_setup(void)
+{
+ static console_ls_16550_t console;
+ /*
+ * Initialize a different console than already in use to display
+ * messages from TSP
+ */
+ console_ls_16550_register(PLAT_LS1043_UART2_BASE, PLAT_LS1043_UART_CLOCK,
+ PLAT_LS1043_UART_BAUDRATE, &console);
+ NOTICE(FIRMWARE_WELCOME_STR_LS1043_BL32);
+}
+
+/*******************************************************************************
+ * Perform platform specific setup placeholder
+ ******************************************************************************/
+void tsp_platform_setup(void)
+{
+ uint32_t gicc_base, gicd_base;
+
+ /* Initialize the GIC driver, cpu and distributor interfaces */
+ get_gic_offset(&gicc_base, &gicd_base);
+ ls_gic_data.gicd_base = (uintptr_t)gicd_base;
+ ls_gic_data.gicc_base = (uintptr_t)gicc_base;
+ gicv2_driver_init(&ls_gic_data);
+ gicv2_distif_init();
+ gicv2_pcpu_distif_init();
+ gicv2_cpuif_enable();
+}
+
+/*******************************************************************************
+ * Perform the very early platform specific architectural setup here. At the
+ * moment this is only intializes the MMU
+ ******************************************************************************/
+void tsp_plat_arch_setup(void)
+{
+ ls_setup_page_tables(BL32_BASE,
+ (BL32_END - BL32_BASE),
+ BL_CODE_BASE,
+ BL_CODE_END,
+ BL_RO_DATA_BASE,
+ BL_RO_DATA_END
+#if USE_COHERENT_MEM
+ , BL_COHERENT_RAM_BASE,
+ BL_COHERENT_RAM_END
+#endif
+ );
+ enable_mmu_el1(0);
+}
diff --git a/plat/layerscape/common/tsp/platform_tsp.h b/plat/layerscape/common/tsp/platform_tsp.h
new file mode 100644
index 0000000..b1c96cb
--- /dev/null
+++ b/plat/layerscape/common/tsp/platform_tsp.h
@@ -0,0 +1,17 @@
+/*
+ * Copyright (c) 2018, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef __PLATFORM_TSP_H__
+#define __PLATFORM_TSP_H__
+
+/*******************************************************************************
+ * Mandatory TSP functions (only if platform contains a TSP)
+ ******************************************************************************/
+void tsp_early_platform_setup(void);
+void tsp_plat_arch_setup(void);
+void tsp_platform_setup(void);
+
+#endif /* __PLATFORM_TSP_H__ */
diff --git a/plat/xilinx/zynqmp/include/platform_def.h b/plat/xilinx/zynqmp/include/platform_def.h
index b446235..e74b9bb 100644
--- a/plat/xilinx/zynqmp/include/platform_def.h
+++ b/plat/xilinx/zynqmp/include/platform_def.h
@@ -34,9 +34,14 @@
* little space for growth.
*/
#ifndef ZYNQMP_ATF_MEM_BASE
+#if !DEBUG
# define BL31_BASE 0xfffea000
# define BL31_LIMIT 0xffffffff
#else
+# define BL31_BASE 0x1000
+# define BL31_LIMIT 0x7ffff
+#endif
+#else
# define BL31_BASE (ZYNQMP_ATF_MEM_BASE)
# define BL31_LIMIT (ZYNQMP_ATF_MEM_BASE + ZYNQMP_ATF_MEM_SIZE - 1)
# ifdef ZYNQMP_ATF_MEM_PROGBITS_SIZE
diff --git a/plat/xilinx/zynqmp/platform.mk b/plat/xilinx/zynqmp/platform.mk
index bddf305..e49a9cd 100644
--- a/plat/xilinx/zynqmp/platform.mk
+++ b/plat/xilinx/zynqmp/platform.mk
@@ -1,5 +1,5 @@
#
-# Copyright (c) 2013-2017, ARM Limited and Contributors. All rights reserved.
+# Copyright (c) 2013-2018, ARM Limited and Contributors. All rights reserved.
#
# SPDX-License-Identifier: BSD-3-Clause
@@ -77,6 +77,9 @@
plat/xilinx/zynqmp/zynqmp_ipi.c \
plat/xilinx/zynqmp/pm_service/pm_svc_main.c \
plat/xilinx/zynqmp/pm_service/pm_api_sys.c \
+ plat/xilinx/zynqmp/pm_service/pm_api_pinctrl.c \
+ plat/xilinx/zynqmp/pm_service/pm_api_ioctl.c \
+ plat/xilinx/zynqmp/pm_service/pm_api_clock.c \
plat/xilinx/zynqmp/pm_service/pm_ipi.c \
plat/xilinx/zynqmp/pm_service/pm_client.c \
plat/xilinx/zynqmp/ipi_mailbox_service/ipi_mailbox_svc.c
diff --git a/plat/xilinx/zynqmp/pm_service/pm_api_clock.c b/plat/xilinx/zynqmp/pm_service/pm_api_clock.c
new file mode 100644
index 0000000..a41eebb
--- /dev/null
+++ b/plat/xilinx/zynqmp/pm_service/pm_api_clock.c
@@ -0,0 +1,3212 @@
+/*
+ * Copyright (c) 2018, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+/*
+ * ZynqMP system level PM-API functions for clock control.
+ */
+
+#include <arch_helpers.h>
+#include <mmio.h>
+#include <platform.h>
+#include <stdbool.h>
+#include <string.h>
+#include "pm_api_clock.h"
+#include "pm_api_sys.h"
+#include "pm_client.h"
+#include "pm_common.h"
+#include "pm_ipi.h"
+
+#define CLK_NODE_MAX U(6)
+
+#define CLK_PARENTS_ID_LEN U(16)
+#define CLK_TOPOLOGY_NODE_OFFSET U(16)
+#define CLK_TOPOLOGY_PAYLOAD_LEN U(12)
+#define CLK_PARENTS_PAYLOAD_LEN U(12)
+#define CLK_INIT_ENABLE_SHIFT U(1)
+#define CLK_TYPE_SHIFT U(2)
+#define CLK_CLKFLAGS_SHIFT U(8)
+#define CLK_TYPEFLAGS_SHIFT U(24)
+
+#define CLK_EXTERNAL_PARENT (PARENT_CLK_EXTERNAL << CLK_PARENTS_ID_LEN)
+
+#define NA_MULT U(0)
+#define NA_DIV U(0)
+#define NA_SHIFT U(0)
+#define NA_WIDTH U(0)
+#define NA_CLK_FLAGS U(0)
+#define NA_TYPE_FLAGS U(0)
+
+/* PLL nodes related definitions */
+#define PLL_PRESRC_MUX_SHIFT U(20)
+#define PLL_PRESRC_MUX_WIDTH U(3)
+#define PLL_POSTSRC_MUX_SHIFT U(24)
+#define PLL_POSTSRC_MUX_WIDTH U(3)
+#define PLL_DIV2_MUX_SHIFT U(16)
+#define PLL_DIV2_MUX_WIDTH U(1)
+#define PLL_BYPASS_MUX_SHIFT U(3)
+#define PLL_BYPASS_MUX_WIDTH U(1)
+
+/* Peripheral nodes related definitions */
+/* Peripheral Clocks */
+#define PERIPH_MUX_SHIFT U(0)
+#define PERIPH_MUX_WIDTH U(3)
+#define PERIPH_DIV1_SHIFT U(8)
+#define PERIPH_DIV1_WIDTH U(6)
+#define PERIPH_DIV2_SHIFT U(16)
+#define PERIPH_DIV2_WIDTH U(6)
+#define PERIPH_GATE_SHIFT U(24)
+#define PERIPH_GATE_WIDTH U(1)
+
+#define USB_GATE_SHIFT U(25)
+
+/* External clock related definitions */
+
+#define EXT_CLK_MIO_DATA(mio) \
+ [EXT_CLK_INDEX(EXT_CLK_MIO##mio)] = { \
+ .name = "mio_clk_"#mio, \
+ }
+
+#define EXT_CLK_INDEX(n) (n - CLK_MAX_OUTPUT_CLK)
+
+/* Clock control related definitions */
+#define BIT_MASK(x, y) (((1U << (y)) - 1) << (x))
+
+#define ISPLL(id) (id == CLK_APLL_INT || \
+ id == CLK_DPLL_INT || \
+ id == CLK_VPLL_INT || \
+ id == CLK_IOPLL_INT || \
+ id == CLK_RPLL_INT)
+
+
+#define PLLCTRL_BP_MASK BIT(3)
+#define PLLCTRL_RESET_MASK U(1)
+#define PLL_FRAC_OFFSET U(8)
+#define PLL_FRAC_MODE U(1)
+#define PLL_INT_MODE U(0)
+#define PLL_FRAC_MODE_MASK U(0x80000000)
+#define PLL_FRAC_MODE_SHIFT U(31)
+#define PLL_FRAC_DATA_MASK U(0xFFFF)
+#define PLL_FRAC_DATA_SHIFT U(0)
+#define PLL_FBDIV_MASK U(0x7F00)
+#define PLL_FBDIV_WIDTH U(7)
+#define PLL_FBDIV_SHIFT U(8)
+
+#define CLK_PLL_RESET_ASSERT U(1)
+#define CLK_PLL_RESET_RELEASE U(2)
+#define CLK_PLL_RESET_PULSE (CLK_PLL_RESET_ASSERT | CLK_PLL_RESET_RELEASE)
+
+/* Common topology definitions */
+#define GENERIC_MUX \
+ { \
+ .type = TYPE_MUX, \
+ .offset = PERIPH_MUX_SHIFT, \
+ .width = PERIPH_MUX_WIDTH, \
+ .clkflags = CLK_SET_RATE_NO_REPARENT | \
+ CLK_IS_BASIC, \
+ .typeflags = NA_TYPE_FLAGS, \
+ .mult = NA_MULT, \
+ .div = NA_DIV, \
+ }
+
+#define IGNORE_UNUSED_MUX \
+ { \
+ .type = TYPE_MUX, \
+ .offset = PERIPH_MUX_SHIFT, \
+ .width = PERIPH_MUX_WIDTH, \
+ .clkflags = CLK_IGNORE_UNUSED | \
+ CLK_SET_RATE_NO_REPARENT | \
+ CLK_IS_BASIC, \
+ .typeflags = NA_TYPE_FLAGS, \
+ .mult = NA_MULT, \
+ .div = NA_DIV, \
+ }
+
+#define GENERIC_DIV(id) \
+ { \
+ .type = TYPE_DIV##id, \
+ .offset = PERIPH_DIV##id##_SHIFT, \
+ .width = PERIPH_DIV##id##_WIDTH, \
+ .clkflags = CLK_SET_RATE_NO_REPARENT | \
+ CLK_IS_BASIC, \
+ .typeflags = CLK_DIVIDER_ONE_BASED | \
+ CLK_DIVIDER_ALLOW_ZERO, \
+ .mult = NA_MULT, \
+ .div = NA_DIV, \
+ }
+
+#define IGNORE_UNUSED_DIV(id) \
+ { \
+ .type = TYPE_DIV##id, \
+ .offset = PERIPH_DIV##id##_SHIFT, \
+ .width = PERIPH_DIV##id##_WIDTH, \
+ .clkflags = CLK_IGNORE_UNUSED | \
+ CLK_SET_RATE_NO_REPARENT | \
+ CLK_IS_BASIC, \
+ .typeflags = CLK_DIVIDER_ONE_BASED | \
+ CLK_DIVIDER_ALLOW_ZERO, \
+ .mult = NA_MULT, \
+ .div = NA_DIV, \
+ }
+
+#define GENERIC_GATE \
+ { \
+ .type = TYPE_GATE, \
+ .offset = PERIPH_GATE_SHIFT, \
+ .width = PERIPH_GATE_WIDTH, \
+ .clkflags = CLK_SET_RATE_PARENT | \
+ CLK_SET_RATE_GATE | \
+ CLK_IS_BASIC, \
+ .typeflags = NA_TYPE_FLAGS, \
+ .mult = NA_MULT, \
+ .div = NA_DIV, \
+ }
+
+#define IGNORE_UNUSED_GATE \
+ { \
+ .type = TYPE_GATE, \
+ .offset = PERIPH_GATE_SHIFT, \
+ .width = PERIPH_GATE_WIDTH, \
+ .clkflags = CLK_SET_RATE_PARENT | \
+ CLK_IGNORE_UNUSED | \
+ CLK_IS_BASIC, \
+ .typeflags = NA_TYPE_FLAGS, \
+ .mult = NA_MULT, \
+ .div = NA_DIV, \
+ }
+
+/**
+ * struct pm_clock_node - Clock topology node information
+ * @type: Topology type (mux/div1/div2/gate/pll/fixed factor)
+ * @offset: Offset in control register
+ * @width: Width of the specific type in control register
+ * @clkflags: Clk specific flags
+ * @typeflags: Type specific flags
+ * @mult: Multiplier for fixed factor
+ * @div: Divisor for fixed factor
+ */
+struct pm_clock_node {
+ uint16_t clkflags;
+ uint16_t typeflags;
+ uint8_t type;
+ uint8_t offset;
+ uint8_t width;
+ uint8_t mult:4;
+ uint8_t div:4;
+};
+
+/**
+ * struct pm_clock - Clock structure
+ * @name: Clock name
+ * @control_reg: Control register address
+ * @status_reg: Status register address
+ * @parents: Parents for first clock node. Lower byte indicates parent
+ * clock id and upper byte indicate flags for that id.
+ * pm_clock_node: Clock nodes
+ */
+struct pm_clock {
+ char name[CLK_NAME_LEN];
+ uint8_t num_nodes;
+ unsigned int control_reg;
+ unsigned int status_reg;
+ int32_t (*parents)[];
+ struct pm_clock_node(*nodes)[];
+};
+
+/**
+ * struct pm_clock - Clock structure
+ * @name: Clock name
+ */
+struct pm_ext_clock {
+ char name[CLK_NAME_LEN];
+};
+
+/* PLL Clocks */
+static struct pm_clock_node generic_pll_nodes[] = {
+ {
+ .type = TYPE_PLL,
+ .offset = NA_SHIFT,
+ .width = NA_WIDTH,
+ .clkflags = CLK_SET_RATE_NO_REPARENT,
+ .typeflags = NA_TYPE_FLAGS,
+ .mult = NA_MULT,
+ .div = NA_DIV,
+ },
+};
+
+static struct pm_clock_node ignore_unused_pll_nodes[] = {
+ {
+ .type = TYPE_PLL,
+ .offset = NA_SHIFT,
+ .width = NA_WIDTH,
+ .clkflags = CLK_IGNORE_UNUSED | CLK_SET_RATE_NO_REPARENT,
+ .typeflags = NA_TYPE_FLAGS,
+ .mult = NA_MULT,
+ .div = NA_DIV,
+ },
+};
+
+static struct pm_clock_node generic_pll_pre_src_nodes[] = {
+ {
+ .type = TYPE_MUX,
+ .offset = PLL_PRESRC_MUX_SHIFT,
+ .width = PLL_PRESRC_MUX_WIDTH,
+ .clkflags = CLK_IS_BASIC,
+ .typeflags = NA_TYPE_FLAGS,
+ .mult = NA_MULT,
+ .div = NA_DIV,
+ },
+};
+
+static struct pm_clock_node generic_pll_half_nodes[] = {
+ {
+ .type = TYPE_FIXEDFACTOR,
+ .offset = NA_SHIFT,
+ .width = NA_WIDTH,
+ .clkflags = CLK_SET_RATE_NO_REPARENT | CLK_SET_RATE_PARENT,
+ .typeflags = NA_TYPE_FLAGS,
+ .mult = 1,
+ .div = 2,
+ },
+};
+
+static struct pm_clock_node generic_pll_int_nodes[] = {
+ {
+ .type = TYPE_MUX,
+ .offset = PLL_DIV2_MUX_SHIFT,
+ .width = PLL_DIV2_MUX_WIDTH,
+ .clkflags = CLK_SET_RATE_NO_REPARENT |
+ CLK_SET_RATE_PARENT |
+ CLK_IS_BASIC,
+ .typeflags = NA_TYPE_FLAGS,
+ .mult = NA_MULT,
+ .div = NA_DIV,
+ },
+};
+
+static struct pm_clock_node generic_pll_post_src_nodes[] = {
+ {
+ .type = TYPE_MUX,
+ .offset = PLL_POSTSRC_MUX_SHIFT,
+ .width = PLL_POSTSRC_MUX_WIDTH,
+ .clkflags = CLK_IS_BASIC,
+ .typeflags = NA_TYPE_FLAGS,
+ .mult = NA_MULT,
+ .div = NA_DIV,
+ },
+};
+
+static struct pm_clock_node generic_pll_system_nodes[] = {
+ {
+ .type = TYPE_MUX,
+ .offset = PLL_BYPASS_MUX_SHIFT,
+ .width = PLL_BYPASS_MUX_WIDTH,
+ .clkflags = CLK_SET_RATE_NO_REPARENT |
+ CLK_SET_RATE_PARENT |
+ CLK_IS_BASIC,
+ .typeflags = NA_TYPE_FLAGS,
+ .mult = NA_MULT,
+ .div = NA_DIV,
+ },
+};
+
+static struct pm_clock_node acpu_nodes[] = {
+ {
+ .type = TYPE_MUX,
+ .offset = PERIPH_MUX_SHIFT,
+ .width = PERIPH_MUX_WIDTH,
+ .clkflags = CLK_SET_RATE_NO_REPARENT | CLK_IS_BASIC,
+ .typeflags = NA_TYPE_FLAGS,
+ .mult = NA_MULT,
+ .div = NA_DIV,
+ },
+ {
+ .type = TYPE_DIV1,
+ .offset = PERIPH_DIV1_SHIFT,
+ .width = PERIPH_DIV1_WIDTH,
+ .clkflags = CLK_IS_BASIC,
+ .typeflags = CLK_DIVIDER_ONE_BASED | CLK_DIVIDER_ALLOW_ZERO,
+ .mult = NA_MULT,
+ .div = NA_DIV,
+ },
+ {
+ .type = TYPE_GATE,
+ .offset = PERIPH_GATE_SHIFT,
+ .width = PERIPH_GATE_WIDTH,
+ .clkflags = CLK_SET_RATE_PARENT |
+ CLK_IGNORE_UNUSED |
+ CLK_IS_BASIC,
+ .typeflags = NA_TYPE_FLAGS,
+ .mult = NA_MULT,
+ .div = NA_DIV,
+ },
+};
+
+static struct pm_clock_node generic_mux_div_nodes[] = {
+ GENERIC_MUX,
+ GENERIC_DIV(1),
+};
+
+static struct pm_clock_node generic_mux_div_gate_nodes[] = {
+ GENERIC_MUX,
+ GENERIC_DIV(1),
+ GENERIC_GATE,
+};
+
+static struct pm_clock_node generic_mux_div_unused_gate_nodes[] = {
+ GENERIC_MUX,
+ GENERIC_DIV(1),
+ IGNORE_UNUSED_GATE,
+};
+
+static struct pm_clock_node generic_mux_div_div_gate_nodes[] = {
+ GENERIC_MUX,
+ GENERIC_DIV(1),
+ GENERIC_DIV(2),
+ GENERIC_GATE,
+};
+
+static struct pm_clock_node dp_audio_video_ref_nodes[] = {
+ {
+ .type = TYPE_MUX,
+ .offset = PERIPH_MUX_SHIFT,
+ .width = PERIPH_MUX_WIDTH,
+ .clkflags = CLK_SET_RATE_NO_REPARENT |
+ CLK_SET_RATE_PARENT |
+ CLK_FRAC | CLK_IS_BASIC,
+ .typeflags = NA_TYPE_FLAGS,
+ .mult = NA_MULT,
+ .div = NA_DIV,
+ },
+ {
+ .type = TYPE_DIV1,
+ .offset = PERIPH_DIV1_SHIFT,
+ .width = PERIPH_DIV1_WIDTH,
+ .clkflags = CLK_SET_RATE_NO_REPARENT | CLK_SET_RATE_PARENT |
+ CLK_FRAC | CLK_IS_BASIC,
+ .typeflags = CLK_DIVIDER_ONE_BASED | CLK_DIVIDER_ALLOW_ZERO,
+ .mult = NA_MULT,
+ .div = NA_DIV,
+ },
+ {
+ .type = TYPE_DIV2,
+ .offset = PERIPH_DIV2_SHIFT,
+ .width = PERIPH_DIV2_WIDTH,
+ .clkflags = CLK_SET_RATE_NO_REPARENT | CLK_SET_RATE_PARENT |
+ CLK_FRAC | CLK_IS_BASIC,
+ .typeflags = CLK_DIVIDER_ONE_BASED | CLK_DIVIDER_ALLOW_ZERO,
+ .mult = NA_MULT,
+ .div = NA_DIV,
+ },
+ {
+ .type = TYPE_GATE,
+ .offset = PERIPH_GATE_SHIFT,
+ .width = PERIPH_GATE_WIDTH,
+ .clkflags = CLK_SET_RATE_PARENT |
+ CLK_SET_RATE_GATE |
+ CLK_IS_BASIC,
+ .typeflags = NA_TYPE_FLAGS,
+ .mult = NA_MULT,
+ .div = NA_DIV,
+ },
+};
+
+static struct pm_clock_node usb_nodes[] = {
+ GENERIC_MUX,
+ GENERIC_DIV(1),
+ GENERIC_DIV(2),
+ {
+ .type = TYPE_GATE,
+ .offset = USB_GATE_SHIFT,
+ .width = PERIPH_GATE_WIDTH,
+ .clkflags = CLK_SET_RATE_PARENT | CLK_IS_BASIC |
+ CLK_SET_RATE_GATE,
+ .typeflags = NA_TYPE_FLAGS,
+ .mult = NA_MULT,
+ .div = NA_DIV,
+ },
+};
+
+static struct pm_clock_node generic_domain_crossing_nodes[] = {
+ {
+ .type = TYPE_DIV1,
+ .offset = 8,
+ .width = 6,
+ .clkflags = CLK_IS_BASIC,
+ .typeflags = CLK_DIVIDER_ONE_BASED | CLK_DIVIDER_ALLOW_ZERO,
+ .mult = NA_MULT,
+ .div = NA_DIV,
+ },
+};
+
+static struct pm_clock_node rpll_to_fpd_nodes[] = {
+ {
+ .type = TYPE_DIV1,
+ .offset = 8,
+ .width = 6,
+ .clkflags = CLK_SET_RATE_PARENT | CLK_IS_BASIC,
+ .typeflags = CLK_DIVIDER_ONE_BASED | CLK_DIVIDER_ALLOW_ZERO,
+ .mult = NA_MULT,
+ .div = NA_DIV,
+ },
+};
+
+static struct pm_clock_node acpu_half_nodes[] = {
+ {
+ .type = TYPE_FIXEDFACTOR,
+ .offset = 0,
+ .width = 1,
+ .clkflags = 0,
+ .typeflags = 0,
+ .mult = 1,
+ .div = 2,
+ },
+ {
+ .type = TYPE_GATE,
+ .offset = 25,
+ .width = PERIPH_GATE_WIDTH,
+ .clkflags = CLK_IGNORE_UNUSED |
+ CLK_SET_RATE_PARENT |
+ CLK_IS_BASIC,
+ .typeflags = NA_TYPE_FLAGS,
+ .mult = NA_MULT,
+ .div = NA_DIV,
+ },
+};
+
+static struct pm_clock_node wdt_nodes[] = {
+ {
+ .type = TYPE_MUX,
+ .offset = 0,
+ .width = 1,
+ .clkflags = CLK_SET_RATE_PARENT |
+ CLK_SET_RATE_NO_REPARENT |
+ CLK_IS_BASIC,
+ .typeflags = NA_TYPE_FLAGS,
+ .mult = NA_MULT,
+ .div = NA_DIV,
+ },
+};
+
+static struct pm_clock_node ddr_nodes[] = {
+ GENERIC_MUX,
+ {
+ .type = TYPE_DIV1,
+ .offset = 8,
+ .width = 6,
+ .clkflags = CLK_IS_BASIC,
+ .typeflags = CLK_DIVIDER_ONE_BASED | CLK_DIVIDER_ALLOW_ZERO,
+ .mult = NA_MULT,
+ .div = NA_DIV,
+ },
+};
+
+static struct pm_clock_node pl_nodes[] = {
+ GENERIC_MUX,
+ {
+ .type = TYPE_DIV1,
+ .offset = PERIPH_DIV1_SHIFT,
+ .width = PERIPH_DIV1_WIDTH,
+ .clkflags = CLK_IS_BASIC,
+ .typeflags = CLK_DIVIDER_ONE_BASED | CLK_DIVIDER_ALLOW_ZERO,
+ .mult = NA_MULT,
+ .div = NA_DIV,
+ },
+ {
+ .type = TYPE_DIV2,
+ .offset = PERIPH_DIV2_SHIFT,
+ .width = PERIPH_DIV2_WIDTH,
+ .clkflags = CLK_IS_BASIC | CLK_SET_RATE_PARENT,
+ .typeflags = CLK_DIVIDER_ONE_BASED | CLK_DIVIDER_ALLOW_ZERO,
+ .mult = NA_MULT,
+ .div = NA_DIV,
+ },
+ {
+ .type = TYPE_GATE,
+ .offset = PERIPH_GATE_SHIFT,
+ .width = PERIPH_GATE_WIDTH,
+ .clkflags = CLK_SET_RATE_PARENT | CLK_IS_BASIC,
+ .typeflags = NA_TYPE_FLAGS,
+ .mult = NA_MULT,
+ .div = NA_DIV,
+ },
+};
+
+static struct pm_clock_node gpu_pp0_nodes[] = {
+ {
+ .type = TYPE_GATE,
+ .offset = 25,
+ .width = PERIPH_GATE_WIDTH,
+ .clkflags = CLK_SET_RATE_PARENT | CLK_IS_BASIC,
+ .typeflags = NA_TYPE_FLAGS,
+ .mult = NA_MULT,
+ .div = NA_DIV,
+ },
+};
+
+static struct pm_clock_node gpu_pp1_nodes[] = {
+ {
+ .type = TYPE_GATE,
+ .offset = 26,
+ .width = PERIPH_GATE_WIDTH,
+ .clkflags = CLK_SET_RATE_PARENT | CLK_IS_BASIC,
+ .typeflags = NA_TYPE_FLAGS,
+ .mult = NA_MULT,
+ .div = NA_DIV,
+ },
+};
+
+static struct pm_clock_node gem_nodes[] = {
+ GENERIC_MUX,
+ {
+ .type = TYPE_DIV1,
+ .offset = 8,
+ .width = 6,
+ .clkflags = CLK_IS_BASIC,
+ .typeflags = CLK_DIVIDER_ONE_BASED | CLK_DIVIDER_ALLOW_ZERO,
+ .mult = NA_MULT,
+ .div = NA_DIV,
+ },
+ {
+ .type = TYPE_DIV2,
+ .offset = 16,
+ .width = 6,
+ .clkflags = CLK_IS_BASIC,
+ .typeflags = CLK_DIVIDER_ONE_BASED | CLK_DIVIDER_ALLOW_ZERO,
+ .mult = NA_MULT,
+ .div = NA_DIV,
+ },
+ {
+ .type = TYPE_GATE,
+ .offset = 25,
+ .width = PERIPH_GATE_WIDTH,
+ .clkflags = CLK_SET_RATE_PARENT | CLK_IS_BASIC,
+ .typeflags = NA_TYPE_FLAGS,
+ .mult = NA_MULT,
+ .div = NA_DIV,
+ },
+};
+
+static struct pm_clock_node gem0_tx_nodes[] = {
+ {
+ .type = TYPE_MUX,
+ .offset = 1,
+ .width = 1,
+ .clkflags = CLK_SET_RATE_NO_REPARENT | CLK_IS_BASIC,
+ .typeflags = NA_TYPE_FLAGS,
+ .mult = NA_MULT,
+ .div = NA_DIV,
+ },
+ {
+ .type = TYPE_GATE,
+ .offset = 26,
+ .width = PERIPH_GATE_WIDTH,
+ .clkflags = CLK_SET_RATE_PARENT | CLK_IS_BASIC,
+ .typeflags = NA_TYPE_FLAGS,
+ .mult = NA_MULT,
+ .div = NA_DIV,
+ },
+};
+
+static struct pm_clock_node gem1_tx_nodes[] = {
+ {
+ .type = TYPE_MUX,
+ .offset = 6,
+ .width = 1,
+ .clkflags = CLK_SET_RATE_NO_REPARENT | CLK_IS_BASIC,
+ .typeflags = NA_TYPE_FLAGS,
+ .mult = NA_MULT,
+ .div = NA_DIV,
+ },
+ {
+ .type = TYPE_GATE,
+ .offset = 26,
+ .width = PERIPH_GATE_WIDTH,
+ .clkflags = CLK_SET_RATE_PARENT | CLK_IS_BASIC,
+ .typeflags = NA_TYPE_FLAGS,
+ .mult = NA_MULT,
+ .div = NA_DIV,
+ },
+};
+
+static struct pm_clock_node gem2_tx_nodes[] = {
+ {
+ .type = TYPE_MUX,
+ .offset = 11,
+ .width = 1,
+ .clkflags = CLK_SET_RATE_NO_REPARENT | CLK_IS_BASIC,
+ .typeflags = NA_TYPE_FLAGS,
+ .mult = NA_MULT,
+ .div = NA_DIV,
+ },
+ {
+ .type = TYPE_GATE,
+ .offset = 26,
+ .width = PERIPH_GATE_WIDTH,
+ .clkflags = CLK_SET_RATE_PARENT | CLK_IS_BASIC,
+ .typeflags = NA_TYPE_FLAGS,
+ .mult = NA_MULT,
+ .div = NA_DIV,
+ },
+};
+
+static struct pm_clock_node gem3_tx_nodes[] = {
+ {
+ .type = TYPE_MUX,
+ .offset = 16,
+ .width = 1,
+ .clkflags = CLK_SET_RATE_NO_REPARENT | CLK_IS_BASIC,
+ .typeflags = NA_TYPE_FLAGS,
+ .mult = NA_MULT,
+ .div = NA_DIV,
+ },
+ {
+ .type = TYPE_GATE,
+ .offset = 26,
+ .width = PERIPH_GATE_WIDTH,
+ .clkflags = CLK_SET_RATE_PARENT | CLK_IS_BASIC,
+ .typeflags = NA_TYPE_FLAGS,
+ .mult = NA_MULT,
+ .div = NA_DIV,
+ },
+};
+
+static struct pm_clock_node gem_tsu_nodes[] = {
+ {
+ .type = TYPE_MUX,
+ .offset = 20,
+ .width = 2,
+ .clkflags = CLK_SET_RATE_PARENT |
+ CLK_SET_RATE_NO_REPARENT |
+ CLK_IS_BASIC,
+ .typeflags = NA_TYPE_FLAGS,
+ .mult = NA_MULT,
+ .div = NA_DIV,
+ },
+};
+
+static struct pm_clock_node can0_mio_nodes[] = {
+ {
+ .type = TYPE_MUX,
+ .offset = 0,
+ .width = 7,
+ .clkflags = CLK_SET_RATE_PARENT |
+ CLK_SET_RATE_NO_REPARENT |
+ CLK_IS_BASIC,
+ .typeflags = NA_TYPE_FLAGS,
+ .mult = NA_MULT,
+ .div = NA_DIV,
+ },
+};
+
+static struct pm_clock_node can1_mio_nodes[] = {
+ {
+ .type = TYPE_MUX,
+ .offset = 15,
+ .width = 1,
+ .clkflags = CLK_SET_RATE_PARENT |
+ CLK_SET_RATE_NO_REPARENT |
+ CLK_IS_BASIC,
+ .typeflags = NA_TYPE_FLAGS,
+ .mult = NA_MULT,
+ .div = NA_DIV,
+ },
+};
+
+static struct pm_clock_node can0_nodes[] = {
+ {
+ .type = TYPE_MUX,
+ .offset = 7,
+ .width = 1,
+ .clkflags = CLK_SET_RATE_PARENT |
+ CLK_SET_RATE_NO_REPARENT |
+ CLK_IS_BASIC,
+ .typeflags = NA_TYPE_FLAGS,
+ .mult = NA_MULT,
+ .div = NA_DIV,
+ },
+};
+
+static struct pm_clock_node can1_nodes[] = {
+ {
+ .type = TYPE_MUX,
+ .offset = 22,
+ .width = 1,
+ .clkflags = CLK_SET_RATE_PARENT |
+ CLK_SET_RATE_NO_REPARENT |
+ CLK_IS_BASIC,
+ .typeflags = NA_TYPE_FLAGS,
+ .mult = NA_MULT,
+ .div = NA_DIV,
+ },
+};
+
+static struct pm_clock_node cpu_r5_core_nodes[] = {
+ {
+ .type = TYPE_GATE,
+ .offset = 25,
+ .width = PERIPH_GATE_WIDTH,
+ .clkflags = CLK_IGNORE_UNUSED |
+ CLK_IS_BASIC,
+ .typeflags = NA_TYPE_FLAGS,
+ .mult = NA_MULT,
+ .div = NA_DIV,
+ },
+};
+
+static struct pm_clock_node dll_ref_nodes[] = {
+ {
+ .type = TYPE_MUX,
+ .offset = 0,
+ .width = 3,
+ .clkflags = CLK_SET_RATE_PARENT |
+ CLK_SET_RATE_NO_REPARENT |
+ CLK_IS_BASIC,
+ .typeflags = NA_TYPE_FLAGS,
+ .mult = NA_MULT,
+ .div = NA_DIV,
+ },
+};
+
+static struct pm_clock_node timestamp_ref_nodes[] = {
+ GENERIC_MUX,
+ {
+ .type = TYPE_DIV1,
+ .offset = 8,
+ .width = 6,
+ .clkflags = CLK_IS_BASIC,
+ .typeflags = CLK_DIVIDER_ONE_BASED | CLK_DIVIDER_ALLOW_ZERO,
+ .mult = NA_MULT,
+ .div = NA_DIV,
+ },
+ IGNORE_UNUSED_GATE,
+};
+
+static int32_t can_mio_parents[] = {
+ EXT_CLK_MIO0, EXT_CLK_MIO1, EXT_CLK_MIO2, EXT_CLK_MIO3,
+ EXT_CLK_MIO4, EXT_CLK_MIO5, EXT_CLK_MIO6, EXT_CLK_MIO7,
+ EXT_CLK_MIO8, EXT_CLK_MIO9, EXT_CLK_MIO10, EXT_CLK_MIO11,
+ EXT_CLK_MIO12, EXT_CLK_MIO13, EXT_CLK_MIO14, EXT_CLK_MIO15,
+ EXT_CLK_MIO16, EXT_CLK_MIO17, EXT_CLK_MIO18, EXT_CLK_MIO19,
+ EXT_CLK_MIO20, EXT_CLK_MIO21, EXT_CLK_MIO22, EXT_CLK_MIO23,
+ EXT_CLK_MIO24, EXT_CLK_MIO25, EXT_CLK_MIO26, EXT_CLK_MIO27,
+ EXT_CLK_MIO28, EXT_CLK_MIO29, EXT_CLK_MIO30, EXT_CLK_MIO31,
+ EXT_CLK_MIO32, EXT_CLK_MIO33, EXT_CLK_MIO34, EXT_CLK_MIO35,
+ EXT_CLK_MIO36, EXT_CLK_MIO37, EXT_CLK_MIO38, EXT_CLK_MIO39,
+ EXT_CLK_MIO40, EXT_CLK_MIO41, EXT_CLK_MIO42, EXT_CLK_MIO43,
+ EXT_CLK_MIO44, EXT_CLK_MIO45, EXT_CLK_MIO46, EXT_CLK_MIO47,
+ EXT_CLK_MIO48, EXT_CLK_MIO49, EXT_CLK_MIO50, EXT_CLK_MIO51,
+ EXT_CLK_MIO52, EXT_CLK_MIO53, EXT_CLK_MIO54, EXT_CLK_MIO55,
+ EXT_CLK_MIO56, EXT_CLK_MIO57, EXT_CLK_MIO58, EXT_CLK_MIO59,
+ EXT_CLK_MIO60, EXT_CLK_MIO61, EXT_CLK_MIO62, EXT_CLK_MIO63,
+ EXT_CLK_MIO64, EXT_CLK_MIO65, EXT_CLK_MIO66, EXT_CLK_MIO67,
+ EXT_CLK_MIO68, EXT_CLK_MIO69, EXT_CLK_MIO70, EXT_CLK_MIO71,
+ EXT_CLK_MIO72, EXT_CLK_MIO73, EXT_CLK_MIO74, EXT_CLK_MIO75,
+ EXT_CLK_MIO76, EXT_CLK_MIO77, CLK_NA_PARENT
+};
+
+/* Clock array containing clock informaton */
+static struct pm_clock clocks[] = {
+ [CLK_APLL_INT] = {
+ .name = "apll_int",
+ .control_reg = CRF_APB_APLL_CTRL,
+ .status_reg = CRF_APB_PLL_STATUS,
+ .parents = &((int32_t []) {CLK_APLL_PRE_SRC, CLK_NA_PARENT}),
+ .nodes = &ignore_unused_pll_nodes,
+ .num_nodes = ARRAY_SIZE(ignore_unused_pll_nodes),
+ },
+ [CLK_APLL_PRE_SRC] = {
+ .name = "apll_pre_src",
+ .control_reg = CRF_APB_APLL_CTRL,
+ .status_reg = CRF_APB_PLL_STATUS,
+ .parents = &((int32_t []) {
+ EXT_CLK_PSS_REF | CLK_EXTERNAL_PARENT,
+ EXT_CLK_PSS_REF | CLK_EXTERNAL_PARENT,
+ EXT_CLK_PSS_REF | CLK_EXTERNAL_PARENT,
+ EXT_CLK_PSS_REF | CLK_EXTERNAL_PARENT,
+ EXT_CLK_VIDEO | CLK_EXTERNAL_PARENT,
+ EXT_CLK_PSS_ALT_REF | CLK_EXTERNAL_PARENT,
+ EXT_CLK_AUX_REF | CLK_EXTERNAL_PARENT,
+ EXT_CLK_GT_CRX_REF | CLK_EXTERNAL_PARENT,
+ CLK_NA_PARENT
+ }),
+ .nodes = &generic_pll_pre_src_nodes,
+ .num_nodes = ARRAY_SIZE(generic_pll_pre_src_nodes),
+ },
+ [CLK_APLL_HALF] = {
+ .name = "apll_half",
+ .control_reg = CRF_APB_APLL_CTRL,
+ .status_reg = CRF_APB_PLL_STATUS,
+ .parents = &((int32_t []) {CLK_APLL_INT, CLK_NA_PARENT}),
+ .nodes = &generic_pll_half_nodes,
+ .num_nodes = ARRAY_SIZE(generic_pll_half_nodes),
+ },
+ [CLK_APLL_INT_MUX] = {
+ .name = "apll_int_mux",
+ .control_reg = CRF_APB_APLL_CTRL,
+ .status_reg = CRF_APB_PLL_STATUS,
+ .parents = &((int32_t []) {
+ CLK_APLL_INT,
+ CLK_APLL_HALF,
+ CLK_NA_PARENT
+ }),
+ .nodes = &generic_pll_int_nodes,
+ .num_nodes = ARRAY_SIZE(generic_pll_int_nodes),
+ },
+ [CLK_APLL_POST_SRC] = {
+ .name = "apll_post_src",
+ .control_reg = CRF_APB_APLL_CTRL,
+ .status_reg = CRF_APB_PLL_STATUS,
+ .parents = &((int32_t []) {
+ EXT_CLK_PSS_REF | CLK_EXTERNAL_PARENT,
+ EXT_CLK_PSS_REF | CLK_EXTERNAL_PARENT,
+ EXT_CLK_PSS_REF | CLK_EXTERNAL_PARENT,
+ EXT_CLK_PSS_REF | CLK_EXTERNAL_PARENT,
+ EXT_CLK_VIDEO | CLK_EXTERNAL_PARENT,
+ EXT_CLK_PSS_ALT_REF | CLK_EXTERNAL_PARENT,
+ EXT_CLK_AUX_REF | CLK_EXTERNAL_PARENT,
+ EXT_CLK_GT_CRX_REF | CLK_EXTERNAL_PARENT,
+ CLK_NA_PARENT
+ }),
+ .nodes = &generic_pll_post_src_nodes,
+ .num_nodes = ARRAY_SIZE(generic_pll_post_src_nodes),
+ },
+ [CLK_APLL] = {
+ .name = "apll",
+ .control_reg = CRF_APB_APLL_CTRL,
+ .status_reg = CRF_APB_PLL_STATUS,
+ .parents = &((int32_t []) {
+ CLK_APLL_INT_MUX,
+ CLK_APLL_POST_SRC,
+ CLK_NA_PARENT
+ }),
+ .nodes = &generic_pll_system_nodes,
+ .num_nodes = ARRAY_SIZE(generic_pll_system_nodes),
+ },
+ [CLK_DPLL_INT] = {
+ .name = "dpll_int",
+ .control_reg = CRF_APB_DPLL_CTRL,
+ .status_reg = CRF_APB_PLL_STATUS,
+ .parents = &((int32_t []) {CLK_DPLL_PRE_SRC, CLK_NA_PARENT}),
+ .nodes = &generic_pll_nodes,
+ .num_nodes = ARRAY_SIZE(generic_pll_nodes),
+ },
+ [CLK_DPLL_PRE_SRC] = {
+ .name = "dpll_pre_src",
+ .control_reg = CRF_APB_DPLL_CTRL,
+ .status_reg = CRF_APB_PLL_STATUS,
+ .parents = &((int32_t []) {
+ EXT_CLK_PSS_REF | CLK_EXTERNAL_PARENT,
+ EXT_CLK_PSS_REF | CLK_EXTERNAL_PARENT,
+ EXT_CLK_PSS_REF | CLK_EXTERNAL_PARENT,
+ EXT_CLK_PSS_REF | CLK_EXTERNAL_PARENT,
+ EXT_CLK_VIDEO | CLK_EXTERNAL_PARENT,
+ EXT_CLK_PSS_ALT_REF | CLK_EXTERNAL_PARENT,
+ EXT_CLK_AUX_REF | CLK_EXTERNAL_PARENT,
+ EXT_CLK_GT_CRX_REF | CLK_EXTERNAL_PARENT,
+ CLK_NA_PARENT
+ }),
+ .nodes = &generic_pll_pre_src_nodes,
+ .num_nodes = ARRAY_SIZE(generic_pll_pre_src_nodes),
+ },
+ [CLK_DPLL_HALF] = {
+ .name = "dpll_half",
+ .control_reg = CRF_APB_DPLL_CTRL,
+ .status_reg = CRF_APB_PLL_STATUS,
+ .parents = &((int32_t []) {CLK_DPLL_INT, CLK_NA_PARENT}),
+ .nodes = &generic_pll_half_nodes,
+ .num_nodes = ARRAY_SIZE(generic_pll_half_nodes),
+ },
+ [CLK_DPLL_INT_MUX] = {
+ .name = "dpll_int_mux",
+ .control_reg = CRF_APB_DPLL_CTRL,
+ .status_reg = CRF_APB_PLL_STATUS,
+ .parents = &((int32_t []) {
+ CLK_DPLL_INT,
+ CLK_DPLL_HALF,
+ CLK_NA_PARENT
+ }),
+ .nodes = &generic_pll_int_nodes,
+ .num_nodes = ARRAY_SIZE(generic_pll_int_nodes),
+ },
+ [CLK_DPLL_POST_SRC] = {
+ .name = "dpll_post_src",
+ .control_reg = CRF_APB_DPLL_CTRL,
+ .status_reg = CRF_APB_PLL_STATUS,
+ .parents = &((int32_t []) {
+ EXT_CLK_PSS_REF | CLK_EXTERNAL_PARENT,
+ EXT_CLK_PSS_REF | CLK_EXTERNAL_PARENT,
+ EXT_CLK_PSS_REF | CLK_EXTERNAL_PARENT,
+ EXT_CLK_PSS_REF | CLK_EXTERNAL_PARENT,
+ EXT_CLK_VIDEO | CLK_EXTERNAL_PARENT,
+ EXT_CLK_PSS_ALT_REF | CLK_EXTERNAL_PARENT,
+ EXT_CLK_AUX_REF | CLK_EXTERNAL_PARENT,
+ EXT_CLK_GT_CRX_REF | CLK_EXTERNAL_PARENT,
+ CLK_NA_PARENT
+ }),
+ .nodes = &generic_pll_post_src_nodes,
+ .num_nodes = ARRAY_SIZE(generic_pll_post_src_nodes),
+ },
+ [CLK_DPLL] = {
+ .name = "dpll",
+ .control_reg = CRF_APB_DPLL_CTRL,
+ .status_reg = CRF_APB_PLL_STATUS,
+ .parents = &((int32_t []) {
+ CLK_DPLL_INT_MUX,
+ CLK_DPLL_POST_SRC,
+ CLK_NA_PARENT
+ }),
+ .nodes = &generic_pll_system_nodes,
+ .num_nodes = ARRAY_SIZE(generic_pll_system_nodes),
+ },
+ [CLK_VPLL_INT] = {
+ .name = "vpll_int",
+ .control_reg = CRF_APB_VPLL_CTRL,
+ .status_reg = CRF_APB_PLL_STATUS,
+ .parents = &((int32_t []) {CLK_VPLL_PRE_SRC, CLK_NA_PARENT}),
+ .nodes = &ignore_unused_pll_nodes,
+ .num_nodes = ARRAY_SIZE(ignore_unused_pll_nodes),
+ },
+ [CLK_VPLL_PRE_SRC] = {
+ .name = "vpll_pre_src",
+ .control_reg = CRF_APB_VPLL_CTRL,
+ .status_reg = CRF_APB_PLL_STATUS,
+ .parents = &((int32_t []) {
+ EXT_CLK_PSS_REF | CLK_EXTERNAL_PARENT,
+ EXT_CLK_PSS_REF | CLK_EXTERNAL_PARENT,
+ EXT_CLK_PSS_REF | CLK_EXTERNAL_PARENT,
+ EXT_CLK_PSS_REF | CLK_EXTERNAL_PARENT,
+ EXT_CLK_VIDEO | CLK_EXTERNAL_PARENT,
+ EXT_CLK_PSS_ALT_REF | CLK_EXTERNAL_PARENT,
+ EXT_CLK_AUX_REF | CLK_EXTERNAL_PARENT,
+ EXT_CLK_GT_CRX_REF | CLK_EXTERNAL_PARENT,
+ CLK_NA_PARENT
+ }),
+ .nodes = &generic_pll_pre_src_nodes,
+ .num_nodes = ARRAY_SIZE(generic_pll_pre_src_nodes),
+ },
+ [CLK_VPLL_HALF] = {
+ .name = "vpll_half",
+ .control_reg = CRF_APB_VPLL_CTRL,
+ .status_reg = CRF_APB_PLL_STATUS,
+ .parents = &((int32_t []) {CLK_VPLL_INT, CLK_NA_PARENT}),
+ .nodes = &generic_pll_half_nodes,
+ .num_nodes = ARRAY_SIZE(generic_pll_half_nodes),
+ },
+ [CLK_VPLL_INT_MUX] = {
+ .name = "vpll_int_mux",
+ .control_reg = CRF_APB_VPLL_CTRL,
+ .status_reg = CRF_APB_PLL_STATUS,
+ .parents = &((int32_t []) {
+ CLK_VPLL_INT,
+ CLK_VPLL_HALF,
+ CLK_NA_PARENT
+ }),
+ .nodes = &generic_pll_int_nodes,
+ .num_nodes = ARRAY_SIZE(generic_pll_int_nodes),
+ },
+ [CLK_VPLL_POST_SRC] = {
+ .name = "vpll_post_src",
+ .control_reg = CRF_APB_VPLL_CTRL,
+ .status_reg = CRF_APB_PLL_STATUS,
+ .parents = &((int32_t []) {
+ EXT_CLK_PSS_REF | CLK_EXTERNAL_PARENT,
+ EXT_CLK_PSS_REF | CLK_EXTERNAL_PARENT,
+ EXT_CLK_PSS_REF | CLK_EXTERNAL_PARENT,
+ EXT_CLK_PSS_REF | CLK_EXTERNAL_PARENT,
+ EXT_CLK_VIDEO | CLK_EXTERNAL_PARENT,
+ EXT_CLK_PSS_ALT_REF | CLK_EXTERNAL_PARENT,
+ EXT_CLK_AUX_REF | CLK_EXTERNAL_PARENT,
+ EXT_CLK_GT_CRX_REF | CLK_EXTERNAL_PARENT,
+ CLK_NA_PARENT
+ }),
+ .nodes = &generic_pll_post_src_nodes,
+ .num_nodes = ARRAY_SIZE(generic_pll_post_src_nodes),
+ },
+ [CLK_VPLL] = {
+ .name = "vpll",
+ .control_reg = CRF_APB_VPLL_CTRL,
+ .status_reg = CRF_APB_PLL_STATUS,
+ .parents = &((int32_t []) {
+ CLK_VPLL_INT_MUX,
+ CLK_VPLL_POST_SRC,
+ CLK_NA_PARENT
+ }),
+ .nodes = &generic_pll_system_nodes,
+ .num_nodes = ARRAY_SIZE(generic_pll_system_nodes),
+ },
+ [CLK_IOPLL_INT] = {
+ .name = "iopll_int",
+ .control_reg = CRL_APB_IOPLL_CTRL,
+ .status_reg = CRF_APB_PLL_STATUS,
+ .parents = &((int32_t []) {CLK_IOPLL_PRE_SRC, CLK_NA_PARENT}),
+ .nodes = &generic_pll_nodes,
+ .num_nodes = ARRAY_SIZE(generic_pll_nodes),
+ },
+ [CLK_IOPLL_PRE_SRC] = {
+ .name = "iopll_pre_src",
+ .control_reg = CRL_APB_IOPLL_CTRL,
+ .status_reg = CRF_APB_PLL_STATUS,
+ .parents = &((int32_t []) {
+ EXT_CLK_PSS_REF | CLK_EXTERNAL_PARENT,
+ EXT_CLK_PSS_REF | CLK_EXTERNAL_PARENT,
+ EXT_CLK_PSS_REF | CLK_EXTERNAL_PARENT,
+ EXT_CLK_PSS_REF | CLK_EXTERNAL_PARENT,
+ EXT_CLK_VIDEO | CLK_EXTERNAL_PARENT,
+ EXT_CLK_PSS_ALT_REF | CLK_EXTERNAL_PARENT,
+ EXT_CLK_AUX_REF | CLK_EXTERNAL_PARENT,
+ EXT_CLK_GT_CRX_REF | CLK_EXTERNAL_PARENT,
+ CLK_NA_PARENT
+ }),
+ .nodes = &generic_pll_pre_src_nodes,
+ .num_nodes = ARRAY_SIZE(generic_pll_pre_src_nodes),
+ },
+ [CLK_IOPLL_HALF] = {
+ .name = "iopll_half",
+ .control_reg = CRL_APB_IOPLL_CTRL,
+ .status_reg = CRF_APB_PLL_STATUS,
+ .parents = &((int32_t []) {CLK_IOPLL_INT, CLK_NA_PARENT}),
+ .nodes = &generic_pll_half_nodes,
+ .num_nodes = ARRAY_SIZE(generic_pll_half_nodes),
+ },
+ [CLK_IOPLL_INT_MUX] = {
+ .name = "iopll_int_mux",
+ .control_reg = CRL_APB_IOPLL_CTRL,
+ .status_reg = CRF_APB_PLL_STATUS,
+ .parents = &((int32_t []) {
+ CLK_IOPLL_INT,
+ CLK_IOPLL_HALF,
+ CLK_NA_PARENT
+ }),
+ .nodes = &generic_pll_int_nodes,
+ .num_nodes = ARRAY_SIZE(generic_pll_int_nodes),
+ },
+ [CLK_IOPLL_POST_SRC] = {
+ .name = "iopll_post_src",
+ .control_reg = CRL_APB_IOPLL_CTRL,
+ .status_reg = CRF_APB_PLL_STATUS,
+ .parents = &((int32_t []) {
+ EXT_CLK_PSS_REF | CLK_EXTERNAL_PARENT,
+ EXT_CLK_PSS_REF | CLK_EXTERNAL_PARENT,
+ EXT_CLK_PSS_REF | CLK_EXTERNAL_PARENT,
+ EXT_CLK_PSS_REF | CLK_EXTERNAL_PARENT,
+ EXT_CLK_VIDEO | CLK_EXTERNAL_PARENT,
+ EXT_CLK_PSS_ALT_REF | CLK_EXTERNAL_PARENT,
+ EXT_CLK_AUX_REF | CLK_EXTERNAL_PARENT,
+ EXT_CLK_GT_CRX_REF | CLK_EXTERNAL_PARENT,
+ CLK_NA_PARENT
+ }),
+ .nodes = &generic_pll_post_src_nodes,
+ .num_nodes = ARRAY_SIZE(generic_pll_post_src_nodes),
+ },
+ [CLK_IOPLL] = {
+ .name = "iopll",
+ .control_reg = CRL_APB_IOPLL_CTRL,
+ .status_reg = CRF_APB_PLL_STATUS,
+ .parents = &((int32_t []) {
+ CLK_IOPLL_INT_MUX,
+ CLK_IOPLL_POST_SRC,
+ CLK_NA_PARENT
+ }),
+ .nodes = &generic_pll_system_nodes,
+ .num_nodes = ARRAY_SIZE(generic_pll_system_nodes),
+ },
+ [CLK_RPLL_INT] = {
+ .name = "rpll_int",
+ .control_reg = CRL_APB_RPLL_CTRL,
+ .status_reg = CRF_APB_PLL_STATUS,
+ .parents = &((int32_t []) {CLK_RPLL_PRE_SRC, CLK_NA_PARENT}),
+ .nodes = &generic_pll_nodes,
+ .num_nodes = ARRAY_SIZE(generic_pll_nodes),
+ },
+ [CLK_RPLL_PRE_SRC] = {
+ .name = "rpll_pre_src",
+ .control_reg = CRL_APB_RPLL_CTRL,
+ .status_reg = CRF_APB_PLL_STATUS,
+ .parents = &((int32_t []) {
+ EXT_CLK_PSS_REF | CLK_EXTERNAL_PARENT,
+ EXT_CLK_PSS_REF | CLK_EXTERNAL_PARENT,
+ EXT_CLK_PSS_REF | CLK_EXTERNAL_PARENT,
+ EXT_CLK_PSS_REF | CLK_EXTERNAL_PARENT,
+ EXT_CLK_VIDEO | CLK_EXTERNAL_PARENT,
+ EXT_CLK_PSS_ALT_REF | CLK_EXTERNAL_PARENT,
+ EXT_CLK_AUX_REF | CLK_EXTERNAL_PARENT,
+ EXT_CLK_GT_CRX_REF | CLK_EXTERNAL_PARENT,
+ CLK_NA_PARENT
+ }),
+
+ .nodes = &generic_pll_pre_src_nodes,
+ .num_nodes = ARRAY_SIZE(generic_pll_pre_src_nodes),
+ },
+ [CLK_RPLL_HALF] = {
+ .name = "rpll_half",
+ .control_reg = CRL_APB_RPLL_CTRL,
+ .status_reg = CRF_APB_PLL_STATUS,
+ .parents = &((int32_t []) {CLK_RPLL_INT, CLK_NA_PARENT}),
+ .nodes = &generic_pll_half_nodes,
+ .num_nodes = ARRAY_SIZE(generic_pll_half_nodes),
+ },
+ [CLK_RPLL_INT_MUX] = {
+ .name = "rpll_int_mux",
+ .control_reg = CRL_APB_RPLL_CTRL,
+ .status_reg = CRF_APB_PLL_STATUS,
+ .parents = &((int32_t []) {
+ CLK_RPLL_INT,
+ CLK_RPLL_HALF,
+ CLK_NA_PARENT
+ }),
+ .nodes = &generic_pll_int_nodes,
+ .num_nodes = ARRAY_SIZE(generic_pll_int_nodes),
+ },
+ [CLK_RPLL_POST_SRC] = {
+ .name = "rpll_post_src",
+ .control_reg = CRL_APB_RPLL_CTRL,
+ .status_reg = CRF_APB_PLL_STATUS,
+ .parents = &((int32_t []) {
+ EXT_CLK_PSS_REF | CLK_EXTERNAL_PARENT,
+ EXT_CLK_PSS_REF | CLK_EXTERNAL_PARENT,
+ EXT_CLK_PSS_REF | CLK_EXTERNAL_PARENT,
+ EXT_CLK_PSS_REF | CLK_EXTERNAL_PARENT,
+ EXT_CLK_VIDEO | CLK_EXTERNAL_PARENT,
+ EXT_CLK_PSS_ALT_REF | CLK_EXTERNAL_PARENT,
+ EXT_CLK_AUX_REF | CLK_EXTERNAL_PARENT,
+ EXT_CLK_GT_CRX_REF | CLK_EXTERNAL_PARENT,
+ CLK_NA_PARENT
+ }),
+ .nodes = &generic_pll_post_src_nodes,
+ .num_nodes = ARRAY_SIZE(generic_pll_post_src_nodes),
+ },
+ [CLK_RPLL] = {
+ .name = "rpll",
+ .control_reg = CRL_APB_RPLL_CTRL,
+ .status_reg = CRL_APB_PLL_STATUS,
+ .parents = &((int32_t []) {
+ CLK_RPLL_INT_MUX,
+ CLK_RPLL_POST_SRC,
+ CLK_NA_PARENT
+ }),
+ .nodes = &generic_pll_system_nodes,
+ .num_nodes = ARRAY_SIZE(generic_pll_system_nodes),
+ },
+ /* Peripheral Clocks */
+ [CLK_ACPU] = {
+ .name = "acpu",
+ .control_reg = CRF_APB_ACPU_CTRL,
+ .status_reg = 0,
+ .parents = &((int32_t []) {
+ CLK_APLL,
+ CLK_DUMMY_PARENT,
+ CLK_DPLL,
+ CLK_VPLL,
+ CLK_NA_PARENT
+ }),
+ .nodes = &acpu_nodes,
+ .num_nodes = ARRAY_SIZE(acpu_nodes),
+ },
+ [CLK_DBG_TRACE] = {
+ .name = "dbg_trace",
+ .control_reg = CRF_APB_DBG_TRACE_CTRL,
+ .status_reg = 0,
+ .parents = &((int32_t []) {
+ CLK_IOPLL_TO_FPD,
+ CLK_DUMMY_PARENT,
+ CLK_DPLL,
+ CLK_APLL,
+ CLK_NA_PARENT
+ }),
+ .nodes = &generic_mux_div_gate_nodes,
+ .num_nodes = ARRAY_SIZE(generic_mux_div_gate_nodes),
+ },
+ [CLK_DBG_FPD] = {
+ .name = "dbg_fpd",
+ .control_reg = CRF_APB_DBG_FPD_CTRL,
+ .status_reg = 0,
+ .parents = &((int32_t []) {
+ CLK_IOPLL_TO_FPD,
+ CLK_DUMMY_PARENT,
+ CLK_DPLL,
+ CLK_APLL,
+ CLK_NA_PARENT
+ }),
+ .nodes = &generic_mux_div_gate_nodes,
+ .num_nodes = ARRAY_SIZE(generic_mux_div_gate_nodes),
+ },
+ [CLK_DBG_TSTMP] = {
+ .name = "dbg_tstmp",
+ .control_reg = CRF_APB_DBG_TSTMP_CTRL,
+ .status_reg = 0,
+ .parents = &((int32_t []) {
+ CLK_IOPLL_TO_FPD,
+ CLK_DUMMY_PARENT,
+ CLK_DPLL,
+ CLK_APLL,
+ CLK_NA_PARENT
+ }),
+ .nodes = &generic_mux_div_nodes,
+ .num_nodes = ARRAY_SIZE(generic_mux_div_nodes),
+ },
+ [CLK_DP_VIDEO_REF] = {
+ .name = "dp_video_ref",
+ .control_reg = CRF_APB_DP_VIDEO_REF_CTRL,
+ .status_reg = 0,
+ .parents = &((int32_t []) {
+ CLK_VPLL,
+ CLK_DUMMY_PARENT,
+ CLK_DPLL,
+ CLK_RPLL_TO_FPD,
+ CLK_NA_PARENT
+ }),
+ .nodes = &dp_audio_video_ref_nodes,
+ .num_nodes = ARRAY_SIZE(dp_audio_video_ref_nodes),
+ },
+ [CLK_DP_AUDIO_REF] = {
+ .name = "dp_audio_ref",
+ .control_reg = CRF_APB_DP_AUDIO_REF_CTRL,
+ .status_reg = 0,
+ .parents = &((int32_t []) {
+ CLK_VPLL,
+ CLK_DUMMY_PARENT,
+ CLK_DPLL,
+ CLK_RPLL_TO_FPD,
+ CLK_NA_PARENT
+ }),
+ .nodes = &dp_audio_video_ref_nodes,
+ .num_nodes = ARRAY_SIZE(dp_audio_video_ref_nodes),
+ },
+ [CLK_DP_STC_REF] = {
+ .name = "dp_stc_ref",
+ .control_reg = CRF_APB_DP_STC_REF_CTRL,
+ .status_reg = 0,
+ .parents = &((int32_t []) {
+ CLK_VPLL,
+ CLK_DUMMY_PARENT,
+ CLK_DPLL,
+ CLK_RPLL_TO_FPD,
+ CLK_NA_PARENT
+ }),
+ .nodes = &generic_mux_div_div_gate_nodes,
+ .num_nodes = ARRAY_SIZE(generic_mux_div_div_gate_nodes),
+ },
+ [CLK_DPDMA_REF] = {
+ .name = "dpdma_ref",
+ .control_reg = CRF_APB_DPDMA_REF_CTRL,
+ .status_reg = 0,
+ .parents = &((int32_t []) {
+ CLK_APLL,
+ CLK_DUMMY_PARENT,
+ CLK_VPLL,
+ CLK_DPLL,
+ CLK_NA_PARENT
+ }),
+ .nodes = &generic_mux_div_gate_nodes,
+ .num_nodes = ARRAY_SIZE(generic_mux_div_gate_nodes),
+ },
+ [CLK_DDR_REF] = {
+ .name = "ddr_ref",
+ .control_reg = CRF_APB_DDR_CTRL,
+ .status_reg = 0,
+ .parents = &((int32_t []) {
+ CLK_DPLL,
+ CLK_VPLL,
+ CLK_NA_PARENT
+ }),
+ .nodes = &ddr_nodes,
+ .num_nodes = ARRAY_SIZE(ddr_nodes),
+ },
+ [CLK_GPU_REF] = {
+ .name = "gpu_ref",
+ .control_reg = CRF_APB_GPU_REF_CTRL,
+ .status_reg = 0,
+ .parents = &((int32_t []) {
+ CLK_IOPLL_TO_FPD,
+ CLK_DUMMY_PARENT,
+ CLK_VPLL,
+ CLK_DPLL,
+ CLK_NA_PARENT
+ }),
+ .nodes = &generic_mux_div_gate_nodes,
+ .num_nodes = ARRAY_SIZE(generic_mux_div_gate_nodes),
+ },
+ [CLK_SATA_REF] = {
+ .name = "sata_ref",
+ .control_reg = CRF_APB_SATA_REF_CTRL,
+ .status_reg = 0,
+ .parents = &((int32_t []) {
+ CLK_IOPLL_TO_FPD,
+ CLK_DUMMY_PARENT,
+ CLK_APLL,
+ CLK_DPLL,
+ CLK_NA_PARENT
+ }),
+ .nodes = &generic_mux_div_gate_nodes,
+ .num_nodes = ARRAY_SIZE(generic_mux_div_gate_nodes),
+ },
+ [CLK_PCIE_REF] = {
+ .name = "pcie_ref",
+ .control_reg = CRF_APB_PCIE_REF_CTRL,
+ .status_reg = 0,
+ .parents = &((int32_t []) {
+ CLK_IOPLL_TO_FPD,
+ CLK_DUMMY_PARENT,
+ CLK_RPLL_TO_FPD,
+ CLK_DPLL,
+ CLK_NA_PARENT
+ }),
+ .nodes = &generic_mux_div_gate_nodes,
+ .num_nodes = ARRAY_SIZE(generic_mux_div_gate_nodes),
+ },
+ [CLK_GDMA_REF] = {
+ .name = "gdma_ref",
+ .control_reg = CRF_APB_GDMA_REF_CTRL,
+ .status_reg = 0,
+ .parents = &((int32_t []) {
+ CLK_APLL,
+ CLK_DUMMY_PARENT,
+ CLK_VPLL,
+ CLK_DPLL,
+ CLK_NA_PARENT
+ }),
+ .nodes = &generic_mux_div_gate_nodes,
+ .num_nodes = ARRAY_SIZE(generic_mux_div_gate_nodes),
+ },
+ [CLK_GTGREF0_REF] = {
+ .name = "gtgref0_ref",
+ .control_reg = CRF_APB_GTGREF0_REF_CTRL,
+ .status_reg = 0,
+ .parents = &((int32_t []) {
+ CLK_IOPLL_TO_FPD,
+ CLK_DUMMY_PARENT,
+ CLK_APLL,
+ CLK_DPLL,
+ CLK_NA_PARENT
+ }),
+ .nodes = &generic_mux_div_gate_nodes,
+ .num_nodes = ARRAY_SIZE(generic_mux_div_gate_nodes),
+ },
+ [CLK_TOPSW_MAIN] = {
+ .name = "topsw_main",
+ .control_reg = CRF_APB_TOPSW_MAIN_CTRL,
+ .status_reg = 0,
+ .parents = &((int32_t []) {
+ CLK_APLL,
+ CLK_DUMMY_PARENT,
+ CLK_VPLL,
+ CLK_DPLL,
+ CLK_NA_PARENT
+ }),
+ .nodes = &generic_mux_div_unused_gate_nodes,
+ .num_nodes = ARRAY_SIZE(generic_mux_div_unused_gate_nodes),
+ },
+ [CLK_TOPSW_LSBUS] = {
+ .name = "topsw_lsbus",
+ .control_reg = CRF_APB_TOPSW_LSBUS_CTRL,
+ .status_reg = 0,
+ .parents = &((int32_t []) {
+ CLK_APLL,
+ CLK_DUMMY_PARENT,
+ CLK_IOPLL_TO_FPD,
+ CLK_DPLL,
+ CLK_NA_PARENT
+ }),
+ .nodes = &generic_mux_div_unused_gate_nodes,
+ .num_nodes = ARRAY_SIZE(generic_mux_div_unused_gate_nodes),
+ },
+ [CLK_IOU_SWITCH] = {
+ .name = "iou_switch",
+ .control_reg = CRL_APB_IOU_SWITCH_CTRL,
+ .status_reg = 0,
+ .parents = &((int32_t []) {
+ CLK_RPLL,
+ CLK_DUMMY_PARENT,
+ CLK_IOPLL,
+ CLK_DPLL_TO_LPD,
+ CLK_NA_PARENT
+ }),
+ .nodes = &generic_mux_div_unused_gate_nodes,
+ .num_nodes = ARRAY_SIZE(generic_mux_div_unused_gate_nodes),
+ },
+ [CLK_GEM0_REF] = {
+ .name = "gem0_ref",
+ .control_reg = CRL_APB_GEM0_REF_CTRL,
+ .status_reg = 0,
+ .parents = &((int32_t []) {
+ CLK_IOPLL,
+ CLK_DUMMY_PARENT,
+ CLK_RPLL,
+ CLK_DPLL_TO_LPD,
+ CLK_NA_PARENT
+ }),
+ .nodes = &gem_nodes,
+ .num_nodes = ARRAY_SIZE(gem_nodes),
+ },
+ [CLK_GEM1_REF] = {
+ .name = "gem1_ref",
+ .control_reg = CRL_APB_GEM1_REF_CTRL,
+ .status_reg = 0,
+ .parents = &((int32_t []) {
+ CLK_IOPLL,
+ CLK_DUMMY_PARENT,
+ CLK_RPLL,
+ CLK_DPLL_TO_LPD,
+ CLK_NA_PARENT
+ }),
+ .nodes = &gem_nodes,
+ .num_nodes = ARRAY_SIZE(gem_nodes),
+ },
+ [CLK_GEM2_REF] = {
+ .name = "gem2_ref",
+ .control_reg = CRL_APB_GEM2_REF_CTRL,
+ .status_reg = 0,
+ .parents = &((int32_t []) {
+ CLK_IOPLL,
+ CLK_DUMMY_PARENT,
+ CLK_RPLL,
+ CLK_DPLL_TO_LPD,
+ CLK_NA_PARENT
+ }),
+ .nodes = &gem_nodes,
+ .num_nodes = ARRAY_SIZE(gem_nodes),
+ },
+ [CLK_GEM3_REF] = {
+ .name = "gem3_ref",
+ .control_reg = CRL_APB_GEM3_REF_CTRL,
+ .status_reg = 0,
+ .parents = &((int32_t []) {
+ CLK_IOPLL,
+ CLK_DUMMY_PARENT,
+ CLK_RPLL,
+ CLK_DPLL_TO_LPD,
+ CLK_NA_PARENT
+ }),
+ .nodes = &gem_nodes,
+ .num_nodes = ARRAY_SIZE(gem_nodes),
+ },
+ [CLK_USB0_BUS_REF] = {
+ .name = "usb0_bus_ref",
+ .control_reg = CRL_APB_USB0_BUS_REF_CTRL,
+ .status_reg = 0,
+ .parents = &((int32_t []) {
+ CLK_IOPLL,
+ CLK_DUMMY_PARENT,
+ CLK_RPLL,
+ CLK_DPLL_TO_LPD,
+ CLK_NA_PARENT
+ }),
+ .nodes = &usb_nodes,
+ .num_nodes = ARRAY_SIZE(usb_nodes),
+ },
+ [CLK_USB1_BUS_REF] = {
+ .name = "usb1_bus_ref",
+ .control_reg = CRL_APB_USB1_BUS_REF_CTRL,
+ .status_reg = 0,
+ .parents = &((int32_t []) {
+ CLK_IOPLL,
+ CLK_DUMMY_PARENT,
+ CLK_RPLL,
+ CLK_DPLL_TO_LPD,
+ CLK_NA_PARENT
+ }),
+ .nodes = &usb_nodes,
+ .num_nodes = ARRAY_SIZE(usb_nodes),
+ },
+ [CLK_USB3_DUAL_REF] = {
+ .name = "usb3_dual_ref",
+ .control_reg = CRL_APB_USB3_DUAL_REF_CTRL,
+ .status_reg = 0,
+ .parents = &((int32_t []) {
+ CLK_IOPLL,
+ CLK_DUMMY_PARENT,
+ CLK_RPLL,
+ CLK_DPLL_TO_LPD,
+ CLK_NA_PARENT
+ }),
+ .nodes = &usb_nodes,
+ .num_nodes = ARRAY_SIZE(usb_nodes),
+ },
+ [CLK_QSPI_REF] = {
+ .name = "qspi_ref",
+ .control_reg = CRL_APB_QSPI_REF_CTRL,
+ .status_reg = 0,
+ .parents = &((int32_t []) {
+ CLK_IOPLL,
+ CLK_DUMMY_PARENT,
+ CLK_RPLL,
+ CLK_DPLL_TO_LPD,
+ CLK_NA_PARENT
+ }),
+ .nodes = &generic_mux_div_div_gate_nodes,
+ .num_nodes = ARRAY_SIZE(generic_mux_div_div_gate_nodes),
+ },
+ [CLK_SDIO0_REF] = {
+ .name = "sdio0_ref",
+ .control_reg = CRL_APB_SDIO0_REF_CTRL,
+ .status_reg = 0,
+ .parents = &((int32_t []) {
+ CLK_IOPLL,
+ CLK_DUMMY_PARENT,
+ CLK_RPLL,
+ CLK_VPLL_TO_LPD,
+ CLK_NA_PARENT
+ }),
+ .nodes = &generic_mux_div_div_gate_nodes,
+ .num_nodes = ARRAY_SIZE(generic_mux_div_div_gate_nodes),
+ },
+ [CLK_SDIO1_REF] = {
+ .name = "sdio1_ref",
+ .control_reg = CRL_APB_SDIO1_REF_CTRL,
+ .status_reg = 0,
+ .parents = &((int32_t []) {
+ CLK_IOPLL,
+ CLK_DUMMY_PARENT,
+ CLK_RPLL,
+ CLK_VPLL_TO_LPD,
+ CLK_NA_PARENT
+ }),
+ .nodes = &generic_mux_div_div_gate_nodes,
+ .num_nodes = ARRAY_SIZE(generic_mux_div_div_gate_nodes),
+ },
+ [CLK_UART0_REF] = {
+ .name = "uart0_ref",
+ .control_reg = CRL_APB_UART0_REF_CTRL,
+ .status_reg = 0,
+ .parents = &((int32_t []) {
+ CLK_IOPLL,
+ CLK_DUMMY_PARENT,
+ CLK_RPLL,
+ CLK_DPLL_TO_LPD,
+ CLK_NA_PARENT
+ }),
+ .nodes = &generic_mux_div_div_gate_nodes,
+ .num_nodes = ARRAY_SIZE(generic_mux_div_div_gate_nodes),
+ },
+ [CLK_UART1_REF] = {
+ .name = "uart1_ref",
+ .control_reg = CRL_APB_UART1_REF_CTRL,
+ .status_reg = 0,
+ .parents = &((int32_t []) {
+ CLK_IOPLL,
+ CLK_DUMMY_PARENT,
+ CLK_RPLL,
+ CLK_DPLL_TO_LPD,
+ CLK_NA_PARENT
+ }),
+ .nodes = &generic_mux_div_div_gate_nodes,
+ .num_nodes = ARRAY_SIZE(generic_mux_div_div_gate_nodes),
+ },
+ [CLK_SPI0_REF] = {
+ .name = "spi0_ref",
+ .control_reg = CRL_APB_SPI0_REF_CTRL,
+ .status_reg = 0,
+ .parents = &((int32_t []) {
+ CLK_IOPLL,
+ CLK_DUMMY_PARENT,
+ CLK_RPLL,
+ CLK_DPLL_TO_LPD,
+ CLK_NA_PARENT
+ }),
+ .nodes = &generic_mux_div_div_gate_nodes,
+ .num_nodes = ARRAY_SIZE(generic_mux_div_div_gate_nodes),
+ },
+ [CLK_SPI1_REF] = {
+ .name = "spi1_ref",
+ .control_reg = CRL_APB_SPI1_REF_CTRL,
+ .status_reg = 0,
+ .parents = &((int32_t []) {
+ CLK_IOPLL,
+ CLK_DUMMY_PARENT,
+ CLK_RPLL,
+ CLK_DPLL_TO_LPD,
+ CLK_NA_PARENT
+ }),
+ .nodes = &generic_mux_div_div_gate_nodes,
+ .num_nodes = ARRAY_SIZE(generic_mux_div_div_gate_nodes),
+ },
+ [CLK_CAN0_REF] = {
+ .name = "can0_ref",
+ .control_reg = CRL_APB_CAN0_REF_CTRL,
+ .status_reg = 0,
+ .parents = &((int32_t []) {
+ CLK_IOPLL,
+ CLK_DUMMY_PARENT,
+ CLK_RPLL,
+ CLK_DPLL_TO_LPD,
+ CLK_NA_PARENT
+ }),
+ .nodes = &generic_mux_div_div_gate_nodes,
+ .num_nodes = ARRAY_SIZE(generic_mux_div_div_gate_nodes),
+ },
+ [CLK_CAN1_REF] = {
+ .name = "can1_ref",
+ .control_reg = CRL_APB_CAN1_REF_CTRL,
+ .status_reg = 0,
+ .parents = &((int32_t []) {
+ CLK_IOPLL,
+ CLK_DUMMY_PARENT,
+ CLK_RPLL,
+ CLK_DPLL_TO_LPD,
+ CLK_NA_PARENT
+ }),
+ .nodes = &generic_mux_div_div_gate_nodes,
+ .num_nodes = ARRAY_SIZE(generic_mux_div_div_gate_nodes),
+ },
+ [CLK_NAND_REF] = {
+ .name = "nand_ref",
+ .control_reg = CRL_APB_NAND_REF_CTRL,
+ .status_reg = 0,
+ .parents = &((int32_t []) {
+ CLK_IOPLL,
+ CLK_DUMMY_PARENT,
+ CLK_RPLL,
+ CLK_DPLL_TO_LPD,
+ CLK_NA_PARENT
+ }),
+ .nodes = &generic_mux_div_div_gate_nodes,
+ .num_nodes = ARRAY_SIZE(generic_mux_div_div_gate_nodes),
+ },
+ [CLK_GEM_TSU_REF] = {
+ .name = "gem_tsu_ref",
+ .control_reg = CRL_APB_GEM_TSU_REF_CTRL,
+ .status_reg = 0,
+ .parents = &((int32_t []) {
+ CLK_IOPLL,
+ CLK_DUMMY_PARENT,
+ CLK_RPLL,
+ CLK_DPLL_TO_LPD,
+ CLK_NA_PARENT
+ }),
+ .nodes = &generic_mux_div_div_gate_nodes,
+ .num_nodes = ARRAY_SIZE(generic_mux_div_div_gate_nodes),
+ },
+ [CLK_DLL_REF] = {
+ .name = "dll_ref",
+ .control_reg = CRL_APB_DLL_REF_CTRL,
+ .status_reg = 0,
+ .parents = &((int32_t []) {
+ CLK_IOPLL,
+ CLK_RPLL,
+ CLK_NA_PARENT
+ }),
+ .nodes = &dll_ref_nodes,
+ .num_nodes = ARRAY_SIZE(dll_ref_nodes),
+ },
+ [CLK_ADMA_REF] = {
+ .name = "adma_ref",
+ .control_reg = CRL_APB_ADMA_REF_CTRL,
+ .status_reg = 0,
+ .parents = &((int32_t []) {
+ CLK_RPLL,
+ CLK_DUMMY_PARENT,
+ CLK_IOPLL,
+ CLK_DPLL_TO_LPD,
+ CLK_NA_PARENT
+ }),
+ .nodes = &generic_mux_div_gate_nodes,
+ .num_nodes = ARRAY_SIZE(generic_mux_div_gate_nodes),
+ },
+ [CLK_DBG_LPD] = {
+ .name = "dbg_lpd",
+ .control_reg = CRL_APB_DBG_LPD_CTRL,
+ .status_reg = 0,
+ .parents = &((int32_t []) {
+ CLK_RPLL,
+ CLK_DUMMY_PARENT,
+ CLK_IOPLL,
+ CLK_DPLL_TO_LPD,
+ CLK_NA_PARENT
+ }),
+ .nodes = &generic_mux_div_gate_nodes,
+ .num_nodes = ARRAY_SIZE(generic_mux_div_gate_nodes),
+ },
+ [CLK_CPU_R5] = {
+ .name = "cpu_r5",
+ .control_reg = CRL_APB_CPU_R5_CTRL,
+ .status_reg = 0,
+ .parents = &((int32_t []) {
+ CLK_RPLL,
+ CLK_DUMMY_PARENT,
+ CLK_IOPLL,
+ CLK_DPLL_TO_LPD,
+ CLK_NA_PARENT
+ }),
+ .nodes = &generic_mux_div_unused_gate_nodes,
+ .num_nodes = ARRAY_SIZE(generic_mux_div_unused_gate_nodes),
+ },
+ [CLK_CSU_PLL] = {
+ .name = "csu_pll",
+ .control_reg = CRL_APB_CSU_PLL_CTRL,
+ .status_reg = 0,
+ .parents = &((int32_t []) {
+ CLK_IOPLL,
+ CLK_DUMMY_PARENT,
+ CLK_RPLL,
+ CLK_DPLL_TO_LPD,
+ CLK_NA_PARENT
+ }),
+ .nodes = &generic_mux_div_gate_nodes,
+ .num_nodes = ARRAY_SIZE(generic_mux_div_gate_nodes),
+ },
+ [CLK_PCAP] = {
+ .name = "pcap",
+ .control_reg = CRL_APB_PCAP_CTRL,
+ .status_reg = 0,
+ .parents = &((int32_t []) {
+ CLK_IOPLL,
+ CLK_DUMMY_PARENT,
+ CLK_RPLL,
+ CLK_DPLL_TO_LPD,
+ CLK_NA_PARENT
+ }),
+ .nodes = &generic_mux_div_gate_nodes,
+ .num_nodes = ARRAY_SIZE(generic_mux_div_gate_nodes),
+ },
+ [CLK_LPD_LSBUS] = {
+ .name = "lpd_lsbus",
+ .control_reg = CRL_APB_LPD_LSBUS_CTRL,
+ .status_reg = 0,
+ .parents = &((int32_t []) {
+ CLK_RPLL,
+ CLK_DUMMY_PARENT,
+ CLK_IOPLL,
+ CLK_DPLL_TO_LPD,
+ CLK_NA_PARENT
+ }),
+ .nodes = &generic_mux_div_unused_gate_nodes,
+ .num_nodes = ARRAY_SIZE(generic_mux_div_unused_gate_nodes),
+ },
+ [CLK_LPD_SWITCH] = {
+ .name = "lpd_switch",
+ .control_reg = CRL_APB_LPD_SWITCH_CTRL,
+ .status_reg = 0,
+ .parents = &((int32_t []) {
+ CLK_RPLL,
+ CLK_DUMMY_PARENT,
+ CLK_IOPLL,
+ CLK_DPLL_TO_LPD,
+ CLK_NA_PARENT
+ }),
+ .nodes = &generic_mux_div_unused_gate_nodes,
+ .num_nodes = ARRAY_SIZE(generic_mux_div_unused_gate_nodes),
+ },
+ [CLK_I2C0_REF] = {
+ .name = "i2c0_ref",
+ .control_reg = CRL_APB_I2C0_REF_CTRL,
+ .status_reg = 0,
+ .parents = &((int32_t []) {
+ CLK_IOPLL,
+ CLK_DUMMY_PARENT,
+ CLK_RPLL,
+ CLK_DPLL_TO_LPD,
+ CLK_NA_PARENT
+ }),
+ .nodes = &generic_mux_div_div_gate_nodes,
+ .num_nodes = ARRAY_SIZE(generic_mux_div_div_gate_nodes),
+ },
+ [CLK_I2C1_REF] = {
+ .name = "i2c1_ref",
+ .control_reg = CRL_APB_I2C1_REF_CTRL,
+ .status_reg = 0,
+ .parents = &((int32_t []) {
+ CLK_IOPLL,
+ CLK_DUMMY_PARENT,
+ CLK_RPLL,
+ CLK_DPLL_TO_LPD,
+ CLK_NA_PARENT
+ }),
+ .nodes = &generic_mux_div_div_gate_nodes,
+ .num_nodes = ARRAY_SIZE(generic_mux_div_div_gate_nodes),
+ },
+ [CLK_TIMESTAMP_REF] = {
+ .name = "timestamp_ref",
+ .control_reg = CRL_APB_TIMESTAMP_REF_CTRL,
+ .status_reg = 0,
+ .parents = &((int32_t []) {
+ CLK_IOPLL,
+ CLK_DUMMY_PARENT,
+ CLK_RPLL,
+ CLK_DPLL_TO_LPD,
+ EXT_CLK_PSS_REF | CLK_EXTERNAL_PARENT,
+ EXT_CLK_PSS_REF | CLK_EXTERNAL_PARENT,
+ EXT_CLK_PSS_REF | CLK_EXTERNAL_PARENT,
+ EXT_CLK_PSS_REF | CLK_EXTERNAL_PARENT,
+ CLK_NA_PARENT
+ }),
+ .nodes = ×tamp_ref_nodes,
+ .num_nodes = ARRAY_SIZE(timestamp_ref_nodes),
+ },
+ [CLK_PL0_REF] = {
+ .name = "pl0_ref",
+ .control_reg = CRL_APB_PL0_REF_CTRL,
+ .status_reg = 0,
+ .parents = &((int32_t []) {
+ CLK_IOPLL,
+ CLK_DUMMY_PARENT,
+ CLK_RPLL,
+ CLK_DPLL_TO_LPD,
+ CLK_NA_PARENT
+ }),
+ .nodes = &pl_nodes,
+ .num_nodes = ARRAY_SIZE(pl_nodes),
+ },
+ [CLK_PL1_REF] = {
+ .name = "pl1_ref",
+ .control_reg = CRL_APB_PL1_REF_CTRL,
+ .status_reg = 0,
+ .parents = &((int32_t []) {
+ CLK_IOPLL,
+ CLK_DUMMY_PARENT,
+ CLK_RPLL,
+ CLK_DPLL_TO_LPD,
+ CLK_NA_PARENT
+ }),
+ .nodes = &pl_nodes,
+ .num_nodes = ARRAY_SIZE(pl_nodes),
+ },
+ [CLK_PL2_REF] = {
+ .name = "pl2_ref",
+ .control_reg = CRL_APB_PL2_REF_CTRL,
+ .status_reg = 0,
+ .parents = &((int32_t []) {
+ CLK_IOPLL,
+ CLK_DUMMY_PARENT,
+ CLK_RPLL,
+ CLK_DPLL_TO_LPD,
+ CLK_NA_PARENT
+ }),
+ .nodes = &pl_nodes,
+ .num_nodes = ARRAY_SIZE(pl_nodes),
+ },
+ [CLK_PL3_REF] = {
+ .name = "pl3_ref",
+ .control_reg = CRL_APB_PL3_REF_CTRL,
+ .status_reg = 0,
+ .parents = &((int32_t []) {
+ CLK_IOPLL,
+ CLK_DUMMY_PARENT,
+ CLK_RPLL,
+ CLK_DPLL_TO_LPD,
+ CLK_NA_PARENT
+ }),
+ .nodes = &pl_nodes,
+ .num_nodes = ARRAY_SIZE(pl_nodes),
+ },
+ [CLK_AMS_REF] = {
+ .name = "ams_ref",
+ .control_reg = CRL_APB_AMS_REF_CTRL,
+ .status_reg = 0,
+ .parents = &((int32_t []) {
+ CLK_RPLL,
+ CLK_DUMMY_PARENT,
+ CLK_IOPLL,
+ CLK_DPLL_TO_LPD,
+ CLK_NA_PARENT
+ }),
+ .nodes = &generic_mux_div_div_gate_nodes,
+ .num_nodes = ARRAY_SIZE(generic_mux_div_div_gate_nodes),
+ },
+ [CLK_IOPLL_TO_FPD] = {
+ .name = "iopll_to_fpd",
+ .control_reg = CRL_APB_IOPLL_TO_FPD_CTRL,
+ .status_reg = 0,
+ .parents = &((int32_t []) {CLK_IOPLL, CLK_NA_PARENT}),
+ .nodes = &generic_domain_crossing_nodes,
+ .num_nodes = ARRAY_SIZE(generic_domain_crossing_nodes),
+ },
+ [CLK_RPLL_TO_FPD] = {
+ .name = "rpll_to_fpd",
+ .control_reg = CRL_APB_RPLL_TO_FPD_CTRL,
+ .status_reg = 0,
+ .parents = &((int32_t []) {CLK_RPLL, CLK_NA_PARENT}),
+ .nodes = &rpll_to_fpd_nodes,
+ .num_nodes = ARRAY_SIZE(rpll_to_fpd_nodes),
+ },
+ [CLK_APLL_TO_LPD] = {
+ .name = "apll_to_lpd",
+ .control_reg = CRF_APB_APLL_TO_LPD_CTRL,
+ .status_reg = 0,
+ .parents = &((int32_t []) {CLK_APLL, CLK_NA_PARENT}),
+ .nodes = &generic_domain_crossing_nodes,
+ .num_nodes = ARRAY_SIZE(generic_domain_crossing_nodes),
+ },
+ [CLK_DPLL_TO_LPD] = {
+ .name = "dpll_to_lpd",
+ .control_reg = CRF_APB_DPLL_TO_LPD_CTRL,
+ .status_reg = 0,
+ .parents = &((int32_t []) {CLK_DPLL, CLK_NA_PARENT}),
+ .nodes = &generic_domain_crossing_nodes,
+ .num_nodes = ARRAY_SIZE(generic_domain_crossing_nodes),
+ },
+ [CLK_VPLL_TO_LPD] = {
+ .name = "vpll_to_lpd",
+ .control_reg = CRF_APB_VPLL_TO_LPD_CTRL,
+ .status_reg = 0,
+ .parents = &((int32_t []) {CLK_VPLL, CLK_NA_PARENT}),
+ .nodes = &generic_domain_crossing_nodes,
+ .num_nodes = ARRAY_SIZE(generic_domain_crossing_nodes),
+ },
+ /*
+ * This clock control requires different registers for mux and gate.
+ * Use control and status registers for the same.
+ */
+ [CLK_GEM0_TX] = {
+ .name = "gem0_tx",
+ .control_reg = IOU_SLCR_GEM_CLK_CTRL,
+ .status_reg = CRL_APB_GEM0_REF_CTRL,
+ .parents = &((int32_t []) {
+ CLK_GEM0_REF | (PARENT_CLK_NODE3 << CLK_PARENTS_ID_LEN),
+ EXT_CLK_GEM0_EMIO | CLK_EXTERNAL_PARENT,
+ CLK_NA_PARENT
+ }),
+ .nodes = &gem0_tx_nodes,
+ .num_nodes = ARRAY_SIZE(gem0_tx_nodes),
+ },
+ /*
+ * This clock control requires different registers for mux and gate.
+ * Use control and status registers for the same.
+ */
+ [CLK_GEM1_TX] = {
+ .name = "gem1_tx",
+ .control_reg = IOU_SLCR_GEM_CLK_CTRL,
+ .status_reg = CRL_APB_GEM1_REF_CTRL,
+ .parents = &((int32_t []) {
+ CLK_GEM1_REF | (PARENT_CLK_NODE3 << CLK_PARENTS_ID_LEN),
+ EXT_CLK_GEM1_EMIO | CLK_EXTERNAL_PARENT,
+ CLK_NA_PARENT
+ }),
+ .nodes = &gem1_tx_nodes,
+ .num_nodes = ARRAY_SIZE(gem1_tx_nodes),
+ },
+ /*
+ * This clock control requires different registers for mux and gate.
+ * Use control and status registers for the same.
+ */
+ [CLK_GEM2_TX] = {
+ .name = "gem2_tx",
+ .control_reg = IOU_SLCR_GEM_CLK_CTRL,
+ .status_reg = CRL_APB_GEM2_REF_CTRL,
+ .parents = &((int32_t []) {
+ CLK_GEM2_REF | (PARENT_CLK_NODE3 << CLK_PARENTS_ID_LEN),
+ EXT_CLK_GEM2_EMIO | CLK_EXTERNAL_PARENT,
+ CLK_NA_PARENT
+ }),
+ .nodes = &gem2_tx_nodes,
+ .num_nodes = ARRAY_SIZE(gem2_tx_nodes),
+ },
+ /*
+ * This clock control requires different registers for mux and gate.
+ * Use control and status registers for the same.
+ */
+ [CLK_GEM3_TX] = {
+ .name = "gem3_tx",
+ .control_reg = IOU_SLCR_GEM_CLK_CTRL,
+ .status_reg = CRL_APB_GEM3_REF_CTRL,
+ .parents = &((int32_t []) {
+ CLK_GEM3_REF | (PARENT_CLK_NODE3 << CLK_PARENTS_ID_LEN),
+ EXT_CLK_GEM3_EMIO | CLK_EXTERNAL_PARENT,
+ CLK_NA_PARENT
+ }),
+ .nodes = &gem3_tx_nodes,
+ .num_nodes = ARRAY_SIZE(gem3_tx_nodes),
+ },
+ [CLK_ACPU_HALF] = {
+ .name = "acpu_half",
+ .control_reg = CRF_APB_ACPU_CTRL,
+ .status_reg = 0,
+ .parents = &((int32_t []) {
+ CLK_ACPU | PARENT_CLK_NODE2 << CLK_PARENTS_ID_LEN,
+ CLK_NA_PARENT
+ }),
+ .nodes = &acpu_half_nodes,
+ .num_nodes = ARRAY_SIZE(acpu_half_nodes),
+ },
+ [CLK_WDT] = {
+ .name = "wdt",
+ .control_reg = IOU_SLCR_WDT_CLK_SEL,
+ .status_reg = 0,
+ .parents = &((int32_t []) {
+ CLK_TOPSW_LSBUS,
+ EXT_CLK_SWDT0 | CLK_EXTERNAL_PARENT,
+ EXT_CLK_SWDT1 | CLK_EXTERNAL_PARENT,
+ CLK_NA_PARENT
+ }),
+ .nodes = &wdt_nodes,
+ .num_nodes = ARRAY_SIZE(wdt_nodes),
+ },
+ [CLK_GPU_PP0_REF] = {
+ .name = "gpu_pp0_ref",
+ .control_reg = CRF_APB_GPU_REF_CTRL,
+ .status_reg = 0,
+ .parents = &((int32_t []) {
+ CLK_GPU_REF | PARENT_CLK_NODE2 << CLK_PARENTS_ID_LEN,
+ CLK_NA_PARENT
+ }),
+ .nodes = &gpu_pp0_nodes,
+ .num_nodes = ARRAY_SIZE(gpu_pp0_nodes),
+ },
+ [CLK_GPU_PP1_REF] = {
+ .name = "gpu_pp1_ref",
+ .control_reg = CRF_APB_GPU_REF_CTRL,
+ .status_reg = 0,
+ .parents = &((int32_t []) {
+ CLK_GPU_REF | PARENT_CLK_NODE2 << CLK_PARENTS_ID_LEN,
+ CLK_NA_PARENT
+ }),
+ .nodes = &gpu_pp1_nodes,
+ .num_nodes = ARRAY_SIZE(gpu_pp1_nodes),
+ },
+ [CLK_GEM_TSU] = {
+ .name = "gem_tsu",
+ .control_reg = IOU_SLCR_GEM_CLK_CTRL,
+ .status_reg = 0,
+ .parents = &((int32_t []) {
+ CLK_GEM_TSU_REF,
+ CLK_GEM_TSU_REF,
+ EXT_CLK_MIO26 | CLK_EXTERNAL_PARENT,
+ EXT_CLK_MIO50_OR_MIO51 | CLK_EXTERNAL_PARENT,
+ CLK_NA_PARENT
+ }),
+ .nodes = &gem_tsu_nodes,
+ .num_nodes = ARRAY_SIZE(gem_tsu_nodes),
+ },
+ [CLK_CPU_R5_CORE] = {
+ .name = "cpu_r5_core",
+ .control_reg = CRL_APB_CPU_R5_CTRL,
+ .status_reg = 0,
+ .parents = &((int32_t []) {
+ CLK_CPU_R5 | PARENT_CLK_NODE2 << CLK_PARENTS_ID_LEN,
+ CLK_DUMMY_PARENT,
+ CLK_NA_PARENT
+ }),
+ .nodes = &cpu_r5_core_nodes,
+ .num_nodes = ARRAY_SIZE(cpu_r5_core_nodes),
+ },
+ [CLK_CAN0_MIO] = {
+ .name = "can0_mio",
+ .control_reg = IOU_SLCR_CAN_MIO_CTRL,
+ .status_reg = 0,
+ .parents = &can_mio_parents,
+ .nodes = &can0_mio_nodes,
+ .num_nodes = ARRAY_SIZE(can0_mio_nodes),
+ },
+ [CLK_CAN1_MIO] = {
+ .name = "can1_mio",
+ .control_reg = IOU_SLCR_CAN_MIO_CTRL,
+ .status_reg = 0,
+ .parents = &can_mio_parents,
+ .nodes = &can1_mio_nodes,
+ .num_nodes = ARRAY_SIZE(can1_mio_nodes),
+ },
+ [CLK_CAN0] = {
+ .name = "can0",
+ .control_reg = IOU_SLCR_CAN_MIO_CTRL,
+ .status_reg = 0,
+ .parents = &((int32_t []) {
+ CLK_CAN0_REF,
+ CLK_CAN0_MIO,
+ CLK_NA_PARENT
+ }),
+ .nodes = &can0_nodes,
+ .num_nodes = ARRAY_SIZE(can0_nodes),
+ },
+ [CLK_CAN1] = {
+ .name = "can1",
+ .control_reg = IOU_SLCR_CAN_MIO_CTRL,
+ .status_reg = 0,
+ .parents = &((int32_t []) {
+ CLK_CAN1_REF,
+ CLK_CAN1_MIO,
+ CLK_NA_PARENT
+ }),
+ .nodes = &can1_nodes,
+ .num_nodes = ARRAY_SIZE(can1_nodes),
+ },
+};
+
+static struct pm_ext_clock ext_clocks[] = {
+ [EXT_CLK_INDEX(EXT_CLK_PSS_REF)] = {
+ .name = "pss_ref_clk",
+ },
+ [EXT_CLK_INDEX(EXT_CLK_VIDEO)] = {
+ .name = "video_clk",
+ },
+ [EXT_CLK_INDEX(EXT_CLK_PSS_ALT_REF)] = {
+ .name = "pss_alt_ref_clk",
+ },
+ [EXT_CLK_INDEX(EXT_CLK_AUX_REF)] = {
+ .name = "aux_ref_clk",
+ },
+ [EXT_CLK_INDEX(EXT_CLK_GT_CRX_REF)] = {
+ .name = "video_clk",
+ },
+ [EXT_CLK_INDEX(EXT_CLK_SWDT0)] = {
+ .name = "swdt0_ext_clk",
+ },
+ [EXT_CLK_INDEX(EXT_CLK_SWDT1)] = {
+ .name = "swdt1_ext_clk",
+ },
+ [EXT_CLK_INDEX(EXT_CLK_GEM0_EMIO)] = {
+ .name = "gem0_emio_clk",
+ },
+ [EXT_CLK_INDEX(EXT_CLK_GEM1_EMIO)] = {
+ .name = "gem1_emio_clk",
+ },
+ [EXT_CLK_INDEX(EXT_CLK_GEM2_EMIO)] = {
+ .name = "gem2_emio_clk",
+ },
+ [EXT_CLK_INDEX(EXT_CLK_GEM3_EMIO)] = {
+ .name = "gem3_emio_clk",
+ },
+ [EXT_CLK_INDEX(EXT_CLK_MIO50_OR_MIO51)] = {
+ .name = "mio_clk_50_51",
+ },
+ EXT_CLK_MIO_DATA(0),
+ EXT_CLK_MIO_DATA(1),
+ EXT_CLK_MIO_DATA(2),
+ EXT_CLK_MIO_DATA(3),
+ EXT_CLK_MIO_DATA(4),
+ EXT_CLK_MIO_DATA(5),
+ EXT_CLK_MIO_DATA(6),
+ EXT_CLK_MIO_DATA(7),
+ EXT_CLK_MIO_DATA(8),
+ EXT_CLK_MIO_DATA(9),
+ EXT_CLK_MIO_DATA(10),
+ EXT_CLK_MIO_DATA(11),
+ EXT_CLK_MIO_DATA(12),
+ EXT_CLK_MIO_DATA(13),
+ EXT_CLK_MIO_DATA(14),
+ EXT_CLK_MIO_DATA(15),
+ EXT_CLK_MIO_DATA(16),
+ EXT_CLK_MIO_DATA(17),
+ EXT_CLK_MIO_DATA(18),
+ EXT_CLK_MIO_DATA(19),
+ EXT_CLK_MIO_DATA(20),
+ EXT_CLK_MIO_DATA(21),
+ EXT_CLK_MIO_DATA(22),
+ EXT_CLK_MIO_DATA(23),
+ EXT_CLK_MIO_DATA(24),
+ EXT_CLK_MIO_DATA(25),
+ EXT_CLK_MIO_DATA(26),
+ EXT_CLK_MIO_DATA(27),
+ EXT_CLK_MIO_DATA(28),
+ EXT_CLK_MIO_DATA(29),
+ EXT_CLK_MIO_DATA(30),
+ EXT_CLK_MIO_DATA(31),
+ EXT_CLK_MIO_DATA(32),
+ EXT_CLK_MIO_DATA(33),
+ EXT_CLK_MIO_DATA(34),
+ EXT_CLK_MIO_DATA(35),
+ EXT_CLK_MIO_DATA(36),
+ EXT_CLK_MIO_DATA(37),
+ EXT_CLK_MIO_DATA(38),
+ EXT_CLK_MIO_DATA(39),
+ EXT_CLK_MIO_DATA(40),
+ EXT_CLK_MIO_DATA(41),
+ EXT_CLK_MIO_DATA(42),
+ EXT_CLK_MIO_DATA(43),
+ EXT_CLK_MIO_DATA(44),
+ EXT_CLK_MIO_DATA(45),
+ EXT_CLK_MIO_DATA(46),
+ EXT_CLK_MIO_DATA(47),
+ EXT_CLK_MIO_DATA(48),
+ EXT_CLK_MIO_DATA(49),
+ EXT_CLK_MIO_DATA(50),
+ EXT_CLK_MIO_DATA(51),
+ EXT_CLK_MIO_DATA(52),
+ EXT_CLK_MIO_DATA(53),
+ EXT_CLK_MIO_DATA(54),
+ EXT_CLK_MIO_DATA(55),
+ EXT_CLK_MIO_DATA(56),
+ EXT_CLK_MIO_DATA(57),
+ EXT_CLK_MIO_DATA(58),
+ EXT_CLK_MIO_DATA(59),
+ EXT_CLK_MIO_DATA(60),
+ EXT_CLK_MIO_DATA(61),
+ EXT_CLK_MIO_DATA(62),
+ EXT_CLK_MIO_DATA(63),
+ EXT_CLK_MIO_DATA(64),
+ EXT_CLK_MIO_DATA(65),
+ EXT_CLK_MIO_DATA(66),
+ EXT_CLK_MIO_DATA(67),
+ EXT_CLK_MIO_DATA(68),
+ EXT_CLK_MIO_DATA(69),
+ EXT_CLK_MIO_DATA(70),
+ EXT_CLK_MIO_DATA(71),
+ EXT_CLK_MIO_DATA(72),
+ EXT_CLK_MIO_DATA(73),
+ EXT_CLK_MIO_DATA(74),
+ EXT_CLK_MIO_DATA(75),
+ EXT_CLK_MIO_DATA(76),
+ EXT_CLK_MIO_DATA(77),
+};
+
+/* Array of clock which are invalid for this variant */
+static uint32_t pm_clk_invalid_list[] = {CLK_USB0, CLK_USB1, CLK_CSU_SPB};
+
+/* Array of clocks which needs to be enabled at init */
+static uint32_t pm_clk_init_enable_list[] = {
+ CLK_ACPU,
+ CLK_DDR_REF,
+};
+
+/**
+ * pm_clock_valid - Check if clock is valid or not
+ * @clock_id Id of the clock to be queried
+ *
+ * This function is used to check if given clock is valid
+ * or not for the chip variant.
+ *
+ * List of invalid clocks are maintained in array list for
+ * different variants.
+ *
+ * Return: Returns 1 if clock is valid else 0.
+ */
+static bool pm_clock_valid(unsigned int clock_id)
+{
+ unsigned int i;
+
+ for (i = 0; i < ARRAY_SIZE(pm_clk_invalid_list); i++)
+ if (pm_clk_invalid_list[i] == clock_id)
+ return 0;
+
+ return 1;
+}
+
+/**
+ * pm_clock_init_enable - Check if clock needs to be enabled at init
+ * @clock_id Id of the clock to be queried
+ *
+ * This function is used to check if given clock needs to be enabled
+ * at boot up or not. Some clocks needs to be enabled at init.
+ *
+ * Return: Returns 1 if clock needs to be enabled at boot up else 0.
+ */
+static unsigned int pm_clock_init_enable(unsigned int clock_id)
+{
+ unsigned int i;
+
+ for (i = 0; i < ARRAY_SIZE(pm_clk_init_enable_list); i++)
+ if (pm_clk_init_enable_list[i] == clock_id)
+ return 1;
+
+ return 0;
+}
+
+/**
+ * pm_clock_type - Get clock's type
+ * @clock_id Id of the clock to be queried
+ *
+ * This function is used to check type of clock (OUTPUT/EXTERNAL).
+ *
+ * Return: Returns type of clock (OUTPUT/EXTERNAL).
+ */
+static unsigned int pm_clock_type(unsigned int clock_id)
+{
+ return (clock_id < CLK_MAX_OUTPUT_CLK) ?
+ CLK_TYPE_OUTPUT : CLK_TYPE_EXTERNAL;
+}
+
+/**
+ * pm_api_clock_get_name() - PM call to request a clock's name
+ * @clock_id Clock ID
+ * @name Name of clock (max 16 bytes)
+ *
+ * This function is used by master to get nmae of clock specified
+ * by given clock ID.
+ *
+ * @return Returns success. In case of error, name data is 0.
+ */
+enum pm_ret_status pm_api_clock_get_name(unsigned int clock_id, char *name)
+{
+ if (clock_id == CLK_MAX)
+ memcpy(name, END_OF_CLK, CLK_NAME_LEN);
+ else if (!pm_clock_valid(clock_id))
+ memset(name, 0, CLK_NAME_LEN);
+ else if (clock_id < CLK_MAX_OUTPUT_CLK)
+ memcpy(name, clocks[clock_id].name, CLK_NAME_LEN);
+ else
+ memcpy(name, ext_clocks[clock_id - CLK_MAX_OUTPUT_CLK].name,
+ CLK_NAME_LEN);
+
+ return PM_RET_SUCCESS;
+}
+
+/**
+ * pm_api_clock_get_topology() - PM call to request a clock's topology
+ * @clock_id Clock ID
+ * @index Topology index for next toplogy node
+ * @topology Buffer to store nodes in topology and flags
+ *
+ * This function is used by master to get topology information for the
+ * clock specified by given clock ID. Each response would return 3
+ * topology nodes. To get next nodes, caller needs to call this API with
+ * index of next node. Index starts from 0.
+ *
+ * @return Returns status, either success or error+reason
+ */
+enum pm_ret_status pm_api_clock_get_topology(unsigned int clock_id,
+ unsigned int index,
+ uint32_t *topology)
+{
+ struct pm_clock_node *clock_nodes;
+ uint8_t num_nodes;
+ unsigned int i;
+
+ if (!pm_clock_valid(clock_id))
+ return PM_RET_ERROR_ARGS;
+
+ if (pm_clock_type(clock_id) != CLK_TYPE_OUTPUT)
+ return PM_RET_ERROR_NOTSUPPORTED;
+
+
+ memset(topology, 0, CLK_TOPOLOGY_PAYLOAD_LEN);
+ clock_nodes = *clocks[clock_id].nodes;
+ num_nodes = clocks[clock_id].num_nodes;
+
+ /* Skip parent till index */
+ if (index >= num_nodes)
+ return PM_RET_SUCCESS;
+
+ for (i = 0; i < 3U; i++) {
+ if ((index + i) == num_nodes)
+ break;
+ topology[i] = clock_nodes[index + i].type;
+ topology[i] |= clock_nodes[index + i].clkflags <<
+ CLK_CLKFLAGS_SHIFT;
+ topology[i] |= clock_nodes[index + i].typeflags <<
+ CLK_TYPEFLAGS_SHIFT;
+ }
+
+ return PM_RET_SUCCESS;
+}
+
+/**
+ * pm_api_clock_get_fixedfactor_params() - PM call to request a clock's fixed
+ * factor parameters for fixed clock
+ * @clock_id Clock ID
+ * @mul Multiplication value
+ * @div Divisor value
+ *
+ * This function is used by master to get fixed factor parameers for the
+ * fixed clock. This API is application only for the fixed clock.
+ *
+ * @return Returns status, either success or error+reason
+ */
+enum pm_ret_status pm_api_clock_get_fixedfactor_params(unsigned int clock_id,
+ uint32_t *mul,
+ uint32_t *div)
+{
+ struct pm_clock_node *clock_nodes;
+ uint8_t num_nodes;
+ unsigned int type, i;
+
+ if (!pm_clock_valid(clock_id))
+ return PM_RET_ERROR_ARGS;
+
+ if (pm_clock_type(clock_id) != CLK_TYPE_OUTPUT)
+ return PM_RET_ERROR_NOTSUPPORTED;
+
+ clock_nodes = *clocks[clock_id].nodes;
+ num_nodes = clocks[clock_id].num_nodes;
+
+ for (i = 0; i < num_nodes; i++) {
+ type = clock_nodes[i].type;
+ if (type == TYPE_FIXEDFACTOR) {
+ *mul = clock_nodes[i].mult;
+ *div = clock_nodes[i].div;
+ break;
+ }
+ }
+
+ /* Clock is not fixed clock */
+ if (i == num_nodes)
+ return PM_RET_ERROR_ARGS;
+
+ return PM_RET_SUCCESS;
+}
+
+/**
+ * pm_api_clock_get_parents() - PM call to request a clock's first 3 parents
+ * @clock_id Clock ID
+ * @index Index of next parent
+ * @parents Parents of the given clock
+ *
+ * This function is used by master to get clock's parents information.
+ * This API will return 3 parents with a single response. To get other
+ * parents, master should call same API in loop with new parent index
+ * till error is returned.
+ *
+ * E.g First call should have index 0 which will return parents 0, 1 and
+ * 2. Next call, index should be 3 which will return parent 3,4 and 5 and
+ * so on.
+ *
+ * @return Returns status, either success or error+reason
+ */
+enum pm_ret_status pm_api_clock_get_parents(unsigned int clock_id,
+ unsigned int index,
+ uint32_t *parents)
+{
+ unsigned int i;
+ int32_t *clk_parents;
+
+ if (!pm_clock_valid(clock_id))
+ return PM_RET_ERROR_ARGS;
+
+ if (pm_clock_type(clock_id) != CLK_TYPE_OUTPUT)
+ return PM_RET_ERROR_NOTSUPPORTED;
+
+ clk_parents = *clocks[clock_id].parents;
+ if (clk_parents == NULL)
+ return PM_RET_ERROR_ARGS;
+
+ memset(parents, 0, CLK_PARENTS_PAYLOAD_LEN);
+
+ /* Skip parent till index */
+ for (i = 0; i < index; i++)
+ if (clk_parents[i] == CLK_NA_PARENT)
+ return PM_RET_SUCCESS;
+
+ for (i = 0; i < 3; i++) {
+ parents[i] = clk_parents[index + i];
+ if (clk_parents[index + i] == CLK_NA_PARENT)
+ break;
+ }
+
+ return PM_RET_SUCCESS;
+}
+
+/**
+ * pm_api_clock_get_attributes() - PM call to request a clock's attributes
+ * @clock_id Clock ID
+ * @attr Clock attributes
+ *
+ * This function is used by master to get clock's attributes
+ * (e.g. valid, clock type, etc).
+ *
+ * @return Returns status, either success or error+reason
+ */
+enum pm_ret_status pm_api_clock_get_attributes(unsigned int clock_id,
+ uint32_t *attr)
+{
+ if (clock_id >= CLK_MAX)
+ return PM_RET_ERROR_ARGS;
+
+ /* Clock valid bit */
+ *attr = pm_clock_valid(clock_id);
+
+ /* If clock needs to be enabled during init */
+ *attr |= (pm_clock_init_enable(clock_id) << CLK_INIT_ENABLE_SHIFT);
+
+ /* Clock type (Output/External) */
+ *attr |= (pm_clock_type(clock_id) << CLK_TYPE_SHIFT);
+
+ return PM_RET_SUCCESS;
+}
+
+/**
+ * pll_get_lockbit() - Returns lockbit index for pll id
+ * @pll_id: Id of the pll
+ *
+ * This function return the PLL_LOCKED bit index in
+ * pll status register accosiated with given pll id.
+ *
+ * Return: Returns bit index
+ */
+static int pll_get_lockbit(unsigned int pll_id)
+{
+ switch (pll_id) {
+ case CLK_APLL_INT:
+ case CLK_IOPLL_INT:
+ return 0;
+ case CLK_DPLL_INT:
+ case CLK_RPLL_INT:
+ return 1;
+ case CLK_VPLL_INT:
+ return 2;
+ default:
+ return -1;
+ }
+}
+
+/**
+ * pm_api_pll_bypass_and_reset() - Bypass and reset PLL
+ * @clock_id: Id of the PLL
+ *
+ * This function is to bypass and reset PLL.
+ */
+static inline enum pm_ret_status
+pm_api_pll_bypass_and_reset(unsigned int clock_id, unsigned int flag)
+{
+ enum pm_ret_status ret = PM_RET_SUCCESS;
+ unsigned int reg, val;
+ int lockbit;
+
+ reg = clocks[clock_id].control_reg;
+
+ if (flag & CLK_PLL_RESET_ASSERT) {
+ ret = pm_mmio_write(reg, PLLCTRL_BP_MASK, PLLCTRL_BP_MASK);
+ if (ret != PM_RET_SUCCESS)
+ return ret;
+ ret = pm_mmio_write(reg, PLLCTRL_RESET_MASK,
+ PLLCTRL_RESET_MASK);
+ if (ret != PM_RET_SUCCESS)
+ return ret;
+ }
+ if (flag & CLK_PLL_RESET_RELEASE) {
+ ret = pm_mmio_write(reg, PLLCTRL_RESET_MASK,
+ ~PLLCTRL_RESET_MASK);
+ if (ret != PM_RET_SUCCESS)
+ return ret;
+
+ lockbit = pll_get_lockbit(clock_id);
+ do {
+ ret = pm_mmio_read(clocks[clock_id].status_reg, &val);
+ if (ret != PM_RET_SUCCESS)
+ return ret;
+ } while ((lockbit >= 0) && !(val & (1 << lockbit)));
+
+ ret = pm_mmio_write(reg, PLLCTRL_BP_MASK,
+ ~(unsigned int)PLLCTRL_BP_MASK);
+ }
+ return ret;
+}
+
+/**
+ * pm_api_clk_enable_disable() - Enable/Disable the clock for given id
+ * @clock_id: Id of the clock to be enabled
+ * @enable: Enable(1)/Disable(0)
+ *
+ * This function is to enable/disable the clock which is not PLL.
+ *
+ * Return: Returns status, either success or error+reason.
+ */
+static enum pm_ret_status pm_api_clk_enable_disable(unsigned int clock_id,
+ unsigned int enable)
+{
+ enum pm_ret_status ret = PM_RET_SUCCESS;
+ struct pm_clock_node *nodes = *clocks[clock_id].nodes;
+ uint8_t num_nodes = clocks[clock_id].num_nodes;
+ unsigned int reg, val;
+ uint8_t i = 0;
+ uint8_t offset = NA_SHIFT, width = NA_WIDTH;
+
+ if (clock_id == CLK_GEM0_TX || clock_id == CLK_GEM1_TX ||
+ clock_id == CLK_GEM2_TX || clock_id == CLK_GEM3_TX)
+ reg = clocks[clock_id].status_reg;
+ else
+ reg = clocks[clock_id].control_reg;
+
+ for (i = 0; i < num_nodes; i++) {
+ if (nodes->type == TYPE_GATE) {
+ offset = nodes->offset;
+ width = nodes->width;
+ break;
+ }
+ nodes++;
+ }
+ if (width == NA_WIDTH)
+ return PM_RET_ERROR_NOTSUPPORTED;
+
+ ret = pm_mmio_read(reg, &val);
+ if (ret != PM_RET_SUCCESS)
+ return ret;
+ if ((val & BIT_MASK(offset, width)) == enable)
+ return PM_RET_SUCCESS;
+
+ if (enable == 0)
+ val &= ~(BIT_MASK(offset, width));
+ else
+ val |= BIT_MASK(offset, width);
+
+ ret = pm_mmio_write(reg, BIT_MASK(offset, width), val);
+
+ return ret;
+}
+
+/**
+ * pm_api_clock_enable() - Enable the clock for given id
+ * @clock_id: Id of the clock to be enabled
+ *
+ * This function is used by master to enable the clock
+ * including peripherals and PLL clocks.
+ *
+ * Return: Returns status, either success or error+reason.
+ */
+enum pm_ret_status pm_api_clock_enable(unsigned int clock_id)
+{
+ enum pm_ret_status ret = PM_RET_SUCCESS;
+
+ if (!pm_clock_valid(clock_id))
+ return PM_RET_ERROR_ARGS;
+
+ if (pm_clock_type(clock_id) != CLK_TYPE_OUTPUT)
+ return PM_RET_ERROR_NOTSUPPORTED;
+
+ if (ISPLL(clock_id))
+ ret = pm_api_pll_bypass_and_reset(clock_id,
+ CLK_PLL_RESET_PULSE);
+ else
+ ret = pm_api_clk_enable_disable(clock_id, 1);
+
+ return ret;
+}
+
+/**
+ * pm_api_clock_disable - Disable the clock for given id
+ * @clock_id Id of the clock to be disable
+ *
+ * This function is used by master to disable the clock
+ * including peripherals and PLL clocks.
+ *
+ * Return: Returns status, either success or error+reason.
+ */
+
+enum pm_ret_status pm_api_clock_disable(unsigned int clock_id)
+{
+ enum pm_ret_status ret = PM_RET_SUCCESS;
+
+ if (!pm_clock_valid(clock_id))
+ return PM_RET_ERROR_ARGS;
+
+ if (pm_clock_type(clock_id) != CLK_TYPE_OUTPUT)
+ return PM_RET_ERROR_NOTSUPPORTED;
+
+ if (ISPLL(clock_id))
+ ret = pm_api_pll_bypass_and_reset(clock_id,
+ CLK_PLL_RESET_ASSERT);
+ else
+ ret = pm_api_clk_enable_disable(clock_id, 0);
+
+ return ret;
+}
+
+/**
+ * pm_api_get_pll_state() - Get state of PLL
+ * @clock_id Id of the PLL
+ * @state State of PLL(1: Enable, 0: Reset)
+ *
+ * This function is to check state of PLL.
+ */
+static inline enum pm_ret_status pm_api_get_pll_state(unsigned int clock_id,
+ unsigned int *state)
+{
+ enum pm_ret_status ret = PM_RET_SUCCESS;
+ unsigned int reg, val;
+
+ reg = clocks[clock_id].control_reg;
+
+ ret = pm_mmio_read(reg, &val);
+
+ /* state:
+ * 1 - PLL is enabled
+ * 0 - PLL is in reset state
+ */
+ *state = !(val & PLLCTRL_RESET_MASK);
+ return ret;
+}
+
+/**
+ * pm_api_get_clk_state() - Get the state of clock for given id
+ * @clock_id: Id of the clock to be enabled
+ * @state: Enable(1)/Disable(0)
+ *
+ * This function is to get state of the clock which is not PLL.
+ *
+ * Return: Returns status, either success or error+reason.
+ */
+static enum pm_ret_status pm_api_get_clk_state(unsigned int clock_id,
+ unsigned int *state)
+{
+ enum pm_ret_status ret = PM_RET_SUCCESS;
+ struct pm_clock_node *nodes = *clocks[clock_id].nodes;
+ uint8_t num_nodes = clocks[clock_id].num_nodes;
+ unsigned int reg, val;
+ uint8_t i = 0;
+ uint8_t offset = NA_SHIFT, width = NA_WIDTH;
+
+ reg = clocks[clock_id].control_reg;
+
+ for (i = 0; i < num_nodes; i++) {
+ if (nodes->type == TYPE_GATE) {
+ offset = nodes->offset;
+ width = nodes->width;
+ }
+ nodes++;
+ }
+ if (width == NA_WIDTH)
+ return PM_RET_ERROR_NOTSUPPORTED;
+
+ ret = pm_mmio_read(reg, &val);
+ *state = (val & BIT_MASK(offset, width)) >> offset;
+
+ return ret;
+}
+
+/**
+ * pm_api_clock_getstate - Get the clock state for given id
+ * @clock_id Id of the clock to be queried
+ * @state 1/0 (Enabled/Disabled)
+ *
+ * This function is used by master to get the state of clock
+ * including peripherals and PLL clocks.
+ *
+ * Return: Returns status, either success or error+reason.
+ */
+enum pm_ret_status pm_api_clock_getstate(unsigned int clock_id,
+ unsigned int *state)
+{
+ enum pm_ret_status ret = PM_RET_SUCCESS;
+
+ if (!pm_clock_valid(clock_id))
+ return PM_RET_ERROR_ARGS;
+
+ if (pm_clock_type(clock_id) != CLK_TYPE_OUTPUT)
+ return PM_RET_ERROR_NOTSUPPORTED;
+
+ if (ISPLL(clock_id))
+ ret = pm_api_get_pll_state(clock_id, state);
+ else
+ ret = pm_api_get_clk_state(clock_id, state);
+
+ return ret;
+}
+
+static enum pm_ret_status pm_api_clk_set_divider(unsigned int clock_id,
+ uint32_t divider)
+{
+ enum pm_ret_status ret = PM_RET_SUCCESS;
+ struct pm_clock_node *nodes;
+ uint8_t num_nodes;
+ uint16_t div1, div2;
+ unsigned int reg, mask = 0, val = 0, i;
+ uint8_t div1_width = NA_WIDTH, div1_offset = NA_SHIFT;
+ uint8_t div2_width = NA_WIDTH, div2_offset = NA_SHIFT;
+
+ div1 = (uint16_t)(divider & 0xFFFFU);
+ div2 = (uint16_t)((divider >> 16) & 0xFFFFU);
+
+ reg = clocks[clock_id].control_reg;
+
+ nodes = *clocks[clock_id].nodes;
+ num_nodes = clocks[clock_id].num_nodes;
+ for (i = 0; i < num_nodes; i++) {
+ if (nodes->type == TYPE_DIV1) {
+ div1_offset = nodes->offset;
+ div1_width = nodes->width;
+ }
+ if (nodes->type == TYPE_DIV2) {
+ div2_offset = nodes->offset;
+ div2_width = nodes->width;
+ }
+ nodes++;
+ }
+
+ if (div1 != (uint16_t)-1) {
+ if (div1_width == NA_WIDTH)
+ return PM_RET_ERROR_NOTSUPPORTED;
+ val |= div1 << div1_offset;
+ mask |= BIT_MASK(div1_offset, div1_width);
+ }
+ if (div2 != (uint16_t)-1) {
+ if (div2_width == NA_WIDTH)
+ return PM_RET_ERROR_NOTSUPPORTED;
+ val |= div2 << div2_offset;
+ mask |= BIT_MASK(div2_offset, div2_width);
+ }
+ ret = pm_mmio_write(reg, mask, val);
+
+ return ret;
+}
+
+static enum pm_ret_status pm_api_pll_set_divider(unsigned int clock_id,
+ unsigned int divider)
+{
+ unsigned int reg = clocks[clock_id].control_reg;
+
+ return pm_mmio_write(reg, PLL_FBDIV_MASK, divider << PLL_FBDIV_SHIFT);
+}
+
+/**
+ * pm_api_clock_setdivider - Set the clock divider for given id
+ * @clock_id Id of the clock
+ * @divider Divider value
+ *
+ * This function is used by master to set divider for any clock
+ * to achieve desired rate.
+ *
+ * Return: Returns status, either success or error+reason.
+ */
+enum pm_ret_status pm_api_clock_setdivider(unsigned int clock_id,
+ unsigned int divider)
+{
+ enum pm_ret_status ret;
+
+ if (!pm_clock_valid(clock_id))
+ return PM_RET_ERROR_ARGS;
+
+ if (pm_clock_type(clock_id) != CLK_TYPE_OUTPUT)
+ return PM_RET_ERROR_NOTSUPPORTED;
+
+ if (ISPLL(clock_id))
+ ret = pm_api_pll_set_divider(clock_id, divider);
+ else
+ ret = pm_api_clk_set_divider(clock_id, divider);
+
+ return ret;
+}
+
+static enum pm_ret_status pm_api_clk_get_divider(unsigned int clock_id,
+ uint32_t *divider)
+{
+ enum pm_ret_status ret = PM_RET_SUCCESS;
+ struct pm_clock_node *nodes;
+ uint8_t num_nodes;
+ unsigned int reg, val, i, div1 = 0, div2 = 0;
+ uint8_t div1_width = NA_WIDTH, div1_offset = NA_SHIFT;
+ uint8_t div2_width = NA_WIDTH, div2_offset = NA_SHIFT;
+
+ reg = clocks[clock_id].control_reg;
+
+ nodes = *clocks[clock_id].nodes;
+ num_nodes = clocks[clock_id].num_nodes;
+ for (i = 0; i < num_nodes; i++) {
+ if (nodes->type == TYPE_DIV1) {
+ div1_offset = nodes->offset;
+ div1_width = nodes->width;
+ }
+ if (nodes->type == TYPE_DIV2) {
+ div2_offset = nodes->offset;
+ div2_width = nodes->width;
+ }
+ nodes++;
+ }
+
+ ret = pm_mmio_read(reg, &val);
+
+ if (div1_width == NA_WIDTH)
+ return PM_RET_ERROR_ARGS;
+
+ div1 = (val & BIT_MASK(div1_offset, div1_width)) >> div1_offset;
+
+ if (div2_width != NA_WIDTH)
+ div2 = (val & BIT_MASK(div2_offset, div2_width)) >> div2_offset;
+
+ *divider = div1 | (div2 << 16);
+
+ return ret;
+}
+
+static enum pm_ret_status pm_api_pll_get_divider(unsigned int clock_id,
+ unsigned int *divider)
+{
+ enum pm_ret_status ret = PM_RET_SUCCESS;
+ unsigned int reg, val;
+
+ reg = clocks[clock_id].control_reg;
+
+ ret = pm_mmio_read(reg, &val);
+ *divider = (val & PLL_FBDIV_MASK) >> PLL_FBDIV_SHIFT;
+
+ return ret;
+}
+
+/**
+ * pm_api_clock_getdivider - Get the clock divider for given id
+ * @clock_id Id of the clock
+ * @divider Divider value
+ *
+ * This function is used by master to get divider values
+ * for any clock.
+ *
+ * Return: Returns status, either success or error+reason.
+ */
+enum pm_ret_status pm_api_clock_getdivider(unsigned int clock_id,
+ unsigned int *divider)
+{
+ enum pm_ret_status ret;
+
+ if (!pm_clock_valid(clock_id))
+ return PM_RET_ERROR_ARGS;
+
+ if (pm_clock_type(clock_id) != CLK_TYPE_OUTPUT)
+ return PM_RET_ERROR_NOTSUPPORTED;
+
+ if (ISPLL(clock_id))
+ ret = pm_api_pll_get_divider(clock_id, divider);
+ else
+ ret = pm_api_clk_get_divider(clock_id, divider);
+
+ return ret;
+}
+
+/**
+ * pm_api_clock_setrate - Set the clock rate for given id
+ * @clock_id Id of the clock
+ * @rate Rate value in hz
+ *
+ * This function is used by master to set rate for any clock.
+ *
+ * Return: Returns status, either success or error+reason.
+ */
+enum pm_ret_status pm_api_clock_setrate(unsigned int clock_id,
+ uint64_t rate)
+{
+ return PM_RET_ERROR_NOTSUPPORTED;
+}
+
+/**
+ * pm_api_clock_getrate - Get the clock rate for given id
+ * @clock_id Id of the clock
+ * @rate rate value in hz
+ *
+ * This function is used by master to get rate
+ * for any clock.
+ *
+ * Return: Returns status, either success or error+reason.
+ */
+enum pm_ret_status pm_api_clock_getrate(unsigned int clock_id,
+ uint64_t *rate)
+{
+ return PM_RET_ERROR_NOTSUPPORTED;
+}
+
+/**
+ * pm_api_clock_setparent - Set the clock parent for given id
+ * @clock_id Id of the clock
+ * @parent_id parent id
+ *
+ * This function is used by master to set parent for any clock.
+ *
+ * Return: Returns status, either success or error+reason.
+ */
+enum pm_ret_status pm_api_clock_setparent(unsigned int clock_id,
+ unsigned int parent_idx)
+{
+ enum pm_ret_status ret = PM_RET_SUCCESS;
+ struct pm_clock_node *nodes;
+ uint8_t num_nodes;
+ unsigned int reg, val;
+ int32_t *clk_parents;
+ unsigned int i = 0;
+ uint8_t offset = NA_SHIFT, width = NA_WIDTH;
+
+ if (!pm_clock_valid(clock_id))
+ return PM_RET_ERROR_ARGS;
+
+ if (pm_clock_type(clock_id) != CLK_TYPE_OUTPUT)
+ return PM_RET_ERROR_NOTSUPPORTED;
+
+ clk_parents = *clocks[clock_id].parents;
+
+ for (i = 0; i <= parent_idx; i++)
+ if (clk_parents[i] == CLK_NA_PARENT)
+ return PM_RET_ERROR_ARGS;
+
+ nodes = *clocks[clock_id].nodes;
+ num_nodes = clocks[clock_id].num_nodes;
+ for (i = 0; i < num_nodes; i++) {
+ if (nodes->type == TYPE_MUX) {
+ offset = nodes->offset;
+ width = nodes->width;
+ }
+ nodes++;
+ }
+ if (width == NA_WIDTH)
+ return PM_RET_ERROR_NOTSUPPORTED;
+
+ reg = clocks[clock_id].control_reg;
+ val = parent_idx << offset;
+ ret = pm_mmio_write(reg, BIT_MASK(offset, width), val);
+
+ return ret;
+}
+
+/**
+ * pm_api_clock_getparent - Get the clock parent for given id
+ * @clock_id Id of the clock
+ * @parent_id parent id
+ *
+ * This function is used by master to get parent index
+ * for any clock.
+ *
+ * Return: Returns status, either success or error+reason.
+ */
+enum pm_ret_status pm_api_clock_getparent(unsigned int clock_id,
+ unsigned int *parent_idx)
+{
+ enum pm_ret_status ret = PM_RET_SUCCESS;
+ struct pm_clock_node *nodes;
+ uint8_t num_nodes;
+ unsigned int reg, val;
+ uint8_t i = 0, offset = NA_SHIFT, width = NA_WIDTH;
+
+ if (!pm_clock_valid(clock_id))
+ return PM_RET_ERROR_ARGS;
+
+ if (pm_clock_type(clock_id) != CLK_TYPE_OUTPUT)
+ return PM_RET_ERROR_NOTSUPPORTED;
+
+ nodes = *clocks[clock_id].nodes;
+ num_nodes = clocks[clock_id].num_nodes;
+
+ for (i = 0; i < num_nodes; i++) {
+ if (nodes->type == TYPE_MUX) {
+ offset = nodes->offset;
+ width = nodes->width;
+ }
+ nodes++;
+ }
+ if (width == NA_WIDTH)
+ return PM_RET_ERROR_NOTSUPPORTED;
+
+ reg = clocks[clock_id].control_reg;
+ ret = pm_mmio_read(reg, &val);
+ val >>= offset;
+ val &= ((1U << width) - 1);
+
+ *parent_idx = val;
+
+ return ret;
+}
+
+/**
+ * pm_api_clk_set_pll_mode() - Set PLL mode
+ * @pll PLL id
+ * @mode Mode fraction/integar
+ *
+ * This function sets PLL mode.
+ *
+ * @return Returns status, either success or error+reason
+ */
+enum pm_ret_status pm_api_clk_set_pll_mode(unsigned int pll,
+ unsigned int mode)
+{
+ enum pm_ret_status ret = PM_RET_SUCCESS;
+ unsigned int reg;
+
+ if (!pm_clock_valid(pll))
+ return PM_RET_ERROR_ARGS;
+
+ if (pm_clock_type(pll) != CLK_TYPE_OUTPUT)
+ return PM_RET_ERROR_NOTSUPPORTED;
+
+ if (!ISPLL(pll))
+ return PM_RET_ERROR_NOTSUPPORTED;
+
+ if (mode != PLL_FRAC_MODE && mode != PLL_INT_MODE)
+ return PM_RET_ERROR_ARGS;
+
+ reg = clocks[pll].control_reg + PLL_FRAC_OFFSET;
+
+ ret = pm_mmio_write(reg, PLL_FRAC_MODE_MASK,
+ mode << PLL_FRAC_MODE_SHIFT);
+
+ return ret;
+}
+
+/**
+ * pm_ioctl_get_pll_mode() - Get PLL mode
+ * @pll PLL id
+ * @mode Mode fraction/integar
+ *
+ * This function returns current PLL mode.
+ *
+ * @return Returns status, either success or error+reason
+ */
+enum pm_ret_status pm_api_clk_get_pll_mode(unsigned int pll,
+ unsigned int *mode)
+{
+ enum pm_ret_status ret = PM_RET_SUCCESS;
+ unsigned int val, reg;
+
+ if (!pm_clock_valid(pll))
+ return PM_RET_ERROR_ARGS;
+
+ if (pm_clock_type(pll) != CLK_TYPE_OUTPUT)
+ return PM_RET_ERROR_NOTSUPPORTED;
+
+ if (!ISPLL(pll))
+ return PM_RET_ERROR_NOTSUPPORTED;
+
+ reg = clocks[pll].control_reg + PLL_FRAC_OFFSET;
+
+ ret = pm_mmio_read(reg, &val);
+ val = val & PLL_FRAC_MODE_MASK;
+ if (val == 0)
+ *mode = PLL_INT_MODE;
+ else
+ *mode = PLL_FRAC_MODE;
+
+ return ret;
+}
+
+/**
+ * pm_api_clk_set_pll_frac_data() - Set PLL fraction data
+ * @pll PLL id
+ * @data fraction data
+ *
+ * This function sets fraction data. It is valid for fraction
+ * mode only.
+ *
+ * @return Returns status, either success or error+reason
+ */
+enum pm_ret_status pm_api_clk_set_pll_frac_data(unsigned int pll,
+ unsigned int data)
+{
+ enum pm_ret_status ret = PM_RET_SUCCESS;
+ unsigned int val, reg, mode = 0;
+
+ if (!pm_clock_valid(pll))
+ return PM_RET_ERROR_ARGS;
+
+ if (pm_clock_type(pll) != CLK_TYPE_OUTPUT)
+ return PM_RET_ERROR_NOTSUPPORTED;
+
+ if (!ISPLL(pll))
+ return PM_RET_ERROR_NOTSUPPORTED;
+
+ ret = pm_api_clk_get_pll_mode(pll, &mode);
+ if (ret != PM_RET_SUCCESS)
+ return ret;
+ if (mode == PLL_FRAC_MODE) {
+ reg = clocks[pll].control_reg + PLL_FRAC_OFFSET;
+ val = data << PLL_FRAC_DATA_SHIFT;
+ ret = pm_mmio_write(reg, PLL_FRAC_DATA_MASK, val);
+ } else {
+ return PM_RET_ERROR_ARGS;
+ }
+
+ return ret;
+}
+
+/**
+ * pm_api_clk_get_pll_frac_data() - Get PLL fraction data
+ * @pll PLL id
+ * @data fraction data
+ *
+ * This function returns fraction data value.
+ *
+ * @return Returns status, either success or error+reason
+ */
+enum pm_ret_status pm_api_clk_get_pll_frac_data(unsigned int pll,
+ unsigned int *data)
+{
+ enum pm_ret_status ret = PM_RET_SUCCESS;
+ unsigned int val, reg;
+
+ if (!pm_clock_valid(pll))
+ return PM_RET_ERROR_ARGS;
+
+ if (pm_clock_type(pll) != CLK_TYPE_OUTPUT)
+ return PM_RET_ERROR_NOTSUPPORTED;
+
+ if (!ISPLL(pll))
+ return PM_RET_ERROR_NOTSUPPORTED;
+
+ reg = clocks[pll].control_reg + PLL_FRAC_OFFSET;
+
+ ret = pm_mmio_read(reg, &val);
+ *data = (val & PLL_FRAC_DATA_MASK);
+
+ return ret;
+}
diff --git a/plat/xilinx/zynqmp/pm_service/pm_api_clock.h b/plat/xilinx/zynqmp/pm_service/pm_api_clock.h
new file mode 100644
index 0000000..56f850a
--- /dev/null
+++ b/plat/xilinx/zynqmp/pm_service/pm_api_clock.h
@@ -0,0 +1,315 @@
+/*
+ * Copyright (c) 2018, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+/*
+ * ZynqMP system level PM-API functions for clock control.
+ */
+
+#ifndef _PM_API_CLOCK_H_
+#define _PM_API_CLOCK_H_
+
+#include <utils_def.h>
+#include "pm_common.h"
+
+#define CLK_NAME_LEN U(15)
+#define MAX_PARENTS U(100)
+#define CLK_NA_PARENT -1
+#define CLK_DUMMY_PARENT -2
+
+/* Flags for parent id */
+#define PARENT_CLK_SELF U(0)
+#define PARENT_CLK_NODE1 U(1)
+#define PARENT_CLK_NODE2 U(2)
+#define PARENT_CLK_NODE3 U(3)
+#define PARENT_CLK_NODE4 U(4)
+#define PARENT_CLK_EXTERNAL U(5)
+#define PARENT_CLK_MIO0_MIO77 U(6)
+
+#define CLK_SET_RATE_GATE BIT(0) /* must be gated across rate change */
+#define CLK_SET_PARENT_GATE BIT(1) /* must be gated across re-parent */
+#define CLK_SET_RATE_PARENT BIT(2) /* propagate rate change up one level */
+#define CLK_IGNORE_UNUSED BIT(3) /* do not gate even if unused */
+/* unused */
+#define CLK_IS_BASIC BIT(5) /* Basic clk, can't do a to_clk_foo() */
+#define CLK_GET_RATE_NOCACHE BIT(6) /* do not use the cached clk rate */
+#define CLK_SET_RATE_NO_REPARENT BIT(7) /* don't re-parent on rate change */
+#define CLK_GET_ACCURACY_NOCACHE BIT(8) /* do not use the cached clk accuracy */
+#define CLK_RECALC_NEW_RATES BIT(9) /* recalc rates after notifications */
+#define CLK_SET_RATE_UNGATE BIT(10) /* clock needs to run to set rate */
+#define CLK_IS_CRITICAL BIT(11) /* do not gate, ever */
+/* parents need enable during gate/ungate, set rate and re-parent */
+#define CLK_OPS_PARENT_ENABLE BIT(12)
+#define CLK_FRAC BIT(13)
+
+#define CLK_DIVIDER_ONE_BASED BIT(0)
+#define CLK_DIVIDER_POWER_OF_TWO BIT(1)
+#define CLK_DIVIDER_ALLOW_ZERO BIT(2)
+#define CLK_DIVIDER_HIWORD_MASK BIT(3)
+#define CLK_DIVIDER_ROUND_CLOSEST BIT(4)
+#define CLK_DIVIDER_READ_ONLY BIT(5)
+#define CLK_DIVIDER_MAX_AT_ZERO BIT(6)
+
+#define END_OF_CLK "END_OF_CLK"
+
+//CLock Ids
+enum {
+ CLK_IOPLL,
+ CLK_RPLL,
+ CLK_APLL,
+ CLK_DPLL,
+ CLK_VPLL,
+ CLK_IOPLL_TO_FPD,
+ CLK_RPLL_TO_FPD,
+ CLK_APLL_TO_LPD,
+ CLK_DPLL_TO_LPD,
+ CLK_VPLL_TO_LPD,
+ CLK_ACPU,
+ CLK_ACPU_HALF,
+ CLK_DBG_FPD,
+ CLK_DBG_LPD,
+ CLK_DBG_TRACE,
+ CLK_DBG_TSTMP,
+ CLK_DP_VIDEO_REF,
+ CLK_DP_AUDIO_REF,
+ CLK_DP_STC_REF,
+ CLK_GDMA_REF,
+ CLK_DPDMA_REF,
+ CLK_DDR_REF,
+ CLK_SATA_REF,
+ CLK_PCIE_REF,
+ CLK_GPU_REF,
+ CLK_GPU_PP0_REF,
+ CLK_GPU_PP1_REF,
+ CLK_TOPSW_MAIN,
+ CLK_TOPSW_LSBUS,
+ CLK_GTGREF0_REF,
+ CLK_LPD_SWITCH,
+ CLK_LPD_LSBUS,
+ CLK_USB0_BUS_REF,
+ CLK_USB1_BUS_REF,
+ CLK_USB3_DUAL_REF,
+ CLK_USB0,
+ CLK_USB1,
+ CLK_CPU_R5,
+ CLK_CPU_R5_CORE,
+ CLK_CSU_SPB,
+ CLK_CSU_PLL,
+ CLK_PCAP,
+ CLK_IOU_SWITCH,
+ CLK_GEM_TSU_REF,
+ CLK_GEM_TSU,
+ CLK_GEM0_REF,
+ CLK_GEM1_REF,
+ CLK_GEM2_REF,
+ CLK_GEM3_REF,
+ CLK_GEM0_TX,
+ CLK_GEM1_TX,
+ CLK_GEM2_TX,
+ CLK_GEM3_TX,
+ CLK_QSPI_REF,
+ CLK_SDIO0_REF,
+ CLK_SDIO1_REF,
+ CLK_UART0_REF,
+ CLK_UART1_REF,
+ CLK_SPI0_REF,
+ CLK_SPI1_REF,
+ CLK_NAND_REF,
+ CLK_I2C0_REF,
+ CLK_I2C1_REF,
+ CLK_CAN0_REF,
+ CLK_CAN1_REF,
+ CLK_CAN0,
+ CLK_CAN1,
+ CLK_DLL_REF,
+ CLK_ADMA_REF,
+ CLK_TIMESTAMP_REF,
+ CLK_AMS_REF,
+ CLK_PL0_REF,
+ CLK_PL1_REF,
+ CLK_PL2_REF,
+ CLK_PL3_REF,
+ CLK_WDT,
+ CLK_IOPLL_INT,
+ CLK_IOPLL_PRE_SRC,
+ CLK_IOPLL_HALF,
+ CLK_IOPLL_INT_MUX,
+ CLK_IOPLL_POST_SRC,
+ CLK_RPLL_INT,
+ CLK_RPLL_PRE_SRC,
+ CLK_RPLL_HALF,
+ CLK_RPLL_INT_MUX,
+ CLK_RPLL_POST_SRC,
+ CLK_APLL_INT,
+ CLK_APLL_PRE_SRC,
+ CLK_APLL_HALF,
+ CLK_APLL_INT_MUX,
+ CLK_APLL_POST_SRC,
+ CLK_DPLL_INT,
+ CLK_DPLL_PRE_SRC,
+ CLK_DPLL_HALF,
+ CLK_DPLL_INT_MUX,
+ CLK_DPLL_POST_SRC,
+ CLK_VPLL_INT,
+ CLK_VPLL_PRE_SRC,
+ CLK_VPLL_HALF,
+ CLK_VPLL_INT_MUX,
+ CLK_VPLL_POST_SRC,
+ CLK_CAN0_MIO,
+ CLK_CAN1_MIO,
+ END_OF_OUTPUT_CLKS,
+};
+
+#define CLK_MAX_OUTPUT_CLK (unsigned int)(END_OF_OUTPUT_CLKS)
+
+//External clock ids
+enum {
+ EXT_CLK_PSS_REF = END_OF_OUTPUT_CLKS,
+ EXT_CLK_VIDEO,
+ EXT_CLK_PSS_ALT_REF,
+ EXT_CLK_AUX_REF,
+ EXT_CLK_GT_CRX_REF,
+ EXT_CLK_SWDT0,
+ EXT_CLK_SWDT1,
+ EXT_CLK_GEM0_EMIO,
+ EXT_CLK_GEM1_EMIO,
+ EXT_CLK_GEM2_EMIO,
+ EXT_CLK_GEM3_EMIO,
+ EXT_CLK_MIO50_OR_MIO51,
+ EXT_CLK_MIO0,
+ EXT_CLK_MIO1,
+ EXT_CLK_MIO2,
+ EXT_CLK_MIO3,
+ EXT_CLK_MIO4,
+ EXT_CLK_MIO5,
+ EXT_CLK_MIO6,
+ EXT_CLK_MIO7,
+ EXT_CLK_MIO8,
+ EXT_CLK_MIO9,
+ EXT_CLK_MIO10,
+ EXT_CLK_MIO11,
+ EXT_CLK_MIO12,
+ EXT_CLK_MIO13,
+ EXT_CLK_MIO14,
+ EXT_CLK_MIO15,
+ EXT_CLK_MIO16,
+ EXT_CLK_MIO17,
+ EXT_CLK_MIO18,
+ EXT_CLK_MIO19,
+ EXT_CLK_MIO20,
+ EXT_CLK_MIO21,
+ EXT_CLK_MIO22,
+ EXT_CLK_MIO23,
+ EXT_CLK_MIO24,
+ EXT_CLK_MIO25,
+ EXT_CLK_MIO26,
+ EXT_CLK_MIO27,
+ EXT_CLK_MIO28,
+ EXT_CLK_MIO29,
+ EXT_CLK_MIO30,
+ EXT_CLK_MIO31,
+ EXT_CLK_MIO32,
+ EXT_CLK_MIO33,
+ EXT_CLK_MIO34,
+ EXT_CLK_MIO35,
+ EXT_CLK_MIO36,
+ EXT_CLK_MIO37,
+ EXT_CLK_MIO38,
+ EXT_CLK_MIO39,
+ EXT_CLK_MIO40,
+ EXT_CLK_MIO41,
+ EXT_CLK_MIO42,
+ EXT_CLK_MIO43,
+ EXT_CLK_MIO44,
+ EXT_CLK_MIO45,
+ EXT_CLK_MIO46,
+ EXT_CLK_MIO47,
+ EXT_CLK_MIO48,
+ EXT_CLK_MIO49,
+ EXT_CLK_MIO50,
+ EXT_CLK_MIO51,
+ EXT_CLK_MIO52,
+ EXT_CLK_MIO53,
+ EXT_CLK_MIO54,
+ EXT_CLK_MIO55,
+ EXT_CLK_MIO56,
+ EXT_CLK_MIO57,
+ EXT_CLK_MIO58,
+ EXT_CLK_MIO59,
+ EXT_CLK_MIO60,
+ EXT_CLK_MIO61,
+ EXT_CLK_MIO62,
+ EXT_CLK_MIO63,
+ EXT_CLK_MIO64,
+ EXT_CLK_MIO65,
+ EXT_CLK_MIO66,
+ EXT_CLK_MIO67,
+ EXT_CLK_MIO68,
+ EXT_CLK_MIO69,
+ EXT_CLK_MIO70,
+ EXT_CLK_MIO71,
+ EXT_CLK_MIO72,
+ EXT_CLK_MIO73,
+ EXT_CLK_MIO74,
+ EXT_CLK_MIO75,
+ EXT_CLK_MIO76,
+ EXT_CLK_MIO77,
+ END_OF_CLKS,
+};
+
+#define CLK_MAX (unsigned int)(END_OF_CLKS)
+
+//CLock types
+#define CLK_TYPE_OUTPUT 0U
+#define CLK_TYPE_EXTERNAL 1U
+
+//Topology types
+#define TYPE_INVALID 0U
+#define TYPE_MUX 1U
+#define TYPE_PLL 2U
+#define TYPE_FIXEDFACTOR 3U
+#define TYPE_DIV1 4U
+#define TYPE_DIV2 5U
+#define TYPE_GATE 6U
+
+
+enum pm_ret_status pm_api_clock_get_name(unsigned int clock_id, char *name);
+enum pm_ret_status pm_api_clock_get_topology(unsigned int clock_id,
+ unsigned int index,
+ uint32_t *topology);
+enum pm_ret_status pm_api_clock_get_fixedfactor_params(unsigned int clock_id,
+ uint32_t *mul,
+ uint32_t *div);
+enum pm_ret_status pm_api_clock_get_parents(unsigned int clock_id,
+ unsigned int index,
+ uint32_t *parents);
+enum pm_ret_status pm_api_clock_get_attributes(unsigned int clock_id,
+ uint32_t *attr);
+enum pm_ret_status pm_api_clock_enable(unsigned int clock_id);
+enum pm_ret_status pm_api_clock_disable(unsigned int clock_id);
+enum pm_ret_status pm_api_clock_getstate(unsigned int clock_id,
+ unsigned int *state);
+enum pm_ret_status pm_api_clock_setdivider(unsigned int clock_id,
+ unsigned int divider);
+enum pm_ret_status pm_api_clock_getdivider(unsigned int clock_id,
+ unsigned int *divider);
+enum pm_ret_status pm_api_clock_setrate(unsigned int clock_id,
+ uint64_t rate);
+enum pm_ret_status pm_api_clock_getrate(unsigned int clock_id,
+ uint64_t *rate);
+enum pm_ret_status pm_api_clock_setparent(unsigned int clock_id,
+ unsigned int parent_idx);
+enum pm_ret_status pm_api_clock_getparent(unsigned int clock_id,
+ unsigned int *parent_idx);
+enum pm_ret_status pm_api_clk_set_pll_mode(unsigned int pll,
+ unsigned int mode);
+enum pm_ret_status pm_api_clk_get_pll_mode(unsigned int pll,
+ unsigned int *mode);
+enum pm_ret_status pm_api_clk_set_pll_frac_data(unsigned int pll,
+ unsigned int data);
+enum pm_ret_status pm_api_clk_get_pll_frac_data(unsigned int pll,
+ unsigned int *data);
+
+#endif /* _PM_API_CLOCK_H_ */
diff --git a/plat/xilinx/zynqmp/pm_service/pm_api_ioctl.c b/plat/xilinx/zynqmp/pm_service/pm_api_ioctl.c
new file mode 100644
index 0000000..cdbb515
--- /dev/null
+++ b/plat/xilinx/zynqmp/pm_service/pm_api_ioctl.c
@@ -0,0 +1,549 @@
+/*
+ * Copyright (c) 2018, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+/*
+ * ZynqMP system level PM-API functions for ioctl.
+ */
+
+#include <arch_helpers.h>
+#include <delay_timer.h>
+#include <mmio.h>
+#include <platform.h>
+#include "pm_api_clock.h"
+#include "pm_api_ioctl.h"
+#include "pm_api_sys.h"
+#include "pm_client.h"
+#include "pm_common.h"
+#include "pm_ipi.h"
+#include "../zynqmp_def.h"
+
+/**
+ * pm_ioctl_get_rpu_oper_mode () - Get current RPU operation mode
+ * @mode Buffer to store value of oper mode(Split/Lock-step)
+ *
+ * This function provides current configured RPU operational mode.
+ *
+ * @return Returns status, either success or error+reason
+ */
+static enum pm_ret_status pm_ioctl_get_rpu_oper_mode(unsigned int *mode)
+{
+ unsigned int val;
+
+ val = mmio_read_32(ZYNQMP_RPU_GLBL_CNTL);
+ val &= ZYNQMP_SLSPLIT_MASK;
+ if (val == 0)
+ *mode = PM_RPU_MODE_LOCKSTEP;
+ else
+ *mode = PM_RPU_MODE_SPLIT;
+
+ return PM_RET_SUCCESS;
+}
+
+/**
+ * pm_ioctl_set_rpu_oper_mode () - Configure RPU operation mode
+ * @mode Value to set for oper mode(Split/Lock-step)
+ *
+ * This function configures RPU operational mode(Split/Lock-step).
+ * It also sets TCM combined mode in RPU lock-step and TCM non-combined
+ * mode for RPU split mode. In case of Lock step mode, RPU1's output is
+ * clamped.
+ *
+ * @return Returns status, either success or error+reason
+ */
+static enum pm_ret_status pm_ioctl_set_rpu_oper_mode(unsigned int mode)
+{
+ unsigned int val;
+
+ if (mmio_read_32(CRL_APB_RST_LPD_TOP) && CRL_APB_RPU_AMBA_RESET)
+ return PM_RET_ERROR_ACCESS;
+
+ val = mmio_read_32(ZYNQMP_RPU_GLBL_CNTL);
+
+ if (mode == PM_RPU_MODE_SPLIT) {
+ val |= ZYNQMP_SLSPLIT_MASK;
+ val &= ~ZYNQMP_TCM_COMB_MASK;
+ val &= ~ZYNQMP_SLCLAMP_MASK;
+ } else if (mode == PM_RPU_MODE_LOCKSTEP) {
+ val &= ~ZYNQMP_SLSPLIT_MASK;
+ val |= ZYNQMP_TCM_COMB_MASK;
+ val |= ZYNQMP_SLCLAMP_MASK;
+ } else {
+ return PM_RET_ERROR_ARGS;
+ }
+
+ mmio_write_32(ZYNQMP_RPU_GLBL_CNTL, val);
+
+ return PM_RET_SUCCESS;
+}
+
+/**
+ * pm_ioctl_config_boot_addr() - Configure RPU boot address
+ * @nid Node ID of RPU
+ * @value Value to set for boot address (TCM/OCM)
+ *
+ * This function configures RPU boot address(memory).
+ *
+ * @return Returns status, either success or error+reason
+ */
+static enum pm_ret_status pm_ioctl_config_boot_addr(enum pm_node_id nid,
+ unsigned int value)
+{
+ unsigned int rpu_cfg_addr, val;
+
+ if (nid == NODE_RPU_0)
+ rpu_cfg_addr = ZYNQMP_RPU0_CFG;
+ else if (nid == NODE_RPU_1)
+ rpu_cfg_addr = ZYNQMP_RPU1_CFG;
+ else
+ return PM_RET_ERROR_ARGS;
+
+ val = mmio_read_32(rpu_cfg_addr);
+
+ if (value == PM_RPU_BOOTMEM_LOVEC)
+ val &= ~ZYNQMP_VINITHI_MASK;
+ else if (value == PM_RPU_BOOTMEM_HIVEC)
+ val |= ZYNQMP_VINITHI_MASK;
+ else
+ return PM_RET_ERROR_ARGS;
+
+ mmio_write_32(rpu_cfg_addr, val);
+
+ return PM_RET_SUCCESS;
+}
+
+/**
+ * pm_ioctl_config_tcm_comb() - Configure TCM combined mode
+ * @value Value to set (Split/Combined)
+ *
+ * This function configures TCM to be in split mode or combined
+ * mode.
+ *
+ * @return Returns status, either success or error+reason
+ */
+static enum pm_ret_status pm_ioctl_config_tcm_comb(unsigned int value)
+{
+ unsigned int val;
+
+ val = mmio_read_32(ZYNQMP_RPU_GLBL_CNTL);
+
+ if (value == PM_RPU_TCM_SPLIT)
+ val &= ~ZYNQMP_TCM_COMB_MASK;
+ else if (value == PM_RPU_TCM_COMB)
+ val |= ZYNQMP_TCM_COMB_MASK;
+ else
+ return PM_RET_ERROR_ARGS;
+
+ mmio_write_32(ZYNQMP_RPU_GLBL_CNTL, val);
+
+ return PM_RET_SUCCESS;
+}
+
+/**
+ * pm_ioctl_set_tapdelay_bypass() - Enable/Disable tap delay bypass
+ * @type Type of tap delay to enable/disable (e.g. QSPI)
+ * @value Enable/Disable
+ *
+ * This function enable/disable tap delay bypass.
+ *
+ * @return Returns status, either success or error+reason
+ */
+static enum pm_ret_status pm_ioctl_set_tapdelay_bypass(unsigned int type,
+ unsigned int value)
+{
+ if ((value != PM_TAPDELAY_BYPASS_ENABLE &&
+ value != PM_TAPDELAY_BYPASS_DISABLE) || type >= PM_TAPDELAY_MAX)
+ return PM_RET_ERROR_ARGS;
+
+ return pm_mmio_write(IOU_TAPDLY_BYPASS, TAP_DELAY_MASK, value << type);
+}
+
+/**
+ * pm_ioctl_set_sgmii_mode() - Set SGMII mode for the GEM device
+ * @nid Node ID of the device
+ * @value Enable/Disable
+ *
+ * This function enable/disable SGMII mode for the GEM device.
+ * While enabling SGMII mode, it also ties the GEM PCS Signal
+ * Detect to 1 and selects EMIO for RX clock generation.
+ *
+ * @return Returns status, either success or error+reason
+ */
+static enum pm_ret_status pm_ioctl_set_sgmii_mode(enum pm_node_id nid,
+ unsigned int value)
+{
+ unsigned int val, mask, shift;
+ enum pm_ret_status ret;
+
+ if (value != PM_SGMII_DISABLE && value != PM_SGMII_ENABLE)
+ return PM_RET_ERROR_ARGS;
+
+ switch (nid) {
+ case NODE_ETH_0:
+ shift = 0;
+ break;
+ case NODE_ETH_1:
+ shift = 1;
+ break;
+ case NODE_ETH_2:
+ shift = 2;
+ break;
+ case NODE_ETH_3:
+ shift = 3;
+ break;
+ default:
+ return PM_RET_ERROR_ARGS;
+ }
+
+ if (value == PM_SGMII_DISABLE) {
+ mask = GEM_SGMII_MASK << GEM_CLK_CTRL_OFFSET * shift;
+ ret = pm_mmio_write(IOU_GEM_CLK_CTRL, mask, 0U);
+ } else {
+ /* Tie the GEM PCS Signal Detect to 1 */
+ mask = SGMII_SD_MASK << SGMII_SD_OFFSET * shift;
+ val = SGMII_PCS_SD_1 << SGMII_SD_OFFSET * shift;
+ ret = pm_mmio_write(IOU_GEM_CTRL, mask, val);
+ if (ret != PM_RET_SUCCESS)
+ return ret;
+
+ /* Set the GEM to SGMII mode */
+ mask = GEM_CLK_CTRL_MASK << GEM_CLK_CTRL_OFFSET * shift;
+ val = GEM_RX_SRC_SEL_GTR | GEM_SGMII_MODE;
+ val <<= GEM_CLK_CTRL_OFFSET * shift;
+ ret = pm_mmio_write(IOU_GEM_CLK_CTRL, mask, val);
+ }
+
+ return ret;
+}
+
+/**
+ * pm_ioctl_sd_dll_reset() - Reset DLL logic
+ * @nid Node ID of the device
+ * @type Reset type
+ *
+ * This function resets DLL logic for the SD device.
+ *
+ * @return Returns status, either success or error+reason
+ */
+static enum pm_ret_status pm_ioctl_sd_dll_reset(enum pm_node_id nid,
+ unsigned int type)
+{
+ unsigned int mask, val;
+ enum pm_ret_status ret;
+
+ if (nid == NODE_SD_0) {
+ mask = ZYNQMP_SD0_DLL_RST_MASK;
+ val = ZYNQMP_SD0_DLL_RST;
+ } else if (nid == NODE_SD_1) {
+ mask = ZYNQMP_SD1_DLL_RST_MASK;
+ val = ZYNQMP_SD1_DLL_RST;
+ } else {
+ return PM_RET_ERROR_ARGS;
+ }
+
+ switch (type) {
+ case PM_DLL_RESET_ASSERT:
+ case PM_DLL_RESET_PULSE:
+ ret = pm_mmio_write(ZYNQMP_SD_DLL_CTRL, mask, val);
+ if (ret != PM_RET_SUCCESS)
+ return ret;
+
+ if (type == PM_DLL_RESET_ASSERT)
+ break;
+ mdelay(1);
+ case PM_DLL_RESET_RELEASE:
+ ret = pm_mmio_write(ZYNQMP_SD_DLL_CTRL, mask, 0);
+ break;
+ default:
+ ret = PM_RET_ERROR_ARGS;
+ break;
+ }
+
+ return ret;
+}
+
+/**
+ * pm_ioctl_sd_set_tapdelay() - Set tap delay for the SD device
+ * @nid Node ID of the device
+ * @type Type of tap delay to set (input/output)
+ * @value Value to set fot the tap delay
+ *
+ * This function sets input/output tap delay for the SD device.
+ *
+ * @return Returns status, either success or error+reason
+ */
+static enum pm_ret_status pm_ioctl_sd_set_tapdelay(enum pm_node_id nid,
+ enum tap_delay_type type,
+ unsigned int value)
+{
+ unsigned int shift;
+ enum pm_ret_status ret;
+
+ if (nid == NODE_SD_0)
+ shift = 0;
+ else if (nid == NODE_SD_1)
+ shift = ZYNQMP_SD_TAP_OFFSET;
+ else
+ return PM_RET_ERROR_ARGS;
+
+ ret = pm_ioctl_sd_dll_reset(nid, PM_DLL_RESET_ASSERT);
+ if (ret != PM_RET_SUCCESS)
+ return ret;
+
+ if (type == PM_TAPDELAY_INPUT) {
+ ret = pm_mmio_write(ZYNQMP_SD_ITAP_DLY,
+ (ZYNQMP_SD_ITAPCHGWIN_MASK << shift),
+ (ZYNQMP_SD_ITAPCHGWIN << shift));
+ if (ret != PM_RET_SUCCESS)
+ goto reset_release;
+ ret = pm_mmio_write(ZYNQMP_SD_ITAP_DLY,
+ (ZYNQMP_SD_ITAPDLYENA_MASK << shift),
+ (ZYNQMP_SD_ITAPDLYENA << shift));
+ if (ret != PM_RET_SUCCESS)
+ goto reset_release;
+ ret = pm_mmio_write(ZYNQMP_SD_ITAP_DLY,
+ (ZYNQMP_SD_ITAPDLYSEL_MASK << shift),
+ (value << shift));
+ if (ret != PM_RET_SUCCESS)
+ goto reset_release;
+ ret = pm_mmio_write(ZYNQMP_SD_ITAP_DLY,
+ (ZYNQMP_SD_ITAPCHGWIN_MASK << shift), 0);
+ } else if (type == PM_TAPDELAY_OUTPUT) {
+ ret = pm_mmio_write(ZYNQMP_SD_OTAP_DLY,
+ (ZYNQMP_SD_OTAPDLYENA_MASK << shift),
+ (ZYNQMP_SD_OTAPDLYENA << shift));
+ if (ret != PM_RET_SUCCESS)
+ goto reset_release;
+ ret = pm_mmio_write(ZYNQMP_SD_OTAP_DLY,
+ (ZYNQMP_SD_OTAPDLYSEL_MASK << shift),
+ (value << shift));
+ } else {
+ ret = PM_RET_ERROR_ARGS;
+ }
+
+reset_release:
+ pm_ioctl_sd_dll_reset(nid, PM_DLL_RESET_RELEASE);
+ return ret;
+}
+
+/**
+ * pm_ioctl_set_pll_frac_mode() - Ioctl function for
+ * setting pll mode
+ * @pll PLL id
+ * @mode Mode fraction/integar
+ *
+ * This function sets PLL mode
+ *
+ * @return Returns status, either success or error+reason
+ */
+static enum pm_ret_status pm_ioctl_set_pll_frac_mode
+ (unsigned int pll, unsigned int mode)
+{
+ return pm_api_clk_set_pll_mode(pll, mode);
+}
+
+/**
+ * pm_ioctl_get_pll_frac_mode() - Ioctl function for
+ * getting pll mode
+ * @pll PLL id
+ * @mode Mode fraction/integar
+ *
+ * This function return current PLL mode
+ *
+ * @return Returns status, either success or error+reason
+ */
+static enum pm_ret_status pm_ioctl_get_pll_frac_mode
+ (unsigned int pll, unsigned int *mode)
+{
+ return pm_api_clk_get_pll_mode(pll, mode);
+}
+
+/**
+ * pm_ioctl_set_pll_frac_data() - Ioctl function for
+ * setting pll fraction data
+ * @pll PLL id
+ * @data fraction data
+ *
+ * This function sets fraction data.
+ * It is valid for fraction mode only.
+ *
+ * @return Returns status, either success or error+reason
+ */
+static enum pm_ret_status pm_ioctl_set_pll_frac_data
+ (unsigned int pll, unsigned int data)
+{
+ return pm_api_clk_set_pll_frac_data(pll, data);
+}
+
+/**
+ * pm_ioctl_get_pll_frac_data() - Ioctl function for
+ * getting pll fraction data
+ * @pll PLL id
+ * @data fraction data
+ *
+ * This function returns fraction data value.
+ *
+ * @return Returns status, either success or error+reason
+ */
+static enum pm_ret_status pm_ioctl_get_pll_frac_data
+ (unsigned int pll, unsigned int *data)
+{
+ return pm_api_clk_get_pll_frac_data(pll, data);
+}
+
+/**
+ * pm_ioctl_write_ggs() - Ioctl function for writing
+ * global general storage (ggs)
+ * @index GGS register index
+ * @value Register value to be written
+ *
+ * This function writes value to GGS register.
+ *
+ * @return Returns status, either success or error+reason
+ */
+static enum pm_ret_status pm_ioctl_write_ggs(unsigned int index,
+ unsigned int value)
+{
+ if (index >= GGS_NUM_REGS)
+ return PM_RET_ERROR_ARGS;
+
+ return pm_mmio_write(GGS_BASEADDR + (index << 2),
+ 0xFFFFFFFFU, value);
+}
+
+/**
+ * pm_ioctl_read_ggs() - Ioctl function for reading
+ * global general storage (ggs)
+ * @index GGS register index
+ * @value Register value
+ *
+ * This function returns GGS register value.
+ *
+ * @return Returns status, either success or error+reason
+ */
+static enum pm_ret_status pm_ioctl_read_ggs(unsigned int index,
+ unsigned int *value)
+{
+ if (index >= GGS_NUM_REGS)
+ return PM_RET_ERROR_ARGS;
+
+ return pm_mmio_read(GGS_BASEADDR + (index << 2), value);
+}
+
+/**
+ * pm_ioctl_write_pggs() - Ioctl function for writing persistent
+ * global general storage (pggs)
+ * @index PGGS register index
+ * @value Register value to be written
+ *
+ * This function writes value to PGGS register.
+ *
+ * @return Returns status, either success or error+reason
+ */
+static enum pm_ret_status pm_ioctl_write_pggs(unsigned int index,
+ unsigned int value)
+{
+ if (index >= PGGS_NUM_REGS)
+ return PM_RET_ERROR_ARGS;
+
+ return pm_mmio_write(PGGS_BASEADDR + (index << 2),
+ 0xFFFFFFFFU, value);
+}
+
+/**
+ * pm_ioctl_read_pggs() - Ioctl function for reading persistent
+ * global general storage (pggs)
+ * @index PGGS register index
+ * @value Register value
+ *
+ * This function returns PGGS register value.
+ *
+ * @return Returns status, either success or error+reason
+ */
+static enum pm_ret_status pm_ioctl_read_pggs(unsigned int index,
+ unsigned int *value)
+{
+ if (index >= PGGS_NUM_REGS)
+ return PM_RET_ERROR_ARGS;
+
+ return pm_mmio_read(PGGS_BASEADDR + (index << 2), value);
+}
+
+/**
+ * pm_api_ioctl() - PM IOCTL API for device control and configs
+ * @node_id Node ID of the device
+ * @ioctl_id ID of the requested IOCTL
+ * @arg1 Argument 1 to requested IOCTL call
+ * @arg2 Argument 2 to requested IOCTL call
+ * @value Returned output value
+ *
+ * This function calls IOCTL to firmware for device control and configuration.
+ *
+ * @return Returns status, either success or error+reason
+ */
+enum pm_ret_status pm_api_ioctl(enum pm_node_id nid,
+ unsigned int ioctl_id,
+ unsigned int arg1,
+ unsigned int arg2,
+ unsigned int *value)
+{
+ enum pm_ret_status ret;
+
+ switch (ioctl_id) {
+ case IOCTL_GET_RPU_OPER_MODE:
+ ret = pm_ioctl_get_rpu_oper_mode(value);
+ break;
+ case IOCTL_SET_RPU_OPER_MODE:
+ ret = pm_ioctl_set_rpu_oper_mode(arg1);
+ break;
+ case IOCTL_RPU_BOOT_ADDR_CONFIG:
+ ret = pm_ioctl_config_boot_addr(nid, arg1);
+ break;
+ case IOCTL_TCM_COMB_CONFIG:
+ ret = pm_ioctl_config_tcm_comb(arg1);
+ break;
+ case IOCTL_SET_TAPDELAY_BYPASS:
+ ret = pm_ioctl_set_tapdelay_bypass(arg1, arg2);
+ break;
+ case IOCTL_SET_SGMII_MODE:
+ ret = pm_ioctl_set_sgmii_mode(nid, arg1);
+ break;
+ case IOCTL_SD_DLL_RESET:
+ ret = pm_ioctl_sd_dll_reset(nid, arg1);
+ break;
+ case IOCTL_SET_SD_TAPDELAY:
+ ret = pm_ioctl_sd_set_tapdelay(nid, arg1, arg2);
+ break;
+ case IOCTL_SET_PLL_FRAC_MODE:
+ ret = pm_ioctl_set_pll_frac_mode(arg1, arg2);
+ break;
+ case IOCTL_GET_PLL_FRAC_MODE:
+ ret = pm_ioctl_get_pll_frac_mode(arg1, value);
+ break;
+ case IOCTL_SET_PLL_FRAC_DATA:
+ ret = pm_ioctl_set_pll_frac_data(arg1, arg2);
+ break;
+ case IOCTL_GET_PLL_FRAC_DATA:
+ ret = pm_ioctl_get_pll_frac_data(arg1, value);
+ break;
+ case IOCTL_WRITE_GGS:
+ ret = pm_ioctl_write_ggs(arg1, arg2);
+ break;
+ case IOCTL_READ_GGS:
+ ret = pm_ioctl_read_ggs(arg1, value);
+ break;
+ case IOCTL_WRITE_PGGS:
+ ret = pm_ioctl_write_pggs(arg1, arg2);
+ break;
+ case IOCTL_READ_PGGS:
+ ret = pm_ioctl_read_pggs(arg1, value);
+ break;
+ default:
+ ret = PM_RET_ERROR_NOTSUPPORTED;
+ break;
+ }
+
+ return ret;
+}
diff --git a/plat/xilinx/zynqmp/pm_service/pm_api_ioctl.h b/plat/xilinx/zynqmp/pm_service/pm_api_ioctl.h
new file mode 100644
index 0000000..081259f
--- /dev/null
+++ b/plat/xilinx/zynqmp/pm_service/pm_api_ioctl.h
@@ -0,0 +1,78 @@
+/*
+ * Copyright (c) 2018, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+/*
+ * ZynqMP system level PM-API functions for pin control.
+ */
+
+#ifndef _PM_API_IOCTL_H_
+#define _PM_API_IOCTL_H_
+
+#include "pm_common.h"
+
+//ioctl id
+enum {
+ IOCTL_GET_RPU_OPER_MODE,
+ IOCTL_SET_RPU_OPER_MODE,
+ IOCTL_RPU_BOOT_ADDR_CONFIG,
+ IOCTL_TCM_COMB_CONFIG,
+ IOCTL_SET_TAPDELAY_BYPASS,
+ IOCTL_SET_SGMII_MODE,
+ IOCTL_SD_DLL_RESET,
+ IOCTL_SET_SD_TAPDELAY,
+ /* Ioctl for clock driver */
+ IOCTL_SET_PLL_FRAC_MODE,
+ IOCTL_GET_PLL_FRAC_MODE,
+ IOCTL_SET_PLL_FRAC_DATA,
+ IOCTL_GET_PLL_FRAC_DATA,
+ IOCTL_WRITE_GGS,
+ IOCTL_READ_GGS,
+ IOCTL_WRITE_PGGS,
+ IOCTL_READ_PGGS,
+};
+
+//RPU operation mode
+#define PM_RPU_MODE_LOCKSTEP 0U
+#define PM_RPU_MODE_SPLIT 1U
+
+//RPU boot mem
+#define PM_RPU_BOOTMEM_LOVEC 0U
+#define PM_RPU_BOOTMEM_HIVEC 1U
+
+//RPU tcm mpde
+#define PM_RPU_TCM_SPLIT 0U
+#define PM_RPU_TCM_COMB 1U
+
+//tap delay signal type
+#define PM_TAPDELAY_NAND_DQS_IN 0U
+#define PM_TAPDELAY_NAND_DQS_OUT 1U
+#define PM_TAPDELAY_QSPI 2U
+#define PM_TAPDELAY_MAX 3U
+
+//tap delay bypass
+#define PM_TAPDELAY_BYPASS_DISABLE 0U
+#define PM_TAPDELAY_BYPASS_ENABLE 1U
+
+//sgmii mode
+#define PM_SGMII_DISABLE 0U
+#define PM_SGMII_ENABLE 1U
+
+enum tap_delay_type {
+ PM_TAPDELAY_INPUT,
+ PM_TAPDELAY_OUTPUT,
+};
+
+//dll reset type
+#define PM_DLL_RESET_ASSERT 0U
+#define PM_DLL_RESET_RELEASE 1U
+#define PM_DLL_RESET_PULSE 2U
+
+enum pm_ret_status pm_api_ioctl(enum pm_node_id nid,
+ unsigned int ioctl_id,
+ unsigned int arg1,
+ unsigned int arg2,
+ unsigned int *value);
+#endif /* _PM_API_IOCTL_H_ */
diff --git a/plat/xilinx/zynqmp/pm_service/pm_api_pinctrl.c b/plat/xilinx/zynqmp/pm_service/pm_api_pinctrl.c
new file mode 100644
index 0000000..12b9c2d
--- /dev/null
+++ b/plat/xilinx/zynqmp/pm_service/pm_api_pinctrl.c
@@ -0,0 +1,3039 @@
+/*
+ * Copyright (c) 2018, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+/*
+ * ZynqMP system level PM-API functions for pin control.
+ */
+
+#include <arch_helpers.h>
+#include <platform.h>
+#include <string.h>
+#include "pm_api_pinctrl.h"
+#include "pm_api_sys.h"
+#include "pm_client.h"
+#include "pm_common.h"
+#include "pm_ipi.h"
+
+#define PINCTRL_FUNCTION_MASK U(0xFE)
+#define PINCTRL_VOLTAGE_STATUS_MASK U(0x01)
+#define NFUNCS_PER_PIN U(13)
+#define PINCTRL_NUM_MIOS U(78)
+#define MAX_PIN_PER_REG U(26)
+#define PINCTRL_BANK_ADDR_STEP U(28)
+
+#define PINCTRL_DRVSTRN0_REG_OFFSET U(0)
+#define PINCTRL_DRVSTRN1_REG_OFFSET U(4)
+#define PINCTRL_SCHCMOS_REG_OFFSET U(8)
+#define PINCTRL_PULLCTRL_REG_OFFSET U(12)
+#define PINCTRL_PULLSTAT_REG_OFFSET U(16)
+#define PINCTRL_SLEWCTRL_REG_OFFSET U(20)
+#define PINCTRL_VOLTAGE_STAT_REG_OFFSET U(24)
+
+#define IOU_SLCR_BANK1_CTRL5 U(0XFF180164)
+
+#define PINCTRL_CFG_ADDR_OFFSET(addr, reg, miopin) \
+ ((addr) + 4 * PINCTRL_NUM_MIOS + PINCTRL_BANK_ADDR_STEP * \
+ ((miopin) / MAX_PIN_PER_REG) + (reg))
+
+#define PINCTRL_PIN_OFFSET(_miopin) \
+ ((_miopin) - (MAX_PIN_PER_REG * ((_miopin) / MAX_PIN_PER_REG)))
+
+#define PINCTRL_REGVAL_TO_PIN_CONFIG(_pin, _val) \
+ (((_val) >> PINCTRL_PIN_OFFSET(_pin)) & 0x1)
+
+static uint8_t pm_pinctrl_mux[NFUNCS_PER_PIN] = {
+ 0x02, 0x04, 0x08, 0x10, 0x18,
+ 0x00, 0x20, 0x40, 0x60, 0x80,
+ 0xA0, 0xC0, 0xE0
+};
+
+struct pinctrl_function {
+ char name[FUNCTION_NAME_LEN];
+ uint16_t (*groups)[];
+ uint8_t regval;
+};
+
+/* Max groups for one pin */
+#define MAX_PIN_GROUPS U(13)
+
+struct zynqmp_pin_group {
+ uint16_t (*groups)[];
+};
+
+static struct pinctrl_function pinctrl_functions[MAX_FUNCTION] = {
+ [PINCTRL_FUNC_CAN0] = {
+ .name = "can0",
+ .regval = 0x20,
+ .groups = &((uint16_t []) {
+ PINCTRL_GRP_CAN0_0,
+ PINCTRL_GRP_CAN0_1,
+ PINCTRL_GRP_CAN0_2,
+ PINCTRL_GRP_CAN0_3,
+ PINCTRL_GRP_CAN0_4,
+ PINCTRL_GRP_CAN0_5,
+ PINCTRL_GRP_CAN0_6,
+ PINCTRL_GRP_CAN0_7,
+ PINCTRL_GRP_CAN0_8,
+ PINCTRL_GRP_CAN0_9,
+ PINCTRL_GRP_CAN0_10,
+ PINCTRL_GRP_CAN0_11,
+ PINCTRL_GRP_CAN0_12,
+ PINCTRL_GRP_CAN0_13,
+ PINCTRL_GRP_CAN0_14,
+ PINCTRL_GRP_CAN0_15,
+ PINCTRL_GRP_CAN0_16,
+ PINCTRL_GRP_CAN0_17,
+ PINCTRL_GRP_CAN0_18,
+ END_OF_GROUPS,
+ }),
+ },
+ [PINCTRL_FUNC_CAN1] = {
+ .name = "can1",
+ .regval = 0x20,
+ .groups = &((uint16_t []) {
+ PINCTRL_GRP_CAN1_0,
+ PINCTRL_GRP_CAN1_1,
+ PINCTRL_GRP_CAN1_2,
+ PINCTRL_GRP_CAN1_3,
+ PINCTRL_GRP_CAN1_4,
+ PINCTRL_GRP_CAN1_5,
+ PINCTRL_GRP_CAN1_6,
+ PINCTRL_GRP_CAN1_7,
+ PINCTRL_GRP_CAN1_8,
+ PINCTRL_GRP_CAN1_9,
+ PINCTRL_GRP_CAN1_10,
+ PINCTRL_GRP_CAN1_11,
+ PINCTRL_GRP_CAN1_12,
+ PINCTRL_GRP_CAN1_13,
+ PINCTRL_GRP_CAN1_14,
+ PINCTRL_GRP_CAN1_15,
+ PINCTRL_GRP_CAN1_16,
+ PINCTRL_GRP_CAN1_17,
+ PINCTRL_GRP_CAN1_18,
+ PINCTRL_GRP_CAN1_19,
+ END_OF_GROUPS,
+ }),
+ },
+ [PINCTRL_FUNC_ETHERNET0] = {
+ .name = "ethernet0",
+ .regval = 0x02,
+ .groups = &((uint16_t []) {
+ PINCTRL_GRP_ETHERNET0_0,
+ END_OF_GROUPS,
+ }),
+ },
+ [PINCTRL_FUNC_ETHERNET1] = {
+ .name = "ethernet1",
+ .regval = 0x02,
+ .groups = &((uint16_t []) {
+ PINCTRL_GRP_ETHERNET1_0,
+ END_OF_GROUPS,
+ }),
+ },
+ [PINCTRL_FUNC_ETHERNET2] = {
+ .name = "ethernet2",
+ .regval = 0x02,
+ .groups = &((uint16_t []) {
+ PINCTRL_GRP_ETHERNET2_0,
+ END_OF_GROUPS,
+ }),
+ },
+ [PINCTRL_FUNC_ETHERNET3] = {
+ .name = "ethernet3",
+ .regval = 0x02,
+ .groups = &((uint16_t []) {
+ PINCTRL_GRP_ETHERNET3_0,
+ END_OF_GROUPS,
+ }),
+ },
+ [PINCTRL_FUNC_GEMTSU0] = {
+ .name = "gemtsu0",
+ .regval = 0x02,
+ .groups = &((uint16_t []) {
+ PINCTRL_GRP_GEMTSU0_0,
+ PINCTRL_GRP_GEMTSU0_1,
+ PINCTRL_GRP_GEMTSU0_2,
+ END_OF_GROUPS,
+ }),
+ },
+ [PINCTRL_FUNC_GPIO0] = {
+ .name = "gpio0",
+ .regval = 0x00,
+ .groups = &((uint16_t []) {
+ PINCTRL_GRP_GPIO0_0,
+ PINCTRL_GRP_GPIO0_1,
+ PINCTRL_GRP_GPIO0_2,
+ PINCTRL_GRP_GPIO0_3,
+ PINCTRL_GRP_GPIO0_4,
+ PINCTRL_GRP_GPIO0_5,
+ PINCTRL_GRP_GPIO0_6,
+ PINCTRL_GRP_GPIO0_7,
+ PINCTRL_GRP_GPIO0_8,
+ PINCTRL_GRP_GPIO0_9,
+ PINCTRL_GRP_GPIO0_10,
+ PINCTRL_GRP_GPIO0_11,
+ PINCTRL_GRP_GPIO0_12,
+ PINCTRL_GRP_GPIO0_13,
+ PINCTRL_GRP_GPIO0_14,
+ PINCTRL_GRP_GPIO0_15,
+ PINCTRL_GRP_GPIO0_16,
+ PINCTRL_GRP_GPIO0_17,
+ PINCTRL_GRP_GPIO0_18,
+ PINCTRL_GRP_GPIO0_19,
+ PINCTRL_GRP_GPIO0_20,
+ PINCTRL_GRP_GPIO0_21,
+ PINCTRL_GRP_GPIO0_22,
+ PINCTRL_GRP_GPIO0_23,
+ PINCTRL_GRP_GPIO0_24,
+ PINCTRL_GRP_GPIO0_25,
+ PINCTRL_GRP_GPIO0_26,
+ PINCTRL_GRP_GPIO0_27,
+ PINCTRL_GRP_GPIO0_28,
+ PINCTRL_GRP_GPIO0_29,
+ PINCTRL_GRP_GPIO0_30,
+ PINCTRL_GRP_GPIO0_31,
+ PINCTRL_GRP_GPIO0_32,
+ PINCTRL_GRP_GPIO0_33,
+ PINCTRL_GRP_GPIO0_34,
+ PINCTRL_GRP_GPIO0_35,
+ PINCTRL_GRP_GPIO0_36,
+ PINCTRL_GRP_GPIO0_37,
+ PINCTRL_GRP_GPIO0_38,
+ PINCTRL_GRP_GPIO0_39,
+ PINCTRL_GRP_GPIO0_40,
+ PINCTRL_GRP_GPIO0_41,
+ PINCTRL_GRP_GPIO0_42,
+ PINCTRL_GRP_GPIO0_43,
+ PINCTRL_GRP_GPIO0_44,
+ PINCTRL_GRP_GPIO0_45,
+ PINCTRL_GRP_GPIO0_46,
+ PINCTRL_GRP_GPIO0_47,
+ PINCTRL_GRP_GPIO0_48,
+ PINCTRL_GRP_GPIO0_49,
+ PINCTRL_GRP_GPIO0_50,
+ PINCTRL_GRP_GPIO0_51,
+ PINCTRL_GRP_GPIO0_52,
+ PINCTRL_GRP_GPIO0_53,
+ PINCTRL_GRP_GPIO0_54,
+ PINCTRL_GRP_GPIO0_55,
+ PINCTRL_GRP_GPIO0_56,
+ PINCTRL_GRP_GPIO0_57,
+ PINCTRL_GRP_GPIO0_58,
+ PINCTRL_GRP_GPIO0_59,
+ PINCTRL_GRP_GPIO0_60,
+ PINCTRL_GRP_GPIO0_61,
+ PINCTRL_GRP_GPIO0_62,
+ PINCTRL_GRP_GPIO0_63,
+ PINCTRL_GRP_GPIO0_64,
+ PINCTRL_GRP_GPIO0_65,
+ PINCTRL_GRP_GPIO0_66,
+ PINCTRL_GRP_GPIO0_67,
+ PINCTRL_GRP_GPIO0_68,
+ PINCTRL_GRP_GPIO0_69,
+ PINCTRL_GRP_GPIO0_70,
+ PINCTRL_GRP_GPIO0_71,
+ PINCTRL_GRP_GPIO0_72,
+ PINCTRL_GRP_GPIO0_73,
+ PINCTRL_GRP_GPIO0_74,
+ PINCTRL_GRP_GPIO0_75,
+ PINCTRL_GRP_GPIO0_76,
+ PINCTRL_GRP_GPIO0_77,
+ END_OF_GROUPS,
+ }),
+ },
+ [PINCTRL_FUNC_I2C0] = {
+ .name = "i2c0",
+ .regval = 0x40,
+ .groups = &((uint16_t []) {
+ PINCTRL_GRP_I2C0_0,
+ PINCTRL_GRP_I2C0_1,
+ PINCTRL_GRP_I2C0_2,
+ PINCTRL_GRP_I2C0_3,
+ PINCTRL_GRP_I2C0_4,
+ PINCTRL_GRP_I2C0_5,
+ PINCTRL_GRP_I2C0_6,
+ PINCTRL_GRP_I2C0_7,
+ PINCTRL_GRP_I2C0_8,
+ PINCTRL_GRP_I2C0_9,
+ PINCTRL_GRP_I2C0_10,
+ PINCTRL_GRP_I2C0_11,
+ PINCTRL_GRP_I2C0_12,
+ PINCTRL_GRP_I2C0_13,
+ PINCTRL_GRP_I2C0_14,
+ PINCTRL_GRP_I2C0_15,
+ PINCTRL_GRP_I2C0_16,
+ PINCTRL_GRP_I2C0_17,
+ PINCTRL_GRP_I2C0_18,
+ END_OF_GROUPS,
+ }),
+ },
+ [PINCTRL_FUNC_I2C1] = {
+ .name = "i2c1",
+ .regval = 0x40,
+ .groups = &((uint16_t []) {
+ PINCTRL_GRP_I2C1_0,
+ PINCTRL_GRP_I2C1_1,
+ PINCTRL_GRP_I2C1_2,
+ PINCTRL_GRP_I2C1_3,
+ PINCTRL_GRP_I2C1_4,
+ PINCTRL_GRP_I2C1_5,
+ PINCTRL_GRP_I2C1_6,
+ PINCTRL_GRP_I2C1_7,
+ PINCTRL_GRP_I2C1_8,
+ PINCTRL_GRP_I2C1_9,
+ PINCTRL_GRP_I2C1_10,
+ PINCTRL_GRP_I2C1_11,
+ PINCTRL_GRP_I2C1_12,
+ PINCTRL_GRP_I2C1_13,
+ PINCTRL_GRP_I2C1_14,
+ PINCTRL_GRP_I2C1_15,
+ PINCTRL_GRP_I2C1_16,
+ PINCTRL_GRP_I2C1_17,
+ PINCTRL_GRP_I2C1_18,
+ PINCTRL_GRP_I2C1_19,
+ END_OF_GROUPS,
+ }),
+ },
+ [PINCTRL_FUNC_MDIO0] = {
+ .name = "mdio0",
+ .regval = 0x60,
+ .groups = &((uint16_t []) {
+ PINCTRL_GRP_MDIO0_0,
+ END_OF_GROUPS,
+ }),
+ },
+ [PINCTRL_FUNC_MDIO1] = {
+ .name = "mdio1",
+ .regval = 0x80,
+ .groups = &((uint16_t []) {
+ PINCTRL_GRP_MDIO1_0,
+ PINCTRL_GRP_MDIO1_1,
+ END_OF_GROUPS,
+ }),
+ },
+ [PINCTRL_FUNC_MDIO2] = {
+ .name = "mdio2",
+ .regval = 0xa0,
+ .groups = &((uint16_t []) {
+ PINCTRL_GRP_MDIO2_0,
+ END_OF_GROUPS,
+ }),
+ },
+ [PINCTRL_FUNC_MDIO3] = {
+ .name = "mdio3",
+ .regval = 0xc0,
+ .groups = &((uint16_t []) {
+ PINCTRL_GRP_MDIO3_0,
+ END_OF_GROUPS,
+ }),
+ },
+ [PINCTRL_FUNC_QSPI0] = {
+ .name = "qspi0",
+ .regval = 0x02,
+ .groups = &((uint16_t []) {
+ PINCTRL_GRP_QSPI0_0,
+ END_OF_GROUPS,
+ }),
+ },
+ [PINCTRL_FUNC_QSPI_FBCLK] = {
+ .name = "qspi_fbclk",
+ .regval = 0x02,
+ .groups = &((uint16_t []) {
+ PINCTRL_GRP_QSPI_FBCLK,
+ END_OF_GROUPS,
+ }),
+ },
+ [PINCTRL_FUNC_QSPI_SS] = {
+ .name = "qspi_ss",
+ .regval = 0x02,
+ .groups = &((uint16_t []) {
+ PINCTRL_GRP_QSPI_SS,
+ END_OF_GROUPS,
+ }),
+ },
+ [PINCTRL_FUNC_SPI0] = {
+ .name = "spi0",
+ .regval = 0x80,
+ .groups = &((uint16_t []) {
+ PINCTRL_GRP_SPI0_0,
+ PINCTRL_GRP_SPI0_1,
+ PINCTRL_GRP_SPI0_2,
+ PINCTRL_GRP_SPI0_3,
+ PINCTRL_GRP_SPI0_4,
+ PINCTRL_GRP_SPI0_5,
+ END_OF_GROUPS,
+ }),
+ },
+ [PINCTRL_FUNC_SPI1] = {
+ .name = "spi1",
+ .regval = 0x80,
+ .groups = &((uint16_t []) {
+ PINCTRL_GRP_SPI1_0,
+ PINCTRL_GRP_SPI1_1,
+ PINCTRL_GRP_SPI1_2,
+ PINCTRL_GRP_SPI1_3,
+ PINCTRL_GRP_SPI1_4,
+ PINCTRL_GRP_SPI1_5,
+ END_OF_GROUPS,
+ }),
+ },
+ [PINCTRL_FUNC_SPI0_SS] = {
+ .name = "spi0_ss",
+ .regval = 0x80,
+ .groups = &((uint16_t []) {
+ PINCTRL_GRP_SPI0_0_SS0,
+ PINCTRL_GRP_SPI0_0_SS1,
+ PINCTRL_GRP_SPI0_0_SS2,
+ PINCTRL_GRP_SPI0_1_SS0,
+ PINCTRL_GRP_SPI0_1_SS1,
+ PINCTRL_GRP_SPI0_1_SS2,
+ PINCTRL_GRP_SPI0_2_SS0,
+ PINCTRL_GRP_SPI0_2_SS1,
+ PINCTRL_GRP_SPI0_2_SS2,
+ PINCTRL_GRP_SPI0_3_SS0,
+ PINCTRL_GRP_SPI0_3_SS1,
+ PINCTRL_GRP_SPI0_3_SS2,
+ PINCTRL_GRP_SPI0_4_SS0,
+ PINCTRL_GRP_SPI0_4_SS1,
+ PINCTRL_GRP_SPI0_4_SS2,
+ PINCTRL_GRP_SPI0_5_SS0,
+ PINCTRL_GRP_SPI0_5_SS1,
+ PINCTRL_GRP_SPI0_5_SS2,
+ END_OF_GROUPS,
+ }),
+ },
+ [PINCTRL_FUNC_SPI1_SS] = {
+ .name = "spi1_ss",
+ .regval = 0x80,
+ .groups = &((uint16_t []) {
+ PINCTRL_GRP_SPI1_0_SS0,
+ PINCTRL_GRP_SPI1_0_SS1,
+ PINCTRL_GRP_SPI1_0_SS2,
+ PINCTRL_GRP_SPI1_1_SS0,
+ PINCTRL_GRP_SPI1_1_SS1,
+ PINCTRL_GRP_SPI1_1_SS2,
+ PINCTRL_GRP_SPI1_2_SS0,
+ PINCTRL_GRP_SPI1_2_SS1,
+ PINCTRL_GRP_SPI1_2_SS2,
+ PINCTRL_GRP_SPI1_3_SS0,
+ PINCTRL_GRP_SPI1_3_SS1,
+ PINCTRL_GRP_SPI1_3_SS2,
+ PINCTRL_GRP_SPI1_4_SS0,
+ PINCTRL_GRP_SPI1_4_SS1,
+ PINCTRL_GRP_SPI1_4_SS2,
+ PINCTRL_GRP_SPI1_5_SS0,
+ PINCTRL_GRP_SPI1_5_SS1,
+ PINCTRL_GRP_SPI1_5_SS2,
+ END_OF_GROUPS,
+ }),
+ },
+ [PINCTRL_FUNC_SDIO0] = {
+ .name = "sdio0",
+ .regval = 0x08,
+ .groups = &((uint16_t []) {
+ PINCTRL_GRP_SDIO0_0,
+ PINCTRL_GRP_SDIO0_1,
+ PINCTRL_GRP_SDIO0_2,
+ PINCTRL_GRP_SDIO0_4BIT_0_0,
+ PINCTRL_GRP_SDIO0_4BIT_0_1,
+ PINCTRL_GRP_SDIO0_4BIT_1_0,
+ PINCTRL_GRP_SDIO0_4BIT_1_1,
+ PINCTRL_GRP_SDIO0_4BIT_2_0,
+ PINCTRL_GRP_SDIO0_4BIT_2_1,
+ PINCTRL_GRP_SDIO0_1BIT_0_0,
+ PINCTRL_GRP_SDIO0_1BIT_0_1,
+ PINCTRL_GRP_SDIO0_1BIT_0_2,
+ PINCTRL_GRP_SDIO0_1BIT_0_3,
+ PINCTRL_GRP_SDIO0_1BIT_0_4,
+ PINCTRL_GRP_SDIO0_1BIT_0_5,
+ PINCTRL_GRP_SDIO0_1BIT_0_6,
+ PINCTRL_GRP_SDIO0_1BIT_0_7,
+ PINCTRL_GRP_SDIO0_1BIT_1_0,
+ PINCTRL_GRP_SDIO0_1BIT_1_1,
+ PINCTRL_GRP_SDIO0_1BIT_1_2,
+ PINCTRL_GRP_SDIO0_1BIT_1_3,
+ PINCTRL_GRP_SDIO0_1BIT_1_4,
+ PINCTRL_GRP_SDIO0_1BIT_1_5,
+ PINCTRL_GRP_SDIO0_1BIT_1_6,
+ PINCTRL_GRP_SDIO0_1BIT_1_7,
+ PINCTRL_GRP_SDIO0_1BIT_2_0,
+ PINCTRL_GRP_SDIO0_1BIT_2_1,
+ PINCTRL_GRP_SDIO0_1BIT_2_2,
+ PINCTRL_GRP_SDIO0_1BIT_2_3,
+ PINCTRL_GRP_SDIO0_1BIT_2_4,
+ PINCTRL_GRP_SDIO0_1BIT_2_5,
+ PINCTRL_GRP_SDIO0_1BIT_2_6,
+ PINCTRL_GRP_SDIO0_1BIT_2_7,
+ END_OF_GROUPS,
+ }),
+ },
+ [PINCTRL_FUNC_SDIO0_PC] = {
+ .name = "sdio0_pc",
+ .regval = 0x08,
+ .groups = &((uint16_t []) {
+ PINCTRL_GRP_SDIO0_0_PC,
+ PINCTRL_GRP_SDIO0_1_PC,
+ PINCTRL_GRP_SDIO0_2_PC,
+ END_OF_GROUPS,
+ }),
+ },
+ [PINCTRL_FUNC_SDIO0_CD] = {
+ .name = "sdio0_cd",
+ .regval = 0x08,
+ .groups = &((uint16_t []) {
+ PINCTRL_GRP_SDIO0_0_CD,
+ PINCTRL_GRP_SDIO0_1_CD,
+ PINCTRL_GRP_SDIO0_2_CD,
+ END_OF_GROUPS,
+ }),
+ },
+ [PINCTRL_FUNC_SDIO0_WP] = {
+ .name = "sdio0_wp",
+ .regval = 0x08,
+ .groups = &((uint16_t []) {
+ PINCTRL_GRP_SDIO0_0_WP,
+ PINCTRL_GRP_SDIO0_1_WP,
+ PINCTRL_GRP_SDIO0_2_WP,
+ END_OF_GROUPS,
+ }),
+ },
+ [PINCTRL_FUNC_SDIO1] = {
+ .name = "sdio1",
+ .regval = 0x10,
+ .groups = &((uint16_t []) {
+ PINCTRL_GRP_SDIO1_0,
+ PINCTRL_GRP_SDIO1_4BIT_0_0,
+ PINCTRL_GRP_SDIO1_4BIT_0_1,
+ PINCTRL_GRP_SDIO1_4BIT_1_0,
+ PINCTRL_GRP_SDIO1_1BIT_0_0,
+ PINCTRL_GRP_SDIO1_1BIT_0_1,
+ PINCTRL_GRP_SDIO1_1BIT_0_2,
+ PINCTRL_GRP_SDIO1_1BIT_0_3,
+ PINCTRL_GRP_SDIO1_1BIT_0_4,
+ PINCTRL_GRP_SDIO1_1BIT_0_5,
+ PINCTRL_GRP_SDIO1_1BIT_0_6,
+ PINCTRL_GRP_SDIO1_1BIT_0_7,
+ PINCTRL_GRP_SDIO1_1BIT_1_0,
+ PINCTRL_GRP_SDIO1_1BIT_1_1,
+ PINCTRL_GRP_SDIO1_1BIT_1_2,
+ PINCTRL_GRP_SDIO1_1BIT_1_3,
+ END_OF_GROUPS,
+ }),
+ },
+ [PINCTRL_FUNC_SDIO1_PC] = {
+ .name = "sdio1_pc",
+ .regval = 0x10,
+ .groups = &((uint16_t []) {
+ PINCTRL_GRP_SDIO1_0_PC,
+ PINCTRL_GRP_SDIO1_1_PC,
+ END_OF_GROUPS,
+ }),
+ },
+ [PINCTRL_FUNC_SDIO1_CD] = {
+ .name = "sdio1_cd",
+ .regval = 0x10,
+ .groups = &((uint16_t []) {
+ PINCTRL_GRP_SDIO1_0_CD,
+ PINCTRL_GRP_SDIO1_1_CD,
+ END_OF_GROUPS,
+ }),
+ },
+ [PINCTRL_FUNC_SDIO1_WP] = {
+ .name = "sdio1_wp",
+ .regval = 0x10,
+ .groups = &((uint16_t []) {
+ PINCTRL_GRP_SDIO1_0_WP,
+ PINCTRL_GRP_SDIO1_1_WP,
+ END_OF_GROUPS,
+ }),
+ },
+ [PINCTRL_FUNC_NAND0] = {
+ .name = "nand0",
+ .regval = 0x04,
+ .groups = &((uint16_t []) {
+ PINCTRL_GRP_NAND0_0,
+ END_OF_GROUPS,
+ }),
+ },
+ [PINCTRL_FUNC_NAND0_CE] = {
+ .name = "nand0_ce",
+ .regval = 0x04,
+ .groups = &((uint16_t []) {
+ PINCTRL_GRP_NAND0_0_CE,
+ PINCTRL_GRP_NAND0_1_CE,
+ END_OF_GROUPS,
+ }),
+ },
+ [PINCTRL_FUNC_NAND0_RB] = {
+ .name = "nand0_rb",
+ .regval = 0x04,
+ .groups = &((uint16_t []) {
+ PINCTRL_GRP_NAND0_0_RB,
+ PINCTRL_GRP_NAND0_1_RB,
+ END_OF_GROUPS,
+ }),
+ },
+ [PINCTRL_FUNC_NAND0_DQS] = {
+ .name = "nand0_dqs",
+ .regval = 0x04,
+ .groups = &((uint16_t []) {
+ PINCTRL_GRP_NAND0_0_DQS,
+ PINCTRL_GRP_NAND0_1_DQS,
+ END_OF_GROUPS,
+ }),
+ },
+ [PINCTRL_FUNC_TTC0_CLK] = {
+ .name = "ttc0_clk",
+ .regval = 0xa0,
+ .groups = &((uint16_t []) {
+ PINCTRL_GRP_TTC0_0_CLK,
+ PINCTRL_GRP_TTC0_1_CLK,
+ PINCTRL_GRP_TTC0_2_CLK,
+ PINCTRL_GRP_TTC0_3_CLK,
+ PINCTRL_GRP_TTC0_4_CLK,
+ PINCTRL_GRP_TTC0_5_CLK,
+ PINCTRL_GRP_TTC0_6_CLK,
+ PINCTRL_GRP_TTC0_7_CLK,
+ PINCTRL_GRP_TTC0_8_CLK,
+ END_OF_GROUPS,
+ }),
+ },
+ [PINCTRL_FUNC_TTC0_WAV] = {
+ .name = "ttc0_wav",
+ .regval = 0xa0,
+ .groups = &((uint16_t []) {
+ PINCTRL_GRP_TTC0_0_WAV,
+ PINCTRL_GRP_TTC0_1_WAV,
+ PINCTRL_GRP_TTC0_2_WAV,
+ PINCTRL_GRP_TTC0_3_WAV,
+ PINCTRL_GRP_TTC0_4_WAV,
+ PINCTRL_GRP_TTC0_5_WAV,
+ PINCTRL_GRP_TTC0_6_WAV,
+ PINCTRL_GRP_TTC0_7_WAV,
+ PINCTRL_GRP_TTC0_8_WAV,
+ END_OF_GROUPS,
+ }),
+ },
+ [PINCTRL_FUNC_TTC1_CLK] = {
+ .name = "ttc1_clk",
+ .regval = 0xa0,
+ .groups = &((uint16_t []) {
+ PINCTRL_GRP_TTC1_0_CLK,
+ PINCTRL_GRP_TTC1_1_CLK,
+ PINCTRL_GRP_TTC1_2_CLK,
+ PINCTRL_GRP_TTC1_3_CLK,
+ PINCTRL_GRP_TTC1_4_CLK,
+ PINCTRL_GRP_TTC1_5_CLK,
+ PINCTRL_GRP_TTC1_6_CLK,
+ PINCTRL_GRP_TTC1_7_CLK,
+ PINCTRL_GRP_TTC1_8_CLK,
+ END_OF_GROUPS,
+ }),
+ },
+ [PINCTRL_FUNC_TTC1_WAV] = {
+ .name = "ttc1_wav",
+ .regval = 0xa0,
+ .groups = &((uint16_t []) {
+ PINCTRL_GRP_TTC1_0_WAV,
+ PINCTRL_GRP_TTC1_1_WAV,
+ PINCTRL_GRP_TTC1_2_WAV,
+ PINCTRL_GRP_TTC1_3_WAV,
+ PINCTRL_GRP_TTC1_4_WAV,
+ PINCTRL_GRP_TTC1_5_WAV,
+ PINCTRL_GRP_TTC1_6_WAV,
+ PINCTRL_GRP_TTC1_7_WAV,
+ PINCTRL_GRP_TTC1_8_WAV,
+ END_OF_GROUPS,
+ }),
+ },
+ [PINCTRL_FUNC_TTC2_CLK] = {
+ .name = "ttc2_clk",
+ .regval = 0xa0,
+ .groups = &((uint16_t []) {
+ PINCTRL_GRP_TTC2_0_CLK,
+ PINCTRL_GRP_TTC2_1_CLK,
+ PINCTRL_GRP_TTC2_2_CLK,
+ PINCTRL_GRP_TTC2_3_CLK,
+ PINCTRL_GRP_TTC2_4_CLK,
+ PINCTRL_GRP_TTC2_5_CLK,
+ PINCTRL_GRP_TTC2_6_CLK,
+ PINCTRL_GRP_TTC2_7_CLK,
+ PINCTRL_GRP_TTC2_8_CLK,
+ END_OF_GROUPS,
+ }),
+ },
+ [PINCTRL_FUNC_TTC2_WAV] = {
+ .name = "ttc2_wav",
+ .regval = 0xa0,
+ .groups = &((uint16_t []) {
+ PINCTRL_GRP_TTC2_0_WAV,
+ PINCTRL_GRP_TTC2_1_WAV,
+ PINCTRL_GRP_TTC2_2_WAV,
+ PINCTRL_GRP_TTC2_3_WAV,
+ PINCTRL_GRP_TTC2_4_WAV,
+ PINCTRL_GRP_TTC2_5_WAV,
+ PINCTRL_GRP_TTC2_6_WAV,
+ PINCTRL_GRP_TTC2_7_WAV,
+ PINCTRL_GRP_TTC2_8_WAV,
+ END_OF_GROUPS,
+ }),
+ },
+ [PINCTRL_FUNC_TTC3_CLK] = {
+ .name = "ttc3_clk",
+ .regval = 0xa0,
+ .groups = &((uint16_t []) {
+ PINCTRL_GRP_TTC3_0_CLK,
+ PINCTRL_GRP_TTC3_1_CLK,
+ PINCTRL_GRP_TTC3_2_CLK,
+ PINCTRL_GRP_TTC3_3_CLK,
+ PINCTRL_GRP_TTC3_4_CLK,
+ PINCTRL_GRP_TTC3_5_CLK,
+ PINCTRL_GRP_TTC3_6_CLK,
+ PINCTRL_GRP_TTC3_7_CLK,
+ PINCTRL_GRP_TTC3_8_CLK,
+ END_OF_GROUPS,
+ }),
+ },
+ [PINCTRL_FUNC_TTC3_WAV] = {
+ .name = "ttc3_wav",
+ .regval = 0xa0,
+ .groups = &((uint16_t []) {
+ PINCTRL_GRP_TTC3_0_WAV,
+ PINCTRL_GRP_TTC3_1_WAV,
+ PINCTRL_GRP_TTC3_2_WAV,
+ PINCTRL_GRP_TTC3_3_WAV,
+ PINCTRL_GRP_TTC3_4_WAV,
+ PINCTRL_GRP_TTC3_5_WAV,
+ PINCTRL_GRP_TTC3_6_WAV,
+ PINCTRL_GRP_TTC3_7_WAV,
+ PINCTRL_GRP_TTC3_8_WAV,
+ END_OF_GROUPS,
+ }),
+ },
+ [PINCTRL_FUNC_UART0] = {
+ .name = "uart0",
+ .regval = 0xc0,
+ .groups = &((uint16_t []) {
+ PINCTRL_GRP_UART0_0,
+ PINCTRL_GRP_UART0_1,
+ PINCTRL_GRP_UART0_2,
+ PINCTRL_GRP_UART0_3,
+ PINCTRL_GRP_UART0_4,
+ PINCTRL_GRP_UART0_5,
+ PINCTRL_GRP_UART0_6,
+ PINCTRL_GRP_UART0_7,
+ PINCTRL_GRP_UART0_8,
+ PINCTRL_GRP_UART0_9,
+ PINCTRL_GRP_UART0_10,
+ PINCTRL_GRP_UART0_11,
+ PINCTRL_GRP_UART0_12,
+ PINCTRL_GRP_UART0_13,
+ PINCTRL_GRP_UART0_14,
+ PINCTRL_GRP_UART0_15,
+ PINCTRL_GRP_UART0_16,
+ PINCTRL_GRP_UART0_17,
+ PINCTRL_GRP_UART0_18,
+ END_OF_GROUPS,
+ }),
+ },
+ [PINCTRL_FUNC_UART1] = {
+ .name = "uart1",
+ .regval = 0xc0,
+ .groups = &((uint16_t []) {
+ PINCTRL_GRP_UART1_0,
+ PINCTRL_GRP_UART1_1,
+ PINCTRL_GRP_UART1_2,
+ PINCTRL_GRP_UART1_3,
+ PINCTRL_GRP_UART1_4,
+ PINCTRL_GRP_UART1_5,
+ PINCTRL_GRP_UART1_6,
+ PINCTRL_GRP_UART1_7,
+ PINCTRL_GRP_UART1_8,
+ PINCTRL_GRP_UART1_9,
+ PINCTRL_GRP_UART1_10,
+ PINCTRL_GRP_UART1_11,
+ PINCTRL_GRP_UART1_12,
+ PINCTRL_GRP_UART1_13,
+ PINCTRL_GRP_UART1_14,
+ PINCTRL_GRP_UART1_15,
+ PINCTRL_GRP_UART1_16,
+ PINCTRL_GRP_UART1_17,
+ PINCTRL_GRP_UART1_18,
+ END_OF_GROUPS,
+ }),
+ },
+ [PINCTRL_FUNC_USB0] = {
+ .name = "usb0",
+ .regval = 0x04,
+ .groups = &((uint16_t []) {
+ PINCTRL_GRP_USB0_0,
+ END_OF_GROUPS,
+ }),
+ },
+ [PINCTRL_FUNC_USB1] = {
+ .name = "usb1",
+ .regval = 0x04,
+ .groups = &((uint16_t []) {
+ PINCTRL_GRP_USB1_0,
+ END_OF_GROUPS,
+ }),
+ },
+ [PINCTRL_FUNC_SWDT0_CLK] = {
+ .name = "swdt0_clk",
+ .regval = 0x60,
+ .groups = &((uint16_t []) {
+ PINCTRL_GRP_SWDT0_0_CLK,
+ PINCTRL_GRP_SWDT0_1_CLK,
+ PINCTRL_GRP_SWDT0_2_CLK,
+ PINCTRL_GRP_SWDT0_3_CLK,
+ PINCTRL_GRP_SWDT0_4_CLK,
+ PINCTRL_GRP_SWDT0_5_CLK,
+ PINCTRL_GRP_SWDT0_6_CLK,
+ PINCTRL_GRP_SWDT0_7_CLK,
+ PINCTRL_GRP_SWDT0_8_CLK,
+ PINCTRL_GRP_SWDT0_9_CLK,
+ PINCTRL_GRP_SWDT0_10_CLK,
+ PINCTRL_GRP_SWDT0_11_CLK,
+ PINCTRL_GRP_SWDT0_12_CLK,
+ END_OF_GROUPS,
+ }),
+ },
+ [PINCTRL_FUNC_SWDT0_RST] = {
+ .name = "swdt0_rst",
+ .regval = 0x60,
+ .groups = &((uint16_t []) {
+ PINCTRL_GRP_SWDT0_0_RST,
+ PINCTRL_GRP_SWDT0_1_RST,
+ PINCTRL_GRP_SWDT0_2_RST,
+ PINCTRL_GRP_SWDT0_3_RST,
+ PINCTRL_GRP_SWDT0_4_RST,
+ PINCTRL_GRP_SWDT0_5_RST,
+ PINCTRL_GRP_SWDT0_6_RST,
+ PINCTRL_GRP_SWDT0_7_RST,
+ PINCTRL_GRP_SWDT0_8_RST,
+ PINCTRL_GRP_SWDT0_9_RST,
+ PINCTRL_GRP_SWDT0_10_RST,
+ PINCTRL_GRP_SWDT0_11_RST,
+ PINCTRL_GRP_SWDT0_12_RST,
+ END_OF_GROUPS,
+ }),
+ },
+ [PINCTRL_FUNC_SWDT1_CLK] = {
+ .name = "swdt1_clk",
+ .regval = 0x60,
+ .groups = &((uint16_t []) {
+ PINCTRL_GRP_SWDT1_0_CLK,
+ PINCTRL_GRP_SWDT1_1_CLK,
+ PINCTRL_GRP_SWDT1_2_CLK,
+ PINCTRL_GRP_SWDT1_3_CLK,
+ PINCTRL_GRP_SWDT1_4_CLK,
+ PINCTRL_GRP_SWDT1_5_CLK,
+ PINCTRL_GRP_SWDT1_6_CLK,
+ PINCTRL_GRP_SWDT1_7_CLK,
+ PINCTRL_GRP_SWDT1_8_CLK,
+ PINCTRL_GRP_SWDT1_9_CLK,
+ PINCTRL_GRP_SWDT1_10_CLK,
+ PINCTRL_GRP_SWDT1_11_CLK,
+ PINCTRL_GRP_SWDT1_12_CLK,
+ END_OF_GROUPS,
+ }),
+ },
+ [PINCTRL_FUNC_SWDT1_RST] = {
+ .name = "swdt1_rst",
+ .regval = 0x60,
+ .groups = &((uint16_t []) {
+ PINCTRL_GRP_SWDT1_0_RST,
+ PINCTRL_GRP_SWDT1_1_RST,
+ PINCTRL_GRP_SWDT1_2_RST,
+ PINCTRL_GRP_SWDT1_3_RST,
+ PINCTRL_GRP_SWDT1_4_RST,
+ PINCTRL_GRP_SWDT1_5_RST,
+ PINCTRL_GRP_SWDT1_6_RST,
+ PINCTRL_GRP_SWDT1_7_RST,
+ PINCTRL_GRP_SWDT1_8_RST,
+ PINCTRL_GRP_SWDT1_9_RST,
+ PINCTRL_GRP_SWDT1_10_RST,
+ PINCTRL_GRP_SWDT1_11_RST,
+ PINCTRL_GRP_SWDT1_12_RST,
+ END_OF_GROUPS,
+ }),
+ },
+ [PINCTRL_FUNC_PMU0] = {
+ .name = "pmu0",
+ .regval = 0x08,
+ .groups = &((uint16_t []) {
+ PINCTRL_GRP_PMU0_0,
+ PINCTRL_GRP_PMU0_1,
+ PINCTRL_GRP_PMU0_2,
+ PINCTRL_GRP_PMU0_3,
+ PINCTRL_GRP_PMU0_4,
+ PINCTRL_GRP_PMU0_5,
+ PINCTRL_GRP_PMU0_6,
+ PINCTRL_GRP_PMU0_7,
+ PINCTRL_GRP_PMU0_8,
+ PINCTRL_GRP_PMU0_9,
+ PINCTRL_GRP_PMU0_10,
+ PINCTRL_GRP_PMU0_11,
+ END_OF_GROUPS,
+ }),
+ },
+ [PINCTRL_FUNC_PCIE0] = {
+ .name = "pcie0",
+ .regval = 0x04,
+ .groups = &((uint16_t []) {
+ PINCTRL_GRP_PCIE0_0,
+ PINCTRL_GRP_PCIE0_1,
+ PINCTRL_GRP_PCIE0_2,
+ PINCTRL_GRP_PCIE0_3,
+ PINCTRL_GRP_PCIE0_4,
+ PINCTRL_GRP_PCIE0_5,
+ PINCTRL_GRP_PCIE0_6,
+ PINCTRL_GRP_PCIE0_7,
+ END_OF_GROUPS,
+ }),
+ },
+ [PINCTRL_FUNC_CSU0] = {
+ .name = "csu0",
+ .regval = 0x18,
+ .groups = &((uint16_t []) {
+ PINCTRL_GRP_CSU0_0,
+ PINCTRL_GRP_CSU0_1,
+ PINCTRL_GRP_CSU0_2,
+ PINCTRL_GRP_CSU0_3,
+ PINCTRL_GRP_CSU0_4,
+ PINCTRL_GRP_CSU0_5,
+ PINCTRL_GRP_CSU0_6,
+ PINCTRL_GRP_CSU0_7,
+ PINCTRL_GRP_CSU0_8,
+ PINCTRL_GRP_CSU0_9,
+ PINCTRL_GRP_CSU0_10,
+ PINCTRL_GRP_CSU0_11,
+ END_OF_GROUPS,
+ }),
+ },
+ [PINCTRL_FUNC_DPAUX0] = {
+ .name = "dpaux0",
+ .regval = 0x18,
+ .groups = &((uint16_t []) {
+ PINCTRL_GRP_DPAUX0_0,
+ PINCTRL_GRP_DPAUX0_1,
+ PINCTRL_GRP_DPAUX0_2,
+ PINCTRL_GRP_DPAUX0_3,
+ END_OF_GROUPS,
+ }),
+ },
+ [PINCTRL_FUNC_PJTAG0] = {
+ .name = "pjtag0",
+ .regval = 0x60,
+ .groups = &((uint16_t []) {
+ PINCTRL_GRP_PJTAG0_0,
+ PINCTRL_GRP_PJTAG0_1,
+ PINCTRL_GRP_PJTAG0_2,
+ PINCTRL_GRP_PJTAG0_3,
+ PINCTRL_GRP_PJTAG0_4,
+ PINCTRL_GRP_PJTAG0_5,
+ END_OF_GROUPS,
+ }),
+ },
+ [PINCTRL_FUNC_TRACE0] = {
+ .name = "trace0",
+ .regval = 0xe0,
+ .groups = &((uint16_t []) {
+ PINCTRL_GRP_TRACE0_0,
+ PINCTRL_GRP_TRACE0_1,
+ PINCTRL_GRP_TRACE0_2,
+ END_OF_GROUPS,
+ }),
+ },
+ [PINCTRL_FUNC_TRACE0_CLK] = {
+ .name = "trace0_clk",
+ .regval = 0xe0,
+ .groups = &((uint16_t []) {
+ PINCTRL_GRP_TRACE0_0_CLK,
+ PINCTRL_GRP_TRACE0_1_CLK,
+ PINCTRL_GRP_TRACE0_2_CLK,
+ END_OF_GROUPS,
+ }),
+ },
+ [PINCTRL_FUNC_TESTSCAN0] = {
+ .name = "testscan0",
+ .regval = 0x10,
+ .groups = &((uint16_t []) {
+ PINCTRL_GRP_TESTSCAN0_0,
+ END_OF_GROUPS,
+ }),
+ },
+};
+
+static struct zynqmp_pin_group zynqmp_pin_groups[MAX_PIN] = {
+ [PINCTRL_PIN_0] = {
+ .groups = &((uint16_t []) {
+ PINCTRL_GRP_QSPI0_0,
+ PINCTRL_GRP_RESERVED,
+ PINCTRL_GRP_RESERVED,
+ PINCTRL_GRP_TESTSCAN0_0,
+ PINCTRL_GRP_RESERVED,
+ PINCTRL_GRP_GPIO0_0,
+ PINCTRL_GRP_CAN1_0,
+ PINCTRL_GRP_I2C1_0,
+ PINCTRL_GRP_PJTAG0_0,
+ PINCTRL_GRP_SPI0_0,
+ PINCTRL_GRP_TTC3_0_CLK,
+ PINCTRL_GRP_UART1_0,
+ PINCTRL_GRP_TRACE0_0_CLK,
+ END_OF_GROUPS,
+ }),
+ },
+ [PINCTRL_PIN_1] = {
+ .groups = &((uint16_t []) {
+ PINCTRL_GRP_QSPI0_0,
+ PINCTRL_GRP_RESERVED,
+ PINCTRL_GRP_RESERVED,
+ PINCTRL_GRP_TESTSCAN0_0,
+ PINCTRL_GRP_RESERVED,
+ PINCTRL_GRP_GPIO0_1,
+ PINCTRL_GRP_CAN1_0,
+ PINCTRL_GRP_I2C1_0,
+ PINCTRL_GRP_PJTAG0_0,
+ PINCTRL_GRP_SPI0_0_SS2,
+ PINCTRL_GRP_TTC3_0_WAV,
+ PINCTRL_GRP_UART1_0,
+ PINCTRL_GRP_TRACE0_0_CLK,
+ END_OF_GROUPS,
+ }),
+ },
+ [PINCTRL_PIN_2] = {
+ .groups = &((uint16_t []) {
+ PINCTRL_GRP_QSPI0_0,
+ PINCTRL_GRP_RESERVED,
+ PINCTRL_GRP_RESERVED,
+ PINCTRL_GRP_TESTSCAN0_0,
+ PINCTRL_GRP_RESERVED,
+ PINCTRL_GRP_GPIO0_2,
+ PINCTRL_GRP_CAN0_0,
+ PINCTRL_GRP_I2C0_0,
+ PINCTRL_GRP_PJTAG0_0,
+ PINCTRL_GRP_SPI0_0_SS1,
+ PINCTRL_GRP_TTC2_0_CLK,
+ PINCTRL_GRP_UART0_0,
+ PINCTRL_GRP_TRACE0_0,
+ END_OF_GROUPS,
+ }),
+ },
+ [PINCTRL_PIN_3] = {
+ .groups = &((uint16_t []) {
+ PINCTRL_GRP_QSPI0_0,
+ PINCTRL_GRP_RESERVED,
+ PINCTRL_GRP_RESERVED,
+ PINCTRL_GRP_TESTSCAN0_0,
+ PINCTRL_GRP_RESERVED,
+ PINCTRL_GRP_GPIO0_3,
+ PINCTRL_GRP_CAN0_0,
+ PINCTRL_GRP_I2C0_0,
+ PINCTRL_GRP_PJTAG0_0,
+ PINCTRL_GRP_SPI0_0_SS0,
+ PINCTRL_GRP_TTC2_0_WAV,
+ PINCTRL_GRP_UART0_0,
+ PINCTRL_GRP_TRACE0_0,
+ END_OF_GROUPS,
+ }),
+ },
+ [PINCTRL_PIN_4] = {
+ .groups = &((uint16_t []) {
+ PINCTRL_GRP_QSPI0_0,
+ PINCTRL_GRP_RESERVED,
+ PINCTRL_GRP_RESERVED,
+ PINCTRL_GRP_TESTSCAN0_0,
+ PINCTRL_GRP_RESERVED,
+ PINCTRL_GRP_GPIO0_4,
+ PINCTRL_GRP_CAN1_1,
+ PINCTRL_GRP_I2C1_1,
+ PINCTRL_GRP_SWDT1_0_CLK,
+ PINCTRL_GRP_SPI0_0,
+ PINCTRL_GRP_TTC1_0_CLK,
+ PINCTRL_GRP_UART1_1,
+ PINCTRL_GRP_TRACE0_0,
+ END_OF_GROUPS,
+ }),
+ },
+ [PINCTRL_PIN_5] = {
+ .groups = &((uint16_t []) {
+ PINCTRL_GRP_QSPI_SS,
+ PINCTRL_GRP_RESERVED,
+ PINCTRL_GRP_RESERVED,
+ PINCTRL_GRP_TESTSCAN0_0,
+ PINCTRL_GRP_RESERVED,
+ PINCTRL_GRP_GPIO0_5,
+ PINCTRL_GRP_CAN1_1,
+ PINCTRL_GRP_I2C1_1,
+ PINCTRL_GRP_SWDT1_0_RST,
+ PINCTRL_GRP_SPI0_0,
+ PINCTRL_GRP_TTC1_0_WAV,
+ PINCTRL_GRP_UART1_1,
+ PINCTRL_GRP_TRACE0_0,
+ END_OF_GROUPS,
+ }),
+ },
+ [PINCTRL_PIN_6] = {
+ .groups = &((uint16_t []) {
+ PINCTRL_GRP_QSPI_FBCLK,
+ PINCTRL_GRP_RESERVED,
+ PINCTRL_GRP_RESERVED,
+ PINCTRL_GRP_TESTSCAN0_0,
+ PINCTRL_GRP_RESERVED,
+ PINCTRL_GRP_GPIO0_6,
+ PINCTRL_GRP_CAN0_1,
+ PINCTRL_GRP_I2C0_1,
+ PINCTRL_GRP_SWDT0_0_CLK,
+ PINCTRL_GRP_SPI1_0,
+ PINCTRL_GRP_TTC0_0_CLK,
+ PINCTRL_GRP_UART0_1,
+ PINCTRL_GRP_TRACE0_0,
+ END_OF_GROUPS,
+ }),
+ },
+ [PINCTRL_PIN_7] = {
+ .groups = &((uint16_t []) {
+ PINCTRL_GRP_QSPI_SS,
+ PINCTRL_GRP_RESERVED,
+ PINCTRL_GRP_RESERVED,
+ PINCTRL_GRP_TESTSCAN0_0,
+ PINCTRL_GRP_RESERVED,
+ PINCTRL_GRP_GPIO0_7,
+ PINCTRL_GRP_CAN0_1,
+ PINCTRL_GRP_I2C0_1,
+ PINCTRL_GRP_SWDT0_0_RST,
+ PINCTRL_GRP_SPI1_0_SS2,
+ PINCTRL_GRP_TTC0_0_WAV,
+ PINCTRL_GRP_UART0_1,
+ PINCTRL_GRP_TRACE0_0,
+ END_OF_GROUPS,
+ }),
+ },
+ [PINCTRL_PIN_8] = {
+ .groups = &((uint16_t []) {
+ PINCTRL_GRP_QSPI0_0,
+ PINCTRL_GRP_RESERVED,
+ PINCTRL_GRP_RESERVED,
+ PINCTRL_GRP_TESTSCAN0_0,
+ PINCTRL_GRP_RESERVED,
+ PINCTRL_GRP_GPIO0_8,
+ PINCTRL_GRP_CAN1_2,
+ PINCTRL_GRP_I2C1_2,
+ PINCTRL_GRP_SWDT1_1_CLK,
+ PINCTRL_GRP_SPI1_0_SS1,
+ PINCTRL_GRP_TTC3_1_CLK,
+ PINCTRL_GRP_UART1_2,
+ PINCTRL_GRP_TRACE0_0,
+ END_OF_GROUPS,
+ }),
+ },
+ [PINCTRL_PIN_9] = {
+ .groups = &((uint16_t []) {
+ PINCTRL_GRP_QSPI0_0,
+ PINCTRL_GRP_NAND0_0_CE,
+ PINCTRL_GRP_RESERVED,
+ PINCTRL_GRP_TESTSCAN0_0,
+ PINCTRL_GRP_RESERVED,
+ PINCTRL_GRP_GPIO0_9,
+ PINCTRL_GRP_CAN1_2,
+ PINCTRL_GRP_I2C1_2,
+ PINCTRL_GRP_SWDT1_1_RST,
+ PINCTRL_GRP_SPI1_0_SS0,
+ PINCTRL_GRP_TTC3_1_WAV,
+ PINCTRL_GRP_UART1_2,
+ PINCTRL_GRP_TRACE0_0,
+ END_OF_GROUPS,
+ }),
+ },
+ [PINCTRL_PIN_10] = {
+ .groups = &((uint16_t []) {
+ PINCTRL_GRP_QSPI0_0,
+ PINCTRL_GRP_NAND0_0_RB,
+ PINCTRL_GRP_RESERVED,
+ PINCTRL_GRP_TESTSCAN0_0,
+ PINCTRL_GRP_RESERVED,
+ PINCTRL_GRP_GPIO0_10,
+ PINCTRL_GRP_CAN0_2,
+ PINCTRL_GRP_I2C0_2,
+ PINCTRL_GRP_SWDT0_1_CLK,
+ PINCTRL_GRP_SPI1_0,
+ PINCTRL_GRP_TTC2_1_CLK,
+ PINCTRL_GRP_UART0_2,
+ PINCTRL_GRP_TRACE0_0,
+ END_OF_GROUPS,
+ }),
+ },
+ [PINCTRL_PIN_11] = {
+ .groups = &((uint16_t []) {
+ PINCTRL_GRP_QSPI0_0,
+ PINCTRL_GRP_NAND0_0_RB,
+ PINCTRL_GRP_RESERVED,
+ PINCTRL_GRP_TESTSCAN0_0,
+ PINCTRL_GRP_RESERVED,
+ PINCTRL_GRP_GPIO0_11,
+ PINCTRL_GRP_CAN0_2,
+ PINCTRL_GRP_I2C0_2,
+ PINCTRL_GRP_SWDT0_1_RST,
+ PINCTRL_GRP_SPI1_0,
+ PINCTRL_GRP_TTC2_1_WAV,
+ PINCTRL_GRP_UART0_2,
+ PINCTRL_GRP_TRACE0_0,
+ END_OF_GROUPS,
+ }),
+ },
+ [PINCTRL_PIN_12] = {
+ .groups = &((uint16_t []) {
+ PINCTRL_GRP_QSPI0_0,
+ PINCTRL_GRP_NAND0_0_DQS,
+ PINCTRL_GRP_RESERVED,
+ PINCTRL_GRP_TESTSCAN0_0,
+ PINCTRL_GRP_RESERVED,
+ PINCTRL_GRP_GPIO0_12,
+ PINCTRL_GRP_CAN1_3,
+ PINCTRL_GRP_I2C1_3,
+ PINCTRL_GRP_PJTAG0_1,
+ PINCTRL_GRP_SPI0_1,
+ PINCTRL_GRP_TTC1_1_CLK,
+ PINCTRL_GRP_UART1_3,
+ PINCTRL_GRP_TRACE0_0,
+ END_OF_GROUPS,
+ }),
+ },
+ [PINCTRL_PIN_13] = {
+ .groups = &((uint16_t []) {
+ PINCTRL_GRP_RESERVED,
+ PINCTRL_GRP_NAND0_0,
+ PINCTRL_GRP_SDIO0_0,
+ PINCTRL_GRP_TESTSCAN0_0,
+ PINCTRL_GRP_RESERVED,
+ PINCTRL_GRP_GPIO0_13,
+ PINCTRL_GRP_CAN1_3,
+ PINCTRL_GRP_I2C1_3,
+ PINCTRL_GRP_PJTAG0_1,
+ PINCTRL_GRP_SPI0_1_SS2,
+ PINCTRL_GRP_TTC1_1_WAV,
+ PINCTRL_GRP_UART1_3,
+ PINCTRL_GRP_TRACE0_0,
+ PINCTRL_GRP_SDIO0_4BIT_0_0,
+ PINCTRL_GRP_SDIO0_1BIT_0_0,
+ END_OF_GROUPS,
+ }),
+ },
+ [PINCTRL_PIN_14] = {
+ .groups = &((uint16_t []) {
+ PINCTRL_GRP_RESERVED,
+ PINCTRL_GRP_NAND0_0,
+ PINCTRL_GRP_SDIO0_0,
+ PINCTRL_GRP_TESTSCAN0_0,
+ PINCTRL_GRP_RESERVED,
+ PINCTRL_GRP_GPIO0_14,
+ PINCTRL_GRP_CAN0_3,
+ PINCTRL_GRP_I2C0_3,
+ PINCTRL_GRP_PJTAG0_1,
+ PINCTRL_GRP_SPI0_1_SS1,
+ PINCTRL_GRP_TTC0_1_CLK,
+ PINCTRL_GRP_UART0_3,
+ PINCTRL_GRP_TRACE0_0,
+ PINCTRL_GRP_SDIO0_4BIT_0_0,
+ PINCTRL_GRP_SDIO0_1BIT_0_1,
+ END_OF_GROUPS,
+ }),
+ },
+ [PINCTRL_PIN_15] = {
+ .groups = &((uint16_t []) {
+ PINCTRL_GRP_RESERVED,
+ PINCTRL_GRP_NAND0_0,
+ PINCTRL_GRP_SDIO0_0,
+ PINCTRL_GRP_TESTSCAN0_0,
+ PINCTRL_GRP_RESERVED,
+ PINCTRL_GRP_GPIO0_15,
+ PINCTRL_GRP_CAN0_3,
+ PINCTRL_GRP_I2C0_3,
+ PINCTRL_GRP_PJTAG0_1,
+ PINCTRL_GRP_SPI0_1_SS0,
+ PINCTRL_GRP_TTC0_1_WAV,
+ PINCTRL_GRP_UART0_3,
+ PINCTRL_GRP_TRACE0_0,
+ PINCTRL_GRP_SDIO0_4BIT_0_0,
+ PINCTRL_GRP_SDIO0_1BIT_0_2,
+ END_OF_GROUPS,
+ }),
+ },
+ [PINCTRL_PIN_16] = {
+ .groups = &((uint16_t []) {
+ PINCTRL_GRP_RESERVED,
+ PINCTRL_GRP_NAND0_0,
+ PINCTRL_GRP_SDIO0_0,
+ PINCTRL_GRP_TESTSCAN0_0,
+ PINCTRL_GRP_RESERVED,
+ PINCTRL_GRP_GPIO0_16,
+ PINCTRL_GRP_CAN1_4,
+ PINCTRL_GRP_I2C1_4,
+ PINCTRL_GRP_SWDT1_2_CLK,
+ PINCTRL_GRP_SPI0_1,
+ PINCTRL_GRP_TTC3_2_CLK,
+ PINCTRL_GRP_UART1_4,
+ PINCTRL_GRP_TRACE0_0,
+ PINCTRL_GRP_SDIO0_4BIT_0_0,
+ PINCTRL_GRP_SDIO0_1BIT_0_3,
+ END_OF_GROUPS,
+ }),
+ },
+ [PINCTRL_PIN_17] = {
+ .groups = &((uint16_t []) {
+ PINCTRL_GRP_RESERVED,
+ PINCTRL_GRP_NAND0_0,
+ PINCTRL_GRP_SDIO0_0,
+ PINCTRL_GRP_TESTSCAN0_0,
+ PINCTRL_GRP_RESERVED,
+ PINCTRL_GRP_GPIO0_17,
+ PINCTRL_GRP_CAN1_4,
+ PINCTRL_GRP_I2C1_4,
+ PINCTRL_GRP_SWDT1_2_RST,
+ PINCTRL_GRP_SPI0_1,
+ PINCTRL_GRP_TTC3_2_WAV,
+ PINCTRL_GRP_UART1_4,
+ PINCTRL_GRP_TRACE0_0,
+ PINCTRL_GRP_SDIO0_4BIT_0_1,
+ PINCTRL_GRP_SDIO0_1BIT_0_4,
+ END_OF_GROUPS,
+ }),
+ },
+ [PINCTRL_PIN_18] = {
+ .groups = &((uint16_t []) {
+ PINCTRL_GRP_RESERVED,
+ PINCTRL_GRP_NAND0_0,
+ PINCTRL_GRP_SDIO0_0,
+ PINCTRL_GRP_TESTSCAN0_0,
+ PINCTRL_GRP_CSU0_0,
+ PINCTRL_GRP_GPIO0_18,
+ PINCTRL_GRP_CAN0_4,
+ PINCTRL_GRP_I2C0_4,
+ PINCTRL_GRP_SWDT0_2_CLK,
+ PINCTRL_GRP_SPI1_1,
+ PINCTRL_GRP_TTC2_2_CLK,
+ PINCTRL_GRP_UART0_4,
+ PINCTRL_GRP_RESERVED,
+ PINCTRL_GRP_SDIO0_4BIT_0_1,
+ PINCTRL_GRP_SDIO0_1BIT_0_5,
+ END_OF_GROUPS,
+ }),
+ },
+ [PINCTRL_PIN_19] = {
+ .groups = &((uint16_t []) {
+ PINCTRL_GRP_RESERVED,
+ PINCTRL_GRP_NAND0_0,
+ PINCTRL_GRP_SDIO0_0,
+ PINCTRL_GRP_TESTSCAN0_0,
+ PINCTRL_GRP_CSU0_1,
+ PINCTRL_GRP_GPIO0_19,
+ PINCTRL_GRP_CAN0_4,
+ PINCTRL_GRP_I2C0_4,
+ PINCTRL_GRP_SWDT0_2_RST,
+ PINCTRL_GRP_SPI1_1_SS2,
+ PINCTRL_GRP_TTC2_2_WAV,
+ PINCTRL_GRP_UART0_4,
+ PINCTRL_GRP_RESERVED,
+ PINCTRL_GRP_SDIO0_4BIT_0_1,
+ PINCTRL_GRP_SDIO0_1BIT_0_6,
+ END_OF_GROUPS,
+ }),
+ },
+ [PINCTRL_PIN_20] = {
+ .groups = &((uint16_t []) {
+ PINCTRL_GRP_RESERVED,
+ PINCTRL_GRP_NAND0_0,
+ PINCTRL_GRP_SDIO0_0,
+ PINCTRL_GRP_TESTSCAN0_0,
+ PINCTRL_GRP_CSU0_2,
+ PINCTRL_GRP_GPIO0_20,
+ PINCTRL_GRP_CAN1_5,
+ PINCTRL_GRP_I2C1_5,
+ PINCTRL_GRP_SWDT1_3_CLK,
+ PINCTRL_GRP_SPI1_1_SS1,
+ PINCTRL_GRP_TTC1_2_CLK,
+ PINCTRL_GRP_UART1_5,
+ PINCTRL_GRP_RESERVED,
+ PINCTRL_GRP_SDIO0_4BIT_0_1,
+ PINCTRL_GRP_SDIO0_1BIT_0_7,
+ END_OF_GROUPS,
+ }),
+ },
+ [PINCTRL_PIN_21] = {
+ .groups = &((uint16_t []) {
+ PINCTRL_GRP_RESERVED,
+ PINCTRL_GRP_NAND0_0,
+ PINCTRL_GRP_SDIO0_0,
+ PINCTRL_GRP_TESTSCAN0_0,
+ PINCTRL_GRP_CSU0_3,
+ PINCTRL_GRP_GPIO0_21,
+ PINCTRL_GRP_CAN1_5,
+ PINCTRL_GRP_I2C1_5,
+ PINCTRL_GRP_SWDT1_3_RST,
+ PINCTRL_GRP_SPI1_1_SS0,
+ PINCTRL_GRP_TTC1_2_WAV,
+ PINCTRL_GRP_UART1_5,
+ PINCTRL_GRP_RESERVED,
+ PINCTRL_GRP_SDIO0_4BIT_0_0,
+ PINCTRL_GRP_SDIO0_4BIT_0_1,
+ PINCTRL_GRP_SDIO0_1BIT_0_0,
+ PINCTRL_GRP_SDIO0_1BIT_0_1,
+ PINCTRL_GRP_SDIO0_1BIT_0_2,
+ PINCTRL_GRP_SDIO0_1BIT_0_3,
+ PINCTRL_GRP_SDIO0_1BIT_0_4,
+ PINCTRL_GRP_SDIO0_1BIT_0_5,
+ PINCTRL_GRP_SDIO0_1BIT_0_6,
+ PINCTRL_GRP_SDIO0_1BIT_0_7,
+ END_OF_GROUPS,
+ }),
+ },
+ [PINCTRL_PIN_22] = {
+ .groups = &((uint16_t []) {
+ PINCTRL_GRP_RESERVED,
+ PINCTRL_GRP_NAND0_0,
+ PINCTRL_GRP_SDIO0_0,
+ PINCTRL_GRP_TESTSCAN0_0,
+ PINCTRL_GRP_CSU0_4,
+ PINCTRL_GRP_GPIO0_22,
+ PINCTRL_GRP_CAN0_5,
+ PINCTRL_GRP_I2C0_5,
+ PINCTRL_GRP_SWDT0_3_CLK,
+ PINCTRL_GRP_SPI1_1,
+ PINCTRL_GRP_TTC0_2_CLK,
+ PINCTRL_GRP_UART0_5,
+ PINCTRL_GRP_RESERVED,
+ PINCTRL_GRP_SDIO0_4BIT_0_0,
+ PINCTRL_GRP_SDIO0_4BIT_0_1,
+ PINCTRL_GRP_SDIO0_1BIT_0_0,
+ PINCTRL_GRP_SDIO0_1BIT_0_1,
+ PINCTRL_GRP_SDIO0_1BIT_0_2,
+ PINCTRL_GRP_SDIO0_1BIT_0_3,
+ PINCTRL_GRP_SDIO0_1BIT_0_4,
+ PINCTRL_GRP_SDIO0_1BIT_0_5,
+ PINCTRL_GRP_SDIO0_1BIT_0_6,
+ PINCTRL_GRP_SDIO0_1BIT_0_7,
+ END_OF_GROUPS,
+ }),
+ },
+ [PINCTRL_PIN_23] = {
+ .groups = &((uint16_t []) {
+ PINCTRL_GRP_RESERVED,
+ PINCTRL_GRP_NAND0_0,
+ PINCTRL_GRP_SDIO0_0_PC,
+ PINCTRL_GRP_TESTSCAN0_0,
+ PINCTRL_GRP_CSU0_5,
+ PINCTRL_GRP_GPIO0_23,
+ PINCTRL_GRP_CAN0_5,
+ PINCTRL_GRP_I2C0_5,
+ PINCTRL_GRP_SWDT0_3_RST,
+ PINCTRL_GRP_SPI1_1,
+ PINCTRL_GRP_TTC0_2_WAV,
+ PINCTRL_GRP_UART0_5,
+ PINCTRL_GRP_RESERVED,
+ END_OF_GROUPS,
+ }),
+ },
+ [PINCTRL_PIN_24] = {
+ .groups = &((uint16_t []) {
+ PINCTRL_GRP_RESERVED,
+ PINCTRL_GRP_NAND0_0,
+ PINCTRL_GRP_SDIO0_0_CD,
+ PINCTRL_GRP_TESTSCAN0_0,
+ PINCTRL_GRP_CSU0_6,
+ PINCTRL_GRP_GPIO0_24,
+ PINCTRL_GRP_CAN1_6,
+ PINCTRL_GRP_I2C1_6,
+ PINCTRL_GRP_SWDT1_4_CLK,
+ PINCTRL_GRP_RESERVED,
+ PINCTRL_GRP_TTC3_3_CLK,
+ PINCTRL_GRP_UART1_6,
+ PINCTRL_GRP_RESERVED,
+ END_OF_GROUPS,
+ }),
+ },
+ [PINCTRL_PIN_25] = {
+ .groups = &((uint16_t []) {
+ PINCTRL_GRP_RESERVED,
+ PINCTRL_GRP_NAND0_0,
+ PINCTRL_GRP_SDIO0_0_WP,
+ PINCTRL_GRP_TESTSCAN0_0,
+ PINCTRL_GRP_CSU0_7,
+ PINCTRL_GRP_GPIO0_25,
+ PINCTRL_GRP_CAN1_6,
+ PINCTRL_GRP_I2C1_6,
+ PINCTRL_GRP_SWDT1_4_RST,
+ PINCTRL_GRP_RESERVED,
+ PINCTRL_GRP_TTC3_3_WAV,
+ PINCTRL_GRP_UART1_6,
+ PINCTRL_GRP_RESERVED,
+ END_OF_GROUPS,
+ }),
+ },
+ [PINCTRL_PIN_26] = {
+ .groups = &((uint16_t []) {
+ PINCTRL_GRP_GEMTSU0_0,
+ PINCTRL_GRP_NAND0_1_CE,
+ PINCTRL_GRP_PMU0_0,
+ PINCTRL_GRP_TESTSCAN0_0,
+ PINCTRL_GRP_CSU0_8,
+ PINCTRL_GRP_GPIO0_26,
+ PINCTRL_GRP_CAN0_6,
+ PINCTRL_GRP_I2C0_6,
+ PINCTRL_GRP_PJTAG0_2,
+ PINCTRL_GRP_SPI0_2,
+ PINCTRL_GRP_TTC2_3_CLK,
+ PINCTRL_GRP_UART0_6,
+ PINCTRL_GRP_TRACE0_1,
+ END_OF_GROUPS,
+ }),
+ },
+ [PINCTRL_PIN_27] = {
+ .groups = &((uint16_t []) {
+ PINCTRL_GRP_ETHERNET0_0,
+ PINCTRL_GRP_NAND0_1_RB,
+ PINCTRL_GRP_PMU0_1,
+ PINCTRL_GRP_TESTSCAN0_0,
+ PINCTRL_GRP_DPAUX0_0,
+ PINCTRL_GRP_GPIO0_27,
+ PINCTRL_GRP_CAN0_6,
+ PINCTRL_GRP_I2C0_6,
+ PINCTRL_GRP_PJTAG0_2,
+ PINCTRL_GRP_SPI0_2_SS2,
+ PINCTRL_GRP_TTC2_3_WAV,
+ PINCTRL_GRP_UART0_6,
+ PINCTRL_GRP_TRACE0_1,
+ END_OF_GROUPS,
+ }),
+ },
+ [PINCTRL_PIN_28] = {
+ .groups = &((uint16_t []) {
+ PINCTRL_GRP_ETHERNET0_0,
+ PINCTRL_GRP_NAND0_1_RB,
+ PINCTRL_GRP_PMU0_2,
+ PINCTRL_GRP_TESTSCAN0_0,
+ PINCTRL_GRP_DPAUX0_0,
+ PINCTRL_GRP_GPIO0_28,
+ PINCTRL_GRP_CAN1_7,
+ PINCTRL_GRP_I2C1_7,
+ PINCTRL_GRP_PJTAG0_2,
+ PINCTRL_GRP_SPI0_2_SS1,
+ PINCTRL_GRP_TTC1_3_CLK,
+ PINCTRL_GRP_UART1_7,
+ PINCTRL_GRP_TRACE0_1,
+ END_OF_GROUPS,
+ }),
+ },
+ [PINCTRL_PIN_29] = {
+ .groups = &((uint16_t []) {
+ PINCTRL_GRP_ETHERNET0_0,
+ PINCTRL_GRP_PCIE0_0,
+ PINCTRL_GRP_PMU0_3,
+ PINCTRL_GRP_TESTSCAN0_0,
+ PINCTRL_GRP_DPAUX0_1,
+ PINCTRL_GRP_GPIO0_29,
+ PINCTRL_GRP_CAN1_7,
+ PINCTRL_GRP_I2C1_7,
+ PINCTRL_GRP_PJTAG0_2,
+ PINCTRL_GRP_SPI0_2_SS0,
+ PINCTRL_GRP_TTC1_3_WAV,
+ PINCTRL_GRP_UART1_7,
+ PINCTRL_GRP_TRACE0_1,
+ END_OF_GROUPS,
+ }),
+ },
+ [PINCTRL_PIN_30] = {
+ .groups = &((uint16_t []) {
+ PINCTRL_GRP_ETHERNET0_0,
+ PINCTRL_GRP_PCIE0_1,
+ PINCTRL_GRP_PMU0_4,
+ PINCTRL_GRP_TESTSCAN0_0,
+ PINCTRL_GRP_DPAUX0_1,
+ PINCTRL_GRP_GPIO0_30,
+ PINCTRL_GRP_CAN0_7,
+ PINCTRL_GRP_I2C0_7,
+ PINCTRL_GRP_SWDT0_4_CLK,
+ PINCTRL_GRP_SPI0_2,
+ PINCTRL_GRP_TTC0_3_CLK,
+ PINCTRL_GRP_UART0_7,
+ PINCTRL_GRP_TRACE0_1,
+ END_OF_GROUPS,
+ }),
+ },
+ [PINCTRL_PIN_31] = {
+ .groups = &((uint16_t []) {
+ PINCTRL_GRP_ETHERNET0_0,
+ PINCTRL_GRP_PCIE0_2,
+ PINCTRL_GRP_PMU0_5,
+ PINCTRL_GRP_TESTSCAN0_0,
+ PINCTRL_GRP_CSU0_9,
+ PINCTRL_GRP_GPIO0_31,
+ PINCTRL_GRP_CAN0_7,
+ PINCTRL_GRP_I2C0_7,
+ PINCTRL_GRP_SWDT0_4_RST,
+ PINCTRL_GRP_SPI0_2,
+ PINCTRL_GRP_TTC0_3_WAV,
+ PINCTRL_GRP_UART0_7,
+ PINCTRL_GRP_TRACE0_1,
+ END_OF_GROUPS,
+ }),
+ },
+ [PINCTRL_PIN_32] = {
+ .groups = &((uint16_t []) {
+ PINCTRL_GRP_ETHERNET0_0,
+ PINCTRL_GRP_NAND0_1_DQS,
+ PINCTRL_GRP_PMU0_6,
+ PINCTRL_GRP_TESTSCAN0_0,
+ PINCTRL_GRP_CSU0_10,
+ PINCTRL_GRP_GPIO0_32,
+ PINCTRL_GRP_CAN1_8,
+ PINCTRL_GRP_I2C1_8,
+ PINCTRL_GRP_SWDT1_5_CLK,
+ PINCTRL_GRP_SPI1_2,
+ PINCTRL_GRP_TTC3_4_CLK,
+ PINCTRL_GRP_UART1_8,
+ PINCTRL_GRP_TRACE0_1,
+ END_OF_GROUPS,
+ }),
+ },
+ [PINCTRL_PIN_33] = {
+ .groups = &((uint16_t []) {
+ PINCTRL_GRP_ETHERNET0_0,
+ PINCTRL_GRP_PCIE0_3,
+ PINCTRL_GRP_PMU0_7,
+ PINCTRL_GRP_TESTSCAN0_0,
+ PINCTRL_GRP_CSU0_11,
+ PINCTRL_GRP_GPIO0_33,
+ PINCTRL_GRP_CAN1_8,
+ PINCTRL_GRP_I2C1_8,
+ PINCTRL_GRP_SWDT1_5_RST,
+ PINCTRL_GRP_SPI1_2_SS2,
+ PINCTRL_GRP_TTC3_4_WAV,
+ PINCTRL_GRP_UART1_8,
+ PINCTRL_GRP_TRACE0_1,
+ END_OF_GROUPS,
+ }),
+ },
+ [PINCTRL_PIN_34] = {
+ .groups = &((uint16_t []) {
+ PINCTRL_GRP_ETHERNET0_0,
+ PINCTRL_GRP_PCIE0_4,
+ PINCTRL_GRP_PMU0_8,
+ PINCTRL_GRP_TESTSCAN0_0,
+ PINCTRL_GRP_DPAUX0_2,
+ PINCTRL_GRP_GPIO0_34,
+ PINCTRL_GRP_CAN0_8,
+ PINCTRL_GRP_I2C0_8,
+ PINCTRL_GRP_SWDT0_5_CLK,
+ PINCTRL_GRP_SPI1_2_SS1,
+ PINCTRL_GRP_TTC2_4_CLK,
+ PINCTRL_GRP_UART0_8,
+ PINCTRL_GRP_TRACE0_1,
+ END_OF_GROUPS,
+ }),
+ },
+ [PINCTRL_PIN_35] = {
+ .groups = &((uint16_t []) {
+ PINCTRL_GRP_ETHERNET0_0,
+ PINCTRL_GRP_PCIE0_5,
+ PINCTRL_GRP_PMU0_9,
+ PINCTRL_GRP_TESTSCAN0_0,
+ PINCTRL_GRP_DPAUX0_2,
+ PINCTRL_GRP_GPIO0_35,
+ PINCTRL_GRP_CAN0_8,
+ PINCTRL_GRP_I2C0_8,
+ PINCTRL_GRP_SWDT0_5_RST,
+ PINCTRL_GRP_SPI1_2_SS0,
+ PINCTRL_GRP_TTC2_4_WAV,
+ PINCTRL_GRP_UART0_8,
+ PINCTRL_GRP_TRACE0_1,
+ END_OF_GROUPS,
+ }),
+ },
+ [PINCTRL_PIN_36] = {
+ .groups = &((uint16_t []) {
+ PINCTRL_GRP_ETHERNET0_0,
+ PINCTRL_GRP_PCIE0_6,
+ PINCTRL_GRP_PMU0_10,
+ PINCTRL_GRP_TESTSCAN0_0,
+ PINCTRL_GRP_DPAUX0_3,
+ PINCTRL_GRP_GPIO0_36,
+ PINCTRL_GRP_CAN1_9,
+ PINCTRL_GRP_I2C1_9,
+ PINCTRL_GRP_SWDT1_6_CLK,
+ PINCTRL_GRP_SPI1_2,
+ PINCTRL_GRP_TTC1_4_CLK,
+ PINCTRL_GRP_UART1_9,
+ PINCTRL_GRP_TRACE0_1,
+ END_OF_GROUPS,
+ }),
+ },
+ [PINCTRL_PIN_37] = {
+ .groups = &((uint16_t []) {
+ PINCTRL_GRP_ETHERNET0_0,
+ PINCTRL_GRP_PCIE0_7,
+ PINCTRL_GRP_PMU0_11,
+ PINCTRL_GRP_TESTSCAN0_0,
+ PINCTRL_GRP_DPAUX0_3,
+ PINCTRL_GRP_GPIO0_37,
+ PINCTRL_GRP_CAN1_9,
+ PINCTRL_GRP_I2C1_9,
+ PINCTRL_GRP_SWDT1_6_RST,
+ PINCTRL_GRP_SPI1_2,
+ PINCTRL_GRP_TTC1_4_WAV,
+ PINCTRL_GRP_UART1_9,
+ PINCTRL_GRP_TRACE0_1,
+ END_OF_GROUPS,
+ }),
+ },
+ [PINCTRL_PIN_38] = {
+ .groups = &((uint16_t []) {
+ PINCTRL_GRP_ETHERNET1_0,
+ PINCTRL_GRP_RESERVED,
+ PINCTRL_GRP_SDIO0_1,
+ PINCTRL_GRP_RESERVED,
+ PINCTRL_GRP_RESERVED,
+ PINCTRL_GRP_GPIO0_38,
+ PINCTRL_GRP_CAN0_9,
+ PINCTRL_GRP_I2C0_9,
+ PINCTRL_GRP_PJTAG0_3,
+ PINCTRL_GRP_SPI0_3,
+ PINCTRL_GRP_TTC0_4_CLK,
+ PINCTRL_GRP_UART0_9,
+ PINCTRL_GRP_TRACE0_1_CLK,
+ PINCTRL_GRP_SDIO0_4BIT_1_0,
+ PINCTRL_GRP_SDIO0_4BIT_1_1,
+ PINCTRL_GRP_SDIO0_1BIT_1_0,
+ PINCTRL_GRP_SDIO0_1BIT_1_1,
+ PINCTRL_GRP_SDIO0_1BIT_1_2,
+ PINCTRL_GRP_SDIO0_1BIT_1_3,
+ PINCTRL_GRP_SDIO0_1BIT_1_4,
+ PINCTRL_GRP_SDIO0_1BIT_1_5,
+ PINCTRL_GRP_SDIO0_1BIT_1_6,
+ PINCTRL_GRP_SDIO0_1BIT_1_7,
+ END_OF_GROUPS,
+ }),
+ },
+ [PINCTRL_PIN_39] = {
+ .groups = &((uint16_t []) {
+ PINCTRL_GRP_ETHERNET1_0,
+ PINCTRL_GRP_RESERVED,
+ PINCTRL_GRP_SDIO0_1_CD,
+ PINCTRL_GRP_SDIO1_0,
+ PINCTRL_GRP_RESERVED,
+ PINCTRL_GRP_GPIO0_39,
+ PINCTRL_GRP_CAN0_9,
+ PINCTRL_GRP_I2C0_9,
+ PINCTRL_GRP_PJTAG0_3,
+ PINCTRL_GRP_SPI0_3_SS2,
+ PINCTRL_GRP_TTC0_4_WAV,
+ PINCTRL_GRP_UART0_9,
+ PINCTRL_GRP_TRACE0_1_CLK,
+ PINCTRL_GRP_SDIO1_4BIT_0_0,
+ PINCTRL_GRP_SDIO1_1BIT_0_0,
+ END_OF_GROUPS,
+ }),
+ },
+ [PINCTRL_PIN_40] = {
+ .groups = &((uint16_t []) {
+ PINCTRL_GRP_ETHERNET1_0,
+ PINCTRL_GRP_RESERVED,
+ PINCTRL_GRP_SDIO0_1,
+ PINCTRL_GRP_SDIO1_0,
+ PINCTRL_GRP_RESERVED,
+ PINCTRL_GRP_GPIO0_40,
+ PINCTRL_GRP_CAN1_10,
+ PINCTRL_GRP_I2C1_10,
+ PINCTRL_GRP_PJTAG0_3,
+ PINCTRL_GRP_SPI0_3_SS1,
+ PINCTRL_GRP_TTC3_5_CLK,
+ PINCTRL_GRP_UART1_10,
+ PINCTRL_GRP_TRACE0_1,
+ PINCTRL_GRP_SDIO0_4BIT_1_0,
+ PINCTRL_GRP_SDIO0_4BIT_1_1,
+ PINCTRL_GRP_SDIO0_1BIT_1_0,
+ PINCTRL_GRP_SDIO0_1BIT_1_1,
+ PINCTRL_GRP_SDIO0_1BIT_1_2,
+ PINCTRL_GRP_SDIO0_1BIT_1_3,
+ PINCTRL_GRP_SDIO0_1BIT_1_4,
+ PINCTRL_GRP_SDIO0_1BIT_1_5,
+ PINCTRL_GRP_SDIO0_1BIT_1_6,
+ PINCTRL_GRP_SDIO0_1BIT_1_7,
+ PINCTRL_GRP_SDIO1_4BIT_0_0,
+ PINCTRL_GRP_SDIO1_1BIT_0_1,
+ END_OF_GROUPS,
+ }),
+ },
+ [PINCTRL_PIN_41] = {
+ .groups = &((uint16_t []) {
+ PINCTRL_GRP_ETHERNET1_0,
+ PINCTRL_GRP_RESERVED,
+ PINCTRL_GRP_SDIO0_1,
+ PINCTRL_GRP_SDIO1_0,
+ PINCTRL_GRP_RESERVED,
+ PINCTRL_GRP_GPIO0_41,
+ PINCTRL_GRP_CAN1_10,
+ PINCTRL_GRP_I2C1_10,
+ PINCTRL_GRP_PJTAG0_3,
+ PINCTRL_GRP_SPI0_3_SS0,
+ PINCTRL_GRP_TTC3_5_WAV,
+ PINCTRL_GRP_UART1_10,
+ PINCTRL_GRP_TRACE0_1,
+ PINCTRL_GRP_SDIO0_4BIT_1_0,
+ PINCTRL_GRP_SDIO0_1BIT_1_0,
+ PINCTRL_GRP_SDIO1_4BIT_0_0,
+ PINCTRL_GRP_SDIO1_1BIT_0_2,
+ END_OF_GROUPS,
+ }),
+ },
+ [PINCTRL_PIN_42] = {
+ .groups = &((uint16_t []) {
+ PINCTRL_GRP_ETHERNET1_0,
+ PINCTRL_GRP_RESERVED,
+ PINCTRL_GRP_SDIO0_1,
+ PINCTRL_GRP_SDIO1_0,
+ PINCTRL_GRP_RESERVED,
+ PINCTRL_GRP_GPIO0_42,
+ PINCTRL_GRP_CAN0_10,
+ PINCTRL_GRP_I2C0_10,
+ PINCTRL_GRP_SWDT0_6_CLK,
+ PINCTRL_GRP_SPI0_3,
+ PINCTRL_GRP_TTC2_5_CLK,
+ PINCTRL_GRP_UART0_10,
+ PINCTRL_GRP_TRACE0_1,
+ PINCTRL_GRP_SDIO0_1,
+ PINCTRL_GRP_SDIO0_4BIT_1_0,
+ PINCTRL_GRP_SDIO0_1BIT_1_1,
+ PINCTRL_GRP_SDIO1_4BIT_0_0,
+ PINCTRL_GRP_SDIO1_1BIT_0_3,
+ END_OF_GROUPS,
+ }),
+ },
+ [PINCTRL_PIN_43] = {
+ .groups = &((uint16_t []) {
+ PINCTRL_GRP_ETHERNET1_0,
+ PINCTRL_GRP_RESERVED,
+ PINCTRL_GRP_SDIO0_1,
+ PINCTRL_GRP_SDIO1_0_PC,
+ PINCTRL_GRP_RESERVED,
+ PINCTRL_GRP_GPIO0_43,
+ PINCTRL_GRP_CAN0_10,
+ PINCTRL_GRP_I2C0_10,
+ PINCTRL_GRP_SWDT0_6_RST,
+ PINCTRL_GRP_SPI0_3,
+ PINCTRL_GRP_TTC2_5_WAV,
+ PINCTRL_GRP_UART0_10,
+ PINCTRL_GRP_TRACE0_1,
+ PINCTRL_GRP_SDIO0_4BIT_1_0,
+ PINCTRL_GRP_SDIO0_1BIT_1_2,
+ END_OF_GROUPS,
+ }),
+ },
+ [PINCTRL_PIN_44] = {
+ .groups = &((uint16_t []) {
+ PINCTRL_GRP_ETHERNET1_0,
+ PINCTRL_GRP_RESERVED,
+ PINCTRL_GRP_SDIO0_1,
+ PINCTRL_GRP_SDIO1_0_WP,
+ PINCTRL_GRP_RESERVED,
+ PINCTRL_GRP_GPIO0_44,
+ PINCTRL_GRP_CAN1_11,
+ PINCTRL_GRP_I2C1_11,
+ PINCTRL_GRP_SWDT1_7_CLK,
+ PINCTRL_GRP_SPI1_3,
+ PINCTRL_GRP_TTC1_5_CLK,
+ PINCTRL_GRP_UART1_11,
+ PINCTRL_GRP_RESERVED,
+ PINCTRL_GRP_SDIO0_4BIT_1_0,
+ PINCTRL_GRP_SDIO0_1BIT_1_3,
+ END_OF_GROUPS,
+ }),
+ },
+ [PINCTRL_PIN_45] = {
+ .groups = &((uint16_t []) {
+ PINCTRL_GRP_ETHERNET1_0,
+ PINCTRL_GRP_RESERVED,
+ PINCTRL_GRP_SDIO0_1,
+ PINCTRL_GRP_SDIO1_0_CD,
+ PINCTRL_GRP_RESERVED,
+ PINCTRL_GRP_GPIO0_45,
+ PINCTRL_GRP_CAN1_11,
+ PINCTRL_GRP_I2C1_11,
+ PINCTRL_GRP_SWDT1_7_RST,
+ PINCTRL_GRP_SPI1_3_SS2,
+ PINCTRL_GRP_TTC1_5_WAV,
+ PINCTRL_GRP_UART1_11,
+ PINCTRL_GRP_RESERVED,
+ PINCTRL_GRP_SDIO0_4BIT_1_1,
+ PINCTRL_GRP_SDIO0_1BIT_1_4,
+ END_OF_GROUPS,
+ }),
+ },
+ [PINCTRL_PIN_46] = {
+ .groups = &((uint16_t []) {
+ PINCTRL_GRP_ETHERNET1_0,
+ PINCTRL_GRP_RESERVED,
+ PINCTRL_GRP_SDIO0_1,
+ PINCTRL_GRP_SDIO1_0,
+ PINCTRL_GRP_RESERVED,
+ PINCTRL_GRP_GPIO0_46,
+ PINCTRL_GRP_CAN0_11,
+ PINCTRL_GRP_I2C0_11,
+ PINCTRL_GRP_SWDT0_7_CLK,
+ PINCTRL_GRP_SPI1_3_SS1,
+ PINCTRL_GRP_TTC0_5_CLK,
+ PINCTRL_GRP_UART0_11,
+ PINCTRL_GRP_RESERVED,
+ PINCTRL_GRP_SDIO0_4BIT_1_1,
+ PINCTRL_GRP_SDIO0_1BIT_1_5,
+ PINCTRL_GRP_SDIO1_4BIT_0_1,
+ PINCTRL_GRP_SDIO1_1BIT_0_4,
+ END_OF_GROUPS,
+ }),
+ },
+ [PINCTRL_PIN_47] = {
+ .groups = &((uint16_t []) {
+ PINCTRL_GRP_ETHERNET1_0,
+ PINCTRL_GRP_RESERVED,
+ PINCTRL_GRP_SDIO0_1,
+ PINCTRL_GRP_SDIO1_0,
+ PINCTRL_GRP_RESERVED,
+ PINCTRL_GRP_GPIO0_47,
+ PINCTRL_GRP_CAN0_11,
+ PINCTRL_GRP_I2C0_11,
+ PINCTRL_GRP_SWDT0_7_RST,
+ PINCTRL_GRP_SPI1_3_SS0,
+ PINCTRL_GRP_TTC0_5_WAV,
+ PINCTRL_GRP_UART0_11,
+ PINCTRL_GRP_RESERVED,
+ PINCTRL_GRP_SDIO0_4BIT_1_1,
+ PINCTRL_GRP_SDIO0_1BIT_1_6,
+ PINCTRL_GRP_SDIO1_4BIT_0_1,
+ PINCTRL_GRP_SDIO1_1BIT_0_5,
+ END_OF_GROUPS,
+ }),
+ },
+ [PINCTRL_PIN_48] = {
+ .groups = &((uint16_t []) {
+ PINCTRL_GRP_ETHERNET1_0,
+ PINCTRL_GRP_RESERVED,
+ PINCTRL_GRP_SDIO0_1,
+ PINCTRL_GRP_SDIO1_0,
+ PINCTRL_GRP_RESERVED,
+ PINCTRL_GRP_GPIO0_48,
+ PINCTRL_GRP_CAN1_12,
+ PINCTRL_GRP_I2C1_12,
+ PINCTRL_GRP_SWDT1_8_CLK,
+ PINCTRL_GRP_SPI1_3,
+ PINCTRL_GRP_TTC3_6_CLK,
+ PINCTRL_GRP_UART1_12,
+ PINCTRL_GRP_RESERVED,
+ PINCTRL_GRP_SDIO0_4BIT_1_1,
+ PINCTRL_GRP_SDIO0_1BIT_1_7,
+ PINCTRL_GRP_SDIO1_4BIT_0_1,
+ PINCTRL_GRP_SDIO1_1BIT_0_6,
+ END_OF_GROUPS,
+ }),
+ },
+ [PINCTRL_PIN_49] = {
+ .groups = &((uint16_t []) {
+ PINCTRL_GRP_ETHERNET1_0,
+ PINCTRL_GRP_RESERVED,
+ PINCTRL_GRP_SDIO0_1_PC,
+ PINCTRL_GRP_SDIO1_0,
+ PINCTRL_GRP_RESERVED,
+ PINCTRL_GRP_GPIO0_49,
+ PINCTRL_GRP_CAN1_12,
+ PINCTRL_GRP_I2C1_12,
+ PINCTRL_GRP_SWDT1_8_RST,
+ PINCTRL_GRP_SPI1_3,
+ PINCTRL_GRP_TTC3_6_WAV,
+ PINCTRL_GRP_UART1_12,
+ PINCTRL_GRP_RESERVED,
+ PINCTRL_GRP_SDIO1_4BIT_0_1,
+ PINCTRL_GRP_SDIO1_1BIT_0_7,
+ END_OF_GROUPS,
+ }),
+ },
+ [PINCTRL_PIN_50] = {
+ .groups = &((uint16_t []) {
+ PINCTRL_GRP_GEMTSU0_1,
+ PINCTRL_GRP_RESERVED,
+ PINCTRL_GRP_SDIO0_1_WP,
+ PINCTRL_GRP_SDIO1_0,
+ PINCTRL_GRP_RESERVED,
+ PINCTRL_GRP_GPIO0_50,
+ PINCTRL_GRP_CAN0_12,
+ PINCTRL_GRP_I2C0_12,
+ PINCTRL_GRP_SWDT0_8_CLK,
+ PINCTRL_GRP_MDIO1_0,
+ PINCTRL_GRP_TTC2_6_CLK,
+ PINCTRL_GRP_UART0_12,
+ PINCTRL_GRP_RESERVED,
+ PINCTRL_GRP_SDIO1_4BIT_0_0,
+ PINCTRL_GRP_SDIO1_4BIT_0_1,
+ PINCTRL_GRP_SDIO1_1BIT_0_0,
+ PINCTRL_GRP_SDIO1_1BIT_0_1,
+ PINCTRL_GRP_SDIO1_1BIT_0_2,
+ PINCTRL_GRP_SDIO1_1BIT_0_3,
+ PINCTRL_GRP_SDIO1_1BIT_0_4,
+ PINCTRL_GRP_SDIO1_1BIT_0_5,
+ PINCTRL_GRP_SDIO1_1BIT_0_6,
+ PINCTRL_GRP_SDIO1_1BIT_0_7,
+ END_OF_GROUPS,
+ }),
+ },
+ [PINCTRL_PIN_51] = {
+ .groups = &((uint16_t []) {
+ PINCTRL_GRP_GEMTSU0_2,
+ PINCTRL_GRP_RESERVED,
+ PINCTRL_GRP_RESERVED,
+ PINCTRL_GRP_SDIO1_0,
+ PINCTRL_GRP_RESERVED,
+ PINCTRL_GRP_GPIO0_51,
+ PINCTRL_GRP_CAN0_12,
+ PINCTRL_GRP_I2C0_12,
+ PINCTRL_GRP_SWDT0_8_RST,
+ PINCTRL_GRP_MDIO1_0,
+ PINCTRL_GRP_TTC2_6_WAV,
+ PINCTRL_GRP_UART0_12,
+ PINCTRL_GRP_RESERVED,
+ PINCTRL_GRP_SDIO1_4BIT_0_0,
+ PINCTRL_GRP_SDIO1_4BIT_0_1,
+ PINCTRL_GRP_SDIO1_1BIT_0_0,
+ PINCTRL_GRP_SDIO1_1BIT_0_1,
+ PINCTRL_GRP_SDIO1_1BIT_0_2,
+ PINCTRL_GRP_SDIO1_1BIT_0_3,
+ PINCTRL_GRP_SDIO1_1BIT_0_4,
+ PINCTRL_GRP_SDIO1_1BIT_0_5,
+ PINCTRL_GRP_SDIO1_1BIT_0_6,
+ PINCTRL_GRP_SDIO1_1BIT_0_7,
+ END_OF_GROUPS,
+ }),
+ },
+ [PINCTRL_PIN_52] = {
+ .groups = &((uint16_t []) {
+ PINCTRL_GRP_ETHERNET2_0,
+ PINCTRL_GRP_USB0_0,
+ PINCTRL_GRP_RESERVED,
+ PINCTRL_GRP_RESERVED,
+ PINCTRL_GRP_RESERVED,
+ PINCTRL_GRP_GPIO0_52,
+ PINCTRL_GRP_CAN1_13,
+ PINCTRL_GRP_I2C1_13,
+ PINCTRL_GRP_PJTAG0_4,
+ PINCTRL_GRP_SPI0_4,
+ PINCTRL_GRP_TTC1_6_CLK,
+ PINCTRL_GRP_UART1_13,
+ PINCTRL_GRP_TRACE0_2_CLK,
+ END_OF_GROUPS,
+ }),
+ },
+ [PINCTRL_PIN_53] = {
+ .groups = &((uint16_t []) {
+ PINCTRL_GRP_ETHERNET2_0,
+ PINCTRL_GRP_USB0_0,
+ PINCTRL_GRP_RESERVED,
+ PINCTRL_GRP_RESERVED,
+ PINCTRL_GRP_RESERVED,
+ PINCTRL_GRP_GPIO0_53,
+ PINCTRL_GRP_CAN1_13,
+ PINCTRL_GRP_I2C1_13,
+ PINCTRL_GRP_PJTAG0_4,
+ PINCTRL_GRP_SPI0_4_SS2,
+ PINCTRL_GRP_TTC1_6_WAV,
+ PINCTRL_GRP_UART1_13,
+ PINCTRL_GRP_TRACE0_2_CLK,
+ END_OF_GROUPS,
+ }),
+ },
+ [PINCTRL_PIN_54] = {
+ .groups = &((uint16_t []) {
+ PINCTRL_GRP_ETHERNET2_0,
+ PINCTRL_GRP_USB0_0,
+ PINCTRL_GRP_RESERVED,
+ PINCTRL_GRP_RESERVED,
+ PINCTRL_GRP_RESERVED,
+ PINCTRL_GRP_GPIO0_54,
+ PINCTRL_GRP_CAN0_13,
+ PINCTRL_GRP_I2C0_13,
+ PINCTRL_GRP_PJTAG0_4,
+ PINCTRL_GRP_SPI0_4_SS1,
+ PINCTRL_GRP_TTC0_6_CLK,
+ PINCTRL_GRP_UART0_13,
+ PINCTRL_GRP_TRACE0_2,
+ END_OF_GROUPS,
+ }),
+ },
+ [PINCTRL_PIN_55] = {
+ .groups = &((uint16_t []) {
+ PINCTRL_GRP_ETHERNET2_0,
+ PINCTRL_GRP_USB0_0,
+ PINCTRL_GRP_RESERVED,
+ PINCTRL_GRP_RESERVED,
+ PINCTRL_GRP_RESERVED,
+ PINCTRL_GRP_GPIO0_55,
+ PINCTRL_GRP_CAN0_13,
+ PINCTRL_GRP_I2C0_13,
+ PINCTRL_GRP_PJTAG0_4,
+ PINCTRL_GRP_SPI0_4_SS0,
+ PINCTRL_GRP_TTC0_6_WAV,
+ PINCTRL_GRP_UART0_13,
+ PINCTRL_GRP_TRACE0_2,
+ END_OF_GROUPS,
+ }),
+ },
+ [PINCTRL_PIN_56] = {
+ .groups = &((uint16_t []) {
+ PINCTRL_GRP_ETHERNET2_0,
+ PINCTRL_GRP_USB0_0,
+ PINCTRL_GRP_RESERVED,
+ PINCTRL_GRP_RESERVED,
+ PINCTRL_GRP_RESERVED,
+ PINCTRL_GRP_GPIO0_56,
+ PINCTRL_GRP_CAN1_14,
+ PINCTRL_GRP_I2C1_14,
+ PINCTRL_GRP_SWDT1_9_CLK,
+ PINCTRL_GRP_SPI0_4,
+ PINCTRL_GRP_TTC3_7_CLK,
+ PINCTRL_GRP_UART1_14,
+ PINCTRL_GRP_TRACE0_2,
+ END_OF_GROUPS,
+ }),
+ },
+ [PINCTRL_PIN_57] = {
+ .groups = &((uint16_t []) {
+ PINCTRL_GRP_ETHERNET2_0,
+ PINCTRL_GRP_USB0_0,
+ PINCTRL_GRP_RESERVED,
+ PINCTRL_GRP_RESERVED,
+ PINCTRL_GRP_RESERVED,
+ PINCTRL_GRP_GPIO0_57,
+ PINCTRL_GRP_CAN1_14,
+ PINCTRL_GRP_I2C1_14,
+ PINCTRL_GRP_SWDT1_9_RST,
+ PINCTRL_GRP_SPI0_4,
+ PINCTRL_GRP_TTC3_7_WAV,
+ PINCTRL_GRP_UART1_14,
+ PINCTRL_GRP_TRACE0_2,
+ END_OF_GROUPS,
+ }),
+ },
+ [PINCTRL_PIN_58] = {
+ .groups = &((uint16_t []) {
+ PINCTRL_GRP_ETHERNET2_0,
+ PINCTRL_GRP_USB0_0,
+ PINCTRL_GRP_RESERVED,
+ PINCTRL_GRP_RESERVED,
+ PINCTRL_GRP_RESERVED,
+ PINCTRL_GRP_GPIO0_58,
+ PINCTRL_GRP_CAN0_14,
+ PINCTRL_GRP_I2C0_14,
+ PINCTRL_GRP_PJTAG0_5,
+ PINCTRL_GRP_SPI1_4,
+ PINCTRL_GRP_TTC2_7_CLK,
+ PINCTRL_GRP_UART0_14,
+ PINCTRL_GRP_TRACE0_2,
+ END_OF_GROUPS,
+ }),
+ },
+ [PINCTRL_PIN_59] = {
+ .groups = &((uint16_t []) {
+ PINCTRL_GRP_ETHERNET2_0,
+ PINCTRL_GRP_USB0_0,
+ PINCTRL_GRP_RESERVED,
+ PINCTRL_GRP_RESERVED,
+ PINCTRL_GRP_RESERVED,
+ PINCTRL_GRP_GPIO0_59,
+ PINCTRL_GRP_CAN0_14,
+ PINCTRL_GRP_I2C0_14,
+ PINCTRL_GRP_PJTAG0_5,
+ PINCTRL_GRP_SPI1_4_SS2,
+ PINCTRL_GRP_TTC2_7_WAV,
+ PINCTRL_GRP_UART0_14,
+ PINCTRL_GRP_TRACE0_2,
+ END_OF_GROUPS,
+ }),
+ },
+ [PINCTRL_PIN_60] = {
+ .groups = &((uint16_t []) {
+ PINCTRL_GRP_ETHERNET2_0,
+ PINCTRL_GRP_USB0_0,
+ PINCTRL_GRP_RESERVED,
+ PINCTRL_GRP_RESERVED,
+ PINCTRL_GRP_RESERVED,
+ PINCTRL_GRP_GPIO0_60,
+ PINCTRL_GRP_CAN1_15,
+ PINCTRL_GRP_I2C1_15,
+ PINCTRL_GRP_PJTAG0_5,
+ PINCTRL_GRP_SPI1_4_SS1,
+ PINCTRL_GRP_TTC1_7_CLK,
+ PINCTRL_GRP_UART1_15,
+ PINCTRL_GRP_TRACE0_2,
+ END_OF_GROUPS,
+ }),
+ },
+ [PINCTRL_PIN_61] = {
+ .groups = &((uint16_t []) {
+ PINCTRL_GRP_ETHERNET2_0,
+ PINCTRL_GRP_USB0_0,
+ PINCTRL_GRP_RESERVED,
+ PINCTRL_GRP_RESERVED,
+ PINCTRL_GRP_RESERVED,
+ PINCTRL_GRP_GPIO0_61,
+ PINCTRL_GRP_CAN1_15,
+ PINCTRL_GRP_I2C1_15,
+ PINCTRL_GRP_PJTAG0_5,
+ PINCTRL_GRP_SPI1_4_SS0,
+ PINCTRL_GRP_TTC1_7_WAV,
+ PINCTRL_GRP_UART1_15,
+ PINCTRL_GRP_TRACE0_2,
+ END_OF_GROUPS,
+ }),
+ },
+ [PINCTRL_PIN_62] = {
+ .groups = &((uint16_t []) {
+ PINCTRL_GRP_ETHERNET2_0,
+ PINCTRL_GRP_USB0_0,
+ PINCTRL_GRP_RESERVED,
+ PINCTRL_GRP_RESERVED,
+ PINCTRL_GRP_RESERVED,
+ PINCTRL_GRP_GPIO0_62,
+ PINCTRL_GRP_CAN0_15,
+ PINCTRL_GRP_I2C0_15,
+ PINCTRL_GRP_SWDT0_9_CLK,
+ PINCTRL_GRP_SPI1_4,
+ PINCTRL_GRP_TTC0_7_CLK,
+ PINCTRL_GRP_UART0_15,
+ PINCTRL_GRP_TRACE0_2,
+ END_OF_GROUPS,
+ }),
+ },
+ [PINCTRL_PIN_63] = {
+ .groups = &((uint16_t []) {
+ PINCTRL_GRP_ETHERNET2_0,
+ PINCTRL_GRP_USB0_0,
+ PINCTRL_GRP_RESERVED,
+ PINCTRL_GRP_RESERVED,
+ PINCTRL_GRP_RESERVED,
+ PINCTRL_GRP_GPIO0_63,
+ PINCTRL_GRP_CAN0_15,
+ PINCTRL_GRP_I2C0_15,
+ PINCTRL_GRP_SWDT0_9_RST,
+ PINCTRL_GRP_SPI1_4,
+ PINCTRL_GRP_TTC0_7_WAV,
+ PINCTRL_GRP_UART0_15,
+ PINCTRL_GRP_TRACE0_2,
+ END_OF_GROUPS,
+ }),
+ },
+ [PINCTRL_PIN_64] = {
+ .groups = &((uint16_t []) {
+ PINCTRL_GRP_ETHERNET3_0,
+ PINCTRL_GRP_USB1_0,
+ PINCTRL_GRP_SDIO0_2,
+ PINCTRL_GRP_RESERVED,
+ PINCTRL_GRP_RESERVED,
+ PINCTRL_GRP_GPIO0_64,
+ PINCTRL_GRP_CAN1_16,
+ PINCTRL_GRP_I2C1_16,
+ PINCTRL_GRP_SWDT1_10_CLK,
+ PINCTRL_GRP_SPI0_5,
+ PINCTRL_GRP_TTC3_8_CLK,
+ PINCTRL_GRP_UART1_16,
+ PINCTRL_GRP_TRACE0_2,
+ PINCTRL_GRP_SDIO0_4BIT_2_0,
+ PINCTRL_GRP_SDIO0_4BIT_2_1,
+ PINCTRL_GRP_SDIO0_1BIT_2_0,
+ PINCTRL_GRP_SDIO0_1BIT_2_1,
+ PINCTRL_GRP_SDIO0_1BIT_2_2,
+ PINCTRL_GRP_SDIO0_1BIT_2_3,
+ PINCTRL_GRP_SDIO0_1BIT_2_4,
+ PINCTRL_GRP_SDIO0_1BIT_2_5,
+ PINCTRL_GRP_SDIO0_1BIT_2_6,
+ PINCTRL_GRP_SDIO0_1BIT_2_7,
+ END_OF_GROUPS,
+ }),
+ },
+ [PINCTRL_PIN_65] = {
+ .groups = &((uint16_t []) {
+ PINCTRL_GRP_ETHERNET3_0,
+ PINCTRL_GRP_USB1_0,
+ PINCTRL_GRP_SDIO0_2_CD,
+ PINCTRL_GRP_RESERVED,
+ PINCTRL_GRP_RESERVED,
+ PINCTRL_GRP_GPIO0_65,
+ PINCTRL_GRP_CAN1_16,
+ PINCTRL_GRP_I2C1_16,
+ PINCTRL_GRP_SWDT1_10_RST,
+ PINCTRL_GRP_SPI0_5_SS2,
+ PINCTRL_GRP_TTC3_8_WAV,
+ PINCTRL_GRP_UART1_16,
+ PINCTRL_GRP_TRACE0_2,
+ END_OF_GROUPS,
+ }),
+ },
+ [PINCTRL_PIN_66] = {
+ .groups = &((uint16_t []) {
+ PINCTRL_GRP_ETHERNET3_0,
+ PINCTRL_GRP_USB1_0,
+ PINCTRL_GRP_SDIO0_2,
+ PINCTRL_GRP_RESERVED,
+ PINCTRL_GRP_RESERVED,
+ PINCTRL_GRP_GPIO0_66,
+ PINCTRL_GRP_CAN0_16,
+ PINCTRL_GRP_I2C0_16,
+ PINCTRL_GRP_SWDT0_10_CLK,
+ PINCTRL_GRP_SPI0_5_SS1,
+ PINCTRL_GRP_TTC2_8_CLK,
+ PINCTRL_GRP_UART0_16,
+ PINCTRL_GRP_TRACE0_2,
+ PINCTRL_GRP_SDIO0_4BIT_2_0,
+ PINCTRL_GRP_SDIO0_4BIT_2_1,
+ PINCTRL_GRP_SDIO0_1BIT_2_0,
+ PINCTRL_GRP_SDIO0_1BIT_2_1,
+ PINCTRL_GRP_SDIO0_1BIT_2_2,
+ PINCTRL_GRP_SDIO0_1BIT_2_3,
+ PINCTRL_GRP_SDIO0_1BIT_2_4,
+ PINCTRL_GRP_SDIO0_1BIT_2_5,
+ PINCTRL_GRP_SDIO0_1BIT_2_6,
+ PINCTRL_GRP_SDIO0_1BIT_2_7,
+ END_OF_GROUPS,
+ }),
+ },
+ [PINCTRL_PIN_67] = {
+ .groups = &((uint16_t []) {
+ PINCTRL_GRP_ETHERNET3_0,
+ PINCTRL_GRP_USB1_0,
+ PINCTRL_GRP_SDIO0_2,
+ PINCTRL_GRP_RESERVED,
+ PINCTRL_GRP_RESERVED,
+ PINCTRL_GRP_GPIO0_67,
+ PINCTRL_GRP_CAN0_16,
+ PINCTRL_GRP_I2C0_16,
+ PINCTRL_GRP_SWDT0_10_RST,
+ PINCTRL_GRP_SPI0_5_SS0,
+ PINCTRL_GRP_TTC2_8_WAV,
+ PINCTRL_GRP_UART0_16,
+ PINCTRL_GRP_TRACE0_2,
+ PINCTRL_GRP_SDIO0_4BIT_2_0,
+ PINCTRL_GRP_SDIO0_1BIT_2_0,
+ END_OF_GROUPS,
+ }),
+ },
+ [PINCTRL_PIN_68] = {
+ .groups = &((uint16_t []) {
+ PINCTRL_GRP_ETHERNET3_0,
+ PINCTRL_GRP_USB1_0,
+ PINCTRL_GRP_SDIO0_2,
+ PINCTRL_GRP_RESERVED,
+ PINCTRL_GRP_RESERVED,
+ PINCTRL_GRP_GPIO0_68,
+ PINCTRL_GRP_CAN1_17,
+ PINCTRL_GRP_I2C1_17,
+ PINCTRL_GRP_SWDT1_11_CLK,
+ PINCTRL_GRP_SPI0_5,
+ PINCTRL_GRP_TTC1_8_CLK,
+ PINCTRL_GRP_UART1_17,
+ PINCTRL_GRP_TRACE0_2,
+ PINCTRL_GRP_SDIO0_4BIT_2_0,
+ PINCTRL_GRP_SDIO0_1BIT_2_1,
+ END_OF_GROUPS,
+ }),
+ },
+ [PINCTRL_PIN_69] = {
+ .groups = &((uint16_t []) {
+ PINCTRL_GRP_ETHERNET3_0,
+ PINCTRL_GRP_USB1_0,
+ PINCTRL_GRP_SDIO0_2,
+ PINCTRL_GRP_SDIO1_1_WP,
+ PINCTRL_GRP_RESERVED,
+ PINCTRL_GRP_GPIO0_69,
+ PINCTRL_GRP_CAN1_17,
+ PINCTRL_GRP_I2C1_17,
+ PINCTRL_GRP_SWDT1_11_RST,
+ PINCTRL_GRP_SPI0_5,
+ PINCTRL_GRP_TTC1_8_WAV,
+ PINCTRL_GRP_UART1_17,
+ PINCTRL_GRP_TRACE0_2,
+ PINCTRL_GRP_SDIO0_4BIT_2_0,
+ PINCTRL_GRP_SDIO0_1BIT_2_2,
+ END_OF_GROUPS,
+ }),
+ },
+ [PINCTRL_PIN_70] = {
+ .groups = &((uint16_t []) {
+ PINCTRL_GRP_ETHERNET3_0,
+ PINCTRL_GRP_USB1_0,
+ PINCTRL_GRP_SDIO0_2,
+ PINCTRL_GRP_SDIO1_1_PC,
+ PINCTRL_GRP_RESERVED,
+ PINCTRL_GRP_GPIO0_70,
+ PINCTRL_GRP_CAN0_17,
+ PINCTRL_GRP_I2C0_17,
+ PINCTRL_GRP_SWDT0_11_CLK,
+ PINCTRL_GRP_SPI1_5,
+ PINCTRL_GRP_TTC0_8_CLK,
+ PINCTRL_GRP_UART0_17,
+ PINCTRL_GRP_RESERVED,
+ PINCTRL_GRP_SDIO0_4BIT_2_0,
+ PINCTRL_GRP_SDIO0_1BIT_2_3,
+ END_OF_GROUPS,
+ }),
+ },
+ [PINCTRL_PIN_71] = {
+ .groups = &((uint16_t []) {
+ PINCTRL_GRP_ETHERNET3_0,
+ PINCTRL_GRP_USB1_0,
+ PINCTRL_GRP_SDIO0_2,
+ PINCTRL_GRP_SDIO1_4BIT_1_0,
+ PINCTRL_GRP_RESERVED,
+ PINCTRL_GRP_GPIO0_71,
+ PINCTRL_GRP_CAN0_17,
+ PINCTRL_GRP_I2C0_17,
+ PINCTRL_GRP_SWDT0_11_RST,
+ PINCTRL_GRP_SPI1_5_SS2,
+ PINCTRL_GRP_TTC0_8_WAV,
+ PINCTRL_GRP_UART0_17,
+ PINCTRL_GRP_RESERVED,
+ PINCTRL_GRP_SDIO0_2,
+ PINCTRL_GRP_SDIO0_4BIT_2_1,
+ PINCTRL_GRP_SDIO0_1BIT_2_4,
+ PINCTRL_GRP_SDIO1_1BIT_1_0,
+ END_OF_GROUPS,
+ }),
+ },
+ [PINCTRL_PIN_72] = {
+ .groups = &((uint16_t []) {
+ PINCTRL_GRP_ETHERNET3_0,
+ PINCTRL_GRP_USB1_0,
+ PINCTRL_GRP_SDIO0_2,
+ PINCTRL_GRP_SDIO1_4BIT_1_0,
+ PINCTRL_GRP_RESERVED,
+ PINCTRL_GRP_GPIO0_72,
+ PINCTRL_GRP_CAN1_18,
+ PINCTRL_GRP_I2C1_18,
+ PINCTRL_GRP_SWDT1_12_CLK,
+ PINCTRL_GRP_SPI1_5_SS1,
+ PINCTRL_GRP_RESERVED,
+ PINCTRL_GRP_UART1_18,
+ PINCTRL_GRP_RESERVED,
+ PINCTRL_GRP_SDIO0_4BIT_2_1,
+ PINCTRL_GRP_SDIO0_1BIT_2_5,
+ PINCTRL_GRP_SDIO1_1BIT_1_1,
+ END_OF_GROUPS,
+ }),
+ },
+ [PINCTRL_PIN_73] = {
+ .groups = &((uint16_t []) {
+ PINCTRL_GRP_ETHERNET3_0,
+ PINCTRL_GRP_USB1_0,
+ PINCTRL_GRP_SDIO0_2,
+ PINCTRL_GRP_SDIO1_4BIT_1_0,
+ PINCTRL_GRP_RESERVED,
+ PINCTRL_GRP_GPIO0_73,
+ PINCTRL_GRP_CAN1_18,
+ PINCTRL_GRP_I2C1_18,
+ PINCTRL_GRP_SWDT1_12_RST,
+ PINCTRL_GRP_SPI1_5_SS0,
+ PINCTRL_GRP_RESERVED,
+ PINCTRL_GRP_UART1_18,
+ PINCTRL_GRP_RESERVED,
+ PINCTRL_GRP_SDIO0_4BIT_2_1,
+ PINCTRL_GRP_SDIO0_1BIT_2_6,
+ PINCTRL_GRP_SDIO1_1BIT_1_2,
+ END_OF_GROUPS,
+ }),
+ },
+ [PINCTRL_PIN_74] = {
+ .groups = &((uint16_t []) {
+ PINCTRL_GRP_ETHERNET3_0,
+ PINCTRL_GRP_USB1_0,
+ PINCTRL_GRP_SDIO0_2,
+ PINCTRL_GRP_SDIO1_4BIT_1_0,
+ PINCTRL_GRP_RESERVED,
+ PINCTRL_GRP_GPIO0_74,
+ PINCTRL_GRP_CAN0_18,
+ PINCTRL_GRP_I2C0_18,
+ PINCTRL_GRP_SWDT0_12_CLK,
+ PINCTRL_GRP_SPI1_5,
+ PINCTRL_GRP_RESERVED,
+ PINCTRL_GRP_UART0_18,
+ PINCTRL_GRP_RESERVED,
+ PINCTRL_GRP_SDIO0_4BIT_2_1,
+ PINCTRL_GRP_SDIO0_1BIT_2_7,
+ PINCTRL_GRP_SDIO1_1BIT_1_3,
+ END_OF_GROUPS,
+ }),
+ },
+ [PINCTRL_PIN_75] = {
+ .groups = &((uint16_t []) {
+ PINCTRL_GRP_ETHERNET3_0,
+ PINCTRL_GRP_USB1_0,
+ PINCTRL_GRP_SDIO0_2_PC,
+ PINCTRL_GRP_SDIO1_4BIT_1_0,
+ PINCTRL_GRP_RESERVED,
+ PINCTRL_GRP_GPIO0_75,
+ PINCTRL_GRP_CAN0_18,
+ PINCTRL_GRP_I2C0_18,
+ PINCTRL_GRP_SWDT0_12_RST,
+ PINCTRL_GRP_SPI1_5,
+ PINCTRL_GRP_RESERVED,
+ PINCTRL_GRP_UART0_18,
+ PINCTRL_GRP_RESERVED,
+ PINCTRL_GRP_SDIO1_1BIT_1_0,
+ PINCTRL_GRP_SDIO1_1BIT_1_1,
+ PINCTRL_GRP_SDIO1_1BIT_1_2,
+ PINCTRL_GRP_SDIO1_1BIT_1_3,
+ END_OF_GROUPS,
+ }),
+ },
+ [PINCTRL_PIN_76] = {
+ .groups = &((uint16_t []) {
+ PINCTRL_GRP_RESERVED,
+ PINCTRL_GRP_RESERVED,
+ PINCTRL_GRP_SDIO0_2_WP,
+ PINCTRL_GRP_SDIO1_4BIT_1_0,
+ PINCTRL_GRP_RESERVED,
+ PINCTRL_GRP_GPIO0_76,
+ PINCTRL_GRP_CAN1_19,
+ PINCTRL_GRP_I2C1_19,
+ PINCTRL_GRP_MDIO0_0,
+ PINCTRL_GRP_MDIO1_1,
+ PINCTRL_GRP_MDIO2_0,
+ PINCTRL_GRP_MDIO3_0,
+ PINCTRL_GRP_RESERVED,
+ PINCTRL_GRP_SDIO1_1BIT_1_0,
+ PINCTRL_GRP_SDIO1_1BIT_1_1,
+ PINCTRL_GRP_SDIO1_1BIT_1_2,
+ PINCTRL_GRP_SDIO1_1BIT_1_3,
+ END_OF_GROUPS,
+ }),
+ },
+ [PINCTRL_PIN_77] = {
+ .groups = &((uint16_t []) {
+ PINCTRL_GRP_RESERVED,
+ PINCTRL_GRP_RESERVED,
+ PINCTRL_GRP_RESERVED,
+ PINCTRL_GRP_SDIO1_1_CD,
+ PINCTRL_GRP_RESERVED,
+ PINCTRL_GRP_GPIO0_77,
+ PINCTRL_GRP_CAN1_19,
+ PINCTRL_GRP_I2C1_19,
+ PINCTRL_GRP_MDIO0_0,
+ PINCTRL_GRP_MDIO1_1,
+ PINCTRL_GRP_MDIO2_0,
+ PINCTRL_GRP_MDIO3_0,
+ PINCTRL_GRP_RESERVED,
+ END_OF_GROUPS,
+ }),
+ },
+};
+
+/**
+ * pm_api_pinctrl_get_num_pins() - PM call to request number of pins
+ * @npins Number of pins
+ *
+ * This function is used by master to get number of pins
+ *
+ * @return Returns success.
+ */
+enum pm_ret_status pm_api_pinctrl_get_num_pins(unsigned int *npins)
+{
+ *npins = MAX_PIN;
+
+ return PM_RET_SUCCESS;
+}
+
+/**
+ * pm_api_pinctrl_get_num_functions() - PM call to request number of functions
+ * @nfuncs Number of functions
+ *
+ * This function is used by master to get number of functions
+ *
+ * @return Returns success.
+ */
+enum pm_ret_status pm_api_pinctrl_get_num_functions(unsigned int *nfuncs)
+{
+ *nfuncs = MAX_FUNCTION;
+
+ return PM_RET_SUCCESS;
+}
+
+/**
+ * pm_api_pinctrl_get_num_func_groups() - PM call to request number of
+ * function groups
+ * @fid Function Id
+ * @ngroups Number of function groups
+ *
+ * This function is used by master to get number of function groups
+ *
+ * @return Returns success.
+ */
+enum pm_ret_status pm_api_pinctrl_get_num_func_groups(unsigned int fid,
+ unsigned int *ngroups)
+{
+ int i = 0;
+ uint16_t *grps;
+
+ if (fid >= MAX_FUNCTION)
+ return PM_RET_ERROR_ARGS;
+
+ *ngroups = 0;
+
+ grps = *pinctrl_functions[fid].groups;
+ if (grps == NULL)
+ return PM_RET_SUCCESS;
+
+ while (grps[i++] != (uint16_t)END_OF_GROUPS)
+ (*ngroups)++;
+
+ return PM_RET_SUCCESS;
+}
+
+/**
+ * pm_api_pinctrl_get_function_name() - PM call to request a function name
+ * @fid Function ID
+ * @name Name of function (max 16 bytes)
+ *
+ * This function is used by master to get name of function specified
+ * by given function ID.
+ *
+ * @return Returns success. In case of error, name data is 0.
+ */
+enum pm_ret_status pm_api_pinctrl_get_function_name(unsigned int fid,
+ char *name)
+{
+ if (fid >= MAX_FUNCTION)
+ memcpy(name, END_OF_FUNCTION, FUNCTION_NAME_LEN);
+ else
+ memcpy(name, pinctrl_functions[fid].name, FUNCTION_NAME_LEN);
+
+ return PM_RET_SUCCESS;
+}
+
+/**
+ * pm_api_pinctrl_get_function_groups() - PM call to request first 6 function
+ * groups of function Id
+ * @fid Function ID
+ * @index Index of next function groups
+ * @groups Function groups
+ *
+ * This function is used by master to get function groups specified
+ * by given function Id. This API will return 6 function groups with
+ * a single response. To get other function groups, master should call
+ * same API in loop with new function groups index till error is returned.
+ *
+ * E.g First call should have index 0 which will return function groups
+ * 0, 1, 2, 3, 4 and 5. Next call, index should be 6 which will return
+ * function groups 6, 7, 8, 9, 10 and 11 and so on.
+ *
+ * Return: Returns status, either success or error+reason.
+ */
+enum pm_ret_status pm_api_pinctrl_get_function_groups(unsigned int fid,
+ unsigned int index,
+ uint16_t *groups)
+{
+ unsigned int i;
+ uint16_t *grps;
+
+ if (fid >= MAX_FUNCTION)
+ return PM_RET_ERROR_ARGS;
+
+ memset(groups, END_OF_GROUPS, GROUPS_PAYLOAD_LEN);
+
+ grps = *pinctrl_functions[fid].groups;
+ if (grps == NULL)
+ return PM_RET_SUCCESS;
+
+ /* Skip groups till index */
+ for (i = 0; i < index; i++)
+ if (grps[i] == (uint16_t)END_OF_GROUPS)
+ return PM_RET_SUCCESS;
+
+ for (i = 0; i < NUM_GROUPS_PER_RESP; i++) {
+ groups[i] = grps[index + i];
+ if (groups[i] == (uint16_t)END_OF_GROUPS)
+ break;
+ }
+
+ return PM_RET_SUCCESS;
+}
+
+/**
+ * pm_api_pinctrl_get_pin_groups() - PM call to request first 6 pin
+ * groups of pin
+ * @pin Pin
+ * @index Index of next pin groups
+ * @groups pin groups
+ *
+ * This function is used by master to get pin groups specified
+ * by given pin Id. This API will return 6 pin groups with
+ * a single response. To get other pin groups, master should call
+ * same API in loop with new pin groups index till error is returned.
+ *
+ * E.g First call should have index 0 which will return pin groups
+ * 0, 1, 2, 3, 4 and 5. Next call, index should be 6 which will return
+ * pin groups 6, 7, 8, 9, 10 and 11 and so on.
+ *
+ * Return: Returns status, either success or error+reason.
+ */
+enum pm_ret_status pm_api_pinctrl_get_pin_groups(unsigned int pin,
+ unsigned int index,
+ uint16_t *groups)
+{
+ unsigned int i;
+ uint16_t *grps;
+
+ if (pin >= MAX_PIN)
+ return PM_RET_ERROR_ARGS;
+
+ memset(groups, END_OF_GROUPS, GROUPS_PAYLOAD_LEN);
+
+ grps = *zynqmp_pin_groups[pin].groups;
+ if (!grps)
+ return PM_RET_SUCCESS;
+
+ /* Skip groups till index */
+ for (i = 0; i < index; i++)
+ if (grps[i] == (uint16_t)END_OF_GROUPS)
+ return PM_RET_SUCCESS;
+
+ for (i = 0; i < NUM_GROUPS_PER_RESP; i++) {
+ groups[i] = grps[index + i];
+ if (groups[i] == (uint16_t)END_OF_GROUPS)
+ break;
+ }
+
+ return PM_RET_SUCCESS;
+}
+
+/**
+ * pm_api_pinctrl_get_function() - Read function id set for the given pin
+ * @pin Pin number
+ * @nid Node ID of function currently set for given pin
+ *
+ * This function provides the function currently set for the given pin.
+ *
+ * @return Returns status, either success or error+reason
+ */
+enum pm_ret_status pm_api_pinctrl_get_function(unsigned int pin,
+ unsigned int *id)
+{
+ unsigned int i = 0, j = 0;
+ enum pm_ret_status ret = PM_RET_SUCCESS;
+ unsigned int ctrlreg, val, gid;
+ uint16_t *grps;
+
+ ctrlreg = IOU_SLCR_BASEADDR + 4U * pin;
+ ret = pm_mmio_read(ctrlreg, &val);
+ if (ret != PM_RET_SUCCESS)
+ return ret;
+
+ val &= PINCTRL_FUNCTION_MASK;
+
+ for (i = 0; i < NFUNCS_PER_PIN; i++)
+ if (val == pm_pinctrl_mux[i])
+ break;
+
+ if (i == NFUNCS_PER_PIN)
+ return PM_RET_ERROR_NOTSUPPORTED;
+
+ gid = *(*zynqmp_pin_groups[pin].groups + i);
+
+ for (i = 0; i < MAX_FUNCTION; i++) {
+ grps = *pinctrl_functions[i].groups;
+ if (grps == NULL)
+ continue;
+ if (val != pinctrl_functions[i].regval)
+ continue;
+
+ for (j = 0; grps[j] != (uint16_t)END_OF_GROUPS; j++) {
+ if (gid == grps[j]) {
+ *id = i;
+ goto done;
+ }
+ }
+ }
+ if (i == MAX_FUNCTION)
+ ret = PM_RET_ERROR_ARGS;
+done:
+ return ret;
+}
+
+/**
+ * pm_api_pinctrl_set_function() - Set function id set for the given pin
+ * @pin Pin number
+ * @nid Node ID of function to set for given pin
+ *
+ * This function provides the function currently set for the given pin.
+ *
+ * @return Returns status, either success or error+reason
+ */
+enum pm_ret_status pm_api_pinctrl_set_function(unsigned int pin,
+ unsigned int fid)
+{
+ int i, j;
+ unsigned int ctrlreg, val;
+ uint16_t *pgrps, *fgrps;
+
+ ctrlreg = IOU_SLCR_BASEADDR + 4U * pin;
+ val = pinctrl_functions[fid].regval;
+
+ for (i = 0; i < NFUNCS_PER_PIN; i++)
+ if (val == pm_pinctrl_mux[i])
+ break;
+
+ if (i == NFUNCS_PER_PIN)
+ return PM_RET_ERROR_NOTSUPPORTED;
+
+ pgrps = *zynqmp_pin_groups[pin].groups;
+ if (!pgrps)
+ return PM_RET_ERROR_NOTSUPPORTED;
+
+ fgrps = *pinctrl_functions[fid].groups;
+ if (!fgrps)
+ return PM_RET_ERROR_NOTSUPPORTED;
+
+ for (i = 0; fgrps[i] != (uint16_t)END_OF_GROUPS; i++)
+ for (j = 0; pgrps[j] != (uint16_t)END_OF_GROUPS; j++)
+ if (fgrps[i] == pgrps[j])
+ goto match;
+
+ return PM_RET_ERROR_NOTSUPPORTED;
+
+match:
+ return pm_mmio_write(ctrlreg, PINCTRL_FUNCTION_MASK, val);
+}
+
+/**
+ * pm_api_pinctrl_set_config() - Set configuration parameter for given pin
+ * @pin: Pin for which configuration is to be set
+ * @param: Configuration parameter to be set
+ * @value: Value to be set for configuration parameter
+ *
+ * This function sets value of requested configuration parameter for given pin.
+ *
+ * @return Returns status, either success or error+reason
+ */
+enum pm_ret_status pm_api_pinctrl_set_config(unsigned int pin,
+ unsigned int param,
+ unsigned int value)
+{
+ enum pm_ret_status ret;
+ unsigned int ctrlreg, mask, val, offset;
+
+ if (param >= PINCTRL_CONFIG_MAX)
+ return PM_RET_ERROR_NOTSUPPORTED;
+
+ if (pin >= PINCTRL_NUM_MIOS)
+ return PM_RET_ERROR_ARGS;
+
+ mask = 1 << PINCTRL_PIN_OFFSET(pin);
+
+ switch (param) {
+ case PINCTRL_CONFIG_SLEW_RATE:
+ if (value != PINCTRL_SLEW_RATE_FAST &&
+ value != PINCTRL_SLEW_RATE_SLOW)
+ return PM_RET_ERROR_ARGS;
+
+ ctrlreg = PINCTRL_CFG_ADDR_OFFSET(IOU_SLCR_BASEADDR,
+ PINCTRL_SLEWCTRL_REG_OFFSET,
+ pin);
+ val = value << PINCTRL_PIN_OFFSET(pin);
+ ret = pm_mmio_write(ctrlreg, mask, val);
+ break;
+ case PINCTRL_CONFIG_BIAS_STATUS:
+ if (value != PINCTRL_BIAS_ENABLE &&
+ value != PINCTRL_BIAS_DISABLE)
+ return PM_RET_ERROR_ARGS;
+
+ ctrlreg = PINCTRL_CFG_ADDR_OFFSET(IOU_SLCR_BASEADDR,
+ PINCTRL_PULLSTAT_REG_OFFSET,
+ pin);
+
+ offset = PINCTRL_PIN_OFFSET(pin);
+ if (ctrlreg == IOU_SLCR_BANK1_CTRL5)
+ offset = (offset < 12U) ?
+ (offset + 14U) : (offset - 12U);
+
+ val = value << offset;
+ mask = 1 << offset;
+ ret = pm_mmio_write(ctrlreg, mask, val);
+ break;
+ case PINCTRL_CONFIG_PULL_CTRL:
+
+ if (value != PINCTRL_BIAS_PULL_DOWN &&
+ value != PINCTRL_BIAS_PULL_UP)
+ return PM_RET_ERROR_ARGS;
+
+ ctrlreg = PINCTRL_CFG_ADDR_OFFSET(IOU_SLCR_BASEADDR,
+ PINCTRL_PULLSTAT_REG_OFFSET,
+ pin);
+
+ offset = PINCTRL_PIN_OFFSET(pin);
+ if (ctrlreg == IOU_SLCR_BANK1_CTRL5)
+ offset = (offset < 12U) ?
+ (offset + 14U) : (offset - 12U);
+
+ val = PINCTRL_BIAS_ENABLE << offset;
+ ret = pm_mmio_write(ctrlreg, 1 << offset, val);
+ if (ret != PM_RET_SUCCESS)
+ return ret;
+
+ ctrlreg = PINCTRL_CFG_ADDR_OFFSET(IOU_SLCR_BASEADDR,
+ PINCTRL_PULLCTRL_REG_OFFSET,
+ pin);
+ val = value << PINCTRL_PIN_OFFSET(pin);
+ ret = pm_mmio_write(ctrlreg, mask, val);
+ break;
+ case PINCTRL_CONFIG_SCHMITT_CMOS:
+ if (value != PINCTRL_INPUT_TYPE_CMOS &&
+ value != PINCTRL_INPUT_TYPE_SCHMITT)
+ return PM_RET_ERROR_ARGS;
+
+ ctrlreg = PINCTRL_CFG_ADDR_OFFSET(IOU_SLCR_BASEADDR,
+ PINCTRL_SCHCMOS_REG_OFFSET,
+ pin);
+
+ val = value << PINCTRL_PIN_OFFSET(pin);
+ ret = pm_mmio_write(ctrlreg, mask, val);
+ break;
+ case PINCTRL_CONFIG_DRIVE_STRENGTH:
+ if (value > PINCTRL_DRIVE_STRENGTH_12MA)
+ return PM_RET_ERROR_ARGS;
+
+ ctrlreg = PINCTRL_CFG_ADDR_OFFSET(IOU_SLCR_BASEADDR,
+ PINCTRL_DRVSTRN0_REG_OFFSET,
+ pin);
+ val = (value >> 1) << PINCTRL_PIN_OFFSET(pin);
+ ret = pm_mmio_write(ctrlreg, mask, val);
+ if (ret)
+ return ret;
+
+ ctrlreg = PINCTRL_CFG_ADDR_OFFSET(IOU_SLCR_BASEADDR,
+ PINCTRL_DRVSTRN1_REG_OFFSET,
+ pin);
+ val = (value & 0x01U) << PINCTRL_PIN_OFFSET(pin);
+ ret = pm_mmio_write(ctrlreg, mask, val);
+ break;
+ default:
+ ERROR("Invalid parameter %u\n", param);
+ ret = PM_RET_ERROR_NOTSUPPORTED;
+ break;
+ }
+
+ return ret;
+}
+
+/**
+ * pm_api_pinctrl_get_config() - Get configuration parameter value for given pin
+ * @pin: Pin for which configuration is to be read
+ * @param: Configuration parameter to be read
+ * @value: buffer to store value of configuration parameter
+ *
+ * This function reads value of requested configuration parameter for given pin.
+ *
+ * @return Returns status, either success or error+reason
+ */
+enum pm_ret_status pm_api_pinctrl_get_config(unsigned int pin,
+ unsigned int param,
+ unsigned int *value)
+{
+ enum pm_ret_status ret;
+ unsigned int ctrlreg, val;
+
+ if (param >= PINCTRL_CONFIG_MAX)
+ return PM_RET_ERROR_NOTSUPPORTED;
+
+ if (pin >= PINCTRL_NUM_MIOS)
+ return PM_RET_ERROR_ARGS;
+
+ switch (param) {
+ case PINCTRL_CONFIG_SLEW_RATE:
+ ctrlreg = PINCTRL_CFG_ADDR_OFFSET(IOU_SLCR_BASEADDR,
+ PINCTRL_SLEWCTRL_REG_OFFSET,
+ pin);
+
+ ret = pm_mmio_read(ctrlreg, &val);
+ if (ret != PM_RET_SUCCESS)
+ return ret;
+
+ *value = PINCTRL_REGVAL_TO_PIN_CONFIG(pin, val);
+ break;
+ case PINCTRL_CONFIG_BIAS_STATUS:
+ ctrlreg = PINCTRL_CFG_ADDR_OFFSET(IOU_SLCR_BASEADDR,
+ PINCTRL_PULLSTAT_REG_OFFSET,
+ pin);
+
+ ret = pm_mmio_read(ctrlreg, &val);
+ if (ret)
+ return ret;
+
+ if (ctrlreg == IOU_SLCR_BANK1_CTRL5)
+ val = ((val & 0x3FFF) << 12) | ((val >> 14) & 0xFFF);
+
+ *value = PINCTRL_REGVAL_TO_PIN_CONFIG(pin, val);
+ break;
+ case PINCTRL_CONFIG_PULL_CTRL:
+
+ ctrlreg = PINCTRL_CFG_ADDR_OFFSET(IOU_SLCR_BASEADDR,
+ PINCTRL_PULLCTRL_REG_OFFSET,
+ pin);
+
+ ret = pm_mmio_read(ctrlreg, &val);
+ if (ret)
+ return ret;
+
+ *value = PINCTRL_REGVAL_TO_PIN_CONFIG(pin, val);
+ break;
+ case PINCTRL_CONFIG_SCHMITT_CMOS:
+ ctrlreg = PINCTRL_CFG_ADDR_OFFSET(IOU_SLCR_BASEADDR,
+ PINCTRL_SCHCMOS_REG_OFFSET,
+ pin);
+
+ ret = pm_mmio_read(ctrlreg, &val);
+ if (ret)
+ return ret;
+
+ *value = PINCTRL_REGVAL_TO_PIN_CONFIG(pin, val);
+ break;
+ case PINCTRL_CONFIG_DRIVE_STRENGTH:
+ ctrlreg = PINCTRL_CFG_ADDR_OFFSET(IOU_SLCR_BASEADDR,
+ PINCTRL_DRVSTRN0_REG_OFFSET,
+ pin);
+ ret = pm_mmio_read(ctrlreg, &val);
+ if (ret)
+ return ret;
+
+ *value = PINCTRL_REGVAL_TO_PIN_CONFIG(pin, val) << 1;
+
+ ctrlreg = PINCTRL_CFG_ADDR_OFFSET(IOU_SLCR_BASEADDR,
+ PINCTRL_DRVSTRN1_REG_OFFSET,
+ pin);
+ ret = pm_mmio_read(ctrlreg, &val);
+ if (ret)
+ return ret;
+
+ *value |= PINCTRL_REGVAL_TO_PIN_CONFIG(pin, val);
+ break;
+ case PINCTRL_CONFIG_VOLTAGE_STATUS:
+ ctrlreg = PINCTRL_CFG_ADDR_OFFSET(IOU_SLCR_BASEADDR,
+ PINCTRL_VOLTAGE_STAT_REG_OFFSET,
+ pin);
+
+ ret = pm_mmio_read(ctrlreg, &val);
+ if (ret)
+ return ret;
+
+ *value = val & PINCTRL_VOLTAGE_STATUS_MASK;
+ break;
+ default:
+ return PM_RET_ERROR_NOTSUPPORTED;
+ }
+
+ return PM_RET_SUCCESS;
+}
diff --git a/plat/xilinx/zynqmp/pm_service/pm_api_pinctrl.h b/plat/xilinx/zynqmp/pm_service/pm_api_pinctrl.h
new file mode 100644
index 0000000..c70a774
--- /dev/null
+++ b/plat/xilinx/zynqmp/pm_service/pm_api_pinctrl.h
@@ -0,0 +1,734 @@
+/*
+ * Copyright (c) 2018, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+/*
+ * ZynqMP system level PM-API functions for pin control.
+ */
+
+#ifndef _PM_API_PINCTRL_H_
+#define _PM_API_PINCTRL_H_
+
+#include "pm_common.h"
+
+#define FUNCTION_NAME_LEN U(16)
+#define GROUPS_PAYLOAD_LEN U(12)
+#define NUM_GROUPS_PER_RESP U(6)
+#define END_OF_FUNCTION "END_OF_FUNCTION"
+#define END_OF_GROUPS -1
+#define PINCTRL_GRP_RESERVED -2
+
+//pinctrl function ids
+enum {
+ PINCTRL_FUNC_CAN0,
+ PINCTRL_FUNC_CAN1,
+ PINCTRL_FUNC_ETHERNET0,
+ PINCTRL_FUNC_ETHERNET1,
+ PINCTRL_FUNC_ETHERNET2,
+ PINCTRL_FUNC_ETHERNET3,
+ PINCTRL_FUNC_GEMTSU0,
+ PINCTRL_FUNC_GPIO0,
+ PINCTRL_FUNC_I2C0,
+ PINCTRL_FUNC_I2C1,
+ PINCTRL_FUNC_MDIO0,
+ PINCTRL_FUNC_MDIO1,
+ PINCTRL_FUNC_MDIO2,
+ PINCTRL_FUNC_MDIO3,
+ PINCTRL_FUNC_QSPI0,
+ PINCTRL_FUNC_QSPI_FBCLK,
+ PINCTRL_FUNC_QSPI_SS,
+ PINCTRL_FUNC_SPI0,
+ PINCTRL_FUNC_SPI1,
+ PINCTRL_FUNC_SPI0_SS,
+ PINCTRL_FUNC_SPI1_SS,
+ PINCTRL_FUNC_SDIO0,
+ PINCTRL_FUNC_SDIO0_PC,
+ PINCTRL_FUNC_SDIO0_CD,
+ PINCTRL_FUNC_SDIO0_WP,
+ PINCTRL_FUNC_SDIO1,
+ PINCTRL_FUNC_SDIO1_PC,
+ PINCTRL_FUNC_SDIO1_CD,
+ PINCTRL_FUNC_SDIO1_WP,
+ PINCTRL_FUNC_NAND0,
+ PINCTRL_FUNC_NAND0_CE,
+ PINCTRL_FUNC_NAND0_RB,
+ PINCTRL_FUNC_NAND0_DQS,
+ PINCTRL_FUNC_TTC0_CLK,
+ PINCTRL_FUNC_TTC0_WAV,
+ PINCTRL_FUNC_TTC1_CLK,
+ PINCTRL_FUNC_TTC1_WAV,
+ PINCTRL_FUNC_TTC2_CLK,
+ PINCTRL_FUNC_TTC2_WAV,
+ PINCTRL_FUNC_TTC3_CLK,
+ PINCTRL_FUNC_TTC3_WAV,
+ PINCTRL_FUNC_UART0,
+ PINCTRL_FUNC_UART1,
+ PINCTRL_FUNC_USB0,
+ PINCTRL_FUNC_USB1,
+ PINCTRL_FUNC_SWDT0_CLK,
+ PINCTRL_FUNC_SWDT0_RST,
+ PINCTRL_FUNC_SWDT1_CLK,
+ PINCTRL_FUNC_SWDT1_RST,
+ PINCTRL_FUNC_PMU0,
+ PINCTRL_FUNC_PCIE0,
+ PINCTRL_FUNC_CSU0,
+ PINCTRL_FUNC_DPAUX0,
+ PINCTRL_FUNC_PJTAG0,
+ PINCTRL_FUNC_TRACE0,
+ PINCTRL_FUNC_TRACE0_CLK,
+ PINCTRL_FUNC_TESTSCAN0,
+ END_FUNCTION,
+};
+
+#define MAX_FUNCTION (unsigned int)(END_FUNCTION)
+
+// pinctrl pin numbers
+enum {
+ PINCTRL_PIN_0,
+ PINCTRL_PIN_1,
+ PINCTRL_PIN_2,
+ PINCTRL_PIN_3,
+ PINCTRL_PIN_4,
+ PINCTRL_PIN_5,
+ PINCTRL_PIN_6,
+ PINCTRL_PIN_7,
+ PINCTRL_PIN_8,
+ PINCTRL_PIN_9,
+ PINCTRL_PIN_10,
+ PINCTRL_PIN_11,
+ PINCTRL_PIN_12,
+ PINCTRL_PIN_13,
+ PINCTRL_PIN_14,
+ PINCTRL_PIN_15,
+ PINCTRL_PIN_16,
+ PINCTRL_PIN_17,
+ PINCTRL_PIN_18,
+ PINCTRL_PIN_19,
+ PINCTRL_PIN_20,
+ PINCTRL_PIN_21,
+ PINCTRL_PIN_22,
+ PINCTRL_PIN_23,
+ PINCTRL_PIN_24,
+ PINCTRL_PIN_25,
+ PINCTRL_PIN_26,
+ PINCTRL_PIN_27,
+ PINCTRL_PIN_28,
+ PINCTRL_PIN_29,
+ PINCTRL_PIN_30,
+ PINCTRL_PIN_31,
+ PINCTRL_PIN_32,
+ PINCTRL_PIN_33,
+ PINCTRL_PIN_34,
+ PINCTRL_PIN_35,
+ PINCTRL_PIN_36,
+ PINCTRL_PIN_37,
+ PINCTRL_PIN_38,
+ PINCTRL_PIN_39,
+ PINCTRL_PIN_40,
+ PINCTRL_PIN_41,
+ PINCTRL_PIN_42,
+ PINCTRL_PIN_43,
+ PINCTRL_PIN_44,
+ PINCTRL_PIN_45,
+ PINCTRL_PIN_46,
+ PINCTRL_PIN_47,
+ PINCTRL_PIN_48,
+ PINCTRL_PIN_49,
+ PINCTRL_PIN_50,
+ PINCTRL_PIN_51,
+ PINCTRL_PIN_52,
+ PINCTRL_PIN_53,
+ PINCTRL_PIN_54,
+ PINCTRL_PIN_55,
+ PINCTRL_PIN_56,
+ PINCTRL_PIN_57,
+ PINCTRL_PIN_58,
+ PINCTRL_PIN_59,
+ PINCTRL_PIN_60,
+ PINCTRL_PIN_61,
+ PINCTRL_PIN_62,
+ PINCTRL_PIN_63,
+ PINCTRL_PIN_64,
+ PINCTRL_PIN_65,
+ PINCTRL_PIN_66,
+ PINCTRL_PIN_67,
+ PINCTRL_PIN_68,
+ PINCTRL_PIN_69,
+ PINCTRL_PIN_70,
+ PINCTRL_PIN_71,
+ PINCTRL_PIN_72,
+ PINCTRL_PIN_73,
+ PINCTRL_PIN_74,
+ PINCTRL_PIN_75,
+ PINCTRL_PIN_76,
+ PINCTRL_PIN_77,
+ END_PINS,
+};
+
+#define MAX_PIN (unsigned int)(END_PINS)
+
+// pinctrl group ids
+enum {
+ PINCTRL_GRP_ETHERNET0_0,
+ PINCTRL_GRP_ETHERNET1_0,
+ PINCTRL_GRP_ETHERNET2_0,
+ PINCTRL_GRP_ETHERNET3_0,
+ PINCTRL_GRP_GEMTSU0_0,
+ PINCTRL_GRP_GEMTSU0_1,
+ PINCTRL_GRP_GEMTSU0_2,
+ PINCTRL_GRP_MDIO0_0,
+ PINCTRL_GRP_MDIO1_0,
+ PINCTRL_GRP_MDIO1_1,
+ PINCTRL_GRP_MDIO2_0,
+ PINCTRL_GRP_MDIO3_0,
+ PINCTRL_GRP_QSPI0_0,
+ PINCTRL_GRP_QSPI_SS,
+ PINCTRL_GRP_QSPI_FBCLK,
+ PINCTRL_GRP_SPI0_0,
+ PINCTRL_GRP_SPI0_0_SS0,
+ PINCTRL_GRP_SPI0_0_SS1,
+ PINCTRL_GRP_SPI0_0_SS2,
+ PINCTRL_GRP_SPI0_1,
+ PINCTRL_GRP_SPI0_1_SS0,
+ PINCTRL_GRP_SPI0_1_SS1,
+ PINCTRL_GRP_SPI0_1_SS2,
+ PINCTRL_GRP_SPI0_2,
+ PINCTRL_GRP_SPI0_2_SS0,
+ PINCTRL_GRP_SPI0_2_SS1,
+ PINCTRL_GRP_SPI0_2_SS2,
+ PINCTRL_GRP_SPI0_3,
+ PINCTRL_GRP_SPI0_3_SS0,
+ PINCTRL_GRP_SPI0_3_SS1,
+ PINCTRL_GRP_SPI0_3_SS2,
+ PINCTRL_GRP_SPI0_4,
+ PINCTRL_GRP_SPI0_4_SS0,
+ PINCTRL_GRP_SPI0_4_SS1,
+ PINCTRL_GRP_SPI0_4_SS2,
+ PINCTRL_GRP_SPI0_5,
+ PINCTRL_GRP_SPI0_5_SS0,
+ PINCTRL_GRP_SPI0_5_SS1,
+ PINCTRL_GRP_SPI0_5_SS2,
+ PINCTRL_GRP_SPI1_0,
+ PINCTRL_GRP_SPI1_0_SS0,
+ PINCTRL_GRP_SPI1_0_SS1,
+ PINCTRL_GRP_SPI1_0_SS2,
+ PINCTRL_GRP_SPI1_1,
+ PINCTRL_GRP_SPI1_1_SS0,
+ PINCTRL_GRP_SPI1_1_SS1,
+ PINCTRL_GRP_SPI1_1_SS2,
+ PINCTRL_GRP_SPI1_2,
+ PINCTRL_GRP_SPI1_2_SS0,
+ PINCTRL_GRP_SPI1_2_SS1,
+ PINCTRL_GRP_SPI1_2_SS2,
+ PINCTRL_GRP_SPI1_3,
+ PINCTRL_GRP_SPI1_3_SS0,
+ PINCTRL_GRP_SPI1_3_SS1,
+ PINCTRL_GRP_SPI1_3_SS2,
+ PINCTRL_GRP_SPI1_4,
+ PINCTRL_GRP_SPI1_4_SS0,
+ PINCTRL_GRP_SPI1_4_SS1,
+ PINCTRL_GRP_SPI1_4_SS2,
+ PINCTRL_GRP_SPI1_5,
+ PINCTRL_GRP_SPI1_5_SS0,
+ PINCTRL_GRP_SPI1_5_SS1,
+ PINCTRL_GRP_SPI1_5_SS2,
+ PINCTRL_GRP_SDIO0_0,
+ PINCTRL_GRP_SDIO0_1,
+ PINCTRL_GRP_SDIO0_2,
+ PINCTRL_GRP_SDIO0_4BIT_0_0,
+ PINCTRL_GRP_SDIO0_4BIT_0_1,
+ PINCTRL_GRP_SDIO0_4BIT_1_0,
+ PINCTRL_GRP_SDIO0_4BIT_1_1,
+ PINCTRL_GRP_SDIO0_4BIT_2_0,
+ PINCTRL_GRP_SDIO0_4BIT_2_1,
+ PINCTRL_GRP_SDIO0_1BIT_0_0,
+ PINCTRL_GRP_SDIO0_1BIT_0_1,
+ PINCTRL_GRP_SDIO0_1BIT_0_2,
+ PINCTRL_GRP_SDIO0_1BIT_0_3,
+ PINCTRL_GRP_SDIO0_1BIT_0_4,
+ PINCTRL_GRP_SDIO0_1BIT_0_5,
+ PINCTRL_GRP_SDIO0_1BIT_0_6,
+ PINCTRL_GRP_SDIO0_1BIT_0_7,
+ PINCTRL_GRP_SDIO0_1BIT_1_0,
+ PINCTRL_GRP_SDIO0_1BIT_1_1,
+ PINCTRL_GRP_SDIO0_1BIT_1_2,
+ PINCTRL_GRP_SDIO0_1BIT_1_3,
+ PINCTRL_GRP_SDIO0_1BIT_1_4,
+ PINCTRL_GRP_SDIO0_1BIT_1_5,
+ PINCTRL_GRP_SDIO0_1BIT_1_6,
+ PINCTRL_GRP_SDIO0_1BIT_1_7,
+ PINCTRL_GRP_SDIO0_1BIT_2_0,
+ PINCTRL_GRP_SDIO0_1BIT_2_1,
+ PINCTRL_GRP_SDIO0_1BIT_2_2,
+ PINCTRL_GRP_SDIO0_1BIT_2_3,
+ PINCTRL_GRP_SDIO0_1BIT_2_4,
+ PINCTRL_GRP_SDIO0_1BIT_2_5,
+ PINCTRL_GRP_SDIO0_1BIT_2_6,
+ PINCTRL_GRP_SDIO0_1BIT_2_7,
+ PINCTRL_GRP_SDIO0_0_PC,
+ PINCTRL_GRP_SDIO0_0_CD,
+ PINCTRL_GRP_SDIO0_0_WP,
+ PINCTRL_GRP_SDIO0_1_PC,
+ PINCTRL_GRP_SDIO0_1_CD,
+ PINCTRL_GRP_SDIO0_1_WP,
+ PINCTRL_GRP_SDIO0_2_PC,
+ PINCTRL_GRP_SDIO0_2_CD,
+ PINCTRL_GRP_SDIO0_2_WP,
+ PINCTRL_GRP_SDIO1_0,
+ PINCTRL_GRP_SDIO1_4BIT_0_0,
+ PINCTRL_GRP_SDIO1_4BIT_0_1,
+ PINCTRL_GRP_SDIO1_4BIT_1_0,
+ PINCTRL_GRP_SDIO1_1BIT_0_0,
+ PINCTRL_GRP_SDIO1_1BIT_0_1,
+ PINCTRL_GRP_SDIO1_1BIT_0_2,
+ PINCTRL_GRP_SDIO1_1BIT_0_3,
+ PINCTRL_GRP_SDIO1_1BIT_0_4,
+ PINCTRL_GRP_SDIO1_1BIT_0_5,
+ PINCTRL_GRP_SDIO1_1BIT_0_6,
+ PINCTRL_GRP_SDIO1_1BIT_0_7,
+ PINCTRL_GRP_SDIO1_1BIT_1_0,
+ PINCTRL_GRP_SDIO1_1BIT_1_1,
+ PINCTRL_GRP_SDIO1_1BIT_1_2,
+ PINCTRL_GRP_SDIO1_1BIT_1_3,
+ PINCTRL_GRP_SDIO1_0_PC,
+ PINCTRL_GRP_SDIO1_0_CD,
+ PINCTRL_GRP_SDIO1_0_WP,
+ PINCTRL_GRP_SDIO1_1_PC,
+ PINCTRL_GRP_SDIO1_1_CD,
+ PINCTRL_GRP_SDIO1_1_WP,
+ PINCTRL_GRP_NAND0_0,
+ PINCTRL_GRP_NAND0_0_CE,
+ PINCTRL_GRP_NAND0_0_RB,
+ PINCTRL_GRP_NAND0_0_DQS,
+ PINCTRL_GRP_NAND0_1_CE,
+ PINCTRL_GRP_NAND0_1_RB,
+ PINCTRL_GRP_NAND0_1_DQS,
+ PINCTRL_GRP_CAN0_0,
+ PINCTRL_GRP_CAN0_1,
+ PINCTRL_GRP_CAN0_2,
+ PINCTRL_GRP_CAN0_3,
+ PINCTRL_GRP_CAN0_4,
+ PINCTRL_GRP_CAN0_5,
+ PINCTRL_GRP_CAN0_6,
+ PINCTRL_GRP_CAN0_7,
+ PINCTRL_GRP_CAN0_8,
+ PINCTRL_GRP_CAN0_9,
+ PINCTRL_GRP_CAN0_10,
+ PINCTRL_GRP_CAN0_11,
+ PINCTRL_GRP_CAN0_12,
+ PINCTRL_GRP_CAN0_13,
+ PINCTRL_GRP_CAN0_14,
+ PINCTRL_GRP_CAN0_15,
+ PINCTRL_GRP_CAN0_16,
+ PINCTRL_GRP_CAN0_17,
+ PINCTRL_GRP_CAN0_18,
+ PINCTRL_GRP_CAN1_0,
+ PINCTRL_GRP_CAN1_1,
+ PINCTRL_GRP_CAN1_2,
+ PINCTRL_GRP_CAN1_3,
+ PINCTRL_GRP_CAN1_4,
+ PINCTRL_GRP_CAN1_5,
+ PINCTRL_GRP_CAN1_6,
+ PINCTRL_GRP_CAN1_7,
+ PINCTRL_GRP_CAN1_8,
+ PINCTRL_GRP_CAN1_9,
+ PINCTRL_GRP_CAN1_10,
+ PINCTRL_GRP_CAN1_11,
+ PINCTRL_GRP_CAN1_12,
+ PINCTRL_GRP_CAN1_13,
+ PINCTRL_GRP_CAN1_14,
+ PINCTRL_GRP_CAN1_15,
+ PINCTRL_GRP_CAN1_16,
+ PINCTRL_GRP_CAN1_17,
+ PINCTRL_GRP_CAN1_18,
+ PINCTRL_GRP_CAN1_19,
+ PINCTRL_GRP_UART0_0,
+ PINCTRL_GRP_UART0_1,
+ PINCTRL_GRP_UART0_2,
+ PINCTRL_GRP_UART0_3,
+ PINCTRL_GRP_UART0_4,
+ PINCTRL_GRP_UART0_5,
+ PINCTRL_GRP_UART0_6,
+ PINCTRL_GRP_UART0_7,
+ PINCTRL_GRP_UART0_8,
+ PINCTRL_GRP_UART0_9,
+ PINCTRL_GRP_UART0_10,
+ PINCTRL_GRP_UART0_11,
+ PINCTRL_GRP_UART0_12,
+ PINCTRL_GRP_UART0_13,
+ PINCTRL_GRP_UART0_14,
+ PINCTRL_GRP_UART0_15,
+ PINCTRL_GRP_UART0_16,
+ PINCTRL_GRP_UART0_17,
+ PINCTRL_GRP_UART0_18,
+ PINCTRL_GRP_UART1_0,
+ PINCTRL_GRP_UART1_1,
+ PINCTRL_GRP_UART1_2,
+ PINCTRL_GRP_UART1_3,
+ PINCTRL_GRP_UART1_4,
+ PINCTRL_GRP_UART1_5,
+ PINCTRL_GRP_UART1_6,
+ PINCTRL_GRP_UART1_7,
+ PINCTRL_GRP_UART1_8,
+ PINCTRL_GRP_UART1_9,
+ PINCTRL_GRP_UART1_10,
+ PINCTRL_GRP_UART1_11,
+ PINCTRL_GRP_UART1_12,
+ PINCTRL_GRP_UART1_13,
+ PINCTRL_GRP_UART1_14,
+ PINCTRL_GRP_UART1_15,
+ PINCTRL_GRP_UART1_16,
+ PINCTRL_GRP_UART1_17,
+ PINCTRL_GRP_UART1_18,
+ PINCTRL_GRP_I2C0_0,
+ PINCTRL_GRP_I2C0_1,
+ PINCTRL_GRP_I2C0_2,
+ PINCTRL_GRP_I2C0_3,
+ PINCTRL_GRP_I2C0_4,
+ PINCTRL_GRP_I2C0_5,
+ PINCTRL_GRP_I2C0_6,
+ PINCTRL_GRP_I2C0_7,
+ PINCTRL_GRP_I2C0_8,
+ PINCTRL_GRP_I2C0_9,
+ PINCTRL_GRP_I2C0_10,
+ PINCTRL_GRP_I2C0_11,
+ PINCTRL_GRP_I2C0_12,
+ PINCTRL_GRP_I2C0_13,
+ PINCTRL_GRP_I2C0_14,
+ PINCTRL_GRP_I2C0_15,
+ PINCTRL_GRP_I2C0_16,
+ PINCTRL_GRP_I2C0_17,
+ PINCTRL_GRP_I2C0_18,
+ PINCTRL_GRP_I2C1_0,
+ PINCTRL_GRP_I2C1_1,
+ PINCTRL_GRP_I2C1_2,
+ PINCTRL_GRP_I2C1_3,
+ PINCTRL_GRP_I2C1_4,
+ PINCTRL_GRP_I2C1_5,
+ PINCTRL_GRP_I2C1_6,
+ PINCTRL_GRP_I2C1_7,
+ PINCTRL_GRP_I2C1_8,
+ PINCTRL_GRP_I2C1_9,
+ PINCTRL_GRP_I2C1_10,
+ PINCTRL_GRP_I2C1_11,
+ PINCTRL_GRP_I2C1_12,
+ PINCTRL_GRP_I2C1_13,
+ PINCTRL_GRP_I2C1_14,
+ PINCTRL_GRP_I2C1_15,
+ PINCTRL_GRP_I2C1_16,
+ PINCTRL_GRP_I2C1_17,
+ PINCTRL_GRP_I2C1_18,
+ PINCTRL_GRP_I2C1_19,
+ PINCTRL_GRP_TTC0_0_CLK,
+ PINCTRL_GRP_TTC0_0_WAV,
+ PINCTRL_GRP_TTC0_1_CLK,
+ PINCTRL_GRP_TTC0_1_WAV,
+ PINCTRL_GRP_TTC0_2_CLK,
+ PINCTRL_GRP_TTC0_2_WAV,
+ PINCTRL_GRP_TTC0_3_CLK,
+ PINCTRL_GRP_TTC0_3_WAV,
+ PINCTRL_GRP_TTC0_4_CLK,
+ PINCTRL_GRP_TTC0_4_WAV,
+ PINCTRL_GRP_TTC0_5_CLK,
+ PINCTRL_GRP_TTC0_5_WAV,
+ PINCTRL_GRP_TTC0_6_CLK,
+ PINCTRL_GRP_TTC0_6_WAV,
+ PINCTRL_GRP_TTC0_7_CLK,
+ PINCTRL_GRP_TTC0_7_WAV,
+ PINCTRL_GRP_TTC0_8_CLK,
+ PINCTRL_GRP_TTC0_8_WAV,
+ PINCTRL_GRP_TTC1_0_CLK,
+ PINCTRL_GRP_TTC1_0_WAV,
+ PINCTRL_GRP_TTC1_1_CLK,
+ PINCTRL_GRP_TTC1_1_WAV,
+ PINCTRL_GRP_TTC1_2_CLK,
+ PINCTRL_GRP_TTC1_2_WAV,
+ PINCTRL_GRP_TTC1_3_CLK,
+ PINCTRL_GRP_TTC1_3_WAV,
+ PINCTRL_GRP_TTC1_4_CLK,
+ PINCTRL_GRP_TTC1_4_WAV,
+ PINCTRL_GRP_TTC1_5_CLK,
+ PINCTRL_GRP_TTC1_5_WAV,
+ PINCTRL_GRP_TTC1_6_CLK,
+ PINCTRL_GRP_TTC1_6_WAV,
+ PINCTRL_GRP_TTC1_7_CLK,
+ PINCTRL_GRP_TTC1_7_WAV,
+ PINCTRL_GRP_TTC1_8_CLK,
+ PINCTRL_GRP_TTC1_8_WAV,
+ PINCTRL_GRP_TTC2_0_CLK,
+ PINCTRL_GRP_TTC2_0_WAV,
+ PINCTRL_GRP_TTC2_1_CLK,
+ PINCTRL_GRP_TTC2_1_WAV,
+ PINCTRL_GRP_TTC2_2_CLK,
+ PINCTRL_GRP_TTC2_2_WAV,
+ PINCTRL_GRP_TTC2_3_CLK,
+ PINCTRL_GRP_TTC2_3_WAV,
+ PINCTRL_GRP_TTC2_4_CLK,
+ PINCTRL_GRP_TTC2_4_WAV,
+ PINCTRL_GRP_TTC2_5_CLK,
+ PINCTRL_GRP_TTC2_5_WAV,
+ PINCTRL_GRP_TTC2_6_CLK,
+ PINCTRL_GRP_TTC2_6_WAV,
+ PINCTRL_GRP_TTC2_7_CLK,
+ PINCTRL_GRP_TTC2_7_WAV,
+ PINCTRL_GRP_TTC2_8_CLK,
+ PINCTRL_GRP_TTC2_8_WAV,
+ PINCTRL_GRP_TTC3_0_CLK,
+ PINCTRL_GRP_TTC3_0_WAV,
+ PINCTRL_GRP_TTC3_1_CLK,
+ PINCTRL_GRP_TTC3_1_WAV,
+ PINCTRL_GRP_TTC3_2_CLK,
+ PINCTRL_GRP_TTC3_2_WAV,
+ PINCTRL_GRP_TTC3_3_CLK,
+ PINCTRL_GRP_TTC3_3_WAV,
+ PINCTRL_GRP_TTC3_4_CLK,
+ PINCTRL_GRP_TTC3_4_WAV,
+ PINCTRL_GRP_TTC3_5_CLK,
+ PINCTRL_GRP_TTC3_5_WAV,
+ PINCTRL_GRP_TTC3_6_CLK,
+ PINCTRL_GRP_TTC3_6_WAV,
+ PINCTRL_GRP_TTC3_7_CLK,
+ PINCTRL_GRP_TTC3_7_WAV,
+ PINCTRL_GRP_TTC3_8_CLK,
+ PINCTRL_GRP_TTC3_8_WAV,
+ PINCTRL_GRP_SWDT0_0_CLK,
+ PINCTRL_GRP_SWDT0_0_RST,
+ PINCTRL_GRP_SWDT0_1_CLK,
+ PINCTRL_GRP_SWDT0_1_RST,
+ PINCTRL_GRP_SWDT0_2_CLK,
+ PINCTRL_GRP_SWDT0_2_RST,
+ PINCTRL_GRP_SWDT0_3_CLK,
+ PINCTRL_GRP_SWDT0_3_RST,
+ PINCTRL_GRP_SWDT0_4_CLK,
+ PINCTRL_GRP_SWDT0_4_RST,
+ PINCTRL_GRP_SWDT0_5_CLK,
+ PINCTRL_GRP_SWDT0_5_RST,
+ PINCTRL_GRP_SWDT0_6_CLK,
+ PINCTRL_GRP_SWDT0_6_RST,
+ PINCTRL_GRP_SWDT0_7_CLK,
+ PINCTRL_GRP_SWDT0_7_RST,
+ PINCTRL_GRP_SWDT0_8_CLK,
+ PINCTRL_GRP_SWDT0_8_RST,
+ PINCTRL_GRP_SWDT0_9_CLK,
+ PINCTRL_GRP_SWDT0_9_RST,
+ PINCTRL_GRP_SWDT0_10_CLK,
+ PINCTRL_GRP_SWDT0_10_RST,
+ PINCTRL_GRP_SWDT0_11_CLK,
+ PINCTRL_GRP_SWDT0_11_RST,
+ PINCTRL_GRP_SWDT0_12_CLK,
+ PINCTRL_GRP_SWDT0_12_RST,
+ PINCTRL_GRP_SWDT1_0_CLK,
+ PINCTRL_GRP_SWDT1_0_RST,
+ PINCTRL_GRP_SWDT1_1_CLK,
+ PINCTRL_GRP_SWDT1_1_RST,
+ PINCTRL_GRP_SWDT1_2_CLK,
+ PINCTRL_GRP_SWDT1_2_RST,
+ PINCTRL_GRP_SWDT1_3_CLK,
+ PINCTRL_GRP_SWDT1_3_RST,
+ PINCTRL_GRP_SWDT1_4_CLK,
+ PINCTRL_GRP_SWDT1_4_RST,
+ PINCTRL_GRP_SWDT1_5_CLK,
+ PINCTRL_GRP_SWDT1_5_RST,
+ PINCTRL_GRP_SWDT1_6_CLK,
+ PINCTRL_GRP_SWDT1_6_RST,
+ PINCTRL_GRP_SWDT1_7_CLK,
+ PINCTRL_GRP_SWDT1_7_RST,
+ PINCTRL_GRP_SWDT1_8_CLK,
+ PINCTRL_GRP_SWDT1_8_RST,
+ PINCTRL_GRP_SWDT1_9_CLK,
+ PINCTRL_GRP_SWDT1_9_RST,
+ PINCTRL_GRP_SWDT1_10_CLK,
+ PINCTRL_GRP_SWDT1_10_RST,
+ PINCTRL_GRP_SWDT1_11_CLK,
+ PINCTRL_GRP_SWDT1_11_RST,
+ PINCTRL_GRP_SWDT1_12_CLK,
+ PINCTRL_GRP_SWDT1_12_RST,
+ PINCTRL_GRP_GPIO0_0,
+ PINCTRL_GRP_GPIO0_1,
+ PINCTRL_GRP_GPIO0_2,
+ PINCTRL_GRP_GPIO0_3,
+ PINCTRL_GRP_GPIO0_4,
+ PINCTRL_GRP_GPIO0_5,
+ PINCTRL_GRP_GPIO0_6,
+ PINCTRL_GRP_GPIO0_7,
+ PINCTRL_GRP_GPIO0_8,
+ PINCTRL_GRP_GPIO0_9,
+ PINCTRL_GRP_GPIO0_10,
+ PINCTRL_GRP_GPIO0_11,
+ PINCTRL_GRP_GPIO0_12,
+ PINCTRL_GRP_GPIO0_13,
+ PINCTRL_GRP_GPIO0_14,
+ PINCTRL_GRP_GPIO0_15,
+ PINCTRL_GRP_GPIO0_16,
+ PINCTRL_GRP_GPIO0_17,
+ PINCTRL_GRP_GPIO0_18,
+ PINCTRL_GRP_GPIO0_19,
+ PINCTRL_GRP_GPIO0_20,
+ PINCTRL_GRP_GPIO0_21,
+ PINCTRL_GRP_GPIO0_22,
+ PINCTRL_GRP_GPIO0_23,
+ PINCTRL_GRP_GPIO0_24,
+ PINCTRL_GRP_GPIO0_25,
+ PINCTRL_GRP_GPIO0_26,
+ PINCTRL_GRP_GPIO0_27,
+ PINCTRL_GRP_GPIO0_28,
+ PINCTRL_GRP_GPIO0_29,
+ PINCTRL_GRP_GPIO0_30,
+ PINCTRL_GRP_GPIO0_31,
+ PINCTRL_GRP_GPIO0_32,
+ PINCTRL_GRP_GPIO0_33,
+ PINCTRL_GRP_GPIO0_34,
+ PINCTRL_GRP_GPIO0_35,
+ PINCTRL_GRP_GPIO0_36,
+ PINCTRL_GRP_GPIO0_37,
+ PINCTRL_GRP_GPIO0_38,
+ PINCTRL_GRP_GPIO0_39,
+ PINCTRL_GRP_GPIO0_40,
+ PINCTRL_GRP_GPIO0_41,
+ PINCTRL_GRP_GPIO0_42,
+ PINCTRL_GRP_GPIO0_43,
+ PINCTRL_GRP_GPIO0_44,
+ PINCTRL_GRP_GPIO0_45,
+ PINCTRL_GRP_GPIO0_46,
+ PINCTRL_GRP_GPIO0_47,
+ PINCTRL_GRP_GPIO0_48,
+ PINCTRL_GRP_GPIO0_49,
+ PINCTRL_GRP_GPIO0_50,
+ PINCTRL_GRP_GPIO0_51,
+ PINCTRL_GRP_GPIO0_52,
+ PINCTRL_GRP_GPIO0_53,
+ PINCTRL_GRP_GPIO0_54,
+ PINCTRL_GRP_GPIO0_55,
+ PINCTRL_GRP_GPIO0_56,
+ PINCTRL_GRP_GPIO0_57,
+ PINCTRL_GRP_GPIO0_58,
+ PINCTRL_GRP_GPIO0_59,
+ PINCTRL_GRP_GPIO0_60,
+ PINCTRL_GRP_GPIO0_61,
+ PINCTRL_GRP_GPIO0_62,
+ PINCTRL_GRP_GPIO0_63,
+ PINCTRL_GRP_GPIO0_64,
+ PINCTRL_GRP_GPIO0_65,
+ PINCTRL_GRP_GPIO0_66,
+ PINCTRL_GRP_GPIO0_67,
+ PINCTRL_GRP_GPIO0_68,
+ PINCTRL_GRP_GPIO0_69,
+ PINCTRL_GRP_GPIO0_70,
+ PINCTRL_GRP_GPIO0_71,
+ PINCTRL_GRP_GPIO0_72,
+ PINCTRL_GRP_GPIO0_73,
+ PINCTRL_GRP_GPIO0_74,
+ PINCTRL_GRP_GPIO0_75,
+ PINCTRL_GRP_GPIO0_76,
+ PINCTRL_GRP_GPIO0_77,
+ PINCTRL_GRP_USB0_0,
+ PINCTRL_GRP_USB1_0,
+ PINCTRL_GRP_PMU0_0,
+ PINCTRL_GRP_PMU0_1,
+ PINCTRL_GRP_PMU0_2,
+ PINCTRL_GRP_PMU0_3,
+ PINCTRL_GRP_PMU0_4,
+ PINCTRL_GRP_PMU0_5,
+ PINCTRL_GRP_PMU0_6,
+ PINCTRL_GRP_PMU0_7,
+ PINCTRL_GRP_PMU0_8,
+ PINCTRL_GRP_PMU0_9,
+ PINCTRL_GRP_PMU0_10,
+ PINCTRL_GRP_PMU0_11,
+ PINCTRL_GRP_PCIE0_0,
+ PINCTRL_GRP_PCIE0_1,
+ PINCTRL_GRP_PCIE0_2,
+ PINCTRL_GRP_PCIE0_3,
+ PINCTRL_GRP_PCIE0_4,
+ PINCTRL_GRP_PCIE0_5,
+ PINCTRL_GRP_PCIE0_6,
+ PINCTRL_GRP_PCIE0_7,
+ PINCTRL_GRP_CSU0_0,
+ PINCTRL_GRP_CSU0_1,
+ PINCTRL_GRP_CSU0_2,
+ PINCTRL_GRP_CSU0_3,
+ PINCTRL_GRP_CSU0_4,
+ PINCTRL_GRP_CSU0_5,
+ PINCTRL_GRP_CSU0_6,
+ PINCTRL_GRP_CSU0_7,
+ PINCTRL_GRP_CSU0_8,
+ PINCTRL_GRP_CSU0_9,
+ PINCTRL_GRP_CSU0_10,
+ PINCTRL_GRP_CSU0_11,
+ PINCTRL_GRP_DPAUX0_0,
+ PINCTRL_GRP_DPAUX0_1,
+ PINCTRL_GRP_DPAUX0_2,
+ PINCTRL_GRP_DPAUX0_3,
+ PINCTRL_GRP_PJTAG0_0,
+ PINCTRL_GRP_PJTAG0_1,
+ PINCTRL_GRP_PJTAG0_2,
+ PINCTRL_GRP_PJTAG0_3,
+ PINCTRL_GRP_PJTAG0_4,
+ PINCTRL_GRP_PJTAG0_5,
+ PINCTRL_GRP_TRACE0_0,
+ PINCTRL_GRP_TRACE0_0_CLK,
+ PINCTRL_GRP_TRACE0_1,
+ PINCTRL_GRP_TRACE0_1_CLK,
+ PINCTRL_GRP_TRACE0_2,
+ PINCTRL_GRP_TRACE0_2_CLK,
+ PINCTRL_GRP_TESTSCAN0_0,
+};
+
+// pinctrl config parameters
+enum {
+ PINCTRL_CONFIG_SLEW_RATE,
+ PINCTRL_CONFIG_BIAS_STATUS,
+ PINCTRL_CONFIG_PULL_CTRL,
+ PINCTRL_CONFIG_SCHMITT_CMOS,
+ PINCTRL_CONFIG_DRIVE_STRENGTH,
+ PINCTRL_CONFIG_VOLTAGE_STATUS,
+ PINCTRL_CONFIG_MAX,
+};
+
+// pinctrl slew rate
+#define PINCTRL_SLEW_RATE_FAST 0U
+#define PINCTRL_SLEW_RATE_SLOW 1U
+
+// pinctrl bias status
+#define PINCTRL_BIAS_DISABLE 0U
+#define PINCTRL_BIAS_ENABLE 1U
+
+// pinctrl pull control
+#define PINCTRL_BIAS_PULL_DOWN 0U
+#define PINCTRL_BIAS_PULL_UP 1U
+
+// pinctrl schmitt cmos type
+#define PINCTRL_INPUT_TYPE_CMOS 0U
+#define PINCTRL_INPUT_TYPE_SCHMITT 1U
+
+//pinctrl drive strength values
+#define PINCTRL_DRIVE_STRENGTH_2MA 0U
+#define PINCTRL_DRIVE_STRENGTH_4MA 1U
+#define PINCTRL_DRIVE_STRENGTH_8MA 2U
+#define PINCTRL_DRIVE_STRENGTH_12MA 3U
+
+enum pm_ret_status pm_api_pinctrl_set_function(unsigned int pin,
+ unsigned int fid);
+enum pm_ret_status pm_api_pinctrl_get_function(unsigned int pin,
+ unsigned int *id);
+enum pm_ret_status pm_api_pinctrl_set_config(unsigned int pin,
+ unsigned int param,
+ unsigned int value);
+enum pm_ret_status pm_api_pinctrl_get_config(unsigned int pin,
+ unsigned int param,
+ unsigned int *value);
+enum pm_ret_status pm_api_pinctrl_get_function_name(unsigned int fid,
+ char *name);
+enum pm_ret_status pm_api_pinctrl_get_function_groups(unsigned int fid,
+ unsigned int index,
+ uint16_t *groups);
+enum pm_ret_status pm_api_pinctrl_get_pin_groups(unsigned int pin,
+ unsigned int index,
+ uint16_t *groups);
+enum pm_ret_status pm_api_pinctrl_get_num_pins(unsigned int *npins);
+enum pm_ret_status pm_api_pinctrl_get_num_functions(unsigned int *nfuncs);
+enum pm_ret_status pm_api_pinctrl_get_num_func_groups(unsigned int fid,
+ unsigned int *ngroups);
+#endif /* _PM_API_PINCTRL_H_ */
diff --git a/plat/xilinx/zynqmp/pm_service/pm_api_sys.c b/plat/xilinx/zynqmp/pm_service/pm_api_sys.c
index 9e21067..d75f7c0 100644
--- a/plat/xilinx/zynqmp/pm_service/pm_api_sys.c
+++ b/plat/xilinx/zynqmp/pm_service/pm_api_sys.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2013-2017, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2013-2018, ARM Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -11,6 +11,9 @@
#include <arch_helpers.h>
#include <platform.h>
+#include "pm_api_clock.h"
+#include "pm_api_ioctl.h"
+#include "pm_api_pinctrl.h"
#include "pm_api_sys.h"
#include "pm_client.h"
#include "pm_common.h"
@@ -545,3 +548,529 @@
pm_ipi_buff_read_callb(data, count);
pm_ipi_irq_clear(primary_proc);
}
+
+/**
+ * pm_pinctrl_request() - Request Pin from firmware
+ * @pin Pin number to request
+ *
+ * This function requests pin from firmware.
+ *
+ * @return Returns status, either success or error+reason.
+ */
+enum pm_ret_status pm_pinctrl_request(unsigned int pin)
+{
+ return PM_RET_SUCCESS;
+}
+
+/**
+ * pm_pinctrl_release() - Release Pin from firmware
+ * @pin Pin number to release
+ *
+ * This function releases pin from firmware.
+ *
+ * @return Returns status, either success or error+reason.
+ */
+enum pm_ret_status pm_pinctrl_release(unsigned int pin)
+{
+ return PM_RET_SUCCESS;
+}
+
+/**
+ * pm_pinctrl_get_function() - Read function id set for the given pin
+ * @pin Pin number
+ * @nid Node ID of function currently set for given pin
+ *
+ * This function provides the function currently set for the given pin.
+ *
+ * @return Returns status, either success or error+reason
+ */
+enum pm_ret_status pm_pinctrl_get_function(unsigned int pin,
+ enum pm_node_id *nid)
+{
+ return pm_api_pinctrl_get_function(pin, nid);
+}
+
+/**
+ * pm_pinctrl_set_function() - Set function id set for the given pin
+ * @pin Pin number
+ * @nid Node ID of function to set for given pin
+ *
+ * This function provides the function currently set for the given pin.
+ *
+ * @return Returns status, either success or error+reason
+ */
+enum pm_ret_status pm_pinctrl_set_function(unsigned int pin,
+ enum pm_node_id nid)
+{
+ return pm_api_pinctrl_set_function(pin, (unsigned int)nid);
+}
+
+/**
+ * pm_pinctrl_get_config() - Read value of requested config param for given pin
+ * @pin Pin number
+ * @param Parameter values to be read
+ * @value Buffer for configuration Parameter value
+ *
+ * This function provides the configuration parameter value for the given pin.
+ *
+ * @return Returns status, either success or error+reason
+ */
+enum pm_ret_status pm_pinctrl_get_config(unsigned int pin,
+ unsigned int param,
+ unsigned int *value)
+{
+ return pm_api_pinctrl_get_config(pin, param, value);
+}
+
+/**
+ * pm_pinctrl_set_config() - Read value of requested config param for given pin
+ * @pin Pin number
+ * @param Parameter to set
+ * @value Parameter value to set
+ *
+ * This function provides the configuration parameter value for the given pin.
+ *
+ * @return Returns status, either success or error+reason
+ */
+enum pm_ret_status pm_pinctrl_set_config(unsigned int pin,
+ unsigned int param,
+ unsigned int value)
+{
+ return pm_api_pinctrl_set_config(pin, param, value);
+}
+
+/**
+ * pm_ioctl() - PM IOCTL API for device control and configs
+ * @node_id Node ID of the device
+ * @ioctl_id ID of the requested IOCTL
+ * @arg1 Argument 1 to requested IOCTL call
+ * @arg2 Argument 2 to requested IOCTL call
+ * @out Returned output value
+ *
+ * This function calls IOCTL to firmware for device control and configuration.
+ *
+ * @return Returns status, either success or error+reason
+ */
+enum pm_ret_status pm_ioctl(enum pm_node_id nid,
+ unsigned int ioctl_id,
+ unsigned int arg1,
+ unsigned int arg2,
+ unsigned int *value)
+{
+ return pm_api_ioctl(nid, ioctl_id, arg1, arg2, value);
+}
+
+/**
+ * pm_clock_get_name() - PM call to request a clock's name
+ * @clock_id Clock ID
+ * @name Name of clock (max 16 bytes)
+ *
+ * This function is used by master to get nmae of clock specified
+ * by given clock ID.
+ *
+ * @return Returns status, either success or error+reason
+ */
+static enum pm_ret_status pm_clock_get_name(unsigned int clock_id, char *name)
+{
+ return pm_api_clock_get_name(clock_id, name);
+}
+
+/**
+ * pm_clock_get_topology() - PM call to request a clock's topology
+ * @clock_id Clock ID
+ * @index Topology index for next toplogy node
+ * @topology Buffer to store nodes in topology and flags
+ *
+ * This function is used by master to get topology information for the
+ * clock specified by given clock ID. Each response would return 3
+ * topology nodes. To get next nodes, caller needs to call this API with
+ * index of next node. Index starts from 0.
+ *
+ * @return Returns status, either success or error+reason
+ */
+static enum pm_ret_status pm_clock_get_topology(unsigned int clock_id,
+ unsigned int index,
+ uint32_t *topology)
+{
+ return pm_api_clock_get_topology(clock_id, index, topology);
+}
+
+/**
+ * pm_clock_get_fixedfactor_params() - PM call to request a clock's fixed factor
+ * parameters for fixed clock
+ * @clock_id Clock ID
+ * @mul Multiplication value
+ * @div Divisor value
+ *
+ * This function is used by master to get fixed factor parameers for the
+ * fixed clock. This API is application only for the fixed clock.
+ *
+ * @return Returns status, either success or error+reason
+ */
+static enum pm_ret_status pm_clock_get_fixedfactor_params(unsigned int clock_id,
+ uint32_t *mul,
+ uint32_t *div)
+{
+ return pm_api_clock_get_fixedfactor_params(clock_id, mul, div);
+}
+
+/**
+ * pm_clock_get_parents() - PM call to request a clock's first 3 parents
+ * @clock_id Clock ID
+ * @index Index of next parent
+ * @parents Parents of the given clock
+ *
+ * This function is used by master to get clock's parents information.
+ * This API will return 3 parents with a single response. To get other
+ * parents, master should call same API in loop with new parent index
+ * till error is returned.
+ *
+ * E.g First call should have index 0 which will return parents 0, 1 and
+ * 2. Next call, index should be 3 which will return parent 3,4 and 5 and
+ * so on.
+ *
+ * @return Returns status, either success or error+reason
+ */
+static enum pm_ret_status pm_clock_get_parents(unsigned int clock_id,
+ unsigned int index,
+ uint32_t *parents)
+{
+ return pm_api_clock_get_parents(clock_id, index, parents);
+}
+
+/**
+ * pm_clock_get_attributes() - PM call to request a clock's attributes
+ * @clock_id Clock ID
+ * @attr Clock attributes
+ *
+ * This function is used by master to get clock's attributes
+ * (e.g. valid, clock type, etc).
+ *
+ * @return Returns status, either success or error+reason
+ */
+static enum pm_ret_status pm_clock_get_attributes(unsigned int clock_id,
+ uint32_t *attr)
+{
+ return pm_api_clock_get_attributes(clock_id, attr);
+}
+
+/**
+ * pm_clock_enable() - Enable the clock for given id
+ * @clock_id: Id of the clock to be enabled
+ *
+ * This function is used by master to enable the clock
+ * including peripherals and PLL clocks.
+ *
+ * Return: Returns status, either success or error+reason.
+ */
+
+enum pm_ret_status pm_clock_enable(unsigned int clock_id)
+{
+ return pm_api_clock_enable(clock_id);
+}
+
+/**
+ * pm_clock_disable - Disable the clock for given id
+ * @clock_id: Id of the clock to be disable
+ *
+ * This function is used by master to disable the clock
+ * including peripherals and PLL clocks.
+ *
+ * Return: Returns status, either success or error+reason.
+ */
+
+enum pm_ret_status pm_clock_disable(unsigned int clock_id)
+{
+ return pm_api_clock_disable(clock_id);
+}
+
+/**
+ * pm_clock_getstate - Get the clock state for given id
+ * @clock_id: Id of the clock to be queried
+ * @state: 1/0 (Enabled/Disabled)
+ *
+ * This function is used by master to get the state of clock
+ * including peripherals and PLL clocks.
+ *
+ * Return: Returns status, either success or error+reason.
+ */
+enum pm_ret_status pm_clock_getstate(unsigned int clock_id,
+ unsigned int *state)
+{
+ return pm_api_clock_getstate(clock_id, state);
+}
+
+/**
+ * pm_clock_setdivider - Set the clock divider for given id
+ * @clock_id: Id of the clock
+ * @divider: divider value
+ *
+ * This function is used by master to set divider for any clock
+ * to achieve desired rate.
+ *
+ * Return: Returns status, either success or error+reason.
+ */
+enum pm_ret_status pm_clock_setdivider(unsigned int clock_id,
+ unsigned int divider)
+{
+ return pm_api_clock_setdivider(clock_id, divider);
+}
+
+/**
+ * pm_clock_getdivider - Get the clock divider for given id
+ * @clock_id: Id of the clock
+ * @divider: divider value
+ *
+ * This function is used by master to get divider values
+ * for any clock.
+ *
+ * Return: Returns status, either success or error+reason.
+ */
+enum pm_ret_status pm_clock_getdivider(unsigned int clock_id,
+ unsigned int *divider)
+{
+ return pm_api_clock_getdivider(clock_id, divider);
+}
+
+/**
+ * pm_clock_setrate - Set the clock rate for given id
+ * @clock_id: Id of the clock
+ * @rate: rate value in hz
+ *
+ * This function is used by master to set rate for any clock.
+ *
+ * Return: Returns status, either success or error+reason.
+ */
+enum pm_ret_status pm_clock_setrate(unsigned int clock_id,
+ uint64_t rate)
+{
+ return pm_api_clock_setrate(clock_id, rate);
+}
+
+/**
+ * pm_clock_getrate - Get the clock rate for given id
+ * @clock_id: Id of the clock
+ * @rate: rate value in hz
+ *
+ * This function is used by master to get rate
+ * for any clock.
+ *
+ * Return: Returns status, either success or error+reason.
+ */
+enum pm_ret_status pm_clock_getrate(unsigned int clock_id,
+ uint64_t *rate)
+{
+ return pm_api_clock_getrate(clock_id, rate);
+}
+
+/**
+ * pm_clock_setparent - Set the clock parent for given id
+ * @clock_id: Id of the clock
+ * @parent_id: parent id
+ *
+ * This function is used by master to set parent for any clock.
+ *
+ * Return: Returns status, either success or error+reason.
+ */
+enum pm_ret_status pm_clock_setparent(unsigned int clock_id,
+ unsigned int parent_id)
+{
+ return pm_api_clock_setparent(clock_id, parent_id);
+}
+
+/**
+ * pm_clock_getparent - Get the clock parent for given id
+ * @clock_id: Id of the clock
+ * @parent_id: parent id
+ *
+ * This function is used by master to get parent index
+ * for any clock.
+ *
+ * Return: Returns status, either success or error+reason.
+ */
+enum pm_ret_status pm_clock_getparent(unsigned int clock_id,
+ unsigned int *parent_id)
+{
+ return pm_api_clock_getparent(clock_id, parent_id);
+}
+
+/**
+ * pm_pinctrl_get_num_pins - PM call to request number of pins
+ * @npins: Number of pins
+ *
+ * This function is used by master to get number of pins
+ *
+ * Return: Returns status, either success or error+reason.
+ */
+static enum pm_ret_status pm_pinctrl_get_num_pins(uint32_t *npins)
+{
+ return pm_api_pinctrl_get_num_pins(npins);
+}
+
+/**
+ * pm_pinctrl_get_num_functions - PM call to request number of functions
+ * @nfuncs: Number of functions
+ *
+ * This function is used by master to get number of functions
+ *
+ * Return: Returns status, either success or error+reason.
+ */
+static enum pm_ret_status pm_pinctrl_get_num_functions(uint32_t *nfuncs)
+{
+ return pm_api_pinctrl_get_num_functions(nfuncs);
+}
+
+/**
+ * pm_pinctrl_get_num_function_groups - PM call to request number of
+ * function groups
+ * @fid: Id of function
+ * @ngroups: Number of function groups
+ *
+ * This function is used by master to get number of function groups specified
+ * by given function Id
+ *
+ * Return: Returns status, either success or error+reason.
+ */
+static enum pm_ret_status pm_pinctrl_get_num_function_groups(unsigned int fid,
+ uint32_t *ngroups)
+{
+ return pm_api_pinctrl_get_num_func_groups(fid, ngroups);
+}
+
+/**
+ * pm_pinctrl_get_function_name - PM call to request function name
+ * @fid: Id of function
+ * @name: Name of function
+ *
+ * This function is used by master to get name of function specified
+ * by given function Id
+ *
+ * Return: Returns status, either success or error+reason.
+ */
+static enum pm_ret_status pm_pinctrl_get_function_name(unsigned int fid,
+ char *name)
+{
+ return pm_api_pinctrl_get_function_name(fid, name);
+}
+
+/**
+ * pm_pinctrl_get_function_groups - PM call to request function groups
+ * @fid: Id of function
+ * @index: Index of next function groups
+ * @groups: Function groups
+ *
+ * This function is used by master to get function groups specified
+ * by given function Id. This API will return 6 function groups with
+ * a single response. To get other function groups, master should call
+ * same API in loop with new function groups index till error is returned.
+ *
+ * E.g First call should have index 0 which will return function groups
+ * 0, 1, 2, 3, 4 and 5. Next call, index should be 6 which will return
+ * function groups 6, 7, 8, 9, 10 and 11 and so on.
+ *
+ * Return: Returns status, either success or error+reason.
+ */
+static enum pm_ret_status pm_pinctrl_get_function_groups(unsigned int fid,
+ unsigned int index,
+ uint16_t *groups)
+{
+ return pm_api_pinctrl_get_function_groups(fid, index, groups);
+}
+
+/**
+ * pm_pinctrl_get_pin_groups - PM call to request pin groups
+ * @pin_id: Id of pin
+ * @index: Index of next pin groups
+ * @groups: pin groups
+ *
+ * This function is used by master to get pin groups specified
+ * by given pin Id. This API will return 6 pin groups with
+ * a single response. To get other pin groups, master should call
+ * same API in loop with new pin groups index till error is returned.
+ *
+ * E.g First call should have index 0 which will return pin groups
+ * 0, 1, 2, 3, 4 and 5. Next call, index should be 6 which will return
+ * pin groups 6, 7, 8, 9, 10 and 11 and so on.
+ *
+ * Return: Returns status, either success or error+reason.
+ */
+static enum pm_ret_status pm_pinctrl_get_pin_groups(unsigned int pin_id,
+ unsigned int index,
+ uint16_t *groups)
+{
+ return pm_api_pinctrl_get_pin_groups(pin_id, index, groups);
+}
+
+/**
+ * pm_query_data() - PM API for querying firmware data
+ * @arg1 Argument 1 to requested IOCTL call
+ * @arg2 Argument 2 to requested IOCTL call
+ * @arg3 Argument 3 to requested IOCTL call
+ * @arg4 Argument 4 to requested IOCTL call
+ * @data Returned output data
+ *
+ * This function returns requested data.
+ *
+ * @return Returns status, either success or error+reason
+ */
+enum pm_ret_status pm_query_data(enum pm_query_id qid,
+ unsigned int arg1,
+ unsigned int arg2,
+ unsigned int arg3,
+ unsigned int *data)
+{
+ enum pm_ret_status ret;
+
+ switch (qid) {
+ case PM_QID_CLOCK_GET_NAME:
+ ret = pm_clock_get_name(arg1, (char *)data);
+ break;
+ case PM_QID_CLOCK_GET_TOPOLOGY:
+ ret = pm_clock_get_topology(arg1, arg2, &data[1]);
+ data[0] = (unsigned int)ret;
+ break;
+ case PM_QID_CLOCK_GET_FIXEDFACTOR_PARAMS:
+ ret = pm_clock_get_fixedfactor_params(arg1, &data[1], &data[2]);
+ data[0] = (unsigned int)ret;
+ break;
+ case PM_QID_CLOCK_GET_PARENTS:
+ ret = pm_clock_get_parents(arg1, arg2, &data[1]);
+ data[0] = (unsigned int)ret;
+ break;
+ case PM_QID_CLOCK_GET_ATTRIBUTES:
+ ret = pm_clock_get_attributes(arg1, &data[1]);
+ data[0] = (unsigned int)ret;
+ break;
+ case PM_QID_PINCTRL_GET_NUM_PINS:
+ ret = pm_pinctrl_get_num_pins(&data[1]);
+ data[0] = (unsigned int)ret;
+ break;
+ case PM_QID_PINCTRL_GET_NUM_FUNCTIONS:
+ ret = pm_pinctrl_get_num_functions(&data[1]);
+ data[0] = (unsigned int)ret;
+ break;
+ case PM_QID_PINCTRL_GET_NUM_FUNCTION_GROUPS:
+ ret = pm_pinctrl_get_num_function_groups(arg1, &data[1]);
+ data[0] = (unsigned int)ret;
+ break;
+ case PM_QID_PINCTRL_GET_FUNCTION_NAME:
+ ret = pm_pinctrl_get_function_name(arg1, (char *)data);
+ break;
+ case PM_QID_PINCTRL_GET_FUNCTION_GROUPS:
+ ret = pm_pinctrl_get_function_groups(arg1, arg2,
+ (uint16_t *)&data[1]);
+ data[0] = (unsigned int)ret;
+ break;
+ case PM_QID_PINCTRL_GET_PIN_GROUPS:
+ ret = pm_pinctrl_get_pin_groups(arg1, arg2,
+ (uint16_t *)&data[1]);
+ data[0] = (unsigned int)ret;
+ break;
+ default:
+ ret = PM_RET_ERROR_ARGS;
+ WARN("Unimplemented query service call: 0x%x\n", qid);
+ break;
+ }
+
+ return ret;
+}
diff --git a/plat/xilinx/zynqmp/pm_service/pm_api_sys.h b/plat/xilinx/zynqmp/pm_service/pm_api_sys.h
index af7b252..c6de560 100644
--- a/plat/xilinx/zynqmp/pm_service/pm_api_sys.h
+++ b/plat/xilinx/zynqmp/pm_service/pm_api_sys.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2013-2015, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2013-2018, ARM Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -10,6 +10,21 @@
#include <stdint.h>
#include "pm_defs.h"
+enum pm_query_id {
+ PM_QID_INVALID,
+ PM_QID_CLOCK_GET_NAME,
+ PM_QID_CLOCK_GET_TOPOLOGY,
+ PM_QID_CLOCK_GET_FIXEDFACTOR_PARAMS,
+ PM_QID_CLOCK_GET_PARENTS,
+ PM_QID_CLOCK_GET_ATTRIBUTES,
+ PM_QID_PINCTRL_GET_NUM_PINS,
+ PM_QID_PINCTRL_GET_NUM_FUNCTIONS,
+ PM_QID_PINCTRL_GET_NUM_FUNCTION_GROUPS,
+ PM_QID_PINCTRL_GET_FUNCTION_NAME,
+ PM_QID_PINCTRL_GET_FUNCTION_GROUPS,
+ PM_QID_PINCTRL_GET_PIN_GROUPS,
+};
+
/**********************************************************
* System-level API function declarations
**********************************************************/
@@ -93,5 +108,42 @@
enum pm_ret_status pm_get_chipid(uint32_t *value);
void pm_get_callbackdata(uint32_t *data, size_t count);
-
+enum pm_ret_status pm_pinctrl_request(unsigned int pin);
+enum pm_ret_status pm_pinctrl_release(unsigned int pin);
+enum pm_ret_status pm_pinctrl_get_function(unsigned int pin,
+ enum pm_node_id *nid);
+enum pm_ret_status pm_pinctrl_set_function(unsigned int pin,
+ enum pm_node_id nid);
+enum pm_ret_status pm_pinctrl_get_config(unsigned int pin,
+ unsigned int param,
+ unsigned int *value);
+enum pm_ret_status pm_pinctrl_set_config(unsigned int pin,
+ unsigned int param,
+ unsigned int value);
+enum pm_ret_status pm_ioctl(enum pm_node_id nid,
+ unsigned int ioctl_id,
+ unsigned int arg1,
+ unsigned int arg2,
+ unsigned int *value);
+enum pm_ret_status pm_clock_enable(unsigned int clock_id);
+enum pm_ret_status pm_clock_disable(unsigned int clock_id);
+enum pm_ret_status pm_clock_getstate(unsigned int clock_id,
+ unsigned int *state);
+enum pm_ret_status pm_clock_setdivider(unsigned int clock_id,
+ unsigned int divider);
+enum pm_ret_status pm_clock_getdivider(unsigned int clock_id,
+ unsigned int *divider);
+enum pm_ret_status pm_clock_setrate(unsigned int clock_id,
+ uint64_t rate);
+enum pm_ret_status pm_clock_getrate(unsigned int clock_id,
+ uint64_t *rate);
+enum pm_ret_status pm_clock_setparent(unsigned int clock_id,
+ unsigned int parent_id);
+enum pm_ret_status pm_clock_getparent(unsigned int clock_id,
+ unsigned int *parent_id);
+enum pm_ret_status pm_query_data(enum pm_query_id qid,
+ unsigned int arg1,
+ unsigned int arg2,
+ unsigned int arg3,
+ unsigned int *data);
#endif /* _PM_API_SYS_H_ */
diff --git a/plat/xilinx/zynqmp/pm_service/pm_common.h b/plat/xilinx/zynqmp/pm_service/pm_common.h
index 5dcbb0d..4d03bc0 100644
--- a/plat/xilinx/zynqmp/pm_service/pm_common.h
+++ b/plat/xilinx/zynqmp/pm_service/pm_common.h
@@ -19,6 +19,11 @@
#define PAYLOAD_ARG_CNT 6U
#define PAYLOAD_ARG_SIZE 4U /* size in bytes */
+#define ZYNQMP_TZ_VERSION_MAJOR 1
+#define ZYNQMP_TZ_VERSION_MINOR 0
+#define ZYNQMP_TZ_VERSION ((ZYNQMP_TZ_VERSION_MAJOR << 16) | \
+ ZYNQMP_TZ_VERSION_MINOR)
+
/**
* pm_ipi - struct for capturing IPI-channel specific info
* @apu_ipi_id APU IPI agent ID
diff --git a/plat/xilinx/zynqmp/pm_service/pm_defs.h b/plat/xilinx/zynqmp/pm_service/pm_defs.h
index ba0c52a..0c46e73 100644
--- a/plat/xilinx/zynqmp/pm_service/pm_defs.h
+++ b/plat/xilinx/zynqmp/pm_service/pm_defs.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2013-2015, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2013-2018, ARM Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -17,8 +17,8 @@
* Version number is a 32bit value, like:
* (PM_VERSION_MAJOR << 16) | PM_VERSION_MINOR
*/
-#define PM_VERSION_MAJOR 0
-#define PM_VERSION_MINOR 2
+#define PM_VERSION_MAJOR 1
+#define PM_VERSION_MINOR 0
#define PM_VERSION ((PM_VERSION_MAJOR << 16) | PM_VERSION_MINOR)
@@ -66,6 +66,28 @@
PM_FPGA_LOAD,
PM_FPGA_GET_STATUS,
PM_GET_CHIPID,
+ PM_SECURE_RSA_AES,
+ PM_SECURE_SHA,
+ PM_SECURE_RSA,
+ PM_PINCTRL_REQUEST,
+ PM_PINCTRL_RELEASE,
+ PM_PINCTRL_GET_FUNCTION,
+ PM_PINCTRL_SET_FUNCTION,
+ PM_PINCTRL_CONFIG_PARAM_GET,
+ PM_PINCTRL_CONFIG_PARAM_SET,
+ PM_IOCTL,
+ /* API to query information from firmware */
+ PM_QUERY_DATA,
+ /* Clock control API functions */
+ PM_CLOCK_ENABLE,
+ PM_CLOCK_DISABLE,
+ PM_CLOCK_GETSTATE,
+ PM_CLOCK_SETDIVIDER,
+ PM_CLOCK_GETDIVIDER,
+ PM_CLOCK_SETRATE,
+ PM_CLOCK_GETRATE,
+ PM_CLOCK_SETPARENT,
+ PM_CLOCK_GETPARENT,
PM_API_MAX
};
@@ -79,7 +101,7 @@
NODE_RPU,
NODE_RPU_0,
NODE_RPU_1,
- NODE_PL,
+ NODE_PLD,
NODE_FPD,
NODE_OCM_BANK_0,
NODE_OCM_BANK_1,
@@ -132,7 +154,23 @@
NODE_PCIE,
NODE_PCAP,
NODE_RTC,
- NODE_MAX
+ NODE_LPD,
+ NODE_VCU,
+ NODE_IPI_RPU_1,
+ NODE_IPI_PL_0,
+ NODE_IPI_PL_1,
+ NODE_IPI_PL_2,
+ NODE_IPI_PL_3,
+ NODE_PL,
+ NODE_GEM_TSU,
+ NODE_SWDT_0,
+ NODE_SWDT_1,
+ NODE_CSU,
+ NODE_PJTAG,
+ NODE_TRACE,
+ NODE_TESTSCAN,
+ NODE_PMU,
+ NODE_MAX,
};
enum pm_request_ack {
diff --git a/plat/xilinx/zynqmp/pm_service/pm_svc_main.c b/plat/xilinx/zynqmp/pm_service/pm_svc_main.c
index fb64bc5..34b3ad4 100644
--- a/plat/xilinx/zynqmp/pm_service/pm_svc_main.c
+++ b/plat/xilinx/zynqmp/pm_service/pm_svc_main.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2013-2017, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2013-2018, ARM Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -19,6 +19,7 @@
#include "pm_ipi.h"
#define PM_GET_CALLBACK_DATA 0xa01
+#define PM_GET_TRUSTZONE_VERSION 0xa03
/* 0 - UP, !0 - DOWN */
static int32_t pm_down = !0;
@@ -248,6 +249,118 @@
(uint64_t)result[2] | ((uint64_t)result[3] << 32));
}
+ case PM_PINCTRL_REQUEST:
+ ret = pm_pinctrl_request(pm_arg[0]);
+ SMC_RET1(handle, (uint64_t)ret);
+
+ case PM_PINCTRL_RELEASE:
+ ret = pm_pinctrl_release(pm_arg[0]);
+ SMC_RET1(handle, (uint64_t)ret);
+
+ case PM_PINCTRL_GET_FUNCTION:
+ {
+ uint32_t value = 0;
+
+ ret = pm_pinctrl_get_function(pm_arg[0], &value);
+ SMC_RET1(handle, (uint64_t)ret | ((uint64_t)value) << 32);
+ }
+
+ case PM_PINCTRL_SET_FUNCTION:
+ ret = pm_pinctrl_set_function(pm_arg[0], pm_arg[1]);
+ SMC_RET1(handle, (uint64_t)ret);
+
+ case PM_PINCTRL_CONFIG_PARAM_GET:
+ {
+ uint32_t value;
+
+ ret = pm_pinctrl_get_config(pm_arg[0], pm_arg[1], &value);
+ SMC_RET1(handle, (uint64_t)ret | ((uint64_t)value) << 32);
+ }
+
+ case PM_PINCTRL_CONFIG_PARAM_SET:
+ ret = pm_pinctrl_set_config(pm_arg[0], pm_arg[1], pm_arg[2]);
+ SMC_RET1(handle, (uint64_t)ret);
+
+ case PM_IOCTL:
+ {
+ uint32_t value;
+
+ ret = pm_ioctl(pm_arg[0], pm_arg[1], pm_arg[2],
+ pm_arg[3], &value);
+ SMC_RET1(handle, (uint64_t)ret | ((uint64_t)value) << 32);
+ }
+
+ case PM_QUERY_DATA:
+ {
+ uint32_t data[4] = { 0 };
+
+ ret = pm_query_data(pm_arg[0], pm_arg[1], pm_arg[2],
+ pm_arg[3], data);
+ SMC_RET2(handle, (uint64_t)data[0] | ((uint64_t)data[1] << 32),
+ (uint64_t)data[2] | ((uint64_t)data[3] << 32));
+ }
+
+ case PM_CLOCK_ENABLE:
+ ret = pm_clock_enable(pm_arg[0]);
+ SMC_RET1(handle, (uint64_t)ret);
+
+ case PM_CLOCK_DISABLE:
+ ret = pm_clock_disable(pm_arg[0]);
+ SMC_RET1(handle, (uint64_t)ret);
+
+ case PM_CLOCK_GETSTATE:
+ {
+ uint32_t value;
+
+ ret = pm_clock_getstate(pm_arg[0], &value);
+ SMC_RET1(handle, (uint64_t)ret | ((uint64_t)value) << 32);
+ }
+
+ case PM_CLOCK_SETDIVIDER:
+ ret = pm_clock_setdivider(pm_arg[0], pm_arg[1]);
+ SMC_RET1(handle, (uint64_t)ret);
+
+ case PM_CLOCK_GETDIVIDER:
+ {
+ uint32_t value;
+
+ ret = pm_clock_getdivider(pm_arg[0], &value);
+ SMC_RET1(handle, (uint64_t)ret | ((uint64_t)value) << 32);
+ }
+
+ case PM_CLOCK_SETRATE:
+ ret = pm_clock_setrate(pm_arg[0],
+ ((uint64_t)pm_arg[2]) << 32 | pm_arg[1]);
+
+ SMC_RET1(handle, (uint64_t)ret);
+
+ case PM_CLOCK_GETRATE:
+ {
+ uint64_t value;
+
+ ret = pm_clock_getrate(pm_arg[0], &value);
+ SMC_RET2(handle, (uint64_t)ret |
+ (((uint64_t)value & 0xFFFFFFFFU) << 32U),
+ (value >> 32U) & 0xFFFFFFFFU);
+
+ }
+
+ case PM_CLOCK_SETPARENT:
+ ret = pm_clock_setparent(pm_arg[0], pm_arg[1]);
+ SMC_RET1(handle, (uint64_t)ret);
+
+ case PM_CLOCK_GETPARENT:
+ {
+ uint32_t value;
+
+ ret = pm_clock_getparent(pm_arg[0], &value);
+ SMC_RET1(handle, (uint64_t)ret | ((uint64_t)value) << 32);
+ }
+
+ case PM_GET_TRUSTZONE_VERSION:
+ SMC_RET1(handle, (uint64_t)PM_RET_SUCCESS |
+ ((uint64_t)ZYNQMP_TZ_VERSION << 32));
+
default:
WARN("Unimplemented PM Service Call: 0x%x\n", smc_fid);
SMC_RET1(handle, SMC_UNK);
diff --git a/plat/xilinx/zynqmp/zynqmp_def.h b/plat/xilinx/zynqmp/zynqmp_def.h
index e90ad02..60df187 100644
--- a/plat/xilinx/zynqmp/zynqmp_def.h
+++ b/plat/xilinx/zynqmp/zynqmp_def.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2014-2016, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2014-2018, ARM Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -27,33 +27,36 @@
* ZYNQMP memory map related constants
******************************************************************************/
/* Aggregate of all devices in the first GB */
-#define DEVICE0_BASE 0xFF000000
-#define DEVICE0_SIZE 0x00E00000
-#define DEVICE1_BASE 0xF9000000
-#define DEVICE1_SIZE 0x00800000
+#define DEVICE0_BASE U(0xFF000000)
+#define DEVICE0_SIZE U(0x00E00000)
+#define DEVICE1_BASE U(0xF9000000)
+#define DEVICE1_SIZE U(0x00800000)
/* For cpu reset APU space here too 0xFE5F1000 CRF_APB*/
-#define CRF_APB_BASE 0xFD1A0000
-#define CRF_APB_SIZE 0x00600000
+#define CRF_APB_BASE U(0xFD1A0000)
+#define CRF_APB_SIZE U(0x00600000)
+#define CRF_APB_CLK_BASE U(0xFD1A0020)
/* CRF registers and bitfields */
#define CRF_APB_RST_FPD_APU (CRF_APB_BASE + 0X00000104)
-#define CRF_APB_RST_FPD_APU_ACPU_RESET (1 << 0)
-#define CRF_APB_RST_FPD_APU_ACPU_PWRON_RESET (1 << 10)
+#define CRF_APB_RST_FPD_APU_ACPU_RESET (U(1) << 0)
+#define CRF_APB_RST_FPD_APU_ACPU_PWRON_RESET (U(1) << 10)
/* CRL registers and bitfields */
-#define CRL_APB_BASE 0xFF5E0000
-#define CRL_APB_RPLL_CTRL (CRL_APB_BASE + 0x30)
+#define CRL_APB_BASE U(0xFF5E0000)
#define CRL_APB_BOOT_MODE_USER (CRL_APB_BASE + 0x200)
#define CRL_APB_RESET_CTRL (CRL_APB_BASE + 0x218)
+#define CRL_APB_RST_LPD_TOP (CRL_APB_BASE + 0x23C)
+#define CRL_APB_CLK_BASE U(0xFF5E0020)
-#define CRL_APB_RPLL_CTRL_BYPASS (1 << 3)
+#define CRL_APB_RPU_AMBA_RESET (U(1) << 2)
+#define CRL_APB_RPLL_CTRL_BYPASS (U(1) << 3)
-#define CRL_APB_RESET_CTRL_SOFT_RESET (1 << 4)
+#define CRL_APB_RESET_CTRL_SOFT_RESET (U(1) << 4)
-#define CRL_APB_BOOT_MODE_MASK (0xf << 0)
-#define ZYNQMP_BOOTMODE_JTAG 0
+#define CRL_APB_BOOT_MODE_MASK (U(0xf) << 0)
+#define ZYNQMP_BOOTMODE_JTAG U(0)
/* system counter registers and bitfields */
#define IOU_SCNTRS_BASE 0xFF260000
@@ -174,4 +177,138 @@
#define ACTLR_EL3_L2ACTLR_BIT (1 << 6)
#define ACTLR_EL3_CPUACTLR_BIT (1 << 0)
+#define IOU_SLCR_BASEADDR U(0xFF180000)
+
+#define ZYNQMP_RPU_GLBL_CNTL U(0xFF9A0000)
+#define ZYNQMP_RPU0_CFG U(0xFF9A0100)
+#define ZYNQMP_RPU1_CFG U(0xFF9A0200)
+#define ZYNQMP_SLSPLIT_MASK U(0x08)
+#define ZYNQMP_TCM_COMB_MASK U(0x40)
+#define ZYNQMP_SLCLAMP_MASK U(0x10)
+#define ZYNQMP_VINITHI_MASK U(0x04)
+
+/* Tap delay bypass */
+#define IOU_TAPDLY_BYPASS U(0XFF180390)
+#define TAP_DELAY_MASK U(0x7)
+
+/* SGMII mode */
+#define IOU_GEM_CTRL U(0xFF180360)
+#define IOU_GEM_CLK_CTRL U(0xFF180308)
+#define SGMII_SD_MASK U(0x3)
+#define SGMII_SD_OFFSET U(2)
+#define SGMII_PCS_SD_0 U(0x0)
+#define SGMII_PCS_SD_1 U(0x1)
+#define SGMII_PCS_SD_PHY U(0x2)
+#define GEM_SGMII_MASK U(0x4)
+#define GEM_CLK_CTRL_MASK U(0xF)
+#define GEM_CLK_CTRL_OFFSET U(5)
+#define GEM_RX_SRC_SEL_GTR U(0x1)
+#define GEM_SGMII_MODE U(0x4)
+
+/* SD DLL reset */
+#define ZYNQMP_SD_DLL_CTRL U(0xFF180358)
+#define ZYNQMP_SD0_DLL_RST_MASK U(0x00000004)
+#define ZYNQMP_SD0_DLL_RST U(0x00000004)
+#define ZYNQMP_SD1_DLL_RST_MASK U(0x00040000)
+#define ZYNQMP_SD1_DLL_RST U(0x00040000)
+
+/* SD tap delay */
+#define ZYNQMP_SD_DLL_CTRL U(0xFF180358)
+#define ZYNQMP_SD_ITAP_DLY U(0xFF180314)
+#define ZYNQMP_SD_OTAP_DLY U(0xFF180318)
+#define ZYNQMP_SD_TAP_OFFSET U(16)
+#define ZYNQMP_SD_ITAPCHGWIN_MASK U(0x200)
+#define ZYNQMP_SD_ITAPCHGWIN U(0x200)
+#define ZYNQMP_SD_ITAPDLYENA_MASK U(0x100)
+#define ZYNQMP_SD_ITAPDLYENA U(0x100)
+#define ZYNQMP_SD_ITAPDLYSEL_MASK U(0xFF)
+#define ZYNQMP_SD_OTAPDLYSEL_MASK U(0x3F)
+#define ZYNQMP_SD_OTAPDLYENA_MASK U(0x40)
+#define ZYNQMP_SD_OTAPDLYENA U(0x40)
+
+/* Clock control registers */
+/* Full power domain clocks */
+#define CRF_APB_APLL_CTRL (CRF_APB_CLK_BASE + 0x00)
+#define CRF_APB_DPLL_CTRL (CRF_APB_CLK_BASE + 0x0c)
+#define CRF_APB_VPLL_CTRL (CRF_APB_CLK_BASE + 0x18)
+#define CRF_APB_PLL_STATUS (CRF_APB_CLK_BASE + 0x24)
+#define CRF_APB_APLL_TO_LPD_CTRL (CRF_APB_CLK_BASE + 0x28)
+#define CRF_APB_DPLL_TO_LPD_CTRL (CRF_APB_CLK_BASE + 0x2c)
+#define CRF_APB_VPLL_TO_LPD_CTRL (CRF_APB_CLK_BASE + 0x30)
+/* Peripheral clocks */
+#define CRF_APB_ACPU_CTRL (CRF_APB_CLK_BASE + 0x40)
+#define CRF_APB_DBG_TRACE_CTRL (CRF_APB_CLK_BASE + 0x44)
+#define CRF_APB_DBG_FPD_CTRL (CRF_APB_CLK_BASE + 0x48)
+#define CRF_APB_DP_VIDEO_REF_CTRL (CRF_APB_CLK_BASE + 0x50)
+#define CRF_APB_DP_AUDIO_REF_CTRL (CRF_APB_CLK_BASE + 0x54)
+#define CRF_APB_DP_STC_REF_CTRL (CRF_APB_CLK_BASE + 0x5c)
+#define CRF_APB_DDR_CTRL (CRF_APB_CLK_BASE + 0x60)
+#define CRF_APB_GPU_REF_CTRL (CRF_APB_CLK_BASE + 0x64)
+#define CRF_APB_SATA_REF_CTRL (CRF_APB_CLK_BASE + 0x80)
+#define CRF_APB_PCIE_REF_CTRL (CRF_APB_CLK_BASE + 0x94)
+#define CRF_APB_GDMA_REF_CTRL (CRF_APB_CLK_BASE + 0x98)
+#define CRF_APB_DPDMA_REF_CTRL (CRF_APB_CLK_BASE + 0x9c)
+#define CRF_APB_TOPSW_MAIN_CTRL (CRF_APB_CLK_BASE + 0xa0)
+#define CRF_APB_TOPSW_LSBUS_CTRL (CRF_APB_CLK_BASE + 0xa4)
+#define CRF_APB_GTGREF0_REF_CTRL (CRF_APB_CLK_BASE + 0xa8)
+#define CRF_APB_DBG_TSTMP_CTRL (CRF_APB_CLK_BASE + 0xd8)
+
+/* Low power domain clocks */
+#define CRL_APB_IOPLL_CTRL (CRL_APB_CLK_BASE + 0x00)
+#define CRL_APB_RPLL_CTRL (CRL_APB_CLK_BASE + 0x10)
+#define CRL_APB_PLL_STATUS (CRL_APB_CLK_BASE + 0x20)
+#define CRL_APB_IOPLL_TO_FPD_CTRL (CRL_APB_CLK_BASE + 0x24)
+#define CRL_APB_RPLL_TO_FPD_CTRL (CRL_APB_CLK_BASE + 0x28)
+/* Peripheral clocks */
+#define CRL_APB_USB3_DUAL_REF_CTRL (CRL_APB_CLK_BASE + 0x2c)
+#define CRL_APB_GEM0_REF_CTRL (CRL_APB_CLK_BASE + 0x30)
+#define CRL_APB_GEM1_REF_CTRL (CRL_APB_CLK_BASE + 0x34)
+#define CRL_APB_GEM2_REF_CTRL (CRL_APB_CLK_BASE + 0x38)
+#define CRL_APB_GEM3_REF_CTRL (CRL_APB_CLK_BASE + 0x3c)
+#define CRL_APB_USB0_BUS_REF_CTRL (CRL_APB_CLK_BASE + 0x40)
+#define CRL_APB_USB1_BUS_REF_CTRL (CRL_APB_CLK_BASE + 0x44)
+#define CRL_APB_QSPI_REF_CTRL (CRL_APB_CLK_BASE + 0x48)
+#define CRL_APB_SDIO0_REF_CTRL (CRL_APB_CLK_BASE + 0x4c)
+#define CRL_APB_SDIO1_REF_CTRL (CRL_APB_CLK_BASE + 0x50)
+#define CRL_APB_UART0_REF_CTRL (CRL_APB_CLK_BASE + 0x54)
+#define CRL_APB_UART1_REF_CTRL (CRL_APB_CLK_BASE + 0x58)
+#define CRL_APB_SPI0_REF_CTRL (CRL_APB_CLK_BASE + 0x5c)
+#define CRL_APB_SPI1_REF_CTRL (CRL_APB_CLK_BASE + 0x60)
+#define CRL_APB_CAN0_REF_CTRL (CRL_APB_CLK_BASE + 0x64)
+#define CRL_APB_CAN1_REF_CTRL (CRL_APB_CLK_BASE + 0x68)
+#define CRL_APB_CPU_R5_CTRL (CRL_APB_CLK_BASE + 0x70)
+#define CRL_APB_IOU_SWITCH_CTRL (CRL_APB_CLK_BASE + 0x7c)
+#define CRL_APB_CSU_PLL_CTRL (CRL_APB_CLK_BASE + 0x80)
+#define CRL_APB_PCAP_CTRL (CRL_APB_CLK_BASE + 0x84)
+#define CRL_APB_LPD_SWITCH_CTRL (CRL_APB_CLK_BASE + 0x88)
+#define CRL_APB_LPD_LSBUS_CTRL (CRL_APB_CLK_BASE + 0x8c)
+#define CRL_APB_DBG_LPD_CTRL (CRL_APB_CLK_BASE + 0x90)
+#define CRL_APB_NAND_REF_CTRL (CRL_APB_CLK_BASE + 0x94)
+#define CRL_APB_ADMA_REF_CTRL (CRL_APB_CLK_BASE + 0x98)
+#define CRL_APB_PL0_REF_CTRL (CRL_APB_CLK_BASE + 0xa0)
+#define CRL_APB_PL1_REF_CTRL (CRL_APB_CLK_BASE + 0xa4)
+#define CRL_APB_PL2_REF_CTRL (CRL_APB_CLK_BASE + 0xa8)
+#define CRL_APB_PL3_REF_CTRL (CRL_APB_CLK_BASE + 0xac)
+#define CRL_APB_PL0_THR_CNT (CRL_APB_CLK_BASE + 0xb4)
+#define CRL_APB_PL1_THR_CNT (CRL_APB_CLK_BASE + 0xbc)
+#define CRL_APB_PL2_THR_CNT (CRL_APB_CLK_BASE + 0xc4)
+#define CRL_APB_PL3_THR_CNT (CRL_APB_CLK_BASE + 0xdc)
+#define CRL_APB_GEM_TSU_REF_CTRL (CRL_APB_CLK_BASE + 0xe0)
+#define CRL_APB_DLL_REF_CTRL (CRL_APB_CLK_BASE + 0xe4)
+#define CRL_APB_AMS_REF_CTRL (CRL_APB_CLK_BASE + 0xe8)
+#define CRL_APB_I2C0_REF_CTRL (CRL_APB_CLK_BASE + 0x100)
+#define CRL_APB_I2C1_REF_CTRL (CRL_APB_CLK_BASE + 0x104)
+#define CRL_APB_TIMESTAMP_REF_CTRL (CRL_APB_CLK_BASE + 0x108)
+#define IOU_SLCR_GEM_CLK_CTRL (IOU_SLCR_BASEADDR + 0x308)
+#define IOU_SLCR_CAN_MIO_CTRL (IOU_SLCR_BASEADDR + 0x304)
+#define IOU_SLCR_WDT_CLK_SEL (IOU_SLCR_BASEADDR + 0x300)
+
+/* Global general storage register base address */
+#define GGS_BASEADDR (0xFFD80030U)
+#define GGS_NUM_REGS U(4)
+
+/* Persistent global general storage register base address */
+#define PGGS_BASEADDR (0xFFD80050U)
+#define PGGS_NUM_REGS U(4)
+
#endif /* __ZYNQMP_DEF_H__ */
diff --git a/services/arm_arch_svc/arm_arch_svc_setup.c b/services/arm_arch_svc/arm_arch_svc_setup.c
index 83d3625..eb736c0 100644
--- a/services/arm_arch_svc/arm_arch_svc_setup.c
+++ b/services/arm_arch_svc/arm_arch_svc_setup.c
@@ -19,19 +19,16 @@
static int32_t smccc_arch_features(u_register_t arg)
{
- int ret;
-
switch (arg) {
case SMCCC_VERSION:
case SMCCC_ARCH_FEATURES:
return SMC_OK;
+#if WORKAROUND_CVE_2017_5715
case SMCCC_ARCH_WORKAROUND_1:
- ret = check_workaround_cve_2017_5715();
- if (ret == ERRATA_APPLIES)
- return 0;
- else if (ret == ERRATA_NOT_APPLIES)
+ if (check_workaround_cve_2017_5715() == ERRATA_NOT_APPLIES)
return 1;
- return -1; /* ERRATA_MISSING */
+ return 0; /* ERRATA_APPLIES || ERRATA_MISSING */
+#endif
default:
return SMC_UNK;
}
diff --git a/services/spd/tspd/tspd_private.h b/services/spd/tspd/tspd_private.h
index 8fadb7a..a63daff 100644
--- a/services/spd/tspd/tspd_private.h
+++ b/services/spd/tspd/tspd_private.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2013-2017, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2013-2018, ARM Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -206,7 +206,7 @@
/*******************************************************************************
* Forward declarations
******************************************************************************/
-struct tsp_vectors;
+typedef struct tsp_vectors tsp_vectors_t;
/*******************************************************************************
* Function & Data prototypes
@@ -215,14 +215,26 @@
void __dead2 tspd_exit_sp(uint64_t c_rt_ctx, uint64_t ret);
uint64_t tspd_synchronous_sp_entry(tsp_context_t *tsp_ctx);
void __dead2 tspd_synchronous_sp_exit(tsp_context_t *tsp_ctx, uint64_t ret);
-void tspd_init_tsp_ep_state(struct entry_point_info *tsp_ep,
+void tspd_init_tsp_ep_state(struct entry_point_info *tsp_entry_point,
uint32_t rw,
uint64_t pc,
tsp_context_t *tsp_ctx);
int tspd_abort_preempted_smc(tsp_context_t *tsp_ctx);
+uint64_t tspd_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);
+
+int32_t tspd_setup(void);
+uint64_t tspd_handle_sp_preemption(void *handle);
+
extern tsp_context_t tspd_sp_context[TSPD_CORE_COUNT];
-extern struct tsp_vectors *tsp_vectors;
+extern tsp_vectors_t *tsp_vectors;
#endif /*__ASSEMBLY__*/
#endif /* __TSPD_PRIVATE_H__ */
diff --git a/services/std_svc/spm/spm_main.c b/services/std_svc/spm/spm_main.c
index 6c4e1f0..e0fe494 100644
--- a/services/std_svc/spm/spm_main.c
+++ b/services/std_svc/spm/spm_main.c
@@ -35,7 +35,7 @@
* Replace the S-EL1 re-entry information with S-EL0 re-entry
* information
******************************************************************************/
-void spm_setup_next_eret_into_sel0(cpu_context_t *secure_context)
+static void spm_setup_next_eret_into_sel0(const cpu_context_t *secure_context)
{
assert(secure_context == cm_get_context(SECURE));
@@ -83,14 +83,14 @@
* as the generic smc entry routine should have saved those.
******************************************************************************/
static void __dead2 spm_synchronous_sp_exit(
- secure_partition_context_t *sp_ctx_ptr, uint64_t ret)
+ const secure_partition_context_t *sp_ctx_ptr, uint64_t ret)
{
assert(sp_ctx_ptr != NULL);
/* Save the Secure EL1 system register context */
assert(cm_get_context(SECURE) == &sp_ctx_ptr->cpu_ctx);
cm_el1_sysregs_context_save(SECURE);
- assert(sp_ctx_ptr->c_rt_ctx != 0);
+ assert(sp_ctx_ptr->c_rt_ctx != 0U);
spm_secure_partition_exit(sp_ctx_ptr->c_rt_ctx, ret);
/* Should never reach here */
@@ -104,7 +104,7 @@
* used. This function performs a synchronous entry into the Secure partition.
* The SP passes control back to this routine through a SMC.
******************************************************************************/
-int32_t spm_init(void)
+static int32_t spm_init(void)
{
entry_point_info_t *secure_partition_ep_info;
uint64_t rc;
@@ -116,7 +116,7 @@
* absence is a critical failure.
*/
secure_partition_ep_info = bl31_plat_get_next_image_ep_info(SECURE);
- assert(secure_partition_ep_info);
+ assert(secure_partition_ep_info != NULL);
/*
* Initialise the common context and then overlay the S-EL0 specific
@@ -155,15 +155,15 @@
{
uint32_t ep_attr;
- assert(sp_ep_info);
- assert(pc);
- assert(sp_ctx_ptr);
+ assert(sp_ep_info != NULL);
+ assert(pc != 0U);
+ assert(sp_ctx_ptr != NULL);
cm_set_context(&sp_ctx_ptr->cpu_ctx, SECURE);
/* initialise an entrypoint to set up the CPU context */
ep_attr = SECURE | EP_ST_ENABLE;
- if (read_sctlr_el3() & SCTLR_EE_BIT)
+ if ((read_sctlr_el3() & SCTLR_EE_BIT) != 0U)
ep_attr |= EP_EE_BIG;
SET_PARAM_HEAD(sp_ep_info, PARAM_EP, VERSION_1, ep_attr);
@@ -192,7 +192,7 @@
* absence is a critical failure.
*/
secure_partition_ep_info = bl31_plat_get_next_image_ep_info(SECURE);
- if (!secure_partition_ep_info) {
+ if (secure_partition_ep_info == NULL) {
WARN("No SPM provided by BL2 boot loader, Booting device"
" without SPM initialization. SMCs destined for SPM"
" will return SMC_UNK\n");
@@ -204,7 +204,7 @@
* signalling failure initializing the service. We bail out without
* registering any handlers
*/
- if (!secure_partition_ep_info->pc) {
+ if (secure_partition_ep_info->pc == 0U) {
return 1;
}
@@ -231,9 +231,9 @@
* The other fields are left as 0 because they are ignored by the function
* change_mem_attributes().
*/
-static mmap_attr_t smc_attr_to_mmap_attr(unsigned int attributes)
+static unsigned int smc_attr_to_mmap_attr(unsigned int attributes)
{
- mmap_attr_t tf_attr = 0;
+ unsigned int tf_attr = 0U;
unsigned int access = (attributes & SP_MEMORY_ATTRIBUTES_ACCESS_MASK)
>> SP_MEMORY_ATTRIBUTES_ACCESS_SHIFT;
@@ -262,11 +262,11 @@
* This function converts attributes from the Trusted Firmware format into the
* SMC interface format.
*/
-static int smc_mmap_to_smc_attr(mmap_attr_t attr)
+static unsigned int smc_mmap_to_smc_attr(unsigned int attr)
{
- int smc_attr = 0;
+ unsigned int smc_attr = 0U;
- int data_access;
+ unsigned int data_access;
if ((attr & MT_USER) == 0) {
/* No access from EL0. */
@@ -283,28 +283,29 @@
smc_attr |= (data_access & SP_MEMORY_ATTRIBUTES_ACCESS_MASK)
<< SP_MEMORY_ATTRIBUTES_ACCESS_SHIFT;
- if (attr & MT_EXECUTE_NEVER) {
+ if ((attr & MT_EXECUTE_NEVER) != 0U) {
smc_attr |= SP_MEMORY_ATTRIBUTES_NON_EXEC;
}
return smc_attr;
}
-static int spm_memory_attributes_get_smc_handler(uintptr_t base_va)
+static int32_t spm_memory_attributes_get_smc_handler(uintptr_t base_va)
{
+ uint32_t attributes;
+
spin_lock(&mem_attr_smc_lock);
- mmap_attr_t attributes;
int rc = get_mem_attributes(secure_partition_xlat_ctx_handle,
base_va, &attributes);
spin_unlock(&mem_attr_smc_lock);
/* Convert error codes of get_mem_attributes() into SPM ones. */
- assert(rc == 0 || rc == -EINVAL);
+ assert((rc == 0) || (rc == -EINVAL));
if (rc == 0) {
- return smc_mmap_to_smc_attr(attributes);
+ return (int32_t) smc_mmap_to_smc_attr(attributes);
} else {
return SPM_INVALID_PARAMETER;
}
@@ -316,7 +317,7 @@
{
uintptr_t base_va = (uintptr_t) page_address;
size_t size = (size_t) (pages_count * PAGE_SIZE);
- unsigned int attributes = (unsigned int) smc_attributes;
+ uint32_t attributes = (uint32_t) smc_attributes;
INFO(" Start address : 0x%lx\n", base_va);
INFO(" Number of pages: %i (%zi bytes)\n", (int) pages_count, size);
@@ -330,7 +331,7 @@
spin_unlock(&mem_attr_smc_lock);
/* Convert error codes of change_mem_attributes() into SPM ones. */
- assert(ret == 0 || ret == -EINVAL);
+ assert((ret == 0) || (ret == -EINVAL));
return (ret == 0) ? SPM_SUCCESS : SPM_INVALID_PARAMETER;
}
@@ -389,7 +390,7 @@
/* Get a reference to the non-secure context */
ns_cpu_context = cm_get_context(NON_SECURE);
- assert(ns_cpu_context);
+ assert(ns_cpu_context != NULL);
/* Restore non-secure state */
cm_el1_sysregs_context_restore(NON_SECURE);
@@ -435,17 +436,17 @@
uint64_t comm_size_address = x3;
/* Cookie. Reserved for future use. It must be zero. */
- if (mm_cookie != 0) {
+ if (mm_cookie != 0U) {
ERROR("MM_COMMUNICATE: cookie is not zero\n");
SMC_RET1(handle, SPM_INVALID_PARAMETER);
}
- if (comm_buffer_address == 0) {
+ if (comm_buffer_address == 0U) {
ERROR("MM_COMMUNICATE: comm_buffer_address is zero\n");
SMC_RET1(handle, SPM_INVALID_PARAMETER);
}
- if (comm_size_address != 0) {
+ if (comm_size_address != 0U) {
VERBOSE("MM_COMMUNICATE: comm_size_address is not 0 as recommended.\n");
}