summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Makefile29
-rw-r--r--bl31/aarch64/bl31_arch_setup.c7
-rw-r--r--bl31/aarch64/bl31_entrypoint.S18
-rw-r--r--bl31/aarch64/crash_reporting.S2
-rw-r--r--bl31/bl31.ld.S5
-rw-r--r--bl31/bl31.mk4
-rw-r--r--bl31/bl31_hash.c25
-rw-r--r--bl31/bl31_main.c8
-rw-r--r--bl31/context_mgmt.c7
-rw-r--r--bl31/head_data.c23
-rw-r--r--common/tf_printf.c13
-rw-r--r--drivers/arm/gic/arm_gic.c20
-rw-r--r--include/bl31/cpu_data.h5
-rw-r--r--include/bl31/head_data.h27
-rw-r--r--include/bl31/services/std_svc.h1
-rw-r--r--include/drivers/console.h1
-rw-r--r--include/lib/aarch64/arch_helpers.h26
-rw-r--r--include/plat/common/platform.h2
-rw-r--r--lib/aarch64/xlat_tables.c57
-rw-r--r--lib/cpus/aarch64/cpu_helpers.S5
-rw-r--r--lib/locks/bakery/bakery_lock.c2
-rw-r--r--lib/stdlib/assert.c1
-rw-r--r--plat/fvp/platform.mk3
-rw-r--r--plat/sun50iw1p1/aarch64/plat_helpers.S144
-rw-r--r--plat/sun50iw1p1/aarch64/sunxi_common.c246
-rw-r--r--plat/sun50iw1p1/bl1_sunxi_setup.c136
-rw-r--r--plat/sun50iw1p1/bl2_sunxi_setup.c285
-rw-r--r--plat/sun50iw1p1/bl31_sunxi_setup.c275
-rw-r--r--plat/sun50iw1p1/drivers/gpio/gpio.c228
-rw-r--r--plat/sun50iw1p1/drivers/uart/uart.c149
-rw-r--r--plat/sun50iw1p1/gic_sunxi.h344
-rw-r--r--plat/sun50iw1p1/include/arisc.h789
-rw-r--r--plat/sun50iw1p1/include/ccmu.h81
-rw-r--r--plat/sun50iw1p1/include/gpio.h69
-rw-r--r--plat/sun50iw1p1/include/plat_macros.S106
-rw-r--r--plat/sun50iw1p1/include/platform_def.h135
-rw-r--r--plat/sun50iw1p1/include/uart.h43
-rw-r--r--plat/sun50iw1p1/mhu.c136
-rw-r--r--plat/sun50iw1p1/mhu.h43
-rw-r--r--plat/sun50iw1p1/plat_gic.c402
-rw-r--r--plat/sun50iw1p1/plat_pm.c335
-rw-r--r--plat/sun50iw1p1/plat_topology.c253
-rw-r--r--plat/sun50iw1p1/platform.mk91
-rw-r--r--plat/sun50iw1p1/scp/arisc.c248
-rw-r--r--plat/sun50iw1p1/scp/arisc.mk35
-rw-r--r--plat/sun50iw1p1/scp/arisc_i.h84
-rw-r--r--plat/sun50iw1p1/scp/hwmsgbox/hwmsgbox.c291
-rw-r--r--plat/sun50iw1p1/scp/hwmsgbox/hwmsgbox.mk31
-rw-r--r--plat/sun50iw1p1/scp/hwmsgbox/hwmsgbox_i.h46
-rw-r--r--plat/sun50iw1p1/scp/hwspinlock/hwspinlock.c109
-rw-r--r--plat/sun50iw1p1/scp/hwspinlock/hwspinlock.mk31
-rw-r--r--plat/sun50iw1p1/scp/hwspinlock/hwspinlock_i.h48
-rw-r--r--plat/sun50iw1p1/scp/include/arisc_cfgs.h74
-rw-r--r--plat/sun50iw1p1/scp/include/arisc_dbgs.h66
-rw-r--r--plat/sun50iw1p1/scp/include/arisc_hwmsgbox.h77
-rw-r--r--plat/sun50iw1p1/scp/include/arisc_hwspinlock.h63
-rw-r--r--plat/sun50iw1p1/scp/include/arisc_includes.h92
-rw-r--r--plat/sun50iw1p1/scp/include/arisc_message_manager.h73
-rw-r--r--plat/sun50iw1p1/scp/include/arisc_messages.h81
-rw-r--r--plat/sun50iw1p1/scp/include/arisc_para.h192
-rw-r--r--plat/sun50iw1p1/scp/interfaces/arisc_axp.c402
-rw-r--r--plat/sun50iw1p1/scp/interfaces/arisc_debug_level.c137
-rw-r--r--plat/sun50iw1p1/scp/interfaces/arisc_dram_crc.c57
-rw-r--r--plat/sun50iw1p1/scp/interfaces/arisc_dvfs.c81
-rw-r--r--plat/sun50iw1p1/scp/interfaces/arisc_loopback.c51
-rw-r--r--plat/sun50iw1p1/scp/interfaces/arisc_rsb.c329
-rw-r--r--plat/sun50iw1p1/scp/interfaces/arisc_standby.c286
-rw-r--r--plat/sun50iw1p1/scp/interfaces/interfaces.mk37
-rw-r--r--plat/sun50iw1p1/scp/message_manager/message_manager.c282
-rw-r--r--plat/sun50iw1p1/scp/message_manager/message_manager.mk31
-rw-r--r--plat/sun50iw1p1/scp/message_manager/message_manager_i.h40
-rw-r--r--plat/sun50iw1p1/scpi.c140
-rw-r--r--plat/sun50iw1p1/scpi.h82
-rw-r--r--plat/sun50iw1p1/sun50iw1p1.h127
-rw-r--r--plat/sun50iw1p1/sunxi_cpu_ops.c245
-rw-r--r--plat/sun50iw1p1/sunxi_cpu_ops.h39
-rw-r--r--plat/sun50iw1p1/sunxi_def.h124
-rw-r--r--plat/sun50iw1p1/sunxi_private.h107
-rw-r--r--plat/sun50iw1p1/sunxi_security.c110
-rw-r--r--plat/sun50iw1p1/tsp/tsp-wine.mk38
-rw-r--r--plat/sun50iw1p1/tsp/tsp_sunxi_setup.c101
-rw-r--r--services/arm/arm_svc_setup.c202
-rw-r--r--services/spd/tspd/tspd_main.c3
-rw-r--r--services/std_svc/psci/psci_afflvl_off.c51
-rw-r--r--services/std_svc/psci/psci_afflvl_on.c1
-rw-r--r--services/std_svc/psci/psci_afflvl_suspend.c49
-rw-r--r--services/std_svc/psci/psci_common.c7
-rw-r--r--services/std_svc/psci/psci_entry.S9
-rw-r--r--services/std_svc/psci/psci_main.c10
-rw-r--r--services/std_svc/psci/psci_private.h2
-rw-r--r--services/std_svc/psci/psci_setup.c5
-rw-r--r--services/std_svc/std_svc_setup.c8
-rwxr-xr-xtools/add_hash_bl31.sh51
-rw-r--r--tools/fip_create/Makefile4
94 files changed, 9368 insertions, 102 deletions
diff --git a/Makefile b/Makefile
index ac66642..afd00c9 100644
--- a/Makefile
+++ b/Makefile
@@ -27,7 +27,16 @@
# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
# POSSIBILITY OF SUCH DAMAGE.
#
+#check gcc tools chain
+arm_toolchain_check=$(strip $(shell if [ -d ../toolchain/gcc-arm -a -d ../toolchain/gcc-aarch64 ]; then echo yes; fi ) )
+ifneq ("$(arm_toolchain_check)", "yes")
+ $(info "gcc tools chain not exist")
+ $(info "Please run ./build.sh -t under brandy directory at the first time")
+ $(error "")
+endif
+CROSS_COMPILE = ../toolchain/gcc-aarch64/bin/aarch64-linux-gnu-
+BL33=
#
# Trusted Firmware Version
#
@@ -41,11 +50,11 @@ VERSION_MINOR := 0
# Build verbosity
V := 0
# Debug build
-DEBUG := 0
+DEBUG := 1
# Build architecture
ARCH := aarch64
# Build platform
-DEFAULT_PLAT := fvp
+DEFAULT_PLAT := sun50iw1p1
PLAT := ${DEFAULT_PLAT}
# SPD choice
SPD := none
@@ -227,14 +236,13 @@ ASFLAGS += -nostdinc -ffreestanding -Wa,--fatal-warnings \
-Werror -Wmissing-include-dirs \
-mgeneral-regs-only -D__ASSEMBLY__ \
${DEFINES} ${INCLUDES}
-CFLAGS += -nostdinc -pedantic -ffreestanding -Wall \
+CFLAGS += -nostdinc -ffreestanding -Wall \
-Werror -Wmissing-include-dirs \
-mgeneral-regs-only -std=c99 -c -Os \
${DEFINES} ${INCLUDES}
CFLAGS += -ffunction-sections -fdata-sections
-
LDFLAGS += --fatal-warnings -O1
-LDFLAGS += --gc-sections
+LDFLAGS += --gc-sections --fix-cortex-a53-843419
CC := ${CROSS_COMPILE}gcc
@@ -249,7 +257,7 @@ PP := ${CROSS_COMPILE}gcc -E ${CFLAGS}
# Variables for use with Firmware Image Package
FIPTOOLPATH ?= tools/fip_create
-FIPTOOL ?= ${FIPTOOLPATH}/fip_create
+FIPTOOL ?= ${FIPTOOLPATH}/fip_create
fiptool: ${FIPTOOL}
fip: ${BUILD_PLAT}/fip.bin
@@ -421,6 +429,11 @@ $(BIN) : $(ELF)
@echo
@echo "Built $$@ successfully"
@echo
+ifeq (bl31.bin,$(notdir ${BIN}))
+ $${Q}git show HEAD --pretty=format:"%H" | head -n 1 > cur.log
+ $${Q}./tools/add_hash_bl31.sh -f $$@ -m bl31
+endif
+ @cp -v $$@ ../../tools/pack/chips/$(DEFAULT_PLAT)/bin/
.PHONY : bl$(1)
bl$(1) : $(BUILD_DIR) $(BIN) $(DUMP)
@@ -482,6 +495,10 @@ cscope:
${Q}find ${CURDIR} -name "*.[chsS]" > cscope.files
${Q}cscope -b -q -k
+ctag:
+ ctags -R --c++-kinds=+p --fields=+iaS --extra=+q -w -o ctags `find $(CURDIR) \
+ -name '*.[chS]' -print`
+
help:
@echo "usage: ${MAKE} PLAT=<${HELP_PLATFORMS}> <all|bl1|bl2|bl31|distclean|clean|checkcodebase|checkpatch>"
@echo ""
diff --git a/bl31/aarch64/bl31_arch_setup.c b/bl31/aarch64/bl31_arch_setup.c
index a88b029..97d98d9 100644
--- a/bl31/aarch64/bl31_arch_setup.c
+++ b/bl31/aarch64/bl31_arch_setup.c
@@ -33,7 +33,10 @@
#include <assert.h>
#include <bl_common.h>
#include <bl31.h>
+#include <cpu_data.h>
#include <platform.h>
+#include <debug.h>
+
/*******************************************************************************
* This duplicates what the primary cpu did after a cold boot in BL1. The same
@@ -47,4 +50,8 @@ void bl31_arch_setup(void)
/* Program the counter frequency */
write_cntfrq_el0(plat_get_syscnt_freq());
+
+ /* Initialize the cpu_ops pointer. */
+ init_cpu_ops();
+
}
diff --git a/bl31/aarch64/bl31_entrypoint.S b/bl31/aarch64/bl31_entrypoint.S
index 04063e1..6f5a7c0 100644
--- a/bl31/aarch64/bl31_entrypoint.S
+++ b/bl31/aarch64/bl31_entrypoint.S
@@ -40,7 +40,6 @@
* executed only by the primary cpu.
* -----------------------------------------------------
*/
-
func bl31_entrypoint
/* ---------------------------------------------------------------
* Preceding bootloader has populated x0 with a pointer to a
@@ -49,8 +48,16 @@ func bl31_entrypoint
* ---------------------------------------------------------------
*/
#if !RESET_TO_BL31
- mov x20, x0
- mov x21, x1
+ /*
+ *AA32 warmreset to AA64, the high 32bit in reg R0,R1 is unpredictable
+ */
+ /*mov x20, x0*/
+ /*mov x21, x1*/
+
+ mov x20, 0
+ mov x21, 0
+ mov w20, w0
+ mov w21, w1
#else
/* ---------------------------------------------
* Set the CPU endianness before doing anything
@@ -153,11 +160,6 @@ func bl31_entrypoint
ldr x1, =__COHERENT_RAM_UNALIGNED_SIZE__
bl zeromem16
- /* ---------------------------------------------
- * Initialize the cpu_ops pointer.
- * ---------------------------------------------
- */
- bl init_cpu_ops
/* ---------------------------------------------
* Use SP_EL0 for the C runtime stack.
diff --git a/bl31/aarch64/crash_reporting.S b/bl31/aarch64/crash_reporting.S
index 68fe256..79d7457 100644
--- a/bl31/aarch64/crash_reporting.S
+++ b/bl31/aarch64/crash_reporting.S
@@ -342,7 +342,7 @@ func do_crash_reporting
plat_print_gic_regs
/* Print the interconnect registers */
- plat_print_interconnect_regs
+ /*plat_print_interconnect_regs*/
/* Done reporting */
b crash_panic
diff --git a/bl31/bl31.ld.S b/bl31/bl31.ld.S
index add65b8..b7a867f 100644
--- a/bl31/bl31.ld.S
+++ b/bl31/bl31.ld.S
@@ -32,7 +32,6 @@
OUTPUT_FORMAT(PLATFORM_LINKER_FORMAT)
OUTPUT_ARCH(PLATFORM_LINKER_ARCH)
-ENTRY(bl31_entrypoint)
MEMORY {
@@ -48,7 +47,9 @@ SECTIONS
ro . : {
__RO_START__ = .;
- *bl31_entrypoint.o(.text*)
+ KEEP(*head_data.o(.head_data*))
+ KEEP(*bl31_hash.o(.hash_data*))
+ KEEP(*bl31_entrypoint.o(.text*))
*(.text*)
*(.rodata*)
diff --git a/bl31/bl31.mk b/bl31/bl31.mk
index f53a41f..cbeac94 100644
--- a/bl31/bl31.mk
+++ b/bl31/bl31.mk
@@ -28,7 +28,9 @@
# POSSIBILITY OF SUCH DAMAGE.
#
-BL31_SOURCES += bl31/bl31_main.c \
+BL31_SOURCES+= bl31/head_data.c \
+ bl31/bl31_hash.c \
+ bl31/bl31_main.c \
bl31/context_mgmt.c \
bl31/cpu_data_array.c \
bl31/runtime_svc.c \
diff --git a/bl31/bl31_hash.c b/bl31/bl31_hash.c
new file mode 100644
index 0000000..2722d64
--- /dev/null
+++ b/bl31/bl31_hash.c
@@ -0,0 +1,25 @@
+/*
+ * (C) Copyright 2007-2013
+ * Allwinner Technology Co., Ltd. <www.allwinnertech.com>
+ * Jerry Wang <wangflord@allwinnertech.com>
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+
+ char bl31_hash_value[64] __attribute__ ((section(".hash_data"))) = {0x38};
diff --git a/bl31/bl31_main.c b/bl31/bl31_main.c
index 19f3774..cab46d7 100644
--- a/bl31/bl31_main.c
+++ b/bl31/bl31_main.c
@@ -71,8 +71,11 @@ void bl31_lib_init(void)
******************************************************************************/
void bl31_main(void)
{
+ extern char bl31_hash_value[64];
+
NOTICE("BL3-1: %s\n", version_string);
NOTICE("BL3-1: %s\n", build_message);
+ NOTICE("BL3-1 commit: %s\n", bl31_hash_value);
/* Perform remaining generic architectural setup from EL3 */
bl31_arch_setup();
@@ -89,7 +92,7 @@ void bl31_main(void)
/* Clean caches before re-entering normal world */
dcsw_op_all(DCCSW);
-
+
/*
* All the cold boot actions on the primary cpu are done. We now need to
* decide which is the next image (BL32 or BL33) and how to execute it.
@@ -105,8 +108,9 @@ void bl31_main(void)
*/
if (bl32_init) {
INFO("BL3-1: Initializing BL3-2\n");
- (*bl32_init)();
+ //(*bl32_init)();
}
+ //__asm__ __volatile__ ("b .");
/*
* We are ready to enter the next EL. Prepare entry into the image
* corresponding to the desired security state after the next ERET.
diff --git a/bl31/context_mgmt.c b/bl31/context_mgmt.c
index 489d454..56b6a0a 100644
--- a/bl31/context_mgmt.c
+++ b/bl31/context_mgmt.c
@@ -183,6 +183,13 @@ void cm_init_context(uint64_t mpidr, const entry_point_info_t *ep)
*/
sctlr_elx = EP_GET_EE(ep->h.attr) ? SCTLR_EE_BIT : 0;
sctlr_elx |= SCTLR_EL1_RES1;
+
+ //if use AA32 SVC
+ if(GET_M32(ep->spsr) == MODE32_svc)
+ {
+ sctlr_elx |= 1<<5;//AArch32 CP15 barrier operations enabled
+ }
+
write_ctx_reg(get_sysregs_ctx(ctx), CTX_SCTLR_EL1, sctlr_elx);
if ((GET_RW(ep->spsr) == MODE_RW_64
diff --git a/bl31/head_data.c b/bl31/head_data.c
new file mode 100644
index 0000000..d14dd86
--- /dev/null
+++ b/bl31/head_data.c
@@ -0,0 +1,23 @@
+/*
+ *
+ * Header for semelis
+ *
+ */
+
+#include <head_data.h>
+#include <platform_def.h>
+
+extern char bl31_hash_value[64];
+
+struct spare_boot_ctrl_head monitor_head __attribute__ ((section(".head_data"))) =
+{
+ (0x14000000 |(((sizeof(struct spare_boot_ctrl_head)+sizeof(bl31_hash_value)) / sizeof(int)) & 0x00FFFFFF)),
+ "monitor",
+ 0,
+ 0,
+ 0,
+ 0,
+ "2.0",
+ "monitor",
+ {BL31_BASE}
+};
diff --git a/common/tf_printf.c b/common/tf_printf.c
index 02461c0..d39711f 100644
--- a/common/tf_printf.c
+++ b/common/tf_printf.c
@@ -115,6 +115,14 @@ loop:
unsigned_num_print(unum, 16);
break;
+ case 'p':
+ unum =(uint64_t)va_arg(args, void *);
+ unsigned_num_print(unum, 16);
+ break;
+ case 'z':
+ fmt++;
+ bit64 = sizeof(long) == 0x8 ? 1:0;
+ goto loop;
case 'l':
bit64 = 1;
fmt++;
@@ -134,6 +142,11 @@ loop:
fmt++;
continue;
}
+ //for windos newline"\r\n"
+ else if (*fmt == '\n')
+ {
+ putchar('\r');
+ }
putchar(*fmt++);
}
exit:
diff --git a/drivers/arm/gic/arm_gic.c b/drivers/arm/gic/arm_gic.c
index 86aaa9a..0600af8 100644
--- a/drivers/arm/gic/arm_gic.c
+++ b/drivers/arm/gic/arm_gic.c
@@ -47,6 +47,9 @@ static unsigned long g_gicr_base;
static const unsigned int *g_irq_sec_ptr;
static unsigned int g_num_irqs;
+void gic_sunxi_distributor_init(void);
+void gic_sunxi_cpuif_init(void);
+
/*******************************************************************************
* This function does some minimal GICv3 configuration. The Firmware itself does
@@ -161,6 +164,7 @@ static void gicv3_cpuif_deactivate(void)
******************************************************************************/
void arm_gic_cpuif_setup(void)
{
+
unsigned int val;
assert(g_gicc_base);
@@ -174,11 +178,13 @@ void arm_gic_cpuif_setup(void)
if (((val >> GICC_IIDR_ARCH_SHIFT) & GICC_IIDR_ARCH_MASK) >= 3)
gicv3_cpuif_setup();
+
val = ENABLE_GRP0 | FIQ_EN | FIQ_BYP_DIS_GRP0;
val |= IRQ_BYP_DIS_GRP0 | FIQ_BYP_DIS_GRP1 | IRQ_BYP_DIS_GRP1;
gicc_write_pmr(g_gicc_base, GIC_PRI_MASK);
gicc_write_ctlr(g_gicc_base, val);
+
}
/*******************************************************************************
@@ -238,6 +244,7 @@ void arm_gic_pcpu_distif_setup(void)
******************************************************************************/
static void arm_gic_distif_setup(void)
{
+
unsigned int num_ints, ctlr, index, irq_num;
/* Disable the distributor before going further */
@@ -273,6 +280,7 @@ static void arm_gic_distif_setup(void)
arm_gic_pcpu_distif_setup();
gicd_write_ctlr(g_gicd_base, ctlr | ENABLE_GRP0);
+
}
/*******************************************************************************
@@ -301,8 +309,16 @@ void arm_gic_init(unsigned int gicc_base,
******************************************************************************/
void arm_gic_setup(void)
{
- arm_gic_cpuif_setup();
- arm_gic_distif_setup();
+ if(0)
+ {
+ arm_gic_cpuif_setup();
+ arm_gic_distif_setup();
+ }else
+ {
+ gic_sunxi_cpuif_init();
+ gic_sunxi_distributor_init();
+ }
+
}
/*******************************************************************************
diff --git a/include/bl31/cpu_data.h b/include/bl31/cpu_data.h
index ba7ae06..859a8d4 100644
--- a/include/bl31/cpu_data.h
+++ b/include/bl31/cpu_data.h
@@ -104,6 +104,7 @@ static inline struct cpu_data *_cpu_data(void)
*************************************************************************/
void init_cpu_data_ptr(void);
+void init_cpu_ops(void);
#define get_cpu_data(_m) _cpu_data()->_m
#define set_cpu_data(_m, _v) _cpu_data()->_m = _v
@@ -115,6 +116,10 @@ void init_cpu_data_ptr(void);
#define flush_cpu_data(_m) flush_dcache_range((uint64_t) \
&(_cpu_data()->_m), \
sizeof(_cpu_data()->_m))
+#define flush_cpu_data_by_index(_ix, _m) \
+ flush_dcache_range((uint64_t) \
+ &(_cpu_data_by_index(_ix)->_m), \
+ sizeof(_cpu_data_by_index(_ix)->_m))
#endif /* __ASSEMBLY__ */
diff --git a/include/bl31/head_data.h b/include/bl31/head_data.h
new file mode 100644
index 0000000..9c5223f
--- /dev/null
+++ b/include/bl31/head_data.h
@@ -0,0 +1,27 @@
+/*
+ *
+ * Header for system
+ *
+ */
+
+#ifndef __HEAD_H__
+#define __HEAD_H__
+
+/******************************************************************************/
+/* the control information stored in file head */
+/******************************************************************************/
+struct spare_boot_ctrl_head {
+ unsigned int jump_instruction; // one intruction jumping to real code
+ unsigned char magic[8]; // ="u-boot"
+ unsigned int check_sum; // generated by PC
+ unsigned int align_size; // align size in byte
+ unsigned int length; // the size of all file
+ unsigned int uboot_length; // the size of uboot
+ unsigned char version[8]; // uboot version
+ unsigned char platform[8]; // platform information
+ int reserved[1]; //stamp space, 16bytes align
+} ;
+
+
+
+#endif /* __HEAD_H__ */
diff --git a/include/bl31/services/std_svc.h b/include/bl31/services/std_svc.h
index cbd5b62..329cee2 100644
--- a/include/bl31/services/std_svc.h
+++ b/include/bl31/services/std_svc.h
@@ -38,6 +38,7 @@
/* 0x8400ff02 is reserved */
#define ARM_STD_SVC_VERSION 0x8400ff03
+
/* ARM Standard Service Calls version numbers */
#define STD_SVC_VERSION_MAJOR 0x0
#define STD_SVC_VERSION_MINOR 0x1
diff --git a/include/drivers/console.h b/include/drivers/console.h
index f144ab9..6b0fe35 100644
--- a/include/drivers/console.h
+++ b/include/drivers/console.h
@@ -33,6 +33,7 @@
int console_init(unsigned long base_addr,
unsigned int uart_clk, unsigned int baud_rate);
+int console_exit(void);
int console_putc(int c);
int console_getc(void);
diff --git a/include/lib/aarch64/arch_helpers.h b/include/lib/aarch64/arch_helpers.h
index 09365fb..9b238d1 100644
--- a/include/lib/aarch64/arch_helpers.h
+++ b/include/lib/aarch64/arch_helpers.h
@@ -40,24 +40,24 @@
* registers
*********************************************************************/
-#define _DEFINE_SYSREG_READ_FUNC(_name, _reg_name) \
-static inline uint64_t read_ ## _name(void) \
-{ \
- uint64_t v; \
- __asm__ ("mrs %0, " #_reg_name : "=r" (v)); \
- return v; \
+#define _DEFINE_SYSREG_READ_FUNC(_name, _reg_name) \
+static inline uint64_t read_ ## _name(void) \
+{ \
+ uint64_t v; \
+ __asm__ volatile ("mrs %0, " #_reg_name : "=r" (v)); \
+ return v; \
}
-#define _DEFINE_SYSREG_WRITE_FUNC(_name, _reg_name) \
-static inline void write_ ## _name(uint64_t v) \
-{ \
- __asm__ ("msr " #_reg_name ", %0" : : "r" (v)); \
+#define _DEFINE_SYSREG_WRITE_FUNC(_name, _reg_name) \
+static inline void write_ ## _name(uint64_t v) \
+{ \
+ __asm__ volatile ("msr " #_reg_name ", %0" : : "r" (v)); \
}
#define _DEFINE_SYSREG_WRITE_CONST_FUNC(_name, _reg_name) \
-static inline void write_ ## _name(const uint64_t v) \
-{ \
- __asm__ ("msr " #_reg_name ", %0" : : "i" (v)); \
+static inline void write_ ## _name(const uint64_t v) \
+{ \
+ __asm__ volatile ("msr " #_reg_name ", %0" : : "i" (v)); \
}
/* Define read function for system register */
diff --git a/include/plat/common/platform.h b/include/plat/common/platform.h
index 69bb749..bedff9e 100644
--- a/include/plat/common/platform.h
+++ b/include/plat/common/platform.h
@@ -191,4 +191,6 @@ void bl31_plat_enable_mmu(uint32_t flags);
******************************************************************************/
void bl32_plat_enable_mmu(uint32_t flags);
+void platform_smp_init(void);
+
#endif /* __PLATFORM_H__ */
diff --git a/lib/aarch64/xlat_tables.c b/lib/aarch64/xlat_tables.c
index ddc9ba8..82ae898 100644
--- a/lib/aarch64/xlat_tables.c
+++ b/lib/aarch64/xlat_tables.c
@@ -35,7 +35,7 @@
#include <platform_def.h>
#include <string.h>
#include <xlat_tables.h>
-
+#include <stdio.h>
#ifndef DEBUG_XLAT_TABLE
#define DEBUG_XLAT_TABLE 0
@@ -349,3 +349,58 @@ DEFINE_ENABLE_MMU_EL(1,
DEFINE_ENABLE_MMU_EL(3,
TCR_EL3_RES1 | (tcr_ps_bits << TCR_EL3_PS_SHIFT),
tlbialle3)
+
+#if 0
+void enable_mmu_el3(uint32_t flags)
+{
+ uint64_t mair, tcr, ttbr;
+ uint32_t sctlr;
+ uint32_t _tcr_extra = TCR_EL3_RES1 | (tcr_ps_bits << TCR_EL3_PS_SHIFT);
+
+
+ assert(IS_IN_EL(_el));
+ assert((read_sctlr_el3() & SCTLR_M_BIT) == 0);
+
+ /* Set attributes in the right indices of the MAIR */
+ mair = MAIR_ATTR_SET(ATTR_DEVICE, ATTR_DEVICE_INDEX);
+ mair |= MAIR_ATTR_SET(ATTR_IWBWA_OWBWA_NTR,
+ ATTR_IWBWA_OWBWA_NTR_INDEX);
+ write_mair_el3(mair);
+
+ /* Invalidate TLBs at the current exception level */
+ tlbialle3();
+
+ /* Set TCR bits as well. */
+ /* Inner & outer WBWA & shareable + T0SZ = 32 */
+ tcr = TCR_SH_INNER_SHAREABLE | TCR_RGN_OUTER_WBA |
+ TCR_RGN_INNER_WBA |
+ (64 - __builtin_ctzl(ADDR_SPACE_SIZE));
+ tcr |= _tcr_extra;
+ write_tcr_el3(tcr);
+
+ /* Set TTBR bits as well */
+ ttbr = (uint64_t) l1_xlation_table;
+ write_ttbr0_el3(ttbr);
+
+ /* Ensure all translation table writes have drained */
+ /* into memory, the TLB invalidation is complete, */
+ /* and translation register writes are committed */
+ /* before enabling the MMU */
+ dsb();
+ isb();
+
+ sctlr = read_sctlr_el3();
+ sctlr |= SCTLR_WXN_BIT | SCTLR_M_BIT;
+
+ if (flags & DISABLE_DCACHE)
+ sctlr &= ~SCTLR_C_BIT;
+ else
+ sctlr |= SCTLR_C_BIT;
+
+ write_sctlr_el3(sctlr);
+
+ /* Ensure the MMU enable takes effect immediately */
+ isb();
+}
+#endif
+
diff --git a/lib/cpus/aarch64/cpu_helpers.S b/lib/cpus/aarch64/cpu_helpers.S
index 46584b3..ecc2088 100644
--- a/lib/cpus/aarch64/cpu_helpers.S
+++ b/lib/cpus/aarch64/cpu_helpers.S
@@ -105,7 +105,8 @@ func prepare_cluster_pwr_dwn
/*
* Initializes the cpu_ops_ptr if not already initialized
- * in cpu_data. This can be called without a runtime stack.
+ * in cpu_data. This can be called without a runtime stack, but may
+ * only be called after the MMU is enabled.
* clobbers: x0 - x6, x10
*/
.globl init_cpu_ops
@@ -119,7 +120,7 @@ func init_cpu_ops
cmp x0, #0
ASM_ASSERT(ne)
#endif
- str x0, [x6, #CPU_DATA_CPU_OPS_PTR]
+ str x0, [x6, #CPU_DATA_CPU_OPS_PTR]!
mov x30, x10
1:
ret
diff --git a/lib/locks/bakery/bakery_lock.c b/lib/locks/bakery/bakery_lock.c
index 877f526..7e71dec 100644
--- a/lib/locks/bakery/bakery_lock.c
+++ b/lib/locks/bakery/bakery_lock.c
@@ -107,6 +107,7 @@ static unsigned int bakery_get_ticket(bakery_lock_t *bakery, unsigned int me)
++my_ticket;
bakery->number[me] = my_ticket;
bakery->entering[me] = 0;
+ dsb();
sev();
return my_ticket;
@@ -189,5 +190,6 @@ void bakery_lock_release(bakery_lock_t *bakery)
*/
bakery->owner = NO_OWNER;
bakery->number[me] = 0;
+ dsb();
sev();
}
diff --git a/lib/stdlib/assert.c b/lib/stdlib/assert.c
index 90a1afe..b6570da 100644
--- a/lib/stdlib/assert.c
+++ b/lib/stdlib/assert.c
@@ -36,6 +36,5 @@
void __assert (const char *function, const char *file, unsigned int line,
const char *assertion)
{
- tf_printf("ASSERT: %s <%d> : %s\n", function, line, assertion);
while(1);
}
diff --git a/plat/fvp/platform.mk b/plat/fvp/platform.mk
index e7c06a8..73d6052 100644
--- a/plat/fvp/platform.mk
+++ b/plat/fvp/platform.mk
@@ -71,7 +71,8 @@ PLAT_BL_COMMON_SOURCES := drivers/arm/pl011/pl011_console.S \
lib/semihosting/semihosting.c \
lib/semihosting/aarch64/semihosting_call.S \
plat/common/aarch64/plat_common.c \
- plat/fvp/fvp_io_storage.c
+ plat/fvp/fvp_io_storage.c
+
BL1_SOURCES += drivers/arm/cci400/cci400.c \
lib/cpus/aarch64/aem_generic.S \
diff --git a/plat/sun50iw1p1/aarch64/plat_helpers.S b/plat/sun50iw1p1/aarch64/plat_helpers.S
new file mode 100644
index 0000000..1bb225f
--- /dev/null
+++ b/plat/sun50iw1p1/aarch64/plat_helpers.S
@@ -0,0 +1,144 @@
+/*
+ * Copyright (c) 2013-2014, ARM Limited and Contributors. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * Neither the name of ARM nor the names of its contributors may be used
+ * to endorse or promote products derived from this software without specific
+ * prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <arch.h>
+#include <asm_macros.S>
+#include <bl_common.h>
+#include <cortex_a57.h>
+#include <cpu_macros.S>
+#include <platform_def.h>
+#include "../sunxi_def.h"
+
+ .globl plat_crash_console_init
+ .globl plat_crash_console_putc
+ .globl plat_report_exception
+ .globl plat_reset_handler
+ .globl platform_get_core_pos
+ .globl platform_mem_init
+ .globl platform_smp_init
+
+ /* Define a crash console for the plaform */
+#define JUNO_CRASH_CONSOLE_BASE 0
+
+ /* ---------------------------------------------
+ * void plat_report_exception(unsigned int type)
+ * Function to report an unhandled exception
+ * with platform-specific means.
+ * On Juno platform, it updates the LEDs
+ * to indicate where we are
+ * ---------------------------------------------
+ */
+func plat_report_exception
+
+ ret
+
+ /*
+ * Return 0 to 3 for the A53s and 4 or 5 for the A57s
+ */
+func platform_get_core_pos
+ and x1, x0, #MPIDR_CPU_MASK
+ and x0, x0, #MPIDR_CLUSTER_MASK
+ add x0, x1, x0, LSR #6
+ ret
+
+
+ /* -----------------------------------------------------
+ * void platform_mem_init(void);
+ *
+ * We don't need to carry out any memory initialization
+ * on Juno. The Secure RAM is accessible straight away.
+ * -----------------------------------------------------
+ */
+func platform_mem_init
+ ret
+
+ /* -----------------------------------------------------
+ * void plat_reset_handler(void);
+ *
+ * Implement workaround for defect id 831273 by enabling
+ * an event stream every 65536 cycles and set the L2 RAM
+ * latencies for Cortex-A57.
+ * -----------------------------------------------------
+ */
+func plat_reset_handler
+ /* Read the MIDR_EL1 */
+ mrs x0, midr_el1
+ ubfx x1, x0, MIDR_PN_SHIFT, #12
+ cmp w1, #((CORTEX_A57_MIDR >> MIDR_PN_SHIFT) & MIDR_PN_MASK)
+ b.ne 1f
+
+ /* Change the L2 Data and Tag Ram latency to 3 cycles */
+ mov x0, #(L2_DATA_RAM_LATENCY_3_CYCLES | \
+ (L2_TAG_RAM_LATENCY_3_CYCLES << \
+ L2CTLR_TAG_RAM_LATENCY_SHIFT))
+ msr L2CTLR_EL1, x0
+
+1:
+ /* ---------------------------------------------
+ * Enable the event stream every 65536 cycles
+ * ---------------------------------------------
+ */
+ mov x0, #(0xf << EVNTI_SHIFT)
+ orr x0, x0, #EVNTEN_BIT
+ msr CNTKCTL_EL1, x0
+ isb
+ ret
+
+func platform_smp_init
+ mrs x0, ACTLR_EL3 // Read ACTLR_EL3
+ orr x0, x0, #(1 << 1) // Set CPUECTLR_EL1 access control bit
+ msr ACTLR_EL3, x0 // Write ACTLR_EL3
+ mrs x0, ACTLR_EL2 // Read ACTLR_EL2
+ orr x0, x0, #(1 << 1) // Set CPUECTLR_EL1 access control bit
+ msr ACTLR_EL2, x0 // Write ACTLR_EL2
+ mrs x0, S3_1_c15_c2_1 // Read CPUECTLR_EL1
+ orr x0, x0, #(1 << 6) // Set the SMPEN bit
+ msr S3_1_c15_c2_1, x0 // Write CPUECTLR_EL1
+ mov x0, #0x0
+ msr cntvoff_el2, x0
+ ret
+
+func console_core_putc
+ ldr x1, =0x01c28000
+1:
+ ldr w2, [x1,#20]
+ tbz w2, #6, 1b
+ str w0, [x1,#0]
+ ret
+
+func plat_crash_console_init
+ mov w0, #1
+ ret
+
+func plat_crash_console_putc
+ b console_core_putc
+
+
+
diff --git a/plat/sun50iw1p1/aarch64/sunxi_common.c b/plat/sun50iw1p1/aarch64/sunxi_common.c
new file mode 100644
index 0000000..b7de9d0
--- /dev/null
+++ b/plat/sun50iw1p1/aarch64/sunxi_common.c
@@ -0,0 +1,246 @@
+/*
+ * Copyright (c) 2013-2014, ARM Limited and Contributors. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * Neither the name of ARM nor the names of its contributors may be used
+ * to endorse or promote products derived from this software without specific
+ * prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <arch.h>
+#include <arch_helpers.h>
+#include <arm_gic.h>
+#include <bl_common.h>
+#include <cci400.h>
+#include <debug.h>
+#include <mmio.h>
+#include <platform.h>
+#include <plat_config.h>
+#include <xlat_tables.h>
+#include "../sunxi_def.h"
+#include "../sunxi_private.h"
+
+/*******************************************************************************
+ * plat_config holds the characteristics of the differences between the three
+ * FVP platforms (Base, A53_A57 & Foundation). It will be populated during cold
+ * boot at each boot stage by the primary before enabling the MMU (to allow cci
+ * configuration) & used thereafter. Each BL will have its own copy to allow
+ * independent operation.
+ ******************************************************************************/
+plat_config_t plat_config;
+
+/*
+ * Table of regions to map using the MMU.
+ * This doesn't include TZRAM as the 'mem_layout' argument passed to
+ * configure_mmu_elx() will give the available subset of that,
+ */
+const mmap_region_t sunxi_mmap[] = {
+
+ //1G
+ { 0, 0, DRAM1_BASE, MT_DEVICE | MT_RW | MT_SECURE },
+ //2G
+ { DRAM1_BASE, DRAM1_BASE, SUNXI_MAX_DRAM_SIZE, MT_MEMORY | MT_RW | MT_NS},
+ //TRUSTED dram for secure os and shared memory
+ { SUNXI_TRUSTED_DRAM_BASE, SUNXI_TRUSTED_DRAM_BASE, SUNXI_TRUSTED_DRAM_SIZE, MT_MEMORY | MT_RW | MT_SECURE },
+ { MEMRES_BASE, MEMRES_BASE, MEMRES_SIZE, MT_DEVICE | MT_RW | MT_SECURE },
+ {0}
+};
+
+
+
+
+/*******************************************************************************
+ * Macro generating the code for the function setting up the pagetables as per
+ * the platform memory map & initialize the mmu, for the given exception level
+ ******************************************************************************/
+#define DEFINE_CONFIGURE_MMU_EL(_el) \
+ void sunxi_configure_mmu_el##_el(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(sunxi_mmap); \
+ init_xlat_tables(); \
+ \
+ enable_mmu_el##_el(0); \
+ }
+
+void sunxi_configure_mmu_el3(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(sunxi_mmap);
+ init_xlat_tables();
+
+ enable_mmu_el3(0);
+}
+
+void sunxi_configure_mmu_el1(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(sunxi_mmap);
+ init_xlat_tables();
+
+ enable_mmu_el1(0);
+}
+
+
+/* Define EL1 and EL3 variants of the function initialising the MMU */
+//DEFINE_CONFIGURE_MMU_EL(1)
+//DEFINE_CONFIGURE_MMU_EL(3)
+
+/*******************************************************************************
+ * A single boot loader stack is expected to work on both the Foundation FVP
+ * models and the two flavours of the Base FVP models (AEMv8 & Cortex). The
+ * SYS_ID register provides a mechanism for detecting the differences between
+ * these platforms. This information is stored in a per-BL array to allow the
+ * code to take the correct path.Per BL platform configuration.
+ ******************************************************************************/
+int sunxi_config_setup(void)
+{
+
+ return 0;
+}
+
+unsigned long plat_get_ns_image_entrypoint(void)
+{
+ return NS_IMAGE_OFFSET;
+}
+
+uint64_t plat_get_syscnt_freq(void)
+{
+ uint64_t counter_base_frequency;
+
+ /* Read the frequency from Frequency modes table */
+ counter_base_frequency = 24<<20;//mmio_read_32(SYS_CNTCTL_BASE + CNTFID_OFF);
+
+ /* The first entry of the frequency modes table must not be 0 */
+ if (counter_base_frequency == 0)
+ panic();
+
+ return counter_base_frequency;
+}
+
+void sunxi_cci_init(void)
+{
+ /*
+ * Initialize CCI-400 driver
+ */
+
+}
+
+void sunxi_cci_enable(void)
+{
+ /*
+ * Enable CCI-400 coherency for this cluster. No need
+ * for locks as no other cpu is active at the
+ * moment
+ */
+
+}
+
+
+void sunxi_gic_init(void)
+{
+ gic_setup();
+}
+
+
+/*******************************************************************************
+ * Gets SPSR for BL32 entry
+ ******************************************************************************/
+uint32_t sunxi_get_spsr_for_bl32_entry(void)
+{
+ /*
+ * The Secure Payload Dispatcher service is responsible for
+ * setting the SPSR prior to entry into the BL32 image.
+ */
+ return 0;
+}
+
+/*******************************************************************************
+ * Gets SPSR for BL33 entry
+ ******************************************************************************/
+uint32_t sunxi_get_spsr_for_bl33_entry(void)
+{
+ #if 0
+ unsigned long el_status;
+ unsigned int mode;
+ uint32_t spsr;
+
+ /* Figure out what mode we enter the non-secure world in */
+ el_status = read_id_aa64pfr0_el1() >> ID_AA64PFR0_EL2_SHIFT;
+ el_status &= ID_AA64PFR0_ELX_MASK;
+
+ if (el_status)
+ mode = MODE_EL2;
+ else
+ mode = MODE_EL1;
+
+ /*
+ * TODO: Consider the possibility of specifying the SPSR in
+ * the FIP ToC and allowing the platform to have a say as
+ * well.
+ */
+ spsr = SPSR_64(mode, MODE_SP_ELX, DISABLE_ALL_EXCEPTIONS);
+ return spsr;
+ #endif
+ return SPSR_MODE32(MODE32_svc,SPSR_T_ARM,SPSR_E_LITTLE,DISABLE_ALL_EXCEPTIONS);
+}
diff --git a/plat/sun50iw1p1/bl1_sunxi_setup.c b/plat/sun50iw1p1/bl1_sunxi_setup.c
new file mode 100644
index 0000000..b1205d4
--- /dev/null
+++ b/plat/sun50iw1p1/bl1_sunxi_setup.c
@@ -0,0 +1,136 @@
+/*
+ * Copyright (c) 2013-2014, ARM Limited and Contributors. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * Neither the name of ARM nor the names of its contributors may be used
+ * to endorse or promote products derived from this software without specific
+ * prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <arch_helpers.h>
+#include <assert.h>
+#include <bl_common.h>
+#include <debug.h>
+#include <console.h>
+#include <mmio.h>
+#include <platform.h>
+#include <platform_def.h>
+#include "../../bl1/bl1_private.h"
+#include "fvp_def.h"
+#include "fvp_private.h"
+
+/*******************************************************************************
+ * Declarations of linker defined symbols which will help us find the layout
+ * of trusted SRAM
+ ******************************************************************************/
+extern unsigned long __COHERENT_RAM_START__;
+extern unsigned long __COHERENT_RAM_END__;
+
+/*
+ * The next 2 constants identify the extents of the coherent memory region.
+ * These addresses are used by the MMU setup code and therefore they must be
+ * page-aligned. It is the responsibility of the linker script to ensure that
+ * __COHERENT_RAM_START__ and __COHERENT_RAM_END__ linker symbols refer to
+ * page-aligned addresses.
+ */
+#define BL1_COHERENT_RAM_BASE (unsigned long)(&__COHERENT_RAM_START__)
+#define BL1_COHERENT_RAM_LIMIT (unsigned long)(&__COHERENT_RAM_END__)
+
+/* Data structure which holds the extents of the trusted SRAM for BL1*/
+static meminfo_t bl1_tzram_layout;
+
+meminfo_t *bl1_plat_sec_mem_layout(void)
+{
+ return &bl1_tzram_layout;
+}
+
+/*******************************************************************************
+ * Perform any BL1 specific platform actions.
+ ******************************************************************************/
+void bl1_early_platform_setup(void)
+{
+ const size_t bl1_size = BL1_RAM_LIMIT - BL1_RAM_BASE;
+
+ /* Initialize the console to provide early debug support */
+ console_init(PL011_UART0_BASE, PL011_UART0_CLK_IN_HZ, PL011_BAUDRATE);
+
+ /* Allow BL1 to see the whole Trusted RAM */
+ bl1_tzram_layout.total_base = FVP_TRUSTED_SRAM_BASE;
+ bl1_tzram_layout.total_size = FVP_TRUSTED_SRAM_SIZE;
+
+ /* Calculate how much RAM BL1 is using and how much remains free */
+ bl1_tzram_layout.free_base = FVP_TRUSTED_SRAM_BASE;
+ bl1_tzram_layout.free_size = FVP_TRUSTED_SRAM_SIZE;
+ reserve_mem(&bl1_tzram_layout.free_base,
+ &bl1_tzram_layout.free_size,
+ BL1_RAM_BASE,
+ bl1_size);
+
+ /* Initialize the platform config for future decision making */
+ fvp_config_setup();
+}
+
+/*******************************************************************************
+ * Function which will evaluate how much of the trusted ram has been gobbled
+ * up by BL1 and return the base and size of whats available for loading BL2.
+ * Its called after coherency and the MMU have been turned on.
+ ******************************************************************************/
+void bl1_platform_setup(void)
+{
+ /* Initialise the IO layer and register platform IO devices */
+ fvp_io_setup();
+}
+
+
+/*******************************************************************************
+ * Perform the very early platform specific architecture setup here. At the
+ * moment this only does basic initialization. Later architectural setup
+ * (bl1_arch_setup()) does not do anything platform specific.
+ ******************************************************************************/
+void bl1_plat_arch_setup(void)
+{
+ fvp_cci_init();
+ fvp_cci_enable();
+
+ fvp_configure_mmu_el3(bl1_tzram_layout.total_base,
+ bl1_tzram_layout.total_size,
+ BL1_RO_BASE,
+ BL1_RO_LIMIT,
+ BL1_COHERENT_RAM_BASE,
+ BL1_COHERENT_RAM_LIMIT);
+}
+
+
+/*******************************************************************************
+ * Before calling this function BL2 is loaded in memory and its entrypoint
+ * is set by load_image. This is a placeholder for the platform to change
+ * the entrypoint of BL2 and set SPSR and security state.
+ * On FVP we are only setting the security state, entrypoint
+ ******************************************************************************/
+void bl1_plat_set_bl2_ep_info(image_info_t *bl2_image,
+ entry_point_info_t *bl2_ep)
+{
+ SET_SECURITY_STATE(bl2_ep->h.attr, SECURE);
+ bl2_ep->spsr = SPSR_64(MODE_EL1, MODE_SP_ELX, DISABLE_ALL_EXCEPTIONS);
+}
diff --git a/plat/sun50iw1p1/bl2_sunxi_setup.c b/plat/sun50iw1p1/bl2_sunxi_setup.c
new file mode 100644
index 0000000..d4fa4cb
--- /dev/null
+++ b/plat/sun50iw1p1/bl2_sunxi_setup.c
@@ -0,0 +1,285 @@
+/*
+ * Copyright (c) 2013-2014, ARM Limited and Contributors. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * Neither the name of ARM nor the names of its contributors may be used
+ * to endorse or promote products derived from this software without specific
+ * prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <arch_helpers.h>
+#include <assert.h>
+#include <bl_common.h>
+#include <console.h>
+#include <platform.h>
+#include <platform_def.h>
+#include <string.h>
+#include "fvp_def.h"
+#include "fvp_private.h"
+
+/*******************************************************************************
+ * Declarations of linker defined symbols which will help us find the layout
+ * of trusted SRAM
+ ******************************************************************************/
+extern unsigned long __RO_START__;
+extern unsigned long __RO_END__;
+
+extern unsigned long __COHERENT_RAM_START__;
+extern unsigned long __COHERENT_RAM_END__;
+
+/*
+ * The next 2 constants identify the extents of the code & RO data region.
+ * These addresses are used by the MMU setup code and therefore they must be
+ * page-aligned. It is the responsibility of the linker script to ensure that
+ * __RO_START__ and __RO_END__ linker symbols refer to page-aligned addresses.
+ */
+#define BL2_RO_BASE (unsigned long)(&__RO_START__)
+#define BL2_RO_LIMIT (unsigned long)(&__RO_END__)
+
+/*
+ * The next 2 constants identify the extents of the coherent memory region.
+ * These addresses are used by the MMU setup code and therefore they must be
+ * page-aligned. It is the responsibility of the linker script to ensure that
+ * __COHERENT_RAM_START__ and __COHERENT_RAM_END__ linker symbols refer to
+ * page-aligned addresses.
+ */
+#define BL2_COHERENT_RAM_BASE (unsigned long)(&__COHERENT_RAM_START__)
+#define BL2_COHERENT_RAM_LIMIT (unsigned long)(&__COHERENT_RAM_END__)
+
+/* Data structure which holds the extents of the trusted SRAM for BL2 */
+static meminfo_t bl2_tzram_layout
+__attribute__ ((aligned(PLATFORM_CACHE_LINE_SIZE),
+ section("tzfw_coherent_mem")));
+
+/* Assert that BL3-1 parameters fit in shared memory */
+CASSERT((PARAMS_BASE + sizeof(bl2_to_bl31_params_mem_t)) <
+ (FVP_SHARED_RAM_BASE + FVP_SHARED_RAM_SIZE),
+ assert_bl31_params_do_not_fit_in_shared_memory);
+
+/*******************************************************************************
+ * Reference to structures which holds the arguments which need to be passed
+ * to BL31
+ ******************************************************************************/
+static bl31_params_t *bl2_to_bl31_params;
+static entry_point_info_t *bl31_ep_info;
+
+meminfo_t *bl2_plat_sec_mem_layout(void)
+{
+ return &bl2_tzram_layout;
+}
+
+/*******************************************************************************
+ * This function assigns a pointer to the memory that the platform has kept
+ * aside to pass platform specific and trusted firmware related information
+ * to BL31. This memory is allocated by allocating memory to
+ * bl2_to_bl31_params_mem_t structure which is a superset of all the
+ * structure whose information is passed to BL31
+ * NOTE: This function should be called only once and should be done
+ * before generating params to BL31
+ ******************************************************************************/
+bl31_params_t *bl2_plat_get_bl31_params(void)
+{
+ bl2_to_bl31_params_mem_t *bl31_params_mem;
+
+ /*
+ * Allocate the memory for all the arguments that needs to
+ * be passed to BL31
+ */
+ bl31_params_mem = (bl2_to_bl31_params_mem_t *)PARAMS_BASE;
+ memset((void *)PARAMS_BASE, 0, sizeof(bl2_to_bl31_params_mem_t));
+
+ /* Assign memory for TF related information */
+ bl2_to_bl31_params = &bl31_params_mem->bl31_params;
+ SET_PARAM_HEAD(bl2_to_bl31_params, PARAM_BL31, VERSION_1, 0);
+
+ /* Fill BL31 related information */
+ bl31_ep_info = &bl31_params_mem->bl31_ep_info;
+ bl2_to_bl31_params->bl31_image_info = &bl31_params_mem->bl31_image_info;
+ SET_PARAM_HEAD(bl2_to_bl31_params->bl31_image_info, PARAM_IMAGE_BINARY,
+ VERSION_1, 0);
+
+ /* Fill BL32 related information if it exists */
+ if (BL32_BASE) {
+ bl2_to_bl31_params->bl32_ep_info =
+ &bl31_params_mem->bl32_ep_info;
+ SET_PARAM_HEAD(bl2_to_bl31_params->bl32_ep_info,
+ PARAM_EP, VERSION_1, 0);
+ bl2_to_bl31_params->bl32_image_info =
+ &bl31_params_mem->bl32_image_info;
+ SET_PARAM_HEAD(bl2_to_bl31_params->bl32_image_info,
+ PARAM_IMAGE_BINARY,
+ VERSION_1, 0);
+ }
+
+ /* Fill BL33 related information */
+ bl2_to_bl31_params->bl33_ep_info = &bl31_params_mem->bl33_ep_info;
+ SET_PARAM_HEAD(bl2_to_bl31_params->bl33_ep_info,
+ PARAM_EP, VERSION_1, 0);
+ bl2_to_bl31_params->bl33_image_info = &bl31_params_mem->bl33_image_info;
+ SET_PARAM_HEAD(bl2_to_bl31_params->bl33_image_info, PARAM_IMAGE_BINARY,
+ VERSION_1, 0);
+
+ return bl2_to_bl31_params;
+}
+
+
+/*******************************************************************************
+ * This function returns a pointer to the shared memory that the platform
+ * has kept to point to entry point information of BL31 to BL2
+ ******************************************************************************/
+struct entry_point_info *bl2_plat_get_bl31_ep_info(void)
+{
+#if DEBUG
+ bl31_ep_info->args.arg1 = FVP_BL31_PLAT_PARAM_VAL;
+#endif
+ return bl31_ep_info;
+}
+
+
+/*******************************************************************************
+ * BL1 has passed the extents of the trusted SRAM that should be visible to BL2
+ * in x0. This memory layout is sitting at the base of the free trusted SRAM.
+ * Copy it to a safe loaction before its reclaimed by later BL2 functionality.
+ ******************************************************************************/
+void bl2_early_platform_setup(meminfo_t *mem_layout)
+{
+ /* Initialize the console to provide early debug support */
+ console_init(PL011_UART0_BASE, PL011_UART0_CLK_IN_HZ, PL011_BAUDRATE);
+
+ /* Setup the BL2 memory layout */
+ bl2_tzram_layout = *mem_layout;
+
+ /* Initialize the platform config for future decision making */
+ fvp_config_setup();
+}
+
+/*******************************************************************************
+ * Perform platform specific setup. For now just initialize the memory location
+ * to use for passing arguments to BL31.
+ ******************************************************************************/
+void bl2_platform_setup(void)
+{
+ /*
+ * Do initial security configuration to allow DRAM/device access. On
+ * Base FVP only DRAM security is programmable (via TrustZone), but
+ * other platforms might have more programmable security devices
+ * present.
+ */
+ fvp_security_setup();
+
+ /* Initialise the IO layer and register platform IO devices */
+ fvp_io_setup();
+}
+
+/* Flush the TF params and the TF plat params */
+void bl2_plat_flush_bl31_params(void)
+{
+ flush_dcache_range((unsigned long)PARAMS_BASE, \
+ sizeof(bl2_to_bl31_params_mem_t));
+}
+
+
+/*******************************************************************************
+ * 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 bl2_plat_arch_setup(void)
+{
+ fvp_configure_mmu_el1(bl2_tzram_layout.total_base,
+ bl2_tzram_layout.total_size,
+ BL2_RO_BASE,
+ BL2_RO_LIMIT,
+ BL2_COHERENT_RAM_BASE,
+ BL2_COHERENT_RAM_LIMIT);
+}
+
+/*******************************************************************************
+ * Before calling this function BL31 is loaded in memory and its entrypoint
+ * is set by load_image. This is a placeholder for the platform to change
+ * the entrypoint of BL31 and set SPSR and security state.
+ * On FVP we are only setting the security state, entrypoint
+ ******************************************************************************/
+void bl2_plat_set_bl31_ep_info(image_info_t *bl31_image_info,
+ entry_point_info_t *bl31_ep_info)
+{
+ SET_SECURITY_STATE(bl31_ep_info->h.attr, SECURE);
+ bl31_ep_info->spsr = SPSR_64(MODE_EL3, MODE_SP_ELX,
+ DISABLE_ALL_EXCEPTIONS);
+}
+
+
+/*******************************************************************************
+ * Before calling this function BL32 is loaded in memory and its entrypoint
+ * is set by load_image. This is a placeholder for the platform to change
+ * the entrypoint of BL32 and set SPSR and security state.
+ * On FVP we are only setting the security state, entrypoint
+ ******************************************************************************/
+void bl2_plat_set_bl32_ep_info(image_info_t *bl32_image_info,
+ entry_point_info_t *bl32_ep_info)
+{
+ SET_SECURITY_STATE(bl32_ep_info->h.attr, SECURE);
+ bl32_ep_info->spsr = fvp_get_spsr_for_bl32_entry();
+}
+
+/*******************************************************************************
+ * Before calling this function BL33 is loaded in memory and its entrypoint
+ * is set by load_image. This is a placeholder for the platform to change
+ * the entrypoint of BL33 and set SPSR and security state.
+ * On FVP we are only setting the security state, entrypoint
+ ******************************************************************************/
+void bl2_plat_set_bl33_ep_info(image_info_t *image,
+ entry_point_info_t *bl33_ep_info)
+{
+ SET_SECURITY_STATE(bl33_ep_info->h.attr, NON_SECURE);
+ bl33_ep_info->spsr = fvp_get_spsr_for_bl33_entry();
+}
+
+
+/*******************************************************************************
+ * Populate the extents of memory available for loading BL32
+ ******************************************************************************/
+void bl2_plat_get_bl32_meminfo(meminfo_t *bl32_meminfo)
+{
+ /*
+ * Populate the extents of memory available for loading BL32.
+ */
+ bl32_meminfo->total_base = BL32_BASE;
+ bl32_meminfo->free_base = BL32_BASE;
+ bl32_meminfo->total_size = TSP_SEC_MEM_SIZE;
+ //(TSP_SEC_MEM_BASE + TSP_SEC_MEM_SIZE) - BL32_BASE;
+ bl32_meminfo->free_size =TSP_SEC_MEM_SIZE;
+ //(TSP_SEC_MEM_BASE + TSP_SEC_MEM_SIZE) - BL32_BASE;
+}
+
+
+/*******************************************************************************
+ * Populate the extents of memory available for loading BL33
+ ******************************************************************************/
+void bl2_plat_get_bl33_meminfo(meminfo_t *bl33_meminfo)
+{
+ bl33_meminfo->total_base = DRAM_BASE;
+ bl33_meminfo->total_size = DRAM_SIZE - DRAM1_SEC_SIZE;
+ bl33_meminfo->free_base = DRAM_BASE;
+ bl33_meminfo->free_size = DRAM_SIZE - DRAM1_SEC_SIZE;
+}
diff --git a/plat/sun50iw1p1/bl31_sunxi_setup.c b/plat/sun50iw1p1/bl31_sunxi_setup.c
new file mode 100644
index 0000000..4237a25
--- /dev/null
+++ b/plat/sun50iw1p1/bl31_sunxi_setup.c
@@ -0,0 +1,275 @@
+/*
+ * Copyright (c) 2013-2014, ARM Limited and Contributors. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * Neither the name of ARM nor the names of its contributors may be used
+ * to endorse or promote products derived from this software without specific
+ * prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <arch.h>
+#include <arch_helpers.h>
+#include <arm_gic.h>
+#include <assert.h>
+#include <bl_common.h>
+#include <bl31.h>
+#include <console.h>
+#include <mmio.h>
+#include <platform.h>
+#include <stddef.h>
+#include "sunxi_def.h"
+#include "sunxi_private.h"
+
+/*******************************************************************************
+ * Declarations of linker defined symbols which will help us find the layout
+ * of trusted SRAM
+ ******************************************************************************/
+extern unsigned long __RO_START__;
+extern unsigned long __RO_END__;
+
+extern unsigned long __COHERENT_RAM_START__;
+extern unsigned long __COHERENT_RAM_END__;
+
+/*
+ * The next 2 constants identify the extents of the code & RO data region.
+ * These addresses are used by the MMU setup code and therefore they must be
+ * page-aligned. It is the responsibility of the linker script to ensure that
+ * __RO_START__ and __RO_END__ linker symbols refer to page-aligned addresses.
+ */
+#define BL31_RO_BASE (unsigned long)(&__RO_START__)
+#define BL31_RO_LIMIT (unsigned long)(&__RO_END__)
+
+/*
+ * The next 2 constants identify the extents of the coherent memory region.
+ * These addresses are used by the MMU setup code and therefore they must be
+ * page-aligned. It is the responsibility of the linker script to ensure that
+ * __COHERENT_RAM_START__ and __COHERENT_RAM_END__ linker symbols
+ * refer to page-aligned addresses.
+ */
+#define BL31_COHERENT_RAM_BASE (unsigned long)(&__COHERENT_RAM_START__)
+#define BL31_COHERENT_RAM_LIMIT (unsigned long)(&__COHERENT_RAM_END__)
+
+
+#if 0
+#if RESET_TO_BL31
+static entry_point_info_t bl32_image_ep_info;
+static entry_point_info_t bl33_image_ep_info;
+#else
+/*******************************************************************************
+ * Reference to structure which holds the arguments that have been passed to
+ * BL31 from BL2.
+ ******************************************************************************/
+static bl31_params_t *bl2_to_bl31_params;
+#endif
+#else
+static entry_point_info_t bl32_image_ep_info;
+static entry_point_info_t bl33_image_ep_info;
+#endif
+
+
+/*******************************************************************************
+ * Return a pointer to the 'entry_point_info' structure of the next image for the
+ * security state specified. BL33 corresponds to the non-secure image type
+ * while BL32 corresponds to the secure image type. A NULL pointer is returned
+ * if the image does not exist.
+ ******************************************************************************/
+entry_point_info_t *bl31_plat_get_next_image_ep_info(uint32_t type)
+{
+//#if RESET_TO_BL31
+#if 1
+
+ assert(sec_state_is_valid(type));
+
+ if (type == NON_SECURE)
+ return &bl33_image_ep_info;
+ else
+ return &bl32_image_ep_info;
+#else
+ entry_point_info_t *next_image_info;
+
+ assert(sec_state_is_valid(type));
+
+ next_image_info = (type == NON_SECURE) ?
+ bl2_to_bl31_params->bl33_ep_info :
+ bl2_to_bl31_params->bl32_ep_info;
+
+ /* None of the images on this platform can have 0x0 as the entrypoint */
+ if (next_image_info->pc)
+ return next_image_info;
+ else
+ return NULL;
+#endif
+}
+
+/*******************************************************************************
+ * Perform any BL31 specific platform actions. Here is an opportunity to copy
+ * parameters passed by the calling EL (S-EL1 in BL2 & S-EL3 in BL1) before they
+ * are lost (potentially). This needs to be done before the MMU is initialized
+ * so that the memory layout can be used while creating page tables. On the FVP
+ * we know that BL2 has populated the parameters in secure DRAM. So we just use
+ * the reference passed in 'from_bl2' instead of copying. The 'data' parameter
+ * is not used since all the information is contained in 'from_bl2'. Also, BL2
+ * has flushed this information to memory, so we are guaranteed to pick up good
+ * data
+ ******************************************************************************/
+void bl31_early_platform_setup(bl31_params_t *from_bl2,
+ void *plat_params_from_bl2)
+{
+
+
+ /* Initialize the console to provide early debug support */
+ console_init(SUNXI_UART0_BASE, UART0_CLK_IN_HZ, UART0_BAUDRATE);
+
+ /* Initialize the platform config for future decision making */
+ sunxi_config_setup();
+
+#if 0
+#if RESET_TO_BL31
+ /* There are no parameters from BL2 if BL31 is a reset vector */
+ assert(from_bl2 == NULL);
+ assert(plat_params_from_bl2 == NULL);
+
+ /*
+ * Do initial security configuration to allow DRAM/device access. On
+ * Base FVP only DRAM security is programmable (via TrustZone), but
+ * other platforms might have more programmable security devices
+ * present.
+ */
+ sunxi_security_setup();
+
+ /* Populate entry point information for BL3-2 and BL3-3 */
+ SET_PARAM_HEAD(&bl32_image_ep_info,
+ PARAM_EP,
+ VERSION_1,
+ 0);
+ SET_SECURITY_STATE(bl32_image_ep_info.h.attr, SECURE);
+ bl32_image_ep_info.pc = BL32_BASE;
+ bl32_image_ep_info.spsr = sunxi_get_spsr_for_bl32_entry();
+
+ SET_PARAM_HEAD(&bl33_image_ep_info,
+ PARAM_EP,
+ VERSION_1,
+ 0);
+ /*
+ * Tell BL31 where the non-trusted software image
+ * is located and the entry state information
+ */
+ bl33_image_ep_info.pc = plat_get_ns_image_entrypoint();
+ bl33_image_ep_info.spsr = sunxi_get_spsr_for_bl33_entry();
+ SET_SECURITY_STATE(bl33_image_ep_info.h.attr, NON_SECURE);
+
+#else
+ /* Check params passed from BL2 should not be NULL,
+ * We are not checking plat_params_from_bl2 as NULL as we are not
+ * using it on FVP
+ */
+ assert(from_bl2 != NULL);
+ assert(from_bl2->h.type == PARAM_BL31);
+ assert(from_bl2->h.version >= VERSION_1);
+ sunxi_security_setup();
+ bl2_to_bl31_params = from_bl2;
+ assert(((unsigned long)plat_params_from_bl2) == SUNXI_BL31_PLAT_PARAM_VAL);
+#endif
+#endif
+ /*
+ * Do initial security configuration to allow DRAM/device access. On
+ * Base FVP only DRAM security is programmable (via TrustZone), but
+ * other platforms might have more programmable security devices
+ * present.
+ */
+ sunxi_security_setup();
+ /*
+ * Tell BL31 where the non-trusted software image
+ * is located and the entry state information
+ */
+ bl33_image_ep_info.pc = plat_get_ns_image_entrypoint();
+ bl33_image_ep_info.spsr = sunxi_get_spsr_for_bl33_entry();
+ SET_SECURITY_STATE(bl33_image_ep_info.h.attr, NON_SECURE);
+
+
+
+}
+
+/*******************************************************************************
+ * Initialize the gic, configure the CLCD and zero out variables needed by the
+ * secondaries to boot up correctly.
+ ******************************************************************************/
+void bl31_platform_setup(void)
+{
+
+ //unsigned int reg_val;
+
+ /* Initialize the gic cpu and distributor interfaces */
+ sunxi_gic_init();
+#if 0
+
+ /*
+ * TODO: Configure the CLCD before handing control to
+ * linux. Need to see if a separate driver is needed
+ * instead.
+ */
+ mmio_write_32(VE_SYSREGS_BASE + V2M_SYS_CFGDATA, 0);
+ mmio_write_32(VE_SYSREGS_BASE + V2M_SYS_CFGCTRL,
+ (1ull << 31) | (1 << 30) | (7 << 20) | (0 << 16));
+
+ /* Enable and initialize the System level generic timer */
+ mmio_write_32(SYS_CNTCTL_BASE + CNTCR_OFF, CNTCR_FCREQ(0) | CNTCR_EN);
+
+ /* Allow access to the System counter timer module */
+ reg_val = (1 << CNTACR_RPCT_SHIFT) | (1 << CNTACR_RVCT_SHIFT);
+ reg_val |= (1 << CNTACR_RFRQ_SHIFT) | (1 << CNTACR_RVOFF_SHIFT);
+ reg_val |= (1 << CNTACR_RWVT_SHIFT) | (1 << CNTACR_RWPT_SHIFT);
+ mmio_write_32(SYS_TIMCTL_BASE + CNTACR_BASE(0), reg_val);
+ mmio_write_32(SYS_TIMCTL_BASE + CNTACR_BASE(1), reg_val);
+
+ reg_val = (1 << CNTNSAR_NS_SHIFT(0)) | (1 << CNTNSAR_NS_SHIFT(1));
+ mmio_write_32(SYS_TIMCTL_BASE + CNTNSAR, reg_val);
+#endif
+
+ /* Intialize the power controller */
+ //sunxi_pwrc_setup();
+
+ /* Topologies are best known to the platform. */
+ sunxi_setup_topology();
+
+}
+
+/*******************************************************************************
+ * 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 bl31_plat_arch_setup(void)
+{
+ //set smp bit before cache enable
+ platform_smp_init();
+#if 1
+ sunxi_configure_mmu_el3(BL31_RO_BASE,
+ (BL31_COHERENT_RAM_LIMIT - BL31_RO_BASE),
+ BL31_RO_BASE,
+ BL31_RO_LIMIT,
+ BL31_COHERENT_RAM_BASE,
+ BL31_COHERENT_RAM_LIMIT);
+#endif
+
+}
diff --git a/plat/sun50iw1p1/drivers/gpio/gpio.c b/plat/sun50iw1p1/drivers/gpio/gpio.c
new file mode 100644
index 0000000..f741041
--- /dev/null
+++ b/plat/sun50iw1p1/drivers/gpio/gpio.c
@@ -0,0 +1,228 @@
+/*
+**********************************************************************************************************************
+*
+* the Embedded Secure Bootloader System
+*
+*
+* Copyright(C), 2006-2014, Allwinnertech Co., Ltd.
+* All Rights Reserved
+*
+* File :
+*
+* By :
+*
+* Version : V2.00
+*
+* Date :
+*
+* Descript:
+**********************************************************************************************************************
+*/
+
+
+#include "../../sunxi_def.h"
+#include <gpio.h>
+
+#define GPIO_REG_READ(reg) mmio_read_32((reg))
+#define GPIO_REG_WRITE(reg, value) mmio_write_32((reg),(value))
+
+/*
+************************************************************************************************************
+*
+* normal_gpio_cfg
+*
+* 函数名称:
+*
+* 参数列表:
+*
+*
+*
+* 返回值 :
+*
+* 说明 :
+*
+*
+************************************************************************************************************
+*/
+int32_t boot_set_gpio(void *user_gpio_list, uint32_t group_count_max, int32_t set_gpio)
+{
+ normal_gpio_set_t *tmp_user_gpio_data, *gpio_list;
+ uint32_t first_port; //保存真正有效的GPIO的个数
+ uint32_t tmp_group_func_data;
+ uint32_t tmp_group_pull_data;
+ uint32_t tmp_group_dlevel_data;
+ uint32_t tmp_group_data_data;
+ uint32_t data_change = 0;
+ uint32_t tmp_group_func_addr, tmp_group_pull_addr;
+ uint32_t tmp_group_dlevel_addr, tmp_group_data_addr;
+ uint32_t port, port_num, port_num_func, port_num_pull;
+ uint32_t pre_port, pre_port_num_func;
+ uint32_t pre_port_num_pull;
+ int32_t i, tmp_val;
+
+
+ gpio_list = (normal_gpio_set_t *)user_gpio_list;
+
+ for(first_port = 0; first_port < group_count_max; first_port++)
+ {
+ tmp_user_gpio_data = gpio_list + first_port;
+ port = tmp_user_gpio_data->port; //读出端口数值
+ port_num = tmp_user_gpio_data->port_num; //读出端口中的某一个GPIO
+ if(!port)
+ {
+ continue;
+ }
+ port_num_func = (port_num >> 3);
+ port_num_pull = (port_num >> 4);
+
+ tmp_group_func_addr = PIO_REG_CFG(port, port_num_func); //更新功能寄存器地址
+ tmp_group_pull_addr = PIO_REG_PULL(port, port_num_pull); //更新pull寄存器
+ tmp_group_dlevel_addr = PIO_REG_DLEVEL(port, port_num_pull);//更新level寄存器
+ tmp_group_data_addr = PIO_REG_DATA(port); //更新data寄存器
+
+ tmp_group_func_data = GPIO_REG_READ(tmp_group_func_addr);
+ tmp_group_pull_data = GPIO_REG_READ(tmp_group_pull_addr);
+ tmp_group_dlevel_data = GPIO_REG_READ(tmp_group_dlevel_addr);
+ tmp_group_data_data = GPIO_REG_READ(tmp_group_data_addr);
+
+ pre_port = port;
+ pre_port_num_func = port_num_func;
+ pre_port_num_pull = port_num_pull;
+ //更新功能寄存器
+ tmp_val = (port_num - (port_num_func << 3)) << 2;
+ tmp_group_func_data &= ~(0x07 << tmp_val);
+ if(set_gpio)
+ {
+ tmp_group_func_data |= (tmp_user_gpio_data->mul_sel & 0x07) << tmp_val;
+ }
+ //根据pull的值决定是否更新pull寄存器
+ tmp_val = (port_num - (port_num_pull << 4)) << 1;
+ if(tmp_user_gpio_data->pull >= 0)
+ {
+ tmp_group_pull_data &= ~( 0x03 << tmp_val);
+ tmp_group_pull_data |= (tmp_user_gpio_data->pull & 0x03) << tmp_val;
+ }
+ //根据driver level的值决定是否更新driver level寄存器
+ if(tmp_user_gpio_data->drv_level >= 0)
+ {
+ tmp_group_dlevel_data &= ~( 0x03 << tmp_val);
+ tmp_group_dlevel_data |= (tmp_user_gpio_data->drv_level & 0x03) << tmp_val;
+ }
+ //根据用户输入,以及功能分配决定是否更新data寄存器
+ if(tmp_user_gpio_data->mul_sel == 1)
+ {
+ if(tmp_user_gpio_data->data >= 0)
+ {
+ tmp_val = tmp_user_gpio_data->data & 1;
+ tmp_group_data_data &= ~(1 << port_num);
+ tmp_group_data_data |= tmp_val << port_num;
+ data_change = 1;
+ }
+ }
+
+ break;
+ }
+ //检查是否有数据存在
+ if(first_port >= group_count_max)
+ {
+ return -1;
+ }
+ //保存用户数据
+ for(i = first_port + 1; i < group_count_max; i++)
+ {
+ tmp_user_gpio_data = gpio_list + i; //gpio_set依次指向用户的每个GPIO数组成员
+ port = tmp_user_gpio_data->port; //读出端口数值
+ port_num = tmp_user_gpio_data->port_num; //读出端口中的某一个GPIO
+ if(!port)
+ {
+ break;
+ }
+ port_num_func = (port_num >> 3);
+ port_num_pull = (port_num >> 4);
+
+ if((port_num_pull != pre_port_num_pull) || (port != pre_port)) //如果发现当前引脚的端口不一致,或者所在的pull寄存器不一致
+ {
+ GPIO_REG_WRITE(tmp_group_func_addr, tmp_group_func_data); //回写功能寄存器
+ GPIO_REG_WRITE(tmp_group_pull_addr, tmp_group_pull_data); //回写pull寄存器
+ GPIO_REG_WRITE(tmp_group_dlevel_addr, tmp_group_dlevel_data); //回写driver level寄存器
+ if(data_change)
+ {
+ data_change = 0;
+ GPIO_REG_WRITE(tmp_group_data_addr, tmp_group_data_data); //回写data寄存器
+ }
+
+ tmp_group_func_addr = PIO_REG_CFG(port, port_num_func); //更新功能寄存器地址
+ tmp_group_pull_addr = PIO_REG_PULL(port, port_num_pull); //更新pull寄存器
+ tmp_group_dlevel_addr = PIO_REG_DLEVEL(port, port_num_pull);//更新level寄存器
+ tmp_group_data_addr = PIO_REG_DATA(port); //更新data寄存器
+
+ tmp_group_func_data = GPIO_REG_READ(tmp_group_func_addr);
+ tmp_group_pull_data = GPIO_REG_READ(tmp_group_pull_addr);
+ tmp_group_dlevel_data = GPIO_REG_READ(tmp_group_dlevel_addr);
+ tmp_group_data_data = GPIO_REG_READ(tmp_group_data_addr);
+ }
+ else if(pre_port_num_func != port_num_func) //如果发现当前引脚的功能寄存器不一致
+ {
+ GPIO_REG_WRITE(tmp_group_func_addr, tmp_group_func_data); //则只回写功能寄存器
+ tmp_group_func_addr = PIO_REG_CFG(port, port_num_func); //更新功能寄存器地址
+
+ tmp_group_func_data = GPIO_REG_READ(tmp_group_func_addr);
+ }
+ //保存当前硬件寄存器数据
+ pre_port_num_pull = port_num_pull; //设置当前GPIO成为前一个GPIO
+ pre_port_num_func = port_num_func;
+ pre_port = port;
+
+ //更新功能寄存器
+ tmp_val = (port_num - (port_num_func << 3)) << 2;
+ if(tmp_user_gpio_data->mul_sel >= 0)
+ {
+ tmp_group_func_data &= ~( 0x07 << tmp_val);
+ if(set_gpio)
+ {
+ tmp_group_func_data |= (tmp_user_gpio_data->mul_sel & 0x07) << tmp_val;
+ }
+ }
+ //根据pull的值决定是否更新pull寄存器
+ tmp_val = (port_num - (port_num_pull << 4)) << 1;
+ if(tmp_user_gpio_data->pull >= 0)
+ {
+ tmp_group_pull_data &= ~( 0x03 << tmp_val);
+ tmp_group_pull_data |= (tmp_user_gpio_data->pull & 0x03) << tmp_val;
+ }
+ //根据driver level的值决定是否更新driver level寄存器
+ if(tmp_user_gpio_data->drv_level >= 0)
+ {
+ tmp_group_dlevel_data &= ~( 0x03 << tmp_val);
+ tmp_group_dlevel_data |= (tmp_user_gpio_data->drv_level & 0x03) << tmp_val;
+ }
+ //根据用户输入,以及功能分配决定是否更新data寄存器
+ if(tmp_user_gpio_data->mul_sel == 1)
+ {
+ if(tmp_user_gpio_data->data >= 0)
+ {
+ tmp_val = tmp_user_gpio_data->data & 1;
+ tmp_group_data_data &= ~(1 << port_num);
+ tmp_group_data_data |= tmp_val << port_num;
+ data_change = 1;
+ }
+ }
+ }
+ //for循环结束,如果存在还没有回写的寄存器,这里写回到硬件当中
+ if(tmp_group_func_addr) //只要更新过寄存器地址,就可以对硬件赋值
+ { //那么把所有的值全部回写到硬件寄存器
+ GPIO_REG_WRITE(tmp_group_func_addr, tmp_group_func_data); //回写功能寄存器
+ GPIO_REG_WRITE(tmp_group_pull_addr, tmp_group_pull_data); //回写pull寄存器
+ GPIO_REG_WRITE(tmp_group_dlevel_addr, tmp_group_dlevel_data); //回写driver level寄存器
+ if(data_change)
+ {
+ GPIO_REG_WRITE(tmp_group_data_addr, tmp_group_data_data); //回写data寄存器
+ }
+ }
+
+ return 0;
+}
+
+
+
+
diff --git a/plat/sun50iw1p1/drivers/uart/uart.c b/plat/sun50iw1p1/drivers/uart/uart.c
new file mode 100644
index 0000000..710957c
--- /dev/null
+++ b/plat/sun50iw1p1/drivers/uart/uart.c
@@ -0,0 +1,149 @@
+/*
+ * Copyright (c) 2013-2014, ARM Limited and Contributors. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * Neither the name of ARM nor the names of its contributors may be used
+ * to endorse or promote products derived from this software without specific
+ * prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <stdint.h>
+#include <mmio.h>
+#include <uart.h>
+#include <gpio.h>
+#include <ccmu.h>
+#if DEBUG
+#define thr rbr
+#define dll rbr
+#define dlh ier
+#define iir fcr
+
+static serial_hw_t *serial_ctrl_base = NULL;
+static uint32_t uart_lock = 1;
+#if 0
+normal_gpio_set_t uart_ctrl[2] =
+{
+ { 2, 8, 4, 1, 1, 0, {0}},//PB8: 4--RX
+ { 2, 9, 4, 1, 1, 0, {0}},//PB9: 4--TX
+};
+#endif
+
+void sunxi_serial_init(int uart_port, void *gpio_cfg, int gpio_max)
+{
+ uint32_t reg, i;
+ uint32_t uart_clk;
+
+ if( (uart_port < 0) ||(uart_port > 0) )
+ {
+ return ;
+ }
+ //reset
+ reg = mmio_read_32(CCMU_BUS_SOFT_RST_REG4);
+ reg &= ~(1<<(CCM_UART_PORT_OFFSET + uart_port));
+ mmio_write_32(CCMU_BUS_SOFT_RST_REG4,reg);
+ for( i = 0; i < 100; i++ );
+ reg |= (1<<(CCM_UART_PORT_OFFSET + uart_port));
+ mmio_write_32(CCMU_BUS_SOFT_RST_REG4,reg);
+ //gate
+ reg = mmio_read_32(CCMU_BUS_CLK_GATING_REG3);
+ reg &= ~(1<<(CCM_UART_PORT_OFFSET + uart_port));
+ mmio_write_32(CCMU_BUS_CLK_GATING_REG3,reg);
+ for( i = 0; i < 100; i++ );
+ reg |= (1<<(CCM_UART_PORT_OFFSET + uart_port));
+ mmio_write_32(CCMU_BUS_CLK_GATING_REG3,reg);
+
+ //gpio
+ //boot_set_gpio(gpio_cfg, gpio_max, 1); //boot set,so not need to set again
+ //uart init
+ serial_ctrl_base = (serial_hw_t *)(SUNXI_UART0_BASE + uart_port * CCM_UART_ADDR_OFFSET);
+ serial_ctrl_base->mcr = 0x3;
+ uart_clk = (24000000 + 8 * UART_BAUD)/(16 * UART_BAUD);
+ serial_ctrl_base->lcr |= 0x80;
+ serial_ctrl_base->dlh = uart_clk>>8;
+ serial_ctrl_base->dll = uart_clk&0xff;
+ serial_ctrl_base->lcr &= ~0x80;
+ serial_ctrl_base->lcr = ((PARITY&0x03)<<3) | ((STOP&0x01)<<2) | (DLEN&0x03);
+ serial_ctrl_base->fcr = 0x7;
+
+ uart_lock = 0;
+
+ return;
+}
+
+
+void sunxi_serial_exit(void)
+{
+ uart_lock = 1;
+}
+
+void sunxi_serial_putc (char c)
+{
+ if (uart_lock)
+ return;
+
+ while((serial_ctrl_base->lsr & ( 1 << 6 )) == 0);
+ serial_ctrl_base->thr = c;
+}
+
+
+char sunxi_serial_getc (void)
+{
+ if (uart_lock)
+ return 0;
+
+ while((serial_ctrl_base->lsr & 1) == 0);
+ return serial_ctrl_base->rbr;
+
+}
+
+int sunxi_serial_tstc (void)
+{
+ return serial_ctrl_base->lsr & 1;
+}
+#endif /* DEBUG */
+
+int console_init(unsigned long base_addr,
+ unsigned int uart_clk, unsigned int baud_rate)
+{
+ sunxi_serial_init(0,NULL,0);
+ return 0;
+}
+
+int console_exit()
+{
+ sunxi_serial_exit();
+ return 0;
+}
+
+int console_putc(int c)
+{
+ sunxi_serial_putc(c);
+ return 0;
+}
+
+int console_getc(void)
+{
+ return sunxi_serial_getc();
+}
+
diff --git a/plat/sun50iw1p1/gic_sunxi.h b/plat/sun50iw1p1/gic_sunxi.h
new file mode 100644
index 0000000..f52bde4
--- /dev/null
+++ b/plat/sun50iw1p1/gic_sunxi.h
@@ -0,0 +1,344 @@
+/*
+ * Copyright (c) 2014, ARM Limited and Contributors. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * Neither the name of ARM nor the names of its contributors may be used
+ * to endorse or promote products derived from this software without specific
+ * prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef __GIC_SUNXI_H_
+#define __GIC_SUNXI_H_
+
+
+#include "sunxi_def.h"
+/*irq num*/
+#define GIC_SRC_SPI(_n) (32 + (_n))
+#define AW_IRQ_UART0 GIC_SRC_SPI(0) /* 32 */
+#define AW_IRQ_UART1 GIC_SRC_SPI(1) /* 33 */
+#define AW_IRQ_UART2 GIC_SRC_SPI(2) /* 34 */
+#define AW_IRQ_UART3 GIC_SRC_SPI(3) /* 35 */
+#define AW_IRQ_UART4 GIC_SRC_SPI(4) /* 36 */
+
+#define AW_IRQ_TWI0 GIC_SRC_SPI(6) /* 38 */
+#define AW_IRQ_TWI1 GIC_SRC_SPI(7) /* 39 */
+#define AW_IRQ_TWI2 GIC_SRC_SPI(8) /* 40 */
+
+#define AW_IRQ_PBEINT GIC_SRC_SPI(11) /* 43 */
+#define AW_IRQ_OWA GIC_SRC_SPI(12) /* 44*/
+#define AW_IRQ_DAUDIO0 GIC_SRC_SPI(13) /* 45 */
+#define AW_IRQ_DAUDIO1 GIC_SRC_SPI(14) /* 46 */
+#define AW_IRQ_DAUDIO2 GIC_SRC_SPI(15) /* 47 */
+
+#define AW_IRQ_PG_EINT GIC_SRC_SPI(17) /* 49 */
+#define AW_IRQ_TIMER0 GIC_SRC_SPI(18) /* 50 */
+#define AW_IRQ_TIMER1 GIC_SRC_SPI(19) /* 51 */
+#define AW_IRQ_PH_EINT GIC_SRC_SPI(21) /* 53 */
+
+#define AW_IRQ_WATCHDOG GIC_SRC_SPI(25) /* 57*/
+#define AW_IRQ_NMI GIC_SRC_SPI(32) /* 64*/
+
+
+#define AW_IRQ_DMA GIC_SRC_SPI(50) /* 82 */
+#define AW_IRQ_HSTIMER GIC_SRC_SPI(51) /* 83 */
+#define AW_IRQ_SMC GIC_SRC_SPI(56) /* 88 */
+#define AW_IRQ_MMC0 GIC_SRC_SPI(60) /* 92 */
+#define AW_IRQ_MMC1 GIC_SRC_SPI(61) /* 93 */
+#define AW_IRQ_MMC2 GIC_SRC_SPI(62) /* 94 */
+#define AW_IRQ_SPI0 GIC_SRC_SPI(65) /* 97 */
+#define AW_IRQ_SPI1 GIC_SRC_SPI(66) /* 98 */
+#define AW_IRQ_NAND GIC_SRC_SPI(70) /* 102 */
+#define AW_IRQ_USB_OTG GIC_SRC_SPI(71) /* 103 */
+#define AW_IRQ_USB_EHCI0 GIC_SRC_SPI(72) /* 104*/
+#define AW_IRQ_USB_OHCI0 GIC_SRC_SPI(73) /* 105 */
+#define AW_IRQ_USB_EHCI1 GIC_SRC_SPI(74) /* 106 */
+#define AW_IRQ_USB_OHCI1 GIC_SRC_SPI(75) /* 107 */
+
+#define AW_IRQ_CE0 GIC_SRC_SPI(80) /* 112 */
+#define AW_IRQ_TS GIC_SRC_SPI(81) /* 113 */
+#define AW_IRQ_EMC GIC_SRC_SPI(82) /* 114 */
+#define AW_IRQ_SCR GIC_SRC_SPI(83) /* 115 */
+#define AW_IRQ_CSI GIC_SRC_SPI(84) /* 116 */
+#define AW_IRQ_CSI_CCI GIC_SRC_SPI(85) /* 117 */
+#define AW_IRQ_TCON0 GIC_SRC_SPI(86) /* 118 */
+#define AW_IRQ_TCON1 GIC_SRC_SPI(87) /* 119 */
+#define AW_IRQ_HDMI GIC_SRC_SPI(88) /* 120 */
+#define AW_IRQ_MIPI_DSI GIC_SRC_SPI(89) /* 121 */
+
+#define AW_IRQ_DIT GIC_SRC_SPI(93) /* 125 */
+#define AW_IRQ_CE1 GIC_SRC_SPI(94) /* 126 */
+#define AW_IRQ_DE GIC_SRC_SPI(95) /* 127 */
+#define AW_IRQ_ROT GIC_SRC_SPI(96) /* 128 */
+#define AW_IRQ_GPU_GP GIC_SRC_SPI(97) /* 129 */
+#define AW_IRQ_GPU_GPMMU GIC_SRC_SPI(98) /* 130 */
+#define AW_IRQ_GPU_PP0 GIC_SRC_SPI(99) /* 131 */
+#define AW_IRQ_GPU_PP0MMU GIC_SRC_SPI(100) /* 132 */
+#define AW_IRQ_GPU_PMU GIC_SRC_SPI(101) /* 133 */
+#define AW_IRQ_GPU_PP1 GIC_SRC_SPI(102) /* 134 */
+#define AW_IRQ_GPU_PPMMU1 GIC_SRC_SPI(103) /* 135 */
+
+#define AW_IRQ_CTI0 GIC_SRC_SPI(108) /* 140 */
+#define AW_IRQ_CTI1 GIC_SRC_SPI(109) /* 141 */
+#define AW_IRQ_CTI2 GIC_SRC_SPI(110) /* 142 */
+#define AW_IRQ_CTI3 GIC_SRC_SPI(111) /* 143 */
+#define AW_IRQ_COMMTX0 GIC_SRC_SPI(112) /* 144 */
+#define AW_IRQ_COMMTX1 GIC_SRC_SPI(113) /* 145 */
+#define AW_IRQ_COMMTX2 GIC_SRC_SPI(114) /* 146 */
+#define AW_IRQ_COMMTX3 GIC_SRC_SPI(115) /* 147 */
+#define AW_IRQ_COMMRX0 GIC_SRC_SPI(116) /* 148 */
+#define AW_IRQ_COMMRX1 GIC_SRC_SPI(117) /* 149 */
+#define AW_IRQ_COMMRX2 GIC_SRC_SPI(118) /* 150 */
+#define AW_IRQ_COMMRX3 GIC_SRC_SPI(119) /* 151 */
+#define AW_IRQ_PMU0 GIC_SRC_SPI(120) /* 152 */
+#define AW_IRQ_PMU1 GIC_SRC_SPI(121) /* 153 */
+#define AW_IRQ_PMU2 GIC_SRC_SPI(122) /* 154 */
+#define AW_IRQ_PMU3 GIC_SRC_SPI(123) /* 155 */
+#define AW_IRQ_AXI_ERROR GIC_SRC_SPI(124) /*156*/
+#define GIC_IRQ_NUM (AW_IRQ_AXI_ERROR + 1)
+/*irq num end*/
+
+
+
+/* GIC registers */
+#define GIC_DIST_CON (ARMA9_GIC_BASE + 0x0000)
+#define GIC_CON_TYPE (ARMA9_GIC_BASE + 0x0004)
+#define GIC_CON_IIDR (ARMA9_GIC_BASE + 0x0008)
+
+#define GIC_CON_IGRP(n) (ARMA9_GIC_BASE + 0x0080 + (n)*4)
+
+#define GIC_SET_EN(_n) (ARMA9_GIC_BASE + 0x100 + 4 * (_n))
+#define GIC_SET_EN0 GIC_SET_EN(0) // 0x100
+#define GIC_SET_EN1 GIC_SET_EN(1) // 0x104
+#define GIC_SET_EN2 GIC_SET_EN(2) // 0x108
+#define GIC_SET_EN3 GIC_SET_EN(3) // 0x10c
+#define GIC_SET_EN4 GIC_SET_EN(4) // 0x110
+
+#define GIC_CLR_EN(_n) (ARMA9_GIC_BASE + 0x180 + 4 * (_n))
+#define GIC_CLR_EN0 GIC_CLR_EN(0) // 0x180
+#define GIC_CLR_EN1 GIC_CLR_EN(1) // 0x184
+#define GIC_CLR_EN2 GIC_CLR_EN(2) // 0x188
+#define GIC_CLR_EN3 GIC_CLR_EN(3) // 0x18c
+#define GIC_CLR_EN4 GIC_CLR_EN(4) // 0x190
+
+#define GIC_PEND_SET(_n) (ARMA9_GIC_BASE + 0x200 + 4 * (_n))
+#define GIC_PEND_SET0 GIC_PEND_SET(0) // 0x200
+#define GIC_PEND_SET1 GIC_PEND_SET(1) // 0x204
+#define GIC_PEND_SET2 GIC_PEND_SET(2) // 0x208
+#define GIC_PEND_SET3 GIC_PEND_SET(3) // 0x20c
+#define GIC_PEND_SET4 GIC_PEND_SET(4) // 0x210
+
+#define GIC_PEND_CLR(_n) (ARMA9_GIC_BASE + 0x280 + 4 * (_n))
+#define GIC_PEND_CLR0 GIC_PEND_CLR(0) // 0x280
+#define GIC_PEND_CLR1 GIC_PEND_CLR(1) // 0x284
+#define GIC_PEND_CLR2 GIC_PEND_CLR(2) // 0x288
+#define GIC_PEND_CLR3 GIC_PEND_CLR(3) // 0x28c
+#define GIC_PEND_CLR4 GIC_PEND_CLR(4) // 0x290
+
+#define GIC_ACT_SET(_n) (ARMA9_GIC_BASE + 0x300 + 4 * (_n))
+#define GIC_ACT_SET0 GIC_ACT_SET(0) // 0x300
+#define GIC_ACT_SET1 GIC_ACT_SET(1) // 0x304
+#define GIC_ACT_SET2 GIC_ACT_SET(2) // 0x308
+#define GIC_ACT_SET3 GIC_ACT_SET(3) // 0x30c
+#define GIC_ACT_SET4 GIC_ACT_SET(4) // 0x310
+
+#define GIC_ACT_CLR(_n) (ARMA9_GIC_BASE + 0x380 + 4 * (_n))
+#define GIC_ACT_CLR0 GIC_ACT_CLR(0) // 0x380
+#define GIC_ACT_CLR1 GIC_ACT_CLR(1) // 0x384
+#define GIC_ACT_CLR2 GIC_ACT_CLR(2) // 0x388
+#define GIC_ACT_CLR3 GIC_ACT_CLR(3) // 0x38c
+#define GIC_ACT_CLR4 GIC_ACT_CLR(4) // 0x390
+
+#define GIC_SGI_PRIO(_n) (ARMA9_GIC_BASE + 0x400 + 4 * (_n))
+#define GIC_SGI_PRIO0 GIC_SGI_PRIO(0) // 0x400
+#define GIC_SGI_PRIO1 GIC_SGI_PRIO(1) // 0x404
+#define GIC_SGI_PRIO2 GIC_SGI_PRIO(2) // 0x408
+#define GIC_SGI_PRIO3 GIC_SGI_PRIO(3) // 0x40C
+
+#define GIC_PPI_PRIO(_n) (ARMA9_GIC_BASE + 0x410 + 4 * (_n))
+#define GIC_PPI_PRIO0 GIC_PPI_PRIO(0) // 0x410
+#define GIC_PPI_PRIO1 GIC_PPI_PRIO(1) // 0x414
+#define GIC_PPI_PRIO2 GIC_PPI_PRIO(2) // 0x418
+#define GIC_PPI_PRIO3 GIC_PPI_PRIO(3) // 0x41C
+
+#define GIC_SPI_PRIO(_n) (ARMA9_GIC_BASE + 0x420 + 4 * (_n))
+#define GIC_SPI_PRIO0 GIC_SPI_PRIO(0 ) // 0x420
+#define GIC_SPI_PRIO1 GIC_SPI_PRIO(1 ) // 0x424
+#define GIC_SPI_PRIO2 GIC_SPI_PRIO(2 ) // 0x428
+#define GIC_SPI_PRIO3 GIC_SPI_PRIO(3 ) // 0x42C
+#define GIC_SPI_PRIO4 GIC_SPI_PRIO(4 ) // 0x430
+#define GIC_SPI_PRIO5 GIC_SPI_PRIO(5 ) // 0x434
+#define GIC_SPI_PRIO6 GIC_SPI_PRIO(6 ) // 0x438
+#define GIC_SPI_PRIO7 GIC_SPI_PRIO(7 ) // 0x43C
+#define GIC_SPI_PRIO8 GIC_SPI_PRIO(8 ) // 0x440
+#define GIC_SPI_PRIO9 GIC_SPI_PRIO(9 ) // 0x444
+#define GIC_SPI_PRIO10 GIC_SPI_PRIO(10) // 0x448
+#define GIC_SPI_PRIO11 GIC_SPI_PRIO(11) // 0x44C
+#define GIC_SPI_PRIO12 GIC_SPI_PRIO(12) // 0x450
+#define GIC_SPI_PRIO13 GIC_SPI_PRIO(13) // 0x454
+#define GIC_SPI_PRIO14 GIC_SPI_PRIO(14) // 0x458
+#define GIC_SPI_PRIO15 GIC_SPI_PRIO(15) // 0x45C
+#define GIC_SPI_PRIO16 GIC_SPI_PRIO(16) // 0x460
+#define GIC_SPI_PRIO17 GIC_SPI_PRIO(17) // 0x464
+#define GIC_SPI_PRIO18 GIC_SPI_PRIO(18) // 0x468
+#define GIC_SPI_PRIO19 GIC_SPI_PRIO(19) // 0x46C
+#define GIC_SPI_PRIO20 GIC_SPI_PRIO(20) // 0x470
+#define GIC_SPI_PRIO21 GIC_SPI_PRIO(21) // 0x474
+#define GIC_SPI_PRIO22 GIC_SPI_PRIO(22) // 0x478
+#define GIC_SPI_PRIO23 GIC_SPI_PRIO(23) // 0x47C
+#define GIC_SPI_PRIO24 GIC_SPI_PRIO(24) // 0x480
+#define GIC_SPI_PRIO25 GIC_SPI_PRIO(25) // 0x484
+#define GIC_SPI_PRIO26 GIC_SPI_PRIO(26) // 0x488
+#define GIC_SPI_PRIO27 GIC_SPI_PRIO(27) // 0x48C
+#define GIC_SPI_PRIO28 GIC_SPI_PRIO(28) // 0x490
+#define GIC_SPI_PRIO29 GIC_SPI_PRIO(29) // 0x494
+#define GIC_SPI_PRIO30 GIC_SPI_PRIO(30) // 0x498
+#define GIC_SPI_PRIO31 GIC_SPI_PRIO(31) // 0x49C
+
+#define GIC_SGI_PROC_TARG(_n) (ARMA9_GIC_BASE + 0x800 + 4 * (_n))
+#define GIC_SGI_PROC_TARG0 GIC_SGI_PROC_TARG(0) // 0x800
+#define GIC_SGI_PROC_TARG1 GIC_SGI_PROC_TARG(1) // 0x804
+#define GIC_SGI_PROC_TARG2 GIC_SGI_PROC_TARG(2) // 0x808
+#define GIC_SGI_PROC_TARG3 GIC_SGI_PROC_TARG(3) // 0x80C
+
+#define GIC_PPI_PROC_TARG(_n) (ARMA9_GIC_BASE + 0x810 + 4 * (_n))
+#define GIC_PPI_PROC_TARG0 GIC_PPI_PROC_TARG(0) // 0x810
+#define GIC_PPI_PROC_TARG1 GIC_PPI_PROC_TARG(1) // 0x814
+#define GIC_PPI_PROC_TARG2 GIC_PPI_PROC_TARG(2) // 0x818
+#define GIC_PPI_PROC_TARG3 GIC_PPI_PROC_TARG(3) // 0x81C
+
+#define GIC_SPI_PROC_TARG(_n) (ARMA9_GIC_BASE + 0x820 + 4 * (_n))
+#define GIC_SPI_PROC_TARG0 GIC_SPI_PROC_TARG(0 ) // 0x820
+#define GIC_SPI_PROC_TARG1 GIC_SPI_PROC_TARG(1 ) // 0x824
+#define GIC_SPI_PROC_TARG2 GIC_SPI_PROC_TARG(2 ) // 0x828
+#define GIC_SPI_PROC_TARG3 GIC_SPI_PROC_TARG(3 ) // 0x82C
+#define GIC_SPI_PROC_TARG4 GIC_SPI_PROC_TARG(4 ) // 0x830
+#define GIC_SPI_PROC_TARG5 GIC_SPI_PROC_TARG(5 ) // 0x834
+#define GIC_SPI_PROC_TARG6 GIC_SPI_PROC_TARG(6 ) // 0x838
+#define GIC_SPI_PROC_TARG7 GIC_SPI_PROC_TARG(7 ) // 0x83C
+#define GIC_SPI_PROC_TARG8 GIC_SPI_PROC_TARG(8 ) // 0x840
+#define GIC_SPI_PROC_TARG9 GIC_SPI_PROC_TARG(9 ) // 0x844
+#define GIC_SPI_PROC_TARG10 GIC_SPI_PROC_TARG(10) // 0x848
+#define GIC_SPI_PROC_TARG11 GIC_SPI_PROC_TARG(11) // 0x84C
+#define GIC_SPI_PROC_TARG12 GIC_SPI_PROC_TARG(12) // 0x850
+#define GIC_SPI_PROC_TARG13 GIC_SPI_PROC_TARG(13) // 0x854
+#define GIC_SPI_PROC_TARG14 GIC_SPI_PROC_TARG(14) // 0x858
+#define GIC_SPI_PROC_TARG15 GIC_SPI_PROC_TARG(15) // 0x85C
+#define GIC_SPI_PROC_TARG16 GIC_SPI_PROC_TARG(16) // 0x860
+#define GIC_SPI_PROC_TARG17 GIC_SPI_PROC_TARG(17) // 0x864
+#define GIC_SPI_PROC_TARG18 GIC_SPI_PROC_TARG(18) // 0x868
+#define GIC_SPI_PROC_TARG19 GIC_SPI_PROC_TARG(19) // 0x86C
+#define GIC_SPI_PROC_TARG20 GIC_SPI_PROC_TARG(20) // 0x870
+#define GIC_SPI_PROC_TARG21 GIC_SPI_PROC_TARG(21) // 0x874
+#define GIC_SPI_PROC_TARG22 GIC_SPI_PROC_TARG(22) // 0x878
+#define GIC_SPI_PROC_TARG23 GIC_SPI_PROC_TARG(23) // 0x87C
+#define GIC_SPI_PROC_TARG24 GIC_SPI_PROC_TARG(24) // 0x880
+#define GIC_SPI_PROC_TARG25 GIC_SPI_PROC_TARG(25) // 0x884
+#define GIC_SPI_PROC_TARG26 GIC_SPI_PROC_TARG(26) // 0x888
+#define GIC_SPI_PROC_TARG27 GIC_SPI_PROC_TARG(27) // 0x88C
+#define GIC_SPI_PROC_TARG28 GIC_SPI_PROC_TARG(28) // 0x890
+#define GIC_SPI_PROC_TARG29 GIC_SPI_PROC_TARG(29) // 0x894
+#define GIC_SPI_PROC_TARG30 GIC_SPI_PROC_TARG(30) // 0x898
+#define GIC_SPI_PROC_TARG31 GIC_SPI_PROC_TARG(31) // 0x89C
+
+#define GIC_IRQ_MOD_CFG(_n) (ARMA9_GIC_BASE + 0xc00 + 4 * (_n))
+#define GIC_IRQ_MOD_CFG0 GIC_IRQ_MOD_CFG(0) // 0xc00 - SGI
+#define GIC_IRQ_MOD_CFG1 GIC_IRQ_MOD_CFG(1) // 0xc04 - PPI
+#define GIC_IRQ_MOD_CFG2 GIC_IRQ_MOD_CFG(2) // 0xc08 - SPI0 ~ 15
+#define GIC_IRQ_MOD_CFG3 GIC_IRQ_MOD_CFG(3) // 0xc0C - SPI16 ~ 31
+#define GIC_IRQ_MOD_CFG4 GIC_IRQ_MOD_CFG(4) // 0xc10 - SPI32 ~ 47
+#define GIC_IRQ_MOD_CFG5 GIC_IRQ_MOD_CFG(5) // 0xc14 - SPI48 ~ 63
+#define GIC_IRQ_MOD_CFG6 GIC_IRQ_MOD_CFG(6) // 0xc18 - SPI64 ~ 79
+#define GIC_IRQ_MOD_CFG7 GIC_IRQ_MOD_CFG(7) // 0xc1C - SPI80 ~ 95
+#define GIC_IRQ_MOD_CFG8 GIC_IRQ_MOD_CFG(8) // 0xc20 - SPI96 ~ 111
+#define GIC_IRQ_MOD_CFG9 GIC_IRQ_MOD_CFG(9) // 0xc24 - SPI112 ~ 127
+
+#define GIC_SOFT_IRQ_GEN (ARMA9_GIC_BASE + 0xf00) // 0xf00
+#define GIC_SGI_PEND_SET(_n) (ARMA9_GIC_BASE + 0xf10 + 4 * (_n))
+#define GIC_SGI_PEND_SET0 GIC_SGI_PEND_SET(0) // 0xf10
+#define GIC_SGI_PEND_SET1 GIC_SGI_PEND_SET(1) // 0xf14
+#define GIC_SGI_PEND_SET2 GIC_SGI_PEND_SET(2) // 0xf18
+#define GIC_SGI_PEND_SET3 GIC_SGI_PEND_SET(3) // 0xf1C
+#define GIC_SGI_PEND_CLR(_n) (ARMA9_GIC_BASE + 0xf10 + 4 * (_n))
+#define GIC_SGI_PEND_CLR0 GIC_SGI_PEND_CLR(0) // 0xf20
+#define GIC_SGI_PEND_CLR1 GIC_SGI_PEND_CLR(1) // 0xf24
+#define GIC_SGI_PEND_CLR2 GIC_SGI_PEND_CLR(2) // 0xf28
+#define GIC_SGI_PEND_CLR3 GIC_SGI_PEND_CLR(3) // 0xf2C
+
+
+#define GIC_CPU_IF_CTRL (ARMA9_CPUIF_BASE + 0x000) // 0x8000
+#define GIC_INT_PRIO_MASK (ARMA9_CPUIF_BASE + 0x004) // 0x8004
+#define GIC_BINARY_POINT (ARMA9_CPUIF_BASE + 0x008) // 0x8008
+#define GIC_INT_ACK_REG (ARMA9_CPUIF_BASE + 0x00c) // 0x800c
+#define GIC_END_INT_REG (ARMA9_CPUIF_BASE + 0x010) // 0x8010
+#define GIC_RUNNING_PRIO (ARMA9_CPUIF_BASE + 0x014) // 0x8014
+#define GIC_HIGHEST_PENDINT (ARMA9_CPUIF_BASE + 0x018) // 0x8018
+#define GIC_DEACT_INT_REG (ARMA9_CPUIF_BASE + 0x1000)// 0x1000
+#define GIC_AIAR_REG (ARMA9_CPUIF_BASE + 0x020) // 0x8020
+#define GIC_AEOI_REG (ARMA9_CPUIF_BASE + 0x024) // 0x8024
+#define GIC_AHIGHEST_PENDINT (ARMA9_CPUIF_BASE + 0x028) // 0x8028
+
+
+/* gic source list */
+/* software generated interrupt */
+#define GIC_SRC_SGI(_n) (_n)
+#define GIC_SRC_SGI0 GIC_SRC_SGI(0 ) // (0 )
+#define GIC_SRC_SGI1 GIC_SRC_SGI(1 ) // (1 )
+#define GIC_SRC_SGI2 GIC_SRC_SGI(2 ) // (2 )
+#define GIC_SRC_SGI3 GIC_SRC_SGI(3 ) // (3 )
+#define GIC_SRC_SGI4 GIC_SRC_SGI(4 ) // (4 )
+#define GIC_SRC_SGI5 GIC_SRC_SGI(5 ) // (5 )
+#define GIC_SRC_SGI6 GIC_SRC_SGI(6 ) // (6 )
+#define GIC_SRC_SGI7 GIC_SRC_SGI(7 ) // (7 )
+#define GIC_SRC_SGI8 GIC_SRC_SGI(8 ) // (8 )
+#define GIC_SRC_SGI9 GIC_SRC_SGI(9 ) // (9 )
+#define GIC_SRC_SGI10 GIC_SRC_SGI(10) // (10)
+#define GIC_SRC_SGI11 GIC_SRC_SGI(11) // (11)
+#define GIC_SRC_SGI12 GIC_SRC_SGI(12) // (12)
+#define GIC_SRC_SGI13 GIC_SRC_SGI(13) // (13)
+#define GIC_SRC_SGI14 GIC_SRC_SGI(14) // (14)
+#define GIC_SRC_SGI15 GIC_SRC_SGI(15) // (15)
+/* private peripheral interrupt */
+#define GIC_SRC_PPI(_n) (16 + (_n))
+#define GIC_SRC_PPI0 GIC_SRC_PPI(0 ) // (16)
+#define GIC_SRC_PPI1 GIC_SRC_PPI(1 ) // (17)
+#define GIC_SRC_PPI2 GIC_SRC_PPI(2 ) // (18)
+#define GIC_SRC_PPI3 GIC_SRC_PPI(3 ) // (19)
+#define GIC_SRC_PPI4 GIC_SRC_PPI(4 ) // (20)
+#define GIC_SRC_PPI5 GIC_SRC_PPI(5 ) // (21)
+#define GIC_SRC_PPI6 GIC_SRC_PPI(6 ) // (22)
+#define GIC_SRC_PPI7 GIC_SRC_PPI(7 ) // (23)
+#define GIC_SRC_PPI8 GIC_SRC_PPI(8 ) // (24)
+#define GIC_SRC_PPI9 GIC_SRC_PPI(9 ) // (25)
+#define GIC_SRC_PPI10 GIC_SRC_PPI(10) // (26)
+#define GIC_SRC_PPI11 GIC_SRC_PPI(11) // (27)
+#define GIC_SRC_PPI12 GIC_SRC_PPI(12) // (28)
+#define GIC_SRC_PPI13 GIC_SRC_PPI(13) // (29)
+#define GIC_SRC_PPI14 GIC_SRC_PPI(14) // (30)
+#define GIC_SRC_PPI15 GIC_SRC_PPI(15) // (31)
+/* external peripheral interrupt */
+#define GIC_SRC_SPI(_n) (32 + (_n))
+
+
+#endif
+
diff --git a/plat/sun50iw1p1/include/arisc.h b/plat/sun50iw1p1/include/arisc.h
new file mode 100644
index 0000000..00384f5
--- /dev/null
+++ b/plat/sun50iw1p1/include/arisc.h
@@ -0,0 +1,789 @@
+/*
+ * include/linux/arisc/arisc.h
+ *
+ * Copyright 2012 (c) Allwinner.
+ * superm (superm@allwinnertech.com)
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ */
+
+#ifndef __ASM_ARCH_ARISC_H
+#define __ASM_ARCH_ARISC_H
+
+/* the base of messages */
+#define ARISC_MESSAGE_BASE (0x10)
+
+/* standby commands */
+#define ARISC_SSTANDBY_ENTER_REQ (ARISC_MESSAGE_BASE + 0x00) /* request to enter (ac327 to arisc) */
+#define ARISC_SSTANDBY_RESTORE_NOTIFY (ARISC_MESSAGE_BASE + 0x01) /* restore finished (ac327 to arisc) */
+#define ARISC_NSTANDBY_ENTER_REQ (ARISC_MESSAGE_BASE + 0x02) /* request to enter (ac327 to arisc) */
+#define ARISC_NSTANDBY_WAKEUP_NOTIFY (ARISC_MESSAGE_BASE + 0x03) /* wakeup notify (arisc to ac327) */
+#define ARISC_NSTANDBY_RESTORE_REQ (ARISC_MESSAGE_BASE + 0x04) /* request to restore (ac327 to arisc) */
+#define ARISC_NSTANDBY_RESTORE_COMPLETE (ARISC_MESSAGE_BASE + 0x05) /* arisc restore complete (arisc to ac327) */
+#define ARISC_ESSTANDBY_ENTER_REQ (ARISC_MESSAGE_BASE + 0x06) /* request to enter (ac327 to arisc) */
+#define ARISC_TSTANDBY_ENTER_REQ (ARISC_MESSAGE_BASE + 0x07) /* request to enter (ac327 to arisc) */
+#define ARISC_TSTANDBY_RESTORE_NOTIFY (ARISC_MESSAGE_BASE + 0x08) /* restore finished (ac327 to arisc) */
+#define ARISC_FAKE_POWER_OFF_REQ (ARISC_MESSAGE_BASE + 0x09) /* request to enter (ac327 to arisc) */
+#define ARISC_CPUIDLE_ENTER_REQ (ARISC_MESSAGE_BASE + 0x0a) /* request to enter (ac327 to arisc) */
+#define ARISC_STANDBY_INFO_REQ (ARISC_MESSAGE_BASE + 0x10) /* request sst info (ac327 to arisc) */
+#define ARISC_CPUIDLE_CFG_REQ (ARISC_MESSAGE_BASE + 0x11) /* request to config (ac327 to arisc) */
+#define ARISC_CPU_OP_REQ (ARISC_MESSAGE_BASE + 0x12) /* cpu operations (ac327 to arisc) */
+#define ARISC_QUERY_WAKEUP_SRC_REQ (ARISC_MESSAGE_BASE + 0x13) /* query wakeup source (ac327 to arisc) */
+#define ARISC_SYS_OP_REQ (ARISC_MESSAGE_BASE + 0x14) /* system operations (ac327 to arisc) */
+
+/* dvfs commands */
+#define ARISC_CPUX_DVFS_REQ (ARISC_MESSAGE_BASE + 0x20) /* request dvfs (ac327 to arisc) */
+#define ARISC_CPUX_DVFS_CFG_VF_REQ (ARISC_MESSAGE_BASE + 0x21) /* request config dvfs v-f table(ac327 to arisc) */
+
+/* pmu commands */
+#define ARISC_AXP_INT_COMING_NOTIFY (ARISC_MESSAGE_BASE + 0x40) /* interrupt coming notify(arisc to ac327) */
+#define ARISC_AXP_DISABLE_IRQ (ARISC_MESSAGE_BASE + 0x41) /* disable axp irq of arisc */
+#define ARISC_AXP_ENABLE_IRQ (ARISC_MESSAGE_BASE + 0x42) /* enable axp irq of arisc */
+#define ARISC_AXP_GET_CHIP_ID (ARISC_MESSAGE_BASE + 0x43) /* axp get chip id */
+#define ARISC_AXP_SET_PARAS (ARISC_MESSAGE_BASE + 0x44) /* config axp parameters (ac327 to arisc) */
+#define ARISC_SET_PMU_VOLT (ARISC_MESSAGE_BASE + 0x45) /* set pmu volt (ac327 to arisc) */
+#define ARISC_GET_PMU_VOLT (ARISC_MESSAGE_BASE + 0x46) /* get pmu volt (ac327 to arisc) */
+#define ARISC_SET_LED_BLN (ARISC_MESSAGE_BASE + 0x47) /* set led bln (ac327 to arisc) */
+#define ARISC_AXP_REBOOT (ARISC_MESSAGE_BASE + 0x48) /* reboot system for no pmu protocols */
+#define ARISC_SET_PWR_TREE (ARISC_MESSAGE_BASE + 0x49) /* set power tree (ac327 to arisc) */
+#define ARISC_CLR_NMI_STATUS (ARISC_MESSAGE_BASE + 0x4a) /* clear nmi status (ac327 to arisc) */
+#define ARISC_SET_NMI_TRIGGER (ARISC_MESSAGE_BASE + 0x4b) /* set nmi tigger (ac327 to arisc) */
+
+/* set arisc debug commands */
+#define ARISC_SET_DEBUG_LEVEL (ARISC_MESSAGE_BASE + 0x50) /* set arisc debug level (ac327 to arisc) */
+#define ARISC_MESSAGE_LOOPBACK (ARISC_MESSAGE_BASE + 0x51) /* loopback message (ac327 to arisc) */
+#define ARISC_SET_UART_BAUDRATE (ARISC_MESSAGE_BASE + 0x52) /* set uart baudrate (ac327 to arisc) */
+#define ARISC_SET_DRAM_PARAS (ARISC_MESSAGE_BASE + 0x53) /* config dram parameter (ac327 to arisc) */
+#define ARISC_SET_DEBUG_DRAM_CRC_PARAS (ARISC_MESSAGE_BASE + 0x54) /* config dram crc parameters (ac327 to arisc) */
+#define ARISC_SET_IR_PARAS (ARISC_MESSAGE_BASE + 0x55) /* config ir parameter (ac327 to arisc) */
+#define ARISC_REPORT_ERR_INFO (ARISC_MESSAGE_BASE + 0x56) /* report arisc error info (arisc to ac327) */
+#define ARISC_SET_PARAS (ARISC_MESSAGE_BASE + 0x57) /* set paras (arisc to ac327) */
+
+/* audio commands */
+#define ARISC_AUDIO_START (ARISC_MESSAGE_BASE + 0x60) /* audio start play/capture(ac327 to arisc) */
+#define ARISC_AUDIO_STOP (ARISC_MESSAGE_BASE + 0x61) /* audio stop play/capture(ac327 to arisc) */
+#define ARISC_AUDIO_SET_BUF_PER_PARAS (ARISC_MESSAGE_BASE + 0x62) /* set audio buffer and peroid paras(ac327 to arisc) */
+#define ARISC_AUDIO_GET_POSITION (ARISC_MESSAGE_BASE + 0x63) /* get audio buffer position(ac327 to arisc) */
+#define ARISC_AUDIO_SET_TDM_PARAS (ARISC_MESSAGE_BASE + 0x64) /* set audio tdm parameters(ac327 to arisc) */
+#define ARISC_AUDIO_PERDONE_NOTIFY (ARISC_MESSAGE_BASE + 0x65) /* audio period done notify(arisc to ac327) */
+#define ARISC_AUDIO_ADD_PERIOD (ARISC_MESSAGE_BASE + 0x66) /* audio period done notify(arisc to ac327) */
+
+/* rsb commands */
+#define ARISC_RSB_READ_BLOCK_DATA (ARISC_MESSAGE_BASE + 0x70) /* rsb read block data (ac327 to arisc) */
+#define ARISC_RSB_WRITE_BLOCK_DATA (ARISC_MESSAGE_BASE + 0x71) /* rsb write block data (ac327 to arisc) */
+#define ARISC_RSB_BITS_OPS_SYNC (ARISC_MESSAGE_BASE + 0x72) /* rsb clear bits sync (ac327 to arisc) */
+#define ARISC_RSB_SET_INTERFACE_MODE (ARISC_MESSAGE_BASE + 0x73) /* rsb set interface mode (ac327 to arisc) */
+#define ARISC_RSB_SET_RTSADDR (ARISC_MESSAGE_BASE + 0x74) /* rsb set runtime slave addr (ac327 to arisc) */
+
+/* arisc initialize state notify commands */
+#define ARISC_STARTUP_NOTIFY (ARISC_MESSAGE_BASE + 0x80) /* arisc init state notify(arisc to ac327) */
+
+
+/* the base of ARM SVC ARISC */
+#define ARM_SVC_ARISC_BASE (0xc0000000)
+
+/* standby commands */
+#define ARM_SVC_ARISC_SSTANDBY_ENTER_REQ (ARM_SVC_ARISC_BASE + ARISC_SSTANDBY_ENTER_REQ) /* request to enter (ac327 to arisc) */
+#define ARM_SVC_ARISC_SSTANDBY_RESTORE_NOTIFY (ARM_SVC_ARISC_BASE + ARISC_SSTANDBY_RESTORE_NOTIFY) /* restore finished (ac327 to arisc) */
+#define ARM_SVC_ARISC_NSTANDBY_ENTER_REQ (ARM_SVC_ARISC_BASE + ARISC_NSTANDBY_ENTER_REQ) /* request to enter (ac327 to arisc) */
+#define ARM_SVC_ARISC_NSTANDBY_WAKEUP_NOTIFY (ARM_SVC_ARISC_BASE + ARISC_NSTANDBY_WAKEUP_NOTIFY) /* wakeup notify (arisc to ac327) */
+#define ARM_SVC_ARISC_NSTANDBY_RESTORE_REQ (ARM_SVC_ARISC_BASE + ARISC_NSTANDBY_RESTORE_REQ) /* request to restore (ac327 to arisc) */
+#define ARM_SVC_ARISC_NSTANDBY_RESTORE_COMPLETE (ARM_SVC_ARISC_BASE + ARISC_NSTANDBY_RESTORE_COMPLETE) /* arisc restore complete (arisc to ac327) */
+#define ARM_SVC_ARISC_ESSTANDBY_ENTER_REQ (ARM_SVC_ARISC_BASE + ARISC_ESSTANDBY_ENTER_REQ) /* request to enter (ac327 to arisc) */
+#define ARM_SVC_ARISC_TSTANDBY_ENTER_REQ (ARM_SVC_ARISC_BASE + ARISC_TSTANDBY_ENTER_REQ) /* request to enter (ac327 to arisc) */
+#define ARM_SVC_ARISC_TSTANDBY_RESTORE_NOTIFY (ARM_SVC_ARISC_BASE + ARISC_TSTANDBY_RESTORE_NOTIFY) /* restore finished (ac327 to arisc) */
+#define ARM_SVC_ARISC_FAKE_POWER_OFF_REQ (ARM_SVC_ARISC_BASE + ARISC_FAKE_POWER_OFF_REQ) /* request to enter (ac327 to arisc) */
+#define ARM_SVC_ARISC_CPUIDLE_ENTER_REQ (ARM_SVC_ARISC_BASE + ARISC_CPUIDLE_ENTER_REQ) /* request to enter (ac327 to arisc) */
+#define ARM_SVC_ARISC_STANDBY_INFO_REQ (ARM_SVC_ARISC_BASE + ARISC_STANDBY_INFO_REQ) /* request sst info (ac327 to arisc) */
+#define ARM_SVC_ARISC_CPUIDLE_CFG_REQ (ARM_SVC_ARISC_BASE + ARISC_CPUIDLE_CFG_REQ) /* request to config (ac327 to arisc) */
+#define ARM_SVC_ARISC_CPU_OP_REQ (ARM_SVC_ARISC_BASE + ARISC_CPU_OP_REQ) /* cpu operations (ac327 to arisc) */
+#define ARM_SVC_ARISC_QUERY_WAKEUP_SRC_REQ (ARM_SVC_ARISC_BASE + ARISC_QUERY_WAKEUP_SRC_REQ) /* query wakeup source (ac327 to arisc) */
+#define ARM_SVC_ARISC_SYS_OP_REQ (ARM_SVC_ARISC_BASE + ARISC_SYS_OP_REQ) /* system operations (ac327 to arisc) */
+
+/* dvfs commands */
+#define ARM_SVC_ARISC_CPUX_DVFS_REQ (ARM_SVC_ARISC_BASE + ARISC_CPUX_DVFS_REQ) /* request dvfs (ac327 to arisc) */
+#define ARM_SVC_ARISC_CPUX_DVFS_CFG_VF_REQ (ARM_SVC_ARISC_BASE + ARISC_CPUX_DVFS_CFG_VF_REQ) /* request config dvfs v-f table(ac327 to arisc) */
+
+/* pmu commands */
+#define ARM_SVC_ARISC_AXP_INT_COMING_NOTIFY (ARM_SVC_ARISC_BASE + ARISC_AXP_INT_COMING_NOTIFY) /* interrupt coming notify(arisc to ac327) */
+#define ARM_SVC_ARISC_AXP_DISABLE_IRQ (ARM_SVC_ARISC_BASE + ARISC_AXP_DISABLE_IRQ) /* disable axp irq of arisc */
+#define ARM_SVC_ARISC_AXP_ENABLE_IRQ (ARM_SVC_ARISC_BASE + ARISC_AXP_ENABLE_IRQ) /* enable axp irq of arisc */
+#define ARM_SVC_ARISC_AXP_GET_CHIP_ID (ARM_SVC_ARISC_BASE + ARISC_AXP_GET_CHIP_ID) /* axp get chip id */
+#define ARM_SVC_ARISC_AXP_SET_PARAS (ARM_SVC_ARISC_BASE + ARISC_AXP_SET_PARAS) /* config axp parameters (ac327 to arisc) */
+#define ARM_SVC_ARISC_SET_PMU_VOLT (ARM_SVC_ARISC_BASE + ARISC_SET_PMU_VOLT) /* set pmu volt (ac327 to arisc) */
+#define ARM_SVC_ARISC_GET_PMU_VOLT (ARM_SVC_ARISC_BASE + ARISC_GET_PMU_VOLT) /* get pmu volt (ac327 to arisc) */
+#define ARM_SVC_ARISC_SET_LED_BLN (ARM_SVC_ARISC_BASE + ARISC_SET_LED_BLN) /* set led bln (ac327 to arisc) */
+#define ARM_SVC_ARISC_AXP_REBOOT (ARM_SVC_ARISC_BASE + ARISC_AXP_REBOOT) /* reboot system for no pmu protocols */
+#define ARM_SVC_ARISC_SET_PWR_TREE (ARM_SVC_ARISC_BASE + ARISC_SET_PWR_TREE) /* set power tree (ac327 to arisc) */
+#define ARM_SVC_ARISC_CLR_NMI_STATUS (ARM_SVC_ARISC_BASE + ARISC_CLR_NMI_STATUS) /* clear nmi status (ac327 to arisc) */
+#define ARM_SVC_ARISC_SET_NMI_TRIGGER (ARM_SVC_ARISC_BASE + ARISC_SET_NMI_TRIGGER) /* set nmi tigger (ac327 to arisc) */
+
+/* set arisc debug commands */
+#define ARM_SVC_ARISC_SET_DEBUG_LEVEL (ARM_SVC_ARISC_BASE + ARISC_SET_DEBUG_LEVEL) /* set arisc debug level (ac327 to arisc) */
+#define ARM_SVC_ARISC_MESSAGE_LOOPBACK (ARM_SVC_ARISC_BASE + ARISC_MESSAGE_LOOPBACK) /* loopback message (ac327 to arisc) */
+#define ARM_SVC_ARISC_SET_UART_BAUDRATE (ARM_SVC_ARISC_BASE + ARISC_SET_UART_BAUDRATE) /* set uart baudrate (ac327 to arisc) */
+#define ARM_SVC_ARISC_SET_DRAM_PARAS (ARM_SVC_ARISC_BASE + ARISC_SET_DRAM_PARAS) /* config dram parameter (ac327 to arisc) */
+#define ARM_SVC_ARISC_SET_DEBUG_DRAM_CRC_PARAS (ARM_SVC_ARISC_BASE + ARISC_SET_DEBUG_DRAM_CRC_PARAS) /* config dram crc parameters (ac327 to arisc) */
+#define ARM_SVC_ARISC_SET_IR_PARAS (ARM_SVC_ARISC_BASE + ARISC_SET_IR_PARAS) /* config ir parameter (ac327 to arisc) */
+#define ARM_SVC_ARISC_REPORT_ERR_INFO (ARM_SVC_ARISC_BASE + ARISC_REPORT_ERR_INFO) /* report arisc error info (arisc to ac327) */
+#define ARM_SVC_ARISC_SET_PARAS (ARM_SVC_ARISC_BASE + ARISC_SET_PARAS) /* set paras (arisc to ac327) */
+
+/* audio commands */
+#define ARM_SVC_ARISC_AUDIO_START (ARM_SVC_ARISC_BASE + ARISC_AUDIO_START) /* audio start play/capture(ac327 to arisc) */
+#define ARM_SVC_ARISC_AUDIO_STOP (ARM_SVC_ARISC_BASE + ARISC_AUDIO_STOP) /* audio stop play/capture(ac327 to arisc) */
+#define ARM_SVC_ARISC_AUDIO_SET_BUF_PER_PARAS (ARM_SVC_ARISC_BASE + ARISC_AUDIO_SET_BUF_PER_PARAS) /* set audio buffer and peroid paras(ac327 to arisc) */
+#define ARM_SVC_ARISC_AUDIO_GET_POSITION (ARM_SVC_ARISC_BASE + ARISC_AUDIO_GET_POSITION) /* get audio buffer position(ac327 to arisc) */
+#define ARM_SVC_ARISC_AUDIO_SET_TDM_PARAS (ARM_SVC_ARISC_BASE + ARISC_AUDIO_SET_TDM_PARAS) /* set audio tdm parameters(ac327 to arisc) */
+#define ARM_SVC_ARISC_AUDIO_PERDONE_NOTIFY (ARM_SVC_ARISC_BASE + ARISC_AUDIO_PERDONE_NOTIFY) /* audio period done notify(arisc to ac327) */
+#define ARM_SVC_ARISC_AUDIO_ADD_PERIOD (ARM_SVC_ARISC_BASE + ARISC_AUDIO_ADD_PERIOD) /* audio period done notify(arisc to ac327) */
+
+/* rsb commands */
+#define ARM_SVC_ARISC_RSB_READ_BLOCK_DATA (ARM_SVC_ARISC_BASE + ARISC_RSB_READ_BLOCK_DATA) /* rsb read block data (ac327 to arisc) */
+#define ARM_SVC_ARISC_RSB_WRITE_BLOCK_DATA (ARM_SVC_ARISC_BASE + ARISC_RSB_WRITE_BLOCK_DATA) /* rsb write block data (ac327 to arisc) */
+#define ARM_SVC_ARISC_RSB_BITS_OPS_SYNC (ARM_SVC_ARISC_BASE + ARISC_RSB_BITS_OPS_SYNC) /* rsb clear bits sync (ac327 to arisc) */
+#define ARM_SVC_ARISC_RSB_SET_INTERFACE_MODE (ARM_SVC_ARISC_BASE + ARISC_RSB_SET_INTERFACE_MODE) /* rsb set interface mode (ac327 to arisc) */
+#define ARM_SVC_ARISC_RSB_SET_RTSADDR (ARM_SVC_ARISC_BASE + ARISC_RSB_SET_RTSADDR) /* rsb set runtime slave addr (ac327 to arisc) */
+
+/* arisc initialize state notify commands */
+#define ARM_SVC_ARISC_STARTUP_NOTIFY (ARM_SVC_ARISC_BASE + ARISC_STARTUP_NOTIFY) /* arisc init state notify(arisc to ac327) */
+
+#define AW_MSG_HWSPINLOCK (0)
+#define AW_AUDIO_HWSPINLOCK (1)
+#define AW_RTC_REG_HWSPINLOCK (2)
+
+#define NMI_INT_TYPE_PMU (0)
+#define NMI_INT_TYPE_RTC (1)
+#define NMI_INT_TYPE_PMU_OFFSET (0x1 << NMI_INT_TYPE_PMU)
+#define NMI_INT_TYPE_RTC_OFFSET (0x1 << NMI_INT_TYPE_RTC)
+
+/* the modes of arisc dvfs */
+#define ARISC_DVFS_SYN (1<<0)
+
+/* message attributes(only use 8bit) */
+#define ARISC_MESSAGE_ATTR_ASYN (0<<0) /* need asyn with another cpu */
+#define ARISC_MESSAGE_ATTR_SOFTSYN (1<<0) /* need soft syn with another cpu */
+#define ARISC_MESSAGE_ATTR_HARDSYN (1<<1) /* need hard syn with another cpu */
+
+/* axp driver interfaces */
+#define AXP_TRANS_BYTE_MAX (4)
+#define RSB_TRANS_BYTE_MAX (4)
+#define P2WI_TRANS_BYTE_MAX (8)
+
+/* RSB devices' address */
+#define RSB_DEVICE_SADDR1 (0x3A3) /* (0x01d1)AXP22x(AW1669) */
+#define RSB_DEVICE_SADDR3 (0x745) /* (0x03a2)AXP15x(AW1657) */
+#define RSB_DEVICE_SADDR7 (0xE89) /* (0x0744)Audio codec, AC100 */
+
+/* RSB run time address */
+#define RSB_RTSADDR_AXP809 (0x2d)
+#define RSB_RTSADDR_AXP806 (0x3a)
+#define RSB_RTSADDR_AC100 (0x4e)
+
+/* audio sram base address */
+#define AUDIO_SRAM_BASE_PALY (0x08117000)
+#define AUDIO_SRAM_BASE_CAPTURE (0x0811f000)
+
+#define AUDIO_SRAM_BUF_SIZE_02K (2048) /* buffer size 2k = 0x800 = 2048 */
+#define AUDIO_SRAM_BUF_SIZE_04K (4096) /* buffer size 4k = 0x1000 = 4096 */
+#define AUDIO_SRAM_BUF_SIZE_08K (8192) /* buffer size 8k = 0x2000 = 8192 */
+#define AUDIO_SRAM_BUF_SIZE_16K (16384) /* buffer size 16k = 0x4000 = 16384 */
+#define AUDIO_SRAM_BUF_SIZE_32K (32768) /* buffer size 32k = 0x8000 = 32768 */
+
+#define AUDIO_SRAM_PER_SIZE_02K (2048) /* period size 2k = 0x800 = 2048 */
+#define AUDIO_SRAM_PER_SIZE_04K (4096) /* period size 4k = 0x1000 = 4096 */
+#define AUDIO_SRAM_PER_SIZE_08K (8192) /* period size 8k = 0x2000 = 8192 */
+#define AUDIO_SRAM_PER_SIZE_16K (16384) /* period size 16k = 0x4000 = 16384 */
+#define AUDIO_SRAM_PER_SIZE_32K (32768) /* period size 32k = 0x8000 = 32768 */
+
+typedef enum {
+ arisc_power_on = 0,
+ arisc_power_retention = 1,
+ arisc_power_off = 3,
+} arisc_power_state_t;
+
+typedef enum {
+ arisc_system_shutdown = 0,
+ arisc_system_reboot = 1,
+ arisc_system_reset = 2
+} arisc_system_state_t;
+
+//pmu voltage types
+typedef enum power_voltage_type
+{
+ AXP809_POWER_VOL_DCDC1 = 0x0,
+ AXP809_POWER_VOL_DCDC2,
+ AXP809_POWER_VOL_DCDC3,
+ AXP809_POWER_VOL_DCDC4,
+ AXP809_POWER_VOL_DCDC5,
+ AXP809_POWER_VOL_DC5LDO,
+ AXP809_POWER_VOL_ALDO1,
+ AXP809_POWER_VOL_ALDO2,
+ AXP809_POWER_VOL_ALDO3,
+ AXP809_POWER_VOL_DLDO1,
+ AXP809_POWER_VOL_DLDO2,
+ AXP809_POWER_VOL_ELDO1,
+ AXP809_POWER_VOL_ELDO2,
+ AXP809_POWER_VOL_ELDO3,
+
+ AXP806_POWER_VOL_DCDCA,
+ AXP806_POWER_VOL_DCDCB,
+ AXP806_POWER_VOL_DCDCC,
+ AXP806_POWER_VOL_DCDCD,
+ AXP806_POWER_VOL_DCDCE,
+ AXP806_POWER_VOL_ALDO1,
+ AXP806_POWER_VOL_ALDO2,
+ AXP806_POWER_VOL_ALDO3,
+ AXP806_POWER_VOL_BLDO1,
+ AXP806_POWER_VOL_BLDO2,
+ AXP806_POWER_VOL_BLDO3,
+ AXP806_POWER_VOL_BLDO4,
+ AXP806_POWER_VOL_CLDO1,
+ AXP806_POWER_VOL_CLDO2,
+ AXP806_POWER_VOL_CLDO3,
+
+ OZ80120_POWER_VOL_DCDC,
+
+ POWER_VOL_MAX,
+} power_voltage_type_e;
+
+/* the pll of arisc dvfs */
+typedef enum arisc_pll_no {
+ ARISC_DVFS_PLL1 = 1,
+ ARISC_DVFS_PLL2 = 2
+} arisc_pll_no_e;
+
+/* rsb transfer data type */
+typedef enum arisc_rsb_datatype {
+ RSB_DATA_TYPE_BYTE = 1,
+ RSB_DATA_TYPE_HWORD = 2,
+ RSB_DATA_TYPE_WORD = 4
+} arisc_rsb_datatype_e;
+
+#if defined CONFIG_ARCH_SUN8IW1P1
+typedef enum arisc_p2wi_bits_ops {
+ P2WI_CLR_BITS,
+ P2WI_SET_BITS
+} arisc_p2wi_bits_ops_e;
+#elif (defined CONFIG_ARCH_SUN8IW3P1) || (defined CONFIG_ARCH_SUN8IW5P1) || (defined CONFIG_ARCH_SUN8IW6P1) || \
+ (defined CONFIG_ARCH_SUN8IW7P1) || (defined CONFIG_ARCH_SUN8IW9P1) || (defined CONFIG_ARCH_SUN9IW1P1) || \
+ (defined CONFIG_ARCH_SUN50IW1P1)
+/* rsb transfer data type */
+typedef enum arisc_rsb_bits_ops {
+ RSB_CLR_BITS,
+ RSB_SET_BITS
+} arisc_rsb_bits_ops_e;
+#endif
+
+typedef enum arisc_audio_mode {
+ AUDIO_PLAY, /* play mode */
+ AUDIO_CAPTURE /* capture mode */
+} arisc_audio_mode_e;
+
+typedef struct arisc_audio_mem
+{
+ uint32_t mode;
+ uint32_t sram_base_addr;
+ uint32_t buffer_size;
+ uint32_t period_size;
+}arisc_audio_mem_t;
+
+typedef struct arisc_audio_tdm
+{
+ uint32_t mode;
+ uint32_t samplerate;
+ uint32_t channum;
+}arisc_audio_tdm_t;
+
+/* arisc call-back */
+typedef int (*arisc_cb_t)(void *arg);
+
+/* sunxi_perdone_cbfn
+ *
+ * period done callback routine type
+*/
+/* audio callback struct */
+typedef struct audio_cb {
+ arisc_cb_t handler; /* dma callback fuction */
+ void *arg; /* args of func */
+}audio_cb_t;
+
+/*
+ * @len : number of read registers, max len:4;
+ * @datatype: type of the data, 0:byte(8bits), 1:halfword(16bits), 2:word(32bits)
+ * @msgattr: message attribute, 0:async, 1:soft sync, 2:hard aync
+ * @devaddr: devices address;
+ * @regaddr: array of registers address;
+ * @data: array of registers data;
+ */
+typedef struct arisc_rsb_block_cfg
+{
+ uint32_t len;
+ uint32_t datatype;
+ uint32_t msgattr;
+ uint32_t devaddr;
+ unsigned char *regaddr;
+ uint32_t *data;
+}arisc_rsb_block_cfg_t;
+
+/*
+ * @len : number of operate registers, max len:4;
+ * @datatype: type of the data, 0:byte(8bits), 1:halfword(16bits), 2:word(32bits)
+ * @msgattr: message attribute, 0:async, 1:soft sync, 2:hard aync
+ * @ops: bits operation, 0:clear bits, 1:set bits
+ * @devaddr : devices address;
+ * @regaddr : point of registers address;
+ * @mask : point of mask bits data;
+ * @delay: point of delay times;
+ */
+typedef struct arisc_rsb_bits_cfg
+{
+ uint32_t len;
+ uint32_t datatype;
+ uint32_t msgattr;
+ uint32_t ops;
+ uint32_t devaddr;
+ unsigned char *regaddr;
+ unsigned char *delay;
+ uint32_t *mask;
+}arisc_rsb_bits_cfg_t;
+
+typedef enum arisc_rw_type
+{
+ ARISC_READ = 0x0,
+ ARISC_WRITE = 0x1,
+} arisc_rw_type_e;
+
+typedef struct nmi_isr
+{
+ arisc_cb_t handler;
+ void *arg;
+} nmi_isr_t;
+
+extern nmi_isr_t nmi_isr_node[2];
+
+/*
+ * @flags: 0x01-clean pendings, 0x10-enter cupidle.
+ * @resume_addr: resume address for cpu0 out of idle.
+ */
+typedef struct sunxi_enter_idle_para{
+ unsigned long flags;
+ void *resume_addr;
+}sunxi_enter_idle_para_t;
+
+typedef struct sst_power_info_para
+{
+ /*
+ * define for sun9iw1p1
+ * power_reg bit0 ~ 7 AXP_main REG10, bit 8~15 AXP_main REG12
+ * power_reg bit16~23 AXP_slav REG10, bit24~31 AXP_slav REG11
+ *
+ * AXP_main REG10: 0-off, 1-on
+ * bit7 bit6 bit5 bit4 bit3 bit2 bit1 bit0
+ * aldo2 aldo1 dcdc5 dcdc4 dcdc3 dcdc2 dcdc1 dc5ldo
+ *
+ * REG12: bit0~5:0-off, 1-on, bit6~7: 0-on, 1-off, dc1sw's power come from dcdc1
+ * bit7 bit6 bit5 bit4 bit3 bit2 bit1 bit0
+ * dc1sw swout aldo3 dldo2 dldo1 eldo3 eldo2 eldo1
+ *
+ * AXP_slave REG10: 0-off, 1-on. dcdc b&c is not used, ignore them.
+ * bit7 bit6 bit5 bit4 bit3 bit2 bit1 bit0
+ * aldo3 aldo2 aldo1 dcdce dcdcd dcdcc dcdcb dcdca
+ *
+ * AXP_slave REG11: 0-off, 1-on
+ * bit7 bit6 bit5 bit4 bit3 bit2 bit1 bit0
+ * swout cldo3 cldo2 cldo1 bldo4 bldo3 bldo2 bldo1
+ */
+ /*
+ * define for sun8iw5p1
+ * power_reg0 ~ 7 AXP_main REG10, 8~15 AXP_main REG12
+ * power_reg16~32 null
+ *
+ * AXP_main REG10: 0-off, 1-on
+ * bit7 bit6 bit5 bit4 bit3 bit2 bit1 bit0
+ * aldo2 aldo1 dcdc5 dcdc4 dcdc3 dcdc2 dcdc1 dc5ldo
+ *
+ * REG12: 0-off, 1-on
+ * bit7 bit6 bit5 bit4 bit3 bit2 bit1 bit0
+ * dc1sw dldo4 dldo3 dldo2 dldo1 eldo3 eldo2 eldo1
+ *
+ * REG13: bit16 aldo3, 0-off, 1-on
+ * REG90: bit17 gpio0/ldo, 0-off, 1-on
+ * REG92: bit18 gpio1/ldo, 0-off, 1-on
+ */
+ unsigned int enable; /* enable bit */
+ unsigned int power_reg; /* registers of power state should be */
+ signed int system_power; /* the max power of system, signed, power mabe negative when charge */
+} sst_power_info_para_t;
+
+typedef struct sst_dram_info
+{
+ unsigned int dram_crc_enable;
+ unsigned int dram_crc_src;
+ unsigned int dram_crc_len;
+ unsigned int dram_crc_error;
+ unsigned int dram_crc_total_count;
+ unsigned int dram_crc_error_count;
+} sst_dram_info_t;
+
+typedef struct standby_info_para
+{
+ sst_power_info_para_t power_state; /* size 3W=12B */
+ sst_dram_info_t dram_state; /*size 6W=24B */
+} standby_info_para_t;
+
+int sunxi_arisc_probe(void *cfg);
+int sunxi_arisc_wait_ready(void);
+
+
+/* ====================================dvfs interface==================================== */
+/*
+ * set specific pll target frequency.
+ * @freq: target frequency to be set, based on KHZ;
+ * @pll: which pll will be set
+ * @mode: the attribute of message, whether syn or asyn;
+ * @cb: callback handler;
+ * @cb_arg: callback handler arguments;
+ *
+ * return: result, 0 - set frequency successed,
+ * !0 - set frequency failed;
+ */
+int arisc_dvfs_set_cpufreq(uint32_t freq, uint32_t pll, uint32_t mode);
+
+/*
+ * enter cpu idle.
+ * @cb: callback function.
+ * @cb_arg: arg for callback function.
+ * @pars: arg for enter cpuidle.
+ *
+ * return: result, 0 - enter cpuidle successed, !0 - failed;
+ */
+int arisc_enter_cpuidle(arisc_cb_t cb, void *cb_arg, struct sunxi_enter_idle_para *para);
+
+/**
+ * cpu operations.
+ * @mpidr: cpu id;
+ * @entrypoint: cpu resume entrypoint;
+ * @cpu_state: cpu state;
+ * @cluster_state: cluster state;
+ *
+ * return: result, 0 - super standby successed,
+ * !0 - super standby failed;
+ */
+int arisc_cpu_op(uint32_t mpidr, uint32_t entrypoint, arisc_power_state_t cpu_state,
+ arisc_power_state_t cluster_state);
+
+ /**
+ * system operations.
+ * @state: system state;
+ *
+ * return: result, 0 - system operations successed,
+ * !0 - system operations failed;
+ */
+int arisc_system_op(arisc_system_state_t state);
+
+/* ====================================standby interface==================================== */
+/**
+ * query super-standby wakeup source.
+ * @para: point of buffer to store wakeup event informations.
+ *
+ * return: result, 0 - query successed, !0 - query failed;
+ */
+int arisc_query_wakeup_source(uint32_t *event);
+
+int arisc_query_set_standby_info(struct standby_info_para *para, arisc_rw_type_e op);
+
+/*
+ * query config of standby power state and consumer.
+ * @para: point of buffer to store power informations.
+ *
+ * return: result, 0 - query successed, !0 - query failed;
+ */
+int arisc_query_standby_power_cfg(struct standby_info_para *para);
+
+/*
+ * set config of standby power state and consumer.
+ * @para: point of buffer to store power informations.
+ *
+ * return: result, 0 - set successed, !0 - set failed;
+ */
+#define arisc_set_standby_power_cfg(para) \
+ arisc_query_set_standby_info(para, ARISC_WRITE)
+
+/*
+ * query standby power state and consumer.
+ * @para: point of buffer to store power informations.
+ *
+ * return: result, 0 - query successed, !0 - query failed;
+ */
+#define arisc_query_standby_power(para) \
+ arisc_query_set_standby_info(para, ARISC_READ)
+
+/**
+ * query super-standby dram crc result.
+ * @perror: pointer of dram crc result.
+ * @ptotal_count: pointer of dram crc total count
+ * @perror_count: pointer of dram crc error count
+ *
+ * return: result, 0 - query successed,
+ * !0 - query failed;
+ */
+int arisc_query_dram_crc_result(unsigned long *perror, unsigned long *ptotal_count,
+ unsigned long *perror_count);
+
+int arisc_set_dram_crc_result(unsigned long error, unsigned long total_count,
+ unsigned long error_count);
+
+/**
+ * notify arisc cpux restored.
+ * @para: none.
+ *
+ * return: result, 0 - notify successed, !0 - notify failed;
+ */
+int arisc_cpux_ready_notify(void);
+
+#if defined CONFIG_ARCH_SUN8IW1P1
+void arisc_fake_power_off(void);
+#endif
+
+/* ====================================axp interface==================================== */
+/**
+ * register call-back function, call-back function is for arisc notify some event to ac327,
+ * axp/rtc interrupt for external interrupt NMI.
+ * @type: nmi type, pmu/rtc;
+ * @func: call-back function;
+ * @para: parameter for call-back function;
+ *
+ * @return: result, 0 - register call-back function successed;
+ * !0 - register call-back function failed;
+ * NOTE: the function is like "int callback(void *para)";
+ * this function will execute in system ISR.
+ */
+int arisc_nmi_cb_register(uint32_t type, arisc_cb_t func, void *para);
+
+/**
+ * unregister call-back function.
+ * @type: nmi type, pmu/rtc;
+ * @func: call-back function which need be unregister;
+ */
+void arisc_nmi_cb_unregister(uint32_t type, arisc_cb_t func);
+
+int arisc_disable_nmi_irq(void);
+int arisc_enable_nmi_irq(void);
+int arisc_clear_nmi_status(void);
+int arisc_set_nmi_trigger(uint32_t type);
+
+int arisc_axp_get_chip_id(unsigned char *chip_id);
+int arisc_adjust_pmu_chgcur(uint32_t max_chgcur, uint32_t chg_ic_temp, uint32_t flag);
+int arisc_set_pwr_tree(uint32_t *pwr_tree);
+
+int arisc_set_led_bln(uint32_t *paras);
+
+/* ====================================audio interface==================================== */
+/**
+ * start audio play or capture.
+ * @mode: start audio in which mode ; 0:play, 1;capture.
+ *
+ * return: result, 0 - start audio play or capture successed,
+ * !0 - start audio play or capture failed.
+ */
+int arisc_audio_start(int mode);
+
+/**
+ * stop audio play or capture.
+ * @mode: stop audio in which mode ; 0:play, 1;capture.
+ *
+ * return: result, 0 - stop audio play or capture successed,
+ * !0 - stop audio play or capture failed.
+ */
+int arisc_audio_stop(int mode);
+
+/**
+ * set audio buffer and period parameters.
+ * @audio_mem:
+ * mode :which mode be set; 0:paly, 1:capture;
+ * sram_base_addr:sram base addr of buffer;
+ * buffer_size :the size of buffer;
+ * period_size :the size of period;
+ *
+ * |period|period|period|period|...|period|period|period|period|...|
+ * | paly buffer | capture buffer |
+ * | |
+ * 1 2
+ * 1:paly sram_base_addr, 2:capture sram_base_addr;
+ * buffer size = capture sram_base_addr - paly sram_base_addr.
+ *
+ * return: result, 0 - set buffer and period parameters successed,
+ * !0 - set buffer and period parameters failed.
+ *
+ */
+int arisc_buffer_period_paras(struct arisc_audio_mem audio_mem);
+
+/**
+ * get audio play or capture real-time address.
+ * @mode: in which mode; 0:play, 1;capture;
+ * @addr: real-time address in which mode.
+ *
+ * return: result, 0 - get real-time address successed,
+ * !0 - get real-time address failed.
+ */
+int arisc_get_position(int mode, uint32_t *addr);
+
+/**
+ * register audio callback function.
+ * @mode: in which mode; 0:play, 1;capture;
+ * @handler: audio callback handler which need be register;
+ * @arg : the pointer of audio callback arguments.
+ *
+ * return: result, 0 - register audio callback function successed,
+ * !0 - register audio callback function failed.
+ */
+int arisc_audio_cb_register(int mode, arisc_cb_t handler, void *arg);
+
+/**
+ * unregister audio callback function.
+ * @mode: in which mode; 0:play, 1;capture;
+ * @handler: audio callback handler which need be register;
+ * @arg : the pointer of audio callback arguments.
+ *
+ * return: result, 0 - unregister audio callback function successed,
+ * !0 - unregister audio callback function failed.
+ */
+int arisc_audio_cb_unregister(int mode, arisc_cb_t handler);
+
+/**
+ * set audio tdm parameters.
+ * @tdm_cfg: audio tdm struct
+ * mode :in which mode; 0:play, 1;capture;
+ * samplerate:tdm samplerate depend on audio data;
+ * channel :audio channel number, 1 or 2.
+
+ * return: result, 0 - set buffer and period parameters successed,
+ * !0 - set buffer and period parameters failed.
+ *
+ */
+int arisc_tdm_paras(struct arisc_audio_tdm tdm_cfg);
+
+/**
+ * add audio period.
+ * @mode: start audio in which mode ; 0:play, 1;capture.
+ * @addr: period address which will be add in buffer
+ *
+ * return: result, 0 - add audio period successed,
+ * !0 - add audio period failed.
+ *
+ */
+int arisc_add_period(uint32_t mode, uint32_t addr);
+
+/* ====================================rsb interface==================================== */
+/**
+ * rsb read block data.
+ * @cfg: point of arisc_rsb_block_cfg struct;
+ *
+ * return: result, 0 - read register successed,
+ * !0 - read register failed or the len more then max len;
+ */
+int arisc_rsb_read_block_data(uint32_t *paras);
+
+/**
+ * rsb write block data.
+ * @cfg: point of arisc_rsb_block_cfg struct;
+ *
+ * return: result, 0 - write register successed,
+ * !0 - write register failedor the len more then max len;
+ */
+int arisc_rsb_write_block_data(uint32_t *paras);
+
+
+/**
+ * rsb read pmu reg.
+ * @addr: pmu reg addr;
+ *
+ * return: if read pmu reg successed, return data of pmu reg;
+ * if read pmu reg failed, return -1.
+ */
+uint8_t arisc_rsb_read_pmu_reg(uint32_t addr);
+
+/**
+ * rsb write pmu reg.
+ * @addr: pmu reg addr;
+ * @data: pmu reg data;
+ *
+ * return: result, 0 - write register successed,
+ * !0 - write register failedor the len more then max len;
+ */
+int arisc_rsb_write_pmu_reg(uint32_t addr, uint32_t data);
+
+
+/**
+ * rsb bits operation sync.
+ * @cfg: point of arisc_rsb_bits_cfg struct;
+ *
+ * return: result, 0 - bits operation successed,
+ * !0 - bits operation failed, or the len more then max len;
+ *
+ * rsb clear bits internal:
+ * data = rsb_read(regaddr);
+ * data = data & (~mask);
+ * rsb_write(regaddr, data);
+ *
+ * rsb set bits internal:
+ * data = rsb_read(addr);
+ * data = data | mask;
+ * rsb_write(addr, data);
+ *
+ */
+int rsb_bits_ops_sync(uint32_t *paras);
+
+/**
+ * rsb set interface mode.
+ * @devaddr: rsb slave device address;
+ * @regaddr: register address of rsb slave device;
+ * @data: data which to init rsb slave device interface mode;
+ *
+ * return: result, 0 - set interface mode successed,
+ * !0 - set interface mode failed;
+ */
+int arisc_rsb_set_interface_mode(uint32_t devaddr, uint32_t regaddr, uint32_t data);
+
+/**
+ * rsb set runtime slave address.
+ * @devaddr: rsb slave device address;
+ * @rtsaddr: rsb slave device's runtime slave address;
+ *
+ * return: result, 0 - set rsb runtime address successed,
+ * !0 - set rsb runtime address failed;
+ */
+int arisc_rsb_set_rtsaddr(uint32_t devaddr, uint32_t rtsaddr);
+
+/**
+ * set pmu voltage.
+ * @type: pmu regulator type;
+ * @voltage: pmu regulator voltage;
+ *
+ * return: result, 0 - set pmu voltage successed,
+ * !0 - set pmu voltage failed;
+ */
+int arisc_pmu_set_voltage(uint32_t type, uint32_t voltage);
+
+/**
+ * get pmu voltage.
+ * @type: pmu regulator type;
+ *
+ * return: pmu regulator voltage;
+ */
+int arisc_pmu_get_voltage(uint32_t type, uint32_t *voltage);
+
+/* ====================================debug interface==================================== */
+int arisc_message_loopback(void);
+int arisc_config_ir_paras(uint32_t ir_code, uint32_t ir_addr);
+int arisc_set_debug_level(unsigned int level);
+int arisc_set_uart_baudrate(uint32_t baudrate);
+int arisc_set_dram_crc_paras(unsigned int dram_crc_en, unsigned int dram_crc_srcaddr, unsigned int dram_crc_len);
+int arisc_set_paras(void);
+
+#endif /* __ASM_ARCH_A100_H */
+
diff --git a/plat/sun50iw1p1/include/ccmu.h b/plat/sun50iw1p1/include/ccmu.h
new file mode 100644
index 0000000..a1e817f
--- /dev/null
+++ b/plat/sun50iw1p1/include/ccmu.h
@@ -0,0 +1,81 @@
+/*
+ * (C) Copyright 2007-2015
+ * Allwinner Technology Co., Ltd. <www.allwinnertech.com>
+ * Jerry Wang <wangflord@allwinnertech.com>
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * SPDX-License-Identifier: GPL-2.0
+ */
+
+#ifndef __CCMU_H
+#define __CCMU_H
+
+
+#include "../sunxi_def.h"
+
+/* pll list */
+#define CCMU_PLL_CPUX_CTRL_REG (SUNXI_CCM_BASE + 0x00)
+#define CCMU_PLL_AUDIO_CTRL_REG (SUNXI_CCM_BASE + 0x08)
+#define CCMU_PLL_VIDEO0_CTRL_REG (SUNXI_CCM_BASE + 0x10)
+#define CCMU_PLL_VE_CTRL_REG (SUNXI_CCM_BASE + 0x18)
+#define CCMU_PLL_DDR0_CTRL_REG (SUNXI_CCM_BASE + 0x20)
+#define CCMU_PLL_PERIPH0_CTRL_REG (SUNXI_CCM_BASE + 0x28)
+#define CCMU_PLL_PERIPH1_CTRL_REG (SUNXI_CCM_BASE + 0x2C)
+#define CCMU_PLL_VIDEO1_CTRL_REG (SUNXI_CCM_BASE + 0x30)
+#define CCMU_PLL_GPU_CTRL_REG (SUNXI_CCM_BASE + 0x38)
+#define CCMU_PLL_MIPI_CTRL_REG (SUNXI_CCM_BASE + 0x40)
+#define CCMU_PLL_HSIC_CTRL_REG (SUNXI_CCM_BASE + 0x44)
+#define CCMU_PLL_DE_CTRL_REG (SUNXI_CCM_BASE + 0x48)
+#define CCMU_PLL_DDR1_CTRL_REG (SUNXI_CCM_BASE + 0x4C)
+
+/* cfg list */
+#define CCMU_CPUX_AXI_CFG_REG (SUNXI_CCM_BASE + 0x50)
+#define CCMU_AHB1_APB1_CFG_REG (SUNXI_CCM_BASE + 0x54)
+#define CCMU_APB2_CFG_GREG (SUNXI_CCM_BASE + 0x58)
+#define CCMU_AHB2_CFG_GREG (SUNXI_CCM_BASE + 0x5C)
+
+/* gate list */
+#define CCMU_BUS_CLK_GATING_REG0 (SUNXI_CCM_BASE + 0x60)
+#define CCMU_BUS_CLK_GATING_REG1 (SUNXI_CCM_BASE + 0x64)
+#define CCMU_BUS_CLK_GATING_REG2 (SUNXI_CCM_BASE + 0x68)
+#define CCMU_BUS_CLK_GATING_REG3 (SUNXI_CCM_BASE + 0x6C)
+#define CCMU_BUS_CLK_GATING_REG4 (SUNXI_CCM_BASE + 0x70)
+
+/* module list */
+#define CCMU_NAND0_CLK_REG (SUNXI_CCM_BASE + 0x80)
+#define CCMU_SDMMC0_CLK_REG (SUNXI_CCM_BASE + 0x88)
+#define CCMU_SDMMC1_CLK_REG (SUNXI_CCM_BASE + 0x8C)
+#define CCMU_SDMMC2_CLK_REG (SUNXI_CCM_BASE + 0x90)
+
+#define CCMU_CE_CLK_REG (SUNXI_CCM_BASE + 0x9C)
+
+#define CCMU_USBPHY_CLK_REG (SUNXI_CCM_BASE + 0xCC)
+#define CCMU_DRAM_CLK_REG (SUNXI_CCM_BASE + 0xF4)
+#define CCMU_PLL_DDR_CFG_REG (SUNXI_CCM_BASE + 0xF8)
+#define CCMU_MBUS_RST_REG (SUNXI_CCM_BASE + 0xFC)
+#define CCMU_DRAM_CLK_GATING_REG (SUNXI_CCM_BASE + 0x100)
+
+#define CCMU_AVS_CLK_REG (SUNXI_CCM_BASE + 0x144)
+#define CCMU_MBUS_CLK_REG (SUNXI_CCM_BASE + 0x15C)
+
+/*gate rst list*/
+#define CCMU_BUS_SOFT_RST_REG0 (SUNXI_CCM_BASE + 0x2C0)
+#define CCMU_BUS_SOFT_RST_REG1 (SUNXI_CCM_BASE + 0x2C4)
+#define CCMU_BUS_SOFT_RST_REG2 (SUNXI_CCM_BASE + 0x2C8)
+#define CCMU_BUS_SOFT_RST_REG3 (SUNXI_CCM_BASE + 0x2D0)
+#define CCMU_BUS_SOFT_RST_REG4 (SUNXI_CCM_BASE + 0x2D8)
+
+#endif
+
diff --git a/plat/sun50iw1p1/include/gpio.h b/plat/sun50iw1p1/include/gpio.h
new file mode 100644
index 0000000..7cab9c9
--- /dev/null
+++ b/plat/sun50iw1p1/include/gpio.h
@@ -0,0 +1,69 @@
+/*
+ * (C) Copyright 2007-2013
+ * Allwinner Technology Co., Ltd. <www.allwinnertech.com>
+ * Jerry Wang <wangflord@allwinnertech.com>
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+
+#ifndef _SUNXI_GPIO_H
+#define _SUNXI_GPIO_H
+
+#include <mmio.h>
+
+
+#define PIOC_REG_o_CFG0 0x00
+#define PIOC_REG_o_CFG1 0x04
+#define PIOC_REG_o_CFG2 0x08
+#define PIOC_REG_o_CFG3 0x0C
+#define PIOC_REG_o_DATA 0x10
+#define PIOC_REG_o_DRV0 0x14
+#define PIOC_REG_o_DRV1 0x18
+#define PIOC_REG_o_PUL0 0x1C
+#define PIOC_REG_o_PUL1 0x20
+
+
+
+/**#############################################################################################################
+ *
+ * GPIO(PIN) Operations
+ *
+-##############################################################################################################*/
+#define PIO_REG_CFG(n, i) (( SUNXI_PIO_BASE + ((n)-1)*0x24 + ((i)<<2) + 0x00))
+#define PIO_REG_DLEVEL(n, i) (( SUNXI_PIO_BASE + ((n)-1)*0x24 + ((i)<<2) + 0x14))
+#define PIO_REG_PULL(n, i) (( SUNXI_PIO_BASE + ((n)-1)*0x24 + ((i)<<2) + 0x1C))
+#define PIO_REG_DATA(n) (( SUNXI_PIO_BASE + ((n)-1)*0x24 + 0x10))
+
+
+//struct for gpio
+typedef struct
+{
+ unsigned char port; //端口号
+ unsigned char port_num; //端口内编号
+ char mul_sel; //功能编号
+ char pull; //电阻状态
+ char drv_level; //驱动驱动能力
+ char data; //输出电平
+ unsigned char reserved[2]; //保留位,保证对齐
+}
+normal_gpio_set_t;
+
+int32_t boot_set_gpio(void *user_gpio_list, uint32_t group_count_max, int32_t set_gpio);
+
+#endif /* _SUNXI_GPIO_H */
diff --git a/plat/sun50iw1p1/include/plat_macros.S b/plat/sun50iw1p1/include/plat_macros.S
new file mode 100644
index 0000000..4e35541
--- /dev/null
+++ b/plat/sun50iw1p1/include/plat_macros.S
@@ -0,0 +1,106 @@
+/*
+ * Copyright (c) 2014, ARM Limited and Contributors. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * Neither the name of ARM nor the names of its contributors may be used
+ * to endorse or promote products derived from this software without specific
+ * prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+#include <cci400.h>
+#include <gic_v2.h>
+#include <plat_config.h>
+#include "../sunxi_def.h"
+
+.section .rodata.gic_reg_name, "aS"
+gic_regs:
+ .asciz "gic_hppir", "gic_ahppir", "gic_ctlr", ""
+gicd_pend_reg:
+ .asciz "gicd_ispendr regs (Offsets 0x200 - 0x278)\n Offset:\t\t\tvalue\n"
+newline:
+ .asciz "\n"
+spacer:
+ .asciz ":\t\t0x"
+
+ /* ---------------------------------------------
+ * The below macro prints out relevant GIC
+ * registers whenever an unhandled exception is
+ * taken in BL3-1.
+ * Clobbers: x0 - x10, x16, sp
+ * ---------------------------------------------
+ */
+ .macro plat_print_gic_regs
+ adr x0, plat_config
+ ldr w16, [x0, #CONFIG_GICC_BASE_OFFSET]
+ cbz x16, exit_print_gic_regs
+ /* gic base address is now in x16 */
+ adr x6, gic_regs /* Load the gic reg list to x6 */
+ /* Load the gic regs to gp regs used by str_in_crash_buf_print */
+ ldr w8, [x16, #GICC_HPPIR]
+ ldr w9, [x16, #GICC_AHPPIR]
+ ldr w10, [x16, #GICC_CTLR]
+ /* Store to the crash buf and print to console */
+ bl str_in_crash_buf_print
+
+ /* Print the GICD_ISPENDR regs */
+ add x7, x16, #GICD_ISPENDR
+ adr x4, gicd_pend_reg
+ bl asm_print_str
+gicd_ispendr_loop:
+ sub x4, x7, x16
+ cmp x4, #0x280
+ b.eq exit_print_gic_regs
+ bl asm_print_hex
+ adr x4, spacer
+ bl asm_print_str
+ ldr x4, [x7], #8
+ bl asm_print_hex
+ adr x4, newline
+ bl asm_print_str
+ b gicd_ispendr_loop
+exit_print_gic_regs:
+ .endm
+#if 0
+.section .rodata.cci_reg_name, "aS"
+cci_iface_regs:
+ .asciz "cci_snoop_ctrl_cluster0", "cci_snoop_ctrl_cluster1" , ""
+
+ /* ------------------------------------------------
+ * The below macro prints out relevant interconnect
+ * registers whenever an unhandled exception is
+ * taken in BL3-1.
+ * Clobbers: x0 - x9, sp
+ * ------------------------------------------------
+ */
+ .macro plat_print_interconnect_regs
+ adr x6, cci_iface_regs
+ /* Store in x7 the base address of the first interface */
+ mov_imm x7, (CCI400_BASE + SLAVE_IFACE3_OFFSET)
+ ldr w8, [x7, #SNOOP_CTRL_REG]
+ /* Store in x7 the base address of the second interface */
+ mov_imm x7, (CCI400_BASE + SLAVE_IFACE4_OFFSET)
+ ldr w9, [x7, #SNOOP_CTRL_REG]
+ /* Store to the crash buf and print to console */
+ bl str_in_crash_buf_print
+ .endm
+#endif
diff --git a/plat/sun50iw1p1/include/platform_def.h b/plat/sun50iw1p1/include/platform_def.h
new file mode 100644
index 0000000..70b8b79
--- /dev/null
+++ b/plat/sun50iw1p1/include/platform_def.h
@@ -0,0 +1,135 @@
+/*
+ * Copyright (c) 2014, ARM Limited and Contributors. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * Neither the name of ARM nor the names of its contributors may be used
+ * to endorse or promote products derived from this software without specific
+ * prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef __PLATFORM_DEF_H__
+#define __PLATFORM_DEF_H__
+
+#include <arch.h>
+#include "../sunxi_def.h"
+
+
+/*******************************************************************************
+ * Platform binary types for linking
+ ******************************************************************************/
+#define PLATFORM_LINKER_FORMAT "elf64-littleaarch64"
+#define PLATFORM_LINKER_ARCH aarch64
+
+/*******************************************************************************
+ * Generic platform constants
+ ******************************************************************************/
+
+#define DEBUG_XLAT_TABLE 0
+
+/* Size of cacheable stacks */
+#if DEBUG_XLAT_TABLE
+#define PLATFORM_STACK_SIZE 0x800
+#elif IMAGE_BL1
+#define PLATFORM_STACK_SIZE 0x440
+#elif IMAGE_BL2
+#define PLATFORM_STACK_SIZE 0x400
+#elif IMAGE_BL31
+#define PLATFORM_STACK_SIZE 0x400
+#elif IMAGE_BL32
+#define PLATFORM_STACK_SIZE 0x440
+#endif
+
+#define FIRMWARE_WELCOME_STR "Booting Trusted Firmware\n"
+
+/* Trusted Boot Firmware BL2 */
+#define BL2_IMAGE_NAME "bl2.bin"
+
+/* EL3 Runtime Firmware BL31 */
+#define BL31_IMAGE_NAME "bl31.bin"
+
+/* Secure Payload BL32 (Trusted OS) */
+#define BL32_IMAGE_NAME "bl32.bin"
+
+/* Non-Trusted Firmware BL33 */
+#define BL33_IMAGE_NAME "bl33.bin" /* e.g. UEFI */
+
+#define PLATFORM_CACHE_LINE_SIZE 64
+
+#define PLATFORM_CLUSTER_COUNT 1
+#define PLATFORM_CORE_COUNT 4
+#define PLATFORM_NUM_AFFS (PLATFORM_CLUSTER_COUNT + PLATFORM_CORE_COUNT)
+#define PLATFORM_MAX_CPUS_PER_CLUSTER 4
+
+
+/*******************************************************************************
+ * BL31 specific defines.
+ ******************************************************************************/
+/*
+ * Put BL3-1 at the top of the Trusted SRAM (just below the shared memory, if
+ * present). BL31_BASE is calculated using the current BL3-1 debug size plus a
+ * little space for growth.
+ */
+#define BL31_BASE (SUNXI_TRUSTED_MONITOR_BASE)
+#define BL31_PROGBITS_LIMIT (SUNXI_TRUSTED_MONITOR_LIMIT - 0x6000)
+#define BL31_LIMIT SUNXI_TRUSTED_MONITOR_LIMIT
+
+/*******************************************************************************
+ * BL32 specific defines.
+ ******************************************************************************/
+/*
+ * On sun50iw1p1, the TSP can execute either from Trusted SRAM or Trusted DRAM.
+ */
+
+#define TSP_SEC_MEM_BASE SUNXI_TRUSTED_DRAM_BASE
+#define TSP_SEC_MEM_SIZE SUNXI_TRUSTED_DRAM_SIZE
+#define BL32_BASE (SUNXI_TRUSTED_DRAM_BASE + SUNXI_SHARED_RAM_SIZE)
+#define BL32_LIMIT (SUNXI_TRUSTED_DRAM_BASE + (1 << 21))
+
+
+/*
+ * ID of the secure physical generic timer interrupt used by the TSP.
+ */
+#define TSP_IRQ_SEC_PHY_TIMER IRQ_SEC_PHY_TIMER
+
+/*******************************************************************************
+ * Platform specific page table and MMU setup constants
+ ******************************************************************************/
+#define ADDR_SPACE_SIZE (1ull << 32)
+#define MAX_XLAT_TABLES 2
+#define MAX_MMAP_REGIONS 16
+
+/*******************************************************************************
+ * 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)
+
+
+#endif /* __PLATFORM_DEF_H__ */
diff --git a/plat/sun50iw1p1/include/uart.h b/plat/sun50iw1p1/include/uart.h
new file mode 100644
index 0000000..af26c0b
--- /dev/null
+++ b/plat/sun50iw1p1/include/uart.h
@@ -0,0 +1,43 @@
+#ifndef _UART_H_
+#define _UART_H_
+
+#define NULL ((void*)0)
+#define CCM_UART_PORT_OFFSET 16
+#define CCM_UART_ADDR_OFFSET 0x400
+
+typedef struct serial_hw
+{
+ volatile unsigned int rbr; /* 0 */
+ volatile unsigned int ier; /* 1 */
+ volatile unsigned int fcr; /* 2 */
+ volatile unsigned int lcr; /* 3 */
+ volatile unsigned int mcr; /* 4 */
+ volatile unsigned int lsr; /* 5 */
+ volatile unsigned int msr; /* 6 */
+ volatile unsigned int sch; /* 7 */
+}serial_hw_t;
+
+
+#define UART_BAUD 115200 // Baud rate for UART
+ // Compute the divisor factor
+// UART Line Control Parameter
+#define PARITY 0 // Parity: 0,2 - no parity; 1 - odd parity; 3 - even parity
+#define STOP 0 // Number of Stop Bit: 0 - 1bit; 1 - 2(or 1.5)bits
+#define DLEN 3 // Data Length: 0 - 5bits; 1 - 6bits; 2 - 7bits; 3 - 8bits
+
+#if DEBUG
+void sunxi_serial_init(int uart_port, void *gpio_cfg, int gpio_max);
+void sunxi_serial_exit(void);
+void sunxi_serial_putc (char c);
+char sunxi_serial_getc (void);
+int sunxi_serial_tstc (void);
+#else
+static inline void sunxi_serial_init(int uart_port, void *gpio_cfg, int gpio_max) {}
+static inline void sunxi_serial_exit(void) {}
+static inline void sunxi_serial_putc(char c) {}
+static inline char sunxi_serial_getc(void) { return 0;}
+static inline int sunxi_serial_tstc(void) { return 0;}
+#endif
+
+
+#endif /* #ifndef _UART_H_ */
diff --git a/plat/sun50iw1p1/mhu.c b/plat/sun50iw1p1/mhu.c
new file mode 100644
index 0000000..a817b4d
--- /dev/null
+++ b/plat/sun50iw1p1/mhu.c
@@ -0,0 +1,136 @@
+/*
+ * Copyright (c) 2014, ARM Limited and Contributors. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * Neither the name of ARM nor the names of its contributors may be used
+ * to endorse or promote products derived from this software without specific
+ * prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <arch_helpers.h>
+#include <bakery_lock.h>
+#include <mmio.h>
+#include <debug.h>
+#include "sunxi_def.h"
+#include "mhu.h"
+#include "scpi.h"
+
+#if 1
+void mhu_secure_message_start(void)
+{
+
+}
+
+void mhu_secure_message_send(uint32_t command)
+{
+ switch(command&0xf)
+ {
+ case SCPI_CMD_SCP_READY:
+ NOTICE("send cmd to scp: SCPI_CMD_SCP_READY\n");
+ break;
+ case SCPI_CMD_SET_CSS_POWER_STATE:
+ NOTICE("send cmd to scp: SCPI_CMD_SET_CSS_POWER_STATE\n");
+ break;
+ case SCPI_CMD_SYS_POWER_STATE:
+ NOTICE("send cmd to scp: SCPI_CMD_SYS_POWER_STATE\n");
+ break;
+ }
+}
+
+uint32_t mhu_secure_message_wait(void)
+{
+ /* Wait for response from SCP */
+
+ return 1;
+}
+
+void mhu_secure_message_end(void)
+{
+
+}
+
+void mhu_secure_init(void)
+{
+
+}
+#else
+/* SCP MHU secure channel registers */
+#define SCP_INTR_S_STAT 0x200
+#define SCP_INTR_S_SET 0x208
+#define SCP_INTR_S_CLEAR 0x210
+
+/* CPU MHU secure channel registers */
+#define CPU_INTR_S_STAT 0x300
+#define CPU_INTR_S_SET 0x308
+#define CPU_INTR_S_CLEAR 0x310
+
+
+static bakery_lock_t mhu_secure_lock __attribute__ ((section("tzfw_coherent_mem")));
+
+void mhu_secure_message_start(void)
+{
+ bakery_lock_get(&mhu_secure_lock);
+
+ /* Make sure any previous command has finished */
+ while (mmio_read_32(MHU_BASE + CPU_INTR_S_STAT) != 0)
+ ;
+}
+
+void mhu_secure_message_send(uint32_t command)
+{
+ /* Send command to SCP and wait for it to pick it up */
+ mmio_write_32(MHU_BASE + CPU_INTR_S_SET, command);
+ while (mmio_read_32(MHU_BASE + CPU_INTR_S_STAT) != 0)
+ ;
+}
+
+uint32_t mhu_secure_message_wait(void)
+{
+ /* Wait for response from SCP */
+ uint32_t response;
+ while (!(response = mmio_read_32(MHU_BASE + SCP_INTR_S_STAT)))
+ ;
+
+ return response;
+}
+
+void mhu_secure_message_end(void)
+{
+ /* Clear any response we got by writing all ones to the CLEAR register */
+ mmio_write_32(MHU_BASE + SCP_INTR_S_CLEAR, 0xffffffffu);
+
+ bakery_lock_release(&mhu_secure_lock);
+}
+
+void mhu_secure_init(void)
+{
+ bakery_lock_init(&mhu_secure_lock);
+
+ /*
+ * Clear the CPU's INTR register to make sure we don't see a stale
+ * or garbage value and think it's a message we've already sent.
+ */
+ mmio_write_32(MHU_BASE + CPU_INTR_S_CLEAR, 0xffffffffu);
+}
+#endif
diff --git a/plat/sun50iw1p1/mhu.h b/plat/sun50iw1p1/mhu.h
new file mode 100644
index 0000000..5149c82
--- /dev/null
+++ b/plat/sun50iw1p1/mhu.h
@@ -0,0 +1,43 @@
+/*
+ * Copyright (c) 2014, ARM Limited and Contributors. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * Neither the name of ARM nor the names of its contributors may be used
+ * to endorse or promote products derived from this software without specific
+ * prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef __MHU_H__
+#define __MHU_H__
+
+#include <stdint.h>
+
+extern void mhu_secure_message_start(void);
+extern void mhu_secure_message_send(uint32_t command);
+extern uint32_t mhu_secure_message_wait(void);
+extern void mhu_secure_message_end(void);
+
+extern void mhu_secure_init(void);
+
+#endif /* __MHU_H__ */
diff --git a/plat/sun50iw1p1/plat_gic.c b/plat/sun50iw1p1/plat_gic.c
new file mode 100644
index 0000000..78e1a81
--- /dev/null
+++ b/plat/sun50iw1p1/plat_gic.c
@@ -0,0 +1,402 @@
+/*
+ * Copyright (c) 2013-2014, ARM Limited and Contributors. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * Neither the name of ARM nor the names of its contributors may be used
+ * to endorse or promote products derived from this software without specific
+ * prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <arch_helpers.h>
+#include <assert.h>
+#include <bl_common.h>
+#include <gic_v2.h>
+#include <interrupt_mgmt.h>
+#include <platform.h>
+#include <debug.h>
+#include "sunxi_def.h"
+#include "sunxi_private.h"
+#include "gic_sunxi.h"
+
+
+/* Value used to initialise Non-Secure irq priorities four at a time */
+#define DEFAULT_NS_PRIORITY_X4 \
+ (GIC_HIGHEST_NS_PRIORITY | \
+ (GIC_HIGHEST_NS_PRIORITY << 8) | \
+ (GIC_HIGHEST_NS_PRIORITY << 16) | \
+ (GIC_HIGHEST_NS_PRIORITY << 24))
+
+
+/*******************************************************************************
+ * Enable secure interrupts and use FIQs to route them. Disable legacy bypass
+ * and set the priority mask register to allow all interrupts to trickle in.
+ ******************************************************************************/
+void gic_cpuif_setup(unsigned int gicc_base)
+{
+ unsigned int val;
+
+ gicc_write_pmr(gicc_base, GIC_PRI_MASK);
+
+ val = ENABLE_GRP0 | FIQ_EN;
+ val |= FIQ_BYP_DIS_GRP0 | IRQ_BYP_DIS_GRP0;
+ val |= FIQ_BYP_DIS_GRP1 | IRQ_BYP_DIS_GRP1;
+ gicc_write_ctlr(gicc_base, val);
+}
+
+/*******************************************************************************
+ * Place the cpu interface in a state where it can never make a cpu exit wfi as
+ * as result of an asserted interrupt. This is critical for powering down a cpu
+ ******************************************************************************/
+void gic_cpuif_deactivate(unsigned int gicc_base)
+{
+ unsigned int val;
+
+ /* Disable secure, non-secure interrupts and disable their bypass */
+ val = gicc_read_ctlr(gicc_base);
+ val &= ~(ENABLE_GRP0 | ENABLE_GRP1);
+ val |= FIQ_BYP_DIS_GRP1 | FIQ_BYP_DIS_GRP0;
+ val |= IRQ_BYP_DIS_GRP0 | IRQ_BYP_DIS_GRP1;
+ gicc_write_ctlr(gicc_base, val);
+}
+
+void gic_set_secure(unsigned int gicd_base, unsigned id)
+{
+ /* Set interrupt as Group 0 */
+ gicd_clr_igroupr(gicd_base, id);
+
+ /* Set priority to max */
+ gicd_set_ipriorityr(gicd_base, id, GIC_HIGHEST_SEC_PRIORITY);
+}
+
+#if 0
+/*******************************************************************************
+ * Per cpu gic distributor setup which will be done by all cpus after a cold
+ * boot/hotplug. This marks out the secure interrupts & enables them.
+ ******************************************************************************/
+void gic_pcpu_distif_setup(unsigned int gicd_base)
+{
+ unsigned i;
+
+ /* Mark all 32 PPI interrupts as Group 1 (non-secure) */
+ mmio_write_32(gicd_base + GICD_IGROUPR, 0xffffffffu);
+
+ /* Setup PPI priorities doing four at a time */
+ for (i = 0; i < 32; i += 4)
+ mmio_write_32(gicd_base + GICD_IPRIORITYR + i, DEFAULT_NS_PRIORITY_X4);
+
+ /* Configure those PPIs we want as secure, and enable them. */
+ static const char sec_irq[] = {
+ IRQ_SEC_PHY_TIMER,
+ IRQ_SEC_SGI_0,
+ IRQ_SEC_SGI_1,
+ IRQ_SEC_SGI_2,
+ IRQ_SEC_SGI_3,
+ IRQ_SEC_SGI_4,
+ IRQ_SEC_SGI_5,
+ IRQ_SEC_SGI_6,
+ IRQ_SEC_SGI_7
+ };
+ for (i = 0; i < sizeof(sec_irq) / sizeof(sec_irq[0]); i++) {
+ gic_set_secure(gicd_base, sec_irq[i]);
+ gicd_set_isenabler(gicd_base, sec_irq[i]);
+ }
+}
+
+/*******************************************************************************
+ * Global gic distributor setup which will be done by the primary cpu after a
+ * cold boot. It marks out the secure SPIs, PPIs & SGIs and enables them. It
+ * then enables the secure GIC distributor interface.
+ ******************************************************************************/
+static void gic_distif_setup(unsigned int gicd_base)
+{
+ unsigned int i, ctlr;
+ const unsigned int ITLinesNumber =
+ gicd_read_typer(gicd_base) & IT_LINES_NO_MASK;
+
+ /* Disable the distributor before going further */
+ ctlr = gicd_read_ctlr(gicd_base);
+ ctlr &= ~(ENABLE_GRP0 | ENABLE_GRP1);
+ gicd_write_ctlr(gicd_base, ctlr);
+
+ /* Mark all lines of SPIs as Group 1 (non-secure) */
+ for (i = 0; i < ITLinesNumber; i++)
+ mmio_write_32(gicd_base + GICD_IGROUPR + 4 + i * 4, 0xffffffffu);
+
+ /* Setup SPI priorities doing four at a time */
+ for (i = 0; i < ITLinesNumber * 32; i += 4)
+ mmio_write_32(gicd_base + GICD_IPRIORITYR + 32 + i, DEFAULT_NS_PRIORITY_X4);
+
+ /* Configure the SPIs we want as secure */
+ static const char sec_irq[] = {
+ IRQ_MHU,
+ IRQ_GPU_SMMU_0,
+ IRQ_GPU_SMMU_1,
+ IRQ_ETR_SMMU,
+ IRQ_TZC400,
+ IRQ_TZ_WDOG
+ };
+ for (i = 0; i < sizeof(sec_irq) / sizeof(sec_irq[0]); i++)
+ gic_set_secure(gicd_base, sec_irq[i]);
+
+ /* Route watchdog interrupt to this CPU and enable it. */
+ gicd_set_itargetsr(gicd_base, IRQ_TZ_WDOG,
+ platform_get_core_pos(read_mpidr()));
+ gicd_set_isenabler(gicd_base, IRQ_TZ_WDOG);
+
+ /* Now setup the PPIs */
+ gic_pcpu_distif_setup(gicd_base);
+
+ /* Enable Group 0 (secure) interrupts */
+ gicd_write_ctlr(gicd_base, ctlr | ENABLE_GRP0);
+}
+#endif
+
+#define writel(v,a) mmio_write_32((a),(v))
+
+void gic_distributor_init(uint32_t addr)
+{
+ uint32_t cpumask = 0x01010101;
+ uint32_t gic_irqs;
+ uint32_t i;
+
+ writel(0, GIC_DIST_CON);
+ /* check GIC hardware configutation */
+ gic_irqs = ((mmio_read_32(GIC_CON_TYPE) & 0x1f) + 1) * 32;
+ if (gic_irqs > 1020)
+ {
+ gic_irqs = 1020;
+ }
+ if (gic_irqs < GIC_IRQ_NUM)
+ {
+ NOTICE("GIC parameter config error, only support %d"
+ " irqs < %d(spec define)!!\n", gic_irqs, GIC_IRQ_NUM);
+ return ;
+ }
+
+ /* Set ALL interrupts as group1(non-secure) interrupts */
+ for (i=1; i<GIC_IRQ_NUM; i+=16)
+ {
+ writel(0xffffffff, GIC_CON_IGRP(i>>4));
+ }
+
+
+ /* set trigger type to be level-triggered, active low */
+ for (i=0; i<GIC_IRQ_NUM; i+=16)
+ {
+ writel(0, GIC_IRQ_MOD_CFG(i>>4));
+ }
+ /* set priority */
+ for (i=GIC_SRC_SPI(0); i<GIC_IRQ_NUM; i+=4)
+ {
+ writel(0xa0a0a0a0, GIC_SPI_PRIO((i-32)>>2));
+ }
+ /* set processor target */
+ for (i=32; i<GIC_IRQ_NUM; i+=4)
+ {
+ writel(cpumask, GIC_SPI_PROC_TARG((i-32)>>2));
+ }
+ /* disable all interrupts */
+ for (i=32; i<GIC_IRQ_NUM; i+=32)
+ {
+ writel(0xffffffff, GIC_CLR_EN(i>>5));
+ }
+ /* clear all interrupt active state */
+ for (i=32; i<GIC_IRQ_NUM; i+=32)
+ {
+ writel(0xffffffff, GIC_ACT_CLR(i>>5));
+ }
+
+ writel(3, GIC_DIST_CON);
+
+
+ return ;
+}
+/*
+************************************************************************************************************
+*
+* function
+*
+* name :
+*
+* parmeters :
+*
+* return :
+*
+* note :
+*
+*
+************************************************************************************************************
+*/
+void gic_cpuif_init(uint32_t addr)
+{
+ uint32_t i;
+
+ writel(0, GIC_CPU_IF_CTRL);
+ /*
+ * Deal with the banked PPI and SGI interrupts - disable all
+ * PPI interrupts, ensure all SGI interrupts are enabled.
+ */
+ writel(0xffff0000, GIC_CLR_EN(0));
+ writel(0x0000ffff, GIC_SET_EN(0));
+ /* Set priority on PPI and SGI interrupts */
+ for (i=0; i<16; i+=4)
+ {
+ writel(0xa0a0a0a0, GIC_SGI_PRIO(i>>2));
+ }
+ for (i=16; i<32; i+=4)
+ {
+ writel(0xa0a0a0a0, GIC_PPI_PRIO((i-16)>>2));
+ }
+
+ writel(0xf0, GIC_INT_PRIO_MASK);
+
+ writel(0xb, GIC_CPU_IF_CTRL);
+
+ return ;
+}
+
+void gic_pcpu_distif_setup(unsigned int gicd_base)
+{
+ int i ;
+ /* Mark all 32 PPI interrupts as Group 1 (non-secure) */
+ mmio_write_32(gicd_base + GICD_IGROUPR, 0xffffffffu);
+
+ /* Setup PPI priorities doing four at a time */
+ for (i = 0; i < 32; i += 4)
+ mmio_write_32(gicd_base + GICD_IPRIORITYR + i, 0xa0a0a0a0);
+}
+
+void gic_setup(void)
+{
+ gic_cpuif_init(GICC_BASE);
+ gic_distributor_init(GICD_BASE);
+}
+
+/*******************************************************************************
+ * An ARM processor signals interrupt exceptions through the IRQ and FIQ pins.
+ * The interrupt controller knows which pin/line it uses to signal a type of
+ * interrupt. The platform knows which interrupt controller type is being used
+ * in a particular security state e.g. with an ARM GIC, normal world could use
+ * the GICv2 features while the secure world could use GICv3 features and vice
+ * versa.
+ * This function is exported by the platform to let the interrupt management
+ * framework determine for a type of interrupt and security state, which line
+ * should be used in the SCR_EL3 to control its routing to EL3. The interrupt
+ * line is represented as the bit position of the IRQ or FIQ bit in the SCR_EL3.
+ ******************************************************************************/
+uint32_t plat_interrupt_type_to_line(uint32_t type, uint32_t security_state)
+{
+ assert(type == INTR_TYPE_S_EL1 ||
+ type == INTR_TYPE_EL3 ||
+ type == INTR_TYPE_NS);
+
+ assert(sec_state_is_valid(security_state));
+
+ /*
+ * We ignore the security state parameter because Juno is GICv2 only
+ * so both normal and secure worlds are using ARM GICv2.
+ */
+ return gicv2_interrupt_type_to_line(GICC_BASE, type);
+}
+
+/*******************************************************************************
+ * This function returns the type of the highest priority pending interrupt at
+ * the GIC cpu interface. INTR_TYPE_INVAL is returned when there is no
+ * interrupt pending.
+ ******************************************************************************/
+uint32_t plat_ic_get_pending_interrupt_type(void)
+{
+ uint32_t id;
+
+ id = gicc_read_hppir(GICC_BASE);
+
+ /* Assume that all secure interrupts are S-EL1 interrupts */
+ if (id < 1022)
+ return INTR_TYPE_S_EL1;
+
+ if (id == GIC_SPURIOUS_INTERRUPT)
+ return INTR_TYPE_INVAL;
+
+ return INTR_TYPE_NS;
+}
+
+/*******************************************************************************
+ * This function returns the id of the highest priority pending interrupt at
+ * the GIC cpu interface. INTR_ID_UNAVAILABLE is returned when there is no
+ * interrupt pending.
+ ******************************************************************************/
+uint32_t plat_ic_get_pending_interrupt_id(void)
+{
+ uint32_t id;
+
+ id = gicc_read_hppir(GICC_BASE);
+
+ if (id < 1022)
+ return id;
+
+ if (id == 1023)
+ return INTR_ID_UNAVAILABLE;
+
+ /*
+ * Find out which non-secure interrupt it is under the assumption that
+ * the GICC_CTLR.AckCtl bit is 0.
+ */
+ return gicc_read_ahppir(GICC_BASE);
+}
+
+/*******************************************************************************
+ * This functions reads the GIC cpu interface Interrupt Acknowledge register
+ * to start handling the pending interrupt. It returns the contents of the IAR.
+ ******************************************************************************/
+uint32_t plat_ic_acknowledge_interrupt(void)
+{
+ return gicc_read_IAR(GICC_BASE);
+}
+
+/*******************************************************************************
+ * This functions writes the GIC cpu interface End Of Interrupt register with
+ * the passed value to finish handling the active interrupt
+ ******************************************************************************/
+void plat_ic_end_of_interrupt(uint32_t id)
+{
+ gicc_write_EOIR(GICC_BASE, id);
+}
+
+/*******************************************************************************
+ * This function returns the type of the interrupt id depending upon the group
+ * this interrupt has been configured under by the interrupt controller i.e.
+ * group0 or group1.
+ ******************************************************************************/
+uint32_t plat_ic_get_interrupt_type(uint32_t id)
+{
+ uint32_t group;
+
+ group = gicd_get_igroupr(GICD_BASE, id);
+
+ /* Assume that all secure interrupts are S-EL1 interrupts */
+ if (group == GRP0)
+ return INTR_TYPE_S_EL1;
+ else
+ return INTR_TYPE_NS;
+}
diff --git a/plat/sun50iw1p1/plat_pm.c b/plat/sun50iw1p1/plat_pm.c
new file mode 100644
index 0000000..f4f4e29
--- /dev/null
+++ b/plat/sun50iw1p1/plat_pm.c
@@ -0,0 +1,335 @@
+/*
+ * Copyright (c) 2013, ARM Limited and Contributors. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * Neither the name of ARM nor the names of its contributors may be used
+ * to endorse or promote products derived from this software without specific
+ * prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <assert.h>
+#include <arch_helpers.h>
+#include <debug.h>
+#include <errno.h>
+#include <platform.h>
+#include <platform_def.h>
+#include <psci.h>
+#include <mmio.h>
+#include <bakery_lock.h>
+#include "sunxi_def.h"
+#include "sunxi_private.h"
+#include "scpi.h"
+#include "sunxi_cpu_ops.h"
+#include <arisc.h>
+#include <cci400.h>
+#include <console.h>
+#include <psci.h>
+
+bakery_lock_t plat_console_lock __attribute__ ((section("tzfw_coherent_mem")));
+
+/*******************************************************************************
+ * Private Sunxi function to program the mailbox for a cpu before it is released
+ * from reset.
+ ******************************************************************************/
+
+/*******************************************************************************
+ * Private Sunxi function which is used to determine if any platform actions
+ * should be performed for the specified affinity instance given its
+ * state. Nothing needs to be done if the 'state' is not off or if this is not
+ * the highest affinity level which will enter the 'state'.
+ ******************************************************************************/
+static int32_t sunxi_do_plat_actions(uint32_t afflvl, uint32_t state)
+{
+ uint32_t max_phys_off_afflvl;
+
+ assert(afflvl <= MPIDR_MAX_AFFLVL);
+
+ if (state != PSCI_STATE_OFF)
+ return -EAGAIN;
+
+ /*
+ * Find the highest affinity level which will be suspended and postpone
+ * all the platform specific actions until that level is hit.
+ */
+ max_phys_off_afflvl = psci_get_max_phys_off_afflvl();
+ assert(max_phys_off_afflvl != PSCI_INVALID_DATA);
+ assert(psci_get_suspend_afflvl() >= max_phys_off_afflvl);
+ if (afflvl != max_phys_off_afflvl)
+ return -EAGAIN;
+
+ return 0;
+}
+
+/*******************************************************************************
+ * Sunxi handler called when an affinity instance is about to be turned on. The
+ * level and mpidr determine the affinity instance.
+ ******************************************************************************/
+int32_t sunxi_affinst_on(uint64_t mpidr,
+ uint64_t sec_entrypoint,
+ uint64_t ns_entrypoint,
+ uint32_t afflvl,
+ uint32_t state)
+{
+ /*
+ * SCP takes care of powering up higher affinity levels so we
+ * only need to care about level 0
+ */
+ if (afflvl != MPIDR_AFFLVL0)
+ return PSCI_E_SUCCESS;
+
+ //INFO("mpidr:0x%llx, sec_entrypoint:0x%lx, ns_entrypoint:0x%lx, afflvl:0x%x, state:0x%x\n",
+ //mpidr, sec_entrypoint, ns_entrypoint, afflvl, state);
+ arisc_cpu_op(mpidr&0xff, sec_entrypoint, arisc_power_on, arisc_power_on);
+
+ return PSCI_E_SUCCESS;
+}
+
+/*******************************************************************************
+ * Sunxi handler called when an affinity instance has just been powered on after
+ * being turned off earlier. The level and mpidr determine the affinity
+ * instance. The 'state' arg. allows the platform to decide whether the cluster
+ * was turned off prior to wakeup and do what's necessary to setup it up
+ * correctly.
+ ******************************************************************************/
+int32_t sunxi_affinst_on_finish(uint64_t mpidr, uint32_t afflvl, uint32_t state)
+{
+ /* Determine if any platform actions need to be executed. */
+ if (sunxi_do_plat_actions(afflvl, state) == -EAGAIN)
+ return PSCI_E_SUCCESS;
+
+
+ /*
+ * Perform the common cluster specific operations i.e enable coherency
+ * if this cluster was off.
+ */
+ if (afflvl != MPIDR_AFFLVL0)
+ {
+ //cci_enable_cluster_coherency(mpidr);
+ }
+
+ // set smp bit before cache enable
+ platform_smp_init();
+
+ /* Enable the gic cpu interface */
+ gic_cpuif_setup(GICC_BASE);
+
+ /* Sunxi todo: Is this setup only needed after a cold boot? */
+ gic_pcpu_distif_setup(GICD_BASE);
+
+ return PSCI_E_SUCCESS;
+}
+
+/*******************************************************************************
+ * sunxi handler called when an affinity instance is about to enter standby.
+ ******************************************************************************/
+int sunxi_affinst_standby(unsigned int power_state)
+{
+ unsigned int target_afflvl;
+ uint64_t scr = 0;
+
+ /* Sanity check the requested state */
+ target_afflvl = psci_get_pstate_afflvl(power_state);
+
+ /*
+ * * It's possible to enter standby only on affinity level 0 i.e. a cpu
+ * * on the FVP. Ignore any other affinity level.
+ * */
+ if (target_afflvl != MPIDR_AFFLVL0)
+ return PSCI_E_INVALID_PARAMS;
+
+ scr = read_scr_el3();
+ /* enable physical IRQ bit for NS world to wakeup the CPU */
+ write_scr_el3(scr | SCR_IRQ_BIT);
+ isb();
+
+ /*
+ * * Enter standby state
+ * * dsb is good practice before using wfi to enter low power states
+ * */
+ dsb();
+ wfi();
+
+ /*
+ * * Restore SCR to the original value, sync of scr_el3 is done
+ * * by eret while el3_exit to save some execution cycles.
+ * * */
+ write_scr_el3(scr);
+
+ return PSCI_E_SUCCESS;
+
+}
+
+/*******************************************************************************
+ * Common function called while turning a cpu off or suspending it. It is called
+ * from sunxi_off() or sunxi_suspend() when these functions in turn are called for
+ * the highest affinity level which will be powered down. It performs the
+ * actions common to the OFF and SUSPEND calls.
+ ******************************************************************************/
+static int32_t sunxi_power_down_common(uint32_t afflvl, uint64_t mpidr, uint64_t sec_entrypoint)
+{
+ uint32_t cluster_state = arisc_power_on;
+
+ /* Prevent interrupts from spuriously waking up this cpu */
+ gic_cpuif_deactivate(GICC_BASE);
+
+ /* Cluster is to be turned off, so disable coherency */
+ if (afflvl > MPIDR_AFFLVL0) {
+ //cci_disable_cluster_coherency(read_mpidr_el1());
+ cluster_state = arisc_power_off;
+ }
+
+ //INFO("afflvl:0x%x, mpidr:0x%lx, sec_entrypoint: %lx\n",
+ //afflvl, mpidr, sec_entrypoint);
+ arisc_cpu_op(mpidr&0xff, sec_entrypoint, scpi_power_off, cluster_state);
+
+ return PSCI_E_SUCCESS;
+}
+
+/*******************************************************************************
+ * Handler called when an affinity instance is about to be turned off. The
+ * level and mpidr determine the affinity instance. The 'state' arg. allows the
+ * platform to decide whether the cluster is being turned off and take
+ * appropriate actions.
+ *
+ * CAUTION: There is no guarantee that caches will remain turned on across calls
+ * to this function as each affinity level is dealt with. So do not write & read
+ * global variables across calls. It will be wise to do flush a write to the
+ * global to prevent unpredictable results.
+ ******************************************************************************/
+static int32_t sunxi_affinst_off(uint64_t mpidr, uint32_t afflvl, uint32_t state)
+{
+ /* Determine if any platform actions need to be executed */
+ if (sunxi_do_plat_actions(afflvl, state) == -EAGAIN)
+ return PSCI_E_SUCCESS;
+
+ return sunxi_power_down_common(afflvl, mpidr, 0);
+}
+
+/*******************************************************************************
+ * Handler called when an affinity instance is about to be suspended. The
+ * level and mpidr determine the affinity instance. The 'state' arg. allows the
+ * platform to decide whether the cluster is being turned off and take apt
+ * actions. The 'sec_entrypoint' determines the address in BL3-1 from where
+ * execution should resume.
+ *
+ * CAUTION: There is no guarantee that caches will remain turned on across calls
+ * to this function as each affinity level is dealt with. So do not write & read
+ * global variables across calls. It will be wise to do flush a write to the
+ * global to prevent unpredictable results.
+ ******************************************************************************/
+static int32_t sunxi_affinst_suspend(uint64_t mpidr,
+ uint64_t sec_entrypoint,
+ uint64_t ns_entrypoint,
+ uint32_t afflvl,
+ uint32_t state)
+{
+ /* Determine if any platform actions need to be executed */
+ if (sunxi_do_plat_actions(afflvl, state) == -EAGAIN)
+ return PSCI_E_SUCCESS;
+
+ if (afflvl == psci_get_suspend_afflvl())
+ console_exit();
+
+ return sunxi_power_down_common(afflvl, mpidr, sec_entrypoint);
+}
+
+/*******************************************************************************
+ * Sunxi handler called when an affinity instance has just been powered on after
+ * having been suspended earlier. The level and mpidr determine the affinity
+ * instance.
+ * TODO: At the moment we reuse the on finisher and reinitialize the secure
+ * context. Need to implement a separate suspend finisher.
+ ******************************************************************************/
+static int32_t sunxi_affinst_suspend_finish(uint64_t mpidr,
+ uint32_t afflvl,
+ uint32_t state)
+{
+ if ((afflvl == psci_get_suspend_afflvl()) && ((mpidr & 0xff) == 0x0)) {
+ gic_setup();
+ console_init(SUNXI_UART0_BASE, UART0_CLK_IN_HZ, UART0_BAUDRATE);
+ arisc_cpux_ready_notify();
+
+ }
+
+ return sunxi_affinst_on_finish(mpidr, afflvl, state);
+}
+
+/*******************************************************************************
+ * Sunxi handlers to shutdown/reboot the system
+ ******************************************************************************/
+static void __dead2 sunxi_system_off(void)
+{
+ uint32_t response;
+
+ /* Send the power down request to the SCP */
+ response = arisc_system_op(arisc_system_shutdown);
+
+ if (response != SCP_OK) {
+ ERROR("Sunxi System Off: SCP error %u.\n", response);
+ panic();
+ }
+ wfi();
+ ERROR("Sunxi System Off: operation not handled.\n");
+ panic();
+}
+
+static void __dead2 sunxi_system_reset(void)
+{
+ uint32_t response;
+
+ /* Send the system reset request to the SCP */
+ response = arisc_system_op(scpi_system_reboot);
+
+ if (response != SCP_OK) {
+ ERROR("Sunxi System Reset: SCP error %u.\n", response);
+ panic();
+ }
+ wfi();
+ ERROR("Sunxi System Reset: operation not handled.\n");
+ panic();
+}
+
+/*******************************************************************************
+ * Export the platform handlers to enable psci to invoke them
+ ******************************************************************************/
+static const plat_pm_ops_t sunxi_ops = {
+ .affinst_standby = sunxi_affinst_standby,
+ .affinst_on = sunxi_affinst_on,
+ .affinst_on_finish = sunxi_affinst_on_finish,
+ .affinst_off = sunxi_affinst_off,
+ .affinst_suspend = sunxi_affinst_suspend,
+ .affinst_suspend_finish = sunxi_affinst_suspend_finish,
+ .system_off = sunxi_system_off,
+ .system_reset = sunxi_system_reset
+};
+
+/*******************************************************************************
+ * Export the platform specific power ops.
+ ******************************************************************************/
+int32_t platform_setup_pm(const plat_pm_ops_t **plat_ops)
+{
+ *plat_ops = &sunxi_ops;
+ bakery_lock_init(&plat_console_lock);
+ return 0;
+}
diff --git a/plat/sun50iw1p1/plat_topology.c b/plat/sun50iw1p1/plat_topology.c
new file mode 100644
index 0000000..7b2426a
--- /dev/null
+++ b/plat/sun50iw1p1/plat_topology.c
@@ -0,0 +1,253 @@
+/*
+ * Copyright (c) 2013-2014, ARM Limited and Contributors. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * Neither the name of ARM nor the names of its contributors may be used
+ * to endorse or promote products derived from this software without specific
+ * prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <assert.h>
+#include <platform_def.h>
+/* TODO: Reusing psci error codes & state information. Get our own! */
+#include <psci.h>
+
+/* We treat '255' as an invalid affinity instance */
+#define AFFINST_INVAL 0xff
+
+/*******************************************************************************
+ * We support 3 flavours of the FVP: Foundation, Base AEM & Base Cortex. Each
+ * flavour has a different topology. The common bit is that there can be a max.
+ * of 2 clusters (affinity 1) and 4 cpus (affinity 0) per cluster. So we define
+ * a tree like data structure which caters to these maximum bounds. It simply
+ * marks the absent affinity level instances as PSCI_AFF_ABSENT e.g. there is no
+ * cluster 1 on the Foundation FVP. The 'data' field is currently unused.
+ ******************************************************************************/
+typedef struct affinity_info {
+ unsigned char sibling;
+ unsigned char child;
+ unsigned char state;
+ unsigned int data;
+} affinity_info_t;
+
+/*******************************************************************************
+ * The following two data structures store the topology tree for the fvp. There
+ * is a separate array for each affinity level i.e. cpus and clusters. The child
+ * and sibling references allow traversal inside and in between the two arrays.
+ ******************************************************************************/
+static affinity_info_t sunxi_aff2_topology_map[1];
+static affinity_info_t sunxi_aff1_topology_map[PLATFORM_CLUSTER_COUNT];
+static affinity_info_t sunxi_aff0_topology_map[PLATFORM_CORE_COUNT];
+
+/* Simple global variable to safeguard us from stupidity */
+static unsigned int topology_setup_done;
+
+/*******************************************************************************
+ * This function implements a part of the critical interface between the psci
+ * generic layer and the platform to allow the former to detect the platform
+ * topology. psci queries the platform to determine how many affinity instances
+ * are present at a particular level for a given mpidr e.g. consider a dual
+ * cluster platform where each cluster has 4 cpus. A call to this function with
+ * (0, 0x100) will return the number of cpus implemented under cluster 1 i.e. 4.
+ * Similarly a call with (1, 0x100) will return 2 i.e. the number of clusters.
+ * This is 'cause we are effectively asking how many affinity level 1 instances
+ * are implemented under affinity level 2 instance 0.
+ ******************************************************************************/
+unsigned int plat_get_aff_count(unsigned int aff_lvl,
+ unsigned long mpidr)
+{
+ unsigned int aff_count = 1, ctr;
+ unsigned char parent_aff_id;
+
+ assert(topology_setup_done == 1);
+
+ switch (aff_lvl) {
+ case 3:
+ case 2:
+ /*
+ * Assert if the parent affinity instance is not 0.
+ * This also takes care of level 3 in an obfuscated way
+ */
+ parent_aff_id = (mpidr >> MPIDR_AFF3_SHIFT) & MPIDR_AFFLVL_MASK;
+ assert(parent_aff_id == 0);
+
+ /* Fetch the starting index in the aff1 array */
+ for (ctr = 0;
+ sunxi_aff2_topology_map[ctr].sibling != AFFINST_INVAL;
+ ctr = sunxi_aff2_topology_map[ctr].sibling) {
+ aff_count++;
+ }
+
+ /*
+ * Report that we implement a single instance of
+ * affinity levels 2 & 3 which are AFF_ABSENT
+ */
+ break;
+ case 1:
+ /* Assert if the parent affinity instance is not 0. */
+ parent_aff_id = (mpidr >> MPIDR_AFF2_SHIFT) & MPIDR_AFFLVL_MASK;
+ assert(parent_aff_id == 0);
+
+ /* Fetch the starting index in the aff1 array */
+ for (ctr = 0;
+ sunxi_aff1_topology_map[ctr].sibling != AFFINST_INVAL;
+ ctr = sunxi_aff1_topology_map[ctr].sibling) {
+ aff_count++;
+ }
+
+ break;
+ case 0:
+ /* Assert if the cluster id is anything apart from 0 or 1 */
+ parent_aff_id = (mpidr >> MPIDR_AFF1_SHIFT) & MPIDR_AFFLVL_MASK;
+ assert(parent_aff_id < PLATFORM_CLUSTER_COUNT);
+
+ /* Fetch the starting index in the aff0 array */
+ for (ctr = sunxi_aff1_topology_map[parent_aff_id].child;
+ sunxi_aff0_topology_map[ctr].sibling != AFFINST_INVAL;
+ ctr = sunxi_aff0_topology_map[ctr].sibling) {
+ aff_count++;
+ }
+
+ break;
+ default:
+ assert(0);
+ }
+
+ return aff_count;
+}
+
+/*******************************************************************************
+ * This function implements a part of the critical interface between the psci
+ * generic layer and the platform to allow the former to detect the state of a
+ * affinity instance in the platform topology. psci queries the platform to
+ * determine whether an affinity instance is present or absent. This caters for
+ * topologies where an intermediate affinity level instance is missing e.g.
+ * consider a platform which implements a single cluster with 4 cpus and there
+ * is another cpu sitting directly on the interconnect along with the cluster.
+ * The mpidrs of the cluster would range from 0x0-0x3. The mpidr of the single
+ * cpu would be 0x100 to highlight that it does not belong to cluster 0. Cluster
+ * 1 is however missing but needs to be accounted to reach this single cpu in
+ * the topology tree. Hence it will be marked as PSCI_AFF_ABSENT. This is not
+ * applicable to the FVP but depicted as an example.
+ ******************************************************************************/
+unsigned int plat_get_aff_state(unsigned int aff_lvl,
+ unsigned long mpidr)
+{
+ unsigned int aff_state = PSCI_AFF_ABSENT, idx;
+ idx = (mpidr >> MPIDR_AFF1_SHIFT) & MPIDR_AFFLVL_MASK;
+
+ assert(topology_setup_done == 1);
+
+ switch (aff_lvl) {
+ case 3:
+ case 2:
+ aff_state = sunxi_aff2_topology_map[0].state;
+ /* Report affinity levels 2 & 3 as absent */
+ break;
+ case 1:
+ aff_state = sunxi_aff1_topology_map[idx].state;
+ break;
+ case 0:
+ /*
+ * First get start index of the aff0 in its array & then add
+ * to it the affinity id that we want the state of
+ */
+ idx = sunxi_aff1_topology_map[idx].child;
+ idx += (mpidr >> MPIDR_AFF0_SHIFT) & MPIDR_AFFLVL_MASK;
+ aff_state = sunxi_aff0_topology_map[idx].state;
+ break;
+ default:
+ assert(0);
+ }
+
+ return aff_state;
+}
+
+/*******************************************************************************
+ * Handy optimization to prevent the psci implementation from traversing through
+ * affinity levels which are not present while detecting the platform topology.
+ ******************************************************************************/
+int plat_get_max_afflvl(void)
+{
+ return MPIDR_MAX_AFFLVL;
+}
+
+/*******************************************************************************
+ * This function populates the FVP specific topology information depending upon
+ * the FVP flavour its running on. We construct all the mpidrs we can handle
+ * and rely on the PWRC.PSYSR to flag absent cpus when their status is queried.
+ ******************************************************************************/
+int sunxi_setup_topology(void)
+{
+ unsigned char aff0, aff1, aff_state, aff0_offset = 0;
+ unsigned long mpidr;
+
+ topology_setup_done = 0;
+
+ sunxi_aff2_topology_map[0].child = 0;
+ sunxi_aff2_topology_map[0].sibling = AFFINST_INVAL;
+ sunxi_aff2_topology_map[0].state = PSCI_AFF_PRESENT;
+
+
+ for (aff1 = 0; aff1 < PLATFORM_CLUSTER_COUNT; aff1++) {
+
+ sunxi_aff1_topology_map[aff1].child = aff0_offset;
+ sunxi_aff1_topology_map[aff1].sibling = aff1 + 1;
+
+ for (aff0 = 0; aff0 < PLATFORM_MAX_CPUS_PER_CLUSTER; aff0++) {
+
+ mpidr = aff1 << MPIDR_AFF1_SHIFT;
+ mpidr |= aff0 << MPIDR_AFF0_SHIFT;
+
+ if (1) {
+ /*
+ * Presence of even a single aff0 indicates
+ * presence of parent aff1 on the FVP.
+ */
+ aff_state = PSCI_AFF_PRESENT;
+ sunxi_aff1_topology_map[aff1].state =
+ PSCI_AFF_PRESENT;
+ } else {
+ aff_state = PSCI_AFF_ABSENT;
+ }
+
+ sunxi_aff0_topology_map[aff0_offset].child = AFFINST_INVAL;
+ sunxi_aff0_topology_map[aff0_offset].state = aff_state;
+ sunxi_aff0_topology_map[aff0_offset].sibling =
+ aff0_offset + 1;
+
+ /* Increment the absolute number of aff0s traversed */
+ aff0_offset++;
+ }
+
+ /* Tie-off the last aff0 sibling to -1 to avoid overflow */
+ sunxi_aff0_topology_map[aff0_offset - 1].sibling = AFFINST_INVAL;
+ }
+
+ /* Tie-off the last aff1 sibling to AFFINST_INVAL to avoid overflow */
+ sunxi_aff1_topology_map[aff1 - 1].sibling = AFFINST_INVAL;
+
+ topology_setup_done = 1;
+ return 0;
+}
diff --git a/plat/sun50iw1p1/platform.mk b/plat/sun50iw1p1/platform.mk
new file mode 100644
index 0000000..b250d20
--- /dev/null
+++ b/plat/sun50iw1p1/platform.mk
@@ -0,0 +1,91 @@
+#
+# Copyright (c) 2013-2014, ARM Limited and Contributors. All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions are met:
+#
+# Redistributions of source code must retain the above copyright notice, this
+# list of conditions and the following disclaimer.
+#
+# Redistributions in binary form must reproduce the above copyright notice,
+# this list of conditions and the following disclaimer in the documentation
+# and/or other materials provided with the distribution.
+#
+# Neither the name of ARM nor the names of its contributors may be used
+# to endorse or promote products derived from this software without specific
+# prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+# POSSIBILITY OF SUCH DAMAGE.
+#
+
+# Shared memory may be allocated at the top of Trusted SRAM (tsram) or at the
+# base of Trusted SRAM (tdram)
+SUNXI_SHARED_DATA_LOCATION := tdram
+ifeq (${SUNXI_SHARED_DATA_LOCATION}, tsram)
+ SUNXI_SHARED_DATA_LOCATION_ID := SUNXI_IN_TRUSTED_SRAM
+else ifeq (${SUNXI_SHARED_DATA_LOCATION}, tdram)
+ SUNXI_SHARED_DATA_LOCATION_ID := SUNXI_IN_TRUSTED_DRAM
+else
+ $(error "Unsupported SUNXI_SHARED_DATA_LOCATION value")
+endif
+
+# On FVP, the TSP can execute either from Trusted SRAM or Trusted DRAM.
+# Trusted SRAM is the default.
+SUNXI_TSP_RAM_LOCATION := tdram
+ifeq (${SUNXI_TSP_RAM_LOCATION}, tsram)
+ SUNXI_TSP_RAM_LOCATION_ID := SUNXI_IN_TRUSTED_SRAM
+else ifeq (${SUNXI_TSP_RAM_LOCATION}, tdram)
+ SUNXI_TSP_RAM_LOCATION_ID := SUNXI_IN_TRUSTED_DRAM
+else
+ $(error "Unsupported SUNXI_TSP_RAM_LOCATION value")
+endif
+
+ifeq (${SUNXI_SHARED_DATA_LOCATION}, tsram)
+ ifeq (${SUNXI_TSP_RAM_LOCATION}, tdram)
+ $(error Shared data in Trusted SRAM and TSP in Trusted DRAM is not supported)
+ endif
+endif
+
+# Process flags
+$(eval $(call add_define,SUNXI_SHARED_DATA_LOCATION_ID))
+$(eval $(call add_define,SUNXI_TSP_RAM_LOCATION_ID))
+
+PLAT_INCLUDES := -Iplat/sun50iw1p1/include/
+
+
+PLAT_BL_COMMON_SOURCES := lib/aarch64/xlat_tables.c \
+ plat/common/aarch64/plat_common.c \
+ plat/sun50iw1p1/drivers/uart/uart.c \
+ plat/sun50iw1p1/drivers/gpio/gpio.c
+
+
+
+BL31_SOURCES += drivers/arm/cci400/cci400.c \
+ drivers/arm/gic/gic_v2.c \
+ lib/cpus/aarch64/aem_generic.S \
+ lib/cpus/aarch64/cortex_a53.S \
+ lib/cpus/aarch64/cortex_a57.S \
+ plat/common/aarch64/platform_mp_stack.S \
+ plat/sun50iw1p1/bl31_sunxi_setup.c \
+ plat/sun50iw1p1/plat_pm.c \
+ plat/sun50iw1p1/plat_gic.c \
+ plat/sun50iw1p1/mhu.c \
+ plat/sun50iw1p1/scpi.c \
+ plat/sun50iw1p1/sunxi_security.c \
+ plat/sun50iw1p1/sunxi_cpu_ops.c \
+ plat/sun50iw1p1/plat_topology.c \
+ plat/sun50iw1p1/aarch64/plat_helpers.S \
+ plat/sun50iw1p1/aarch64/sunxi_common.c \
+ services/arm/arm_svc_setup.c
+
+include plat/${PLAT}/scp/arisc.mk
diff --git a/plat/sun50iw1p1/scp/arisc.c b/plat/sun50iw1p1/scp/arisc.c
new file mode 100644
index 0000000..1430b7e
--- /dev/null
+++ b/plat/sun50iw1p1/scp/arisc.c
@@ -0,0 +1,248 @@
+/*
+ * drivers/arisc/arisc.c
+ *
+ * Copyright (c) 2012 Allwinner.
+ * 2012-10-01 Written by superm (superm@allwinnertech.com).
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#include "arisc_i.h"
+
+/* local functions */
+static int arisc_wait_ready(unsigned int timeout);
+
+struct dts_cfg dts_cfg;
+unsigned int arisc_debug_dram_crc_en = 0;
+unsigned int arisc_debug_dram_crc_srcaddr = 0x40000000;
+unsigned int arisc_debug_dram_crc_len = (1024 * 1024);
+unsigned int arisc_debug_dram_crc_error = 0;
+unsigned int arisc_debug_dram_crc_total_count = 0;
+unsigned int arisc_debug_dram_crc_error_count = 0;
+volatile const unsigned int arisc_debug_level = 2;
+static unsigned char arisc_version[40] = "arisc defualt version";
+
+static int arisc_wait_ready(unsigned int timeout)
+{
+ /* wait arisc startup ready */
+ while (1) {
+ /*
+ * linux cpu interrupt is disable now,
+ * we should query message by hand.
+ */
+ struct arisc_message *pmessage = arisc_hwmsgbox_query_message();
+ if (pmessage == NULL) {
+ /* try to query again */
+ continue;
+ }
+ /* query valid message */
+ if (pmessage->type == ARISC_STARTUP_NOTIFY) {
+ /* check arisc software and driver version match or not */
+ if (pmessage->paras[0] != ARISC_VERSIONS) {
+ ARISC_ERR("arisc firmware:%d and driver version:%u not matched\n", pmessage->paras[0], ARISC_VERSIONS);
+ return -EINVAL;
+ } else {
+ /* printf the main and sub version string */
+ memcpy((void *)arisc_version, (const void*)(&(pmessage->paras[1])), 40);
+ ARISC_LOG("arisc version: [%s]\n", arisc_version);
+ }
+
+ /* received arisc startup ready message */
+ ARISC_INF("arisc startup ready\n");
+ if ((pmessage->attr & ARISC_MESSAGE_ATTR_SOFTSYN) ||
+ (pmessage->attr & ARISC_MESSAGE_ATTR_HARDSYN)) {
+ /* synchronous message, just feedback it */
+ ARISC_INF("arisc startup notify message feedback\n");
+ pmessage->paras[0] = (uint32_t)dts_cfg.image.base;
+ arisc_hwmsgbox_feedback_message(pmessage, ARISC_SEND_MSG_TIMEOUT);
+ } else {
+ /* asyn message, free message directly */
+ ARISC_INF("arisc startup notify message free directly\n");
+ arisc_message_free(pmessage);
+ }
+ break;
+ }
+ /*
+ * invalid message detected, ignore it.
+ * by superm at 2012-7-6 18:34:38.
+ */
+ ARISC_WRN("arisc startup waiting ignore message\n");
+ if ((pmessage->attr & ARISC_MESSAGE_ATTR_SOFTSYN) ||
+ (pmessage->attr & ARISC_MESSAGE_ATTR_HARDSYN)) {
+ /* synchronous message, just feedback it */
+ arisc_hwmsgbox_send_message(pmessage, ARISC_SEND_MSG_TIMEOUT);
+ } else {
+ /* asyn message, free message directly */
+ arisc_message_free(pmessage);
+ }
+ /* we need waiting continue */
+ }
+
+ return 0;
+}
+
+int sunxi_deassert_arisc(void)
+{
+ ARISC_INF("set arisc reset to de-assert state\n");
+ {
+ volatile unsigned long value;
+ value = readl(dts_cfg.cpuscfg.base + 0x0);
+ value &= ~1;
+ writel(value, dts_cfg.cpuscfg.base + 0x0);
+ value = readl(dts_cfg.cpuscfg.base + 0x0);
+ value |= 1;
+ writel(value, dts_cfg.cpuscfg.base + 0x0);
+ }
+
+ return 0;
+}
+
+static int sunxi_arisc_para_init(struct arisc_para *para)
+{
+ /* init para */
+ memset(para, 0, sizeof(struct arisc_para));
+ para->message_pool_phys = (uint32_t)dts_cfg.space.msgpool_dst;
+ para->message_pool_size = (uint32_t)dts_cfg.space.msgpool_size;
+ para->standby_base = (uint32_t)dts_cfg.space.standby_dst;
+ para->standby_size = (uint32_t)dts_cfg.space.standby_size;
+ memcpy((void *)&para->vf, (void *)dts_cfg.vf, sizeof(para->vf));
+ memcpy((void *)&para->dram_para, (void *)&dts_cfg.dram_para, sizeof(para->dram_para));
+ para->power_key_code = dts_cfg.s_cir.power_key_code;
+ para->addr_code = dts_cfg.s_cir.addr_code;
+ para->suart_status = dts_cfg.s_uart.status;
+ para->pmu_bat_shutdown_ltf = dts_cfg.pmu.pmu_bat_shutdown_ltf;
+ para->pmu_bat_shutdown_htf = dts_cfg.pmu.pmu_bat_shutdown_htf;
+ para->pmu_pwroff_vol = dts_cfg.pmu.pmu_pwroff_vol;
+ para->power_start = dts_cfg.pmu.power_start;
+ para->powchk_used = dts_cfg.power.powchk_used;
+ para->power_reg = dts_cfg.power.power_reg;
+ para->system_power = dts_cfg.power.system_power;
+
+ ARISC_LOG("arisc_para size:%llx\n", sizeof(struct arisc_para));
+ ARISC_INF("msgpool base:%x, size:%u\n", para->message_pool_phys,
+ para->message_pool_size);
+
+ return 0;
+}
+
+uint32_t sunxi_load_arisc(uintptr_t image_addr, size_t image_size, void *para, size_t para_size)
+{
+ void *dst;
+ void *src;
+ size_t size;
+
+#if 0
+ /*
+ * phys addr to virt addr
+ * io space: ioremap
+ * kernel space: phys_to_virt
+ */
+ /* sram code space */
+ dst = (void *)dts_cfg.space.sram_dst;
+ src = (void *)((ptrdiff_t)image_addr + (ptrdiff_t)dts_cfg.space.sram_offset);
+ size = dts_cfg.space.sram_size;
+ memset(dst, 0, size);
+ memcpy(dst, src, size);
+ flush_dcache_range((uint64_t)dst, (uint64_t)size);
+
+ /* dram code space */
+ dst = (void *)dts_cfg.space.dram_dst;
+ src = (void *)((ptrdiff_t)image_addr + (ptrdiff_t)dts_cfg.space.dram_offset);
+ size = dts_cfg.space.dram_size;
+ memset(dst, 0, size);
+ memcpy(dst, src, size);
+ flush_dcache_range((uint64_t)dst, (uint64_t)size);
+
+ ARISC_INF("load arisc image finish\n");
+#endif
+ /* para space */
+ dst = (void *)dts_cfg.space.para_dst;
+ src = para;
+ size = dts_cfg.space.para_size;
+ memset(dst, 0, size);
+ memcpy(dst, src, size);
+ ARISC_INF("setup arisc para finish\n");
+ //dcsw_op_all(DCCISW);
+ flush_dcache_range((uint64_t)dst, (uint64_t)size);
+ isb();
+
+#if 0
+ /* relese arisc reset */
+ sunxi_deassert_arisc();
+ ARISC_INF("release arisc reset finish\n");
+
+ ARISC_INF("load arisc finish\n");
+#endif
+
+ return 0;
+}
+
+int sunxi_arisc_probe(void *cfg)
+{
+ struct arisc_para para;
+
+ ARISC_LOG("sunxi-arisc driver begin startup %d\n", arisc_debug_level);
+ memcpy((void *)&dts_cfg, (const void *)cfg, sizeof(struct dts_cfg));
+
+ /* init arisc parameter */
+ sunxi_arisc_para_init(&para);
+
+ /* load arisc */
+ sunxi_load_arisc(dts_cfg.image.base, dts_cfg.image.size,
+ (void *)(&para), sizeof(struct arisc_para));
+
+ /* initialize hwspinlock */
+ ARISC_INF("hwspinlock initialize\n");
+ arisc_hwspinlock_init();
+
+ /* initialize hwmsgbox */
+ ARISC_INF("hwmsgbox initialize\n");
+ arisc_hwmsgbox_init();
+
+ /* initialize message manager */
+ ARISC_INF("message manager initialize start:0x%llx, size:0x%llx\n", dts_cfg.space.msgpool_dst, dts_cfg.space.msgpool_size);
+ arisc_message_manager_init((void *)dts_cfg.space.msgpool_dst, dts_cfg.space.msgpool_size);
+
+ /* wait arisc ready */
+ ARISC_INF("wait arisc ready....\n");
+ if (arisc_wait_ready(10000)) {
+ ARISC_LOG("arisc startup failed\n");
+ }
+
+ arisc_set_paras();
+
+ /* enable arisc asyn tx interrupt */
+ //arisc_hwmsgbox_enable_receiver_int(ARISC_HWMSGBOX_ARISC_ASYN_TX_CH, AW_HWMSG_QUEUE_USER_AC327);
+
+ /* enable arisc syn tx interrupt */
+ //arisc_hwmsgbox_enable_receiver_int(ARISC_HWMSGBOX_ARISC_SYN_TX_CH, AW_HWMSG_QUEUE_USER_AC327);
+
+ /* arisc initialize succeeded */
+ ARISC_LOG("sunxi-arisc driver v%s is starting\n", DRV_VERSION);
+
+ return 0;
+}
+
+int sunxi_arisc_wait_ready(void)
+{
+ ARISC_INF("wait arisc ready....\n");
+ if (arisc_wait_ready(10000)) {
+ ARISC_LOG("arisc startup failed\n");
+ }
+ arisc_set_paras();
+ ARISC_LOG("sunxi-arisc driver v%s startup ok\n", DRV_VERSION);
+ return 0;
+}
+
diff --git a/plat/sun50iw1p1/scp/arisc.mk b/plat/sun50iw1p1/scp/arisc.mk
new file mode 100644
index 0000000..f75311c
--- /dev/null
+++ b/plat/sun50iw1p1/scp/arisc.mk
@@ -0,0 +1,35 @@
+#
+# Copyright (c) 2013-2014, ARM Limited and Contributors. All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions are met:
+#
+# Redistributions of source code must retain the above copyright notice, this
+# list of conditions and the following disclaimer.
+#
+# Redistributions in binary form must reproduce the above copyright notice,
+# this list of conditions and the following disclaimer in the documentation
+# and/or other materials provided with the distribution.
+#
+# Neither the name of ARM nor the names of its contributors may be used
+# to endorse or promote products derived from this software without specific
+# prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+# POSSIBILITY OF SUCH DAMAGE.
+#
+BL31_SOURCES += plat/sun50iw1p1/scp/arisc.c
+
+include plat/sun50iw1p1/scp/hwmsgbox/hwmsgbox.mk
+include plat/sun50iw1p1/scp/hwspinlock/hwspinlock.mk
+include plat/sun50iw1p1/scp/message_manager/message_manager.mk
+include plat/sun50iw1p1/scp/interfaces/interfaces.mk
diff --git a/plat/sun50iw1p1/scp/arisc_i.h b/plat/sun50iw1p1/scp/arisc_i.h
new file mode 100644
index 0000000..f44ffc1
--- /dev/null
+++ b/plat/sun50iw1p1/scp/arisc_i.h
@@ -0,0 +1,84 @@
+/*
+ * arch/arm/mach-sun6i/arisc/arisc_i.h
+ *
+ * Copyright (c) 2012 Allwinner.
+ * 2012-10-01 Written by superm (superm@allwinnertech.com).
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#ifndef __ARISC_I_H__
+#define __ARISC_I_H__
+
+//#include <asm/atomic.h>
+//#include <asm/barrier.h>
+//#include <asm/memory.h>
+//#include <linux/arisc/arisc.h>
+//#include <linux/sysfs.h>
+//#include <linux/device.h>
+//#include <linux/gpio.h>
+//#include <linux/pinctrl/consumer.h>
+//#include <linux/module.h>
+//#include <linux/platform_device.h>
+//#include <linux/delay.h>
+//#include <linux/clk.h>
+//#include <linux/arisc/arisc-notifier.h>
+//#include <linux/of_address.h>
+//#include <linux/of_irq.h>
+//#include <linux/of_platform.h>
+
+#include "./include/arisc_includes.h"
+
+#define DRV_NAME "sunxi-arisc"
+#define DEV_NAME "sunxi-arisc"
+
+#if defined CONFIG_ARCH_SUN8IW1P1
+#define DRV_VERSION "1.00"
+#elif defined CONFIG_ARCH_SUN8IW3P1
+#define DRV_VERSION "1.01"
+#elif defined CONFIG_ARCH_SUN8IW5P1
+#define DRV_VERSION "1.02"
+#elif defined CONFIG_ARCH_SUN8IW6P1
+#define DRV_VERSION "1.03"
+#elif defined CONFIG_ARCH_SUN8IW7P1
+#define DRV_VERSION "1.04"
+#elif defined CONFIG_ARCH_SUN8IW9P1
+#define DRV_VERSION "1.05"
+#elif defined CONFIG_ARCH_SUN50IW1P1
+#define DRV_VERSION "1.10"
+#elif defined CONFIG_ARCH_SUN9IW1P1
+#define DRV_VERSION "2.00"
+#else
+#error "please select a platform\n"
+#endif
+
+extern unsigned int arisc_debug_dram_crc_en;
+extern unsigned int arisc_debug_dram_crc_srcaddr;
+extern unsigned int arisc_debug_dram_crc_len;
+extern unsigned int arisc_debug_dram_crc_error;
+extern unsigned int arisc_debug_dram_crc_total_count;
+extern unsigned int arisc_debug_dram_crc_error_count;
+extern volatile const unsigned int arisc_debug_level;
+extern struct standby_info_para arisc_powchk_back;
+
+//local functions
+extern int arisc_config_dram_paras(void);
+extern int arisc_sysconfig_ir_paras(void);
+extern int arisc_config_pmu_paras(void);
+extern int arisc_suspend_flag_query(void);
+#if (defined CONFIG_ARCH_SUN8IW7P1)
+extern void arisc_power_off(void);
+#endif
+#endif //__ARISC_I_H__
diff --git a/plat/sun50iw1p1/scp/hwmsgbox/hwmsgbox.c b/plat/sun50iw1p1/scp/hwmsgbox/hwmsgbox.c
new file mode 100644
index 0000000..f1bc032
--- /dev/null
+++ b/plat/sun50iw1p1/scp/hwmsgbox/hwmsgbox.c
@@ -0,0 +1,291 @@
+/*
+ * arch/arm/mach-sunxi/arisc/hwmsgbox/hwmsgbox.c
+ *
+ * Copyright (c) 2012 Allwinner.
+ * 2012-10-01 Written by superm (superm@allwinnertech.com).
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#include "hwmsgbox_i.h"
+
+/* spinlock for syn and asyn channel */
+static spinlock_t syn_channel_lock;
+static spinlock_t asyn_channel_lock;
+static uintptr_t base;
+
+/**
+ * initialize hwmsgbox.
+ * @para: none.
+ *
+ * returns: 0 if initialize hwmsgbox succeeded, others if failed.
+ */
+int arisc_hwmsgbox_init(void)
+{
+ base = dts_cfg.msgbox.base;
+
+ /* initialize syn and asyn spinlock */
+ //writel(0xffffffff, base + AW_MSGBOX_IRQ_STATUS_REG(AW_HWMSG_QUEUE_USER_AC327));
+ //writel(0x0, base + AW_MSGBOX_IRQ_EN_REG(AW_HWMSG_QUEUE_USER_AC327));
+
+ return 0;
+}
+
+/**
+ * exit hwmsgbox.
+ * @para: none.
+ *
+ * returns: 0 if exit hwmsgbox succeeded, others if failed.
+ */
+int arisc_hwmsgbox_exit(void)
+{
+ return 0;
+}
+
+/**
+ * send one message to another processor by hwmsgbox.
+ * @pmessage: the pointer of sended message frame.
+ * @timeout: the wait time limit when message fifo is full, it is valid only when parameter mode = HWMSG_SEND_WAIT_TIMEOUT.
+ *
+ * returns: 0 if send message succeeded, other if failed.
+ */
+int arisc_hwmsgbox_send_message(struct arisc_message *pmessage, unsigned int timeout)
+{
+ volatile uint32_t value;
+
+ if (pmessage == NULL) {
+ return -EINVAL;
+ }
+ if (pmessage->attr & ARISC_MESSAGE_ATTR_HARDSYN) {
+ /* use ac327 hwsyn transmit channel */
+ spin_lock(&syn_channel_lock);
+ while (readl(base + AW_MSGBOX_FIFO_STATUS_REG(ARISC_HWMSGBOX_AC327_SYN_TX_CH)) == 1);
+
+ value = arisc_message_map_to_cpus(pmessage);
+ ARISC_INF("ac327 send hard syn message : %x\n", (unsigned int)value);
+ writel(value, base + AW_MSGBOX_MSG_REG(ARISC_HWMSGBOX_AC327_SYN_TX_CH));
+
+ /* hwsyn messsage must feedback use syn rx channel */
+ while (readl(base + AW_MSGBOX_MSG_STATUS_REG(ARISC_HWMSGBOX_AC327_SYN_RX_CH)) == 0);
+
+ /* check message valid */
+ if (value != (readl(base + AW_MSGBOX_MSG_REG(ARISC_HWMSGBOX_AC327_SYN_RX_CH)))) {
+ ARISC_ERR("hard syn message error [%x, %x]\n", (uint32_t)value, (uint32_t)(readl(base + AW_MSGBOX_MSG_REG(ARISC_HWMSGBOX_AC327_SYN_RX_CH))));
+ spin_unlock(&syn_channel_lock);
+ return -EINVAL;
+ }
+ ARISC_INF("ac327 hard syn message [%x, %x] feedback\n", (unsigned int)value, (unsigned int)pmessage->type);
+ /* if error call the callback function. by superm */
+ if(pmessage->result != 0) {
+ ARISC_ERR("message process error\n");
+ ARISC_ERR("message addr : %llx\n", pmessage);
+ ARISC_ERR("message state : %x\n", pmessage->state);
+ ARISC_ERR("message attr : %x\n", pmessage->attr);
+ ARISC_ERR("message type : %x\n", pmessage->type);
+ ARISC_ERR("message result : %x\n", pmessage->result);
+ if (pmessage->cb.handler == NULL) {
+ ARISC_WRN("callback not install\n");
+ } else {
+ /* call callback function */
+ ARISC_WRN("call the callback function\n");
+ (*(pmessage->cb.handler))(pmessage->cb.arg);
+ }
+ }
+ spin_unlock(&syn_channel_lock);
+ return 0;
+ }
+
+ /* use ac327 asyn transmit channel */
+ spin_lock(&asyn_channel_lock);
+ while (readl(base + AW_MSGBOX_FIFO_STATUS_REG(ARISC_HWMSGBOX_ARISC_ASYN_RX_CH)) == 1);
+
+ /* write message to message-queue fifo */
+ value = arisc_message_map_to_cpus(pmessage);
+ ARISC_INF("ac327 send message : %x\n", (unsigned int)value);
+ writel(value, base + AW_MSGBOX_MSG_REG(ARISC_HWMSGBOX_ARISC_ASYN_RX_CH));
+ spin_unlock(&asyn_channel_lock);
+
+ return 0;
+}
+
+int arisc_hwmsgbox_feedback_message(struct arisc_message *pmessage, unsigned int timeout)
+{
+ volatile unsigned long value;
+
+ if (pmessage->attr & ARISC_MESSAGE_ATTR_HARDSYN) {
+ /* use ac327 hard syn receiver channel */
+ spin_lock(&syn_channel_lock);
+ while (readl(base + AW_MSGBOX_FIFO_STATUS_REG(ARISC_HWMSGBOX_ARISC_SYN_RX_CH)) == 1);
+
+ value = arisc_message_map_to_cpus(pmessage);
+ ARISC_INF("arisc feedback hard syn message : %x\n", (unsigned int)value);
+ writel(value, base + AW_MSGBOX_MSG_REG(ARISC_HWMSGBOX_ARISC_SYN_RX_CH));
+ spin_unlock(&syn_channel_lock);
+
+ return 0;
+ }
+
+ /* invalid syn message */
+ return -EINVAL;
+}
+
+/**
+ * enbale the receiver interrupt of message-queue.
+ * @queue: the number of message-queue which we want to enable interrupt.
+ * @user: the user which we want to enable interrupt.
+ *
+ * returns: 0 if enable interrupt succeeded, others if failed.
+ */
+int arisc_hwmsgbox_enable_receiver_int(int queue, int user)
+{
+ volatile unsigned int value;
+
+ value = readl(base + AW_MSGBOX_IRQ_EN_REG(user));
+ value &= ~(0x1 << (queue * 2));
+ value |= (0x1 << (queue * 2));
+ writel(value, base + AW_MSGBOX_IRQ_EN_REG(user));
+
+ return 0;
+}
+
+/**
+ * disbale the receiver interrupt of message-queue.
+ * @queue: the number of message-queue which we want to enable interrupt.
+ * @user: the user which we want to enable interrupt.
+ *
+ * returns: 0 if disable interrupt succeeded, others if failed.
+ */
+int arisc_hwmsgbox_disable_receiver_int(int queue, int user)
+{
+ volatile unsigned int value;
+
+ value = readl(base + AW_MSGBOX_IRQ_EN_REG(user));
+ value &= ~(0x1 << (queue * 2));
+ writel(value, base + AW_MSGBOX_IRQ_EN_REG(user));
+
+ return 0;
+}
+
+/**
+ * query the receiver interrupt pending of message-queue.
+ * @queue: the number of message-queue which we want to query.
+ * @user: the user which we want to query.
+ *
+ * returns: 0 if query pending succeeded, others if failed.
+ */
+int arisc_hwmsgbox_query_receiver_pending(int queue, int user)
+{
+ volatile unsigned long value;
+
+ value = readl(base + (AW_MSGBOX_IRQ_STATUS_REG(user)));
+
+ return value & (0x1 << (queue * 2));
+}
+
+/**
+ * clear the receiver interrupt pending of message-queue.
+ * @queue: the number of message-queue which we want to clear.
+ * @user: the user which we want to clear.
+ *
+ * returns: 0 if clear pending succeeded, others if failed.
+ */
+int arisc_hwmsgbox_clear_receiver_pending(int queue, int user)
+{
+ writel((0x1 << (queue * 2)), base + AW_MSGBOX_IRQ_STATUS_REG(user));
+
+ return 0;
+}
+
+/**
+ * query message of hwmsgbox by hand, mainly for.
+ * @para: none.
+ *
+ * returns: the point of message, NULL if timeout.
+ */
+struct arisc_message *arisc_hwmsgbox_query_message(void)
+{
+ struct arisc_message *pmessage = NULL;
+
+ /* query ac327 asyn received channel */
+ if (readl(base + AW_MSGBOX_MSG_STATUS_REG(ARISC_HWMSGBOX_ARISC_ASYN_TX_CH))) {
+ volatile unsigned long value;
+ value = readl(base + AW_MSGBOX_MSG_REG(ARISC_HWMSGBOX_ARISC_ASYN_TX_CH));
+ pmessage = arisc_message_map_to_cpux(value);
+
+ if (arisc_message_valid(pmessage)) {
+ /* message state switch */
+ if (pmessage->state == ARISC_MESSAGE_PROCESSED) {
+ /* ARISC_MESSAGE_PROCESSED->ARISC_MESSAGE_FEEDBACKED */
+ pmessage->state = ARISC_MESSAGE_FEEDBACKED;
+ } else {
+ /* ARISC_MESSAGE_INITIALIZED->ARISC_MESSAGE_RECEIVED */
+ pmessage->state = ARISC_MESSAGE_RECEIVED;
+ }
+ } else {
+ ARISC_ERR("invalid asyn message received: pmessage = 0x%llx. \n", pmessage);
+ return NULL;
+ }
+ /* clear pending */
+ arisc_hwmsgbox_clear_receiver_pending(ARISC_HWMSGBOX_ARISC_ASYN_TX_CH, AW_HWMSG_QUEUE_USER_AC327);
+ return pmessage;
+ }
+ /* query ac327 syn received channel */
+ if (readl(base + AW_MSGBOX_MSG_STATUS_REG(ARISC_HWMSGBOX_ARISC_SYN_TX_CH))) {
+ volatile unsigned long value;
+ value = readl(base + AW_MSGBOX_MSG_REG(ARISC_HWMSGBOX_ARISC_SYN_TX_CH));
+ pmessage = arisc_message_map_to_cpux(value);
+ if (arisc_message_valid(pmessage)) {
+ /* message state switch */
+ if (pmessage->state == ARISC_MESSAGE_PROCESSED) {
+ /* ARISC_MESSAGE_PROCESSED->ARISC_MESSAGE_FEEDBACKED */
+ pmessage->state = ARISC_MESSAGE_FEEDBACKED;
+ } else {
+ /* ARISC_MESSAGE_INITIALIZED->ARISC_MESSAGE_RECEIVED */
+ pmessage->state = ARISC_MESSAGE_RECEIVED;
+ }
+ } else {
+ ARISC_ERR("invalid syn message received: pmessage = 0x%llx. \n", pmessage);
+ arisc_hwmsgbox_clear_receiver_pending(ARISC_HWMSGBOX_ARISC_SYN_TX_CH, AW_HWMSG_QUEUE_USER_AC327);
+ return NULL;
+ }
+ arisc_hwmsgbox_clear_receiver_pending(ARISC_HWMSGBOX_ARISC_SYN_TX_CH, AW_HWMSG_QUEUE_USER_AC327);
+ return pmessage;
+ }
+
+ /* no valid message now */
+ return NULL;
+}
+
+int arisc_hwmsgbox_standby_suspend(void)
+{
+ /* enable arisc asyn tx interrupt */
+ //arisc_hwmsgbox_disable_receiver_int(ARISC_HWMSGBOX_ARISC_ASYN_TX_CH, AW_HWMSG_QUEUE_USER_AC327);
+
+ /* enable arisc syn tx interrupt */
+ //arisc_hwmsgbox_disable_receiver_int(ARISC_HWMSGBOX_ARISC_SYN_TX_CH, AW_HWMSG_QUEUE_USER_AC327);
+
+ return 0;
+}
+
+int arisc_hwmsgbox_standby_resume(void)
+{
+ /* enable arisc asyn tx interrupt */
+ //arisc_hwmsgbox_enable_receiver_int(ARISC_HWMSGBOX_ARISC_ASYN_TX_CH, AW_HWMSG_QUEUE_USER_AC327);
+
+ /* enable arisc syn tx interrupt */
+ //arisc_hwmsgbox_enable_receiver_int(ARISC_HWMSGBOX_ARISC_SYN_TX_CH, AW_HWMSG_QUEUE_USER_AC327);
+
+ return 0;
+}
diff --git a/plat/sun50iw1p1/scp/hwmsgbox/hwmsgbox.mk b/plat/sun50iw1p1/scp/hwmsgbox/hwmsgbox.mk
new file mode 100644
index 0000000..aebb5ec
--- /dev/null
+++ b/plat/sun50iw1p1/scp/hwmsgbox/hwmsgbox.mk
@@ -0,0 +1,31 @@
+#
+# Copyright (c) 2013-2014, ARM Limited and Contributors. All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions are met:
+#
+# Redistributions of source code must retain the above copyright notice, this
+# list of conditions and the following disclaimer.
+#
+# Redistributions in binary form must reproduce the above copyright notice,
+# this list of conditions and the following disclaimer in the documentation
+# and/or other materials provided with the distribution.
+#
+# Neither the name of ARM nor the names of its contributors may be used
+# to endorse or promote products derived from this software without specific
+# prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+# POSSIBILITY OF SUCH DAMAGE.
+#
+
+BL31_SOURCES += plat/sun50iw1p1/scp/hwmsgbox/hwmsgbox.c
diff --git a/plat/sun50iw1p1/scp/hwmsgbox/hwmsgbox_i.h b/plat/sun50iw1p1/scp/hwmsgbox/hwmsgbox_i.h
new file mode 100644
index 0000000..ffee2a9
--- /dev/null
+++ b/plat/sun50iw1p1/scp/hwmsgbox/hwmsgbox_i.h
@@ -0,0 +1,46 @@
+/*
+ * arch/arm/mach-sunxi/arisc/hwmsgbox/hwmsgbox_i.h
+ *
+ * Copyright (c) 2012 Allwinner.
+ * 2012-10-01 Written by superm (superm@allwinnertech.com).
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#ifndef __ARISC_HWMSGBOX_I_H
+#define __ARISC_HWMSGBOX_I_H
+
+#include "../include/arisc_includes.h"
+
+//hardware message-box register list
+#define AW_MSGBOX_CTRL_REG(m) (0x0000 + (0x4 * (m>>2)))
+#define AW_MSGBOX_IRQ_EN_REG(u) (0x0040 + (0x20* u))
+#define AW_MSGBOX_IRQ_STATUS_REG(u) (0x0050 + (0x20* u))
+#define AW_MSGBOX_FIFO_STATUS_REG(m) (0x0100 + (0x4 * m))
+#define AW_MSGBOX_MSG_STATUS_REG(m) (0x0140 + (0x4 * m))
+#define AW_MSGBOX_MSG_REG(m) (0x0180 + (0x4 * m))
+#define AW_MSGBOX_DEBUG_REG (0x01c0)
+
+/* local functions */
+int arisc_hwmsgbox_clear_receiver_pending(int queue, int user);
+int arisc_hwmsgbox_query_receiver_pending(int queue, int user);
+int arisc_hwmsgbox_enable_receiver_int(int queue, int user);
+int arisc_hwmsgbox_set_receiver(int queue, int user);
+int arisc_hwmsgbox_set_transmitter(int queue, int user);
+int arisc_hwmsgbox_wait_message_feedback(struct arisc_message *pmessage);
+int arisc_hwmsgbox_message_feedback(struct arisc_message *pmessage);
+int arisc_message_valid(struct arisc_message *pmessage);
+
+#endif /* __ARISC_HWMSGBOX_I_H */
diff --git a/plat/sun50iw1p1/scp/hwspinlock/hwspinlock.c b/plat/sun50iw1p1/scp/hwspinlock/hwspinlock.c
new file mode 100644
index 0000000..863d457
--- /dev/null
+++ b/plat/sun50iw1p1/scp/hwspinlock/hwspinlock.c
@@ -0,0 +1,109 @@
+/*
+ * arch/arm/mach-sunxi/arisc/hwspinlock/hwspinlock.c
+ *
+ * Copyright (c) 2012 Allwinner.
+ * 2012-10-01 Written by superm (superm@allwinnertech.com).
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#include "hwspinlock_i.h"
+
+static struct arisc_hwspinlock arisc_hwspinlocks[ARISC_HW_SPINLOCK_NUM];
+static uintptr_t base;
+
+/**
+ * initialize hwspinlock.
+ * @para: none.
+ *
+ * returns: 0 if initialize hwspinlock succeeded, others if failed.
+ */
+int arisc_hwspinlock_init(void)
+{
+ base = dts_cfg.hwspinlock.base;
+
+ return 0;
+}
+
+/**
+ * exit hwspinlock.
+ * @para:none.
+ *
+ * returns: 0 if exit hwspinlock succeeded, others if failed.
+ */
+int arisc_hwspinlock_exit(void)
+{
+ return 0;
+}
+
+/**
+ * lock an hwspinlock with timeout limit,
+ * and hwspinlock will be unlocked in arisc_hwspin_unlock().
+ * @hwid: an hwspinlock id which we want to lock.
+ *
+ * returns: 0 if lock hwspinlock succeeded, other if failed.
+ */
+int arisc_hwspin_lock(int hwid)
+{
+ arisc_hwspinlock_t *spinlock;
+
+ if (hwid >= ARISC_HW_SPINLOCK_NUM) {
+ ARISC_ERR("invalid hwspinlock id [%d] for trylock\n", hwid);
+ return -EINVAL;
+ }
+ spinlock = &(arisc_hwspinlocks[hwid]);
+
+ /* is lock already taken by another context on the local cpu ? */
+ spin_lock(&(spinlock->lock));
+
+ /* try to take spinlock */
+ while (readl(base + AW_SPINLOCK_LOCK_REG(hwid)) == AW_SPINLOCK_TAKEN);
+
+ return 0;
+}
+
+/**
+ * unlock a specific hwspinlock.
+ * hwid: an hwspinlock id which we want to unlock.
+ *
+ * returns: 0 if unlock hwspinlock succeeded, other if failed.
+ */
+int arisc_hwspin_unlock(int hwid)
+{
+ arisc_hwspinlock_t *spinlock;
+
+ if (hwid >= ARISC_HW_SPINLOCK_NUM) {
+ ARISC_ERR("invalid hwspinlock id [%d] for unlock\n", hwid);
+ return -EINVAL;
+ }
+ spinlock = &(arisc_hwspinlocks[hwid]);
+
+ /* untaken the spinlock */
+ writel(0x0, base + AW_SPINLOCK_LOCK_REG(hwid));
+
+ spin_unlock(&(spinlock->lock));
+
+ return 0;
+}
+
+int arisc_hwspinlock_standby_suspend(void)
+{
+ return 0;
+}
+
+int arisc_hwspinlock_standby_resume(void)
+{
+ return 0;
+}
diff --git a/plat/sun50iw1p1/scp/hwspinlock/hwspinlock.mk b/plat/sun50iw1p1/scp/hwspinlock/hwspinlock.mk
new file mode 100644
index 0000000..2c5ee59
--- /dev/null
+++ b/plat/sun50iw1p1/scp/hwspinlock/hwspinlock.mk
@@ -0,0 +1,31 @@
+#
+# Copyright (c) 2013-2014, ARM Limited and Contributors. All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions are met:
+#
+# Redistributions of source code must retain the above copyright notice, this
+# list of conditions and the following disclaimer.
+#
+# Redistributions in binary form must reproduce the above copyright notice,
+# this list of conditions and the following disclaimer in the documentation
+# and/or other materials provided with the distribution.
+#
+# Neither the name of ARM nor the names of its contributors may be used
+# to endorse or promote products derived from this software without specific
+# prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+# POSSIBILITY OF SUCH DAMAGE.
+#
+
+BL31_SOURCES += plat/sun50iw1p1/scp/hwspinlock/hwspinlock.c
diff --git a/plat/sun50iw1p1/scp/hwspinlock/hwspinlock_i.h b/plat/sun50iw1p1/scp/hwspinlock/hwspinlock_i.h
new file mode 100644
index 0000000..231d7ee
--- /dev/null
+++ b/plat/sun50iw1p1/scp/hwspinlock/hwspinlock_i.h
@@ -0,0 +1,48 @@
+/*
+ * arch/arm/mach-sunxi/arisc/hwspinlock/hwspinlock-i.h
+ *
+ * Copyright (c) 2012 Allwinner.
+ * 2012-10-01 Written by superm (superm@allwinnertech.com).
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#ifndef __HW_SPINLOCK_I_H
+#define __HW_SPINLOCK_I_H
+
+#include "../include/arisc_includes.h"
+
+/* the used state of spinlock */
+#define SPINLOCK_FREE (0)
+#define SPINLOCK_USED (1)
+
+//the taken ot not state of spinlock
+#define AW_SPINLOCK_NOTTAKEN (0)
+#define AW_SPINLOCK_TAKEN (1)
+
+//hardware spinlock register list
+#define AW_SPINLOCK_SYS_STATUS_REG (0x0000)
+#define AW_SPINLOCK_STATUS_REG (0x0010)
+#define AW_SPINLOCK_IRQ_EN_REG (0x0020)
+#define AW_SPINLOCK_IRQ_PEND_REG (0x0040)
+#define AW_SPINLOCK_LOCK_REG(id) (0x0100 + id * 4)
+
+typedef struct arisc_hwspinlock
+{
+ unsigned long flags;
+ spinlock_t lock;
+} arisc_hwspinlock_t;
+
+#endif /* __HW_SPINLOCK_I_H */
diff --git a/plat/sun50iw1p1/scp/include/arisc_cfgs.h b/plat/sun50iw1p1/scp/include/arisc_cfgs.h
new file mode 100644
index 0000000..32234ba
--- /dev/null
+++ b/plat/sun50iw1p1/scp/include/arisc_cfgs.h
@@ -0,0 +1,74 @@
+/*
+ * arch/arm/mach-sunxi/arisc/include/arisc_cfgs.h
+ *
+ * Copyright (c) 2012 Allwinner.
+ * 2012-10-01 Written by superm (superm@allwinnertech.com).
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#ifndef __ARISC_CFGS_H
+#define __ARISC_CFGS_H
+
+/* arisc software version number */
+#if defined CONFIG_ARCH_SUN8IW1P1
+#define ARISC_VERSIONS (100)
+#elif defined CONFIG_ARCH_SUN8IW3P1
+#define ARISC_VERSIONS (101)
+#elif defined CONFIG_ARCH_SUN8IW5P1
+#define ARISC_VERSIONS (102)
+#elif defined CONFIG_ARCH_SUN8IW6P1
+#define ARISC_VERSIONS (103)
+#elif defined CONFIG_ARCH_SUN8IW7P1
+#define ARISC_VERSIONS (104)
+#elif defined CONFIG_ARCH_SUN8IW9P1
+#define ARISC_VERSIONS (105)
+#elif defined CONFIG_ARCH_SUN50IW1P1
+#define ARISC_VERSIONS (110)
+#elif defined CONFIG_ARCH_SUN9IW1P1
+#define ARISC_VERSIONS (200)
+#else
+#error "please select a platform\n"
+#endif
+
+/* debugger system */
+#define ARISC_DEBUG_ON
+#define ARISC_DEBUG_LEVEL (3) /* debug level */
+
+/* the max number of cached message frame */
+#define ARISC_MESSAGE_CACHED_MAX (4)
+
+/* spinlock max timeout, base on ms */
+#define ARISC_SPINLOCK_TIMEOUT (100)
+
+/* send message max timeout, base on ms */
+#define ARISC_SEND_MSG_TIMEOUT (4000)
+
+/* hwmsgbox channels configure */
+#define ARISC_HWMSGBOX_ARISC_ASYN_TX_CH (0)
+#define ARISC_HWMSGBOX_ARISC_ASYN_RX_CH (1)
+#define ARISC_HWMSGBOX_ARISC_SYN_TX_CH (2)
+#define ARISC_HWMSGBOX_ARISC_SYN_RX_CH (3)
+#define ARISC_HWMSGBOX_AC327_SYN_TX_CH (4)
+#define ARISC_HWMSGBOX_AC327_SYN_RX_CH (5)
+
+/* dvfs config */
+#define ARISC_DVFS_VF_TABLE_MAX (16)
+/* ir config */
+#define ARISC_IR_KEY_SUP_NUM (8) /* the number of IR remote support */
+
+#define ARISC_DEV_CLKSRC_NUM (4) /* the number of dev clocksource support */
+
+#endif /* __ARISC_CFGS_H */
diff --git a/plat/sun50iw1p1/scp/include/arisc_dbgs.h b/plat/sun50iw1p1/scp/include/arisc_dbgs.h
new file mode 100644
index 0000000..aef8f5e
--- /dev/null
+++ b/plat/sun50iw1p1/scp/include/arisc_dbgs.h
@@ -0,0 +1,66 @@
+/*
+ * arch/arm/mach-sunxi/arisc/include/arisc_dbgs.h
+ *
+ * Copyright (c) 2012 Allwinner.
+ * 2012-10-01 Written by superm (superm@allwinnertech.com).
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#ifndef __ARISC_DBGS_H
+#define __ARISC_DBGS_H
+
+/*
+ * debug level define,
+ * level 0 : dump debug information--none;
+ * level 1 : dump debug information--error;
+ * level 2 : dump debug information--error+warning;
+ * level 3 : dump debug information--error+warning+information;
+ * extern void printk(const char *, ...);
+ */
+#ifdef ARISC_DEBUG_ON
+/* debug levels */
+#define DEBUG_LEVEL_INF ((uint32_t)1 << 0)
+#define DEBUG_LEVEL_LOG ((uint32_t)1 << 1)
+#define DEBUG_LEVEL_WRN ((uint32_t)1 << 2)
+#define DEBUG_LEVEL_ERR ((uint32_t)1 << 3)
+
+#define ARISC_INF(format, args...) \
+ if(DEBUG_LEVEL_INF & (0xf0 >> (arisc_debug_level +1))) \
+ tf_printf("[SCP] :"format, ##args);
+
+#define ARISC_LOG(format, args...) \
+ if(DEBUG_LEVEL_LOG & (0xf0 >> (arisc_debug_level +1))) \
+ tf_printf("[SCP] :"format, ##args);
+
+#define ARISC_WRN(format, args...) \
+ if(DEBUG_LEVEL_WRN & (0xf0 >> (arisc_debug_level +1))) \
+ tf_printf("[SCP WARING] :"format, ##args);
+
+#define ARISC_ERR(format, args...) \
+ if(DEBUG_LEVEL_ERR & (0xf0 >> (arisc_debug_level +1))) \
+ tf_printf("[SCP ERROR] :"format, ##args);
+
+#else /* ARISC_DEBUG_ON */
+#define ARISC_INF(...)
+#define ARISC_WRN(...)
+#define ARISC_ERR(...)
+#define ARISC_LOG(...)
+#endif /* ARISC_DEBUG_ON */
+
+/* report error information id */
+#define ERR_NMI_INT_TIMEOUT (0x1)
+
+#endif /* __ARISC_DBGS_H */
diff --git a/plat/sun50iw1p1/scp/include/arisc_hwmsgbox.h b/plat/sun50iw1p1/scp/include/arisc_hwmsgbox.h
new file mode 100644
index 0000000..4bab7bc
--- /dev/null
+++ b/plat/sun50iw1p1/scp/include/arisc_hwmsgbox.h
@@ -0,0 +1,77 @@
+/*
+ * arch/arm/mach-sunxi/arisc/include/arisc_hwmsgbox.h
+ *
+ * Copyright (c) 2012 Allwinner.
+ * 2012-10-01 Written by superm (superm@allwinnertech.com).
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#ifndef __ARISC_HWMSGBOX_H
+#define __ARISC_HWMSGBOX_H
+
+//the number of hardware message queue.
+#define AW_HWMSG_QUEUE_NUMBER (8)
+
+//the user of hardware message queue.
+typedef enum aw_hwmsg_queue_user
+{
+ AW_HWMSG_QUEUE_USER_ARISC, //arisc
+ AW_HWMSG_QUEUE_USER_AC327, //cpu0
+} aw_hwmsg_queue_user_e;
+
+/**
+ * initialize hwmsgbox.
+ * @para: none.
+ *
+ * returns: OK if initialize hwmsgbox succeeded, others if failed.
+ */
+int arisc_hwmsgbox_init(void);
+
+/**
+ * exit hwmsgbox.
+ * @para: none.
+ *
+ * returns: OK if exit hwmsgbox succeeded, others if failed.
+ */
+int arisc_hwmsgbox_exit(void);
+
+/**
+ * send one message to another processor by hwmsgbox.
+ * @pmessage: the pointer of sended message frame.
+ * @timeout: the wait time limit when message fifo is full,
+ * it is valid only when parameter mode = SEND_MESSAGE_WAIT_TIMEOUT.
+ *
+ * returns: OK if send message succeeded, other if failed.
+ */
+int arisc_hwmsgbox_send_message(struct arisc_message *pmessage, unsigned int timeout);
+
+/**
+ * Description: query message of hwmsgbox by hand, mainly for.
+ * @para: none.
+ *
+ * returns: the point of message, NULL if timeout.
+ */
+struct arisc_message *arisc_hwmsgbox_query_message(void);
+
+int arisc_hwmsgbox_enable_receiver_int(int queue, int user);
+int arisc_hwmsgbox_disable_receiver_int(int queue, int user);
+
+int arisc_hwmsgbox_feedback_message(struct arisc_message *pmessage, unsigned int timeout);
+
+int arisc_hwmsgbox_standby_resume(void);
+int arisc_hwmsgbox_standby_suspend(void);
+
+#endif /* __ARISC_HWMSGBOX_H */
diff --git a/plat/sun50iw1p1/scp/include/arisc_hwspinlock.h b/plat/sun50iw1p1/scp/include/arisc_hwspinlock.h
new file mode 100644
index 0000000..2b34276
--- /dev/null
+++ b/plat/sun50iw1p1/scp/include/arisc_hwspinlock.h
@@ -0,0 +1,63 @@
+/*
+ * arch/arm/mach-sunxi/arisc/include/arisc_hwspinlock.h
+ *
+ * Copyright (c) 2012 Allwinner.
+ * 2012-10-01 Written by superm (superm@allwinnertech.com).
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#ifndef __ARISC_HW_SPINLOCK_H
+#define __ARISC_HW_SPINLOCK_H
+
+/* the max number of hardware spinlock */
+#define ARISC_HW_SPINLOCK_NUM (32)
+
+/**
+ * initialize hwspinlock.
+ * @para: none.
+ *
+ * returns: OK if initialize hwspinlock succeeded, others if failed.
+ */
+int arisc_hwspinlock_init(void);
+
+/**
+ * exit hwspinlock.
+ * @para: none.
+ *
+ * returns: OK if exit hwspinlock succeeded, others if failed.
+ */
+int arisc_hwspinlock_exit(void);
+
+/**
+ * lock an hwspinlock with timeout limit.
+ * @hwid : an hwspinlock id which we want to lock.
+ *
+ * returns: OK if lock hwspinlock succeeded, other if failed.
+ */
+int arisc_hwspin_lock(int hwid);
+
+/**
+ * unlock a specific hwspinlock.
+ * @hwid : an hwspinlock id which we want to unlock.
+ *
+ * returns: OK if unlock hwspinlock succeeded, other if failed.
+ */
+int arisc_hwspin_unlock(int hwid);
+
+int arisc_hwspinlock_standby_suspend(void);
+int arisc_hwspinlock_standby_resume(void);
+
+#endif /* __ARISC_HW_SPINLOCK_H */
diff --git a/plat/sun50iw1p1/scp/include/arisc_includes.h b/plat/sun50iw1p1/scp/include/arisc_includes.h
new file mode 100644
index 0000000..571c90c
--- /dev/null
+++ b/plat/sun50iw1p1/scp/include/arisc_includes.h
@@ -0,0 +1,92 @@
+/*
+ * arch/arm/mach-sunxi/arisc/include/arisc_includes.h
+ *
+ * Copyright (c) 2012 Allwinner.
+ * 2012-10-01 Written by superm (superm@allwinnertech.com).
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#ifndef __ARISC_INCLUDES_H
+#define __ARISC_INCLUDES_H
+
+//#include <linux/kernel.h>
+//#include <linux/module.h>
+//#include <linux/string.h>
+//#include <linux/spinlock.h>
+//#include <linux/err.h>
+//#include <linux/io.h>
+//#include <linux/slab.h>
+//#include <linux/semaphore.h>
+//#include <linux/interrupt.h>
+//#include <linux/jiffies.h>
+//#include <linux/delay.h>
+//#include <linux/arisc/hwmsgbox.h>
+//#include <linux/arisc/hwspinlock.h>
+#define CONFIG_ARCH_SUN50IW1P1
+
+#include <arch_helpers.h>
+#include <platform.h>
+#include <platform_def.h>
+#include <bakery_lock.h>
+#include <mmio.h>
+#include <debug.h>
+#include <stdint.h>
+#include <stdio.h>
+#include <string.h>
+#include <assert.h>
+#include <errno.h>
+#include <psci.h>
+#include <bakery_lock.h>
+#include <spinlock.h>
+#include <arisc.h>
+
+#include "../../sunxi_private.h"
+#include "../../sunxi_cpu_ops.h"
+#include "../../sunxi_def.h"
+#include "../../mhu.h"
+#include "../../scpi.h"
+#include "../../sun50iw1p1.h"
+
+/* configure and debugger */
+#include "../arisc_i.h"
+#include "./arisc_cfgs.h"
+#include "./arisc_dbgs.h"
+#include "./arisc_para.h"
+
+/* messages define */
+#include "./arisc_messages.h"
+#include "./arisc_message_manager.h"
+
+/* driver headers */
+#include "./arisc_hwmsgbox.h"
+#include "./arisc_hwspinlock.h"
+
+#define readl(x) mmio_read_32((x))
+#define writel(v, a) mmio_write_32((a), (v))
+
+/* global functions */
+extern int arisc_axp_int_notify(struct arisc_message *pmessage);
+extern int arisc_audio_perdone_notify(struct arisc_message *pmessage);
+extern int arisc_dvfs_cfg_vf_table(void);
+extern int arisc_query_set_standby_info(struct standby_info_para *para, arisc_rw_type_e op);
+extern int arisc_sysconfig_sstpower_paras(void);
+extern int arisc_report_error_info(struct arisc_message *pmessage);
+
+/* global vars */
+extern unsigned long arisc_sram_a2_base;
+extern struct dts_cfg dts_cfg;
+
+#endif /* __ARISC_INCLUDES_H */
diff --git a/plat/sun50iw1p1/scp/include/arisc_message_manager.h b/plat/sun50iw1p1/scp/include/arisc_message_manager.h
new file mode 100644
index 0000000..5b80596
--- /dev/null
+++ b/plat/sun50iw1p1/scp/include/arisc_message_manager.h
@@ -0,0 +1,73 @@
+/*
+ * arch/arm/mach-sunxi/arisc/include/arisc_message_manager.h
+ *
+ * Copyright (c) 2012 Allwinner.
+ * 2012-10-01 Written by superm (superm@allwinnertech.com).
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#ifndef __ARISC_MESSAGE_MANAGER_H
+#define __ARISC_MESSAGE_MANAGER_H
+
+/**
+ * initialize message manager.
+ * @para: none.
+ *
+ * returns: OK if initialize succeeded, others if failed.
+ */
+int arisc_message_manager_init(void *addr, uint32_t size);
+
+/**
+ * exit message manager.
+ * para: none.
+ *
+ * returns: OK if exit succeeded, others if failed.
+ */
+int arisc_message_manager_exit(void);
+
+/**
+ * allocate one message frame. mainly use for send message by message-box,
+ * the message frame allocate form messages pool shared memory area.
+ * @para: none.
+ *
+ * returns: the pointer of allocated message frame, NULL if failed;
+ */
+struct arisc_message *arisc_message_allocate(unsigned int msg_attr);
+
+/**
+ * free one message frame. mainly use for process message finished,
+ * free it to messages pool or add to free message queue.
+ * @pmessage: the pointer of free message frame.
+ *
+ * returns: none.
+ */
+void arisc_message_free(struct arisc_message *pmessage);
+
+/**
+ * notify system that one message coming.
+ * @pmessage : the pointer of coming message frame.
+ *
+ * returns: OK if notify succeeded, other if failed.
+ */
+int arisc_message_coming_notify(struct arisc_message *pmessage);
+
+int arisc_semaphore_used_num_query(void);
+
+struct arisc_message *arisc_message_map_to_cpux(uint32_t addr);
+uint32_t arisc_message_map_to_cpus(struct arisc_message *message);
+int arisc_message_valid(struct arisc_message *pmessage);
+
+#endif /* __MESSAGE_MANAGER_H */
diff --git a/plat/sun50iw1p1/scp/include/arisc_messages.h b/plat/sun50iw1p1/scp/include/arisc_messages.h
new file mode 100644
index 0000000..98c47b1
--- /dev/null
+++ b/plat/sun50iw1p1/scp/include/arisc_messages.h
@@ -0,0 +1,81 @@
+/*
+ * arch/arm/mach-sunxi/arisc/include/arisc_messages.h
+ *
+ * Copyright (c) 2012 Allwinner.
+ * 2012-10-01 Written by superm (superm@allwinnertech.com).
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+
+#ifndef __ARISC_MESSAGES_H__
+#define __ARISC_MESSAGES_H__
+
+#include <arisc.h>
+
+/* message states */
+#define ARISC_MESSAGE_FREED (0x0) /* freed state */
+#define ARISC_MESSAGE_ALLOCATED (0x1) /* allocated state */
+#define ARISC_MESSAGE_INITIALIZED (0x2) /* initialized state */
+#define ARISC_MESSAGE_RECEIVED (0x3) /* received state */
+#define ARISC_MESSAGE_PROCESSING (0x4) /* processing state */
+#define ARISC_MESSAGE_PROCESSED (0x5) /* processed state */
+#define ARISC_MESSAGE_FEEDBACKED (0x6) /* feedback state */
+
+/* call back struct */
+typedef struct arisc_msg_cb
+{
+ arisc_cb_t handler;
+ void *arg;
+} arisc_msg_cb_t;
+
+#ifdef CONFIG_ARCH_SUN50IW1P1
+/*
+ * the structure of message frame,
+ * this structure will transfer between arisc and ac327.
+ * sizeof(struct message) : 128Byte.
+ */
+typedef struct arisc_message
+{
+ volatile unsigned char state; /* identify the used status of message frame */
+ volatile unsigned char attr; /* message attribute : SYN OR ASYN */
+ volatile unsigned char type; /* message type : DVFS_REQ */
+ volatile unsigned char result; /* message process result */
+ volatile unsigned char reserved[4]; /* reserved for 8byte align */
+ volatile struct arisc_message *next; /* pointer of next message frame */
+ volatile struct arisc_msg_cb cb; /* the callback function and arg of message */
+ volatile void *private; /* message private data */
+ volatile unsigned int paras[22]; /* the parameters of message */
+} arisc_message_t;
+#else
+/*
+ * the structure of message frame,
+ * this structure will transfer between arisc and ac327.
+ * sizeof(struct message) : 64Byte.
+ */
+typedef struct arisc_message
+{
+ volatile unsigned char state; /* identify the used status of message frame */
+ volatile unsigned char attr; /* message attribute : SYN OR ASYN */
+ volatile unsigned char type; /* message type : DVFS_REQ */
+ volatile unsigned char result; /* message process result */
+ volatile struct arisc_message *next; /* pointer of next message frame */
+ volatile struct arisc_msg_cb cb; /* the callback function and arg of message */
+ volatile void *private; /* message private data */
+ volatile unsigned int paras[11]; /* the parameters of message */
+} arisc_message_t;
+#endif
+
+#endif /* __ARISC_MESSAGES_H */
diff --git a/plat/sun50iw1p1/scp/include/arisc_para.h b/plat/sun50iw1p1/scp/include/arisc_para.h
new file mode 100644
index 0000000..1943759
--- /dev/null
+++ b/plat/sun50iw1p1/scp/include/arisc_para.h
@@ -0,0 +1,192 @@
+#ifndef __ARISC_PARA_H__
+#define __ARISC_PARA_H__
+
+#define ARISC_MACHINE_PAD 0
+#define ARISC_MACHINE_HOMLET 1
+
+/* arisc parameter size: 128byte */
+/*
+ * machine: machine id, pad = 0, homlet = 1;
+ * message_pool_phys: message pool physical address;
+ * message_pool_size: message pool size;
+ */
+#define SERVICES_DVFS_USED (1<<0)
+
+/* FIXME: if you modify this struct, you should
+ * sync this change with linux source,
+ * by superm at 2015-05-15.
+ */
+typedef enum power_dm
+{
+ DM_CPUA = 0, /* 0 */
+ DM_CPUB, /* 1 */
+ DM_DRAM, /* 2 */
+ DM_GPU, /* 3 */
+ DM_SYS, /* 4 */
+ DM_VPU, /* 5 */
+ DM_CPUS, /* 6 */
+ DM_DRAMPLL, /* 7 */
+ DM_ADC, /* 8 */
+ DM_PL, /* 9 */
+ DM_PM, /* 10 */
+ DM_IO, /* 11 */
+ DM_CPVDD, /* 12 */
+ DM_LDOIN, /* 13 */
+ DM_PLL, /* 14 */
+ DM_LPDDR, /* 15 */
+ DM_TEST, /* 16 */
+ DM_RES1, /* 17 */
+ DM_RES2, /* 18 */
+ DM_RES3, /* 19 */
+ DM_MAX, /* 20 */
+} power_dm_e;
+
+typedef struct mem_cfg
+{
+ uintptr_t base;
+ size_t size;
+} mem_cfg_t;
+
+typedef struct dev_cfg
+{
+ uintptr_t base;
+ size_t size;
+ uint32_t irq;
+ int status;
+} dev_cfg_t;
+
+typedef struct cir_cfg
+{
+ uintptr_t base;
+ size_t size;
+ uint32_t irq;
+ uint32_t power_key_code;
+ uint32_t addr_code;
+ int status;
+} cir_cfg_t;
+
+typedef struct pmu_cfg
+{
+ uint32_t pmu_bat_shutdown_ltf;
+ uint32_t pmu_bat_shutdown_htf;
+ uint32_t pmu_pwroff_vol;
+ uint32_t power_start;
+} pmu_cfg_t;
+
+typedef struct power_cfg
+{
+ uint32_t powchk_used;
+ uint32_t power_reg;
+ uint32_t system_power;
+} power_cfg_t;
+
+typedef struct image_cfg
+{
+ uintptr_t base;
+ size_t size;
+} image_cfg_t;
+
+typedef struct space_cfg
+{
+ uintptr_t sram_dst;
+ uintptr_t sram_offset;
+ size_t sram_size;
+ uintptr_t dram_dst;
+ uintptr_t dram_offset;
+ size_t dram_size;
+ uintptr_t para_dst;
+ uintptr_t para_offset;
+ size_t para_size;
+ uintptr_t msgpool_dst;
+ uintptr_t msgpool_offset;
+ size_t msgpool_size;
+ uintptr_t standby_dst;
+ uintptr_t standby_offset;
+ size_t standby_size;
+} space_cfg_t;
+
+typedef struct dram_para
+{
+ //normal configuration
+ uint32_t dram_clk;
+ uint32_t dram_type; //dram_type DDR2: 2 DDR3: 3 LPDDR2: 6 DDR3L: 31
+ uint32_t dram_zq;
+ uint32_t dram_odt_en;
+
+ //control configuration
+ uint32_t dram_para1;
+ uint32_t dram_para2;
+
+ //timing configuration
+ uint32_t dram_mr0;
+ uint32_t dram_mr1;
+ uint32_t dram_mr2;
+ uint32_t dram_mr3;
+ uint32_t dram_tpr0;
+ uint32_t dram_tpr1;
+ uint32_t dram_tpr2;
+ uint32_t dram_tpr3;
+ uint32_t dram_tpr4;
+ uint32_t dram_tpr5;
+ uint32_t dram_tpr6;
+
+ //reserved for future use
+ uint32_t dram_tpr7;
+ uint32_t dram_tpr8;
+ uint32_t dram_tpr9;
+ uint32_t dram_tpr10;
+ uint32_t dram_tpr11;
+ uint32_t dram_tpr12;
+ uint32_t dram_tpr13;
+
+}dram_para_t;
+
+typedef struct arisc_freq_voltage
+{
+ uint32_t freq; //cpu frequency
+ uint32_t voltage; //voltage for the frequency
+ uint32_t axi_div; //the divide ratio of axi bus
+} arisc_freq_voltage_t;
+
+typedef struct dts_cfg
+{
+ struct dram_para dram_para;
+ struct arisc_freq_voltage vf[ARISC_DVFS_VF_TABLE_MAX];
+ struct space_cfg space;
+ struct image_cfg image;
+ struct mem_cfg prcm;
+ struct mem_cfg cpuscfg;
+ struct dev_cfg msgbox;
+ struct dev_cfg hwspinlock;
+ struct dev_cfg s_uart;
+ struct dev_cfg s_rsb;
+ struct dev_cfg s_jtag;
+ struct cir_cfg s_cir;
+ struct pmu_cfg pmu;
+ struct power_cfg power;
+} dts_cfg_t;
+
+typedef struct arisc_para
+{
+ uint32_t message_pool_phys;
+ uint32_t message_pool_size;
+ uint32_t standby_base;
+ uint32_t standby_size;
+ uint32_t power_key_code;
+ uint32_t addr_code;
+ uint32_t suart_status;
+ uint32_t pmu_bat_shutdown_ltf;
+ uint32_t pmu_bat_shutdown_htf;
+ uint32_t pmu_pwroff_vol;
+ uint32_t power_start;
+ uint32_t powchk_used;
+ uint32_t power_reg;
+ uint32_t system_power;
+ struct dram_para dram_para;
+ struct arisc_freq_voltage vf[ARISC_DVFS_VF_TABLE_MAX];
+ uint32_t power_regu_tree[DM_MAX];
+} arisc_para_t;
+
+#define ARISC_PARA_SIZE (sizeof(struct arisc_para))
+
+#endif /* __ARISC_PARA_H__ */
diff --git a/plat/sun50iw1p1/scp/interfaces/arisc_axp.c b/plat/sun50iw1p1/scp/interfaces/arisc_axp.c
new file mode 100644
index 0000000..a33cfe2
--- /dev/null
+++ b/plat/sun50iw1p1/scp/interfaces/arisc_axp.c
@@ -0,0 +1,402 @@
+/*
+ * drivers/arisc/interfaces/arisc_axp.c
+ *
+ * Copyright (c) 2012 Allwinner.
+ * 2012-10-01 Written by superm (superm@allwinnertech.com).
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#include "../arisc_i.h"
+
+/* nmi isr node, record current nmi interrupt handler and argument */
+nmi_isr_t nmi_isr_node[2];
+
+/**
+ * register call-back function, call-back function is for arisc notify some event to ac327,
+ * axp/rtc interrupt for external interrupt NMI.
+ * @type: nmi type, pmu/rtc;
+ * @func: call-back function;
+ * @para: parameter for call-back function;
+ *
+ * @return: result, 0 - register call-back function successed;
+ * !0 - register call-back function failed;
+ * NOTE: the function is like "int callback(void *para)";
+ * this function will execute in system ISR.
+ */
+int arisc_nmi_cb_register(uint32_t type, arisc_cb_t func, void *para)
+{
+ if (nmi_isr_node[type].handler) {
+ if(func == nmi_isr_node[type].handler) {
+ ARISC_WRN("nmi interrupt handler register already\n");
+ return 0;
+ }
+ /* just output warning message, overlay handler */
+ ARISC_WRN("nmi interrupt handler register already\n");
+ return -EINVAL;
+ }
+ nmi_isr_node[type].handler = func;
+ nmi_isr_node[type].arg = para;
+
+ return 0;
+}
+
+
+/**
+ * unregister call-back function.
+ * @type: nmi type, pmu/rtc;
+ * @func: call-back function which need be unregister;
+ */
+void arisc_nmi_cb_unregister(uint32_t type, arisc_cb_t func)
+{
+ if ((nmi_isr_node[type].handler) != (func)) {
+ /* invalid handler */
+ ARISC_WRN("invalid handler for unreg\n\n");
+ return ;
+ }
+ nmi_isr_node[type].handler = NULL;
+ nmi_isr_node[type].arg = NULL;
+}
+
+int arisc_disable_nmi_irq(void)
+{
+ int result;
+ struct arisc_message *pmessage;
+
+ /* allocate a message frame */
+ pmessage = arisc_message_allocate(ARISC_MESSAGE_ATTR_HARDSYN);
+ if (pmessage == NULL) {
+ ARISC_WRN("allocate message failed\n");
+ return -ENOMEM;
+ }
+
+ /* initialize message */
+ pmessage->type = ARISC_AXP_DISABLE_IRQ;
+ pmessage->state = ARISC_MESSAGE_INITIALIZED;
+ pmessage->cb.handler = NULL;
+ pmessage->cb.arg = NULL;
+
+ /* send message use hwmsgbox */
+ arisc_hwmsgbox_send_message(pmessage, ARISC_SEND_MSG_TIMEOUT);
+
+ /* free message */
+ result = pmessage->result;
+ arisc_message_free(pmessage);
+
+ return result;
+}
+
+int arisc_enable_nmi_irq(void)
+{
+ int result;
+ struct arisc_message *pmessage;
+
+ /* allocate a message frame */
+ pmessage = arisc_message_allocate(ARISC_MESSAGE_ATTR_HARDSYN);
+ if (pmessage == NULL) {
+ ARISC_WRN("allocate message failed\n");
+ return -ENOMEM;
+ }
+
+ /* initialize message */
+ pmessage->type = ARISC_AXP_ENABLE_IRQ;
+ pmessage->state = ARISC_MESSAGE_INITIALIZED;
+ pmessage->cb.handler = NULL;
+ pmessage->cb.arg = NULL;
+
+ /* send message use hwmsgbox */
+ arisc_hwmsgbox_send_message(pmessage, ARISC_SEND_MSG_TIMEOUT);
+
+ /* free message */
+ result = pmessage->result;
+ arisc_message_free(pmessage);
+
+ return result;
+}
+
+int arisc_clear_nmi_status(void)
+{
+ int result;
+ struct arisc_message *pmessage;
+
+ /* allocate a message frame */
+ pmessage = arisc_message_allocate(ARISC_MESSAGE_ATTR_HARDSYN);
+ if (pmessage == NULL) {
+ ARISC_WRN("allocate message failed\n");
+ return -ENOMEM;
+ }
+
+ /* initialize message */
+ pmessage->type = ARISC_CLR_NMI_STATUS;
+ pmessage->state = ARISC_MESSAGE_INITIALIZED;
+ pmessage->cb.handler = NULL;
+ pmessage->cb.arg = NULL;
+
+ /* send message use hwmsgbox */
+ arisc_hwmsgbox_send_message(pmessage, ARISC_SEND_MSG_TIMEOUT);
+
+ /* free message */
+ result = pmessage->result;
+ arisc_message_free(pmessage);
+
+ return result;
+}
+
+int arisc_set_nmi_trigger(uint32_t type)
+{
+ int result;
+ struct arisc_message *pmessage;
+
+ /* allocate a message frame */
+ pmessage = arisc_message_allocate(ARISC_MESSAGE_ATTR_HARDSYN);
+ if (pmessage == NULL) {
+ ARISC_WRN("allocate message failed\n");
+ return -ENOMEM;
+ }
+
+ /* initialize message */
+ pmessage->type = ARISC_SET_NMI_TRIGGER;
+ pmessage->state = ARISC_MESSAGE_INITIALIZED;
+ pmessage->cb.handler = NULL;
+ pmessage->cb.arg = NULL;
+ pmessage->paras[0] = type;
+
+ /* send message use hwmsgbox */
+ arisc_hwmsgbox_send_message(pmessage, ARISC_SEND_MSG_TIMEOUT);
+
+ /* free message */
+ result = pmessage->result;
+ arisc_message_free(pmessage);
+
+ return result;
+}
+
+int arisc_axp_get_chip_id(unsigned char *chip_id)
+{
+ int i;
+ int result;
+ struct arisc_message *pmessage;
+
+ /* allocate a message frame */
+ pmessage = arisc_message_allocate(ARISC_MESSAGE_ATTR_HARDSYN);
+ if (pmessage == NULL) {
+ ARISC_WRN("allocate message failed\n");
+ return -ENOMEM;
+ }
+
+ /* initialize message */
+ pmessage->type = ARISC_AXP_GET_CHIP_ID;
+ pmessage->state = ARISC_MESSAGE_INITIALIZED;
+ pmessage->cb.handler = NULL;
+ pmessage->cb.arg = NULL;
+
+ memset((void *)pmessage->paras, 0, 16);
+
+ /* send message use hwmsgbox */
+ arisc_hwmsgbox_send_message(pmessage, ARISC_SEND_MSG_TIMEOUT);
+
+ /* |paras[0] |paras[1] |paras[2] |paras[3] |
+ * |chip_id[0~3]|chip_id[4~7]|chip_id[8~11]|chip_id[12~15]|
+ */
+ /* copy message readout data to user data buffer */
+ for (i = 0; i < 4; i++) {
+ chip_id[i] = (pmessage->paras[0] >> (i * 8)) & 0xff;
+ chip_id[4 + i] = (pmessage->paras[1] >> (i * 8)) & 0xff;
+ chip_id[8 + i] = (pmessage->paras[2] >> (i * 8)) & 0xff;
+ chip_id[12 + i] = (pmessage->paras[3] >> (i * 8)) & 0xff;
+ }
+
+ /* free message */
+ result = pmessage->result;
+ arisc_message_free(pmessage);
+
+ return result;
+}
+
+int arisc_set_led_bln(uint32_t *paras)
+{
+ int result;
+ struct arisc_message *pmessage;
+
+ /* allocate a message frame */
+ pmessage = arisc_message_allocate(ARISC_MESSAGE_ATTR_HARDSYN);
+ if (pmessage == NULL) {
+ ARISC_WRN("allocate message failed\n");
+ return -ENOMEM;
+ }
+
+ /* initialize message */
+ pmessage->type = ARISC_SET_LED_BLN;
+ pmessage->paras[0] = paras[0];
+ pmessage->paras[1] = paras[1];
+ pmessage->paras[2] = paras[2];
+ pmessage->paras[3] = paras[3];
+
+ /* send message use hwmsgbox */
+ arisc_hwmsgbox_send_message(pmessage, ARISC_SEND_MSG_TIMEOUT);
+
+ /* free message */
+ result = pmessage->result;
+ arisc_message_free(pmessage);
+
+ return result;
+
+}
+
+#if (defined CONFIG_ARCH_SUN8IW5P1) || (defined CONFIG_ARCH_SUN50IW1P1)
+int arisc_adjust_pmu_chgcur(uint32_t max_chgcur, uint32_t chg_ic_temp, uint32_t flag)
+{
+ int result;
+ struct arisc_message *pmessage;
+
+ /* allocate a message frame */
+ pmessage = arisc_message_allocate(ARISC_MESSAGE_ATTR_HARDSYN);
+ if (pmessage == NULL) {
+ ARISC_WRN("allocate message failed\n");
+ return -ENOMEM;
+ }
+
+ /* initialize message */
+ pmessage->type = ARISC_AXP_SET_PARAS;
+ pmessage->paras[0] = chg_ic_temp;
+ pmessage->paras[1] = max_chgcur;
+ pmessage->paras[2] = flag;
+
+ /* send message use hwmsgbox */
+ arisc_hwmsgbox_send_message(pmessage, ARISC_SEND_MSG_TIMEOUT);
+
+ /* free message */
+ result = pmessage->result;
+ arisc_message_free(pmessage);
+
+ return result;
+}
+#endif
+
+int arisc_set_pwr_tree(uint32_t *pwr_tree)
+{
+ int result;
+ struct arisc_message *pmessage;
+
+ /* allocate a message frame */
+ pmessage = arisc_message_allocate(ARISC_MESSAGE_ATTR_HARDSYN);
+ if (pmessage == NULL) {
+ ARISC_WRN("allocate message failed\n");
+ return -ENOMEM;
+ }
+
+ /* initialize message */
+ pmessage->type = ARISC_SET_PWR_TREE;
+ memcpy((void *)pmessage->paras, (void *)pwr_tree, sizeof(int)*DM_MAX);
+
+ /* send message use hwmsgbox */
+ arisc_hwmsgbox_send_message(pmessage, ARISC_SEND_MSG_TIMEOUT);
+
+ /* free message */
+ result = pmessage->result;
+ arisc_message_free(pmessage);
+
+ return result;
+}
+
+int arisc_axp_int_notify(struct arisc_message *pmessage)
+{
+ uint32_t type = pmessage->paras[0];
+ uint32_t ret = 0;
+
+ if (type & NMI_INT_TYPE_PMU_OFFSET) {
+ /* call pmu interrupt handler */
+ if (nmi_isr_node[NMI_INT_TYPE_PMU].handler == NULL) {
+ ARISC_WRN("pmu irq handler not install\n");
+ return 1;
+ }
+
+ ARISC_INF("call pmu interrupt handler\n");
+ ret |= (*(nmi_isr_node[NMI_INT_TYPE_PMU].handler))(nmi_isr_node[NMI_INT_TYPE_PMU].arg);
+ }
+ if (type & NMI_INT_TYPE_RTC_OFFSET)
+ {
+ /* call rtc interrupt handler */
+ if (nmi_isr_node[NMI_INT_TYPE_RTC].handler == NULL) {
+ ARISC_WRN("rtc irq handler not install\n");
+ return 1;
+ }
+
+ ARISC_INF("call rtc interrupt handler\n");
+ ret |= (*(nmi_isr_node[NMI_INT_TYPE_RTC].handler))(nmi_isr_node[NMI_INT_TYPE_RTC].arg);
+ }
+
+ return ret;
+}
+
+int arisc_pmu_set_voltage(uint32_t type, uint32_t voltage)
+{
+ int result;
+ struct arisc_message *pmessage;
+
+ /* allocate a message frame */
+ pmessage = arisc_message_allocate(ARISC_MESSAGE_ATTR_HARDSYN);
+ if (pmessage == NULL) {
+ ARISC_WRN("allocate message failed\n");
+ return -ENOMEM;
+ }
+
+ /* initialize message */
+ pmessage->type = ARISC_SET_PMU_VOLT;
+ pmessage->state = ARISC_MESSAGE_INITIALIZED;
+ pmessage->cb.handler = NULL;
+ pmessage->cb.arg = NULL;
+ pmessage->paras[0] = type;
+ pmessage->paras[1] = voltage;
+
+ /* send message use hwmsgbox */
+ arisc_hwmsgbox_send_message(pmessage, ARISC_SEND_MSG_TIMEOUT);
+
+ /* free message */
+ result = pmessage->result;
+ arisc_message_free(pmessage);
+
+ return result;
+}
+
+int arisc_pmu_get_voltage(uint32_t type, uint32_t *voltage)
+{
+ int result;
+ struct arisc_message *pmessage;
+
+ /* allocate a message frame */
+ pmessage = arisc_message_allocate(ARISC_MESSAGE_ATTR_HARDSYN);
+ if (pmessage == NULL) {
+ ARISC_WRN("allocate message failed\n");
+ return -ENOMEM;
+ }
+
+ /* initialize message */
+ pmessage->type = ARISC_GET_PMU_VOLT;
+ pmessage->state = ARISC_MESSAGE_INITIALIZED;
+ pmessage->cb.handler = NULL;
+ pmessage->cb.arg = NULL;
+ pmessage->paras[0] = type;
+
+ /* send message use hwmsgbox */
+ arisc_hwmsgbox_send_message(pmessage, ARISC_SEND_MSG_TIMEOUT);
+ *voltage = pmessage->paras[1];
+
+ /* free message */
+ result = pmessage->result;
+ arisc_message_free(pmessage);
+
+ return result;
+}
diff --git a/plat/sun50iw1p1/scp/interfaces/arisc_debug_level.c b/plat/sun50iw1p1/scp/interfaces/arisc_debug_level.c
new file mode 100644
index 0000000..e1e5346
--- /dev/null
+++ b/plat/sun50iw1p1/scp/interfaces/arisc_debug_level.c
@@ -0,0 +1,137 @@
+/*
+ * drivers/arisc/interfaces/arisc_debug_level.c
+ *
+ * Copyright (c) 2012 Allwinner.
+ * 2012-10-01 Written by superm (superm@allwinnertech.com).
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#include "../arisc_i.h"
+
+/**
+ * set arisc debug level.
+ * @level: arisc debug level;
+ *
+ * return: 0 - set arisc debug level successed, !0 - set arisc debug level failed;
+ */
+int arisc_set_debug_level(unsigned int level)
+{
+ int result;
+ struct arisc_message *pmessage;
+
+ /* allocate a message frame */
+ pmessage = arisc_message_allocate(ARISC_MESSAGE_ATTR_HARDSYN);
+ if (pmessage == NULL) {
+ ARISC_ERR("allocate message for debug level request failed\n");
+ return -ENOMEM;
+ }
+
+ /* initialize message */
+ pmessage->type = ARISC_SET_DEBUG_LEVEL;
+ pmessage->state = ARISC_MESSAGE_INITIALIZED;
+ pmessage->paras[0] = level;
+ pmessage->cb.handler = NULL;
+ pmessage->cb.arg = NULL;
+
+ /* send set debug level request to arisc */
+ arisc_hwmsgbox_send_message(pmessage, ARISC_SEND_MSG_TIMEOUT);
+
+ /* free message */
+ result = pmessage->result;
+ arisc_message_free(pmessage);
+
+ return result;
+}
+
+int arisc_set_uart_baudrate(uint32_t baudrate)
+{
+ int result;
+ struct arisc_message *pmessage;
+
+ /* allocate a message frame */
+ pmessage = arisc_message_allocate(ARISC_MESSAGE_ATTR_HARDSYN);
+ if (pmessage == NULL) {
+ ARISC_ERR("allocate message for set baudrate request failed\n");
+ return -ENOMEM;
+ }
+
+ /* initialize message */
+ pmessage->type = ARISC_SET_UART_BAUDRATE;
+ pmessage->state = ARISC_MESSAGE_INITIALIZED;
+ pmessage->paras[0] = baudrate;
+ pmessage->cb.handler = NULL;
+ pmessage->cb.arg = NULL;
+
+ /* send message use hwmsgbox */
+ arisc_hwmsgbox_send_message(pmessage, ARISC_SEND_MSG_TIMEOUT);
+
+ /* free message */
+ result = pmessage->result;
+ arisc_message_free(pmessage);
+
+ return result;
+}
+
+int arisc_report_error_info(struct arisc_message *pmessage)
+{
+ uint32_t id = pmessage->paras[0];
+
+ switch(id) {
+ case ERR_NMI_INT_TIMEOUT: {
+ ARISC_ERR("arisc report error info: nmi int response timeout\n");
+ break;
+ }
+ default: {
+ ARISC_ERR("invaid arisc report error infomation id:%u\n", id);
+ return -EINVAL;
+ }
+ }
+
+ return 0;
+}
+
+/**
+ * set paras.
+ *
+ * return: 0 - set paras successed, !0 - set paras failed;
+ */
+int arisc_set_paras(void)
+{
+ int result;
+ struct arisc_message *pmessage;
+
+ /* allocate a message frame */
+ pmessage = arisc_message_allocate(ARISC_MESSAGE_ATTR_HARDSYN);
+ if (pmessage == NULL) {
+ ARISC_ERR("allocate message for set paras request failed\n");
+ return -ENOMEM;
+ }
+
+ /* initialize message */
+ pmessage->type = ARISC_SET_PARAS;
+ pmessage->state = ARISC_MESSAGE_INITIALIZED;
+ pmessage->cb.handler = NULL;
+ pmessage->cb.arg = NULL;
+
+ /* send set debug level request to arisc */
+ arisc_hwmsgbox_send_message(pmessage, ARISC_SEND_MSG_TIMEOUT);
+
+ /* free message */
+ result = pmessage->result;
+ arisc_message_free(pmessage);
+
+ return result;
+} \ No newline at end of file
diff --git a/plat/sun50iw1p1/scp/interfaces/arisc_dram_crc.c b/plat/sun50iw1p1/scp/interfaces/arisc_dram_crc.c
new file mode 100644
index 0000000..fd82232
--- /dev/null
+++ b/plat/sun50iw1p1/scp/interfaces/arisc_dram_crc.c
@@ -0,0 +1,57 @@
+/*
+ * drivers/arisc/interfaces/arisc_dram_crc.c
+ *
+ * Copyright (c) 2012 Allwinner.
+ * 2012-10-01 Written by superm (superm@allwinnertech.com).
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#include "../arisc_i.h"
+
+/**
+ * set arisc debug dram crc paras.
+ * @dram_crc_en: arisc debug dram crc enable or disable;
+ * @dram_crc_srcaddr: source address of dram crc area
+ * @dram_crc_len: lenght of dram crc area
+ *
+ * return: 0 - set arisc debug dram crc paras successed, !0 - set arisc debug dram crc paras failed;
+ */
+int arisc_set_dram_crc_paras(unsigned int dram_crc_en, unsigned int dram_crc_srcaddr, unsigned int dram_crc_len)
+{
+ struct arisc_message *pmessage;
+
+ ARISC_INF("en:%x, src:%x len:%x\n", dram_crc_en, dram_crc_srcaddr, dram_crc_len);
+
+ /* allocate a message frame */
+ pmessage = arisc_message_allocate(0);
+ if (pmessage == NULL) {
+ ARISC_ERR("allocate message for seting dram crc paras request failed\n");
+ return -ENOMEM;
+ }
+
+ /* initialize message */
+ pmessage->type = ARISC_SET_DEBUG_DRAM_CRC_PARAS;
+ pmessage->paras[0] = dram_crc_en;
+ pmessage->paras[1] = dram_crc_srcaddr;
+ pmessage->paras[2] = dram_crc_len;
+ pmessage->state = ARISC_MESSAGE_INITIALIZED;
+
+ /* send set debug level request to arisc */
+ arisc_hwmsgbox_send_message(pmessage, ARISC_SEND_MSG_TIMEOUT);
+
+ return 0;
+}
+
diff --git a/plat/sun50iw1p1/scp/interfaces/arisc_dvfs.c b/plat/sun50iw1p1/scp/interfaces/arisc_dvfs.c
new file mode 100644
index 0000000..c7c50cc
--- /dev/null
+++ b/plat/sun50iw1p1/scp/interfaces/arisc_dvfs.c
@@ -0,0 +1,81 @@
+/*
+ * drivers/arisc/interfaces/arisc_dvfs.c
+ *
+ * Copyright (c) 2012 Allwinner.
+ * 2012-10-01 Written by superm (superm@allwinnertech.com).
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#include "../arisc_i.h"
+
+static int dvfs_err_cb(void *arg)
+{
+ ARISC_ERR("dvfs error\n");
+
+ return 0;
+}
+
+/*
+ * set specific pll target frequency.
+ * @freq: target frequency to be set, based on KHZ;
+ * @pll: which pll will be set
+ * @mode: the attribute of message, whether syn or asyn;
+ * @cb: callback handler;
+ * @cb_arg: callback handler arguments;
+ *
+ * return: result, 0 - set frequency successed,
+ * !0 - set frequency failed;
+ */
+int arisc_dvfs_set_cpufreq(uint32_t freq, uint32_t pll, uint32_t mode)
+{
+ unsigned int msg_attr = 0;
+ struct arisc_message *pmessage;
+ int result = 0;
+
+ if (mode & ARISC_DVFS_SYN) {
+ msg_attr |= ARISC_MESSAGE_ATTR_HARDSYN;
+ }
+
+ /* allocate a message frame */
+ pmessage = arisc_message_allocate(msg_attr);
+ if (pmessage == NULL) {
+ ARISC_WRN("allocate message failed\n");
+ return -ENOMEM;
+ }
+
+ /* initialize message
+ *
+ * |paras[0]|paras[1]|
+ * |freq |pll |
+ */
+ pmessage->type = ARISC_CPUX_DVFS_REQ;
+ pmessage->paras[0] = freq;
+ pmessage->paras[1] = pll;
+ pmessage->state = ARISC_MESSAGE_INITIALIZED;
+ pmessage->cb.handler = dvfs_err_cb;
+ pmessage->cb.arg = NULL;
+
+ ARISC_INF("arisc dvfs request : %d\n", freq);
+ arisc_hwmsgbox_send_message(pmessage, ARISC_SEND_MSG_TIMEOUT);
+
+ /* dvfs mode : syn or not */
+ if (mode & ARISC_DVFS_SYN) {
+ result = pmessage->result;
+ arisc_message_free(pmessage);
+ }
+
+ return result;
+}
diff --git a/plat/sun50iw1p1/scp/interfaces/arisc_loopback.c b/plat/sun50iw1p1/scp/interfaces/arisc_loopback.c
new file mode 100644
index 0000000..029d4dc
--- /dev/null
+++ b/plat/sun50iw1p1/scp/interfaces/arisc_loopback.c
@@ -0,0 +1,51 @@
+/*
+ * drivers/arisc/interfaces/arisc_loopback.c
+ *
+ * Copyright (c) 2012 Allwinner.
+ * 2012-10-01 Written by superm (superm@allwinnertech.com).
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#include "../arisc_i.h"
+
+int arisc_message_loopback(void)
+{
+ int result;
+ struct arisc_message *pmessage;
+
+ /* allocate a message frame */
+ pmessage = arisc_message_allocate(ARISC_MESSAGE_ATTR_HARDSYN);
+ if (pmessage == NULL) {
+ ARISC_WRN("allocate message failed\n");
+ return -ENOMEM;
+ }
+
+ /* initialize message */
+ pmessage->type = ARISC_MESSAGE_LOOPBACK;
+ pmessage->state = ARISC_MESSAGE_INITIALIZED;
+ pmessage->paras[0] = 11;
+ pmessage->cb.handler = NULL;
+ pmessage->cb.arg = NULL;
+
+ /* send message use hwmsgbox */
+ arisc_hwmsgbox_send_message(pmessage, ARISC_SEND_MSG_TIMEOUT);
+
+ /* free message */
+ result = pmessage->result;
+ arisc_message_free(pmessage);
+
+ return result;
+}
diff --git a/plat/sun50iw1p1/scp/interfaces/arisc_rsb.c b/plat/sun50iw1p1/scp/interfaces/arisc_rsb.c
new file mode 100644
index 0000000..f3b685b
--- /dev/null
+++ b/plat/sun50iw1p1/scp/interfaces/arisc_rsb.c
@@ -0,0 +1,329 @@
+/*
+ * drivers/arisc/interfaces/arisc_rsb.c
+ *
+ * Copyright (c) 2013 Allwinner.
+ * 2013-07-01 Written by superm (superm@allwinnertech.com).
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#include "../arisc_i.h"
+
+#if (defined CONFIG_ARCH_SUN8IW3P1) || (defined CONFIG_ARCH_SUN8IW5P1) || (defined CONFIG_ARCH_SUN8IW6P1) || \
+ (defined CONFIG_ARCH_SUN8IW7P1) || (defined CONFIG_ARCH_SUN8IW9P1) || (defined CONFIG_ARCH_SUN9IW1P1) || \
+ (defined CONFIG_ARCH_SUN50IW1P1)
+
+/*
+ * used for indicate aduio codec been initialized,
+ * modules like audio & trc mabye initialize,
+ * but audio codec only can be initialize once
+ */
+static int audio_codec_init = 0;
+
+/**
+ * rsb read block data.
+ * @cfg: point of arisc_rsb_block_cfg struct;
+ *
+ * return: result, 0 - read register successed,
+ * !0 - read register failed or the len more then max len;
+ */
+int arisc_rsb_read_block_data(uint32_t *paras)
+{
+ int result;
+ struct arisc_message *pmessage;
+
+ pmessage = arisc_message_allocate(ARISC_MESSAGE_ATTR_HARDSYN);
+
+ if (pmessage == NULL) {
+ ARISC_WRN("allocate message failed\n");
+ return -ENOMEM;
+ }
+
+ /* initialize message */
+ pmessage->type = ARISC_RSB_READ_BLOCK_DATA;
+ pmessage->state = ARISC_MESSAGE_INITIALIZED;
+ pmessage->cb.handler = NULL;
+ pmessage->cb.arg = NULL;
+
+ memcpy((void *)pmessage->paras, (const void *)paras, sizeof(pmessage->paras));
+
+ /* send message use hwmsgbox */
+ arisc_hwmsgbox_send_message(pmessage, ARISC_SEND_MSG_TIMEOUT);
+
+ memcpy((void *)paras, (const void *)pmessage->paras, sizeof(pmessage->paras));
+
+ /* free message */
+ result = pmessage->result;
+ arisc_message_free(pmessage);
+
+ return result;
+}
+
+
+/**
+ * rsb write block data.
+ * @cfg: point of arisc_rsb_block_cfg struct;
+ *
+ * return: result, 0 - write register successed,
+ * !0 - write register failedor the len more then max len;
+ */
+int arisc_rsb_write_block_data(uint32_t *paras)
+{
+ int result;
+ struct arisc_message *pmessage;
+
+ pmessage = arisc_message_allocate(ARISC_MESSAGE_ATTR_HARDSYN);
+
+ if (pmessage == NULL) {
+ ARISC_WRN("allocate message failed\n");
+ return -ENOMEM;
+ }
+ /* initialize message */
+ pmessage->type = ARISC_RSB_WRITE_BLOCK_DATA;
+ pmessage->state = ARISC_MESSAGE_INITIALIZED;
+ pmessage->cb.handler = NULL;
+ pmessage->cb.arg = NULL;
+
+ memcpy((void *)pmessage->paras, (const void *)paras, sizeof(pmessage->paras));
+
+ /* send message use hwmsgbox */
+ arisc_hwmsgbox_send_message(pmessage, ARISC_SEND_MSG_TIMEOUT);
+
+ /* free message */
+ result = pmessage->result;
+ arisc_message_free(pmessage);
+
+ return result;
+}
+
+
+/**
+ * rsb read pmu reg.
+ * @addr: pmu reg addr;
+ *
+ * return: if read pmu reg successed, return data of pmu reg;
+ * if read pmu reg failed, return -1.
+ */
+uint8_t arisc_rsb_read_pmu_reg(uint32_t addr)
+{
+ int result;
+ uint32_t paras[22];
+ uint32_t data = 0;
+
+ /*
+ * package address and data to message->paras,
+ * message->paras data layout:
+ * |para[0] |para[1]|para[2] |para[3]|para[4]|para[5]|para[6]|
+ * |(len|datatype)|devaddr|regaddr0~3|data0 |data1 |data2 |data3 |
+ */
+ memset((void *)paras, 0, sizeof(uint32_t) * 6);
+ paras[0] = ((1 & 0xffff) | ((RSB_DATA_TYPE_BYTE << 16) & 0xffff0000));
+ paras[1] = 0x2d;
+ paras[2] = addr&0xff;
+
+ result = arisc_rsb_read_block_data(paras);
+ if (!result) {
+ data = paras[3];
+ } else {
+ ARISC_ERR("arisc rsb read pmu reg 0x%x err\n", addr);
+ return -1;
+ }
+
+ ARISC_INF("read pmu reg 0x%x:0x%x\n", addr, data);
+
+ return data;
+}
+
+
+/**
+ * rsb write pmu reg.
+ * @addr: pmu reg addr;
+ * @data: pmu reg data;
+ *
+ * return: result, 0 - write register successed,
+ * !0 - write register failedor the len more then max len;
+ */
+int arisc_rsb_write_pmu_reg(uint32_t addr, uint32_t data)
+{
+ int result;
+ uint32_t paras[22];
+
+ /*
+ * package address and data to message->paras,
+ * message->paras data layout:
+ * |para[0] |para[1]|para[2] |para[3]|para[4]|para[5]|para[6]|
+ * |(len|datatype)|devaddr|regaddr0~3|data0 |data1 |data2 |data3 |
+ */
+ memset((void *)paras, 0, sizeof(uint32_t) * 6);
+ paras[0] = ((1 & 0xffff) | ((RSB_DATA_TYPE_BYTE << 16) & 0xffff0000));
+ paras[1] = 0x2d;
+ paras[2] = addr&0xff;
+ paras[3] = data&0xff;
+
+ result = arisc_rsb_write_block_data(paras);
+ if (result) {
+ ARISC_ERR("arisc rsb write pmu reg 0x%x:0x%x err\n", addr, data);
+ }
+ ARISC_INF("write pmu reg 0x%x:0x%x\n", addr, data);
+
+ return result;
+}
+
+
+/**
+ * rsb bits operation sync.
+ * @cfg: point of arisc_rsb_bits_cfg struct;
+ *
+ * return: result, 0 - bits operation successed,
+ * !0 - bits operation failed, or the len more then max len;
+ *
+ * rsb clear bits internal:
+ * data = rsb_read(regaddr);
+ * data = data & (~mask);
+ * rsb_write(regaddr, data);
+ *
+ * rsb set bits internal:
+ * data = rsb_read(addr);
+ * data = data | mask;
+ * rsb_write(addr, data);
+ *
+ */
+int rsb_bits_ops_sync(uint32_t *paras)
+{
+ int result;
+ struct arisc_message *pmessage;
+
+ pmessage = arisc_message_allocate(ARISC_MESSAGE_ATTR_HARDSYN);
+
+ if (pmessage == NULL) {
+ ARISC_WRN("allocate message failed\n");
+ return -ENOMEM;
+ }
+ /* initialize message */
+ pmessage->type = ARISC_RSB_BITS_OPS_SYNC;
+ pmessage->state = ARISC_MESSAGE_INITIALIZED;
+ pmessage->cb.handler = NULL;
+ pmessage->cb.arg = NULL;
+
+ memcpy((void *)pmessage->paras, (const void *)paras, sizeof(pmessage->paras));
+
+ /* send message use hwmsgbox */
+ arisc_hwmsgbox_send_message(pmessage, ARISC_SEND_MSG_TIMEOUT);
+
+ /* free message */
+ result = pmessage->result;
+ arisc_message_free(pmessage);
+
+ return result;
+}
+
+/**
+ * rsb set interface mode.
+ * @devaddr: rsb slave device address;
+ * @regaddr: register address of rsb slave device;
+ * @data: data which to init rsb slave device interface mode;
+ *
+ * return: result, 0 - set interface mode successed,
+ * !0 - set interface mode failed;
+ */
+int arisc_rsb_set_interface_mode(uint32_t devaddr, uint32_t regaddr, uint32_t data)
+{
+ int result;
+ struct arisc_message *pmessage;
+
+ pmessage = arisc_message_allocate(ARISC_MESSAGE_ATTR_HARDSYN);
+
+ if (pmessage == NULL) {
+ ARISC_WRN("allocate message failed\n");
+ return -ENOMEM;
+ }
+
+ /* initialize message */
+ pmessage->type = ARISC_RSB_SET_INTERFACE_MODE;
+ pmessage->state = ARISC_MESSAGE_INITIALIZED;
+ pmessage->cb.handler = NULL;
+ pmessage->cb.arg = NULL;
+
+ /*
+ * package address and data to message->paras,
+ * message->paras data layout:
+ * |para[0]|para[1]|para[2]|
+ * |devaddr|regaddr|data |
+ */
+ pmessage->paras[0] = devaddr;
+ pmessage->paras[1] = regaddr;
+ pmessage->paras[2] = data;
+ /* send message use hwmsgbox */
+ arisc_hwmsgbox_send_message(pmessage, ARISC_SEND_MSG_TIMEOUT);
+
+ /* free message */
+ result = pmessage->result;
+ arisc_message_free(pmessage);
+
+ return result;
+}
+
+/**
+ * rsb set runtime slave address.
+ * @devaddr: rsb slave device address;
+ * @rtsaddr: rsb slave device's runtime slave address;
+ *
+ * return: result, 0 - set rsb runtime address successed,
+ * !0 - set rsb runtime address failed;
+ */
+int arisc_rsb_set_rtsaddr(uint32_t devaddr, uint32_t rtsaddr)
+{
+ int result;
+ struct arisc_message *pmessage;
+
+ /* check audio codec has been initialized */
+ if (devaddr == RSB_DEVICE_SADDR7) {
+ if (audio_codec_init)
+ return 0;
+ else
+ audio_codec_init = 1;
+ }
+
+ pmessage = arisc_message_allocate(ARISC_MESSAGE_ATTR_HARDSYN);
+
+ if (pmessage == NULL) {
+ ARISC_WRN("allocate message failed\n");
+ return -ENOMEM;
+ }
+
+ /* initialize message */
+ pmessage->type = ARISC_RSB_SET_RTSADDR;
+ pmessage->state = ARISC_MESSAGE_INITIALIZED;
+ pmessage->cb.handler = NULL;
+ pmessage->cb.arg = NULL;
+
+ /*
+ * package address and data to message->paras,
+ * message->paras data layout:
+ * |para[0]|para[1]|
+ * |devaddr|rtsaddr|
+ */
+ pmessage->paras[0] = devaddr;
+ pmessage->paras[1] = rtsaddr;
+ /* send message use hwmsgbox */
+ arisc_hwmsgbox_send_message(pmessage, ARISC_SEND_MSG_TIMEOUT);
+
+ /* free message */
+ result = pmessage->result;
+ arisc_message_free(pmessage);
+
+ return result;
+}
+#endif
diff --git a/plat/sun50iw1p1/scp/interfaces/arisc_standby.c b/plat/sun50iw1p1/scp/interfaces/arisc_standby.c
new file mode 100644
index 0000000..d570ddf
--- /dev/null
+++ b/plat/sun50iw1p1/scp/interfaces/arisc_standby.c
@@ -0,0 +1,286 @@
+/*
+ * drivers/arisc/interfaces/arisc_standby.c
+ *
+ * Copyright (c) 2012 Allwinner.
+ * 2012-10-01 Written by superm (superm@allwinnertech.com).
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#include "../arisc_i.h"
+
+/* record super-standby wakeup event */
+static unsigned long wakeup_event = 0;
+static unsigned long dram_crc_error = 0;
+static unsigned long dram_crc_total_count = 0;
+static unsigned long dram_crc_error_count = 0;
+
+/**
+ * cpu operations.
+ * @mpidr: cpu id;
+ * @entrypoint: cpu resume entrypoint;
+ * @cpu_state: cpu state;
+ * @cluster_state: cluster state;
+ *
+ * return: result, 0 - cpu operations successed,
+ * !0 - cpu operations failed;
+ */
+int arisc_cpu_op(uint32_t mpidr, uint32_t entrypoint, arisc_power_state_t cpu_state,
+ arisc_power_state_t cluster_state)
+{
+ struct arisc_message *pmessage;
+
+ /* allocate a message frame */
+ pmessage = arisc_message_allocate(0);
+ if (pmessage == NULL) {
+ ARISC_ERR("allocate message for cpu op request failed\n");
+ return -ENOMEM;
+ }
+
+ pmessage->type = ARISC_CPU_OP_REQ;
+ pmessage->cb.handler = NULL;
+ pmessage->cb.arg = NULL;
+ pmessage->paras[0] = mpidr;
+ pmessage->paras[1] = entrypoint;
+ pmessage->paras[2] = cpu_state;
+ pmessage->paras[3] = cluster_state;
+ pmessage->state = ARISC_MESSAGE_INITIALIZED;
+
+ /* send enter cpu operations request to arisc */
+ arisc_hwmsgbox_send_message(pmessage, ARISC_SEND_MSG_TIMEOUT);
+
+ return 0;
+}
+
+ /**
+ * system operations.
+ * @state: system state;
+ *
+ * return: result, 0 - system operations successed,
+ * !0 - system operations failed;
+ */
+int arisc_system_op(arisc_system_state_t state)
+{
+ struct arisc_message *pmessage;
+
+ /* allocate a message frame */
+ pmessage = arisc_message_allocate(0);
+ if (pmessage == NULL) {
+ ARISC_ERR("allocate message for sys op request failed\n");
+ return -ENOMEM;
+ }
+
+ pmessage->type = ARISC_SYS_OP_REQ;
+ pmessage->cb.handler = NULL;
+ pmessage->cb.arg = NULL;
+ pmessage->paras[0] = state;
+ pmessage->state = ARISC_MESSAGE_INITIALIZED;
+
+ /* send enter sys operations request to arisc */
+ arisc_hwmsgbox_send_message(pmessage, ARISC_SEND_MSG_TIMEOUT);
+
+ return 0;
+}
+
+/*
+ * enter cpu idle.
+ * @para: parameter for enter cpu idle.
+ * para->flag: 0x01-clear pending, 0x10-enter cpuidle
+ * para->resume_addr: the address cpu0 will run when exit idle
+ *
+ * return: result, 0 - super standby successed,
+ * !0 - super standby failed;
+ */
+int arisc_enter_cpuidle(arisc_cb_t cb, void *cb_arg, struct sunxi_enter_idle_para *para)
+{
+ struct arisc_message *pmessage; /* allocate a message frame */
+ pmessage = arisc_message_allocate(0);
+ if (pmessage == NULL) {
+ ARISC_ERR("allocate message for super-standby request failed\n");
+ return -ENOMEM;
+ }
+ pmessage->type = ARISC_CPUIDLE_ENTER_REQ;
+ pmessage->cb.handler = cb;
+ pmessage->cb.arg = cb_arg;
+ pmessage->state = ARISC_MESSAGE_INITIALIZED;
+ pmessage->paras[0] = para->flags;
+ pmessage->paras[1] = (unsigned long)para->resume_addr;
+ arisc_hwmsgbox_send_message(pmessage, ARISC_SEND_MSG_TIMEOUT);
+ return 0;
+}
+
+/**
+ * query super-standby wakeup source.
+ * @para: point of buffer to store wakeup event informations.
+ *
+ * return: result, 0 - query successed,
+ * !0 - query failed;
+ */
+int arisc_query_wakeup_source(uint32_t *event)
+{
+ *event = wakeup_event;
+
+ return 0;
+}
+
+/*
+ * query super-standby infoation.
+ * @para: point of array to store power states informations during sst.
+ * @op: 0:read, 1:set
+ *
+ * return: result, 0 - query successed,
+ * !0 - query failed;
+ */
+int arisc_query_set_standby_info(struct standby_info_para *para, arisc_rw_type_e op)
+{
+ struct arisc_message *pmsg;
+ int result;
+
+ /* allocate a message frame */
+ pmsg = arisc_message_allocate(ARISC_MESSAGE_ATTR_HARDSYN);
+ if (pmsg == NULL) {
+ ARISC_ERR("allocate message for query standby info failed\n");
+ return -ENOMEM;
+ }
+
+ /* check standby_info_para size valid or not */
+ if (sizeof(struct standby_info_para) > sizeof(pmsg->paras)) {
+ ARISC_ERR("standby info parameters number too long\n");
+ return -EINVAL;
+ }
+
+ /* initialize message */
+ pmsg->type = ARISC_STANDBY_INFO_REQ;
+ pmsg->cb.handler = NULL;
+ pmsg->cb.arg = NULL;
+ pmsg->private = (void *)op;
+ if (ARISC_WRITE == op) {
+ memcpy((void *)pmsg->paras, (const void *)para, sizeof(struct standby_info_para));
+ }
+ pmsg->state = ARISC_MESSAGE_INITIALIZED;
+
+ /* send query sst info request to arisc */
+ arisc_hwmsgbox_send_message(pmsg, ARISC_SEND_MSG_TIMEOUT);
+ if (ARISC_READ == op)
+ memcpy((void *)para, (void *)pmsg->paras, sizeof(struct standby_info_para));
+
+ /* free message */
+ result = pmsg->result;
+ arisc_message_free(pmsg);
+
+ return result;
+}
+
+/*
+ * query super-standby dram crc result.
+ * @para: point of buffer to store dram crc result informations.
+ *
+ * return: result, 0 - query successed,
+ * !0 - query failed;
+ */
+int arisc_query_dram_crc_result(unsigned long *perror, unsigned long *ptotal_count,
+ unsigned long *perror_count)
+{
+ *perror = dram_crc_error;
+ *ptotal_count = dram_crc_total_count;
+ *perror_count = dram_crc_error_count;
+
+ return 0;
+}
+
+int arisc_set_dram_crc_result(unsigned long error, unsigned long total_count,
+ unsigned long error_count)
+{
+ dram_crc_error = error;
+ dram_crc_total_count = total_count;
+ dram_crc_error_count = error_count;
+
+ return 0;
+}
+
+/**
+ * notify arisc cpux restored.
+ * @para: none.
+ *
+ * return: result, 0 - notify successed, !0 - notify failed;
+ */
+int arisc_cpux_ready_notify(void)
+{
+ struct arisc_message *pmessage;
+
+ /* notify hwspinlock and hwmsgbox resume first */
+ arisc_hwmsgbox_standby_resume();
+ arisc_hwspinlock_standby_resume();
+
+ /* allocate a message frame */
+ pmessage = arisc_message_allocate(ARISC_MESSAGE_ATTR_HARDSYN);
+ if (pmessage == NULL) {
+ ARISC_WRN("allocate message failed\n");
+ return -ENOMEM;
+ }
+
+ /* initialize message */
+ pmessage->type = ARISC_SSTANDBY_RESTORE_NOTIFY;
+ pmessage->state = ARISC_MESSAGE_INITIALIZED;
+
+ arisc_hwmsgbox_send_message(pmessage, ARISC_SEND_MSG_TIMEOUT);
+
+ /* record wakeup event */
+ wakeup_event = pmessage->paras[0];
+ if (arisc_debug_dram_crc_en) {
+ dram_crc_error = pmessage->paras[1];
+ dram_crc_total_count++;
+ dram_crc_error_count += (dram_crc_error ? 1 : 0);
+ }
+
+ /* free message */
+ arisc_message_free(pmessage);
+
+ return 0;
+}
+
+int arisc_config_ir_paras(uint32_t ir_code, uint32_t ir_addr)
+{
+ int result = 0;
+ struct arisc_message *pmessage;
+
+ /* allocate a message frame */
+ pmessage = arisc_message_allocate(ARISC_MESSAGE_ATTR_HARDSYN);
+ if (pmessage == NULL) {
+ ARISC_WRN("allocate message failed\n");
+ return -ENOMEM;
+ }
+ /* initialize message */
+ pmessage->type = ARISC_SET_IR_PARAS;
+ pmessage->paras[0] = ir_code;
+ pmessage->paras[1] = ir_addr;
+ pmessage->state = ARISC_MESSAGE_INITIALIZED;
+ pmessage->cb.handler = NULL;
+ pmessage->cb.arg = NULL;
+
+ ARISC_INF("ir power key:0x%x, addr:0x%x\n", ir_code, ir_addr);
+
+ /* send request message */
+ arisc_hwmsgbox_send_message(pmessage, ARISC_SEND_MSG_TIMEOUT);
+ if (pmessage->result) {
+ ARISC_WRN("config ir power key code [%d] fail\n", pmessage->paras[0]);
+ result = -EINVAL;
+ }
+
+ /* free allocated message */
+ arisc_message_free(pmessage);
+
+ return result;
+}
diff --git a/plat/sun50iw1p1/scp/interfaces/interfaces.mk b/plat/sun50iw1p1/scp/interfaces/interfaces.mk
new file mode 100644
index 0000000..1571046
--- /dev/null
+++ b/plat/sun50iw1p1/scp/interfaces/interfaces.mk
@@ -0,0 +1,37 @@
+#
+# Copyright (c) 2013-2014, ARM Limited and Contributors. All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions are met:
+#
+# Redistributions of source code must retain the above copyright notice, this
+# list of conditions and the following disclaimer.
+#
+# Redistributions in binary form must reproduce the above copyright notice,
+# this list of conditions and the following disclaimer in the documentation
+# and/or other materials provided with the distribution.
+#
+# Neither the name of ARM nor the names of its contributors may be used
+# to endorse or promote products derived from this software without specific
+# prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+# POSSIBILITY OF SUCH DAMAGE.
+#
+
+BL31_SOURCES += plat/sun50iw1p1/scp/interfaces/arisc_loopback.c \
+ plat/sun50iw1p1/scp/interfaces/arisc_dvfs.c \
+ plat/sun50iw1p1/scp/interfaces/arisc_rsb.c\
+ plat/sun50iw1p1/scp/interfaces/arisc_axp.c \
+ plat/sun50iw1p1/scp/interfaces/arisc_standby.c \
+ plat/sun50iw1p1/scp/interfaces/arisc_dram_crc.c \
+ plat/sun50iw1p1/scp/interfaces/arisc_debug_level.c
diff --git a/plat/sun50iw1p1/scp/message_manager/message_manager.c b/plat/sun50iw1p1/scp/message_manager/message_manager.c
new file mode 100644
index 0000000..46b8969
--- /dev/null
+++ b/plat/sun50iw1p1/scp/message_manager/message_manager.c
@@ -0,0 +1,282 @@
+/*
+ * arch/arm/mach-sunxi/arisc/message_manager/message_manager.c
+ *
+ * Copyright (c) 2012 Allwinner.
+ * 2012-10-01 Written by superm (superm@allwinnertech.com).
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+
+#include "message_manager_i.h"
+
+/* the start and end of message pool */
+static struct arisc_message *message_start;
+static struct arisc_message *message_end;
+
+/* spinlock for this module */
+static spinlock_t msg_mgr_lock;
+
+/* message cache manager */
+static struct arisc_message_cache message_cache;
+
+static void *arisc_message_pool_base;
+static uint32_t arisc_message_pool_size;
+
+/**
+ * initialize message manager.
+ * @para: none.
+ *
+ * returns: 0 if initialize succeeded, others if failed.
+ */
+int arisc_message_manager_init(void *addr, uint32_t size)
+{
+ int i;
+
+ arisc_message_pool_base = addr;
+ arisc_message_pool_size = size;
+
+ /* initialize message pool start and end */
+ message_start = (struct arisc_message *)(arisc_message_pool_base);
+ message_end = (struct arisc_message *)((ptrdiff_t)arisc_message_pool_base + arisc_message_pool_size);
+
+ //memset((void *)message_start, 0, arisc_message_pool_size);
+
+ /* initialize message_cache */
+ for (i = 0; i < ARISC_MESSAGE_CACHED_MAX; i++) {
+ message_cache.cache[i] = NULL;
+ }
+ message_cache.number = 0;
+
+ return 0;
+}
+
+/**
+ * exit message manager.
+ * @para: none.
+ *
+ * returns: 0 if exit succeeded, others if failed.
+ */
+int arisc_message_manager_exit(void)
+{
+ return 0;
+}
+
+static int arisc_message_invalid(struct arisc_message *pmessage)
+{
+ if ((pmessage >= message_start) &&
+ (pmessage < message_end)) {
+ /* valid arisc message */
+ return 0;
+ }
+ /* invalid arisc message */
+ return 1;
+}
+
+/**
+ * allocate one message frame. mainly use for send message by message-box,
+ * the message frame allocate form messages pool shared memory area.
+ * @para: none.
+ *
+ * returns: the pointer of allocated message frame, NULL if failed;
+ */
+struct arisc_message *arisc_message_allocate(unsigned int msg_attr)
+{
+ struct arisc_message *pmessage = NULL;
+ struct arisc_message *palloc = NULL;
+
+ /* first find in message_cache */
+ spin_lock(&msg_mgr_lock);
+ if (message_cache.number) {
+ ARISC_INF("arisc message_cache.number = 0x%x.\n", message_cache.number);
+ message_cache.number--;
+ palloc = message_cache.cache[message_cache.number];
+ ARISC_INF("message [%llx] allocate from message_cache\n", palloc);
+ if (arisc_message_invalid(palloc)) {
+ ARISC_ERR("allocate cache message [%llx] invalid\n", palloc);
+ }
+ }
+ spin_unlock(&msg_mgr_lock);
+ if (arisc_message_invalid(palloc)) {
+ /*
+ * cached message_cache finded fail,
+ * use spinlock 0 to exclusive with arisc.
+ */
+ arisc_hwspin_lock(AW_MSG_HWSPINLOCK);
+
+ /* search from the start of message pool every time. */
+ pmessage = message_start;
+ while (pmessage < message_end) {
+ if (pmessage->state == ARISC_MESSAGE_FREED) {
+ /* find free message in message pool, allocate it */
+ palloc = pmessage;
+ palloc->state = ARISC_MESSAGE_ALLOCATED;
+ ARISC_INF("message [%llx] allocate from message pool\n", palloc);
+ break;
+ }
+ /* next message frame */
+ pmessage++;
+ }
+ /* unlock hwspinlock 0 */
+ arisc_hwspin_unlock(AW_MSG_HWSPINLOCK);
+ }
+ if (arisc_message_invalid(palloc)) {
+ ARISC_ERR("allocate message [%llx] frame is invalid\n", palloc);
+ return NULL;
+ }
+ /* initialize messgae frame */
+ palloc->next = NULL;
+ palloc->attr = msg_attr;
+ palloc->private = NULL;
+
+ return palloc;
+}
+
+/**
+ * free one message frame. mainly use for process message finished,
+ * free it to messages pool or add to free message queue.
+ * @pmessage: the pointer of free message frame.
+ *
+ * returns: none.
+ */
+void arisc_message_free(struct arisc_message *pmessage)
+{
+ struct arisc_message *free_message = pmessage;
+
+ /* check this message valid or not */
+ if (arisc_message_invalid(free_message)) {
+ ARISC_ERR("free invalid arisc message [%llx]\n", free_message);
+ return;
+ }
+
+ /* try to free to free_list first */
+ spin_lock(&msg_mgr_lock);
+ if (message_cache.number < ARISC_MESSAGE_CACHED_MAX) {
+ ARISC_INF("insert message [%llx] to message_cache\n", free_message);
+ ARISC_INF("message_cache number : %d\n", message_cache.number);
+ /* cached this message, message state: ALLOCATED */
+ message_cache.cache[message_cache.number] = free_message;
+ message_cache.number++;
+ free_message->next = NULL;
+ free_message->state = ARISC_MESSAGE_ALLOCATED;
+ free_message = NULL;
+ }
+ spin_unlock(&msg_mgr_lock);
+
+ /* try to free message to pool if free to cache fail */
+ if (free_message) {
+ /* free to message pool,set message state as FREED. */
+ arisc_hwspin_lock(AW_MSG_HWSPINLOCK);
+ ARISC_INF("insert message [%llx] to message pool\n", free_message);
+ free_message->state = ARISC_MESSAGE_FREED;
+ free_message->next = NULL;
+ arisc_hwspin_unlock(AW_MSG_HWSPINLOCK);
+ }
+}
+
+/**
+ * notify system that one message coming.
+ * @pmessage: the pointer of coming message frame.
+ *
+ * returns: 0 if notify succeeded, other if failed.
+ */
+int arisc_message_coming_notify(struct arisc_message *pmessage)
+{
+ int ret;
+
+ /* ac327 receive message to arisc */
+ ARISC_INF("-------------------------------------------------------------\n");
+ ARISC_INF(" MESSAGE FROM ARISC \n");
+ ARISC_INF("message addr : %llx\n", pmessage);
+ ARISC_INF("message type : %x\n", pmessage->type);
+ ARISC_INF("message attr : %x\n", pmessage->attr);
+ ARISC_INF("-------------------------------------------------------------\n");
+
+ /* message per-process */
+ pmessage->state = ARISC_MESSAGE_PROCESSING;
+
+ /* process message */
+ switch (pmessage->type) {
+ case ARISC_AXP_INT_COMING_NOTIFY: {
+ ARISC_INF("pmu interrupt coming notify\n");
+ ret = arisc_axp_int_notify(pmessage);
+ pmessage->result = ret;
+ break;
+ }
+ case ARISC_AUDIO_PERDONE_NOTIFY: {
+ ARISC_INF("audio perdone notify\n");
+ ret = arisc_audio_perdone_notify(pmessage);
+ pmessage->result = ret;
+ break;
+ }
+ case ARISC_REPORT_ERR_INFO: {
+ ARISC_INF("arisc report error info\n");
+ ret = arisc_report_error_info(pmessage);
+ pmessage->result = ret;
+ break;
+ }
+
+ default : {
+ ARISC_ERR("invalid message type for ac327 process\n");
+ ARISC_ERR("message addr : %llx\n", pmessage);
+ ARISC_ERR("message state : %x\n", pmessage->state);
+ ARISC_ERR("message attr : %x\n", pmessage->attr);
+ ARISC_ERR("message type : %x\n", pmessage->type);
+ ARISC_ERR("message result : %x\n", pmessage->result);
+ ret = -EINVAL;
+ break;
+ }
+ }
+ /* message post process */
+ pmessage->state = ARISC_MESSAGE_PROCESSED;
+ if (pmessage->attr & ARISC_MESSAGE_ATTR_HARDSYN) {
+ /* synchronous message, should feedback process result */
+ arisc_hwmsgbox_feedback_message(pmessage, ARISC_SEND_MSG_TIMEOUT);
+ } else {
+ /*
+ * asyn message, no need feedback message result,
+ * free message directly.
+ */
+ arisc_message_free(pmessage);
+ }
+
+ return ret;
+}
+
+struct arisc_message *arisc_message_map_to_cpux(uint32_t addr)
+{
+ struct arisc_message *message;
+ message = (struct arisc_message *)((ptrdiff_t)addr + (ptrdiff_t)arisc_message_pool_base);
+
+ return message;
+}
+
+uint32_t arisc_message_map_to_cpus(struct arisc_message *message)
+{
+ uint32_t value = (uint32_t)((ptrdiff_t)message - (ptrdiff_t)arisc_message_pool_base);
+
+ return value;
+}
+
+int arisc_message_valid(struct arisc_message *pmessage)
+{
+ if ((pmessage >= message_start) && (pmessage < message_end)) {
+ /* valid message */
+ return 1;
+ }
+
+ return 0;
+}
+
diff --git a/plat/sun50iw1p1/scp/message_manager/message_manager.mk b/plat/sun50iw1p1/scp/message_manager/message_manager.mk
new file mode 100644
index 0000000..806f3ef
--- /dev/null
+++ b/plat/sun50iw1p1/scp/message_manager/message_manager.mk
@@ -0,0 +1,31 @@
+#
+# Copyright (c) 2013-2014, ARM Limited and Contributors. All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions are met:
+#
+# Redistributions of source code must retain the above copyright notice, this
+# list of conditions and the following disclaimer.
+#
+# Redistributions in binary form must reproduce the above copyright notice,
+# this list of conditions and the following disclaimer in the documentation
+# and/or other materials provided with the distribution.
+#
+# Neither the name of ARM nor the names of its contributors may be used
+# to endorse or promote products derived from this software without specific
+# prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+# POSSIBILITY OF SUCH DAMAGE.
+#
+
+BL31_SOURCES += plat/sun50iw1p1/scp/message_manager/message_manager.c
diff --git a/plat/sun50iw1p1/scp/message_manager/message_manager_i.h b/plat/sun50iw1p1/scp/message_manager/message_manager_i.h
new file mode 100644
index 0000000..54c5383
--- /dev/null
+++ b/plat/sun50iw1p1/scp/message_manager/message_manager_i.h
@@ -0,0 +1,40 @@
+/*
+ * arch/arm/mach-sunxi/arisc/message_manager/message_manager_i.h
+ *
+ * Copyright (c) 2012 Allwinner.
+ * 2012-10-01 Written by superm (superm@allwinnertech.com).
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#ifndef __ARISC_MESSAGE_MANAGER_I_H
+#define __ARISC_MESSAGE_MANAGER_I_H
+
+#include "../include/arisc_includes.h"
+#include "../arisc_i.h"
+
+#define ARISC_SEM_CACHE_MAX (8)
+
+/*
+ *the strcuture of message cache,
+ *main for messages cache management.
+ */
+typedef struct arisc_message_cache
+{
+ uint32_t number; /* valid message number */
+ struct arisc_message *cache[ARISC_MESSAGE_CACHED_MAX]; /* message cache table */
+} arisc_message_cache_t;
+
+#endif /* __ARISC_MESSAGE_MANAGER_I_H */
diff --git a/plat/sun50iw1p1/scpi.c b/plat/sun50iw1p1/scpi.c
new file mode 100644
index 0000000..e09ed90
--- /dev/null
+++ b/plat/sun50iw1p1/scpi.c
@@ -0,0 +1,140 @@
+/*
+ * Copyright (c) 2014, ARM Limited and Contributors. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * Neither the name of ARM nor the names of its contributors may be used
+ * to endorse or promote products derived from this software without specific
+ * prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <arch_helpers.h>
+#include <platform.h>
+#include "sunxi_def.h"
+#include "mhu.h"
+#include "scpi.h"
+
+#define MHU_SECURE_SCP_TO_AP_PAYLOAD (MHU_SECURE_BASE+0x0080)
+#define MHU_SECURE_AP_TO_SCP_PAYLOAD (MHU_SECURE_BASE+0x0280)
+
+#define SIZE_SHIFT 20 /* Bit position for size value in MHU header */
+#define SIZE_MASK 0x1ff /* Mask to extract size value in MHU header*/
+
+
+void *scpi_secure_message_start(void)
+{
+ mhu_secure_message_start();
+
+ /* Return address of payload area. */
+ return (void *)MHU_SECURE_AP_TO_SCP_PAYLOAD;
+}
+
+void scpi_secure_message_send(unsigned command, size_t size)
+{
+ /* Make sure payload can be seen by SCP */
+ if (MHU_PAYLOAD_CACHED)
+ flush_dcache_range(MHU_SECURE_AP_TO_SCP_PAYLOAD, size);
+
+ mhu_secure_message_send(command | (size << SIZE_SHIFT));
+}
+
+unsigned scpi_secure_message_receive(void **message_out, size_t *size_out)
+{
+ uint32_t response = mhu_secure_message_wait();
+
+ /* Get size of payload */
+ size_t size = (response >> SIZE_SHIFT) & SIZE_MASK;
+
+ /* Clear size from response */
+ response &= ~(SIZE_MASK << SIZE_SHIFT);
+
+ /* Make sure we don't read stale data */
+ if (MHU_PAYLOAD_CACHED)
+ inv_dcache_range(MHU_SECURE_SCP_TO_AP_PAYLOAD, size);
+
+ if (size_out)
+ *size_out = size;
+
+ if (message_out)
+ *message_out = (void *)MHU_SECURE_SCP_TO_AP_PAYLOAD;
+
+ return response;
+}
+
+void scpi_secure_message_end(void)
+{
+ mhu_secure_message_end();
+}
+
+static void scpi_secure_send32(unsigned command, uint32_t message)
+{
+ *(__typeof__(message) *)scpi_secure_message_start() = message;
+ scpi_secure_message_send(command, sizeof(message));
+ scpi_secure_message_end();
+}
+
+int scpi_wait_ready(void)
+{
+ /* Get a message from the SCP */
+ scpi_secure_message_start();
+ size_t size;
+ unsigned command = scpi_secure_message_receive(NULL, &size);
+ scpi_secure_message_end();
+
+ /* We are expecting 'SCP Ready', produce correct error if it's not */
+ scpi_status_t response = SCP_OK;
+ if (command != SCPI_CMD_SCP_READY)
+ response = SCP_E_SUPPORT;
+ else if (size != 0)
+ response = SCP_E_SIZE;
+
+ /* Send our response back to SCP */
+ scpi_secure_send32(command, response);
+
+ return response == SCP_OK ? 0 : -1;
+}
+
+void scpi_set_css_power_state(unsigned mpidr, scpi_power_state_t cpu_state,
+ scpi_power_state_t cluster_state, scpi_power_state_t css_state)
+{
+ uint32_t state = mpidr & 0x0f; /* CPU ID */
+ state |= (mpidr & 0xf00) >> 4; /* Cluster ID */
+ state |= cpu_state << 8;
+ state |= cluster_state << 12;
+ state |= css_state << 16;
+ scpi_secure_send32(SCPI_CMD_SET_CSS_POWER_STATE, state);
+}
+
+uint32_t scpi_sys_power_state(scpi_system_state_t system_state)
+{
+ uint32_t *response;
+ size_t size;
+ uint8_t state = system_state & 0xff;
+
+ /* Send the command */
+ *(__typeof__(state) *)scpi_secure_message_start() = state;
+ scpi_secure_message_send(SCPI_CMD_SYS_POWER_STATE, sizeof(state));
+ scpi_secure_message_receive((void *)&response, &size);
+ scpi_secure_message_end();
+ return *response;
+}
diff --git a/plat/sun50iw1p1/scpi.h b/plat/sun50iw1p1/scpi.h
new file mode 100644
index 0000000..8a5ef65
--- /dev/null
+++ b/plat/sun50iw1p1/scpi.h
@@ -0,0 +1,82 @@
+/*
+ * Copyright (c) 2014, ARM Limited and Contributors. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * Neither the name of ARM nor the names of its contributors may be used
+ * to endorse or promote products derived from this software without specific
+ * prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef __SCPI_H__
+#define __SCPI_H__
+
+#include <stddef.h>
+#include <stdint.h>
+
+extern void *scpi_secure_message_start(void);
+extern void scpi_secure_message_send(unsigned command, size_t size);
+extern unsigned scpi_secure_message_receive(void **message_out, size_t *size_out);
+extern void scpi_secure_message_end(void);
+
+
+enum {
+ SCP_OK = 0, /* Success */
+ SCP_E_PARAM, /* Invalid parameter(s) */
+ SCP_E_ALIGN, /* Invalid alignment */
+ SCP_E_SIZE, /* Invalid size */
+ SCP_E_HANDLER, /* Invalid handler or callback */
+ SCP_E_ACCESS, /* Invalid access or permission denied */
+ SCP_E_RANGE, /* Value out of range */
+ SCP_E_TIMEOUT, /* Time out has ocurred */
+ SCP_E_NOMEM, /* Invalid memory area or pointer */
+ SCP_E_PWRSTATE, /* Invalid power state */
+ SCP_E_SUPPORT, /* Feature not supported or disabled */
+};
+
+typedef uint32_t scpi_status_t;
+
+typedef enum {
+ SCPI_CMD_SCP_READY = 0x01,
+ SCPI_CMD_SET_CSS_POWER_STATE = 0x04,
+ SCPI_CMD_SYS_POWER_STATE = 0x08
+} scpi_command_t;
+
+typedef enum {
+ scpi_power_on = 0,
+ scpi_power_retention = 1,
+ scpi_power_off = 3,
+} scpi_power_state_t;
+
+typedef enum {
+ scpi_system_shutdown = 0,
+ scpi_system_reboot = 1,
+ scpi_system_reset = 2
+} scpi_system_state_t;
+
+extern int scpi_wait_ready(void);
+extern void scpi_set_css_power_state(unsigned mpidr, scpi_power_state_t cpu_state,
+ scpi_power_state_t cluster_state, scpi_power_state_t css_state);
+uint32_t scpi_sys_power_state(scpi_system_state_t system_state);
+
+#endif /* __SCPI_H__ */
diff --git a/plat/sun50iw1p1/sun50iw1p1.h b/plat/sun50iw1p1/sun50iw1p1.h
new file mode 100644
index 0000000..2013b38
--- /dev/null
+++ b/plat/sun50iw1p1/sun50iw1p1.h
@@ -0,0 +1,127 @@
+/*
+ * (C) Copyright 2007-2015
+ * Allwinner Technology Co., Ltd. <www.allwinnertech.com>
+ * Jerry Wang <wangflord@allwinnertech.com>
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * SPDX-License-Identifier: GPL-2.0
+ */
+
+#ifndef __PLATFORM_H
+#define __PLATFORM_H
+
+#define SUNXI_SRAM_D_BASE (0x00010000L)
+/* base address of modules */
+#define SUNXI_DE_BASE (0x01000000L)
+#define SUNXI_CORESIGHT_DEBUG_BASE (0x01400000L)
+#define SUNXI_CPU_MBIST_BASE (0x01502000L)
+#define SUNXI_CPUX_CFG_BASE (0x01700000L)
+
+
+#define SUNXI_SYSCRL_BASE (0x01c00000L)
+
+#define SUNXI_DMA_BASE (0x01c02000L)
+#define SUNXI_NFC_BASE (0x01c03000L)
+#define SUNXI_TSC_BASE (0x01c06000L)
+
+#define SUNXI_TCON0_BASE (0x01c0c000L)
+#define SUNXI_TCON1_BASE (0x01c0d000L)
+#define SUNXI_VE_BASE (0x01c0e000L)
+
+#define SUNXI_SMHC0_BASE (0x01c0f000L)
+#define SUNXI_SMHC1_BASE (0x01c10000L)
+#define SUNXI_SMHC2_BASE (0x01c11000L)
+
+#define SUNXI_SID_BASE (0x01c14000L)
+#define SUNXI_SS_BASE (0x01c15000L)
+
+#define SUNXI_MSGBOX_BASE (0x01c17000L)
+#define SUNXI_SPINLOCK_BASE (0x01c18000L)
+
+#define SUNXI_USBOTG_BASE (0x01c19000L)
+#define SUNXI_EHCI0_BASE (0x01c1a000L)
+#define SUNXI_EHCI1_BASE (0x01c1b000L)
+
+#define SUNXI_SMC_BASE (0x01c1e000L)
+
+#define SUNXI_CCM_BASE (0x01c20000L)
+#define SUNXI_PIO_BASE (0x01c20800L)
+#define SUNXI_TIMER_BASE (0x01c20c00L)
+#define SUNXI_SPDIF_BASE (0x01c21000L)
+#define SUNXI_PWM03_BASE (0x01c21400L)
+
+#define SUNXI_KEYADC_BASE (0x01c21800L)
+#define SUNXI_DAUDIO0_BASE (0x01c22000L)
+#define SUNXI_DAUDIO1_BASE (0x01c24000L)
+#define SUNXI_DAUDIO2_BASE (0x01c28000L)
+
+#define SUNXI_AC_BASE (0x01c22c00L)
+#define SUNXI_SPC_BASE (0x01c23400L)
+#define SUNXI_THC_BASE (0x01c25000L)
+
+#define SUNXI_UART0_BASE (0x01c28000L)
+#define SUNXI_UART1_BASE (0x01c28400L)
+#define SUNXI_UART2_BASE (0x01c28800L)
+#define SUNXI_UART3_BASE (0x01c28c00L)
+#define SUNXI_UART4_BASE (0x01c29000L)
+
+#define SUNXI_TWI0_BASE (0x01c2ac00L)
+#define SUNXI_TWI1_BASE (0x01c2b000L)
+#define SUNXI_TWI2_BASE (0x01c2b400L)
+#define SUNXI_SCR_BASE (0x01c2c400L)
+
+#define SUNXI_EMAC_BASE (0x01c30000L)
+#define SUNXI_GPU_BASE (0x01c40000L)
+#define SUNXI_HSTMR_BASE (0x01c60000L)
+
+#define SUNXI_DRAMCOM_BASE (0x01c62000L)
+#define SUNXI_DRAMCTL0_BASE (0x01c63000L)
+#define SUNXI_DRAMPHY0_BASE (0x01c65000L)
+
+#define SUNXI_SPI0_BASE (0x01c68000L)
+#define SUNXI_SPI1_BASE (0x01c69000L)
+
+#define ARMA9_SCU_BASE (0x01c80000L)
+#define ARMA9_GIC_BASE (0x01c81000L)
+#define ARMA9_CPUIF_BASE (0x01c82000L)
+
+/* Base sunxi compatible GIC memory map */
+#define GICD_BASE ARMA9_GIC_BASE
+#define GICC_BASE ARMA9_CPUIF_BASE
+
+
+#define SUNXI_MIPI_DSI0_BASE (0x01ca0000L)
+#define SUNXI_MIPI_DSIPHY_BASE (0x01ca1000L)
+
+#define SUNXI_CSI0_BASE (0x01cb0000L)
+#define SUNXI_DE_INTERLACED_BASE (0x01e00000L)
+#define SUNXI_HDMI_BASE (0x01ee0000L)
+#define HDMI_BASE SUNXI_HDMI_BASE
+
+#define SUNXI_RTC_BASE (0x01f00000L)
+#define SUNXI_RTMR01_BASE (0x01f00800L)
+#define SUNXI_RINTC_BASE (0x01f00C00L)
+#define SUNXI_RWDOG_BASE (0x01f01000L)
+#define SUNXI_RPRCM_BASE (0x01f01400L)
+#define SUNXI_RTWD_BASE (0x01f01800L)
+#define SUNXI_RCPUCFG_BASE (0x01f01C00L)
+#define SUNXI_RCIR_BASE (0x01f02000L)
+#define SUNXI_RTWI_BASE (0x01f02400L)
+#define SUNXI_RUART_BASE (0x01f02800L)
+#define SUNXI_RPIO_BASE (0x01f02c00L)
+#define SUNXI_RRSB_BASE (0x01f03400L)
+#define SUNXI_RPWM_BASE (0x01f03800L)
+
+#endif
diff --git a/plat/sun50iw1p1/sunxi_cpu_ops.c b/plat/sun50iw1p1/sunxi_cpu_ops.c
new file mode 100644
index 0000000..04978b1
--- /dev/null
+++ b/plat/sun50iw1p1/sunxi_cpu_ops.c
@@ -0,0 +1,245 @@
+/*
+ * Copyright (c) 2014, ARM Limited and Contributors. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * Neither the name of ARM nor the names of its contributors may be used
+ * to endorse or promote products derived from this software without specific
+ * prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+#include <arch.h>
+#include <arch_helpers.h>
+#include <platform.h>
+#include <platform_def.h>
+#include <mmio.h>
+#include <debug.h>
+#include <bakery_lock.h>
+#include "sunxi_def.h"
+#include "sunxi_private.h"
+
+#define SUN50I_PRCM_PBASE (0x01F01400)
+#define SUN50I_CPUCFG_PBASE (0x01700000)
+#define SUN50I_RCPUCFG_PBASE (0x01F01C00)
+
+#define SUNXI_CPU_PWR_CLAMP(cluster, cpu) (0x140 + (cluster*4 + cpu)*0x04)
+#define SUNXI_CLUSTER_PWROFF_GATING(cluster) (0x100 + (cluster)*0x04)
+#define SUNXI_CLUSTER_PWRON_RESET(cluster) (0x30 + (cluster)*0x04)
+
+#define SUNXI_DBG_REG0 (0x20)
+#define SUNXI_CLUSTER_CPU_STATUS(cluster) (0x30 + (cluster)*0x4)
+#define SUNXI_CPU_RST_CTRL(cluster) (0x80 + (cluster)*0x4)
+#define SUNXI_CLUSTER_CTRL0(cluster) (0x00 + (cluster)*0x10)
+
+#define SUNXI_CPU_RVBA_L(cpu) (0xA0 + (cpu)*0x8)
+#define SUNXI_CPU_RVBA_H(cpu) (0xA4 + (cpu)*0x8)
+
+#define readl(x) mmio_read_32((x))
+#define writel(v, a) mmio_write_32((a), (v))
+ typedef unsigned int bool;
+
+ static unsigned int sun50i_cpucfg_base = SUN50I_CPUCFG_PBASE;
+ static unsigned int sun50i_prcm_base = SUN50I_PRCM_PBASE;
+ static unsigned int sun50i_r_cpucfg_base = SUN50I_RCPUCFG_PBASE;
+ extern bakery_lock_t plat_console_lock;
+ void udelay(unsigned int delay)
+ {
+ unsigned int i, j;
+
+ for (i=0; i<1000*delay; i++)
+ {
+ j+=i;
+ }
+ }
+
+ void sun50i_set_secondary_entry(unsigned long entry, unsigned int cpu)
+ {
+ mmio_write_32(sun50i_cpucfg_base + SUNXI_CPU_RVBA_L(cpu) ,entry);
+ mmio_write_32(sun50i_cpucfg_base + SUNXI_CPU_RVBA_H(cpu), 0);
+ }
+
+ void sun50i_set_AA32nAA64(unsigned int cluster, unsigned int cpu, bool is_aa64)
+ {
+ volatile unsigned int value;
+
+ value = readl(sun50i_cpucfg_base + SUNXI_CLUSTER_CTRL0(cluster));
+ value &= ~(1<<(cpu + 24));
+ value |= (is_aa64 <<(cpu + 24));
+ writel(value, sun50i_cpucfg_base + SUNXI_CLUSTER_CTRL0(cluster));
+ value = readl(sun50i_cpucfg_base + SUNXI_CLUSTER_CTRL0(cluster));
+ }
+
+ int sun50i_power_switch_set(unsigned int cluster, unsigned int cpu, bool enable)
+ {
+ if (enable) {
+ if (0x00 == readl(sun50i_prcm_base + SUNXI_CPU_PWR_CLAMP(cluster, cpu))) {
+ NOTICE("%s: power switch enable already\n", __func__);
+ return 0;
+ }
+
+ /* de-active cpu power clamp */
+ writel(0xFE, sun50i_prcm_base + SUNXI_CPU_PWR_CLAMP(cluster, cpu));
+ udelay(20);
+
+ writel(0xF8, sun50i_prcm_base + SUNXI_CPU_PWR_CLAMP(cluster, cpu));
+ udelay(10);
+
+ writel(0xE0, sun50i_prcm_base + SUNXI_CPU_PWR_CLAMP(cluster, cpu));
+ udelay(10);
+
+ writel(0x80, sun50i_prcm_base + SUNXI_CPU_PWR_CLAMP(cluster, cpu));
+ udelay(10);
+
+ writel(0x00, sun50i_prcm_base + SUNXI_CPU_PWR_CLAMP(cluster, cpu));
+ udelay(20);
+
+ while (0x00 != readl(sun50i_prcm_base + SUNXI_CPU_PWR_CLAMP(cluster, cpu)));
+ } else {
+ if (0xFF == readl(sun50i_prcm_base + SUNXI_CPU_PWR_CLAMP(cluster, cpu))) {
+ NOTICE("%s: power switch disable already\n", __func__);
+ return 0;
+ }
+
+ writel(0xFF, sun50i_prcm_base + SUNXI_CPU_PWR_CLAMP(cluster, cpu));
+ udelay(30);
+
+ while (0xFF != readl(sun50i_prcm_base + SUNXI_CPU_PWR_CLAMP(cluster, cpu)));
+ }
+ return 0;
+ }
+
+ void sun50i_cpu_power_up(unsigned int cluster, unsigned int cpu)
+ {
+ unsigned int value;
+
+ /* Assert nCPUPORESET LOW */
+ value = readl(sun50i_cpucfg_base + SUNXI_CPU_RST_CTRL(cluster));
+ value &= (~(1<<cpu));
+ writel(value, sun50i_cpucfg_base + SUNXI_CPU_RST_CTRL(cluster));
+ udelay(10);
+
+ /* Assert cpu power-on reset */
+ value = readl(sun50i_r_cpucfg_base + SUNXI_CLUSTER_PWRON_RESET(cluster));
+ value &= (~(1<<cpu));
+ writel(value, sun50i_r_cpucfg_base + SUNXI_CLUSTER_PWRON_RESET(cluster));
+ udelay(10);
+
+ /* set AA32nAA64 to AA64 */
+ sun50i_set_AA32nAA64(cluster, cpu, 1);
+
+ /* Apply power to the PDCPU power domain. */
+ sun50i_power_switch_set(cluster, cpu, 1);
+
+ /* Release the core output clamps */
+ value = readl(sun50i_prcm_base + SUNXI_CLUSTER_PWROFF_GATING(cluster));
+ value &= (~(0x1<<cpu));
+ writel(value, sun50i_prcm_base + SUNXI_CLUSTER_PWROFF_GATING(cluster));
+ udelay(20);
+
+ /* Deassert cpu power-on reset */
+ value = readl(sun50i_r_cpucfg_base + SUNXI_CLUSTER_PWRON_RESET(cluster));
+ value |= ((1<<cpu));
+ writel(value, sun50i_r_cpucfg_base + SUNXI_CLUSTER_PWRON_RESET(cluster));
+ udelay(10);
+
+ /* Deassert core reset */
+ value = readl(sun50i_cpucfg_base + SUNXI_CPU_RST_CTRL(cluster));
+ value |= (1<<cpu);
+ writel(value, sun50i_cpucfg_base + SUNXI_CPU_RST_CTRL(cluster));
+ udelay(10);
+
+ /* Assert DBGPWRDUP HIGH */
+ value = readl(sun50i_cpucfg_base + SUNXI_DBG_REG0);
+ value |= (1<<cpu);
+ writel(value, sun50i_cpucfg_base + SUNXI_DBG_REG0);
+ udelay(10);
+ bakery_lock_get(&plat_console_lock);
+ INFO("sun50i power-up cluster-%d cpu-%d ok\n", cluster, cpu);
+ bakery_lock_release(&plat_console_lock);
+ }
+
+void sun50i_cpu_power_down(unsigned int cluster, unsigned int cpu)
+{
+ unsigned int value;
+
+ /* step7: Deassert DBGPWRDUP LOW */
+ value = readl(sun50i_cpucfg_base + SUNXI_DBG_REG0);
+ value &= (~(1<<cpu));
+ writel(value, sun50i_cpucfg_base + SUNXI_DBG_REG0);
+ udelay(10);
+
+ /* step8: Activate the core output clamps */
+ value = readl(sun50i_prcm_base + SUNXI_CLUSTER_PWROFF_GATING(cluster));
+ value |= (1 << cpu);
+ writel(value, sun50i_prcm_base + SUNXI_CLUSTER_PWROFF_GATING(cluster));
+ udelay(20);
+
+ /* step9: Assert nCPUPORESET LOW */
+ value = readl(sun50i_cpucfg_base + SUNXI_CPU_RST_CTRL(cluster));
+ value &= (~(1<<cpu));
+ writel(value, sun50i_cpucfg_base + SUNXI_CPU_RST_CTRL(cluster));
+ udelay(10);
+
+ /* step10: Remove power from th e PDCPU power domain */
+ sun50i_power_switch_set(cluster, cpu, 0);
+ bakery_lock_get(&plat_console_lock);
+ INFO("sun50i power-down cluster-%d cpu-%d ok.\n", cluster, cpu);
+ bakery_lock_release(&plat_console_lock);
+
+}
+
+void sunxi_cpu_die(unsigned int cpu)
+{
+ #if 0
+ unsigned long sctlr, cpuectlr;
+
+ /* step1: Disable the data cache */
+ __asm("mrs %0, SCTLR_EL1\n" : "=r" (sctlr));
+ sctlr &= ~(0x1<<2);
+ __asm volatile("msr SCTLR_EL1, %0\n" : : "r" (sctlr));
+
+ /* step2: Clean and invalidate all data from the L1 Data cache */
+ //flush_cache_all();
+ dcsw_op_louis(DCCSW);
+
+ /* step3: Disable data coherency with other cores in the cluster */
+ __asm("mrs %0, S3_1_c15_c2_1\n" : "=r" (cpuectlr));
+ cpuectlr &= ~(0x1<<6);
+ __asm volatile("msr S3_1_c15_c2_1, %0\n" : : "r" (cpuectlr));
+
+ /*
+ * step4: Execute an ISB instruction to ensure that
+ * all of the register changes from the previous steps
+ * have been committed
+ */
+ isb();
+
+ /*
+ * step5: Execute a DSB SY instruction to ensure that all cache,
+ * TLB and branch predictor maintenance operations issued
+ * by any core in the cluster device before the SMPEN bit
+ * was cleared have completed
+ */
+ dsb();
+ #endif
+}
+
diff --git a/plat/sun50iw1p1/sunxi_cpu_ops.h b/plat/sun50iw1p1/sunxi_cpu_ops.h
new file mode 100644
index 0000000..ce49903
--- /dev/null
+++ b/plat/sun50iw1p1/sunxi_cpu_ops.h
@@ -0,0 +1,39 @@
+/*
+ * Copyright (c) 2014, ARM Limited and Contributors. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * Neither the name of ARM nor the names of its contributors may be used
+ * to endorse or promote products derived from this software without specific
+ * prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef __SUNXI_CPU_OPS_H__
+#define __SUNXI_CPU_OPS_H__
+
+void sun50i_set_secondary_entry(unsigned long entry, unsigned int cpu);
+void sun50i_cpu_power_up(unsigned int cluster, unsigned int cpu);
+void sun50i_cpu_power_down(unsigned int cluster, unsigned int cpu);
+void sunxi_cpu_die(unsigned int cpu);
+
+#endif
diff --git a/plat/sun50iw1p1/sunxi_def.h b/plat/sun50iw1p1/sunxi_def.h
new file mode 100644
index 0000000..f4db727
--- /dev/null
+++ b/plat/sun50iw1p1/sunxi_def.h
@@ -0,0 +1,124 @@
+/*
+ * Copyright (c) 2014, ARM Limited and Contributors. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * Neither the name of ARM nor the names of its contributors may be used
+ * to endorse or promote products derived from this software without specific
+ * prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+ /*-------------------------------------------------------------------------------
+| | | | |
+| ATF | (atf&scp)share | Trusted OS | Linux |
+| | | | |
+ ----------------------------------------------------------------------------------
+| | | | |
+| 1M | 1M | 14M | other |
+| | | | |
+----------------------------------------------------------------------------------*/
+
+#ifndef __SUNXI_DEF_H__
+#define __SUNXI_DEF_H__
+
+#include "sun50iw1p1.h"
+/* Firmware Image Package */
+#define FIP_IMAGE_NAME "fip.bin"
+#define SUNXI_PRIMARY_CPU 0x0
+
+/* Memory location options for Shared data and TSP in sunxi */
+#define SUNXI_IN_TRUSTED_SRAM 0
+#define SUNXI_IN_TRUSTED_DRAM 1
+
+/*******************************************************************************
+ * sunxi memory map related constants
+ ******************************************************************************/
+
+#define SUNXI_MAX_DRAM_SIZE (2ull<<30) /*2G*/
+
+//monitor area(atf+scp)
+#define SUNXI_TRUSTED_MONITOR_BASE 0x40000000
+#define SUNXI_TRUSTED_MONITOR_SIZE (2<<20) //2MB
+
+//sec os area
+#define SUNXI_TRUSTED_DRAM_BASE 0x40200000
+#define SUNXI_TRUSTED_DRAM_SIZE (14<<20) //14 MB
+
+//monitor area + sec os area
+#define SUNXI_TRUSTED_RAM_SIZE 0x01000000 //total 16M
+
+//atf code limit
+#define SUNXI_TRUSTED_MONITOR_LIMIT (SUNXI_TRUSTED_MONITOR_BASE + (1<<20)) //1M
+
+
+/* 4KB shared memory */
+#define SUNXI_SHARED_RAM_SIZE 0x1000
+
+/* Shared memory at the base of Trusted DRAM */
+#define SUNXI_SHARED_RAM_BASE SUNXI_TRUSTED_DRAM_BASE
+
+
+#define DRAM1_BASE 0x40000000ull
+#define DRAM1_SIZE 0x40000000ull //1G
+#define DRAM1_END (DRAM1_BASE + DRAM1_SIZE - 1)
+#define DRAM1_SEC_SIZE 0x01000000ull
+
+#define DRAM_BASE DRAM1_BASE
+#define DRAM_SIZE DRAM1_SIZE
+
+#define MEMRES_BASE SUNXI_TRUSTED_MONITOR_LIMIT //0x40100000
+#define MEMRES_SIZE 0x100000 //1M
+
+/* Load address of BL33 in the sunxi */
+#define NS_IMAGE_OFFSET (DRAM1_BASE + 0xA000000) /* DRAM + 128MB */
+
+/* Special value used to verify platform parameters from BL2 to BL3-1 */
+#define SUNXI_BL31_PLAT_PARAM_VAL 0x12345678 //0x0f1e2d3c4b5a6978ULL
+
+
+/*******************************************************************************
+ * PL011 related constants
+ ******************************************************************************/
+#define UART0_BAUDRATE 115200
+
+#define UART0_CLK_IN_HZ 24000000
+
+/*******************************************************************************
+ * Shared Data
+ ******************************************************************************/
+
+/* Entrypoint mailboxes */
+#define TRUSTED_MAILBOXES_BASE SUNXI_SHARED_RAM_BASE
+#define TRUSTED_MAILBOXES_SIZE 0x200
+#define TRUSTED_MAILBOX_SHIFT 4
+
+
+/* Base address where parameters to BL31 are stored */
+#define PARAMS_BASE (TRUSTED_MAILBOXES_BASE + TRUSTED_MAILBOXES_SIZE)
+
+#define MHU_SECURE_BASE 0x10000
+#define MHU_SECURE_SIZE 0x1000
+
+#define MHU_PAYLOAD_CACHED 0
+
+#endif /* __SUNXI_DEF_H__ */
diff --git a/plat/sun50iw1p1/sunxi_private.h b/plat/sun50iw1p1/sunxi_private.h
new file mode 100644
index 0000000..e2c548f
--- /dev/null
+++ b/plat/sun50iw1p1/sunxi_private.h
@@ -0,0 +1,107 @@
+/*
+ * Copyright (c) 2014, ARM Limited and Contributors. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * Neither the name of ARM nor the names of its contributors may be used
+ * to endorse or promote products derived from this software without specific
+ * prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef __SUNXI_PRIVATE_H__
+#define __SUNXI_PRIVATE_H__
+
+#include <bl_common.h>
+#include <platform_def.h>
+
+
+void gic_cpuif_deactivate(unsigned int gicc_base);
+void gic_cpuif_setup(unsigned int gicc_base);
+void gic_pcpu_distif_setup(unsigned int gicd_base);
+void gic_setup(void);
+
+
+typedef volatile struct mailbox {
+ unsigned long value
+ __attribute__((__aligned__(CACHE_WRITEBACK_GRANULE)));
+} mailbox_t;
+
+/*******************************************************************************
+ * This structure represents the superset of information that is passed to
+ * BL31 e.g. while passing control to it from BL2 which is bl31_params
+ * and bl31_plat_params and its elements
+ ******************************************************************************/
+typedef struct bl2_to_bl31_params_mem {
+ bl31_params_t bl31_params;
+ image_info_t bl31_image_info;
+ image_info_t bl32_image_info;
+ image_info_t bl33_image_info;
+ entry_point_info_t bl33_ep_info;
+ entry_point_info_t bl32_ep_info;
+ entry_point_info_t bl31_ep_info;
+} bl2_to_bl31_params_mem_t;
+
+/*******************************************************************************
+ * Forward declarations
+ ******************************************************************************/
+struct meminfo;
+
+/*******************************************************************************
+ * Function and variable prototypes
+ ******************************************************************************/
+void sunxi_configure_mmu_el1(unsigned long total_base,
+ unsigned long total_size,
+ unsigned long,
+ unsigned long,
+ unsigned long,
+ unsigned long);
+void sunxi_configure_mmu_el3(unsigned long total_base,
+ unsigned long total_size,
+ unsigned long,
+ unsigned long,
+ unsigned long,
+ unsigned long);
+int sunxi_config_setup(void);
+
+void sunxi_cci_init(void);
+void sunxi_cci_enable(void);
+
+void sunxi_gic_init(void);
+
+/* Declarations for sunxi_topology.c */
+int sunxi_setup_topology(void);
+
+/* Declarations for sunxi_io_storage.c */
+void sunxi_io_setup(void);
+
+/* Declarations for sunxi_security.c */
+void sunxi_security_setup(void);
+
+/* Gets the SPR for BL32 entry */
+uint32_t sunxi_get_spsr_for_bl32_entry(void);
+
+/* Gets the SPSR for BL33 entry */
+uint32_t sunxi_get_spsr_for_bl33_entry(void);
+
+
+#endif /* __FVP_PRIVATE_H__ */
diff --git a/plat/sun50iw1p1/sunxi_security.c b/plat/sun50iw1p1/sunxi_security.c
new file mode 100644
index 0000000..c0ccac0
--- /dev/null
+++ b/plat/sun50iw1p1/sunxi_security.c
@@ -0,0 +1,110 @@
+/*
+ * Copyright (c) 2014, ARM Limited and Contributors. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * Neither the name of ARM nor the names of its contributors may be used
+ * to endorse or promote products derived from this software without specific
+ * prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <assert.h>
+#include <debug.h>
+#include <plat_config.h>
+#include <tzc400.h>
+#include <mmio.h>
+#include "sunxi_def.h"
+#include "sunxi_private.h"
+
+#define SPC_BASE (0x1c23400ull)
+
+#define SPC_DECPORT0_STA_REG (SPC_BASE+0x4)
+#define SPC_DECPORT0_SET_REG (SPC_BASE+0x8)
+#define SPC_DECPORT0_CLR_REG (SPC_BASE+0xc)
+
+#define SPC_DECPORT1_STA_REG (SPC_BASE+0x10)
+#define SPC_DECPORT1_SET_REG (SPC_BASE+0x14)
+#define SPC_DECPORT1_CLR_REG (SPC_BASE+0x18)
+
+#define SPC_DECPORT2_STA_REG (SPC_BASE+0x1c)
+#define SPC_DECPORT2_SET_REG (SPC_BASE+0x20)
+#define SPC_DECPORT2_CLR_REG (SPC_BASE+0x24)
+
+#define SPC_DECPORT3_STA_REG (SPC_BASE+0x28)
+#define SPC_DECPORT3_SET_REG (SPC_BASE+0x2c)
+#define SPC_DECPORT3_CLR_REG (SPC_BASE+0x30)
+
+#define SPC_DECPORT4_STA_REG (SPC_BASE+0x34)
+#define SPC_DECPORT4_SET_REG (SPC_BASE+0x38)
+#define SPC_DECPORT4_CLR_REG (SPC_BASE+0x3c)
+
+#define SPC_DECPORT5_STA_REG (SPC_BASE+0x40)
+#define SPC_DECPORT5_SET_REG (SPC_BASE+0x44)
+#define SPC_DECPORT5_CLR_REG (SPC_BASE+0x48)
+
+
+
+
+
+
+
+
+/* Used to improve readability for configuring regions. */
+#define FILTER_SHIFT(filter) (1 << filter)
+
+/*
+ * For the moment we assume that all security programming is done by the
+ * primary core.
+ * TODO:
+ * Might want to enable interrupt on violations when supported?
+ */
+void sunxi_security_setup(void)
+{
+ /*
+ *
+ * If the platform had additional peripheral specific security
+ * configurations, those would be configured here.
+ */
+
+ //if (!(get_plat_config()->flags & CONFIG_HAS_TZC))
+ // return;
+
+ INFO("Configuring SPC Controller\n");
+ //set all peripherals to non-sec
+ mmio_write_32(SPC_DECPORT0_SET_REG,0xff);
+ mmio_write_32(SPC_DECPORT1_SET_REG,0xff);
+ mmio_write_32(SPC_DECPORT2_SET_REG,0xff);
+ mmio_write_32(SPC_DECPORT3_SET_REG,0xff);
+ mmio_write_32(SPC_DECPORT4_SET_REG,0xff);
+ mmio_write_32(SPC_DECPORT5_SET_REG,0xff);
+
+ //set ccmu security switch: set mbus_sec bus_sec pll_sec to non-sec
+ mmio_write_32(0x01c20000+0x2f0, 0x7);
+
+ //set R_PRCM security switch: set power_sec pll_sec cpus_clk to non-sec
+ mmio_write_32(0x01f01400+0x1d0, 0x7);
+
+ //set dma security switch: set DMA channel0-7 to non-sec
+ mmio_write_32(0x01c02000+0x20, 0xff);
+
+}
diff --git a/plat/sun50iw1p1/tsp/tsp-wine.mk b/plat/sun50iw1p1/tsp/tsp-wine.mk
new file mode 100644
index 0000000..3cbc6ec
--- /dev/null
+++ b/plat/sun50iw1p1/tsp/tsp-wine.mk
@@ -0,0 +1,38 @@
+#
+# Copyright (c) 2013-2014, ARM Limited and Contributors. All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions are met:
+#
+# Redistributions of source code must retain the above copyright notice, this
+# list of conditions and the following disclaimer.
+#
+# Redistributions in binary form must reproduce the above copyright notice,
+# this list of conditions and the following disclaimer in the documentation
+# and/or other materials provided with the distribution.
+#
+# Neither the name of ARM nor the names of its contributors may be used
+# to endorse or promote products derived from this software without specific
+# prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+# POSSIBILITY OF SUCH DAMAGE.
+#
+
+# TSP source files specific to FVP platform
+BL32_SOURCES += drivers/arm/gic/arm_gic.c \
+ drivers/arm/gic/gic_v2.c \
+ plat/common/aarch64/platform_mp_stack.S \
+ plat/common/plat_gic.c \
+ plat/sun50iw1p1/aarch64/sunxi_common.c \
+ plat/sun50iw1p1/aarch64/sunxi_helpers.S \
+ plat/sun50iw1p1/tsp/tsp_sunxi_setup.c
diff --git a/plat/sun50iw1p1/tsp/tsp_sunxi_setup.c b/plat/sun50iw1p1/tsp/tsp_sunxi_setup.c
new file mode 100644
index 0000000..82c74af
--- /dev/null
+++ b/plat/sun50iw1p1/tsp/tsp_sunxi_setup.c
@@ -0,0 +1,101 @@
+/*
+ * Copyright (c) 2013-2014, ARM Limited and Contributors. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * Neither the name of ARM nor the names of its contributors may be used
+ * to endorse or promote products derived from this software without specific
+ * prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <bl_common.h>
+#include <console.h>
+#include <platform_tsp.h>
+#include "../sunxi_def.h"
+#include "../sunxi_private.h"
+
+/*******************************************************************************
+ * Declarations of linker defined symbols which will help us find the layout
+ * of trusted SRAM
+ ******************************************************************************/
+extern unsigned long __RO_START__;
+extern unsigned long __RO_END__;
+
+extern unsigned long __COHERENT_RAM_START__;
+extern unsigned long __COHERENT_RAM_END__;
+
+/*
+ * The next 2 constants identify the extents of the code & RO data region.
+ * These addresses are used by the MMU setup code and therefore they must be
+ * page-aligned. It is the responsibility of the linker script to ensure that
+ * __RO_START__ and __RO_END__ linker symbols refer to page-aligned addresses.
+ */
+#define BL32_RO_BASE (unsigned long)(&__RO_START__)
+#define BL32_RO_LIMIT (unsigned long)(&__RO_END__)
+
+/*
+ * The next 2 constants identify the extents of the coherent memory region.
+ * These addresses are used by the MMU setup code and therefore they must be
+ * page-aligned. It is the responsibility of the linker script to ensure that
+ * __COHERENT_RAM_START__ and __COHERENT_RAM_END__ linker symbols refer to
+ * page-aligned addresses.
+ */
+#define BL32_COHERENT_RAM_BASE (unsigned long)(&__COHERENT_RAM_START__)
+#define BL32_COHERENT_RAM_LIMIT (unsigned long)(&__COHERENT_RAM_END__)
+
+/*******************************************************************************
+ * Initialize the UART
+ ******************************************************************************/
+void tsp_early_platform_setup(void)
+{
+ /*
+ * Initialize a different console than already in use to display
+ * messages from TSP
+ */
+ console_init(SUNXI_UART0_BASE, UART0_CLK_IN_HZ, UART0_BAUDRATE);
+
+ /* Initialize the platform config for future decision making */
+ sunxi_config_setup();
+}
+
+/*******************************************************************************
+ * Perform platform specific setup placeholder
+ ******************************************************************************/
+void tsp_platform_setup(void)
+{
+ sunxi_gic_init();
+}
+
+/*******************************************************************************
+ * Perform the very early platform specific architectural setup here. At the
+ * moment this is only intializes the MMU
+ ******************************************************************************/
+void tsp_plat_arch_setup(void)
+{
+ sunxi_configure_mmu_el1(BL32_RO_BASE,
+ (BL32_COHERENT_RAM_LIMIT - BL32_RO_BASE),
+ BL32_RO_BASE,
+ BL32_RO_LIMIT,
+ BL32_COHERENT_RAM_BASE,
+ BL32_COHERENT_RAM_LIMIT);
+}
diff --git a/services/arm/arm_svc_setup.c b/services/arm/arm_svc_setup.c
new file mode 100644
index 0000000..7e2a396
--- /dev/null
+++ b/services/arm/arm_svc_setup.c
@@ -0,0 +1,202 @@
+/*
+ * Copyright (c) 2014, ARM Limited and Contributors. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * Neither the name of ARM nor the names of its contributors may be used
+ * to endorse or promote products derived from this software without specific
+ * prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <debug.h>
+#include <psci.h>
+#include <runtime_svc.h>
+#include <std_svc.h>
+#include <stdint.h>
+#include <uuid.h>
+#include <assert.h>
+#include <string.h>
+#include <bl_common.h>
+#include <context_mgmt.h>
+#include <arisc.h>
+#include <mmio.h>
+
+#define ARM_NUM_CALLS 6
+
+#define ARM_SVC_CALL_COUNT 0x8000ff00
+#define ARM_SVC_UID 0x8000ff01
+//0x8000ff02 reserved
+#define ARM_SVC_VERSION 0x8000ff03
+#define ARM_SVC_RUNNSOS 0x8000ff04
+#define ARM_SVC_READ_SEC_REG 0x8000ff05
+#define ARM_SVC_WRITE_SEC_REG 0x8000ff06
+
+#define ARM_SVC_ARISC_STARTUP 0x8000ff10
+#define ARM_SVC_ARISC_WAIT_READY 0x8000ff11
+#define ARM_SVC_ARISC_READ_PMU 0x8000ff12
+#define ARM_SVC_ARISC_WRITE_PMU 0x8000ff13
+
+
+/* ARM Standard Service Calls version numbers */
+#define ARM_SVC_VERSION_MAJOR 0x0
+#define ARM_SVC_VERSION_MINOR 0x1
+
+/* Arm arch Service UUID */
+
+DEFINE_SVC_UUID(arm_svc_uid,
+ 0x83B53A5B, 0xC594, 0x40B9, 0x53, 0x91,
+ 0xF2, 0xFC, 0x54, 0x29, 0x86, 0x48);
+/*******************************************************************************
+ * This function programs EL3 registers and performs other setup to enable entry
+ * into the next image after BL31 at the next ERET.
+ ******************************************************************************/
+void prepare_nonsec_os_entry(uint64_t kernel_addr, uint64_t dtb_addr)
+{
+ entry_point_info_t next_image_info;
+ uint32_t image_type;
+
+ /* Determine which image to execute next */
+ image_type = NON_SECURE;
+
+ /* Program EL3 registers to enable entry into the next EL */
+ memset(&next_image_info, 0, sizeof(next_image_info));
+ SET_SECURITY_STATE(next_image_info.h.attr, NON_SECURE);
+ next_image_info.spsr = SPSR_64(MODE_EL1, MODE_SP_ELX, DISABLE_ALL_EXCEPTIONS);
+ next_image_info.pc = kernel_addr;
+ next_image_info.args.arg0 = dtb_addr;
+
+
+
+ INFO("BL3-1: Next image address = 0x%llx\n",(unsigned long long) next_image_info.pc);
+ INFO("BL3-1: Next image spsr = 0x%x\n", next_image_info.spsr);
+
+ cm_init_context(read_mpidr_el1(), &next_image_info);
+ cm_prepare_el3_exit(image_type);
+}
+
+
+/*
+ * Top-level Standard Service SMC handler. This handler will in turn dispatch
+ * calls to PSCI SMC handler
+ */
+uint64_t arm_svc_smc_handler(uint32_t smc_fid,
+ uint64_t x1,
+ uint64_t x2,
+ uint64_t x3,
+ uint64_t x4,
+ void *cookie,
+ void *handle,
+ uint64_t flags)
+{
+ //INFO(" Arm Architechture Service Call: 0x%x \n", smc_fid);
+
+ switch (smc_fid) {
+ case ARM_SVC_CALL_COUNT:
+ SMC_RET1(handle, ARM_NUM_CALLS);
+ case ARM_SVC_UID:
+ /* Return UID to the caller */
+ SMC_UUID_RET(handle, arm_svc_uid);
+ case ARM_SVC_VERSION:
+ /* Return the version of current implementation */
+ SMC_RET2(handle, ARM_SVC_VERSION_MAJOR, ARM_SVC_VERSION_MINOR);
+ case ARM_SVC_RUNNSOS:
+ prepare_nonsec_os_entry((uint32_t)x1,(uint32_t)x2);
+ SMC_RET0(handle);
+ case ARM_SVC_READ_SEC_REG:
+ SMC_RET1(handle, mmio_read_32((uintptr_t)x1));
+ case ARM_SVC_WRITE_SEC_REG:
+ mmio_write_32((uintptr_t)x1,(uint32_t)x2);
+ SMC_RET0(handle);
+
+ //arise cmd begin
+ //arise aa32 cmd
+ case ARM_SVC_ARISC_STARTUP:
+ SMC_RET1(handle, sunxi_arisc_probe((void *)x1));
+ case ARM_SVC_ARISC_WAIT_READY:
+ SMC_RET1(handle, sunxi_arisc_wait_ready());
+ case ARM_SVC_ARISC_READ_PMU:
+ SMC_RET1(handle, arisc_rsb_read_pmu_reg((uint32_t)x1));
+ case ARM_SVC_ARISC_WRITE_PMU:
+ SMC_RET1(handle,arisc_rsb_write_pmu_reg((uint32_t)x1,(uint32_t)x2));
+
+ //arise aa64 cmd
+ case ARM_SVC_ARISC_CPUX_DVFS_REQ:
+ SMC_RET1(handle, arisc_dvfs_set_cpufreq((uint32_t)x1, (uint32_t)x2, (uint32_t)x3));
+ case ARM_SVC_ARISC_RSB_READ_BLOCK_DATA:
+ SMC_RET1(handle, arisc_rsb_read_block_data((uint32_t *)x1));
+ case ARM_SVC_ARISC_RSB_WRITE_BLOCK_DATA:
+ SMC_RET1(handle, arisc_rsb_write_block_data((uint32_t *)x1));
+ case ARM_SVC_ARISC_RSB_BITS_OPS_SYNC:
+ SMC_RET1(handle, rsb_bits_ops_sync((uint32_t *)x1));
+ case ARM_SVC_ARISC_RSB_SET_INTERFACE_MODE:
+ SMC_RET1(handle, arisc_rsb_set_interface_mode((uint32_t)x1, (uint32_t)x2, (uint32_t)x3));
+ case ARM_SVC_ARISC_RSB_SET_RTSADDR:
+ SMC_RET1(handle, arisc_rsb_set_rtsaddr((uint32_t)x1, (uint32_t)x2));
+ case ARM_SVC_ARISC_SET_DEBUG_LEVEL:
+ SMC_RET1(handle, arisc_set_debug_level((uint32_t)x1));
+ case ARM_SVC_ARISC_SET_UART_BAUDRATE:
+ SMC_RET1(handle, arisc_set_uart_baudrate((uint32_t)x1));
+ case ARM_SVC_ARISC_MESSAGE_LOOPBACK:
+ SMC_RET1(handle, arisc_message_loopback());
+ case ARM_SVC_ARISC_SET_DEBUG_DRAM_CRC_PARAS:
+ SMC_RET1(handle, arisc_set_dram_crc_paras((uint32_t)x1, (uint32_t)x2, (uint32_t)x3));
+ case ARM_SVC_ARISC_AXP_DISABLE_IRQ:
+ SMC_RET1(handle, arisc_disable_nmi_irq());
+ case ARM_SVC_ARISC_AXP_ENABLE_IRQ:
+ SMC_RET1(handle, arisc_enable_nmi_irq());
+ case ARM_SVC_ARISC_CLR_NMI_STATUS:
+ SMC_RET1(handle, arisc_clear_nmi_status());
+ case ARM_SVC_ARISC_SET_NMI_TRIGGER:
+ SMC_RET1(handle, arisc_set_nmi_trigger((uint32_t)x1));
+ case ARM_SVC_ARISC_AXP_GET_CHIP_ID:
+ SMC_RET1(handle, arisc_axp_get_chip_id((unsigned char *)x1));
+ case ARM_SVC_ARISC_AXP_SET_PARAS:
+ SMC_RET1(handle, arisc_adjust_pmu_chgcur((uint32_t)x1, (uint32_t)x2, (uint32_t)x3));
+ case ARM_SVC_ARISC_SET_PWR_TREE:
+ SMC_RET1(handle, arisc_set_pwr_tree((uint32_t *)x1));
+ case ARM_SVC_ARISC_SET_PMU_VOLT:
+ SMC_RET1(handle, arisc_pmu_set_voltage((uint32_t)x1, (uint32_t)x2));
+ case ARM_SVC_ARISC_GET_PMU_VOLT:
+ SMC_RET1(handle, arisc_pmu_get_voltage((uint32_t)x1, (uint32_t *)x2));
+ case ARM_SVC_ARISC_SET_LED_BLN:
+ SMC_RET1(handle, arisc_set_led_bln((uint32_t *)x1));
+ case ARM_SVC_ARISC_QUERY_WAKEUP_SRC_REQ:
+ SMC_RET1(handle, arisc_query_wakeup_source((uint32_t *)x1));
+ case ARM_SVC_ARISC_STANDBY_INFO_REQ:
+ SMC_RET1(handle, arisc_query_set_standby_info((standby_info_para_t *)x1, (arisc_rw_type_e)x2));
+ default:
+ WARN("Unimplemented Standard Service Call: 0x%x \n", smc_fid);
+ SMC_RET1(handle, SMC_UNK);
+ }
+}
+
+/* Register Standard Service Calls as runtime service */
+DECLARE_RT_SVC(
+ arm_svc,
+
+ OEN_ARM_START,
+ OEN_ARM_END,
+ SMC_TYPE_FAST,
+ NULL,
+ arm_svc_smc_handler
+);
diff --git a/services/spd/tspd/tspd_main.c b/services/spd/tspd/tspd_main.c
index b8d4569..1d5d5c5 100644
--- a/services/spd/tspd/tspd_main.c
+++ b/services/spd/tspd/tspd_main.c
@@ -255,7 +255,7 @@ uint64_t tspd_smc_handler(uint32_t smc_fid,
#if TSP_INIT_ASYNC
entry_point_info_t *next_image_info;
#endif
-
+ WARN("tspd_smc_handler call\n");
/* Determine which security state this SMC originated from */
ns = is_caller_non_secure(flags);
@@ -358,6 +358,7 @@ uint64_t tspd_smc_handler(uint32_t smc_fid,
* finished initialising itself after a cold boot
*/
case TSP_ENTRY_DONE:
+ WARN("tspd_smc_handler call:TSP_ENTRY_DONE\n");
if (ns)
SMC_RET1(handle, SMC_UNK);
diff --git a/services/std_svc/psci/psci_afflvl_off.c b/services/std_svc/psci/psci_afflvl_off.c
index 7e05789..f0f4234 100644
--- a/services/std_svc/psci/psci_afflvl_off.c
+++ b/services/std_svc/psci/psci_afflvl_off.c
@@ -62,12 +62,6 @@ static int psci_afflvl0_off(aff_map_node_t *cpu_node)
return rc;
}
- /*
- * Arch. management. Perform the necessary steps to flush all
- * cpu caches.
- */
- psci_do_pwrdown_cache_maintenance(MPIDR_AFFLVL0);
-
if (!psci_plat_pm_ops->affinst_off)
return PSCI_E_SUCCESS;
@@ -75,22 +69,25 @@ static int psci_afflvl0_off(aff_map_node_t *cpu_node)
* Plat. management: Perform platform specific actions to turn this
* cpu off e.g. exit cpu coherency, program the power controller etc.
*/
- return psci_plat_pm_ops->affinst_off(read_mpidr_el1(),
+ rc = psci_plat_pm_ops->affinst_off(read_mpidr_el1(),
cpu_node->level,
psci_get_phys_state(cpu_node));
+ /*
+ * Arch. management. Perform the necessary steps to flush all
+ * cpu caches.
+ */
+ psci_do_pwrdown_cache_maintenance(MPIDR_AFFLVL0);
+
+ return rc;
}
static int psci_afflvl1_off(aff_map_node_t *cluster_node)
{
+ int rc;
+
/* Sanity check the cluster level */
assert(cluster_node->level == MPIDR_AFFLVL1);
- /*
- * Arch. Management. Flush all levels of caches to PoC if
- * the cluster is to be shutdown.
- */
- psci_do_pwrdown_cache_maintenance(MPIDR_AFFLVL1);
-
if (!psci_plat_pm_ops->affinst_off)
return PSCI_E_SUCCESS;
@@ -99,13 +96,23 @@ static int psci_afflvl1_off(aff_map_node_t *cluster_node)
* specific bookeeping e.g. turn off interconnect coherency,
* program the power controller etc.
*/
- return psci_plat_pm_ops->affinst_off(read_mpidr_el1(),
+ rc = psci_plat_pm_ops->affinst_off(read_mpidr_el1(),
cluster_node->level,
psci_get_phys_state(cluster_node));
+
+ /*
+ * Arch. Management. Flush all levels of caches to PoC if
+ * the cluster is to be shutdown.
+ */
+ psci_do_pwrdown_cache_maintenance(MPIDR_AFFLVL1);
+
+ return rc;
}
static int psci_afflvl2_off(aff_map_node_t *system_node)
{
+ int rc;
+
/* Cannot go beyond this level */
assert(system_node->level == MPIDR_AFFLVL2);
@@ -114,12 +121,6 @@ static int psci_afflvl2_off(aff_map_node_t *system_node)
* action needs to be taken
*/
- /*
- * Arch. Management. Flush all levels of caches to PoC if
- * the system is to be shutdown.
- */
- psci_do_pwrdown_cache_maintenance(MPIDR_AFFLVL2);
-
if (!psci_plat_pm_ops->affinst_off)
return PSCI_E_SUCCESS;
@@ -127,9 +128,17 @@ static int psci_afflvl2_off(aff_map_node_t *system_node)
* Plat. Management : Allow the platform to do its bookeeping
* at this affinity level
*/
- return psci_plat_pm_ops->affinst_off(read_mpidr_el1(),
+ rc = psci_plat_pm_ops->affinst_off(read_mpidr_el1(),
system_node->level,
psci_get_phys_state(system_node));
+
+ /*
+ * Arch. Management. Flush all levels of caches to PoC if
+ * the system is to be shutdown.
+ */
+ psci_do_pwrdown_cache_maintenance(MPIDR_AFFLVL2);
+
+ return rc;
}
static const afflvl_off_handler_t psci_afflvl_off_handlers[] = {
diff --git a/services/std_svc/psci/psci_afflvl_on.c b/services/std_svc/psci/psci_afflvl_on.c
index f1d30c9..de08251 100644
--- a/services/std_svc/psci/psci_afflvl_on.c
+++ b/services/std_svc/psci/psci_afflvl_on.c
@@ -38,6 +38,7 @@
#include <runtime_svc.h>
#include <stddef.h>
#include "psci_private.h"
+#include <debug.h>
typedef int (*afflvl_on_handler_t)(unsigned long,
aff_map_node_t *,
diff --git a/services/std_svc/psci/psci_afflvl_suspend.c b/services/std_svc/psci/psci_afflvl_suspend.c
index 4fcabfc..8472821 100644
--- a/services/std_svc/psci/psci_afflvl_suspend.c
+++ b/services/std_svc/psci/psci_afflvl_suspend.c
@@ -38,6 +38,7 @@
#include <platform.h>
#include <runtime_svc.h>
#include <stddef.h>
+#include <debug.h>
#include "psci_private.h"
typedef int (*afflvl_suspend_handler_t)(aff_map_node_t *,
@@ -146,12 +147,6 @@ static int psci_afflvl0_suspend(aff_map_node_t *cpu_node,
/* Set the secure world (EL3) re-entry point after BL1 */
psci_entrypoint = (unsigned long) psci_aff_suspend_finish_entry;
- /*
- * Arch. management. Perform the necessary steps to flush all
- * cpu caches.
- */
- psci_do_pwrdown_cache_maintenance(MPIDR_AFFLVL0);
-
if (!psci_plat_pm_ops->affinst_suspend)
return PSCI_E_SUCCESS;
@@ -161,11 +156,19 @@ static int psci_afflvl0_suspend(aff_map_node_t *cpu_node,
* platform defined mailbox with the psci entrypoint,
* program the power controller etc.
*/
- return psci_plat_pm_ops->affinst_suspend(read_mpidr_el1(),
+ rc = psci_plat_pm_ops->affinst_suspend(read_mpidr_el1(),
psci_entrypoint,
ns_entrypoint,
cpu_node->level,
psci_get_phys_state(cpu_node));
+
+ /*
+ * Arch. management. Perform the necessary steps to flush all
+ * cpu caches.
+ */
+ psci_do_pwrdown_cache_maintenance(MPIDR_AFFLVL0);
+
+ return rc;
}
static int psci_afflvl1_suspend(aff_map_node_t *cluster_node,
@@ -175,16 +178,11 @@ static int psci_afflvl1_suspend(aff_map_node_t *cluster_node,
{
unsigned int plat_state;
unsigned long psci_entrypoint;
+ int rc;
/* Sanity check the cluster level */
assert(cluster_node->level == MPIDR_AFFLVL1);
- /*
- * Arch. management: Flush all levels of caches to PoC if the
- * cluster is to be shutdown.
- */
- psci_do_pwrdown_cache_maintenance(MPIDR_AFFLVL1);
-
if (!psci_plat_pm_ops->affinst_suspend)
return PSCI_E_SUCCESS;
@@ -198,11 +196,18 @@ static int psci_afflvl1_suspend(aff_map_node_t *cluster_node,
*/
plat_state = psci_get_phys_state(cluster_node);
psci_entrypoint = (unsigned long) psci_aff_suspend_finish_entry;
- return psci_plat_pm_ops->affinst_suspend(read_mpidr_el1(),
+ rc = psci_plat_pm_ops->affinst_suspend(read_mpidr_el1(),
psci_entrypoint,
ns_entrypoint,
cluster_node->level,
plat_state);
+ /*
+ * Arch. management: Flush all levels of caches to PoC if the
+ * cluster is to be shutdown.
+ */
+ psci_do_pwrdown_cache_maintenance(MPIDR_AFFLVL1);
+
+ return rc;
}
@@ -213,6 +218,7 @@ static int psci_afflvl2_suspend(aff_map_node_t *system_node,
{
unsigned int plat_state;
unsigned long psci_entrypoint;
+ int rc;
/* Cannot go beyond this */
assert(system_node->level == MPIDR_AFFLVL2);
@@ -224,12 +230,6 @@ static int psci_afflvl2_suspend(aff_map_node_t *system_node,
plat_state = psci_get_phys_state(system_node);
/*
- * Arch. management: Flush all levels of caches to PoC if the
- * system is to be shutdown.
- */
- psci_do_pwrdown_cache_maintenance(MPIDR_AFFLVL2);
-
- /*
* Plat. Management : Allow the platform to do its bookeeping
* at this affinity level
*/
@@ -244,11 +244,18 @@ static int psci_afflvl2_suspend(aff_map_node_t *system_node,
*/
plat_state = psci_get_phys_state(system_node);
psci_entrypoint = (unsigned long) psci_aff_suspend_finish_entry;
- return psci_plat_pm_ops->affinst_suspend(read_mpidr_el1(),
+ rc = psci_plat_pm_ops->affinst_suspend(read_mpidr_el1(),
psci_entrypoint,
ns_entrypoint,
system_node->level,
plat_state);
+ /*
+ * Arch. management: Flush all levels of caches to PoC if the
+ * system is to be shutdown.
+ */
+ psci_do_pwrdown_cache_maintenance(MPIDR_AFFLVL2);
+
+ return rc;
}
static const afflvl_suspend_handler_t psci_afflvl_suspend_handlers[] = {
diff --git a/services/std_svc/psci/psci_common.c b/services/std_svc/psci/psci_common.c
index 2267ad0..75f52f5 100644
--- a/services/std_svc/psci/psci_common.c
+++ b/services/std_svc/psci/psci_common.c
@@ -140,7 +140,11 @@ int get_power_on_target_afflvl()
* Sanity check the state of the cpu. It should be either suspend or "on
* pending"
*/
- state = psci_get_state(node);
+ do
+ {
+ state = psci_get_state(node); //wait cpu0 set this state --by wangwei
+ }while(state != PSCI_STATE_SUSPEND && state != PSCI_STATE_ON_PENDING);
+
assert(state == PSCI_STATE_SUSPEND || state == PSCI_STATE_ON_PENDING);
#endif
@@ -480,7 +484,6 @@ void psci_afflvl_power_on_finish(int start_afflvl,
int rc;
unsigned int max_phys_off_afflvl;
-
/*
* Collect the pointers to the nodes in the topology tree for
* each affinity instance in the mpidr. If this function does
diff --git a/services/std_svc/psci/psci_entry.S b/services/std_svc/psci/psci_entry.S
index 8145012..b2ad074 100644
--- a/services/std_svc/psci/psci_entry.S
+++ b/services/std_svc/psci/psci_entry.S
@@ -70,7 +70,6 @@ psci_aff_common_finish_entry:
msr sctlr_el3, x0
isb
#endif
-
/* ---------------------------------------------
* Initialise the pcpu cache pointer for the CPU
* ---------------------------------------------
@@ -78,12 +77,6 @@ psci_aff_common_finish_entry:
bl init_cpu_data_ptr
/* ---------------------------------------------
- * Initialize the cpu_ops pointer.
- * ---------------------------------------------
- */
- bl init_cpu_ops
-
- /* ---------------------------------------------
* Set the exception vectors
* ---------------------------------------------
*/
@@ -157,7 +150,7 @@ psci_aff_common_finish_entry:
*/
func psci_power_down_wfi
dsb sy // ensure write buffer empty
- wfi
wfi_spill:
+ wfi
b wfi_spill
diff --git a/services/std_svc/psci/psci_main.c b/services/std_svc/psci/psci_main.c
index 0ffa5d7..900c5e1 100644
--- a/services/std_svc/psci/psci_main.c
+++ b/services/std_svc/psci/psci_main.c
@@ -115,8 +115,11 @@ int psci_cpu_suspend(unsigned int power_state,
power_state,
MPIDR_AFFLVL0,
target_afflvl);
- if (rc == PSCI_E_SUCCESS)
+ if (rc == PSCI_E_SUCCESS) {
+ dcsw_op_all(DCCISW);
psci_power_down_wfi();
+ }
+
assert(rc == PSCI_E_INVALID_PARAMS);
return rc;
}
@@ -139,8 +142,11 @@ int psci_cpu_off(void)
* successfully completed. Enter a wfi loop which will allow the
* power controller to physically power down this cpu.
*/
- if (rc == PSCI_E_SUCCESS)
+ if (rc == PSCI_E_SUCCESS) {
+ dcsw_op_all(DCCISW);
psci_power_down_wfi();
+ }
+
/*
* The only error cpu_off can return is E_DENIED. So check if that's
diff --git a/services/std_svc/psci/psci_private.h b/services/std_svc/psci/psci_private.h
index 924a24f..24a5604 100644
--- a/services/std_svc/psci/psci_private.h
+++ b/services/std_svc/psci/psci_private.h
@@ -60,7 +60,7 @@ typedef struct aff_limits_node {
int max;
} aff_limits_node_t;
-typedef aff_map_node_t (*mpidr_aff_map_nodes_t[MPIDR_MAX_AFFLVL]);
+typedef aff_map_node_t (*mpidr_aff_map_nodes_t[MPIDR_MAX_AFFLVL + 1]);
typedef unsigned int (*afflvl_power_on_finisher_t)(aff_map_node_t *);
/*******************************************************************************
diff --git a/services/std_svc/psci/psci_setup.c b/services/std_svc/psci/psci_setup.c
index a5ae4ef..6abf151 100644
--- a/services/std_svc/psci/psci_setup.c
+++ b/services/std_svc/psci/psci_setup.c
@@ -36,6 +36,7 @@
#include <context_mgmt.h>
#include <platform.h>
#include <stddef.h>
+#include <debug.h>
#include "psci_private.h"
/*******************************************************************************
@@ -194,6 +195,7 @@ static void psci_init_aff_map_node(unsigned long mpidr,
* instance through the context management library.
*/
linear_id = platform_get_core_pos(mpidr);
+ //NOTICE("linear_id %d, mpidr %d max %d\n",linear_id,mpidr,PLATFORM_CORE_COUNT );
assert(linear_id < PLATFORM_CORE_COUNT);
/* Invalidate the suspend context for the node */
@@ -210,10 +212,11 @@ static void psci_init_aff_map_node(unsigned long mpidr,
psci_svc_cpu_data.max_phys_off_afflvl,
PSCI_INVALID_DATA);
+ flush_cpu_data_by_index(linear_id, psci_svc_cpu_data);
+
cm_set_context_by_mpidr(mpidr,
(void *) &psci_ns_context[linear_id],
NON_SECURE);
-
}
return;
diff --git a/services/std_svc/std_svc_setup.c b/services/std_svc/std_svc_setup.c
index 6cb0319..79c94b0 100644
--- a/services/std_svc/std_svc_setup.c
+++ b/services/std_svc/std_svc_setup.c
@@ -35,8 +35,9 @@
#include <stdint.h>
#include <uuid.h>
+
/* Standard Service UUID */
-DEFINE_SVC_UUID(arm_svc_uid,
+DEFINE_SVC_UUID(std_svc_uid,
0x108d905b, 0xf863, 0x47e8, 0xae, 0x2d,
0xc0, 0xfb, 0x56, 0x41, 0xf6, 0xe2);
@@ -71,7 +72,7 @@ uint64_t std_svc_smc_handler(uint32_t smc_fid,
return psci_smc_handler(smc_fid, x1, x2, x3, x4, cookie,
handle, flags);
}
-
+
switch (smc_fid) {
case ARM_STD_SVC_CALL_COUNT:
/*
@@ -82,12 +83,11 @@ uint64_t std_svc_smc_handler(uint32_t smc_fid,
case ARM_STD_SVC_UID:
/* Return UID to the caller */
- SMC_UUID_RET(handle, arm_svc_uid);
+ SMC_UUID_RET(handle, std_svc_uid);
case ARM_STD_SVC_VERSION:
/* Return the version of current implementation */
SMC_RET2(handle, STD_SVC_VERSION_MAJOR, STD_SVC_VERSION_MINOR);
-
default:
WARN("Unimplemented Standard Service Call: 0x%x \n", smc_fid);
SMC_RET1(handle, SMC_UNK);
diff --git a/tools/add_hash_bl31.sh b/tools/add_hash_bl31.sh
new file mode 100755
index 0000000..1814460
--- /dev/null
+++ b/tools/add_hash_bl31.sh
@@ -0,0 +1,51 @@
+#!/bin/bash
+set -e
+
+BUILD_FILE=bl31.bin
+BUILD_MODE=bl31
+
+show_help()
+{
+ printf "\n add_hash.sh - add git log hash value into uboot,boot0,sboot,fes \n"
+ echo " eg :"
+ echo " ./add_hash.sh -f input_file -m file_flag "
+ echo " file_flag = uboot or boot0 or sboot"
+ printf "\n\n"
+}
+
+
+build_bl31()
+{
+ dd if=./${BUILD_FILE} of=./bl31_back bs=48 count=1 status=noxfer 2> /dev/null
+ dd if=./cur.log of=./bl31_back ibs=64 conv=notrunc,sync oflag=append obs=64 count=1 status=noxfer 2> /dev/null
+ dd if=./${BUILD_FILE} of=./bl31_back ibs=112 obs=112 conv=notrunc oflag=append skip=1 status=noxfer 2> /dev/null
+ mv bl31_back ${BUILD_FILE}
+}
+
+
+do_common()
+{
+ if [ "x${BUILD_MODE}" = "xbl31" ] ; then
+ echo " add commit info for bl31 "
+ build_bl31
+ else
+ echo "build none"
+ fi
+}
+while getopts f:m: OPTION
+do
+ case $OPTION in
+ f)
+ BUILD_FILE=$OPTARG
+ ;;
+ m)
+ BUILD_MODE=$OPTARG
+ ;;
+ *)
+ show_help
+ exit
+ ;;
+ esac
+done
+
+do_common
diff --git a/tools/fip_create/Makefile b/tools/fip_create/Makefile
index 69569a1..1ffb62f 100644
--- a/tools/fip_create/Makefile
+++ b/tools/fip_create/Makefile
@@ -31,6 +31,8 @@
PROJECT = fip_create
OBJECTS = fip_create.o
+
+
CFLAGS = -Wall -Werror -pedantic -std=c99
ifeq (${DEBUG},1)
CFLAGS += -g -O0 -DDEBUG
@@ -51,7 +53,7 @@ all: ${PROJECT}
${PROJECT}: ${OBJECTS} Makefile
@echo " LD $@"
- ${Q}${CC} ${OBJECTS} -o $@
+ ${Q}${CC} ${OBJECTS} -o $@ -static
%.o: %.c %.h Makefile
@echo " CC $<"