Merge "fix(imx): disable DRAM retention by default on i.MX8MQ" into integration
diff --git a/docs/about/release-information.rst b/docs/about/release-information.rst
index a5fd1d6..7fafe03 100644
--- a/docs/about/release-information.rst
+++ b/docs/about/release-information.rst
@@ -83,7 +83,7 @@
| | Date | after | |
| | | Release | |
+================================+=============+=========+=========================================================+
-| STM32MP15_OPTEE_RSV_SHM | 2.10 | 3.0 | OP-TEE manages its own memory on STM32MP15 |
+| | | | |
+--------------------------------+-------------+---------+---------------------------------------------------------+
Removal of Deprecated Drivers
diff --git a/docs/components/granule-protection-tables-design.rst b/docs/components/granule-protection-tables-design.rst
index 9d85bef..78d2f12 100644
--- a/docs/components/granule-protection-tables-design.rst
+++ b/docs/components/granule-protection-tables-design.rst
@@ -1,17 +1,17 @@
Granule Protection Tables Library
=================================
-This document describes the design of the granule protection tables (GPT)
+This document describes the design of the Granule Protection Tables (GPT)
library used by Trusted Firmware-A (TF-A). This library provides the APIs needed
to initialize the GPTs based on a data structure containing information about
the systems memory layout, configure the system registers to enable granule
protection checks based on these tables, and transition granules between
different PAS (physical address spaces) at runtime.
-Arm CCA adds two new security states for a total of four: root, realm, secure, and
-non-secure. In addition to new security states, corresponding physical address
-spaces have been added to control memory access for each state. The PAS access
-allowed to each security state can be seen in the table below.
+Arm CCA adds two new security states for a total of four: root, realm, secure,
+and non-secure. In addition to new security states, corresponding physical
+address spaces have been added to control memory access for each state. The PAS
+access allowed to each security state can be seen in the table below.
.. list-table:: Security states and PAS access rights
:widths: 25 25 25 25 25
@@ -45,12 +45,15 @@
The GPT can function as either a 1 level or 2 level lookup depending on how a
PAS region is configured. The first step is the level 0 table, each entry in the
-level 0 table controls access to a relatively large region in memory (block
+level 0 table controls access to a relatively large region in memory (GPT Block
descriptor), and the entire region can belong to a single PAS when a one step
-mapping is used, or a level 0 entry can link to a level 1 table where relatively
-small regions (granules) of memory can be assigned to different PAS with a 2
-step mapping. The type of mapping used for each PAS is determined by the user
-when setting up the configuration structure.
+mapping is used. Level 0 entry can also link to a level 1 table (GPT Table
+descriptor) with a 2 step mapping. To change PAS of a region dynamically, the
+region must be mapped in Level 1 table.
+
+The Level 1 tables entries with the same PAS can be combined to form a
+contiguous block entry using GPT Contiguous descriptor. More details about this
+is explained in the following section.
Design Concepts and Interfaces
------------------------------
@@ -73,7 +76,8 @@
GPT setup is split into two parts: table creation and runtime initialization. In
the table creation step, a data structure containing information about the
desired PAS regions is passed into the library which validates the mappings,
-creates the tables in memory, and enables granule protection checks. In the
+creates the tables in memory, and enables granule protection checks. It also
+allocates memory for fine-grained locks adjacent to the L0 tables. In the
runtime initialization step, the runtime firmware locates the existing tables in
memory using the GPT register configuration and saves important data to a
structure used by the granule transition service which will be covered more
@@ -85,6 +89,10 @@
runtime initialization API calls can be seen in
``plat/arm/common/arm_bl31_setup.c``.
+During the table creation time, the GPT lib opportunistically fuses contiguous
+GPT L1 entries having the same PAS. The maximum size of
+supported contiguous blocks is defined by ``RME_GPT_MAX_BLOCK`` build option.
+
Defining PAS regions
~~~~~~~~~~~~~~~~~~~~
@@ -115,8 +123,13 @@
~~~~~~~~~~~~~~~~~~~~~~~~~~
The GPT initialization APIs require memory to be passed in for the tables to be
-constructed, ``gpt_init_l0_tables`` takes a memory address and size for building
-the level 0 tables and ``gpt_init_pas_l1_tables`` takes an address and size for
+constructed. The ``gpt_init_l0_tables`` API takes a memory address and size for
+building the level 0 tables and also memory for allocating the fine-grained bitlock
+data structure. The amount of memory needed for bitlock structure is controlled via
+``RME_GPT_BITLOCK_BLOCK`` config which defines the block size for each bit of the
+the bitlock.
+
+The ``gpt_init_pas_l1_tables`` API takes an address and size for
building the level 1 tables which are linked from level 0 descriptors. The
tables should have PAS type ``GPT_GPI_ROOT`` and a typical system might place
its level 0 table in SRAM and its level 1 table(s) in DRAM.
@@ -124,12 +137,28 @@
Granule Transition Service
~~~~~~~~~~~~~~~~~~~~~~~~~~
-The Granule Transition Service allows memory mapped with GPT_MAP_REGION_GRANULE
-ownership to be changed using SMC calls. Non-secure granules can be transitioned
-to either realm or secure space, and realm and secure granules can be
-transitioned back to non-secure. This library only allows memory mapped as
-granules to be transitioned, memory mapped as blocks have their GPIs fixed after
-table creation.
+The Granule Transition Service allows memory mapped with
+``GPT_MAP_REGION_GRANULE`` ownership to be changed using SMC calls. Non-secure
+granules can be transitioned to either realm or secure space, and realm and
+secure granules can be transitioned back to non-secure. This library only
+allows Level 1 entries to be transitioned. The lib may either shatter
+contiguous blocks or fuse adjacent GPT entries to form a contiguous block
+opportunistically. Depending on the maximum block size, the fuse operation may
+propogate to higher block sizes as allowed by RME Architecture. Thus a higher
+maximum block size may have a higher runtime cost due to software operations
+that need to be performed for fuse to bigger block sizes. This cost may
+be offset by better TLB performance due to the higher block size and platforms
+need to make the trade-off decision based on their particular workload.
+
+Locking Scheme
+~~~~~~~~~~~~~~
+
+During Granule Transition access to L1 tables is controlled by a lock to ensure
+that no more than one CPU is allowed to make changes at any given time.
+The granularity of the lock is defined by ``RME_GPT_BITLOCK_BLOCK`` build option
+which defines the size of the memory block protected by one bit of ``bitlock``
+structure. Setting this option to 0 chooses a single spinlock for all GPT L1
+table entries.
Library APIs
------------
@@ -196,7 +225,9 @@
is greater. L0 table size is the total protected space (PPS) divided by the
size of each L0 region (L0GPTSZ) multiplied by the size of each L0 descriptor
(8 bytes). ((PPS / L0GPTSZ) * 8)
-* The L0 memory size must be greater than or equal to the table size.
+* The L0 memory size must be greater than the table size and have enough space
+ to allocate array of ``bitlock`` structures at the end of L0 table if
+ required (``RME_GPT_BITLOCK_BLOCK`` is not 0).
* The L0 memory must fall within a PAS of type GPT_GPI_ROOT.
The L1 memory also has some constraints.
@@ -223,6 +254,24 @@
And solve to get 32 bytes. In this case, 4096 is greater than 32, so the L0
tables must be aligned to 4096 bytes.
+Sample calculation for bitlock array size
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Let PGS=GPCCR_PPS_256TB and RME_GPT_BITLOCK_BLOCK=1
+
+The size of bit lock array in bits is the total protected space (PPS) divided
+by the size of memory block per bit. The size of memory block
+is ``RME_GPT_BITLOCK_BLOCK`` (number of 512MB blocks per bit) times
+512MB (0x20000000). This is then divided by the number of bits in ``bitlock``
+structure (8) to get the size of bit array in bytes.
+
+In other words, we can find the total size of ``bitlock`` array
+in bytes with PPS / (RME_GPT_BITLOCK_BLOCK * 0x20000000 * 8).
+
+Substitute values to get this: 0x1000000000000 / (1 * 0x20000000 * 8)
+
+And solve to get 0x10000 bytes.
+
Sample calculation for L1 table size and alignment
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
diff --git a/docs/plat/rockchip.rst b/docs/plat/rockchip.rst
index 01cf176..53f63b5 100644
--- a/docs/plat/rockchip.rst
+++ b/docs/plat/rockchip.rst
@@ -10,6 +10,7 @@
- rk3328: Quad-Core Cortex-A53
- rk3368: Octa-Core Cortex-A53
- rk3399: Hexa-Core Cortex-A53/A72
+- rk3566/rk3568: Quad-Core Cortex-A55
Boot Sequence
diff --git a/fdts/fvp-foundation-gicv2-psci.dts b/fdts/fvp-foundation-gicv2-psci.dts
index 5a82c46..653c75f 100644
--- a/fdts/fvp-foundation-gicv2-psci.dts
+++ b/fdts/fvp-foundation-gicv2-psci.dts
@@ -26,7 +26,9 @@
#address-cells = <2>;
#size-cells = <2>;
- chosen { };
+ chosen {
+ stdout-path = "serial0:115200n8";
+ };
aliases {
serial0 = &v2m_serial0;
diff --git a/fdts/fvp-foundation-gicv3-psci.dts b/fdts/fvp-foundation-gicv3-psci.dts
index e1249d4..2827297 100644
--- a/fdts/fvp-foundation-gicv3-psci.dts
+++ b/fdts/fvp-foundation-gicv3-psci.dts
@@ -26,7 +26,9 @@
#address-cells = <2>;
#size-cells = <2>;
- chosen { };
+ chosen {
+ stdout-path = "serial0:115200n8";
+ };
aliases {
serial0 = &v2m_serial0;
diff --git a/fdts/stm32mp15-fw-config.dtsi b/fdts/stm32mp15-fw-config.dtsi
index d583672..6f478d4 100644
--- a/fdts/stm32mp15-fw-config.dtsi
+++ b/fdts/stm32mp15-fw-config.dtsi
@@ -1,6 +1,6 @@
// SPDX-License-Identifier: (GPL-2.0+ OR BSD-3-Clause)
/*
- * Copyright (c) 2021-2022, STMicroelectronics - All Rights Reserved
+ * Copyright (c) 2021-2024, STMicroelectronics - All Rights Reserved
*/
#include <common/tbbr/tbbr_img_def.h>
@@ -14,12 +14,9 @@
#define DDR_NS_BASE STM32MP_DDR_BASE
#ifdef AARCH32_SP_OPTEE
-/* OP-TEE reserved shared memory: located at DDR top or null size */
-#define DDR_SHARE_SIZE STM32MP_DDR_SHMEM_SIZE
-#define DDR_SHARE_BASE (STM32MP_DDR_BASE + (DDR_SIZE - DDR_SHARE_SIZE))
-/* OP-TEE secure memory: located right below OP-TEE reserved shared memory */
+/* OP-TEE secure memory: located at DDR top */
#define DDR_SEC_SIZE STM32MP_DDR_S_SIZE
-#define DDR_SEC_BASE (DDR_SHARE_BASE - DDR_SEC_SIZE)
+#define DDR_SEC_BASE (STM32MP_DDR_BASE + (DDR_SIZE - DDR_SEC_SIZE))
#define DDR_NS_SIZE (DDR_SEC_BASE - DDR_NS_BASE)
#else /* !AARCH32_SP_OPTEE */
#define DDR_NS_SIZE DDR_SIZE
@@ -70,10 +67,6 @@
memory-ranges = <
DDR_NS_BASE DDR_NS_SIZE TZC_REGION_S_NONE TZC_REGION_NSEC_ALL_ACCESS_RDWR
DDR_SEC_BASE DDR_SEC_SIZE TZC_REGION_S_RDWR 0
-#if STM32MP15_OPTEE_RSV_SHM
- DDR_SHARE_BASE DDR_SHARE_SIZE TZC_REGION_S_NONE
- TZC_REGION_ACCESS_RDWR(STM32MP1_TZC_A7_ID)
-#endif
>;
#else
memory-ranges = <
diff --git a/fdts/tc-base.dtsi b/fdts/tc-base.dtsi
index e32d215..494c825 100644
--- a/fdts/tc-base.dtsi
+++ b/fdts/tc-base.dtsi
@@ -278,37 +278,35 @@
#size-cells = <1>;
ranges = <0 0x0 PLAT_ARM_NSRAM_BASE PLAT_ARM_NSRAM_SIZE>;
- cpu_scp_scmi_mem: scp-shmem@0 {
+ cpu_scp_scmi_a2p: scp-shmem@0 {
compatible = "arm,scmi-shmem";
reg = <0x0 0x80>;
};
};
mbox_db_rx: mhu@MHU_RX_ADDR {
- compatible = "arm,mhuv2-rx","arm,primecell";
- reg = <0x0 ADDRESSIFY(MHU_RX_ADDR) 0x0 0x1000>;
+ compatible = MHU_RX_COMPAT;
+ reg = <0x0 ADDRESSIFY(MHU_RX_ADDR) 0x0 MHU_OFFSET>;
clocks = <&soc_refclk>;
clock-names = "apb_pclk";
- #mbox-cells = <2>;
- interrupts = <GIC_SPI INT_MBOX_RX IRQ_TYPE_LEVEL_HIGH>;
- interrupt-names = "mhu_rx";
+ #mbox-cells = <MHU_MBOX_CELLS>;
+ interrupts = <GIC_SPI MHU_RX_INT_NUM IRQ_TYPE_LEVEL_HIGH>;
+ interrupt-names = MHU_RX_INT_NAME;
};
mbox_db_tx: mhu@MHU_TX_ADDR {
- compatible = "arm,mhuv2-tx","arm,primecell";
- reg = <0x0 ADDRESSIFY(MHU_TX_ADDR) 0x0 0x1000>;
+ compatible = MHU_TX_COMPAT;
+ reg = <0x0 ADDRESSIFY(MHU_TX_ADDR) 0x0 MHU_OFFSET>;
clocks = <&soc_refclk>;
clock-names = "apb_pclk";
- #mbox-cells = <2>;
- interrupt-names = "mhu_tx";
+ #mbox-cells = <MHU_MBOX_CELLS>;
+ interrupt-names = MHU_TX_INT_NAME;
};
firmware {
scmi {
compatible = "arm,scmi";
mbox-names = "tx", "rx";
- mboxes = <&mbox_db_tx 0 0 &mbox_db_rx 0 0 >;
- shmem = <&cpu_scp_scmi_mem &cpu_scp_scmi_mem>;
#address-cells = <1>;
#size-cells = <0>;
@@ -487,6 +485,14 @@
#if TC_IOMMU_EN
iommus = <&smmu_700 0x200>;
#endif /* TC_IOMMU_EN */
+ pbha {
+ int-id-override = <0 0x22>, <2 0x23>, <4 0x23>, <7 0x22>,
+ <8 0x22>, <9 0x22>, <10 0x22>, <11 0x22>,
+ <12 0x22>, <13 0x22>, <16 0x22>, <17 0x32>,
+ <18 0x32>, <19 0x22>, <20 0x22>, <21 0x32>,
+ <22 0x32>, <24 0x22>, <28 0x32>;
+ propagate-bits = <0x0f>;
+ };
};
power_model_simple {
diff --git a/fdts/tc-fvp.dtsi b/fdts/tc-fvp.dtsi
index 46b0e81..9f3a9ac 100644
--- a/fdts/tc-fvp.dtsi
+++ b/fdts/tc-fvp.dtsi
@@ -7,6 +7,23 @@
#define GIC_CTRL_ADDR 2c010000
#define GIC_GICR_OFFSET 0x200000
#define UART_OFFSET 0x1000
+
+#ifdef TC_RESOLUTION_1920X1080P60
+
+#define VENCODER_TIMING_CLK 148500000
+#define VENCODER_TIMING \
+ clock-frequency = <VENCODER_TIMING_CLK>; \
+ hactive = <1920>; \
+ vactive = <1080>; \
+ hfront-porch = <88>; \
+ hback-porch = <148>; \
+ hsync-len = <44>; \
+ vfront-porch = <4>; \
+ vback-porch = <36>; \
+ vsync-len = <5>
+
+#else /* TC_RESOLUTION_640X480P60 */
+
#define VENCODER_TIMING_CLK 25175000
#define VENCODER_TIMING \
clock-frequency = <VENCODER_TIMING_CLK>; \
@@ -19,6 +36,8 @@
vback-porch = <33>; \
vsync-len = <2>
+#endif
+
/ {
chosen {
stdout-path = "serial0:115200n8";
diff --git a/fdts/tc2.dts b/fdts/tc2.dts
index 288b40f..69c6886 100644
--- a/fdts/tc2.dts
+++ b/fdts/tc2.dts
@@ -20,9 +20,17 @@
#endif /* TARGET_FLAVOUR_FPGA */
#define BIG_CAPACITY 1024
-#define INT_MBOX_RX 317
#define MHU_TX_ADDR 45000000 /* hex */
+#define MHU_TX_COMPAT "arm,mhuv2-tx","arm,primecell"
+#define MHU_TX_INT_NAME "mhu_tx"
+
#define MHU_RX_ADDR 45010000 /* hex */
+#define MHU_RX_COMPAT "arm,mhuv2-rx","arm,primecell"
+#define MHU_OFFSET 0x1000
+#define MHU_MBOX_CELLS 2
+#define MHU_RX_INT_NUM 317
+#define MHU_RX_INT_NAME "mhu_rx"
+
#define MPAM_ADDR 0x1 0x00010000 /* 0x1_0001_0000 */
#define UARTCLK_FREQ 5000000
@@ -211,6 +219,24 @@
arm,mhuv2-protocols = <0 1>;
};
+ firmware {
+ /*
+ * TC2 does not have a P2A channel, but wiring one was needed to make Linux work
+ * (by chance). At the time the SCMI driver did not support bidirectional
+ * mailboxes so as a workaround, the A2P channel was wired for TX communication
+ * and the synchronous replies would be read asyncrhonously as if coming from
+ * the P2A channel, while being the actual A2P channel.
+ *
+ * This will not work with kernels > 5.15, but keep it around to keep TC2
+ * working with its target kernel. Newer kernels will still work, but SCMI
+ * won't as they check that the two regions are distinct.
+ */
+ scmi {
+ mboxes = <&mbox_db_tx 0 0 &mbox_db_rx 0 0>;
+ shmem = <&cpu_scp_scmi_a2p &cpu_scp_scmi_a2p>;
+ };
+ };
+
dp0: display@DPU_ADDR {
#if TC_SCMI_PD_CTRL_EN
power-domains = <&scmi_devpd (PLAT_MAX_CPUS_PER_CLUSTER + 2)>;
diff --git a/fdts/tc3.dts b/fdts/tc3.dts
index 52b0856..fe6a695 100644
--- a/fdts/tc3.dts
+++ b/fdts/tc3.dts
@@ -14,9 +14,17 @@
#define MID_CAPACITY 686
#define BIG_CAPACITY 1024
-#define INT_MBOX_RX 300
#define MHU_TX_ADDR 46040000 /* hex */
+#define MHU_TX_COMPAT "arm,mhuv3"
+#define MHU_TX_INT_NAME ""
+
#define MHU_RX_ADDR 46140000 /* hex */
+#define MHU_RX_COMPAT "arm,mhuv3"
+#define MHU_OFFSET 0x10000
+#define MHU_MBOX_CELLS 3
+#define MHU_RX_INT_NUM 300
+#define MHU_RX_INT_NAME "combined-mbx"
+
#define MPAM_ADDR 0x0 0x5f010000 /* 0x5f01_0000 */
#define UARTCLK_FREQ 3750000
@@ -63,4 +71,18 @@
interrupt-affinity = <&CPU0>, <&CPU1>, <&CPU2>, <&CPU3>,
<&CPU4>, <&CPU5>, <&CPU6>, <&CPU7>;
};
+
+ sram: sram@6000000 {
+ cpu_scp_scmi_p2a: scp-shmem@80 {
+ compatible = "arm,scmi-shmem";
+ reg = <0x80 0x80>;
+ };
+ };
+
+ firmware {
+ scmi {
+ mboxes = <&mbox_db_tx 0 0 0 &mbox_db_rx 0 0 0 &mbox_db_rx 0 0 1>;
+ shmem = <&cpu_scp_scmi_a2p &cpu_scp_scmi_p2a>;
+ };
+ };
};
diff --git a/include/drivers/arm/css/css_mhu_doorbell.h b/include/drivers/arm/css/css_mhu_doorbell.h
index 88302fd..d6c1a2a 100644
--- a/include/drivers/arm/css/css_mhu_doorbell.h
+++ b/include/drivers/arm/css/css_mhu_doorbell.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2014-2020, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2014-2024, Arm Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -22,6 +22,10 @@
#define SENDER_REG_STAT(_channel) (0x20 * (_channel))
#define SENDER_REG_SET(_channel) ((0x20 * (_channel)) + 0xC)
+#define MHU_V3_PBX_PDBCW_PAGE_OFFSET UL(0x1000)
+#define MHU_V3_SENDER_REG_SET(_channel) (MHU_V3_PBX_PDBCW_PAGE_OFFSET + \
+ SENDER_REG_SET(_channel))
+
/* Helper macro to ring doorbell */
#define MHU_RING_DOORBELL(addr, modify_mask, preserve_mask) do { \
uint32_t db = mmio_read_32(addr) & (preserve_mask); \
diff --git a/include/lib/cpus/aarch64/cortex_a725.h b/include/lib/cpus/aarch64/cortex_a725.h
new file mode 100644
index 0000000..123c5ab
--- /dev/null
+++ b/include/lib/cpus/aarch64/cortex_a725.h
@@ -0,0 +1,23 @@
+/*
+ * Copyright (c) 2023-2024, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef CORTEX_A725_H
+#define CORTEX_A725_H
+
+#define CORTEX_A725_MIDR U(0x410FD870)
+
+/*******************************************************************************
+ * CPU Extended Control register specific definitions
+ ******************************************************************************/
+#define CORTEX_A725_CPUECTLR_EL1 S3_0_C15_C1_4
+
+/*******************************************************************************
+ * CPU Power Control register specific definitions
+ ******************************************************************************/
+#define CORTEX_A725_CPUPWRCTLR_EL1 S3_0_C15_C2_7
+#define CORTEX_A725_CPUPWRCTLR_EL1_CORE_PWRDN_BIT U(1)
+
+#endif /* CORTEX_A725_H */
diff --git a/include/lib/cpus/aarch64/cortex_blackhawk.h b/include/lib/cpus/aarch64/cortex_blackhawk.h
deleted file mode 100644
index bfb3039..0000000
--- a/include/lib/cpus/aarch64/cortex_blackhawk.h
+++ /dev/null
@@ -1,23 +0,0 @@
-/*
- * Copyright (c) 2023, Arm Limited. All rights reserved.
- *
- * SPDX-License-Identifier: BSD-3-Clause
- */
-
-#ifndef CORTEX_BLACKHAWK_H
-#define CORTEX_BLACKHAWK_H
-
-#define CORTEX_BLACKHAWK_MIDR U(0x410FD850)
-
-/*******************************************************************************
- * CPU Extended Control register specific definitions
- ******************************************************************************/
-#define CORTEX_BLACKHAWK_CPUECTLR_EL1 S3_0_C15_C1_4
-
-/*******************************************************************************
- * CPU Power Control register specific definitions
- ******************************************************************************/
-#define CORTEX_BLACKHAWK_CPUPWRCTLR_EL1 S3_0_C15_C2_7
-#define CORTEX_BLACKHAWK_CPUPWRCTLR_EL1_CORE_PWRDN_BIT U(1)
-
-#endif /* CORTEX_BLACKHAWK_H */
diff --git a/include/lib/cpus/aarch64/cortex_chaberton.h b/include/lib/cpus/aarch64/cortex_chaberton.h
deleted file mode 100644
index 8f10b68..0000000
--- a/include/lib/cpus/aarch64/cortex_chaberton.h
+++ /dev/null
@@ -1,23 +0,0 @@
-/*
- * Copyright (c) 2023, Arm Limited. All rights reserved.
- *
- * SPDX-License-Identifier: BSD-3-Clause
- */
-
-#ifndef CORTEX_CHABERTON_H
-#define CORTEX_CHABERTON_H
-
-#define CORTEX_CHABERTON_MIDR U(0x410FD870)
-
-/*******************************************************************************
- * CPU Extended Control register specific definitions
- ******************************************************************************/
-#define CORTEX_CHABERTON_CPUECTLR_EL1 S3_0_C15_C1_4
-
-/*******************************************************************************
- * CPU Power Control register specific definitions
- ******************************************************************************/
-#define CORTEX_CHABERTON_CPUPWRCTLR_EL1 S3_0_C15_C2_7
-#define CORTEX_CHABERTON_CPUPWRCTLR_EL1_CORE_PWRDN_BIT U(1)
-
-#endif /* CORTEX_CHABERTON_H */
diff --git a/include/lib/cpus/aarch64/cortex_x925.h b/include/lib/cpus/aarch64/cortex_x925.h
new file mode 100644
index 0000000..38aafcf
--- /dev/null
+++ b/include/lib/cpus/aarch64/cortex_x925.h
@@ -0,0 +1,23 @@
+/*
+ * Copyright (c) 2023-2024, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef CORTEX_X925_H
+#define CORTEX_X925_H
+
+#define CORTEX_X925_MIDR U(0x410FD850)
+
+/*******************************************************************************
+ * CPU Extended Control register specific definitions
+ ******************************************************************************/
+#define CORTEX_X925_CPUECTLR_EL1 S3_0_C15_C1_4
+
+/*******************************************************************************
+ * CPU Power Control register specific definitions
+ ******************************************************************************/
+#define CORTEX_X925_CPUPWRCTLR_EL1 S3_0_C15_C2_7
+#define CORTEX_X925_CPUPWRCTLR_EL1_CORE_PWRDN_BIT U(1)
+
+#endif /* CORTEX_X925_H */
diff --git a/include/lib/cpus/aarch64/dsu_def.h b/include/lib/cpus/aarch64/dsu_def.h
index 577de61..51fbfd1 100644
--- a/include/lib/cpus/aarch64/dsu_def.h
+++ b/include/lib/cpus/aarch64/dsu_def.h
@@ -30,6 +30,7 @@
* DSU Cluster Auxiliary Control registers definitions
********************************************************************/
#define CLUSTERACTLR_EL1 S3_0_C15_C3_3
+#define CLUSTERPWRCTLR_EL1 S3_0_C15_C3_5
#define CLUSTERACTLR_EL1_DISABLE_CLOCK_GATING (ULL(1) << 15)
#define CLUSTERACTLR_EL1_DISABLE_SCLK_GATING (ULL(3) << 15)
@@ -39,4 +40,7 @@
********************************************************************/
#define DSU_ERRATA_936184_MASK (U(0x3) << 15)
+#ifndef __ASSEMBLER__
+void dsu_pwr_dwn(void);
+#endif
#endif /* DSU_DEF_H */
diff --git a/include/lib/el3_runtime/aarch64/context.h b/include/lib/el3_runtime/aarch64/context.h
index 4f11ad2..6f97bed 100644
--- a/include/lib/el3_runtime/aarch64/context.h
+++ b/include/lib/el3_runtime/aarch64/context.h
@@ -299,27 +299,6 @@
#endif /* CTX_INCLUDE_PAUTH_REGS */
/*******************************************************************************
- * Registers related to ARMv8.2-MPAM.
- ******************************************************************************/
-#define CTX_MPAM_REGS_OFFSET (CTX_PAUTH_REGS_OFFSET + CTX_PAUTH_REGS_END)
-#if CTX_INCLUDE_MPAM_REGS
-#define CTX_MPAM2_EL2 U(0x0)
-#define CTX_MPAMHCR_EL2 U(0x8)
-#define CTX_MPAMVPM0_EL2 U(0x10)
-#define CTX_MPAMVPM1_EL2 U(0x18)
-#define CTX_MPAMVPM2_EL2 U(0x20)
-#define CTX_MPAMVPM3_EL2 U(0x28)
-#define CTX_MPAMVPM4_EL2 U(0x30)
-#define CTX_MPAMVPM5_EL2 U(0x38)
-#define CTX_MPAMVPM6_EL2 U(0x40)
-#define CTX_MPAMVPM7_EL2 U(0x48)
-#define CTX_MPAMVPMV_EL2 U(0x50)
-#define CTX_MPAM_REGS_END U(0x60)
-#else
-#define CTX_MPAM_REGS_END U(0x0)
-#endif /* CTX_INCLUDE_MPAM_REGS */
-
-/*******************************************************************************
* Registers initialised in a per-world context.
******************************************************************************/
#define CTX_CPTR_EL3 U(0x0)
@@ -355,9 +334,6 @@
#if CTX_INCLUDE_PAUTH_REGS
# define CTX_PAUTH_REGS_ALL (CTX_PAUTH_REGS_END >> DWORD_SHIFT)
#endif
-#if CTX_INCLUDE_MPAM_REGS
-# define CTX_MPAM_REGS_ALL (CTX_MPAM_REGS_END >> DWORD_SHIFT)
-#endif
/*
* AArch64 general purpose register context structure. Usually x0-x18,
@@ -397,11 +373,6 @@
DEFINE_REG_STRUCT(pauth, CTX_PAUTH_REGS_ALL);
#endif
-/* Registers associated to ARMv8.2 MPAM */
-#if CTX_INCLUDE_MPAM_REGS
-DEFINE_REG_STRUCT(mpam, CTX_MPAM_REGS_ALL);
-#endif
-
/*
* Macros to access members of any of the above structures using their
* offsets
@@ -432,10 +403,6 @@
pauth_t pauth_ctx;
#endif
-#if CTX_INCLUDE_MPAM_REGS
- mpam_t mpam_ctx;
-#endif
-
#if CTX_INCLUDE_EL2_REGS
el2_sysregs_t el2_sysregs_ctx;
#endif
@@ -468,9 +435,6 @@
#if CTX_INCLUDE_PAUTH_REGS
# define get_pauth_ctx(h) (&((cpu_context_t *) h)->pauth_ctx)
#endif
-#if CTX_INCLUDE_MPAM_REGS
-# define get_mpam_ctx(h) (&((cpu_context_t *) h)->mpam_ctx)
-#endif
/*
* Compile time assertions related to the 'cpu_context' structure to
@@ -499,11 +463,6 @@
assert_core_context_pauth_offset_mismatch);
#endif /* CTX_INCLUDE_PAUTH_REGS */
-#if CTX_INCLUDE_MPAM_REGS
-CASSERT(CTX_MPAM_REGS_OFFSET == __builtin_offsetof(cpu_context_t, mpam_ctx),
- assert_core_context_mpam_offset_mismatch);
-#endif /* CTX_INCLUDE_MPAM_REGS */
-
/*
* Helper macro to set the general purpose registers that correspond to
* parameters in an aapcs_64 call i.e. x0-x7
diff --git a/include/lib/el3_runtime/context_el2.h b/include/lib/el3_runtime/context_el2.h
index 04f6587..d25ab81 100644
--- a/include/lib/el3_runtime/context_el2.h
+++ b/include/lib/el3_runtime/context_el2.h
@@ -114,6 +114,20 @@
uint64_t gcspr_el2;
} el2_gcs_regs_t;
+typedef struct el2_mpam_regs {
+ uint64_t mpam2_el2;
+ uint64_t mpamhcr_el2;
+ uint64_t mpamvpm0_el2;
+ uint64_t mpamvpm1_el2;
+ uint64_t mpamvpm2_el2;
+ uint64_t mpamvpm3_el2;
+ uint64_t mpamvpm4_el2;
+ uint64_t mpamvpm5_el2;
+ uint64_t mpamvpm6_el2;
+ uint64_t mpamvpm7_el2;
+ uint64_t mpamvpmv_el2;
+} el2_mpam_regs_t;
+
typedef struct el2_sysregs {
el2_common_regs_t common;
@@ -174,6 +188,10 @@
el2_gcs_regs_t gcs;
#endif
+#if CTX_INCLUDE_MPAM_REGS
+ el2_mpam_regs_t mpam;
+#endif
+
} el2_sysregs_t;
/*
@@ -311,6 +329,15 @@
#define write_el2_ctx_gcs(ctx, reg, val)
#endif /* ENABLE_FEAT_GCS */
+#if CTX_INCLUDE_MPAM_REGS
+#define read_el2_ctx_mpam(ctx, reg) (((ctx)->mpam).reg)
+#define write_el2_ctx_mpam(ctx, reg, val) ((((ctx)->mpam).reg) \
+ = (uint64_t) (val))
+#else
+#define read_el2_ctx_mpam(ctx, reg) ULL(0)
+#define write_el2_ctx_mpam(ctx, reg, val)
+#endif /* CTX_INCLUDE_MPAM_REGS */
+
#endif /* CTX_INCLUDE_EL2_REGS */
/******************************************************************************/
diff --git a/include/plat/nuvoton/npcm845x/platform_def.h b/include/plat/nuvoton/npcm845x/platform_def.h
index 9cbf839..c70ef22 100644
--- a/include/plat/nuvoton/npcm845x/platform_def.h
+++ b/include/plat/nuvoton/npcm845x/platform_def.h
@@ -157,7 +157,8 @@
/* MMU entry for internal (register) space access */
#define MAP_DEVICE0 \
- MAP_REGION_FLAT(PLAT_REG_BASE, PLAT_REG_SIZE, MT_DEVICE | MT_RW | MT_NS)
+ MAP_REGION_FLAT(PLAT_REG_BASE, PLAT_REG_SIZE, \
+ MT_DEVICE | MT_RW | MT_SECURE)
#define MAP_DEVICE1 \
MAP_REGION_FLAT(DEVICE1_BASE, DEVICE1_SIZE, \
diff --git a/lib/cpus/aarch64/cortex_a725.S b/lib/cpus/aarch64/cortex_a725.S
new file mode 100644
index 0000000..c08945f
--- /dev/null
+++ b/lib/cpus/aarch64/cortex_a725.S
@@ -0,0 +1,66 @@
+/*
+ * Copyright (c) 2023-2024, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <arch.h>
+#include <asm_macros.S>
+#include <common/bl_common.h>
+#include <cortex_a725.h>
+#include <cpu_macros.S>
+#include <plat_macros.S>
+
+/* Hardware handled coherency */
+#if HW_ASSISTED_COHERENCY == 0
+#error "Cortex-A725 must be compiled with HW_ASSISTED_COHERENCY enabled"
+#endif
+
+/* 64-bit only core */
+#if CTX_INCLUDE_AARCH32_REGS == 1
+#error "Cortex-A725 supports only AArch64. Compile with CTX_INCLUDE_AARCH32_REGS=0"
+#endif
+
+cpu_reset_func_start cortex_a725
+ /* Disable speculative loads */
+ msr SSBS, xzr
+cpu_reset_func_end cortex_a725
+
+ /* ----------------------------------------------------
+ * HW will do the cache maintenance while powering down
+ * ----------------------------------------------------
+ */
+func cortex_a725_core_pwr_dwn
+ /* ---------------------------------------------------
+ * Enable CPU power down bit in power control register
+ * ---------------------------------------------------
+ */
+ sysreg_bit_set CORTEX_A725_CPUPWRCTLR_EL1, CORTEX_A725_CPUPWRCTLR_EL1_CORE_PWRDN_BIT
+ isb
+ ret
+endfunc cortex_a725_core_pwr_dwn
+
+errata_report_shim cortex_a725
+
+ /* ---------------------------------------------
+ * This function provides Cortex-A725 specific
+ * register information for crash reporting.
+ * It needs to return with x6 pointing to
+ * a list of register names in ascii and
+ * x8 - x15 having values of registers to be
+ * reported.
+ * ---------------------------------------------
+ */
+.section .rodata.cortex_a725_regs, "aS"
+cortex_a725_regs: /* The ascii list of register names to be reported */
+ .asciz "cpuectlr_el1", ""
+
+func cortex_a725_cpu_reg_dump
+ adr x6, cortex_a725_regs
+ mrs x8, CORTEX_A725_CPUECTLR_EL1
+ ret
+endfunc cortex_a725_cpu_reg_dump
+
+declare_cpu_ops cortex_a725, CORTEX_A725_MIDR, \
+ cortex_a725_reset_func, \
+ cortex_a725_core_pwr_dwn
diff --git a/lib/cpus/aarch64/cortex_blackhawk.S b/lib/cpus/aarch64/cortex_blackhawk.S
deleted file mode 100644
index b7b7a2d..0000000
--- a/lib/cpus/aarch64/cortex_blackhawk.S
+++ /dev/null
@@ -1,66 +0,0 @@
-/*
- * Copyright (c) 2023, Arm Limited. All rights reserved.
- *
- * SPDX-License-Identifier: BSD-3-Clause
- */
-
-#include <arch.h>
-#include <asm_macros.S>
-#include <common/bl_common.h>
-#include <cortex_blackhawk.h>
-#include <cpu_macros.S>
-#include <plat_macros.S>
-
-/* Hardware handled coherency */
-#if HW_ASSISTED_COHERENCY == 0
-#error "Cortex blackhawk must be compiled with HW_ASSISTED_COHERENCY enabled"
-#endif
-
-/* 64-bit only core */
-#if CTX_INCLUDE_AARCH32_REGS == 1
-#error "Cortex blackhawk supports only AArch64. Compile with CTX_INCLUDE_AARCH32_REGS=0"
-#endif
-
-cpu_reset_func_start cortex_blackhawk
- /* Disable speculative loads */
- msr SSBS, xzr
-cpu_reset_func_end cortex_blackhawk
-
- /* ----------------------------------------------------
- * HW will do the cache maintenance while powering down
- * ----------------------------------------------------
- */
-func cortex_blackhawk_core_pwr_dwn
- /* ---------------------------------------------------
- * Enable CPU power down bit in power control register
- * ---------------------------------------------------
- */
- sysreg_bit_set CORTEX_BLACKHAWK_CPUPWRCTLR_EL1, CORTEX_BLACKHAWK_CPUPWRCTLR_EL1_CORE_PWRDN_BIT
- isb
- ret
-endfunc cortex_blackhawk_core_pwr_dwn
-
-errata_report_shim cortex_blackhawk
-
- /* ---------------------------------------------
- * This function provides Cortex Blackhawk specific
- * register information for crash reporting.
- * It needs to return with x6 pointing to
- * a list of register names in ascii and
- * x8 - x15 having values of registers to be
- * reported.
- * ---------------------------------------------
- */
-.section .rodata.cortex_blackhawk_regs, "aS"
-cortex_blackhawk_regs: /* The ascii list of register names to be reported */
- .asciz "cpuectlr_el1", ""
-
-func cortex_blackhawk_cpu_reg_dump
- adr x6, cortex_blackhawk_regs
- mrs x8, CORTEX_BLACKHAWK_CPUECTLR_EL1
- ret
-endfunc cortex_blackhawk_cpu_reg_dump
-
-declare_cpu_ops cortex_blackhawk, CORTEX_BLACKHAWK_MIDR, \
- cortex_blackhawk_reset_func, \
- cortex_blackhawk_core_pwr_dwn
diff --git a/lib/cpus/aarch64/cortex_chaberton.S b/lib/cpus/aarch64/cortex_chaberton.S
deleted file mode 100644
index 596fe4a..0000000
--- a/lib/cpus/aarch64/cortex_chaberton.S
+++ /dev/null
@@ -1,66 +0,0 @@
-/*
- * Copyright (c) 2023, Arm Limited. All rights reserved.
- *
- * SPDX-License-Identifier: BSD-3-Clause
- */
-
-#include <arch.h>
-#include <asm_macros.S>
-#include <common/bl_common.h>
-#include <cortex_chaberton.h>
-#include <cpu_macros.S>
-#include <plat_macros.S>
-
-/* Hardware handled coherency */
-#if HW_ASSISTED_COHERENCY == 0
-#error "Cortex Chaberton must be compiled with HW_ASSISTED_COHERENCY enabled"
-#endif
-
-/* 64-bit only core */
-#if CTX_INCLUDE_AARCH32_REGS == 1
-#error "Cortex Chaberton supports only AArch64. Compile with CTX_INCLUDE_AARCH32_REGS=0"
-#endif
-
-cpu_reset_func_start cortex_chaberton
- /* Disable speculative loads */
- msr SSBS, xzr
-cpu_reset_func_end cortex_chaberton
-
- /* ----------------------------------------------------
- * HW will do the cache maintenance while powering down
- * ----------------------------------------------------
- */
-func cortex_chaberton_core_pwr_dwn
- /* ---------------------------------------------------
- * Enable CPU power down bit in power control register
- * ---------------------------------------------------
- */
- sysreg_bit_set CORTEX_CHABERTON_CPUPWRCTLR_EL1, CORTEX_CHABERTON_CPUPWRCTLR_EL1_CORE_PWRDN_BIT
- isb
- ret
-endfunc cortex_chaberton_core_pwr_dwn
-
-errata_report_shim cortex_chaberton
-
- /* ---------------------------------------------
- * This function provides Cortex Chaberton specific
- * register information for crash reporting.
- * It needs to return with x6 pointing to
- * a list of register names in ascii and
- * x8 - x15 having values of registers to be
- * reported.
- * ---------------------------------------------
- */
-.section .rodata.cortex_chaberton_regs, "aS"
-cortex_chaberton_regs: /* The ascii list of register names to be reported */
- .asciz "cpuectlr_el1", ""
-
-func cortex_chaberton_cpu_reg_dump
- adr x6, cortex_chaberton_regs
- mrs x8, CORTEX_CHABERTON_CPUECTLR_EL1
- ret
-endfunc cortex_chaberton_cpu_reg_dump
-
-declare_cpu_ops cortex_chaberton, CORTEX_CHABERTON_MIDR, \
- cortex_chaberton_reset_func, \
- cortex_chaberton_core_pwr_dwn
diff --git a/lib/cpus/aarch64/cortex_x925.S b/lib/cpus/aarch64/cortex_x925.S
new file mode 100644
index 0000000..36b442e
--- /dev/null
+++ b/lib/cpus/aarch64/cortex_x925.S
@@ -0,0 +1,66 @@
+/*
+ * Copyright (c) 2023-2024, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <arch.h>
+#include <asm_macros.S>
+#include <common/bl_common.h>
+#include <cortex_x925.h>
+#include <cpu_macros.S>
+#include <plat_macros.S>
+
+/* Hardware handled coherency */
+#if HW_ASSISTED_COHERENCY == 0
+#error "Cortex-X925 must be compiled with HW_ASSISTED_COHERENCY enabled"
+#endif
+
+/* 64-bit only core */
+#if CTX_INCLUDE_AARCH32_REGS == 1
+#error "Cortex-X925 supports only AArch64. Compile with CTX_INCLUDE_AARCH32_REGS=0"
+#endif
+
+cpu_reset_func_start cortex_x925
+ /* Disable speculative loads */
+ msr SSBS, xzr
+cpu_reset_func_end cortex_x925
+
+ /* ----------------------------------------------------
+ * HW will do the cache maintenance while powering down
+ * ----------------------------------------------------
+ */
+func cortex_x925_core_pwr_dwn
+ /* ---------------------------------------------------
+ * Enable CPU power down bit in power control register
+ * ---------------------------------------------------
+ */
+ sysreg_bit_set CORTEX_X925_CPUPWRCTLR_EL1, CORTEX_X925_CPUPWRCTLR_EL1_CORE_PWRDN_BIT
+ isb
+ ret
+endfunc cortex_x925_core_pwr_dwn
+
+errata_report_shim cortex_x925
+
+ /* ---------------------------------------------
+ * This function provides Cortex-X925 specific
+ * register information for crash reporting.
+ * It needs to return with x6 pointing to
+ * a list of register names in ascii and
+ * x8 - x15 having values of registers to be
+ * reported.
+ * ---------------------------------------------
+ */
+.section .rodata.cortex_x925_regs, "aS"
+cortex_x925_regs: /* The ascii list of register names to be reported */
+ .asciz "cpuectlr_el1", ""
+
+func cortex_x925_cpu_reg_dump
+ adr x6, cortex_x925_regs
+ mrs x8, CORTEX_X925_CPUECTLR_EL1
+ ret
+endfunc cortex_x925_cpu_reg_dump
+
+declare_cpu_ops cortex_x925, CORTEX_X925_MIDR, \
+ cortex_x925_reset_func, \
+ cortex_x925_core_pwr_dwn
diff --git a/lib/cpus/aarch64/dsu_helpers.S b/lib/cpus/aarch64/dsu_helpers.S
index 8e5b459..3c5bf2e 100644
--- a/lib/cpus/aarch64/dsu_helpers.S
+++ b/lib/cpus/aarch64/dsu_helpers.S
@@ -24,6 +24,7 @@
*/
.globl check_errata_dsu_798953
.globl errata_dsu_798953_wa
+ .globl dsu_pwr_dwn
func check_errata_dsu_798953
mov x2, #ERRATA_APPLIES
@@ -202,3 +203,15 @@
1:
ret x8
endfunc errata_dsu_2313941_wa
+
+ /* ---------------------------------------------
+ * controls power features of the cluster
+ * 1. Cache portion power not request
+ * 2. Disable the retention circuit
+ * ---------------------------------------------
+ */
+func dsu_pwr_dwn
+ msr CLUSTERPWRCTLR_EL1, xzr
+ isb
+ ret
+endfunc dsu_pwr_dwn
diff --git a/lib/el3_runtime/aarch64/context_mgmt.c b/lib/el3_runtime/aarch64/context_mgmt.c
index 35c98f5..1937c30 100644
--- a/lib/el3_runtime/aarch64/context_mgmt.c
+++ b/lib/el3_runtime/aarch64/context_mgmt.c
@@ -1046,13 +1046,11 @@
write_hfgwtr_el2(read_el2_ctx_fgt(ctx, hfgwtr_el2));
}
-#if CTX_INCLUDE_MPAM_REGS
-
-static void el2_sysregs_context_save_mpam(mpam_t *ctx)
+static void el2_sysregs_context_save_mpam(el2_sysregs_t *ctx)
{
u_register_t mpam_idr = read_mpamidr_el1();
- write_ctx_reg(ctx, CTX_MPAM2_EL2, read_mpam2_el2());
+ write_el2_ctx_mpam(ctx, mpam2_el2, read_mpam2_el2());
/*
* The context registers that we intend to save would be part of the
@@ -1066,9 +1064,9 @@
* MPAMHCR_EL2, MPAMVPMV_EL2 and MPAMVPM0_EL2 are always present if
* MPAMIDR_HAS_HCR_BIT == 1.
*/
- write_ctx_reg(ctx, CTX_MPAMHCR_EL2, read_mpamhcr_el2());
- write_ctx_reg(ctx, CTX_MPAMVPM0_EL2, read_mpamvpm0_el2());
- write_ctx_reg(ctx, CTX_MPAMVPMV_EL2, read_mpamvpmv_el2());
+ write_el2_ctx_mpam(ctx, mpamhcr_el2, read_mpamhcr_el2());
+ write_el2_ctx_mpam(ctx, mpamvpm0_el2, read_mpamvpm0_el2());
+ write_el2_ctx_mpam(ctx, mpamvpmv_el2, read_mpamvpmv_el2());
/*
* The number of MPAMVPM registers is implementation defined, their
@@ -1076,71 +1074,67 @@
*/
switch ((mpam_idr >> MPAMIDR_EL1_VPMR_MAX_SHIFT) & MPAMIDR_EL1_VPMR_MAX_MASK) {
case 7:
- write_ctx_reg(ctx, CTX_MPAMVPM7_EL2, read_mpamvpm7_el2());
+ write_el2_ctx_mpam(ctx, mpamvpm7_el2, read_mpamvpm7_el2());
__fallthrough;
case 6:
- write_ctx_reg(ctx, CTX_MPAMVPM6_EL2, read_mpamvpm6_el2());
+ write_el2_ctx_mpam(ctx, mpamvpm6_el2, read_mpamvpm6_el2());
__fallthrough;
case 5:
- write_ctx_reg(ctx, CTX_MPAMVPM5_EL2, read_mpamvpm5_el2());
+ write_el2_ctx_mpam(ctx, mpamvpm5_el2, read_mpamvpm5_el2());
__fallthrough;
case 4:
- write_ctx_reg(ctx, CTX_MPAMVPM4_EL2, read_mpamvpm4_el2());
+ write_el2_ctx_mpam(ctx, mpamvpm4_el2, read_mpamvpm4_el2());
__fallthrough;
case 3:
- write_ctx_reg(ctx, CTX_MPAMVPM3_EL2, read_mpamvpm3_el2());
+ write_el2_ctx_mpam(ctx, mpamvpm3_el2, read_mpamvpm3_el2());
__fallthrough;
case 2:
- write_ctx_reg(ctx, CTX_MPAMVPM2_EL2, read_mpamvpm2_el2());
+ write_el2_ctx_mpam(ctx, mpamvpm2_el2, read_mpamvpm2_el2());
__fallthrough;
case 1:
- write_ctx_reg(ctx, CTX_MPAMVPM1_EL2, read_mpamvpm1_el2());
+ write_el2_ctx_mpam(ctx, mpamvpm1_el2, read_mpamvpm1_el2());
break;
}
}
-#endif /* CTX_INCLUDE_MPAM_REGS */
-
-#if CTX_INCLUDE_MPAM_REGS
-static void el2_sysregs_context_restore_mpam(mpam_t *ctx)
+static void el2_sysregs_context_restore_mpam(el2_sysregs_t *ctx)
{
u_register_t mpam_idr = read_mpamidr_el1();
- write_mpam2_el2(read_ctx_reg(ctx, CTX_MPAM2_EL2));
+ write_mpam2_el2(read_el2_ctx_mpam(ctx, mpam2_el2));
if ((mpam_idr & MPAMIDR_HAS_HCR_BIT) == 0U) {
return;
}
- write_mpamhcr_el2(read_ctx_reg(ctx, CTX_MPAMHCR_EL2));
- write_mpamvpm0_el2(read_ctx_reg(ctx, CTX_MPAMVPM0_EL2));
- write_mpamvpmv_el2(read_ctx_reg(ctx, CTX_MPAMVPMV_EL2));
+ write_mpamhcr_el2(read_el2_ctx_mpam(ctx, mpamhcr_el2));
+ write_mpamvpm0_el2(read_el2_ctx_mpam(ctx, mpamvpm0_el2));
+ write_mpamvpmv_el2(read_el2_ctx_mpam(ctx, mpamvpmv_el2));
switch ((mpam_idr >> MPAMIDR_EL1_VPMR_MAX_SHIFT) & MPAMIDR_EL1_VPMR_MAX_MASK) {
case 7:
- write_mpamvpm7_el2(read_ctx_reg(ctx, CTX_MPAMVPM7_EL2));
+ write_mpamvpm7_el2(read_el2_ctx_mpam(ctx, mpamvpm7_el2));
__fallthrough;
case 6:
- write_mpamvpm6_el2(read_ctx_reg(ctx, CTX_MPAMVPM6_EL2));
+ write_mpamvpm6_el2(read_el2_ctx_mpam(ctx, mpamvpm6_el2));
__fallthrough;
case 5:
- write_mpamvpm5_el2(read_ctx_reg(ctx, CTX_MPAMVPM5_EL2));
+ write_mpamvpm5_el2(read_el2_ctx_mpam(ctx, mpamvpm5_el2));
__fallthrough;
case 4:
- write_mpamvpm4_el2(read_ctx_reg(ctx, CTX_MPAMVPM4_EL2));
+ write_mpamvpm4_el2(read_el2_ctx_mpam(ctx, mpamvpm4_el2));
__fallthrough;
case 3:
- write_mpamvpm3_el2(read_ctx_reg(ctx, CTX_MPAMVPM3_EL2));
+ write_mpamvpm3_el2(read_el2_ctx_mpam(ctx, mpamvpm3_el2));
__fallthrough;
case 2:
- write_mpamvpm2_el2(read_ctx_reg(ctx, CTX_MPAMVPM2_EL2));
+ write_mpamvpm2_el2(read_el2_ctx_mpam(ctx, mpamvpm2_el2));
__fallthrough;
case 1:
- write_mpamvpm1_el2(read_ctx_reg(ctx, CTX_MPAMVPM1_EL2));
+ write_mpamvpm1_el2(read_el2_ctx_mpam(ctx, mpamvpm1_el2));
break;
}
}
-#endif /* CTX_INCLUDE_MPAM_REGS */
/* ---------------------------------------------------------------------------
* The following registers are not added:
@@ -1283,12 +1277,9 @@
write_el2_ctx_mte2(el2_sysregs_ctx, tfsr_el2, read_tfsr_el2());
}
-#if CTX_INCLUDE_MPAM_REGS
if (is_feat_mpam_supported()) {
- mpam_t *mpam_ctx = get_mpam_ctx(ctx);
- el2_sysregs_context_save_mpam(mpam_ctx);
+ el2_sysregs_context_save_mpam(el2_sysregs_ctx);
}
-#endif
if (is_feat_fgt_supported()) {
el2_sysregs_context_save_fgt(el2_sysregs_ctx);
@@ -1369,12 +1360,9 @@
write_tfsr_el2(read_el2_ctx_mte2(el2_sysregs_ctx, tfsr_el2));
}
-#if CTX_INCLUDE_MPAM_REGS
if (is_feat_mpam_supported()) {
- mpam_t *mpam_ctx = get_mpam_ctx(ctx);
- el2_sysregs_context_restore_mpam(mpam_ctx);
+ el2_sysregs_context_restore_mpam(el2_sysregs_ctx);
}
-#endif
if (is_feat_fgt_supported()) {
el2_sysregs_context_restore_fgt(el2_sysregs_ctx);
diff --git a/lib/gpt_rme/gpt_rme.c b/lib/gpt_rme/gpt_rme.c
index 4d80373..ee502de 100644
--- a/lib/gpt_rme/gpt_rme.c
+++ b/lib/gpt_rme/gpt_rme.c
@@ -700,8 +700,8 @@
* Return
* Address of next granule in range.
*/
-static uintptr_t fill_l1_cont_desc(uint64_t *l1, uintptr_t first,
- size_t length, unsigned int gpi)
+__unused static uintptr_t fill_l1_cont_desc(uint64_t *l1, uintptr_t first,
+ size_t length, unsigned int gpi)
{
/*
* Look up table for contiguous blocks and descriptors.
@@ -826,8 +826,10 @@
/*
* Helper function to fill out GPI entries in a single L1 table.
- * This function fills out an entire L1 table with either Contiguous
- * or Granules descriptors depending on region length and alignment.
+ * This function fills out an entire L1 table with either Granules or Contiguous
+ * (RME_GPT_MAX_BLOCK != 0) descriptors depending on region length and alignment.
+ * Note. If RME_GPT_MAX_BLOCK == 0, then the L1 tables are filled with regular
+ * Granules descriptors.
*
* Parameters
* l1 Pointer to L1 table to fill out
@@ -844,13 +846,14 @@
assert((last & (GPT_PGS_ACTUAL_SIZE(gpt_config.p) - 1UL)) == 0UL);
assert(GPT_L0_IDX(first) == GPT_L0_IDX(last));
+#if (RME_GPT_MAX_BLOCK != 0)
while (first < last) {
/* Region length */
size_t length = last - first + GPT_PGS_ACTUAL_SIZE(gpt_config.p);
if (length < SZ_2M) {
/*
- * Fill with Granule descriptor in case of
+ * Fill with Granule descriptors in case of
* region length < 2MB.
*/
first = fill_l1_gran_desc(l1, first, last, gpi);
@@ -874,7 +877,10 @@
first = fill_l1_gran_desc(l1, first, new_last, gpi);
}
}
-
+#else
+ /* Fill with Granule descriptors */
+ first = fill_l1_gran_desc(l1, first, last, gpi);
+#endif
assert(first == (last + GPT_PGS_ACTUAL_SIZE(gpt_config.p)));
}
diff --git a/lib/romlib/Makefile b/lib/romlib/Makefile
index 1293f06..da3d3d5 100644
--- a/lib/romlib/Makefile
+++ b/lib/romlib/Makefile
@@ -23,8 +23,10 @@
MAPFILE = $(BUILD_PLAT)/romlib/romlib.map
ifneq ($(PLAT_DIR),)
- WRAPPER_SOURCES = $(shell $(ROMLIB_GEN) genwrappers -b $(WRAPPER_DIR) --list ../../$(PLAT_DIR)/jmptbl.i)
- WRAPPER_OBJS = $(WRAPPER_SOURCES:.s=.o)
+ WRAPPER_SOURCES = $(sort $(shell $(ROMLIB_GEN) genwrappers -b $\
+ $(WRAPPER_DIR) --list ../../$(PLAT_DIR)/jmptbl.i))
+
+ WRAPPER_OBJS = $(WRAPPER_SOURCES:.s=.o)
endif
V ?= 0
@@ -82,14 +84,11 @@
@echo " PRE $@"
$(Q)$(ROMLIB_GEN) pre --output $@ --deps $(BUILD_DIR)/jmptbl.d $<
-$(BUILD_DIR)/wrappers.stamp: $(BUILD_DIR)/jmptbl.i
+$(WRAPPER_SOURCES) &: $(BUILD_DIR)/jmptbl.i
@echo " WRP $<"
$(Q)$(ROMLIB_GEN) genwrappers --bti=$(ENABLE_BTI) -b $(WRAPPER_DIR) $<
- @touch $@
-
-$(WRAPPER_SOURCES): $(BUILD_DIR)/wrappers.stamp
-$(WRAPPER_OBJS): $(WRAPPER_SOURCES) $(BUILD_DIR)/wrappers.stamp
+$(WRAPPER_OBJS): $(WRAPPER_DIR)/%.o: $(WRAPPER_DIR)/%.s
$(BUILD_DIR)/jmptbl.s: $(BUILD_DIR)/jmptbl.i
@echo " TBL $@"
diff --git a/make_helpers/build_macros.mk b/make_helpers/build_macros.mk
index cf4595c..fabd74e 100644
--- a/make_helpers/build_macros.mk
+++ b/make_helpers/build_macros.mk
@@ -559,8 +559,8 @@
$$(ECHO) " LD $$@"
ifeq ($($(ARCH)-ld-id),arm-link)
$$(Q)$($(ARCH)-ld) -o $$@ $$(TF_LDFLAGS) $$(LDFLAGS) $(BL_LDFLAGS) --entry=${1}_entrypoint \
- --predefine="-D__LINKER__=$(__LINKER__)" \
- --predefine="-DTF_CFLAGS=$(TF_CFLAGS)" \
+ --predefine=$(call escape-shell,-D__LINKER__=$(__LINKER__)) \
+ --predefine=$(call escape-shell,-DTF_CFLAGS=$(TF_CFLAGS)) \
--map --list="$(MAPFILE)" --scatter=${PLAT_DIR}/scat/${1}.scat \
$(LDPATHS) $(LIBWRAPPER) $(LDLIBS) $(BL_LIBS) $(OBJS)
else ifeq ($($(ARCH)-ld-id),gnu-gcc)
diff --git a/plat/arm/board/arm_fpga/platform.mk b/plat/arm/board/arm_fpga/platform.mk
index ec0b19e..520a73a 100644
--- a/plat/arm/board/arm_fpga/platform.mk
+++ b/plat/arm/board/arm_fpga/platform.mk
@@ -77,8 +77,8 @@
lib/cpus/aarch64/neoverse_n1.S \
lib/cpus/aarch64/neoverse_n2.S \
lib/cpus/aarch64/neoverse_v1.S \
- lib/cpus/aarch64/cortex_chaberton.S \
- lib/cpus/aarch64/cortex_blackhawk.S
+ lib/cpus/aarch64/cortex_a725.S \
+ lib/cpus/aarch64/cortex_x925.S
# AArch64/AArch32 cores
FPGA_CPU_LIBS += lib/cpus/aarch64/cortex_a55.S \
diff --git a/plat/arm/board/tc/include/platform_def.h b/plat/arm/board/tc/include/platform_def.h
index dcae95f..0cf7500 100644
--- a/plat/arm/board/tc/include/platform_def.h
+++ b/plat/arm/board/tc/include/platform_def.h
@@ -298,9 +298,14 @@
#endif /* TARGET_PLATFORM == 3 */
#define PLAT_MHUV2_BASE PLAT_CSS_MHU_BASE
-/* TC2: AP<->RSE MHUs */
+/* AP<->RSS MHUs */
+#if TARGET_PLATFORM <= 2
#define PLAT_RSE_AP_SND_MHU_BASE UL(0x2A840000)
#define PLAT_RSE_AP_RCV_MHU_BASE UL(0x2A850000)
+#elif TARGET_PLATFORM == 3
+#define PLAT_RSE_AP_SND_MHU_BASE UL(0x49000000)
+#define PLAT_RSE_AP_RCV_MHU_BASE UL(0x49100000)
+#endif
#define CSS_SYSTEM_PWR_DMN_LVL ARM_PWR_LVL2
#define PLAT_MAX_PWR_LVL ARM_PWR_LVL1
diff --git a/plat/arm/board/tc/platform.mk b/plat/arm/board/tc/platform.mk
index 37ca4c6..cd5abd0 100644
--- a/plat/arm/board/tc/platform.mk
+++ b/plat/arm/board/tc/platform.mk
@@ -44,6 +44,18 @@
CTX_INCLUDE_PAUTH_REGS := 1
endif
+# TC RESOLUTION - LIST OF VALID OPTIONS (this impacts only FVP)
+TC_RESOLUTION_OPTIONS := 640x480p60 \
+ 1920x1080p60
+# Set default to the 640x480p60 resolution mode
+TC_RESOLUTION ?= $(firstword $(TC_RESOLUTION_OPTIONS))
+
+# Check resolution option for FVP
+ifneq ($(filter ${TARGET_FLAVOUR}, fvp),)
+ifeq ($(filter ${TC_RESOLUTION}, ${TC_RESOLUTION_OPTIONS}),)
+ $(error TC_RESOLUTION is ${TC_RESOLUTION}, it must be: ${TC_RESOLUTION_OPTIONS})
+endif
+endif
ifneq ($(shell expr $(TARGET_PLATFORM) \<= 1), 0)
$(warning Platform ${PLAT}$(TARGET_PLATFORM) is deprecated. \
@@ -61,6 +73,7 @@
$(eval $(call add_defines, \
TARGET_PLATFORM \
TARGET_FLAVOUR_$(call uppercase,${TARGET_FLAVOUR}) \
+ TC_RESOLUTION_$(call uppercase,${TC_RESOLUTION}) \
TC_DPU_USE_SCMI_CLK \
TC_SCMI_PD_CTRL_EN \
TC_IOMMU_EN \
@@ -71,6 +84,13 @@
# Save DSU PMU registers on cluster off and restore them on cluster on
PRESERVE_DSU_PMU_REGS := 1
+# Specify MHU type based on platform
+ifneq ($(filter ${TARGET_PLATFORM}, 2),)
+ PLAT_MHU_VERSION := 2
+else
+ PLAT_MHU_VERSION := 3
+endif
+
# Include GICv3 driver files
include drivers/arm/gic/v3/gicv3.mk
@@ -100,8 +120,8 @@
# CPU libraries for TARGET_PLATFORM=3
ifeq (${TARGET_PLATFORM}, 3)
TC_CPU_SOURCES += lib/cpus/aarch64/cortex_a520.S \
- lib/cpus/aarch64/cortex_chaberton.S \
- lib/cpus/aarch64/cortex_blackhawk.S
+ lib/cpus/aarch64/cortex_a725.S \
+ lib/cpus/aarch64/cortex_x925.S
endif
INTERCONNECT_SOURCES := ${TC_BASE}/tc_interconnect.c
diff --git a/plat/arm/board/tc/tc_bl31_setup.c b/plat/arm/board/tc/tc_bl31_setup.c
index 5742d07..d6b0311 100644
--- a/plat/arm/board/tc/tc_bl31_setup.c
+++ b/plat/arm/board/tc/tc_bl31_setup.c
@@ -50,25 +50,33 @@
}
#endif /* PLATFORM_TEST_TFM_TESTSUITE */
-static scmi_channel_plat_info_t tc_scmi_plat_info[] = {
- {
- .scmi_mbx_mem = CSS_SCMI_PAYLOAD_BASE,
- .db_reg_addr = PLAT_CSS_MHU_BASE + SENDER_REG_SET(0),
- .db_preserve_mask = 0xfffffffe,
- .db_modify_mask = 0x1,
- .ring_doorbell = &mhuv2_ring_doorbell,
- }
+#if TARGET_PLATFORM <= 2
+static scmi_channel_plat_info_t tc_scmi_plat_info = {
+ .scmi_mbx_mem = CSS_SCMI_PAYLOAD_BASE,
+ .db_reg_addr = PLAT_CSS_MHU_BASE + SENDER_REG_SET(0),
+ .db_preserve_mask = 0xfffffffe,
+ .db_modify_mask = 0x1,
+ .ring_doorbell = &mhuv2_ring_doorbell,
};
+#elif TARGET_PLATFORM == 3
+static scmi_channel_plat_info_t tc_scmi_plat_info = {
+ .scmi_mbx_mem = CSS_SCMI_PAYLOAD_BASE,
+ .db_reg_addr = PLAT_CSS_MHU_BASE + MHU_V3_SENDER_REG_SET(0),
+ .db_preserve_mask = 0xfffffffe,
+ .db_modify_mask = 0x1,
+ .ring_doorbell = &mhu_ring_doorbell,
+};
+#endif
void bl31_platform_setup(void)
{
tc_bl31_common_platform_setup();
}
-scmi_channel_plat_info_t *plat_css_get_scmi_info(unsigned int channel_id)
+scmi_channel_plat_info_t *plat_css_get_scmi_info(unsigned int channel_id __unused)
{
- return &tc_scmi_plat_info[channel_id];
+ return &tc_scmi_plat_info;
}
diff --git a/plat/rockchip/common/aarch64/plat_helpers.S b/plat/rockchip/common/aarch64/plat_helpers.S
index c4c0dec..dde66aa 100644
--- a/plat/rockchip/common/aarch64/plat_helpers.S
+++ b/plat/rockchip/common/aarch64/plat_helpers.S
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2013-2016, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2013-2023, ARM Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -150,7 +150,12 @@
* Per-CPU Secure entry point - resume or power up
* --------------------------------------------------------------------
*/
+
+#if USE_COHERENT_MEM
.section .tzfw_coherent_mem, "a"
+#else
+ .data
+#endif
.align 3
cpuson_entry_point:
.rept PLATFORM_CORE_COUNT
diff --git a/plat/rockchip/common/aarch64/platform_common.c b/plat/rockchip/common/aarch64/platform_common.c
index 81e8520..d563dfd 100644
--- a/plat/rockchip/common/aarch64/platform_common.c
+++ b/plat/rockchip/common/aarch64/platform_common.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2013-2016, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2013-2023, ARM Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -13,8 +13,6 @@
#include <common/debug.h>
#include <drivers/arm/cci.h>
#include <lib/utils.h>
-#include <lib/xlat_tables/xlat_tables.h>
-
#include <plat_private.h>
#ifdef PLAT_RK_CCI_BASE
@@ -42,9 +40,10 @@
mmap_add_region(ro_start, ro_start, \
ro_limit - ro_start, \
MT_MEMORY | MT_RO | MT_SECURE); \
- mmap_add_region(coh_start, coh_start, \
- coh_limit - coh_start, \
- MT_DEVICE | MT_RW | MT_SECURE); \
+ if ((coh_limit - coh_start) != 0) \
+ mmap_add_region(coh_start, coh_start, \
+ coh_limit - coh_start, \
+ MT_DEVICE | MT_RW | MT_SECURE); \
mmap_add(plat_rk_mmap); \
rockchip_plat_mmu_el##_el(); \
init_xlat_tables(); \
diff --git a/plat/rockchip/common/bl31_plat_setup.c b/plat/rockchip/common/bl31_plat_setup.c
index 59db3d8..6214722 100644
--- a/plat/rockchip/common/bl31_plat_setup.c
+++ b/plat/rockchip/common/bl31_plat_setup.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2016-2019, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2016-2023, ARM Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -93,10 +93,19 @@
{
plat_cci_init();
plat_cci_enable();
+#if USE_COHERENT_MEM
plat_configure_mmu_el3(BL_CODE_BASE,
BL_COHERENT_RAM_END - BL_CODE_BASE,
BL_CODE_BASE,
BL_CODE_END,
BL_COHERENT_RAM_BASE,
BL_COHERENT_RAM_END);
+#else
+ plat_configure_mmu_el3(BL31_START,
+ BL31_END - BL31_START,
+ BL_CODE_BASE,
+ BL_CODE_END,
+ 0,
+ 0);
+#endif
}
diff --git a/plat/rockchip/common/include/plat_private.h b/plat/rockchip/common/include/plat_private.h
index 990d106..465f372 100644
--- a/plat/rockchip/common/include/plat_private.h
+++ b/plat/rockchip/common/include/plat_private.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2014-2019, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2014-2023, ARM Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -11,9 +11,9 @@
#include <stdint.h>
-#include <lib/psci/psci.h>
-#include <lib/xlat_tables/xlat_tables.h>
#include <lib/mmio.h>
+#include <lib/psci/psci.h>
+#include <lib/xlat_tables/xlat_tables_compat.h>
#include <plat_params.h>
#define __sramdata __attribute__((section(".sram.data")))
@@ -135,7 +135,6 @@
extern void *pmu_cpuson_entrypoint;
extern u_register_t cpuson_entry_point[PLATFORM_CORE_COUNT];
extern uint32_t cpuson_flags[PLATFORM_CORE_COUNT];
-
extern const mmap_region_t plat_rk_mmap[];
uint32_t rockchip_get_uart_base(void);
diff --git a/plat/rockchip/rk3568/drivers/pmu/plat_pmu_macros.S b/plat/rockchip/rk3568/drivers/pmu/plat_pmu_macros.S
new file mode 100644
index 0000000..8ddea0e
--- /dev/null
+++ b/plat/rockchip/rk3568/drivers/pmu/plat_pmu_macros.S
@@ -0,0 +1,18 @@
+/*
+ * Copyright (c) 2023, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <arch.h>
+#include <asm_macros.S>
+
+#include <platform_def.h>
+
+.macro func_rockchip_clst_warmboot
+ /* Nothing to do for rk3568 */
+.endm
+
+.macro rockchip_clst_warmboot_data
+ /* Nothing to do for rk3568 */
+.endm
diff --git a/plat/rockchip/rk3568/drivers/pmu/pmu.c b/plat/rockchip/rk3568/drivers/pmu/pmu.c
new file mode 100644
index 0000000..970caec
--- /dev/null
+++ b/plat/rockchip/rk3568/drivers/pmu/pmu.c
@@ -0,0 +1,543 @@
+/*
+ * Copyright (c) 2023, ARM Limited and Contributors. All rights reserved.
+ *
+ * The power management unit (PMU) is designed for controlling power resources.
+ * The PMU is dedicated for managing the power of the whole chip.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <assert.h>
+#include <errno.h>
+
+#include <bakery_lock.h>
+#include <cortex_a55.h>
+#include <dsu_def.h>
+#include <mmio.h>
+#include <platform.h>
+#include <platform_def.h>
+#include <pmu.h>
+
+#include <cpus_on_fixed_addr.h>
+#include <plat_private.h>
+#include <soc.h>
+
+/*
+ * Use this macro to instantiate lock before it is used in below
+ * rockchip_pd_lock_xxx() macros
+ */
+DECLARE_BAKERY_LOCK(rockchip_pd_lock);
+
+static uint32_t grf_ddr_con3;
+static struct psram_data_t *psram_sleep_cfg =
+ (struct psram_data_t *)&sys_sleep_flag_sram;
+
+/*
+ * These are wrapper macros to the powe domain Bakery Lock API.
+ */
+#define rockchip_pd_lock_init() bakery_lock_init(&rockchip_pd_lock)
+#define rockchip_pd_lock_get() bakery_lock_get(&rockchip_pd_lock)
+#define rockchip_pd_lock_rls() bakery_lock_release(&rockchip_pd_lock)
+
+void __dead2 rockchip_soc_sys_pd_pwr_dn_wfi(void)
+{
+ uint64_t ctrl;
+
+ __asm__ volatile ("mrs %0, " __XSTRING(CORTEX_A55_CPUPWRCTLR_EL1) : "=r" (ctrl));
+ ctrl |= 0x01;
+ __asm__ volatile ("msr " __XSTRING(CORTEX_A55_CPUPWRCTLR_EL1) ", %0" : : "r" (ctrl));
+ isb();
+
+ while (1)
+ wfi();
+}
+
+static void pmu_pmic_sleep_mode_config(void)
+{
+ /* pmic sleep function selection
+ * 1'b0: From reset pulse generator, can reset external PMIC
+ * 1'b1: From pmu block, only support sleep function for external PMIC
+ */
+ mmio_write_32(PMUGRF_BASE + PMU_GRF_SOC_CON(0), WRITE_MASK_SET(BIT(7)));
+ mmio_write_32(PMUGRF_BASE + PMU_GRF_GPIO0A_IOMUX_L, PMIC_SLEEP_FUN);
+}
+
+static void pmu_wakeup_source_config(void)
+{
+ /* config wakeup source */
+ mmio_write_32(PMU_BASE + PMU_WAKEUP_INT_CON, WRITE_MASK_SET(BIT(WAKEUP_GPIO0_INT_EN)));
+
+ INFO("WAKEUP: PMU_WAKEUP_INT_CON:0x%x, reg: 0x%x\n",
+ mmio_read_32(PMU_BASE + PMU_WAKEUP_INT_CON), PMU_WAKEUP_INT_CON);
+}
+
+static void pmu_pll_powerdown_config(void)
+{
+ uint32_t pll_id;
+
+ /* PLL power down by PMU */
+ pll_id = BIT(APLL_PD_ENA) |
+ BIT(CPLL_PD_ENA) |
+ BIT(GPLL_PD_ENA) |
+ BIT(MPLL_PD_ENA) |
+ BIT(NPLL_PD_ENA) |
+ BIT(HPLL_PD_ENA) |
+ BIT(PPLL_PD_ENA) |
+ BIT(VPLL_PD_ENA);
+ mmio_write_32(PMU_BASE + PMU_PLLPD_CON, WRITE_MASK_SET(pll_id));
+ INFO("PLL: PMU_PLLPD_CON(0x%x):0x%x\n",
+ PMU_PLLPD_CON, mmio_read_32(PMU_BASE + PMU_PLLPD_CON));
+}
+
+static void pmu_stable_count_config(void)
+{
+ mmio_write_32(PMU_BASE + PMU_DSU_STABLE_CNT, 0x180);
+ mmio_write_32(PMU_BASE + PMU_PMIC_STABLE_CNT, 0x180);
+ mmio_write_32(PMU_BASE + PMU_OSC_STABLE_CNT, 0x180);
+ mmio_write_32(PMU_BASE + PMU_WAKEUP_RSTCLR_CNT, 0x180);
+ mmio_write_32(PMU_BASE + PMU_PLL_LOCK_CNT, 0x180);
+ mmio_write_32(PMU_BASE + PMU_DSU_PWRUP_CNT, 0x180);
+ mmio_write_32(PMU_BASE + PMU_DSU_PWRDN_CNT, 0x180);
+ mmio_write_32(PMU_BASE + PMU_GPU_VOLUP_CNT, 0x180);
+ mmio_write_32(PMU_BASE + PMU_GPU_VOLDN_CNT, 0x180);
+ mmio_write_32(PMU_BASE + PMU_WAKEUP_TIMEOUT_CNT, 0x180);
+ mmio_write_32(PMU_BASE + PMU_PWM_SWITCH_CNT, 0x180);
+ mmio_write_32(PMU_BASE + PMU_DBG_RST_CNT, 0x180);
+}
+
+static void pmu_pd_powerdown_config(void)
+{
+ uint32_t pwr_gate_con, pwr_dwn_st, pmu_bus_idle_con0 = 0;
+ uint32_t pmu_bus_idle_con1;
+
+ /* Pd power down by PMU */
+ pwr_dwn_st = mmio_read_32(PMU_BASE + PMU_PWR_DWN_ST);
+ pwr_gate_con = ~pwr_dwn_st & 0x3ff;
+
+ if (pwr_gate_con & BIT(PD_GPU_DWN_ENA)) {
+ pmu_bus_idle_con0 |= BIT(IDLE_REQ_GPU);
+ }
+
+ if (pwr_gate_con & BIT(PD_NPU_DWN_ENA)) {
+ pmu_bus_idle_con0 |= BIT(IDLE_REQ_NPU);
+ }
+
+ if (pwr_gate_con & BIT(PD_RKVENC_DWN_ENA)) {
+ pmu_bus_idle_con0 |= BIT(IDLE_REQ_RKVENC);
+ }
+
+ if (pwr_gate_con & BIT(PD_RKVDEC_DWN_ENA)) {
+ pmu_bus_idle_con0 |= BIT(IDLE_REQ_RKVDEC);
+ }
+
+ if (pwr_gate_con & BIT(PD_RGA_DWN_ENA)) {
+ pmu_bus_idle_con0 |= BIT(IDLE_REQ_RGA);
+ }
+
+ if (pwr_gate_con & BIT(PD_VI_DWN_ENA)) {
+ pmu_bus_idle_con0 |= BIT(IDLE_REQ_VI);
+ }
+
+ if (pwr_gate_con & BIT(PD_VO_DWN_ENA)) {
+ pmu_bus_idle_con0 |= BIT(IDLE_REQ_VO);
+ }
+
+ if (pwr_gate_con & BIT(PD_PIPE_DWN_ENA)) {
+ pmu_bus_idle_con0 |= BIT(IDLE_REQ_PIPE);
+ }
+
+ pmu_bus_idle_con0 |= BIT(IDLE_REQ_GIC_AUDIO) |
+ BIT(IDLE_REQ_MSCH) |
+ BIT(IDLE_REQ_PHP) |
+ BIT(IDLE_REQ_SECURE_FLASH) |
+ BIT(IDLE_REQ_PERIMID) |
+ BIT(IDLE_REQ_USB) |
+ BIT(IDLE_REQ_BUS);
+
+ /* Enable power down PD by PMU automatically */
+ pwr_gate_con |= (BIT(PD_GPU_DWN_ENA) |
+ BIT(PD_NPU_DWN_ENA) |
+ BIT(PD_VPU_DWN_ENA) |
+ BIT(PD_RKVENC_DWN_ENA) |
+ BIT(PD_RKVDEC_DWN_ENA) |
+ BIT(PD_RGA_DWN_ENA) |
+ BIT(PD_VI_DWN_ENA) |
+ BIT(PD_VO_DWN_ENA) |
+ BIT(PD_PIPE_DWN_ENA)) << 16;
+
+ pmu_bus_idle_con1 = 0;
+
+ mmio_write_32(PMU_BASE + PMU_PWR_GATE_CON, pwr_gate_con);
+ mmio_write_32(PMU_BASE + PMU_BUS_IDLE_CON0, WRITE_MASK_SET(pmu_bus_idle_con0));
+ mmio_write_32(PMU_BASE + PMU_BUS_IDLE_CON1, WRITE_MASK_SET(pmu_bus_idle_con1));
+
+ /* When perform idle operation,
+ * corresponding clock can be opened or gated automatically
+ */
+ mmio_write_32(PMU_BASE + PMU_NOC_AUTO_CON0, 0xffffffff);
+ mmio_write_32(PMU_BASE + PMU_NOC_AUTO_CON1, 0x00070007);
+
+ mmio_write_32(PMU_BASE + PMU_VOL_GATE_SFTCON, WRITE_MASK_SET(BIT(VD_NPU_ENA)));
+
+ mmio_write_32(PMU_BASE + PMU_PWR_CON, WRITE_MASK_CLR(BIT(PWRDN_BYPASS)));
+ mmio_write_32(PMU_BASE + PMU_PWR_CON, WRITE_MASK_CLR(BIT(BUS_BYPASS)));
+
+ INFO("PD & BUS:PMU_PWR_DWN_ST(0x%x):0x%x\n",
+ PMU_PWR_DWN_ST, mmio_read_32(PMU_BASE + PMU_PWR_DWN_ST));
+ INFO("PD & BUS:PMU_PWR_GATE_CON(0x%x):0x%x\n",
+ PMU_PWR_GATE_CON, mmio_read_32(PMU_BASE + PMU_PWR_GATE_CON));
+ INFO("PD & BUS:PMU_BUS_IDLE_CON0(0x%x):0x%x\n",
+ PMU_BUS_IDLE_CON0, mmio_read_32(PMU_BASE + PMU_BUS_IDLE_CON0));
+ INFO("PD & BUS:PMU_BUS_IDLE_CON1(0x%x):0x%x\n",
+ PMU_BUS_IDLE_CON1, mmio_read_32(PMU_BASE + PMU_BUS_IDLE_CON1));
+ INFO("PD & BUS:PMU_PWR_CON(0x%x):0x%x\n",
+ PMU_PWR_CON, mmio_read_32(PMU_BASE + PMU_PWR_CON));
+}
+
+static void pmu_ddr_suspend_config(void)
+{
+ uint32_t pmu_ddr_pwr_con;
+
+ pmu_ddr_pwr_con = BIT(DDR_SREF_ENA) |
+ BIT(DDRIO_RET_ENTER_ENA) |
+ BIT(DDRIO_RET_EXIT_ENA) |
+ BIT(DDRPHY_AUTO_GATING_ENA);
+
+ mmio_write_32(PMU_BASE + PMU_DDR_PWR_CON, WRITE_MASK_SET(pmu_ddr_pwr_con));
+ /* DPLL power down by PMU */
+ mmio_write_32(PMU_BASE + PMU_PLLPD_CON, WRITE_MASK_SET(BIT(DPLL_PD_ENA)));
+ mmio_write_32(PMU_BASE + PMU_PWR_CON, WRITE_MASK_CLR(BIT(DDR_BYPASS)));
+
+ grf_ddr_con3 = mmio_read_32(DDRGRF_BASE + GRF_DDR_CON3);
+
+ mmio_write_32(DDRGRF_BASE + GRF_DDR_CON3, 0x00600020);
+
+ pmu_ddr_pwr_con = mmio_read_32(PMU_BASE + PMU_DDR_PWR_CON);
+
+ INFO("DDR: PMU_PLLPD_CON(0x%x):0x%x\n",
+ PMU_PLLPD_CON, mmio_read_32(PMU_BASE + PMU_PLLPD_CON));
+ INFO("DDR: PMU_DDR_PWR_CON(0x%x):\t0x%x\n",
+ PMU_DDR_PWR_CON, pmu_ddr_pwr_con);
+
+ if (pmu_ddr_pwr_con & BIT(DDR_SREF_ENA)) {
+ INFO("\t DDR_SREF_ENA\n");
+ }
+
+ if (pmu_ddr_pwr_con & BIT(DDRIO_RET_ENTER_ENA)) {
+ INFO("\t DDRIO_RET_ENTER_ENA\n");
+ }
+
+ if (pmu_ddr_pwr_con & BIT(DDRIO_RET_EXIT_ENA)) {
+ INFO("\t DDRIO_RET_EXIT_ENA\n");
+ }
+
+ if (pmu_ddr_pwr_con & BIT(DDRPHY_AUTO_GATING_ENA)) {
+ INFO("\t DDRPHY_AUTO_GATING_ENA\n");
+ }
+}
+
+static void pmu_dsu_suspend_config(void)
+{
+ uint32_t pmu_dsu_pwr_con;
+
+ pmu_dsu_pwr_con = BIT(DSU_PWRDN_ENA);
+
+ mmio_write_32(PMU_BASE + PMU_CLUSTER_IDLE_CON, 0x000f000f);
+ mmio_write_32(PMU_BASE + PMU_DSU_PWR_CON, WRITE_MASK_SET(pmu_dsu_pwr_con));
+ mmio_write_32(PMU_BASE + PMU_PWR_CON, WRITE_MASK_CLR(BIT(DSU_BYPASS)));
+ dsu_pwr_dwn();
+
+ INFO("DSU: PMU_DSU_PWR_CON(0x%x): 0x%x\n",
+ PMU_DSU_PWR_CON, mmio_read_32(PMU_BASE + PMU_DSU_PWR_CON));
+ INFO("DSU: PMU_CLUSTER_IDLE_CON(0x%x),: 0x%x\n",
+ PMU_CLUSTER_IDLE_CON, mmio_read_32(PMU_BASE + PMU_CLUSTER_IDLE_CON));
+ INFO("DSU: PMU_PWR_CON(0x%x),: 0x%x\n",
+ PMU_PWR_CON, mmio_read_32(PMU_BASE + PMU_PWR_CON));
+}
+
+static void pmu_cpu_powerdown_config(void)
+{
+ uint32_t pmu_cluster_pwr_st, cpus_state, cpus_bypass;
+
+ pmu_cluster_pwr_st = mmio_read_32(PMU_BASE + PMU_CLUSTER_PWR_ST);
+ cpus_state = pmu_cluster_pwr_st & 0x0f;
+
+ cpus_bypass = cpus_state << CPU0_BYPASS;
+
+ INFO("CPU: PMU_CLUSTER_PWR_ST(0x%x):0x%x\n",
+ PMU_CLUSTER_PWR_ST, mmio_read_32(PMU_BASE + PMU_CLUSTER_PWR_ST));
+ mmio_write_32(PMU_BASE + PMU_PWR_CON, (0xf << (16 + CPU0_BYPASS)) | cpus_bypass);
+
+ INFO("CPU: PMU_PWR_CON(0x%x), 0x%x\n",
+ PMU_PWR_CON, mmio_read_32(PMU_BASE + PMU_PWR_CON));
+}
+
+static void pvtm_32k_config(void)
+{
+ uint32_t pmu_cru_pwr_con;
+ uint32_t pvtm_freq_khz, pvtm_div;
+
+ mmio_write_32(PMUCRU_BASE + PMUCRU_PMUGATE_CON01, 0x38000000);
+ mmio_write_32(PMUPVTM_BASE + PVTM_CON0, 0x00020002);
+ dsb();
+
+ mmio_write_32(PMUPVTM_BASE + PVTM_CON0, 0x001c0000);
+
+ mmio_write_32(PMUPVTM_BASE + PVTM_CON1, PVTM_CALC_CNT);
+ dsb();
+
+ mmio_write_32(PMUPVTM_BASE + PVTM_CON0, 0x00010001);
+ dsb();
+
+ while (mmio_read_32(PMUPVTM_BASE + PVTM_STATUS1) < 30) {
+ ;
+ }
+
+ dsb();
+ while (!(mmio_read_32(PMUPVTM_BASE + PVTM_STATUS0) & 0x1)) {
+ ;
+ }
+
+ pvtm_freq_khz = (mmio_read_32(PMUPVTM_BASE + PVTM_STATUS1) * 24000 +
+ PVTM_CALC_CNT / 2) / PVTM_CALC_CNT;
+ pvtm_div = (pvtm_freq_khz + 16) / 32;
+
+ mmio_write_32(PMUGRF_BASE + PMU_GRF_DLL_CON0, pvtm_div);
+
+ mmio_write_32(PMUCRU_BASE + PMUCRU_PMUCLKSEL_CON00, 0x00c00000);
+
+ pmu_cru_pwr_con = BIT(ALIVE_32K_ENA) | BIT(OSC_DIS_ENA);
+
+ mmio_write_32(PMU_BASE + PMU_WAKEUP_TIMEOUT_CNT, 32000 * 10);
+
+ mmio_write_32(PMU_BASE + PMU_CRU_PWR_CON, WRITE_MASK_SET(pmu_cru_pwr_con));
+ INFO("PVTM: PMU_CRU_PWR_CON(0x0%x): 0x%x\n",
+ PMU_CRU_PWR_CON, mmio_read_32(PMU_BASE + PMU_CRU_PWR_CON));
+}
+
+static void pmu_cru_suspendmode_config(void)
+{
+ uint32_t pmu_cru_pwr_con;
+
+ pmu_cru_pwr_con = BIT(ALIVE_OSC_ENA);
+
+ mmio_write_32(PMU_BASE + PMU_CRU_PWR_CON, WRITE_MASK_SET(pmu_cru_pwr_con));
+ INFO("CRU: PMU_CRU_PWR_CON(0x0%x): 0x%x\n",
+ PMU_CRU_PWR_CON, mmio_read_32(PMU_BASE + PMU_CRU_PWR_CON));
+}
+
+static void pmu_suspend_cru_fsm(void)
+{
+ pmu_pmic_sleep_mode_config();
+
+ /* Global interrupt disable */
+ mmio_write_32(PMU_BASE + PMU_INT_MASK_CON, CLB_INT_DISABLE);
+ mmio_write_32(PMU_BASE + PMU_PWR_CON, CPUS_BYPASS);
+
+ pmu_stable_count_config();
+ pmu_wakeup_source_config();
+ mmio_write_32(PMU_BASE + PMU_WAKEUP_TIMEOUT_CNT, 0x5dc0 * 20000);
+ /* default cru config */
+ mmio_write_32(PMU_BASE + PMU_CRU_PWR_CON, WRITE_MASK_SET(BIT(ALIVE_OSC_ENA)));
+
+ pmu_cru_suspendmode_config();
+ pmu_cpu_powerdown_config();
+ pmu_pll_powerdown_config();
+ pmu_pd_powerdown_config();
+ pmu_ddr_suspend_config();
+ pmu_dsu_suspend_config();
+ pvtm_32k_config();
+ mmio_write_32(PMU_BASE + PMU_PWR_CON, 0x00010001);
+}
+
+static void pmu_reinit(void)
+{
+ mmio_write_32(DDRGRF_BASE + GRF_DDR_CON3, grf_ddr_con3 | 0xffff0000);
+ mmio_write_32(PMU_BASE + PMU_PWR_CON, 0xffff0000);
+ mmio_write_32(PMU_BASE + PMU_INT_MASK_CON, 0xffff0000);
+ mmio_write_32(PMU_BASE + PMU_WAKEUP_INT_CON, 0xffff0000);
+ mmio_write_32(PMU_BASE + PMU_BUS_IDLE_CON0, 0xffff0000);
+ mmio_write_32(PMU_BASE + PMU_DDR_PWR_CON, 0xffff0000);
+ mmio_write_32(PMU_BASE + PMU_BUS_IDLE_CON1, 0xffff0000);
+
+ mmio_write_32(PMU_BASE + PMU_PWR_GATE_CON, 0xffff0000);
+ mmio_write_32(PMU_BASE + PMU_VOL_GATE_SFTCON, 0xffff0000);
+ mmio_write_32(PMU_BASE + PMU_CRU_PWR_CON, 0xffff0000);
+
+ mmio_write_32(PMU_BASE + PMU_PLLPD_CON, 0xffff0000);
+ mmio_write_32(PMU_BASE + PMU_INFO_TX_CON, 0xffff0000);
+ mmio_write_32(PMU_BASE + PMU_DSU_PWR_CON, 0xffff0000);
+ mmio_write_32(PMU_BASE + PMU_CLUSTER_IDLE_CON, 0xffff0000);
+}
+
+void rockchip_plat_mmu_el3(void)
+{
+}
+
+int rockchip_soc_cores_pwr_dm_suspend(void)
+{
+ return 0;
+}
+
+int rockchip_soc_cores_pwr_dm_resume(void)
+{
+ return 0;
+}
+
+int rockchip_soc_sys_pwr_dm_suspend(void)
+{
+ psram_sleep_cfg->pm_flag = 0;
+ flush_dcache_range((uintptr_t)&(psram_sleep_cfg->pm_flag),
+ sizeof(uint32_t));
+ pmu_suspend_cru_fsm();
+
+ return 0;
+}
+
+int rockchip_soc_sys_pwr_dm_resume(void)
+{
+ pmu_reinit();
+ plat_rockchip_gic_cpuif_enable();
+ psram_sleep_cfg->pm_flag = PM_WARM_BOOT_BIT;
+ flush_dcache_range((uintptr_t)&(psram_sleep_cfg->pm_flag),
+ sizeof(uint32_t));
+
+ return 0;
+}
+
+static int cpus_power_domain_off(uint32_t cpu_id, uint32_t pd_cfg)
+{
+ uint32_t apm_value, offset, idx;
+
+ apm_value = BIT(core_pm_en) | BIT(core_pm_int_wakeup_glb_msk);
+
+ if (pd_cfg == core_pwr_wfi_int) {
+ apm_value |= BIT(core_pm_int_wakeup_en);
+ }
+
+ idx = cpu_id / 2;
+ offset = (cpu_id % 2) << 3;
+
+ mmio_write_32(PMU_BASE + PMU_CPUAPM_CON(idx),
+ BITS_WITH_WMASK(apm_value, 0xf, offset));
+ dsb();
+
+ return 0;
+}
+
+static int cpus_power_domain_on(uint32_t cpu_id)
+{
+ uint32_t offset, idx;
+
+ idx = cpu_id / 2;
+ offset = (cpu_id % 2) << 3;
+
+ mmio_write_32(PMU_BASE + PMU_CPUAPM_CON(idx),
+ WMSK_BIT(core_pm_en + offset));
+ mmio_write_32(PMU_BASE + PMU_CPUAPM_CON(idx),
+ BIT_WITH_WMSK(core_pm_sft_wakeup_en + offset));
+ dsb();
+
+ return 0;
+}
+
+int rockchip_soc_cores_pwr_dm_on(unsigned long mpidr, uint64_t entrypoint)
+{
+ uint32_t cpu_id = plat_core_pos_by_mpidr(mpidr);
+
+ assert(cpu_id < PLATFORM_CORE_COUNT);
+
+ cpuson_flags[cpu_id] = PMU_CPU_HOTPLUG;
+ cpuson_entry_point[cpu_id] = entrypoint;
+ flush_dcache_range((uintptr_t)cpuson_flags, sizeof(cpuson_flags));
+ flush_dcache_range((uintptr_t)cpuson_entry_point,
+ sizeof(cpuson_entry_point));
+
+ cpus_power_domain_on(cpu_id);
+ return 0;
+}
+
+int rockchip_soc_cores_pwr_dm_off(void)
+{
+ uint32_t cpu_id = plat_my_core_pos();
+
+ cpus_power_domain_off(cpu_id,
+ core_pwr_wfi);
+ return 0;
+}
+
+int rockchip_soc_cores_pwr_dm_on_finish(void)
+{
+ uint32_t cpu_id = plat_my_core_pos();
+ uint32_t offset, idx;
+
+ /* Disable core_pm */
+ idx = cpu_id / 2;
+ offset = (cpu_id % 2) << 3;
+ mmio_write_32(PMU_BASE + PMU_CPUAPM_CON(idx),
+ BITS_WITH_WMASK(0, 0xf, offset));
+
+ return 0;
+}
+
+static void nonboot_cpus_off(void)
+{
+ uint32_t tmp;
+
+ cpus_power_domain_off(1, 0);
+ cpus_power_domain_off(2, 0);
+ cpus_power_domain_off(3, 0);
+
+ mmio_write_32(SYSSRAM_BASE + 0x04, 0xdeadbeaf);
+ mmio_write_32(SYSSRAM_BASE + 0x08, (uintptr_t)&rockchip_soc_sys_pd_pwr_dn_wfi);
+ sev();
+
+ do {
+ tmp = mmio_read_32(PMU_BASE + PMU_CLUSTER_PWR_ST);
+ } while ((tmp & 0xe) != 0xe);
+}
+
+void plat_rockchip_pmu_init(void)
+{
+ uint32_t cpu;
+
+ rockchip_pd_lock_init();
+ nonboot_cpus_off();
+ for (cpu = 0; cpu < PLATFORM_CORE_COUNT; cpu++)
+ cpuson_flags[cpu] = PMU_CPU_HOTPLUG;
+
+ psram_sleep_cfg->ddr_data = (uint64_t)0;
+ psram_sleep_cfg->sp = PSRAM_SP_TOP;
+ psram_sleep_cfg->ddr_flag = 0x00;
+ psram_sleep_cfg->boot_mpidr = read_mpidr_el1() & 0xffff;
+ psram_sleep_cfg->pm_flag = PM_WARM_BOOT_BIT;
+
+ /*
+ * When perform idle operation, corresponding clock can be
+ * opened or gated automatically.
+ */
+ mmio_write_32(PMU_BASE + PMU_NOC_AUTO_CON0, 0xffffffff);
+ mmio_write_32(PMU_BASE + PMU_NOC_AUTO_CON1, 0x00070007);
+
+ /* grf_con_pmic_sleep_sel
+ * pmic sleep function selection
+ * 1'b0: From reset pulse generator, can reset external PMIC
+ * 1'b1: From pmu block, only support sleep function for external PMIC
+ */
+ mmio_write_32(PMUGRF_BASE + PMU_GRF_SOC_CON(0), 0x00800080);
+
+ /*
+ * force jtag control
+ * 1'b0: CPU debug port IO mux is controlled by sdmmc_detect_en status
+ * 1'b0: CPU debug port IO mux IS controlled by GRF
+ */
+ mmio_write_32(SGRF_BASE + 0x008, 0x00100000);
+
+ /*
+ * remap
+ * 2'b00: Boot from boot-rom.
+ * 2'b01: Boot from pmu mem.
+ * 2'b10: Boot from sys mem.
+ */
+ mmio_write_32(PMUSGRF_BASE + PMU_SGRF_SOC_CON1, 0x18000800);
+}
diff --git a/plat/rockchip/rk3568/drivers/pmu/pmu.h b/plat/rockchip/rk3568/drivers/pmu/pmu.h
new file mode 100644
index 0000000..5821514
--- /dev/null
+++ b/plat/rockchip/rk3568/drivers/pmu/pmu.h
@@ -0,0 +1,304 @@
+/*
+ * Copyright (c) 2023, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef __PMU_H__
+#define __PMU_H__
+
+#define PMU_VERSION 0x0000
+#define PMU_PWR_CON 0x0004
+#define PMU_MAIN_PWR_STATE 0x0008
+#define PMU_INT_MASK_CON 0x000C
+#define PMU_WAKEUP_INT_CON 0x0010
+#define PMU_WAKEUP_INT_ST 0x0014
+#define PMU_WAKEUP_EDGE_CON 0x0018
+#define PMU_WAKEUP_EDGE_ST 0x001C
+#define PMU_BUS_IDLE_CON0 0x0040
+#define PMU_BUS_IDLE_CON1 0x0044
+#define PMU_BUS_IDLE_SFTCON0 0x0050
+#define PMU_BUS_IDLE_SFTCON1 0x0054
+#define PMU_BUS_IDLE_ACK 0x0060
+#define PMU_BUS_IDLE_ST 0x0068
+#define PMU_NOC_AUTO_CON0 0x0070
+#define PMU_NOC_AUTO_CON1 0x0074
+#define PMU_DDR_PWR_CON 0x0080
+#define PMU_DDR_PWR_SFTCON 0x0084
+#define PMU_DDR_PWR_STATE 0x0088
+#define PMU_DDR_PWR_ST 0x008C
+#define PMU_PWR_GATE_CON 0x0090
+#define PMU_PWR_GATE_STATE 0x0094
+#define PMU_PWR_DWN_ST 0x0098
+#define PMU_PWR_GATE_SFTCON 0x00A0
+#define PMU_VOL_GATE_SFTCON 0x00A8
+#define PMU_CRU_PWR_CON 0x00B0
+#define PMU_CRU_PWR_SFTCON 0x00B4
+#define PMU_CRU_PWR_STATE 0x00B8
+#define PMU_PLLPD_CON 0x00C0
+#define PMU_PLLPD_SFTCON 0x00C4
+#define PMU_INFO_TX_CON 0x00D0
+#define PMU_DSU_STABLE_CNT 0x0100
+#define PMU_PMIC_STABLE_CNT 0x0104
+#define PMU_OSC_STABLE_CNT 0x0108
+#define PMU_WAKEUP_RSTCLR_CNT 0x010C
+#define PMU_PLL_LOCK_CNT 0x0110
+#define PMU_DSU_PWRUP_CNT 0x0118
+#define PMU_DSU_PWRDN_CNT 0x011C
+#define PMU_GPU_VOLUP_CNT 0x0120
+#define PMU_GPU_VOLDN_CNT 0x0124
+#define PMU_WAKEUP_TIMEOUT_CNT 0x0128
+#define PMU_PWM_SWITCH_CNT 0x012C
+#define PMU_DBG_RST_CNT 0x0130
+#define PMU_SYS_REG0 0x0180
+#define PMU_SYS_REG1 0x0184
+#define PMU_SYS_REG2 0x0188
+#define PMU_SYS_REG3 0x018C
+#define PMU_SYS_REG4 0x0190
+#define PMU_SYS_REG5 0x0194
+#define PMU_SYS_REG6 0x0198
+#define PMU_SYS_REG7 0x019C
+#define PMU_DSU_PWR_CON 0x0300
+#define PMU_DSU_PWR_SFTCON 0x0304
+#define PMU_DSU_AUTO_CON 0x0308
+#define PMU_DSU_PWR_STATE 0x030C
+#define PMU_CPU_AUTO_PWR_CON0 0x0310
+#define PMU_CPU_AUTO_PWR_CON1 0x0314
+#define PMU_CPU_PWR_SFTCON 0x0318
+#define PMU_CLUSTER_PWR_ST 0x031C
+#define PMU_CLUSTER_IDLE_CON 0x0320
+#define PMU_CLUSTER_IDLE_SFTCON 0x0324
+#define PMU_CLUSTER_IDLE_ACK 0x0328
+#define PMU_CLUSTER_IDLE_ST 0x032C
+#define PMU_DBG_PWR_CON 0x0330
+
+/* PMU_SGRF */
+#define PMU_SGRF_SOC_CON1 0x0004
+#define PMU_SGRF_FAST_BOOT_ADDR 0x0180
+
+/* sys grf */
+#define GRF_CPU_STATUS0 0x0420
+
+#define CRU_SOFTRST_CON00 0x0400
+
+#define CORES_PM_DISABLE 0x0
+#define PD_CHECK_LOOP 500
+#define WFEI_CHECK_LOOP 500
+
+#define PMUSGRF_SOC_CON(i) ((i) * 0x4)
+/* Needed aligned 16 bytes for sp stack top */
+#define PSRAM_SP_TOP ((PMUSRAM_BASE + PMUSRAM_RSIZE) & ~0xf)
+#define PMU_CPUAPM_CON(cpu) (0x0310 + (cpu) * 0x4)
+
+#define PMIC_SLEEP_FUN 0x07000100
+#define PMIC_SLEEP_GPIO 0x07000000
+#define GPIO_SWPORT_DR_L 0x0000
+#define GPIO_SWPORT_DR_H 0x0004
+#define GPIO_SWPORT_DDR_L 0x0008
+#define GPIO_SWPORT_DDR_H 0x000C
+#define PMIC_SLEEP_HIGH_LEVEL 0x00040004
+#define PMIC_SLEEP_LOW_LEVEL 0x00040000
+#define PMIC_SLEEP_OUT 0x00040004
+#define CPUS_BYPASS 0x007e4f7e
+#define CLB_INT_DISABLE 0x00010001
+#define WRITE_MASK_SET(value) ((value << 16) | value)
+#define WRITE_MASK_CLR(value) ((value << 16))
+
+enum pmu_cores_pm_by_wfi {
+ core_pm_en = 0,
+ core_pm_int_wakeup_en,
+ core_pm_int_wakeup_glb_msk,
+ core_pm_sft_wakeup_en,
+};
+
+/* The ways of cores power domain contorlling */
+enum cores_pm_ctr_mode {
+ core_pwr_pd = 0,
+ core_pwr_wfi = 1,
+ core_pwr_wfi_int = 2
+};
+
+/* PMU_PWR_DWN_ST */
+enum pmu_pdid {
+ PD_GPU,
+ PD_NPU,
+ PD_VPU,
+ PD_RKVENC,
+ PD_RKVDEC,
+ PD_RGA,
+ PD_VI,
+ PD_VO,
+ PD_PIPE,
+ PD_CENTER,
+ PD_END
+};
+
+/* PMU_PWR_CON */
+enum pmu_pwr_con {
+ POWRMODE_EN,
+ DSU_BYPASS,
+ BUS_BYPASS = 4,
+ DDR_BYPASS,
+ PWRDN_BYPASS,
+ CRU_BYPASS,
+ CPU0_BYPASS,
+ CPU1_BYPASS,
+ CPU2_BYPASS,
+ CPU3_BYPASS,
+ PMU_SLEEP_LOW = 15,
+};
+
+/* PMU_CRU_PWR_CON */
+enum pmu_cru_pwr_con {
+ ALIVE_32K_ENA,
+ OSC_DIS_ENA,
+ WAKEUP_RST_ENA,
+ INPUT_CLAMP_ENA,
+
+ ALIVE_OSC_ENA,
+ POWER_OFF_ENA,
+ PWM_SWITCH_ENA,
+ PWM_GPIO_IOE_ENA,
+
+ PWM_SWITCH_IOUT,
+ PD_BUS_CLK_SRC_GATE_ENA,
+ PD_PERI_CLK_SRC_GATE_ENA,
+ PD_PMU_CLK_SRC_GATE_ENA,
+
+ PMUMEM_CLK_SRC_GATE_ENA,
+ PWR_CON_END
+};
+
+/* PMU_PLLPD_CON */
+enum pmu_pllpd_con {
+ APLL_PD_ENA,
+ DPLL_PD_ENA,
+ CPLL_PD_ENA,
+ GPLL_PD_ENA,
+ MPLL_PD_ENA,
+ NPLL_PD_ENA,
+ HPLL_PD_ENA,
+ PPLL_PD_ENA,
+ VPLL_PD_ENA,
+ PLL_PD_END
+};
+
+/* PMU_DSU_PWR_CON */
+enum pmu_dsu_pwr_con {
+ DSU_PWRDN_ENA = 2,
+ DSU_PWROFF_ENA,
+ DSU_RET_ENA = 6,
+ CLUSTER_CLK_SRC_GATE_ENA,
+ DSU_PWR_CON_END
+};
+
+enum cpu_power_state {
+ CPU_POWER_ON,
+ CPU_POWER_OFF,
+ CPU_EMULATION_OFF,
+ CPU_RETENTION,
+ CPU_DEBUG
+};
+
+enum dsu_power_state {
+ DSU_POWER_ON,
+ CLUSTER_TRANSFER_IDLE,
+ DSU_POWER_DOWN,
+ DSU_OFF,
+ DSU_WAKEUP,
+ DSU_POWER_UP,
+ CLUSTER_TRANSFER_RESUME,
+ DSU_FUNCTION_RETENTION
+};
+
+enum pmu_wakeup_int_con {
+ WAKEUP_CPU0_INT_EN,
+ WAKEUP_CPU1_INT_EN,
+ WAKEUP_CPU2_INT_EN,
+ WAKEUP_CPU3_INT_EN,
+ WAKEUP_GPIO0_INT_EN,
+ WAKEUP_UART0_EN,
+ WAKEUP_SDMMC0_EN,
+ WAKEUP_SDMMC1_EN,
+ WAKEUP_SDMMC2_EN,
+ WAKEUP_USB_EN,
+ WAKEUP_PCIE_EN,
+ WAKEUP_VAD_EN,
+ WAKEUP_TIMER_EN,
+ WAKEUP_PWM0_EN,
+ WAKEUP_TIMEROUT_EN,
+ WAKEUP_MCU_SFT_EN,
+};
+
+enum pmu_wakeup_int_st {
+ WAKEUP_CPU0_INT_ST,
+ WAKEUP_CPU1_INT_ST,
+ WAKEUP_CPU2_INT_ST,
+ WAKEUP_CPU3_INT_ST,
+ WAKEUP_GPIO0_INT_ST,
+ WAKEUP_UART0_ST,
+ WAKEUP_SDMMC0_ST,
+ WAKEUP_SDMMC1_ST,
+ WAKEUP_SDMMC2_ST,
+ WAKEUP_USB_ST,
+ WAKEUP_PCIE_ST,
+ WAKEUP_VAD_ST,
+ WAKEUP_TIMER_ST,
+ WAKEUP_PWM0_ST,
+ WAKEUP_TIMEOUT_ST,
+ WAKEUP_SYS_INT_ST,
+};
+
+enum pmu_bus_idle_con0 {
+ IDLE_REQ_MSCH,
+ IDLE_REQ_GPU,
+ IDLE_REQ_NPU,
+ IDLE_REQ_VI,
+ IDLE_REQ_VO,
+ IDLE_REQ_RGA,
+ IDLE_REQ_VPU,
+ IDLE_REQ_RKVENC,
+ IDLE_REQ_RKVDEC,
+ IDLE_REQ_GIC_AUDIO,
+ IDLE_REQ_PHP,
+ IDLE_REQ_PIPE,
+ IDLE_REQ_SECURE_FLASH,
+ IDLE_REQ_PERIMID,
+ IDLE_REQ_USB,
+ IDLE_REQ_BUS,
+};
+
+enum pmu_bus_idle_con1 {
+ IDLE_REQ_TOP1,
+ IDLE_REQ_TOP2,
+ IDLE_REQ_PMU,
+};
+
+enum pmu_pwr_gate_con {
+ PD_GPU_DWN_ENA,
+ PD_NPU_DWN_ENA,
+ PD_VPU_DWN_ENA,
+ PD_RKVENC_DWN_ENA,
+
+ PD_RKVDEC_DWN_ENA,
+ PD_RGA_DWN_ENA,
+ PD_VI_DWN_ENA,
+ PD_VO_DWN_ENA,
+
+ PD_PIPE_DWN_ENA,
+ PD_CENTER_DWN_ENA,
+};
+
+enum pmu_ddr_pwr_con {
+ DDR_SREF_ENA,
+ DDRIO_RET_ENTER_ENA,
+ DDRIO_RET_EXIT_ENA = 2,
+ DDRPHY_AUTO_GATING_ENA = 4,
+};
+
+enum pmu_vol_gate_soft_con {
+ VD_GPU_ENA,
+ VD_NPU_ENA,
+};
+
+#endif /* __PMU_H__ */
diff --git a/plat/rockchip/rk3568/drivers/soc/soc.c b/plat/rockchip/rk3568/drivers/soc/soc.c
new file mode 100644
index 0000000..2af3887
--- /dev/null
+++ b/plat/rockchip/rk3568/drivers/soc/soc.c
@@ -0,0 +1,103 @@
+/*
+ * Copyright (c) 2023, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <common/debug.h>
+#include <lib/xlat_tables/xlat_tables_v2.h>
+#include <mmio.h>
+#include <platform_def.h>
+
+#include <soc.h>
+
+const mmap_region_t plat_rk_mmap[] = {
+ MAP_REGION_FLAT(RKFPGA_DEV_RNG0_BASE, RKFPGA_DEV_RNG0_SIZE,
+ MT_DEVICE | MT_RW | MT_SECURE),
+ MAP_REGION_FLAT(PMUSRAM_BASE, PMUSRAM_SIZE,
+ MT_MEMORY | MT_RW | MT_SECURE),
+
+ { 0 }
+};
+
+/* The RockChip power domain tree descriptor */
+const unsigned char rockchip_power_domain_tree_desc[] = {
+ /* No of root nodes */
+ PLATFORM_SYSTEM_COUNT,
+ /* No of children for the root node */
+ PLATFORM_CLUSTER_COUNT,
+ /* No of children for the first cluster node */
+ PLATFORM_CLUSTER0_CORE_COUNT,
+};
+
+static void secure_timer_init(void)
+{
+ mmio_write_32(STIMER0_CHN_BASE(1) + TIMER_CONTROL_REG, TIMER_DIS);
+ mmio_write_32(STIMER0_CHN_BASE(1) + TIMER_LOAD_COUNT0, 0xffffffff);
+ mmio_write_32(STIMER0_CHN_BASE(1) + TIMER_LOAD_COUNT1, 0xffffffff);
+
+ /* auto reload & enable the timer */
+ mmio_write_32(STIMER0_CHN_BASE(1) + TIMER_CONTROL_REG, TIMER_EN);
+}
+
+static void sgrf_init(void)
+{
+ mmio_write_32(SGRF_BASE + SGRF_FIREWALL_SLV_CON(0), 0xffff0000);
+ mmio_write_32(SGRF_BASE + SGRF_FIREWALL_SLV_CON(1), 0xffff0000);
+ mmio_write_32(SGRF_BASE + SGRF_FIREWALL_SLV_CON(2), 0xffff0000);
+ mmio_write_32(SGRF_BASE + SGRF_FIREWALL_SLV_CON(3), 0xffff0000);
+ mmio_write_32(SGRF_BASE + SGRF_FIREWALL_SLV_CON(4), 0xffff0000);
+ mmio_write_32(SGRF_BASE + SGRF_FIREWALL_SLV_CON(5), 0xffff0000);
+ mmio_write_32(SGRF_BASE + SGRF_FIREWALL_SLV_CON(6), 0xffff0000);
+ mmio_write_32(SGRF_BASE + SGRF_FIREWALL_SLV_CON(7), 0xffff0000);
+ mmio_write_32(SGRF_BASE + SGRF_FIREWALL_SLV_CON(8), 0xffff0000);
+
+ mmio_write_32(DDRSGRF_BASE + FIREWALL_DDR_FW_DDR_CON_REG, 0xffff0000);
+}
+
+static void set_pll_slow_mode(uint32_t clk_pll)
+{
+ mmio_write_32(CRU_BASE + CRU_MODE_CON00, 0x03 << (16 + clk_pll * 2));
+}
+
+static void __dead2 soc_global_soft_reset(void)
+{
+ set_pll_slow_mode(CLK_CPLL);
+ set_pll_slow_mode(CLK_GPLL);
+ set_pll_slow_mode(CLK_NPLL);
+ set_pll_slow_mode(CLK_VPLL);
+ set_pll_slow_mode(CLK_USBPLL);
+ set_pll_slow_mode(CLK_APLL);
+ mmio_write_32(PMUCRU_BASE + PMUCRU_MODE_CON00, 0x000f0000);
+
+ dsb();
+ mmio_write_32(CRU_BASE + CRU_GLB_SRST_FST, GLB_SRST_FST_CFG_VAL);
+ /*
+ * Maybe the HW needs some times to reset the system,
+ * so we do not hope the core to excute valid codes.
+ */
+ while (1) {
+ ;
+ }
+}
+
+static void rockchip_system_reset_init(void)
+{
+ mmio_write_32(GRF_BASE + 0x0508, 0x00100010);
+ mmio_write_32(CRU_BASE + 0x00dc, 0x01030103);
+}
+
+void __dead2 rockchip_soc_soft_reset(void)
+{
+ soc_global_soft_reset();
+}
+
+void plat_rockchip_soc_init(void)
+{
+ secure_timer_init();
+ sgrf_init();
+ rockchip_system_reset_init();
+ NOTICE("BL31: Rockchip release version: v%d.%d\n",
+ MAJOR_VERSION, MINOR_VERSION);
+}
+
diff --git a/plat/rockchip/rk3568/drivers/soc/soc.h b/plat/rockchip/rk3568/drivers/soc/soc.h
new file mode 100644
index 0000000..41a2586
--- /dev/null
+++ b/plat/rockchip/rk3568/drivers/soc/soc.h
@@ -0,0 +1,63 @@
+/*
+ * Copyright (c) 2023, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef __SOC_H__
+#define __SOC_H__
+
+#define RKFPGA_DEV_RNG0_BASE 0xf8000000
+#define RKFPGA_DEV_RNG0_SIZE 0x07fff000
+
+#define CRU_MODE_CON00 0x00c0
+#define PMUCRU_MODE_CON00 0x0080
+
+#define CRU_GLB_SRST_FST 0x00d4
+#define GLB_SRST_FST_CFG_VAL 0xfdb9
+
+#define PMU_GRF_GPIO0A_IOMUX_L 0x00
+#define PMU_GRF_SOC_CON(i) (0x0100 + i * 4)
+
+#define CRU_SOFTRST_CON 0x300
+#define CRU_SOFTRSTS_CON(n) (CRU_SOFTRST_CON + ((n) * 4))
+#define CRU_SOFTRSTS_CON_CNT 26
+#define GRF_DDR_CON3 0x000c
+#define SGRF_FIREWALL_SLV_CON(i) (0x240 + i * 4)
+
+#define FIREWALL_DDR_FW_DDR_CON_REG 0x80
+
+ /* low 32 bits */
+#define TIMER_LOAD_COUNT0 0x00
+#define TIMER_LOAD_COUNT1 0x04
+#define TIMER_CURRENT_VALUE0 0x08
+#define TIMER_CURRENT_VALUE1 0x0c
+#define TIMER_CONTROL_REG 0x10
+#define TIMER_INTSTATUS 0x18
+#define TIMER_DIS 0x0
+#define TIMER_EN 0x1
+#define STIMER0_CHN_BASE(n) (STIME_BASE + 0x20 * (n))
+
+#define PMU_GRF_GPIO0B_IOMUX_L 0x0008
+#define PMUCRU_PMUCLKSEL_CON00 0x0100
+#define PMUPVTM_BASE 0xfdd80000
+#define PVTM_CON0 0x0004
+#define PVTM_CON1 0x0008
+#define PVTM_STATUS0 0x0080
+#define PVTM_STATUS1 0x0084
+#define PMUCRU_PMUGATE_CON01 0x0184
+#define PVTM_CALC_CNT 0x200
+#define PMU_GRF_DLL_CON0 0x0180
+
+enum cru_mode_con00 {
+ CLK_APLL,
+ CLK_DPLL,
+ CLK_CPLL,
+ CLK_GPLL,
+ CLK_REVSERVED,
+ CLK_NPLL,
+ CLK_VPLL,
+ CLK_USBPLL,
+};
+
+#endif /* __SOC_H__ */
diff --git a/plat/rockchip/rk3568/include/plat.ld.S b/plat/rockchip/rk3568/include/plat.ld.S
new file mode 100644
index 0000000..ddd584d
--- /dev/null
+++ b/plat/rockchip/rk3568/include/plat.ld.S
@@ -0,0 +1,36 @@
+/*
+ * Copyright (c) 2023, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+#ifndef ROCKCHIP_PLAT_LD_S
+#define ROCKCHIP_PLAT_LD_S
+
+MEMORY {
+ PMUSRAM (rwx): ORIGIN = PMUSRAM_BASE, LENGTH = PMUSRAM_RSIZE
+}
+
+SECTIONS
+{
+ . = PMUSRAM_BASE;
+
+ /*
+ * pmu_cpuson_entrypoint request address
+ * align 64K when resume, so put it in the
+ * start of pmusram
+ */
+ .pmusram : {
+ ASSERT(. == ALIGN(64 * 1024),
+ ".pmusram.entry request 64K aligned.");
+ KEEP(*(.pmusram.entry))
+
+ __bl31_pmusram_text_start = .;
+ *(.pmusram.text)
+ *(.pmusram.rodata)
+ __bl31_pmusram_text_end = .;
+ __bl31_pmusram_data_start = .;
+ *(.pmusram.data)
+ __bl31_pmusram_data_end = .;
+ } >PMUSRAM
+}
+#endif /* ROCKCHIP_PLAT_LD_S */
diff --git a/plat/rockchip/rk3568/include/plat_sip_calls.h b/plat/rockchip/rk3568/include/plat_sip_calls.h
new file mode 100644
index 0000000..6acb876
--- /dev/null
+++ b/plat/rockchip/rk3568/include/plat_sip_calls.h
@@ -0,0 +1,12 @@
+/*
+ * Copyright (c) 2023, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef __PLAT_SIP_CALLS_H__
+#define __PLAT_SIP_CALLS_H__
+
+#define RK_PLAT_SIP_NUM_CALLS 0
+
+#endif /* __PLAT_SIP_CALLS_H__ */
diff --git a/plat/rockchip/rk3568/include/platform_def.h b/plat/rockchip/rk3568/include/platform_def.h
new file mode 100644
index 0000000..19363a4
--- /dev/null
+++ b/plat/rockchip/rk3568/include/platform_def.h
@@ -0,0 +1,136 @@
+/*
+ * Copyright (c) 2023, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef __PLATFORM_DEF_H__
+#define __PLATFORM_DEF_H__
+
+#include <arch.h>
+#include <common_def.h>
+#include <rk3568_def.h>
+
+#define DEBUG_XLAT_TABLE 0
+
+/*******************************************************************************
+ * Platform binary types for linking
+ ******************************************************************************/
+#define PLATFORM_LINKER_FORMAT "elf64-littleaarch64"
+#define PLATFORM_LINKER_ARCH aarch64
+
+/*******************************************************************************
+ * Generic platform constants
+ ******************************************************************************/
+
+/* Size of cacheable stacks */
+#if DEBUG_XLAT_TABLE
+#define PLATFORM_STACK_SIZE 0x800
+#elif IMAGE_BL1
+#define PLATFORM_STACK_SIZE 0x440
+#elif IMAGE_BL2
+#define PLATFORM_STACK_SIZE 0x400
+#elif IMAGE_BL31
+#define PLATFORM_STACK_SIZE 0x800
+#elif IMAGE_BL32
+#define PLATFORM_STACK_SIZE 0x440
+#endif
+
+#define FIRMWARE_WELCOME_STR "Booting Trusted Firmware\n"
+
+#define PLATFORM_SYSTEM_COUNT 1
+#define PLATFORM_CLUSTER_COUNT 1
+#define PLATFORM_CLUSTER0_CORE_COUNT 4
+
+#define PLATFORM_CLUSTER1_CORE_COUNT 0
+#define PLATFORM_CORE_COUNT (PLATFORM_CLUSTER1_CORE_COUNT + \
+ PLATFORM_CLUSTER0_CORE_COUNT)
+
+#define PLATFORM_NUM_AFFS (PLATFORM_SYSTEM_COUNT + \
+ PLATFORM_CLUSTER_COUNT + \
+ PLATFORM_CORE_COUNT)
+
+#define PLAT_MAX_PWR_LVL MPIDR_AFFLVL2
+
+#define PLAT_RK_CLST_TO_CPUID_SHIFT 8
+
+/*
+ * 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 1
+
+/*
+ * This macro defines the deepest power down states possible. Any state ID
+ * higher than this is invalid.
+ */
+#define PLAT_MAX_OFF_STATE 2
+/*******************************************************************************
+ * Platform memory map related constants
+ ******************************************************************************/
+/* TF txet, ro, rw, Size: 512KB */
+#define TZRAM_BASE (0x0)
+#define TZRAM_SIZE (0x100000)
+
+/*******************************************************************************
+ * BL31 specific defines.
+ ******************************************************************************/
+/*
+ * Put BL3-1 at the top of the Trusted RAM
+ */
+#define BL31_BASE (TZRAM_BASE + 0x40000)
+#define BL31_LIMIT (TZRAM_BASE + TZRAM_SIZE)
+
+/*******************************************************************************
+ * Platform specific page table and MMU setup constants
+ ******************************************************************************/
+#define PLAT_PHY_ADDR_SPACE_SIZE (1ULL << 32)
+#define PLAT_VIRT_ADDR_SPACE_SIZE (1ULL << 32)
+
+#define ADDR_SPACE_SIZE (1ull << 32)
+#define MAX_XLAT_TABLES 18
+#define MAX_MMAP_REGIONS 27
+
+/*******************************************************************************
+ * Declarations and constants to access the mailboxes safely. Each mailbox is
+ * 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. Such alignment ensures that two maiboxes do not sit on the same cache
+ * line at any cache level. They could belong to different cpus/clusters &
+ * get written while being protected by different locks causing corruption of
+ * a valid mailbox address.
+ ******************************************************************************/
+#define CACHE_WRITEBACK_SHIFT 6
+#define CACHE_WRITEBACK_GRANULE (1 << CACHE_WRITEBACK_SHIFT)
+
+/*
+ * Define GICD and GICC and GICR base
+ */
+#define PLAT_RK_GICD_BASE PLAT_GICD_BASE
+#define PLAT_RK_GICC_BASE PLAT_GICC_BASE
+#define PLAT_RK_GICR_BASE PLAT_GICR_BASE
+
+/*
+ * Define a list of Group 1 Secure and Group 0 interrupts as per GICv3
+ * terminology. On a GICv2 system or mode, the lists will be merged and treated
+ * as Group 0 interrupts.
+ */
+
+#define PLAT_RK_GICV3_G1S_IRQS \
+ INTR_PROP_DESC(RK_IRQ_SEC_PHY_TIMER, GIC_HIGHEST_SEC_PRIORITY, \
+ INTR_GROUP1S, GIC_INTR_CFG_LEVEL)
+
+#define PLAT_RK_GICV3_G0_IRQS \
+ INTR_PROP_DESC(RK_IRQ_SEC_SGI_6, GIC_HIGHEST_SEC_PRIORITY, \
+ INTR_GROUP0, GIC_INTR_CFG_LEVEL)
+
+#define PLAT_RK_UART_BASE FPGA_UART_BASE
+#define PLAT_RK_UART_CLOCK FPGA_UART_CLOCK
+#define PLAT_RK_UART_BAUDRATE FPGA_BAUDRATE
+
+#define PLAT_RK_PRIMARY_CPU 0x0
+
+#define ATAGS_PHYS_SIZE 0x2000
+#define ATAGS_PHYS_BASE (0x200000 - ATAGS_PHYS_SIZE)/* [2M-8K, 2M] */
+
+#endif /* __PLATFORM_DEF_H__ */
diff --git a/plat/rockchip/rk3568/plat_sip_calls.c b/plat/rockchip/rk3568/plat_sip_calls.c
new file mode 100644
index 0000000..b0f3a03
--- /dev/null
+++ b/plat/rockchip/rk3568/plat_sip_calls.c
@@ -0,0 +1,29 @@
+/*
+ * Copyright (c) 2023, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <assert.h>
+#include <errno.h>
+
+#include <common/debug.h>
+#include <common/runtime_svc.h>
+#include <lib/mmio.h>
+#include <platform_def.h>
+
+#include <plat_sip_calls.h>
+#include <rockchip_sip_svc.h>
+
+uintptr_t rockchip_plat_sip_handler(uint32_t smc_fid,
+ u_register_t x1,
+ u_register_t x2,
+ u_register_t x3,
+ u_register_t x4,
+ void *cookie,
+ void *handle,
+ u_register_t flags)
+{
+ ERROR("%s: unhandled SMC (0x%x)\n", __func__, smc_fid);
+ SMC_RET1(handle, SMC_UNK);
+}
diff --git a/plat/rockchip/rk3568/platform.mk b/plat/rockchip/rk3568/platform.mk
new file mode 100644
index 0000000..1155ff8
--- /dev/null
+++ b/plat/rockchip/rk3568/platform.mk
@@ -0,0 +1,96 @@
+#
+# Copyright (c) 2023, ARM Limited and Contributors. All rights reserved.
+#
+# SPDX-License-Identifier: BSD-3-Clause
+#
+
+RK_PLAT := plat/rockchip
+RK_PLAT_SOC := ${RK_PLAT}/${PLAT}
+RK_PLAT_COMMON := ${RK_PLAT}/common
+
+DISABLE_BIN_GENERATION := 1
+GICV3_SUPPORT_GIC600 := 1
+include lib/coreboot/coreboot.mk
+include lib/libfdt/libfdt.mk
+include lib/xlat_tables_v2/xlat_tables.mk
+# GIC-600 configuration
+GICV3_IMPL := GIC600
+# Include GICv3 driver files
+include drivers/arm/gic/v3/gicv3.mk
+
+PLAT_INCLUDES := -Iinclude/bl31 \
+ -Iinclude/common \
+ -Iinclude/drivers \
+ -Iinclude/drivers/arm \
+ -Iinclude/drivers/auth \
+ -Iinclude/drivers/io \
+ -Iinclude/drivers/ti/uart \
+ -Iinclude/lib \
+ -Iinclude/lib/cpus/${ARCH} \
+ -Iinclude/lib/el3_runtime \
+ -Iinclude/lib/pmf \
+ -Iinclude/lib/psci \
+ -Iinclude/plat/common \
+ -Iinclude/services \
+ -Iinclude/plat/common/ \
+ -Idrivers/arm/gic/v3/ \
+ -I${RK_PLAT_COMMON}/ \
+ -I${RK_PLAT_COMMON}/pmusram/ \
+ -I${RK_PLAT_COMMON}/include/ \
+ -I${RK_PLAT_COMMON}/drivers/pmu/ \
+ -I${RK_PLAT_COMMON}/drivers/parameter/ \
+ -I${RK_PLAT_SOC}/ \
+ -I${RK_PLAT_SOC}/drivers/pmu/ \
+ -I${RK_PLAT_SOC}/drivers/soc/ \
+ -I${RK_PLAT_SOC}/include/
+
+RK_GIC_SOURCES := ${GICV3_SOURCES} \
+ plat/common/plat_gicv3.c \
+ ${RK_PLAT}/common/rockchip_gicv3.c
+
+PLAT_BL_COMMON_SOURCES := ${XLAT_TABLES_LIB_SRCS} \
+ common/desc_image_load.c \
+ plat/common/aarch64/crash_console_helpers.S \
+ lib/bl_aux_params/bl_aux_params.c \
+ plat/common/plat_psci_common.c
+
+ifneq (${ENABLE_STACK_PROTECTOR},0)
+PLAT_BL_COMMON_SOURCES += ${RK_PLAT_COMMON}/rockchip_stack_protector.c
+endif
+
+BL31_SOURCES += ${RK_GIC_SOURCES} \
+ drivers/arm/cci/cci.c \
+ lib/cpus/aarch64/cortex_a55.S \
+ drivers/ti/uart/aarch64/16550_console.S \
+ drivers/delay_timer/delay_timer.c \
+ drivers/delay_timer/generic_delay_timer.c \
+ $(LIBFDT_SRCS) \
+ ${RK_PLAT_COMMON}/aarch64/plat_helpers.S \
+ ${RK_PLAT_COMMON}/bl31_plat_setup.c \
+ ${RK_PLAT_COMMON}/params_setup.c \
+ ${RK_PLAT_COMMON}/plat_pm.c \
+ ${RK_PLAT_COMMON}/plat_topology.c \
+ ${RK_PLAT_COMMON}/rockchip_sip_svc.c \
+ ${RK_PLAT_COMMON}/pmusram/cpus_on_fixed_addr.S \
+ ${RK_PLAT_COMMON}/drivers/parameter/ddr_parameter.c \
+ ${RK_PLAT_COMMON}/aarch64/platform_common.c \
+ ${RK_PLAT_SOC}/drivers/soc/soc.c \
+ ${RK_PLAT_SOC}/drivers/pmu/pmu.c \
+ ${RK_PLAT_SOC}/plat_sip_calls.c
+
+ENABLE_PLAT_COMPAT := 0
+MULTI_CONSOLE_API := 1
+# System coherency is managed in hardware
+HW_ASSISTED_COHERENCY := 1
+#Enable errata for cortex_a55
+ERRATA_A55_1530923 := 1
+
+# When building for systems with hardware-assisted coherency, there's no need to
+# use USE_COHERENT_MEM. Require that USE_COHERENT_MEM must be set to 0 too.
+USE_COHERENT_MEM := 0
+
+$(eval $(call add_define,PLAT_SKIP_OPTEE_S_EL1_INT_REGISTER))
+$(eval $(call add_define,PLAT_EXTRA_LD_SCRIPT))
+
+# Do not enable SVE
+ENABLE_SVE_FOR_NS := 0
diff --git a/plat/rockchip/rk3568/rk3568_def.h b/plat/rockchip/rk3568/rk3568_def.h
new file mode 100644
index 0000000..0d1e5d1
--- /dev/null
+++ b/plat/rockchip/rk3568/rk3568_def.h
@@ -0,0 +1,104 @@
+/*
+ * Copyright (c) 2023, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef __PLAT_DEF_H__
+#define __PLAT_DEF_H__
+
+#define MAJOR_VERSION (1)
+#define MINOR_VERSION (0)
+
+#define SIZE_K(n) ((n) * 1024)
+
+/* Special value used to verify platform parameters from BL2 to BL3-1 */
+#define RK_BL31_PLAT_PARAM_VAL 0x0f1e2d3c4b5a6978ULL
+
+#define GIC600_BASE 0xfd400000
+#define GIC600_SIZE SIZE_K(64)
+
+#define PMUSGRF_BASE 0xfdc00000
+#define SYSSGRF_BASE 0xfdc10000
+#define PMUGRF_BASE 0xfdc20000
+#define CPUGRF_BASE 0xfdc30000
+#define DDRGRF_BASE 0xfdc40000
+#define PIPEGRF_BASE 0xfdc50000
+#define GRF_BASE 0xfdc60000
+#define PIPEPHY_GRF0 0xfdc70000
+#define PIPEPHY_GRF1 0xfdc80000
+#define PIPEPHY_GRF2 0xfdc90000
+#define USBPHY_U3_GRF 0xfdca0000
+#define USB2PHY_U2_GRF 0xfdca8000
+#define EDPPHY_GRF 0xfdcb0000
+#define SYSSRAM_BASE 0xfdcc0000
+#define PCIE30PHY_GRF 0xfdcb8000
+#define USBGRF_BASE 0xfdcf0000
+
+#define PMUCRU_BASE 0xfdd00000
+#define SCRU_BASE 0xfdd10000
+#define SGRF_BASE 0xfdd18000
+#define STIME_BASE 0xfdd1c000
+#define CRU_BASE 0xfdd20000
+#define PMUSCRU_BASE 0xfdd30000
+#define I2C0_BASE 0xfdd40000
+
+#define UART0_BASE 0xfdd50000
+#define GPIO0_BASE 0xfdd60000
+#define PMUPVTM_BASE 0xfdd80000
+#define PMU_BASE 0xfdd90000
+#define PMUSRAM_BASE 0xfdcd0000
+#define PMUSRAM_SIZE SIZE_K(128)
+#define PMUSRAM_RSIZE SIZE_K(8)
+
+#define DDRSGRF_BASE 0xfe200000
+#define UART1_BASE 0xfe650000
+#define UART2_BASE 0xfe660000
+#define GPIO1_BASE 0xfe740000
+#define GPIO2_BASE 0xfe750000
+#define GPIO3_BASE 0xfe760000
+#define GPIO4_BASE 0xfe770000
+
+#define REMAP_BASE 0xffff0000
+#define REMAP_SIZE SIZE_K(64)
+/**************************************************************************
+ * UART related constants
+ **************************************************************************/
+#define FPGA_UART_BASE UART2_BASE
+#define FPGA_BAUDRATE 1500000
+#define FPGA_UART_CLOCK 24000000
+
+/******************************************************************************
+ * System counter frequency related constants
+ ******************************************************************************/
+#define SYS_COUNTER_FREQ_IN_TICKS 24000000
+#define SYS_COUNTER_FREQ_IN_MHZ 24
+
+/******************************************************************************
+ * GIC-600 & interrupt handling related constants
+ ******************************************************************************/
+
+/* Base rk_platform compatible GIC memory map */
+#define PLAT_GICD_BASE GIC600_BASE
+#define PLAT_GICC_BASE 0
+#define PLAT_GICR_BASE (GIC600_BASE + 0x60000)
+
+/******************************************************************************
+ * sgi, ppi
+ ******************************************************************************/
+#define RK_IRQ_SEC_PHY_TIMER 29
+
+#define RK_IRQ_SEC_SGI_0 8
+#define RK_IRQ_SEC_SGI_1 9
+#define RK_IRQ_SEC_SGI_2 10
+#define RK_IRQ_SEC_SGI_3 11
+#define RK_IRQ_SEC_SGI_4 12
+#define RK_IRQ_SEC_SGI_5 13
+#define RK_IRQ_SEC_SGI_6 14
+#define RK_IRQ_SEC_SGI_7 15
+
+#define SHARE_MEM_BASE 0x100000/* [1MB, 1MB+60K]*/
+#define SHARE_MEM_PAGE_NUM 15
+#define SHARE_MEM_SIZE SIZE_K(SHARE_MEM_PAGE_NUM * 4)
+
+#endif /* __PLAT_DEF_H__ */
diff --git a/plat/st/stm32mp1/bl2_plat_setup.c b/plat/st/stm32mp1/bl2_plat_setup.c
index bd3903d..24ecb32 100644
--- a/plat/st/stm32mp1/bl2_plat_setup.c
+++ b/plat/st/stm32mp1/bl2_plat_setup.c
@@ -440,8 +440,7 @@
paged_mem_params = get_bl_mem_params_node(BL32_EXTRA2_IMAGE_ID);
if (paged_mem_params != NULL) {
paged_mem_params->image_info.image_base = STM32MP_DDR_BASE +
- (dt_get_ddr_size() - STM32MP_DDR_S_SIZE -
- STM32MP_DDR_SHMEM_SIZE);
+ (dt_get_ddr_size() - STM32MP_DDR_S_SIZE);
paged_mem_params->image_info.image_max_size =
STM32MP_DDR_S_SIZE;
}
diff --git a/plat/st/stm32mp1/platform.mk b/plat/st/stm32mp1/platform.mk
index ddc5289..c411edf 100644
--- a/plat/st/stm32mp1/platform.mk
+++ b/plat/st/stm32mp1/platform.mk
@@ -1,5 +1,5 @@
#
-# Copyright (c) 2015-2023, Arm Limited and Contributors. All rights reserved.
+# Copyright (c) 2015-2024, Arm Limited and Contributors. All rights reserved.
#
# SPDX-License-Identifier: BSD-3-Clause
#
@@ -60,11 +60,6 @@
# STM32 image header version v1.0
STM32_HEADER_VERSION_MAJOR:= 1
STM32_HEADER_VERSION_MINOR:= 0
-
-# Add OP-TEE reserved shared memory area in mapping
-STM32MP15_OPTEE_RSV_SHM := 0
-$(eval $(call add_defines,STM32MP15_OPTEE_RSV_SHM))
-
STM32MP_CRYPTO_ROM_LIB := 1
# Decryption support
diff --git a/plat/st/stm32mp1/stm32mp1_fip_def.h b/plat/st/stm32mp1/stm32mp1_fip_def.h
index e37e2e6..165f152 100644
--- a/plat/st/stm32mp1/stm32mp1_fip_def.h
+++ b/plat/st/stm32mp1/stm32mp1_fip_def.h
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2021-2023, STMicroelectronics - All Rights Reserved
+ * Copyright (C) 2021-2024, STMicroelectronics - All Rights Reserved
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -7,13 +7,7 @@
#ifndef STM32MP1_FIP_DEF_H
#define STM32MP1_FIP_DEF_H
-#if STM32MP15_OPTEE_RSV_SHM
-#define STM32MP_DDR_S_SIZE U(0x01E00000) /* 30 MB */
-#define STM32MP_DDR_SHMEM_SIZE U(0x00200000) /* 2 MB */
-#else
#define STM32MP_DDR_S_SIZE U(0x02000000) /* 32 MB */
-#define STM32MP_DDR_SHMEM_SIZE U(0) /* empty */
-#endif
#if TRUSTED_BOARD_BOOT && !STM32MP_USE_EXTERNAL_HEAP
#if STM32MP15
diff --git a/plat/xilinx/common/include/pm_api_sys.h b/plat/xilinx/common/include/pm_api_sys.h
index 3fcb62f..ffee805 100644
--- a/plat/xilinx/common/include/pm_api_sys.h
+++ b/plat/xilinx/common/include/pm_api_sys.h
@@ -1,6 +1,6 @@
/*
* Copyright (c) 2019-2022, Xilinx, Inc. All rights reserved.
- * Copyright (c) 2022-2023, Advanced Micro Devices, Inc. All rights reserved.
+ * Copyright (c) 2022-2024, Advanced Micro Devices, Inc. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -53,9 +53,6 @@
uint32_t flag);
enum pm_ret_status pm_system_shutdown(uint32_t type, uint32_t subtype,
uint32_t flag);
-enum pm_ret_status pm_api_ioctl(uint32_t device_id, uint32_t ioctl_id,
- uint32_t arg1, uint32_t arg2, uint32_t arg3,
- uint32_t *value, uint32_t flag);
enum pm_ret_status pm_query_data(uint32_t qid, uint32_t arg1, uint32_t arg2,
uint32_t arg3, uint32_t *data, uint32_t flag);
uint32_t pm_get_shutdown_scope(void);
diff --git a/plat/xilinx/common/include/pm_defs.h b/plat/xilinx/common/include/pm_defs.h
index c1872d0..055fa3d 100644
--- a/plat/xilinx/common/include/pm_defs.h
+++ b/plat/xilinx/common/include/pm_defs.h
@@ -1,6 +1,6 @@
/*
* Copyright (c) 2019-2022, Xilinx, Inc. All rights reserved.
- * Copyright (c) 2022-2023, Advanced Micro Devices, Inc. All rights reserved.
+ * Copyright (c) 2022-2024, Advanced Micro Devices, Inc. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -95,8 +95,6 @@
IOCTL_GET_LAST_RESET_REASON = 23,
/* AI engine NPI ISR clear */
IOCTL_AIE_ISR_CLEAR = 24,
- /* Register SGI to TF-A */
- IOCTL_SET_SGI = 25,
};
/**
diff --git a/plat/xilinx/common/pm_service/pm_api_sys.c b/plat/xilinx/common/pm_service/pm_api_sys.c
index 36ea8ed..0a6e810 100644
--- a/plat/xilinx/common/pm_service/pm_api_sys.c
+++ b/plat/xilinx/common/pm_service/pm_api_sys.c
@@ -1,6 +1,6 @@
/*
* Copyright (c) 2019-2022, Xilinx, Inc. All rights reserved.
- * Copyright (c) 2022-2023, Advanced Micro Devices, Inc. All rights reserved.
+ * Copyright (c) 2022-2024, Advanced Micro Devices, Inc. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -287,112 +287,6 @@
}
/**
- * pm_pll_set_param() - Set PLL parameter.
- * @clk_id: PLL clock ID.
- * @param: PLL parameter ID.
- * @value: Value to set for PLL parameter.
- * @flag: 0 - Call from secure source.
- * 1 - Call from non-secure source.
- *
- * This API is deprecated and maintained here for backward compatibility.
- * New use of this API should be avoided for versal platform.
- * This API and its use cases will be removed for versal platform.
- *
- * Return: Returns status, either success or error+reason.
- *
- */
-enum pm_ret_status pm_pll_set_param(uint32_t clk_id, uint32_t param,
- uint32_t value, uint32_t flag)
-{
- uint32_t payload[PAYLOAD_ARG_CNT];
-
- /* Send request to the PMC */
- PM_PACK_PAYLOAD4(payload, LIBPM_MODULE_ID, flag, PM_PLL_SET_PARAMETER,
- clk_id, param, value);
-
- return pm_ipi_send_sync(primary_proc, payload, NULL, 0);
-}
-
-/**
- * pm_pll_get_param() - Get PLL parameter value.
- * @clk_id: PLL clock ID.
- * @param: PLL parameter ID.
- * @value: Buffer to store PLL parameter value.
- * @flag: 0 - Call from secure source.
- * 1 - Call from non-secure source.
- *
- * This API is deprecated and maintained here for backward compatibility.
- * New use of this API should be avoided for versal platform.
- * This API and its use cases will be removed for versal platform.
- *
- * Return: Returns status, either success or error+reason.
- *
- */
-enum pm_ret_status pm_pll_get_param(uint32_t clk_id, uint32_t param,
- uint32_t *value, uint32_t flag)
-{
- uint32_t payload[PAYLOAD_ARG_CNT];
-
- /* Send request to the PMC */
- PM_PACK_PAYLOAD3(payload, LIBPM_MODULE_ID, flag, PM_PLL_GET_PARAMETER,
- clk_id, param);
-
- return pm_ipi_send_sync(primary_proc, payload, value, 1);
-}
-
-/**
- * pm_pll_set_mode() - Set PLL mode.
- * @clk_id: PLL clock ID.
- * @mode: PLL mode.
- * @flag: 0 - Call from secure source.
- * 1 - Call from non-secure source.
- *
- * This API is deprecated and maintained here for backward compatibility.
- * New use of this API should be avoided for versal platform.
- * This API and its use cases will be removed for versal platform.
- *
- * Return: Returns status, either success or error+reason.
- *
- */
-enum pm_ret_status pm_pll_set_mode(uint32_t clk_id, uint32_t mode,
- uint32_t flag)
-{
- uint32_t payload[PAYLOAD_ARG_CNT];
-
- /* Send request to the PMC */
- PM_PACK_PAYLOAD3(payload, LIBPM_MODULE_ID, flag, PM_PLL_SET_MODE,
- clk_id, mode);
-
- return pm_ipi_send_sync(primary_proc, payload, NULL, 0);
-}
-
-/**
- * pm_pll_get_mode() - Get PLL mode.
- * @clk_id: PLL clock ID.
- * @mode: Buffer to store PLL mode.
- * @flag: 0 - Call from secure source.
- * 1 - Call from non-secure source.
- *
- * This API is deprecated and maintained here for backward compatibility.
- * New use of this API should be avoided for versal platform.
- * This API and its use cases will be removed for versal platform.
- *
- * Return: Returns status, either success or error+reason.
- *
- */
-enum pm_ret_status pm_pll_get_mode(uint32_t clk_id, uint32_t *mode,
- uint32_t flag)
-{
- uint32_t payload[PAYLOAD_ARG_CNT];
-
- /* Send request to the PMC */
- PM_PACK_PAYLOAD2(payload, LIBPM_MODULE_ID, flag, PM_PLL_GET_MODE,
- clk_id);
-
- return pm_ipi_send_sync(primary_proc, payload, mode, 1);
-}
-
-/**
* pm_force_powerdown() - PM call to request for another PU or subsystem to
* be powered down forcefully.
* @target: Device ID of the PU node to be forced powered down.
@@ -448,110 +342,6 @@
}
/**
- * pm_query_data() - PM API for querying firmware data.
- * @qid: The type of data to query.
- * @arg1: Argument 1 to requested query data call.
- * @arg2: Argument 2 to requested query data call.
- * @arg3: Argument 3 to requested query data call.
- * @data: Returned output data.
- * @flag: 0 - Call from secure source.
- * 1 - Call from non-secure source.
- *
- * This API is deprecated and maintained here for backward compatibility.
- * New use of this API should be avoided for versal platform.
- * This API and its use cases will be removed for versal platform.
- *
- * Return: 0 if success else non-zero error code of type
- * enum pm_ret_status.
- *
- */
-enum pm_ret_status pm_query_data(uint32_t qid, uint32_t arg1, uint32_t arg2,
- uint32_t arg3, uint32_t *data, uint32_t flag)
-{
- uint32_t ret;
- uint32_t version[PAYLOAD_ARG_CNT] = {0};
- uint32_t payload[PAYLOAD_ARG_CNT];
- uint32_t fw_api_version;
-
- /* Send request to the PMC */
- PM_PACK_PAYLOAD5(payload, LIBPM_MODULE_ID, flag, PM_QUERY_DATA, qid,
- arg1, arg2, arg3);
-
- ret = pm_feature_check((uint32_t)PM_QUERY_DATA, &version[0], flag);
- if (ret == PM_RET_SUCCESS) {
- fw_api_version = version[0] & 0xFFFFU;
- if ((fw_api_version == 2U) &&
- ((qid == XPM_QID_CLOCK_GET_NAME) ||
- (qid == XPM_QID_PINCTRL_GET_FUNCTION_NAME))) {
- ret = pm_ipi_send_sync(primary_proc, payload, data, PAYLOAD_ARG_CNT);
- if (ret == PM_RET_SUCCESS) {
- ret = data[0];
- data[0] = data[1];
- data[1] = data[2];
- data[2] = data[3];
- }
- } else {
- ret = pm_ipi_send_sync(primary_proc, payload, data, PAYLOAD_ARG_CNT);
- }
- }
- return ret;
-}
-/**
- * pm_api_ioctl() - PM IOCTL API for device control and configs.
- * @device_id: Device ID.
- * @ioctl_id: ID of the requested IOCTL.
- * @arg1: Argument 1 to requested IOCTL call.
- * @arg2: Argument 2 to requested IOCTL call.
- * @arg3: Argument 3 to requested IOCTL call.
- * @value: Returned output value.
- * @flag: 0 - Call from secure source.
- * 1 - Call from non-secure source.
- *
- * This API is deprecated and maintained here for backward compatibility.
- * New use of this API should be avoided for versal platform.
- * This API and its use cases will be removed for versal platform.
- *
- * This function calls IOCTL to firmware for device control and configuration.
- *
- * Return: Returns status, either 0 on success or non-zero error code
- * of type enum pm_ret_status.
- *
- */
-enum pm_ret_status pm_api_ioctl(uint32_t device_id, uint32_t ioctl_id,
- uint32_t arg1, uint32_t arg2, uint32_t arg3,
- uint32_t *value, uint32_t flag)
-{
- enum pm_ret_status ret;
-
- switch (ioctl_id) {
- case IOCTL_SET_PLL_FRAC_MODE:
- ret = pm_pll_set_mode(arg1, arg2, flag);
- break;
- case IOCTL_GET_PLL_FRAC_MODE:
- ret = pm_pll_get_mode(arg1, value, flag);
- break;
- case IOCTL_SET_PLL_FRAC_DATA:
- ret = pm_pll_set_param(arg1, (uint32_t)PM_PLL_PARAM_DATA, arg2, flag);
- break;
- case IOCTL_GET_PLL_FRAC_DATA:
- ret = pm_pll_get_param(arg1, (uint32_t)PM_PLL_PARAM_DATA, value, flag);
- break;
- case IOCTL_SET_SGI:
- /* Get the sgi number */
- ret = pm_register_sgi(arg1, arg2);
- if (ret != 0) {
- return PM_RET_ERROR_ARGS;
- }
- ret = PM_RET_SUCCESS;
- break;
- default:
- return PM_RET_ERROR_NOTSUPPORTED;
- }
-
- return ret;
-}
-
-/**
* pm_set_wakeup_source() - PM call to specify the wakeup source while
* suspended.
* @target: Device id of the targeted PU or subsystem
diff --git a/plat/xilinx/common/pm_service/pm_svc_main.c b/plat/xilinx/common/pm_service/pm_svc_main.c
index 7d8f244..7ac0ac1 100644
--- a/plat/xilinx/common/pm_service/pm_svc_main.c
+++ b/plat/xilinx/common/pm_service/pm_svc_main.c
@@ -1,6 +1,6 @@
/*
* Copyright (c) 2019-2022, Xilinx, Inc. All rights reserved.
- * Copyright (c) 2022-2023, Advanced Micro Devices, Inc. All rights reserved.
+ * Copyright (c) 2022-2024, Advanced Micro Devices, Inc. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -149,6 +149,9 @@
}
}
notify_os();
+ } else if (payload[2] == EVENT_CPU_PWRDWN) {
+ request_cpu_pwrdwn();
+ (void)psci_cpu_off();
}
break;
case PM_RET_ERROR_INVALID_CRC:
@@ -240,6 +243,14 @@
}
gicd_write_irouter(gicv3_driver_data->gicd_base, PLAT_VERSAL_IPI_IRQ, MODE);
+
+ /* Register for idle callback during force power down/restart */
+ ret = pm_register_notifier(primary_proc->node_id, EVENT_CPU_PWRDWN,
+ 0x0U, 0x1U, SECURE_FLAG);
+ if (ret != 0) {
+ WARN("BL31: registering idle callback for restart/force power down failed\n");
+ }
+
return ret;
}
@@ -265,30 +276,6 @@
switch (api_id) {
- case (uint32_t)PM_IOCTL:
- {
- uint32_t value = 0U;
-
- ret = pm_api_ioctl(pm_arg[0], pm_arg[1], pm_arg[2],
- pm_arg[3], pm_arg[4],
- &value, security_flag);
- if (ret == PM_RET_ERROR_NOTSUPPORTED)
- return (uintptr_t)0;
-
- SMC_RET1(handle, (uint64_t)ret | ((uint64_t)value) << 32U);
- }
-
- case (uint32_t)PM_QUERY_DATA:
- {
- uint32_t data[PAYLOAD_ARG_CNT] = { 0 };
-
- ret = pm_query_data(pm_arg[0], pm_arg[1], pm_arg[2],
- pm_arg[3], data, security_flag);
-
- SMC_RET2(handle, (uint64_t)ret | ((uint64_t)data[0] << 32U),
- (uint64_t)data[1] | ((uint64_t)data[2] << 32U));
- }
-
case (uint32_t)PM_FEATURE_CHECK:
{
uint32_t result[PAYLOAD_ARG_CNT] = {0U};
diff --git a/services/std_svc/errata_abi/cpu_errata_info.h b/services/std_svc/errata_abi/cpu_errata_info.h
index 2d59fc9..61e1076 100644
--- a/services/std_svc/errata_abi/cpu_errata_info.h
+++ b/services/std_svc/errata_abi/cpu_errata_info.h
@@ -45,7 +45,7 @@
};
struct em_cpu_list{
- unsigned long cpu_partnumber; /* cpu specific part number defined in midr reg */
+ unsigned long cpu_midr; /* cpu specific part number is bit[15:4] of midr value */
struct em_cpu cpu_errata_list[MAX_PLAT_CPU_ERRATA_ENTRIES];
};
diff --git a/services/std_svc/errata_abi/errata_abi_main.c b/services/std_svc/errata_abi/errata_abi_main.c
index 0a1d4f3..0d0ecc3 100644
--- a/services/std_svc/errata_abi/errata_abi_main.c
+++ b/services/std_svc/errata_abi/errata_abi_main.c
@@ -23,7 +23,7 @@
struct em_cpu_list cpu_list[] = {
#if CORTEX_A78_H_INC
{
- .cpu_partnumber = CORTEX_A78_MIDR,
+ .cpu_midr = CORTEX_A78_MIDR,
.cpu_errata_list = {
[0] = {2712571, 0x00, 0x12},
[1 ... ERRATA_LIST_END] = UNDEF_ERRATA,
@@ -33,7 +33,7 @@
#if CORTEX_A78_AE_H_INC
{
- .cpu_partnumber = CORTEX_A78_AE_MIDR,
+ .cpu_midr = CORTEX_A78_AE_MIDR,
.cpu_errata_list = {
[0] = {2712574, 0x00, 0x02},
[1 ... ERRATA_LIST_END] = UNDEF_ERRATA,
@@ -43,7 +43,7 @@
#if CORTEX_A78C_H_INC
{
- .cpu_partnumber = CORTEX_A78C_MIDR,
+ .cpu_midr = CORTEX_A78C_MIDR,
.cpu_errata_list = {
[0] = {2712575, 0x01, 0x02},
[1 ... ERRATA_LIST_END] = UNDEF_ERRATA,
@@ -53,7 +53,7 @@
#if NEOVERSE_V1_H_INC
{
- .cpu_partnumber = NEOVERSE_V1_MIDR,
+ .cpu_midr = NEOVERSE_V1_MIDR,
.cpu_errata_list = {
[0] = {2701953, 0x00, 0x11},
[1 ... ERRATA_LIST_END] = UNDEF_ERRATA,
@@ -63,7 +63,7 @@
#if CORTEX_A710_H_INC
{
- .cpu_partnumber = CORTEX_A710_MIDR,
+ .cpu_midr = CORTEX_A710_MIDR,
.cpu_errata_list = {
[0] = {2701952, 0x00, 0x21},
[1 ... ERRATA_LIST_END] = UNDEF_ERRATA,
@@ -73,7 +73,7 @@
#if NEOVERSE_N2_H_INC
{
- .cpu_partnumber = NEOVERSE_N2_MIDR,
+ .cpu_midr = NEOVERSE_N2_MIDR,
.cpu_errata_list = {
[0] = {2728475, 0x00, 0x02},
[1 ... ERRATA_LIST_END] = UNDEF_ERRATA,
@@ -83,7 +83,7 @@
#if CORTEX_X2_H_INC
{
- .cpu_partnumber = CORTEX_X2_MIDR,
+ .cpu_midr = CORTEX_X2_MIDR,
.cpu_errata_list = {
[0] = {2701952, 0x00, 0x21},
[1 ... ERRATA_LIST_END] = UNDEF_ERRATA,
@@ -93,7 +93,7 @@
#if NEOVERSE_V2_H_INC
{
- .cpu_partnumber = NEOVERSE_V2_MIDR,
+ .cpu_midr = NEOVERSE_V2_MIDR,
.cpu_errata_list = {
[0] = {2719103, 0x00, 0x01},
[1 ... ERRATA_LIST_END] = UNDEF_ERRATA,
@@ -103,7 +103,7 @@
#if CORTEX_X3_H_INC
{
- .cpu_partnumber = CORTEX_X3_MIDR,
+ .cpu_midr = CORTEX_X3_MIDR,
.cpu_errata_list = {
[0] = {2701951, 0x00, 0x11},
[1 ... ERRATA_LIST_END] = UNDEF_ERRATA,
@@ -113,7 +113,7 @@
#if CORTEX_X4_H_INC
{
- .cpu_partnumber = CORTEX_X4_MIDR,
+ .cpu_midr = CORTEX_X4_MIDR,
.cpu_errata_list = {
[0] = {2701112, 0x00, 0x00},
[1 ... ERRATA_LIST_END] = UNDEF_ERRATA,
@@ -142,7 +142,7 @@
* If the cpu partnumber in the cpu list, matches the midr
* part number, check to see if the errata ID matches
*/
- if (EXTRACT_PARTNUM(midr_val) == EXTRACT_PARTNUM(cpu_ptr->cpu_partnumber)) {
+ if (EXTRACT_PARTNUM(midr_val) == EXTRACT_PARTNUM(cpu_ptr->cpu_midr)) {
struct em_cpu *ptr = NULL;