rcar-gen3: initial commit for the rcar-gen3 boards

Reference code:
==============

rar_gen3: IPL and Secure Monitor Rev1.0.22
https://github.com/renesas-rcar/arm-trusted-firmware [rcar_gen3]

Author: Takuya Sakata <takuya.sakata.wz@bp.renesas.com>
Date:   Thu Aug 30 21:26:41 2018 +0900
	Update IPL and Secure Monitor Rev1.0.22

General Information:
===================

This port has been tested on the Salvator-X Soc_id r8a7795 revision
ES1.1 (uses an SPD).

Build Tested:
-------------
ATFW_OPT="LSI=H3 RCAR_DRAM_SPLIT=1 RCAR_LOSSY_ENABLE=1"
MBEDTLS_DIR=$mbedtls

$ make clean bl2 bl31 rcar PLAT=rcar ${ATFW_OPT} SPD=opteed

Other dependencies:
------------------
* mbed_tls:
  git@github.com:ARMmbed/mbedtls.git [devel]

  Merge: 68dbc94 f34a4c1
  Author: Simon Butcher <simon.butcher@arm.com>
  Date:   Thu Aug 30 00:57:28 2018 +0100

* optee_os:
  https://github.com/BayLibre/optee_os

  Until it gets merged into OP-TEE, the port requires Renesas' Trusted
  Environment with a modification to support power management.

  Author: Jorge Ramirez-Ortiz <jramirez@baylibre.com>
  Date:   Thu Aug 30 16:49:49 2018 +0200
    plat-rcar: cpu-suspend: handle the power level
    Signed-off-by: Jorge Ramirez-Ortiz <jramirez@baylibre.com>

* u-boot:
  The port has beent tested using mainline uboot.

  Author: Fabio Estevam <festevam@gmail.com>
  Date:   Tue Sep 4 10:23:12 2018 -0300

*linux:
  The port has beent tested using mainline kernel.

  Author: Linus Torvalds <torvalds@linux-foundation.org>
  Date:   Sun Sep 16 11:52:37 2018 -0700
      Linux 4.19-rc4

Overview
---------

BOOTROM starts the cpu at EL3; In this port BL2 will therefore be entered
at this exception level (the Renesas' ATF reference tree [1] resets into
EL1 before entering BL2 - see its bl2.ld.S)

BL2 initializes DDR (and i2c to talk to the PMIC on some platforms)
before determining the boot reason (cold or warm).

During suspend all CPUs are switched off and the DDR is put in
backup mode (some kind of self-refresh mode). This means that BL2 is
always entered in a cold boot scenario.

Once BL2 boots, it determines the boot reason, writes it to shared
memory (BOOT_KIND_BASE) together with the BL31 parameters
(PARAMS_BASE) and jumps to BL31.

To all effects, BL31 is as if it is being entered in reset mode since
it still needs to initialize the rest of the cores; this is the reason
behind using direct shared memory access to  BOOT_KIND_BASE and
PARAMS_BASE instead of using registers to get to those locations (see
el3_common_macros.S and bl31_entrypoint.S for the RESET_TO_BL31 use
case).

Depending on the boot reason BL31 initializes the rest of the cores:
in case of suspend, it uses a MBOX memory region to recover the
program counters.

[1] https://github.com/renesas-rcar/arm-trusted-firmware
Tests
-----

* cpuidle
  -------
   enable kernel's cpuidle arm_idle driver and boot

* system suspend
  --------------
  $ cat suspend.sh
    #!/bin/bash
    i2cset -f -y 7 0x30 0x20 0x0F
    read -p "Switch off SW23 and press return " foo
    echo mem > /sys/power/state

* cpu hotplug:
  ------------
  $ cat offline.sh
    #!/bin/bash
    nbr=$1
    echo 0 > /sys/devices/system/cpu/cpu$nbr/online
    printf "ONLINE:  " && cat /sys/devices/system/cpu/online
    printf "OFFLINE: " && cat /sys/devices/system/cpu/offline

  $ cat online.sh
    #!/bin/bash
    nbr=$1
    echo 1 > /sys/devices/system/cpu/cpu$nbr/online
    printf "ONLINE:  " && cat /sys/devices/system/cpu/online
    printf "OFFLINE: " && cat /sys/devices/system/cpu/offline

Signed-off-by: ldts <jramirez@baylibre.com>
diff --git a/plat/renesas/rcar/aarch64/plat_helpers.S b/plat/renesas/rcar/aarch64/plat_helpers.S
new file mode 100644
index 0000000..5079937
--- /dev/null
+++ b/plat/renesas/rcar/aarch64/plat_helpers.S
@@ -0,0 +1,376 @@
+/*
+ * Copyright (c) 2013-2014, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2015-2018, Renesas Electronics Corporation. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <arch.h>
+#include <asm_macros.S>
+#include <bl_common.h>
+#include <cortex_a57.h>
+#include <platform_def.h>
+#include <runtime_svc.h>
+#include "rcar_def.h"
+
+	.globl	plat_get_my_entrypoint
+	.extern	plat_set_my_stack
+	.globl	platform_mem_init
+
+	.globl	plat_crash_console_init
+	.globl	plat_crash_console_putc
+	.globl	plat_invalidate_icache
+	.globl	plat_report_exception
+	.globl	plat_secondary_reset
+	.globl	plat_reset_handler
+	.globl	plat_my_core_pos
+	.extern	rcar_log_init
+
+#if IMAGE_BL2
+	#define	INT_ID_MASK	(0x3ff)
+	.extern bl2_interrupt_error_type
+	.extern bl2_interrupt_error_id
+	.globl  bl2_enter_bl31
+	.extern gicv2_acknowledge_interrupt
+	.extern rcar_swdt_exec
+#endif
+
+	/* -----------------------------------------------------
+	 * void platform_get_core_pos (mpidr)
+	 * -----------------------------------------------------
+	 */
+func platform_get_core_pos
+	and     x1, x0, #MPIDR_CPU_MASK
+	and     x0, x0, #MPIDR_CLUSTER_MASK
+	add     x0, x1, x0, LSR #6
+	ret
+endfunc platform_get_core_pos
+
+	/* -----------------------------------------------------
+	 * void platform_my_core_pos
+	 * -----------------------------------------------------
+	 */
+func plat_my_core_pos
+	mrs     x0, mpidr_el1
+	b	platform_get_core_pos
+endfunc plat_my_core_pos
+
+	/* -----------------------------------------------------
+	 * void platform_get_my_entrypoint (unsigned int mpid);
+	 *
+	 * Main job of this routine is to distinguish between
+	 * a cold and warm boot.
+	 * On a cold boot the secondaries first wait for the
+	 * platform to be initialized after which they are
+	 * hotplugged in. The primary proceeds to perform the
+	 * platform initialization.
+	 * On a warm boot, each cpu jumps to the address in its
+	 * mailbox.
+	 *
+	 * TODO: Not a good idea to save lr in a temp reg
+	 * -----------------------------------------------------
+	 */
+func plat_get_my_entrypoint
+	mrs	x0, mpidr_el1
+	mov	x9, x30 /* lr */
+
+#if defined(IMAGE_BL2)
+	/* always cold boot on bl2 */
+	mov	x0, #0
+	ret	x9
+#else
+       ldr 	x1, =BOOT_KIND_BASE
+       ldr	x21, [x1]
+
+	/* Check the reset info */
+	and	x1, x21, #0x000c
+	cmp	x1, #0x0008
+	beq	el3_panic
+	cmp	x1, #0x000c
+	beq	el3_panic
+
+	/* Check the boot kind */
+	and	x1, x21, #0x0003
+	cmp	x1, #0x0002
+	beq	el3_panic
+	cmp	x1, #0x0003
+	beq	el3_panic
+
+	/* warm boot or cold boot */
+	and	x1, x21, #1
+	cmp	x1, #0
+	bne	warm_reset
+
+	/* Cold boot */
+	mov	x0, #0
+	b	exit
+
+warm_reset:
+	/* --------------------------------------------------------------------
+	 * A per-cpu mailbox is maintained in the trusted SDRAM. Its flushed out
+	 * of the caches after every update using normal memory so its safe to
+	 * read it here with SO attributes
+	 * ---------------------------------------------------------------------
+	 */
+	ldr	x10, =MBOX_BASE
+	bl	platform_get_core_pos
+	lsl	x0, x0, #CACHE_WRITEBACK_SHIFT
+	ldr	x0, [x10, x0]
+	cbz	x0, _panic
+exit:
+	ret	x9
+_panic:
+	b	do_panic
+#endif
+
+endfunc plat_get_my_entrypoint
+
+	/* ---------------------------------------------
+	 * plat_secondary_reset
+	 *
+	 * ---------------------------------------------
+	 */
+func plat_secondary_reset
+	mrs	x0, sctlr_el3
+	bic	x0, x0, #SCTLR_EE_BIT
+	msr	sctlr_el3, x0
+	isb
+
+	mrs	x0, cptr_el3
+	bic	w0, w0, #TCPAC_BIT
+	bic	w0, w0, #TTA_BIT
+	bic	w0, w0, #TFP_BIT
+	msr	cptr_el3, x0
+
+	mov_imm	x0, PARAMS_BASE
+	mov_imm	x2, BL31_BASE
+       ldr x3, =BOOT_KIND_BASE
+	mov x1, #0x1
+	str x1, [x3]
+	br	x2	/* jump to BL31 */
+	nop
+	nop
+	nop
+endfunc plat_secondary_reset
+
+	/* ---------------------------------------------
+	 * plat_enter_bl31
+	 *
+	 * ---------------------------------------------
+	 */
+func bl2_enter_bl31
+	mov	x20, x0
+        /*
+         * MMU needs to be disabled because both BL2 and BL31 execute
+         * in EL3, and therefore share the same address space.
+         * BL31 will initialize the address space according to its
+         * own requirement.
+         */
+#if RCAR_BL2_DCACHE == 1
+	/* Disable mmu and data cache */
+	bl	disable_mmu_el3
+	/* Data cache clean and invalidate */
+	mov	x0, #DCCISW
+	bl	dcsw_op_all
+	/* TLB invalidate all, EL3 */
+	tlbi	alle3
+#endif /* RCAR_BL2_DCACHE == 1 */
+	bl	disable_mmu_icache_el3
+	/* Invalidate instruction cache */
+	ic	iallu
+	dsb	sy
+	isb
+	ldp	x0, x1, [x20, #ENTRY_POINT_INFO_PC_OFFSET]
+	msr	elr_el3, x0
+	msr	spsr_el3, x1
+	eret
+endfunc bl2_enter_bl31
+
+	/* -----------------------------------------------------
+	 * void platform_mem_init (void);
+	 *
+	 * Zero out the mailbox registers in the shared memory
+	 * and set the rcar_boot_kind_flag.
+	 * The mmu is turned off right now and only the primary can
+	 * ever execute this code. Secondaries will read the
+	 * mailboxes using SO accesses.
+	 * -----------------------------------------------------
+	 */
+func platform_mem_init
+#if !IMAGE_BL2
+	ldr	x0, =MBOX_BASE
+	mov	w1, #PLATFORM_CORE_COUNT
+loop:
+	str	xzr, [x0], #CACHE_WRITEBACK_GRANULE
+	subs	w1, w1, #1
+	b.gt	loop
+#endif
+	ret
+endfunc platform_mem_init
+
+	/* ---------------------------------------------
+	 * void plat_report_exception(unsigned int type)
+	 * Function to report an unhandled exception
+	 * with platform-specific means.
+	 * ---------------------------------------------
+	 */
+func plat_report_exception
+#if IMAGE_BL2
+	mov	w1, #FIQ_SP_EL0
+	cmp	w0, w1
+	beq	rep_exec_fiq_elx
+	b	rep_exec_panic_type
+rep_exec_fiq_elx:
+	bl	gicv2_acknowledge_interrupt
+	mov	x2, #INT_ID_MASK
+	and	x0, x0, x2
+	mov	x1, #ARM_IRQ_SEC_WDT
+	cmp	x0, x1
+	bne	rep_exec_panic_id
+	mrs	x0, ELR_EL3
+	b	rcar_swdt_exec
+rep_exec_panic_type:
+	/* x0 is interrupt TYPE */
+	b	bl2_interrupt_error_type
+rep_exec_panic_id:
+	/* x0 is interrupt ID */
+	b	bl2_interrupt_error_id
+rep_exec_end:
+#endif
+	ret
+endfunc plat_report_exception
+
+	/* ---------------------------------------------
+	 * int plat_crash_console_init(void)
+	 * Function to initialize log area
+	 * ---------------------------------------------
+	 */
+func plat_crash_console_init
+#if IMAGE_BL2
+	mov	x0, #0
+#else
+	mov	x1, sp
+	mov_imm	x2, RCAR_CRASH_STACK
+	mov	sp, x2
+	str	x1, [sp, #-16]!
+	str	x30, [sp, #-16]!
+	bl	console_core_init
+	ldr	x30, [sp], #16
+	ldr	x1, [sp], #16
+	mov	sp, x1
+#endif
+	ret
+endfunc plat_crash_console_init
+
+	/* ---------------------------------------------
+	 * int plat_crash_console_putc(int c)
+	 * Function to store a character to log area
+	 * ---------------------------------------------
+	 */
+func plat_crash_console_putc
+	mov	x1, sp
+	mov_imm	x2, RCAR_CRASH_STACK
+	mov	sp, x2
+	str	x1, [sp, #-16]!
+	str	x30, [sp, #-16]!
+	str	x3, [sp, #-16]!
+	str	x4, [sp, #-16]!
+	str	x5, [sp, #-16]!
+	bl	console_core_putc
+	ldr	x5, [sp], #16
+	ldr	x4, [sp], #16
+	ldr	x3, [sp], #16
+	ldr	x30, [sp], #16
+	ldr	x1, [sp], #16
+	mov	sp, x1
+	ret
+endfunc plat_crash_console_putc
+
+	/* --------------------------------------------------------------------
+	 * void plat_reset_handler(void);
+	 *
+	 * Before adding code in this function, refer to the guidelines in
+	 * docs/firmware-design.md to determine whether the code should reside
+	 * within the FIRST_RESET_HANDLER_CALL block or not.
+	 *
+	 * For R-Car H3:
+	 * - Set the L2 Tag RAM latency to 2 (i.e. 3 cycles) for Cortex-A57
+	 * - Set the L2 Data setup latency to 1 (i.e. 1 cycles) for Cortex-A57
+	 * - Set the L2 Data RAM latency to 3 (i.e. 4 cycles) for Cortex-A57
+	 * For R-Car M3/M3N:
+	 * - Set the L2 Tag RAM latency to 2 (i.e. 3 cycles) for Cortex-A57
+	 * - Set the L2 Data setup latency to 0 (i.e. 0 cycles) for Cortex-A57
+	 * - Set the L2 Data RAM latency to 3 (i.e. 4 cycles) for Cortex-A57
+	 *
+	 * --------------------------------------------------------------------
+	 */
+func plat_reset_handler
+	/*
+	 * On R-Car H3    :  x2 := 0
+	 * On R-Car M3/M3N:  x2 := 1
+	 */
+	/* read PRR */
+	ldr	x0, =0xFFF00044
+	ldr	w0, [x0]
+	ubfx	w0, w0, 8, 8
+	/* H3? */
+	cmp	w0, #0x4F
+	b.eq	H3
+	/* set R-Car M3/M3N */
+	mov	x2, #1
+	b	CHK_A5x
+H3:
+	/* set R-Car H3 */
+	mov	x2, #0
+	/* --------------------------------------------------------------------
+	 * Determine whether this code is executed on a Cortex-A53 or on a
+	 * Cortex-A57 core.
+	 * --------------------------------------------------------------------
+	 */
+CHK_A5x:
+	mrs	x0, midr_el1
+	ubfx	x1, x0, MIDR_PN_SHIFT, #12
+	cmp     w1, #((CORTEX_A57_MIDR >> MIDR_PN_SHIFT) & MIDR_PN_MASK)
+	b.eq	A57
+	ret
+A57:
+	/* Get data from CORTEX_A57_L2CTLR_EL1	*/
+	mrs	x0, CORTEX_A57_L2CTLR_EL1
+	/*
+	 * On R-Car H3/M3/M3N
+	 *
+	 * L2 Tag RAM latency is bit8-6 of CORTEX_A57_L2CTLR_EL1
+	 * L2 Data RAM setup is bit5 of CORTEX_A57_L2CTLR_EL1
+	 * L2 Data RAM latency is bit2-0 of CORTEX_A57_L2CTLR_EL1
+	 */
+	/* clear bit of L2 RAM	*/
+	/* ~(0x1e7) -> x1	*/
+	mov	x1, #0x1e7
+	neg	x1, x1
+	/* clear bit of L2 RAM -> x0 */
+	and	x0, x0, x1
+	/* L2 Tag RAM latency (3 cycles) */
+	orr	x0, x0, #0x2 << 6
+	/* If M3/M3N then L2 RAM setup is 0 */
+	cbnz	x2, M3_L2
+	/* L2 Data RAM setup (1 cycle) */
+	orr	x0, x0, #0x1 << 5
+M3_L2:
+	/* L2 Data RAM latency (4 cycles) */
+	orr	x0, x0, #0x3
+	/* Store data to L2CTLR_EL1 */
+	msr	CORTEX_A57_L2CTLR_EL1, x0
+apply_l2_ram_latencies:
+	ret
+endfunc plat_reset_handler
+
+	/* ---------------------------------------------
+	 * void plat_invalidate_icache(void)
+	 * Instruction Cache Invalidate All to PoU
+	 * ---------------------------------------------
+	 */
+func plat_invalidate_icache
+	ic	iallu
+
+	ret
+endfunc plat_invalidate_icache