summaryrefslogtreecommitdiff
path: root/plat/sun50iw1p1/scp/interfaces
diff options
context:
space:
mode:
Diffstat (limited to 'plat/sun50iw1p1/scp/interfaces')
-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
8 files changed, 1380 insertions, 0 deletions
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