plat/arm: Add support for SGM775

Add support for System Guidance for Mobile platform SGM775

Change-Id: I2442a50caae8f597e5e5949cd48f695cf75d9653
Signed-off-by: Nariman Poushin <nariman.poushin@linaro.org>
diff --git a/plat/arm/css/sgm/aarch64/css_sgm_helpers.S b/plat/arm/css/sgm/aarch64/css_sgm_helpers.S
new file mode 100644
index 0000000..d9b3df6
--- /dev/null
+++ b/plat/arm/css/sgm/aarch64/css_sgm_helpers.S
@@ -0,0 +1,96 @@
+/*
+ * Copyright (c) 2018, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <arch.h>
+#include <asm_macros.S>
+#include <platform_def.h>
+#include <cortex_a75.h>
+#include <cortex_a55.h>
+
+	.globl	plat_arm_calc_core_pos
+	.globl	plat_reset_handler
+
+	/* ---------------------------------------------------------------------
+	 * unsigned int plat_arm_calc_core_pos(u_register_t mpidr)
+	 *
+	 * Function to calculate the core position on FVP.
+	 *
+	 * (ClusterId * MAX_CPUS_PER_CLUSTER * MAX_PE_PER_CPU) +
+	 * (CPUId * MAX_PE_PER_CPU) +
+	 * ThreadId
+	 *
+	 * which can be simplified as:
+	 *
+	 * ((ClusterId * MAX_CPUS_PER_CLUSTER + CPUId) * MAX_PE_PER_CPU)
+	 * + ThreadId
+	 * ---------------------------------------------------------------------
+	 */
+func plat_arm_calc_core_pos
+	/*
+	 * Check for MT bit in MPIDR. If not set, shift MPIDR to left to make it
+	 * look as if in a multi-threaded implementation.
+	 */
+	tst	x0, #MPIDR_MT_MASK
+	lsr	x3, x0, #MPIDR_AFFINITY_BITS
+	csel	x3, x3, x0, eq
+
+	/* Extract individual affinity fields from MPIDR */
+	ubfx	x0, x3, #MPIDR_AFF0_SHIFT, #MPIDR_AFFINITY_BITS
+	ubfx	x1, x3, #MPIDR_AFF1_SHIFT, #MPIDR_AFFINITY_BITS
+	ubfx	x2, x3, #MPIDR_AFF2_SHIFT, #MPIDR_AFFINITY_BITS
+
+	/* Compute linear position */
+	mov	x4, #PLAT_MAX_CPUS_PER_CLUSTER
+	madd	x1, x2, x4, x1
+	mov	x5, #PLAT_MAX_PE_PER_CPU
+	madd	x0, x1, x5, x0
+	ret
+endfunc plat_arm_calc_core_pos
+
+	/* ------------------------------------------------------
+	 * Helper macro that reads the part number of the current
+	 * CPU and jumps to the given label if it matches the CPU
+	 * MIDR provided.
+	 *
+	 * Clobbers x0.
+	 * -----------------------------------------------------
+	 */
+	.macro  jump_if_cpu_midr _cpu_midr, _label
+	mrs	x0, midr_el1
+	ubfx	x0, x0, MIDR_PN_SHIFT, #12
+	cmp	w0, #((\_cpu_midr >> MIDR_PN_SHIFT) & MIDR_PN_MASK)
+	b.eq	\_label
+	.endm
+
+	/* -----------------------------------------------------
+	 * void plat_reset_handler(void);
+	 *
+	 * Determine the CPU MIDR and disable power down bit for
+	 * that CPU.
+	 * -----------------------------------------------------
+	 */
+func plat_reset_handler
+	jump_if_cpu_midr CORTEX_A75_MIDR, A75
+	jump_if_cpu_midr CORTEX_A55_MIDR, A55
+	ret
+
+	/* -----------------------------------------------------
+	 * Disable CPU power down bit in power control register
+	 * -----------------------------------------------------
+	 */
+A75:
+	mrs	x0, CORTEX_A75_CPUPWRCTLR_EL1
+	bic	x0, x0, #CORTEX_A75_CORE_PWRDN_EN_MASK
+	msr	CORTEX_A75_CPUPWRCTLR_EL1, x0
+	isb
+	ret
+A55:
+	mrs	x0, CORTEX_A55_CPUPWRCTLR_EL1
+	bic	x0, x0, #CORTEX_A55_CORE_PWRDN_EN_MASK
+	msr	CORTEX_A55_CPUPWRCTLR_EL1, x0
+	isb
+	ret
+endfunc plat_reset_handler
diff --git a/plat/arm/css/sgm/fdts/sgm_tb_fw_config.dts b/plat/arm/css/sgm/fdts/sgm_tb_fw_config.dts
new file mode 100644
index 0000000..9502549
--- /dev/null
+++ b/plat/arm/css/sgm/fdts/sgm_tb_fw_config.dts
@@ -0,0 +1,16 @@
+/*
+ * Copyright (c) 2018, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+/dts-v1/;
+
+/ {
+	/* Platform Config */
+	plat_arm_bl2 {
+		compatible = "arm,tb_fw";
+		hw_config_addr = <0x0 0x83000000>;
+		hw_config_max_size = <0x01000000>;
+	};
+};
diff --git a/plat/arm/css/sgm/include/plat_macros.S b/plat/arm/css/sgm/include/plat_macros.S
new file mode 100644
index 0000000..d877ef8
--- /dev/null
+++ b/plat/arm/css/sgm/include/plat_macros.S
@@ -0,0 +1,24 @@
+/*
+ * Copyright (c) 2018, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+#ifndef __PLAT_MACROS_S__
+#define __PLAT_MACROS_S__
+
+#include <cci_macros.S>
+#include <css_macros.S>
+
+/* ---------------------------------------------
+ * The below required platform porting macro
+ * prints out relevant platform registers
+ * whenever an unhandled exception is taken in
+ * BL31.
+ * ---------------------------------------------
+ */
+.macro plat_crash_print_regs
+css_print_gic_regs
+print_cci_regs
+.endm
+
+#endif /* __PLAT_MACROS_S__ */
diff --git a/plat/arm/css/sgm/include/platform_oid.h b/plat/arm/css/sgm/include/platform_oid.h
new file mode 100644
index 0000000..18d41e3
--- /dev/null
+++ b/plat/arm/css/sgm/include/platform_oid.h
@@ -0,0 +1,11 @@
+/*
+ * Copyright (c) 2018, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+#include "../../../../../include/plat/arm/board/common/board_arm_oid.h"
+
+/*
+ * Required platform OIDs
+ * (Provided by included header)
+ */
diff --git a/plat/arm/css/sgm/include/sgm_base_platform_def.h b/plat/arm/css/sgm/include/sgm_base_platform_def.h
new file mode 100644
index 0000000..2498430
--- /dev/null
+++ b/plat/arm/css/sgm/include/sgm_base_platform_def.h
@@ -0,0 +1,234 @@
+/*
+ * Copyright (c) 2018, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef __SGM_BASE_PLATFORM_DEF_H__
+#define __SGM_BASE_PLATFORM_DEF_H__
+
+#include <arm_def.h>
+#include <board_arm_def.h>
+#include <board_css_def.h>
+#include <common_def.h>
+#include <css_def.h>
+#include <soc_css_def.h>
+#include <tzc400.h>
+#include <tzc_common.h>
+
+/* CPU topology */
+#define PLAT_ARM_CLUSTER_COUNT		1
+#define PLAT_ARM_CLUSTER_CORE_COUNT	8
+#define PLATFORM_CORE_COUNT		PLAT_ARM_CLUSTER_CORE_COUNT
+
+#define PLAT_MAX_PWR_LVL		ARM_PWR_LVL2
+#define PLAT_NUM_PWR_DOMAINS		(ARM_SYSTEM_COUNT + \
+					PLAT_ARM_CLUSTER_COUNT + \
+					PLATFORM_CORE_COUNT)
+
+/*
+ * Define a list of Group 1 Secure and Group 0 interrupts as per GICv3
+ * terminology. On a GICv2 system or mode, the lists will be merged and treated
+ * as Group 0 interrupts.
+ */
+#define PLAT_ARM_G1S_IRQ_PROPS(grp) \
+			CSS_G1S_IRQ_PROPS(grp), \
+			ARM_G1S_IRQ_PROPS(grp)
+
+#define PLAT_ARM_G0_IRQ_PROPS(grp)	ARM_G0_IRQ_PROPS(grp)
+
+/* GIC related constants */
+#define PLAT_ARM_GICD_BASE		0x30000000
+#define PLAT_ARM_GICR_BASE		0x300C0000
+#define PLAT_ARM_GICC_BASE		0x2c000000
+
+#define CSS_GIC_SIZE			0x00200000
+
+#define CSS_MAP_GIC_DEVICE		MAP_REGION_FLAT(	\
+					PLAT_ARM_GICD_BASE,	\
+					CSS_GIC_SIZE,		\
+					MT_DEVICE | MT_RW | MT_SECURE)
+
+/* Platform ID address */
+#define SSC_VERSION                     (SSC_REG_BASE + SSC_VERSION_OFFSET)
+#ifndef __ASSEMBLY__
+/* SSC_VERSION related accessors */
+/* Returns the part number of the platform */
+#define GET_PLAT_PART_NUM                                       \
+		GET_SSC_VERSION_PART_NUM(mmio_read_32(SSC_VERSION))
+/* Returns the configuration number of the platform */
+#define GET_PLAT_CONFIG_NUM                                     \
+		GET_SSC_VERSION_CONFIG(mmio_read_32(SSC_VERSION))
+#endif /* __ASSEMBLY__ */
+
+
+/*************************************************************************
+ * Definitions common to all SGM CSS based platforms
+ *************************************************************************/
+
+/* TZC-400 related constants */
+#define PLAT_ARM_TZC_BASE		0x2a500000
+#define TZC_NSAID_ALL_AP		0  /* Note: Same as default NSAID!! */
+#define TZC_NSAID_HDLCD0		2
+#define TZC_NSAID_HDLCD1		3
+#define TZC_NSAID_GPU			9
+#define TZC_NSAID_VIDEO			10
+#define TZC_NSAID_DISP0			11
+#define TZC_NSAID_DISP1			12
+
+
+/*************************************************************************
+ * Required platform porting definitions common to all SGM CSS based
+ * platforms
+ *************************************************************************/
+
+/* MHU related constants */
+#define PLAT_CSS_MHU_BASE		0x2b1f0000
+
+#define PLAT_ARM_TRUSTED_ROM_BASE	0x00000000
+#define PLAT_ARM_TRUSTED_ROM_SIZE	0x00080000
+
+#define PLAT_ARM_CCI_BASE		0x2a000000
+
+/* Cluster to CCI slave mapping */
+#define PLAT_ARM_CCI_CLUSTER0_SL_IFACE_IX	6
+#define PLAT_ARM_CCI_CLUSTER1_SL_IFACE_IX	5
+
+/* System timer related constants */
+#define PLAT_ARM_NSTIMER_FRAME_ID	0
+
+/* TZC related constants */
+#define PLAT_ARM_TZC_NS_DEV_ACCESS	(				\
+		TZC_REGION_ACCESS_RDWR(TZC_NSAID_ALL_AP)	|	\
+		TZC_REGION_ACCESS_RDWR(TZC_NSAID_HDLCD0)	|	\
+		TZC_REGION_ACCESS_RDWR(TZC_NSAID_HDLCD1)	|	\
+		TZC_REGION_ACCESS_RDWR(TZC_NSAID_GPU)	|	\
+		TZC_REGION_ACCESS_RDWR(TZC_NSAID_VIDEO)	|	\
+		TZC_REGION_ACCESS_RDWR(TZC_NSAID_DISP0)	|	\
+		TZC_REGION_ACCESS_RDWR(TZC_NSAID_DISP1))
+
+/* Display Processor register definitions to setup the NSAIDs */
+#define MALI_DP_BASE           0x2cc00000
+#define DP_NPROT_NSAID_OFFSET     0x1000c
+#define W_NPROT_NSAID_SHIFT            24
+#define LS_NPORT_NSAID_SHIFT           12
+
+/*
+ * Base address of the first memory region used for communication between AP
+ * and SCP. Used by the BootOverMHU and SCPI protocols.
+ */
+#if !CSS_USE_SCMI_SDS_DRIVER
+/*
+ * Note that this is located at the same address as SCP_BOOT_CFG_ADDR, which
+ * means the SCP/AP configuration data gets overwritten when the AP initiates
+ * communication with the SCP. The configuration data is expected to be a
+ * 32-bit word on all CSS platforms. Part of this configuration is
+ * which CPU is the primary, according to the shift and mask definitions below.
+ */
+#define PLAT_CSS_SCP_COM_SHARED_MEM_BASE	(ARM_TRUSTED_SRAM_BASE + 0x80)
+#define PLAT_CSS_PRIMARY_CPU_SHIFT		8
+#define PLAT_CSS_PRIMARY_CPU_BIT_WIDTH		4
+#endif
+
+/*
+ * tspd support is conditional so enable this for CSS sgm platforms.
+ */
+#define SPD_tspd
+
+/*
+ * PLAT_CSS_MAX_SCP_BL2_SIZE is calculated using the current
+ * SCP_BL2 size plus a little space for growth.
+ */
+#define PLAT_CSS_MAX_SCP_BL2_SIZE	0x15000
+
+/*
+ * PLAT_CSS_MAX_SCP_BL2U_SIZE is calculated using the current
+ * SCP_BL2U size plus a little space for growth.
+ */
+#define PLAT_CSS_MAX_SCP_BL2U_SIZE	0x15000
+
+/*
+ * Most platform porting definitions provided by included headers
+ */
+
+/*
+ * If ARM_BOARD_OPTIMISE_MEM=0 then use the default, unoptimised values
+ * defined for ARM development platforms.
+ */
+#if ARM_BOARD_OPTIMISE_MEM
+/*
+ * PLAT_ARM_MMAP_ENTRIES depends on the number of entries in the
+ * plat_arm_mmap array defined for each BL stage.
+ */
+#if IMAGE_BL1
+# if TRUSTED_BOARD_BOOT
+#  define PLAT_ARM_MMAP_ENTRIES		7
+# else
+#  define PLAT_ARM_MMAP_ENTRIES		6
+# endif /* TRUSTED_BOARD_BOOT */
+#elif IMAGE_BL2
+#  define PLAT_ARM_MMAP_ENTRIES		8
+#elif IMAGE_BL2U
+#  define PLAT_ARM_MMAP_ENTRIES		4
+#elif IMAGE_BL31
+#  define PLAT_ARM_MMAP_ENTRIES		6
+#elif IMAGE_BL32
+#  define PLAT_ARM_MMAP_ENTRIES		5
+#endif
+
+/*
+ * Platform specific page table and MMU setup constants
+ */
+#if IMAGE_BL1
+# if TRUSTED_BOARD_BOOT
+#  define MAX_XLAT_TABLES		4
+# else
+#  define MAX_XLAT_TABLES		3
+#endif
+#elif IMAGE_BL2
+#  define MAX_XLAT_TABLES		4
+#elif IMAGE_BL2U
+#  define MAX_XLAT_TABLES		4
+#elif IMAGE_BL31
+#  define MAX_XLAT_TABLES		2
+#elif IMAGE_BL32
+# if ARM_TSP_RAM_LOCATION_ID == ARM_DRAM_ID
+#  define MAX_XLAT_TABLES		3
+# else
+#  define MAX_XLAT_TABLES		2
+# endif
+#endif
+
+/*
+ * PLAT_ARM_MAX_BL1_RW_SIZE is calculated using the current BL1 RW debug size
+ * plus a little space for growth.
+ */
+#if TRUSTED_BOARD_BOOT
+# define PLAT_ARM_MAX_BL1_RW_SIZE	0xA000
+#else
+# define PLAT_ARM_MAX_BL1_RW_SIZE	0x7000
+#endif
+
+/*
+ * PLAT_ARM_MAX_BL2_SIZE is calculated using the current BL2 debug size plus a
+ * little space for growth.
+ */
+#if TRUSTED_BOARD_BOOT
+# define PLAT_ARM_MAX_BL2_SIZE		0x1D000
+#else
+# define PLAT_ARM_MAX_BL2_SIZE		0xD000
+#endif
+
+#endif /* ARM_BOARD_OPTIMISE_MEM */
+
+/*******************************************************************************
+ * Memprotect definitions
+ ******************************************************************************/
+/* PSCI memory protect definitions:
+ * This variable is stored in a non-secure flash because some ARM reference
+ * platforms do not have secure NVRAM. Real systems that provided MEM_PROTECT
+ * support must use a secure NVRAM to store the PSCI MEM_PROTECT definitions.
+ */
+#define PLAT_ARM_MEM_PROT_ADDR		(V2M_FLASH0_BASE + \
+					 V2M_FLASH0_SIZE - V2M_FLASH_BLOCK_SIZE)
+#endif /* __SGM_BASE_PLATFORM_DEF_H__ */
diff --git a/plat/arm/css/sgm/include/sgm_plat_config.h b/plat/arm/css/sgm/include/sgm_plat_config.h
new file mode 100644
index 0000000..b171d9a
--- /dev/null
+++ b/plat/arm/css/sgm/include/sgm_plat_config.h
@@ -0,0 +1,43 @@
+/*
+ * Copyright (c) 2018, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef __SGM_PLAT_CONFIG_H__
+#define __SGM_PLAT_CONFIG_H__
+
+#include <arm_gic.h>
+#include <ccn.h>
+#include <gicv3.h>
+
+/* The type of interconnect */
+typedef enum {
+	ARM_CCI = 0,
+	ARM_CCN,
+	ARM_CMN
+} css_inteconn_type_t;
+
+typedef ccn_desc_t inteconn_desc_t;
+
+/* Interconnect configurations */
+typedef struct css_inteconn_config {
+	css_inteconn_type_t ip_type;
+	const inteconn_desc_t *plat_inteconn_desc;
+} css_inteconn_config_t;
+
+/* Topology configurations */
+typedef struct css_topology {
+	const unsigned char *power_tree;
+	unsigned int plat_cluster_core_count;
+} css_topology_t;
+
+typedef struct css_plat_config {
+	const gicv3_driver_data_t *gic_data;
+	const css_inteconn_config_t *inteconn;
+	const css_topology_t *topology;
+} css_plat_config_t;
+
+void plat_config_init(void);
+css_plat_config_t *get_plat_config(void);
+#endif /* __SGM_PLAT_CONFIG_H__ */
diff --git a/plat/arm/css/sgm/include/sgm_variant.h b/plat/arm/css/sgm/include/sgm_variant.h
new file mode 100644
index 0000000..a0a91b0
--- /dev/null
+++ b/plat/arm/css/sgm/include/sgm_variant.h
@@ -0,0 +1,17 @@
+/*
+ * Copyright (c) 2018, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef __SGM_VARIANT_H__
+#define __SGM_VARIANT_H__
+
+/* SSC_VERSION values for sgm */
+#define SGM775_SSC_VER_PART_NUM		0x0790
+
+/* DMC configuration for sgm */
+#define SGM_DMC_SIZE			0x40000
+#define SGM775_DMC_COUNT		4
+
+#endif /* __SGM_VARIANT_H__ */
diff --git a/plat/arm/css/sgm/sgm-common.mk b/plat/arm/css/sgm/sgm-common.mk
new file mode 100644
index 0000000..6a3caba
--- /dev/null
+++ b/plat/arm/css/sgm/sgm-common.mk
@@ -0,0 +1,68 @@
+#
+# Copyright (c) 2018, ARM Limited and Contributors. All rights reserved.
+#
+# SPDX-License-Identifier: BSD-3-Clause
+#
+
+CSS_SGM_BASE		:=	plat/arm/css/sgm
+
+PLAT_INCLUDES		:=	-I${CSS_SGM_BASE}/include
+
+PLAT_BL_COMMON_SOURCES	:=	${CSS_SGM_BASE}/sgm_mmap_config.c	\
+				${CSS_SGM_BASE}/aarch64/css_sgm_helpers.S
+
+SECURITY_SOURCES	:=	drivers/arm/tzc/tzc_dmc500.c		\
+				plat/arm/common/arm_tzc_dmc500.c 	\
+				${CSS_SGM_BASE}/sgm_security.c
+
+SGM_CPU_SOURCES		:=	lib/cpus/aarch64/cortex_a55.S		\
+				lib/cpus/aarch64/cortex_a75.S
+
+INTERCONNECT_SOURCES	:=	${CSS_SGM_BASE}/sgm_interconnect.c
+
+SGM_GIC_SOURCES		:=	drivers/arm/gic/common/gic_common.c	\
+				drivers/arm/gic/v3/gicv3_main.c		\
+				drivers/arm/gic/v3/gicv3_helpers.c	\
+				plat/common/plat_gicv3.c		\
+				plat/arm/common/arm_gicv3.c		\
+				drivers/arm/gic/v3/gic600.c		\
+				drivers/arm/gic/v3/arm_gicv3_common.c
+
+BL1_SOURCES		+=	$(SGM_CPU_SOURCES)			\
+				${INTERCONNECT_SOURCES}			\
+				${CSS_SGM_BASE}/sgm_bl1_setup.c	\
+				${CSS_SGM_BASE}/sgm_plat_config.c
+
+BL2_SOURCES		+=	${SECURITY_SOURCES}
+
+BL2U_SOURCES		+=	${SECURITY_SOURCES}
+
+BL31_SOURCES		+=	$(SGM_CPU_SOURCES)			\
+				${INTERCONNECT_SOURCES}			\
+				${SECURITY_SOURCES}			\
+				${SGM_GIC_SOURCES}			\
+				${CSS_SGM_BASE}/sgm_topology.c	\
+				${CSS_SGM_BASE}/sgm_bl31_setup.c	\
+				${CSS_SGM_BASE}/sgm_plat_config.c
+
+# sgm uses CCI-500 as Cache Coherent Interconnect
+ARM_CCI_PRODUCT_ID	:=	500
+
+# Disable the PSCI platform compatibility layer
+ENABLE_PLAT_COMPAT	:=	0
+
+# System coherency is managed in hardware
+HW_ASSISTED_COHERENCY	:=	1
+
+# When building for systems with hardware-assisted coherency, there's no need to
+# use USE_COHERENT_MEM. Require that USE_COHERENT_MEM must be set to 0 too.
+USE_COHERENT_MEM	:=	0
+
+override ARM_PLAT_MT	:=	1
+
+$(eval $(call add_define,SGM_PLAT))
+
+include plat/arm/common/arm_common.mk
+include plat/arm/board/common/board_common.mk
+include plat/arm/css/common/css_common.mk
+include plat/arm/soc/common/soc_css.mk
diff --git a/plat/arm/css/sgm/sgm_bl1_setup.c b/plat/arm/css/sgm/sgm_bl1_setup.c
new file mode 100644
index 0000000..51e3e53
--- /dev/null
+++ b/plat/arm/css/sgm/sgm_bl1_setup.c
@@ -0,0 +1,31 @@
+/*
+ * Copyright (c) 2018, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <bl_common.h>
+#include <debug.h>
+#include <plat_arm.h>
+#include <sgm_plat_config.h>
+#include <soc_css.h>
+
+void bl1_early_platform_setup(void)
+{
+	/* Initialize the platform configuration structure */
+	plat_config_init();
+
+	arm_bl1_early_platform_setup();
+
+#if !HW_ASSISTED_COHERENCY
+	/*
+	 * Initialize Interconnect for this cluster during cold boot.
+	 * No need for locks as no other CPU is active.
+	 */
+	plat_arm_interconnect_init();
+	/*
+	 * Enable Interconnect coherency for the primary CPU's cluster.
+	 */
+	plat_arm_interconnect_enter_coherency();
+#endif
+}
diff --git a/plat/arm/css/sgm/sgm_bl31_setup.c b/plat/arm/css/sgm/sgm_bl31_setup.c
new file mode 100644
index 0000000..a55176a
--- /dev/null
+++ b/plat/arm/css/sgm/sgm_bl31_setup.c
@@ -0,0 +1,34 @@
+/*
+ * Copyright (c) 2018, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <bl_common.h>
+#include <debug.h>
+#include <plat_arm.h>
+#include <sgm_plat_config.h>
+
+void bl31_early_platform_setup2(u_register_t arg0, u_register_t arg1,
+				u_register_t arg2, u_register_t arg3)
+{
+	uint32_t plat_version;
+	bl_params_node_t *bl_params;
+
+	bl_params = ((bl_params_t *)arg0)->head;
+
+	/* Initialize the platform configuration structure */
+	plat_config_init();
+
+	while (bl_params) {
+		if (bl_params->image_id == BL33_IMAGE_ID) {
+			plat_version = mmio_read_32(SSC_VERSION);
+			bl_params->ep_info->args.arg2 = plat_version;
+			break;
+		}
+
+		bl_params = bl_params->next_params_info;
+	}
+
+	arm_bl31_early_platform_setup((void *)arg0, arg1, arg2, (void *)arg3);
+}
diff --git a/plat/arm/css/sgm/sgm_interconnect.c b/plat/arm/css/sgm/sgm_interconnect.c
new file mode 100644
index 0000000..301ea84
--- /dev/null
+++ b/plat/arm/css/sgm/sgm_interconnect.c
@@ -0,0 +1,32 @@
+/*
+ * Copyright (c) 2018, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+/*
+ * As the SGM platform supports FCM (with automatic interconnect
+ * enter/exit), we should not do anything in these interface functions.
+ * They are used to override the weak functions in cci drivers.
+ */
+
+/******************************************************************************
+ * Helper function to initialize ARM interconnect driver.
+ *****************************************************************************/
+void plat_arm_interconnect_init(void)
+{
+}
+
+/******************************************************************************
+ * Helper function to place current master into coherency
+ *****************************************************************************/
+void plat_arm_interconnect_enter_coherency(void)
+{
+}
+
+/******************************************************************************
+ * Helper function to remove current master from coherency
+ *****************************************************************************/
+void plat_arm_interconnect_exit_coherency(void)
+{
+}
diff --git a/plat/arm/css/sgm/sgm_mmap_config.c b/plat/arm/css/sgm/sgm_mmap_config.c
new file mode 100644
index 0000000..009ee64
--- /dev/null
+++ b/plat/arm/css/sgm/sgm_mmap_config.c
@@ -0,0 +1,83 @@
+/*
+ * Copyright (c) 2018, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <arm_def.h>
+#include <bl_common.h>
+#include <debug.h>
+#include <plat_arm.h>
+#include <platform_def.h>
+#include <sgm_variant.h>
+
+/*
+ * Table of regions for different BL stages to map using the MMU.
+ * This doesn't include Trusted RAM as the 'mem_layout' argument passed to
+ * arm_configure_mmu_elx() will give the available subset of that.
+ */
+#if IMAGE_BL1
+const mmap_region_t plat_arm_mmap[] = {
+	ARM_MAP_SHARED_RAM,
+	V2M_MAP_FLASH0_RO,
+	V2M_MAP_IOFPGA,
+	CSS_MAP_DEVICE,
+	CSS_MAP_GIC_DEVICE,
+	SOC_CSS_MAP_DEVICE,
+#if TRUSTED_BOARD_BOOT
+	ARM_MAP_NS_DRAM1,
+#endif
+	{0}
+};
+#endif
+#if IMAGE_BL2
+const mmap_region_t plat_arm_mmap[] = {
+	ARM_MAP_SHARED_RAM,
+	V2M_MAP_FLASH0_RO,
+	V2M_MAP_IOFPGA,
+	CSS_MAP_DEVICE,
+	CSS_MAP_GIC_DEVICE,
+	SOC_CSS_MAP_DEVICE,
+	ARM_MAP_NS_DRAM1,
+	ARM_MAP_TSP_SEC_MEM,
+#ifdef SPD_opteed
+	ARM_OPTEE_PAGEABLE_LOAD_MEM,
+#endif
+	{0}
+};
+#endif
+#if IMAGE_BL2U
+const mmap_region_t plat_arm_mmap[] = {
+	ARM_MAP_SHARED_RAM,
+	CSS_MAP_DEVICE,
+	CSS_MAP_GIC_DEVICE,
+	SOC_CSS_MAP_DEVICE,
+	{0}
+};
+#endif
+#if IMAGE_BL31
+const mmap_region_t plat_arm_mmap[] = {
+	ARM_MAP_SHARED_RAM,
+	V2M_MAP_IOFPGA,
+	CSS_MAP_DEVICE,
+	CSS_MAP_GIC_DEVICE,
+	SOC_CSS_MAP_DEVICE,
+	{0}
+};
+#endif
+#if IMAGE_BL32
+const mmap_region_t plat_arm_mmap[] = {
+	V2M_MAP_IOFPGA,
+	CSS_MAP_DEVICE,
+	CSS_MAP_GIC_DEVICE,
+	SOC_CSS_MAP_DEVICE,
+	{0}
+};
+#endif
+
+ARM_CASSERT_MMAP
+
+const mmap_region_t *plat_arm_get_mmap(void)
+{
+	return plat_arm_mmap;
+}
diff --git a/plat/arm/css/sgm/sgm_plat_config.c b/plat/arm/css/sgm/sgm_plat_config.c
new file mode 100644
index 0000000..809edf6
--- /dev/null
+++ b/plat/arm/css/sgm/sgm_plat_config.c
@@ -0,0 +1,69 @@
+/*
+ * Copyright (c) 2018, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <assert.h>
+#include <debug.h>
+#include <plat_arm.h>
+#include <platform_def.h>
+#include <sgm_plat_config.h>
+#include <sgm_variant.h>
+#include <string.h>
+
+static css_plat_config_t *css_plat_info;
+
+/* Interconnect */
+const css_inteconn_config_t sgm_inteconn = {
+	.ip_type = ARM_CCI,
+	.plat_inteconn_desc = NULL
+};
+
+/* Special definition for SGM775 */
+/* Topology configuration for SGM775 */
+const unsigned char sgm775_power_domain_tree_desc[] = {
+	/* No of root nodes */
+	ARM_SYSTEM_COUNT,
+	/* No of children for the root node */
+	PLAT_ARM_CLUSTER_COUNT,
+	/* No of children for the first cluster node */
+	PLAT_ARM_CLUSTER_CORE_COUNT,
+};
+
+const css_topology_t sgm775_topology = {
+	.power_tree = sgm775_power_domain_tree_desc,
+	.plat_cluster_core_count = PLAT_ARM_CLUSTER_CORE_COUNT
+};
+
+/* Configuration structure for SGM775 */
+css_plat_config_t sgm775_config = {
+	.inteconn = &sgm_inteconn,
+	.topology = &sgm775_topology
+};
+
+/*******************************************************************************
+ * This function initializes the platform structure.
+ ******************************************************************************/
+void plat_config_init(void)
+{
+	/* Get the platform configurations */
+	switch (GET_PLAT_PART_NUM) {
+	case SGM775_SSC_VER_PART_NUM:
+		css_plat_info = &sgm775_config;
+
+		break;
+	default:
+		ERROR("Not a valid sgm variant!\n");
+		panic();
+	}
+}
+
+/*******************************************************************************
+ * This function returns the platform structure pointer.
+ ******************************************************************************/
+css_plat_config_t *get_plat_config(void)
+{
+	assert(css_plat_info != NULL);
+	return css_plat_info;
+}
diff --git a/plat/arm/css/sgm/sgm_security.c b/plat/arm/css/sgm/sgm_security.c
new file mode 100644
index 0000000..7f98060
--- /dev/null
+++ b/plat/arm/css/sgm/sgm_security.c
@@ -0,0 +1,64 @@
+/*
+ * Copyright (c) 2018, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <debug.h>
+#include <plat_arm.h>
+#include <sgm_variant.h>
+#include <soc_css.h>
+#include <tzc_dmc500.h>
+
+/* Is populated with the DMC-500 controllers base addresses */
+static tzc_dmc500_driver_data_t plat_driver_data;
+
+void plat_sgm_dp_security_setup(void)
+{
+	unsigned int nprot_nsaid;
+
+	/*
+	 * At reset the Mali display processors start with NSAIDs set to zero
+	 * so the firmware must set them up to the expected values for ARM sgm
+	 * platforms.
+	 */
+
+	nprot_nsaid = mmio_read_32(MALI_DP_BASE + DP_NPROT_NSAID_OFFSET);
+	nprot_nsaid &= ~((0xF << W_NPROT_NSAID_SHIFT) |
+			(0xF << LS_NPORT_NSAID_SHIFT));
+	nprot_nsaid |= ((TZC_NSAID_DISP1 << W_NPROT_NSAID_SHIFT) |
+			(TZC_NSAID_DISP0 << LS_NPORT_NSAID_SHIFT));
+	mmio_write_32(MALI_DP_BASE + DP_NPROT_NSAID_OFFSET, nprot_nsaid);
+}
+
+void plat_arm_security_setup(void)
+{
+	unsigned int i;
+	unsigned int part_num = GET_PLAT_PART_NUM;
+
+	INFO("part_num: 0x%x\n", part_num);
+
+	/*
+	 * Initialise plat_driver_data with platform specific DMC_BASE
+	 * addresses
+	 */
+	switch (part_num) {
+	case SGM775_SSC_VER_PART_NUM:
+		for (i = 0; i < SGM775_DMC_COUNT; i++)
+			plat_driver_data.dmc_base[i] = PLAT_ARM_TZC_BASE
+					+ SGM_DMC_SIZE * i;
+		plat_driver_data.dmc_count = SGM775_DMC_COUNT;
+		break;
+	default:
+		/* Unexpected platform */
+		ERROR("Unexpected platform\n");
+		panic();
+	}
+	/* Initialize the TrustZone Controller in DMC-500 */
+	arm_tzc_dmc500_setup(&plat_driver_data, NULL);
+
+	/* Do DP NSAID setup */
+	plat_sgm_dp_security_setup();
+	/* Do ARM CSS SoC security setup */
+	soc_css_security_setup();
+}
diff --git a/plat/arm/css/sgm/sgm_topology.c b/plat/arm/css/sgm/sgm_topology.c
new file mode 100644
index 0000000..ce72464
--- /dev/null
+++ b/plat/arm/css/sgm/sgm_topology.c
@@ -0,0 +1,32 @@
+/*
+ * Copyright (c) 2018, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <plat_arm.h>
+#include <sgm_plat_config.h>
+
+/*******************************************************************************
+ * This function returns the topology tree information.
+ ******************************************************************************/
+const unsigned char *plat_get_power_domain_tree_desc(void)
+{
+	return get_plat_config()->topology->power_tree;
+}
+
+/*******************************************************************************
+ * This function returns the core count within the cluster corresponding to
+ * `mpidr`.
+ ******************************************************************************/
+unsigned int plat_arm_get_cluster_core_count(u_register_t mpidr)
+{
+	return get_plat_config()->topology->plat_cluster_core_count;
+}
+
+/*
+ * The array mapping platform core position (implemented by plat_my_core_pos())
+ * to the SCMI power domain ID implemented by SCP.
+ */
+const uint32_t plat_css_core_pos_to_scmi_dmn_id_map[PLATFORM_CORE_COUNT] = {
+			0, 1, 2, 3, 4, 5, 6, 7 };
diff --git a/plat/arm/css/sgm/tsp/sgm_tsp_setup.c b/plat/arm/css/sgm/tsp/sgm_tsp_setup.c
new file mode 100644
index 0000000..39bba94
--- /dev/null
+++ b/plat/arm/css/sgm/tsp/sgm_tsp_setup.c
@@ -0,0 +1,16 @@
+/*
+ * Copyright (c) 2018, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <plat_arm.h>
+#include <sgm_plat_config.h>
+
+void tsp_early_platform_setup(void)
+{
+	/* Initialize the platform configuration structure */
+	plat_config_init();
+
+	arm_tsp_early_platform_setup();
+}
diff --git a/plat/arm/css/sgm/tsp/tsp-sgm.mk b/plat/arm/css/sgm/tsp/tsp-sgm.mk
new file mode 100644
index 0000000..a9e4131
--- /dev/null
+++ b/plat/arm/css/sgm/tsp/tsp-sgm.mk
@@ -0,0 +1,11 @@
+#
+# Copyright (c) 2018, ARM Limited and Contributors. All rights reserved.
+#
+# SPDX-License-Identifier: BSD-3-Clause
+#
+
+BL32_SOURCES		+= 	${SGM_GIC_SOURCES}			\
+				${CSS_SGM_BASE}/sgm_plat_config.c	\
+				plat/arm/board/sgm/tsp/sgm_tsp_setup.c
+
+include plat/arm/common/tsp/arm_tsp.mk