Merge "TF-A AMU extension: fix detection of group 1 counters." into integration
diff --git a/docs/about/maintainers.rst b/docs/about/maintainers.rst
index 0014d3b..a628704 100644
--- a/docs/about/maintainers.rst
+++ b/docs/about/maintainers.rst
@@ -446,6 +446,15 @@
 :F: docs/plat/qemu.rst
 :F: plat/qemu/
 
+QTI platform port
+^^^^^^^^^^^^^^^^^
+:M: Saurabh Gorecha <sgorecha@codeaurora.org>
+:G: `sgorecha`_
+:M: Debasish Mandal <dmandal@codeaurora.org>
+:M: QTI TF Maintainers <qti.trustedfirmware.maintainers@codeaurora.org>
+:F: docs/plat/qti.rst
+:F: plat/qti/
+
 Raspberry Pi 3 platform port
 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 :M: Ying-Chun Liu (PaulLiu) <paul.liu@linaro.org>
@@ -614,6 +623,7 @@
 .. _remi-triplefault: https://github.com/repk
 .. _rockchip-linux: https://github.com/rockchip-linux
 .. _sandrine-bailleux-arm: https://github.com/sandrine-bailleux-arm
+.. _sgorecha: https://github.com/sgorecha
 .. _shawnguo2: https://github.com/shawnguo2
 .. _sivadur: https://github.com/sivadur
 .. _smaeul: https://github.com/smaeul
diff --git a/docs/plat/index.rst b/docs/plat/index.rst
index 6a38113..bd23410 100644
--- a/docs/plat/index.rst
+++ b/docs/plat/index.rst
@@ -28,6 +28,7 @@
    poplar
    qemu
    qemu-sbsa
+   qti
    rpi3
    rpi4
    rcar-gen3
diff --git a/docs/plat/marvell/armada/build.rst b/docs/plat/marvell/armada/build.rst
index da4ba56..6b9054c 100644
--- a/docs/plat/marvell/armada/build.rst
+++ b/docs/plat/marvell/armada/build.rst
@@ -26,7 +26,7 @@
 
        *u-boot.bin* should be used and not *u-boot-spl.bin*
 
-Set MSS/SCP image path (mandatory only for Armada80x0)
+Set MSS/SCP image path (mandatory only for A7K/8K/CN913x)
 
     .. code:: shell
 
@@ -92,22 +92,31 @@
 
 - BLE_PATH
 
-        Points to BLE (Binary ROM extension) sources folder. Only required for A8K builds.
+        Points to BLE (Binary ROM extension) sources folder.
+        Only required for A7K/8K/CN913x builds.
         The parameter is optional, its default value is ``plat/marvell/armada/a8k/common/ble``.
 
 - MV_DDR_PATH
 
-        For A7/8K, use this parameter to point to mv_ddr driver sources to allow BLE build. For A37x0,
+        For A7K/8K/CN913x, use this parameter to point to mv_ddr driver sources to allow BLE build. For A37x0,
         it is used for ddr_tool build.
 
         Usage example: MV_DDR_PATH=path/to/mv_ddr
 
-        The parameter is optional for A7/8K, when this parameter is not set, the mv_ddr
+        The parameter is optional for A7K/8K/CN913x, when this parameter is not set, the mv_ddr
         sources are expected to be located at: drivers/marvell/mv_ddr. However, the parameter
         is necessary for A37x0.
 
         For the mv_ddr source location, check the section "Tools and external components installation"
 
+- CP_NUM
+
+        Total amount of CPs (South Bridge) connected to AP. When the parameter is omitted,
+        the build uses the default number of CPs, which is a number of embedded CPs inside the
+        package: 1 or 2 depending on the SoC used. The parameter is valid for OcteonTX2 CN913x SoC
+        family (PLAT=t9130), which can have external CPs connected to the MCI ports. Valid
+        values with CP_NUM are in a range of 1 to 3.
+
 - DDR_TOPOLOGY
 
         For Armada37x0 only, the DDR topology map index/name, default is 0.
@@ -191,7 +200,8 @@
         - a70x0
         - a70x0_amc (for AMC board)
         - a80x0
-        - a80x0_mcbin (for MacciatoBin)
+        - a80x0_mcbin (for MacchiatoBin)
+        - t9130 (OcteonTX2 CN913x)
 
 Special Build Flags
 --------------------
@@ -199,7 +209,7 @@
 - PLAT_RECOVERY_IMAGE_ENABLE
     When set this option to enable secondary recovery function when build atf.
     In order to build UART recovery image this operation should be disabled for
-    a70x0 and a80x0 because of hardware limitation (boot from secondary image
+    A7K/8K/CN913x because of hardware limitation (boot from secondary image
     can interrupt UART recovery process). This MACRO definition is set in
     ``plat/marvell/armada/a8k/common/include/platform_def.h`` file.
 
diff --git a/docs/plat/marvell/armada/porting.rst b/docs/plat/marvell/armada/porting.rst
index 1723ebb..ba8736d 100644
--- a/docs/plat/marvell/armada/porting.rst
+++ b/docs/plat/marvell/armada/porting.rst
@@ -36,7 +36,7 @@
 .. note::
    For a detailed information on how CCU, IOWIN, AXI-MBUS & IOB work, please
    refer to the SoC functional spec, and under
-   ``docs/marvell/misc/mvebu-[ccu/iob/amb/io-win].txt`` files.
+   ``docs/plat/marvell/armada/misc/mvebu-[ccu/iob/amb/io-win].rst`` files.
 
 boot loader recovery (marvell_plat_config.c)
 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
@@ -110,11 +110,6 @@
     parameters need to be suited and the board designer should provide relevant
     values.
 
-    .. seealso::
-        For XFI/SFI comphy type there is procedure "rx_training" which eases
-        process of suiting some of the parameters. Please see *uboot_cmd*
-        section: rx_training.
-
     The PHY porting layer simplifies updating static values per board type,
     which are now grouped in one place.
 
diff --git a/docs/plat/qti.rst b/docs/plat/qti.rst
new file mode 100644
index 0000000..814e672
--- /dev/null
+++ b/docs/plat/qti.rst
@@ -0,0 +1,41 @@
+Qualcomm Technologies, Inc.
+===========================
+
+Trusted Firmware-A (TF-A) implements the EL3 firmware layer for QTI SC7180.
+
+
+Boot Trace
+-------------
+
+Bootrom --> BL1/BL2 --> BL31 --> BL33 --> Linux kernel
+
+BL1/2 and BL33 can currently be supplied from Coreboot + Depthcharge
+
+How to build
+------------
+
+Code Locations
+~~~~~~~~~~~~~~
+
+-  Trusted Firmware-A:
+   `link <https://git.trustedfirmware.org/TF-A/trusted-firmware-a.git>`__
+
+Build Procedure
+~~~~~~~~~~~~~~~
+
+QTI SoC expects TF-A's BL31 to get integrated with other boot software
+Coreboot, so only bl31.elf need to get build from the TF-A repository.
+
+The build command looks like
+
+    make CROSS_COMPILE=aarch64-linux-gnu- PLAT=sc7180 COREBOOT=1
+
+update value of CROSS_COMPILE argument with your cross-compilation toolchain.
+
+Additional QTISECLIB_PATH=<path to qtiseclib> can be added in build command.
+if QTISECLIB_PATH is not added in build command stub implementation of qtiseclib
+is picked. qtiseclib with stub implementation doesn't boot device. This was
+added to satisfy compilation.
+
+QTISELIB for SC7180 is available at
+`link <https://review.coreboot.org/cgit/qc_blobs.git/plain/sc7180/qtiseclib/libqtisec.a>`__
diff --git a/include/drivers/marvell/mochi/cp110_setup.h b/include/drivers/marvell/mochi/cp110_setup.h
index f8cd26b..11dc4e0 100644
--- a/include/drivers/marvell/mochi/cp110_setup.h
+++ b/include/drivers/marvell/mochi/cp110_setup.h
@@ -24,6 +24,7 @@
 #define MVEBU_3900_DEV_ID		(0x6025)
 #define MVEBU_80X0_DEV_ID		(0x8040)
 #define MVEBU_80X0_CP115_DEV_ID		(0x8045)
+#define MVEBU_CN9130_DEV_ID		(0x7025)
 #define MVEBU_CP110_SA_DEV_ID		(0x110)
 #define MVEBU_CP110_REF_ID_A1		1
 #define MVEBU_CP110_REF_ID_A2		2
diff --git a/include/plat/arm/common/arm_reclaim_init.ld.S b/include/plat/arm/common/arm_reclaim_init.ld.S
index 03976f3..e4d4f12 100644
--- a/include/plat/arm/common/arm_reclaim_init.ld.S
+++ b/include/plat/arm/common/arm_reclaim_init.ld.S
@@ -13,8 +13,6 @@
             . = ALIGN(PAGE_SIZE);
             __INIT_CODE_START__ = .;
 	    *(*text.init*);
-            __INIT_CODE_UNALIGNED__ = .;
-            .  = ALIGN(PAGE_SIZE);
             __INIT_CODE_END__ = .;
         } >RAM
 
@@ -42,6 +40,7 @@
 	/* Offset mask */						\
 	MASK = ABS(SIGN >> 63) - 1;					\
 	. +=  ABS(OFFSET) & ABS(MASK);					\
+	.  = ALIGN(PAGE_SIZE);						\
 	__STACKS_END__ = .;						\
 	/* Total stack size */						\
 	SIZE = ABS(. - __STACKS_START__);				\
diff --git a/plat/arm/common/arm_bl31_setup.c b/plat/arm/common/arm_bl31_setup.c
index 58ccf0e..fc238b1 100644
--- a/plat/arm/common/arm_bl31_setup.c
+++ b/plat/arm/common/arm_bl31_setup.c
@@ -46,7 +46,10 @@
 					MT_MEMORY | MT_RW | MT_SECURE)
 #if RECLAIM_INIT_CODE
 IMPORT_SYM(unsigned long, __INIT_CODE_START__, BL_INIT_CODE_BASE);
-IMPORT_SYM(unsigned long, __INIT_CODE_END__, BL_INIT_CODE_END);
+IMPORT_SYM(unsigned long, __INIT_CODE_END__, BL_CODE_END_UNALIGNED);
+
+#define	BL_INIT_CODE_END	((BL_CODE_END_UNALIGNED + PAGE_SIZE - 1) & \
+					~(PAGE_SIZE - 1))
 
 #define MAP_BL_INIT_CODE	MAP_REGION_FLAT(			\
 					BL_INIT_CODE_BASE,		\
diff --git a/plat/marvell/armada/a8k/a70x0/board/dram_port.c b/plat/marvell/armada/a8k/a70x0/board/dram_port.c
index 4fca7e3..355770b 100644
--- a/plat/marvell/armada/a8k/a70x0/board/dram_port.c
+++ b/plat/marvell/armada/a8k/a70x0/board/dram_port.c
@@ -46,6 +46,7 @@
 	   MV_DDR_TEMP_LOW} },		/* temperature */
 	MV_DDR_32BIT_ECC_PUP8_BUS_MASK,	/* subphys mask */
 	MV_DDR_CFG_DEFAULT,		/* ddr configuration data source */
+	NOT_COMBINED,			/* ddr twin-die combined*/
 	{ {0} },			/* raw spd data */
 	{0},				/* timing parameters */
 	{				/* electrical configuration */
diff --git a/plat/marvell/armada/a8k/a70x0_amc/board/dram_port.c b/plat/marvell/armada/a8k/a70x0_amc/board/dram_port.c
index aecf6c5..9c8c97e 100644
--- a/plat/marvell/armada/a8k/a70x0_amc/board/dram_port.c
+++ b/plat/marvell/armada/a8k/a70x0_amc/board/dram_port.c
@@ -46,6 +46,7 @@
 	   MV_DDR_TEMP_LOW} },		/* temperature */
 	MV_DDR_32BIT_ECC_PUP8_BUS_MASK,	/* subphys mask */
 	MV_DDR_CFG_DEFAULT,		/* ddr configuration data source */
+	NOT_COMBINED,			/* ddr twin-die combined*/
 	{ {0} },			/* raw spd data */
 	{0},				/* timing parameters */
 	{				/* electrical configuration */
diff --git a/plat/marvell/armada/a8k/a80x0/board/dram_port.c b/plat/marvell/armada/a8k/a80x0/board/dram_port.c
index 017d8a7..381c871 100644
--- a/plat/marvell/armada/a8k/a80x0/board/dram_port.c
+++ b/plat/marvell/armada/a8k/a80x0/board/dram_port.c
@@ -58,6 +58,7 @@
 	MV_DDR_64BIT_ECC_PUP8_BUS_MASK, /* subphys mask */
 #endif
 	MV_DDR_CFG_SPD,			/* ddr configuration data source */
+	NOT_COMBINED,			/* ddr twin-die combined*/
 	{ {0} },			/* raw spd data */
 	{0},				/* timing parameters */
 	{				/* electrical configuration */
diff --git a/plat/marvell/armada/a8k/a80x0_mcbin/board/dram_port.c b/plat/marvell/armada/a8k/a80x0_mcbin/board/dram_port.c
index 2580852..50a68b3 100644
--- a/plat/marvell/armada/a8k/a80x0_mcbin/board/dram_port.c
+++ b/plat/marvell/armada/a8k/a80x0_mcbin/board/dram_port.c
@@ -48,6 +48,7 @@
 	   MV_DDR_TEMP_LOW} },		/* temperature */
 	   MV_DDR_64BIT_BUS_MASK,	/* subphys mask */
 	   MV_DDR_CFG_SPD,		/* ddr configuration data source */
+	NOT_COMBINED,			/* ddr twin-die combined*/
 	{ {0} },			/* raw spd data */
 	{0},				/* timing parameters */
 	{				/* electrical configuration */
diff --git a/plat/marvell/armada/a8k/a80x0_puzzle/board/dram_port.c b/plat/marvell/armada/a8k/a80x0_puzzle/board/dram_port.c
index 46a9a26..3879c98 100644
--- a/plat/marvell/armada/a8k/a80x0_puzzle/board/dram_port.c
+++ b/plat/marvell/armada/a8k/a80x0_puzzle/board/dram_port.c
@@ -54,6 +54,7 @@
 	   MV_DDR_TEMP_LOW} },		/* temperature */
 	   MV_DDR_64BIT_BUS_MASK,	/* subphys mask */
 	   MV_DDR_CFG_SPD,		/* ddr configuration data source */
+	NOT_COMBINED,			/* ddr twin-die combined*/
 	{ {0} },			/* raw spd data */
 	{0},				/* timing parameters */
 	{				/* electrical configuration */
diff --git a/plat/marvell/armada/a8k/common/mss/mss_bl2_setup.c b/plat/marvell/armada/a8k/common/mss/mss_bl2_setup.c
index c2cd933..b919cb3 100644
--- a/plat/marvell/armada/a8k/common/mss/mss_bl2_setup.c
+++ b/plat/marvell/armada/a8k/common/mss/mss_bl2_setup.c
@@ -138,6 +138,8 @@
 	if (revision == MVEBU_80X0_DEV_ID ||
 	    revision == MVEBU_80X0_CP115_DEV_ID)
 		return 2;
+	else if (revision == MVEBU_CN9130_DEV_ID)
+		return CP_COUNT;
 	else
 		return 1;
 }
diff --git a/plat/marvell/armada/a8k/common/plat_ble_setup.c b/plat/marvell/armada/a8k/common/plat_ble_setup.c
index f11b5ac..e4e09fb 100644
--- a/plat/marvell/armada/a8k/common/plat_ble_setup.c
+++ b/plat/marvell/armada/a8k/common/plat_ble_setup.c
@@ -74,22 +74,9 @@
 					 (0x24 << AVS_LOW_VDD_LIMIT_OFFSET) | \
 					 (0x1 << AVS_SOFT_RESET_OFFSET) | \
 					 (0x1 << AVS_ENABLE_OFFSET))
-/* VDD limit is 0.82V for all A3900 devices
- * AVS offsets are not the same as in A70x0
- */
-#define AVS_A3900_CLK_VALUE		((0x80u << 24) | \
-					 (0x2c2 << 13) | \
-					 (0x2c2 << 3) | \
-					 (0x1 << AVS_SOFT_RESET_OFFSET) | \
-					 (0x1 << AVS_ENABLE_OFFSET))
-/* VDD is 0.88V for 2GHz clock */
-#define AVS_A3900_HIGH_CLK_VALUE	((0x80u << 24) | \
-					 (0x2f5 << 13) | \
-					 (0x2f5 << 3) | \
-					 (0x1 << AVS_SOFT_RESET_OFFSET) | \
-					 (0x1 << AVS_ENABLE_OFFSET))
 
-#define AVS_CN9130_HIGH_CLK_VALUE	((0x80 << 24) | \
+/* VDD is 0.88V for 2GHz clock on CN913x devices */
+#define AVS_AP807_CLK_VALUE		((0x80UL << 24) | \
 					 (0x2dc << 13) | \
 					 (0x2dc << 3) | \
 					 (0x1 << AVS_SOFT_RESET_OFFSET) | \
@@ -123,7 +110,6 @@
 #define EFUSE_AP_LD0_REVID_MASK		0xF
 #define EFUSE_AP_LD0_BIN_OFFS		16		/* LD0[80:79] */
 #define EFUSE_AP_LD0_BIN_MASK		0x3
-#define EFUSE_AP_LD0_SWREV_OFFS		50		/* LD0[115:113] */
 #define EFUSE_AP_LD0_SWREV_MASK		0x7
 
 #ifndef MVEBU_SOC_AP807
@@ -137,16 +123,18 @@
 	#define EFUSE_AP_LD0_SVC2_OFFS		26	/* LD0[96:89] */
 	#define EFUSE_AP_LD0_SVC3_OFFS		34	/* LD0[104:97] */
 	#define EFUSE_AP_LD0_WP_MASK		0xFF
+	#define EFUSE_AP_LD0_SWREV_OFFS		50	/* LD0[115:113] */
 #else
 	/* AP807 AVS work points in the LD0 eFuse
 	 * SVC1 work point:     LD0[91:81]
 	 * SVC2 work point:     LD0[102:92]
 	 * SVC3 work point:     LD0[113:103]
 	 */
-	#define EFUSE_AP_LD0_SVC1_OFFS		17	/* LD0[91:81] */
-	#define EFUSE_AP_LD0_SVC2_OFFS		28	/* LD0[102:92] */
-	#define EFUSE_AP_LD0_SVC3_OFFS		39	/* LD0[113:103] */
-	#define EFUSE_AP_LD0_WP_MASK		0x3FF
+	#define EFUSE_AP_LD0_SVC1_OFFS		18	/* LD0[91:81] */
+	#define EFUSE_AP_LD0_SVC2_OFFS		29	/* LD0[102:92] */
+	#define EFUSE_AP_LD0_SVC3_OFFS		40	/* LD0[113:103] */
+	#define EFUSE_AP_LD0_WP_MASK		0x7FF	/* 10 data,1 parity */
+	#define EFUSE_AP_LD0_SWREV_OFFS		51	/* LD0[116:114] */
 #endif
 
 #define EFUSE_AP_LD0_SVC4_OFFS			42	/* LD0[112:105] */
@@ -229,19 +217,8 @@
 						 FREQ_MODE_AP_SAR_REG_NUM)));
 	/* Check which SoC is running and act accordingly */
 	if (ble_get_ap_type() == CHIP_ID_AP807) {
-		/* Increase CPU voltage for higher CPU clock */
-		switch (freq_mode) {
-		case CPU_2000_DDR_1200_RCLK_1200:
-			avs_val = AVS_A3900_HIGH_CLK_VALUE;
-			break;
-#ifdef MVEBU_SOC_AP807
-		case CPU_2200_DDR_1200_RCLK_1200:
-			avs_val = AVS_CN9130_HIGH_CLK_VALUE;
-			break;
-#endif
-		default:
-			avs_val = AVS_A3900_CLK_VALUE;
-		}
+
+		avs_val = AVS_AP807_CLK_VALUE;
 
 	} else {
 		/* Check which SoC is running and act accordingly */
@@ -396,6 +373,7 @@
 	uint64_t efuse;
 	uint32_t device_id, single_cluster;
 	uint16_t  svc[4], perr[4], i, sw_ver;
+	uint8_t	 avs_data_bits, min_sw_ver, svc_fields;
 	unsigned int ap_type;
 
 	/* Set access to LD0 */
@@ -449,22 +427,28 @@
 			 & EFUSE_AP_LD0_WP_MASK;
 		INFO("SVC: Efuse WP: [0]=0x%x, [1]=0x%x, [2]=0x%x, [3]=0x%x\n",
 		     svc[0], svc[1], svc[2], svc[3]);
+		avs_data_bits = 7;
+		min_sw_ver = 2; /* parity check from sw revision 2 */
+		svc_fields = 4;
 	} else {
 		INFO("SVC: Efuse WP: [0]=0x%x, [1]=0x%x, [2]=0x%x\n",
 		     svc[0], svc[1], svc[2]);
+		avs_data_bits = 10;
+		min_sw_ver = 1; /* parity check required from sw revision 1 */
+		svc_fields = 3;
 	}
 
 	/* Validate parity of SVC workpoint values */
-	for (i = 0; i < 4; i++) {
+	for (i = 0; i < svc_fields; i++) {
 		uint8_t parity, bit;
-
 		perr[i] = 0;
 
-		for (bit = 1, parity = svc[i] & 1; bit < 7; bit++)
+		for (bit = 1, parity = (svc[i] & 1); bit < avs_data_bits; bit++)
 			parity ^= (svc[i] >> bit) & 1;
 
-		/* Starting from SW version 2, the parity check is mandatory */
-		if ((sw_ver > 1) && (parity != ((svc[i] >> 7) & 1)))
+		/* From SW version 1 or 2 (AP806/AP807), check parity */
+		if ((sw_ver >= min_sw_ver) &&
+		    (parity != ((svc[i] >> avs_data_bits) & 1)))
 			perr[i] = 1; /* register the error */
 	}
 
@@ -554,8 +538,19 @@
 				if (perr[0])
 					goto perror;
 				avs_workpoint = svc[0];
-			} else
-				avs_workpoint = 0;
+			} else {
+#if MARVELL_SVC_TEST
+				reg_val = mmio_read_32(AVS_EN_CTRL_REG);
+				avs_workpoint = (reg_val &
+					AVS_VDD_LOW_LIMIT_MASK) >>
+					AVS_LOW_VDD_LIMIT_OFFSET;
+				NOTICE("7040 1600Mhz, avs = 0x%x\n",
+					avs_workpoint);
+#else
+				NOTICE("SVC: AVS work point not changed\n");
+				return;
+#endif
+			}
 			break;
 		}
 	} else if (device_id == MVEBU_3900_DEV_ID) {
@@ -578,6 +573,31 @@
 			avs_workpoint = svc[0];
 			break;
 		}
+	} else if (device_id == MVEBU_CN9130_DEV_ID) {
+		NOTICE("SVC: DEV ID: %s, FREQ Mode: 0x%x\n",
+		       "CN913x", freq_pidi_mode);
+		switch (freq_pidi_mode) {
+		case CPU_2200_DDR_1200_RCLK_1200:
+			if (perr[0])
+				goto perror;
+			avs_workpoint = svc[0];
+			break;
+		case CPU_2000_DDR_1200_RCLK_1200:
+			if (perr[1])
+				goto perror;
+			avs_workpoint = svc[1];
+			break;
+		case CPU_1600_DDR_1200_RCLK_1200:
+			if (perr[2])
+				goto perror;
+			avs_workpoint = svc[2];
+			break;
+		default:
+			ERROR("SVC: Unsupported Frequency 0x%x\n",
+				freq_pidi_mode);
+			return;
+
+		}
 	} else {
 		ERROR("SVC: Unsupported Device ID 0x%x\n", device_id);
 		return;
@@ -585,13 +605,17 @@
 
 	/* Set AVS control if needed */
 	if (avs_workpoint == 0) {
-		ERROR("SVC: AVS work point not changed\n");
+		ERROR("SVC: You are using a frequency setup which is\n");
+		ERROR("Not supported by this device\n");
+		ERROR("This may result in malfunction of the device\n");
 		return;
 	}
 
 	/* Remove parity bit */
 	if (ap_type != CHIP_ID_AP807)
 		avs_workpoint &= 0x7F;
+	else
+		avs_workpoint &= 0x3FF;
 
 	/* Update WP from EEPROM if needed */
 	avs_workpoint = avs_update_from_eeprom(avs_workpoint);
diff --git a/plat/marvell/octeontx/otx2/t91/t9130/board/dram_port.c b/plat/marvell/octeontx/otx2/t91/t9130/board/dram_port.c
new file mode 100644
index 0000000..0befadf
--- /dev/null
+++ b/plat/marvell/octeontx/otx2/t91/t9130/board/dram_port.c
@@ -0,0 +1,158 @@
+/*
+ * Copyright (C) 2018 Marvell International Ltd.
+ *
+ * SPDX-License-Identifier:	BSD-3-Clause
+ * https://spdx.org/licenses
+ */
+
+#include <arch_helpers.h>
+#include <common/debug.h>
+#include <drivers/mentor/mi2cv.h>
+#include <lib/mmio.h>
+
+#include <mv_ddr_if.h>
+#include <mvebu_def.h>
+#include <plat_marvell.h>
+
+#define MVEBU_CP_MPP_CTRL37_OFFS		20
+#define MVEBU_CP_MPP_CTRL38_OFFS		24
+#define MVEBU_CP_MPP_CTRL37_I2C0_SCK_ENA	0x2
+#define MVEBU_CP_MPP_CTRL38_I2C0_SDA_ENA	0x2
+
+#define MVEBU_MPP_CTRL_MASK			0xf
+
+/*
+ * This struct provides the DRAM training code with
+ * the appropriate board DRAM configuration
+ */
+struct mv_ddr_iface dram_iface_ap0 = {
+	.ap_base = MVEBU_REGS_BASE_AP(0),
+	.state = MV_DDR_IFACE_NRDY,
+	.validation = MV_DDR_MEMORY_CHECK,
+	.sscg = SSCG_EN,
+	.id = 0,
+	.iface_base_addr = 0,
+	.tm = {
+		DEBUG_LEVEL_ERROR,
+		0x1, /* active interfaces */
+		/* cs_mask, mirror, dqs_swap, ck_swap X subphys */
+		{ { { {0x1, 0x0, 0, 0},
+		      {0x1, 0x0, 0, 0},
+		      {0x1, 0x0, 0, 0},
+		      {0x1, 0x0, 0, 0},
+		      {0x1, 0x0, 0, 0},
+		      {0x1, 0x0, 0, 0},
+		      {0x1, 0x0, 0, 0},
+		      {0x1, 0x0, 0, 0},
+		      {0x1, 0x0, 0, 0} },
+		   SPEED_BIN_DDR_2400T,		/* speed_bin */
+		   MV_DDR_DEV_WIDTH_8BIT,	/* sdram device width */
+		   MV_DDR_DIE_CAP_8GBIT,	/* die capacity */
+		   MV_DDR_FREQ_SAR,		/* frequency */
+		   0, 0,			/* cas_l, cas_wl */
+		   MV_DDR_TEMP_LOW} },		/* temperature */
+#if DDR32
+		MV_DDR_32BIT_ECC_PUP8_BUS_MASK,	/* subphys mask */
+#else
+		MV_DDR_64BIT_ECC_PUP8_BUS_MASK,	/* subphys mask */
+#endif
+		MV_DDR_CFG_SPD,			/* ddr configuration data src */
+		NOT_COMBINED,			/* ddr twin-die combined*/
+		{ {0} },			/* raw spd data */
+		{0},				/* timing parameters */
+		{	/* electrical configuration */
+			{	/* memory electrical configuration */
+				MV_DDR_RTT_NOM_PARK_RZQ_DISABLE,  /* rtt_nom */
+				{	/* rtt_park 1cs */
+					MV_DDR_RTT_NOM_PARK_RZQ_DIV4,
+					/* rtt_park 2cs */
+					MV_DDR_RTT_NOM_PARK_RZQ_DIV1
+				},
+				{	/* rtt_wr 1cs */
+					MV_DDR_RTT_WR_DYN_ODT_OFF,
+					/* rtt_wr 2cs */
+					MV_DDR_RTT_WR_RZQ_DIV2
+				},
+				MV_DDR_DIC_RZQ_DIV7	/* dic */
+			},
+			{	/* phy electrical configuration */
+				MV_DDR_OHM_30,	/* data_drv_p */
+				MV_DDR_OHM_30,	/* data_drv_n */
+				MV_DDR_OHM_30,	/* ctrl_drv_p */
+				MV_DDR_OHM_30,	/* ctrl_drv_n */
+				{
+					MV_DDR_OHM_60,	/* odt_p 1cs */
+					MV_DDR_OHM_120	/* odt_p 2cs */
+				},
+				{
+					MV_DDR_OHM_60,	/* odt_n 1cs */
+					MV_DDR_OHM_120	/* odt_n 2cs */
+				},
+			},
+			{	/* mac electrical configuration */
+				MV_DDR_ODT_CFG_NORMAL,	/* odtcfg_pattern */
+				MV_DDR_ODT_CFG_ALWAYS_ON,/* odtcfg_write */
+				MV_DDR_ODT_CFG_NORMAL	/* odtcfg_read */
+			},
+		},
+	},
+};
+
+/* Pointer to the first DRAM interface in the system */
+struct mv_ddr_iface *ptr_iface = &dram_iface_ap0;
+
+struct mv_ddr_iface *mv_ddr_iface_get(void)
+{
+	/* Return current ddr interface */
+	return ptr_iface;
+}
+
+struct mv_ddr_topology_map *mv_ddr_topology_map_get(void)
+{
+	/* Return the board topology as defined in the board code */
+	return &ptr_iface->tm;
+}
+
+static void mpp_config(void)
+{
+	uintptr_t reg;
+	uint32_t val;
+
+	reg = MVEBU_CP_MPP_REGS(0, 4);
+	/* configure CP0 MPP 37 and 38 to i2c */
+	val = mmio_read_32(reg);
+	val &= ~((MVEBU_MPP_CTRL_MASK << MVEBU_CP_MPP_CTRL37_OFFS) |
+		(MVEBU_MPP_CTRL_MASK << MVEBU_CP_MPP_CTRL38_OFFS));
+	val |= (MVEBU_CP_MPP_CTRL37_I2C0_SCK_ENA <<
+			MVEBU_CP_MPP_CTRL37_OFFS) |
+		(MVEBU_CP_MPP_CTRL38_I2C0_SDA_ENA <<
+			MVEBU_CP_MPP_CTRL38_OFFS);
+	mmio_write_32(reg, val);
+}
+
+/*
+ * This function may modify the default DRAM parameters
+ * based on information received from SPD or bootloader
+ * configuration located on non volatile storage
+ */
+void plat_marvell_dram_update_topology(void)
+{
+	struct mv_ddr_topology_map *tm = mv_ddr_topology_map_get();
+
+	INFO("Gathering DRAM information\n");
+
+	if (tm->cfg_src == MV_DDR_CFG_SPD) {
+		/* configure MPPs to enable i2c */
+		mpp_config();
+
+		/* initialize i2c */
+		i2c_init((void *)MVEBU_CP0_I2C_BASE);
+
+		/* select SPD memory page 0 to access DRAM configuration */
+		i2c_write(I2C_SPD_P0_ADDR, 0x0, 1, tm->spd_data.all_bytes, 1);
+
+		/* read data from spd */
+		i2c_read(I2C_SPD_ADDR, 0x0, 1, tm->spd_data.all_bytes,
+			 sizeof(tm->spd_data.all_bytes));
+	}
+}
diff --git a/plat/marvell/octeontx/otx2/t91/t9130/board/marvell_plat_config.c b/plat/marvell/octeontx/otx2/t91/t9130/board/marvell_plat_config.c
new file mode 100644
index 0000000..7debd65
--- /dev/null
+++ b/plat/marvell/octeontx/otx2/t91/t9130/board/marvell_plat_config.c
@@ -0,0 +1,188 @@
+/*
+ * Copyright (C) 2018 Marvell International Ltd.
+ *
+ * SPDX-License-Identifier:	BSD-3-Clause
+ * https://spdx.org/licenses
+ */
+
+#include <armada_common.h>
+#include <mvebu_def.h>
+
+/*
+ * If bootrom is currently at BLE there's no need to include the memory
+ * maps structure at this point
+ */
+#ifndef IMAGE_BLE
+
+/*****************************************************************************
+ * AMB Configuration
+ *****************************************************************************
+ */
+struct addr_map_win amb_memory_map_cp0[] = {
+	/* CP0 SPI1 CS0 Direct Mode access */
+	{0xe800,	0x2000000,	AMB_SPI1_CS0_ID},
+};
+
+int marvell_get_amb_memory_map(struct addr_map_win **win, uint32_t *size,
+			       uintptr_t base)
+{
+	switch (base) {
+	case MVEBU_CP_REGS_BASE(0):
+		*win = amb_memory_map_cp0;
+		*size = ARRAY_SIZE(amb_memory_map_cp0);
+		return 0;
+	case MVEBU_CP_REGS_BASE(1):
+	case MVEBU_CP_REGS_BASE(2):
+	default:
+		*size = 0;
+		*win = 0;
+		return 1;
+	}
+}
+#endif
+
+/*****************************************************************************
+ * IO WIN Configuration
+ *****************************************************************************
+ */
+struct addr_map_win io_win_memory_map[] = {
+#ifndef IMAGE_BLE
+	/* SB (MCi0) PCIe0-2 on CP1 */
+	{0x00000000e2000000,		0x3000000,	MCI_0_TID},
+	/* SB (MCi1) PCIe0-2 on CP2 */
+	{0x00000000e5000000,		0x3000000,	MCI_1_TID},
+	/* SB (MCi0) internal regs */
+	{0x00000000f4000000,		0x2000000,	MCI_0_TID},
+	/* SB (MCi1) internal regs */
+	{0x00000000f6000000,		0x2000000,	MCI_1_TID},
+	/* MCI 0 indirect window */
+	{MVEBU_MCI_REG_BASE_REMAP(0),	0x100000,	MCI_0_TID},
+	/* MCI 1 indirect window */
+	{MVEBU_MCI_REG_BASE_REMAP(1),	0x100000,	MCI_1_TID},
+#endif
+};
+
+/* Global Control Register - window default target */
+uint32_t marvell_get_io_win_gcr_target(int ap_index)
+{
+	/*
+	 * PIDI == iMCIP AP to SB internal MoChi connection.
+	 * In other words CP0
+	 */
+	return PIDI_TID;
+}
+
+int marvell_get_io_win_memory_map(int ap_index, struct addr_map_win **win,
+				  uint32_t *size)
+{
+	*win = io_win_memory_map;
+	if (*win == NULL)
+		*size = 0;
+	else
+		*size = ARRAY_SIZE(io_win_memory_map);
+
+	return 0;
+}
+
+#ifndef IMAGE_BLE
+/*****************************************************************************
+ * IOB Configuration
+ *****************************************************************************
+ */
+struct addr_map_win iob_memory_map_cp0[] = {
+	/* SPI1_CS0 (RUNIT) window */
+	{0x00000000e8000000,	0x2000000,	RUNIT_TID},
+	/* PEX2_X1 window */
+	{0x00000000e1000000,	0x1000000,	PEX2_TID},
+	/* PEX1_X1 window */
+	{0x00000000e0000000,	0x1000000,	PEX1_TID},
+	/* PEX0_X4 window */
+	{0x00000000c0000000,	0x20000000,	PEX0_TID},
+};
+
+struct addr_map_win iob_memory_map_cp1[] = {
+
+	/* PEX2_X1 window */
+	{0x00000000e4000000,	0x1000000,	PEX2_TID},
+	/* PEX1_X1 window */
+	{0x00000000e3000000,	0x1000000,	PEX1_TID},
+	/* PEX0_X4 window */
+	{0x00000000e2000000,	0x1000000,	PEX0_TID},
+};
+
+struct addr_map_win iob_memory_map_cp2[] = {
+
+	/* PEX2_X1 window */
+	{0x00000000e7000000,	0x1000000,	PEX2_TID},
+	/* PEX1_X1 window */
+	{0x00000000e6000000,	0x1000000,	PEX1_TID},
+	/* PEX0_X4 window */
+	{0x00000000e5000000,	0x1000000,	PEX0_TID},
+};
+
+int marvell_get_iob_memory_map(struct addr_map_win **win, uint32_t *size,
+			       uintptr_t base)
+{
+	switch (base) {
+	case MVEBU_CP_REGS_BASE(0):
+		*win = iob_memory_map_cp0;
+		*size = ARRAY_SIZE(iob_memory_map_cp0);
+		return 0;
+	case MVEBU_CP_REGS_BASE(1):
+		*win = iob_memory_map_cp1;
+		*size = ARRAY_SIZE(iob_memory_map_cp1);
+		return 0;
+	case MVEBU_CP_REGS_BASE(2):
+		*win = iob_memory_map_cp2;
+		*size = ARRAY_SIZE(iob_memory_map_cp2);
+		return 0;
+	default:
+		*size = 0;
+		*win = 0;
+		return 1;
+	}
+}
+#endif
+
+/*****************************************************************************
+ * CCU Configuration
+ *****************************************************************************
+ */
+struct addr_map_win ccu_memory_map[] = {	/* IO window */
+#ifdef IMAGE_BLE
+	{0x00000000f2000000,	0x6000000,	IO_0_TID}, /* IO window */
+#else
+#if LLC_SRAM
+	{PLAT_MARVELL_LLC_SRAM_BASE, PLAT_MARVELL_LLC_SRAM_SIZE, DRAM_0_TID},
+#endif
+	{0x00000000f2000000,	0xe000000,	IO_0_TID}, /* IO window */
+	{0x00000000c0000000,	0x30000000,	IO_0_TID}, /* IO window */
+	{0x0000002000000000,	0x70e000000,	IO_0_TID}, /* IO for CV-OS */
+#endif
+};
+
+uint32_t marvell_get_ccu_gcr_target(int ap)
+{
+	return DRAM_0_TID;
+}
+
+int marvell_get_ccu_memory_map(int ap_index, struct addr_map_win **win,
+			       uint32_t *size)
+{
+	*win = ccu_memory_map;
+	*size = ARRAY_SIZE(ccu_memory_map);
+
+	return 0;
+}
+
+#ifdef IMAGE_BLE
+/*****************************************************************************
+ * SKIP IMAGE Configuration
+ *****************************************************************************
+ */
+void *plat_get_skip_image_data(void)
+{
+	/* No recovery button on CN-9130 board? */
+	return NULL;
+}
+#endif
diff --git a/plat/marvell/octeontx/otx2/t91/t9130/board/phy-porting-layer.h b/plat/marvell/octeontx/otx2/t91/t9130/board/phy-porting-layer.h
new file mode 100644
index 0000000..a866055
--- /dev/null
+++ b/plat/marvell/octeontx/otx2/t91/t9130/board/phy-porting-layer.h
@@ -0,0 +1,138 @@
+/*
+ * Copyright (C) 2018 Marvell International Ltd.
+ *
+ * SPDX-License-Identifier:     BSD-3-Clause
+ * https://spdx.org/licenses
+ */
+
+#ifndef __PHY_PORTING_LAYER_H
+#define __PHY_PORTING_LAYER_H
+
+
+#define MAX_LANE_NR		6
+#define XFI_PARAMS static const struct xfi_params
+
+
+XFI_PARAMS xfi_static_values_tab[AP_NUM][CP_NUM][MAX_LANE_NR] = {
+	/* AP0 */
+	{
+		/* CP 0 */
+		{
+			{ 0 }, /* Comphy0 not relevant*/
+			{ 0 }, /* Comphy1 not relevant*/
+			{ .g1_ffe_res_sel = 0x3, .g1_ffe_cap_sel = 0xf,
+					.align90 = 0x5f,
+				.g1_dfe_res = 0x2, .g1_amp = 0x1c,
+				.g1_emph = 0xe,
+				.g1_emph_en = 0x1, .g1_tx_amp_adj = 0x1,
+				.g1_tx_emph_en = 0x1,
+				.g1_tx_emph = 0x0, .g1_rx_selmuff = 0x1,
+				.g1_rx_selmufi = 0x0,
+				.g1_rx_selmupf = 0x2, .g1_rx_selmupi = 0x2,
+				.valid = 1 }, /* Comphy2 */
+			{ 0 }, /* Comphy3 not relevant*/
+			{ .g1_ffe_res_sel = 0x3, .g1_ffe_cap_sel = 0xf,
+					.align90 = 0x5f,
+				.g1_dfe_res = 0x2, .g1_amp = 0x1c,
+				.g1_emph = 0xe,
+				.g1_emph_en = 0x1, .g1_tx_amp_adj = 0x1,
+				.g1_tx_emph_en = 0x1,
+				.g1_tx_emph = 0x0, .g1_rx_selmuff = 0x1,
+				.g1_rx_selmufi = 0x0,
+				.g1_rx_selmupf = 0x2, .g1_rx_selmupi = 0x2,
+				.valid = 1 }, /* Comphy4 */
+			{ 0 }, /* Comphy5 not relevant*/
+		},
+#if CP_NUM > 1
+		/* CP 1 */
+		{
+			{ 0 }, /* Comphy0 not relevant*/
+			{ 0 }, /* Comphy1 not relevant*/
+			{ .g1_ffe_res_sel = 0x3, .g1_ffe_cap_sel = 0xf,
+					.align90 = 0x5f,
+				.g1_dfe_res = 0x2, .g1_amp = 0x1c,
+				.g1_emph = 0xe,
+				.g1_emph_en = 0x1, .g1_tx_amp_adj = 0x1,
+				.g1_tx_emph_en = 0x1,
+				.g1_tx_emph = 0x0, .g1_rx_selmuff = 0x1,
+				.g1_rx_selmufi = 0x0,
+				.g1_rx_selmupf = 0x2, .g1_rx_selmupi = 0x2,
+				.valid = 1 }, /* Comphy2 */
+			{ 0 }, /* Comphy3 not relevant*/
+			/* different from defaults */
+			{ .g1_ffe_res_sel = 0x3, .g1_ffe_cap_sel = 0xf,
+					.align90 = 0x5f,
+				.g1_dfe_res = 0x2, .g1_amp = 0xc,
+				.g1_emph = 0x5,
+				.g1_emph_en = 0x1, .g1_tx_amp_adj = 0x1,
+				.g1_tx_emph_en = 0x1,
+				.g1_tx_emph = 0x0, .g1_rx_selmuff = 0x1,
+				.g1_rx_selmufi = 0x0,
+				.g1_rx_selmupf = 0x2, .g1_rx_selmupi = 0x2,
+				.valid = 1}, /* Comphy4 */
+			{ 0 }, /* Comphy5 not relevant*/
+		},
+#if CP_NUM > 2
+		/* CP 2 */
+		{
+			{ 0 }, /* Comphy0 not relevant*/
+			{ 0 }, /* Comphy1 not relevant*/
+			{ .g1_ffe_res_sel = 0x3, .g1_ffe_cap_sel = 0xf,
+					.align90 = 0x5f,
+				.g1_dfe_res = 0x2, .g1_amp = 0x1c,
+				.g1_emph = 0xe,
+				.g1_emph_en = 0x1, .g1_tx_amp_adj = 0x1,
+				.g1_tx_emph_en = 0x1,
+				.g1_tx_emph = 0x0, .g1_rx_selmuff = 0x1,
+				.g1_rx_selmufi = 0x0,
+				.g1_rx_selmupf = 0x2, .g1_rx_selmupi = 0x2,
+				.valid = 1 }, /* Comphy2 */
+			{ 0 }, /* Comphy3 not relevant*/
+			{ .g1_ffe_res_sel = 0x3, .g1_ffe_cap_sel = 0xf,
+					.align90 = 0x5f,
+				.g1_dfe_res = 0x2, .g1_amp = 0x1c,
+				.g1_emph = 0xe,
+				.g1_emph_en = 0x1, .g1_tx_amp_adj = 0x1,
+				.g1_tx_emph_en = 0x1,
+				.g1_tx_emph = 0x0, .g1_rx_selmuff = 0x1,
+				.g1_rx_selmufi = 0x0,
+				.g1_rx_selmupf = 0x2, .g1_rx_selmupi = 0x2,
+				.valid = 1 }, /* Comphy4 */
+			{ 0 }, /* Comphy5 not relevant*/
+		},
+#endif
+#endif
+	},
+};
+
+#define SATA_PARAMS static const struct sata_params
+SATA_PARAMS sata_static_values_tab[AP_NUM][CP_NUM][MAX_LANE_NR] = {
+	[0 ... AP_NUM-1][0 ... CP_NUM-1][0 ... MAX_LANE_NR-1] = {
+		.g1_amp = 0x8, .g2_amp = 0xa,
+		.g3_amp = 0x1e,
+		.g1_emph = 0x1, .g2_emph = 0x2,
+		.g3_emph = 0xe,
+		.g1_emph_en = 0x1, .g2_emph_en = 0x1,
+		.g3_emph_en = 0x1,
+		.g1_tx_amp_adj = 0x1, .g2_tx_amp_adj = 0x1,
+		.g3_tx_amp_adj = 0x1,
+		.g1_tx_emph_en = 0x0, .g2_tx_emph_en = 0x0,
+		.g3_tx_emph_en = 0x0,
+		.g1_tx_emph = 0x1, .g2_tx_emph = 0x1,
+		.g3_tx_emph = 0x1,
+		.g3_dfe_res = 0x1, .g3_ffe_res_sel = 0x4,
+		.g3_ffe_cap_sel = 0xf,
+		.align90 = 0x61,
+		.g1_rx_selmuff = 0x3, .g2_rx_selmuff = 0x3,
+		.g3_rx_selmuff = 0x3,
+		.g1_rx_selmufi = 0x0, .g2_rx_selmufi = 0x0,
+		.g3_rx_selmufi = 0x3,
+		.g1_rx_selmupf = 0x1, .g2_rx_selmupf = 0x1,
+		.g3_rx_selmupf = 0x2,
+		.g1_rx_selmupi = 0x0, .g2_rx_selmupi = 0x0,
+		.g3_rx_selmupi = 0x2,
+		.valid = 0x1
+	},
+};
+
+#endif /* __PHY_PORTING_LAYER_H */
diff --git a/plat/marvell/octeontx/otx2/t91/t9130/mvebu_def.h b/plat/marvell/octeontx/otx2/t91/t9130/mvebu_def.h
new file mode 100644
index 0000000..490be73
--- /dev/null
+++ b/plat/marvell/octeontx/otx2/t91/t9130/mvebu_def.h
@@ -0,0 +1,25 @@
+/*
+ * Copyright (C) 2018 Marvell International Ltd.
+ *
+ * SPDX-License-Identifier:	BSD-3-Clause
+ * https://spdx.org/licenses
+ */
+
+#ifndef __MVEBU_DEF_H__
+#define __MVEBU_DEF_H__
+
+#include <a8k_plat_def.h>
+
+/*
+ * CN-9130 has single CP0 inside the package and 2 additional one
+ * from MoChi interface. In case of db-9130-modular board the MCI interface
+ * is routed to:
+ * - on-board CP115 (MCI0)
+ * - extension board CP115 (MCI1)
+ */
+#define CP_COUNT		CP_NUM
+#define MVEBU_SOC_AP807		1
+#define I2C_SPD_ADDR		0x53	/* Access SPD data */
+#define I2C_SPD_P0_ADDR		0x36	/* Select SPD data page 0 */
+
+#endif /* __MVEBU_DEF_H__ */
diff --git a/plat/marvell/octeontx/otx2/t91/t9130/platform.mk b/plat/marvell/octeontx/otx2/t91/t9130/platform.mk
new file mode 100644
index 0000000..1e2716d
--- /dev/null
+++ b/plat/marvell/octeontx/otx2/t91/t9130/platform.mk
@@ -0,0 +1,20 @@
+#
+# Copyright (C) 2018 Marvell International Ltd.
+#
+# SPDX-License-Identifier:	BSD-3-Clause
+# https://spdx.org/licenses
+#
+
+PCI_EP_SUPPORT		:= 0
+
+CP_NUM			:= 1
+$(eval $(call add_define,CP_NUM))
+
+DOIMAGE_SEC     	:=	tools/doimage/secure/sec_img_7K.cfg
+
+MARVELL_MOCHI_DRV	:=	drivers/marvell/mochi/ap807_setup.c
+
+BOARD_DIR		:= $(shell dirname $(lastword $(MAKEFILE_LIST)))
+include plat/marvell/armada/a8k/common/a8k_common.mk
+
+include plat/marvell/armada/common/marvell_common.mk
diff --git a/plat/qti/common/inc/aarch64/plat_macros.S b/plat/qti/common/inc/aarch64/plat_macros.S
new file mode 100644
index 0000000..2e292fb
--- /dev/null
+++ b/plat/qti/common/inc/aarch64/plat_macros.S
@@ -0,0 +1,106 @@
+/*
+ * Copyright (c) 2015-2018, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2018,2020, The Linux Foundation. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef __PLAT_MACROS_S__
+#define __PLAT_MACROS_S__
+
+#include <drivers/arm/gic_common.h>
+#include <drivers/arm/gicv2.h>
+#include <drivers/arm/gicv3.h>
+
+#include <platform_def.h>
+
+.section .rodata.gic_reg_name, "aS"
+/* Applicable only to GICv2 and GICv3 with SRE disabled (legacy mode) */
+gicc_regs:
+	.asciz "gicc_hppir", "gicc_ahppir", "gicc_ctlr", ""
+
+/* Applicable only to GICv3 with SRE enabled */
+icc_regs:
+	.asciz "icc_hppir0_el1", "icc_hppir1_el1", "icc_ctlr_el3", ""
+
+/* Registers common to both GICv2 and GICv3 */
+gicd_pend_reg:
+	.asciz "gicd_ispendr regs (Offsets 0x200 - 0x278)\n"	\
+		" Offset:\t\t\tvalue\n"
+newline:
+	.asciz "\n"
+spacer:
+	.asciz ":\t\t0x"
+
+/** Macro : plat_crash_print_regs
+ * This macro allows the crash reporting routine to print GIC registers
+ * in case of an unhandled exception in BL31. This aids in debugging and
+ * this macro can be defined to be empty in case GIC register reporting is
+ * not desired.
+ * The below required platform porting macro
+ * prints out relevant GIC registers whenever an
+ * unhandled exception is taken in BL31.
+ * Clobbers: x0 - x10, x26, x27, sp
+ * ---------------------------------------------
+ */
+	.macro plat_crash_print_regs
+print_gic_regs:
+	ldr	x26, =QTI_GICD_BASE
+	ldr	x27, =QTI_GICC_BASE
+
+	/* Check for GICv3 system register access */
+	mrs	x7, id_aa64pfr0_el1
+	ubfx	x7, x7, #ID_AA64PFR0_GIC_SHIFT, #ID_AA64PFR0_GIC_WIDTH
+	cmp	x7, #1
+	b.ne	print_gicv2
+
+	/* Check for SRE enable */
+	mrs	x8, ICC_SRE_EL3
+	tst	x8, #ICC_SRE_SRE_BIT
+	b.eq	print_gicv2
+
+	/* Load the icc reg list to x6 */
+	adr	x6, icc_regs
+	/* Load the icc regs to gp regs used by str_in_crash_buf_print */
+	mrs	x8, ICC_HPPIR0_EL1
+	mrs	x9, ICC_HPPIR1_EL1
+	mrs	x10, ICC_CTLR_EL3
+	/* Store to the crash buf and print to console */
+	bl	str_in_crash_buf_print
+	b	print_gic_common
+
+print_gicv2:
+	/* Load the gicc reg list to x6 */
+	adr	x6, gicc_regs
+	/* Load the gicc regs to gp regs used by str_in_crash_buf_print */
+	ldr	w8, [x27, #GICC_HPPIR]
+	ldr	w9, [x27, #GICC_AHPPIR]
+	ldr	w10, [x27, #GICC_CTLR]
+	/* Store to the crash buf and print to console */
+	bl	str_in_crash_buf_print
+
+print_gic_common:
+	/* Print the GICD_ISPENDR regs */
+	add	x7, x26, #GICD_ISPENDR
+	adr	x4, gicd_pend_reg
+	bl	asm_print_str
+gicd_ispendr_loop:
+	sub	x4, x7, x26
+	cmp	x4, #0x280
+	b.eq	exit_print_gic_regs
+	bl	asm_print_hex
+
+	adr	x4, spacer
+	bl	asm_print_str
+
+	ldr	x4, [x7], #8
+	bl	asm_print_hex
+
+	adr	x4, newline
+	bl	asm_print_str
+	b	gicd_ispendr_loop
+exit_print_gic_regs:
+
+	.endm
+
+#endif /* __PLAT_MACROS_S__ */
diff --git a/plat/qti/common/inc/qti_board_def.h b/plat/qti/common/inc/qti_board_def.h
new file mode 100644
index 0000000..4c84661
--- /dev/null
+++ b/plat/qti/common/inc/qti_board_def.h
@@ -0,0 +1,29 @@
+/*
+ * Copyright (c) 2015-2018, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2018-2020, The Linux Foundation. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+#ifndef QTI_BOARD_DEF_H
+#define QTI_BOARD_DEF_H
+
+/*
+ * Required platform porting definitions common to all ARM
+ * development platforms
+ */
+
+/* Size of cacheable stacks */
+#define PLATFORM_STACK_SIZE	0x1000
+
+/*
+ * PLAT_QTI_MMAP_ENTRIES depends on the number of entries in the
+ * plat_qti_mmap array defined for each BL stage.
+ */
+#define PLAT_QTI_MMAP_ENTRIES	12
+
+/*
+ * Platform specific page table and MMU setup constants
+ */
+#define MAX_XLAT_TABLES		12
+
+#endif /* QTI_BOARD_DEF_H */
diff --git a/plat/qti/common/inc/qti_cpu.h b/plat/qti/common/inc/qti_cpu.h
new file mode 100644
index 0000000..3eda02b
--- /dev/null
+++ b/plat/qti/common/inc/qti_cpu.h
@@ -0,0 +1,16 @@
+/*
+ * Copyright (c) 2018-2020, The Linux Foundation. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef QTI_CPU_H
+#define QTI_CPU_H
+
+/* KRYO-4xx Gold MIDR */
+#define QTI_KRYO4_GOLD_MIDR	0x517F804D
+
+/* KRYO-4xx Silver MIDR */
+#define QTI_KRYO4_SILVER_MIDR	0x517F805D
+
+#endif /* QTI_CPU_H */
diff --git a/plat/qti/common/inc/qti_interrupt_svc.h b/plat/qti/common/inc/qti_interrupt_svc.h
new file mode 100644
index 0000000..59bde86
--- /dev/null
+++ b/plat/qti/common/inc/qti_interrupt_svc.h
@@ -0,0 +1,12 @@
+/*
+ * Copyright (c) 2018,2020, The Linux Foundation. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef QTI_INTERRUPT_SVC_H
+#define QTI_INTERRUPT_SVC_H
+
+int qti_interrupt_svc_init(void);
+
+#endif /* QTI_INTERRUPT_SVC_H */
diff --git a/plat/qti/common/inc/qti_plat.h b/plat/qti/common/inc/qti_plat.h
new file mode 100644
index 0000000..0e867be
--- /dev/null
+++ b/plat/qti/common/inc/qti_plat.h
@@ -0,0 +1,53 @@
+/*
+ * Copyright (c) 2018, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2018-2020, The Linux Foundation. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef QTI_PLAT_H
+#define QTI_PLAT_H
+
+#include <stdint.h>
+
+#include <common/bl_common.h>
+#include <lib/cassert.h>
+#include <lib/el3_runtime/cpu_data.h>
+#include <lib/xlat_tables/xlat_tables_v2.h>
+
+/*
+ * Utility functions common to QTI platforms
+ */
+int qti_mmap_add_dynamic_region(uintptr_t base_pa, size_t size,
+				unsigned int attr);
+int qti_mmap_remove_dynamic_region(uintptr_t base_va, size_t size);
+
+/*
+ * Utility functions common to ARM standard platforms
+ */
+void qti_setup_page_tables(uintptr_t total_base,
+			   size_t total_size,
+			   uintptr_t code_start,
+			   uintptr_t code_limit,
+			   uintptr_t rodata_start,
+			   uintptr_t rodata_limit,
+			   uintptr_t coh_start, uintptr_t coh_limit);
+
+/*
+ * Mandatory functions required in ARM standard platforms
+ */
+void plat_qti_gic_driver_init(void);
+void plat_qti_gic_init(void);
+void plat_qti_gic_cpuif_enable(void);
+void plat_qti_gic_cpuif_disable(void);
+void plat_qti_gic_pcpu_init(void);
+
+/*
+ * Optional functions required in ARM standard platforms
+ */
+unsigned int plat_qti_core_pos_by_mpidr(u_register_t mpidr);
+unsigned int plat_qti_my_cluster_pos(void);
+
+void gic_set_spi_routing(unsigned int id, unsigned int irm, u_register_t mpidr);
+
+#endif /* QTI_PLAT_H */
diff --git a/plat/qti/common/inc/qti_uart_console.h b/plat/qti/common/inc/qti_uart_console.h
new file mode 100644
index 0000000..c5a65d6
--- /dev/null
+++ b/plat/qti/common/inc/qti_uart_console.h
@@ -0,0 +1,19 @@
+/*
+ * Copyright (c) 2017-2018, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2018,2020 The Linux Foundation. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef QTI_UART_CONSOLE_H
+#define QTI_UART_CONSOLE_H
+
+#include <drivers/console.h>
+
+#ifndef __ASSEMBLER__
+
+int qti_console_uart_register(console_t *console, uintptr_t uart_base_addr);
+
+#endif /* __ASSEMBLER__ */
+
+#endif /* QTI_UART_CONSOLE_H */
diff --git a/plat/qti/common/src/aarch64/qti_helpers.S b/plat/qti/common/src/aarch64/qti_helpers.S
new file mode 100644
index 0000000..c1ea7b3
--- /dev/null
+++ b/plat/qti/common/src/aarch64/qti_helpers.S
@@ -0,0 +1,88 @@
+/*
+ * Copyright (c) 2013-2018, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2018,2020, The Linux Foundation. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <arch.h>
+#include <asm_macros.S>
+#include <drivers/arm/gicv2.h>
+#include <drivers/arm/gicv3.h>
+#include <drivers/console.h>
+
+#include <platform_def.h>
+
+	.globl	plat_my_core_pos
+	.globl	plat_qti_core_pos_by_mpidr
+	.globl	plat_reset_handler
+	.globl	plat_panic_handler
+
+	/* -----------------------------------------------------
+	 *  unsigned int plat_qti_core_pos_by_mpidr(uint64_t mpidr)
+	 *  Helper function to calculate the core position.
+	 *  With this function:
+	 *  CorePos = (ClusterId * 4) + CoreId
+	 *  - In ARM v8   (MPIDR_EL1[24]=0)
+	 *    ClusterId = MPIDR_EL1[15:8]
+	 *    CoreId    = MPIDR_EL1[7:0]
+	 *  - In ARM v8.1 (MPIDR_EL1[24]=1)
+	 *    ClusterId = MPIDR_EL1[23:15]
+	 *    CoreId    = MPIDR_EL1[15:8]
+	 *  Clobbers: x0 & x1.
+	 * -----------------------------------------------------
+	 */
+func plat_qti_core_pos_by_mpidr
+	mrs	x1, mpidr_el1
+	tst	x1, #MPIDR_MT_MASK
+	beq	plat_qti_core_pos_by_mpidr_no_mt
+	/* Right shift mpidr by one affinity level when MT=1. */
+	lsr	x0, x0, #MPIDR_AFFINITY_BITS
+plat_qti_core_pos_by_mpidr_no_mt:
+	and	x1, x0, #MPIDR_CPU_MASK
+	and	x0, x0, #MPIDR_CLUSTER_MASK
+	add	x0, x1, x0, LSR #6
+	ret
+endfunc plat_qti_core_pos_by_mpidr
+
+	/* --------------------------------------------------------------------
+	 * void plat_panic_handler(void)
+	 * calls SDI and reset system
+	 * --------------------------------------------------------------------
+	 */
+func plat_panic_handler
+	msr	spsel, #0
+	bl	plat_set_my_stack
+	b	qtiseclib_panic
+endfunc plat_panic_handler
+
+	/* -----------------------------------------------------
+	 *  unsigned int plat_my_core_pos(void)
+	 *  This function uses the plat_qti_calc_core_pos()
+	 *  definition to get the index of the calling CPU
+	 *  Clobbers: x0 & x1.
+	 * -----------------------------------------------------
+	 */
+func plat_my_core_pos
+	mrs	x0, mpidr_el1
+	b	plat_qti_core_pos_by_mpidr
+endfunc plat_my_core_pos
+
+func plat_reset_handler
+	/* save the lr */
+	mov	x18, x30
+
+	/* Serialize CPUSS boot setup. Multi core enter simultaneously. */
+	ldr	x0, =g_qti_cpuss_boot_lock
+	bl	spin_lock
+
+	/* pass cold boot status. */
+	ldr	w0, g_qti_bl31_cold_booted
+	/* Execuete CPUSS boot set up on every core. */
+	bl	qtiseclib_cpuss_reset_asm
+
+	ldr	x0, =g_qti_cpuss_boot_lock
+	bl	spin_unlock
+
+	ret	x18
+endfunc plat_reset_handler
diff --git a/plat/qti/common/src/aarch64/qti_kryo4_gold.S b/plat/qti/common/src/aarch64/qti_kryo4_gold.S
new file mode 100644
index 0000000..a1b40c8
--- /dev/null
+++ b/plat/qti/common/src/aarch64/qti_kryo4_gold.S
@@ -0,0 +1,83 @@
+/*
+ * Copyright (c) 2015-2018, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2018-2020, The Linux Foundation. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <arch.h>
+#include <asm_macros.S>
+#include <cpu_macros.S>
+
+#include <plat_macros.S>
+#include <qti_cpu.h>
+
+	.p2align 3
+
+/* -------------------------------------------------
+ * The CPU Ops reset function for Kryo-3 Gold
+ * -------------------------------------------------
+ */
+func qti_kryo4_gold_reset_func
+#if IMAGE_BL31 && WORKAROUND_CVE_2017_5715
+	adr	x0, wa_cve_2017_5715_bpiall_vbar
+	msr	vbar_el3, x0
+	isb
+#endif
+
+	mov	x19, x30
+
+	bl	qtiseclib_kryo4_gold_reset_asm
+
+	ret	x19
+
+endfunc qti_kryo4_gold_reset_func
+
+/* ----------------------------------------------------
+ * The CPU Ops core power down function for Kryo-3 Gold
+ * ----------------------------------------------------
+ */
+func qti_kryo4_gold_core_pwr_dwn
+	ret
+endfunc qti_kryo4_gold_core_pwr_dwn
+
+/* -------------------------------------------------------
+ * The CPU Ops cluster power down function for Kryo-3 Gold
+ * -------------------------------------------------------
+ */
+func qti_kryo4_gold_cluster_pwr_dwn
+	ret
+endfunc qti_kryo4_gold_cluster_pwr_dwn
+
+#if REPORT_ERRATA
+/*
+ * Errata printing function for Kryo4 Gold. Must follow AAPCS.
+ */
+func qti_kryo4_gold_errata_report
+	/* TODO : Need to add support. Required only for debug bl31 image.*/
+	ret
+endfunc qti_kryo4_gold_errata_report
+#endif
+
+/* ---------------------------------------------
+ * This function provides kryo4_gold specific
+ * register information for crash reporting.
+ * It needs to return with x6 pointing to
+ * a list of register names in ASCII and
+ * x8 - x15 having values of registers to be
+ * reported.
+ * ---------------------------------------------
+ */
+.section .rodata.qti_kryo4_gold_regs, "aS"
+qti_kryo4_gold_regs:  /* The ASCII list of register names to be reported */
+	.asciz	""
+
+func qti_kryo4_gold_cpu_reg_dump
+	adr	x6, qti_kryo4_gold_regs
+	ret
+endfunc qti_kryo4_gold_cpu_reg_dump
+
+declare_cpu_ops	qti_kryo4_gold, QTI_KRYO4_GOLD_MIDR,	\
+		qti_kryo4_gold_reset_func,		\
+		qti_kryo4_gold_core_pwr_dwn,	\
+		qti_kryo4_gold_cluster_pwr_dwn
diff --git a/plat/qti/common/src/aarch64/qti_kryo4_silver.S b/plat/qti/common/src/aarch64/qti_kryo4_silver.S
new file mode 100644
index 0000000..183eeb0
--- /dev/null
+++ b/plat/qti/common/src/aarch64/qti_kryo4_silver.S
@@ -0,0 +1,79 @@
+/*
+ * Copyright (c) 2015-2018, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2018-2020, The Linux Foundation. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <arch.h>
+#include <asm_macros.S>
+#include <cpu_macros.S>
+
+#include <plat_macros.S>
+#include <qti_cpu.h>
+
+	.p2align 3
+
+/* -------------------------------------------------
+ * The CPU Ops reset function for Kryo-3 Silver
+ * -------------------------------------------------
+ */
+func qti_kryo4_silver_reset_func
+	mov	x19, x30
+
+	bl	qtiseclib_kryo4_silver_reset_asm
+
+	ret	x19
+
+endfunc qti_kryo4_silver_reset_func
+
+/* ------------------------------------------------------
+ * The CPU Ops core power down function for Kryo-3 Silver
+ * ------------------------------------------------------
+ */
+func qti_kryo4_silver_core_pwr_dwn
+	ret
+endfunc qti_kryo4_silver_core_pwr_dwn
+
+/* ---------------------------------------------------------
+ * The CPU Ops cluster power down function for Kryo-3 Silver
+ * ---------------------------------------------------------
+ */
+func qti_kryo4_silver_cluster_pwr_dwn
+	ret
+endfunc qti_kryo4_silver_cluster_pwr_dwn
+
+#if REPORT_ERRATA
+/*
+ * Errata printing function for Kryo4 Silver. Must follow AAPCS.
+ */
+func qti_kryo4_silver_errata_report
+	/* TODO : Need to add support. Required only for debug bl31 image.*/
+	ret
+endfunc qti_kryo4_silver_errata_report
+#endif
+
+
+/* ---------------------------------------------
+ * This function provides kryo4_silver specific
+ * register information for crash reporting.
+ * It needs to return with x6 pointing to
+ * a list of register names in ASCII and
+ * x8 - x15 having values of registers to be
+ * reported.
+ * ---------------------------------------------
+ */
+.section .rodata.qti_kryo4_silver_regs, "aS"
+qti_kryo4_silver_regs:  /* The ASCII list of register names to be reported */
+	.asciz	""
+
+func qti_kryo4_silver_cpu_reg_dump
+	adr	x6, qti_kryo4_silver_regs
+	ret
+endfunc qti_kryo4_silver_cpu_reg_dump
+
+
+declare_cpu_ops	qti_kryo4_silver, QTI_KRYO4_SILVER_MIDR,	\
+		qti_kryo4_silver_reset_func,		\
+		qti_kryo4_silver_core_pwr_dwn,		\
+		qti_kryo4_silver_cluster_pwr_dwn
diff --git a/plat/qti/common/src/aarch64/qti_uart_console.S b/plat/qti/common/src/aarch64/qti_uart_console.S
new file mode 100644
index 0000000..2eb33d9
--- /dev/null
+++ b/plat/qti/common/src/aarch64/qti_uart_console.S
@@ -0,0 +1,102 @@
+/*
+ * Copyright (c) 2017-2018, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2018,2020 The Linux Foundation. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <asm_macros.S>
+#include <console_macros.S>
+
+#include <platform_def.h>
+#include <qti_uart_console.h>
+
+/*
+ * This driver implements console logging into a ring buffer.
+ */
+
+	.globl qti_console_uart_register
+
+	/* -----------------------------------------------
+	 * int qti_console_uart_register(console_t *console,
+	 *				 uintptr_t uart_base_addr)
+	 * Registers uart console instance.
+	 * In:  x0 - pointer to empty console_t struct
+	 *      x1 - start address of uart block.
+	 * Out: x0 - 1 to indicate success
+	 * Clobber list: x0, x1, x14
+	 * -----------------------------------------------
+	 */
+func qti_console_uart_register
+	str	x1, [x0, #CONSOLE_T_BASE]	/* Save UART base. */
+	finish_console_register uart putc=1, flush=1
+endfunc qti_console_uart_register
+
+	/* -----------------------------------------------
+	 * int qti_console_uart_puts(int c, console_t *console)
+	 * Writes a character to the UART console.
+	 * The character must be preserved in x0.
+	 * In: x0 - character to be stored
+	 *     x1 - pointer to console_t struct
+	 * Clobber list: x1, x2
+	 * -----------------------------------------------
+	 */
+func console_uart_putc
+	/* set x1 = UART base. */
+	ldr	x1, [x1, #CONSOLE_T_BASE]
+
+	/* Loop until M_GENI_CMD_ACTIVE bit not clear. */
+1:	ldr	w2, [x1, #GENI_STATUS_REG]
+	and	w2, w2, #GENI_STATUS_M_GENI_CMD_ACTIVE_MASK
+	cmp	w2, #GENI_STATUS_M_GENI_CMD_ACTIVE_MASK
+	b.eq	1b
+
+	/* Transmit data. */
+	cmp	w0, #0xA
+	b.ne	3f
+
+	/* Add '\r' when input char is '\n' */
+	mov	w2, #0x1
+	mov	w0, #0xD
+	str	w2, [x1, #UART_TX_TRANS_LEN_REG]
+	mov	w2, #GENI_M_CMD_TX
+	str	w2, [x1, #GENI_M_CMD0_REG]
+	str	w0, [x1, #GENI_TX_FIFOn_REG]
+	mov	w0, #0xA
+
+	/* Loop until M_GENI_CMD_ACTIVE bit not clear. */
+2:	ldr	w2, [x1, #GENI_STATUS_REG]
+	and	w2, w2, #GENI_STATUS_M_GENI_CMD_ACTIVE_MASK
+	cmp	w2, #GENI_STATUS_M_GENI_CMD_ACTIVE_MASK
+	b.eq	2b
+
+	/* Transmit i/p data. */
+3:	mov	w2, #0x1
+	str	w2, [x1, #UART_TX_TRANS_LEN_REG]
+	mov	w2, #GENI_M_CMD_TX
+	str	w2, [x1, #GENI_M_CMD0_REG]
+	str	w0, [x1, #GENI_TX_FIFOn_REG]
+
+	ret
+endfunc	console_uart_putc
+
+	/* -----------------------------------------------
+	 * int qti_console_uart_flush(console_t *console)
+	 * In:  x0 - pointer to console_t struct
+	 * Out: x0 - 0 for success
+	 * Clobber list: x0, x1
+	 * -----------------------------------------------
+	 */
+func console_uart_flush
+	/* set x0 = UART base. */
+	ldr	x0, [x0, #CONSOLE_T_BASE]
+
+	/* Loop until M_GENI_CMD_ACTIVE bit not clear. */
+1:	ldr	w1, [x0, #GENI_STATUS_REG]
+	and	w1, w1, #GENI_STATUS_M_GENI_CMD_ACTIVE_MASK
+	cmp	w1, #GENI_STATUS_M_GENI_CMD_ACTIVE_MASK
+	b.eq	1b
+
+	mov	w0, #0
+	ret
+endfunc console_uart_flush
diff --git a/plat/qti/common/src/qti_bl31_setup.c b/plat/qti/common/src/qti_bl31_setup.c
new file mode 100644
index 0000000..b2bc543
--- /dev/null
+++ b/plat/qti/common/src/qti_bl31_setup.c
@@ -0,0 +1,155 @@
+/*
+ * Copyright (c) 2018, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2018-2020, The Linux Foundation. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <assert.h>
+
+#include <bl31/bl31.h>
+#include <common/debug.h>
+#include <common/desc_image_load.h>
+#include <drivers/console.h>
+#include <drivers/generic_delay_timer.h>
+#include <lib/bl_aux_params/bl_aux_params.h>
+#include <lib/coreboot.h>
+#include <lib/spinlock.h>
+
+#include <platform.h>
+#include <qti_interrupt_svc.h>
+#include <qti_plat.h>
+#include <qti_uart_console.h>
+#include <qtiseclib_interface.h>
+
+/*
+ * Placeholder variables for copying the arguments that have been passed to
+ * BL31 from BL2.
+ */
+static entry_point_info_t bl33_image_ep_info;
+
+/*
+ * Variable to hold counter frequency for the CPU's generic timer. In this
+ * platform coreboot image configure counter frequency for boot core before
+ * reaching TF-A.
+ */
+static uint64_t g_qti_cpu_cntfrq;
+
+/*
+ * Lock variable to serialize cpuss reset execution.
+ */
+spinlock_t g_qti_cpuss_boot_lock __attribute__ ((section("tzfw_coherent_mem"),
+		    aligned(CACHE_WRITEBACK_GRANULE))) = {0x0};
+
+/*
+ * Variable to hold bl31 cold boot status. Default value 0x0 means yet to boot.
+ * Any other value means cold booted.
+ */
+uint32_t g_qti_bl31_cold_booted __attribute__ ((section("tzfw_coherent_mem"))) = 0x0;
+
+/*******************************************************************************
+ * Perform any BL31 early platform setup common to ARM standard platforms.
+ * Here is an opportunity to copy parameters passed by the calling EL (S-EL1
+ * in BL2 & S-EL3 in BL1) before they are lost (potentially). This needs to be
+ * done before the MMU is initialized so that the memory layout can be used
+ * while creating page tables. BL2 has flushed this information to memory, so
+ * we are guaranteed to pick up good data.
+ ******************************************************************************/
+void bl31_early_platform_setup(u_register_t from_bl2,
+			       u_register_t plat_params_from_bl2)
+{
+
+	g_qti_cpu_cntfrq = read_cntfrq_el0();
+
+	bl_aux_params_parse(plat_params_from_bl2, NULL);
+
+#if COREBOOT
+	if (coreboot_serial.baseaddr != 0) {
+		static console_t g_qti_console_uart;
+
+		qti_console_uart_register(&g_qti_console_uart,
+					  coreboot_serial.baseaddr);
+	}
+#endif
+
+	/*
+	 * Tell BL31 where the non-trusted software image
+	 * is located and the entry state information
+	 */
+	bl31_params_parse_helper(from_bl2, NULL, &bl33_image_ep_info);
+}
+
+void bl31_early_platform_setup2(u_register_t arg0, u_register_t arg1,
+				u_register_t arg2, u_register_t arg3)
+{
+	bl31_early_platform_setup(arg0, arg1);
+}
+
+/*******************************************************************************
+ * Perform the very early platform specific architectural setup here. At the
+ * moment this only intializes the mmu in a quick and dirty way.
+ ******************************************************************************/
+void bl31_plat_arch_setup(void)
+{
+	qti_setup_page_tables(BL_CODE_BASE,
+			      BL_COHERENT_RAM_END - BL_CODE_BASE,
+			      BL_CODE_BASE,
+			      BL_CODE_END,
+			      BL_RO_DATA_BASE,
+			      BL_RO_DATA_END,
+			      BL_COHERENT_RAM_BASE, BL_COHERENT_RAM_END);
+	enable_mmu_el3(0);
+}
+
+/*******************************************************************************
+ * Perform any BL31 platform setup common to ARM standard platforms
+ ******************************************************************************/
+void bl31_platform_setup(void)
+{
+	generic_delay_timer_init();
+	/* Initialize the GIC driver, CPU and distributor interfaces */
+	plat_qti_gic_driver_init();
+	plat_qti_gic_init();
+	qti_interrupt_svc_init();
+	qtiseclib_bl31_platform_setup();
+
+	/* set boot state to cold boot complete. */
+	g_qti_bl31_cold_booted = 0x1;
+}
+
+/*******************************************************************************
+ * Return a pointer to the 'entry_point_info' structure of the next image for the
+ * security state specified. BL33 corresponds to the non-secure image type
+ * while BL32 corresponds to the secure image type. A NULL pointer is returned
+ * if the image does not exist.
+ ******************************************************************************/
+entry_point_info_t *bl31_plat_get_next_image_ep_info(uint32_t type)
+{
+	/* QTI platform don't have BL32 implementation. */
+	assert(type == NON_SECURE);
+	assert(bl33_image_ep_info.h.type == PARAM_EP);
+	assert(bl33_image_ep_info.h.attr == NON_SECURE);
+	/*
+	 * None of the images on the platforms can have 0x0
+	 * as the entrypoint.
+	 */
+	if (bl33_image_ep_info.pc) {
+		return &bl33_image_ep_info;
+	} else {
+		return NULL;
+	}
+}
+
+/*******************************************************************************
+ * This function is used by the architecture setup code to retrieve the counter
+ * frequency for the CPU's generic timer. This value will be programmed into the
+ * CNTFRQ_EL0 register. In Arm standard platforms, it returns the base frequency
+ * of the system counter, which is retrieved from the first entry in the
+ * frequency modes table. This will be used later in warm boot (psci_arch_setup)
+ * of CPUs to set when CPU frequency.
+ ******************************************************************************/
+unsigned int plat_get_syscnt_freq2(void)
+{
+	assert(g_qti_cpu_cntfrq != 0);
+	return g_qti_cpu_cntfrq;
+}
diff --git a/plat/qti/common/src/qti_common.c b/plat/qti/common/src/qti_common.c
new file mode 100644
index 0000000..ff0fa30
--- /dev/null
+++ b/plat/qti/common/src/qti_common.c
@@ -0,0 +1,148 @@
+/*
+ * Copyright (c) 2018, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2018-2020, The Linux Foundation. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <assert.h>
+#include <errno.h>
+#include <stdbool.h>
+#include <stdint.h>
+
+#include <common/debug.h>
+#include <lib/xlat_tables/xlat_tables_v2.h>
+
+#include <platform_def.h>
+#include <qti_plat.h>
+#include <qtiseclib_interface.h>
+
+/*
+ * Table of regions for various BL stages to map using the MMU.
+ * This doesn't include TZRAM as the 'mem_layout' argument passed to
+ * qti_configure_mmu_elx() will give the available subset of that,
+ */
+
+const mmap_region_t plat_qti_mmap[] = {
+	MAP_REGION_FLAT(QTI_DEVICE_BASE, QTI_DEVICE_SIZE,
+			MT_DEVICE | MT_RW | MT_SECURE),
+	MAP_REGION_FLAT(QTI_AOP_CMD_DB_BASE, QTI_AOP_CMD_DB_SIZE,
+			MT_NS | MT_RO | MT_EXECUTE_NEVER),
+	{0}
+};
+
+CASSERT(ARRAY_SIZE(plat_qti_mmap) <= MAX_MMAP_REGIONS, assert_max_mmap_regions);
+
+
+bool qti_is_overlap_atf_rg(unsigned long long addr, size_t size)
+{
+	if (addr > addr + size
+			|| (BL31_BASE < addr + size && BL31_LIMIT > addr)) {
+		return true;
+	}
+	return false;
+}
+
+/*
+ *  unsigned int plat_qti_my_cluster_pos(void)
+ *  definition to get the cluster index of the calling CPU.
+ *  - In ARM v8   (MPIDR_EL1[24]=0)
+ *    ClusterId = MPIDR_EL1[15:8]
+ *  - In ARM v8.1 & Later version (MPIDR_EL1[24]=1)
+ *    ClusterId = MPIDR_EL1[23:15]
+ */
+unsigned int plat_qti_my_cluster_pos(void)
+{
+	unsigned int mpidr, cluster_id;
+
+	mpidr = read_mpidr_el1();
+	if ((mpidr & MPIDR_MT_MASK) == 0) {	/* MT not supported */
+		cluster_id = (mpidr >> MPIDR_AFF1_SHIFT) & MPIDR_AFFLVL_MASK;
+	} else {		/* MT supported */
+		cluster_id = (mpidr >> MPIDR_AFF2_SHIFT) & MPIDR_AFFLVL_MASK;
+	}
+	assert(cluster_id < PLAT_CLUSTER_COUNT);
+	return cluster_id;
+}
+
+/*
+ * Set up the page tables for the generic and platform-specific memory regions.
+ * The extents of the generic memory regions are specified by the function
+ * arguments and consist of:
+ * - Trusted SRAM seen by the BL image;
+ * - Code section;
+ * - Read-only data section;
+ * - Coherent memory region, if applicable.
+ */
+void qti_setup_page_tables(uintptr_t total_base,
+			   size_t total_size,
+			   uintptr_t code_start,
+			   uintptr_t code_limit,
+			   uintptr_t rodata_start,
+			   uintptr_t rodata_limit,
+			   uintptr_t coh_start, uintptr_t coh_limit)
+{
+	/*
+	 * Map the Trusted SRAM with appropriate memory attributes.
+	 * Subsequent mappings will adjust the attributes for specific regions.
+	 */
+	VERBOSE("Trusted SRAM seen by this BL image: %p - %p\n",
+		(void *)total_base, (void *)(total_base + total_size));
+	mmap_add_region(total_base, total_base,
+			total_size, MT_MEMORY | MT_RW | MT_SECURE);
+
+	/* Re-map the code section */
+	VERBOSE("Code region: %p - %p\n",
+		(void *)code_start, (void *)code_limit);
+	mmap_add_region(code_start, code_start,
+			code_limit - code_start, MT_CODE | MT_SECURE);
+
+	/* Re-map the read-only data section */
+	VERBOSE("Read-only data region: %p - %p\n",
+		(void *)rodata_start, (void *)rodata_limit);
+	mmap_add_region(rodata_start, rodata_start,
+			rodata_limit - rodata_start, MT_RO_DATA | MT_SECURE);
+
+	/* Re-map the coherent memory region */
+	VERBOSE("Coherent region: %p - %p\n",
+		(void *)coh_start, (void *)coh_limit);
+	mmap_add_region(coh_start, coh_start,
+			coh_limit - coh_start, MT_DEVICE | MT_RW | MT_SECURE);
+
+	/* Now (re-)map the platform-specific memory regions */
+	mmap_add(plat_qti_mmap);
+
+	/* Create the page tables to reflect the above mappings */
+	init_xlat_tables();
+}
+
+static inline void qti_align_mem_region(uintptr_t addr, size_t size,
+					uintptr_t *aligned_addr,
+					size_t *aligned_size)
+{
+	*aligned_addr = round_down(addr, PAGE_SIZE);
+	*aligned_size = round_up(addr - *aligned_addr + size, PAGE_SIZE);
+}
+
+int qti_mmap_add_dynamic_region(uintptr_t base_pa, size_t size,
+				unsigned int attr)
+{
+	uintptr_t aligned_pa;
+	size_t aligned_size;
+
+	qti_align_mem_region(base_pa, size, &aligned_pa, &aligned_size);
+
+	if (qti_is_overlap_atf_rg(base_pa, size)) {
+		/* Memory shouldn't overlap with TF-A range. */
+		return -EPERM;
+	}
+
+	return mmap_add_dynamic_region(aligned_pa, aligned_pa, aligned_size,
+				       attr);
+}
+
+int qti_mmap_remove_dynamic_region(uintptr_t base_va, size_t size)
+{
+	qti_align_mem_region(base_va, size, &base_va, &size);
+	return mmap_remove_dynamic_region(base_va, size);
+}
diff --git a/plat/qti/common/src/qti_gic_v3.c b/plat/qti/common/src/qti_gic_v3.c
new file mode 100644
index 0000000..a5e0ae7
--- /dev/null
+++ b/plat/qti/common/src/qti_gic_v3.c
@@ -0,0 +1,159 @@
+/*
+ * Copyright (c) 2015-2018, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2018-2020, The Linux Foundation. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <common/bl_common.h>
+#include <drivers/arm/gicv3.h>
+
+#include <platform.h>
+#include <platform_def.h>
+#include <qti_plat.h>
+#include <qtiseclib_defs.h>
+#include <qtiseclib_defs_plat.h>
+
+/* The GICv3 driver only needs to be initialized in EL3 */
+static uintptr_t rdistif_base_addrs[PLATFORM_CORE_COUNT];
+
+/* Array of interrupts to be configured by the gic driver */
+static const interrupt_prop_t qti_interrupt_props[] = {
+	INTR_PROP_DESC(QTISECLIB_INT_ID_CPU_WAKEUP_SGI,
+		       GIC_HIGHEST_SEC_PRIORITY, INTR_GROUP0,
+		       GIC_INTR_CFG_EDGE),
+	INTR_PROP_DESC(QTISECLIB_INT_ID_RESET_SGI, GIC_HIGHEST_SEC_PRIORITY,
+		       INTR_GROUP0,
+		       GIC_INTR_CFG_EDGE),
+	INTR_PROP_DESC(QTISECLIB_INT_ID_SEC_WDOG_BARK, GIC_HIGHEST_SEC_PRIORITY,
+		       INTR_GROUP0,
+		       GIC_INTR_CFG_EDGE),
+	INTR_PROP_DESC(QTISECLIB_INT_ID_NON_SEC_WDOG_BITE,
+		       GIC_HIGHEST_SEC_PRIORITY, INTR_GROUP0,
+		       GIC_INTR_CFG_LEVEL),
+	INTR_PROP_DESC(QTISECLIB_INT_ID_VMIDMT_ERR_CLT_SEC,
+		       GIC_HIGHEST_SEC_PRIORITY, INTR_GROUP0,
+		       GIC_INTR_CFG_EDGE),
+	INTR_PROP_DESC(QTISECLIB_INT_ID_VMIDMT_ERR_CLT_NONSEC,
+		       GIC_HIGHEST_SEC_PRIORITY, INTR_GROUP0,
+		       GIC_INTR_CFG_EDGE),
+	INTR_PROP_DESC(QTISECLIB_INT_ID_VMIDMT_ERR_CFG_SEC,
+		       GIC_HIGHEST_SEC_PRIORITY, INTR_GROUP0,
+		       GIC_INTR_CFG_EDGE),
+	INTR_PROP_DESC(QTISECLIB_INT_ID_VMIDMT_ERR_CFG_NONSEC,
+		       GIC_HIGHEST_SEC_PRIORITY, INTR_GROUP0,
+		       GIC_INTR_CFG_EDGE),
+	INTR_PROP_DESC(QTISECLIB_INT_ID_XPU_SEC, GIC_HIGHEST_SEC_PRIORITY,
+		       INTR_GROUP0,
+		       GIC_INTR_CFG_EDGE),
+	INTR_PROP_DESC(QTISECLIB_INT_ID_XPU_NON_SEC, GIC_HIGHEST_SEC_PRIORITY,
+		       INTR_GROUP0,
+		       GIC_INTR_CFG_EDGE),
+#ifdef QTISECLIB_INT_ID_A1_NOC_ERROR
+	INTR_PROP_DESC(QTISECLIB_INT_ID_A1_NOC_ERROR, GIC_HIGHEST_SEC_PRIORITY,
+		       INTR_GROUP0,
+		       GIC_INTR_CFG_EDGE),
+#endif
+	INTR_PROP_DESC(QTISECLIB_INT_ID_A2_NOC_ERROR, GIC_HIGHEST_SEC_PRIORITY,
+		       INTR_GROUP0,
+		       GIC_INTR_CFG_EDGE),
+	INTR_PROP_DESC(QTISECLIB_INT_ID_CONFIG_NOC_ERROR,
+		       GIC_HIGHEST_SEC_PRIORITY, INTR_GROUP0,
+		       GIC_INTR_CFG_EDGE),
+	INTR_PROP_DESC(QTISECLIB_INT_ID_DC_NOC_ERROR, GIC_HIGHEST_SEC_PRIORITY,
+		       INTR_GROUP0,
+		       GIC_INTR_CFG_EDGE),
+	INTR_PROP_DESC(QTISECLIB_INT_ID_MEM_NOC_ERROR, GIC_HIGHEST_SEC_PRIORITY,
+		       INTR_GROUP0,
+		       GIC_INTR_CFG_EDGE),
+	INTR_PROP_DESC(QTISECLIB_INT_ID_SYSTEM_NOC_ERROR,
+		       GIC_HIGHEST_SEC_PRIORITY, INTR_GROUP0,
+		       GIC_INTR_CFG_EDGE),
+	INTR_PROP_DESC(QTISECLIB_INT_ID_MMSS_NOC_ERROR,
+		       GIC_HIGHEST_SEC_PRIORITY, INTR_GROUP0,
+		       GIC_INTR_CFG_EDGE),
+};
+
+const gicv3_driver_data_t qti_gic_data = {
+	.gicd_base = QTI_GICD_BASE,
+	.gicr_base = QTI_GICR_BASE,
+	.interrupt_props = qti_interrupt_props,
+	.interrupt_props_num = ARRAY_SIZE(qti_interrupt_props),
+	.rdistif_num = PLATFORM_CORE_COUNT,
+	.rdistif_base_addrs = rdistif_base_addrs,
+	.mpidr_to_core_pos = plat_qti_core_pos_by_mpidr
+};
+
+void plat_qti_gic_driver_init(void)
+{
+	/*
+	 * The GICv3 driver is initialized in EL3 and does not need
+	 * to be initialized again in SEL1. This is because the S-EL1
+	 * can use GIC system registers to manage interrupts and does
+	 * not need GIC interface base addresses to be configured.
+	 */
+	gicv3_driver_init(&qti_gic_data);
+}
+
+/******************************************************************************
+ * ARM common helper to initialize the GIC. Only invoked by BL31
+ *****************************************************************************/
+void plat_qti_gic_init(void)
+{
+	unsigned int i;
+
+	gicv3_distif_init();
+	gicv3_rdistif_init(plat_my_core_pos());
+	gicv3_cpuif_enable(plat_my_core_pos());
+
+	/* Route secure spi interrupt to ANY. */
+	for (i = 0; i < ARRAY_SIZE(qti_interrupt_props); i++) {
+		unsigned int int_id = qti_interrupt_props[i].intr_num;
+
+		if (plat_ic_is_spi(int_id)) {
+			gicv3_set_spi_routing(int_id, GICV3_IRM_ANY, 0x0);
+		}
+	}
+}
+
+void gic_set_spi_routing(unsigned int id, unsigned int irm, u_register_t target)
+{
+	gicv3_set_spi_routing(id, irm, target);
+}
+
+/******************************************************************************
+ * ARM common helper to enable the GIC CPU interface
+ *****************************************************************************/
+void plat_qti_gic_cpuif_enable(void)
+{
+	gicv3_cpuif_enable(plat_my_core_pos());
+}
+
+/******************************************************************************
+ * ARM common helper to disable the GIC CPU interface
+ *****************************************************************************/
+void plat_qti_gic_cpuif_disable(void)
+{
+	gicv3_cpuif_disable(plat_my_core_pos());
+}
+
+/******************************************************************************
+ * ARM common helper to initialize the per-CPU redistributor interface in GICv3
+ *****************************************************************************/
+void plat_qti_gic_pcpu_init(void)
+{
+	gicv3_rdistif_init(plat_my_core_pos());
+}
+
+/******************************************************************************
+ * ARM common helpers to power GIC redistributor interface
+ *****************************************************************************/
+void plat_qti_gic_redistif_on(void)
+{
+	gicv3_rdistif_on(plat_my_core_pos());
+}
+
+void plat_qti_gic_redistif_off(void)
+{
+	gicv3_rdistif_off(plat_my_core_pos());
+}
diff --git a/plat/qti/common/src/qti_interrupt_svc.c b/plat/qti/common/src/qti_interrupt_svc.c
new file mode 100644
index 0000000..89cd7b5
--- /dev/null
+++ b/plat/qti/common/src/qti_interrupt_svc.c
@@ -0,0 +1,65 @@
+/*
+ * Copyright (c) 2015-2018, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2018,2020, The Linux Foundation. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+#include <assert.h>
+#include <stdint.h>
+
+#include <arch_helpers.h>
+#include <bl31/interrupt_mgmt.h>
+#include <drivers/arm/gic_common.h>
+#include <lib/el3_runtime/context_mgmt.h>
+
+#include <platform.h>
+#include <qti_interrupt_svc.h>
+#include <qtiseclib_interface.h>
+
+#define QTI_INTR_INVALID_INT_NUM		0xFFFFFFFFU
+
+/*
+ * Top-level EL3 interrupt handler.
+ */
+static uint64_t qti_el3_interrupt_handler(uint32_t id, uint32_t flags,
+					  void *handle, void *cookie)
+{
+	uint32_t irq = QTI_INTR_INVALID_INT_NUM;
+
+	/*
+	 * EL3 non-interruptible. Interrupt shouldn't occur when we are at
+	 * EL3 / Secure.
+	 */
+	assert(handle != cm_get_context(SECURE));
+
+	irq = plat_ic_acknowledge_interrupt();
+
+	qtiseclib_invoke_isr(irq, handle);
+
+	/* End of Interrupt. */
+	if (irq < 1022U) {
+		plat_ic_end_of_interrupt(irq);
+	}
+
+	return (uint64_t) handle;
+}
+
+int qti_interrupt_svc_init(void)
+{
+	int ret;
+	uint64_t flags = 0U;
+
+	/*
+	 * Route EL3 interrupts to EL3 when in Non-secure.
+	 * Note: EL3 won't have interrupt enable
+	 * & we don't have S-EL1 support.
+	 */
+	set_interrupt_rm_flag(flags, NON_SECURE);
+
+	/* Register handler for EL3 interrupts */
+	ret = register_interrupt_type_handler(INTR_TYPE_EL3,
+					      qti_el3_interrupt_handler, flags);
+	assert(ret == 0);
+
+	return ret;
+}
diff --git a/plat/qti/common/src/qti_pm.c b/plat/qti/common/src/qti_pm.c
new file mode 100644
index 0000000..4a5877c
--- /dev/null
+++ b/plat/qti/common/src/qti_pm.c
@@ -0,0 +1,274 @@
+/*
+ * Copyright (c) 2018, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2018, 2020, The Linux Foundation. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+#include <assert.h>
+
+#include <arch_helpers.h>
+#include <bl31/bl31.h>
+#include <common/debug.h>
+#include <lib/psci/psci.h>
+
+#include <platform.h>
+#include <platform_def.h>
+#include <qti_cpu.h>
+#include <qti_plat.h>
+#include <qtiseclib_cb_interface.h>
+#include <qtiseclib_defs_plat.h>
+#include <qtiseclib_interface.h>
+
+#define QTI_LOCAL_PSTATE_WIDTH		4
+#define QTI_LOCAL_PSTATE_MASK		((1 << QTI_LOCAL_PSTATE_WIDTH) - 1)
+
+/* Make composite power state parameter till level 0 */
+#define qti_make_pwrstate_lvl0(lvl0_state, type) \
+		(((lvl0_state) << PSTATE_ID_SHIFT) | ((type) << PSTATE_TYPE_SHIFT))
+
+/* Make composite power state parameter till level 1 */
+#define qti_make_pwrstate_lvl1(lvl1_state, lvl0_state, type) \
+		(((lvl1_state) << QTI_LOCAL_PSTATE_WIDTH) | \
+		qti_make_pwrstate_lvl0(lvl0_state, type))
+
+/* Make composite power state parameter till level 2 */
+#define qti_make_pwrstate_lvl2(lvl2_state, lvl1_state, lvl0_state, type) \
+		(((lvl2_state) << (QTI_LOCAL_PSTATE_WIDTH * 2)) | \
+		qti_make_pwrstate_lvl1(lvl1_state, lvl0_state, type))
+
+/* Make composite power state parameter till level 3 */
+#define qti_make_pwrstate_lvl3(lvl3_state, lvl2_state, lvl1_state, lvl0_state, type) \
+		(((lvl3_state) << (QTI_LOCAL_PSTATE_WIDTH * 3)) | \
+		qti_make_pwrstate_lvl2(lvl2_state, lvl1_state, lvl0_state, type))
+
+/* QTI_CORE_PWRDN_EN_MASK happens to be same across all CPUs */
+#define QTI_CORE_PWRDN_EN_MASK		1
+
+/* cpu power control happens to be same across all CPUs */
+_DEFINE_SYSREG_WRITE_FUNC(cpu_pwrctrl_val, S3_0_C15_C2_7)
+_DEFINE_SYSREG_READ_FUNC(cpu_pwrctrl_val, S3_0_C15_C2_7)
+
+const unsigned int qti_pm_idle_states[] = {
+	qti_make_pwrstate_lvl0(QTI_LOCAL_STATE_OFF,
+			       PSTATE_TYPE_POWERDOWN),
+	qti_make_pwrstate_lvl0(QTI_LOCAL_STATE_DEEPOFF,
+			       PSTATE_TYPE_POWERDOWN),
+	qti_make_pwrstate_lvl1(QTI_LOCAL_STATE_DEEPOFF,
+			       QTI_LOCAL_STATE_DEEPOFF,
+			       PSTATE_TYPE_POWERDOWN),
+	qti_make_pwrstate_lvl2(QTI_LOCAL_STATE_OFF,
+			       QTI_LOCAL_STATE_DEEPOFF,
+			       QTI_LOCAL_STATE_DEEPOFF,
+			       PSTATE_TYPE_POWERDOWN),
+	qti_make_pwrstate_lvl3(QTI_LOCAL_STATE_OFF,
+			       QTI_LOCAL_STATE_DEEPOFF,
+			       QTI_LOCAL_STATE_DEEPOFF,
+			       QTI_LOCAL_STATE_DEEPOFF,
+			       PSTATE_TYPE_POWERDOWN),
+	0,
+};
+
+/*******************************************************************************
+ * QTI standard platform handler called to check the validity of the power
+ * state parameter. The power state parameter has to be a composite power
+ * state.
+ ******************************************************************************/
+int qti_validate_power_state(unsigned int power_state,
+			     psci_power_state_t *req_state)
+{
+	unsigned int state_id;
+	int i;
+
+	assert(req_state);
+
+	/*
+	 *  Currently we are using a linear search for finding the matching
+	 *  entry in the idle power state array. This can be made a binary
+	 *  search if the number of entries justify the additional complexity.
+	 */
+	for (i = 0; !!qti_pm_idle_states[i]; i++) {
+		if (power_state == qti_pm_idle_states[i])
+			break;
+	}
+
+	/* Return error if entry not found in the idle state array */
+	if (!qti_pm_idle_states[i])
+		return PSCI_E_INVALID_PARAMS;
+
+	i = 0;
+	state_id = psci_get_pstate_id(power_state);
+
+	/* Parse the State ID and populate the state info parameter */
+	while (state_id) {
+		req_state->pwr_domain_state[i++] = state_id &
+		    QTI_LOCAL_PSTATE_MASK;
+		state_id >>= QTI_LOCAL_PSTATE_WIDTH;
+	}
+
+	return PSCI_E_SUCCESS;
+}
+
+/*******************************************************************************
+ * PLATFORM FUNCTIONS
+ ******************************************************************************/
+
+static void qti_set_cpupwrctlr_val(void)
+{
+	unsigned long val;
+
+	val = read_cpu_pwrctrl_val();
+	val |= QTI_CORE_PWRDN_EN_MASK;
+	write_cpu_pwrctrl_val(val);
+
+	isb();
+}
+
+/**
+ * CPU power on function - ideally we want a wrapper since this function is
+ * target specific. But to unblock teams.
+ */
+static int qti_cpu_power_on(u_register_t mpidr)
+{
+	int core_pos = plat_core_pos_by_mpidr(mpidr);
+
+	/* If not valid mpidr, return error */
+	if (core_pos < 0 || core_pos >= QTISECLIB_PLAT_CORE_COUNT) {
+		return PSCI_E_INVALID_PARAMS;
+	}
+
+	return qtiseclib_psci_node_power_on(mpidr);
+}
+
+static bool is_cpu_off(const psci_power_state_t *target_state)
+{
+	if ((target_state->pwr_domain_state[QTI_PWR_LVL0] ==
+	     QTI_LOCAL_STATE_OFF) ||
+	    (target_state->pwr_domain_state[QTI_PWR_LVL0] ==
+	     QTI_LOCAL_STATE_DEEPOFF)) {
+		return true;
+	} else {
+		return false;
+	}
+}
+
+static void qti_cpu_power_on_finish(const psci_power_state_t *target_state)
+{
+	const uint8_t *pwr_states =
+	    (const uint8_t *)target_state->pwr_domain_state;
+	qtiseclib_psci_node_on_finish(pwr_states);
+
+	if (is_cpu_off(target_state)) {
+		plat_qti_gic_cpuif_enable();
+	}
+}
+
+static void qti_cpu_standby(plat_local_state_t cpu_state)
+{
+}
+
+static void qti_node_power_off(const psci_power_state_t *target_state)
+{
+	qtiseclib_psci_node_power_off((const uint8_t *)
+				      target_state->pwr_domain_state);
+	if (is_cpu_off(target_state)) {
+		plat_qti_gic_cpuif_disable();
+		qti_set_cpupwrctlr_val();
+	}
+}
+
+static void qti_node_suspend(const psci_power_state_t *target_state)
+{
+	qtiseclib_psci_node_suspend((const uint8_t *)target_state->
+				    pwr_domain_state);
+	if (is_cpu_off(target_state)) {
+		plat_qti_gic_cpuif_disable();
+		qti_set_cpupwrctlr_val();
+	}
+}
+
+static void qti_node_suspend_finish(const psci_power_state_t *target_state)
+{
+	const uint8_t *pwr_states =
+	    (const uint8_t *)target_state->pwr_domain_state;
+	qtiseclib_psci_node_suspend_finish(pwr_states);
+	if (is_cpu_off(target_state)) {
+		plat_qti_gic_cpuif_enable();
+	}
+}
+
+__dead2 void qti_domain_power_down_wfi(const psci_power_state_t *target_state)
+{
+
+	/* For now just do WFI - add any target specific handling if needed */
+	psci_power_down_wfi();
+	/* We should never reach here */
+}
+
+__dead2 void qti_system_off(void)
+{
+	qtiseclib_psci_system_off();
+}
+
+__dead2 void qti_system_reset(void)
+{
+	qtiseclib_psci_system_reset();
+}
+
+void qti_get_sys_suspend_power_state(psci_power_state_t *req_state)
+{
+	int i = 0;
+	unsigned int state_id, power_state;
+	int size = ARRAY_SIZE(qti_pm_idle_states);
+
+	/*
+	 * Find deepest state.
+	 * The arm_pm_idle_states[] array has last element by default 0,
+	 * so the real deepest state is second last element of that array.
+	 */
+	power_state = qti_pm_idle_states[size - 2];
+	state_id = psci_get_pstate_id(power_state);
+
+	/* Parse the State ID and populate the state info parameter */
+	while (state_id) {
+		req_state->pwr_domain_state[i++] =
+		    state_id & QTI_LOCAL_PSTATE_MASK;
+		state_id >>= QTI_LOCAL_PSTATE_WIDTH;
+	}
+}
+
+/*
+ * Structure containing platform specific PSCI operations. Common
+ * PSCI layer will use this.
+ */
+const plat_psci_ops_t plat_qti_psci_pm_ops = {
+	.pwr_domain_on = qti_cpu_power_on,
+	.pwr_domain_on_finish = qti_cpu_power_on_finish,
+	.cpu_standby = qti_cpu_standby,
+	.pwr_domain_off = qti_node_power_off,
+	.pwr_domain_suspend = qti_node_suspend,
+	.pwr_domain_suspend_finish = qti_node_suspend_finish,
+	.pwr_domain_pwr_down_wfi = qti_domain_power_down_wfi,
+	.system_off = qti_system_off,
+	.system_reset = qti_system_reset,
+	.get_node_hw_state = NULL,
+	.translate_power_state_by_mpidr = NULL,
+	.get_sys_suspend_power_state = qti_get_sys_suspend_power_state,
+	.validate_power_state = qti_validate_power_state,
+};
+
+/**
+ * The QTI Standard platform definition of platform porting API
+ * `plat_setup_psci_ops`.
+ */
+int plat_setup_psci_ops(uintptr_t sec_entrypoint,
+			const plat_psci_ops_t **psci_ops)
+{
+	int err;
+
+	err = qtiseclib_psci_init((uintptr_t)bl31_warm_entrypoint);
+	if (err == PSCI_E_SUCCESS) {
+		*psci_ops = &plat_qti_psci_pm_ops;
+	}
+
+	return err;
+}
diff --git a/plat/qti/common/src/qti_stack_protector.c b/plat/qti/common/src/qti_stack_protector.c
new file mode 100644
index 0000000..b2dbfb0
--- /dev/null
+++ b/plat/qti/common/src/qti_stack_protector.c
@@ -0,0 +1,24 @@
+/*
+ * Copyright (c) 2018-2019, The Linux Foundation. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <assert.h>
+#include <stdint.h>
+
+#include <platform.h>
+#include <platform_def.h>
+#include <qtiseclib_interface.h>
+
+u_register_t plat_get_stack_protector_canary(void)
+{
+	u_register_t random = 0x0;
+
+	/* get random data , the below API doesn't return random = 0 in success
+	 * case */
+	qtiseclib_prng_get_data((uint8_t *) &random, sizeof(random));
+	assert(0x0 != random);
+
+	return random;
+}
diff --git a/plat/qti/common/src/qti_syscall.c b/plat/qti/common/src/qti_syscall.c
new file mode 100644
index 0000000..27c4895
--- /dev/null
+++ b/plat/qti/common/src/qti_syscall.c
@@ -0,0 +1,333 @@
+/*
+ * Copyright (c) 2018, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2018-2020, The Linux Foundation. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+#include <stdbool.h>
+#include <stddef.h>
+#include <stdint.h>
+#include <string.h>
+
+#include <common/debug.h>
+#include <common/runtime_svc.h>
+#include <context.h>
+#include <lib/coreboot.h>
+#include <lib/utils_def.h>
+#include <lib/xlat_tables/xlat_tables_v2.h>
+#include <smccc_helpers.h>
+#include <tools_share/uuid.h>
+
+#include <qti_plat.h>
+#include <qti_secure_io_cfg.h>
+#include <qtiseclib_interface.h>
+/*
+ * SIP service - SMC function IDs for SiP Service queries
+ *
+ */
+#define	QTI_SIP_SVC_CALL_COUNT_ID			U(0x0200ff00)
+#define	QTI_SIP_SVC_UID_ID				U(0x0200ff01)
+/*							0x8200ff02 is reserved */
+#define	QTI_SIP_SVC_VERSION_ID				U(0x0200ff03)
+
+/*
+ * Syscall's to allow Non Secure world accessing peripheral/IO memory
+ * those are secure/proteced BUT not required to be secure.
+ */
+#define	QTI_SIP_SVC_SECURE_IO_READ_ID		U(0x02000501)
+#define	QTI_SIP_SVC_SECURE_IO_WRITE_ID		U(0x02000502)
+
+/*
+ * Syscall's to assigns a list of intermediate PAs from a
+ * source Virtual Machine (VM) to a destination VM.
+ */
+#define	QTI_SIP_SVC_MEM_ASSIGN_ID		U(0x02000C16)
+
+#define	QTI_SIP_SVC_SECURE_IO_READ_PARAM_ID	U(0x1)
+#define	QTI_SIP_SVC_SECURE_IO_WRITE_PARAM_ID	U(0x2)
+#define	QTI_SIP_SVC_MEM_ASSIGN_PARAM_ID		U(0x1117)
+
+#define	QTI_SIP_SVC_CALL_COUNT			U(0x3)
+#define QTI_SIP_SVC_VERSION_MAJOR		U(0x0)
+#define	QTI_SIP_SVC_VERSION_MINOR		U(0x0)
+
+#define QTI_VM_LAST				U(44)
+#define SIZE4K					U(0x1000)
+#define QTI_VM_MAX_LIST_SIZE			U(0x20)
+
+#define	FUNCID_OEN_NUM_MASK	((FUNCID_OEN_MASK << FUNCID_OEN_SHIFT)\
+				|(FUNCID_NUM_MASK << FUNCID_NUM_SHIFT))
+
+enum {
+	QTI_SIP_SUCCESS = 0,
+	QTI_SIP_NOT_SUPPORTED = -1,
+	QTI_SIP_PREEMPTED = -2,
+	QTI_SIP_INVALID_PARAM = -3,
+};
+
+/* QTI SiP Service UUID */
+DEFINE_SVC_UUID2(qti_sip_svc_uid,
+		 0x43864748, 0x217f, 0x41ad, 0xaa, 0x5a,
+		 0xba, 0xe7, 0x0f, 0xa5, 0x52, 0xaf);
+
+static bool qti_is_secure_io_access_allowed(u_register_t addr)
+{
+	int i = 0;
+
+	for (i = 0; i < ARRAY_SIZE(qti_secure_io_allowed_regs); i++) {
+		if ((uintptr_t) addr == qti_secure_io_allowed_regs[i]) {
+			return true;
+		}
+	}
+
+	return false;
+}
+
+bool qti_mem_assign_validate_param(memprot_info_t *mem_info,
+				   u_register_t u_num_mappings,
+				   uint32_t *source_vm_list,
+				   u_register_t src_vm_list_cnt,
+				   memprot_dst_vm_perm_info_t *dest_vm_list,
+				   u_register_t dst_vm_list_cnt)
+{
+	int i;
+
+	if (!source_vm_list || !dest_vm_list || !mem_info
+	    || (src_vm_list_cnt == 0)
+	    || (src_vm_list_cnt >= QTI_VM_LAST) || (dst_vm_list_cnt == 0)
+	    || (dst_vm_list_cnt >= QTI_VM_LAST) || (u_num_mappings == 0)
+	    || u_num_mappings > QTI_VM_MAX_LIST_SIZE) {
+		return false;
+	}
+	for (i = 0; i < u_num_mappings; i++) {
+		if ((mem_info[i].mem_addr & (SIZE4K - 1))
+		    || (mem_info[i].mem_size & (SIZE4K - 1))) {
+			return false;
+		}
+
+		if ((mem_info[i].mem_addr + mem_info[i].mem_size) <
+		    mem_info[i].mem_addr) {
+			return false;
+		}
+		if (coreboot_get_memory_type(mem_info[i].mem_addr) !=
+		    CB_MEM_RAM) {
+			return false;
+		}
+
+		if (coreboot_get_memory_type
+		    (mem_info[i].mem_addr + mem_info[i].mem_size) !=
+		    CB_MEM_RAM) {
+			return false;
+		}
+
+	}
+	for (i = 0; i < src_vm_list_cnt; i++) {
+		if (source_vm_list[i] >= QTI_VM_LAST) {
+			return false;
+		}
+	}
+	for (i = 0; i < dst_vm_list_cnt; i++) {
+		if (dest_vm_list[i].dst_vm >= QTI_VM_LAST) {
+			return false;
+		}
+	}
+	return true;
+}
+
+static uintptr_t qti_sip_mem_assign(void *handle, uint32_t smc_cc,
+				    u_register_t x1,
+				    u_register_t x2,
+				    u_register_t x3, u_register_t x4)
+{
+	uintptr_t dyn_map_start = 0, dyn_map_end = 0;
+	size_t dyn_map_size = 0;
+	u_register_t x6, x7;
+	int ret = QTI_SIP_NOT_SUPPORTED;
+	u_register_t x5 = read_ctx_reg(get_gpregs_ctx(handle), CTX_GPREG_X5);
+
+	if (smc_cc == SMC_32) {
+		x5 = (uint32_t) x5;
+	}
+	/* Validate input arg count & retrieve arg3-6 from NS Buffer. */
+	if ((x1 != QTI_SIP_SVC_MEM_ASSIGN_PARAM_ID) || (x5 == 0x0)) {
+		goto unmap_return;
+	}
+
+	/* Map NS Buffer. */
+	dyn_map_start = x5;
+	dyn_map_size =
+		(smc_cc ==
+		 SMC_32) ? (sizeof(uint32_t) * 4) : (sizeof(uint64_t) * 4);
+	if (qti_mmap_add_dynamic_region(dyn_map_start, dyn_map_size,
+				(MT_NS | MT_RO_DATA)) != 0) {
+		goto unmap_return;
+	}
+	/* Retrieve indirect args. */
+	if (smc_cc == SMC_32) {
+		x6 = *((uint32_t *) x5 + 1);
+		x7 = *((uint32_t *) x5 + 2);
+		x5 = *(uint32_t *) x5;
+	} else {
+		x6 = *((uint64_t *) x5 + 1);
+		x7 = *((uint64_t *) x5 + 2);
+		x5 = *(uint64_t *) x5;
+	}
+	/* Un-Map NS Buffer. */
+	if (qti_mmap_remove_dynamic_region(dyn_map_start, dyn_map_size) != 0) {
+		goto unmap_return;
+	}
+
+	/*
+	 * Map NS Buffers.
+	 * arg0,2,4 points to buffers & arg1,3,5 hold sizes.
+	 * MAP api's fail to map if it's already mapped. Let's
+	 * find lowest start & highest end address, then map once.
+	 */
+	dyn_map_start = MIN(x2, x4);
+	dyn_map_start = MIN(dyn_map_start, x6);
+	dyn_map_end = MAX((x2 + x3), (x4 + x5));
+	dyn_map_end = MAX(dyn_map_end, (x6 + x7));
+	dyn_map_size = dyn_map_end - dyn_map_start;
+
+	if (qti_mmap_add_dynamic_region(dyn_map_start, dyn_map_size,
+					(MT_NS | MT_RO_DATA)) != 0) {
+		goto unmap_return;
+	}
+	memprot_info_t *mem_info_p = (memprot_info_t *) x2;
+	uint32_t u_num_mappings = x3 / sizeof(memprot_info_t);
+	uint32_t *source_vm_list_p = (uint32_t *) x4;
+	uint32_t src_vm_list_cnt = x5 / sizeof(uint32_t);
+	memprot_dst_vm_perm_info_t *dest_vm_list_p =
+		(memprot_dst_vm_perm_info_t *) x6;
+	uint32_t dst_vm_list_cnt =
+		x7 / sizeof(memprot_dst_vm_perm_info_t);
+	if (qti_mem_assign_validate_param(mem_info_p, u_num_mappings,
+				source_vm_list_p, src_vm_list_cnt,
+				dest_vm_list_p,
+				dst_vm_list_cnt) != true) {
+		goto unmap_return;
+	}
+
+	memprot_info_t mem_info[QTI_VM_MAX_LIST_SIZE];
+	/* Populating the arguments */
+	for (int i = 0; i < u_num_mappings; i++) {
+		mem_info[i].mem_addr = mem_info_p[i].mem_addr;
+		mem_info[i].mem_size = mem_info_p[i].mem_size;
+	}
+
+	memprot_dst_vm_perm_info_t dest_vm_list[QTI_VM_LAST];
+
+	for (int i = 0; i < dst_vm_list_cnt; i++) {
+		dest_vm_list[i].dst_vm = dest_vm_list_p[i].dst_vm;
+		dest_vm_list[i].dst_vm_perm =
+			dest_vm_list_p[i].dst_vm_perm;
+		dest_vm_list[i].ctx = dest_vm_list_p[i].ctx;
+		dest_vm_list[i].ctx_size = dest_vm_list_p[i].ctx_size;
+	}
+
+	uint32_t source_vm_list[QTI_VM_LAST];
+
+	for (int i = 0; i < src_vm_list_cnt; i++) {
+		source_vm_list[i] = source_vm_list_p[i];
+	}
+	/* Un-Map NS Buffers. */
+	if (qti_mmap_remove_dynamic_region(dyn_map_start,
+				dyn_map_size) != 0) {
+		goto unmap_return;
+	}
+	/* Invoke API lib api. */
+	ret = qtiseclib_mem_assign(mem_info, u_num_mappings,
+			source_vm_list, src_vm_list_cnt,
+			dest_vm_list, dst_vm_list_cnt);
+
+	if (ret == 0) {
+		SMC_RET2(handle, QTI_SIP_SUCCESS, ret);
+	}
+unmap_return:
+	/* Un-Map NS Buffers if mapped */
+	if (dyn_map_start && dyn_map_size) {
+		qti_mmap_remove_dynamic_region(dyn_map_start, dyn_map_size);
+	}
+
+	SMC_RET2(handle, QTI_SIP_INVALID_PARAM, ret);
+}
+
+/*
+ * This function handles QTI specific syscalls. Currently only SiP calls are present.
+ * Both FAST & YIELD type call land here.
+ */
+static uintptr_t qti_sip_handler(uint32_t smc_fid,
+				 u_register_t x1,
+				 u_register_t x2,
+				 u_register_t x3,
+				 u_register_t x4,
+				 void *cookie, void *handle, u_register_t flags)
+{
+	uint32_t l_smc_fid = smc_fid & FUNCID_OEN_NUM_MASK;
+
+	if (GET_SMC_CC(smc_fid) == SMC_32) {
+		x1 = (uint32_t) x1;
+		x2 = (uint32_t) x2;
+		x3 = (uint32_t) x3;
+		x4 = (uint32_t) x4;
+	}
+
+	switch (l_smc_fid) {
+	case QTI_SIP_SVC_CALL_COUNT_ID:
+		{
+			SMC_RET1(handle, QTI_SIP_SVC_CALL_COUNT);
+			break;
+		}
+	case QTI_SIP_SVC_UID_ID:
+		{
+			/* Return UID to the caller */
+			SMC_UUID_RET(handle, qti_sip_svc_uid);
+			break;
+		}
+	case QTI_SIP_SVC_VERSION_ID:
+		{
+			/* Return the version of current implementation */
+			SMC_RET2(handle, QTI_SIP_SVC_VERSION_MAJOR,
+				 QTI_SIP_SVC_VERSION_MINOR);
+			break;
+		}
+	case QTI_SIP_SVC_SECURE_IO_READ_ID:
+		{
+			if ((x1 == QTI_SIP_SVC_SECURE_IO_READ_PARAM_ID) &&
+			    qti_is_secure_io_access_allowed(x2)) {
+				SMC_RET2(handle, QTI_SIP_SUCCESS,
+					 *((volatile uint32_t *)x2));
+			}
+			SMC_RET1(handle, QTI_SIP_INVALID_PARAM);
+			break;
+		}
+	case QTI_SIP_SVC_SECURE_IO_WRITE_ID:
+		{
+			if ((x1 == QTI_SIP_SVC_SECURE_IO_WRITE_PARAM_ID) &&
+			    qti_is_secure_io_access_allowed(x2)) {
+				*((volatile uint32_t *)x2) = x3;
+				SMC_RET1(handle, QTI_SIP_SUCCESS);
+			}
+			SMC_RET1(handle, QTI_SIP_INVALID_PARAM);
+			break;
+		}
+	case QTI_SIP_SVC_MEM_ASSIGN_ID:
+		{
+			return qti_sip_mem_assign(handle, GET_SMC_CC(smc_fid),
+						  x1, x2, x3, x4);
+			break;
+		}
+	default:
+		{
+			SMC_RET1(handle, QTI_SIP_NOT_SUPPORTED);
+		}
+	}
+	return (uintptr_t) handle;
+}
+
+/* Define a runtime service descriptor for both fast & yield SiP calls */
+DECLARE_RT_SVC(qti_sip_fast_svc, OEN_SIP_START,
+	       OEN_SIP_END, SMC_TYPE_FAST, NULL, qti_sip_handler);
+
+DECLARE_RT_SVC(qti_sip_yield_svc, OEN_SIP_START,
+	       OEN_SIP_END, SMC_TYPE_YIELD, NULL, qti_sip_handler);
diff --git a/plat/qti/common/src/qti_topology.c b/plat/qti/common/src/qti_topology.c
new file mode 100644
index 0000000..bf2e3f3
--- /dev/null
+++ b/plat/qti/common/src/qti_topology.c
@@ -0,0 +1,48 @@
+/*
+ * Copyright (c) 2015-2018, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2018,2020 The Linux Foundation. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <arch.h>
+
+#include <platform_def.h>
+#include <qti_plat.h>
+
+/* The QTI power domain tree descriptor */
+const unsigned char qti_power_domain_tree_desc[] = {
+	/* One domain to represent PDC */
+	PLAT_PDC_COUNT,
+	/* One domain to represent RSC */
+	PLAT_RSC_COUNT,
+	/* There is one top-level FCM cluster */
+	PLAT_CLUSTER_COUNT,
+	/* No. of cores in the FCM cluster */
+	PLAT_CLUSTER0_CORE_COUNT
+};
+
+/*******************************************************************************
+ * This function returns the ARM default topology tree information.
+ ******************************************************************************/
+const unsigned char *plat_get_power_domain_tree_desc(void)
+{
+	return qti_power_domain_tree_desc;
+}
+
+/** Function: plat_core_pos_by_mpidr
+ * This function implements a part of the critical interface between the psci
+ * generic layer and the platform that allows the former to query the platform
+ * to convert an MPIDR to a unique linear index. An error code (-1) is returned
+ * in case the MPIDR is invalid.
+ */
+int plat_core_pos_by_mpidr(u_register_t mpidr)
+{
+	int core_linear_index = plat_qti_core_pos_by_mpidr(mpidr);
+
+	if (core_linear_index < PLATFORM_CORE_COUNT) {
+		return core_linear_index;
+	} else {
+		return -1;
+	}
+}
diff --git a/plat/qti/qtiseclib/inc/qtiseclib_cb_interface.h b/plat/qti/qtiseclib/inc/qtiseclib_cb_interface.h
new file mode 100644
index 0000000..9c4a724
--- /dev/null
+++ b/plat/qti/qtiseclib/inc/qtiseclib_cb_interface.h
@@ -0,0 +1,54 @@
+/*
+ * Copyright (c) 2018-2020, The Linux Foundation. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef QTISECLIB_CB_INTERFACE_H
+#define QTISECLIB_CB_INTERFACE_H
+
+#include <stdarg.h>
+#include <stdbool.h>
+#include <stddef.h>
+#include <stdint.h>
+
+#include <qtiseclib_defs.h>
+
+/* Standard Library API's */
+void *qtiseclib_cb_memcpy(void *dst, const void *src, size_t len);
+
+#define QTISECLIB_CB_ERROR(...)		qtiseclib_cb_log(QTISECLIB_LOG_LEVEL_ERROR, __VA_ARGS__)
+#define QTISECLIB_CB_NOTICE(...)	qtiseclib_cb_log(QTISECLIB_LOG_LEVEL_NOTICE, __VA_ARGS__)
+#define QTISECLIB_CB_WARN(...)		qtiseclib_cb_log(QTISECLIB_LOG_LEVEL_WARNING, __VA_ARGS__)
+#define QTISECLIB_CB_INFO(...)		qtiseclib_cb_log(QTISECLIB_LOG_LEVEL_INFO, __VA_ARGS__)
+
+void qtiseclib_cb_log(unsigned int loglvl, const char *fmt, ...);
+
+void qtiseclib_cb_spin_lock(qtiseclib_cb_spinlock_t *lock);
+void qtiseclib_cb_spin_unlock(qtiseclib_cb_spinlock_t *lock);
+
+unsigned int qtiseclib_cb_plat_my_core_pos(void);
+int qtiseclib_cb_plat_core_pos_by_mpidr(u_register_t mpidr);
+unsigned int qtiseclib_cb_plat_my_cluster_pos(void);
+
+/* GIC platform wrappers */
+void qtiseclib_cb_gic_pcpu_init(void);
+void qtiseclib_cb_ic_raise_sgi(int sgi_num, u_register_t target);
+void qtiseclib_cb_set_spi_routing(unsigned int id, unsigned int irm,
+				  u_register_t target);
+/* Crash reporting api's wrappers */
+void qtiseclib_cb_switch_console_to_crash_state(void);
+
+void qtiseclib_cb_udelay(uint32_t usec);
+
+#if QTI_SDI_BUILD
+int qtiseclib_cb_mmap_remove_dynamic_region(uintptr_t base_va, size_t size);
+int qtiseclib_cb_mmap_add_dynamic_region(unsigned long long base_pa,
+					 size_t size,
+					 qtiseclib_mmap_attr_t attr);
+
+void qtiseclib_cb_flush_dcache_all(void);
+void qtiseclib_cb_get_ns_ctx(qtiseclib_dbg_a64_ctxt_regs_type *ns_ctx);
+#endif
+
+#endif /* QTISECLIB_CB_INTERFACE_H */
diff --git a/plat/qti/qtiseclib/inc/qtiseclib_defs.h b/plat/qti/qtiseclib/inc/qtiseclib_defs.h
new file mode 100644
index 0000000..2afefe1
--- /dev/null
+++ b/plat/qti/qtiseclib/inc/qtiseclib_defs.h
@@ -0,0 +1,104 @@
+/*
+ * Copyright (c) 2018-2020, The Linux Foundation. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef QTISECLIB_DEFS_H
+#define QTISECLIB_DEFS_H
+
+#include <stdint.h>
+
+#ifndef u_register_t
+typedef uintptr_t u_register_t;
+#endif
+
+/*
+ * Different Log Level supported in qtiseclib.
+ * TODO: Currently no filtering done on QTISECLIB logs.
+ */
+#define QTISECLIB_LOG_LEVEL_NONE	0
+#define QTISECLIB_LOG_LEVEL_ERROR	10
+#define QTISECLIB_LOG_LEVEL_NOTICE	20
+#define QTISECLIB_LOG_LEVEL_WARNING	30
+#define QTISECLIB_LOG_LEVEL_INFO	40
+#define QTISECLIB_LOG_LEVEL_VERBOSE	50
+
+#define QTI_GICV3_IRM_PE		0
+#define QTI_GICV3_IRM_ANY		1
+
+/* Common interrupt number/ID defs. */
+#define QTISECLIB_INT_ID_RESET_SGI			(0xf)
+#define QTISECLIB_INT_ID_CPU_WAKEUP_SGI			(0x8)
+
+#define	QTISECLIB_INT_INVALID_INT_NUM			(0xFFFFFFFFU)
+
+typedef struct qtiseclib_cb_spinlock {
+	volatile uint32_t lock;
+} qtiseclib_cb_spinlock_t;
+
+#if QTI_SDI_BUILD
+/* External CPU Dump Structure - 64 bit EL */
+typedef struct {
+	uint64_t x0;
+	uint64_t x1;
+	uint64_t x2;
+	uint64_t x3;
+	uint64_t x4;
+	uint64_t x5;
+	uint64_t x6;
+	uint64_t x7;
+	uint64_t x8;
+	uint64_t x9;
+	uint64_t x10;
+	uint64_t x11;
+	uint64_t x12;
+	uint64_t x13;
+	uint64_t x14;
+	uint64_t x15;
+	uint64_t x16;
+	uint64_t x17;
+	uint64_t x18;
+	uint64_t x19;
+	uint64_t x20;
+	uint64_t x21;
+	uint64_t x22;
+	uint64_t x23;
+	uint64_t x24;
+	uint64_t x25;
+	uint64_t x26;
+	uint64_t x27;
+	uint64_t x28;
+	uint64_t x29;
+	uint64_t x30;
+	uint64_t pc;
+	uint64_t currentEL;
+	uint64_t sp_el3;
+	uint64_t elr_el3;
+	uint64_t spsr_el3;
+	uint64_t sp_el2;
+	uint64_t elr_el2;
+	uint64_t spsr_el2;
+	uint64_t sp_el1;
+	uint64_t elr_el1;
+	uint64_t spsr_el1;
+	uint64_t sp_el0;
+	uint64_t __reserved1;
+	uint64_t __reserved2;
+	uint64_t __reserved3;
+	uint64_t __reserved4;
+	uint64_t __reserved5;
+	uint64_t __reserved6;
+	uint64_t __reserved7;
+	uint64_t __reserved8;
+} qtiseclib_dbg_a64_ctxt_regs_type;
+
+typedef enum qtiseclib_mmap_attr_s {
+	QTISECLIB_MAP_NS_RO_XN_DATA = 1,
+	QTISECLIB_MAP_RW_XN_NC_DATA = 2,
+	QTISECLIB_MAP_RW_XN_DATA = 3,
+} qtiseclib_mmap_attr_t;
+
+#endif /* QTI_SDI_BUILD */
+
+#endif /* QTISECLIB_DEFS_H */
diff --git a/plat/qti/qtiseclib/inc/qtiseclib_interface.h b/plat/qti/qtiseclib/inc/qtiseclib_interface.h
new file mode 100644
index 0000000..edabc5b
--- /dev/null
+++ b/plat/qti/qtiseclib/inc/qtiseclib_interface.h
@@ -0,0 +1,88 @@
+/*
+ * Copyright (c) 2018-2020, The Linux Foundation. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef QTISECLIB_INTERFACE_H
+#define QTISECLIB_INTERFACE_H
+
+#include <stdbool.h>
+#include <stdint.h>
+
+#include <qtiseclib_defs.h>
+
+typedef struct memprot_ipa_info_s {
+	uint64_t mem_addr;
+	uint64_t mem_size;
+} memprot_info_t;
+
+typedef struct memprot_dst_vm_perm_info_s {
+	uint32_t dst_vm;
+	uint32_t dst_vm_perm;
+	uint64_t ctx;
+	uint32_t ctx_size;
+} memprot_dst_vm_perm_info_t;
+
+/*
+ * QTISECLIB Published API's.
+ */
+
+/*
+ * Assembly API's
+ */
+
+/*
+ * CPUSS common reset handler for all CPU wake up (both cold & warm boot).
+ * Executes on all core. This API assume serialization across CPU
+ * already taken care before invoking.
+ *
+ * Clobbers: x0 - x17, x30
+ */
+void qtiseclib_cpuss_reset_asm(uint32_t bl31_cold_boot_state);
+
+/*
+ * Execute CPU (Kryo4 gold) specific reset handler / system initialization.
+ * This takes care of executing required CPU errata's.
+ *
+ * Clobbers: x0 - x16
+ */
+void qtiseclib_kryo4_gold_reset_asm(void);
+
+/*
+ * Execute CPU (Kryo4 silver) specific reset handler / system initialization.
+ * This takes care of executing required CPU errata's.
+ *
+ * Clobbers: x0 - x16
+ */
+void qtiseclib_kryo4_silver_reset_asm(void);
+
+/*
+ * C Api's
+ */
+void qtiseclib_bl31_platform_setup(void);
+void qtiseclib_invoke_isr(uint32_t irq, void *handle);
+void qtiseclib_panic(void);
+int qtiseclib_prng_get_data(uint8_t *out, uint32_t out_len);
+
+int qtiseclib_mem_assign(const memprot_info_t *mem_info,
+			 uint32_t mem_info_list_cnt,
+			 const uint32_t *source_vm_list,
+			 uint32_t src_vm_list_cnt,
+			 const memprot_dst_vm_perm_info_t *dest_vm_list,
+			 uint32_t dst_vm_list_cnt);
+
+int qtiseclib_psci_init(uintptr_t warmboot_entry);
+int qtiseclib_psci_node_power_on(u_register_t mpidr);
+void qtiseclib_psci_node_on_finish(const uint8_t *states);
+void qtiseclib_psci_cpu_standby(uint8_t pwr_state);
+void qtiseclib_psci_node_power_off(const uint8_t *states);
+void qtiseclib_psci_node_suspend(const uint8_t *states);
+void qtiseclib_psci_node_suspend_finish(const uint8_t *states);
+__attribute__ ((noreturn))
+void qtiseclib_psci_system_off(void);
+__attribute__ ((noreturn))
+void qtiseclib_psci_system_reset(void);
+void qtiseclib_disable_cluster_coherency(uint8_t state);
+
+#endif /* QTISECLIB_INTERFACE_H */
diff --git a/plat/qti/qtiseclib/inc/sc7180/qtiseclib_defs_plat.h b/plat/qti/qtiseclib/inc/sc7180/qtiseclib_defs_plat.h
new file mode 100644
index 0000000..c695c19
--- /dev/null
+++ b/plat/qti/qtiseclib/inc/sc7180/qtiseclib_defs_plat.h
@@ -0,0 +1,41 @@
+/*
+ * Copyright (c) 2018-2020, The Linux Foundation. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef QTISECLIB_DEFS_PLAT_H
+#define QTISECLIB_DEFS_PLAT_H
+
+#define QTISECLIB_PLAT_CLUSTER_COUNT	1
+#define QTISECLIB_PLAT_CORE_COUNT	8
+
+#define BL31_BASE						0x80b00000
+#define BL31_SIZE						0x00100000
+
+/*----------------------------------------------------------------------------*/
+/* AOP CMD DB  address space for mapping */
+/*----------------------------------------------------------------------------*/
+#define QTI_AOP_CMD_DB_BASE			0x80820000
+#define QTI_AOP_CMD_DB_SIZE			0x00020000
+
+/* Chipset specific secure interrupt number/ID defs. */
+#define QTISECLIB_INT_ID_SEC_WDOG_BARK			(0x204)
+#define QTISECLIB_INT_ID_NON_SEC_WDOG_BITE		(0x21)
+
+#define QTISECLIB_INT_ID_VMIDMT_ERR_CLT_SEC		(0xE6)
+#define QTISECLIB_INT_ID_VMIDMT_ERR_CLT_NONSEC		(0xE7)
+#define QTISECLIB_INT_ID_VMIDMT_ERR_CFG_SEC		(0xE8)
+#define QTISECLIB_INT_ID_VMIDMT_ERR_CFG_NONSEC		(0xE9)
+
+#define QTISECLIB_INT_ID_XPU_SEC			(0xE3)
+#define QTISECLIB_INT_ID_XPU_NON_SEC			(0xE4)
+
+#define QTISECLIB_INT_ID_A2_NOC_ERROR			(0x194)
+#define QTISECLIB_INT_ID_CONFIG_NOC_ERROR		(0xE2)
+#define QTISECLIB_INT_ID_DC_NOC_ERROR			(0x122)
+#define QTISECLIB_INT_ID_MEM_NOC_ERROR			(0x6C)
+#define QTISECLIB_INT_ID_SYSTEM_NOC_ERROR		(0xC6)
+#define QTISECLIB_INT_ID_MMSS_NOC_ERROR			(0xBA)
+
+#endif /* QTISECLIB_DEFS_PLAT_H */
diff --git a/plat/qti/qtiseclib/src/qtiseclib_cb_interface.c b/plat/qti/qtiseclib/src/qtiseclib_cb_interface.c
new file mode 100644
index 0000000..1b1393e
--- /dev/null
+++ b/plat/qti/qtiseclib/src/qtiseclib_cb_interface.c
@@ -0,0 +1,187 @@
+/*
+ * Copyright (c) 2018-2020, The Linux Foundation. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+#include <assert.h>
+#include <stdarg.h>
+#include <stdint.h>
+#include <stdio.h>
+#include <string.h>
+
+#include <arch.h>
+#include <arch_helpers.h>
+#include <bl31/bl31.h>
+#include <context.h>
+#include <drivers/arm/gicv3.h>
+#include <drivers/delay_timer.h>
+#include <lib/coreboot.h>
+#include <lib/el3_runtime/context_mgmt.h>
+#include <lib/spinlock.h>
+#include <lib/xlat_tables/xlat_tables_v2.h>
+
+#include <platform.h>
+#include <qti_plat.h>
+#include <qtiseclib_cb_interface.h>
+
+void *qtiseclib_cb_memcpy(void *dst, const void *src, size_t len)
+{
+	return memcpy(dst, src, len);
+}
+
+/* Printing logs below or equal LOG_LEVEL from QTISECLIB. */
+void qtiseclib_cb_log(unsigned int loglvl, const char *fmt, ...)
+{
+	if (loglvl <= LOG_LEVEL) {
+		va_list argp;
+		static spinlock_t qti_log_lock;
+		uint64_t uptime = read_cntpct_el0();
+
+		va_start(argp, fmt);
+
+		spin_lock(&qti_log_lock);
+		printf("QTISECLIB [%x%08x]",
+		       (uint32_t) ((uptime >> 32) & 0xFFFFFFFF),
+		       (uint32_t) (uptime & 0xFFFFFFFF));
+		vprintf(fmt, argp);
+		putchar('\n');
+		spin_unlock(&qti_log_lock);
+
+		va_end(argp);
+	}
+}
+
+void qtiseclib_cb_spin_lock(qtiseclib_cb_spinlock_t *lock)
+{
+	spin_lock((spinlock_t *) lock);
+}
+
+void qtiseclib_cb_spin_unlock(qtiseclib_cb_spinlock_t *lock)
+{
+	spin_unlock((spinlock_t *) lock);
+}
+
+unsigned int qtiseclib_cb_plat_my_core_pos(void)
+{
+	return plat_my_core_pos();
+}
+
+int qtiseclib_cb_plat_core_pos_by_mpidr(u_register_t mpidr)
+{
+	return plat_core_pos_by_mpidr(mpidr);
+}
+
+unsigned int qtiseclib_cb_plat_my_cluster_pos(void)
+{
+	return plat_qti_my_cluster_pos();
+}
+
+/* GIC platform functions */
+void qtiseclib_cb_gic_pcpu_init(void)
+{
+	plat_qti_gic_pcpu_init();
+}
+
+void qtiseclib_cb_ic_raise_sgi(int sgi_num, u_register_t target)
+{
+	plat_ic_raise_el3_sgi(sgi_num, target);
+}
+
+void qtiseclib_cb_set_spi_routing(unsigned int id, unsigned int irm,
+				  u_register_t target)
+{
+	assert(QTI_GICV3_IRM_PE == GICV3_IRM_PE);
+	assert(QTI_GICV3_IRM_ANY == GICV3_IRM_ANY);
+	gic_set_spi_routing(id, irm, target);
+}
+
+/* Crash reporting api's wrappers */
+void qtiseclib_cb_switch_console_to_crash_state(void)
+{
+	console_switch_state(CONSOLE_FLAG_CRASH);
+}
+
+void qtiseclib_cb_udelay(uint32_t usec)
+{
+	udelay(usec);
+}
+
+#if QTI_SDI_BUILD
+void qtiseclib_cb_get_ns_ctx(qtiseclib_dbg_a64_ctxt_regs_type *qti_ns_ctx)
+{
+	void *ctx;
+
+	ctx = cm_get_context(NON_SECURE);
+
+	qti_ns_ctx->spsr_el3 =
+	    read_ctx_reg(get_el3state_ctx(ctx), CTX_SPSR_EL3);
+	qti_ns_ctx->elr_el3 = read_ctx_reg(get_el3state_ctx(ctx), CTX_ELR_EL3);
+
+	qti_ns_ctx->spsr_el1 =
+	    read_ctx_reg(get_el1_sysregs_ctx(ctx), CTX_SPSR_EL1);
+	qti_ns_ctx->elr_el1 =
+	    read_ctx_reg(get_el1_sysregs_ctx(ctx), CTX_ELR_EL1);
+	qti_ns_ctx->sp_el1 = read_ctx_reg(get_el1_sysregs_ctx(ctx), CTX_SP_EL1);
+
+	qti_ns_ctx->x0 = read_ctx_reg(get_gpregs_ctx(ctx), CTX_GPREG_X0);
+	qti_ns_ctx->x1 = read_ctx_reg(get_gpregs_ctx(ctx), CTX_GPREG_X1);
+	qti_ns_ctx->x2 = read_ctx_reg(get_gpregs_ctx(ctx), CTX_GPREG_X2);
+	qti_ns_ctx->x3 = read_ctx_reg(get_gpregs_ctx(ctx), CTX_GPREG_X3);
+	qti_ns_ctx->x4 = read_ctx_reg(get_gpregs_ctx(ctx), CTX_GPREG_X4);
+	qti_ns_ctx->x5 = read_ctx_reg(get_gpregs_ctx(ctx), CTX_GPREG_X5);
+	qti_ns_ctx->x6 = read_ctx_reg(get_gpregs_ctx(ctx), CTX_GPREG_X6);
+	qti_ns_ctx->x7 = read_ctx_reg(get_gpregs_ctx(ctx), CTX_GPREG_X7);
+	qti_ns_ctx->x8 = read_ctx_reg(get_gpregs_ctx(ctx), CTX_GPREG_X8);
+	qti_ns_ctx->x9 = read_ctx_reg(get_gpregs_ctx(ctx), CTX_GPREG_X9);
+	qti_ns_ctx->x10 = read_ctx_reg(get_gpregs_ctx(ctx), CTX_GPREG_X10);
+	qti_ns_ctx->x11 = read_ctx_reg(get_gpregs_ctx(ctx), CTX_GPREG_X11);
+	qti_ns_ctx->x12 = read_ctx_reg(get_gpregs_ctx(ctx), CTX_GPREG_X12);
+	qti_ns_ctx->x13 = read_ctx_reg(get_gpregs_ctx(ctx), CTX_GPREG_X13);
+	qti_ns_ctx->x14 = read_ctx_reg(get_gpregs_ctx(ctx), CTX_GPREG_X14);
+	qti_ns_ctx->x15 = read_ctx_reg(get_gpregs_ctx(ctx), CTX_GPREG_X15);
+	qti_ns_ctx->x16 = read_ctx_reg(get_gpregs_ctx(ctx), CTX_GPREG_X16);
+	qti_ns_ctx->x17 = read_ctx_reg(get_gpregs_ctx(ctx), CTX_GPREG_X17);
+	qti_ns_ctx->x18 = read_ctx_reg(get_gpregs_ctx(ctx), CTX_GPREG_X18);
+	qti_ns_ctx->x19 = read_ctx_reg(get_gpregs_ctx(ctx), CTX_GPREG_X19);
+	qti_ns_ctx->x20 = read_ctx_reg(get_gpregs_ctx(ctx), CTX_GPREG_X20);
+	qti_ns_ctx->x21 = read_ctx_reg(get_gpregs_ctx(ctx), CTX_GPREG_X21);
+	qti_ns_ctx->x22 = read_ctx_reg(get_gpregs_ctx(ctx), CTX_GPREG_X22);
+	qti_ns_ctx->x23 = read_ctx_reg(get_gpregs_ctx(ctx), CTX_GPREG_X23);
+	qti_ns_ctx->x24 = read_ctx_reg(get_gpregs_ctx(ctx), CTX_GPREG_X24);
+	qti_ns_ctx->x25 = read_ctx_reg(get_gpregs_ctx(ctx), CTX_GPREG_X25);
+	qti_ns_ctx->x26 = read_ctx_reg(get_gpregs_ctx(ctx), CTX_GPREG_X26);
+	qti_ns_ctx->x27 = read_ctx_reg(get_gpregs_ctx(ctx), CTX_GPREG_X27);
+	qti_ns_ctx->x28 = read_ctx_reg(get_gpregs_ctx(ctx), CTX_GPREG_X28);
+	qti_ns_ctx->x29 = read_ctx_reg(get_gpregs_ctx(ctx), CTX_GPREG_X29);
+	qti_ns_ctx->x30 = read_ctx_reg(get_gpregs_ctx(ctx), CTX_GPREG_LR);
+	qti_ns_ctx->sp_el0 =
+	    read_ctx_reg(get_gpregs_ctx(ctx), CTX_GPREG_SP_EL0);
+}
+
+void qtiseclib_cb_flush_dcache_all(void)
+{
+	dcsw_op_all(DCCISW);
+}
+
+int qtiseclib_cb_mmap_add_dynamic_region(unsigned long long base_pa,
+					 size_t size,
+					 qtiseclib_mmap_attr_t attr)
+{
+	unsigned int l_attr = 0;
+
+	if (attr == QTISECLIB_MAP_NS_RO_XN_DATA) {
+		l_attr = MT_NS | MT_RO | MT_EXECUTE_NEVER;
+	} else if (attr == QTISECLIB_MAP_RW_XN_NC_DATA) {
+		l_attr = MT_RW | MT_NON_CACHEABLE | MT_EXECUTE_NEVER;
+	} else if (attr == QTISECLIB_MAP_RW_XN_DATA) {
+		l_attr = MT_RW | MT_EXECUTE_NEVER;
+	}
+	return qti_mmap_add_dynamic_region(base_pa, size, l_attr);
+}
+
+int qtiseclib_cb_mmap_remove_dynamic_region(uintptr_t base_va, size_t size)
+{
+	return qti_mmap_remove_dynamic_region(base_va, size);
+}
+#endif
+
diff --git a/plat/qti/qtiseclib/src/qtiseclib_interface_stub.c b/plat/qti/qtiseclib/src/qtiseclib_interface_stub.c
new file mode 100644
index 0000000..494083b
--- /dev/null
+++ b/plat/qti/qtiseclib/src/qtiseclib_interface_stub.c
@@ -0,0 +1,137 @@
+/*
+ * Copyright (c) 2020, The Linux Foundation. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <stdbool.h>
+#include <stdint.h>
+
+#include <common/debug.h>
+
+#include <qtiseclib_defs.h>
+#include <qtiseclib_interface.h>
+
+/*
+ * This file contains dummy implementation of QTISECLIB Published API's.
+ * which will be used to compile PLATFORM successfully when
+ * qtiseclib is not available
+ */
+
+/*
+ * CPUSS common reset handler for all CPU wake up (both cold & warm boot).
+ * Executes on all core. This API assume serialization across CPU
+ * already taken care before invoking.
+ *
+ * Clobbers: x0 - x17, x30
+ */
+void qtiseclib_cpuss_reset_asm(uint32_t bl31_cold_boot_state)
+{
+}
+
+/*
+ * Execute CPU (Kryo4 gold) specific reset handler / system initialization.
+ * This takes care of executing required CPU errata's.
+ *
+ * Clobbers: x0 - x16
+ */
+void qtiseclib_kryo4_gold_reset_asm(void)
+{
+}
+
+/*
+ * Execute CPU (Kryo4 silver) specific reset handler / system initialization.
+ * This takes care of executing required CPU errata's.
+ *
+ * Clobbers: x0 - x16
+ */
+void qtiseclib_kryo4_silver_reset_asm(void)
+{
+}
+
+/*
+ * C Api's
+ */
+void qtiseclib_bl31_platform_setup(void)
+{
+	ERROR("Please use QTISECLIB_PATH while building TF-A\n");
+	ERROR("Please refer docs/plat/qti.rst for more details.\n");
+	panic();
+}
+
+void qtiseclib_invoke_isr(uint32_t irq, void *handle)
+{
+}
+
+void qtiseclib_panic(void)
+{
+}
+
+int qtiseclib_prng_get_data(uint8_t *out, uint32_t out_len)
+{
+	/* fill dummy data to avoid assert and print
+	 * stub implementation in setup call
+	 */
+	for (int i = 0; i < out_len; i++) {
+		out[i] = 0x11;
+	}
+	return 0;
+}
+
+int
+qtiseclib_mem_assign(const memprot_info_t *mem_info,
+		     uint32_t mem_info_list_cnt,
+		     const uint32_t *source_vm_list,
+		     uint32_t src_vm_list_cnt,
+		     const memprot_dst_vm_perm_info_t *dest_vm_list,
+		     uint32_t dst_vm_list_cnt)
+{
+	return 0;
+}
+
+int qtiseclib_psci_init(uintptr_t warmboot_entry)
+{
+	return 0;
+}
+
+int qtiseclib_psci_node_power_on(u_register_t mpidr)
+{
+	return 0;
+}
+
+void qtiseclib_psci_node_on_finish(const uint8_t *states)
+{
+}
+
+void qtiseclib_psci_cpu_standby(uint8_t pwr_state)
+{
+}
+
+void qtiseclib_psci_node_power_off(const uint8_t *states)
+{
+}
+
+void qtiseclib_psci_node_suspend(const uint8_t *states)
+{
+}
+
+void qtiseclib_psci_node_suspend_finish(const uint8_t *states)
+{
+}
+
+void qtiseclib_psci_system_off(void)
+{
+	while (1) {
+	};
+}
+
+void qtiseclib_psci_system_reset(void)
+{
+	while (1) {
+	};
+}
+
+void qtiseclib_disable_cluster_coherency(uint8_t state)
+{
+}
+
diff --git a/plat/qti/sc7180/inc/platform_def.h b/plat/qti/sc7180/inc/platform_def.h
new file mode 100644
index 0000000..d95b365
--- /dev/null
+++ b/plat/qti/sc7180/inc/platform_def.h
@@ -0,0 +1,176 @@
+/*
+ * Copyright (c) 2018, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2018-2020, The Linux Foundation. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+#ifndef PLATFORM_DEF_H
+#define PLATFORM_DEF_H
+
+/* Enable the dynamic translation tables library. */
+#define PLAT_XLAT_TABLES_DYNAMIC	1
+
+#include <common_def.h>
+
+#include <qti_board_def.h>
+#include <qtiseclib_defs_plat.h>
+
+/*----------------------------------------------------------------------------*/
+
+/*----------------------------------------------------------------------------*/
+/*
+ * MPIDR_PRIMARY_CPU
+ * You just need to have the correct core_affinity_val i.e. [7:0]
+ * and cluster_affinity_val i.e. [15:8]
+ * the other bits will be ignored
+ */
+/*----------------------------------------------------------------------------*/
+#define MPIDR_PRIMARY_CPU	0x0000
+/*----------------------------------------------------------------------------*/
+
+#define QTI_PWR_LVL0		MPIDR_AFFLVL0
+#define QTI_PWR_LVL1		MPIDR_AFFLVL1
+#define QTI_PWR_LVL2		MPIDR_AFFLVL2
+#define QTI_PWR_LVL3		MPIDR_AFFLVL3
+
+/*
+ *  Macros for local power states encoded by State-ID field
+ *  within the power-state parameter.
+ */
+/* Local power state for power domains in Run state. */
+#define QTI_LOCAL_STATE_RUN	0
+/*
+ * Local power state for clock-gating. Valid only for CPU and not cluster power
+ * domains
+ */
+#define QTI_LOCAL_STATE_STB	1
+/*
+ * Local power state for retention. Valid for CPU and cluster power
+ * domains
+ */
+#define QTI_LOCAL_STATE_RET	2
+/*
+ * Local power state for OFF/power down. Valid for CPU, cluster, RSC and PDC
+ * power domains
+ */
+#define QTI_LOCAL_STATE_OFF	3
+/*
+ * Local power state for DEEPOFF/power rail down. Valid for CPU, cluster and RSC
+ * power domains
+ */
+#define QTI_LOCAL_STATE_DEEPOFF	4
+
+/*
+ * This macro defines the deepest retention state possible. A higher state
+ * id will represent an invalid or a power down state.
+ */
+#define PLAT_MAX_RET_STATE	QTI_LOCAL_STATE_RET
+
+/*
+ * This macro defines the deepest power down states possible. Any state ID
+ * higher than this is invalid.
+ */
+#define PLAT_MAX_OFF_STATE	QTI_LOCAL_STATE_DEEPOFF
+
+/******************************************************************************
+ * Required platform porting definitions common to all ARM standard platforms
+ *****************************************************************************/
+
+/*
+ * Platform specific page table and MMU setup constants.
+ */
+#define MAX_MMAP_REGIONS	(PLAT_QTI_MMAP_ENTRIES)
+
+#define PLAT_PHY_ADDR_SPACE_SIZE	(1ull << 36)
+#define PLAT_VIRT_ADDR_SPACE_SIZE	(1ull << 36)
+
+#define ARM_CACHE_WRITEBACK_SHIFT	6
+
+/*
+ * Some data must be aligned on the biggest cache line size in the platform.
+ * This is known only to the platform as it might have a combination of
+ * integrated and external caches.
+ */
+#define CACHE_WRITEBACK_GRANULE		(1 << ARM_CACHE_WRITEBACK_SHIFT)
+
+/*
+ * One cache line needed for bakery locks on ARM platforms
+ */
+#define PLAT_PERCPU_BAKERY_LOCK_SIZE	(1 * CACHE_WRITEBACK_GRANULE)
+
+/*----------------------------------------------------------------------------*/
+/* PSCI power domain topology definitions */
+/*----------------------------------------------------------------------------*/
+/* One domain each to represent RSC and PDC level */
+#define PLAT_PDC_COUNT			1
+#define PLAT_RSC_COUNT			1
+
+/* There is one top-level FCM cluster */
+#define PLAT_CLUSTER_COUNT		1
+
+/* No. of cores in the FCM cluster */
+#define PLAT_CLUSTER0_CORE_COUNT	8
+
+#define PLATFORM_CORE_COUNT		(PLAT_CLUSTER0_CORE_COUNT)
+
+#define PLAT_NUM_PWR_DOMAINS		(PLAT_PDC_COUNT +\
+					PLAT_RSC_COUNT	+\
+					PLAT_CLUSTER_COUNT	+\
+					PLATFORM_CORE_COUNT)
+
+#define PLAT_MAX_PWR_LVL		3
+
+/*****************************************************************************/
+/* Memory mapped Generic timer interfaces  */
+/*****************************************************************************/
+
+/*----------------------------------------------------------------------------*/
+/* GIC-600 constants */
+/*----------------------------------------------------------------------------*/
+#define BASE_GICD_BASE		0x17A00000
+#define BASE_GICR_BASE		0x17A60000
+#define BASE_GICC_BASE		0x0
+#define BASE_GICH_BASE		0x0
+#define BASE_GICV_BASE		0x0
+
+#define QTI_GICD_BASE		BASE_GICD_BASE
+#define QTI_GICR_BASE		BASE_GICR_BASE
+#define QTI_GICC_BASE		BASE_GICC_BASE
+
+/*----------------------------------------------------------------------------*/
+
+/*----------------------------------------------------------------------------*/
+/* UART related constants. */
+/*----------------------------------------------------------------------------*/
+/* BASE ADDRESS OF DIFFERENT REGISTER SPACES IN HW */
+#define GENI4_CFG				0x0
+#define GENI4_IMAGE_REGS			0x100
+#define GENI4_DATA				0x600
+
+/* COMMON STATUS/CONFIGURATION REGISTERS AND MASKS */
+#define GENI_STATUS_REG				(GENI4_CFG + 0x00000040)
+#define GENI_STATUS_M_GENI_CMD_ACTIVE_MASK	(0x1)
+#define UART_TX_TRANS_LEN_REG			(GENI4_IMAGE_REGS + 0x00000170)
+/* MASTER/TX ENGINE REGISTERS */
+#define GENI_M_CMD0_REG				(GENI4_DATA + 0x00000000)
+/* FIFO, STATUS REGISTERS AND MASKS */
+#define GENI_TX_FIFOn_REG			(GENI4_DATA + 0x00000100)
+
+#define GENI_M_CMD_TX				(0x08000000)
+
+/*----------------------------------------------------------------------------*/
+/* Device address space for mapping. Excluding starting 4K */
+/*----------------------------------------------------------------------------*/
+#define QTI_DEVICE_BASE				0x1000
+#define QTI_DEVICE_SIZE				(0x80000000 - QTI_DEVICE_BASE)
+
+/*******************************************************************************
+ * BL31 specific defines.
+ ******************************************************************************/
+/*
+ * Put BL31 at DDR as per memory map. BL31_BASE is calculated using the
+ * current BL31 debug size plus a little space for growth.
+ */
+#define BL31_LIMIT				(BL31_BASE + BL31_SIZE)
+
+#endif /* PLATFORM_DEF_H */
diff --git a/plat/qti/sc7180/inc/qti_secure_io_cfg.h b/plat/qti/sc7180/inc/qti_secure_io_cfg.h
new file mode 100644
index 0000000..3de636d
--- /dev/null
+++ b/plat/qti/sc7180/inc/qti_secure_io_cfg.h
@@ -0,0 +1,30 @@
+/*
+ * Copyright (c) 2019-2020, The Linux Foundation. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+#ifndef QTI_SECURE_IO_CFG_H
+#define QTI_SECURE_IO_CFG_H
+
+#include <stdint.h>
+
+/*
+ * List of peripheral/IO memory areas that are protected from
+ * non-secure world but not required to be secure.
+ */
+
+#define APPS_SMMU_TBU_PWR_STATUS		0x15002204
+#define APPS_SMMU_CUSTOM_CFG			0x15002300
+#define APPS_SMMU_STATS_SYNC_INV_TBU_ACK	0x150025DC
+#define APPS_SMMU_SAFE_SEC_CFG			0x15002648
+#define APPS_SMMU_MMU2QSS_AND_SAFE_WAIT_CNTR	0x15002670
+
+static const uintptr_t qti_secure_io_allowed_regs[] = {
+	APPS_SMMU_TBU_PWR_STATUS,
+	APPS_SMMU_CUSTOM_CFG,
+	APPS_SMMU_STATS_SYNC_INV_TBU_ACK,
+	APPS_SMMU_SAFE_SEC_CFG,
+	APPS_SMMU_MMU2QSS_AND_SAFE_WAIT_CNTR,
+};
+
+#endif /* QTI_SECURE_IO_CFG_H */
diff --git a/plat/qti/sc7180/platform.mk b/plat/qti/sc7180/platform.mk
new file mode 100644
index 0000000..45e6b33
--- /dev/null
+++ b/plat/qti/sc7180/platform.mk
@@ -0,0 +1,116 @@
+#
+# Copyright (c) 2017-2018, ARM Limited and Contributors. All rights reserved.
+# Copyright (c) 2018-2020, The Linux Foundation. All rights reserved.
+#
+# SPDX-License-Identifier: BSD-3-Clause
+#
+
+# Make for SC7180 QTI platform.
+
+QTI_PLAT_PATH		:=	plat/qti
+CHIPSET			:=	${PLAT}
+
+# Turn On Separate code & data.
+SEPARATE_CODE_AND_RODATA	:=	1
+USE_COHERENT_MEM		:=	1
+WARMBOOT_ENABLE_DCACHE_EARLY	:=	1
+
+# Disable the PSCI platform compatibility layer
+ENABLE_PLAT_COMPAT		:=	0
+
+# Enable PSCI v1.0 extended state ID format
+PSCI_EXTENDED_STATE_ID	:=  1
+ARM_RECOM_STATE_ID_ENC  :=  1
+
+COLD_BOOT_SINGLE_CPU		:=	1
+PROGRAMMABLE_RESET_ADDRESS	:=	1
+
+RESET_TO_BL31			:=	0
+
+MULTI_CONSOLE_API		:=	1
+
+QTI_SDI_BUILD := 0
+$(eval $(call assert_boolean,QTI_SDI_BUILD))
+$(eval $(call add_define,QTI_SDI_BUILD))
+
+#disable CTX_INCLUDE_AARCH32_REGS to support sc7180 gold cores
+override CTX_INCLUDE_AARCH32_REGS	:=	0
+WORKAROUND_CVE_2017_5715		:=      0
+DYNAMIC_WORKAROUND_CVE_2018_3639	:=      1
+# Enable stack protector.
+ENABLE_STACK_PROTECTOR := strong
+
+
+QTI_EXTERNAL_INCLUDES	:=	-I${QTI_PLAT_PATH}/${CHIPSET}/inc			\
+				-I${QTI_PLAT_PATH}/common/inc				\
+				-I${QTI_PLAT_PATH}/common/inc/$(ARCH)			\
+				-I${QTI_PLAT_PATH}/qtiseclib/inc			\
+				-I${QTI_PLAT_PATH}/qtiseclib/inc/${CHIPSET}			\
+
+QTI_BL31_SOURCES	:=	$(QTI_PLAT_PATH)/common/src/$(ARCH)/qti_helpers.S	\
+				$(QTI_PLAT_PATH)/common/src/$(ARCH)/qti_kryo4_silver.S	\
+				$(QTI_PLAT_PATH)/common/src/$(ARCH)/qti_kryo4_gold.S	\
+				$(QTI_PLAT_PATH)/common/src/$(ARCH)/qti_uart_console.S	\
+				$(QTI_PLAT_PATH)/common/src/qti_stack_protector.c	\
+				$(QTI_PLAT_PATH)/common/src/qti_common.c		\
+				$(QTI_PLAT_PATH)/common/src/qti_bl31_setup.c		\
+				$(QTI_PLAT_PATH)/common/src/qti_gic_v3.c		\
+				$(QTI_PLAT_PATH)/common/src/qti_interrupt_svc.c		\
+				$(QTI_PLAT_PATH)/common/src/qti_syscall.c		\
+				$(QTI_PLAT_PATH)/common/src/qti_topology.c		\
+				$(QTI_PLAT_PATH)/common/src/qti_pm.c			\
+				$(QTI_PLAT_PATH)/qtiseclib/src/qtiseclib_cb_interface.c	\
+
+
+PLAT_INCLUDES		:=	-Iinclude/plat/common/					\
+
+PLAT_INCLUDES		+=	${QTI_EXTERNAL_INCLUDES}
+
+include lib/xlat_tables_v2/xlat_tables.mk
+PLAT_BL_COMMON_SOURCES	+=	${XLAT_TABLES_LIB_SRCS}					\
+				plat/common/aarch64/crash_console_helpers.S    \
+				common/desc_image_load.c			\
+				lib/bl_aux_params/bl_aux_params.c		\
+
+include lib/coreboot/coreboot.mk
+
+#PSCI Sources.
+PSCI_SOURCES		:=	plat/common/plat_psci_common.c				\
+
+# GIC-600 configuration
+GICV3_IMPL			:=	GIC600
+# Include GICv3 driver files
+include drivers/arm/gic/v3/gicv3.mk
+
+#Timer sources
+TIMER_SOURCES		:=	drivers/delay_timer/generic_delay_timer.c	\
+				drivers/delay_timer/delay_timer.c		\
+
+#GIC sources.
+GIC_SOURCES		:=	plat/common/plat_gicv3.c			\
+				${GICV3_SOURCES}				\
+
+BL31_SOURCES		+=	${QTI_BL31_SOURCES}					\
+				${PSCI_SOURCES}						\
+				${GIC_SOURCES}						\
+				${TIMER_SOURCES}					\
+
+LIB_QTI_PATH	:=	${QTI_PLAT_PATH}/qtiseclib/lib/${CHIPSET}
+
+
+# Override this on the command line to point to the qtiseclib library which
+# will be available in coreboot.org
+QTISECLIB_PATH ?=
+
+ifeq ($(QTISECLIB_PATH),)
+# if No lib then use stub implementation for qtiseclib interface
+$(warning QTISECLIB_PATH is not provided while building, using stub implementation. \
+		Please refer docs/plat/qti.rst for more details \
+		THIS FIRMWARE WILL NOT BOOT!)
+BL31_SOURCES	+=	plat/qti/qtiseclib/src/qtiseclib_interface_stub.c
+else
+# use library provided by QTISECLIB_PATH
+LDFLAGS += -L $(dir $(QTISECLIB_PATH))
+LDLIBS += -l$(patsubst lib%.a,%,$(notdir $(QTISECLIB_PATH)))
+endif
+