summaryrefslogtreecommitdiff
path: root/plat/marvell/a8k/common/mss
diff options
context:
space:
mode:
Diffstat (limited to 'plat/marvell/a8k/common/mss')
-rw-r--r--plat/marvell/a8k/common/mss/mss_bl2_setup.c64
-rw-r--r--plat/marvell/a8k/common/mss/mss_common.mk52
-rw-r--r--plat/marvell/a8k/common/mss/mss_ipc_drv.c147
-rw-r--r--plat/marvell/a8k/common/mss/mss_ipc_drv.h168
-rw-r--r--plat/marvell/a8k/common/mss/mss_mem.h87
-rw-r--r--plat/marvell/a8k/common/mss/mss_pm_ipc.c147
-rw-r--r--plat/marvell/a8k/common/mss/mss_pm_ipc.h88
-rw-r--r--plat/marvell/a8k/common/mss/mss_scp_bootloader.c218
-rw-r--r--plat/marvell/a8k/common/mss/mss_scp_bootloader.h40
9 files changed, 1011 insertions, 0 deletions
diff --git a/plat/marvell/a8k/common/mss/mss_bl2_setup.c b/plat/marvell/a8k/common/mss/mss_bl2_setup.c
new file mode 100644
index 00000000..e5f4f6b8
--- /dev/null
+++ b/plat/marvell/a8k/common/mss/mss_bl2_setup.c
@@ -0,0 +1,64 @@
+/*
+ * ***************************************************************************
+ * Copyright (C) 2016 Marvell International Ltd.
+ * ***************************************************************************
+ *
+ * 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 Marvell 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 <debug.h>
+#include <plat_private.h> /* timer functionality */
+#include "mss_scp_bootloader.h"
+
+
+/*******************************************************************************
+ * Transfer SCP_BL2 from Trusted RAM using the SCP Download protocol.
+ * Return 0 on success, -1 otherwise.
+ ******************************************************************************/
+int bl2_plat_handle_scp_bl2(image_info_t *scp_bl2_image_info)
+{
+ int ret;
+
+ INFO("BL2: Initiating SCP_BL2 transfer to SCP\n");
+ printf("BL2: Initiating SCP_BL2 transfer to SCP\n");
+
+ /* initialize time (for delay functionality) */
+ plat_delay_timer_init();
+
+ ret = scp_bootloader_transfer((void *)scp_bl2_image_info->image_base,
+ scp_bl2_image_info->image_size);
+
+ if (ret == 0)
+ INFO("BL2: SCP_BL2 transferred to SCP\n");
+ else
+ ERROR("BL2: SCP_BL2 transfer failure\n");
+
+ return ret;
+}
diff --git a/plat/marvell/a8k/common/mss/mss_common.mk b/plat/marvell/a8k/common/mss/mss_common.mk
new file mode 100644
index 00000000..b806dc13
--- /dev/null
+++ b/plat/marvell/a8k/common/mss/mss_common.mk
@@ -0,0 +1,52 @@
+#
+# ***************************************************************************
+# Copyright (C) 2016 Marvell International Ltd.
+# ***************************************************************************
+#
+# 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 Marvell 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.
+#
+
+PLAT_MARVELL := plat/marvell
+MSS_SOURCE := $(PLAT_MARVELL)/a8k/common/mss
+
+BL2_SOURCES += $(MSS_SOURCE)/mss_bl2_setup.c \
+ $(MSS_SOURCE)/mss_scp_bootloader.c \
+ $(PLAT_MARVELL)/common/plat_delay_timer.c \
+ drivers/delay_timer/delay_timer.c
+
+BL31_SOURCES += $(MSS_SOURCE)/mss_ipc_drv.c \
+ $(MSS_SOURCE)/mss_pm_ipc.c
+
+PLAT_INCLUDES += -I$(MSS_SOURCE)
+
+ifneq (${SCP_BL2},)
+# Subsystems require a SCP_BL2 image
+$(eval $(call FIP_ADD_IMG,SCP_BL2,--scp-fw))
+
+# This define is used to inidcate the SCP image is present
+$(eval $(call add_define,SCP_IMAGE))
+endif
diff --git a/plat/marvell/a8k/common/mss/mss_ipc_drv.c b/plat/marvell/a8k/common/mss/mss_ipc_drv.c
new file mode 100644
index 00000000..e261bb44
--- /dev/null
+++ b/plat/marvell/a8k/common/mss/mss_ipc_drv.c
@@ -0,0 +1,147 @@
+/*
+ * ***************************************************************************
+ * Copyright (C) 2016 Marvell International Ltd.
+ * ***************************************************************************
+ *
+ * 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 Marvell 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 <string.h>
+#include <mss_ipc_drv.h>
+#include <mmio.h>
+
+#define IPC_MSG_BASE_MASK MVEBU_REGS_BASE_MASK
+
+
+unsigned long mv_pm_ipc_msg_base;
+unsigned int mv_pm_ipc_num_of_ch;
+unsigned int mv_pm_ipc_channel_size;
+unsigned int mv_pm_ipc_queue_size;
+
+/*******************************************************************************
+ * mss_pm_ipc_init
+ *
+ * DESCRIPTION: Initialize PM IPC infrastructure
+ ******************************************************************************
+ */
+int mv_pm_ipc_init(unsigned long ipc_control_addr)
+{
+ struct mss_pm_ipc_ctrl *ipc_control =
+ (struct mss_pm_ipc_ctrl *)ipc_control_addr;
+
+ /* Initialize PM IPC control block */
+ mv_pm_ipc_msg_base = ipc_control->msg_base_address |
+ IPC_MSG_BASE_MASK;
+ mv_pm_ipc_num_of_ch = ipc_control->num_of_channels;
+ mv_pm_ipc_channel_size = ipc_control->channel_size;
+ mv_pm_ipc_queue_size = ipc_control->queue_size;
+
+ return 0;
+}
+
+/*******************************************************************************
+ * mv_pm_ipc_queue_addr_get
+ *
+ * DESCRIPTION: Returns the IPC queue address
+ ******************************************************************************
+ */
+unsigned int mv_pm_ipc_queue_addr_get(unsigned int channel_id,
+ unsigned int direction)
+{
+ return (unsigned int)(mv_pm_ipc_msg_base +
+ (channel_id * mv_pm_ipc_channel_size) +
+ (direction * mv_pm_ipc_queue_size));
+}
+
+/*******************************************************************************
+ * mv_pm_ipc_msg_rx
+ *
+ * DESCRIPTION: Retrieve message from IPC channel
+ ******************************************************************************
+ */
+int mv_pm_ipc_msg_rx(unsigned int channel_id, unsigned int direction,
+ struct mss_pm_ipc_msg *msg)
+{
+ unsigned int addr = mv_pm_ipc_queue_addr_get(channel_id, direction);
+
+ msg->msg_reply = mmio_read_32(addr + IPC_MSG_REPLY_LOC);
+
+ return 0;
+}
+
+/*******************************************************************************
+ * mss_pm_ipc_msg_reply
+ *
+ * DESCRIPTION: Send message via IPC channel
+ ******************************************************************************
+ */
+int mv_pm_ipc_msg_tx(unsigned int channel_id, unsigned int direction,
+ unsigned int cluster_power_state)
+{
+ unsigned int addr = mv_pm_ipc_queue_addr_get(channel_id, direction);
+
+ mmio_write_32(addr + IPC_MSG_POWER_STATE_LOC, cluster_power_state);
+ mmio_write_32(addr + IPC_MSG_STATE_LOC, IPC_MSG_OCCUPY);
+
+ return 0;
+}
+
+/*******************************************************************************
+ * mv_pm_ipc_msg_validate
+ *
+ * DESCRIPTION: Validate IPC channel state
+ ******************************************************************************
+ */
+int mv_pm_ipc_msg_validate(unsigned int channel_id, unsigned int direction,
+ unsigned int state)
+{
+ unsigned int addr = mv_pm_ipc_queue_addr_get(channel_id, direction);
+
+ if (mmio_read_32(addr + IPC_MSG_STATE_LOC) != state)
+ return -1;
+
+ return 0;
+}
+
+/*******************************************************************************
+ * mv_pm_ipc_msg_update
+ *
+ * DESCRIPTION: Update IPC channel state
+ ******************************************************************************
+ */
+int mv_pm_ipc_msg_update(unsigned int channel_id, unsigned int direction,
+ unsigned int state)
+{
+ unsigned int addr = mv_pm_ipc_queue_addr_get(channel_id, direction);
+
+ mmio_write_32(addr + IPC_MSG_STATE_LOC, state);
+
+ return 0;
+}
diff --git a/plat/marvell/a8k/common/mss/mss_ipc_drv.h b/plat/marvell/a8k/common/mss/mss_ipc_drv.h
new file mode 100644
index 00000000..7c8995cf
--- /dev/null
+++ b/plat/marvell/a8k/common/mss/mss_ipc_drv.h
@@ -0,0 +1,168 @@
+/*
+ * ***************************************************************************
+ * Copyright (C) 2016 Marvell International Ltd.
+ * ***************************************************************************
+ *
+ * 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 Marvell 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 __PM_IPC_DRV_H
+#define __PM_IPC_DRV_H
+
+
+#include <platform_def.h>
+
+
+#define MV_PM_FW_IPC_VERSION_MAGIC (0xCA530000) /* Do NOT change */
+/* Increament for each version */
+#define MV_PM_FW_IPC_VERSION_SEQ (0x00000001)
+#define MV_PM_FW_IPC_VERSION (MV_PM_FW_IPC_VERSION_MAGIC | \
+ MV_PM_FW_IPC_VERSION_SEQ)
+
+#define IPC_MSG_STATE_LOC (0x0)
+#define IPC_MSG_SYNC_ID_LOC (0x4)
+#define IPC_MSG_ID_LOC (0x8)
+#define IPC_MSG_RET_CH_ID_LOC (0xC)
+#define IPC_MSG_CPU_ID_LOC (0x10)
+#define IPC_MSG_CLUSTER_ID_LOC (0x14)
+#define IPC_MSG_SYSTEM_ID_LOC (0x18)
+#define IPC_MSG_POWER_STATE_LOC (0x1C)
+#define IPC_MSG_REPLY_LOC (0x20)
+#define IPC_MSG_RESERVED_LOC (0x24)
+
+/* IPC initialization state */
+enum mss_pm_ipc_init_state {
+ IPC_UN_INITIALIZED = 1,
+ IPC_INITIALIZED = 2
+};
+
+/* IPC queue direction */
+enum mss_pm_ipc_init_msg_dir {
+ IPC_MSG_TX = 0,
+ IPC_MSG_RX = 1
+};
+
+/* IPC message state */
+enum mss_pm_ipc_msg_state {
+ IPC_MSG_FREE = 1,
+ IPC_MSG_OCCUPY = 2
+
+};
+
+/* IPC control block */
+struct mss_pm_ipc_ctrl {
+ unsigned int ctrl_base_address;
+ unsigned int msg_base_address;
+ unsigned int num_of_channels;
+ unsigned int channel_size;
+ unsigned int queue_size;
+};
+
+/* IPC message types */
+enum mss_pm_msg_id {
+ PM_IPC_MSG_CPU_SUSPEND = 1,
+ PM_IPC_MSG_CPU_OFF = 2,
+ PM_IPC_MSG_CPU_ON = 3,
+ PM_IPC_MSG_SYSTEM_RESET = 4,
+ PM_IPC_MSG_SYSTEM_SUSPEND = 5,
+ PM_IPC_MAX_MSG
+};
+
+struct mss_pm_ipc_msg {
+ unsigned int msg_sync_id; /*
+ * Sync number, validate message
+ * reply corresponding to message
+ * received
+ */
+ unsigned int msg_id; /* Message Id */
+ unsigned int ret_channel_id; /* IPC channel reply */
+ unsigned int cpu_id; /* CPU Id */
+ unsigned int cluster_id; /* Cluster Id */
+ unsigned int system_id; /* System Id */
+ unsigned int power_state;
+ unsigned int msg_reply; /* Message reply */
+};
+
+/* IPC queue */
+struct mss_pm_ipc_queue {
+ unsigned int state;
+ struct mss_pm_ipc_msg msg;
+};
+
+/* IPC channel */
+struct mss_pm_ipc_ch {
+ struct mss_pm_ipc_queue *tx_queue;
+ struct mss_pm_ipc_queue *rx_queue;
+};
+
+/*******************************************************************************
+ * mv_pm_ipc_init
+ *
+ * DESCRIPTION: Initialize PM IPC infrastructure
+ ******************************************************************************
+ */
+int mv_pm_ipc_init(unsigned long ipc_control_addr);
+
+/*******************************************************************************
+ * mv_pm_ipc_msg_rx
+ *
+ * DESCRIPTION: Retrieve message from IPC channel
+ ******************************************************************************
+ */
+int mv_pm_ipc_msg_rx(unsigned int channel_id, unsigned int direction,
+ struct mss_pm_ipc_msg *msg);
+
+/*******************************************************************************
+ * mv_pm_ipc_msg_tx
+ *
+ * DESCRIPTION: Send message via IPC channel
+ ******************************************************************************
+ */
+int mv_pm_ipc_msg_tx(unsigned int channel_id, unsigned int direction,
+ unsigned int cluster_power_state);
+
+/*******************************************************************************
+ * mv_pm_ipc_msg_validate
+ *
+ * DESCRIPTION: Validate IPC channel state
+ ******************************************************************************
+ */
+int mv_pm_ipc_msg_validate(unsigned int channel_id, unsigned int direction,
+ unsigned int state);
+
+/*******************************************************************************
+ * mv_pm_ipc_msg_update
+ *
+ * DESCRIPTION: Update IPC channel state
+ ******************************************************************************
+ */
+int mv_pm_ipc_msg_update(unsigned int channel_id, unsigned int direction,
+ unsigned int state);
+
+#endif /* __PM_IPC_DRV_H */
diff --git a/plat/marvell/a8k/common/mss/mss_mem.h b/plat/marvell/a8k/common/mss/mss_mem.h
new file mode 100644
index 00000000..bed5584c
--- /dev/null
+++ b/plat/marvell/a8k/common/mss/mss_mem.h
@@ -0,0 +1,87 @@
+/*
+ * ***************************************************************************
+ * Copyright (C) 2016 Marvell International Ltd.
+ * ***************************************************************************
+ *
+ * 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 Marvell 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 __MSS_PM_MEM_H
+#define __MSS_PM_MEM_H
+
+/* MSS SRAM Memory base */
+#define MSS_SRAM_PM_CONTROL_BASE (MVEBU_REGS_BASE + 0x520000)
+
+enum mss_pm_ctrl_handshake {
+ MSS_UN_INITIALIZED = 0,
+ MSS_COMPATIBILITY_ERROR = 1,
+ MSS_ACKNOWLEDGEMENT = 2,
+ HOST_ACKNOWLEDGEMENT = 3
+};
+
+enum mss_pm_ctrl_rtos_env {
+ MSS_MULTI_PROCESS_ENV = 0,
+ MSS_SINGLE_PROCESS_ENV = 1,
+ MSS_MAX_PROCESS_ENV
+};
+
+struct mss_pm_ctrl_block {
+ /* This field is used to synchronize the Host
+ * and MSS initialization sequence
+ * Valid Values
+ * 0 - Un-Initialized
+ * 1 - Compatibility Error
+ * 2 - MSS Acknowledgment
+ * 3 - Host Acknowledgment
+ */
+ unsigned int handshake;
+
+ /*
+ * This field include Host IPC version. Once received by the MSS
+ * It will be compared to MSS IPC version and set MSS Acknowledge to
+ * "compatibility error" in case there is no match
+ */
+ unsigned int ipc_version;
+ unsigned int ipc_base_address;
+ unsigned int ipc_state;
+
+ /* Following fields defines firmware core architecture */
+ unsigned int num_of_cores;
+ unsigned int num_of_clusters;
+ unsigned int num_of_cores_per_cluster;
+
+ /* Following fields define pm trace debug base address */
+ unsigned int pm_trace_ctrl_base_address;
+ unsigned int pm_trace_info_base_address;
+ unsigned int pm_trace_info_core_size;
+
+ unsigned int ctrl_blk_size;
+};
+
+#endif /* __MSS_PM_MEM_H */
diff --git a/plat/marvell/a8k/common/mss/mss_pm_ipc.c b/plat/marvell/a8k/common/mss/mss_pm_ipc.c
new file mode 100644
index 00000000..c5b01465
--- /dev/null
+++ b/plat/marvell/a8k/common/mss/mss_pm_ipc.c
@@ -0,0 +1,147 @@
+/*
+ * ***************************************************************************
+ * Copyright (C) 2016 Marvell International Ltd.
+ * ***************************************************************************
+ *
+ * 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 Marvell 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 <mmio.h>
+#include <psci.h>
+#include <debug.h>
+#include <string.h>
+
+#include <mss_ipc_drv.h>
+#include <mss_pm_ipc.h>
+
+/*
+ ** SISR is 32 bit interrupt register representing 32 interrupts
+ **
+ ** +==================+==================+==================+=============+
+ ** + Suspend msg int + Off msg int + On msg int + Reserved +
+ ** +==================+==================+==================+=============+
+ ** + Bits 31 30 29 28 + Bits 27 26 25 24 + Bits 23 22 21 20 + Bits 19 - 0 +
+ ** +==================+==================+==================+=============+
+ ** + Core 3 2 1 0 + Core 3 2 1 0 + Core 3 2 1 0 + +
+ ** +==================+==================+==================+=============+
+ **
+ ** Example: Bit 26 = Off Message Interrupt to core #2
+ */
+#define MSS_SISR (MVEBU_REGS_BASE + 0x5800D0)
+
+#define MSS_CPU_SUSPEND_INT_SET_OFFSET (28)
+#define MSS_CPU_OFF_INT_SET_OFFSET (24)
+#define MSS_CPU_ON_INT_SET_OFFSET (20)
+
+/*******************************************************************************
+ * mss_pm_ipc_msg_send
+ *
+ * DESCRIPTION: create and transmit IPC message
+ ******************************************************************************
+ */
+int mss_pm_ipc_msg_send(unsigned int channel_id,
+ const psci_power_state_t *target_state)
+{
+ /* Transmit IPC message */
+#ifndef DISABLE_CLUSTER_LEVEL
+ mv_pm_ipc_msg_tx(channel_id, IPC_MSG_TX,
+ (unsigned int)target_state->pwr_domain_state[MPIDR_AFFLVL1]);
+#else
+ mv_pm_ipc_msg_tx(channel_id, IPC_MSG_TX, 0);
+#endif
+
+ return 0;
+}
+
+/*******************************************************************************
+ * mss_pm_ipc_msg_recv
+ *
+ * DESCRIPTION: wait from reception of IPC message indication,
+ * once received, read the message from IPC channel,
+ * mark IPC channel as Free, and validate reply
+ ******************************************************************************
+ */
+int mss_pm_ipc_msg_recv(unsigned int channel_id, unsigned int msg_id)
+{
+ struct mss_pm_ipc_msg msg;
+
+ /* Wait for PC message indication */
+ do {} while (mv_pm_ipc_msg_validate(channel_id,
+ IPC_MSG_RX, IPC_MSG_OCCUPY) != 0);
+
+ /* Read the message from IPC channel */
+ mv_pm_ipc_msg_rx(channel_id, IPC_MSG_RX, &msg);
+
+ /* Mark IPC channel as Free */
+ mv_pm_ipc_msg_update(channel_id, IPC_MSG_RX, IPC_MSG_FREE);
+
+ if (msg_id != msg.msg_reply) {
+ ERROR("MSS Error, Invalid reply message type %d\n",
+ msg.msg_reply);
+ return -1;
+ }
+
+ return 0;
+}
+
+/*******************************************************************************
+ * mss_pm_ipc_on_msg_trigger
+ *
+ * DESCRIPTION: Trigger IPC ON message interrupt to MSS
+ ******************************************************************************
+ */
+int mss_pm_ipc_on_msg_trigger(unsigned int cpu_id)
+{
+ mmio_write_32(MSS_SISR, 1 << (MSS_CPU_ON_INT_SET_OFFSET + cpu_id));
+ return 0;
+}
+
+/*******************************************************************************
+ * mss_pm_ipc_msg_trigger
+ *
+ * DESCRIPTION: Trigger IPC OFF message interrupt to MSS
+ ******************************************************************************
+ */
+int mss_pm_ipc_suspend_msg_trigger(unsigned int cpu_id)
+{
+ mmio_write_32(MSS_SISR, 1 << (MSS_CPU_SUSPEND_INT_SET_OFFSET + cpu_id));
+ return 0;
+}
+
+/*******************************************************************************
+ * mss_pm_ipc_msg_trigger
+ *
+ * DESCRIPTION: Trigger IPC SUSPEND message interrupt to MSS
+ ******************************************************************************
+ */
+int mss_pm_ipc_off_msg_trigger(unsigned int cpu_id)
+{
+ mmio_write_32(MSS_SISR, 1 << (MSS_CPU_OFF_INT_SET_OFFSET + cpu_id));
+ return 0;
+}
diff --git a/plat/marvell/a8k/common/mss/mss_pm_ipc.h b/plat/marvell/a8k/common/mss/mss_pm_ipc.h
new file mode 100644
index 00000000..16044c06
--- /dev/null
+++ b/plat/marvell/a8k/common/mss/mss_pm_ipc.h
@@ -0,0 +1,88 @@
+/*
+ * ***************************************************************************
+ * Copyright (C) 2016 Marvell International Ltd.
+ * ***************************************************************************
+ *
+ * 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 Marvell 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 __MSS_PM_IPC_H
+#define __MSS_PM_IPC_H
+
+
+#include <mss_ipc_drv.h>
+/* Currently MSS does not support Cluster level Power Down */
+#define DISABLE_CLUSTER_LEVEL
+
+
+/*******************************************************************************
+ * mss_pm_ipc_msg_send
+ *
+ * DESCRIPTION: create and transmit IPC message
+ ******************************************************************************
+ */
+int mss_pm_ipc_msg_send(unsigned int channel_id,
+ const psci_power_state_t *target_state);
+
+/*******************************************************************************
+ * mss_pm_ipc_msg_recv
+ *
+ * DESCRIPTION: wait from reception of IPC message indication,
+ * once received, read the message from IPC channel,
+ * mark IPC channel as Free, and validate reply
+ ******************************************************************************
+ */
+int mss_pm_ipc_msg_recv(unsigned int channel_id, unsigned int msg_id);
+
+/*******************************************************************************
+ * mss_pm_ipc_on_msg_trigger
+ *
+ * DESCRIPTION: Trigger IPC ON message interrupt to MSS
+ ******************************************************************************
+ */
+int mss_pm_ipc_on_msg_trigger(unsigned int cpu_id);
+
+/*******************************************************************************
+ * mss_pm_ipc_on_msg_trigger
+ *
+ * DESCRIPTION: Trigger IPC OFF message interrupt to MSS
+ ******************************************************************************
+ */
+int mss_pm_ipc_off_msg_trigger(unsigned int cpu_id);
+
+/*******************************************************************************
+ * mss_pm_ipc_on_msg_trigger
+ *
+ * DESCRIPTION: Trigger IPC SUSPEND message interrupt to MSS
+ ******************************************************************************
+ */
+int mss_pm_ipc_suspend_msg_trigger(unsigned int cpu_id);
+
+
+#endif /* __MSS_PM_IPC_H */
diff --git a/plat/marvell/a8k/common/mss/mss_scp_bootloader.c b/plat/marvell/a8k/common/mss/mss_scp_bootloader.c
new file mode 100644
index 00000000..2fc93120
--- /dev/null
+++ b/plat/marvell/a8k/common/mss/mss_scp_bootloader.c
@@ -0,0 +1,218 @@
+/*
+ * ***************************************************************************
+ * Copyright (C) 2016 Marvell International Ltd.
+ * ***************************************************************************
+ *
+ * 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 Marvell 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 <mmio.h>
+#include <arch_helpers.h> /* for cache maintanance operations */
+#include <platform_def.h>
+#include <delay_timer.h>
+#include <apn806_setup.h>
+
+#include <plat_pm_trace.h>
+#include <mss_scp_bootloader.h>
+#include <mss_ipc_drv.h>
+#include <mss_mem.h>
+
+
+#define MSS_DMA_SRCBR(base) (base + 0xC0)
+#define MSS_DMA_DSTBR(base) (base + 0xC4)
+#define MSS_DMA_CTRLR(base) (base + 0xC8)
+#define MSS_M3_RSTCR(base) (base + 0xFC)
+#define MSS_AEBR(base) (base + 0x160)
+#define MSS_AIBR(base) (base + 0x164)
+
+#define MSS_DMA_CTRLR_SIZE_OFFSET (0)
+#define MSS_DMA_CTRLR_REQ_OFFSET (15)
+#define MSS_DMA_CTRLR_REQ_SET (1)
+#define MSS_DMA_CTRLR_ACK_OFFSET (12)
+#define MSS_DMA_CTRLR_ACK_MASK (0x1)
+#define MSS_DMA_CTRLR_ACK_READY (1)
+#define MSS_M3_RSTCR_RST_OFFSET (0)
+#define MSS_M3_RSTCR_RST_OFF (1)
+#define MSS_AEBR_MASK 0xFFF
+#define MSS_AIBR_MASK 0xFFF
+
+#define MSS_DMA_TIMEOUT 1000
+#define MSS_EXTERNAL_SPACE 0x50000000
+#define MSS_EXTERNAL_ACCESS_BIT 28
+#define MSS_EXTERNAL_ADDR_MASK 0xfffffff
+#define MSS_INTERNAL_ACCESS_BIT 28
+
+#define DMA_SIZE 128
+
+#define MSS_HANDSHAKE_TIMEOUT 50
+/* TODO: Fix this */
+#define AP_MSS_REG_BASE (MVEBU_REGS_BASE + 0x580000)
+
+
+static int mss_check_image_ready(struct mss_pm_ctrl_block *mss_pm_crtl)
+{
+ int timeout = MSS_HANDSHAKE_TIMEOUT;
+
+ /* Wait for SCP to signal it's ready */
+ while ((mss_pm_crtl->handshake != MSS_ACKNOWLEDGEMENT) &&
+ (timeout-- > 0))
+ mdelay(1);
+
+ /*
+ * Check that the handshake was completed successfully
+ * Note: since A0 doesn't support MSS load, this check is skipped
+ */
+ if ((mss_pm_crtl->handshake != MSS_ACKNOWLEDGEMENT) &&
+ (apn806_rev_id_get() != APN806_REV_ID_A0))
+ return -1;
+
+ mss_pm_crtl->handshake = HOST_ACKNOWLEDGEMENT;
+
+ return 0;
+}
+
+
+static int mss_image_load(uint32_t src_addr, uint32_t size, uintptr_t mss_regs)
+{
+ uint32_t i, loop_num, timeout;
+
+ NOTICE("Loading MSS image from address 0x%x Size 0x%x to MSS at 0x%x\n",
+ src_addr, size, (uint32_t)mss_regs);
+ /* load image to MSS RAM using DMA */
+ loop_num = (size / DMA_SIZE) + (((size & (DMA_SIZE - 1)) == 0) ? 0 : 1);
+
+ /* set AXI External and Internal Address Bus extension */
+ mmio_write_32(MSS_AEBR(mss_regs), ((src_addr >> MSS_EXTERNAL_ACCESS_BIT)
+ & MSS_AEBR_MASK));
+ mmio_write_32(MSS_AIBR(mss_regs), ((mss_regs >> MSS_INTERNAL_ACCESS_BIT)
+ & MSS_AIBR_MASK));
+
+ for (i = 0; i < loop_num; i++) {
+ /* write destination and source addresses */
+ mmio_write_32(MSS_DMA_SRCBR(mss_regs),
+ MSS_EXTERNAL_SPACE |
+ ((src_addr & MSS_EXTERNAL_ADDR_MASK) +
+ (i * DMA_SIZE)));
+ mmio_write_32(MSS_DMA_DSTBR(mss_regs), (i * DMA_SIZE));
+
+ dsb(); /* make sure DMA data is ready before triggering it */
+
+ /* set the DMA control register */
+ mmio_write_32(MSS_DMA_CTRLR(mss_regs), ((MSS_DMA_CTRLR_REQ_SET
+ << MSS_DMA_CTRLR_REQ_OFFSET) |
+ (DMA_SIZE << MSS_DMA_CTRLR_SIZE_OFFSET)));
+
+ /* Poll DMA_ACK at MSS_DMACTLR until it is ready */
+ timeout = MSS_DMA_TIMEOUT;
+ while (timeout) {
+ if ((mmio_read_32(MSS_DMA_CTRLR(mss_regs)) >>
+ MSS_DMA_CTRLR_ACK_OFFSET & MSS_DMA_CTRLR_ACK_MASK)
+ == MSS_DMA_CTRLR_ACK_READY) {
+ break;
+ }
+
+ udelay(50);
+ timeout--;
+ }
+
+ if (timeout == 0) {
+ ERROR("\nDMA failed to load MSS image\n");
+ return 1;
+ }
+ }
+
+ /* Release M3 from reset */
+ mmio_write_32(MSS_M3_RSTCR(mss_regs), (MSS_M3_RSTCR_RST_OFF <<
+ MSS_M3_RSTCR_RST_OFFSET));
+
+ NOTICE("Done\n");
+
+ return 0;
+}
+
+int scp_bootloader_transfer(void *image, unsigned int image_size)
+{
+ int ret;
+ struct mss_pm_ctrl_block *mss_pm_crtl;
+
+ assert((uintptr_t) image == SCP_BL2_BASE);
+
+ if ((image_size == 0) || (image_size % 4 != 0)) {
+ ERROR("SCP_BL2 image size must be a multiple of 4 bytes\n");
+ ERROR("and not zero (current size = 0x%x)\n", image_size);
+ return -1;
+ }
+
+ /* TODO: add PM Control Info from platform */
+ mss_pm_crtl = (struct mss_pm_ctrl_block *)MSS_SRAM_PM_CONTROL_BASE;
+ mss_pm_crtl->ipc_version = MV_PM_FW_IPC_VERSION;
+ mss_pm_crtl->num_of_clusters = PLAT_MARVELL_CLUSTER_COUNT;
+ mss_pm_crtl->num_of_cores_per_cluster =
+ PLAT_MARVELL_CLUSTER_CORE_COUNT;
+ mss_pm_crtl->num_of_cores = PLAT_MARVELL_CLUSTER_COUNT *
+ PLAT_MARVELL_CLUSTER_CORE_COUNT;
+ mss_pm_crtl->pm_trace_ctrl_base_address = AP_MSS_ATF_CORE_CTRL_BASE;
+ mss_pm_crtl->pm_trace_info_base_address = AP_MSS_ATF_CORE_INFO_BASE;
+ mss_pm_crtl->pm_trace_info_core_size = AP_MSS_ATF_CORE_INFO_SIZE;
+ VERBOSE("MSS Control Block = 0x%x\n", MSS_SRAM_PM_CONTROL_BASE);
+ VERBOSE("mss_pm_crtl->ipc_version = 0x%x\n",
+ mss_pm_crtl->ipc_version);
+ VERBOSE("mss_pm_crtl->num_of_cores = 0x%x\n",
+ mss_pm_crtl->num_of_cores);
+ VERBOSE("mss_pm_crtl->num_of_clusters = 0x%x\n",
+ mss_pm_crtl->num_of_clusters);
+ VERBOSE("mss_pm_crtl->num_of_cores_per_cluster = 0x%x\n",
+ mss_pm_crtl->num_of_cores_per_cluster);
+ VERBOSE("mss_pm_crtl->pm_trace_ctrl_base_address = 0x%x\n",
+ mss_pm_crtl->pm_trace_ctrl_base_address);
+ VERBOSE("mss_pm_crtl->pm_trace_info_base_address = 0x%x\n",
+ mss_pm_crtl->pm_trace_info_base_address);
+ VERBOSE("mss_pm_crtl->pm_trace_info_core_size = 0x%x\n",
+ mss_pm_crtl->pm_trace_info_core_size);
+
+ /* TODO: add checksum to image */
+ VERBOSE("Send info about the SCP_BL2 image to be transferred to SCP\n");
+ NOTICE("Load image to AP MSS\n");
+ ret = mss_image_load((uintptr_t)image, image_size, AP_MSS_REG_BASE);
+ if (ret != 0) {
+ ERROR("SCP Image load failed\n");
+ return -1;
+ }
+
+ /* check that the image was loaded successfully */
+ ret = mss_check_image_ready(mss_pm_crtl);
+ if (ret != 0) {
+ ERROR("SCP Image check failed\n");
+ return -1;
+ }
+
+ return 0;
+}
diff --git a/plat/marvell/a8k/common/mss/mss_scp_bootloader.h b/plat/marvell/a8k/common/mss/mss_scp_bootloader.h
new file mode 100644
index 00000000..fe97e7a5
--- /dev/null
+++ b/plat/marvell/a8k/common/mss/mss_scp_bootloader.h
@@ -0,0 +1,40 @@
+/*
+ * ***************************************************************************
+ * Copyright (C) 2016 Marvell International Ltd.
+ * ***************************************************************************
+ *
+ * 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 Marvell 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 __MSS_SCP_BOOTLOADER_H__
+#define __MSS_SCP_BOOTLOADER_H__
+
+int scp_bootloader_transfer(void *image, unsigned int image_size);
+
+#endif /* __MSS_SCP_BOOTLOADER_H__ */