aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--bl32/sp_min/sp_min.ld.S3
-rw-r--r--bl32/sp_min/sp_min_private.h1
-rw-r--r--docs/auth-framework.rst3
-rw-r--r--docs/firmware-design.rst4
-rw-r--r--docs/plat/rockchip.rst54
-rw-r--r--docs/plat/stm32mp1.rst2
-rw-r--r--docs/trusted-board-boot.rst12
-rw-r--r--drivers/ti/uart/aarch32/16550_console.S267
-rw-r--r--fdts/stm32mp15-ddr.dtsi2
-rw-r--r--fdts/stm32mp157-pinctrl.dtsi13
-rw-r--r--fdts/stm32mp157a-avenger96.dts283
-rw-r--r--fdts/stm32mp157c-security.dtsi2
-rw-r--r--include/bl32/sp_min/platform_sp_min.h1
-rw-r--r--lib/cpus/aarch64/cortex_a53.S42
-rw-r--r--maintainers.rst3
-rw-r--r--plat/allwinner/common/sunxi_pm.c6
-rw-r--r--plat/hisilicon/hikey/include/hikey_def.h1
-rw-r--r--plat/marvell/common/mrvl_sip_svc.c31
-rw-r--r--plat/rockchip/common/aarch32/plat_helpers.S164
-rw-r--r--plat/rockchip/common/aarch32/platform_common.c57
-rw-r--r--plat/rockchip/common/aarch32/pmu_sram_cpus_on.S56
-rw-r--r--plat/rockchip/common/aarch64/pmu_sram_cpus_on.S (renamed from plat/rockchip/common/pmusram/pmu_sram_cpus_on.S)0
-rw-r--r--plat/rockchip/common/drivers/pmu/pmu_com.h11
-rw-r--r--plat/rockchip/common/include/plat_private.h17
-rw-r--r--plat/rockchip/common/params_setup.c32
-rw-r--r--plat/rockchip/common/plat_topology.c4
-rw-r--r--plat/rockchip/common/sp_min_plat_setup.c116
-rw-r--r--plat/rockchip/rk3288/drivers/pmu/plat_pmu_macros.S17
-rw-r--r--plat/rockchip/rk3288/drivers/pmu/pmu.c391
-rw-r--r--plat/rockchip/rk3288/drivers/pmu/pmu.h151
-rw-r--r--plat/rockchip/rk3288/drivers/secure/secure.c162
-rw-r--r--plat/rockchip/rk3288/drivers/secure/secure.h102
-rw-r--r--plat/rockchip/rk3288/drivers/soc/soc.c215
-rw-r--r--plat/rockchip/rk3288/drivers/soc/soc.h110
-rw-r--r--plat/rockchip/rk3288/include/plat_sip_calls.h12
-rw-r--r--plat/rockchip/rk3288/include/plat_sp_min.ld.S72
-rw-r--r--plat/rockchip/rk3288/include/platform_def.h101
-rw-r--r--plat/rockchip/rk3288/include/shared/bl32_param.h26
-rw-r--r--plat/rockchip/rk3288/plat_sip_calls.c25
-rw-r--r--plat/rockchip/rk3288/platform.mk65
-rw-r--r--plat/rockchip/rk3288/rk3288_def.h116
-rw-r--r--plat/rockchip/rk3288/sp_min/sp_min-rk3288.mk8
-rw-r--r--plat/rockchip/rk3328/drivers/pmu/pmu.h2
-rw-r--r--plat/rockchip/rk3328/platform.mk8
-rw-r--r--plat/rockchip/rk3368/platform.mk8
-rw-r--r--plat/rockchip/rk3399/drivers/m0/src/dram.c2
-rw-r--r--plat/rockchip/rk3399/drivers/m0/src/startup.c6
-rw-r--r--plat/rockchip/rk3399/drivers/m0/src/suspend.c2
-rw-r--r--plat/rockchip/rk3399/platform.mk8
-rw-r--r--plat/ti/k3/common/k3_bl31_setup.c9
-rw-r--r--plat/ti/k3/common/k3_psci.c8
-rw-r--r--readme.rst3
52 files changed, 2729 insertions, 87 deletions
diff --git a/bl32/sp_min/sp_min.ld.S b/bl32/sp_min/sp_min.ld.S
index 83b78600e..4559903bf 100644
--- a/bl32/sp_min/sp_min.ld.S
+++ b/bl32/sp_min/sp_min.ld.S
@@ -16,6 +16,9 @@ MEMORY {
RAM (rwx): ORIGIN = BL32_BASE, LENGTH = BL32_LIMIT - BL32_BASE
}
+#ifdef PLAT_SP_MIN_EXTRA_LD_SCRIPT
+#include <plat_sp_min.ld.S>
+#endif
SECTIONS
{
diff --git a/bl32/sp_min/sp_min_private.h b/bl32/sp_min/sp_min_private.h
index 6b5d7925b..628581a4c 100644
--- a/bl32/sp_min/sp_min_private.h
+++ b/bl32/sp_min/sp_min_private.h
@@ -7,7 +7,6 @@
#ifndef SP_MIN_PRIVATE_H
#define SP_MIN_PRIVATE_H
-void sp_min_warm_entrypoint(void);
void sp_min_main(void);
void sp_min_warm_boot(void);
void sp_min_fiq(void);
diff --git a/docs/auth-framework.rst b/docs/auth-framework.rst
index 317ac1898..0142fbd3e 100644
--- a/docs/auth-framework.rst
+++ b/docs/auth-framework.rst
@@ -80,7 +80,7 @@ Chain of Trust
A CoT is basically a sequence of authentication images which usually starts with
a root of trust and culminates in a single data image. The following diagram
illustrates how this maps to a CoT for the BL31 image described in the
-TBBR-Client specification.
+`TBBR-Client specification`_.
::
@@ -969,3 +969,4 @@ of SHA-256 with smaller memory footprint (~1.5 KB less) but slower (~30%).
.. _Trusted Board Boot: ./trusted-board-boot.rst
.. _Platform Porting Guide: ./porting-guide.rst
+.. _TBBR-Client specification: https://developer.arm.com/docs/den0006/latest/trusted-board-boot-requirements-client-tbbr-client-armv8-a
diff --git a/docs/firmware-design.rst b/docs/firmware-design.rst
index 66b16fa2e..8384c9c00 100644
--- a/docs/firmware-design.rst
+++ b/docs/firmware-design.rst
@@ -2655,8 +2655,7 @@ kernel at boot time. These can be found in the ``fdts`` directory.
References
----------
-.. [#] Trusted Board Boot Requirements CLIENT PDD (Arm DEN0006C-1). Available
- under NDA through your Arm account representative.
+.. [#] `Trusted Board Boot Requirements CLIENT (TBBR-CLIENT) Armv8-A (ARM DEN0006D)`_
.. [#] `Power State Coordination Interface PDD`_
.. [#] `SMC Calling Convention PDD`_
.. [#] `TF-A Interrupt Management Design guide`_.
@@ -2684,5 +2683,6 @@ References
.. _Xlat_tables design: xlat-tables-lib-v2-design.rst
.. _Exception Handling Framework: exception-handling.rst
.. _ROMLIB Design: romlib-design.rst
+.. _Trusted Board Boot Requirements CLIENT (TBBR-CLIENT) Armv8-A (ARM DEN0006D): https://developer.arm.com/docs/den0006/latest/trusted-board-boot-requirements-client-tbbr-client-armv8-a
.. |Image 1| image:: diagrams/rt-svc-descs-layout.png?raw=true
diff --git a/docs/plat/rockchip.rst b/docs/plat/rockchip.rst
new file mode 100644
index 000000000..e88706b2f
--- /dev/null
+++ b/docs/plat/rockchip.rst
@@ -0,0 +1,54 @@
+Trusted Firmware-A for Rockchip SoCs
+====================================
+
+Trusted Firmware-A supports a number of Rockchip ARM SoCs from both
+AARCH32 and AARCH64 fields.
+
+This includes right now:
+- rk3288: Quad-Core Cortex-A17 (past A12)
+- rk3328: Quad-Core Cortex-A53
+- rk3368: Octa-Core Cortex-A53
+- rk3399: Hexa-Core Cortex-A53/A72
+
+
+Boot Sequence
+=============
+
+For AARCH32:
+ Bootrom --> BL1/BL2 --> BL32 --> BL33 --> Linux kernel
+
+For AARCH64:
+ Bootrom --> BL1/BL2 --> BL31 --> BL33 --> Linux kernel
+
+BL1/2 and BL33 can currently be supplied from either:
+- Coreboot + Depthcharge
+- U-Boot - either separately as TPL+SPL or only SPL
+
+
+How to build
+============
+
+Rockchip SoCs expect TF-A's BL31 (AARCH64) or BL32 (AARCH32) to get
+integrated with other boot software like U-Boot or Coreboot, so only
+these images need to get build from the TF-A repository.
+
+For AARCH64 architectures the build command looks like
+
+ make CROSS_COMPILE=aarch64-linux-gnu- PLAT=rk3399 bl32
+
+while AARCH32 needs a slightly different command
+
+ make ARCH=aarch32 CROSS_COMPILE=arm-linux-gnueabihf- PLAT=rk3288 AARCH32_SP=sp_min bl32
+
+Both need replacing the PLAT argument with the platform from above you
+want to build for and the CROSS_COMPILE argument with you cross-
+compilation toolchain.
+
+
+How to deploy
+=============
+
+Both upstream U-Boot and Coreboot projects contain instructions on where
+to put the built images during their respective build process.
+So after successfully building TF-A just follow their build instructions
+to continue.
diff --git a/docs/plat/stm32mp1.rst b/docs/plat/stm32mp1.rst
index 75dfa3f70..1cfdb8453 100644
--- a/docs/plat/stm32mp1.rst
+++ b/docs/plat/stm32mp1.rst
@@ -81,7 +81,7 @@ To build with SP_min:
.. code:: bash
- make CROSS_COMPILE=arm-linux-gnueabihf- PLAT=stm32mp1 ARCH=aarch32 ARM_ARCH_MAJOR=7 AARCH32_SP=sp_min
+ make CROSS_COMPILE=arm-linux-gnueabihf- PLAT=stm32mp1 ARCH=aarch32 ARM_ARCH_MAJOR=7 AARCH32_SP=sp_min DTB_FILE_NAME=stm32mp157c-ev1.dtb
cd <u-boot_directory>
make stm32mp15_basic_defconfig
make DEVICE_TREE=stm32mp157c-ev1 all
diff --git a/docs/trusted-board-boot.rst b/docs/trusted-board-boot.rst
index 1ca6fef75..3ba963634 100644
--- a/docs/trusted-board-boot.rst
+++ b/docs/trusted-board-boot.rst
@@ -12,9 +12,9 @@ the platform by authenticating all firmware images up to and including the
normal world bootloader. It does this by establishing a Chain of Trust using
Public-Key-Cryptography Standards (PKCS).
-This document describes the design of Trusted Firmware-A (TF-A) TBB, which is
-an implementation of the Trusted Board Boot Requirements (TBBR) specification,
-Arm DEN0006C-1. It should be used in conjunction with the `Firmware Update`_
+This document describes the design of Trusted Firmware-A (TF-A) TBB, which is an
+implementation of the `Trusted Board Boot Requirements (TBBR)`_ specification,
+Arm DEN0006D. It should be used in conjunction with the `Firmware Update`_
design document, which implements a specific aspect of the TBBR.
Chain of Trust
@@ -206,7 +206,7 @@ Authentication Framework
The authentication framework included in TF-A provides support to implement
the desired trusted boot sequence. Arm platforms use this framework to
-implement the boot requirements specified in the TBBR-client document.
+implement the boot requirements specified in the `TBBR-client`_ document.
More information about the authentication framework can be found in the
`Auth Framework`_ document.
@@ -230,9 +230,11 @@ for building and using the tool can be found in the `User Guide`_.
--------------
-*Copyright (c) 2015-2018, Arm Limited and Contributors. All rights reserved.*
+*Copyright (c) 2015-2019, Arm Limited and Contributors. All rights reserved.*
.. _Firmware Update: firmware-update.rst
.. _X.509 v3: https://tools.ietf.org/rfc/rfc5280.txt
.. _User Guide: user-guide.rst
.. _Auth Framework: auth-framework.rst
+.. _TBBR-client: https://developer.arm.com/docs/den0006/latest/trusted-board-boot-requirements-client-tbbr-client-armv8-a
+.. _Trusted Board Boot Requirements (TBBR): `TBBR-client`_
diff --git a/drivers/ti/uart/aarch32/16550_console.S b/drivers/ti/uart/aarch32/16550_console.S
new file mode 100644
index 000000000..692188412
--- /dev/null
+++ b/drivers/ti/uart/aarch32/16550_console.S
@@ -0,0 +1,267 @@
+/*
+ * Copyright (c) 2015-2018, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <arch.h>
+#include <asm_macros.S>
+#include <assert_macros.S>
+#include <console_macros.S>
+#include <drivers/ti/uart/uart_16550.h>
+
+ /*
+ * "core" functions are low-level implementations that don't require
+ * writable memory and are thus safe to call in BL1 crash context.
+ */
+ .globl console_16550_core_init
+ .globl console_16550_core_putc
+ .globl console_16550_core_getc
+ .globl console_16550_core_flush
+
+ .globl console_16550_putc
+ .globl console_16550_getc
+ .globl console_16550_flush
+
+ /* -----------------------------------------------
+ * int console_16550_core_init(uintptr_t base_addr,
+ * unsigned int uart_clk, unsigned int baud_rate)
+ * Function to initialize the console without a
+ * C Runtime to print debug information. This
+ * function will be accessed by console_init and
+ * crash reporting.
+ * In: r0 - console base address
+ * r1 - Uart clock in Hz
+ * r2 - Baud rate
+ * Out: return 1 on success, 0 on error
+ * Clobber list : r1, r2, r3
+ * -----------------------------------------------
+ */
+func console_16550_core_init
+ /* Check the input base address */
+ cmp r0, #0
+ beq init_fail
+ /* Check baud rate and uart clock for sanity */
+ cmp r1, #0
+ beq init_fail
+ cmp r2, #0
+ beq init_fail
+
+ /* Program the baudrate */
+ /* Divisor = Uart clock / (16 * baudrate) */
+ lsl r2, r2, #4
+ udiv r2, r1, r2
+ and r1, r2, #0xff /* w1 = DLL */
+ lsr r2, r2, #8
+ and r2, r2, #0xff /* w2 = DLLM */
+ ldr r3, [r0, #UARTLCR]
+ orr r3, r3, #UARTLCR_DLAB
+ str r3, [r0, #UARTLCR] /* enable DLL, DLLM programming */
+ str r1, [r0, #UARTDLL] /* program DLL */
+ str r2, [r0, #UARTDLLM] /* program DLLM */
+ mov r2, #~UARTLCR_DLAB
+ and r3, r3, r2
+ str r3, [r0, #UARTLCR] /* disable DLL, DLLM programming */
+
+ /* 8n1 */
+ mov r3, #3
+ str r3, [r0, #UARTLCR]
+ /* no interrupt */
+ mov r3, #0
+ str r3, [r0, #UARTIER]
+#ifdef TI_16550_MDR_QUIRK
+ /* UART must be enabled on some platforms via the MDR register */
+ str r3, [r0, #UARTMDR1]
+#endif /* TI_16550_MDR_QUIRK */
+ /* enable fifo, DMA */
+ mov r3, #(UARTFCR_FIFOEN | UARTFCR_DMAEN)
+ str r3, [r0, #UARTFCR]
+ /* DTR + RTS */
+ mov r3, #3
+ str r3, [r0, #UARTMCR]
+ mov r0, #1
+ bx lr
+init_fail:
+ mov r0, #0
+ bx lr
+endfunc console_16550_core_init
+
+ .globl console_16550_register
+
+ /* -------------------------------------------------------
+ * int console_stm32_register(uintptr_t baseaddr,
+ * uint32_t clock, uint32_t baud,
+ * struct console_stm32 *console);
+ * Function to initialize and register a new STM32
+ * console. Storage passed in for the console struct
+ * *must* be persistent (i.e. not from the stack).
+ * In: r0 - UART register base address
+ * r1 - UART clock in Hz
+ * r2 - Baud rate
+ * r3 - pointer to empty console_stm32 struct
+ * Out: return 1 on success, 0 on error
+ * Clobber list : r0, r1, r2
+ * -------------------------------------------------------
+ */
+func console_16550_register
+ push {r4, lr}
+ mov r4, r3
+ cmp r4, #0
+ beq register_fail
+ str r0, [r4, #CONSOLE_T_16550_BASE]
+
+ bl console_16550_core_init
+ cmp r0, #0
+ beq register_fail
+
+ mov r0, r4
+ pop {r4, lr}
+ finish_console_register 16550 putc=1, getc=1, flush=1
+
+register_fail:
+ pop {r4, pc}
+endfunc console_16550_register
+
+ /* --------------------------------------------------------
+ * int console_16550_core_putc(int c, uintptr_t base_addr)
+ * Function to output a character over the console. It
+ * returns the character printed on success or -1 on error.
+ * In : r0 - character to be printed
+ * r1 - console base address
+ * Out : return -1 on error else return character.
+ * Clobber list : r2
+ * --------------------------------------------------------
+ */
+func console_16550_core_putc
+#if ENABLE_ASSERTIONS
+ cmp r1, #0
+ ASM_ASSERT(ne)
+#endif /* ENABLE_ASSERTIONS */
+
+ /* Prepend '\r' to '\n' */
+ cmp r0, #0xA
+ bne 2f
+ /* Check if the transmit FIFO is full */
+1: ldr r2, [r1, #UARTLSR]
+ and r2, r2, #(UARTLSR_TEMT | UARTLSR_THRE)
+ cmp r2, #(UARTLSR_TEMT | UARTLSR_THRE)
+ bne 1b
+ mov r2, #0xD /* '\r' */
+ str r2, [r1, #UARTTX]
+
+ /* Check if the transmit FIFO is full */
+2: ldr r2, [r1, #UARTLSR]
+ and r2, r2, #(UARTLSR_TEMT | UARTLSR_THRE)
+ cmp r2, #(UARTLSR_TEMT | UARTLSR_THRE)
+ bne 2b
+ str r0, [r1, #UARTTX]
+ bx lr
+endfunc console_16550_core_putc
+
+ /* --------------------------------------------------------
+ * int console_16550_putc(int c, console_16550_t *console)
+ * Function to output a character over the console. It
+ * returns the character printed on success or -1 on error.
+ * In : r0 - character to be printed
+ * r1 - pointer to console_t structure
+ * Out : return -1 on error else return character.
+ * Clobber list : r2
+ * --------------------------------------------------------
+ */
+func console_16550_putc
+#if ENABLE_ASSERTIONS
+ cmp r1, #0
+ ASM_ASSERT(ne)
+#endif /* ENABLE_ASSERTIONS */
+ ldr r1, [r1, #CONSOLE_T_16550_BASE]
+ b console_16550_core_putc
+endfunc console_16550_putc
+
+ /* ---------------------------------------------
+ * int console_16550_core_getc(uintptr_t base_addr)
+ * Function to get a character from the console.
+ * It returns the character grabbed on success
+ * or -1 on if no character is available.
+ * In : r0 - console base address
+ * Clobber list : r0, r1
+ * ---------------------------------------------
+ */
+func console_16550_core_getc
+#if ENABLE_ASSERTIONS
+ cmp r0, #0
+ ASM_ASSERT(ne)
+#endif /* ENABLE_ASSERTIONS */
+
+ /* Check if the receive FIFO is empty */
+1: ldr r1, [r0, #UARTLSR]
+ tst r1, #UARTLSR_RDR_BIT
+ beq no_char
+ ldr r1, [r0, #UARTRX]
+ mov r0, r1
+ bx lr
+no_char:
+ mov r0, #ERROR_NO_PENDING_CHAR
+ bx lr
+endfunc console_16550_core_getc
+
+ /* ---------------------------------------------
+ * int console_16550_getc(console_16550_t *console)
+ * Function to get a character from the console.
+ * It returns the character grabbed on success
+ * or -1 on if no character is available.
+ * In : r0 - pointer to console_t stucture
+ * Out : r0 - character if available, else -1
+ * Clobber list : r0, r1
+ * ---------------------------------------------
+ */
+func console_16550_getc
+#if ENABLE_ASSERTIONS
+ cmp r0, #0
+ ASM_ASSERT(ne)
+#endif /* ENABLE_ASSERTIONS */
+ ldr r0, [r0, #CONSOLE_T_16550_BASE]
+ b console_16550_core_getc
+endfunc console_16550_getc
+
+ /* ---------------------------------------------
+ * int console_16550_core_flush(uintptr_t base_addr)
+ * Function to force a write of all buffered
+ * data that hasn't been output.
+ * In : r0 - console base address
+ * Out : return -1 on error else return 0.
+ * Clobber list : r0, r1
+ * ---------------------------------------------
+ */
+func console_16550_core_flush
+#if ENABLE_ASSERTIONS
+ cmp r0, #0
+ ASM_ASSERT(ne)
+#endif /* ENABLE_ASSERTIONS */
+
+ /* Loop until the transmit FIFO is empty */
+1: ldr r1, [r0, #UARTLSR]
+ and r1, r1, #(UARTLSR_TEMT | UARTLSR_THRE)
+ cmp r1, #(UARTLSR_TEMT | UARTLSR_THRE)
+ bne 1b
+
+ mov r0, #0
+ bx lr
+endfunc console_16550_core_flush
+
+ /* ---------------------------------------------
+ * int console_16550_flush(console_pl011_t *console)
+ * Function to force a write of all buffered
+ * data that hasn't been output.
+ * In : r0 - pointer to console_t structure
+ * Out : return -1 on error else return 0.
+ * Clobber list : r0, r1
+ * ---------------------------------------------
+ */
+func console_16550_flush
+#if ENABLE_ASSERTIONS
+ cmp r0, #0
+ ASM_ASSERT(ne)
+#endif /* ENABLE_ASSERTIONS */
+ ldr r0, [r0, #CONSOLE_T_16550_BASE]
+ b console_16550_core_flush
+endfunc console_16550_flush
diff --git a/fdts/stm32mp15-ddr.dtsi b/fdts/stm32mp15-ddr.dtsi
index 1a5c51c97..4825691f9 100644
--- a/fdts/stm32mp15-ddr.dtsi
+++ b/fdts/stm32mp15-ddr.dtsi
@@ -5,7 +5,7 @@
/ {
soc {
- ddr: ddr@5A003000{
+ ddr: ddr@5a003000{
compatible = "st,stm32mp1-ddr";
diff --git a/fdts/stm32mp157-pinctrl.dtsi b/fdts/stm32mp157-pinctrl.dtsi
index 9dcd7b5e1..c7553ca50 100644
--- a/fdts/stm32mp157-pinctrl.dtsi
+++ b/fdts/stm32mp157-pinctrl.dtsi
@@ -273,6 +273,19 @@
};
};
+ uart4_pins_b: uart4-1 {
+ pins1 {
+ pinmux = <STM32_PINMUX('D', 1, AF8)>; /* UART4_TX */
+ bias-disable;
+ drive-push-pull;
+ slew-rate = <0>;
+ };
+ pins2 {
+ pinmux = <STM32_PINMUX('B', 2, AF8)>; /* UART4_RX */
+ bias-disable;
+ };
+ };
+
usart3_pins_a: usart3-0 {
pins1 {
pinmux = <STM32_PINMUX('B', 10, AF7)>, /* USART3_TX */
diff --git a/fdts/stm32mp157a-avenger96.dts b/fdts/stm32mp157a-avenger96.dts
new file mode 100644
index 000000000..9df72b444
--- /dev/null
+++ b/fdts/stm32mp157a-avenger96.dts
@@ -0,0 +1,283 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR BSD-3-Clause)
+/*
+ * Copyright (C) Arrow Electronics 2019 - All Rights Reserved
+ * Author: Botond Kardos <botond.kardos@arroweurope.com>
+ *
+ * Copyright (C) Linaro Ltd 2019 - All Rights Reserved
+ * Author: Manivannan Sadhasivam <manivannan.sadhasivam@linaro.org>
+ */
+
+/dts-v1/;
+
+#include "stm32mp157c.dtsi"
+#include "stm32mp157cac-pinctrl.dtsi"
+
+/ {
+ model = "Arrow Electronics STM32MP157A Avenger96 board";
+ compatible = "st,stm32mp157a-avenger96", "st,stm32mp157";
+
+ aliases {
+ serial0 = &uart4;
+ };
+
+ chosen {
+ stdout-path = "serial0:115200n8";
+ };
+
+};
+
+&i2c4 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&i2c4_pins_a>;
+ i2c-scl-rising-time-ns = <185>;
+ i2c-scl-falling-time-ns = <20>;
+ status = "okay";
+
+ pmic: stpmic@33 {
+ compatible = "st,stpmic1";
+ reg = <0x33>;
+ interrupts-extended = <&exti_pwr 55 IRQ_TYPE_EDGE_FALLING>;
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ status = "okay";
+
+ st,main-control-register = <0x04>;
+ st,vin-control-register = <0xc0>;
+ st,usb-control-register = <0x20>;
+
+ regulators {
+ compatible = "st,stpmic1-regulators";
+
+ ldo1-supply = <&v3v3>;
+ ldo2-supply = <&v3v3>;
+ ldo3-supply = <&vdd_ddr>;
+ ldo5-supply = <&v3v3>;
+ ldo6-supply = <&v3v3>;
+
+ vddcore: buck1 {
+ regulator-name = "vddcore";
+ regulator-min-microvolt = <1200000>;
+ regulator-max-microvolt = <1350000>;
+ regulator-always-on;
+ regulator-initial-mode = <0>;
+ regulator-over-current-protection;
+ };
+
+ vdd_ddr: buck2 {
+ regulator-name = "vdd_ddr";
+ regulator-min-microvolt = <1350000>;
+ regulator-max-microvolt = <1350000>;
+ regulator-always-on;
+ regulator-initial-mode = <0>;
+ regulator-over-current-protection;
+ };
+
+ vdd: buck3 {
+ regulator-name = "vdd";
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ regulator-always-on;
+ st,mask-reset;
+ regulator-initial-mode = <0>;
+ regulator-over-current-protection;
+ };
+
+ v3v3: buck4 {
+ regulator-name = "v3v3";
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ regulator-always-on;
+ regulator-over-current-protection;
+ regulator-initial-mode = <0>;
+ };
+
+ vdda: ldo1 {
+ regulator-name = "vdda";
+ regulator-min-microvolt = <2900000>;
+ regulator-max-microvolt = <2900000>;
+ };
+
+ v2v8: ldo2 {
+ regulator-name = "v2v8";
+ regulator-min-microvolt = <2800000>;
+ regulator-max-microvolt = <2800000>;
+ };
+
+ vtt_ddr: ldo3 {
+ regulator-name = "vtt_ddr";
+ regulator-min-microvolt = <500000>;
+ regulator-max-microvolt = <750000>;
+ regulator-always-on;
+ regulator-over-current-protection;
+ };
+
+ vdd_usb: ldo4 {
+ regulator-name = "vdd_usb";
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ };
+
+ vdd_sd: ldo5 {
+ regulator-name = "vdd_sd";
+ regulator-min-microvolt = <2900000>;
+ regulator-max-microvolt = <2900000>;
+ regulator-boot-on;
+ };
+
+ v1v8: ldo6 {
+ regulator-name = "v1v8";
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+ };
+
+ vref_ddr: vref_ddr {
+ regulator-name = "vref_ddr";
+ regulator-always-on;
+ regulator-over-current-protection;
+ };
+ };
+ };
+};
+
+&iwdg2 {
+ timeout-sec = <32>;
+ status = "okay";
+};
+
+&rng1 {
+ status = "okay";
+};
+
+&rtc {
+ status = "okay";
+};
+
+&sdmmc1 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&sdmmc1_b4_pins_a &sdmmc1_dir_pins_a>;
+ broken-cd;
+ st,sig-dir;
+ st,neg-edge;
+ st,use-ckin;
+ bus-width = <4>;
+ vmmc-supply = <&vdda>;
+ status = "okay";
+};
+
+&uart4 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&uart4_pins_b>;
+ status = "okay";
+};
+
+/* ATF Specific */
+#include <dt-bindings/clock/stm32mp1-clksrc.h>
+#include "stm32mp15-ddr3-2x4Gb-1066-binG.dtsi"
+#include "stm32mp157c-security.dtsi"
+
+/ {
+ aliases {
+ gpio0 = &gpioa;
+ gpio1 = &gpiob;
+ gpio2 = &gpioc;
+ gpio3 = &gpiod;
+ gpio4 = &gpioe;
+ gpio5 = &gpiof;
+ gpio6 = &gpiog;
+ gpio7 = &gpioh;
+ gpio8 = &gpioi;
+ gpio25 = &gpioz;
+ i2c3 = &i2c4;
+ };
+};
+
+/* CLOCK init */
+&rcc {
+ secure-status = "disabled";
+ st,clksrc = <
+ CLK_MPU_PLL1P
+ CLK_AXI_PLL2P
+ CLK_MCU_PLL3P
+ CLK_PLL12_HSE
+ CLK_PLL3_HSE
+ CLK_PLL4_HSE
+ CLK_RTC_LSE
+ CLK_MCO1_DISABLED
+ CLK_MCO2_DISABLED
+ >;
+
+ st,clkdiv = <
+ 1 /*MPU*/
+ 0 /*AXI*/
+ 0 /*MCU*/
+ 1 /*APB1*/
+ 1 /*APB2*/
+ 1 /*APB3*/
+ 1 /*APB4*/
+ 2 /*APB5*/
+ 23 /*RTC*/
+ 0 /*MCO1*/
+ 0 /*MCO2*/
+ >;
+
+ st,pkcs = <
+ CLK_CKPER_HSE
+ CLK_FMC_ACLK
+ CLK_QSPI_ACLK
+ CLK_ETH_DISABLED
+ CLK_SDMMC12_PLL4P
+ CLK_DSI_DSIPLL
+ CLK_STGEN_HSE
+ CLK_USBPHY_HSE
+ CLK_SPI2S1_PLL3Q
+ CLK_SPI2S23_PLL3Q
+ CLK_SPI45_HSI
+ CLK_SPI6_HSI
+ CLK_I2C46_HSI
+ CLK_SDMMC3_PLL4P
+ CLK_USBO_USBPHY
+ CLK_ADC_CKPER
+ CLK_CEC_LSE
+ CLK_I2C12_HSI
+ CLK_I2C35_HSI
+ CLK_UART1_HSI
+ CLK_UART24_HSI
+ CLK_UART35_HSI
+ CLK_UART6_HSI
+ CLK_UART78_HSI
+ CLK_SPDIF_PLL4P
+ CLK_FDCAN_PLL4Q
+ CLK_SAI1_PLL3Q
+ CLK_SAI2_PLL3Q
+ CLK_SAI3_PLL3Q
+ CLK_SAI4_PLL3Q
+ CLK_RNG1_LSI
+ CLK_RNG2_LSI
+ CLK_LPTIM1_PCLK1
+ CLK_LPTIM23_PCLK3
+ CLK_LPTIM45_LSE
+ >;
+
+ /* VCO = 1300.0 MHz => P = 650 (CPU) */
+ pll1: st,pll@0 {
+ cfg = < 2 80 0 0 0 PQR(1,0,0) >;
+ frac = < 0x800 >;
+ };
+
+ /* VCO = 1066.0 MHz => P = 266 (AXI), Q = 533 (GPU), R = 533 (DDR) */
+ pll2: st,pll@1 {
+ cfg = < 2 65 1 0 0 PQR(1,1,1) >;
+ frac = < 0x1400 >;
+ };
+
+ /* VCO = 417.8 MHz => P = 209, Q = 24, R = 11 */
+ pll3: st,pll@2 {
+ cfg = < 1 33 1 16 36 PQR(1,1,1) >;
+ frac = < 0x1a04 >;
+ };
+
+ /* VCO = 480.0 MHz => P = 120, Q = 40, R = 96 */
+ pll4: st,pll@3 {
+ cfg = < 1 39 3 11 4 PQR(1,1,1) >;
+ };
+};
diff --git a/fdts/stm32mp157c-security.dtsi b/fdts/stm32mp157c-security.dtsi
index fb04e7ddd..59119c529 100644
--- a/fdts/stm32mp157c-security.dtsi
+++ b/fdts/stm32mp157c-security.dtsi
@@ -6,7 +6,7 @@
/ {
soc {
- stgen: stgen@5C008000 {
+ stgen: stgen@5c008000 {
compatible = "st,stm32-stgen";
reg = <0x5C008000 0x1000>;
status = "okay";
diff --git a/include/bl32/sp_min/platform_sp_min.h b/include/bl32/sp_min/platform_sp_min.h
index feb4ec371..971f66185 100644
--- a/include/bl32/sp_min/platform_sp_min.h
+++ b/include/bl32/sp_min/platform_sp_min.h
@@ -18,6 +18,7 @@ void sp_min_platform_setup(void);
void sp_min_plat_runtime_setup(void);
void sp_min_plat_arch_setup(void);
entry_point_info_t *sp_min_plat_get_bl33_ep_info(void);
+void sp_min_warm_entrypoint(void);
/* Platforms that enable SP_MIN_WITH_SECURE_FIQ shall implement this api */
void sp_min_plat_fiq_handler(uint32_t id);
diff --git a/lib/cpus/aarch64/cortex_a53.S b/lib/cpus/aarch64/cortex_a53.S
index f20082d2d..6fd3c53fd 100644
--- a/lib/cpus/aarch64/cortex_a53.S
+++ b/lib/cpus/aarch64/cortex_a53.S
@@ -45,31 +45,35 @@ endfunc cortex_a53_disable_smp
/* ---------------------------------------------------
* Errata Workaround for Cortex A53 Errata #819472.
* This applies only to revision <= r0p1 of Cortex A53.
+ * Due to the nature of the errata it is applied unconditionally
+ * when built in, report it as applicable in this case
* ---------------------------------------------------
*/
func check_errata_819472
- /*
- * Even though this is only needed for revision <= r0p1, it
- * is always applied due to limitations of the current
- * errata framework.
- */
- mov x0, #ERRATA_APPLIES
+#if ERRATA_A53_819472
+ mov x0, #ERRATA_APPLIES
ret
+#else
+ mov x1, #0x01
+ b cpu_rev_var_ls
+#endif
endfunc check_errata_819472
/* ---------------------------------------------------
* Errata Workaround for Cortex A53 Errata #824069.
* This applies only to revision <= r0p2 of Cortex A53.
+ * Due to the nature of the errata it is applied unconditionally
+ * when built in, report it as applicable in this case
* ---------------------------------------------------
*/
func check_errata_824069
- /*
- * Even though this is only needed for revision <= r0p2, it
- * is always applied due to limitations of the current
- * errata framework.
- */
- mov x0, #ERRATA_APPLIES
+#if ERRATA_A53_824069
+ mov x0, #ERRATA_APPLIES
ret
+#else
+ mov x1, #0x02
+ b cpu_rev_var_ls
+#endif
endfunc check_errata_824069
/* --------------------------------------------------
@@ -103,16 +107,18 @@ endfunc check_errata_826319
/* ---------------------------------------------------
* Errata Workaround for Cortex A53 Errata #827319.
* This applies only to revision <= r0p2 of Cortex A53.
+ * Due to the nature of the errata it is applied unconditionally
+ * when built in, report it as applicable in this case
* ---------------------------------------------------
*/
func check_errata_827319
- /*
- * Even though this is only needed for revision <= r0p2, it
- * is always applied due to limitations of the current
- * errata framework.
- */
- mov x0, #ERRATA_APPLIES
+#if ERRATA_A53_827319
+ mov x0, #ERRATA_APPLIES
ret
+#else
+ mov x1, #0x02
+ b cpu_rev_var_ls
+#endif
endfunc check_errata_827319
/* ---------------------------------------------------------------------
diff --git a/maintainers.rst b/maintainers.rst
index 52c3daca1..4bee64ccf 100644
--- a/maintainers.rst
+++ b/maintainers.rst
@@ -208,6 +208,8 @@ RockChip platform port
:M: Tony Xie <tony.xie@rock-chips.com>
:G: `TonyXie06`_
:G: `rockchip-linux`_
+:M: Heiko Stuebner <heiko@sntech.de>
+:G: `mmind`_
:F: plat/rockchip/
STM32MP1 platform port
@@ -277,6 +279,7 @@ Xilinx platform port
.. _niej: https://github.com/niej
.. _kostapr: https://github.com/kostapr
.. _masahir0y: https://github.com/masahir0y
+.. _mmind: https://github.com/mmind
.. _mtk09422: https://github.com/mtk09422
.. _npoushin: https://github.com/npoushin
.. _qoriq-open-source: https://github.com/qoriq-open-source
diff --git a/plat/allwinner/common/sunxi_pm.c b/plat/allwinner/common/sunxi_pm.c
index 1d2dc9385..13e135325 100644
--- a/plat/allwinner/common/sunxi_pm.c
+++ b/plat/allwinner/common/sunxi_pm.c
@@ -20,9 +20,9 @@
#include <sunxi_mmap.h>
#include <sunxi_private.h>
-#define SUNXI_WDOG0_CTRL_REG (SUNXI_WDOG_BASE + 0x0010)
-#define SUNXI_WDOG0_CFG_REG (SUNXI_WDOG_BASE + 0x0014)
-#define SUNXI_WDOG0_MODE_REG (SUNXI_WDOG_BASE + 0x0018)
+#define SUNXI_WDOG0_CTRL_REG (SUNXI_R_WDOG_BASE + 0x0010)
+#define SUNXI_WDOG0_CFG_REG (SUNXI_R_WDOG_BASE + 0x0014)
+#define SUNXI_WDOG0_MODE_REG (SUNXI_R_WDOG_BASE + 0x0018)
#define mpidr_is_valid(mpidr) ( \
MPIDR_AFFLVL3_VAL(mpidr) == 0 && \
diff --git a/plat/hisilicon/hikey/include/hikey_def.h b/plat/hisilicon/hikey/include/hikey_def.h
index b9679f576..4fb3e56a1 100644
--- a/plat/hisilicon/hikey/include/hikey_def.h
+++ b/plat/hisilicon/hikey/include/hikey_def.h
@@ -40,6 +40,7 @@
* PL011 related constants
*/
#define PL011_UART0_BASE 0xF8015000
+#define PL011_UART2_BASE 0xF7112000
#define PL011_UART3_BASE 0xF7113000
#define PL011_BAUDRATE 115200
#define PL011_UART_CLK_IN_HZ 19200000
diff --git a/plat/marvell/common/mrvl_sip_svc.c b/plat/marvell/common/mrvl_sip_svc.c
index df211059b..0291024d7 100644
--- a/plat/marvell/common/mrvl_sip_svc.c
+++ b/plat/marvell/common/mrvl_sip_svc.c
@@ -15,6 +15,7 @@
#include <plat_marvell.h>
#include "comphy/phy-comphy-cp110.h"
+#include <stdbool.h>
/* #define DEBUG_COMPHY */
#ifdef DEBUG_COMPHY
@@ -38,12 +39,24 @@
#define MAX_LANE_NR 6
#define MVEBU_COMPHY_OFFSET 0x441000
-#define MVEBU_SD_OFFSET 0x120000
+#define MVEBU_CP_BASE_MASK (~0xffffff)
/* This macro is used to identify COMPHY related calls from SMC function ID */
#define is_comphy_fid(fid) \
((fid) >= MV_SIP_COMPHY_POWER_ON && (fid) <= MV_SIP_COMPHY_DIG_RESET)
+_Bool is_cp_range_valid(u_register_t *addr)
+{
+ int cp_nr;
+
+ *addr &= MVEBU_CP_BASE_MASK;
+ for (cp_nr = 0; cp_nr < CP_NUM; cp_nr++) {
+ if (*addr == MVEBU_CP_REGS_BASE(cp_nr))
+ return true;
+ }
+
+ return false;
+}
uintptr_t mrvl_sip_smc_handler(uint32_t smc_fid,
u_register_t x1,
@@ -59,20 +72,17 @@ uintptr_t mrvl_sip_smc_handler(uint32_t smc_fid,
debug("%s: got SMC (0x%x) x1 0x%lx, x2 0x%lx, x3 0x%lx\n",
__func__, smc_fid, x1, x2, x3);
- if (is_comphy_fid(smc_fid)) {
-
- /* some systems passes SD phys address instead of COMPHY phys
- * address - convert it
- */
- if (x1 & MVEBU_SD_OFFSET)
- x1 = (x1 & ~0xffffff) + MVEBU_COMPHY_OFFSET;
- if ((x1 & 0xffffff) != MVEBU_COMPHY_OFFSET) {
+ if (is_comphy_fid(smc_fid)) {
+ /* validate address passed via x1 */
+ if (!is_cp_range_valid(&x1)) {
ERROR("%s: Wrong smc (0x%x) address: %lx\n",
__func__, smc_fid, x1);
SMC_RET1(handle, SMC_UNK);
}
+ x1 += MVEBU_COMPHY_OFFSET;
+
if (x2 >= MAX_LANE_NR) {
ERROR("%s: Wrong smc (0x%x) lane nr: %lx\n",
__func__, smc_fid, x2);
@@ -106,8 +116,7 @@ uintptr_t mrvl_sip_smc_handler(uint32_t smc_fid,
/* Miscellaneous FID's' */
case MV_SIP_DRAM_SIZE:
- /* x1: ap_base_addr */
- ret = mvebu_get_dram_size(x1);
+ ret = mvebu_get_dram_size(MVEBU_REGS_BASE);
SMC_RET1(handle, ret);
case MV_SIP_LLC_ENABLE:
for (i = 0; i < ap_get_count(); i++)
diff --git a/plat/rockchip/common/aarch32/plat_helpers.S b/plat/rockchip/common/aarch32/plat_helpers.S
new file mode 100644
index 000000000..475c2972f
--- /dev/null
+++ b/plat/rockchip/common/aarch32/plat_helpers.S
@@ -0,0 +1,164 @@
+/*
+ * Copyright (c) 2013-2019, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <platform_def.h>
+
+#include <arch.h>
+#include <asm_macros.S>
+#include <common/bl_common.h>
+#include <cortex_a12.h>
+#include <plat_private.h>
+#include <plat_pmu_macros.S>
+
+ .globl cpuson_entry_point
+ .globl cpuson_flags
+ .globl platform_cpu_warmboot
+ .globl plat_secondary_cold_boot_setup
+ .globl plat_report_exception
+ .globl plat_is_my_cpu_primary
+ .globl plat_my_core_pos
+ .globl plat_reset_handler
+ .globl plat_panic_handler
+
+ /*
+ * void plat_reset_handler(void);
+ *
+ * Determine the SOC type and call the appropriate reset
+ * handler.
+ *
+ */
+func plat_reset_handler
+ bx lr
+endfunc plat_reset_handler
+
+func plat_my_core_pos
+ ldcopr r0, MPIDR
+ and r1, r0, #MPIDR_CPU_MASK
+#ifdef PLAT_RK_MPIDR_CLUSTER_MASK
+ and r0, r0, #PLAT_RK_MPIDR_CLUSTER_MASK
+#else
+ and r0, r0, #MPIDR_CLUSTER_MASK
+#endif
+ add r0, r1, r0, LSR #PLAT_RK_CLST_TO_CPUID_SHIFT
+ bx lr
+endfunc plat_my_core_pos
+
+ /* --------------------------------------------------------------------
+ * void plat_secondary_cold_boot_setup (void);
+ *
+ * This function performs any platform specific actions
+ * needed for a secondary cpu after a cold reset e.g
+ * mark the cpu's presence, mechanism to place it in a
+ * holding pen etc.
+ * --------------------------------------------------------------------
+ */
+func plat_secondary_cold_boot_setup
+ /* rk3288 does not do cold boot for secondary CPU */
+cb_panic:
+ b cb_panic
+endfunc plat_secondary_cold_boot_setup
+
+func plat_is_my_cpu_primary
+ ldcopr r0, MPIDR
+#ifdef PLAT_RK_MPIDR_CLUSTER_MASK
+ ldr r1, =(PLAT_RK_MPIDR_CLUSTER_MASK | MPIDR_CPU_MASK)
+#else
+ ldr r1, =(MPIDR_CLUSTER_MASK | MPIDR_CPU_MASK)
+#endif
+ and r0, r1
+ cmp r0, #PLAT_RK_PRIMARY_CPU
+ moveq r0, #1
+ movne r0, #0
+ bx lr
+endfunc plat_is_my_cpu_primary
+
+ /* --------------------------------------------------------------------
+ * void plat_panic_handler(void)
+ * Call system reset function on panic. Set up an emergency stack so we
+ * can run C functions (it only needs to last for a few calls until we
+ * reboot anyway).
+ * --------------------------------------------------------------------
+ */
+func plat_panic_handler
+ bl plat_set_my_stack
+ b rockchip_soc_soft_reset
+endfunc plat_panic_handler
+
+ /* --------------------------------------------------------------------
+ * void platform_cpu_warmboot (void);
+ * cpus online or resume entrypoint
+ * --------------------------------------------------------------------
+ */
+func platform_cpu_warmboot _align=16
+ push { r4 - r7, lr }
+ ldcopr r0, MPIDR
+ and r5, r0, #MPIDR_CPU_MASK
+#ifdef PLAT_RK_MPIDR_CLUSTER_MASK
+ and r6, r0, #PLAT_RK_MPIDR_CLUSTER_MASK
+#else
+ and r6, r0, #MPIDR_CLUSTER_MASK
+#endif
+ mov r0, r6
+
+ func_rockchip_clst_warmboot
+ /* --------------------------------------------------------------------
+ * big cluster id is 1
+ * big cores id is from 0-3, little cores id 4-7
+ * --------------------------------------------------------------------
+ */
+ add r7, r5, r6, LSR #PLAT_RK_CLST_TO_CPUID_SHIFT
+ /* --------------------------------------------------------------------
+ * get per cpuup flag
+ * --------------------------------------------------------------------
+ */
+ ldr r4, =cpuson_flags
+ add r4, r4, r7, lsl #2
+ ldr r1, [r4]
+ /* --------------------------------------------------------------------
+ * check cpuon reason
+ * --------------------------------------------------------------------
+ */
+ cmp r1, #PMU_CPU_AUTO_PWRDN
+ beq boot_entry
+ cmp r1, #PMU_CPU_HOTPLUG
+ beq boot_entry
+ /* --------------------------------------------------------------------
+ * If the boot core cpuson_flags or cpuson_entry_point is not
+ * expection. force the core into wfe.
+ * --------------------------------------------------------------------
+ */
+wfe_loop:
+ wfe
+ b wfe_loop
+boot_entry:
+ mov r1, #0
+ str r1, [r4]
+ /* --------------------------------------------------------------------
+ * get per cpuup boot addr
+ * --------------------------------------------------------------------
+ */
+ ldr r5, =cpuson_entry_point
+ ldr r2, [r5, r7, lsl #2] /* ehem. #3 */
+ pop { r4 - r7, lr }
+
+ bx r2
+endfunc platform_cpu_warmboot
+
+ /* --------------------------------------------------------------------
+ * Per-CPU Secure entry point - resume or power up
+ * --------------------------------------------------------------------
+ */
+ .section tzfw_coherent_mem, "a"
+ .align 3
+cpuson_entry_point:
+ .rept PLATFORM_CORE_COUNT
+ .quad 0
+ .endr
+cpuson_flags:
+ .rept PLATFORM_CORE_COUNT
+ .word 0
+ .endr
+rockchip_clst_warmboot_data
diff --git a/plat/rockchip/common/aarch32/platform_common.c b/plat/rockchip/common/aarch32/platform_common.c
new file mode 100644
index 000000000..9030951e4
--- /dev/null
+++ b/plat/rockchip/common/aarch32/platform_common.c
@@ -0,0 +1,57 @@
+/*
+ * Copyright (c) 2013-2019, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <string.h>
+
+#include <platform_def.h>
+
+#include <arch_helpers.h>
+#include <common/bl_common.h>
+#include <common/debug.h>
+#include <lib/utils.h>
+#include <lib/xlat_tables/xlat_tables.h>
+
+#include <plat_private.h>
+
+void plat_configure_mmu_svc_mon(unsigned long total_base,
+ unsigned long total_size,
+ unsigned long ro_start,
+ unsigned long ro_limit,
+ unsigned long coh_start,
+ unsigned long coh_limit)
+{
+ mmap_add_region(total_base, total_base, total_size,
+ MT_MEMORY | MT_RW | MT_SECURE);
+ 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);
+ mmap_add(plat_rk_mmap);
+ rockchip_plat_mmu_svc_mon();
+ init_xlat_tables();
+ enable_mmu_svc_mon(0);
+}
+
+unsigned int plat_get_syscnt_freq2(void)
+{
+ return SYS_COUNTER_FREQ_IN_TICKS;
+}
+
+/*
+ * generic pm code does cci handling, but rockchip arm32 platforms
+ * have ever only 1 cluster, so nothing to do.
+ */
+void plat_cci_init(void)
+{
+}
+
+void plat_cci_enable(void)
+{
+}
+
+void plat_cci_disable(void)
+{
+}
diff --git a/plat/rockchip/common/aarch32/pmu_sram_cpus_on.S b/plat/rockchip/common/aarch32/pmu_sram_cpus_on.S
new file mode 100644
index 000000000..a05ae5435
--- /dev/null
+++ b/plat/rockchip/common/aarch32/pmu_sram_cpus_on.S
@@ -0,0 +1,56 @@
+/*
+ * Copyright (c) 2019, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <arch.h>
+#include <asm_macros.S>
+#include <platform_def.h>
+
+ .globl pmu_cpuson_entrypoint
+ .macro pmusram_entry_func _name
+ .section .pmusram.entry, "ax"
+ .type \_name, %function
+ .cfi_startproc
+ \_name:
+ .endm
+
+pmusram_entry_func pmu_cpuson_entrypoint
+
+#if PSRAM_CHECK_WAKEUP_CPU
+check_wake_cpus:
+ ldcopr r0, MPIDR
+ and r1, r0, #MPIDR_CPU_MASK
+#ifdef PLAT_RK_MPIDR_CLUSTER_MASK
+ and r0, r0, #PLAT_RK_MPIDR_CLUSTER_MASK
+#else
+ and r0, r0, #MPIDR_CLUSTER_MASK
+#endif
+ orr r0, r0, r1
+
+ /* primary_cpu */
+ ldr r1, boot_mpidr
+ cmp r0, r1
+ beq sys_wakeup
+
+ /*
+ * If the core is not the primary cpu,
+ * force the core into wfe.
+ */
+wfe_loop:
+ wfe
+ b wfe_loop
+sys_wakeup:
+#endif
+
+#if PSRAM_DO_DDR_RESUME
+ddr_resume:
+ ldr r2, =__bl32_sram_stack_end
+ mov sp, r2
+ bl dmc_resume
+#endif
+ bl sram_restore
+sys_resume:
+ bl sp_min_warm_entrypoint
+endfunc pmu_cpuson_entrypoint
diff --git a/plat/rockchip/common/pmusram/pmu_sram_cpus_on.S b/plat/rockchip/common/aarch64/pmu_sram_cpus_on.S
index d91ee0e2f..d91ee0e2f 100644
--- a/plat/rockchip/common/pmusram/pmu_sram_cpus_on.S
+++ b/plat/rockchip/common/aarch64/pmu_sram_cpus_on.S
diff --git a/plat/rockchip/common/drivers/pmu/pmu_com.h b/plat/rockchip/common/drivers/pmu/pmu_com.h
index 4b4b00fde..5359f73b4 100644
--- a/plat/rockchip/common/drivers/pmu/pmu_com.h
+++ b/plat/rockchip/common/drivers/pmu/pmu_com.h
@@ -88,6 +88,17 @@ static int check_cpu_wfie(uint32_t cpu_id, uint32_t wfie_msk)
cluster_id = 0;
}
+ /*
+ * wfe/wfi tracking not possible, hopefully the host
+ * was sucessful in enabling wfe/wfi.
+ * We'll give a bit of additional time, like the kernel does.
+ */
+ if ((cluster_id && clstb_cpu_wfe < 0) ||
+ (!cluster_id && clstl_cpu_wfe < 0)) {
+ mdelay(1);
+ return 0;
+ }
+
if (cluster_id)
wfie_msk <<= (clstb_cpu_wfe + cpu_id);
else
diff --git a/plat/rockchip/common/include/plat_private.h b/plat/rockchip/common/include/plat_private.h
index e8750a5e9..f9470e56a 100644
--- a/plat/rockchip/common/include/plat_private.h
+++ b/plat/rockchip/common/include/plat_private.h
@@ -68,6 +68,16 @@ struct rockchip_bl31_params {
/******************************************************************************
* Function and variable prototypes
*****************************************************************************/
+#ifdef AARCH32
+void plat_configure_mmu_svc_mon(unsigned long total_base,
+ unsigned long total_size,
+ unsigned long,
+ unsigned long,
+ unsigned long,
+ unsigned long);
+
+void rockchip_plat_mmu_svc_mon(void);
+#else
void plat_configure_mmu_el3(unsigned long total_base,
unsigned long total_size,
unsigned long,
@@ -75,6 +85,9 @@ void plat_configure_mmu_el3(unsigned long total_base,
unsigned long,
unsigned long);
+void rockchip_plat_mmu_el3(void);
+#endif
+
void plat_cci_init(void);
void plat_cci_enable(void);
void plat_cci_disable(void);
@@ -128,13 +141,11 @@ void __dead2 rockchip_soc_sys_pd_pwr_dn_wfi(void);
extern const unsigned char rockchip_power_domain_tree_desc[];
extern void *pmu_cpuson_entrypoint;
-extern uint64_t cpuson_entry_point[PLATFORM_CORE_COUNT];
+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[];
-void rockchip_plat_mmu_el3(void);
-
#endif /* __ASSEMBLY__ */
/******************************************************************************
diff --git a/plat/rockchip/common/params_setup.c b/plat/rockchip/common/params_setup.c
index dda98d962..baf256330 100644
--- a/plat/rockchip/common/params_setup.c
+++ b/plat/rockchip/common/params_setup.c
@@ -5,6 +5,7 @@
*/
#include <assert.h>
+#include <errno.h>
#include <string.h>
#include <common/bl_common.h>
@@ -28,6 +29,12 @@ static struct gpio_info suspend_gpio[10];
uint32_t suspend_gpio_cnt;
static struct apio_info *suspend_apio;
+#if COREBOOT
+static int dt_process_fdt(void *blob)
+{
+ return -ENODEV;
+}
+#else
static uint8_t fdt_buffer[0x10000];
void *plat_get_fdt(void)
@@ -35,6 +42,19 @@ void *plat_get_fdt(void)
return &fdt_buffer[0];
}
+static int dt_process_fdt(void *blob)
+{
+ void *fdt = plat_get_fdt();
+ int ret;
+
+ ret = fdt_open_into(blob, fdt, 0x10000);
+ if (ret < 0)
+ return ret;
+
+ return 0;
+}
+#endif
+
struct gpio_info *plat_get_rockchip_gpio_reset(void)
{
return rst_gpio;
@@ -57,18 +77,6 @@ struct apio_info *plat_get_rockchip_suspend_apio(void)
return suspend_apio;
}
-static int dt_process_fdt(void *blob)
-{
- void *fdt = plat_get_fdt();
- int ret;
-
- ret = fdt_open_into(blob, fdt, 0x10000);
- if (ret < 0)
- return ret;
-
- return 0;
-}
-
void params_early_setup(void *plat_param_from_bl2)
{
struct bl31_plat_param *bl2_param;
diff --git a/plat/rockchip/common/plat_topology.c b/plat/rockchip/common/plat_topology.c
index a31e4103e..4987eeb2f 100644
--- a/plat/rockchip/common/plat_topology.c
+++ b/plat/rockchip/common/plat_topology.c
@@ -24,7 +24,11 @@ int plat_core_pos_by_mpidr(u_register_t mpidr)
unsigned int cluster_id, cpu_id;
cpu_id = mpidr & MPIDR_AFFLVL_MASK;
+#ifdef PLAT_RK_MPIDR_CLUSTER_MASK
+ cluster_id = mpidr & PLAT_RK_MPIDR_CLUSTER_MASK;
+#else
cluster_id = mpidr & MPIDR_CLUSTER_MASK;
+#endif
cpu_id += (cluster_id >> PLAT_RK_CLST_TO_CPUID_SHIFT);
diff --git a/plat/rockchip/common/sp_min_plat_setup.c b/plat/rockchip/common/sp_min_plat_setup.c
new file mode 100644
index 000000000..7250919e7
--- /dev/null
+++ b/plat/rockchip/common/sp_min_plat_setup.c
@@ -0,0 +1,116 @@
+/*
+ * Copyright (c) 2016-2018, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <assert.h>
+
+#include <platform_def.h>
+
+#include <arch_helpers.h>
+#include <common/bl_common.h>
+#include <common/debug.h>
+#include <drivers/console.h>
+#include <drivers/generic_delay_timer.h>
+#include <drivers/ti/uart/uart_16550.h>
+#include <lib/coreboot.h>
+#include <lib/mmio.h>
+#include <plat_private.h>
+#include <plat/common/platform.h>
+
+static entry_point_info_t bl33_ep_info;
+
+/*******************************************************************************
+ * Return a pointer to the 'entry_point_info' structure of the next image for
+ * the security state specified. BL33 corresponds to the non-secure image type.
+ * A NULL pointer is returned if the image does not exist.
+ ******************************************************************************/
+entry_point_info_t *sp_min_plat_get_bl33_ep_info(void)
+{
+ entry_point_info_t *next_image_info;
+
+ next_image_info = &bl33_ep_info;
+
+ if (next_image_info->pc == 0U) {
+ return NULL;
+ }
+
+ return next_image_info;
+}
+
+#pragma weak params_early_setup
+void params_early_setup(void *plat_param_from_bl2)
+{
+}
+
+unsigned int plat_is_my_cpu_primary(void);
+
+/*******************************************************************************
+ * Perform any BL32 specific platform actions.
+ ******************************************************************************/
+void sp_min_early_platform_setup2(u_register_t arg0, u_register_t arg1,
+ u_register_t arg2, u_register_t arg3)
+{
+ static console_16550_t console;
+ struct rockchip_bl31_params *arg_from_bl2 = (struct rockchip_bl31_params *) arg0;
+ void *plat_params_from_bl2 = (void *) arg1;
+
+ params_early_setup(plat_params_from_bl2);
+
+#if COREBOOT
+ if (coreboot_serial.type)
+ console_16550_register(coreboot_serial.baseaddr,
+ coreboot_serial.input_hertz,
+ coreboot_serial.baud,
+ &console);
+#else
+ console_16550_register(PLAT_RK_UART_BASE, PLAT_RK_UART_CLOCK,
+ PLAT_RK_UART_BAUDRATE, &console);
+#endif
+ VERBOSE("sp_min_setup\n");
+
+ /* Passing a NULL context is a critical programming error */
+ assert(arg_from_bl2);
+
+ assert(arg_from_bl2->h.type == PARAM_BL31);
+ assert(arg_from_bl2->h.version >= VERSION_1);
+
+ bl33_ep_info = *arg_from_bl2->bl33_ep_info;
+}
+
+/*******************************************************************************
+ * Perform any sp_min platform setup code
+ ******************************************************************************/
+void sp_min_platform_setup(void)
+{
+ generic_delay_timer_init();
+ plat_rockchip_soc_init();
+
+ /* Initialize the gic cpu and distributor interfaces */
+ plat_rockchip_gic_driver_init();
+ plat_rockchip_gic_init();
+ plat_rockchip_pmu_init();
+}
+
+/*******************************************************************************
+ * Perform the very early platform specific architectural setup here. At the
+ * moment this is only intializes the mmu in a quick and dirty way.
+ ******************************************************************************/
+void sp_min_plat_arch_setup(void)
+{
+ plat_cci_init();
+ plat_cci_enable();
+
+ plat_configure_mmu_svc_mon(BL_CODE_BASE,
+ BL_COHERENT_RAM_END - BL_CODE_BASE,
+ BL_CODE_BASE,
+ BL_CODE_END,
+ BL_COHERENT_RAM_BASE,
+ BL_COHERENT_RAM_END);
+}
+
+void sp_min_plat_fiq_handler(uint32_t id)
+{
+ VERBOSE("[sp_min] interrupt #%d\n", id);
+}
diff --git a/plat/rockchip/rk3288/drivers/pmu/plat_pmu_macros.S b/plat/rockchip/rk3288/drivers/pmu/plat_pmu_macros.S
new file mode 100644
index 000000000..200374960
--- /dev/null
+++ b/plat/rockchip/rk3288/drivers/pmu/plat_pmu_macros.S
@@ -0,0 +1,17 @@
+/*
+ * Copyright (c) 2016, 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 rk3288 */
+.endm
+
+.macro rockchip_clst_warmboot_data
+ /* Nothing to do for rk3288 */
+.endm
diff --git a/plat/rockchip/rk3288/drivers/pmu/pmu.c b/plat/rockchip/rk3288/drivers/pmu/pmu.c
new file mode 100644
index 000000000..d6d709887
--- /dev/null
+++ b/plat/rockchip/rk3288/drivers/pmu/pmu.c
@@ -0,0 +1,391 @@
+/*
+ * Copyright (c) 2016, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <assert.h>
+#include <errno.h>
+
+#include <platform_def.h>
+
+#include <arch_helpers.h>
+#include <common/debug.h>
+#include <drivers/delay_timer.h>
+#include <lib/mmio.h>
+#include <plat/common/platform.h>
+
+#include <plat_private.h>
+#include <pmu.h>
+#include <pmu_com.h>
+#include <rk3288_def.h>
+#include <secure.h>
+#include <soc.h>
+
+DEFINE_BAKERY_LOCK(rockchip_pd_lock);
+
+static uint32_t cpu_warm_boot_addr;
+
+static uint32_t store_pmu_pwrmode_con;
+static uint32_t store_sgrf_soc_con0;
+static uint32_t store_sgrf_cpu_con0;
+
+/* These enum are variants of low power mode */
+enum {
+ ROCKCHIP_ARM_OFF_LOGIC_NORMAL = 0,
+ ROCKCHIP_ARM_OFF_LOGIC_DEEP = 1,
+};
+
+static inline int rk3288_pmu_bus_idle(uint32_t req, uint32_t idle)
+{
+ uint32_t mask = BIT(req);
+ uint32_t idle_mask = 0;
+ uint32_t idle_target = 0;
+ uint32_t val;
+ uint32_t wait_cnt = 0;
+
+ switch (req) {
+ case bus_ide_req_gpu:
+ idle_mask = BIT(pmu_idle_ack_gpu) | BIT(pmu_idle_gpu);
+ idle_target = (idle << pmu_idle_ack_gpu) |
+ (idle << pmu_idle_gpu);
+ break;
+ case bus_ide_req_core:
+ idle_mask = BIT(pmu_idle_ack_core) | BIT(pmu_idle_core);
+ idle_target = (idle << pmu_idle_ack_core) |
+ (idle << pmu_idle_core);
+ break;
+ case bus_ide_req_cpup:
+ idle_mask = BIT(pmu_idle_ack_cpup) | BIT(pmu_idle_cpup);
+ idle_target = (idle << pmu_idle_ack_cpup) |
+ (idle << pmu_idle_cpup);
+ break;
+ case bus_ide_req_bus:
+ idle_mask = BIT(pmu_idle_ack_bus) | BIT(pmu_idle_bus);
+ idle_target = (idle << pmu_idle_ack_bus) |
+ (idle << pmu_idle_bus);
+ break;
+ case bus_ide_req_dma:
+ idle_mask = BIT(pmu_idle_ack_dma) | BIT(pmu_idle_dma);
+ idle_target = (idle << pmu_idle_ack_dma) |
+ (idle << pmu_idle_dma);
+ break;
+ case bus_ide_req_peri:
+ idle_mask = BIT(pmu_idle_ack_peri) | BIT(pmu_idle_peri);
+ idle_target = (idle << pmu_idle_ack_peri) |
+ (idle << pmu_idle_peri);
+ break;
+ case bus_ide_req_video:
+ idle_mask = BIT(pmu_idle_ack_video) | BIT(pmu_idle_video);
+ idle_target = (idle << pmu_idle_ack_video) |
+ (idle << pmu_idle_video);
+ break;
+ case bus_ide_req_hevc:
+ idle_mask = BIT(pmu_idle_ack_hevc) | BIT(pmu_idle_hevc);
+ idle_target = (idle << pmu_idle_ack_hevc) |
+ (idle << pmu_idle_hevc);
+ break;
+ case bus_ide_req_vio:
+ idle_mask = BIT(pmu_idle_ack_vio) | BIT(pmu_idle_vio);
+ idle_target = (pmu_idle_ack_vio) |
+ (idle << pmu_idle_vio);
+ break;
+ case bus_ide_req_alive:
+ idle_mask = BIT(pmu_idle_ack_alive) | BIT(pmu_idle_alive);
+ idle_target = (idle << pmu_idle_ack_alive) |
+ (idle << pmu_idle_alive);
+ break;
+ default:
+ ERROR("%s: Unsupported the idle request\n", __func__);
+ break;
+ }
+
+ val = mmio_read_32(PMU_BASE + PMU_BUS_IDE_REQ);
+ if (idle)
+ val |= mask;
+ else
+ val &= ~mask;
+
+ mmio_write_32(PMU_BASE + PMU_BUS_IDE_REQ, val);
+
+ while ((mmio_read_32(PMU_BASE +
+ PMU_BUS_IDE_ST) & idle_mask) != idle_target) {
+ wait_cnt++;
+ if (!(wait_cnt % MAX_WAIT_CONUT))
+ WARN("%s:st=%x(%x)\n", __func__,
+ mmio_read_32(PMU_BASE + PMU_BUS_IDE_ST),
+ idle_mask);
+ }
+
+ return 0;
+}
+
+static bool rk3288_sleep_disable_osc(void)
+{
+ static const uint32_t reg_offset[] = { GRF_UOC0_CON0, GRF_UOC1_CON0,
+ GRF_UOC2_CON0 };
+ uint32_t reg, i;
+
+ /*
+ * if any usb phy is still on(GRF_SIDDQ==0), that means we need the
+ * function of usb wakeup, so do not switch to 32khz, since the usb phy
+ * clk does not connect to 32khz osc
+ */
+ for (i = 0; i < ARRAY_SIZE(reg_offset); i++) {
+ reg = mmio_read_32(GRF_BASE + reg_offset[i]);
+ if (!(reg & GRF_SIDDQ))
+ return false;
+ }
+
+ return true;
+}
+
+static void pmu_set_sleep_mode(int level)
+{
+ uint32_t mode_set, mode_set1;
+ bool osc_disable = rk3288_sleep_disable_osc();
+
+ mode_set = BIT(pmu_mode_glb_int_dis) | BIT(pmu_mode_l2_flush_en) |
+ BIT(pmu_mode_sref0_enter) | BIT(pmu_mode_sref1_enter) |
+ BIT(pmu_mode_ddrc0_gt) | BIT(pmu_mode_ddrc1_gt) |
+ BIT(pmu_mode_en) | BIT(pmu_mode_chip_pd) |
+ BIT(pmu_mode_scu_pd);
+
+ mode_set1 = BIT(pmu_mode_clr_core) | BIT(pmu_mode_clr_cpup);
+
+ if (level == ROCKCHIP_ARM_OFF_LOGIC_DEEP) {
+ /* arm off, logic deep sleep */
+ mode_set |= BIT(pmu_mode_bus_pd) | BIT(pmu_mode_pmu_use_lf) |
+ BIT(pmu_mode_ddrio1_ret) |
+ BIT(pmu_mode_ddrio0_ret) |
+ BIT(pmu_mode_pmu_alive_use_lf) |
+ BIT(pmu_mode_pll_pd);
+
+ if (osc_disable)
+ mode_set |= BIT(pmu_mode_osc_dis);
+
+ mode_set1 |= BIT(pmu_mode_clr_alive) | BIT(pmu_mode_clr_bus) |
+ BIT(pmu_mode_clr_peri) | BIT(pmu_mode_clr_dma);
+
+ mmio_write_32(PMU_BASE + PMU_WAKEUP_CFG1,
+ pmu_armint_wakeup_en);
+
+ /*
+ * In deep suspend we use PMU_PMU_USE_LF to let the rk3288
+ * switch its main clock supply to the alternative 32kHz
+ * source. Therefore set 30ms on a 32kHz clock for pmic
+ * stabilization. Similar 30ms on 24MHz for the other
+ * mode below.
+ */
+ mmio_write_32(PMU_BASE + PMU_STABL_CNT, 32 * 30);
+
+ /* only wait for stabilization, if we turned the osc off */
+ mmio_write_32(PMU_BASE + PMU_OSC_CNT,
+ osc_disable ? 32 * 30 : 0);
+ } else {
+ /*
+ * arm off, logic normal
+ * if pmu_clk_core_src_gate_en is not set,
+ * wakeup will be error
+ */
+ mode_set |= BIT(pmu_mode_core_src_gt);
+
+ mmio_write_32(PMU_BASE + PMU_WAKEUP_CFG1,
+ BIT(pmu_armint_wakeup_en) |
+ BIT(pmu_gpioint_wakeup_en));
+
+ /* 30ms on a 24MHz clock for pmic stabilization */
+ mmio_write_32(PMU_BASE + PMU_STABL_CNT, 24000 * 30);
+
+ /* oscillator is still running, so no need to wait */
+ mmio_write_32(PMU_BASE + PMU_OSC_CNT, 0);
+ }
+
+ mmio_write_32(PMU_BASE + PMU_PWRMODE_CON, mode_set);
+ mmio_write_32(PMU_BASE + PMU_PWRMODE_CON1, mode_set1);
+}
+
+static int cpus_power_domain_on(uint32_t cpu_id)
+{
+ uint32_t cpu_pd;
+
+ cpu_pd = PD_CPU0 + cpu_id;
+
+ /* if the core has been on, power it off first */
+ if (pmu_power_domain_st(cpu_pd) == pmu_pd_on) {
+ /* put core in reset - some sort of A12/A17 bug */
+ mmio_write_32(CRU_BASE + CRU_SOFTRSTS_CON(0),
+ BIT(cpu_id) | (BIT(cpu_id) << 16));
+
+ pmu_power_domain_ctr(cpu_pd, pmu_pd_off);
+ }
+
+ pmu_power_domain_ctr(cpu_pd, pmu_pd_on);
+
+ /* pull core out of reset */
+ mmio_write_32(CRU_BASE + CRU_SOFTRSTS_CON(0), BIT(cpu_id) << 16);
+
+ return 0;
+}
+
+static int cpus_power_domain_off(uint32_t cpu_id)
+{
+ uint32_t cpu_pd = PD_CPU0 + cpu_id;
+
+ if (pmu_power_domain_st(cpu_pd) == pmu_pd_off)
+ return 0;
+
+ if (check_cpu_wfie(cpu_id, CKECK_WFEI_MSK))
+ return -EINVAL;
+
+ /* put core in reset - some sort of A12/A17 bug */
+ mmio_write_32(CRU_BASE + CRU_SOFTRSTS_CON(0),
+ BIT(cpu_id) | (BIT(cpu_id) << 16));
+
+ pmu_power_domain_ctr(cpu_pd, pmu_pd_off);
+
+ return 0;
+}
+
+static void nonboot_cpus_off(void)
+{
+ uint32_t boot_cpu, cpu;
+
+ boot_cpu = plat_my_core_pos();
+ boot_cpu = MPIDR_AFFLVL0_VAL(read_mpidr());
+
+ /* turn off noboot cpus */
+ for (cpu = 0; cpu < PLATFORM_CORE_COUNT; cpu++) {
+ if (cpu == boot_cpu)
+ continue;
+
+ cpus_power_domain_off(cpu);
+ }
+}
+
+void sram_save(void)
+{
+ /* TODO: support the sdram save for rk3288 SoCs*/
+}
+
+void sram_restore(void)
+{
+ /* TODO: support the sdram restore for rk3288 SoCs */
+}
+
+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);
+ assert(cpuson_flags[cpu_id] == 0);
+ cpuson_flags[cpu_id] = PMU_CPU_HOTPLUG;
+ cpuson_entry_point[cpu_id] = entrypoint;
+ dsb();
+
+ cpus_power_domain_on(cpu_id);
+
+ /*
+ * We communicate with the bootrom to active the cpus other
+ * than cpu0, after a blob of initialize code, they will
+ * stay at wfe state, once they are actived, they will check
+ * the mailbox:
+ * sram_base_addr + 4: 0xdeadbeaf
+ * sram_base_addr + 8: start address for pc
+ * The cpu0 need to wait the other cpus other than cpu0 entering
+ * the wfe state.The wait time is affected by many aspects.
+ * (e.g: cpu frequency, bootrom frequency, sram frequency, ...)
+ */
+ mdelay(1); /* ensure the cpus other than cpu0 to startup */
+
+ /* tell the bootrom mailbox where to start from */
+ mmio_write_32(SRAM_BASE + 8, cpu_warm_boot_addr);
+ mmio_write_32(SRAM_BASE + 4, 0xDEADBEAF);
+ dsb();
+ sev();
+
+ return 0;
+}
+
+int rockchip_soc_cores_pwr_dm_on_finish(void)
+{
+ return 0;
+}
+
+int rockchip_soc_sys_pwr_dm_resume(void)
+{
+ mmio_write_32(PMU_BASE + PMU_PWRMODE_CON, store_pmu_pwrmode_con);
+ mmio_write_32(SGRF_BASE + SGRF_CPU_CON(0),
+ store_sgrf_cpu_con0 | SGRF_DAPDEVICE_MSK);
+
+ /* disable fastboot mode */
+ mmio_write_32(SGRF_BASE + SGRF_SOC_CON(0),
+ store_sgrf_soc_con0 | SGRF_FAST_BOOT_DIS);
+
+ secure_watchdog_ungate();
+ clk_gate_con_restore();
+ clk_sel_con_restore();
+ clk_plls_resume();
+
+ secure_gic_init();
+ plat_rockchip_gic_init();
+
+ return 0;
+}
+
+int rockchip_soc_sys_pwr_dm_suspend(void)
+{
+ nonboot_cpus_off();
+
+ store_sgrf_cpu_con0 = mmio_read_32(SGRF_BASE + SGRF_CPU_CON(0));
+ store_sgrf_soc_con0 = mmio_read_32(SGRF_BASE + SGRF_SOC_CON(0));
+ store_pmu_pwrmode_con = mmio_read_32(PMU_BASE + PMU_PWRMODE_CON);
+
+ /* save clk-gates and ungate all for suspend */
+ clk_gate_con_save();
+ clk_gate_con_disable();
+ clk_sel_con_save();
+
+ pmu_set_sleep_mode(ROCKCHIP_ARM_OFF_LOGIC_NORMAL);
+
+ clk_plls_suspend();
+ secure_watchdog_gate();
+
+ /*
+ * The dapswjdp can not auto reset before resume, that cause it may
+ * access some illegal address during resume. Let's disable it before
+ * suspend, and the MASKROM will enable it back.
+ */
+ mmio_write_32(SGRF_BASE + SGRF_CPU_CON(0), SGRF_DAPDEVICE_MSK);
+
+ /*
+ * SGRF_FAST_BOOT_EN - system to boot from FAST_BOOT_ADDR
+ */
+ mmio_write_32(SGRF_BASE + SGRF_SOC_CON(0), SGRF_FAST_BOOT_ENA);
+
+ /* boot-address of resuming system is from this register value */
+ mmio_write_32(SGRF_BASE + SGRF_FAST_BOOT_ADDR,
+ (uint32_t)&pmu_cpuson_entrypoint);
+
+ /* flush all caches - otherwise we might loose the resume address */
+ dcsw_op_all(DC_OP_CISW);
+
+ return 0;
+}
+
+void rockchip_plat_mmu_svc_mon(void)
+{
+}
+
+void plat_rockchip_pmu_init(void)
+{
+ uint32_t cpu;
+
+ cpu_warm_boot_addr = (uint32_t)platform_cpu_warmboot;
+
+ /* on boot all power-domains are on */
+ for (cpu = 0; cpu < PLATFORM_CORE_COUNT; cpu++)
+ cpuson_flags[cpu] = pmu_pd_on;
+
+ nonboot_cpus_off();
+}
diff --git a/plat/rockchip/rk3288/drivers/pmu/pmu.h b/plat/rockchip/rk3288/drivers/pmu/pmu.h
new file mode 100644
index 000000000..06d552837
--- /dev/null
+++ b/plat/rockchip/rk3288/drivers/pmu/pmu.h
@@ -0,0 +1,151 @@
+/*
+ * Copyright (c) 2016, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef PMU_H
+#define PMU_H
+
+/* Allocate sp reginon in pmusram */
+#define PSRAM_SP_SIZE 0x80
+#define PSRAM_SP_BOTTOM (PSRAM_SP_TOP - PSRAM_SP_SIZE)
+
+/*****************************************************************************
+ * pmu con,reg
+ *****************************************************************************/
+#define PMU_WAKEUP_CFG0 0x0
+#define PMU_WAKEUP_CFG1 0x4
+#define PMU_PWRDN_CON 0x8
+#define PMU_PWRDN_ST 0xc
+
+#define PMU_PWRMODE_CON 0x18
+#define PMU_BUS_IDE_REQ 0x10
+#define PMU_BUS_IDE_ST 0x14
+
+#define PMU_OSC_CNT 0x20
+#define PMU_PLL_CNT 0x24
+#define PMU_STABL_CNT 0x28
+#define PMU_DDRIO0_PWR_CNT 0x2c
+#define PMU_DDRIO1_PWR_CNT 0x30
+#define PMU_WKUPRST_CNT 0x44
+#define PMU_SFT_CON 0x48
+#define PMU_PWRMODE_CON1 0x90
+
+enum pmu_pdid {
+ PD_CPU0 = 0,
+ PD_CPU1,
+ PD_CPU2,
+ PD_CPU3,
+ PD_BUS = 5,
+ PD_PERI,
+ PD_VIO,
+ PD_VIDEO,
+ PD_GPU,
+ PD_SCU = 11,
+ PD_HEVC = 14,
+ PD_END
+};
+
+enum pmu_bus_ide {
+ bus_ide_req_bus = 0,
+ bus_ide_req_peri,
+ bus_ide_req_gpu,
+ bus_ide_req_video,
+ bus_ide_req_vio,
+ bus_ide_req_core,
+ bus_ide_req_alive,
+ bus_ide_req_dma,
+ bus_ide_req_cpup,
+ bus_ide_req_hevc,
+ bus_ide_req_end
+};
+
+enum pmu_pwrmode {
+ pmu_mode_en = 0,
+ pmu_mode_core_src_gt,
+ pmu_mode_glb_int_dis,
+ pmu_mode_l2_flush_en,
+ pmu_mode_bus_pd,
+ pmu_mode_cpu0_pd,
+ pmu_mode_scu_pd,
+ pmu_mode_pll_pd = 7,
+ pmu_mode_chip_pd,
+ pmu_mode_pwr_off_comb,
+ pmu_mode_pmu_alive_use_lf,
+ pmu_mode_pmu_use_lf,
+ pmu_mode_osc_dis = 12,
+ pmu_mode_input_clamp,
+ pmu_mode_wkup_rst,
+ pmu_mode_sref0_enter,
+ pmu_mode_sref1_enter,
+ pmu_mode_ddrio0_ret,
+ pmu_mode_ddrio1_ret,
+ pmu_mode_ddrc0_gt,
+ pmu_mode_ddrc1_gt,
+ pmu_mode_ddrio0_ret_deq,
+ pmu_mode_ddrio1_ret_deq,
+};
+
+enum pmu_pwrmode1 {
+ pmu_mode_clr_bus = 0,
+ pmu_mode_clr_core,
+ pmu_mode_clr_cpup,
+ pmu_mode_clr_alive,
+ pmu_mode_clr_dma,
+ pmu_mode_clr_peri,
+ pmu_mode_clr_gpu,
+ pmu_mode_clr_video,
+ pmu_mode_clr_hevc,
+ pmu_mode_clr_vio
+};
+
+enum pmu_sft_con {
+ pmu_sft_ddrio0_ret_cfg = 6,
+ pmu_sft_ddrio1_ret_cfg = 9,
+ pmu_sft_l2flsh = 15,
+};
+
+enum pmu_wakeup_cfg1 {
+ pmu_armint_wakeup_en = 0,
+ pmu_gpio_wakeup_negedge,
+ pmu_sdmmc0_wakeup_en,
+ pmu_gpioint_wakeup_en,
+};
+
+enum pmu_bus_idle_st {
+ pmu_idle_bus = 0,
+ pmu_idle_peri,
+ pmu_idle_gpu,
+ pmu_idle_video,
+ pmu_idle_vio,
+ pmu_idle_core,
+ pmu_idle_alive,
+ pmu_idle_dma,
+ pmu_idle_cpup,
+ pmu_idle_hevc,
+ pmu_idle_ack_bus = 16,
+ pmu_idle_ack_peri,
+ pmu_idle_ack_gpu,
+ pmu_idle_ack_video,
+ pmu_idle_ack_vio,
+ pmu_idle_ack_core,
+ pmu_idle_ack_alive,
+ pmu_idle_ack_dma,
+ pmu_idle_ack_cpup,
+ pmu_idle_ack_hevc,
+};
+
+#define CHECK_CPU_WFIE_BASE (0)
+
+#define clstl_cpu_wfe -1
+#define clstb_cpu_wfe -1
+#define CKECK_WFEI_MSK 0
+
+
+#define PD_CTR_LOOP 500
+#define CHK_CPU_LOOP 500
+
+#define MAX_WAIT_CONUT 1000
+
+#endif /* PMU_H */
diff --git a/plat/rockchip/rk3288/drivers/secure/secure.c b/plat/rockchip/rk3288/drivers/secure/secure.c
new file mode 100644
index 000000000..68994e458
--- /dev/null
+++ b/plat/rockchip/rk3288/drivers/secure/secure.c
@@ -0,0 +1,162 @@
+/*
+ * Copyright (c) 2016, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <assert.h>
+
+#include <arch_helpers.h>
+#include <common/debug.h>
+#include <drivers/delay_timer.h>
+
+#include <plat_private.h>
+#include <secure.h>
+#include <soc.h>
+
+static void sgrf_ddr_rgn_global_bypass(uint32_t bypass)
+{
+ if (bypass)
+ /* set bypass (non-secure regions) for whole ddr regions */
+ mmio_write_32(SGRF_BASE + SGRF_SOC_CON(21),
+ SGRF_DDR_RGN_BYPS);
+ else
+ /* cancel bypass for whole ddr regions */
+ mmio_write_32(SGRF_BASE + SGRF_SOC_CON(21),
+ SGRF_DDR_RGN_NO_BYPS);
+}
+
+/**
+ * There are 8 + 1 regions for DDR secure control:
+ * DDR_RGN_0 ~ DDR_RGN_7: Per DDR_RGNs grain size is 1MB
+ * DDR_RGN_X - the memories of exclude DDR_RGN_0 ~ DDR_RGN_7
+ *
+ * SGRF_SOC_CON6 - start address of RGN_0 + control
+ * SGRF_SOC_CON7 - end address of RGN_0
+ * ...
+ * SGRF_SOC_CON20 - start address of the RGN_7 + control
+ * SGRF_SOC_CON21 - end address of the RGN_7 + RGN_X control
+ *
+ * @rgn - the DDR regions 0 ~ 7 which are can be configured.
+ * The @st and @ed indicate the start and end addresses for which to set
+ * the security, and the unit is byte. When the st_mb == 0, ed_mb == 0, the
+ * address range 0x0 ~ 0xfffff is secure.
+ *
+ * For example, if we would like to set the range [0, 32MB) is security via
+ * DDR_RGN0, then rgn == 0, st_mb == 0, ed_mb == 31.
+ */
+static void sgrf_ddr_rgn_config(uint32_t rgn, uintptr_t st, uintptr_t ed)
+{
+ uintptr_t st_mb, ed_mb;
+
+ assert(rgn <= 7);
+ assert(st < ed);
+
+ /* check aligned 1MB */
+ assert(st % SIZE_M(1) == 0);
+ assert(ed % SIZE_M(1) == 0);
+
+ st_mb = st / SIZE_M(1);
+ ed_mb = ed / SIZE_M(1);
+
+ /* set ddr region addr start */
+ mmio_write_32(SGRF_BASE + SGRF_SOC_CON(6 + (rgn * 2)),
+ BITS_WITH_WMASK(st_mb, SGRF_DDR_RGN_ADDR_WMSK, 0));
+
+ /* set ddr region addr end */
+ mmio_write_32(SGRF_BASE + SGRF_SOC_CON(6 + (rgn * 2) + 1),
+ BITS_WITH_WMASK((ed_mb - 1), SGRF_DDR_RGN_ADDR_WMSK, 0));
+
+ /* select region security */
+ mmio_write_32(SGRF_BASE + SGRF_SOC_CON(6 + (rgn * 2)),
+ SGRF_DDR_RGN_SECURE_SEL);
+
+ /* enable region security */
+ mmio_write_32(SGRF_BASE + SGRF_SOC_CON(6 + (rgn * 2)),
+ SGRF_DDR_RGN_SECURE_EN);
+}
+
+void secure_watchdog_gate(void)
+{
+ mmio_write_32(SGRF_BASE + SGRF_SOC_CON(0), SGRF_PCLK_WDT_GATE);
+}
+
+void secure_watchdog_ungate(void)
+{
+ mmio_write_32(SGRF_BASE + SGRF_SOC_CON(0), SGRF_PCLK_WDT_UNGATE);
+}
+
+__pmusramfunc void sram_secure_timer_init(void)
+{
+ mmio_write_32(STIMER1_BASE + TIMER_CONTROL_REG, 0);
+
+ mmio_write_32(STIMER1_BASE + TIMER_LOAD_COUNT0, 0xffffffff);
+ mmio_write_32(STIMER1_BASE + TIMER_LOAD_COUNT1, 0xffffffff);
+
+ /* auto reload & enable the timer */
+ mmio_write_32(STIMER1_BASE + TIMER_CONTROL_REG, TIMER_EN);
+}
+
+void secure_gic_init(void)
+{
+ /* (re-)enable non-secure access to the gic*/
+ mmio_write_32(CORE_AXI_BUS_BASE + CORE_AXI_SECURITY0,
+ AXI_SECURITY0_GIC);
+}
+
+void secure_timer_init(void)
+{
+ mmio_write_32(STIMER1_BASE + TIMER_CONTROL_REG, 0);
+
+ mmio_write_32(STIMER1_BASE + TIMER_LOAD_COUNT0, 0xffffffff);
+ mmio_write_32(STIMER1_BASE + TIMER_LOAD_COUNT1, 0xffffffff);
+
+ /* auto reload & enable the timer */
+ mmio_write_32(STIMER1_BASE + TIMER_CONTROL_REG, TIMER_EN);
+}
+
+void secure_sgrf_init(void)
+{
+ /*
+ * We use the first sram part to talk to the bootrom,
+ * so make it secure.
+ */
+ mmio_write_32(TZPC_BASE + TZPC_R0SIZE, TZPC_SRAM_SECURE_4K(1));
+
+ secure_gic_init();
+
+ /* set all master ip to non-secure */
+ mmio_write_32(SGRF_BASE + SGRF_SOC_CON(2), SGRF_SOC_CON2_MST_NS);
+ mmio_write_32(SGRF_BASE + SGRF_SOC_CON(3), SGRF_SOC_CON3_MST_NS);
+
+ /* setting all configurable ip into non-secure */
+ mmio_write_32(SGRF_BASE + SGRF_SOC_CON(4),
+ SGRF_SOC_CON4_SECURE_WMSK /*TODO:|SGRF_STIMER_SECURE*/);
+ mmio_write_32(SGRF_BASE + SGRF_SOC_CON(5), SGRF_SOC_CON5_SECURE_WMSK);
+
+ /* secure dma to non-secure */
+ mmio_write_32(TZPC_BASE + TZPC_DECPROT1SET, 0xff);
+ mmio_write_32(TZPC_BASE + TZPC_DECPROT2SET, 0xff);
+ mmio_write_32(SGRF_BASE + SGRF_BUSDMAC_CON(1), 0x3800);
+ dsb();
+
+ /* rst dma1 */
+ mmio_write_32(CRU_BASE + CRU_SOFTRSTS_CON(1),
+ RST_DMA1_MSK | (RST_DMA1_MSK << 16));
+ /* rst dma2 */
+ mmio_write_32(CRU_BASE + CRU_SOFTRSTS_CON(4),
+ RST_DMA2_MSK | (RST_DMA2_MSK << 16));
+
+ dsb();
+
+ /* release dma1 rst*/
+ mmio_write_32(CRU_BASE + CRU_SOFTRSTS_CON(1), (RST_DMA1_MSK << 16));
+ /* release dma2 rst*/
+ mmio_write_32(CRU_BASE + CRU_SOFTRSTS_CON(4), (RST_DMA2_MSK << 16));
+}
+
+void secure_sgrf_ddr_rgn_init(void)
+{
+ sgrf_ddr_rgn_config(0, TZRAM_BASE, TZRAM_SIZE);
+ sgrf_ddr_rgn_global_bypass(0);
+}
diff --git a/plat/rockchip/rk3288/drivers/secure/secure.h b/plat/rockchip/rk3288/drivers/secure/secure.h
new file mode 100644
index 000000000..6c0b2b7dc
--- /dev/null
+++ b/plat/rockchip/rk3288/drivers/secure/secure.h
@@ -0,0 +1,102 @@
+/*
+ * Copyright (c) 2016, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef SECURE_H
+#define SECURE_H
+
+/******************************************************************************
+ * TZPC TrustZone controller
+ ******************************************************************************/
+
+#define TZPC_R0SIZE 0x0
+#define TZPC_SRAM_SECURE_4K(n) ((n) > 0x200 ? 0x200 : (n))
+#define TZPC_DECPROT1STAT 0x80c
+#define TZPC_DECPROT1SET 0x810
+#define TZPC_DECPROT1CLR 0x814
+#define TZPC_DECPROT2STAT 0x818
+#define TZPC_DECPROT2SET 0x818
+#define TZPC_DECPROT2CLR 0x820
+
+/**************************************************
+ * sgrf reg, offset
+ **************************************************/
+/*
+ * soc_con0-5 start at 0x0, soc_con6-... start art 0x50
+ * adjusted for the 5 lower registers
+ */
+#define SGRF_SOC_CON(n) ((((n) < 6) ? 0x0 : 0x38) + (n) * 4)
+#define SGRF_BUSDMAC_CON(n) (0x20 + (n) * 4)
+#define SGRF_CPU_CON(n) (0x40 + (n) * 4)
+#define SGRF_SOC_STATUS(n) (0x100 + (n) * 4)
+#define SGRF_FAST_BOOT_ADDR 0x120
+
+/* SGRF_SOC_CON0 */
+#define SGRF_FAST_BOOT_ENA BIT_WITH_WMSK(8)
+#define SGRF_FAST_BOOT_DIS WMSK_BIT(8)
+#define SGRF_PCLK_WDT_GATE BIT_WITH_WMSK(6)
+#define SGRF_PCLK_WDT_UNGATE WMSK_BIT(6)
+#define SGRF_PCLK_STIMER_GATE BIT_WITH_WMSK(4)
+
+#define SGRF_SOC_CON2_MST_NS 0xffe0ffe0
+#define SGRF_SOC_CON3_MST_NS 0x003f003f
+
+/* SGRF_SOC_CON4 */
+#define SGRF_SOC_CON4_SECURE_WMSK 0xffff0000
+#define SGRF_DDRC1_SECURE BIT_WITH_WMSK(12)
+#define SGRF_DDRC0_SECURE BIT_WITH_WMSK(11)
+#define SGRF_PMUSRAM_SECURE BIT_WITH_WMSK(8)
+#define SGRF_WDT_SECURE BIT_WITH_WMSK(7)
+#define SGRF_STIMER_SECURE BIT_WITH_WMSK(6)
+
+/* SGRF_SOC_CON5 */
+#define SGRF_SLV_SEC_BYPS BIT_WITH_WMSK(15)
+#define SGRF_SLV_SEC_NO_BYPS WMSK_BIT(15)
+#define SGRF_SOC_CON5_SECURE_WMSK 0x00ff0000
+
+/* ddr regions in SGRF_SOC_CON6 and following */
+#define SGRF_DDR_RGN_SECURE_SEL BIT_WITH_WMSK(15)
+#define SGRF_DDR_RGN_SECURE_EN BIT_WITH_WMSK(14)
+#define SGRF_DDR_RGN_ADDR_WMSK 0x0fff
+
+/* SGRF_SOC_CON21 */
+/* All security of the DDR RGNs are bypassed */
+#define SGRF_DDR_RGN_BYPS BIT_WITH_WMSK(15)
+#define SGRF_DDR_RGN_NO_BYPS WMSK_BIT(15)
+
+/* SGRF_CPU_CON0 */
+#define SGRF_DAPDEVICE_ENA BIT_WITH_WMSK(0)
+#define SGRF_DAPDEVICE_MSK WMSK_BIT(0)
+
+/*****************************************************************************
+ * core-axi
+ *****************************************************************************/
+#define CORE_AXI_SECURITY0 0x08
+#define AXI_SECURITY0_GIC BIT(0)
+
+/*****************************************************************************
+ * secure timer
+ *****************************************************************************/
+#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_EN 0x1
+
+#define STIMER1_BASE (STIME_BASE + 0x20)
+
+/* export secure operating APIs */
+void secure_watchdog_gate(void);
+void secure_watchdog_ungate(void);
+void secure_gic_init(void);
+void secure_timer_init(void);
+void secure_sgrf_init(void);
+void secure_sgrf_ddr_rgn_init(void);
+__pmusramfunc void sram_secure_timer_init(void);
+
+#endif /* SECURE_H */
diff --git a/plat/rockchip/rk3288/drivers/soc/soc.c b/plat/rockchip/rk3288/drivers/soc/soc.c
new file mode 100644
index 000000000..db90ae41b
--- /dev/null
+++ b/plat/rockchip/rk3288/drivers/soc/soc.c
@@ -0,0 +1,215 @@
+/*
+ * Copyright (c) 2016, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <platform_def.h>
+
+#include <arch_helpers.h>
+#include <common/debug.h>
+#include <lib/mmio.h>
+
+#include <plat_private.h>
+#include <rk3288_def.h>
+#include <soc.h>
+#include <secure.h>
+
+/* sleep data for pll suspend */
+static struct deepsleep_data_s slp_data;
+
+/* Table of regions to map using the MMU. */
+const mmap_region_t plat_rk_mmap[] = {
+ MAP_REGION_FLAT(GIC400_BASE, GIC400_SIZE,
+ MT_DEVICE | MT_RW | MT_SECURE),
+ MAP_REGION_FLAT(STIME_BASE, STIME_SIZE,
+ MT_DEVICE | MT_RW | MT_SECURE),
+ MAP_REGION_FLAT(SGRF_BASE, SGRF_SIZE,
+ MT_DEVICE | MT_RW | MT_SECURE),
+ MAP_REGION_FLAT(TZPC_BASE, TZPC_SIZE,
+ MT_DEVICE | MT_RW | MT_SECURE),
+ MAP_REGION_FLAT(PMUSRAM_BASE, PMUSRAM_SIZE,
+ MT_MEMORY | MT_RW | MT_SECURE),
+ MAP_REGION_FLAT(SRAM_BASE, SRAM_SIZE,
+ MT_DEVICE | MT_RW | MT_SECURE),
+ MAP_REGION_FLAT(PMU_BASE, PMU_SIZE,
+ MT_DEVICE | MT_RW | MT_SECURE),
+ MAP_REGION_FLAT(UART_DBG_BASE, UART_DBG_SIZE,
+ MT_DEVICE | MT_RW | MT_SECURE),
+ MAP_REGION_FLAT(CRU_BASE, CRU_SIZE,
+ MT_DEVICE | MT_RW | MT_SECURE),
+ MAP_REGION_FLAT(GRF_BASE, GRF_SIZE,
+ MT_DEVICE | MT_RW | MT_SECURE),
+ MAP_REGION_FLAT(DDR_PCTL0_BASE, DDR_PCTL0_SIZE,
+ MT_DEVICE | MT_RW | MT_SECURE),
+ MAP_REGION_FLAT(DDR_PHY0_BASE, DDR_PHY0_SIZE,
+ MT_DEVICE | MT_RW | MT_SECURE),
+ MAP_REGION_FLAT(DDR_PCTL1_BASE, DDR_PCTL1_SIZE,
+ MT_DEVICE | MT_RW | MT_SECURE),
+ MAP_REGION_FLAT(DDR_PHY1_BASE, DDR_PHY1_SIZE,
+ MT_DEVICE | MT_RW | MT_SECURE),
+ MAP_REGION_FLAT(SERVICE_BUS_BASE, SERVICE_BUS_SIZE,
+ MT_DEVICE | MT_RW | MT_SECURE),
+ MAP_REGION_FLAT(CORE_AXI_BUS_BASE, CORE_AXI_BUS_SIZE,
+ MT_DEVICE | 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,
+};
+
+void plat_rockchip_soc_init(void)
+{
+ secure_timer_init();
+ secure_sgrf_init();
+ /*
+ * We cannot enable ddr security at this point, as the kernel
+ * seems to have an issue with it even living in the same 128MB
+ * memory block. Only when moving the kernel to the second
+ * 128MB block does it not conflict, but then we'd loose this
+ * memory area for use. Late maybe enable
+ * secure_sgrf_ddr_rgn_init();
+ */
+}
+
+void regs_update_bits(uintptr_t addr, uint32_t val,
+ uint32_t mask, uint32_t shift)
+{
+ uint32_t tmp, orig;
+
+ orig = mmio_read_32(addr);
+
+ tmp = orig & ~(mask << shift);
+ tmp |= (val & mask) << shift;
+
+ if (tmp != orig)
+ mmio_write_32(addr, tmp);
+ dsb();
+}
+
+static void pll_save(uint32_t pll_id)
+{
+ uint32_t *pll = slp_data.pll_con[pll_id];
+
+ pll[0] = mmio_read_32(CRU_BASE + PLL_CONS((pll_id), 0));
+ pll[1] = mmio_read_32(CRU_BASE + PLL_CONS((pll_id), 1));
+ pll[2] = mmio_read_32(CRU_BASE + PLL_CONS((pll_id), 2));
+ pll[3] = mmio_read_32(CRU_BASE + PLL_CONS((pll_id), 3));
+}
+
+void clk_plls_suspend(void)
+{
+ pll_save(NPLL_ID);
+ pll_save(CPLL_ID);
+ pll_save(GPLL_ID);
+ pll_save(APLL_ID);
+ slp_data.pll_mode = mmio_read_32(CRU_BASE + PLL_MODE_CON);
+
+ /*
+ * Switch PLLs other than DPLL (for SDRAM) to slow mode to
+ * avoid crashes on resume. The Mask ROM on the system will
+ * put APLL, CPLL, and GPLL into slow mode at resume time
+ * anyway (which is why we restore them), but we might not
+ * even make it to the Mask ROM if this isn't done at suspend
+ * time.
+ *
+ * NOTE: only APLL truly matters here, but we'll do them all.
+ */
+ mmio_write_32(CRU_BASE + PLL_MODE_CON, 0xf3030000);
+}
+
+void clk_plls_resume(void)
+{
+ /* restore pll-modes */
+ mmio_write_32(CRU_BASE + PLL_MODE_CON,
+ slp_data.pll_mode | REG_SOC_WMSK);
+}
+
+void clk_gate_con_save(void)
+{
+ uint32_t i = 0;
+
+ for (i = 0; i < CRU_CLKGATES_CON_CNT; i++)
+ slp_data.cru_gate_con[i] =
+ mmio_read_32(CRU_BASE + CRU_CLKGATES_CON(i));
+}
+
+void clk_gate_con_disable(void)
+{
+ uint32_t i;
+
+ for (i = 0; i < CRU_CLKGATES_CON_CNT; i++)
+ mmio_write_32(CRU_BASE + CRU_CLKGATES_CON(i), REG_SOC_WMSK);
+}
+
+void clk_gate_con_restore(void)
+{
+ uint32_t i;
+
+ for (i = 0; i < CRU_CLKGATES_CON_CNT; i++)
+ mmio_write_32(CRU_BASE + CRU_CLKGATES_CON(i),
+ REG_SOC_WMSK | slp_data.cru_gate_con[i]);
+}
+
+void clk_sel_con_save(void)
+{
+ uint32_t i = 0;
+
+ for (i = 0; i < CRU_CLKSELS_CON_CNT; i++)
+ slp_data.cru_sel_con[i] =
+ mmio_read_32(CRU_BASE + CRU_CLKSELS_CON(i));
+}
+
+void clk_sel_con_restore(void)
+{
+ uint32_t i, val;
+
+ for (i = 0; i < CRU_CLKSELS_CON_CNT; i++) {
+ /* fractional dividers don't have write-masks */
+ if ((i >= 7 && i <= 9) ||
+ (i >= 17 && i <= 20) ||
+ (i == 23) || (i == 41))
+ val = slp_data.cru_sel_con[i];
+ else
+ val = slp_data.cru_sel_con[i] | REG_SOC_WMSK;
+
+ mmio_write_32(CRU_BASE + CRU_CLKSELS_CON(i), val);
+ }
+}
+
+void __dead2 rockchip_soc_soft_reset(void)
+{
+ uint32_t temp_val;
+
+ /*
+ * Switch PLLs other than DPLL (for SDRAM) to slow mode to
+ * avoid crashes on resume. The Mask ROM on the system will
+ * put APLL, CPLL, and GPLL into slow mode at resume time
+ * anyway (which is why we restore them), but we might not
+ * even make it to the Mask ROM if this isn't done at suspend
+ * time.
+ *
+ * NOTE: only APLL truly matters here, but we'll do them all.
+ */
+ mmio_write_32(CRU_BASE + PLL_MODE_CON, 0xf3030000);
+
+ temp_val = mmio_read_32(CRU_BASE + CRU_GLB_RST_CON);
+ temp_val &= ~PMU_RST_MASK;
+ temp_val |= PMU_RST_BY_SECOND_SFT;
+ mmio_write_32(CRU_BASE + CRU_GLB_RST_CON, temp_val);
+ mmio_write_32(CRU_BASE + CRU_GLB_SRST_SND, 0xeca8);
+
+ /*
+ * Maybe the HW needs some times to reset the system,
+ * so we do not hope the core to excute valid codes.
+ */
+ while (1)
+ ;
+}
diff --git a/plat/rockchip/rk3288/drivers/soc/soc.h b/plat/rockchip/rk3288/drivers/soc/soc.h
new file mode 100644
index 000000000..b96c4dcd2
--- /dev/null
+++ b/plat/rockchip/rk3288/drivers/soc/soc.h
@@ -0,0 +1,110 @@
+/*
+ * Copyright (c) 2016, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef SOC_H
+#define SOC_H
+
+enum plls_id {
+ APLL_ID = 0,
+ DPLL_ID,
+ CPLL_ID,
+ GPLL_ID,
+ NPLL_ID,
+ END_PLL_ID,
+};
+
+
+#define CYCL_24M_CNT_US(us) (24 * (us))
+#define CYCL_24M_CNT_MS(ms) ((ms) * CYCL_24M_CNT_US(1000))
+
+/*****************************************************************************
+ * grf regs
+ *****************************************************************************/
+#define GRF_UOC0_CON0 0x320
+#define GRF_UOC1_CON0 0x334
+#define GRF_UOC2_CON0 0x348
+#define GRF_SIDDQ BIT(13)
+
+/*****************************************************************************
+ * cru reg, offset
+ *****************************************************************************/
+#define CRU_SOFTRST_CON 0x1b8
+#define CRU_SOFTRSTS_CON(n) (CRU_SOFTRST_CON + ((n) * 4))
+#define CRU_SOFTRSTS_CON_CNT 11
+
+#define RST_DMA1_MSK 0x4
+#define RST_DMA2_MSK 0x1
+
+#define CRU_CLKSEL_CON 0x60
+#define CRU_CLKSELS_CON(i) (CRU_CLKSEL_CON + ((i) * 4))
+#define CRU_CLKSELS_CON_CNT 42
+
+#define CRU_CLKGATE_CON 0x160
+#define CRU_CLKGATES_CON(i) (CRU_CLKGATE_CON + ((i) * 4))
+#define CRU_CLKGATES_CON_CNT 18
+
+#define CRU_GLB_SRST_FST 0x1b0
+#define CRU_GLB_SRST_SND 0x1b4
+#define CRU_GLB_RST_CON 0x1f0
+
+#define CRU_CONS_GATEID(i) (16 * (i))
+#define GATE_ID(reg, bit) (((reg) * 16) + (bit))
+
+#define PMU_RST_MASK 0x3
+#define PMU_RST_BY_FIRST_SFT (0 << 2)
+#define PMU_RST_BY_SECOND_SFT (1 << 2)
+#define PMU_RST_NOT_BY_SFT (2 << 2)
+
+/***************************************************************************
+ * pll
+ ***************************************************************************/
+#define PLL_CON_COUNT 4
+#define PLL_CONS(id, i) ((id) * 0x10 + ((i) * 4))
+#define PLL_PWR_DN_MSK BIT(1)
+#define PLL_PWR_DN REG_WMSK_BITS(1, 1, 0x1)
+#define PLL_PWR_ON REG_WMSK_BITS(0, 1, 0x1)
+#define PLL_RESET REG_WMSK_BITS(1, 5, 0x1)
+#define PLL_RESET_RESUME REG_WMSK_BITS(0, 5, 0x1)
+#define PLL_BYPASS_MSK BIT(0)
+#define PLL_BYPASS_W_MSK (PLL_BYPASS_MSK << 16)
+#define PLL_BYPASS REG_WMSK_BITS(1, 0, 0x1)
+#define PLL_NO_BYPASS REG_WMSK_BITS(0, 0, 0x1)
+
+#define PLL_MODE_CON 0x50
+
+struct deepsleep_data_s {
+ uint32_t pll_con[END_PLL_ID][PLL_CON_COUNT];
+ uint32_t pll_mode;
+ uint32_t cru_sel_con[CRU_CLKSELS_CON_CNT];
+ uint32_t cru_gate_con[CRU_CLKGATES_CON_CNT];
+};
+
+#define REG_W_MSK(bits_shift, msk) \
+ ((msk) << ((bits_shift) + 16))
+#define REG_VAL_CLRBITS(val, bits_shift, msk) \
+ ((val) & (~((msk) << bits_shift)))
+#define REG_SET_BITS(bits, bits_shift, msk) \
+ (((bits) & (msk)) << (bits_shift))
+#define REG_WMSK_BITS(bits, bits_shift, msk) \
+ (REG_W_MSK(bits_shift, msk) | \
+ REG_SET_BITS(bits, bits_shift, msk))
+#define REG_SOC_WMSK 0xffff0000
+
+#define regs_update_bit_set(addr, shift) \
+ regs_update_bits((addr), 0x1, 0x1, (shift))
+#define regs_update_bit_clr(addr, shift) \
+ regs_update_bits((addr), 0x0, 0x1, (shift))
+
+void regs_update_bits(uintptr_t addr, uint32_t val,
+ uint32_t mask, uint32_t shift);
+void clk_plls_suspend(void);
+void clk_plls_resume(void);
+void clk_gate_con_save(void);
+void clk_gate_con_disable(void);
+void clk_gate_con_restore(void);
+void clk_sel_con_save(void);
+void clk_sel_con_restore(void);
+#endif /* SOC_H */
diff --git a/plat/rockchip/rk3288/include/plat_sip_calls.h b/plat/rockchip/rk3288/include/plat_sip_calls.h
new file mode 100644
index 000000000..66c4868cb
--- /dev/null
+++ b/plat/rockchip/rk3288/include/plat_sip_calls.h
@@ -0,0 +1,12 @@
+/*
+ * Copyright (c) 2016, 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/rk3288/include/plat_sp_min.ld.S b/plat/rockchip/rk3288/include/plat_sp_min.ld.S
new file mode 100644
index 000000000..287843768
--- /dev/null
+++ b/plat/rockchip/rk3288/include/plat_sp_min.ld.S
@@ -0,0 +1,72 @@
+/*
+ * Copyright (c) 2016, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+#ifndef ROCKCHIP_PLAT_LD_S
+#define ROCKCHIP_PLAT_LD_S
+
+#include <lib/xlat_tables/xlat_tables_defs.h>
+
+MEMORY {
+ SRAM (rwx): ORIGIN = SRAM_BASE, LENGTH = SRAM_SIZE
+ PMUSRAM (rwx): ORIGIN = PMUSRAM_BASE, LENGTH = PMUSRAM_RSIZE
+}
+
+SECTIONS
+{
+ . = SRAM_BASE;
+ ASSERT(. == ALIGN(PAGE_SIZE),
+ "SRAM_BASE address is not aligned on a page boundary.")
+
+ .text_sram : ALIGN(PAGE_SIZE) {
+ __bl32_sram_text_start = .;
+ *(.sram.text)
+ *(.sram.rodata)
+ __bl32_sram_text_real_end = .;
+ . = ALIGN(PAGE_SIZE);
+ __bl32_sram_text_end = .;
+ } >SRAM
+ ASSERT((__bl32_sram_text_real_end - __bl32_sram_text_start) <=
+ SRAM_TEXT_LIMIT, ".text_sram has exceeded its limit")
+
+ .data_sram : ALIGN(PAGE_SIZE) {
+ __bl32_sram_data_start = .;
+ *(.sram.data)
+ __bl32_sram_data_real_end = .;
+ . = ALIGN(PAGE_SIZE);
+ __bl32_sram_data_end = .;
+ } >SRAM
+ ASSERT((__bl32_sram_data_real_end - __bl32_sram_data_start) <=
+ SRAM_DATA_LIMIT, ".data_sram has exceeded its limit")
+
+ .stack_sram : ALIGN(PAGE_SIZE) {
+ __bl32_sram_stack_start = .;
+ . += PAGE_SIZE;
+ __bl32_sram_stack_end = .;
+ } >SRAM
+
+ . = 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.");
+ *(.pmusram.entry)
+
+ __bl32_pmusram_text_start = .;
+ *(.pmusram.text)
+ *(.pmusram.rodata)
+ __bl32_pmusram_text_end = .;
+
+ __bl32_pmusram_data_start = .;
+ *(.pmusram.data)
+ __bl32_pmusram_data_end = .;
+ } >PMUSRAM
+}
+
+#endif /* ROCKCHIP_PLAT_LD_S */
diff --git a/plat/rockchip/rk3288/include/platform_def.h b/plat/rockchip/rk3288/include/platform_def.h
new file mode 100644
index 000000000..d9e0bc64c
--- /dev/null
+++ b/plat/rockchip/rk3288/include/platform_def.h
@@ -0,0 +1,101 @@
+/*
+ * Copyright (c) 2014-2018, 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 <lib/utils_def.h>
+#include <plat/common/common_def.h>
+
+#include <bl32_param.h>
+#include <rk3288_def.h>
+
+/*******************************************************************************
+ * Platform binary types for linking
+ ******************************************************************************/
+#define PLATFORM_LINKER_FORMAT "elf32-littlearm"
+#define PLATFORM_LINKER_ARCH arm
+
+/*******************************************************************************
+ * Generic platform constants
+ ******************************************************************************/
+
+/* Size of cacheable stacks */
+#if defined(IMAGE_BL1)
+#define PLATFORM_STACK_SIZE 0x440
+#elif defined(IMAGE_BL2)
+#define PLATFORM_STACK_SIZE 0x400
+#elif defined(IMAGE_BL32)
+#define PLATFORM_STACK_SIZE 0x800
+#endif
+
+#define FIRMWARE_WELCOME_STR "Booting Trusted Firmware\n"
+
+#define PLATFORM_MAX_AFFLVL MPIDR_AFFLVL2
+#define PLATFORM_SYSTEM_COUNT 1
+#define PLATFORM_CLUSTER_COUNT 1
+#define PLATFORM_CLUSTER0_CORE_COUNT 4
+#define PLATFORM_CORE_COUNT (PLATFORM_CLUSTER0_CORE_COUNT)
+#define PLATFORM_MAX_CPUS_PER_CLUSTER 4
+#define PLATFORM_NUM_AFFS (PLATFORM_SYSTEM_COUNT + \
+ PLATFORM_CLUSTER_COUNT + \
+ PLATFORM_CORE_COUNT)
+
+#define PLAT_RK_CLST_TO_CPUID_SHIFT 6
+
+#define PLAT_MAX_PWR_LVL MPIDR_AFFLVL2
+
+/*
+ * 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 U(1)
+
+/*
+ * This macro defines the deepest power down states possible. Any state ID
+ * higher than this is invalid.
+ */
+#define PLAT_MAX_OFF_STATE U(2)
+
+/*******************************************************************************
+ * Platform specific page table and MMU setup constants
+ ******************************************************************************/
+#define PLAT_VIRT_ADDR_SPACE_SIZE (1ULL << 32)
+#define PLAT_PHY_ADDR_SPACE_SIZE (1ULL << 32)
+#define MAX_XLAT_TABLES 8
+#define MAX_MMAP_REGIONS 18
+
+/*******************************************************************************
+ * 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 RK3288_GICD_BASE
+#define PLAT_RK_GICC_BASE RK3288_GICC_BASE
+
+#define PLAT_RK_UART_BASE RK3288_UART2_BASE
+#define PLAT_RK_UART_CLOCK RK3288_UART_CLOCK
+#define PLAT_RK_UART_BAUDRATE RK3288_BAUDRATE
+
+/* ClusterId is always 0x5 on rk3288, filter it */
+#define PLAT_RK_MPIDR_CLUSTER_MASK 0
+#define PLAT_RK_PRIMARY_CPU 0x0
+
+#define PSRAM_DO_DDR_RESUME 0
+#define PSRAM_CHECK_WAKEUP_CPU 0
+
+#endif /* PLATFORM_DEF_H */
diff --git a/plat/rockchip/rk3288/include/shared/bl32_param.h b/plat/rockchip/rk3288/include/shared/bl32_param.h
new file mode 100644
index 000000000..743dad41b
--- /dev/null
+++ b/plat/rockchip/rk3288/include/shared/bl32_param.h
@@ -0,0 +1,26 @@
+/*
+ * Copyright (c) 2016, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef BL32_PARAM_H
+#define BL32_PARAM_H
+
+/*******************************************************************************
+ * Platform memory map related constants
+ ******************************************************************************/
+/* TF txet, ro, rw, Size: 2MB */
+#define TZRAM_BASE (0x0)
+#define TZRAM_SIZE (0x200000)
+
+/*******************************************************************************
+ * BL32 specific defines.
+ ******************************************************************************/
+/*
+ * Put BL32 at the top of the Trusted RAM
+ */
+#define BL32_BASE (TZRAM_BASE + 0x100000)
+#define BL32_LIMIT (TZRAM_BASE + TZRAM_SIZE)
+
+#endif /* BL32_PARAM_H */
diff --git a/plat/rockchip/rk3288/plat_sip_calls.c b/plat/rockchip/rk3288/plat_sip_calls.c
new file mode 100644
index 000000000..5918d58ce
--- /dev/null
+++ b/plat/rockchip/rk3288/plat_sip_calls.c
@@ -0,0 +1,25 @@
+/*
+ * Copyright (c) 2016, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <common/debug.h>
+#include <common/runtime_svc.h>
+#include <lib/mmio.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/rk3288/platform.mk b/plat/rockchip/rk3288/platform.mk
new file mode 100644
index 000000000..d20358150
--- /dev/null
+++ b/plat/rockchip/rk3288/platform.mk
@@ -0,0 +1,65 @@
+#
+# Copyright (c) 2016-2017, ARM Limited and Contributors. All rights reserved.
+#
+# SPDX-License-Identifier: BSD-3-Clause
+#
+
+ARM_CORTEX_A12 := yes
+ARM_ARCH_MAJOR := 7
+
+RK_PLAT := plat/rockchip
+RK_PLAT_SOC := ${RK_PLAT}/${PLAT}
+RK_PLAT_COMMON := ${RK_PLAT}/common
+
+PLAT_INCLUDES := -I${RK_PLAT_COMMON}/ \
+ -I${RK_PLAT_COMMON}/include/ \
+ -I${RK_PLAT_COMMON}/aarch32/ \
+ -I${RK_PLAT_COMMON}/drivers/pmu/ \
+ -I${RK_PLAT_SOC}/ \
+ -I${RK_PLAT_SOC}/drivers/pmu/ \
+ -I${RK_PLAT_SOC}/drivers/secure/ \
+ -I${RK_PLAT_SOC}/drivers/soc/ \
+ -I${RK_PLAT_SOC}/include/ \
+ -I${RK_PLAT_SOC}/include/shared/ \
+
+RK_GIC_SOURCES := drivers/arm/gic/common/gic_common.c \
+ drivers/arm/gic/v2/gicv2_main.c \
+ drivers/arm/gic/v2/gicv2_helpers.c \
+ plat/common/plat_gicv2.c \
+ ${RK_PLAT}/common/rockchip_gicv2.c
+
+PLAT_BL_COMMON_SOURCES := plat/common/aarch32/crash_console_helpers.S \
+ plat/common/plat_psci_common.c
+
+PLAT_BL_COMMON_SOURCES += lib/xlat_tables/xlat_tables_common.c \
+ lib/xlat_tables/aarch32/xlat_tables.c
+
+BL32_SOURCES += ${RK_GIC_SOURCES} \
+ drivers/arm/cci/cci.c \
+ drivers/ti/uart/aarch32/16550_console.S \
+ drivers/delay_timer/delay_timer.c \
+ drivers/delay_timer/generic_delay_timer.c \
+ lib/cpus/aarch32/cortex_a12.S \
+ ${RK_PLAT_COMMON}/aarch32/plat_helpers.S \
+ ${RK_PLAT_COMMON}/params_setup.c \
+ ${RK_PLAT_COMMON}/aarch32/pmu_sram_cpus_on.S \
+ ${RK_PLAT_COMMON}/plat_pm.c \
+ ${RK_PLAT_COMMON}/plat_topology.c \
+ ${RK_PLAT_COMMON}/aarch32/platform_common.c \
+ ${RK_PLAT_COMMON}/rockchip_sip_svc.c \
+ ${RK_PLAT_SOC}/plat_sip_calls.c \
+ ${RK_PLAT_SOC}/drivers/pmu/pmu.c \
+ ${RK_PLAT_SOC}/drivers/secure/secure.c \
+ ${RK_PLAT_SOC}/drivers/soc/soc.c \
+
+MULTI_CONSOLE_API := 1
+
+include lib/coreboot/coreboot.mk
+include lib/libfdt/libfdt.mk
+
+$(eval $(call add_define,PLAT_SP_MIN_EXTRA_LD_SCRIPT))
+
+# Do not enable SVE
+ENABLE_SVE_FOR_NS := 0
+
+WORKAROUND_CVE_2017_5715 := 0
diff --git a/plat/rockchip/rk3288/rk3288_def.h b/plat/rockchip/rk3288/rk3288_def.h
new file mode 100644
index 000000000..7b5018c7a
--- /dev/null
+++ b/plat/rockchip/rk3288/rk3288_def.h
@@ -0,0 +1,116 @@
+/*
+ * Copyright (c) 2016-2019, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef RK3288_DEF_H
+#define RK3288_DEF_H
+
+/* Special value used to verify platform parameters from BL2 to BL31 */
+#define RK_BL31_PLAT_PARAM_VAL 0x0f1e2d3c4b5a6978ULL
+
+#define SIZE_K(n) ((n) * 1024)
+#define SIZE_M(n) ((n) * 1024 * 1024)
+
+#define SRAM_TEXT_LIMIT (4 * 1024)
+#define SRAM_DATA_LIMIT (4 * 1024)
+
+#define DDR_PCTL0_BASE 0xff610000
+#define DDR_PCTL0_SIZE SIZE_K(64)
+
+#define DDR_PHY0_BASE 0xff620000
+#define DDR_PHY0_SIZE SIZE_K(64)
+
+#define DDR_PCTL1_BASE 0xff630000
+#define DDR_PCTL1_SIZE SIZE_K(64)
+
+#define DDR_PHY1_BASE 0xff640000
+#define DDR_PHY1_SIZE SIZE_K(64)
+
+#define UART_DBG_BASE 0xff690000
+#define UART_DBG_SIZE SIZE_K(64)
+
+/* 96k instead of 64k? */
+#define SRAM_BASE 0xff700000
+#define SRAM_SIZE SIZE_K(64)
+
+#define PMUSRAM_BASE 0xff720000
+#define PMUSRAM_SIZE SIZE_K(4)
+#define PMUSRAM_RSIZE SIZE_K(4)
+
+#define PMU_BASE 0xff730000
+#define PMU_SIZE SIZE_K(64)
+
+#define SGRF_BASE 0xff740000
+#define SGRF_SIZE SIZE_K(64)
+
+#define CRU_BASE 0xff760000
+#define CRU_SIZE SIZE_K(64)
+
+#define GRF_BASE 0xff770000
+#define GRF_SIZE SIZE_K(64)
+
+/* timer 6+7 can be set as secure in SGRF */
+#define STIME_BASE 0xff810000
+#define STIME_SIZE SIZE_K(64)
+
+#define SERVICE_BUS_BASE 0xffac0000
+#define SERVICE_BUS_SIZE SIZE_K(64)
+
+#define TZPC_BASE 0xffb00000
+#define TZPC_SIZE SIZE_K(64)
+
+#define GIC400_BASE 0xffc00000
+#define GIC400_SIZE SIZE_K(64)
+
+#define CORE_AXI_BUS_BASE 0xffd00000
+#define CORE_AXI_BUS_SIZE SIZE_M(1)
+
+#define COLD_BOOT_BASE 0xffff0000
+/**************************************************************************
+ * UART related constants
+ **************************************************************************/
+#define RK3288_UART2_BASE UART_DBG_BASE
+#define RK3288_BAUDRATE 115200
+#define RK3288_UART_CLOCK 24000000
+
+/******************************************************************************
+ * System counter frequency related constants
+ ******************************************************************************/
+#define SYS_COUNTER_FREQ_IN_TICKS 24000000
+
+/******************************************************************************
+ * GIC-400 & interrupt handling related constants
+ ******************************************************************************/
+
+/* Base rk_platform compatible GIC memory map */
+#define RK3288_GICD_BASE (GIC400_BASE + 0x1000)
+#define RK3288_GICC_BASE (GIC400_BASE + 0x2000)
+#define RK3288_GICR_BASE 0 /* no GICR in GIC-400 */
+
+/******************************************************************************
+ * sgi, ppi
+ ******************************************************************************/
+#define RK_IRQ_SEC_PHY_TIMER 29
+
+/* what are these, and are they present on rk3288? */
+#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 a list of Group 0 interrupts.
+ */
+#define PLAT_RK_GICV2_G0_IRQS \
+ INTR_PROP_DESC(RK_IRQ_SEC_PHY_TIMER, GIC_HIGHEST_SEC_PRIORITY, \
+ GICV2_INTR_GROUP0, GIC_INTR_CFG_LEVEL), \
+ INTR_PROP_DESC(RK_IRQ_SEC_SGI_6, GIC_HIGHEST_SEC_PRIORITY, \
+ GICV2_INTR_GROUP0, GIC_INTR_CFG_LEVEL)
+
+#endif /* RK3288_DEF_H */
diff --git a/plat/rockchip/rk3288/sp_min/sp_min-rk3288.mk b/plat/rockchip/rk3288/sp_min/sp_min-rk3288.mk
new file mode 100644
index 000000000..befdca34d
--- /dev/null
+++ b/plat/rockchip/rk3288/sp_min/sp_min-rk3288.mk
@@ -0,0 +1,8 @@
+#
+# Copyright (c) 2016-2018, ARM Limited and Contributors. All rights reserved.
+#
+# SPDX-License-Identifier: BSD-3-Clause
+#
+
+BL32_SOURCES += plat/common/aarch32/platform_mp_stack.S \
+ plat/rockchip/common/sp_min_plat_setup.c
diff --git a/plat/rockchip/rk3328/drivers/pmu/pmu.h b/plat/rockchip/rk3328/drivers/pmu/pmu.h
index d98f53cb1..dfb8912c2 100644
--- a/plat/rockchip/rk3328/drivers/pmu/pmu.h
+++ b/plat/rockchip/rk3328/drivers/pmu/pmu.h
@@ -49,8 +49,6 @@ enum pmu_cores_pm_by_wfi {
extern void *pmu_cpuson_entrypoint_start;
extern void *pmu_cpuson_entrypoint_end;
-extern uint64_t cpuson_entry_point[PLATFORM_CORE_COUNT];
-extern uint32_t cpuson_flags[PLATFORM_CORE_COUNT];
#define CORES_PM_DISABLE 0x0
diff --git a/plat/rockchip/rk3328/platform.mk b/plat/rockchip/rk3328/platform.mk
index 18b1b9419..3caa1082f 100644
--- a/plat/rockchip/rk3328/platform.mk
+++ b/plat/rockchip/rk3328/platform.mk
@@ -8,13 +8,11 @@ RK_PLAT := plat/rockchip
RK_PLAT_SOC := ${RK_PLAT}/${PLAT}
RK_PLAT_COMMON := ${RK_PLAT}/common
-include lib/libfdt/libfdt.mk
-
PLAT_INCLUDES := -Idrivers/arm/gic/common/ \
-Idrivers/arm/gic/v2/ \
-I${RK_PLAT_COMMON}/ \
-I${RK_PLAT_COMMON}/include/ \
- -I${RK_PLAT_COMMON}/pmusram \
+ -I${RK_PLAT_COMMON}/aarch64/ \
-I${RK_PLAT_COMMON}/drivers/pmu/ \
-I${RK_PLAT_COMMON}/drivers/parameter/ \
-I${RK_PLAT_SOC}/ \
@@ -40,11 +38,10 @@ BL31_SOURCES += ${RK_GIC_SOURCES} \
drivers/delay_timer/generic_delay_timer.c \
lib/cpus/aarch64/aem_generic.S \
lib/cpus/aarch64/cortex_a53.S \
- $(LIBFDT_SRCS) \
${RK_PLAT_COMMON}/drivers/parameter/ddr_parameter.c \
${RK_PLAT_COMMON}/aarch64/plat_helpers.S \
${RK_PLAT_COMMON}/bl31_plat_setup.c \
- ${RK_PLAT_COMMON}/pmusram/pmu_sram_cpus_on.S \
+ ${RK_PLAT_COMMON}/aarch64/pmu_sram_cpus_on.S \
${RK_PLAT_COMMON}/plat_pm.c \
${RK_PLAT_COMMON}/plat_topology.c \
${RK_PLAT_COMMON}/aarch64/platform_common.c \
@@ -54,6 +51,7 @@ BL31_SOURCES += ${RK_GIC_SOURCES} \
MULTI_CONSOLE_API := 1
include lib/coreboot/coreboot.mk
+include lib/libfdt/libfdt.mk
$(eval $(call add_define,PLAT_EXTRA_LD_SCRIPT))
$(eval $(call add_define,PLAT_SKIP_OPTEE_S_EL1_INT_REGISTER))
diff --git a/plat/rockchip/rk3368/platform.mk b/plat/rockchip/rk3368/platform.mk
index d1315fc58..0495a1619 100644
--- a/plat/rockchip/rk3368/platform.mk
+++ b/plat/rockchip/rk3368/platform.mk
@@ -8,11 +8,9 @@ RK_PLAT := plat/rockchip
RK_PLAT_SOC := ${RK_PLAT}/${PLAT}
RK_PLAT_COMMON := ${RK_PLAT}/common
-include lib/libfdt/libfdt.mk
-
PLAT_INCLUDES := -I${RK_PLAT_COMMON}/ \
-I${RK_PLAT_COMMON}/include/ \
- -I${RK_PLAT_COMMON}/pmusram \
+ -I${RK_PLAT_COMMON}/aarch64/ \
-I${RK_PLAT_COMMON}/drivers/pmu/ \
-I${RK_PLAT_SOC}/ \
-I${RK_PLAT_SOC}/drivers/pmu/ \
@@ -37,11 +35,10 @@ BL31_SOURCES += ${RK_GIC_SOURCES} \
drivers/delay_timer/delay_timer.c \
drivers/delay_timer/generic_delay_timer.c \
lib/cpus/aarch64/cortex_a53.S \
- $(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}/pmusram/pmu_sram_cpus_on.S \
+ ${RK_PLAT_COMMON}/aarch64/pmu_sram_cpus_on.S \
${RK_PLAT_COMMON}/plat_pm.c \
${RK_PLAT_COMMON}/plat_topology.c \
${RK_PLAT_COMMON}/aarch64/platform_common.c \
@@ -54,6 +51,7 @@ BL31_SOURCES += ${RK_GIC_SOURCES} \
MULTI_CONSOLE_API := 1
include lib/coreboot/coreboot.mk
+include lib/libfdt/libfdt.mk
$(eval $(call add_define,PLAT_EXTRA_LD_SCRIPT))
diff --git a/plat/rockchip/rk3399/drivers/m0/src/dram.c b/plat/rockchip/rk3399/drivers/m0/src/dram.c
index b939a9605..84e88849e 100644
--- a/plat/rockchip/rk3399/drivers/m0/src/dram.c
+++ b/plat/rockchip/rk3399/drivers/m0/src/dram.c
@@ -55,7 +55,7 @@ static void ddr_set_pll(void)
mmio_write_32(CRU_BASE + CRU_DPLL_CON3, PLL_MODE(PLL_NORMAL_MODE));
}
-__attribute__((noreturn)) void main(void)
+__attribute__((noreturn)) void m0_main(void)
{
mmio_setbits_32(PHY_REG(0, 927), (1 << 22));
mmio_setbits_32(PHY_REG(1, 927), (1 << 22));
diff --git a/plat/rockchip/rk3399/drivers/m0/src/startup.c b/plat/rockchip/rk3399/drivers/m0/src/startup.c
index dba031370..dfd8af230 100644
--- a/plat/rockchip/rk3399/drivers/m0/src/startup.c
+++ b/plat/rockchip/rk3399/drivers/m0/src/startup.c
@@ -23,7 +23,7 @@ void WEAK svc_handler(void);
void WEAK pend_sv_handler(void);
void WEAK systick_handler(void);
-extern int main(void);
+extern int m0_main(void);
/* Function prototypes */
static void default_reset_handler(void);
@@ -59,12 +59,12 @@ void (* const g_pfnVectors[])(void) = {
* This is the code that gets called when the processor first
* starts execution following a reset event. Only the absolutely
* necessary set is performed, after which the application
- * supplied main() routine is called.
+ * supplied m0_main() routine is called.
*/
static void default_reset_handler(void)
{
/* call the application's entry point */
- main();
+ m0_main();
}
/**
diff --git a/plat/rockchip/rk3399/drivers/m0/src/suspend.c b/plat/rockchip/rk3399/drivers/m0/src/suspend.c
index 39dfd1138..9ad2fa26a 100644
--- a/plat/rockchip/rk3399/drivers/m0/src/suspend.c
+++ b/plat/rockchip/rk3399/drivers/m0/src/suspend.c
@@ -11,7 +11,7 @@
#define SCR_SLEEPDEEP_SHIFT (1 << 2)
-__attribute__((noreturn)) void main(void)
+__attribute__((noreturn)) void m0_main(void)
{
unsigned int status_value;
diff --git a/plat/rockchip/rk3399/platform.mk b/plat/rockchip/rk3399/platform.mk
index 101359856..c73df6d76 100644
--- a/plat/rockchip/rk3399/platform.mk
+++ b/plat/rockchip/rk3399/platform.mk
@@ -8,11 +8,9 @@ RK_PLAT := plat/rockchip
RK_PLAT_SOC := ${RK_PLAT}/${PLAT}
RK_PLAT_COMMON := ${RK_PLAT}/common
-include lib/libfdt/libfdt.mk
-
PLAT_INCLUDES := -I${RK_PLAT_COMMON}/ \
-I${RK_PLAT_COMMON}/include/ \
- -I${RK_PLAT_COMMON}/pmusram \
+ -I${RK_PLAT_COMMON}/aarch64/ \
-I${RK_PLAT_COMMON}/drivers/pmu/ \
-I${RK_PLAT_SOC}/ \
-I${RK_PLAT_SOC}/drivers/pmu/ \
@@ -45,11 +43,10 @@ BL31_SOURCES += ${RK_GIC_SOURCES} \
drivers/gpio/gpio.c \
lib/cpus/aarch64/cortex_a53.S \
lib/cpus/aarch64/cortex_a72.S \
- $(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}/pmusram/pmu_sram_cpus_on.S \
+ ${RK_PLAT_COMMON}/aarch64/pmu_sram_cpus_on.S \
${RK_PLAT_COMMON}/plat_pm.c \
${RK_PLAT_COMMON}/plat_topology.c \
${RK_PLAT_COMMON}/aarch64/platform_common.c \
@@ -71,6 +68,7 @@ BL31_SOURCES += ${RK_GIC_SOURCES} \
MULTI_CONSOLE_API := 1
include lib/coreboot/coreboot.mk
+include lib/libfdt/libfdt.mk
$(eval $(call add_define,PLAT_EXTRA_LD_SCRIPT))
diff --git a/plat/ti/k3/common/k3_bl31_setup.c b/plat/ti/k3/common/k3_bl31_setup.c
index b4ec37458..8bd736292 100644
--- a/plat/ti/k3/common/k3_bl31_setup.c
+++ b/plat/ti/k3/common/k3_bl31_setup.c
@@ -99,9 +99,12 @@ void bl31_early_platform_setup2(u_register_t arg0, u_register_t arg1,
void bl31_plat_arch_setup(void)
{
const mmap_region_t bl_regions[] = {
- MAP_REGION_FLAT(BL31_START, BL31_END - BL31_START, MT_MEMORY | MT_RW | MT_SECURE),
- MAP_REGION_FLAT(BL_CODE_BASE, BL_CODE_END - BL_CODE_BASE, MT_CODE | MT_RO | MT_SECURE),
- MAP_REGION_FLAT(BL_RO_DATA_BASE, BL_RO_DATA_END - BL_RO_DATA_END, MT_RO_DATA | MT_RO | MT_SECURE),
+ MAP_REGION_FLAT(BL31_START, BL31_END - BL31_START, MT_MEMORY | MT_RW | MT_SECURE),
+ MAP_REGION_FLAT(BL_CODE_BASE, BL_CODE_END - BL_CODE_BASE, MT_CODE | MT_RO | MT_SECURE),
+ MAP_REGION_FLAT(BL_RO_DATA_BASE, BL_RO_DATA_END - BL_RO_DATA_BASE, MT_RO_DATA | MT_RO | MT_SECURE),
+#if USE_COHERENT_MEM
+ MAP_REGION_FLAT(BL_COHERENT_RAM_BASE, BL_COHERENT_RAM_END - BL_COHERENT_RAM_BASE, MT_DEVICE | MT_RW | MT_SECURE),
+#endif
{ /* sentinel */ }
};
diff --git a/plat/ti/k3/common/k3_psci.c b/plat/ti/k3/common/k3_psci.c
index f66f12a3d..c7754e994 100644
--- a/plat/ti/k3/common/k3_psci.c
+++ b/plat/ti/k3/common/k3_psci.c
@@ -17,10 +17,10 @@
#include <k3_gicv3.h>
#include <ti_sci.h>
+#ifdef TI_AM65X_WORKAROUND
/* Need to flush psci internal locks before shutdown or their values are lost */
#include "../../../../lib/psci/psci_private.h"
-
-#define STUB() ERROR("stub %s called\n", __func__)
+#endif
uintptr_t k3_sec_entrypoint;
@@ -115,6 +115,7 @@ void k3_pwr_domain_on_finish(const psci_power_state_t *target_state)
k3_gic_cpuif_enable();
}
+#ifdef TI_AM65X_WORKAROUND
static void __dead2 k3_pwr_domain_pwr_down_wfi(const psci_power_state_t
*target_state)
{
@@ -122,6 +123,7 @@ static void __dead2 k3_pwr_domain_pwr_down_wfi(const psci_power_state_t
flush_dcache_range((uintptr_t) psci_locks, sizeof(psci_locks));
psci_power_down_wfi();
}
+#endif
static void __dead2 k3_system_reset(void)
{
@@ -152,7 +154,9 @@ static const plat_psci_ops_t k3_plat_psci_ops = {
.pwr_domain_on = k3_pwr_domain_on,
.pwr_domain_off = k3_pwr_domain_off,
.pwr_domain_on_finish = k3_pwr_domain_on_finish,
+#ifdef TI_AM65X_WORKAROUND
.pwr_domain_pwr_down_wfi = k3_pwr_domain_pwr_down_wfi,
+#endif
.system_reset = k3_system_reset,
.validate_power_state = k3_validate_power_state,
.validate_ns_entrypoint = k3_validate_ns_entrypoint
diff --git a/readme.rst b/readme.rst
index 998369f08..fc0355585 100644
--- a/readme.rst
+++ b/readme.rst
@@ -12,7 +12,7 @@ at Exception Level 3 (EL3). It implements various Arm interface standards,
such as:
- The `Power State Coordination Interface (PSCI)`_
-- Trusted Board Boot Requirements (TBBR, Arm DEN0006C-1)
+- `Trusted Board Boot Requirements CLIENT (TBBR-CLIENT)`_
- `SMC Calling Convention`_
- `System Control and Management Interface (SCMI)`_
- `Software Delegated Exception Interface (SDEI)`_
@@ -320,6 +320,7 @@ Security advisories
.. _Secure Monitor: http://www.arm.com/products/processors/technologies/trustzone/tee-smc.php
.. _Power State Coordination Interface (PSCI): PSCI_
.. _PSCI: http://infocenter.arm.com/help/topic/com.arm.doc.den0022d/Power_State_Coordination_Interface_PDD_v1_1_DEN0022D.pdf
+.. _Trusted Board Boot Requirements CLIENT (TBBR-CLIENT): https://developer.arm.com/docs/den0006/latest/trusted-board-boot-requirements-client-tbbr-client-armv8-a
.. _SMC Calling Convention: http://infocenter.arm.com/help/topic/com.arm.doc.den0028b/ARM_DEN0028B_SMC_Calling_Convention.pdf
.. _System Control and Management Interface (SCMI): SCMI_
.. _SCMI: http://infocenter.arm.com/help/topic/com.arm.doc.den0056a/DEN0056A_System_Control_and_Management_Interface.pdf