Merge pull request #1494 from hzhuang1/pcie_pin

Hikey960: configure pins for PCIe controller
diff --git a/.gitignore b/.gitignore
index 7f8642e..78da669 100644
--- a/.gitignore
+++ b/.gitignore
@@ -19,6 +19,9 @@
 tools/cert_create/cert_create
 tools/cert_create/cert_create.exe
 tools/doimage/doimage
+tools/stm32image/*.o
+tools/stm32image/stm32image
+tools/stm32image/stm32image.exe
 
 # GNU GLOBAL files
 GPATH
diff --git a/acknowledgements.rst b/acknowledgements.rst
index 5686a58..4d527f4 100644
--- a/acknowledgements.rst
+++ b/acknowledgements.rst
@@ -16,5 +16,7 @@
 
 Marvell International Ltd.
 
+STMicroelectronics
+
 Individuals
 -----------
diff --git a/docs/plat/stm32mp1.rst b/docs/plat/stm32mp1.rst
new file mode 100644
index 0000000..9e731a4
--- /dev/null
+++ b/docs/plat/stm32mp1.rst
@@ -0,0 +1,82 @@
+Trusted Firmware-A for STM32MP1
+===============================
+
+STM32MP1 is a microprocessor designed by STMicroelectronics
+based on a dual Arm Cortex-A7.
+It is an Armv7-A platform, using dedicated code from TF-A.
+
+
+Design
+------
+The STM32MP1 resets in the ROM code of the Cortex-A7.
+The primary boot core (core 0) executes the boot sequence while
+secondary boot core (core 1) is kept in a holding pen loop.
+The ROM code boot sequence loads the TF-A binary image from boot device
+to embedded SRAM.
+
+The TF-A image must be properly formatted with a STM32 header structure
+for ROM code is able to load this image.
+Tool stm32image can be used to prepend this header to the generated TF-A binary.
+
+At compilation step, BL2, BL32 and DTB file are linked together in a single
+binary. The stm32image tool is also generated and the header is added to TF-A
+binary. This binary file with header is named tf-a-stm32mp157c-ev1.stm32.
+It can then be copied in the first partition of the boot device.
+
+
+Memory mapping
+~~~~~~~~~~~~~~
+
+::
+
+    0x00000000 +-----------------+
+               |                 |   ROM
+    0x00020000 +-----------------+
+               |                 |
+               |       ...       |
+               |                 |
+    0x2FFC0000 +-----------------+ \
+               |                 | |
+               |       ...       | |
+               |                 | |
+    0x2FFD8000 +-----------------+ |
+               |    TF-A DTB     | | Embedded SRAM
+    0x2FFDC000 +-----------------+ |
+               |       BL2       | |
+    0x2FFEF000 +-----------------+ |
+               |       BL32      | |
+    0x30000000 +-----------------+ /
+               |                 |
+               |       ...       |
+               |                 |
+    0x40000000 +-----------------+
+               |                 |
+               |                 |   Devices
+               |                 |
+    0xC0000000 +-----------------+ \
+               |                 | |
+    0xC0100000 +-----------------+ |
+               |       BL33      | | Non-secure RAM (DDR)
+               |       ...       | |
+               |                 | |
+    0xFFFFFFFF +-----------------+ /
+
+
+Boot sequence
+~~~~~~~~~~~~~
+
+ROM code -> BL2 (compiled with BL2_AT_EL3) -> BL32 (SP_min) -> BL33 (U-Boot)
+
+
+Build Instructions
+------------------
+
+To build:
+
+.. code:: bash
+
+    make CROSS_COMPILE=arm-linux-gnueabihf- PLAT=stm32mp1 ARCH=aarch32 ARM_ARCH_MAJOR=7 AARCH32_SP=sp_min
+
+The following build options are supported:
+
+- ``ENABLE_STACK_PROTECTOR``: To enable the stack protection.
diff --git a/docs/porting-guide.rst b/docs/porting-guide.rst
index a7a88f6..65f39b0 100644
--- a/docs/porting-guide.rst
+++ b/docs/porting-guide.rst
@@ -952,9 +952,9 @@
     Argument : void
     Return   : void
 
-This api allows a platform to disable the Accelerator Coherency Port (if
+This API allows a platform to disable the Accelerator Coherency Port (if
 present) during a cluster power down sequence. The default weak implementation
-doesn't do anything. Since this api is called during the power down sequence,
+doesn't do anything. Since this API is called during the power down sequence,
 it has restrictions for stack usage and it can use the registers x0 - x17 as
 scratch registers. It should preserve the value in x18 register as it is used
 by the caller to store the return address.
diff --git a/docs/user-guide.rst b/docs/user-guide.rst
index da26026..2b90bec 100644
--- a/docs/user-guide.rst
+++ b/docs/user-guide.rst
@@ -485,8 +485,8 @@
 -  ``LOAD_IMAGE_V2``: Boolean option to enable support for new version (v2) of
    image loading, which provides more flexibility and scalability around what
    images are loaded and executed during boot. Default is 0.
-   Note: ``TRUSTED_BOARD_BOOT`` is currently only supported for AArch64 when
-   ``LOAD_IMAGE_V2`` is enabled.
+
+   Note: this flag must be enabled for AArch32 builds.
 
 -  ``LOG_LEVEL``: Chooses the log level, which controls the amount of console log
    output compiled into the build. This should be one of the following:
diff --git a/drivers/st/clk/stm32mp1_clk.c b/drivers/st/clk/stm32mp1_clk.c
new file mode 100644
index 0000000..7dff98b
--- /dev/null
+++ b/drivers/st/clk/stm32mp1_clk.c
@@ -0,0 +1,1611 @@
+/*
+ * Copyright (C) 2018, STMicroelectronics - All Rights Reserved
+ *
+ * SPDX-License-Identifier: GPL-2.0+ OR BSD-3-Clause
+ */
+
+#include <arch.h>
+#include <arch_helpers.h>
+#include <assert.h>
+#include <debug.h>
+#include <delay_timer.h>
+#include <dt-bindings/clock/stm32mp1-clks.h>
+#include <dt-bindings/clock/stm32mp1-clksrc.h>
+#include <errno.h>
+#include <generic_delay_timer.h>
+#include <libfdt.h>
+#include <mmio.h>
+#include <platform.h>
+#include <stdint.h>
+#include <stm32mp1_clk.h>
+#include <stm32mp1_clkfunc.h>
+#include <stm32mp1_dt.h>
+#include <stm32mp1_private.h>
+#include <stm32mp1_rcc.h>
+#include <utils_def.h>
+
+#define MAX_HSI_HZ	64000000
+
+#define TIMEOUT_200MS	(plat_get_syscnt_freq2() / 5U)
+#define TIMEOUT_1S	plat_get_syscnt_freq2()
+
+#define PLLRDY_TIMEOUT	TIMEOUT_200MS
+#define CLKSRC_TIMEOUT	TIMEOUT_200MS
+#define CLKDIV_TIMEOUT	TIMEOUT_200MS
+#define HSIDIV_TIMEOUT	TIMEOUT_200MS
+#define OSCRDY_TIMEOUT	TIMEOUT_1S
+
+enum stm32mp1_parent_id {
+/* Oscillators are defined in enum stm32mp_osc_id */
+
+/* Other parent source */
+	_HSI_KER = NB_OSC,
+	_HSE_KER,
+	_HSE_KER_DIV2,
+	_CSI_KER,
+	_PLL1_P,
+	_PLL1_Q,
+	_PLL1_R,
+	_PLL2_P,
+	_PLL2_Q,
+	_PLL2_R,
+	_PLL3_P,
+	_PLL3_Q,
+	_PLL3_R,
+	_PLL4_P,
+	_PLL4_Q,
+	_PLL4_R,
+	_ACLK,
+	_PCLK1,
+	_PCLK2,
+	_PCLK3,
+	_PCLK4,
+	_PCLK5,
+	_HCLK6,
+	_HCLK2,
+	_CK_PER,
+	_CK_MPU,
+	_PARENT_NB,
+	_UNKNOWN_ID = 0xff,
+};
+
+enum stm32mp1_parent_sel {
+	_I2C46_SEL,
+	_UART6_SEL,
+	_UART24_SEL,
+	_UART35_SEL,
+	_UART78_SEL,
+	_SDMMC12_SEL,
+	_SDMMC3_SEL,
+	_QSPI_SEL,
+	_FMC_SEL,
+	_USBPHY_SEL,
+	_USBO_SEL,
+	_STGEN_SEL,
+	_PARENT_SEL_NB,
+	_UNKNOWN_SEL = 0xff,
+};
+
+enum stm32mp1_pll_id {
+	_PLL1,
+	_PLL2,
+	_PLL3,
+	_PLL4,
+	_PLL_NB
+};
+
+enum stm32mp1_div_id {
+	_DIV_P,
+	_DIV_Q,
+	_DIV_R,
+	_DIV_NB,
+};
+
+enum stm32mp1_clksrc_id {
+	CLKSRC_MPU,
+	CLKSRC_AXI,
+	CLKSRC_PLL12,
+	CLKSRC_PLL3,
+	CLKSRC_PLL4,
+	CLKSRC_RTC,
+	CLKSRC_MCO1,
+	CLKSRC_MCO2,
+	CLKSRC_NB
+};
+
+enum stm32mp1_clkdiv_id {
+	CLKDIV_MPU,
+	CLKDIV_AXI,
+	CLKDIV_APB1,
+	CLKDIV_APB2,
+	CLKDIV_APB3,
+	CLKDIV_APB4,
+	CLKDIV_APB5,
+	CLKDIV_RTC,
+	CLKDIV_MCO1,
+	CLKDIV_MCO2,
+	CLKDIV_NB
+};
+
+enum stm32mp1_pllcfg {
+	PLLCFG_M,
+	PLLCFG_N,
+	PLLCFG_P,
+	PLLCFG_Q,
+	PLLCFG_R,
+	PLLCFG_O,
+	PLLCFG_NB
+};
+
+enum stm32mp1_pllcsg {
+	PLLCSG_MOD_PER,
+	PLLCSG_INC_STEP,
+	PLLCSG_SSCG_MODE,
+	PLLCSG_NB
+};
+
+enum stm32mp1_plltype {
+	PLL_800,
+	PLL_1600,
+	PLL_TYPE_NB
+};
+
+struct stm32mp1_pll {
+	uint8_t refclk_min;
+	uint8_t refclk_max;
+	uint8_t divn_max;
+};
+
+struct stm32mp1_clk_gate {
+	uint16_t offset;
+	uint8_t bit;
+	uint8_t index;
+	uint8_t set_clr;
+	enum stm32mp1_parent_sel sel;
+	enum stm32mp1_parent_id fixed;
+	bool secure;
+};
+
+struct stm32mp1_clk_sel {
+	uint16_t offset;
+	uint8_t src;
+	uint8_t msk;
+	uint8_t nb_parent;
+	const uint8_t *parent;
+};
+
+#define REFCLK_SIZE 4
+struct stm32mp1_clk_pll {
+	enum stm32mp1_plltype plltype;
+	uint16_t rckxselr;
+	uint16_t pllxcfgr1;
+	uint16_t pllxcfgr2;
+	uint16_t pllxfracr;
+	uint16_t pllxcr;
+	uint16_t pllxcsgr;
+	enum stm32mp_osc_id refclk[REFCLK_SIZE];
+};
+
+struct stm32mp1_clk_data {
+	const struct stm32mp1_clk_gate *gate;
+	const struct stm32mp1_clk_sel *sel;
+	const struct stm32mp1_clk_pll *pll;
+	const int nb_gate;
+};
+
+struct stm32mp1_clk_priv {
+	uint32_t base;
+	const struct stm32mp1_clk_data *data;
+	unsigned long osc[NB_OSC];
+	uint32_t pkcs_usb_value;
+};
+
+#define STM32MP1_CLK(off, b, idx, s)			\
+	{						\
+		.offset = (off),			\
+		.bit = (b),				\
+		.index = (idx),				\
+		.set_clr = 0,				\
+		.sel = (s),				\
+		.fixed = _UNKNOWN_ID,			\
+		.secure = 0,				\
+	}
+
+#define STM32MP1_CLK_F(off, b, idx, f)			\
+	{						\
+		.offset = (off),			\
+		.bit = (b),				\
+		.index = (idx),				\
+		.set_clr = 0,				\
+		.sel = _UNKNOWN_SEL,			\
+		.fixed = (f),				\
+		.secure = 0,				\
+	}
+
+#define STM32MP1_CLK_SET_CLR(off, b, idx, s)		\
+	{						\
+		.offset = (off),			\
+		.bit = (b),				\
+		.index = (idx),				\
+		.set_clr = 1,				\
+		.sel = (s),				\
+		.fixed = _UNKNOWN_ID,			\
+		.secure = 0,				\
+	}
+
+#define STM32MP1_CLK_SET_CLR_F(off, b, idx, f)		\
+	{						\
+		.offset = (off),			\
+		.bit = (b),				\
+		.index = (idx),				\
+		.set_clr = 1,				\
+		.sel = _UNKNOWN_SEL,			\
+		.fixed = (f),				\
+		.secure = 0,				\
+	}
+
+#define STM32MP1_CLK_SEC_SET_CLR(off, b, idx, s)	\
+	{						\
+		.offset = (off),			\
+		.bit = (b),				\
+		.index = (idx),				\
+		.set_clr = 1,				\
+		.sel = (s),				\
+		.fixed = _UNKNOWN_ID,			\
+		.secure = 1,				\
+	}
+
+#define STM32MP1_CLK_PARENT(idx, off, s, m, p)		\
+	[(idx)] = {					\
+		.offset = (off),			\
+		.src = (s),				\
+		.msk = (m),				\
+		.parent = (p),				\
+		.nb_parent = ARRAY_SIZE((p))		\
+	}
+
+#define STM32MP1_CLK_PLL(idx, type, off1, off2, off3,	\
+			 off4, off5, off6,		\
+			 p1, p2, p3, p4)		\
+	[(idx)] = {					\
+		.plltype = (type),			\
+		.rckxselr = (off1),			\
+		.pllxcfgr1 = (off2),			\
+		.pllxcfgr2 = (off3),			\
+		.pllxfracr = (off4),			\
+		.pllxcr = (off5),			\
+		.pllxcsgr = (off6),			\
+		.refclk[0] = (p1),			\
+		.refclk[1] = (p2),			\
+		.refclk[2] = (p3),			\
+		.refclk[3] = (p4),			\
+	}
+
+static const uint8_t stm32mp1_clks[][2] = {
+	{CK_PER, _CK_PER},
+	{CK_MPU, _CK_MPU},
+	{CK_AXI, _ACLK},
+	{CK_HSE, _HSE},
+	{CK_CSI, _CSI},
+	{CK_LSI, _LSI},
+	{CK_LSE, _LSE},
+	{CK_HSI, _HSI},
+	{CK_HSE_DIV2, _HSE_KER_DIV2},
+};
+
+static const struct stm32mp1_clk_gate stm32mp1_clk_gate[] = {
+	STM32MP1_CLK(RCC_DDRITFCR, 0, DDRC1, _UNKNOWN_SEL),
+	STM32MP1_CLK(RCC_DDRITFCR, 1, DDRC1LP, _UNKNOWN_SEL),
+	STM32MP1_CLK(RCC_DDRITFCR, 2, DDRC2, _UNKNOWN_SEL),
+	STM32MP1_CLK(RCC_DDRITFCR, 3, DDRC2LP, _UNKNOWN_SEL),
+	STM32MP1_CLK_F(RCC_DDRITFCR, 4, DDRPHYC, _PLL2_R),
+	STM32MP1_CLK(RCC_DDRITFCR, 5, DDRPHYCLP, _UNKNOWN_SEL),
+	STM32MP1_CLK(RCC_DDRITFCR, 6, DDRCAPB, _UNKNOWN_SEL),
+	STM32MP1_CLK(RCC_DDRITFCR, 7, DDRCAPBLP, _UNKNOWN_SEL),
+	STM32MP1_CLK(RCC_DDRITFCR, 8, AXIDCG, _UNKNOWN_SEL),
+	STM32MP1_CLK(RCC_DDRITFCR, 9, DDRPHYCAPB, _UNKNOWN_SEL),
+	STM32MP1_CLK(RCC_DDRITFCR, 10, DDRPHYCAPBLP, _UNKNOWN_SEL),
+
+	STM32MP1_CLK_SET_CLR(RCC_MP_APB1ENSETR, 14, USART2_K, _UART24_SEL),
+	STM32MP1_CLK_SET_CLR(RCC_MP_APB1ENSETR, 15, USART3_K, _UART35_SEL),
+	STM32MP1_CLK_SET_CLR(RCC_MP_APB1ENSETR, 16, UART4_K, _UART24_SEL),
+	STM32MP1_CLK_SET_CLR(RCC_MP_APB1ENSETR, 17, UART5_K, _UART35_SEL),
+	STM32MP1_CLK_SET_CLR(RCC_MP_APB1ENSETR, 18, UART7_K, _UART78_SEL),
+	STM32MP1_CLK_SET_CLR(RCC_MP_APB1ENSETR, 19, UART8_K, _UART78_SEL),
+
+	STM32MP1_CLK_SET_CLR(RCC_MP_APB2ENSETR, 13, USART6_K, _UART6_SEL),
+
+	STM32MP1_CLK_SET_CLR(RCC_MP_APB4ENSETR, 8, DDRPERFM, _UNKNOWN_SEL),
+	STM32MP1_CLK_SET_CLR(RCC_MP_APB4ENSETR, 15, IWDG2, _UNKNOWN_SEL),
+	STM32MP1_CLK_SET_CLR(RCC_MP_APB4ENSETR, 16, USBPHY_K, _USBPHY_SEL),
+
+	STM32MP1_CLK_SEC_SET_CLR(RCC_MP_APB5ENSETR, 2, I2C4_K, _I2C46_SEL),
+	STM32MP1_CLK_SEC_SET_CLR(RCC_MP_APB5ENSETR, 8, RTCAPB, _PCLK5),
+	STM32MP1_CLK_SEC_SET_CLR(RCC_MP_APB5ENSETR, 11, TZC1, _UNKNOWN_SEL),
+	STM32MP1_CLK_SEC_SET_CLR(RCC_MP_APB5ENSETR, 12, TZC2, _UNKNOWN_SEL),
+	STM32MP1_CLK_SEC_SET_CLR(RCC_MP_APB5ENSETR, 20, STGEN_K, _STGEN_SEL),
+
+	STM32MP1_CLK_SET_CLR(RCC_MP_AHB2ENSETR, 8, USBO_K, _USBO_SEL),
+	STM32MP1_CLK_SET_CLR(RCC_MP_AHB2ENSETR, 16, SDMMC3_K, _SDMMC3_SEL),
+
+	STM32MP1_CLK_SET_CLR(RCC_MP_AHB4ENSETR, 0, GPIOA, _UNKNOWN_SEL),
+	STM32MP1_CLK_SET_CLR(RCC_MP_AHB4ENSETR, 1, GPIOB, _UNKNOWN_SEL),
+	STM32MP1_CLK_SET_CLR(RCC_MP_AHB4ENSETR, 2, GPIOC, _UNKNOWN_SEL),
+	STM32MP1_CLK_SET_CLR(RCC_MP_AHB4ENSETR, 3, GPIOD, _UNKNOWN_SEL),
+	STM32MP1_CLK_SET_CLR(RCC_MP_AHB4ENSETR, 4, GPIOE, _UNKNOWN_SEL),
+	STM32MP1_CLK_SET_CLR(RCC_MP_AHB4ENSETR, 5, GPIOF, _UNKNOWN_SEL),
+	STM32MP1_CLK_SET_CLR(RCC_MP_AHB4ENSETR, 6, GPIOG, _UNKNOWN_SEL),
+	STM32MP1_CLK_SET_CLR(RCC_MP_AHB4ENSETR, 7, GPIOH, _UNKNOWN_SEL),
+	STM32MP1_CLK_SET_CLR(RCC_MP_AHB4ENSETR, 8, GPIOI, _UNKNOWN_SEL),
+	STM32MP1_CLK_SET_CLR(RCC_MP_AHB4ENSETR, 9, GPIOJ, _UNKNOWN_SEL),
+	STM32MP1_CLK_SET_CLR(RCC_MP_AHB4ENSETR, 10, GPIOK, _UNKNOWN_SEL),
+
+	STM32MP1_CLK_SEC_SET_CLR(RCC_MP_AHB5ENSETR, 0, GPIOZ, _UNKNOWN_SEL),
+	STM32MP1_CLK_SEC_SET_CLR(RCC_MP_AHB5ENSETR, 5, HASH1, _UNKNOWN_SEL),
+	STM32MP1_CLK_SEC_SET_CLR(RCC_MP_AHB5ENSETR, 6, RNG1_K, _CSI_KER),
+	STM32MP1_CLK_SEC_SET_CLR(RCC_MP_AHB5ENSETR, 8, BKPSRAM, _UNKNOWN_SEL),
+
+	STM32MP1_CLK_SET_CLR(RCC_MP_AHB6ENSETR, 12, FMC_K, _FMC_SEL),
+	STM32MP1_CLK_SET_CLR(RCC_MP_AHB6ENSETR, 14, QSPI_K, _QSPI_SEL),
+	STM32MP1_CLK_SET_CLR(RCC_MP_AHB6ENSETR, 16, SDMMC1_K, _SDMMC12_SEL),
+	STM32MP1_CLK_SET_CLR(RCC_MP_AHB6ENSETR, 17, SDMMC2_K, _SDMMC12_SEL),
+	STM32MP1_CLK_SET_CLR(RCC_MP_AHB6ENSETR, 24, USBH, _UNKNOWN_SEL),
+
+	STM32MP1_CLK(RCC_DBGCFGR, 8, CK_DBG, _UNKNOWN_SEL),
+};
+
+static const uint8_t i2c46_parents[] = {_PCLK5, _PLL3_Q, _HSI_KER, _CSI_KER};
+static const uint8_t uart6_parents[] = {_PCLK2, _PLL4_Q, _HSI_KER, _CSI_KER,
+					_HSE_KER};
+static const uint8_t uart24_parents[] = {_PCLK1, _PLL4_Q, _HSI_KER, _CSI_KER,
+					 _HSE_KER};
+static const uint8_t uart35_parents[] = {_PCLK1, _PLL4_Q, _HSI_KER, _CSI_KER,
+					 _HSE_KER};
+static const uint8_t uart78_parents[] = {_PCLK1, _PLL4_Q, _HSI_KER, _CSI_KER,
+					 _HSE_KER};
+static const uint8_t sdmmc12_parents[] = {_HCLK6, _PLL3_R, _PLL4_P, _HSI_KER};
+static const uint8_t sdmmc3_parents[] = {_HCLK2, _PLL3_R, _PLL4_P, _HSI_KER};
+static const uint8_t qspi_parents[] = {_ACLK, _PLL3_R, _PLL4_P, _CK_PER};
+static const uint8_t fmc_parents[] = {_ACLK, _PLL3_R, _PLL4_P, _CK_PER};
+static const uint8_t usbphy_parents[] = {_HSE_KER, _PLL4_R, _HSE_KER_DIV2};
+static const uint8_t usbo_parents[] = {_PLL4_R, _USB_PHY_48};
+static const uint8_t stgen_parents[] = {_HSI_KER, _HSE_KER};
+
+static const struct stm32mp1_clk_sel stm32mp1_clk_sel[_PARENT_SEL_NB] = {
+	STM32MP1_CLK_PARENT(_I2C46_SEL, RCC_I2C46CKSELR, 0, 0x7, i2c46_parents),
+	STM32MP1_CLK_PARENT(_UART6_SEL, RCC_UART6CKSELR, 0, 0x7, uart6_parents),
+	STM32MP1_CLK_PARENT(_UART24_SEL, RCC_UART24CKSELR, 0, 0x7,
+			    uart24_parents),
+	STM32MP1_CLK_PARENT(_UART35_SEL, RCC_UART35CKSELR, 0, 0x7,
+			    uart35_parents),
+	STM32MP1_CLK_PARENT(_UART78_SEL, RCC_UART78CKSELR, 0, 0x7,
+			    uart78_parents),
+	STM32MP1_CLK_PARENT(_SDMMC12_SEL, RCC_SDMMC12CKSELR, 0, 0x7,
+			    sdmmc12_parents),
+	STM32MP1_CLK_PARENT(_SDMMC3_SEL, RCC_SDMMC3CKSELR, 0, 0x7,
+			    sdmmc3_parents),
+	STM32MP1_CLK_PARENT(_QSPI_SEL, RCC_QSPICKSELR, 0, 0xf, qspi_parents),
+	STM32MP1_CLK_PARENT(_FMC_SEL, RCC_FMCCKSELR, 0, 0xf, fmc_parents),
+	STM32MP1_CLK_PARENT(_USBPHY_SEL, RCC_USBCKSELR, 0, 0x3, usbphy_parents),
+	STM32MP1_CLK_PARENT(_USBO_SEL, RCC_USBCKSELR, 4, 0x1, usbo_parents),
+	STM32MP1_CLK_PARENT(_STGEN_SEL, RCC_STGENCKSELR, 0, 0x3, stgen_parents),
+};
+
+/* Define characteristic of PLL according type */
+#define DIVN_MIN	24
+static const struct stm32mp1_pll stm32mp1_pll[PLL_TYPE_NB] = {
+	[PLL_800] = {
+		.refclk_min = 4,
+		.refclk_max = 16,
+		.divn_max = 99,
+	},
+	[PLL_1600] = {
+		.refclk_min = 8,
+		.refclk_max = 16,
+		.divn_max = 199,
+	},
+};
+
+/* PLLNCFGR2 register divider by output */
+static const uint8_t pllncfgr2[_DIV_NB] = {
+	[_DIV_P] = RCC_PLLNCFGR2_DIVP_SHIFT,
+	[_DIV_Q] = RCC_PLLNCFGR2_DIVQ_SHIFT,
+	[_DIV_R] = RCC_PLLNCFGR2_DIVR_SHIFT
+};
+
+static const struct stm32mp1_clk_pll stm32mp1_clk_pll[_PLL_NB] = {
+	STM32MP1_CLK_PLL(_PLL1, PLL_1600,
+			 RCC_RCK12SELR, RCC_PLL1CFGR1, RCC_PLL1CFGR2,
+			 RCC_PLL1FRACR, RCC_PLL1CR, RCC_PLL1CSGR,
+			 _HSI, _HSE, _UNKNOWN_OSC_ID, _UNKNOWN_OSC_ID),
+	STM32MP1_CLK_PLL(_PLL2, PLL_1600,
+			 RCC_RCK12SELR, RCC_PLL2CFGR1, RCC_PLL2CFGR2,
+			 RCC_PLL2FRACR, RCC_PLL2CR, RCC_PLL2CSGR,
+			 _HSI, _HSE, _UNKNOWN_OSC_ID, _UNKNOWN_OSC_ID),
+	STM32MP1_CLK_PLL(_PLL3, PLL_800,
+			 RCC_RCK3SELR, RCC_PLL3CFGR1, RCC_PLL3CFGR2,
+			 RCC_PLL3FRACR, RCC_PLL3CR, RCC_PLL3CSGR,
+			 _HSI, _HSE, _CSI, _UNKNOWN_OSC_ID),
+	STM32MP1_CLK_PLL(_PLL4, PLL_800,
+			 RCC_RCK4SELR, RCC_PLL4CFGR1, RCC_PLL4CFGR2,
+			 RCC_PLL4FRACR, RCC_PLL4CR, RCC_PLL4CSGR,
+			 _HSI, _HSE, _CSI, _I2S_CKIN),
+};
+
+/* Prescaler table lookups for clock computation */
+
+/* div = /1 /2 /4 /8 /16 : same divider for PMU and APBX */
+#define stm32mp1_mpu_div stm32mp1_mpu_apbx_div
+#define stm32mp1_apbx_div stm32mp1_mpu_apbx_div
+static const uint8_t stm32mp1_mpu_apbx_div[8] = {
+	0, 1, 2, 3, 4, 4, 4, 4
+};
+
+/* div = /1 /2 /3 /4 */
+static const uint8_t stm32mp1_axi_div[8] = {
+	1, 2, 3, 4, 4, 4, 4, 4
+};
+
+static const struct stm32mp1_clk_data stm32mp1_data = {
+	.gate = stm32mp1_clk_gate,
+	.sel = stm32mp1_clk_sel,
+	.pll = stm32mp1_clk_pll,
+	.nb_gate = ARRAY_SIZE(stm32mp1_clk_gate),
+};
+
+static struct stm32mp1_clk_priv stm32mp1_clk_priv_data;
+
+static unsigned long stm32mp1_clk_get_fixed(struct stm32mp1_clk_priv *priv,
+					    enum stm32mp_osc_id idx)
+{
+	if (idx >= NB_OSC) {
+		return 0;
+	}
+
+	return priv->osc[idx];
+}
+
+static int stm32mp1_clk_get_id(struct stm32mp1_clk_priv *priv, unsigned long id)
+{
+	const struct stm32mp1_clk_gate *gate = priv->data->gate;
+	int i;
+	int nb_clks = priv->data->nb_gate;
+
+	for (i = 0; i < nb_clks; i++) {
+		if (gate[i].index == id) {
+			return i;
+		}
+	}
+
+	ERROR("%s: clk id %d not found\n", __func__, (uint32_t)id);
+
+	return -EINVAL;
+}
+
+static enum stm32mp1_parent_sel
+stm32mp1_clk_get_sel(struct stm32mp1_clk_priv *priv, int i)
+{
+	const struct stm32mp1_clk_gate *gate = priv->data->gate;
+
+	return gate[i].sel;
+}
+
+static enum stm32mp1_parent_id
+stm32mp1_clk_get_fixed_parent(struct stm32mp1_clk_priv *priv, int i)
+{
+	const struct stm32mp1_clk_gate *gate = priv->data->gate;
+
+	return gate[i].fixed;
+}
+
+static int stm32mp1_clk_get_parent(struct stm32mp1_clk_priv *priv,
+				   unsigned long id)
+{
+	const struct stm32mp1_clk_sel *sel = priv->data->sel;
+	uint32_t j, p_sel;
+	int i;
+	enum stm32mp1_parent_id p;
+	enum stm32mp1_parent_sel s;
+
+	for (j = 0; j < ARRAY_SIZE(stm32mp1_clks); j++) {
+		if (stm32mp1_clks[j][0] == id) {
+			return (int)stm32mp1_clks[j][1];
+		}
+	}
+
+	i = stm32mp1_clk_get_id(priv, id);
+	if (i < 0) {
+		return i;
+	}
+
+	p = stm32mp1_clk_get_fixed_parent(priv, i);
+	if (p < _PARENT_NB) {
+		return (int)p;
+	}
+
+	s = stm32mp1_clk_get_sel(priv, i);
+	if (s >= _PARENT_SEL_NB) {
+		return -EINVAL;
+	}
+
+	p_sel = (mmio_read_32(priv->base + sel[s].offset) >> sel[s].src) &
+		sel[s].msk;
+
+	if (p_sel < sel[s].nb_parent) {
+		return (int)sel[s].parent[p_sel];
+	}
+
+	ERROR("%s: no parents defined for clk id %ld\n", __func__, id);
+
+	return -EINVAL;
+}
+
+static unsigned long stm32mp1_pll_get_fref_ck(struct stm32mp1_clk_priv *priv,
+					      enum stm32mp1_pll_id pll_id)
+{
+	const struct stm32mp1_clk_pll *pll = priv->data->pll;
+	uint32_t selr, src;
+	unsigned long refclk;
+
+	selr = mmio_read_32(priv->base + pll[pll_id].rckxselr);
+	src = selr & RCC_SELR_REFCLK_SRC_MASK;
+
+	refclk = stm32mp1_clk_get_fixed(priv, pll[pll_id].refclk[src]);
+
+	return refclk;
+}
+
+/*
+ * pll_get_fvco() : return the VCO or (VCO / 2) frequency for the requested PLL
+ * - PLL1 & PLL2 => return VCO / 2 with Fpll_y_ck = FVCO / 2 * (DIVy + 1)
+ * - PLL3 & PLL4 => return VCO     with Fpll_y_ck = FVCO / (DIVy + 1)
+ * => in all cases Fpll_y_ck = pll_get_fvco() / (DIVy + 1)
+ */
+static unsigned long stm32mp1_pll_get_fvco(struct stm32mp1_clk_priv *priv,
+					   enum stm32mp1_pll_id pll_id)
+{
+	const struct stm32mp1_clk_pll *pll = priv->data->pll;
+	unsigned long refclk, fvco;
+	uint32_t cfgr1, fracr, divm, divn;
+
+	cfgr1 = mmio_read_32(priv->base + pll[pll_id].pllxcfgr1);
+	fracr = mmio_read_32(priv->base + pll[pll_id].pllxfracr);
+
+	divm = (cfgr1 & (RCC_PLLNCFGR1_DIVM_MASK)) >> RCC_PLLNCFGR1_DIVM_SHIFT;
+	divn = cfgr1 & RCC_PLLNCFGR1_DIVN_MASK;
+
+	refclk = stm32mp1_pll_get_fref_ck(priv, pll_id);
+
+	/*
+	 * With FRACV :
+	 *   Fvco = Fck_ref * ((DIVN + 1) + FRACV / 2^13) / (DIVM + 1)
+	 * Without FRACV
+	 *   Fvco = Fck_ref * ((DIVN + 1) / (DIVM + 1)
+	 */
+	if ((fracr & RCC_PLLNFRACR_FRACLE) != 0U) {
+		uint32_t fracv = (fracr & RCC_PLLNFRACR_FRACV_MASK)
+			    >> RCC_PLLNFRACR_FRACV_SHIFT;
+		unsigned long long numerator, denominator;
+
+		numerator = ((unsigned long long)divn + 1U) << 13;
+		numerator = (refclk * numerator) + fracv;
+		denominator = ((unsigned long long)divm + 1U)  << 13;
+		fvco = (unsigned long)(numerator / denominator);
+	} else {
+		fvco = (unsigned long)(refclk * (divn + 1U) / (divm + 1U));
+	}
+
+	return fvco;
+}
+
+static unsigned long stm32mp1_read_pll_freq(struct stm32mp1_clk_priv *priv,
+					    enum stm32mp1_pll_id pll_id,
+					    enum stm32mp1_div_id div_id)
+{
+	const struct stm32mp1_clk_pll *pll = priv->data->pll;
+	unsigned long dfout;
+	uint32_t cfgr2, divy;
+
+	if (div_id >= _DIV_NB) {
+		return 0;
+	}
+
+	cfgr2 = mmio_read_32(priv->base + pll[pll_id].pllxcfgr2);
+	divy = (cfgr2 >> pllncfgr2[div_id]) & RCC_PLLNCFGR2_DIVX_MASK;
+
+	dfout = stm32mp1_pll_get_fvco(priv, pll_id) / (divy + 1U);
+
+	return dfout;
+}
+
+static unsigned long stm32mp1_clk_get(struct stm32mp1_clk_priv *priv, int p)
+{
+	uint32_t reg, clkdiv;
+	unsigned long clock = 0;
+
+	switch (p) {
+	case _CK_MPU:
+	/* MPU sub system */
+		reg = mmio_read_32(priv->base + RCC_MPCKSELR);
+		switch (reg & RCC_SELR_SRC_MASK) {
+		case RCC_MPCKSELR_HSI:
+			clock = stm32mp1_clk_get_fixed(priv, _HSI);
+			break;
+		case RCC_MPCKSELR_HSE:
+			clock = stm32mp1_clk_get_fixed(priv, _HSE);
+			break;
+		case RCC_MPCKSELR_PLL:
+			clock = stm32mp1_read_pll_freq(priv, _PLL1, _DIV_P);
+			break;
+		case RCC_MPCKSELR_PLL_MPUDIV:
+			clock = stm32mp1_read_pll_freq(priv, _PLL1, _DIV_P);
+
+			reg = mmio_read_32(priv->base + RCC_MPCKDIVR);
+			clkdiv = reg & RCC_MPUDIV_MASK;
+			if (clkdiv != 0U) {
+				clock /= stm32mp1_mpu_div[clkdiv];
+			}
+
+			break;
+		default:
+			break;
+		}
+		break;
+	/* AXI sub system */
+	case _ACLK:
+	case _HCLK2:
+	case _HCLK6:
+	case _PCLK4:
+	case _PCLK5:
+		reg = mmio_read_32(priv->base + RCC_ASSCKSELR);
+		switch (reg & RCC_SELR_SRC_MASK) {
+		case RCC_ASSCKSELR_HSI:
+			clock = stm32mp1_clk_get_fixed(priv, _HSI);
+			break;
+		case RCC_ASSCKSELR_HSE:
+			clock = stm32mp1_clk_get_fixed(priv, _HSE);
+			break;
+		case RCC_ASSCKSELR_PLL:
+			clock = stm32mp1_read_pll_freq(priv, _PLL2, _DIV_P);
+			break;
+		default:
+			break;
+		}
+
+		/* System clock divider */
+		reg = mmio_read_32(priv->base + RCC_AXIDIVR);
+		clock /= stm32mp1_axi_div[reg & RCC_AXIDIV_MASK];
+
+		switch (p) {
+		case _PCLK4:
+			reg = mmio_read_32(priv->base + RCC_APB4DIVR);
+			clock >>= stm32mp1_apbx_div[reg & RCC_APBXDIV_MASK];
+			break;
+		case _PCLK5:
+			reg = mmio_read_32(priv->base + RCC_APB5DIVR);
+			clock >>= stm32mp1_apbx_div[reg & RCC_APBXDIV_MASK];
+			break;
+		default:
+			break;
+		}
+		break;
+	case _CK_PER:
+		reg = mmio_read_32(priv->base + RCC_CPERCKSELR);
+		switch (reg & RCC_SELR_SRC_MASK) {
+		case RCC_CPERCKSELR_HSI:
+			clock = stm32mp1_clk_get_fixed(priv, _HSI);
+			break;
+		case RCC_CPERCKSELR_HSE:
+			clock = stm32mp1_clk_get_fixed(priv, _HSE);
+			break;
+		case RCC_CPERCKSELR_CSI:
+			clock = stm32mp1_clk_get_fixed(priv, _CSI);
+			break;
+		default:
+			break;
+		}
+		break;
+	case _HSI:
+	case _HSI_KER:
+		clock = stm32mp1_clk_get_fixed(priv, _HSI);
+		break;
+	case _CSI:
+	case _CSI_KER:
+		clock = stm32mp1_clk_get_fixed(priv, _CSI);
+		break;
+	case _HSE:
+	case _HSE_KER:
+		clock = stm32mp1_clk_get_fixed(priv, _HSE);
+		break;
+	case _HSE_KER_DIV2:
+		clock = stm32mp1_clk_get_fixed(priv, _HSE) >> 1;
+		break;
+	case _LSI:
+		clock = stm32mp1_clk_get_fixed(priv, _LSI);
+		break;
+	case _LSE:
+		clock = stm32mp1_clk_get_fixed(priv, _LSE);
+		break;
+	/* PLL */
+	case _PLL1_P:
+		clock = stm32mp1_read_pll_freq(priv, _PLL1, _DIV_P);
+		break;
+	case _PLL1_Q:
+		clock = stm32mp1_read_pll_freq(priv, _PLL1, _DIV_Q);
+		break;
+	case _PLL1_R:
+		clock = stm32mp1_read_pll_freq(priv, _PLL1, _DIV_R);
+		break;
+	case _PLL2_P:
+		clock = stm32mp1_read_pll_freq(priv, _PLL2, _DIV_P);
+		break;
+	case _PLL2_Q:
+		clock = stm32mp1_read_pll_freq(priv, _PLL2, _DIV_Q);
+		break;
+	case _PLL2_R:
+		clock = stm32mp1_read_pll_freq(priv, _PLL2, _DIV_R);
+		break;
+	case _PLL3_P:
+		clock = stm32mp1_read_pll_freq(priv, _PLL3, _DIV_P);
+		break;
+	case _PLL3_Q:
+		clock = stm32mp1_read_pll_freq(priv, _PLL3, _DIV_Q);
+		break;
+	case _PLL3_R:
+		clock = stm32mp1_read_pll_freq(priv, _PLL3, _DIV_R);
+		break;
+	case _PLL4_P:
+		clock = stm32mp1_read_pll_freq(priv, _PLL4, _DIV_P);
+		break;
+	case _PLL4_Q:
+		clock = stm32mp1_read_pll_freq(priv, _PLL4, _DIV_Q);
+		break;
+	case _PLL4_R:
+		clock = stm32mp1_read_pll_freq(priv, _PLL4, _DIV_R);
+		break;
+	/* Other */
+	case _USB_PHY_48:
+		clock = stm32mp1_clk_get_fixed(priv, _USB_PHY_48);
+		break;
+	default:
+		break;
+	}
+
+	return clock;
+}
+
+bool stm32mp1_clk_is_enabled(unsigned long id)
+{
+	struct stm32mp1_clk_priv *priv = &stm32mp1_clk_priv_data;
+	const struct stm32mp1_clk_gate *gate = priv->data->gate;
+	int i = stm32mp1_clk_get_id(priv, id);
+
+	if (i < 0) {
+		return false;
+	}
+
+	return ((mmio_read_32(priv->base + gate[i].offset) &
+		 BIT(gate[i].bit)) != 0U);
+}
+
+int stm32mp1_clk_enable(unsigned long id)
+{
+	struct stm32mp1_clk_priv *priv = &stm32mp1_clk_priv_data;
+	const struct stm32mp1_clk_gate *gate = priv->data->gate;
+	int i = stm32mp1_clk_get_id(priv, id);
+
+	if (i < 0) {
+		return i;
+	}
+
+	if (gate[i].set_clr != 0U) {
+		mmio_write_32(priv->base + gate[i].offset, BIT(gate[i].bit));
+	} else {
+		mmio_setbits_32(priv->base + gate[i].offset, BIT(gate[i].bit));
+	}
+
+	return 0;
+}
+
+int stm32mp1_clk_disable(unsigned long id)
+{
+	struct stm32mp1_clk_priv *priv = &stm32mp1_clk_priv_data;
+	const struct stm32mp1_clk_gate *gate = priv->data->gate;
+	int i = stm32mp1_clk_get_id(priv, id);
+
+	if (i < 0) {
+		return i;
+	}
+
+	if (gate[i].set_clr != 0U) {
+		mmio_write_32(priv->base + gate[i].offset
+			      + RCC_MP_ENCLRR_OFFSET,
+			      BIT(gate[i].bit));
+	} else {
+		mmio_clrbits_32(priv->base + gate[i].offset, BIT(gate[i].bit));
+	}
+
+	return 0;
+}
+
+unsigned long stm32mp1_clk_get_rate(unsigned long id)
+{
+	struct stm32mp1_clk_priv *priv = &stm32mp1_clk_priv_data;
+	int p = stm32mp1_clk_get_parent(priv, id);
+	unsigned long rate;
+
+	if (p < 0) {
+		return 0;
+	}
+
+	rate = stm32mp1_clk_get(priv, p);
+
+	return rate;
+}
+
+static void stm32mp1_ls_osc_set(int enable, uint32_t rcc, uint32_t offset,
+				uint32_t mask_on)
+{
+	uint32_t address = rcc + offset;
+
+	if (enable != 0) {
+		mmio_setbits_32(address, mask_on);
+	} else {
+		mmio_clrbits_32(address, mask_on);
+	}
+}
+
+static void stm32mp1_hs_ocs_set(int enable, uint32_t rcc, uint32_t mask_on)
+{
+	if (enable != 0) {
+		mmio_setbits_32(rcc + RCC_OCENSETR, mask_on);
+	} else {
+		mmio_setbits_32(rcc + RCC_OCENCLRR, mask_on);
+	}
+}
+
+static int stm32mp1_osc_wait(int enable, uint32_t rcc, uint32_t offset,
+			     uint32_t mask_rdy)
+{
+	unsigned long start;
+	uint32_t mask_test;
+	uint32_t address = rcc + offset;
+
+	if (enable != 0) {
+		mask_test = mask_rdy;
+	} else {
+		mask_test = 0;
+	}
+
+	start = get_timer(0);
+	while ((mmio_read_32(address) & mask_rdy) != mask_test) {
+		if (get_timer(start) > OSCRDY_TIMEOUT) {
+			ERROR("OSC %x @ %x timeout for enable=%d : 0x%x\n",
+			      mask_rdy, address, enable, mmio_read_32(address));
+			return -ETIMEDOUT;
+		}
+	}
+
+	return 0;
+}
+
+static void stm32mp1_lse_enable(uint32_t rcc, bool bypass, uint32_t lsedrv)
+{
+	uint32_t value;
+
+	if (bypass) {
+		mmio_setbits_32(rcc + RCC_BDCR, RCC_BDCR_LSEBYP);
+	}
+
+	/*
+	 * Warning: not recommended to switch directly from "high drive"
+	 * to "medium low drive", and vice-versa.
+	 */
+	value = (mmio_read_32(rcc + RCC_BDCR) & RCC_BDCR_LSEDRV_MASK) >>
+		RCC_BDCR_LSEDRV_SHIFT;
+
+	while (value != lsedrv) {
+		if (value > lsedrv) {
+			value--;
+		} else {
+			value++;
+		}
+
+		mmio_clrsetbits_32(rcc + RCC_BDCR,
+				   RCC_BDCR_LSEDRV_MASK,
+				   value << RCC_BDCR_LSEDRV_SHIFT);
+	}
+
+	stm32mp1_ls_osc_set(1, rcc, RCC_BDCR, RCC_BDCR_LSEON);
+}
+
+static void stm32mp1_lse_wait(uint32_t rcc)
+{
+	if (stm32mp1_osc_wait(1, rcc, RCC_BDCR, RCC_BDCR_LSERDY) != 0) {
+		VERBOSE("%s: failed\n", __func__);
+	}
+}
+
+static void stm32mp1_lsi_set(uint32_t rcc, int enable)
+{
+	stm32mp1_ls_osc_set(enable, rcc, RCC_RDLSICR, RCC_RDLSICR_LSION);
+	if (stm32mp1_osc_wait(enable, rcc, RCC_RDLSICR, RCC_RDLSICR_LSIRDY) !=
+	    0) {
+		VERBOSE("%s: failed\n", __func__);
+	}
+}
+
+static void stm32mp1_hse_enable(uint32_t rcc, bool bypass, bool css)
+{
+	if (bypass) {
+		mmio_setbits_32(rcc + RCC_OCENSETR, RCC_OCENR_HSEBYP);
+	}
+
+	stm32mp1_hs_ocs_set(1, rcc, RCC_OCENR_HSEON);
+	if (stm32mp1_osc_wait(1, rcc, RCC_OCRDYR, RCC_OCRDYR_HSERDY) !=
+	    0) {
+		VERBOSE("%s: failed\n", __func__);
+	}
+
+	if (css) {
+		mmio_setbits_32(rcc + RCC_OCENSETR, RCC_OCENR_HSECSSON);
+	}
+}
+
+static void stm32mp1_csi_set(uint32_t rcc, int enable)
+{
+	stm32mp1_ls_osc_set(enable, rcc, RCC_OCENSETR, RCC_OCENR_CSION);
+	if (stm32mp1_osc_wait(enable, rcc, RCC_OCRDYR, RCC_OCRDYR_CSIRDY) !=
+	    0) {
+		VERBOSE("%s: failed\n", __func__);
+	}
+}
+
+static void stm32mp1_hsi_set(uint32_t rcc, int enable)
+{
+	stm32mp1_hs_ocs_set(enable, rcc, RCC_OCENR_HSION);
+	if (stm32mp1_osc_wait(enable, rcc, RCC_OCRDYR, RCC_OCRDYR_HSIRDY) !=
+	    0) {
+		VERBOSE("%s: failed\n", __func__);
+	}
+}
+
+static int stm32mp1_set_hsidiv(uint32_t rcc, uint8_t hsidiv)
+{
+	unsigned long start;
+	uint32_t address = rcc + RCC_OCRDYR;
+
+	mmio_clrsetbits_32(rcc + RCC_HSICFGR,
+			   RCC_HSICFGR_HSIDIV_MASK,
+			   RCC_HSICFGR_HSIDIV_MASK & (uint32_t)hsidiv);
+
+	start = get_timer(0);
+	while ((mmio_read_32(address) & RCC_OCRDYR_HSIDIVRDY) == 0U) {
+		if (get_timer(start) > HSIDIV_TIMEOUT) {
+			ERROR("HSIDIV failed @ 0x%x: 0x%x\n",
+			      address, mmio_read_32(address));
+			return -ETIMEDOUT;
+		}
+	}
+
+	return 0;
+}
+
+static int stm32mp1_hsidiv(uint32_t rcc, unsigned long hsifreq)
+{
+	uint8_t hsidiv;
+	uint32_t hsidivfreq = MAX_HSI_HZ;
+
+	for (hsidiv = 0; hsidiv < 4U; hsidiv++) {
+		if (hsidivfreq == hsifreq) {
+			break;
+		}
+
+		hsidivfreq /= 2U;
+	}
+
+	if (hsidiv == 4U) {
+		ERROR("Invalid clk-hsi frequency\n");
+		return -1;
+	}
+
+	if (hsidiv != 0U) {
+		return stm32mp1_set_hsidiv(rcc, hsidiv);
+	}
+
+	return 0;
+}
+
+static void stm32mp1_pll_start(struct stm32mp1_clk_priv *priv,
+			       enum stm32mp1_pll_id pll_id)
+{
+	const struct stm32mp1_clk_pll *pll = priv->data->pll;
+
+	mmio_write_32(priv->base + pll[pll_id].pllxcr, RCC_PLLNCR_PLLON);
+}
+
+static int stm32mp1_pll_output(struct stm32mp1_clk_priv *priv,
+			       enum stm32mp1_pll_id pll_id, uint32_t output)
+{
+	const struct stm32mp1_clk_pll *pll = priv->data->pll;
+	uint32_t pllxcr = priv->base + pll[pll_id].pllxcr;
+	unsigned long start;
+
+	start = get_timer(0);
+	/* Wait PLL lock */
+	while ((mmio_read_32(pllxcr) & RCC_PLLNCR_PLLRDY) == 0U) {
+		if (get_timer(start) > PLLRDY_TIMEOUT) {
+			ERROR("PLL%d start failed @ 0x%x: 0x%x\n",
+			      pll_id, pllxcr, mmio_read_32(pllxcr));
+			return -ETIMEDOUT;
+		}
+	}
+
+	/* Start the requested output */
+	mmio_setbits_32(pllxcr, output << RCC_PLLNCR_DIVEN_SHIFT);
+
+	return 0;
+}
+
+static int stm32mp1_pll_stop(struct stm32mp1_clk_priv *priv,
+			     enum stm32mp1_pll_id pll_id)
+{
+	const struct stm32mp1_clk_pll *pll = priv->data->pll;
+	uint32_t pllxcr = priv->base + pll[pll_id].pllxcr;
+	unsigned long start;
+
+	/* Stop all output */
+	mmio_clrbits_32(pllxcr, RCC_PLLNCR_DIVPEN | RCC_PLLNCR_DIVQEN |
+			RCC_PLLNCR_DIVREN);
+
+	/* Stop PLL */
+	mmio_clrbits_32(pllxcr, RCC_PLLNCR_PLLON);
+
+	start = get_timer(0);
+	/* Wait PLL stopped */
+	while ((mmio_read_32(pllxcr) & RCC_PLLNCR_PLLRDY) != 0U) {
+		if (get_timer(start) > PLLRDY_TIMEOUT) {
+			ERROR("PLL%d stop failed @ 0x%x: 0x%x\n",
+			      pll_id, pllxcr, mmio_read_32(pllxcr));
+			return -ETIMEDOUT;
+		}
+	}
+
+	return 0;
+}
+
+static void stm32mp1_pll_config_output(struct stm32mp1_clk_priv *priv,
+				       enum stm32mp1_pll_id pll_id,
+				       uint32_t *pllcfg)
+{
+	const struct stm32mp1_clk_pll *pll = priv->data->pll;
+	uint32_t rcc = priv->base;
+	uint32_t value;
+
+	value = (pllcfg[PLLCFG_P] << RCC_PLLNCFGR2_DIVP_SHIFT) &
+		RCC_PLLNCFGR2_DIVP_MASK;
+	value |= (pllcfg[PLLCFG_Q] << RCC_PLLNCFGR2_DIVQ_SHIFT) &
+		 RCC_PLLNCFGR2_DIVQ_MASK;
+	value |= (pllcfg[PLLCFG_R] << RCC_PLLNCFGR2_DIVR_SHIFT) &
+		 RCC_PLLNCFGR2_DIVR_MASK;
+	mmio_write_32(rcc + pll[pll_id].pllxcfgr2, value);
+}
+
+static int stm32mp1_pll_config(struct stm32mp1_clk_priv *priv,
+			       enum stm32mp1_pll_id pll_id,
+			       uint32_t *pllcfg, uint32_t fracv)
+{
+	const struct stm32mp1_clk_pll *pll = priv->data->pll;
+	uint32_t rcc = priv->base;
+	enum stm32mp1_plltype type = pll[pll_id].plltype;
+	unsigned long refclk;
+	uint32_t ifrge = 0;
+	uint32_t src, value;
+
+	src = mmio_read_32(priv->base + pll[pll_id].rckxselr) &
+		RCC_SELR_REFCLK_SRC_MASK;
+
+	refclk = stm32mp1_clk_get_fixed(priv, pll[pll_id].refclk[src]) /
+		 (pllcfg[PLLCFG_M] + 1U);
+
+	if ((refclk < (stm32mp1_pll[type].refclk_min * 1000000U)) ||
+	    (refclk > (stm32mp1_pll[type].refclk_max * 1000000U))) {
+		return -EINVAL;
+	}
+
+	if ((type == PLL_800) && (refclk >= 8000000U)) {
+		ifrge = 1U;
+	}
+
+	value = (pllcfg[PLLCFG_N] << RCC_PLLNCFGR1_DIVN_SHIFT) &
+		RCC_PLLNCFGR1_DIVN_MASK;
+	value |= (pllcfg[PLLCFG_M] << RCC_PLLNCFGR1_DIVM_SHIFT) &
+		 RCC_PLLNCFGR1_DIVM_MASK;
+	value |= (ifrge << RCC_PLLNCFGR1_IFRGE_SHIFT) &
+		 RCC_PLLNCFGR1_IFRGE_MASK;
+	mmio_write_32(rcc + pll[pll_id].pllxcfgr1, value);
+
+	/* Fractional configuration */
+	value = 0;
+	mmio_write_32(rcc + pll[pll_id].pllxfracr, value);
+
+	value = fracv << RCC_PLLNFRACR_FRACV_SHIFT;
+	mmio_write_32(rcc + pll[pll_id].pllxfracr, value);
+
+	value |= RCC_PLLNFRACR_FRACLE;
+	mmio_write_32(rcc + pll[pll_id].pllxfracr, value);
+
+	stm32mp1_pll_config_output(priv, pll_id, pllcfg);
+
+	return 0;
+}
+
+static void stm32mp1_pll_csg(struct stm32mp1_clk_priv *priv,
+			     enum stm32mp1_pll_id pll_id,
+			     uint32_t *csg)
+{
+	const struct stm32mp1_clk_pll *pll = priv->data->pll;
+	uint32_t pllxcsg = 0;
+
+	pllxcsg |= (csg[PLLCSG_MOD_PER] << RCC_PLLNCSGR_MOD_PER_SHIFT) &
+		    RCC_PLLNCSGR_MOD_PER_MASK;
+
+	pllxcsg |= (csg[PLLCSG_INC_STEP] << RCC_PLLNCSGR_INC_STEP_SHIFT) &
+		    RCC_PLLNCSGR_INC_STEP_MASK;
+
+	pllxcsg |= (csg[PLLCSG_SSCG_MODE] << RCC_PLLNCSGR_SSCG_MODE_SHIFT) &
+		    RCC_PLLNCSGR_SSCG_MODE_MASK;
+
+	mmio_write_32(priv->base + pll[pll_id].pllxcsgr, pllxcsg);
+}
+
+static int stm32mp1_set_clksrc(struct stm32mp1_clk_priv *priv,
+			       unsigned int clksrc)
+{
+	uint32_t address = priv->base + (clksrc >> 4);
+	unsigned long start;
+
+	mmio_clrsetbits_32(address, RCC_SELR_SRC_MASK,
+			   clksrc & RCC_SELR_SRC_MASK);
+
+	start = get_timer(0);
+	while ((mmio_read_32(address) & RCC_SELR_SRCRDY) == 0U) {
+		if (get_timer(start) > CLKSRC_TIMEOUT) {
+			ERROR("CLKSRC %x start failed @ 0x%x: 0x%x\n",
+			      clksrc, address, mmio_read_32(address));
+			return -ETIMEDOUT;
+		}
+	}
+
+	return 0;
+}
+
+static int stm32mp1_set_clkdiv(unsigned int clkdiv, uint32_t address)
+{
+	unsigned long start;
+
+	mmio_clrsetbits_32(address, RCC_DIVR_DIV_MASK,
+			   clkdiv & RCC_DIVR_DIV_MASK);
+
+	start = get_timer(0);
+	while ((mmio_read_32(address) & RCC_DIVR_DIVRDY) == 0U) {
+		if (get_timer(start) > CLKDIV_TIMEOUT) {
+			ERROR("CLKDIV %x start failed @ 0x%x: 0x%x\n",
+			      clkdiv, address, mmio_read_32(address));
+			return -ETIMEDOUT;
+		}
+	}
+
+	return 0;
+}
+
+static void stm32mp1_mco_csg(struct stm32mp1_clk_priv *priv,
+			     uint32_t clksrc, uint32_t clkdiv)
+{
+	uint32_t address = priv->base + (clksrc >> 4);
+
+	/*
+	 * Binding clksrc :
+	 *      bit15-4 offset
+	 *      bit3:   disable
+	 *      bit2-0: MCOSEL[2:0]
+	 */
+	if ((clksrc & 0x8U) != 0U) {
+		mmio_clrbits_32(address, RCC_MCOCFG_MCOON);
+	} else {
+		mmio_clrsetbits_32(address,
+				   RCC_MCOCFG_MCOSRC_MASK,
+				   clksrc & RCC_MCOCFG_MCOSRC_MASK);
+		mmio_clrsetbits_32(address,
+				   RCC_MCOCFG_MCODIV_MASK,
+				   clkdiv << RCC_MCOCFG_MCODIV_SHIFT);
+		mmio_setbits_32(address, RCC_MCOCFG_MCOON);
+	}
+}
+
+static void stm32mp1_set_rtcsrc(struct stm32mp1_clk_priv *priv,
+				unsigned int clksrc, bool lse_css)
+{
+	uint32_t address = priv->base + RCC_BDCR;
+
+	if (((mmio_read_32(address) & RCC_BDCR_RTCCKEN) == 0U) ||
+	    (clksrc != (uint32_t)CLK_RTC_DISABLED)) {
+		mmio_clrsetbits_32(address,
+				   RCC_BDCR_RTCSRC_MASK,
+				   clksrc << RCC_BDCR_RTCSRC_SHIFT);
+
+		mmio_setbits_32(address, RCC_BDCR_RTCCKEN);
+	}
+
+	if (lse_css) {
+		mmio_setbits_32(address, RCC_BDCR_LSECSSON);
+	}
+}
+
+#define CNTCVL_OFF	0x008
+#define CNTCVU_OFF	0x00C
+
+static void stm32mp1_stgen_config(struct stm32mp1_clk_priv *priv)
+{
+	uintptr_t stgen;
+	int p;
+	uint32_t cntfid0;
+	unsigned long rate;
+
+	stgen = fdt_get_stgen_base();
+
+	cntfid0 = mmio_read_32(stgen + CNTFID_OFF);
+	p = stm32mp1_clk_get_parent(priv, STGEN_K);
+	rate = stm32mp1_clk_get(priv, p);
+
+	if (cntfid0 != rate) {
+		unsigned long long counter;
+
+		mmio_clrbits_32(stgen + CNTCR_OFF, CNTCR_EN);
+		counter = (unsigned long long)
+			mmio_read_32(stgen + CNTCVL_OFF);
+		counter |= ((unsigned long long)
+			    (mmio_read_32(stgen + CNTCVU_OFF))) << 32;
+		counter = (counter * rate / cntfid0);
+		mmio_write_32(stgen + CNTCVL_OFF, (uint32_t)counter);
+		mmio_write_32(stgen + CNTCVU_OFF, (uint32_t)(counter >> 32));
+		mmio_write_32(stgen + CNTFID_OFF, rate);
+		mmio_setbits_32(stgen + CNTCR_OFF, CNTCR_EN);
+
+		write_cntfrq((u_register_t)rate);
+
+		/* Need to update timer with new frequency */
+		generic_delay_timer_init();
+	}
+}
+
+void stm32mp1_stgen_increment(unsigned long long offset_in_ms)
+{
+	uintptr_t stgen;
+	unsigned long long cnt;
+
+	stgen = fdt_get_stgen_base();
+
+	cnt = ((unsigned long long)mmio_read_32(stgen + CNTCVU_OFF) << 32) |
+		mmio_read_32(stgen + CNTCVL_OFF);
+
+	cnt += (offset_in_ms * mmio_read_32(stgen + CNTFID_OFF)) / 1000U;
+
+	mmio_clrbits_32(stgen + CNTCR_OFF, CNTCR_EN);
+	mmio_write_32(stgen + CNTCVL_OFF, (uint32_t)cnt);
+	mmio_write_32(stgen + CNTCVU_OFF, (uint32_t)(cnt >> 32));
+	mmio_setbits_32(stgen + CNTCR_OFF, CNTCR_EN);
+}
+
+static void stm32mp1_pkcs_config(struct stm32mp1_clk_priv *priv, uint32_t pkcs)
+{
+	uint32_t address = priv->base + ((pkcs >> 4) & 0xFFFU);
+	uint32_t value = pkcs & 0xFU;
+	uint32_t mask = 0xFU;
+
+	if ((pkcs & BIT(31)) != 0U) {
+		mask <<= 4;
+		value <<= 4;
+	}
+
+	mmio_clrsetbits_32(address, mask, value);
+}
+
+int stm32mp1_clk_init(void)
+{
+	struct stm32mp1_clk_priv *priv = &stm32mp1_clk_priv_data;
+	uint32_t rcc = priv->base;
+	unsigned int clksrc[CLKSRC_NB];
+	unsigned int clkdiv[CLKDIV_NB];
+	unsigned int pllcfg[_PLL_NB][PLLCFG_NB];
+	int plloff[_PLL_NB];
+	int ret, len;
+	enum stm32mp1_pll_id i;
+	bool lse_css = false;
+	const uint32_t *pkcs_cell;
+
+	/* Check status field to disable security */
+	if (!fdt_get_rcc_secure_status()) {
+		mmio_write_32(rcc + RCC_TZCR, 0);
+	}
+
+	ret = fdt_rcc_read_uint32_array("st,clksrc", clksrc,
+					(uint32_t)CLKSRC_NB);
+	if (ret < 0) {
+		return -FDT_ERR_NOTFOUND;
+	}
+
+	ret = fdt_rcc_read_uint32_array("st,clkdiv", clkdiv,
+					(uint32_t)CLKDIV_NB);
+	if (ret < 0) {
+		return -FDT_ERR_NOTFOUND;
+	}
+
+	for (i = (enum stm32mp1_pll_id)0; i < _PLL_NB; i++) {
+		char name[12];
+
+		sprintf(name, "st,pll@%d", i);
+		plloff[i] = fdt_rcc_subnode_offset(name);
+
+		if (!fdt_check_node(plloff[i])) {
+			continue;
+		}
+
+		ret = fdt_read_uint32_array(plloff[i], "cfg",
+					    pllcfg[i], (int)PLLCFG_NB);
+		if (ret < 0) {
+			return -FDT_ERR_NOTFOUND;
+		}
+	}
+
+	stm32mp1_mco_csg(priv, clksrc[CLKSRC_MCO1], clkdiv[CLKDIV_MCO1]);
+	stm32mp1_mco_csg(priv, clksrc[CLKSRC_MCO2], clkdiv[CLKDIV_MCO2]);
+
+	/*
+	 * Switch ON oscillator found in device-tree.
+	 * Note: HSI already ON after BootROM stage.
+	 */
+	if (priv->osc[_LSI] != 0U) {
+		stm32mp1_lsi_set(rcc, 1);
+	}
+	if (priv->osc[_LSE] != 0U) {
+		bool bypass;
+		uint32_t lsedrv;
+
+		bypass = fdt_osc_read_bool(_LSE, "st,bypass");
+		lse_css = fdt_osc_read_bool(_LSE, "st,css");
+		lsedrv = fdt_osc_read_uint32_default(_LSE, "st,drive",
+						     LSEDRV_MEDIUM_HIGH);
+		stm32mp1_lse_enable(rcc, bypass, lsedrv);
+	}
+	if (priv->osc[_HSE] != 0U) {
+		bool bypass, css;
+
+		bypass = fdt_osc_read_bool(_LSE, "st,bypass");
+		css = fdt_osc_read_bool(_LSE, "st,css");
+		stm32mp1_hse_enable(rcc, bypass, css);
+	}
+	/*
+	 * CSI is mandatory for automatic I/O compensation (SYSCFG_CMPCR)
+	 * => switch on CSI even if node is not present in device tree
+	 */
+	stm32mp1_csi_set(rcc, 1);
+
+	/* Come back to HSI */
+	ret = stm32mp1_set_clksrc(priv, CLK_MPU_HSI);
+	if (ret != 0) {
+		return ret;
+	}
+	ret = stm32mp1_set_clksrc(priv, CLK_AXI_HSI);
+	if (ret != 0) {
+		return ret;
+	}
+
+	for (i = (enum stm32mp1_pll_id)0; i < _PLL_NB; i++) {
+		if (i == _PLL4)
+			continue;
+		ret = stm32mp1_pll_stop(priv, i);
+		if (ret != 0) {
+			return ret;
+		}
+	}
+
+	/* Configure HSIDIV */
+	if (priv->osc[_HSI] != 0U) {
+		ret = stm32mp1_hsidiv(rcc, priv->osc[_HSI]);
+		if (ret != 0) {
+			return ret;
+		}
+		stm32mp1_stgen_config(priv);
+	}
+
+	/* Select DIV */
+	/* No ready bit when MPUSRC != CLK_MPU_PLL1P_DIV, MPUDIV is disabled */
+	mmio_write_32(rcc + RCC_MPCKDIVR,
+		      clkdiv[CLKDIV_MPU] & RCC_DIVR_DIV_MASK);
+	ret = stm32mp1_set_clkdiv(clkdiv[CLKDIV_AXI], rcc + RCC_AXIDIVR);
+	if (ret != 0) {
+		return ret;
+	}
+	ret = stm32mp1_set_clkdiv(clkdiv[CLKDIV_APB4], rcc + RCC_APB4DIVR);
+	if (ret != 0) {
+		return ret;
+	}
+	ret = stm32mp1_set_clkdiv(clkdiv[CLKDIV_APB5], rcc + RCC_APB5DIVR);
+	if (ret != 0) {
+		return ret;
+	}
+	ret = stm32mp1_set_clkdiv(clkdiv[CLKDIV_APB1], rcc + RCC_APB1DIVR);
+	if (ret != 0) {
+		return ret;
+	}
+	ret = stm32mp1_set_clkdiv(clkdiv[CLKDIV_APB2], rcc + RCC_APB2DIVR);
+	if (ret != 0) {
+		return ret;
+	}
+	ret = stm32mp1_set_clkdiv(clkdiv[CLKDIV_APB3], rcc + RCC_APB3DIVR);
+	if (ret != 0) {
+		return ret;
+	}
+
+	/* No ready bit for RTC */
+	mmio_write_32(rcc + RCC_RTCDIVR,
+		      clkdiv[CLKDIV_RTC] & RCC_DIVR_DIV_MASK);
+
+	/* Configure PLLs source */
+	ret = stm32mp1_set_clksrc(priv, clksrc[CLKSRC_PLL12]);
+	if (ret != 0) {
+		return ret;
+	}
+	ret = stm32mp1_set_clksrc(priv, clksrc[CLKSRC_PLL3]);
+	if (ret != 0) {
+		return ret;
+	}
+
+	ret = stm32mp1_set_clksrc(priv, clksrc[CLKSRC_PLL4]);
+	if (ret != 0) {
+		return ret;
+	}
+
+	/* Configure and start PLLs */
+	for (i = (enum stm32mp1_pll_id)0; i < _PLL_NB; i++) {
+		uint32_t fracv;
+		uint32_t csg[PLLCSG_NB];
+
+		if (!fdt_check_node(plloff[i])) {
+			continue;
+		}
+
+		fracv = fdt_read_uint32_default(plloff[i], "frac", 0);
+
+		ret = stm32mp1_pll_config(priv, i, pllcfg[i], fracv);
+		if (ret != 0) {
+			return ret;
+		}
+		ret = fdt_read_uint32_array(plloff[i], "csg", csg,
+					    (uint32_t)PLLCSG_NB);
+		if (ret == 0) {
+			stm32mp1_pll_csg(priv, i, csg);
+		} else if (ret != -FDT_ERR_NOTFOUND) {
+			return ret;
+		}
+
+		stm32mp1_pll_start(priv, i);
+	}
+	/* Wait and start PLLs ouptut when ready */
+	for (i = (enum stm32mp1_pll_id)0; i < _PLL_NB; i++) {
+		if (!fdt_check_node(plloff[i])) {
+			continue;
+		}
+
+		ret = stm32mp1_pll_output(priv, i, pllcfg[i][PLLCFG_O]);
+		if (ret != 0) {
+			return ret;
+		}
+	}
+	/* Wait LSE ready before to use it */
+	if (priv->osc[_LSE] != 0U) {
+		stm32mp1_lse_wait(rcc);
+	}
+
+	/* Configure with expected clock source */
+	ret = stm32mp1_set_clksrc(priv, clksrc[CLKSRC_MPU]);
+	if (ret != 0) {
+		return ret;
+	}
+	ret = stm32mp1_set_clksrc(priv, clksrc[CLKSRC_AXI]);
+	if (ret != 0) {
+		return ret;
+	}
+	stm32mp1_set_rtcsrc(priv, clksrc[CLKSRC_RTC], lse_css);
+
+	/* Configure PKCK */
+	pkcs_cell = fdt_rcc_read_prop("st,pkcs", &len);
+	if (pkcs_cell != NULL) {
+		bool ckper_disabled = false;
+		uint32_t j;
+
+		priv->pkcs_usb_value = 0;
+
+		for (j = 0; j < ((uint32_t)len / sizeof(uint32_t)); j++) {
+			uint32_t pkcs = (uint32_t)fdt32_to_cpu(pkcs_cell[j]);
+
+			if (pkcs == (uint32_t)CLK_CKPER_DISABLED) {
+				ckper_disabled = true;
+				continue;
+			}
+			stm32mp1_pkcs_config(priv, pkcs);
+		}
+
+		/*
+		 * CKPER is source for some peripheral clocks
+		 * (FMC-NAND / QPSI-NOR) and switching source is allowed
+		 * only if previous clock is still ON
+		 * => deactivated CKPER only after switching clock
+		 */
+		if (ckper_disabled) {
+			stm32mp1_pkcs_config(priv, CLK_CKPER_DISABLED);
+		}
+	}
+
+	/* Switch OFF HSI if not found in device-tree */
+	if (priv->osc[_HSI] == 0U) {
+		stm32mp1_hsi_set(rcc, 0);
+	}
+	stm32mp1_stgen_config(priv);
+
+	/* Software Self-Refresh mode (SSR) during DDR initilialization */
+	mmio_clrsetbits_32(priv->base + RCC_DDRITFCR,
+			   RCC_DDRITFCR_DDRCKMOD_MASK,
+			   RCC_DDRITFCR_DDRCKMOD_SSR <<
+			   RCC_DDRITFCR_DDRCKMOD_SHIFT);
+
+	return 0;
+}
+
+static void stm32mp1_osc_clk_init(const char *name,
+				  struct stm32mp1_clk_priv *priv,
+				  enum stm32mp_osc_id index)
+{
+	uint32_t frequency;
+
+	priv->osc[index] = 0;
+
+	if (fdt_osc_read_freq(name, &frequency) != 0) {
+		ERROR("%s frequency request failed\n", name);
+		panic();
+	} else {
+		priv->osc[index] = frequency;
+	}
+}
+
+static void stm32mp1_osc_init(void)
+{
+	struct stm32mp1_clk_priv *priv = &stm32mp1_clk_priv_data;
+	enum stm32mp_osc_id i;
+
+	for (i = (enum stm32mp_osc_id)0 ; i < NB_OSC; i++) {
+		stm32mp1_osc_clk_init(stm32mp_osc_node_label[i], priv, i);
+	}
+}
+
+int stm32mp1_clk_probe(void)
+{
+	struct stm32mp1_clk_priv *priv = &stm32mp1_clk_priv_data;
+
+	priv->base = fdt_rcc_read_addr();
+	if (priv->base == 0U) {
+		return -EINVAL;
+	}
+
+	priv->data = &stm32mp1_data;
+
+	if ((priv->data->gate == NULL) || (priv->data->sel == NULL) ||
+	    (priv->data->pll == NULL)) {
+		return -EINVAL;
+	}
+
+	stm32mp1_osc_init();
+
+	return 0;
+}
diff --git a/drivers/st/clk/stm32mp1_clkfunc.c b/drivers/st/clk/stm32mp1_clkfunc.c
new file mode 100644
index 0000000..d4c69cb
--- /dev/null
+++ b/drivers/st/clk/stm32mp1_clkfunc.c
@@ -0,0 +1,365 @@
+/*
+ * Copyright (c) 2017-2018, STMicroelectronics - All Rights Reserved
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <dt-bindings/clock/stm32mp1-clksrc.h>
+#include <errno.h>
+#include <libfdt.h>
+#include <stm32mp1_clk.h>
+#include <stm32mp1_clkfunc.h>
+#include <stm32mp1_dt.h>
+
+#define DT_RCC_NODE_NAME	"rcc@50000000"
+#define DT_RCC_CLK_COMPAT	"st,stm32mp1-rcc"
+#define DT_RCC_COMPAT		"syscon"
+#define DT_STGEN_COMPAT		"st,stm32-stgen"
+#define DT_UART_COMPAT		"st,stm32h7-uart"
+#define DT_USART_COMPAT		"st,stm32h7-usart"
+
+const char *stm32mp_osc_node_label[NB_OSC] = {
+	[_LSI] = "clk-lsi",
+	[_LSE] = "clk-lse",
+	[_HSI] = "clk-hsi",
+	[_HSE] = "clk-hse",
+	[_CSI] = "clk-csi",
+	[_I2S_CKIN] = "i2s_ckin",
+	[_USB_PHY_48] = "ck_usbo_48m"
+};
+
+/*******************************************************************************
+ * This function reads the frequency of an oscillator from its name.
+ * It reads the value indicated inside the device tree.
+ * Returns 0 if success, and a negative value else.
+ * If success, value is stored in the second parameter.
+ ******************************************************************************/
+int fdt_osc_read_freq(const char *name, uint32_t *freq)
+{
+	int node, subnode;
+	void *fdt;
+
+	if (fdt_get_address(&fdt) == 0) {
+		return -ENOENT;
+	}
+
+	node = fdt_path_offset(fdt, "/clocks");
+	if (node < 0) {
+		return -FDT_ERR_NOTFOUND;
+	}
+
+	fdt_for_each_subnode(subnode, fdt, node) {
+		const char *cchar;
+		int ret;
+
+		cchar = fdt_get_name(fdt, subnode, &ret);
+		if (cchar == NULL) {
+			return ret;
+		}
+
+		if (strncmp(cchar, name, (size_t)ret) == 0) {
+			const fdt32_t *cuint;
+
+			cuint = fdt_getprop(fdt, subnode, "clock-frequency",
+					    &ret);
+			if (cuint == NULL) {
+				return ret;
+			}
+
+			*freq = fdt32_to_cpu(*cuint);
+
+			return 0;
+		}
+	}
+
+	/* Oscillator not found, freq=0 */
+	*freq = 0;
+	return 0;
+}
+
+/*******************************************************************************
+ * This function checks the presence of an oscillator property from its id.
+ * The search is done inside the device tree.
+ * Returns true/false regarding search result.
+ ******************************************************************************/
+bool fdt_osc_read_bool(enum stm32mp_osc_id osc_id, const char *prop_name)
+{
+	int node, subnode;
+	void *fdt;
+
+	if (fdt_get_address(&fdt) == 0) {
+		return false;
+	}
+
+	if (osc_id >= NB_OSC) {
+		return false;
+	}
+
+	node = fdt_path_offset(fdt, "/clocks");
+	if (node < 0) {
+		return false;
+	}
+
+	fdt_for_each_subnode(subnode, fdt, node) {
+		const char *cchar;
+		int ret;
+
+		cchar = fdt_get_name(fdt, subnode, &ret);
+		if (cchar == NULL) {
+			return false;
+		}
+
+		if (strncmp(cchar, stm32mp_osc_node_label[osc_id],
+			    (size_t)ret) != 0) {
+			continue;
+		}
+
+		if (fdt_getprop(fdt, subnode, prop_name, NULL) != NULL) {
+			return true;
+		}
+	}
+
+	return false;
+}
+
+/*******************************************************************************
+ * This function reads a value of a oscillator property from its id.
+ * Returns value if success, and a default value if property not found.
+ * Default value is passed as parameter.
+ ******************************************************************************/
+uint32_t fdt_osc_read_uint32_default(enum stm32mp_osc_id osc_id,
+				     const char *prop_name, uint32_t dflt_value)
+{
+	int node, subnode;
+	void *fdt;
+
+	if (fdt_get_address(&fdt) == 0) {
+		return dflt_value;
+	}
+
+	if (osc_id >= NB_OSC) {
+		return dflt_value;
+	}
+
+	node = fdt_path_offset(fdt, "/clocks");
+	if (node < 0) {
+		return dflt_value;
+	}
+
+	fdt_for_each_subnode(subnode, fdt, node) {
+		const char *cchar;
+		int ret;
+
+		cchar = fdt_get_name(fdt, subnode, &ret);
+		if (cchar == NULL) {
+			return dflt_value;
+		}
+
+		if (strncmp(cchar, stm32mp_osc_node_label[osc_id],
+			    (size_t)ret) != 0) {
+			continue;
+		}
+
+		return fdt_read_uint32_default(subnode, prop_name, dflt_value);
+	}
+
+	return dflt_value;
+}
+
+/*******************************************************************************
+ * This function reads the rcc base address.
+ * It reads the value indicated inside the device tree.
+ * Returns address if success, and 0 value else.
+ ******************************************************************************/
+uint32_t fdt_rcc_read_addr(void)
+{
+	int node, subnode;
+	void *fdt;
+
+	if (fdt_get_address(&fdt) == 0) {
+		return 0;
+	}
+
+	node = fdt_path_offset(fdt, "/soc");
+	if (node < 0) {
+		return 0;
+	}
+
+	fdt_for_each_subnode(subnode, fdt, node) {
+		const char *cchar;
+		int ret;
+
+		cchar = fdt_get_name(fdt, subnode, &ret);
+		if (cchar == NULL) {
+			return 0;
+		}
+
+		if (strncmp(cchar, DT_RCC_NODE_NAME, (size_t)ret) == 0) {
+			const fdt32_t *cuint;
+
+			cuint = fdt_getprop(fdt, subnode, "reg", NULL);
+			if (cuint == NULL) {
+				return 0;
+			}
+
+			return fdt32_to_cpu(*cuint);
+		}
+	}
+
+	return 0;
+}
+
+/*******************************************************************************
+ * This function reads a series of parameters in rcc-clk section.
+ * It reads the values indicated inside the device tree, from property name.
+ * The number of parameters is also indicated as entry parameter.
+ * Returns 0 if success, and a negative value else.
+ * If success, values are stored at the second parameter address.
+ ******************************************************************************/
+int fdt_rcc_read_uint32_array(const char *prop_name,
+			      uint32_t *array, uint32_t count)
+{
+	int node;
+	void *fdt;
+
+	if (fdt_get_address(&fdt) == 0) {
+		return -ENOENT;
+	}
+
+	node = fdt_node_offset_by_compatible(fdt, -1, DT_RCC_CLK_COMPAT);
+	if (node < 0) {
+		return -FDT_ERR_NOTFOUND;
+	}
+
+	return fdt_read_uint32_array(node, prop_name, array, count);
+}
+
+/*******************************************************************************
+ * This function gets the subnode offset in rcc-clk section from its name.
+ * It reads the values indicated inside the device tree.
+ * Returns offset if success, and a negative value else.
+ ******************************************************************************/
+int fdt_rcc_subnode_offset(const char *name)
+{
+	int node, subnode;
+	void *fdt;
+
+	if (fdt_get_address(&fdt) == 0) {
+		return -ENOENT;
+	}
+
+	node = fdt_node_offset_by_compatible(fdt, -1, DT_RCC_CLK_COMPAT);
+	if (node < 0) {
+		return -FDT_ERR_NOTFOUND;
+	}
+
+	subnode = fdt_subnode_offset(fdt, node, name);
+	if (subnode <= 0) {
+		return -FDT_ERR_NOTFOUND;
+	}
+
+	return subnode;
+}
+
+/*******************************************************************************
+ * This function gets the pointer to a rcc-clk property from its name.
+ * It reads the values indicated inside the device tree.
+ * Length of the property is stored in the second parameter.
+ * Returns pointer if success, and NULL value else.
+ ******************************************************************************/
+const uint32_t *fdt_rcc_read_prop(const char *prop_name, int *lenp)
+{
+	const uint32_t *cuint;
+	int node, len;
+	void *fdt;
+
+	if (fdt_get_address(&fdt) == 0) {
+		return NULL;
+	}
+
+	node = fdt_node_offset_by_compatible(fdt, -1, DT_RCC_CLK_COMPAT);
+	if (node < 0) {
+		return NULL;
+	}
+
+	cuint = fdt_getprop(fdt, node, prop_name, &len);
+	if (cuint == NULL) {
+		return NULL;
+	}
+
+	*lenp = len;
+	return cuint;
+}
+
+/*******************************************************************************
+ * This function gets the secure status for rcc node.
+ * It reads secure-status in device tree.
+ * Returns 1 if rcc is available from secure world, 0 else.
+ ******************************************************************************/
+bool fdt_get_rcc_secure_status(void)
+{
+	int node;
+	void *fdt;
+
+	if (fdt_get_address(&fdt) == 0) {
+		return false;
+	}
+
+	node = fdt_node_offset_by_compatible(fdt, -1, DT_RCC_COMPAT);
+	if (node < 0) {
+		return false;
+	}
+
+	return fdt_check_secure_status(node);
+}
+
+/*******************************************************************************
+ * This function reads the stgen base address.
+ * It reads the value indicated inside the device tree.
+ * Returns address if success, and NULL value else.
+ ******************************************************************************/
+uintptr_t fdt_get_stgen_base(void)
+{
+	int node;
+	const fdt32_t *cuint;
+	void *fdt;
+
+	if (fdt_get_address(&fdt) == 0) {
+		return 0;
+	}
+
+	node = fdt_node_offset_by_compatible(fdt, -1, DT_STGEN_COMPAT);
+	if (node < 0) {
+		return 0;
+	}
+
+	cuint = fdt_getprop(fdt, node, "reg", NULL);
+	if (cuint == NULL) {
+		return 0;
+	}
+
+	return fdt32_to_cpu(*cuint);
+}
+
+/*******************************************************************************
+ * This function gets the clock ID of the given node.
+ * It reads the value indicated inside the device tree.
+ * Returns ID if success, and a negative value else.
+ ******************************************************************************/
+int fdt_get_clock_id(int node)
+{
+	const fdt32_t *cuint;
+	void *fdt;
+
+	if (fdt_get_address(&fdt) == 0) {
+		return -ENOENT;
+	}
+
+	cuint = fdt_getprop(fdt, node, "clocks", NULL);
+	if (cuint == NULL) {
+		return -FDT_ERR_NOTFOUND;
+	}
+
+	cuint++;
+	return (int)fdt32_to_cpu(*cuint);
+}
diff --git a/drivers/st/ddr/stm32mp1_ddr.c b/drivers/st/ddr/stm32mp1_ddr.c
new file mode 100644
index 0000000..eed1d76
--- /dev/null
+++ b/drivers/st/ddr/stm32mp1_ddr.c
@@ -0,0 +1,895 @@
+/*
+ * Copyright (C) 2018, STMicroelectronics - All Rights Reserved
+ *
+ * SPDX-License-Identifier: GPL-2.0+ OR BSD-3-Clause
+ */
+
+#include <arch.h>
+#include <arch_helpers.h>
+#include <debug.h>
+#include <delay_timer.h>
+#include <dt-bindings/clock/stm32mp1-clks.h>
+#include <mmio.h>
+#include <platform.h>
+#include <stddef.h>
+#include <stm32mp1_clk.h>
+#include <stm32mp1_ddr.h>
+#include <stm32mp1_ddr_regs.h>
+#include <stm32mp1_dt.h>
+#include <stm32mp1_pmic.h>
+#include <stm32mp1_pwr.h>
+#include <stm32mp1_ram.h>
+#include <stm32mp1_rcc.h>
+
+struct reg_desc {
+	const char *name;
+	uint16_t offset;	/* Offset for base address */
+	uint8_t par_offset;	/* Offset for parameter array */
+};
+
+#define INVALID_OFFSET	0xFFU
+
+#define TIMESLOT_1US	(plat_get_syscnt_freq2() / 1000000U)
+
+#define DDRCTL_REG(x, y)					\
+	{							\
+		.name = #x,					\
+		.offset = offsetof(struct stm32mp1_ddrctl, x),	\
+		.par_offset = offsetof(struct y, x)		\
+	}
+
+#define DDRPHY_REG(x, y)					\
+	{							\
+		.name = #x,					\
+		.offset = offsetof(struct stm32mp1_ddrphy, x),	\
+		.par_offset = offsetof(struct y, x)		\
+	}
+
+#define DDRCTL_REG_REG(x)	DDRCTL_REG(x, stm32mp1_ddrctrl_reg)
+static const struct reg_desc ddr_reg[] = {
+	DDRCTL_REG_REG(mstr),
+	DDRCTL_REG_REG(mrctrl0),
+	DDRCTL_REG_REG(mrctrl1),
+	DDRCTL_REG_REG(derateen),
+	DDRCTL_REG_REG(derateint),
+	DDRCTL_REG_REG(pwrctl),
+	DDRCTL_REG_REG(pwrtmg),
+	DDRCTL_REG_REG(hwlpctl),
+	DDRCTL_REG_REG(rfshctl0),
+	DDRCTL_REG_REG(rfshctl3),
+	DDRCTL_REG_REG(crcparctl0),
+	DDRCTL_REG_REG(zqctl0),
+	DDRCTL_REG_REG(dfitmg0),
+	DDRCTL_REG_REG(dfitmg1),
+	DDRCTL_REG_REG(dfilpcfg0),
+	DDRCTL_REG_REG(dfiupd0),
+	DDRCTL_REG_REG(dfiupd1),
+	DDRCTL_REG_REG(dfiupd2),
+	DDRCTL_REG_REG(dfiphymstr),
+	DDRCTL_REG_REG(odtmap),
+	DDRCTL_REG_REG(dbg0),
+	DDRCTL_REG_REG(dbg1),
+	DDRCTL_REG_REG(dbgcmd),
+	DDRCTL_REG_REG(poisoncfg),
+	DDRCTL_REG_REG(pccfg),
+};
+
+#define DDRCTL_REG_TIMING(x)	DDRCTL_REG(x, stm32mp1_ddrctrl_timing)
+static const struct reg_desc ddr_timing[] = {
+	DDRCTL_REG_TIMING(rfshtmg),
+	DDRCTL_REG_TIMING(dramtmg0),
+	DDRCTL_REG_TIMING(dramtmg1),
+	DDRCTL_REG_TIMING(dramtmg2),
+	DDRCTL_REG_TIMING(dramtmg3),
+	DDRCTL_REG_TIMING(dramtmg4),
+	DDRCTL_REG_TIMING(dramtmg5),
+	DDRCTL_REG_TIMING(dramtmg6),
+	DDRCTL_REG_TIMING(dramtmg7),
+	DDRCTL_REG_TIMING(dramtmg8),
+	DDRCTL_REG_TIMING(dramtmg14),
+	DDRCTL_REG_TIMING(odtcfg),
+};
+
+#define DDRCTL_REG_MAP(x)	DDRCTL_REG(x, stm32mp1_ddrctrl_map)
+static const struct reg_desc ddr_map[] = {
+	DDRCTL_REG_MAP(addrmap1),
+	DDRCTL_REG_MAP(addrmap2),
+	DDRCTL_REG_MAP(addrmap3),
+	DDRCTL_REG_MAP(addrmap4),
+	DDRCTL_REG_MAP(addrmap5),
+	DDRCTL_REG_MAP(addrmap6),
+	DDRCTL_REG_MAP(addrmap9),
+	DDRCTL_REG_MAP(addrmap10),
+	DDRCTL_REG_MAP(addrmap11),
+};
+
+#define DDRCTL_REG_PERF(x)	DDRCTL_REG(x, stm32mp1_ddrctrl_perf)
+static const struct reg_desc ddr_perf[] = {
+	DDRCTL_REG_PERF(sched),
+	DDRCTL_REG_PERF(sched1),
+	DDRCTL_REG_PERF(perfhpr1),
+	DDRCTL_REG_PERF(perflpr1),
+	DDRCTL_REG_PERF(perfwr1),
+	DDRCTL_REG_PERF(pcfgr_0),
+	DDRCTL_REG_PERF(pcfgw_0),
+	DDRCTL_REG_PERF(pcfgqos0_0),
+	DDRCTL_REG_PERF(pcfgqos1_0),
+	DDRCTL_REG_PERF(pcfgwqos0_0),
+	DDRCTL_REG_PERF(pcfgwqos1_0),
+	DDRCTL_REG_PERF(pcfgr_1),
+	DDRCTL_REG_PERF(pcfgw_1),
+	DDRCTL_REG_PERF(pcfgqos0_1),
+	DDRCTL_REG_PERF(pcfgqos1_1),
+	DDRCTL_REG_PERF(pcfgwqos0_1),
+	DDRCTL_REG_PERF(pcfgwqos1_1),
+};
+
+#define DDRPHY_REG_REG(x)	DDRPHY_REG(x, stm32mp1_ddrphy_reg)
+static const struct reg_desc ddrphy_reg[] = {
+	DDRPHY_REG_REG(pgcr),
+	DDRPHY_REG_REG(aciocr),
+	DDRPHY_REG_REG(dxccr),
+	DDRPHY_REG_REG(dsgcr),
+	DDRPHY_REG_REG(dcr),
+	DDRPHY_REG_REG(odtcr),
+	DDRPHY_REG_REG(zq0cr1),
+	DDRPHY_REG_REG(dx0gcr),
+	DDRPHY_REG_REG(dx1gcr),
+	DDRPHY_REG_REG(dx2gcr),
+	DDRPHY_REG_REG(dx3gcr),
+};
+
+#define DDRPHY_REG_TIMING(x)	DDRPHY_REG(x, stm32mp1_ddrphy_timing)
+static const struct reg_desc ddrphy_timing[] = {
+	DDRPHY_REG_TIMING(ptr0),
+	DDRPHY_REG_TIMING(ptr1),
+	DDRPHY_REG_TIMING(ptr2),
+	DDRPHY_REG_TIMING(dtpr0),
+	DDRPHY_REG_TIMING(dtpr1),
+	DDRPHY_REG_TIMING(dtpr2),
+	DDRPHY_REG_TIMING(mr0),
+	DDRPHY_REG_TIMING(mr1),
+	DDRPHY_REG_TIMING(mr2),
+	DDRPHY_REG_TIMING(mr3),
+};
+
+#define DDRPHY_REG_CAL(x)	DDRPHY_REG(x, stm32mp1_ddrphy_cal)
+static const struct reg_desc ddrphy_cal[] = {
+	DDRPHY_REG_CAL(dx0dllcr),
+	DDRPHY_REG_CAL(dx0dqtr),
+	DDRPHY_REG_CAL(dx0dqstr),
+	DDRPHY_REG_CAL(dx1dllcr),
+	DDRPHY_REG_CAL(dx1dqtr),
+	DDRPHY_REG_CAL(dx1dqstr),
+	DDRPHY_REG_CAL(dx2dllcr),
+	DDRPHY_REG_CAL(dx2dqtr),
+	DDRPHY_REG_CAL(dx2dqstr),
+	DDRPHY_REG_CAL(dx3dllcr),
+	DDRPHY_REG_CAL(dx3dqtr),
+	DDRPHY_REG_CAL(dx3dqstr),
+};
+
+#define DDR_REG_DYN(x)						\
+	{							\
+		.name = #x,					\
+		.offset = offsetof(struct stm32mp1_ddrctl, x),	\
+		.par_offset = INVALID_OFFSET \
+	}
+
+static const struct reg_desc ddr_dyn[] = {
+	DDR_REG_DYN(stat),
+	DDR_REG_DYN(init0),
+	DDR_REG_DYN(dfimisc),
+	DDR_REG_DYN(dfistat),
+	DDR_REG_DYN(swctl),
+	DDR_REG_DYN(swstat),
+	DDR_REG_DYN(pctrl_0),
+	DDR_REG_DYN(pctrl_1),
+};
+
+#define DDRPHY_REG_DYN(x)					\
+	{							\
+		.name = #x,					\
+		.offset = offsetof(struct stm32mp1_ddrphy, x),	\
+		.par_offset = INVALID_OFFSET			\
+	}
+
+static const struct reg_desc ddrphy_dyn[] = {
+	DDRPHY_REG_DYN(pir),
+	DDRPHY_REG_DYN(pgsr),
+};
+
+enum reg_type {
+	REG_REG,
+	REG_TIMING,
+	REG_PERF,
+	REG_MAP,
+	REGPHY_REG,
+	REGPHY_TIMING,
+	REGPHY_CAL,
+/*
+ * Dynamic registers => managed in driver or not changed,
+ * can be dumped in interactive mode.
+ */
+	REG_DYN,
+	REGPHY_DYN,
+	REG_TYPE_NB
+};
+
+enum base_type {
+	DDR_BASE,
+	DDRPHY_BASE,
+	NONE_BASE
+};
+
+struct ddr_reg_info {
+	const char *name;
+	const struct reg_desc *desc;
+	uint8_t size;
+	enum base_type base;
+};
+
+static const struct ddr_reg_info ddr_registers[REG_TYPE_NB] = {
+	[REG_REG] = {
+		"static", ddr_reg, ARRAY_SIZE(ddr_reg), DDR_BASE
+	},
+	[REG_TIMING] = {
+		"timing", ddr_timing, ARRAY_SIZE(ddr_timing), DDR_BASE
+	},
+	[REG_PERF] = {
+		"perf", ddr_perf, ARRAY_SIZE(ddr_perf), DDR_BASE
+	},
+	[REG_MAP] = {
+		"map", ddr_map, ARRAY_SIZE(ddr_map), DDR_BASE
+	},
+	[REGPHY_REG] = {
+		"static", ddrphy_reg, ARRAY_SIZE(ddrphy_reg), DDRPHY_BASE
+	},
+	[REGPHY_TIMING] = {
+		"timing", ddrphy_timing, ARRAY_SIZE(ddrphy_timing), DDRPHY_BASE
+	},
+	[REGPHY_CAL] = {
+		"cal", ddrphy_cal, ARRAY_SIZE(ddrphy_cal), DDRPHY_BASE
+	},
+	[REG_DYN] = {
+		"dyn", ddr_dyn, ARRAY_SIZE(ddr_dyn), DDR_BASE
+	},
+	[REGPHY_DYN] = {
+		"dyn", ddrphy_dyn, ARRAY_SIZE(ddrphy_dyn), DDRPHY_BASE
+	},
+};
+
+static uint32_t get_base_addr(const struct ddr_info *priv, enum base_type base)
+{
+	if (base == DDRPHY_BASE) {
+		return (uint32_t)priv->phy;
+	} else {
+		return (uint32_t)priv->ctl;
+	}
+}
+
+static void set_reg(const struct ddr_info *priv,
+		    enum reg_type type,
+		    const void *param)
+{
+	unsigned int i;
+	unsigned int *ptr, value;
+	enum base_type base = ddr_registers[type].base;
+	uint32_t base_addr = get_base_addr(priv, base);
+	const struct reg_desc *desc = ddr_registers[type].desc;
+
+	VERBOSE("init %s\n", ddr_registers[type].name);
+	for (i = 0; i < ddr_registers[type].size; i++) {
+		ptr = (unsigned int *)(base_addr + desc[i].offset);
+		if (desc[i].par_offset == INVALID_OFFSET) {
+			ERROR("invalid parameter offset for %s", desc[i].name);
+			panic();
+		} else {
+			value = *((uint32_t *)((uint32_t)param +
+					       desc[i].par_offset));
+			mmio_write_32((uint32_t)ptr, value);
+		}
+	}
+}
+
+static void stm32mp1_ddrphy_idone_wait(struct stm32mp1_ddrphy *phy)
+{
+	uint32_t pgsr;
+	int error = 0;
+	unsigned long start;
+	unsigned long time0, time;
+
+	start = get_timer(0);
+	time0 = start;
+
+	do {
+		pgsr = mmio_read_32((uint32_t)&phy->pgsr);
+		time = get_timer(start);
+		if (time != time0) {
+			VERBOSE("  > [0x%x] pgsr = 0x%x &\n",
+				(uint32_t)&phy->pgsr, pgsr);
+			VERBOSE("    [0x%x] pir = 0x%x (time=%x)\n",
+				(uint32_t)&phy->pir,
+				mmio_read_32((uint32_t)&phy->pir),
+				(uint32_t)time);
+		}
+
+		time0 = time;
+		if (time > plat_get_syscnt_freq2()) {
+			panic();
+		}
+		if ((pgsr & DDRPHYC_PGSR_DTERR) != 0U) {
+			VERBOSE("DQS Gate Trainig Error\n");
+			error++;
+		}
+		if ((pgsr & DDRPHYC_PGSR_DTIERR) != 0U) {
+			VERBOSE("DQS Gate Trainig Intermittent Error\n");
+			error++;
+		}
+		if ((pgsr & DDRPHYC_PGSR_DFTERR) != 0U) {
+			VERBOSE("DQS Drift Error\n");
+			error++;
+		}
+		if ((pgsr & DDRPHYC_PGSR_RVERR) != 0U) {
+			VERBOSE("Read Valid Training Error\n");
+			error++;
+		}
+		if ((pgsr & DDRPHYC_PGSR_RVEIRR) != 0U) {
+			VERBOSE("Read Valid Training Intermittent Error\n");
+			error++;
+		}
+	} while ((pgsr & DDRPHYC_PGSR_IDONE) == 0U && error == 0);
+	VERBOSE("\n[0x%x] pgsr = 0x%x\n",
+		(uint32_t)&phy->pgsr, pgsr);
+}
+
+static void stm32mp1_ddrphy_init(struct stm32mp1_ddrphy *phy, uint32_t pir)
+{
+	uint32_t pir_init = pir | DDRPHYC_PIR_INIT;
+
+	mmio_write_32((uint32_t)&phy->pir, pir_init);
+	VERBOSE("[0x%x] pir = 0x%x -> 0x%x\n",
+		(uint32_t)&phy->pir, pir_init,
+		mmio_read_32((uint32_t)&phy->pir));
+
+	/* Need to wait 10 configuration clock before start polling */
+	udelay(10);
+
+	/* Wait DRAM initialization and Gate Training Evaluation complete */
+	stm32mp1_ddrphy_idone_wait(phy);
+}
+
+/* Start quasi dynamic register update */
+static void stm32mp1_start_sw_done(struct stm32mp1_ddrctl *ctl)
+{
+	mmio_clrbits_32((uint32_t)&ctl->swctl, DDRCTRL_SWCTL_SW_DONE);
+	VERBOSE("[0x%x] swctl = 0x%x\n",
+		(uint32_t)&ctl->swctl,  mmio_read_32((uint32_t)&ctl->swctl));
+}
+
+/* Wait quasi dynamic register update */
+static void stm32mp1_wait_sw_done_ack(struct stm32mp1_ddrctl *ctl)
+{
+	unsigned long start;
+	uint32_t swstat;
+
+	mmio_setbits_32((uint32_t)&ctl->swctl, DDRCTRL_SWCTL_SW_DONE);
+	VERBOSE("[0x%x] swctl = 0x%x\n",
+		(uint32_t)&ctl->swctl, mmio_read_32((uint32_t)&ctl->swctl));
+
+	start = get_timer(0);
+	do {
+		swstat = mmio_read_32((uint32_t)&ctl->swstat);
+		VERBOSE("[0x%x] swstat = 0x%x ",
+			(uint32_t)&ctl->swstat, swstat);
+		VERBOSE("timer in ms 0x%x = start 0x%lx\r",
+			get_timer(0), start);
+		if (get_timer(start) > plat_get_syscnt_freq2()) {
+			panic();
+		}
+	} while ((swstat & DDRCTRL_SWSTAT_SW_DONE_ACK) == 0U);
+
+	VERBOSE("[0x%x] swstat = 0x%x\n",
+		(uint32_t)&ctl->swstat, swstat);
+}
+
+/* Wait quasi dynamic register update */
+static void stm32mp1_wait_operating_mode(struct ddr_info *priv, uint32_t mode)
+{
+	unsigned long start;
+	uint32_t stat;
+	uint32_t operating_mode;
+	uint32_t selref_type;
+	int break_loop = 0;
+
+	start = get_timer(0);
+	for ( ; ; ) {
+		stat = mmio_read_32((uint32_t)&priv->ctl->stat);
+		operating_mode = stat & DDRCTRL_STAT_OPERATING_MODE_MASK;
+		selref_type = stat & DDRCTRL_STAT_SELFREF_TYPE_MASK;
+		VERBOSE("[0x%x] stat = 0x%x\n",
+			(uint32_t)&priv->ctl->stat, stat);
+		VERBOSE("timer in ms 0x%x = start 0x%lx\r",
+			get_timer(0), start);
+		if (get_timer(start) > plat_get_syscnt_freq2()) {
+			panic();
+		}
+
+		if (mode == DDRCTRL_STAT_OPERATING_MODE_SR) {
+			/*
+			 * Self-refresh due to software
+			 * => checking also STAT.selfref_type.
+			 */
+			if ((operating_mode ==
+			     DDRCTRL_STAT_OPERATING_MODE_SR) &&
+			    (selref_type == DDRCTRL_STAT_SELFREF_TYPE_SR)) {
+				break_loop = 1;
+			}
+		} else if (operating_mode == mode) {
+			break_loop = 1;
+		} else if ((mode == DDRCTRL_STAT_OPERATING_MODE_NORMAL) &&
+			   (operating_mode == DDRCTRL_STAT_OPERATING_MODE_SR) &&
+			   (selref_type == DDRCTRL_STAT_SELFREF_TYPE_ASR)) {
+			/* Normal mode: handle also automatic self refresh */
+			break_loop = 1;
+		}
+
+		if (break_loop == 1) {
+			break;
+		}
+	}
+
+	VERBOSE("[0x%x] stat = 0x%x\n",
+		(uint32_t)&priv->ctl->stat, stat);
+}
+
+/* Mode Register Writes (MRW or MRS) */
+static void stm32mp1_mode_register_write(struct ddr_info *priv, uint8_t addr,
+					 uint32_t data)
+{
+	uint32_t mrctrl0;
+
+	VERBOSE("MRS: %d = %x\n", addr, data);
+
+	/*
+	 * 1. Poll MRSTAT.mr_wr_busy until it is '0'.
+	 *    This checks that there is no outstanding MR transaction.
+	 *    No write should be performed to MRCTRL0 and MRCTRL1
+	 *    if MRSTAT.mr_wr_busy = 1.
+	 */
+	while ((mmio_read_32((uint32_t)&priv->ctl->mrstat) &
+		DDRCTRL_MRSTAT_MR_WR_BUSY) != 0U) {
+		;
+	}
+
+	/*
+	 * 2. Write the MRCTRL0.mr_type, MRCTRL0.mr_addr, MRCTRL0.mr_rank
+	 *    and (for MRWs) MRCTRL1.mr_data to define the MR transaction.
+	 */
+	mrctrl0 = DDRCTRL_MRCTRL0_MR_TYPE_WRITE |
+		  DDRCTRL_MRCTRL0_MR_RANK_ALL |
+		  (((uint32_t)addr << DDRCTRL_MRCTRL0_MR_ADDR_SHIFT) &
+		   DDRCTRL_MRCTRL0_MR_ADDR_MASK);
+	mmio_write_32((uint32_t)&priv->ctl->mrctrl0, mrctrl0);
+	VERBOSE("[0x%x] mrctrl0 = 0x%x (0x%x)\n",
+		(uint32_t)&priv->ctl->mrctrl0,
+		mmio_read_32((uint32_t)&priv->ctl->mrctrl0), mrctrl0);
+	mmio_write_32((uint32_t)&priv->ctl->mrctrl1, data);
+	VERBOSE("[0x%x] mrctrl1 = 0x%x\n",
+		(uint32_t)&priv->ctl->mrctrl1,
+		mmio_read_32((uint32_t)&priv->ctl->mrctrl1));
+
+	/*
+	 * 3. In a separate APB transaction, write the MRCTRL0.mr_wr to 1. This
+	 *    bit is self-clearing, and triggers the MR transaction.
+	 *    The uMCTL2 then asserts the MRSTAT.mr_wr_busy while it performs
+	 *    the MR transaction to SDRAM, and no further access can be
+	 *    initiated until it is deasserted.
+	 */
+	mrctrl0 |= DDRCTRL_MRCTRL0_MR_WR;
+	mmio_write_32((uint32_t)&priv->ctl->mrctrl0, mrctrl0);
+
+	while ((mmio_read_32((uint32_t)&priv->ctl->mrstat) &
+	       DDRCTRL_MRSTAT_MR_WR_BUSY) != 0U) {
+		;
+	}
+
+	VERBOSE("[0x%x] mrctrl0 = 0x%x\n",
+		(uint32_t)&priv->ctl->mrctrl0, mrctrl0);
+}
+
+/* Switch DDR3 from DLL-on to DLL-off */
+static void stm32mp1_ddr3_dll_off(struct ddr_info *priv)
+{
+	uint32_t mr1 = mmio_read_32((uint32_t)&priv->phy->mr1);
+	uint32_t mr2 = mmio_read_32((uint32_t)&priv->phy->mr2);
+	uint32_t dbgcam;
+
+	VERBOSE("mr1: 0x%x\n", mr1);
+	VERBOSE("mr2: 0x%x\n", mr2);
+
+	/*
+	 * 1. Set the DBG1.dis_hif = 1.
+	 *    This prevents further reads/writes being received on the HIF.
+	 */
+	mmio_setbits_32((uint32_t)&priv->ctl->dbg1, DDRCTRL_DBG1_DIS_HIF);
+	VERBOSE("[0x%x] dbg1 = 0x%x\n",
+		(uint32_t)&priv->ctl->dbg1,
+		mmio_read_32((uint32_t)&priv->ctl->dbg1));
+
+	/*
+	 * 2. Ensure all commands have been flushed from the uMCTL2 by polling
+	 *    DBGCAM.wr_data_pipeline_empty = 1,
+	 *    DBGCAM.rd_data_pipeline_empty = 1,
+	 *    DBGCAM.dbg_wr_q_depth = 0 ,
+	 *    DBGCAM.dbg_lpr_q_depth = 0, and
+	 *    DBGCAM.dbg_hpr_q_depth = 0.
+	 */
+	do {
+		dbgcam = mmio_read_32((uint32_t)&priv->ctl->dbgcam);
+		VERBOSE("[0x%x] dbgcam = 0x%x\n",
+			(uint32_t)&priv->ctl->dbgcam, dbgcam);
+	} while ((((dbgcam & DDRCTRL_DBGCAM_DATA_PIPELINE_EMPTY) ==
+		   DDRCTRL_DBGCAM_DATA_PIPELINE_EMPTY)) &&
+		 ((dbgcam & DDRCTRL_DBGCAM_DBG_Q_DEPTH) == 0U));
+
+	/*
+	 * 3. Perform an MRS command (using MRCTRL0 and MRCTRL1 registers)
+	 *    to disable RTT_NOM:
+	 *    a. DDR3: Write to MR1[9], MR1[6] and MR1[2]
+	 *    b. DDR4: Write to MR1[10:8]
+	 */
+	mr1 &= ~(BIT(9) | BIT(6) | BIT(2));
+	stm32mp1_mode_register_write(priv, 1, mr1);
+
+	/*
+	 * 4. For DDR4 only: Perform an MRS command
+	 *    (using MRCTRL0 and MRCTRL1 registers) to write to MR5[8:6]
+	 *    to disable RTT_PARK
+	 */
+
+	/*
+	 * 5. Perform an MRS command (using MRCTRL0 and MRCTRL1 registers)
+	 *    to write to MR2[10:9], to disable RTT_WR
+	 *    (and therefore disable dynamic ODT).
+	 *    This applies for both DDR3 and DDR4.
+	 */
+	mr2 &= ~GENMASK(10, 9);
+	stm32mp1_mode_register_write(priv, 2, mr2);
+
+	/*
+	 * 6. Perform an MRS command (using MRCTRL0 and MRCTRL1 registers)
+	 *    to disable the DLL. The timing of this MRS is automatically
+	 *    handled by the uMCTL2.
+	 *    a. DDR3: Write to MR1[0]
+	 *    b. DDR4: Write to MR1[0]
+	 */
+	mr1 |= BIT(0);
+	stm32mp1_mode_register_write(priv, 1, mr1);
+
+	/*
+	 * 7. Put the SDRAM into self-refresh mode by setting
+	 *    PWRCTL.selfref_sw = 1, and polling STAT.operating_mode to ensure
+	 *    the DDRC has entered self-refresh.
+	 */
+	mmio_setbits_32((uint32_t)&priv->ctl->pwrctl,
+			DDRCTRL_PWRCTL_SELFREF_SW);
+	VERBOSE("[0x%x] pwrctl = 0x%x\n",
+		(uint32_t)&priv->ctl->pwrctl,
+		mmio_read_32((uint32_t)&priv->ctl->pwrctl));
+
+	/*
+	 * 8. Wait until STAT.operating_mode[1:0]==11 indicating that the
+	 *    DWC_ddr_umctl2 core is in self-refresh mode.
+	 *    Ensure transition to self-refresh was due to software
+	 *    by checking that STAT.selfref_type[1:0]=2.
+	 */
+	stm32mp1_wait_operating_mode(priv, DDRCTRL_STAT_OPERATING_MODE_SR);
+
+	/*
+	 * 9. Set the MSTR.dll_off_mode = 1.
+	 *    warning: MSTR.dll_off_mode is a quasi-dynamic type 2 field
+	 */
+	stm32mp1_start_sw_done(priv->ctl);
+
+	mmio_setbits_32((uint32_t)&priv->ctl->mstr, DDRCTRL_MSTR_DLL_OFF_MODE);
+	VERBOSE("[0x%x] mstr = 0x%x\n",
+		(uint32_t)&priv->ctl->mstr,
+		mmio_read_32((uint32_t)&priv->ctl->mstr));
+
+	stm32mp1_wait_sw_done_ack(priv->ctl);
+
+	/* 10. Change the clock frequency to the desired value. */
+
+	/*
+	 * 11. Update any registers which may be required to change for the new
+	 *     frequency. This includes static and dynamic registers.
+	 *     This includes both uMCTL2 registers and PHY registers.
+	 */
+
+	/* Change Bypass Mode Frequency Range */
+	if (stm32mp1_clk_get_rate(DDRPHYC) < 100000000U) {
+		mmio_clrbits_32((uint32_t)&priv->phy->dllgcr,
+				DDRPHYC_DLLGCR_BPS200);
+	} else {
+		mmio_setbits_32((uint32_t)&priv->phy->dllgcr,
+				DDRPHYC_DLLGCR_BPS200);
+	}
+
+	mmio_setbits_32((uint32_t)&priv->phy->acdllcr, DDRPHYC_ACDLLCR_DLLDIS);
+
+	mmio_setbits_32((uint32_t)&priv->phy->dx0dllcr,
+			DDRPHYC_DXNDLLCR_DLLDIS);
+	mmio_setbits_32((uint32_t)&priv->phy->dx1dllcr,
+			DDRPHYC_DXNDLLCR_DLLDIS);
+	mmio_setbits_32((uint32_t)&priv->phy->dx2dllcr,
+			DDRPHYC_DXNDLLCR_DLLDIS);
+	mmio_setbits_32((uint32_t)&priv->phy->dx3dllcr,
+			DDRPHYC_DXNDLLCR_DLLDIS);
+
+	/* 12. Exit the self-refresh state by setting PWRCTL.selfref_sw = 0. */
+	mmio_clrbits_32((uint32_t)&priv->ctl->pwrctl,
+			DDRCTRL_PWRCTL_SELFREF_SW);
+	stm32mp1_wait_operating_mode(priv, DDRCTRL_STAT_OPERATING_MODE_NORMAL);
+
+	/*
+	 * 13. If ZQCTL0.dis_srx_zqcl = 0, the uMCTL2 performs a ZQCL command
+	 *     at this point.
+	 */
+
+	/*
+	 * 14. Perform MRS commands as required to re-program timing registers
+	 *     in the SDRAM for the new frequency
+	 *     (in particular, CL, CWL and WR may need to be changed).
+	 */
+
+	/* 15. Write DBG1.dis_hif = 0 to re-enable reads and writes. */
+	mmio_clrbits_32((uint32_t)&priv->ctl->dbg1, DDRCTRL_DBG1_DIS_HIF);
+	VERBOSE("[0x%x] dbg1 = 0x%x\n",
+		(uint32_t)&priv->ctl->dbg1,
+		mmio_read_32((uint32_t)&priv->ctl->dbg1));
+}
+
+static void stm32mp1_refresh_disable(struct stm32mp1_ddrctl *ctl)
+{
+	stm32mp1_start_sw_done(ctl);
+	/* Quasi-dynamic register update*/
+	mmio_setbits_32((uint32_t)&ctl->rfshctl3,
+			DDRCTRL_RFSHCTL3_DIS_AUTO_REFRESH);
+	mmio_clrbits_32((uint32_t)&ctl->pwrctl, DDRCTRL_PWRCTL_POWERDOWN_EN);
+	mmio_clrbits_32((uint32_t)&ctl->dfimisc,
+			DDRCTRL_DFIMISC_DFI_INIT_COMPLETE_EN);
+	stm32mp1_wait_sw_done_ack(ctl);
+}
+
+static void stm32mp1_refresh_restore(struct stm32mp1_ddrctl *ctl,
+				     uint32_t rfshctl3, uint32_t pwrctl)
+{
+	stm32mp1_start_sw_done(ctl);
+	if ((rfshctl3 & DDRCTRL_RFSHCTL3_DIS_AUTO_REFRESH) == 0U) {
+		mmio_clrbits_32((uint32_t)&ctl->rfshctl3,
+				DDRCTRL_RFSHCTL3_DIS_AUTO_REFRESH);
+	}
+	if ((pwrctl & DDRCTRL_PWRCTL_POWERDOWN_EN) != 0U) {
+		mmio_setbits_32((uint32_t)&ctl->pwrctl,
+				DDRCTRL_PWRCTL_POWERDOWN_EN);
+	}
+	mmio_setbits_32((uint32_t)&ctl->dfimisc,
+			DDRCTRL_DFIMISC_DFI_INIT_COMPLETE_EN);
+	stm32mp1_wait_sw_done_ack(ctl);
+}
+
+static int board_ddr_power_init(enum ddr_type ddr_type)
+{
+	if (dt_check_pmic()) {
+		return pmic_ddr_power_init(ddr_type);
+	}
+
+	return 0;
+}
+
+void stm32mp1_ddr_init(struct ddr_info *priv,
+		       struct stm32mp1_ddr_config *config)
+{
+	uint32_t pir;
+	int ret;
+
+	if ((config->c_reg.mstr & DDRCTRL_MSTR_DDR3) != 0U) {
+		ret = board_ddr_power_init(STM32MP_DDR3);
+	} else {
+		ret = board_ddr_power_init(STM32MP_LPDDR2);
+	}
+
+	if (ret != 0) {
+		panic();
+	}
+
+	VERBOSE("name = %s\n", config->info.name);
+	VERBOSE("speed = %d MHz\n", config->info.speed);
+	VERBOSE("size  = 0x%x\n", config->info.size);
+
+	/* DDR INIT SEQUENCE */
+
+	/*
+	 * 1. Program the DWC_ddr_umctl2 registers
+	 *     nota: check DFIMISC.dfi_init_complete = 0
+	 */
+
+	/* 1.1 RESETS: presetn, core_ddrc_rstn, aresetn */
+	mmio_setbits_32(priv->rcc + RCC_DDRITFCR, RCC_DDRITFCR_DDRCAPBRST);
+	mmio_setbits_32(priv->rcc + RCC_DDRITFCR, RCC_DDRITFCR_DDRCAXIRST);
+	mmio_setbits_32(priv->rcc + RCC_DDRITFCR, RCC_DDRITFCR_DDRCORERST);
+	mmio_setbits_32(priv->rcc + RCC_DDRITFCR, RCC_DDRITFCR_DPHYAPBRST);
+	mmio_setbits_32(priv->rcc + RCC_DDRITFCR, RCC_DDRITFCR_DPHYRST);
+	mmio_setbits_32(priv->rcc + RCC_DDRITFCR, RCC_DDRITFCR_DPHYCTLRST);
+
+	/* 1.2. start CLOCK */
+	if (stm32mp1_ddr_clk_enable(priv, config->info.speed) != 0) {
+		panic();
+	}
+
+	/* 1.3. deassert reset */
+	/* De-assert PHY rstn and ctl_rstn via DPHYRST and DPHYCTLRST. */
+	mmio_clrbits_32(priv->rcc + RCC_DDRITFCR, RCC_DDRITFCR_DPHYRST);
+	mmio_clrbits_32(priv->rcc + RCC_DDRITFCR, RCC_DDRITFCR_DPHYCTLRST);
+	/*
+	 * De-assert presetn once the clocks are active
+	 * and stable via DDRCAPBRST bit.
+	 */
+	mmio_clrbits_32(priv->rcc + RCC_DDRITFCR, RCC_DDRITFCR_DDRCAPBRST);
+
+	/* 1.4. wait 128 cycles to permit initialization of end logic */
+	udelay(2);
+	/* For PCLK = 133MHz => 1 us is enough, 2 to allow lower frequency */
+
+	/* 1.5. initialize registers ddr_umctl2 */
+	/* Stop uMCTL2 before PHY is ready */
+	mmio_clrbits_32((uint32_t)&priv->ctl->dfimisc,
+			DDRCTRL_DFIMISC_DFI_INIT_COMPLETE_EN);
+	VERBOSE("[0x%x] dfimisc = 0x%x\n",
+		(uint32_t)&priv->ctl->dfimisc,
+		mmio_read_32((uint32_t)&priv->ctl->dfimisc));
+
+	set_reg(priv, REG_REG, &config->c_reg);
+
+	/* DDR3 = don't set DLLOFF for init mode */
+	if ((config->c_reg.mstr &
+	     (DDRCTRL_MSTR_DDR3 | DDRCTRL_MSTR_DLL_OFF_MODE))
+	    == (DDRCTRL_MSTR_DDR3 | DDRCTRL_MSTR_DLL_OFF_MODE)) {
+		VERBOSE("deactivate DLL OFF in mstr\n");
+		mmio_clrbits_32((uint32_t)&priv->ctl->mstr,
+				DDRCTRL_MSTR_DLL_OFF_MODE);
+		VERBOSE("[0x%x] mstr = 0x%x\n",
+			(uint32_t)&priv->ctl->mstr,
+			mmio_read_32((uint32_t)&priv->ctl->mstr));
+	}
+
+	set_reg(priv, REG_TIMING, &config->c_timing);
+	set_reg(priv, REG_MAP, &config->c_map);
+
+	/* Skip CTRL init, SDRAM init is done by PHY PUBL */
+	mmio_clrsetbits_32((uint32_t)&priv->ctl->init0,
+			   DDRCTRL_INIT0_SKIP_DRAM_INIT_MASK,
+			   DDRCTRL_INIT0_SKIP_DRAM_INIT_NORMAL);
+	VERBOSE("[0x%x] init0 = 0x%x\n",
+		(uint32_t)&priv->ctl->init0,
+		mmio_read_32((uint32_t)&priv->ctl->init0));
+
+	set_reg(priv, REG_PERF, &config->c_perf);
+
+	/*  2. deassert reset signal core_ddrc_rstn, aresetn and presetn */
+	mmio_clrbits_32(priv->rcc + RCC_DDRITFCR, RCC_DDRITFCR_DDRCORERST);
+	mmio_clrbits_32(priv->rcc + RCC_DDRITFCR, RCC_DDRITFCR_DDRCAXIRST);
+	mmio_clrbits_32(priv->rcc + RCC_DDRITFCR, RCC_DDRITFCR_DPHYAPBRST);
+
+	/*
+	 * 3. start PHY init by accessing relevant PUBL registers
+	 *    (DXGCR, DCR, PTR*, MR*, DTPR*)
+	 */
+	set_reg(priv, REGPHY_REG, &config->p_reg);
+	set_reg(priv, REGPHY_TIMING, &config->p_timing);
+	set_reg(priv, REGPHY_CAL, &config->p_cal);
+
+	/* DDR3 = don't set DLLOFF for init mode */
+	if ((config->c_reg.mstr &
+	     (DDRCTRL_MSTR_DDR3 | DDRCTRL_MSTR_DLL_OFF_MODE))
+	    == (DDRCTRL_MSTR_DDR3 | DDRCTRL_MSTR_DLL_OFF_MODE)) {
+		VERBOSE("deactivate DLL OFF in mr1\n");
+		mmio_clrbits_32((uint32_t)&priv->phy->mr1, BIT(0));
+		VERBOSE("[0x%x] mr1 = 0x%x\n",
+			(uint32_t)&priv->phy->mr1,
+			mmio_read_32((uint32_t)&priv->phy->mr1));
+	}
+
+	/*
+	 *  4. Monitor PHY init status by polling PUBL register PGSR.IDONE
+	 *     Perform DDR PHY DRAM initialization and Gate Training Evaluation
+	 */
+	stm32mp1_ddrphy_idone_wait(priv->phy);
+
+	/*
+	 *  5. Indicate to PUBL that controller performs SDRAM initialization
+	 *     by setting PIR.INIT and PIR CTLDINIT and pool PGSR.IDONE
+	 *     DRAM init is done by PHY, init0.skip_dram.init = 1
+	 */
+
+	pir = DDRPHYC_PIR_DLLSRST | DDRPHYC_PIR_DLLLOCK | DDRPHYC_PIR_ZCAL |
+	      DDRPHYC_PIR_ITMSRST | DDRPHYC_PIR_DRAMINIT | DDRPHYC_PIR_ICPC;
+
+	if ((config->c_reg.mstr & DDRCTRL_MSTR_DDR3) != 0U) {
+		pir |= DDRPHYC_PIR_DRAMRST; /* Only for DDR3 */
+	}
+
+	stm32mp1_ddrphy_init(priv->phy, pir);
+
+	/*
+	 *  6. SET DFIMISC.dfi_init_complete_en to 1
+	 *  Enable quasi-dynamic register programming.
+	 */
+	stm32mp1_start_sw_done(priv->ctl);
+
+	mmio_setbits_32((uint32_t)&priv->ctl->dfimisc,
+			DDRCTRL_DFIMISC_DFI_INIT_COMPLETE_EN);
+	VERBOSE("[0x%x] dfimisc = 0x%x\n",
+		(uint32_t)&priv->ctl->dfimisc,
+		mmio_read_32((uint32_t)&priv->ctl->dfimisc));
+
+	stm32mp1_wait_sw_done_ack(priv->ctl);
+
+	/*
+	 *  7. Wait for DWC_ddr_umctl2 to move to normal operation mode
+	 *     by monitoring STAT.operating_mode signal
+	 */
+
+	/* Wait uMCTL2 ready */
+	stm32mp1_wait_operating_mode(priv, DDRCTRL_STAT_OPERATING_MODE_NORMAL);
+
+	/* Switch to DLL OFF mode */
+	if ((config->c_reg.mstr & DDRCTRL_MSTR_DLL_OFF_MODE) != 0U) {
+		stm32mp1_ddr3_dll_off(priv);
+	}
+
+	VERBOSE("DDR DQS training : ");
+
+	/*
+	 *  8. Disable Auto refresh and power down by setting
+	 *    - RFSHCTL3.dis_au_refresh = 1
+	 *    - PWRCTL.powerdown_en = 0
+	 *    - DFIMISC.dfiinit_complete_en = 0
+	 */
+	stm32mp1_refresh_disable(priv->ctl);
+
+	/*
+	 *  9. Program PUBL PGCR to enable refresh during training
+	 *     and rank to train
+	 *     not done => keep the programed value in PGCR
+	 */
+
+	/*
+	 * 10. configure PUBL PIR register to specify which training step
+	 * to run
+	 * Warning : RVTRN  is not supported by this PUBL
+	 */
+	stm32mp1_ddrphy_init(priv->phy, DDRPHYC_PIR_QSTRN);
+
+	/* 11. monitor PUB PGSR.IDONE to poll cpmpletion of training sequence */
+	stm32mp1_ddrphy_idone_wait(priv->phy);
+
+	/*
+	 * 12. set back registers in step 8 to the orginal values if desidered
+	 */
+	stm32mp1_refresh_restore(priv->ctl, config->c_reg.rfshctl3,
+				 config->c_reg.pwrctl);
+
+	/* Enable uMCTL2 AXI port 0 */
+	mmio_setbits_32((uint32_t)&priv->ctl->pctrl_0, DDRCTRL_PCTRL_N_PORT_EN);
+	VERBOSE("[0x%x] pctrl_0 = 0x%x\n",
+		(uint32_t)&priv->ctl->pctrl_0,
+		mmio_read_32((uint32_t)&priv->ctl->pctrl_0));
+
+	/* Enable uMCTL2 AXI port 1 */
+	mmio_setbits_32((uint32_t)&priv->ctl->pctrl_1, DDRCTRL_PCTRL_N_PORT_EN);
+	VERBOSE("[0x%x] pctrl_1 = 0x%x\n",
+		(uint32_t)&priv->ctl->pctrl_1,
+		mmio_read_32((uint32_t)&priv->ctl->pctrl_1));
+}
diff --git a/drivers/st/ddr/stm32mp1_ddr_helpers.c b/drivers/st/ddr/stm32mp1_ddr_helpers.c
new file mode 100644
index 0000000..325c0b8
--- /dev/null
+++ b/drivers/st/ddr/stm32mp1_ddr_helpers.c
@@ -0,0 +1,20 @@
+/*
+ * Copyright (c) 2017-2018, STMicroelectronics - All Rights Reserved
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <mmio.h>
+#include <platform_def.h>
+#include <stm32mp1_ddr_helpers.h>
+#include <stm32mp1_rcc.h>
+
+void ddr_enable_clock(void)
+{
+	mmio_setbits_32(RCC_BASE + RCC_DDRITFCR,
+			RCC_DDRITFCR_DDRC1EN |
+			RCC_DDRITFCR_DDRC2EN |
+			RCC_DDRITFCR_DDRPHYCEN |
+			RCC_DDRITFCR_DDRPHYCAPBEN |
+			RCC_DDRITFCR_DDRCAPBEN);
+}
diff --git a/drivers/st/ddr/stm32mp1_ram.c b/drivers/st/ddr/stm32mp1_ram.c
new file mode 100644
index 0000000..6d515ec
--- /dev/null
+++ b/drivers/st/ddr/stm32mp1_ram.c
@@ -0,0 +1,308 @@
+/*
+ * Copyright (C) 2018, STMicroelectronics - All Rights Reserved
+ *
+ * SPDX-License-Identifier: GPL-2.0+ OR BSD-3-Clause
+ */
+
+#include <arch_helpers.h>
+#include <boot_api.h>
+#include <debug.h>
+#include <dt-bindings/clock/stm32mp1-clks.h>
+#include <errno.h>
+#include <libfdt.h>
+#include <mmio.h>
+#include <platform_def.h>
+#include <stm32mp1_clk.h>
+#include <stm32mp1_ddr.h>
+#include <stm32mp1_ddr_helpers.h>
+#include <stm32mp1_dt.h>
+#include <stm32mp1_private.h>
+#include <stm32mp1_ram.h>
+#include <stm32mp1_rcc.h>
+
+#define DDR_PATTERN	0xAAAAAAAAU
+#define DDR_ANTIPATTERN	0x55555555U
+
+static struct ddr_info ddr_priv_data;
+
+int stm32mp1_ddr_clk_enable(struct ddr_info *priv, uint16_t mem_speed)
+{
+	unsigned long ddrphy_clk, ddr_clk, mem_speed_hz;
+
+	ddr_enable_clock();
+
+	ddrphy_clk = stm32mp1_clk_get_rate(DDRPHYC);
+
+	VERBOSE("DDR: mem_speed (%d MHz), RCC %ld MHz\n",
+		mem_speed, ddrphy_clk / 1000U / 1000U);
+
+	mem_speed_hz = (uint32_t)mem_speed * 1000U * 1000U;
+
+	/* Max 10% frequency delta */
+	if (ddrphy_clk > mem_speed_hz) {
+		ddr_clk = ddrphy_clk - mem_speed_hz;
+	} else {
+		ddr_clk = mem_speed_hz - ddrphy_clk;
+	}
+	if (ddr_clk > mem_speed_hz) {
+		ERROR("DDR expected freq %d MHz, current is %ld MHz\n",
+		      mem_speed, ddrphy_clk / 1000U / 1000U);
+		return -1;
+	}
+	return 0;
+}
+
+/*******************************************************************************
+ * This function tests the DDR data bus wiring.
+ * This is inspired from the Data Bus Test algorithm written by Michael Barr
+ * in "Programming Embedded Systems in C and C++" book.
+ * resources.oreilly.com/examples/9781565923546/blob/master/Chapter6/
+ * File: memtest.c - This source code belongs to Public Domain.
+ * Returns 0 if success, and address value else.
+ ******************************************************************************/
+static uint32_t ddr_test_data_bus(void)
+{
+	uint32_t pattern;
+
+	for (pattern = 1U; pattern != 0U; pattern <<= 1) {
+		mmio_write_32(STM32MP1_DDR_BASE, pattern);
+
+		if (mmio_read_32(STM32MP1_DDR_BASE) != pattern) {
+			return (uint32_t)STM32MP1_DDR_BASE;
+		}
+	}
+
+	return 0;
+}
+
+/*******************************************************************************
+ * This function tests the DDR address bus wiring.
+ * This is inspired from the Data Bus Test algorithm written by Michael Barr
+ * in "Programming Embedded Systems in C and C++" book.
+ * resources.oreilly.com/examples/9781565923546/blob/master/Chapter6/
+ * File: memtest.c - This source code belongs to Public Domain.
+ * Returns 0 if success, and address value else.
+ ******************************************************************************/
+static uint32_t ddr_test_addr_bus(void)
+{
+	uint64_t addressmask = (ddr_priv_data.info.size - 1U);
+	uint64_t offset;
+	uint64_t testoffset = 0;
+
+	/* Write the default pattern at each of the power-of-two offsets. */
+	for (offset = sizeof(uint32_t); (offset & addressmask) != 0U;
+	     offset <<= 1) {
+		mmio_write_32(STM32MP1_DDR_BASE + (uint32_t)offset,
+			      DDR_PATTERN);
+	}
+
+	/* Check for address bits stuck high. */
+	mmio_write_32(STM32MP1_DDR_BASE + (uint32_t)testoffset,
+		      DDR_ANTIPATTERN);
+
+	for (offset = sizeof(uint32_t); (offset & addressmask) != 0U;
+	     offset <<= 1) {
+		if (mmio_read_32(STM32MP1_DDR_BASE + (uint32_t)offset) !=
+		    DDR_PATTERN) {
+			return (uint32_t)(STM32MP1_DDR_BASE + offset);
+		}
+	}
+
+	mmio_write_32(STM32MP1_DDR_BASE + (uint32_t)testoffset, DDR_PATTERN);
+
+	/* Check for address bits stuck low or shorted. */
+	for (testoffset = sizeof(uint32_t); (testoffset & addressmask) != 0U;
+	     testoffset <<= 1) {
+		mmio_write_32(STM32MP1_DDR_BASE + (uint32_t)testoffset,
+			      DDR_ANTIPATTERN);
+
+		if (mmio_read_32(STM32MP1_DDR_BASE) != DDR_PATTERN) {
+			return STM32MP1_DDR_BASE;
+		}
+
+		for (offset = sizeof(uint32_t); (offset & addressmask) != 0U;
+		     offset <<= 1) {
+			if ((mmio_read_32(STM32MP1_DDR_BASE +
+					  (uint32_t)offset) != DDR_PATTERN) &&
+			    (offset != testoffset)) {
+				return (uint32_t)(STM32MP1_DDR_BASE + offset);
+			}
+		}
+
+		mmio_write_32(STM32MP1_DDR_BASE + (uint32_t)testoffset,
+			      DDR_PATTERN);
+	}
+
+	return 0;
+}
+
+/*******************************************************************************
+ * This function checks the DDR size. It has to be run with Data Cache off.
+ * This test is run before data have been put in DDR, and is only done for
+ * cold boot. The DDR data can then be overwritten, and it is not useful to
+ * restore its content.
+ * Returns DDR computed size.
+ ******************************************************************************/
+static uint32_t ddr_check_size(void)
+{
+	uint32_t offset = sizeof(uint32_t);
+
+	mmio_write_32(STM32MP1_DDR_BASE, DDR_PATTERN);
+
+	while (offset < STM32MP1_DDR_MAX_SIZE) {
+		mmio_write_32(STM32MP1_DDR_BASE + offset, DDR_ANTIPATTERN);
+		dsb();
+
+		if (mmio_read_32(STM32MP1_DDR_BASE) != DDR_PATTERN) {
+			break;
+		}
+
+		offset <<= 1;
+	}
+
+	INFO("Memory size = 0x%x (%d MB)\n", offset, offset / (1024U * 1024U));
+
+	return offset;
+}
+
+static int stm32mp1_ddr_setup(void)
+{
+	struct ddr_info *priv = &ddr_priv_data;
+	int ret;
+	struct stm32mp1_ddr_config config;
+	int node, len;
+	uint32_t tamp_clk_off = 0, uret, idx;
+	void *fdt;
+
+#define PARAM(x, y)							\
+	{								\
+		.name = x,						\
+		.offset = offsetof(struct stm32mp1_ddr_config, y),	\
+		.size = sizeof(config.y) / sizeof(uint32_t)		\
+	}
+
+#define CTL_PARAM(x) PARAM("st,ctl-"#x, c_##x)
+#define PHY_PARAM(x) PARAM("st,phy-"#x, p_##x)
+
+	const struct {
+		const char *name; /* Name in DT */
+		const uint32_t offset; /* Offset in config struct */
+		const uint32_t size;   /* Size of parameters */
+	} param[] = {
+		CTL_PARAM(reg),
+		CTL_PARAM(timing),
+		CTL_PARAM(map),
+		CTL_PARAM(perf),
+		PHY_PARAM(reg),
+		PHY_PARAM(timing),
+		PHY_PARAM(cal)
+	};
+
+	if (fdt_get_address(&fdt) == 0) {
+		return -ENOENT;
+	}
+
+	node = fdt_node_offset_by_compatible(fdt, -1, DT_DDR_COMPAT);
+	if (node < 0) {
+		ERROR("%s: Cannot read DDR node in DT\n", __func__);
+		return -EINVAL;
+	}
+
+	config.info.speed =
+		(uint16_t)fdt_read_uint32_default(node, "st,mem-speed",
+						  STM32MP1_DDR_SPEED_DFLT);
+	config.info.size = fdt_read_uint32_default(node, "st,mem-size",
+						   STM32MP1_DDR_SIZE_DFLT);
+	config.info.name = fdt_getprop(fdt, node, "st,mem-name", &len);
+	if (config.info.name == NULL) {
+		VERBOSE("%s: no st,mem-name\n", __func__);
+		return -EINVAL;
+	}
+	INFO("RAM: %s\n", config.info.name);
+
+	for (idx = 0; idx < ARRAY_SIZE(param); idx++) {
+		ret = fdt_read_uint32_array(node, param[idx].name,
+					    (void *)((uint32_t)&config +
+						     param[idx].offset),
+					    param[idx].size);
+
+		VERBOSE("%s: %s[0x%x] = %d\n", __func__,
+			param[idx].name, param[idx].size, ret);
+		if (ret != 0) {
+			ERROR("%s: Cannot read %s\n",
+			      __func__, param[idx].name);
+			return -EINVAL;
+		}
+	}
+
+	if (!stm32mp1_clk_is_enabled(RTCAPB)) {
+		tamp_clk_off = 1;
+		if (stm32mp1_clk_enable(RTCAPB) != 0) {
+			return -EINVAL;
+		}
+	}
+
+	if (tamp_clk_off != 0U) {
+		if (stm32mp1_clk_disable(RTCAPB) != 0) {
+			return -EINVAL;
+		}
+	}
+
+	/* Disable axidcg clock gating during init */
+	mmio_clrbits_32(priv->rcc + RCC_DDRITFCR, RCC_DDRITFCR_AXIDCGEN);
+
+	stm32mp1_ddr_init(priv, &config);
+
+	/* Enable axidcg clock gating */
+	mmio_setbits_32(priv->rcc + RCC_DDRITFCR, RCC_DDRITFCR_AXIDCGEN);
+
+	priv->info.size = config.info.size;
+
+	VERBOSE("%s : ram size(%x, %x)\n", __func__,
+		(uint32_t)priv->info.base, (uint32_t)priv->info.size);
+
+	dcsw_op_all(DC_OP_CISW);
+	write_sctlr(read_sctlr() & ~SCTLR_C_BIT);
+
+	uret = ddr_test_data_bus();
+	if (uret != 0U) {
+		ERROR("DDR data bus test: can't access memory @ 0x%x\n",
+		      uret);
+		panic();
+	}
+
+	uret = ddr_test_addr_bus();
+	if (uret != 0U) {
+		ERROR("DDR addr bus test: can't access memory @ 0x%x\n",
+		      uret);
+		panic();
+	}
+
+	uret = ddr_check_size();
+	if (uret < config.info.size) {
+		ERROR("DDR size: 0x%x does not match DT config: 0x%x\n",
+		      uret, config.info.size);
+		panic();
+	}
+
+	write_sctlr(read_sctlr() | SCTLR_C_BIT);
+
+	return 0;
+}
+
+int stm32mp1_ddr_probe(void)
+{
+	struct ddr_info *priv = &ddr_priv_data;
+
+	VERBOSE("STM32MP DDR probe\n");
+
+	priv->ctl = (struct stm32mp1_ddrctl *)DDRCTRL_BASE;
+	priv->phy = (struct stm32mp1_ddrphy *)DDRPHYC_BASE;
+	priv->pwr = PWR_BASE;
+	priv->rcc = RCC_BASE;
+
+	priv->info.base = STM32MP1_DDR_BASE;
+	priv->info.size = 0;
+
+	return stm32mp1_ddr_setup();
+}
diff --git a/drivers/st/gpio/stm32_gpio.c b/drivers/st/gpio/stm32_gpio.c
new file mode 100644
index 0000000..200b473
--- /dev/null
+++ b/drivers/st/gpio/stm32_gpio.c
@@ -0,0 +1,86 @@
+/*
+ * Copyright (c) 2016-2018, STMicroelectronics - All Rights Reserved
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <bl_common.h>
+#include <debug.h>
+#include <mmio.h>
+#include <stdbool.h>
+#include <stm32_gpio.h>
+
+static bool check_gpio(uint32_t bank, uint32_t pin)
+{
+	if (pin > GPIO_PIN_MAX) {
+		ERROR("%s: wrong pin number (%d)\n", __func__, pin);
+		return false;
+	}
+
+	if ((bank > GPIO_BANK_K) && (bank != GPIO_BANK_Z)) {
+		ERROR("%s: wrong GPIO bank number (%d)\n", __func__, bank);
+		return false;
+	}
+
+	return true;
+}
+
+void set_gpio(uint32_t bank, uint32_t pin, uint32_t mode, uint32_t speed,
+	      uint32_t pull, uint32_t alternate)
+{
+	volatile uint32_t bank_address;
+
+	if (!check_gpio(bank, pin)) {
+		return;
+	}
+
+	if (bank == GPIO_BANK_Z) {
+		bank_address = STM32_GPIOZ_BANK;
+	} else {
+		bank_address = STM32_GPIOA_BANK +
+			(bank * STM32_GPIO_BANK_OFFSET);
+	}
+
+	mmio_clrbits_32(bank_address + GPIO_MODE_OFFSET,
+			((uint32_t)GPIO_MODE_MASK << (pin << 1)));
+	mmio_setbits_32(bank_address + GPIO_MODE_OFFSET,
+			(mode & ~GPIO_OPEN_DRAIN) << (pin << 1));
+
+	if ((mode & GPIO_OPEN_DRAIN) != 0U) {
+		mmio_setbits_32(bank_address + GPIO_TYPE_OFFSET,
+				BIT(pin));
+	}
+
+	mmio_clrbits_32(bank_address + GPIO_SPEED_OFFSET,
+			((uint32_t)GPIO_SPEED_MASK << (pin << 1)));
+	mmio_setbits_32(bank_address + GPIO_SPEED_OFFSET, speed << (pin << 1));
+
+	mmio_clrbits_32(bank_address + GPIO_PUPD_OFFSET,
+			((uint32_t)GPIO_PULL_MASK << (pin << 1)));
+	mmio_setbits_32(bank_address + GPIO_PUPD_OFFSET, pull << (pin << 1));
+
+	if (pin < GPIO_ALT_LOWER_LIMIT) {
+		mmio_clrbits_32(bank_address + GPIO_AFRL_OFFSET,
+				((uint32_t)GPIO_ALTERNATE_MASK << (pin << 2)));
+		mmio_setbits_32(bank_address + GPIO_AFRL_OFFSET,
+				alternate << (pin << 2));
+	} else {
+		mmio_clrbits_32(bank_address + GPIO_AFRH_OFFSET,
+				((uint32_t)GPIO_ALTERNATE_MASK <<
+				 ((pin - GPIO_ALT_LOWER_LIMIT) << 2)));
+		mmio_setbits_32(bank_address + GPIO_AFRH_OFFSET,
+				alternate << ((pin - GPIO_ALT_LOWER_LIMIT) <<
+					      2));
+	}
+
+	VERBOSE("GPIO %u mode set to 0x%x\n", bank,
+		mmio_read_32(bank_address + GPIO_MODE_OFFSET));
+	VERBOSE("GPIO %u speed set to 0x%x\n", bank,
+		mmio_read_32(bank_address + GPIO_SPEED_OFFSET));
+	VERBOSE("GPIO %u mode pull to 0x%x\n", bank,
+		mmio_read_32(bank_address + GPIO_PUPD_OFFSET));
+	VERBOSE("GPIO %u mode alternate low to 0x%x\n", bank,
+		mmio_read_32(bank_address + GPIO_AFRL_OFFSET));
+	VERBOSE("GPIO %u mode alternate high to 0x%x\n", bank,
+		mmio_read_32(bank_address + GPIO_AFRH_OFFSET));
+}
diff --git a/drivers/st/pmic/stm32_i2c.c b/drivers/st/pmic/stm32_i2c.c
new file mode 100644
index 0000000..0980139
--- /dev/null
+++ b/drivers/st/pmic/stm32_i2c.c
@@ -0,0 +1,851 @@
+/*
+ * Copyright (c) 2016-2018, STMicroelectronics - All Rights Reserved
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <arch_helpers.h>
+#include <delay_timer.h>
+#include <errno.h>
+#include <mmio.h>
+#include <stdbool.h>
+#include <stdlib.h>
+#include <stm32_i2c.h>
+
+/* STM32 I2C registers offsets */
+#define I2C_CR1			0x00U
+#define I2C_CR2			0x04U
+#define I2C_OAR1		0x08U
+#define I2C_OAR2		0x0CU
+#define I2C_TIMINGR		0x10U
+#define I2C_TIMEOUTR		0x14U
+#define I2C_ISR			0x18U
+#define I2C_ICR			0x1CU
+#define I2C_PECR		0x20U
+#define I2C_RXDR		0x24U
+#define I2C_TXDR		0x28U
+
+#define MAX_DELAY		0xFFFFFFFFU
+
+/* I2C TIMING clear register Mask */
+#define TIMING_CLEAR_MASK	0xF0FFFFFFU
+/* Timeout 25 ms */
+#define I2C_TIMEOUT_BUSY	25U
+
+#define MAX_NBYTE_SIZE		255U
+
+static int i2c_request_memory_write(struct i2c_handle_s *hi2c,
+				    uint16_t dev_addr, uint16_t mem_addr,
+				    uint16_t mem_add_size, uint32_t timeout,
+				    uint32_t tick_start);
+static int i2c_request_memory_read(struct i2c_handle_s *hi2c, uint16_t dev_addr,
+				   uint16_t mem_addr, uint16_t mem_add_size,
+				   uint32_t timeout, uint32_t tick_start);
+
+/* Private functions to handle flags during polling transfer */
+static int i2c_wait_flag(struct i2c_handle_s *hi2c, uint32_t flag,
+			 uint8_t awaited_value, uint32_t timeout,
+			 uint32_t tick_start);
+static int i2c_wait_txis(struct i2c_handle_s *hi2c, uint32_t timeout,
+			 uint32_t tick_start);
+static int i2c_wait_stop(struct i2c_handle_s *hi2c, uint32_t timeout,
+			 uint32_t tick_start);
+static int i2c_ack_failed(struct i2c_handle_s *hi2c, uint32_t timeout,
+			  uint32_t tick_start);
+
+/* Private function to flush TXDR register */
+static void i2c_flush_txdr(struct i2c_handle_s *hi2c);
+
+/* Private function to start, restart or stop a transfer */
+static void i2c_transfer_config(struct i2c_handle_s *hi2c, uint16_t dev_addr,
+				uint16_t size, uint32_t i2c_mode,
+				uint32_t request);
+
+/*
+ * @brief  Initialize the I2C device.
+ * @param  hi2c: Pointer to a struct i2c_handle_s structure that contains
+ *               the configuration information for the specified I2C.
+ * @retval 0 if OK, negative value else
+ */
+int stm32_i2c_init(struct i2c_handle_s *hi2c)
+{
+	if (hi2c == NULL) {
+		return -ENOENT;
+	}
+
+	if (hi2c->i2c_state == I2C_STATE_RESET) {
+		hi2c->lock = 0;
+	}
+
+	hi2c->i2c_state = I2C_STATE_BUSY;
+
+	/* Disable the selected I2C peripheral */
+	mmio_clrbits_32(hi2c->i2c_base_addr + I2C_CR1, I2C_CR1_PE);
+
+	/* Configure I2Cx: Frequency range */
+	mmio_write_32(hi2c->i2c_base_addr + I2C_TIMINGR,
+		      hi2c->i2c_init.timing & TIMING_CLEAR_MASK);
+
+	/* Disable Own Address1 before set the Own Address1 configuration */
+	mmio_clrbits_32(hi2c->i2c_base_addr + I2C_OAR1, I2C_OAR1_OA1EN);
+
+	/* Configure I2Cx: Own Address1 and ack own address1 mode */
+	if (hi2c->i2c_init.addressing_mode == I2C_ADDRESSINGMODE_7BIT) {
+		mmio_write_32(hi2c->i2c_base_addr + I2C_OAR1,
+			      I2C_OAR1_OA1EN | hi2c->i2c_init.own_address1);
+	} else { /* I2C_ADDRESSINGMODE_10BIT */
+		mmio_write_32(hi2c->i2c_base_addr + I2C_OAR1,
+			      I2C_OAR1_OA1EN | I2C_OAR1_OA1MODE |
+			      hi2c->i2c_init.own_address1);
+	}
+
+	/* Configure I2Cx: Addressing Master mode */
+	if (hi2c->i2c_init.addressing_mode == I2C_ADDRESSINGMODE_10BIT) {
+		mmio_write_32(hi2c->i2c_base_addr + I2C_CR2, I2C_CR2_ADD10);
+	}
+
+	/*
+	 * Enable the AUTOEND by default, and enable NACK
+	 * (should be disable only during Slave process)
+	 */
+	mmio_setbits_32(hi2c->i2c_base_addr + I2C_CR2,
+			I2C_CR2_AUTOEND | I2C_CR2_NACK);
+
+	/* Disable Own Address2 before set the Own Address2 configuration */
+	mmio_clrbits_32(hi2c->i2c_base_addr + I2C_OAR2, I2C_DUALADDRESS_ENABLE);
+
+	/* Configure I2Cx: Dual mode and Own Address2 */
+	mmio_write_32(hi2c->i2c_base_addr + I2C_OAR2,
+		      hi2c->i2c_init.dual_address_mode |
+		      hi2c->i2c_init.own_address2 |
+		      (hi2c->i2c_init.own_address2_masks << 8));
+
+	/* Configure I2Cx: Generalcall and NoStretch mode */
+	mmio_write_32(hi2c->i2c_base_addr + I2C_CR1,
+		      hi2c->i2c_init.general_call_mode |
+		      hi2c->i2c_init.no_stretch_mode);
+
+	/* Enable the selected I2C peripheral */
+	mmio_setbits_32(hi2c->i2c_base_addr + I2C_CR1, I2C_CR1_PE);
+
+	hi2c->i2c_err = I2C_ERROR_NONE;
+	hi2c->i2c_state = I2C_STATE_READY;
+	hi2c->i2c_mode = I2C_MODE_NONE;
+
+	return 0;
+}
+
+/*
+ * @brief  Write an amount of data in blocking mode to a specific memory address
+ * @param  hi2c: Pointer to a struct i2c_handle_s structure that contains
+ *               the configuration information for the specified I2C.
+ * @param  dev_addr: Target device address
+ * @param  mem_addr: Internal memory address
+ * @param  mem_add_size: size of internal memory address
+ * @param  p_data: Pointer to data buffer
+ * @param  size: Amount of data to be sent
+ * @param  timeout: timeout duration
+ * @retval 0 if OK, negative value else
+ */
+int stm32_i2c_mem_write(struct i2c_handle_s *hi2c, uint16_t dev_addr,
+			uint16_t mem_addr, uint16_t mem_add_size,
+			uint8_t *p_data, uint16_t size, uint32_t timeout)
+{
+	uint32_t tickstart;
+
+	if ((hi2c->i2c_state != I2C_STATE_READY) || (hi2c->lock != 0U)) {
+		return -EBUSY;
+	}
+
+	if ((p_data == NULL) || (size == 0U)) {
+		return -EINVAL;
+	}
+
+	hi2c->lock = 1;
+
+	tickstart = (uint32_t)read_cntpct_el0();
+
+	if (i2c_wait_flag(hi2c, I2C_FLAG_BUSY, 1, I2C_TIMEOUT_BUSY,
+			  tickstart) != 0) {
+		return -EIO;
+	}
+
+	hi2c->i2c_state     = I2C_STATE_BUSY_TX;
+	hi2c->i2c_mode      = I2C_MODE_MEM;
+	hi2c->i2c_err = I2C_ERROR_NONE;
+
+	hi2c->p_buff  = p_data;
+	hi2c->xfer_count = size;
+
+	/* Send Slave Address and Memory Address */
+	if (i2c_request_memory_write(hi2c, dev_addr, mem_addr, mem_add_size,
+				     timeout, tickstart) != 0) {
+		hi2c->lock = 0;
+		return -EIO;
+	}
+
+	/*
+	 * Set NBYTES to write and reload
+	 * if hi2c->xfer_count > MAX_NBYTE_SIZE
+	 */
+	if (hi2c->xfer_count > MAX_NBYTE_SIZE) {
+		hi2c->xfer_size = MAX_NBYTE_SIZE;
+		i2c_transfer_config(hi2c, dev_addr, hi2c->xfer_size,
+				    I2C_RELOAD_MODE, I2C_NO_STARTSTOP);
+	} else {
+		hi2c->xfer_size = hi2c->xfer_count;
+		i2c_transfer_config(hi2c, dev_addr, hi2c->xfer_size,
+				    I2C_AUTOEND_MODE, I2C_NO_STARTSTOP);
+	}
+
+	do {
+		if (i2c_wait_txis(hi2c, timeout, tickstart) != 0) {
+			return -EIO;
+		}
+
+		mmio_write_8(hi2c->i2c_base_addr + I2C_TXDR, *hi2c->p_buff);
+		hi2c->p_buff++;
+		hi2c->xfer_count--;
+		hi2c->xfer_size--;
+
+		if ((hi2c->xfer_count != 0U) && (hi2c->xfer_size == 0U)) {
+			/* Wait until TCR flag is set */
+			if (i2c_wait_flag(hi2c, I2C_FLAG_TCR, 0, timeout,
+					  tickstart) != 0) {
+				return -EIO;
+		}
+
+			if (hi2c->xfer_count > MAX_NBYTE_SIZE) {
+				hi2c->xfer_size = MAX_NBYTE_SIZE;
+				i2c_transfer_config(hi2c, dev_addr,
+						    hi2c->xfer_size,
+						    I2C_RELOAD_MODE,
+						    I2C_NO_STARTSTOP);
+			} else {
+				hi2c->xfer_size = hi2c->xfer_count;
+				i2c_transfer_config(hi2c, dev_addr,
+						    hi2c->xfer_size,
+						    I2C_AUTOEND_MODE,
+						    I2C_NO_STARTSTOP);
+			}
+		}
+
+	} while (hi2c->xfer_count > 0U);
+
+	/*
+	 * No need to Check TC flag, with AUTOEND mode the stop
+	 * is automatically generated.
+	 * Wait until STOPF flag is reset.
+	 */
+	if (i2c_wait_stop(hi2c, timeout, tickstart) != 0) {
+		return -EIO;
+	}
+
+	mmio_write_32(hi2c->i2c_base_addr + I2C_ICR, I2C_FLAG_STOPF);
+
+	mmio_clrbits_32(hi2c->i2c_base_addr + I2C_CR2, I2C_RESET_CR2);
+
+	hi2c->i2c_state = I2C_STATE_READY;
+	hi2c->i2c_mode  = I2C_MODE_NONE;
+
+	hi2c->lock = 0;
+
+	return 0;
+}
+
+/*
+ * @brief  Read an amount of data in blocking mode from a specific memory
+ *	   address
+ * @param  hi2c: Pointer to a struct i2c_handle_s structure that contains
+ *               the configuration information for the specified I2C.
+ * @param  dev_addr: Target device address
+ * @param  mem_addr: Internal memory address
+ * @param  mem_add_size: size of internal memory address
+ * @param  p_data: Pointer to data buffer
+ * @param  size: Amount of data to be sent
+ * @param  timeout: timeout duration
+ * @retval 0 if OK, negative value else
+ */
+int stm32_i2c_mem_read(struct i2c_handle_s *hi2c, uint16_t dev_addr,
+		       uint16_t mem_addr, uint16_t mem_add_size,
+		       uint8_t *p_data, uint16_t size, uint32_t timeout)
+{
+	uint32_t tickstart;
+
+	if ((hi2c->i2c_state != I2C_STATE_READY) || (hi2c->lock != 0U)) {
+		return -EBUSY;
+	}
+
+	if ((p_data == NULL) || (size == 0U)) {
+		return  -EINVAL;
+	}
+
+	hi2c->lock = 1;
+
+	tickstart = (uint32_t)read_cntpct_el0();
+
+	if (i2c_wait_flag(hi2c, I2C_FLAG_BUSY, 1, I2C_TIMEOUT_BUSY,
+			  tickstart) != 0) {
+		return -EIO;
+	}
+
+	hi2c->i2c_state     = I2C_STATE_BUSY_RX;
+	hi2c->i2c_mode      = I2C_MODE_MEM;
+	hi2c->i2c_err = I2C_ERROR_NONE;
+
+	hi2c->p_buff  = p_data;
+	hi2c->xfer_count = size;
+
+	/* Send Slave Address and Memory Address */
+	if (i2c_request_memory_read(hi2c, dev_addr, mem_addr, mem_add_size,
+				    timeout, tickstart) != 0) {
+		hi2c->lock = 0;
+		return -EIO;
+	}
+
+	/*
+	 * Send Slave Address.
+	 * Set NBYTES to write and reload if hi2c->xfer_count > MAX_NBYTE_SIZE
+	 * and generate RESTART.
+	 */
+	if (hi2c->xfer_count > MAX_NBYTE_SIZE) {
+		hi2c->xfer_size = MAX_NBYTE_SIZE;
+		i2c_transfer_config(hi2c, dev_addr, hi2c->xfer_size,
+				    I2C_RELOAD_MODE, I2C_GENERATE_START_READ);
+	} else {
+		hi2c->xfer_size = hi2c->xfer_count;
+		i2c_transfer_config(hi2c, dev_addr, hi2c->xfer_size,
+				    I2C_AUTOEND_MODE, I2C_GENERATE_START_READ);
+	}
+
+	do {
+		if (i2c_wait_flag(hi2c, I2C_FLAG_RXNE, 0, timeout,
+				  tickstart) != 0) {
+			return -EIO;
+		}
+
+		*hi2c->p_buff = mmio_read_8(hi2c->i2c_base_addr + I2C_RXDR);
+		hi2c->p_buff++;
+		hi2c->xfer_size--;
+		hi2c->xfer_count--;
+
+		if ((hi2c->xfer_count != 0U) && (hi2c->xfer_size == 0U)) {
+			if (i2c_wait_flag(hi2c, I2C_FLAG_TCR, 0, timeout,
+					  tickstart) != 0) {
+				return -EIO;
+			}
+
+			if (hi2c->xfer_count > MAX_NBYTE_SIZE) {
+				hi2c->xfer_size = MAX_NBYTE_SIZE;
+				i2c_transfer_config(hi2c, dev_addr,
+						    hi2c->xfer_size,
+						    I2C_RELOAD_MODE,
+						    I2C_NO_STARTSTOP);
+			} else {
+				hi2c->xfer_size = hi2c->xfer_count;
+				i2c_transfer_config(hi2c, dev_addr,
+						    hi2c->xfer_size,
+						    I2C_AUTOEND_MODE,
+						    I2C_NO_STARTSTOP);
+			}
+		}
+	} while (hi2c->xfer_count > 0U);
+
+	/*
+	 * No need to Check TC flag, with AUTOEND mode the stop
+	 * is automatically generated
+	 * Wait until STOPF flag is reset
+	 */
+	if (i2c_wait_stop(hi2c, timeout, tickstart) != 0) {
+		return -EIO;
+	}
+
+	mmio_write_32(hi2c->i2c_base_addr + I2C_ICR, I2C_FLAG_STOPF);
+
+	mmio_clrbits_32(hi2c->i2c_base_addr + I2C_CR2, I2C_RESET_CR2);
+
+	hi2c->i2c_state = I2C_STATE_READY;
+	hi2c->i2c_mode  = I2C_MODE_NONE;
+
+	hi2c->lock = 0;
+
+	return 0;
+}
+
+/*
+ * @brief  Checks if target device is ready for communication.
+ * @note   This function is used with Memory devices
+ * @param  hi2c: Pointer to a struct i2c_handle_s structure that contains
+ *               the configuration information for the specified I2C.
+ * @param  dev_addr: Target device address
+ * @param  trials: Number of trials
+ * @param  timeout: timeout duration
+ * @retval 0 if OK, negative value else
+ */
+int stm32_i2c_is_device_ready(struct i2c_handle_s *hi2c,
+			      uint16_t dev_addr, uint32_t trials,
+			      uint32_t timeout)
+{
+	uint32_t i2c_trials = 0U;
+
+	if ((hi2c->i2c_state != I2C_STATE_READY) || (hi2c->lock != 0U)) {
+		return -EBUSY;
+	}
+
+	if ((mmio_read_32(hi2c->i2c_base_addr + I2C_ISR) & I2C_FLAG_BUSY) !=
+	    0U) {
+		return -EBUSY;
+	}
+
+	hi2c->lock = 1;
+
+	hi2c->i2c_state = I2C_STATE_BUSY;
+	hi2c->i2c_err = I2C_ERROR_NONE;
+
+	do {
+		uint32_t tickstart;
+
+		/* Generate Start */
+		if (hi2c->i2c_init.addressing_mode == I2C_ADDRESSINGMODE_7BIT) {
+			mmio_write_32(hi2c->i2c_base_addr + I2C_CR2,
+				      (((uint32_t)dev_addr & I2C_CR2_SADD) |
+				       I2C_CR2_START | I2C_CR2_AUTOEND) &
+				       ~I2C_CR2_RD_WRN);
+		} else {
+			mmio_write_32(hi2c->i2c_base_addr + I2C_CR2,
+				      (((uint32_t)dev_addr & I2C_CR2_SADD) |
+				       I2C_CR2_START | I2C_CR2_ADD10) &
+				      ~I2C_CR2_RD_WRN);
+		}
+
+		/*
+		 * No need to Check TC flag, with AUTOEND mode the stop
+		 * is automatically generated
+		 * Wait until STOPF flag is set or a NACK flag is set
+		 */
+		tickstart = (uint32_t)read_cntpct_el0();
+		while (((mmio_read_32(hi2c->i2c_base_addr + I2C_ISR) &
+			 (I2C_FLAG_STOPF | I2C_FLAG_AF)) == 0U) &&
+		       (hi2c->i2c_state != I2C_STATE_TIMEOUT)) {
+			if (timeout != MAX_DELAY) {
+				if ((((uint32_t)read_cntpct_el0() - tickstart) >
+				     timeout) || (timeout == 0U)) {
+					hi2c->i2c_state = I2C_STATE_READY;
+
+					hi2c->i2c_err |=
+						I2C_ERROR_TIMEOUT;
+
+					hi2c->lock = 0;
+
+					return -EIO;
+				}
+			}
+		}
+
+		/* Check if the NACKF flag has not been set */
+		if ((mmio_read_32(hi2c->i2c_base_addr + I2C_ISR) &
+		     I2C_FLAG_AF) == 0U) {
+			if (i2c_wait_flag(hi2c, I2C_FLAG_STOPF, 0, timeout,
+					  tickstart) != 0) {
+				return -EIO;
+			}
+
+			mmio_write_32(hi2c->i2c_base_addr + I2C_ICR,
+				      I2C_FLAG_STOPF);
+
+			hi2c->i2c_state = I2C_STATE_READY;
+
+			hi2c->lock = 0;
+
+			return 0;
+		}
+
+		if (i2c_wait_flag(hi2c, I2C_FLAG_STOPF, 0, timeout,
+				  tickstart) != 0) {
+			return -EIO;
+		}
+
+		mmio_write_32(hi2c->i2c_base_addr + I2C_ICR, I2C_FLAG_AF);
+
+		mmio_write_32(hi2c->i2c_base_addr + I2C_ICR, I2C_FLAG_STOPF);
+
+		if (i2c_trials == trials) {
+			mmio_setbits_32(hi2c->i2c_base_addr + I2C_CR2,
+					I2C_CR2_STOP);
+
+			if (i2c_wait_flag(hi2c, I2C_FLAG_STOPF, 0, timeout,
+					  tickstart) != 0) {
+				return -EIO;
+			}
+
+			mmio_write_32(hi2c->i2c_base_addr + I2C_ICR,
+				      I2C_FLAG_STOPF);
+		}
+
+		i2c_trials++;
+	} while (i2c_trials < trials);
+
+	hi2c->i2c_state = I2C_STATE_READY;
+
+	hi2c->i2c_err |= I2C_ERROR_TIMEOUT;
+
+	hi2c->lock = 0;
+
+	return -EIO;
+}
+
+/*
+ * @brief  Master sends target device address followed by internal memory
+ *	   address for write request.
+ * @param  hi2c: Pointer to a struct i2c_handle_s structure that contains
+ *               the configuration information for the specified I2C.
+ * @param  dev_addr: Target device address
+ * @param  mem_addr: Internal memory address
+ * @param  mem_add_size: size of internal memory address
+ * @param  timeout: timeout duration
+ * @param  tick_start Tick start value
+ * @retval 0 if OK, negative value else
+ */
+static int i2c_request_memory_write(struct i2c_handle_s *hi2c,
+				    uint16_t dev_addr, uint16_t mem_addr,
+				    uint16_t mem_add_size, uint32_t timeout,
+				    uint32_t tick_start)
+{
+	i2c_transfer_config(hi2c, dev_addr, mem_add_size, I2C_RELOAD_MODE,
+			    I2C_GENERATE_START_WRITE);
+
+	if (i2c_wait_txis(hi2c, timeout, tick_start) != 0) {
+		return -EIO;
+	}
+
+	if (mem_add_size == I2C_MEMADD_SIZE_8BIT) {
+		/* Send Memory Address */
+		mmio_write_8(hi2c->i2c_base_addr + I2C_TXDR,
+			     (uint8_t)(mem_addr & 0x00FFU));
+	} else {
+		/* Send MSB of Memory Address */
+		mmio_write_8(hi2c->i2c_base_addr + I2C_TXDR,
+			     (uint8_t)((mem_addr & 0xFF00U) >> 8));
+
+		/* Wait until TXIS flag is set */
+		if (i2c_wait_txis(hi2c, timeout, tick_start) != 0) {
+			return -EIO;
+		}
+
+		/* Send LSB of Memory Address */
+		mmio_write_8(hi2c->i2c_base_addr + I2C_TXDR,
+			     (uint8_t)(mem_addr & 0x00FFU));
+	}
+
+	if (i2c_wait_flag(hi2c, I2C_FLAG_TCR, 0, timeout, tick_start) !=
+	    0) {
+		return -EIO;
+	}
+
+	return 0;
+}
+
+/*
+ * @brief  Master sends target device address followed by internal memory
+ *	   address for read request.
+ * @param  hi2c: Pointer to a struct i2c_handle_s structure that contains
+ *               the configuration information for the specified I2C.
+ * @param  dev_addr: Target device address
+ * @param  mem_addr: Internal memory address
+ * @param  mem_add_size: size of internal memory address
+ * @param  timeout: timeout duration
+ * @param  tick_start Tick start value
+ * @retval 0 if OK, negative value else
+ */
+static int i2c_request_memory_read(struct i2c_handle_s *hi2c, uint16_t dev_addr,
+				   uint16_t mem_addr, uint16_t mem_add_size,
+				   uint32_t timeout, uint32_t tick_start)
+{
+	i2c_transfer_config(hi2c, dev_addr, mem_add_size, I2C_SOFTEND_MODE,
+			    I2C_GENERATE_START_WRITE);
+
+	if (i2c_wait_txis(hi2c, timeout, tick_start) != 0) {
+		return -EIO;
+	}
+
+	if (mem_add_size == I2C_MEMADD_SIZE_8BIT) {
+		/* Send Memory Address */
+		mmio_write_8(hi2c->i2c_base_addr + I2C_TXDR,
+			     (uint8_t)(mem_addr & 0x00FFU));
+	} else {
+		/* Send MSB of Memory Address */
+		mmio_write_8(hi2c->i2c_base_addr + I2C_TXDR,
+			     (uint8_t)((mem_addr & 0xFF00U) >> 8));
+
+		/* Wait until TXIS flag is set */
+		if (i2c_wait_txis(hi2c, timeout, tick_start) != 0) {
+			return -EIO;
+		}
+
+		/* Send LSB of Memory Address */
+		mmio_write_8(hi2c->i2c_base_addr + I2C_TXDR,
+			     (uint8_t)(mem_addr & 0x00FFU));
+	}
+
+	if (i2c_wait_flag(hi2c, I2C_FLAG_TC, 0, timeout, tick_start) != 0) {
+		return -EIO;
+	}
+
+	return 0;
+}
+
+/*
+ * @brief  I2C Tx data register flush process.
+ * @param  hi2c: I2C handle.
+ * @retval None
+ */
+static void i2c_flush_txdr(struct i2c_handle_s *hi2c)
+{
+	/*
+	 * If a pending TXIS flag is set,
+	 * write a dummy data in TXDR to clear it.
+	 */
+	if ((mmio_read_32(hi2c->i2c_base_addr + I2C_ISR) & I2C_FLAG_TXIS) !=
+	    0U) {
+		mmio_write_32(hi2c->i2c_base_addr + I2C_TXDR, 0);
+	}
+
+	/* Flush TX register if not empty */
+	if ((mmio_read_32(hi2c->i2c_base_addr + I2C_ISR) & I2C_FLAG_TXE) ==
+	    0U) {
+		mmio_setbits_32(hi2c->i2c_base_addr + I2C_ISR,
+				I2C_FLAG_TXE);
+	}
+}
+
+/*
+ * @brief  This function handles I2C Communication timeout.
+ * @param  hi2c: Pointer to a struct i2c_handle_s structure that contains
+ *               the configuration information for the specified I2C.
+ * @param  flag: Specifies the I2C flag to check.
+ * @param  awaited_value: The awaited bit value for the flag (0 or 1).
+ * @param  timeout: timeout duration
+ * @param  tick_start: Tick start value
+ * @retval 0 if OK, negative value else
+ */
+static int i2c_wait_flag(struct i2c_handle_s *hi2c, uint32_t flag,
+			 uint8_t awaited_value, uint32_t timeout,
+			 uint32_t tick_start)
+{
+	uint8_t flag_check;
+
+	do {
+		flag_check = ((mmio_read_32(hi2c->i2c_base_addr + I2C_ISR) &
+			       flag) == flag) ? 1U : 0U;
+
+		if (timeout != MAX_DELAY) {
+			if ((((uint32_t)read_cntpct_el0() - tick_start) >
+			     timeout) || (timeout == 0U)) {
+				hi2c->i2c_err |= I2C_ERROR_TIMEOUT;
+				hi2c->i2c_state = I2C_STATE_READY;
+				hi2c->i2c_mode = I2C_MODE_NONE;
+
+				hi2c->lock = 0;
+				return -EIO;
+			}
+		}
+	} while (flag_check == awaited_value);
+
+	return 0;
+}
+
+/*
+ * @brief  This function handles I2C Communication timeout for specific usage
+ *	   of TXIS flag.
+ * @param  hi2c: Pointer to a struct i2c_handle_s structure that contains
+ *               the configuration information for the specified I2C.
+ * @param  timeout: timeout duration
+ * @param  tick_start: Tick start value
+ * @retval 0 if OK, negative value else
+ */
+static int i2c_wait_txis(struct i2c_handle_s *hi2c, uint32_t timeout,
+			 uint32_t tick_start)
+{
+	while ((mmio_read_32(hi2c->i2c_base_addr + I2C_ISR) &
+		I2C_FLAG_TXIS) == 0U) {
+		if (i2c_ack_failed(hi2c, timeout, tick_start) != 0) {
+			return -EIO;
+		}
+
+		if (timeout != MAX_DELAY) {
+			if ((((uint32_t)read_cntpct_el0() - tick_start) >
+			     timeout) || (timeout == 0U)) {
+				hi2c->i2c_err |= I2C_ERROR_TIMEOUT;
+				hi2c->i2c_state = I2C_STATE_READY;
+				hi2c->i2c_mode = I2C_MODE_NONE;
+
+				hi2c->lock = 0;
+
+				return -EIO;
+			}
+		}
+	}
+
+	return 0;
+}
+
+/*
+ * @brief  This function handles I2C Communication timeout for specific
+ *	   usage of STOP flag.
+ * @param  hi2c: Pointer to a struct i2c_handle_s structure that contains
+ *               the configuration information for the specified I2C.
+ * @param  timeout: timeout duration
+ * @param  tick_start: Tick start value
+ * @retval 0 if OK, negative value else
+ */
+static int i2c_wait_stop(struct i2c_handle_s *hi2c, uint32_t timeout,
+			 uint32_t tick_start)
+{
+	while ((mmio_read_32(hi2c->i2c_base_addr + I2C_ISR) &
+		 I2C_FLAG_STOPF) == 0U) {
+		if (i2c_ack_failed(hi2c, timeout, tick_start) != 0) {
+			return -EIO;
+		}
+
+		if ((((uint32_t)read_cntpct_el0() - tick_start) > timeout) ||
+		    (timeout == 0U)) {
+			hi2c->i2c_err |= I2C_ERROR_TIMEOUT;
+			hi2c->i2c_state = I2C_STATE_READY;
+			hi2c->i2c_mode = I2C_MODE_NONE;
+
+			hi2c->lock = 0;
+
+			return -EIO;
+		}
+	}
+
+	return 0;
+}
+
+/*
+ * @brief  This function handles Acknowledge failed detection during
+ *	   an I2C Communication.
+ * @param  hi2c: Pointer to a struct i2c_handle_s structure that contains
+ *               the configuration information for the specified I2C.
+ * @param  timeout: timeout duration
+ * @param  tick_start: Tick start value
+ * @retval 0 if OK, negative value else
+ */
+static int i2c_ack_failed(struct i2c_handle_s *hi2c, uint32_t timeout,
+			  uint32_t tick_start)
+{
+	if ((mmio_read_32(hi2c->i2c_base_addr + I2C_ISR) & I2C_FLAG_AF) == 0U) {
+		return 0;
+	}
+
+	/*
+	 * Wait until STOP Flag is reset.
+	 * AutoEnd should be initiate after AF.
+	 */
+	while ((mmio_read_32(hi2c->i2c_base_addr + I2C_ISR) &
+		I2C_FLAG_STOPF) == 0U) {
+		if (timeout != MAX_DELAY) {
+			if ((((uint32_t)read_cntpct_el0() - tick_start) >
+			     timeout) || (timeout == 0U)) {
+				hi2c->i2c_err |= I2C_ERROR_TIMEOUT;
+				hi2c->i2c_state = I2C_STATE_READY;
+				hi2c->i2c_mode = I2C_MODE_NONE;
+
+				hi2c->lock = 0;
+
+				return -EIO;
+			}
+		}
+	}
+
+	mmio_write_32(hi2c->i2c_base_addr + I2C_ICR, I2C_FLAG_AF);
+
+	mmio_write_32(hi2c->i2c_base_addr + I2C_ICR, I2C_FLAG_STOPF);
+
+	i2c_flush_txdr(hi2c);
+
+	mmio_clrbits_32(hi2c->i2c_base_addr + I2C_CR2, I2C_RESET_CR2);
+
+	hi2c->i2c_err |= I2C_ERROR_AF;
+	hi2c->i2c_state = I2C_STATE_READY;
+	hi2c->i2c_mode = I2C_MODE_NONE;
+
+	hi2c->lock = 0;
+
+	return -EIO;
+}
+
+/*
+ * @brief  Handles I2Cx communication when starting transfer or during transfer
+ *	   (TC or TCR flag are set).
+ * @param  hi2c: I2C handle.
+ * @param  dev_addr: Specifies the slave address to be programmed.
+ * @param  size: Specifies the number of bytes to be programmed.
+ *   This parameter must be a value between 0 and 255.
+ * @param  i2c_mode: New state of the I2C START condition generation.
+ *   This parameter can be one of the following values:
+ *     @arg @ref I2C_RELOAD_MODE: Enable Reload mode .
+ *     @arg @ref I2C_AUTOEND_MODE: Enable Automatic end mode.
+ *     @arg @ref I2C_SOFTEND_MODE: Enable Software end mode.
+ * @param  request: New state of the I2C START condition generation.
+ *   This parameter can be one of the following values:
+ *     @arg @ref I2C_NO_STARTSTOP: Don't Generate stop and start condition.
+ *     @arg @ref I2C_GENERATE_STOP: Generate stop condition
+ *                                  (size should be set to 0).
+ *     @arg @ref I2C_GENERATE_START_READ: Generate Restart for read request.
+ *     @arg @ref I2C_GENERATE_START_WRITE: Generate Restart for write request.
+ * @retval None
+ */
+static void i2c_transfer_config(struct i2c_handle_s *hi2c, uint16_t dev_addr,
+				uint16_t size, uint32_t i2c_mode,
+				uint32_t request)
+{
+	uint32_t clr_value, set_value;
+
+	clr_value = (I2C_CR2_SADD | I2C_CR2_NBYTES | I2C_CR2_RELOAD |
+		     I2C_CR2_AUTOEND | I2C_CR2_START | I2C_CR2_STOP) |
+		(I2C_CR2_RD_WRN & (request >> (31U - I2C_CR2_RD_WRN_OFFSET)));
+
+	set_value = ((uint32_t)dev_addr & I2C_CR2_SADD) |
+		(((uint32_t)size << I2C_CR2_NBYTES_OFFSET) & I2C_CR2_NBYTES) |
+		i2c_mode | request;
+
+	mmio_clrsetbits_32(hi2c->i2c_base_addr + I2C_CR2, clr_value, set_value);
+}
+
+/*
+ * @brief  Configure I2C Analog noise filter.
+ * @param  hi2c: Pointer to a struct i2c_handle_s structure that contains
+ *               the configuration information for the specified I2Cx peripheral
+ * @param  analog_filter: New state of the Analog filter.
+ * @retval 0 if OK, negative value else
+ */
+int stm32_i2c_config_analog_filter(struct i2c_handle_s *hi2c,
+				   uint32_t analog_filter)
+{
+	if ((hi2c->i2c_state != I2C_STATE_READY) || (hi2c->lock != 0U)) {
+		return -EBUSY;
+	}
+
+	hi2c->lock = 1;
+
+	hi2c->i2c_state = I2C_STATE_BUSY;
+
+	/* Disable the selected I2C peripheral */
+	mmio_clrbits_32(hi2c->i2c_base_addr + I2C_CR1, I2C_CR1_PE);
+
+	/* Reset I2Cx ANOFF bit */
+	mmio_clrbits_32(hi2c->i2c_base_addr + I2C_CR1, I2C_CR1_ANFOFF);
+
+	/* Set analog filter bit*/
+	mmio_setbits_32(hi2c->i2c_base_addr + I2C_CR1, analog_filter);
+
+	/* Enable the selected I2C peripheral */
+	mmio_setbits_32(hi2c->i2c_base_addr + I2C_CR1, I2C_CR1_PE);
+
+	hi2c->i2c_state = I2C_STATE_READY;
+
+	hi2c->lock = 0;
+
+	return 0;
+}
diff --git a/drivers/st/pmic/stm32mp1_pmic.c b/drivers/st/pmic/stm32mp1_pmic.c
new file mode 100644
index 0000000..958de08
--- /dev/null
+++ b/drivers/st/pmic/stm32mp1_pmic.c
@@ -0,0 +1,346 @@
+/*
+ * Copyright (c) 2017-2018, STMicroelectronics - All Rights Reserved
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <debug.h>
+#include <delay_timer.h>
+#include <errno.h>
+#include <libfdt.h>
+#include <mmio.h>
+#include <mmio.h>
+#include <platform_def.h>
+#include <stdbool.h>
+#include <stm32_gpio.h>
+#include <stm32mp1_clk.h>
+#include <stm32mp1_dt.h>
+#include <stm32mp1_pmic.h>
+#include <stpmu1.h>
+#include <utils_def.h>
+
+/* I2C Timing hard-coded value, for I2C clock source is HSI at 64MHz */
+#define I2C_TIMING			0x10D07DB5
+
+#define I2C_TIMEOUT			0xFFFFF
+
+#define MASK_RESET_BUCK3		BIT(2)
+
+#define STPMU1_LDO12356_OUTPUT_MASK	(uint8_t)(GENMASK(6, 2))
+#define STPMU1_LDO12356_OUTPUT_SHIFT	2
+#define STPMU1_LDO3_MODE		(uint8_t)(BIT(7))
+#define STPMU1_LDO3_DDR_SEL		31U
+#define STPMU1_LDO3_1800000		(9U << STPMU1_LDO12356_OUTPUT_SHIFT)
+
+#define STPMU1_BUCK_OUTPUT_SHIFT	2
+#define STPMU1_BUCK3_1V8		(39U << STPMU1_BUCK_OUTPUT_SHIFT)
+
+#define STPMU1_DEFAULT_START_UP_DELAY_MS	1
+
+static struct i2c_handle_s i2c_handle;
+static uint32_t pmic_i2c_addr;
+
+static int dt_get_pmic_node(void *fdt)
+{
+	return fdt_node_offset_by_compatible(fdt, -1, "st,stpmu1");
+}
+
+bool dt_check_pmic(void)
+{
+	int node;
+	void *fdt;
+
+	if (fdt_get_address(&fdt) == 0) {
+		return false;
+	}
+
+	node = dt_get_pmic_node(fdt);
+	if (node < 0) {
+		VERBOSE("%s: No PMIC node found in DT\n", __func__);
+		return false;
+	}
+
+	return fdt_check_status(node);
+}
+
+static int dt_pmic_i2c_config(struct dt_node_info *i2c_info)
+{
+	int pmic_node, i2c_node;
+	void *fdt;
+	const fdt32_t *cuint;
+
+	if (fdt_get_address(&fdt) == 0) {
+		return -ENOENT;
+	}
+
+	pmic_node = dt_get_pmic_node(fdt);
+	if (pmic_node < 0) {
+		return -FDT_ERR_NOTFOUND;
+	}
+
+	cuint = fdt_getprop(fdt, pmic_node, "reg", NULL);
+	if (cuint == NULL) {
+		return -FDT_ERR_NOTFOUND;
+	}
+
+	pmic_i2c_addr = fdt32_to_cpu(*cuint) << 1;
+	if (pmic_i2c_addr > UINT16_MAX) {
+		return -EINVAL;
+	}
+
+	i2c_node = fdt_parent_offset(fdt, pmic_node);
+	if (i2c_node < 0) {
+		return -FDT_ERR_NOTFOUND;
+	}
+
+	dt_fill_device_info(i2c_info, i2c_node);
+	if (i2c_info->base == 0U) {
+		return -FDT_ERR_NOTFOUND;
+	}
+
+	return dt_set_pinctrl_config(i2c_node);
+}
+
+int dt_pmic_enable_boot_on_regulators(void)
+{
+	int pmic_node, regulators_node, regulator_node;
+	void *fdt;
+
+	if (fdt_get_address(&fdt) == 0) {
+		return -ENOENT;
+	}
+
+	pmic_node = dt_get_pmic_node(fdt);
+	if (pmic_node < 0) {
+		return -FDT_ERR_NOTFOUND;
+	}
+
+	regulators_node = fdt_subnode_offset(fdt, pmic_node, "regulators");
+
+	fdt_for_each_subnode(regulator_node, fdt, regulators_node) {
+		const fdt32_t *cuint;
+		const char *node_name;
+		uint16_t voltage;
+
+		if (fdt_getprop(fdt, regulator_node, "regulator-boot-on",
+				NULL) == NULL) {
+			continue;
+		}
+
+		cuint = fdt_getprop(fdt, regulator_node,
+				    "regulator-min-microvolt", NULL);
+		if (cuint == NULL) {
+			continue;
+		}
+
+		/* DT uses microvolts, whereas driver awaits millivolts */
+		voltage = (uint16_t)(fdt32_to_cpu(*cuint) / 1000U);
+		node_name = fdt_get_name(fdt, regulator_node, NULL);
+
+		if (stpmu1_is_regulator_enabled(node_name) == 0U) {
+			int status;
+
+			status = stpmu1_regulator_voltage_set(node_name,
+							      voltage);
+			if (status != 0) {
+				return status;
+			}
+
+			status = stpmu1_regulator_enable(node_name);
+			if (status != 0) {
+				return status;
+			}
+		}
+	}
+
+	return 0;
+}
+
+void initialize_pmic_i2c(void)
+{
+	int ret;
+	struct dt_node_info i2c_info;
+
+	if (dt_pmic_i2c_config(&i2c_info) != 0) {
+		ERROR("I2C configuration failed\n");
+		panic();
+	}
+
+	if (stm32mp1_clk_enable((uint32_t)i2c_info.clock) < 0) {
+		ERROR("I2C clock enable failed\n");
+		panic();
+	}
+
+	/* Initialize PMIC I2C */
+	i2c_handle.i2c_base_addr		= i2c_info.base;
+	i2c_handle.i2c_init.timing		= I2C_TIMING;
+	i2c_handle.i2c_init.own_address1	= pmic_i2c_addr;
+	i2c_handle.i2c_init.addressing_mode	= I2C_ADDRESSINGMODE_7BIT;
+	i2c_handle.i2c_init.dual_address_mode	= I2C_DUALADDRESS_DISABLE;
+	i2c_handle.i2c_init.own_address2	= 0;
+	i2c_handle.i2c_init.own_address2_masks	= I2C_OAR2_OA2NOMASK;
+	i2c_handle.i2c_init.general_call_mode	= I2C_GENERALCALL_DISABLE;
+	i2c_handle.i2c_init.no_stretch_mode	= I2C_NOSTRETCH_DISABLE;
+
+	ret = stm32_i2c_init(&i2c_handle);
+	if (ret != 0) {
+		ERROR("Cannot initialize I2C %x (%d)\n",
+		      i2c_handle.i2c_base_addr, ret);
+		panic();
+	}
+
+	ret = stm32_i2c_config_analog_filter(&i2c_handle,
+					     I2C_ANALOGFILTER_ENABLE);
+	if (ret != 0) {
+		ERROR("Cannot initialize I2C analog filter (%d)\n", ret);
+		panic();
+	}
+
+	ret = stm32_i2c_is_device_ready(&i2c_handle, (uint16_t)pmic_i2c_addr, 1,
+					I2C_TIMEOUT);
+	if (ret != 0) {
+		ERROR("I2C device not ready (%d)\n", ret);
+		panic();
+	}
+
+	stpmu1_bind_i2c(&i2c_handle, (uint16_t)pmic_i2c_addr);
+}
+
+void initialize_pmic(void)
+{
+	int status;
+	uint8_t read_val;
+
+	initialize_pmic_i2c();
+
+	status = stpmu1_register_read(VERSION_STATUS_REG, &read_val);
+	if (status != 0) {
+		panic();
+	}
+
+	INFO("PMIC version = 0x%x\n", read_val);
+
+	/* Keep VDD on during the reset cycle */
+	status = stpmu1_register_update(MASK_RESET_BUCK_REG,
+					MASK_RESET_BUCK3,
+					MASK_RESET_BUCK3);
+	if (status != 0) {
+		panic();
+	}
+}
+
+int pmic_ddr_power_init(enum ddr_type ddr_type)
+{
+	bool buck3_at_1v8 = false;
+	uint8_t read_val;
+	int status;
+
+	switch (ddr_type) {
+	case STM32MP_DDR3:
+		/* Set LDO3 to sync mode */
+		status = stpmu1_register_read(LDO3_CONTROL_REG, &read_val);
+		if (status != 0) {
+			return status;
+		}
+
+		read_val &= ~STPMU1_LDO3_MODE;
+		read_val &= ~STPMU1_LDO12356_OUTPUT_MASK;
+		read_val |= STPMU1_LDO3_DDR_SEL << STPMU1_LDO12356_OUTPUT_SHIFT;
+
+		status = stpmu1_register_write(LDO3_CONTROL_REG, read_val);
+		if (status != 0) {
+			return status;
+		}
+
+		status = stpmu1_regulator_voltage_set("buck2", 1350);
+		if (status != 0) {
+			return status;
+		}
+
+		status = stpmu1_regulator_enable("buck2");
+		if (status != 0) {
+			return status;
+		}
+
+		mdelay(STPMU1_DEFAULT_START_UP_DELAY_MS);
+
+		status = stpmu1_regulator_enable("vref_ddr");
+		if (status != 0) {
+			return status;
+		}
+
+		mdelay(STPMU1_DEFAULT_START_UP_DELAY_MS);
+
+		status = stpmu1_regulator_enable("ldo3");
+		if (status != 0) {
+			return status;
+		}
+
+		mdelay(STPMU1_DEFAULT_START_UP_DELAY_MS);
+		break;
+
+	case STM32MP_LPDDR2:
+		/*
+		 * Set LDO3 to 1.8V
+		 * Set LDO3 to bypass mode if BUCK3 = 1.8V
+		 * Set LDO3 to normal mode if BUCK3 != 1.8V
+		 */
+		status = stpmu1_register_read(BUCK3_CONTROL_REG, &read_val);
+		if (status != 0) {
+			return status;
+		}
+
+		if ((read_val & STPMU1_BUCK3_1V8) == STPMU1_BUCK3_1V8) {
+			buck3_at_1v8 = true;
+		}
+
+		status = stpmu1_register_read(LDO3_CONTROL_REG, &read_val);
+		if (status != 0) {
+			return status;
+		}
+
+		read_val &= ~STPMU1_LDO3_MODE;
+		read_val &= ~STPMU1_LDO12356_OUTPUT_MASK;
+		read_val |= STPMU1_LDO3_1800000;
+		if (buck3_at_1v8) {
+			read_val |= STPMU1_LDO3_MODE;
+		}
+
+		status = stpmu1_register_write(LDO3_CONTROL_REG, read_val);
+		if (status != 0) {
+			return status;
+		}
+
+		status = stpmu1_regulator_voltage_set("buck2", 1200);
+		if (status != 0) {
+			return status;
+		}
+
+		status = stpmu1_regulator_enable("ldo3");
+		if (status != 0) {
+			return status;
+		}
+
+		mdelay(STPMU1_DEFAULT_START_UP_DELAY_MS);
+
+		status = stpmu1_regulator_enable("buck2");
+		if (status != 0) {
+			return status;
+		}
+
+		mdelay(STPMU1_DEFAULT_START_UP_DELAY_MS);
+
+		status = stpmu1_regulator_enable("vref_ddr");
+		if (status != 0) {
+			return status;
+		}
+
+		mdelay(STPMU1_DEFAULT_START_UP_DELAY_MS);
+		break;
+
+	default:
+		break;
+	};
+
+	return 0;
+}
diff --git a/drivers/st/pmic/stpmu1.c b/drivers/st/pmic/stpmu1.c
new file mode 100644
index 0000000..5951899
--- /dev/null
+++ b/drivers/st/pmic/stpmu1.c
@@ -0,0 +1,600 @@
+/*
+ * Copyright (c) 2016-2018, STMicroelectronics - All Rights Reserved
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <debug.h>
+#include <platform.h>
+#include <stpmu1.h>
+#include <string.h>
+
+struct regul_struct {
+	const char *dt_node_name;
+	const uint16_t *voltage_table;
+	uint8_t voltage_table_size;
+	uint8_t control_reg;
+	uint8_t low_power_reg;
+};
+
+static struct i2c_handle_s *stpmu_i2c_handle;
+static uint16_t stpmu_i2c_addr;
+
+/* Voltage tables in mV */
+static const uint16_t buck1_voltage_table[] = {
+	600,
+	625,
+	650,
+	675,
+	700,
+	725,
+	750,
+	775,
+	800,
+	825,
+	850,
+	875,
+	900,
+	925,
+	950,
+	975,
+	1000,
+	1025,
+	1050,
+	1075,
+	1100,
+	1125,
+	1150,
+	1175,
+	1200,
+	1225,
+	1250,
+	1275,
+	1300,
+	1325,
+	1350,
+	1350,
+};
+
+static const uint16_t buck2_voltage_table[] = {
+	1000,
+	1000,
+	1000,
+	1000,
+	1000,
+	1000,
+	1000,
+	1000,
+	1000,
+	1000,
+	1000,
+	1000,
+	1000,
+	1000,
+	1000,
+	1000,
+	1000,
+	1000,
+	1050,
+	1050,
+	1100,
+	1100,
+	1150,
+	1150,
+	1200,
+	1200,
+	1250,
+	1250,
+	1300,
+	1300,
+	1350,
+	1350,
+	1400,
+	1400,
+	1450,
+	1450,
+	1500,
+};
+
+static const uint16_t buck3_voltage_table[] = {
+	1000,
+	1000,
+	1000,
+	1000,
+	1000,
+	1000,
+	1000,
+	1000,
+	1000,
+	1000,
+	1000,
+	1000,
+	1000,
+	1000,
+	1000,
+	1000,
+	1000,
+	1000,
+	1000,
+	1000,
+	1100,
+	1100,
+	1100,
+	1100,
+	1200,
+	1200,
+	1200,
+	1200,
+	1300,
+	1300,
+	1300,
+	1300,
+	1400,
+	1400,
+	1400,
+	1400,
+	1500,
+	1600,
+	1700,
+	1800,
+	1900,
+	2000,
+	2100,
+	2200,
+	2300,
+	2400,
+	2500,
+	2600,
+	2700,
+	2800,
+	2900,
+	3000,
+	3100,
+	3200,
+	3300,
+	3400,
+};
+
+static const uint16_t buck4_voltage_table[] = {
+	600,
+	625,
+	650,
+	675,
+	700,
+	725,
+	750,
+	775,
+	800,
+	825,
+	850,
+	875,
+	900,
+	925,
+	950,
+	975,
+	1000,
+	1025,
+	1050,
+	1075,
+	1100,
+	1125,
+	1150,
+	1175,
+	1200,
+	1225,
+	1250,
+	1275,
+	1300,
+	1300,
+	1350,
+	1350,
+	1400,
+	1400,
+	1450,
+	1450,
+	1500,
+	1600,
+	1700,
+	1800,
+	1900,
+	2000,
+	2100,
+	2200,
+	2300,
+	2400,
+	2500,
+	2600,
+	2700,
+	2800,
+	2900,
+	3000,
+	3100,
+	3200,
+	3300,
+	3400,
+	3500,
+	3600,
+	3700,
+	3800,
+	3900,
+};
+
+static const uint16_t ldo1_voltage_table[] = {
+	1700,
+	1700,
+	1700,
+	1700,
+	1700,
+	1700,
+	1700,
+	1700,
+	1700,
+	1800,
+	1900,
+	2000,
+	2100,
+	2200,
+	2300,
+	2400,
+	2500,
+	2600,
+	2700,
+	2800,
+	2900,
+	3000,
+	3100,
+	3200,
+	3300,
+};
+
+static const uint16_t ldo2_voltage_table[] = {
+	1700,
+	1700,
+	1700,
+	1700,
+	1700,
+	1700,
+	1700,
+	1700,
+	1700,
+	1800,
+	1900,
+	2000,
+	2100,
+	2200,
+	2300,
+	2400,
+	2500,
+	2600,
+	2700,
+	2800,
+	2900,
+	3000,
+	3100,
+	3200,
+	3300,
+};
+
+static const uint16_t ldo3_voltage_table[] = {
+	1700,
+	1700,
+	1700,
+	1700,
+	1700,
+	1700,
+	1700,
+	1700,
+	1700,
+	1800,
+	1900,
+	2000,
+	2100,
+	2200,
+	2300,
+	2400,
+	2500,
+	2600,
+	2700,
+	2800,
+	2900,
+	3000,
+	3100,
+	3200,
+	3300,
+	3300,
+	3300,
+	3300,
+	3300,
+	3300,
+	3300,
+	0xFFFF, /* VREFDDR */
+};
+
+static const uint16_t ldo5_voltage_table[] = {
+	1700,
+	1700,
+	1700,
+	1700,
+	1700,
+	1700,
+	1700,
+	1700,
+	1700,
+	1800,
+	1900,
+	2000,
+	2100,
+	2200,
+	2300,
+	2400,
+	2500,
+	2600,
+	2700,
+	2800,
+	2900,
+	3000,
+	3100,
+	3200,
+	3300,
+	3400,
+	3500,
+	3600,
+	3700,
+	3800,
+	3900,
+};
+
+static const uint16_t ldo6_voltage_table[] = {
+	900,
+	1000,
+	1100,
+	1200,
+	1300,
+	1400,
+	1500,
+	1600,
+	1700,
+	1800,
+	1900,
+	2000,
+	2100,
+	2200,
+	2300,
+	2400,
+	2500,
+	2600,
+	2700,
+	2800,
+	2900,
+	3000,
+	3100,
+	3200,
+	3300,
+};
+
+static const uint16_t ldo4_voltage_table[] = {
+	3300,
+};
+
+static const uint16_t vref_ddr_voltage_table[] = {
+	3300,
+};
+
+/* Table of Regulators in PMIC SoC */
+static const struct regul_struct regulators_table[] = {
+	{
+		.dt_node_name	= "buck1",
+		.voltage_table	= buck1_voltage_table,
+		.voltage_table_size = ARRAY_SIZE(buck1_voltage_table),
+		.control_reg	= BUCK1_CONTROL_REG,
+		.low_power_reg	= BUCK1_PWRCTRL_REG,
+	},
+	{
+		.dt_node_name	= "buck2",
+		.voltage_table	= buck2_voltage_table,
+		.voltage_table_size = ARRAY_SIZE(buck2_voltage_table),
+		.control_reg	= BUCK2_CONTROL_REG,
+		.low_power_reg	= BUCK2_PWRCTRL_REG,
+	},
+	{
+		.dt_node_name	= "buck3",
+		.voltage_table	= buck3_voltage_table,
+		.voltage_table_size = ARRAY_SIZE(buck3_voltage_table),
+		.control_reg	= BUCK3_CONTROL_REG,
+		.low_power_reg	= BUCK3_PWRCTRL_REG,
+	},
+	{
+		.dt_node_name	= "buck4",
+		.voltage_table	= buck4_voltage_table,
+		.voltage_table_size = ARRAY_SIZE(buck4_voltage_table),
+		.control_reg	= BUCK4_CONTROL_REG,
+		.low_power_reg	= BUCK4_PWRCTRL_REG,
+	},
+	{
+		.dt_node_name	= "ldo1",
+		.voltage_table	= ldo1_voltage_table,
+		.voltage_table_size = ARRAY_SIZE(ldo1_voltage_table),
+		.control_reg	= LDO1_CONTROL_REG,
+		.low_power_reg	= LDO1_PWRCTRL_REG,
+	},
+	{
+		.dt_node_name	= "ldo2",
+		.voltage_table	= ldo2_voltage_table,
+		.voltage_table_size = ARRAY_SIZE(ldo2_voltage_table),
+		.control_reg	= LDO2_CONTROL_REG,
+		.low_power_reg	= LDO2_PWRCTRL_REG,
+	},
+	{
+		.dt_node_name	= "ldo3",
+		.voltage_table	= ldo3_voltage_table,
+		.voltage_table_size = ARRAY_SIZE(ldo3_voltage_table),
+		.control_reg	= LDO3_CONTROL_REG,
+		.low_power_reg	= LDO3_PWRCTRL_REG,
+	},
+	{
+		.dt_node_name	= "ldo4",
+		.voltage_table	= ldo4_voltage_table,
+		.voltage_table_size = ARRAY_SIZE(ldo4_voltage_table),
+		.control_reg	= LDO4_CONTROL_REG,
+		.low_power_reg	= LDO4_PWRCTRL_REG,
+	},
+	{
+		.dt_node_name	= "ldo5",
+		.voltage_table	= ldo5_voltage_table,
+		.voltage_table_size = ARRAY_SIZE(ldo5_voltage_table),
+		.control_reg	= LDO5_CONTROL_REG,
+		.low_power_reg	= LDO5_PWRCTRL_REG,
+	},
+	{
+		.dt_node_name	= "ldo6",
+		.voltage_table	= ldo6_voltage_table,
+		.voltage_table_size = ARRAY_SIZE(ldo6_voltage_table),
+		.control_reg	= LDO6_CONTROL_REG,
+		.low_power_reg	= LDO6_PWRCTRL_REG,
+	},
+	{
+		.dt_node_name	= "vref_ddr",
+		.voltage_table	= vref_ddr_voltage_table,
+		.voltage_table_size = ARRAY_SIZE(vref_ddr_voltage_table),
+		.control_reg	= VREF_DDR_CONTROL_REG,
+		.low_power_reg	= VREF_DDR_PWRCTRL_REG,
+	},
+};
+
+#define MAX_REGUL  ARRAY_SIZE(regulators_table)
+
+static const struct regul_struct *stpmu1_get_regulator_data(const char *name)
+{
+	uint8_t i;
+
+	for (i = 0 ; i < MAX_REGUL ; i++) {
+		if (strncmp(name, regulators_table[i].dt_node_name,
+			    strlen(regulators_table[i].dt_node_name)) == 0) {
+			return &regulators_table[i];
+		}
+	}
+
+	/* Regulator not found */
+	panic();
+	return NULL;
+}
+
+static uint8_t stpmu1_voltage_find_index(const char *name,
+					 uint16_t millivolts)
+{
+	const struct regul_struct *regul = stpmu1_get_regulator_data(name);
+	uint8_t i;
+
+	for (i = 0 ; i < regul->voltage_table_size ; i++) {
+		if (regul->voltage_table[i] == millivolts) {
+			return i;
+		}
+	}
+
+	/* Voltage not found */
+	panic();
+
+	return 0;
+}
+
+int stpmu1_switch_off(void)
+{
+	return stpmu1_register_update(MAIN_CONTROL_REG, 1,
+				      SOFTWARE_SWITCH_OFF_ENABLED);
+}
+
+int stpmu1_regulator_enable(const char *name)
+{
+	const struct regul_struct *regul = stpmu1_get_regulator_data(name);
+
+	return stpmu1_register_update(regul->control_reg, BIT(0), BIT(0));
+}
+
+int stpmu1_regulator_disable(const char *name)
+{
+	const struct regul_struct *regul = stpmu1_get_regulator_data(name);
+
+	return stpmu1_register_update(regul->control_reg, 0, BIT(0));
+}
+
+uint8_t stpmu1_is_regulator_enabled(const char *name)
+{
+	uint8_t val;
+	const struct regul_struct *regul = stpmu1_get_regulator_data(name);
+
+	if (stpmu1_register_read(regul->control_reg, &val) != 0) {
+		panic();
+	}
+
+	return (val & 0x1U);
+}
+
+int stpmu1_regulator_voltage_set(const char *name, uint16_t millivolts)
+{
+	uint8_t voltage_index = stpmu1_voltage_find_index(name, millivolts);
+	const struct regul_struct *regul = stpmu1_get_regulator_data(name);
+
+	return stpmu1_register_update(regul->control_reg, voltage_index << 2,
+				      0xFC);
+}
+
+int stpmu1_register_read(uint8_t register_id,  uint8_t *value)
+{
+	return stm32_i2c_mem_read(stpmu_i2c_handle, stpmu_i2c_addr,
+				    (uint16_t)register_id, I2C_MEMADD_SIZE_8BIT,
+				    value, 1, 100000);
+}
+
+int stpmu1_register_write(uint8_t register_id, uint8_t value)
+{
+	int status;
+
+	status = stm32_i2c_mem_write(stpmu_i2c_handle, stpmu_i2c_addr,
+				     (uint16_t)register_id,
+				     I2C_MEMADD_SIZE_8BIT, &value, 1, 100000);
+
+	if (status != 0) {
+		return status;
+	}
+
+	if ((register_id != WATCHDOG_CONTROL_REG) && (register_id <= 0x40U)) {
+		uint8_t readval;
+
+		status = stpmu1_register_read(register_id, &readval);
+		if (status != 0) {
+			return status;
+		}
+
+		if (readval != value) {
+			return -1;
+		}
+	}
+
+	return 0;
+}
+
+int stpmu1_register_update(uint8_t register_id, uint8_t value, uint8_t mask)
+{
+	int status;
+	uint8_t val;
+
+	status = stpmu1_register_read(register_id, &val);
+	if (status != 0) {
+		return status;
+	}
+
+	/* Clear bits to update */
+	val &= ~mask;
+
+	/* Update appropriate bits*/
+	val |= (value & mask);
+
+	/* Send new value on I2C Bus */
+	return stpmu1_register_write(register_id, val);
+}
+
+void stpmu1_bind_i2c(struct i2c_handle_s *i2c_handle, uint16_t i2c_addr)
+{
+	stpmu_i2c_handle = i2c_handle;
+	stpmu_i2c_addr = i2c_addr;
+}
diff --git a/drivers/st/reset/stm32mp1_reset.c b/drivers/st/reset/stm32mp1_reset.c
new file mode 100644
index 0000000..106bbfe
--- /dev/null
+++ b/drivers/st/reset/stm32mp1_reset.c
@@ -0,0 +1,39 @@
+/*
+ * Copyright (c) 2018, STMicroelectronics - All Rights Reserved
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <bl_common.h>
+#include <debug.h>
+#include <limits.h>
+#include <mmio.h>
+#include <platform_def.h>
+#include <stm32mp1_rcc.h>
+#include <stm32mp1_reset.h>
+#include <utils_def.h>
+
+#define RST_CLR_OFFSET	4U
+
+void stm32mp1_reset_assert(uint32_t id)
+{
+	uint32_t offset = (id / (uint32_t)__LONG_BIT) * sizeof(uintptr_t);
+	uint32_t bit = id % (uint32_t)__LONG_BIT;
+
+	mmio_write_32(RCC_BASE + offset, BIT(bit));
+	while ((mmio_read_32(RCC_BASE + offset) & BIT(bit)) == 0U) {
+		;
+	}
+}
+
+void stm32mp1_reset_deassert(uint32_t id)
+{
+	uint32_t offset = ((id / (uint32_t)__LONG_BIT) * sizeof(uintptr_t)) +
+			  RST_CLR_OFFSET;
+	uint32_t bit = id % (uint32_t)__LONG_BIT;
+
+	mmio_write_32(RCC_BASE + offset, BIT(bit));
+	while ((mmio_read_32(RCC_BASE + offset) & BIT(bit)) != 0U) {
+		;
+	}
+}
diff --git a/drivers/st/uart/aarch32/stm32_console.S b/drivers/st/uart/aarch32/stm32_console.S
new file mode 100644
index 0000000..792703a
--- /dev/null
+++ b/drivers/st/uart/aarch32/stm32_console.S
@@ -0,0 +1,184 @@
+/*
+ * Copyright (c) 2018, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+#include <asm_macros.S>
+
+#define USART_TIMEOUT		0x1000
+
+#define USART_CR1		0x00
+#define USART_CR1_UE		0x00000001
+#define USART_CR1_TE		0x00000008
+#define USART_CR1_FIFOEN	0x20000000
+
+#define USART_CR2		0x04
+#define USART_CR2_STOP		0x00003000
+
+#define USART_BRR		0x0C
+
+#define USART_ISR		0x1C
+#define USART_ISR_TC		0x00000040
+#define USART_ISR_TXE		0x00000080
+#define USART_ISR_TEACK		0x00200000
+
+#define USART_TDR		0x28
+
+	.globl	console_core_init
+	.globl	console_core_putc
+	.globl	console_core_getc
+	.globl	console_core_flush
+
+	/* -----------------------------------------------------------------
+	 * int console_core_init(uintptr_t base_addr,
+	 *			 unsigned int uart_clk,
+	 *			 unsigned int baud_rate)
+	 *
+	 * Function to initialize the console without a C Runtime to print
+	 * debug information. This function will be accessed by console_init
+	 * and crash reporting.
+	 *
+	 * In: r0 - console base address
+	 *     r1 - Uart clock in Hz
+	 *     r2 - Baud rate
+	 * Out: return 1 on success else 0 on error
+	 * Clobber list : r1, r2, r3
+	 * -----------------------------------------------------------------
+	 */
+func console_core_init
+	/* Check the input base address */
+	cmp	r0, #0
+	beq	core_init_fail
+#if defined(IMAGE_BL2)
+	/* Check baud rate and uart clock for sanity */
+	cmp	r1, #0
+	beq	core_init_fail
+	cmp	r2, #0
+	beq	core_init_fail
+	/* Disable UART */
+	ldr	r3, [r0, #USART_CR1]
+	bic	r3, r3, #USART_CR1_UE
+	str	r3, [r0, #USART_CR1]
+	/* Configure UART */
+	orr	r3, r3, #(USART_CR1_TE | USART_CR1_FIFOEN)
+	str	r3, [r0, #USART_CR1]
+	ldr	r3, [r0, #USART_CR2]
+	bic	r3, r3, #USART_CR2_STOP
+	str	r3, [r0, #USART_CR2]
+	/* Divisor =  (Uart clock + (baudrate / 2)) / baudrate */
+	lsl	r3, r2, #1
+	add	r3, r1, r3
+	udiv	r3, r3, r2
+	str	r3, [r0, #USART_BRR]
+	/* Enable UART */
+	ldr	r3, [r0, #USART_CR1]
+	orr	r3, r3, #USART_CR1_UE
+	str	r3, [r0, #USART_CR1]
+	/* Check TEACK bit */
+	mov	r2, #USART_TIMEOUT
+teack_loop:
+	subs	r2, r2, #1
+	beq	core_init_fail
+	ldr	r3, [r0, #USART_ISR]
+	tst	r3, #USART_ISR_TEACK
+	beq	teack_loop
+#endif /* IMAGE_BL2 */
+	mov	r0, #1
+	bx	lr
+core_init_fail:
+	mov	r0, #0
+	bx	lr
+endfunc console_core_init
+
+	/* ---------------------------------------------------------------
+	 * int console_core_putc(int c, uintptr_t base_addr)
+	 *
+	 * Function to output a character over the console. It returns the
+	 * character printed on success or -1 on error.
+	 *
+	 * In : r0 - character to be printed
+	 *      r1 - console base address
+	 * Out : return -1 on error else return character.
+	 * Clobber list : r2
+	 * ---------------------------------------------------------------
+	 */
+func console_core_putc
+	/* Check the input parameter */
+	cmp	r1, #0
+	beq	putc_error
+	/* Prepend '\r' to '\n' */
+	cmp	r0, #0xA
+	bne	2f
+1:
+	/* Check Transmit Data Register Empty */
+txe_loop_1:
+	ldr	r2, [r1, #USART_ISR]
+	tst	r2, #USART_ISR_TXE
+	beq	txe_loop_1
+	mov	r2, #0xD
+	str	r2, [r1, #USART_TDR]
+	/* Check transmit complete flag */
+tc_loop_1:
+	ldr	r2, [r1, #USART_ISR]
+	tst	r2, #USART_ISR_TC
+	beq	tc_loop_1
+2:
+	/* Check Transmit Data Register Empty */
+txe_loop_2:
+	ldr	r2, [r1, #USART_ISR]
+	tst	r2, #USART_ISR_TXE
+	beq	txe_loop_2
+	str	r0, [r1, #USART_TDR]
+	/* Check transmit complete flag */
+tc_loop_2:
+	ldr	r2, [r1, #USART_ISR]
+	tst	r2, #USART_ISR_TC
+	beq	tc_loop_2
+	bx	lr
+putc_error:
+	mov	r0, #-1
+	bx	lr
+endfunc console_core_putc
+
+	/* -----------------------------------------------------------
+	 * int console_core_getc(uintptr_t base_addr)
+	 *
+	 * Function to get a character from the console.
+	 * It returns the character grabbed on success or -1 on error.
+	 *
+	 * In : r0 - console base address
+	 * Out : return -1.
+	 * Clobber list : r0, r1
+	 * -----------------------------------------------------------
+	 */
+func console_core_getc
+	/* Not supported */
+	mov	r0, #-1
+	bx	lr
+endfunc console_core_getc
+
+	/* ---------------------------------------------------------------
+	 * int console_core_flush(uintptr_t base_addr)
+	 *
+	 * Function to force a write of all buffered data that hasn't been
+	 * output.
+	 *
+	 * In : r0 - console base address
+	 * Out : return -1 on error else return 0.
+	 * Clobber list : r0, r1
+	 * ---------------------------------------------------------------
+	 */
+func console_core_flush
+	cmp	r0, #0
+	beq	flush_error
+	/* Check Transmit Data Register Empty */
+txe_loop_3:
+	ldr	r1, [r0, #USART_ISR]
+	tst	r1, #USART_ISR_TXE
+	beq	txe_loop_3
+	mov	r0, #0
+	bx	lr
+flush_error:
+	mov	r0, #-1
+	bx	lr
+endfunc console_core_flush
diff --git a/fdts/stm32mp15-ddr.dtsi b/fdts/stm32mp15-ddr.dtsi
new file mode 100644
index 0000000..be4e2c3
--- /dev/null
+++ b/fdts/stm32mp15-ddr.dtsi
@@ -0,0 +1,153 @@
+// SPDX-License-Identifier: GPL-2.0+ OR BSD-3-Clause
+/*
+ * Copyright (C) 2018, STMicroelectronics - All Rights Reserved
+ */
+
+/ {
+	soc {
+		ddr: ddr@0x5A003000{
+
+			compatible = "st,stm32mp1-ddr";
+
+			reg = <0x5A003000 0x550
+			       0x5A004000 0x234>;
+
+			clocks = <&rcc AXIDCG>,
+				 <&rcc DDRC1>,
+				 <&rcc DDRC2>,
+				 <&rcc DDRPHYC>,
+				 <&rcc DDRCAPB>,
+				 <&rcc DDRPHYCAPB>;
+
+			clock-names = "axidcg",
+				      "ddrc1",
+				      "ddrc2",
+				      "ddrphyc",
+				      "ddrcapb",
+				      "ddrphycapb";
+
+			st,mem-name = DDR_MEM_NAME;
+			st,mem-speed = <DDR_MEM_SPEED>;
+			st,mem-size = <DDR_MEM_SIZE>;
+
+			st,ctl-reg = <
+				DDR_MSTR
+				DDR_MRCTRL0
+				DDR_MRCTRL1
+				DDR_DERATEEN
+				DDR_DERATEINT
+				DDR_PWRCTL
+				DDR_PWRTMG
+				DDR_HWLPCTL
+				DDR_RFSHCTL0
+				DDR_RFSHCTL3
+				DDR_CRCPARCTL0
+				DDR_ZQCTL0
+				DDR_DFITMG0
+				DDR_DFITMG1
+				DDR_DFILPCFG0
+				DDR_DFIUPD0
+				DDR_DFIUPD1
+				DDR_DFIUPD2
+				DDR_DFIPHYMSTR
+				DDR_ODTMAP
+				DDR_DBG0
+				DDR_DBG1
+				DDR_DBGCMD
+				DDR_POISONCFG
+				DDR_PCCFG
+			>;
+
+			st,ctl-timing = <
+				DDR_RFSHTMG
+				DDR_DRAMTMG0
+				DDR_DRAMTMG1
+				DDR_DRAMTMG2
+				DDR_DRAMTMG3
+				DDR_DRAMTMG4
+				DDR_DRAMTMG5
+				DDR_DRAMTMG6
+				DDR_DRAMTMG7
+				DDR_DRAMTMG8
+				DDR_DRAMTMG14
+				DDR_ODTCFG
+			>;
+
+			st,ctl-map = <
+				DDR_ADDRMAP1
+				DDR_ADDRMAP2
+				DDR_ADDRMAP3
+				DDR_ADDRMAP4
+				DDR_ADDRMAP5
+				DDR_ADDRMAP6
+				DDR_ADDRMAP9
+				DDR_ADDRMAP10
+				DDR_ADDRMAP11
+			>;
+
+			st,ctl-perf = <
+				DDR_SCHED
+				DDR_SCHED1
+				DDR_PERFHPR1
+				DDR_PERFLPR1
+				DDR_PERFWR1
+				DDR_PCFGR_0
+				DDR_PCFGW_0
+				DDR_PCFGQOS0_0
+				DDR_PCFGQOS1_0
+				DDR_PCFGWQOS0_0
+				DDR_PCFGWQOS1_0
+				DDR_PCFGR_1
+				DDR_PCFGW_1
+				DDR_PCFGQOS0_1
+				DDR_PCFGQOS1_1
+				DDR_PCFGWQOS0_1
+				DDR_PCFGWQOS1_1
+			>;
+
+			st,phy-reg = <
+				DDR_PGCR
+				DDR_ACIOCR
+				DDR_DXCCR
+				DDR_DSGCR
+				DDR_DCR
+				DDR_ODTCR
+				DDR_ZQ0CR1
+				DDR_DX0GCR
+				DDR_DX1GCR
+				DDR_DX2GCR
+				DDR_DX3GCR
+			>;
+
+			st,phy-timing = <
+				DDR_PTR0
+				DDR_PTR1
+				DDR_PTR2
+				DDR_DTPR0
+				DDR_DTPR1
+				DDR_DTPR2
+				DDR_MR0
+				DDR_MR1
+				DDR_MR2
+				DDR_MR3
+			>;
+
+			st,phy-cal = <
+				DDR_DX0DLLCR
+				DDR_DX0DQTR
+				DDR_DX0DQSTR
+				DDR_DX1DLLCR
+				DDR_DX1DQTR
+				DDR_DX1DQSTR
+				DDR_DX2DLLCR
+				DDR_DX2DQTR
+				DDR_DX2DQSTR
+				DDR_DX3DLLCR
+				DDR_DX3DQTR
+				DDR_DX3DQSTR
+			>;
+
+			status = "okay";
+		};
+	};
+};
diff --git a/fdts/stm32mp15-ddr3-2x4Gb-1066-binG.dtsi b/fdts/stm32mp15-ddr3-2x4Gb-1066-binG.dtsi
new file mode 100644
index 0000000..58a4cdc
--- /dev/null
+++ b/fdts/stm32mp15-ddr3-2x4Gb-1066-binG.dtsi
@@ -0,0 +1,121 @@
+// SPDX-License-Identifier: GPL-2.0+ OR BSD-3-Clause
+/*
+ * Copyright (C) 2018, STMicroelectronics - All Rights Reserved
+ */
+
+/* STM32MP157C ED1 and ED2 BOARD configuration
+ * 2x DDR3L 4Gb each, 16-bit, 533MHz, Single Die Package in flyby topology.
+ * Reference used NT5CC256M16DP-DI from NANYA
+ *
+ * DDR type / Platform	DDR3/3L
+ * freq		533MHz
+ * width	32
+ * datasheet	0  = MT41J256M16-187 / DDR3-1066 bin G
+ * DDR density	8
+ * timing mode	optimized
+ * Scheduling/QoS options : type = 2
+ * address mapping : RBC
+ */
+
+#define DDR_MEM_NAME "DDR3-1066 bin G 2x4Gb 533MHz v1.39"
+#define DDR_MEM_SPEED 533
+#define DDR_MEM_SIZE 0x40000000
+
+#define DDR_MSTR 0x00040401
+#define DDR_MRCTRL0 0x00000010
+#define DDR_MRCTRL1 0x00000000
+#define DDR_DERATEEN 0x00000000
+#define DDR_DERATEINT 0x00800000
+#define DDR_PWRCTL 0x00000000
+#define DDR_PWRTMG 0x00400010
+#define DDR_HWLPCTL 0x00000000
+#define DDR_RFSHCTL0 0x00210000
+#define DDR_RFSHCTL3 0x00000000
+#define DDR_RFSHTMG 0x0081008B
+#define DDR_CRCPARCTL0 0x00000000
+#define DDR_DRAMTMG0 0x121B2414
+#define DDR_DRAMTMG1 0x000A041C
+#define DDR_DRAMTMG2 0x0608090F
+#define DDR_DRAMTMG3 0x0050400C
+#define DDR_DRAMTMG4 0x08040608
+#define DDR_DRAMTMG5 0x06060403
+#define DDR_DRAMTMG6 0x02020002
+#define DDR_DRAMTMG7 0x00000202
+#define DDR_DRAMTMG8 0x00001005
+#define DDR_DRAMTMG14 0x000000A0
+#define DDR_ZQCTL0 0xC2000040
+#define DDR_DFITMG0 0x02060105
+#define DDR_DFITMG1 0x00000202
+#define DDR_DFILPCFG0 0x07000000
+#define DDR_DFIUPD0 0xC0400003
+#define DDR_DFIUPD1 0x00000000
+#define DDR_DFIUPD2 0x00000000
+#define DDR_DFIPHYMSTR 0x00000000
+#define DDR_ADDRMAP1 0x00080808
+#define DDR_ADDRMAP2 0x00000000
+#define DDR_ADDRMAP3 0x00000000
+#define DDR_ADDRMAP4 0x00001F1F
+#define DDR_ADDRMAP5 0x07070707
+#define DDR_ADDRMAP6 0x0F070707
+#define DDR_ADDRMAP9 0x00000000
+#define DDR_ADDRMAP10 0x00000000
+#define DDR_ADDRMAP11 0x00000000
+#define DDR_ODTCFG 0x06000600
+#define DDR_ODTMAP 0x00000001
+#define DDR_SCHED 0x00001201
+#define DDR_SCHED1 0x00000000
+#define DDR_PERFHPR1 0x01000001
+#define DDR_PERFLPR1 0x08000200
+#define DDR_PERFWR1 0x08000400
+#define DDR_DBG0 0x00000000
+#define DDR_DBG1 0x00000000
+#define DDR_DBGCMD 0x00000000
+#define DDR_POISONCFG 0x00000000
+#define DDR_PCCFG 0x00000010
+#define DDR_PCFGR_0 0x00010000
+#define DDR_PCFGW_0 0x00000000
+#define DDR_PCFGQOS0_0 0x02100B03
+#define DDR_PCFGQOS1_0 0x00800100
+#define DDR_PCFGWQOS0_0 0x01100B03
+#define DDR_PCFGWQOS1_0 0x01000200
+#define DDR_PCFGR_1 0x00010000
+#define DDR_PCFGW_1 0x00000000
+#define DDR_PCFGQOS0_1 0x02100B03
+#define DDR_PCFGQOS1_1 0x00800000
+#define DDR_PCFGWQOS0_1 0x01100B03
+#define DDR_PCFGWQOS1_1 0x01000200
+#define DDR_PGCR 0x01442E02
+#define DDR_PTR0 0x0022AA5B
+#define DDR_PTR1 0x04841104
+#define DDR_PTR2 0x042DA068
+#define DDR_ACIOCR 0x10400812
+#define DDR_DXCCR 0x00000C40
+#define DDR_DSGCR 0xF200001F
+#define DDR_DCR 0x0000000B
+#define DDR_DTPR0 0x38D488D0
+#define DDR_DTPR1 0x098B00D8
+#define DDR_DTPR2 0x10023600
+#define DDR_MR0 0x00000840
+#define DDR_MR1 0x00000000
+#define DDR_MR2 0x00000208
+#define DDR_MR3 0x00000000
+#define DDR_ODTCR 0x00010000
+#define DDR_ZQ0CR1 0x00000038
+#define DDR_DX0GCR 0x0000CE81
+#define DDR_DX0DLLCR 0x40000000
+#define DDR_DX0DQTR 0xFFFFFFFF
+#define DDR_DX0DQSTR 0x3DB02000
+#define DDR_DX1GCR 0x0000CE81
+#define DDR_DX1DLLCR 0x40000000
+#define DDR_DX1DQTR 0xFFFFFFFF
+#define DDR_DX1DQSTR 0x3DB02000
+#define DDR_DX2GCR 0x0000CE81
+#define DDR_DX2DLLCR 0x40000000
+#define DDR_DX2DQTR 0xFFFFFFFF
+#define DDR_DX2DQSTR 0x3DB02000
+#define DDR_DX3GCR 0x0000CE81
+#define DDR_DX3DLLCR 0x40000000
+#define DDR_DX3DQTR 0xFFFFFFFF
+#define DDR_DX3DQSTR 0x3DB02000
+
+#include "stm32mp15-ddr.dtsi"
diff --git a/fdts/stm32mp157-pinctrl.dtsi b/fdts/stm32mp157-pinctrl.dtsi
new file mode 100644
index 0000000..21bd34e
--- /dev/null
+++ b/fdts/stm32mp157-pinctrl.dtsi
@@ -0,0 +1,250 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR BSD-3-Clause)
+/*
+ * Copyright (C) STMicroelectronics 2017 - All Rights Reserved
+ * Author: Ludovic Barre <ludovic.barre@st.com> for STMicroelectronics.
+ */
+
+#include <dt-bindings/pinctrl/stm32-pinfunc.h>
+/ {
+	soc {
+		pinctrl: pin-controller {
+			#address-cells = <1>;
+			#size-cells = <1>;
+			ranges = <0 0x50002000 0xa400>;
+			pins-are-numbered;
+
+			gpioa: gpio@50002000 {
+				gpio-controller;
+				#gpio-cells = <2>;
+				interrupt-controller;
+				#interrupt-cells = <2>;
+				reg = <0x0 0x400>;
+				clocks = <&rcc GPIOA>;
+				st,bank-name = "GPIOA";
+				status = "disabled";
+			};
+
+			gpiob: gpio@50003000 {
+				gpio-controller;
+				#gpio-cells = <2>;
+				interrupt-controller;
+				#interrupt-cells = <2>;
+				reg = <0x1000 0x400>;
+				clocks = <&rcc GPIOB>;
+				st,bank-name = "GPIOB";
+				status = "disabled";
+			};
+
+			gpioc: gpio@50004000 {
+				gpio-controller;
+				#gpio-cells = <2>;
+				interrupt-controller;
+				#interrupt-cells = <2>;
+				reg = <0x2000 0x400>;
+				clocks = <&rcc GPIOC>;
+				st,bank-name = "GPIOC";
+				status = "disabled";
+			};
+
+			gpiod: gpio@50005000 {
+				gpio-controller;
+				#gpio-cells = <2>;
+				interrupt-controller;
+				#interrupt-cells = <2>;
+				reg = <0x3000 0x400>;
+				clocks = <&rcc GPIOD>;
+				st,bank-name = "GPIOD";
+				status = "disabled";
+			};
+
+			gpioe: gpio@50006000 {
+				gpio-controller;
+				#gpio-cells = <2>;
+				interrupt-controller;
+				#interrupt-cells = <2>;
+				reg = <0x4000 0x400>;
+				clocks = <&rcc GPIOE>;
+				st,bank-name = "GPIOE";
+				status = "disabled";
+			};
+
+			gpiof: gpio@50007000 {
+				gpio-controller;
+				#gpio-cells = <2>;
+				interrupt-controller;
+				#interrupt-cells = <2>;
+				reg = <0x5000 0x400>;
+				clocks = <&rcc GPIOF>;
+				st,bank-name = "GPIOF";
+				status = "disabled";
+			};
+
+			gpiog: gpio@50008000 {
+				gpio-controller;
+				#gpio-cells = <2>;
+				interrupt-controller;
+				#interrupt-cells = <2>;
+				reg = <0x6000 0x400>;
+				clocks = <&rcc GPIOG>;
+				st,bank-name = "GPIOG";
+				status = "disabled";
+			};
+
+			gpioh: gpio@50009000 {
+				gpio-controller;
+				#gpio-cells = <2>;
+				interrupt-controller;
+				#interrupt-cells = <2>;
+				reg = <0x7000 0x400>;
+				clocks = <&rcc GPIOH>;
+				st,bank-name = "GPIOH";
+				status = "disabled";
+			};
+
+			gpioi: gpio@5000a000 {
+				gpio-controller;
+				#gpio-cells = <2>;
+				interrupt-controller;
+				#interrupt-cells = <2>;
+				reg = <0x8000 0x400>;
+				clocks = <&rcc GPIOI>;
+				st,bank-name = "GPIOI";
+				status = "disabled";
+			};
+
+			gpioj: gpio@5000b000 {
+				gpio-controller;
+				#gpio-cells = <2>;
+				interrupt-controller;
+				#interrupt-cells = <2>;
+				reg = <0x9000 0x400>;
+				clocks = <&rcc GPIOJ>;
+				st,bank-name = "GPIOJ";
+				status = "disabled";
+			};
+
+			gpiok: gpio@5000c000 {
+				gpio-controller;
+				#gpio-cells = <2>;
+				interrupt-controller;
+				#interrupt-cells = <2>;
+				reg = <0xa000 0x400>;
+				clocks = <&rcc GPIOK>;
+				st,bank-name = "GPIOK";
+				status = "disabled";
+			};
+
+			uart4_pins_a: uart4@0 {
+				pins1 {
+					pinmux = <STM32_PINMUX('G', 11, AF6)>; /* UART4_TX */
+					bias-disable;
+					drive-push-pull;
+					slew-rate = <0>;
+				};
+				pins2 {
+					pinmux = <STM32_PINMUX('B', 2, AF8)>; /* UART4_RX */
+					bias-disable;
+				};
+			};
+
+			usart3_pins_a: usart3@0 {
+				pins1 {
+					pinmux = <STM32_PINMUX('B', 10, AF7)>, /* USART3_TX */
+						 <STM32_PINMUX('G', 8, AF8)>; /* USART3_RTS */
+					bias-disable;
+					drive-push-pull;
+					slew-rate = <0>;
+				};
+				pins2 {
+					pinmux = <STM32_PINMUX('B', 12, AF8)>, /* USART3_RX */
+						 <STM32_PINMUX('I', 10, AF8)>; /* USART3_CTS_NSS */
+					bias-disable;
+				};
+			};
+
+			sdmmc1_b4_pins_a: sdmmc1-b4@0 {
+				pins {
+					pinmux = <STM32_PINMUX('C', 8, AF12)>, /* SDMMC1_D0 */
+						 <STM32_PINMUX('C', 9, AF12)>, /* SDMMC1_D1 */
+						 <STM32_PINMUX('C', 10, AF12)>, /* SDMMC1_D2 */
+						 <STM32_PINMUX('C', 11, AF12)>, /* SDMMC1_D3 */
+						 <STM32_PINMUX('C', 12, AF12)>, /* SDMMC1_CK */
+						 <STM32_PINMUX('D', 2, AF12)>; /* SDMMC1_CMD */
+					slew-rate = <3>;
+					drive-push-pull;
+					bias-disable;
+				};
+			};
+
+			sdmmc1_dir_pins_a: sdmmc1-dir@0 {
+				pins1 {
+					pinmux = <STM32_PINMUX('F', 2, AF11)>, /* SDMMC1_D0DIR */
+						 <STM32_PINMUX('C', 7, AF8)>, /* SDMMC1_D123DIR */
+						 <STM32_PINMUX('B', 9, AF11)>; /* SDMMC1_CDIR */
+					slew-rate = <3>;
+					drive-push-pull;
+					bias-pull-up;
+				};
+				pins2{
+					pinmux = <STM32_PINMUX('E', 4, AF8)>; /* SDMMC1_CKIN */
+					bias-pull-up;
+				};
+			};
+
+			sdmmc2_b4_pins_a: sdmmc2-b4@0 {
+				pins {
+					pinmux = <STM32_PINMUX('B', 14, AF9)>, /* SDMMC2_D0 */
+						 <STM32_PINMUX('B', 15, AF9)>, /* SDMMC2_D1 */
+						 <STM32_PINMUX('B', 3, AF9)>, /* SDMMC2_D2 */
+						 <STM32_PINMUX('B', 4, AF9)>, /* SDMMC2_D3 */
+						 <STM32_PINMUX('E', 3, AF9)>, /* SDMMC2_CK */
+						 <STM32_PINMUX('G', 6, AF10)>; /* SDMMC2_CMD */
+					slew-rate = <3>;
+					drive-push-pull;
+					bias-pull-up;
+				};
+			};
+
+			sdmmc2_d47_pins_a: sdmmc2-d47@0 {
+				pins {
+					pinmux = <STM32_PINMUX('A', 8, AF9)>, /* SDMMC2_D4 */
+						 <STM32_PINMUX('A', 9, AF10)>, /* SDMMC2_D5 */
+						 <STM32_PINMUX('E', 5, AF9)>, /* SDMMC2_D6 */
+						 <STM32_PINMUX('D', 3, AF9)>; /* SDMMC2_D7 */
+					slew-rate = <3>;
+					drive-push-pull;
+					bias-pull-up;
+				};
+			};
+		};
+
+		pinctrl_z: pin-controller-z {
+			#address-cells = <1>;
+			#size-cells = <1>;
+			ranges = <0 0x54004000 0x400>;
+			pins-are-numbered;
+
+			gpioz: gpio@54004000 {
+				gpio-controller;
+				#gpio-cells = <2>;
+				interrupt-controller;
+				#interrupt-cells = <2>;
+				reg = <0 0x400>;
+				clocks = <&rcc GPIOZ>;
+				st,bank-name = "GPIOZ";
+				st,bank-ioport = <11>;
+				status = "disabled";
+			};
+
+			i2c4_pins_a: i2c4@0 {
+				pins {
+					pinmux = <STM32_PINMUX('Z', 4, AF6)>, /* I2C4_SCL */
+						 <STM32_PINMUX('Z', 5, AF6)>; /* I2C4_SDA */
+					bias-disable;
+					drive-open-drain;
+					slew-rate = <0>;
+				};
+			};
+		};
+	};
+};
diff --git a/fdts/stm32mp157c-ed1.dts b/fdts/stm32mp157c-ed1.dts
new file mode 100644
index 0000000..e3dabe8
--- /dev/null
+++ b/fdts/stm32mp157c-ed1.dts
@@ -0,0 +1,246 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR BSD-3-Clause)
+/*
+ * Copyright (C) STMicroelectronics 2017 - All Rights Reserved
+ * Author: Ludovic Barre <ludovic.barre@st.com> for STMicroelectronics.
+ */
+
+/dts-v1/;
+
+#include "stm32mp157c.dtsi"
+#include "stm32mp157caa-pinctrl.dtsi"
+
+/ {
+	model = "STMicroelectronics STM32MP157C-ED1 pmic eval daughter";
+	compatible = "st,stm32mp157c-ed1", "st,stm32mp157";
+
+	chosen {
+		bootargs = "earlyprintk console=ttyS3,115200 root=/dev/ram";
+		stdout-path = "serial3:115200n8";
+	};
+};
+
+&i2c4 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&i2c4_pins_a>;
+	i2c-scl-rising-time-ns = <185>;
+	i2c-scl-falling-time-ns = <20>;
+	status = "okay";
+
+	pmic: stpmu1@33 {
+		compatible = "st,stpmu1";
+		reg = <0x33>;
+		status = "okay";
+
+		st,main_control_register = <0x04>;
+		st,vin_control_register = <0xc0>;
+		st,usb_control_register = <0x30>;
+
+		regulators {
+			compatible = "st,stpmu1-regulators";
+
+			v3v3: buck4 {
+				regulator-name = "v3v3";
+				regulator-min-microvolt = <3300000>;
+				regulator-max-microvolt = <3300000>;
+				regulator-boot-on;
+				regulator-over-current-protection;
+				regulator-initial-mode = <8>;
+
+				regulator-state-standby {
+					regulator-suspend-microvolt = <3300000>;
+					regulator-unchanged-in-suspend;
+					regulator-mode = <8>;
+				};
+				regulator-state-mem {
+					regulator-off-in-suspend;
+				};
+				regulator-state-disk {
+					regulator-off-in-suspend;
+				};
+			};
+
+			vdd_sd: ldo5 {
+				regulator-name = "vdd_sd";
+				regulator-min-microvolt = <2900000>;
+				regulator-max-microvolt = <2900000>;
+				regulator-boot-on;
+
+				regulator-state-standby {
+					regulator-suspend-microvolt = <2900000>;
+					regulator-unchanged-in-suspend;
+				};
+				regulator-state-mem {
+					regulator-off-in-suspend;
+				};
+				regulator-state-disk {
+					regulator-off-in-suspend;
+				};
+			};
+		};
+	};
+};
+
+&iwdg2 {
+	instance = <2>;
+	timeout-sec = <32>;
+	status = "okay";
+};
+
+&rng1 {
+	status = "okay";
+};
+
+&sdmmc1 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&sdmmc1_b4_pins_a &sdmmc1_dir_pins_a>;
+	broken-cd;
+	st,dirpol;
+	st,negedge;
+	st,pin-ckin;
+	bus-width = <4>;
+	sd-uhs-sdr12;
+	sd-uhs-sdr25;
+	sd-uhs-sdr50;
+	sd-uhs-ddr50;
+	sd-uhs-sdr104;
+	status = "okay";
+};
+
+&sdmmc2 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&sdmmc2_b4_pins_a &sdmmc2_d47_pins_a>;
+	non-removable;
+	no-sd;
+	no-sdio;
+	st,dirpol;
+	st,negedge;
+	bus-width = <8>;
+	status = "okay";
+};
+
+&uart4 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&uart4_pins_a>;
+	resets = <&rcc UART4_R>;
+	status = "okay";
+};
+
+/* ATF Specific */
+#include <dt-bindings/clock/stm32mp1-clksrc.h>
+#include "stm32mp15-ddr3-2x4Gb-1066-binG.dtsi"
+
+/ {
+	aliases {
+		gpio0 = &gpioa;
+		gpio1 = &gpiob;
+		gpio2 = &gpioc;
+		gpio3 = &gpiod;
+		gpio4 = &gpioe;
+		gpio5 = &gpiof;
+		gpio6 = &gpiog;
+		gpio7 = &gpioh;
+		gpio8 = &gpioi;
+		gpio9 = &gpioj;
+		gpio10 = &gpiok;
+		gpio25 = &gpioz;
+		i2c3 = &i2c4;
+	};
+
+	soc {
+		stgen: stgen@5C008000 {
+			compatible = "st,stm32-stgen";
+			reg = <0x5C008000 0x1000>;
+			status = "okay";
+		};
+	};
+};
+
+/* CLOCK init */
+&rcc {
+	st,clksrc = <
+		CLK_MPU_PLL1P
+		CLK_AXI_PLL2P
+		CLK_PLL12_HSE
+		CLK_PLL3_HSE
+		CLK_PLL4_HSE
+		CLK_RTC_LSE
+		CLK_MCO1_DISABLED
+		CLK_MCO2_DISABLED
+	>;
+
+	st,clkdiv = <
+		1 /*MPU*/
+		0 /*AXI*/
+		1 /*APB1*/
+		1 /*APB2*/
+		1 /*APB3*/
+		1 /*APB4*/
+		2 /*APB5*/
+		23 /*RTC*/
+		0 /*MCO1*/
+		0 /*MCO2*/
+	>;
+
+	st,pkcs = <
+		CLK_CKPER_HSE
+		CLK_FMC_ACLK
+		CLK_QSPI_ACLK
+		CLK_ETH_DISABLED
+		CLK_SDMMC12_PLL3R
+		CLK_DSI_DSIPLL
+		CLK_STGEN_HSE
+		CLK_USBPHY_HSE
+		CLK_SPI2S1_PLL3Q
+		CLK_SPI2S23_PLL3Q
+		CLK_SPI45_HSI
+		CLK_SPI6_HSI
+		CLK_I2C46_HSI
+		CLK_SDMMC3_PLL3R
+		CLK_USBO_USBPHY
+		CLK_ADC_CKPER
+		CLK_CEC_LSE
+		CLK_I2C12_HSI
+		CLK_I2C35_HSI
+		CLK_UART1_HSI
+		CLK_UART24_HSI
+		CLK_UART35_HSI
+		CLK_UART6_HSI
+		CLK_UART78_HSI
+		CLK_SPDIF_PLL3Q
+		CLK_FDCAN_PLL4Q
+		CLK_SAI1_PLL3Q
+		CLK_SAI2_PLL3Q
+		CLK_SAI3_PLL3Q
+		CLK_SAI4_PLL3Q
+		CLK_RNG1_CSI
+		CLK_RNG2_CSI
+		CLK_LPTIM1_PCLK1
+		CLK_LPTIM23_PCLK3
+		CLK_LPTIM45_PCLK3
+	>;
+
+	/* VCO = 1300.0 MHz => P = 650 (CPU) */
+	pll1: st,pll@0 {
+		cfg = < 2 80 0 0 0 PQR(1,0,0) >;
+		frac = < 0x800 >;
+	};
+
+	/* VCO = 1066.0 MHz => P = 266 (AXI), Q = 533 (GPU), R = 533 (DDR) */
+	pll2: st,pll@1 {
+		cfg = < 2 65 1 0 0 PQR(1,1,1) >;
+		frac = < 0x1400 >;
+	};
+
+	/* VCO = 786.4 MHz => P = 197, Q = 49, R = 98 */
+	pll3: st,pll@2 {
+		cfg = < 2 97 3 15 7 PQR(1,1,1) >;
+		frac = < 0x9ba >;
+	};
+
+	/* VCO = 508.0 MHz => P = 56, Q = 56, R = 56 */
+	pll4: st,pll@3 {
+		cfg = < 5 126 8 8 8 PQR(1,1,1) >;
+	};
+};
+
+/delete-node/ &clk_csi;
diff --git a/fdts/stm32mp157c-ev1.dts b/fdts/stm32mp157c-ev1.dts
new file mode 100644
index 0000000..98a9d35
--- /dev/null
+++ b/fdts/stm32mp157c-ev1.dts
@@ -0,0 +1,25 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR BSD-3-Clause)
+/*
+ * Copyright (C) STMicroelectronics 2017 - All Rights Reserved
+ * Author: Ludovic Barre <ludovic.barre@st.com> for STMicroelectronics.
+ */
+
+/dts-v1/;
+#include "stm32mp157c-ed1.dts"
+
+/ {
+	model = "STMicroelectronics STM32MP157C-EV1 pmic eval daughter on eval mother";
+	compatible = "st,stm32mp157c-ev1", "st,stm32mp157c-ed1", "st,stm32mp157";
+
+	chosen {
+		bootargs = "earlyprintk console=ttyS3,115200 root=/dev/ram";
+		stdout-path = "serial3:115200n8";
+	};
+};
+
+&usart3 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&usart3_pins_a>;
+	resets = <&rcc USART3_R>;
+	status = "disabled";
+};
diff --git a/fdts/stm32mp157c.dtsi b/fdts/stm32mp157c.dtsi
new file mode 100644
index 0000000..8b13c0e
--- /dev/null
+++ b/fdts/stm32mp157c.dtsi
@@ -0,0 +1,240 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR BSD-3-Clause)
+/*
+ * Copyright (C) STMicroelectronics 2017 - All Rights Reserved
+ * Author: Ludovic Barre <ludovic.barre@st.com> for STMicroelectronics.
+ */
+
+#include <dt-bindings/clock/stm32mp1-clks.h>
+#include <dt-bindings/reset/stm32mp1-resets.h>
+
+/ {
+	#address-cells = <1>;
+	#size-cells = <1>;
+
+	aliases {
+		serial0 = &usart1;
+		serial1 = &usart2;
+		serial2 = &usart3;
+		serial3 = &uart4;
+		serial4 = &uart5;
+		serial5 = &usart6;
+		serial6 = &uart7;
+		serial7 = &uart8;
+	};
+
+	clocks {
+		clk_hse: clk-hse {
+			#clock-cells = <0>;
+			compatible = "fixed-clock";
+			clock-frequency = <24000000>;
+		};
+
+		clk_hsi: clk-hsi {
+			#clock-cells = <0>;
+			compatible = "fixed-clock";
+			clock-frequency = <64000000>;
+		};
+
+		clk_lse: clk-lse {
+			#clock-cells = <0>;
+			compatible = "fixed-clock";
+			clock-frequency = <32768>;
+		};
+
+		clk_lsi: clk-lsi {
+			#clock-cells = <0>;
+			compatible = "fixed-clock";
+			clock-frequency = <32000>;
+		};
+
+		clk_csi: clk-csi {
+			#clock-cells = <0>;
+			compatible = "fixed-clock";
+			clock-frequency = <4000000>;
+		};
+
+		clk_i2s_ckin: i2s_ckin {
+			#clock-cells = <0>;
+			compatible = "fixed-clock";
+			clock-frequency = <64000000>;
+		};
+
+		clk_dsi_phy: ck_dsi_phy {
+			#clock-cells = <0>;
+			compatible = "fixed-clock";
+			clock-frequency = <0>;
+		};
+
+		clk_usbo_48m: ck_usbo_48m {
+			#clock-cells = <0>;
+			compatible = "fixed-clock";
+			clock-frequency = <48000000>;
+		};
+	};
+
+	soc {
+		compatible = "simple-bus";
+		#address-cells = <1>;
+		#size-cells = <1>;
+		ranges;
+
+		usart2: serial@4000e000 {
+			compatible = "st,stm32h7-usart";
+			reg = <0x4000e000 0x400>;
+			clocks = <&rcc USART2_K>;
+			status = "disabled";
+		};
+
+		usart3: serial@4000f000 {
+			compatible = "st,stm32h7-usart";
+			reg = <0x4000f000 0x400>;
+			clocks = <&rcc USART3_K>;
+			status = "disabled";
+		};
+
+		uart4: serial@40010000 {
+			compatible = "st,stm32h7-uart";
+			reg = <0x40010000 0x400>;
+			clocks = <&rcc UART4_K>;
+			status = "disabled";
+		};
+
+		uart5: serial@40011000 {
+			compatible = "st,stm32h7-uart";
+			reg = <0x40011000 0x400>;
+			clocks = <&rcc UART5_K>;
+			status = "disabled";
+		};
+
+
+		uart7: serial@40018000 {
+			compatible = "st,stm32h7-uart";
+			reg = <0x40018000 0x400>;
+			clocks = <&rcc UART7_K>;
+			status = "disabled";
+		};
+
+		uart8: serial@40019000 {
+			compatible = "st,stm32h7-uart";
+			reg = <0x40019000 0x400>;
+			clocks = <&rcc UART8_K>;
+			status = "disabled";
+		};
+
+		usart6: serial@44003000 {
+			compatible = "st,stm32h7-usart";
+			reg = <0x44003000 0x400>;
+			clocks = <&rcc USART6_K>;
+			status = "disabled";
+		};
+
+		sdmmc3: sdmmc@48004000 {
+			compatible = "st,stm32-sdmmc2";
+			reg = <0x48004000 0x400>, <0x48005000 0x400>;
+			reg-names = "sdmmc", "delay";
+			clocks = <&rcc SDMMC3_K>;
+			resets = <&rcc SDMMC3_R>;
+			cap-sd-highspeed;
+			cap-mmc-highspeed;
+			max-frequency = <120000000>;
+			status = "disabled";
+		};
+
+		rcc: rcc@50000000 {
+			compatible = "syscon", "st,stm32mp1-rcc";
+			#clock-cells = <1>;
+			#reset-cells = <1>;
+			reg = <0x50000000 0x1000>;
+		};
+
+		rcc_reboot: rcc-reboot@50000000 {
+				compatible = "syscon-reboot";
+				regmap = <&rcc>;
+				offset = <0x404>;
+				mask = <0x1>;
+		};
+
+		rng1: rng@54003000 {
+			compatible = "st,stm32-rng";
+			reg = <0x54003000 0x400>;
+			clocks = <&rcc RNG1_K>;
+			resets = <&rcc RNG1_R>;
+			status = "disabled";
+		};
+
+		fmc_nand: fmc_nand@58002000 {
+			compatible = "st,stm32mp1-fmc";
+			reg = <0x58002000 0x1000>,
+			      <0x80000000 0x40000>,
+			      <0x81000000 0x40000>,
+			      <0x88000000 0x40000>,
+			      <0x89000000 0x40000>;
+			clocks = <&rcc FMC_K>;
+			resets = <&rcc FMC_R>;
+			status = "disabled";
+		};
+
+		qspi: qspi@58003000 {
+			compatible = "st,stm32f469-qspi";
+			reg = <0x58003000 0x1000>, <0x70000000 0x10000000>;
+			clocks = <&rcc QSPI_K>;
+			status = "disabled";
+		};
+
+		sdmmc1: sdmmc@58005000 {
+			compatible = "st,stm32-sdmmc2";
+			reg = <0x58005000 0x1000>, <0x58006000 0x1000>;
+			reg-names = "sdmmc", "delay";
+			clocks = <&rcc SDMMC1_K>;
+			resets = <&rcc SDMMC1_R>;
+			cap-sd-highspeed;
+			cap-mmc-highspeed;
+			max-frequency = <120000000>;
+			status = "disabled";
+		};
+
+		sdmmc2: sdmmc@58007000 {
+			compatible = "st,stm32-sdmmc2";
+			reg = <0x58007000 0x1000>, <0x58008000 0x1000>;
+			reg-names = "sdmmc", "delay";
+			clocks = <&rcc SDMMC2_K>;
+			resets = <&rcc SDMMC2_R>;
+			cap-sd-highspeed;
+			cap-mmc-highspeed;
+			max-frequency = <120000000>;
+			status = "disabled";
+		};
+
+		iwdg2: iwdg@5a002000 {
+			compatible = "st,stm32mp1-iwdg";
+			reg = <0x5a002000 0x400>;
+			clocks = <&rcc IWDG2>, <&rcc CK_LSI>;
+			clock-names = "pclk", "lsi";
+			status = "disabled";
+		};
+
+		usart1: serial@5c000000 {
+			compatible = "st,stm32h7-usart";
+			reg = <0x5c000000 0x400>;
+			clocks = <&rcc USART1_K>;
+			status = "disabled";
+		};
+
+		i2c4: i2c@5c002000 {
+			compatible = "st,stm32f7-i2c";
+			reg = <0x5c002000 0x400>;
+			clocks = <&rcc I2C4_K>;
+			resets = <&rcc I2C4_R>;
+			#address-cells = <1>;
+			#size-cells = <0>;
+			status = "disabled";
+		};
+
+		rtc: rtc@5c004000 {
+			compatible = "st,stm32mp1-rtc";
+			reg = <0x5c004000 0x400>;
+			clocks = <&rcc RTCAPB>, <&rcc RTC>;
+			clock-names = "pclk", "rtc_ck";
+		};
+	};
+};
diff --git a/fdts/stm32mp157caa-pinctrl.dtsi b/fdts/stm32mp157caa-pinctrl.dtsi
new file mode 100644
index 0000000..774561a
--- /dev/null
+++ b/fdts/stm32mp157caa-pinctrl.dtsi
@@ -0,0 +1,90 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR BSD-3-Clause)
+/*
+ * Copyright (C) STMicroelectronics 2018 - All Rights Reserved
+ * Author: Alexandre Torgue <alexandre.torgue@st.com>
+ */
+
+#include "stm32mp157-pinctrl.dtsi"
+/ {
+	soc {
+		pinctrl: pin-controller {
+			compatible = "st,stm32mp157caa-pinctrl";
+
+			gpioa: gpio@50002000 {
+				status = "okay";
+				ngpios = <16>;
+				gpio-ranges = <&pinctrl 0 0 16>;
+			};
+
+			gpiob: gpio@50003000 {
+				status = "okay";
+				ngpios = <16>;
+				gpio-ranges = <&pinctrl 0 16 16>;
+			};
+
+			gpioc: gpio@50004000 {
+				status = "okay";
+				ngpios = <16>;
+				gpio-ranges = <&pinctrl 0 32 16>;
+			};
+
+			gpiod: gpio@50005000 {
+				status = "okay";
+				ngpios = <16>;
+				gpio-ranges = <&pinctrl 0 48 16>;
+			};
+
+			gpioe: gpio@50006000 {
+				status = "okay";
+				ngpios = <16>;
+				gpio-ranges = <&pinctrl 0 64 16>;
+			};
+
+			gpiof: gpio@50007000 {
+				status = "okay";
+				ngpios = <16>;
+				gpio-ranges = <&pinctrl 0 80 16>;
+			};
+
+			gpiog: gpio@50008000 {
+				status = "okay";
+				ngpios = <16>;
+				gpio-ranges = <&pinctrl 0 96 16>;
+			};
+
+			gpioh: gpio@50009000 {
+				status = "okay";
+				ngpios = <16>;
+				gpio-ranges = <&pinctrl 0 112 16>;
+			};
+
+			gpioi: gpio@5000a000 {
+				status = "okay";
+				ngpios = <16>;
+				gpio-ranges = <&pinctrl 0 128 16>;
+			};
+
+			gpioj: gpio@5000b000 {
+				status = "okay";
+				ngpios = <16>;
+				gpio-ranges = <&pinctrl 0 144 16>;
+			};
+
+			gpiok: gpio@5000c000 {
+				status = "okay";
+				ngpios = <8>;
+				gpio-ranges = <&pinctrl 0 160 8>;
+			};
+		};
+
+		pinctrl_z: pin-controller-z {
+			compatible = "st,stm32mp157caa-z-pinctrl";
+
+			gpioz: gpio@54004000 {
+				status = "okay";
+				ngpios = <8>;
+				gpio-ranges = <&pinctrl_z 0 400 8>;
+			};
+		};
+	};
+};
diff --git a/include/drivers/st/stm32_gpio.h b/include/drivers/st/stm32_gpio.h
new file mode 100644
index 0000000..7a5ccd3
--- /dev/null
+++ b/include/drivers/st/stm32_gpio.h
@@ -0,0 +1,101 @@
+/*
+ * Copyright (c) 2015-2018, STMicroelectronics - All Rights Reserved
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef __PLAT_GPIO_H__
+#define __PLAT_GPIO_H__
+
+#include <utils_def.h>
+
+#define STM32_GPIOA_BANK	U(0x50002000)
+#define STM32_GPIOZ_BANK	U(0x54004000)
+#define STM32_GPIO_BANK_OFFSET	U(0x1000)
+
+#define GPIO_MODE_OFFSET	U(0x00)
+#define GPIO_TYPE_OFFSET	U(0x04)
+#define GPIO_SPEED_OFFSET	U(0x08)
+#define GPIO_PUPD_OFFSET	U(0x0C)
+#define GPIO_BSRR_OFFSET	U(0x18)
+#define GPIO_AFRL_OFFSET	U(0x20)
+#define GPIO_AFRH_OFFSET	U(0x24)
+
+#define GPIO_ALT_LOWER_LIMIT	U(0x08)
+
+#define GPIO_BANK_A		U(0x00)
+#define GPIO_BANK_B		U(0x01)
+#define GPIO_BANK_C		U(0x02)
+#define GPIO_BANK_D		U(0x03)
+#define GPIO_BANK_E		U(0x04)
+#define GPIO_BANK_F		U(0x05)
+#define GPIO_BANK_G		U(0x06)
+#define GPIO_BANK_H		U(0x07)
+#define GPIO_BANK_I		U(0x08)
+#define GPIO_BANK_J		U(0x09)
+#define GPIO_BANK_K		U(0x0A)
+#define GPIO_BANK_Z		U(0x19)
+
+#define GPIO_PIN_0		U(0x00)
+#define GPIO_PIN_1		U(0x01)
+#define GPIO_PIN_2		U(0x02)
+#define GPIO_PIN_3		U(0x03)
+#define GPIO_PIN_4		U(0x04)
+#define GPIO_PIN_5		U(0x05)
+#define GPIO_PIN_6		U(0x06)
+#define GPIO_PIN_7		U(0x07)
+#define GPIO_PIN_8		U(0x08)
+#define GPIO_PIN_9		U(0x09)
+#define GPIO_PIN_10		U(0x0A)
+#define GPIO_PIN_11		U(0x0B)
+#define GPIO_PIN_12		U(0x0C)
+#define GPIO_PIN_13		U(0x0D)
+#define GPIO_PIN_14		U(0x0E)
+#define GPIO_PIN_15		U(0x0F)
+#define GPIO_PIN_MAX		GPIO_PIN_15
+
+#define GPIO_ALTERNATE_0	0x00
+#define GPIO_ALTERNATE_1	0x01
+#define GPIO_ALTERNATE_2	0x02
+#define GPIO_ALTERNATE_3	0x03
+#define GPIO_ALTERNATE_4	0x04
+#define GPIO_ALTERNATE_5	0x05
+#define GPIO_ALTERNATE_6	0x06
+#define GPIO_ALTERNATE_7	0x07
+#define GPIO_ALTERNATE_8	0x08
+#define GPIO_ALTERNATE_9	0x09
+#define GPIO_ALTERNATE_10	0x0A
+#define GPIO_ALTERNATE_11	0x0B
+#define GPIO_ALTERNATE_12	0x0C
+#define GPIO_ALTERNATE_13	0x0D
+#define GPIO_ALTERNATE_14	0x0E
+#define GPIO_ALTERNATE_15	0x0F
+#define GPIO_ALTERNATE_MASK	U(0x0F)
+
+#define GPIO_MODE_INPUT		0x00
+#define GPIO_MODE_OUTPUT	0x01
+#define GPIO_MODE_ALTERNATE	0x02
+#define GPIO_MODE_ANALOG	0x03
+#define GPIO_MODE_MASK		U(0x03)
+
+#define GPIO_OPEN_DRAIN		U(0x10)
+
+#define GPIO_SPEED_LOW		0x00
+#define GPIO_SPEED_MEDIUM	0x01
+#define GPIO_SPEED_FAST		0x02
+#define GPIO_SPEED_HIGH		0x03
+#define GPIO_SPEED_MASK		U(0x03)
+
+#define GPIO_NO_PULL		0x00
+#define GPIO_PULL_UP		0x01
+#define GPIO_PULL_DOWN		0x02
+#define GPIO_PULL_MASK		U(0x03)
+
+#ifndef __ASSEMBLY__
+#include <stdint.h>
+
+void set_gpio(uint32_t bank, uint32_t pin, uint32_t mode, uint32_t speed,
+	      uint32_t pull, uint32_t alternate);
+#endif /*__ASSEMBLY__*/
+
+#endif /*__PLAT_GPIO_H__*/
diff --git a/include/drivers/st/stm32_i2c.h b/include/drivers/st/stm32_i2c.h
new file mode 100644
index 0000000..29b9d34
--- /dev/null
+++ b/include/drivers/st/stm32_i2c.h
@@ -0,0 +1,300 @@
+/*
+ * Copyright (c) 2016-2018, STMicroelectronics - All Rights Reserved
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef __STM32MP1_I2C_H
+#define __STM32MP1_I2C_H
+
+#include <stdint.h>
+#include <utils_def.h>
+
+/* Bit definition for I2C_CR1 register */
+#define I2C_CR1_PE			BIT(0)
+#define I2C_CR1_TXIE			BIT(1)
+#define I2C_CR1_RXIE			BIT(2)
+#define I2C_CR1_ADDRIE			BIT(3)
+#define I2C_CR1_NACKIE			BIT(4)
+#define I2C_CR1_STOPIE			BIT(5)
+#define I2C_CR1_TCIE			BIT(6)
+#define I2C_CR1_ERRIE			BIT(7)
+#define I2C_CR1_DNF			GENMASK(11, 8)
+#define I2C_CR1_ANFOFF			BIT(12)
+#define I2C_CR1_SWRST			BIT(13)
+#define I2C_CR1_TXDMAEN			BIT(14)
+#define I2C_CR1_RXDMAEN			BIT(15)
+#define I2C_CR1_SBC			BIT(16)
+#define I2C_CR1_NOSTRETCH		BIT(17)
+#define I2C_CR1_WUPEN			BIT(18)
+#define I2C_CR1_GCEN			BIT(19)
+#define I2C_CR1_SMBHEN			BIT(22)
+#define I2C_CR1_SMBDEN			BIT(21)
+#define I2C_CR1_ALERTEN			BIT(22)
+#define I2C_CR1_PECEN			BIT(23)
+
+/* Bit definition for I2C_CR2 register */
+#define I2C_CR2_SADD			GENMASK(9, 0)
+#define I2C_CR2_RD_WRN			BIT(10)
+#define I2C_CR2_RD_WRN_OFFSET		10U
+#define I2C_CR2_ADD10			BIT(11)
+#define I2C_CR2_HEAD10R			BIT(12)
+#define I2C_CR2_START			BIT(13)
+#define I2C_CR2_STOP			BIT(14)
+#define I2C_CR2_NACK			BIT(15)
+#define I2C_CR2_NBYTES			GENMASK(23, 16)
+#define I2C_CR2_NBYTES_OFFSET		16U
+#define I2C_CR2_RELOAD			BIT(24)
+#define I2C_CR2_AUTOEND			BIT(25)
+#define I2C_CR2_PECBYTE			BIT(26)
+
+/* Bit definition for I2C_OAR1 register */
+#define I2C_OAR1_OA1			GENMASK(9, 0)
+#define I2C_OAR1_OA1MODE		BIT(10)
+#define I2C_OAR1_OA1EN			BIT(15)
+
+/* Bit definition for I2C_OAR2 register */
+#define I2C_OAR2_OA2			GENMASK(7, 1)
+#define I2C_OAR2_OA2MSK			GENMASK(10, 8)
+#define I2C_OAR2_OA2NOMASK		0
+#define I2C_OAR2_OA2MASK01		BIT(8)
+#define I2C_OAR2_OA2MASK02		BIT(9)
+#define I2C_OAR2_OA2MASK03		GENMASK(9, 8)
+#define I2C_OAR2_OA2MASK04		BIT(10)
+#define I2C_OAR2_OA2MASK05		(BIT(8) | BIT(10))
+#define I2C_OAR2_OA2MASK06		(BIT(9) | BIT(10))
+#define I2C_OAR2_OA2MASK07		GENMASK(10, 8)
+#define I2C_OAR2_OA2EN			BIT(15)
+
+/* Bit definition for I2C_TIMINGR register */
+#define I2C_TIMINGR_SCLL		GENMASK(7, 0)
+#define I2C_TIMINGR_SCLH		GENMASK(15, 8)
+#define I2C_TIMINGR_SDADEL		GENMASK(19, 16)
+#define I2C_TIMINGR_SCLDEL		GENMASK(23, 20)
+#define I2C_TIMINGR_PRESC		GENMASK(31, 28)
+
+/* Bit definition for I2C_TIMEOUTR register */
+#define I2C_TIMEOUTR_TIMEOUTA		GENMASK(11, 0)
+#define I2C_TIMEOUTR_TIDLE		BIT(12)
+#define I2C_TIMEOUTR_TIMOUTEN		BIT(15)
+#define I2C_TIMEOUTR_TIMEOUTB		GENMASK(27, 16)
+#define I2C_TIMEOUTR_TEXTEN		BIT(31)
+
+/* Bit definition for I2C_ISR register */
+#define I2C_ISR_TXE			BIT(0)
+#define I2C_ISR_TXIS			BIT(1)
+#define I2C_ISR_RXNE			BIT(2)
+#define I2C_ISR_ADDR			BIT(3)
+#define I2C_ISR_NACKF			BIT(4)
+#define I2C_ISR_STOPF			BIT(5)
+#define I2C_ISR_TC			BIT(6)
+#define I2C_ISR_TCR			BIT(7)
+#define I2C_ISR_BERR			BIT(8)
+#define I2C_ISR_ARLO			BIT(9)
+#define I2C_ISR_OVR			BIT(10)
+#define I2C_ISR_PECERR			BIT(11)
+#define I2C_ISR_TIMEOUT			BIT(12)
+#define I2C_ISR_ALERT			BIT(13)
+#define I2C_ISR_BUSY			BIT(15)
+#define I2C_ISR_DIR			BIT(16)
+#define I2C_ISR_ADDCODE			GENMASK(23, 17)
+
+/* Bit definition for I2C_ICR register */
+#define I2C_ICR_ADDRCF			BIT(3)
+#define I2C_ICR_NACKCF			BIT(4)
+#define I2C_ICR_STOPCF			BIT(5)
+#define I2C_ICR_BERRCF			BIT(8)
+#define I2C_ICR_ARLOCF			BIT(9)
+#define I2C_ICR_OVRCF			BIT(10)
+#define I2C_ICR_PECCF			BIT(11)
+#define I2C_ICR_TIMOUTCF		BIT(12)
+#define I2C_ICR_ALERTCF			BIT(13)
+
+struct stm32_i2c_init_s {
+	uint32_t timing;           /* Specifies the I2C_TIMINGR_register value
+				    * This parameter is calculated by referring
+				    * to I2C initialization section in Reference
+				    * manual.
+				    */
+
+	uint32_t own_address1;     /* Specifies the first device own address.
+				    * This parameter can be a 7-bit or 10-bit
+				    * address.
+				    */
+
+	uint32_t addressing_mode;  /* Specifies if 7-bit or 10-bit addressing
+				    * mode is selected.
+				    * This parameter can be a value of @ref
+				    * I2C_ADDRESSING_MODE.
+				    */
+
+	uint32_t dual_address_mode; /* Specifies if dual addressing mode is
+				     * selected.
+				     * This parameter can be a value of @ref
+				     * I2C_DUAL_ADDRESSING_MODE.
+				     */
+
+	uint32_t own_address2;     /* Specifies the second device own address
+				    * if dual addressing mode is selected.
+				    * This parameter can be a 7-bit address.
+				    */
+
+	uint32_t own_address2_masks; /* Specifies the acknowledge mask address
+				      * second device own address if dual
+				      * addressing mode is selected.
+				      * This parameter can be a value of @ref
+				      * I2C_OWN_ADDRESS2_MASKS.
+				      */
+
+	uint32_t general_call_mode; /* Specifies if general call mode is
+				     * selected.
+				     * This parameter can be a value of @ref
+				     * I2C_GENERAL_CALL_ADDRESSING_MODE.
+				     */
+
+	uint32_t no_stretch_mode;  /* Specifies if nostretch mode is
+				    * selected.
+				    * This parameter can be a value of @ref
+				    * I2C_NOSTRETCH_MODE.
+				    */
+
+};
+
+enum i2c_state_e {
+	I2C_STATE_RESET          = 0x00U,   /* Peripheral is not yet
+					     * initialized.
+					     */
+	I2C_STATE_READY          = 0x20U,   /* Peripheral Initialized
+					     * and ready for use.
+					     */
+	I2C_STATE_BUSY           = 0x24U,   /* An internal process is
+					     * ongoing.
+					     */
+	I2C_STATE_BUSY_TX        = 0x21U,   /* Data Transmission process
+					     * is ongoing.
+					     */
+	I2C_STATE_BUSY_RX        = 0x22U,   /* Data Reception process
+					     * is ongoing.
+					     */
+	I2C_STATE_LISTEN         = 0x28U,   /* Address Listen Mode is
+					     * ongoing.
+					     */
+	I2C_STATE_BUSY_TX_LISTEN = 0x29U,   /* Address Listen Mode
+					     * and Data Transmission
+					     * process is ongoing.
+					     */
+	I2C_STATE_BUSY_RX_LISTEN = 0x2AU,   /* Address Listen Mode
+					     * and Data Reception
+					     * process is ongoing.
+					     */
+	I2C_STATE_ABORT          = 0x60U,   /* Abort user request ongoing. */
+	I2C_STATE_TIMEOUT        = 0xA0U,   /* Timeout state. */
+	I2C_STATE_ERROR          = 0xE0U    /* Error. */
+
+};
+
+enum i2c_mode_e {
+	I2C_MODE_NONE   = 0x00U,   /* No I2C communication on going.       */
+	I2C_MODE_MASTER = 0x10U,   /* I2C communication is in Master Mode. */
+	I2C_MODE_SLAVE  = 0x20U,   /* I2C communication is in Slave Mode.  */
+	I2C_MODE_MEM    = 0x40U    /* I2C communication is in Memory Mode. */
+
+};
+
+#define I2C_ERROR_NONE		0x00000000U	/* No error              */
+#define I2C_ERROR_BERR		0x00000001U	/* BERR error            */
+#define I2C_ERROR_ARLO		0x00000002U	/* ARLO error            */
+#define I2C_ERROR_AF		0x00000004U	/* ACKF error            */
+#define I2C_ERROR_OVR		0x00000008U	/* OVR error             */
+#define I2C_ERROR_DMA		0x00000010U	/* DMA transfer error    */
+#define I2C_ERROR_TIMEOUT	0x00000020U	/* Timeout error         */
+#define I2C_ERROR_SIZE		0x00000040U	/* Size Management error */
+
+struct i2c_handle_s {
+	uint32_t i2c_base_addr;			/* Registers base address */
+
+	struct stm32_i2c_init_s i2c_init;	/* Communication parameters */
+
+	uint8_t *p_buff;			/* Pointer to transfer buffer */
+
+	uint16_t xfer_size;			/* Transfer size */
+
+	uint16_t xfer_count;			/* Transfer counter */
+
+	uint32_t prev_state;			/* Communication previous
+						 * state
+						 */
+
+	uint8_t lock;				/* Locking object */
+
+	enum i2c_state_e i2c_state;		/* Communication state */
+
+	enum i2c_mode_e i2c_mode;		/* Communication mode */
+
+	uint32_t i2c_err;			/* Error code */
+};
+
+#define I2C_ADDRESSINGMODE_7BIT		0x00000001U
+#define I2C_ADDRESSINGMODE_10BIT	0x00000002U
+
+#define I2C_DUALADDRESS_DISABLE		0x00000000U
+#define I2C_DUALADDRESS_ENABLE		I2C_OAR2_OA2EN
+
+#define I2C_GENERALCALL_DISABLE		0x00000000U
+#define I2C_GENERALCALL_ENABLE		I2C_CR1_GCEN
+
+#define I2C_NOSTRETCH_DISABLE		0x00000000U
+#define I2C_NOSTRETCH_ENABLE		I2C_CR1_NOSTRETCH
+
+#define I2C_MEMADD_SIZE_8BIT		0x00000001U
+#define I2C_MEMADD_SIZE_16BIT		0x00000002U
+
+#define  I2C_RELOAD_MODE		I2C_CR2_RELOAD
+#define  I2C_AUTOEND_MODE		I2C_CR2_AUTOEND
+#define  I2C_SOFTEND_MODE		0x00000000U
+
+#define  I2C_NO_STARTSTOP		0x00000000U
+#define  I2C_GENERATE_STOP		(BIT(31) | I2C_CR2_STOP)
+#define  I2C_GENERATE_START_READ	(BIT(31) | I2C_CR2_START | \
+					 I2C_CR2_RD_WRN)
+#define  I2C_GENERATE_START_WRITE	(BIT(31) | I2C_CR2_START)
+
+#define I2C_FLAG_TXE			I2C_ISR_TXE
+#define I2C_FLAG_TXIS			I2C_ISR_TXIS
+#define I2C_FLAG_RXNE			I2C_ISR_RXNE
+#define I2C_FLAG_ADDR			I2C_ISR_ADDR
+#define I2C_FLAG_AF			I2C_ISR_NACKF
+#define I2C_FLAG_STOPF			I2C_ISR_STOPF
+#define I2C_FLAG_TC			I2C_ISR_TC
+#define I2C_FLAG_TCR			I2C_ISR_TCR
+#define I2C_FLAG_BERR			I2C_ISR_BERR
+#define I2C_FLAG_ARLO			I2C_ISR_ARLO
+#define I2C_FLAG_OVR			I2C_ISR_OVR
+#define I2C_FLAG_PECERR			I2C_ISR_PECERR
+#define I2C_FLAG_TIMEOUT		I2C_ISR_TIMEOUT
+#define I2C_FLAG_ALERT			I2C_ISR_ALERT
+#define I2C_FLAG_BUSY			I2C_ISR_BUSY
+#define I2C_FLAG_DIR			I2C_ISR_DIR
+
+#define I2C_RESET_CR2			(I2C_CR2_SADD | I2C_CR2_HEAD10R | \
+					 I2C_CR2_NBYTES | I2C_CR2_RELOAD  | \
+					 I2C_CR2_RD_WRN)
+
+#define I2C_ANALOGFILTER_ENABLE		((uint32_t)0x00000000U)
+#define I2C_ANALOGFILTER_DISABLE	I2C_CR1_ANFOFF
+
+int stm32_i2c_init(struct i2c_handle_s *hi2c);
+
+int stm32_i2c_mem_write(struct i2c_handle_s *hi2c, uint16_t dev_addr,
+			uint16_t mem_addr, uint16_t mem_add_size,
+			uint8_t *p_data, uint16_t size, uint32_t timeout);
+int stm32_i2c_mem_read(struct i2c_handle_s *hi2c, uint16_t dev_addr,
+		       uint16_t mem_addr, uint16_t mem_add_size,
+		       uint8_t *p_data, uint16_t size, uint32_t timeout);
+int stm32_i2c_is_device_ready(struct i2c_handle_s *hi2c, uint16_t dev_addr,
+			      uint32_t trials, uint32_t timeout);
+
+int stm32_i2c_config_analog_filter(struct i2c_handle_s *hi2c,
+				   uint32_t analog_filter);
+
+#endif /* __STM32MP1_I2C_H */
diff --git a/include/drivers/st/stm32mp1_clk.h b/include/drivers/st/stm32mp1_clk.h
new file mode 100644
index 0000000..85a1eb8
--- /dev/null
+++ b/include/drivers/st/stm32mp1_clk.h
@@ -0,0 +1,30 @@
+/*
+ * Copyright (c) 2018, STMicroelectronics - All Rights Reserved
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef __STM32MP1_CLK_H__
+#define __STM32MP1_CLK_H__
+
+#include <arch_helpers.h>
+#include <stdbool.h>
+
+int stm32mp1_clk_probe(void);
+int stm32mp1_clk_init(void);
+bool stm32mp1_clk_is_enabled(unsigned long id);
+int stm32mp1_clk_enable(unsigned long id);
+int stm32mp1_clk_disable(unsigned long id);
+unsigned long stm32mp1_clk_get_rate(unsigned long id);
+void stm32mp1_stgen_increment(unsigned long long offset_in_ms);
+
+static inline uint32_t get_timer(uint32_t base)
+{
+	if (base == 0U) {
+		return (uint32_t)(~read_cntpct_el0());
+	}
+
+	return base - (uint32_t)(~read_cntpct_el0());
+}
+
+#endif /* __STM32MP1_CLK_H__ */
diff --git a/include/drivers/st/stm32mp1_clkfunc.h b/include/drivers/st/stm32mp1_clkfunc.h
new file mode 100644
index 0000000..635a9cd
--- /dev/null
+++ b/include/drivers/st/stm32mp1_clkfunc.h
@@ -0,0 +1,42 @@
+/*
+ * Copyright (c) 2017-2018, STMicroelectronics - All Rights Reserved
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef __STM32MP1_CLKFUNC_H__
+#define __STM32MP1_CLKFUNC_H__
+
+#include <stdbool.h>
+
+enum stm32mp_osc_id {
+	_HSI,
+	_HSE,
+	_CSI,
+	_LSI,
+	_LSE,
+	_I2S_CKIN,
+	_USB_PHY_48,
+	NB_OSC,
+	_UNKNOWN_OSC_ID = 0xFF
+};
+
+extern const char *stm32mp_osc_node_label[NB_OSC];
+
+int fdt_osc_read_freq(const char *name, uint32_t *freq);
+bool fdt_osc_read_bool(enum stm32mp_osc_id osc_id, const char *prop_name);
+uint32_t fdt_osc_read_uint32_default(enum stm32mp_osc_id osc_id,
+				     const char *prop_name,
+				     uint32_t dflt_value);
+
+uint32_t fdt_rcc_read_addr(void);
+int fdt_rcc_read_uint32_array(const char *prop_name,
+			      uint32_t *array, uint32_t count);
+int fdt_rcc_subnode_offset(const char *name);
+const uint32_t *fdt_rcc_read_prop(const char *prop_name, int *lenp);
+bool fdt_get_rcc_secure_status(void);
+
+uintptr_t fdt_get_stgen_base(void);
+int fdt_get_clock_id(int node);
+
+#endif /* __STM32MP1_CLKFUNC_H__ */
diff --git a/include/drivers/st/stm32mp1_ddr.h b/include/drivers/st/stm32mp1_ddr.h
new file mode 100644
index 0000000..0765664
--- /dev/null
+++ b/include/drivers/st/stm32mp1_ddr.h
@@ -0,0 +1,173 @@
+/*
+ * Copyright (C) 2018, STMicroelectronics - All Rights Reserved
+ *
+ * SPDX-License-Identifier: GPL-2.0+ OR BSD-3-Clause
+ */
+
+#ifndef _STM32MP1_DDR_H
+#define _STM32MP1_DDR_H
+
+#include <stdbool.h>
+
+#define DT_DDR_COMPAT	"st,stm32mp1-ddr"
+
+struct stm32mp1_ddr_size {
+	uint64_t base;
+	uint64_t size;
+};
+
+/**
+ * struct ddr_info
+ *
+ * @dev: pointer for the device
+ * @info: UCLASS RAM information
+ * @ctl: DDR controleur base address
+ * @phy: DDR PHY base address
+ * @syscfg: syscfg base address
+ */
+struct ddr_info {
+	struct stm32mp1_ddr_size info;
+	struct stm32mp1_ddrctl *ctl;
+	struct stm32mp1_ddrphy *phy;
+	uintptr_t pwr;
+	uintptr_t rcc;
+};
+
+struct stm32mp1_ddrctrl_reg {
+	uint32_t mstr;
+	uint32_t mrctrl0;
+	uint32_t mrctrl1;
+	uint32_t derateen;
+	uint32_t derateint;
+	uint32_t pwrctl;
+	uint32_t pwrtmg;
+	uint32_t hwlpctl;
+	uint32_t rfshctl0;
+	uint32_t rfshctl3;
+	uint32_t crcparctl0;
+	uint32_t zqctl0;
+	uint32_t dfitmg0;
+	uint32_t dfitmg1;
+	uint32_t dfilpcfg0;
+	uint32_t dfiupd0;
+	uint32_t dfiupd1;
+	uint32_t dfiupd2;
+	uint32_t dfiphymstr;
+	uint32_t odtmap;
+	uint32_t dbg0;
+	uint32_t dbg1;
+	uint32_t dbgcmd;
+	uint32_t poisoncfg;
+	uint32_t pccfg;
+};
+
+struct stm32mp1_ddrctrl_timing {
+	uint32_t rfshtmg;
+	uint32_t dramtmg0;
+	uint32_t dramtmg1;
+	uint32_t dramtmg2;
+	uint32_t dramtmg3;
+	uint32_t dramtmg4;
+	uint32_t dramtmg5;
+	uint32_t dramtmg6;
+	uint32_t dramtmg7;
+	uint32_t dramtmg8;
+	uint32_t dramtmg14;
+	uint32_t odtcfg;
+};
+
+struct stm32mp1_ddrctrl_map {
+	uint32_t addrmap1;
+	uint32_t addrmap2;
+	uint32_t addrmap3;
+	uint32_t addrmap4;
+	uint32_t addrmap5;
+	uint32_t addrmap6;
+	uint32_t addrmap9;
+	uint32_t addrmap10;
+	uint32_t addrmap11;
+};
+
+struct stm32mp1_ddrctrl_perf {
+	uint32_t sched;
+	uint32_t sched1;
+	uint32_t perfhpr1;
+	uint32_t perflpr1;
+	uint32_t perfwr1;
+	uint32_t pcfgr_0;
+	uint32_t pcfgw_0;
+	uint32_t pcfgqos0_0;
+	uint32_t pcfgqos1_0;
+	uint32_t pcfgwqos0_0;
+	uint32_t pcfgwqos1_0;
+	uint32_t pcfgr_1;
+	uint32_t pcfgw_1;
+	uint32_t pcfgqos0_1;
+	uint32_t pcfgqos1_1;
+	uint32_t pcfgwqos0_1;
+	uint32_t pcfgwqos1_1;
+};
+
+struct stm32mp1_ddrphy_reg {
+	uint32_t pgcr;
+	uint32_t aciocr;
+	uint32_t dxccr;
+	uint32_t dsgcr;
+	uint32_t dcr;
+	uint32_t odtcr;
+	uint32_t zq0cr1;
+	uint32_t dx0gcr;
+	uint32_t dx1gcr;
+	uint32_t dx2gcr;
+	uint32_t dx3gcr;
+};
+
+struct stm32mp1_ddrphy_timing {
+	uint32_t ptr0;
+	uint32_t ptr1;
+	uint32_t ptr2;
+	uint32_t dtpr0;
+	uint32_t dtpr1;
+	uint32_t dtpr2;
+	uint32_t mr0;
+	uint32_t mr1;
+	uint32_t mr2;
+	uint32_t mr3;
+};
+
+struct stm32mp1_ddrphy_cal {
+	uint32_t dx0dllcr;
+	uint32_t dx0dqtr;
+	uint32_t dx0dqstr;
+	uint32_t dx1dllcr;
+	uint32_t dx1dqtr;
+	uint32_t dx1dqstr;
+	uint32_t dx2dllcr;
+	uint32_t dx2dqtr;
+	uint32_t dx2dqstr;
+	uint32_t dx3dllcr;
+	uint32_t dx3dqtr;
+	uint32_t dx3dqstr;
+};
+
+struct stm32mp1_ddr_info {
+	const char *name;
+	uint16_t speed; /* in MHZ */
+	uint32_t size;  /* Memory size in byte = col * row * width */
+};
+
+struct stm32mp1_ddr_config {
+	struct stm32mp1_ddr_info info;
+	struct stm32mp1_ddrctrl_reg c_reg;
+	struct stm32mp1_ddrctrl_timing c_timing;
+	struct stm32mp1_ddrctrl_map c_map;
+	struct stm32mp1_ddrctrl_perf c_perf;
+	struct stm32mp1_ddrphy_reg p_reg;
+	struct stm32mp1_ddrphy_timing p_timing;
+	struct stm32mp1_ddrphy_cal p_cal;
+};
+
+int stm32mp1_ddr_clk_enable(struct ddr_info *priv, uint16_t mem_speed);
+void stm32mp1_ddr_init(struct ddr_info *priv,
+		       struct stm32mp1_ddr_config *config);
+#endif /* _STM32MP1_DDR_H */
diff --git a/include/drivers/st/stm32mp1_ddr_helpers.h b/include/drivers/st/stm32mp1_ddr_helpers.h
new file mode 100644
index 0000000..298a080
--- /dev/null
+++ b/include/drivers/st/stm32mp1_ddr_helpers.h
@@ -0,0 +1,12 @@
+/*
+ * Copyright (c) 2017-2018, STMicroelectronics - All Rights Reserved
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef __STM32MP1_DDR_HELPERS_H__
+#define __STM32MP1_DDR_HELPERS_H__
+
+void ddr_enable_clock(void);
+
+#endif /* __STM32MP1_DDR_HELPERS_H__ */
diff --git a/include/drivers/st/stm32mp1_ddr_regs.h b/include/drivers/st/stm32mp1_ddr_regs.h
new file mode 100644
index 0000000..64ad965
--- /dev/null
+++ b/include/drivers/st/stm32mp1_ddr_regs.h
@@ -0,0 +1,413 @@
+/*
+ * Copyright (c) 2017-2018, STMicroelectronics - All Rights Reserved
+ *
+ * SPDX-License-Identifier: GPL-2.0+ OR BSD-3-Clause
+ */
+
+#ifndef _RAM_STM32MP1_DDR_REGS_H
+#define _RAM_STM32MP1_DDR_REGS_H
+
+#include <utils_def.h>
+
+/* DDR3/LPDDR2/LPDDR3 Controller (DDRCTRL) registers */
+struct stm32mp1_ddrctl {
+	uint32_t mstr ;		/* 0x0 Master */
+	uint32_t stat;		/* 0x4 Operating Mode Status */
+	uint8_t reserved008[0x10 - 0x8];
+	uint32_t mrctrl0;	/* 0x10 Control 0 */
+	uint32_t mrctrl1;	/* 0x14 Control 1 */
+	uint32_t mrstat;	/* 0x18 Status */
+	uint32_t reserved01c;	/* 0x1c */
+	uint32_t derateen;	/* 0x20 Temperature Derate Enable */
+	uint32_t derateint;	/* 0x24 Temperature Derate Interval */
+	uint8_t reserved028[0x30 - 0x28];
+	uint32_t pwrctl;	/* 0x30 Low Power Control */
+	uint32_t pwrtmg;	/* 0x34 Low Power Timing */
+	uint32_t hwlpctl;	/* 0x38 Hardware Low Power Control */
+	uint8_t reserved03c[0x50 - 0x3C];
+	uint32_t rfshctl0;	/* 0x50 Refresh Control 0 */
+	uint32_t reserved054;	/* 0x54 Refresh Control 1 */
+	uint32_t reserved058;	/* 0x58 Refresh Control 2 */
+	uint32_t reserved05C;
+	uint32_t rfshctl3;	/* 0x60 Refresh Control 0 */
+	uint32_t rfshtmg;	/* 0x64 Refresh Timing */
+	uint8_t reserved068[0xc0 - 0x68];
+	uint32_t crcparctl0;		/* 0xc0 CRC Parity Control0 */
+	uint32_t reserved0c4;	/* 0xc4 CRC Parity Control1 */
+	uint32_t reserved0c8;	/* 0xc8 CRC Parity Control2 */
+	uint32_t crcparstat;		/* 0xcc CRC Parity Status */
+	uint32_t init0;		/* 0xd0 SDRAM Initialization 0 */
+	uint32_t init1;		/* 0xd4 SDRAM Initialization 1 */
+	uint32_t init2;		/* 0xd8 SDRAM Initialization 2 */
+	uint32_t init3;		/* 0xdc SDRAM Initialization 3 */
+	uint32_t init4;		/* 0xe0 SDRAM Initialization 4 */
+	uint32_t init5;		/* 0xe4 SDRAM Initialization 5 */
+	uint32_t reserved0e8;
+	uint32_t reserved0ec;
+	uint32_t dimmctl;	/* 0xf0 DIMM Control */
+	uint8_t reserved0f4[0x100 - 0xf4];
+	uint32_t dramtmg0;	/* 0x100 SDRAM Timing 0 */
+	uint32_t dramtmg1;	/* 0x104 SDRAM Timing 1 */
+	uint32_t dramtmg2;	/* 0x108 SDRAM Timing 2 */
+	uint32_t dramtmg3;	/* 0x10c SDRAM Timing 3 */
+	uint32_t dramtmg4;	/* 0x110 SDRAM Timing 4 */
+	uint32_t dramtmg5;	/* 0x114 SDRAM Timing 5 */
+	uint32_t dramtmg6;	/* 0x118 SDRAM Timing 6 */
+	uint32_t dramtmg7;	/* 0x11c SDRAM Timing 7 */
+	uint32_t dramtmg8;	/* 0x120 SDRAM Timing 8 */
+	uint8_t reserved124[0x138 - 0x124];
+	uint32_t dramtmg14;	/* 0x138 SDRAM Timing 14 */
+	uint32_t dramtmg15;	/* 0x13C SDRAM Timing 15 */
+	uint8_t reserved140[0x180 - 0x140];
+	uint32_t zqctl0;	/* 0x180 ZQ Control 0 */
+	uint32_t zqctl1;	/* 0x184 ZQ Control 1 */
+	uint32_t zqctl2;	/* 0x188 ZQ Control 2 */
+	uint32_t zqstat;	/* 0x18c ZQ Status */
+	uint32_t dfitmg0;	/* 0x190 DFI Timing 0 */
+	uint32_t dfitmg1;	/* 0x194 DFI Timing 1 */
+	uint32_t dfilpcfg0;	/* 0x198 DFI Low Power Configuration 0 */
+	uint32_t reserved19c;
+	uint32_t dfiupd0;	/* 0x1a0 DFI Update 0 */
+	uint32_t dfiupd1;	/* 0x1a4 DFI Update 1 */
+	uint32_t dfiupd2;	/* 0x1a8 DFI Update 2 */
+	uint32_t reserved1ac;
+	uint32_t dfimisc;	/* 0x1b0 DFI Miscellaneous Control */
+	uint8_t reserved1b4[0x1bc - 0x1b4];
+	uint32_t dfistat;	/* 0x1bc DFI Miscellaneous Control */
+	uint8_t reserved1c0[0x1c4 - 0x1c0];
+	uint32_t dfiphymstr;	/* 0x1c4 DFI PHY Master interface */
+	uint8_t reserved1c8[0x204 - 0x1c8];
+	uint32_t addrmap1;	/* 0x204 Address Map 1 */
+	uint32_t addrmap2;	/* 0x208 Address Map 2 */
+	uint32_t addrmap3;	/* 0x20c Address Map 3 */
+	uint32_t addrmap4;	/* 0x210 Address Map 4 */
+	uint32_t addrmap5;	/* 0x214 Address Map 5 */
+	uint32_t addrmap6;	/* 0x218 Address Map 6 */
+	uint8_t reserved21c[0x224 - 0x21c];
+	uint32_t addrmap9;	/* 0x224 Address Map 9 */
+	uint32_t addrmap10;	/* 0x228 Address Map 10 */
+	uint32_t addrmap11;	/* 0x22C Address Map 11 */
+	uint8_t reserved230[0x240 - 0x230];
+	uint32_t odtcfg;	/* 0x240 ODT Configuration */
+	uint32_t odtmap;	/* 0x244 ODT/Rank Map */
+	uint8_t reserved248[0x250 - 0x248];
+	uint32_t sched;		/* 0x250 Scheduler Control */
+	uint32_t sched1;	/* 0x254 Scheduler Control 1 */
+	uint32_t reserved258;
+	uint32_t perfhpr1;	/* 0x25c High Priority Read CAM 1 */
+	uint32_t reserved260;
+	uint32_t perflpr1;	/* 0x264 Low Priority Read CAM 1 */
+	uint32_t reserved268;
+	uint32_t perfwr1;	/* 0x26c Write CAM 1 */
+	uint8_t reserved27c[0x300 - 0x270];
+	uint32_t dbg0;		/* 0x300 Debug 0 */
+	uint32_t dbg1;		/* 0x304 Debug 1 */
+	uint32_t dbgcam;	/* 0x308 CAM Debug */
+	uint32_t dbgcmd;	/* 0x30c Command Debug */
+	uint32_t dbgstat;	/* 0x310 Status Debug */
+	uint8_t reserved314[0x320 - 0x314];
+	uint32_t swctl;		/* 0x320 Software Programming Control Enable */
+	uint32_t swstat;	/* 0x324 Software Programming Control Status */
+	uint8_t reserved328[0x36c - 0x328];
+	uint32_t poisoncfg;	/* 0x36c AXI Poison Configuration Register */
+	uint32_t poisonstat;	/* 0x370 AXI Poison Status Register */
+	uint8_t reserved374[0x3fc - 0x374];
+
+	/* Multi Port registers */
+	uint32_t pstat;		/* 0x3fc Port Status */
+	uint32_t pccfg;		/* 0x400 Port Common Configuration */
+
+	/* PORT 0 */
+	uint32_t pcfgr_0;	/* 0x404 Configuration Read */
+	uint32_t pcfgw_0;	/* 0x408 Configuration Write */
+	uint8_t reserved40c[0x490 - 0x40c];
+	uint32_t pctrl_0;	/* 0x490 Port Control Register */
+	uint32_t pcfgqos0_0;	/* 0x494 Read QoS Configuration 0 */
+	uint32_t pcfgqos1_0;	/* 0x498 Read QoS Configuration 1 */
+	uint32_t pcfgwqos0_0;	/* 0x49c Write QoS Configuration 0 */
+	uint32_t pcfgwqos1_0;	/* 0x4a0 Write QoS Configuration 1 */
+	uint8_t reserved4a4[0x4b4 - 0x4a4];
+
+	/* PORT 1 */
+	uint32_t pcfgr_1;	/* 0x4b4 Configuration Read */
+	uint32_t pcfgw_1;	/* 0x4b8 Configuration Write */
+	uint8_t reserved4bc[0x540 - 0x4bc];
+	uint32_t pctrl_1;	/* 0x540 Port 2 Control Register */
+	uint32_t pcfgqos0_1;	/* 0x544 Read QoS Configuration 0 */
+	uint32_t pcfgqos1_1;	/* 0x548 Read QoS Configuration 1 */
+	uint32_t pcfgwqos0_1;	/* 0x54c Write QoS Configuration 0 */
+	uint32_t pcfgwqos1_1;	/* 0x550 Write QoS Configuration 1 */
+} __packed;
+
+/* DDR Physical Interface Control (DDRPHYC) registers*/
+struct stm32mp1_ddrphy {
+	uint32_t ridr;		/* 0x00 R Revision Identification */
+	uint32_t pir;		/* 0x04 R/W PHY Initialization */
+	uint32_t pgcr;		/* 0x08 R/W PHY General Configuration */
+	uint32_t pgsr;		/* 0x0C PHY General Status */
+	uint32_t dllgcr;	/* 0x10 R/W DLL General Control */
+	uint32_t acdllcr;	/* 0x14 R/W AC DLL Control */
+	uint32_t ptr0;		/* 0x18 R/W PHY Timing 0 */
+	uint32_t ptr1;		/* 0x1C R/W PHY Timing 1 */
+	uint32_t ptr2;		/* 0x20 R/W PHY Timing 2 */
+	uint32_t aciocr;	/* 0x24 AC I/O Configuration */
+	uint32_t dxccr;		/* 0x28 DATX8 Common Configuration */
+	uint32_t dsgcr;		/* 0x2C DDR System General Configuration */
+	uint32_t dcr;		/* 0x30 DRAM Configuration */
+	uint32_t dtpr0;		/* 0x34 DRAM Timing Parameters0 */
+	uint32_t dtpr1;		/* 0x38 DRAM Timing Parameters1 */
+	uint32_t dtpr2;		/* 0x3C DRAM Timing Parameters2 */
+	uint32_t mr0;		/* 0x40 Mode 0 */
+	uint32_t mr1;		/* 0x44 Mode 1 */
+	uint32_t mr2;		/* 0x48 Mode 2 */
+	uint32_t mr3;		/* 0x4C Mode 3 */
+	uint32_t odtcr;		/* 0x50 ODT Configuration */
+	uint32_t dtar;		/* 0x54 data training address */
+	uint32_t dtdr0;		/* 0x58 */
+	uint32_t dtdr1;		/* 0x5c */
+	uint8_t res1[0x0c0 - 0x060];	/* 0x60 */
+	uint32_t dcuar;		/* 0xc0 Address */
+	uint32_t dcudr;		/* 0xc4 DCU Data */
+	uint32_t dcurr;		/* 0xc8 DCU Run */
+	uint32_t dculr;		/* 0xcc DCU Loop */
+	uint32_t dcugcr;	/* 0xd0 DCU General Configuration */
+	uint32_t dcutpr;	/* 0xd4 DCU Timing Parameters */
+	uint32_t dcusr0;	/* 0xd8 DCU Status 0 */
+	uint32_t dcusr1;	/* 0xdc DCU Status 1 */
+	uint8_t res2[0x100 - 0xe0];	/* 0xe0 */
+	uint32_t bistrr;	/* 0x100 BIST Run */
+	uint32_t bistmskr0;	/* 0x104 BIST Mask 0 */
+	uint32_t bistmskr1;	/* 0x108 BIST Mask 0 */
+	uint32_t bistwcr;	/* 0x10c BIST Word Count */
+	uint32_t bistlsr;	/* 0x110 BIST LFSR Seed */
+	uint32_t bistar0;	/* 0x114 BIST Address 0 */
+	uint32_t bistar1;	/* 0x118 BIST Address 1 */
+	uint32_t bistar2;	/* 0x11c BIST Address 2 */
+	uint32_t bistupdr;	/* 0x120 BIST User Data Pattern */
+	uint32_t bistgsr;	/* 0x124 BIST General Status */
+	uint32_t bistwer;	/* 0x128 BIST Word Error */
+	uint32_t bistber0;	/* 0x12c BIST Bit Error 0 */
+	uint32_t bistber1;	/* 0x130 BIST Bit Error 1 */
+	uint32_t bistber2;	/* 0x134 BIST Bit Error 2 */
+	uint32_t bistwcsr;	/* 0x138 BIST Word Count Status */
+	uint32_t bistfwr0;	/* 0x13c BIST Fail Word 0 */
+	uint32_t bistfwr1;	/* 0x140 BIST Fail Word 1 */
+	uint8_t res3[0x178 - 0x144];	/* 0x144 */
+	uint32_t gpr0;		/* 0x178 General Purpose 0 (GPR0) */
+	uint32_t gpr1;		/* 0x17C General Purpose 1 (GPR1) */
+	uint32_t zq0cr0;	/* 0x180 zq 0 control 0 */
+	uint32_t zq0cr1;	/* 0x184 zq 0 control 1 */
+	uint32_t zq0sr0;	/* 0x188 zq 0 status 0 */
+	uint32_t zq0sr1;	/* 0x18C zq 0 status 1 */
+	uint8_t res4[0x1C0 - 0x190];	/* 0x190 */
+	uint32_t dx0gcr;	/* 0x1c0 Byte lane 0 General Configuration */
+	uint32_t dx0gsr0;	/* 0x1c4 Byte lane 0 General Status 0 */
+	uint32_t dx0gsr1;	/* 0x1c8 Byte lane 0 General Status 1 */
+	uint32_t dx0dllcr;	/* 0x1cc Byte lane 0 DLL Control */
+	uint32_t dx0dqtr;	/* 0x1d0 Byte lane 0 DQ Timing */
+	uint32_t dx0dqstr;	/* 0x1d4 Byte lane 0 DQS Timing */
+	uint8_t res5[0x200 - 0x1d8];	/* 0x1d8 */
+	uint32_t dx1gcr;	/* 0x200 Byte lane 1 General Configuration */
+	uint32_t dx1gsr0;	/* 0x204 Byte lane 1 General Status 0 */
+	uint32_t dx1gsr1;	/* 0x208 Byte lane 1 General Status 1 */
+	uint32_t dx1dllcr;	/* 0x20c Byte lane 1 DLL Control */
+	uint32_t dx1dqtr;	/* 0x210 Byte lane 1 DQ Timing */
+	uint32_t dx1dqstr;	/* 0x214 Byte lane 1 QS Timing */
+	uint8_t res6[0x240 - 0x218];	/* 0x218 */
+	uint32_t dx2gcr;	/* 0x240 Byte lane 2 General Configuration */
+	uint32_t dx2gsr0;	/* 0x244 Byte lane 2 General Status 0 */
+	uint32_t dx2gsr1;	/* 0x248 Byte lane 2 General Status 1 */
+	uint32_t dx2dllcr;	/* 0x24c Byte lane 2 DLL Control */
+	uint32_t dx2dqtr;	/* 0x250 Byte lane 2 DQ Timing */
+	uint32_t dx2dqstr;	/* 0x254 Byte lane 2 QS Timing */
+	uint8_t res7[0x280 - 0x258];	/* 0x258 */
+	uint32_t dx3gcr;	/* 0x280 Byte lane 3 General Configuration */
+	uint32_t dx3gsr0;	/* 0x284 Byte lane 3 General Status 0 */
+	uint32_t dx3gsr1;	/* 0x288 Byte lane 3 General Status 1 */
+	uint32_t dx3dllcr;	/* 0x28c Byte lane 3 DLL Control */
+	uint32_t dx3dqtr;	/* 0x290 Byte lane 3 DQ Timing */
+	uint32_t dx3dqstr;	/* 0x294 Byte lane 3 QS Timing */
+} __packed;
+
+/* DDR Controller registers offsets */
+#define DDRCTRL_MSTR				0x000
+#define DDRCTRL_STAT				0x004
+#define DDRCTRL_MRCTRL0				0x010
+#define DDRCTRL_MRSTAT				0x018
+#define DDRCTRL_PWRCTL				0x030
+#define DDRCTRL_PWRTMG				0x034
+#define DDRCTRL_HWLPCTL				0x038
+#define DDRCTRL_RFSHCTL3			0x060
+#define DDRCTRL_RFSHTMG				0x064
+#define DDRCTRL_INIT0				0x0D0
+#define DDRCTRL_DFIMISC				0x1B0
+#define DDRCTRL_DBG1				0x304
+#define DDRCTRL_DBGCAM				0x308
+#define DDRCTRL_DBGCMD				0x30C
+#define DDRCTRL_DBGSTAT				0x310
+#define DDRCTRL_SWCTL				0x320
+#define DDRCTRL_SWSTAT				0x324
+#define DDRCTRL_PCTRL_0				0x490
+#define DDRCTRL_PCTRL_1				0x540
+
+/* DDR Controller Register fields */
+#define DDRCTRL_MSTR_DDR3			BIT(0)
+#define DDRCTRL_MSTR_DATA_BUS_WIDTH_MASK	GENMASK(13, 12)
+#define DDRCTRL_MSTR_DATA_BUS_WIDTH_FULL	0
+#define DDRCTRL_MSTR_DATA_BUS_WIDTH_HALF	BIT(12)
+#define DDRCTRL_MSTR_DATA_BUS_WIDTH_QUARTER	BIT(13)
+#define DDRCTRL_MSTR_DLL_OFF_MODE		BIT(15)
+
+#define DDRCTRL_STAT_OPERATING_MODE_MASK	GENMASK(2, 0)
+#define DDRCTRL_STAT_OPERATING_MODE_NORMAL	BIT(0)
+#define DDRCTRL_STAT_OPERATING_MODE_SR		(BIT(0) | BIT(1))
+#define DDRCTRL_STAT_SELFREF_TYPE_MASK		GENMASK(5, 4)
+#define DDRCTRL_STAT_SELFREF_TYPE_ASR		(BIT(4) | BIT(5))
+#define DDRCTRL_STAT_SELFREF_TYPE_SR		BIT(5)
+
+#define DDRCTRL_MRCTRL0_MR_TYPE_WRITE		U(0)
+/* Only one rank supported */
+#define DDRCTRL_MRCTRL0_MR_RANK_SHIFT		4
+#define DDRCTRL_MRCTRL0_MR_RANK_ALL \
+		(0x1U << DDRCTRL_MRCTRL0_MR_RANK_SHIFT)
+#define DDRCTRL_MRCTRL0_MR_ADDR_SHIFT		12
+#define DDRCTRL_MRCTRL0_MR_ADDR_MASK		GENMASK(15, 12)
+#define DDRCTRL_MRCTRL0_MR_WR			BIT(31)
+
+#define DDRCTRL_MRSTAT_MR_WR_BUSY		BIT(0)
+
+#define DDRCTRL_PWRCTL_SELFREF_EN		BIT(0)
+#define DDRCTRL_PWRCTL_POWERDOWN_EN		BIT(1)
+#define DDRCTRL_PWRCTL_EN_DFI_DRAM_CLK_DISABLE	BIT(3)
+#define DDRCTRL_PWRCTL_SELFREF_SW		BIT(5)
+
+#define DDRCTRL_PWRTMG_SELFREF_TO_X32_MASK	GENMASK(19, 12)
+#define DDRCTRL_PWRTMG_SELFREF_TO_X32_0		BIT(16)
+
+#define DDRCTRL_RFSHCTL3_DIS_AUTO_REFRESH	BIT(0)
+
+#define DDRCTRL_HWLPCTL_HW_LP_EN		BIT(0)
+
+#define DDRCTRL_RFSHTMG_T_RFC_NOM_X1_X32_MASK	GENMASK(27, 16)
+#define DDRCTRL_RFSHTMG_T_RFC_NOM_X1_X32_SHIFT	16
+
+#define DDRCTRL_INIT0_SKIP_DRAM_INIT_MASK	GENMASK(31, 30)
+#define DDRCTRL_INIT0_SKIP_DRAM_INIT_NORMAL	BIT(30)
+
+#define DDRCTRL_DFIMISC_DFI_INIT_COMPLETE_EN	BIT(0)
+
+#define DDRCTRL_DBG1_DIS_HIF			BIT(1)
+
+#define DDRCTRL_DBGCAM_WR_DATA_PIPELINE_EMPTY	BIT(29)
+#define DDRCTRL_DBGCAM_RD_DATA_PIPELINE_EMPTY	BIT(28)
+#define DDRCTRL_DBGCAM_DBG_WR_Q_EMPTY		BIT(26)
+#define DDRCTRL_DBGCAM_DBG_LPR_Q_DEPTH		GENMASK(12, 8)
+#define DDRCTRL_DBGCAM_DBG_HPR_Q_DEPTH		GENMASK(4, 0)
+#define DDRCTRL_DBGCAM_DATA_PIPELINE_EMPTY \
+		(DDRCTRL_DBGCAM_WR_DATA_PIPELINE_EMPTY | \
+		 DDRCTRL_DBGCAM_RD_DATA_PIPELINE_EMPTY)
+#define DDRCTRL_DBGCAM_DBG_Q_DEPTH \
+		(DDRCTRL_DBGCAM_DBG_WR_Q_EMPTY | \
+		 DDRCTRL_DBGCAM_DBG_LPR_Q_DEPTH | \
+		 DDRCTRL_DBGCAM_DBG_HPR_Q_DEPTH)
+
+#define DDRCTRL_DBGCMD_RANK0_REFRESH		BIT(0)
+
+#define DDRCTRL_DBGSTAT_RANK0_REFRESH_BUSY	BIT(0)
+
+#define DDRCTRL_SWCTL_SW_DONE			BIT(0)
+
+#define DDRCTRL_SWSTAT_SW_DONE_ACK		BIT(0)
+
+#define DDRCTRL_PCTRL_N_PORT_EN			BIT(0)
+
+/* DDR PHY registers offsets */
+#define DDRPHYC_PIR				0x004
+#define DDRPHYC_PGCR				0x008
+#define DDRPHYC_PGSR				0x00C
+#define DDRPHYC_DLLGCR				0x010
+#define DDRPHYC_ACDLLCR				0x014
+#define DDRPHYC_PTR0				0x018
+#define DDRPHYC_ACIOCR				0x024
+#define DDRPHYC_DXCCR				0x028
+#define DDRPHYC_DSGCR				0x02C
+#define DDRPHYC_ZQ0CR0				0x180
+#define DDRPHYC_DX0GCR				0x1C0
+#define DDRPHYC_DX0DLLCR			0x1CC
+#define DDRPHYC_DX1GCR				0x200
+#define DDRPHYC_DX1DLLCR			0x20C
+#define DDRPHYC_DX2GCR				0x240
+#define DDRPHYC_DX2DLLCR			0x24C
+#define DDRPHYC_DX3GCR				0x280
+#define DDRPHYC_DX3DLLCR			0x28C
+
+/* DDR PHY Register fields */
+#define DDRPHYC_PIR_INIT			BIT(0)
+#define DDRPHYC_PIR_DLLSRST			BIT(1)
+#define DDRPHYC_PIR_DLLLOCK			BIT(2)
+#define DDRPHYC_PIR_ZCAL			BIT(3)
+#define DDRPHYC_PIR_ITMSRST			BIT(4)
+#define DDRPHYC_PIR_DRAMRST			BIT(5)
+#define DDRPHYC_PIR_DRAMINIT			BIT(6)
+#define DDRPHYC_PIR_QSTRN			BIT(7)
+#define DDRPHYC_PIR_ICPC			BIT(16)
+#define DDRPHYC_PIR_ZCALBYP			BIT(30)
+#define DDRPHYC_PIR_INITSTEPS_MASK		GENMASK(31, 7)
+
+#define DDRPHYC_PGCR_DFTCMP			BIT(2)
+#define DDRPHYC_PGCR_PDDISDX			BIT(24)
+#define DDRPHYC_PGCR_RFSHDT_MASK		GENMASK(28, 25)
+
+#define DDRPHYC_PGSR_IDONE			BIT(0)
+#define DDRPHYC_PGSR_DTERR			BIT(5)
+#define DDRPHYC_PGSR_DTIERR			BIT(6)
+#define DDRPHYC_PGSR_DFTERR			BIT(7)
+#define DDRPHYC_PGSR_RVERR			BIT(8)
+#define DDRPHYC_PGSR_RVEIRR			BIT(9)
+
+#define DDRPHYC_DLLGCR_BPS200			BIT(23)
+
+#define DDRPHYC_ACDLLCR_DLLDIS			BIT(31)
+
+#define DDRPHYC_PTR0_TDLLSRST_OFFSET		0
+#define DDRPHYC_PTR0_TDLLSRST_MASK		GENMASK(5, 0)
+#define DDRPHYC_PTR0_TDLLLOCK_OFFSET		6
+#define DDRPHYC_PTR0_TDLLLOCK_MASK		GENMASK(17, 6)
+#define DDRPHYC_PTR0_TITMSRST_OFFSET		18
+#define DDRPHYC_PTR0_TITMSRST_MASK		GENMASK(21, 18)
+
+#define DDRPHYC_ACIOCR_ACPDD			BIT(3)
+#define DDRPHYC_ACIOCR_ACPDR			BIT(4)
+#define DDRPHYC_ACIOCR_CKPDD_MASK		GENMASK(10, 8)
+#define DDRPHYC_ACIOCR_CKPDD_0			BIT(8)
+#define DDRPHYC_ACIOCR_CKPDR_MASK		GENMASK(13, 11)
+#define DDRPHYC_ACIOCR_CKPDR_0			BIT(11)
+#define DDRPHYC_ACIOCR_CSPDD_MASK		GENMASK(21, 18)
+#define DDRPHYC_ACIOCR_CSPDD_0			BIT(18)
+#define DDRPHYC_ACIOCR_RSTPDD			BIT(27)
+#define DDRPHYC_ACIOCR_RSTPDR			BIT(28)
+
+#define DDRPHYC_DXCCR_DXPDD			BIT(2)
+#define DDRPHYC_DXCCR_DXPDR			BIT(3)
+
+#define DDRPHYC_DSGCR_CKEPDD_MASK		GENMASK(19, 16)
+#define DDRPHYC_DSGCR_CKEPDD_0			BIT(16)
+#define DDRPHYC_DSGCR_ODTPDD_MASK		GENMASK(23, 20)
+#define DDRPHYC_DSGCR_ODTPDD_0			BIT(20)
+#define DDRPHYC_DSGCR_NL2PD			BIT(24)
+
+#define DDRPHYC_ZQ0CRN_ZDATA_MASK		GENMASK(27, 0)
+#define DDRPHYC_ZQ0CRN_ZDATA_SHIFT		0
+#define DDRPHYC_ZQ0CRN_ZDEN			BIT(28)
+#define DDRPHYC_ZQ0CRN_ZQPD			BIT(31)
+
+#define DDRPHYC_DXNGCR_DXEN			BIT(0)
+
+#define DDRPHYC_DXNDLLCR_DLLSRST		BIT(30)
+#define DDRPHYC_DXNDLLCR_DLLDIS			BIT(31)
+#define DDRPHYC_DXNDLLCR_SDPHASE_MASK		GENMASK(17, 14)
+#define DDRPHYC_DXNDLLCR_SDPHASE_SHIFT		14
+
+void ddr_enable_clock(void);
+
+#endif /* _RAM_STM32MP1_DDR_REGS_H */
diff --git a/include/drivers/st/stm32mp1_pmic.h b/include/drivers/st/stm32mp1_pmic.h
new file mode 100644
index 0000000..5d94b40
--- /dev/null
+++ b/include/drivers/st/stm32mp1_pmic.h
@@ -0,0 +1,18 @@
+/*
+ * Copyright (c) 2017-2018, STMicroelectronics - All Rights Reserved
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef __STM32MP1_PMIC_H__
+#define __STM32MP1_PMIC_H__
+
+#include <stdbool.h>
+
+bool dt_check_pmic(void);
+int dt_pmic_enable_boot_on_regulators(void);
+void initialize_pmic_i2c(void);
+void initialize_pmic(void);
+int pmic_ddr_power_init(enum ddr_type ddr_type);
+
+#endif /* __STM32MP1_PMIC_H__ */
diff --git a/include/drivers/st/stm32mp1_pwr.h b/include/drivers/st/stm32mp1_pwr.h
new file mode 100644
index 0000000..e567042
--- /dev/null
+++ b/include/drivers/st/stm32mp1_pwr.h
@@ -0,0 +1,32 @@
+/*
+ * Copyright (c) 2017-2018, STMicroelectronics - All Rights Reserved
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef __STM32MP1_PWR_H__
+#define __STM32MP1_PWR_H__
+
+#include <utils_def.h>
+
+#define PWR_CR1			U(0x00)
+#define PWR_CR2			U(0x08)
+#define PWR_CR3			U(0x0C)
+#define PWR_MPUCR		U(0x10)
+#define PWR_WKUPCR		U(0x20)
+#define PWR_MPUWKUPENR		U(0x28)
+
+#define PWR_CR1_LPDS		BIT(0)
+#define PWR_CR1_LPCFG		BIT(1)
+#define PWR_CR1_LVDS		BIT(2)
+#define PWR_CR1_DBP		BIT(8)
+
+#define PWR_CR3_DDRSREN		BIT(10)
+#define PWR_CR3_DDRSRDIS	BIT(11)
+#define PWR_CR3_DDRRETEN	BIT(12)
+
+#define PWR_MPUCR_PDDS		BIT(0)
+#define PWR_MPUCR_CSTDBYDIS	BIT(3)
+#define PWR_MPUCR_CSSF		BIT(9)
+
+#endif /* __STM32MP1_PWR_H__ */
diff --git a/include/drivers/st/stm32mp1_ram.h b/include/drivers/st/stm32mp1_ram.h
new file mode 100644
index 0000000..af96177
--- /dev/null
+++ b/include/drivers/st/stm32mp1_ram.h
@@ -0,0 +1,12 @@
+/*
+ * Copyright (c) 2015-2018, STMicroelectronics - All Rights Reserved
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef _STM32MP1_RAM_H
+#define _STM32MP1_RAM_H
+
+int stm32mp1_ddr_probe(void);
+
+#endif /* _STM32MP1_RAM_H */
diff --git a/include/drivers/st/stm32mp1_rcc.h b/include/drivers/st/stm32mp1_rcc.h
new file mode 100644
index 0000000..e28ca97
--- /dev/null
+++ b/include/drivers/st/stm32mp1_rcc.h
@@ -0,0 +1,368 @@
+/*
+ * Copyright (c) 2015-2018, STMicroelectronics - All Rights Reserved
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef __STM32MP1_RCC_H__
+#define __STM32MP1_RCC_H__
+
+#include <utils_def.h>
+
+#define RCC_TZCR			U(0x00)
+#define RCC_OCENSETR			U(0x0C)
+#define RCC_OCENCLRR			U(0x10)
+#define RCC_HSICFGR			U(0x18)
+#define RCC_CSICFGR			U(0x1C)
+#define RCC_MPCKSELR			U(0x20)
+#define RCC_ASSCKSELR			U(0x24)
+#define RCC_RCK12SELR			U(0x28)
+#define RCC_MPCKDIVR			U(0x2C)
+#define RCC_AXIDIVR			U(0x30)
+#define RCC_APB4DIVR			U(0x3C)
+#define RCC_APB5DIVR			U(0x40)
+#define RCC_RTCDIVR			U(0x44)
+#define RCC_MSSCKSELR			U(0x48)
+#define RCC_PLL1CR			U(0x80)
+#define RCC_PLL1CFGR1			U(0x84)
+#define RCC_PLL1CFGR2			U(0x88)
+#define RCC_PLL1FRACR			U(0x8C)
+#define RCC_PLL1CSGR			U(0x90)
+#define RCC_PLL2CR			U(0x94)
+#define RCC_PLL2CFGR1			U(0x98)
+#define RCC_PLL2CFGR2			U(0x9C)
+#define RCC_PLL2FRACR			U(0xA0)
+#define RCC_PLL2CSGR			U(0xA4)
+#define RCC_I2C46CKSELR			U(0xC0)
+#define RCC_SPI6CKSELR			U(0xC4)
+#define RCC_UART1CKSELR			U(0xC8)
+#define RCC_RNG1CKSELR			U(0xCC)
+#define RCC_CPERCKSELR			U(0xD0)
+#define RCC_STGENCKSELR			U(0xD4)
+#define RCC_DDRITFCR			U(0xD8)
+#define RCC_MP_BOOTCR			U(0x100)
+#define RCC_MP_SREQSETR			U(0x104)
+#define RCC_MP_SREQCLRR			U(0x108)
+#define RCC_MP_GCR			U(0x10C)
+#define RCC_MP_APRSTCR			U(0x110)
+#define RCC_MP_APRSTSR			U(0x114)
+#define RCC_BDCR			U(0x140)
+#define RCC_RDLSICR			U(0x144)
+#define RCC_APB4RSTSETR			U(0x180)
+#define RCC_APB4RSTCLRR			U(0x184)
+#define RCC_APB5RSTSETR			U(0x188)
+#define RCC_APB5RSTCLRR			U(0x18C)
+#define RCC_AHB5RSTSETR			U(0x190)
+#define RCC_AHB5RSTCLRR			U(0x194)
+#define RCC_AHB6RSTSETR			U(0x198)
+#define RCC_AHB6RSTCLRR			U(0x19C)
+#define RCC_TZAHB6RSTSETR		U(0x1A0)
+#define RCC_TZAHB6RSTCLRR		U(0x1A4)
+#define RCC_MP_APB4ENSETR		U(0x200)
+#define RCC_MP_APB4ENCLRR		U(0x204)
+#define RCC_MP_APB5ENSETR		U(0x208)
+#define RCC_MP_APB5ENCLRR		U(0x20C)
+#define RCC_MP_AHB5ENSETR		U(0x210)
+#define RCC_MP_AHB5ENCLRR		U(0x214)
+#define RCC_MP_AHB6ENSETR		U(0x218)
+#define RCC_MP_AHB6ENCLRR		U(0x21C)
+#define RCC_MP_TZAHB6ENSETR		U(0x220)
+#define RCC_MP_TZAHB6ENCLRR		U(0x224)
+#define RCC_MP_APB4LPENSETR		U(0x300)
+#define RCC_MP_APB4LPENCLRR		U(0x304)
+#define RCC_MP_APB5LPENSETR		U(0x308)
+#define RCC_MP_APB5LPENCLRR		U(0x30C)
+#define RCC_MP_AHB5LPENSETR		U(0x310)
+#define RCC_MP_AHB5LPENCLRR		U(0x314)
+#define RCC_MP_AHB6LPENSETR		U(0x318)
+#define RCC_MP_AHB6LPENCLRR		U(0x31C)
+#define RCC_MP_TZAHB6LPENSETR		U(0x320)
+#define RCC_MP_TZAHB6LPENCLRR		U(0x324)
+#define RCC_BR_RSTSCLRR			U(0x400)
+#define RCC_MP_GRSTCSETR		U(0x404)
+#define RCC_MP_RSTSCLRR			U(0x408)
+#define RCC_MP_IWDGFZSETR		U(0x40C)
+#define RCC_MP_IWDGFZCLRR		U(0x410)
+#define RCC_MP_CIER			U(0x414)
+#define RCC_MP_CIFR			U(0x418)
+#define RCC_PWRLPDLYCR			U(0x41C)
+#define RCC_MP_RSTSSETR			U(0x420)
+#define RCC_MCO1CFGR			U(0x800)
+#define RCC_MCO2CFGR			U(0x804)
+#define RCC_OCRDYR			U(0x808)
+#define RCC_DBGCFGR			U(0x80C)
+#define RCC_RCK3SELR			U(0x820)
+#define RCC_RCK4SELR			U(0x824)
+#define RCC_TIMG1PRER			U(0x828)
+#define RCC_TIMG2PRER			U(0x82C)
+#define RCC_APB1DIVR			U(0x834)
+#define RCC_APB2DIVR			U(0x838)
+#define RCC_APB3DIVR			U(0x83C)
+#define RCC_PLL3CR			U(0x880)
+#define RCC_PLL3CFGR1			U(0x884)
+#define RCC_PLL3CFGR2			U(0x888)
+#define RCC_PLL3FRACR			U(0x88C)
+#define RCC_PLL3CSGR			U(0x890)
+#define RCC_PLL4CR			U(0x894)
+#define RCC_PLL4CFGR1			U(0x898)
+#define RCC_PLL4CFGR2			U(0x89C)
+#define RCC_PLL4FRACR			U(0x8A0)
+#define RCC_PLL4CSGR			U(0x8A4)
+#define RCC_I2C12CKSELR			U(0x8C0)
+#define RCC_I2C35CKSELR			U(0x8C4)
+#define RCC_SAI1CKSELR			U(0x8C8)
+#define RCC_SAI2CKSELR			U(0x8CC)
+#define RCC_SAI3CKSELR			U(0x8D0)
+#define RCC_SAI4CKSELR			U(0x8D4)
+#define RCC_SPI2S1CKSELR		U(0x8D8)
+#define RCC_SPI2S23CKSELR		U(0x8DC)
+#define RCC_SPI45CKSELR			U(0x8E0)
+#define RCC_UART6CKSELR			U(0x8E4)
+#define RCC_UART24CKSELR		U(0x8E8)
+#define RCC_UART35CKSELR		U(0x8EC)
+#define RCC_UART78CKSELR		U(0x8F0)
+#define RCC_SDMMC12CKSELR		U(0x8F4)
+#define RCC_SDMMC3CKSELR		U(0x8F8)
+#define RCC_ETHCKSELR			U(0x8FC)
+#define RCC_QSPICKSELR			U(0x900)
+#define RCC_FMCCKSELR			U(0x904)
+#define RCC_FDCANCKSELR			U(0x90C)
+#define RCC_SPDIFCKSELR			U(0x914)
+#define RCC_CECCKSELR			U(0x918)
+#define RCC_USBCKSELR			U(0x91C)
+#define RCC_RNG2CKSELR			U(0x920)
+#define RCC_DSICKSELR			U(0x924)
+#define RCC_ADCCKSELR			U(0x928)
+#define RCC_LPTIM45CKSELR		U(0x92C)
+#define RCC_LPTIM23CKSELR		U(0x930)
+#define RCC_LPTIM1CKSELR		U(0x934)
+#define RCC_APB1RSTSETR			U(0x980)
+#define RCC_APB1RSTCLRR			U(0x984)
+#define RCC_APB2RSTSETR			U(0x988)
+#define RCC_APB2RSTCLRR			U(0x98C)
+#define RCC_APB3RSTSETR			U(0x990)
+#define RCC_APB3RSTCLRR			U(0x994)
+#define RCC_AHB2RSTSETR			U(0x998)
+#define RCC_AHB2RSTCLRR			U(0x99C)
+#define RCC_AHB3RSTSETR			U(0x9A0)
+#define RCC_AHB3RSTCLRR			U(0x9A4)
+#define RCC_AHB4RSTSETR			U(0x9A8)
+#define RCC_AHB4RSTCLRR			U(0x9AC)
+#define RCC_MP_APB1ENSETR		U(0xA00)
+#define RCC_MP_APB1ENCLRR		U(0xA04)
+#define RCC_MP_APB2ENSETR		U(0xA08)
+#define RCC_MP_APB2ENCLRR		U(0xA0C)
+#define RCC_MP_APB3ENSETR		U(0xA10)
+#define RCC_MP_APB3ENCLRR		U(0xA14)
+#define RCC_MP_AHB2ENSETR		U(0xA18)
+#define RCC_MP_AHB2ENCLRR		U(0xA1C)
+#define RCC_MP_AHB3ENSETR		U(0xA20)
+#define RCC_MP_AHB3ENCLRR		U(0xA24)
+#define RCC_MP_AHB4ENSETR		U(0xA28)
+#define RCC_MP_AHB4ENCLRR		U(0xA2C)
+#define RCC_MP_MLAHBENSETR		U(0xA38)
+#define RCC_MP_MLAHBENCLRR		U(0xA3C)
+#define RCC_MP_APB1LPENSETR		U(0xB00)
+#define RCC_MP_APB1LPENCLRR		U(0xB04)
+#define RCC_MP_APB2LPENSETR		U(0xB08)
+#define RCC_MP_APB2LPENCLRR		U(0xB0C)
+#define RCC_MP_APB3LPENSETR		U(0xB10)
+#define RCC_MP_APB3LPENCLRR		U(0xB14)
+#define RCC_MP_AHB2LPENSETR		U(0xB18)
+#define RCC_MP_AHB2LPENCLRR		U(0xB1C)
+#define RCC_MP_AHB3LPENSETR		U(0xB20)
+#define RCC_MP_AHB3LPENCLRR		U(0xB24)
+#define RCC_MP_AHB4LPENSETR		U(0xB28)
+#define RCC_MP_AHB4LPENCLRR		U(0xB2C)
+#define RCC_MP_AXIMLPENSETR		U(0xB30)
+#define RCC_MP_AXIMLPENCLRR		U(0xB34)
+#define RCC_MP_MLAHBLPENSETR		U(0xB38)
+#define RCC_MP_MLAHBLPENCLRR		U(0xB3C)
+#define RCC_VERR			U(0xFF4)
+#define RCC_IDR				U(0xFF8)
+#define RCC_SIDR			U(0xFFC)
+
+/* Values for RCC_TZCR register */
+#define RCC_TZCR_TZEN			BIT(0)
+
+/* Used for most of RCC_<x>SELR registers */
+#define RCC_SELR_SRC_MASK		GENMASK(2, 0)
+#define RCC_SELR_REFCLK_SRC_MASK	GENMASK(1, 0)
+#define RCC_SELR_SRCRDY			BIT(31)
+
+/* Values of RCC_MPCKSELR register */
+#define RCC_MPCKSELR_HSI		0x00000000
+#define RCC_MPCKSELR_HSE		0x00000001
+#define RCC_MPCKSELR_PLL		0x00000002
+#define RCC_MPCKSELR_PLL_MPUDIV		0x00000003
+
+/* Values of RCC_ASSCKSELR register */
+#define RCC_ASSCKSELR_HSI		0x00000000
+#define RCC_ASSCKSELR_HSE		0x00000001
+#define RCC_ASSCKSELR_PLL		0x00000002
+
+/* Values of RCC_MSSCKSELR register */
+#define RCC_MSSCKSELR_HSI		0x00000000
+#define RCC_MSSCKSELR_HSE		0x00000001
+#define RCC_MSSCKSELR_CSI		0x00000002
+#define RCC_MSSCKSELR_PLL		0x00000003
+
+/* Values of RCC_CPERCKSELR register */
+#define RCC_CPERCKSELR_HSI		0x00000000
+#define RCC_CPERCKSELR_CSI		0x00000001
+#define RCC_CPERCKSELR_HSE		0x00000002
+
+/* Used for most of DIVR register: max div for RTC */
+#define RCC_DIVR_DIV_MASK		GENMASK(5, 0)
+#define RCC_DIVR_DIVRDY			BIT(31)
+
+/* Masks for specific DIVR registers */
+#define RCC_APBXDIV_MASK		GENMASK(2, 0)
+#define RCC_MPUDIV_MASK			GENMASK(2, 0)
+#define RCC_AXIDIV_MASK			GENMASK(2, 0)
+
+/* Offset between RCC_MP_xxxENSETR and RCC_MP_xxxENCLRR registers */
+#define RCC_MP_ENCLRR_OFFSET		U(4)
+
+/* Fields of RCC_BDCR register */
+#define RCC_BDCR_LSEON			BIT(0)
+#define RCC_BDCR_LSEBYP			BIT(1)
+#define RCC_BDCR_LSERDY			BIT(2)
+#define RCC_BDCR_LSEDRV_MASK		GENMASK(5, 4)
+#define RCC_BDCR_LSEDRV_SHIFT		4
+#define RCC_BDCR_LSECSSON		BIT(8)
+#define RCC_BDCR_RTCCKEN		BIT(20)
+#define RCC_BDCR_RTCSRC_MASK		GENMASK(17, 16)
+#define RCC_BDCR_RTCSRC_SHIFT		16
+#define RCC_BDCR_VSWRST			BIT(31)
+
+/* Fields of RCC_RDLSICR register */
+#define RCC_RDLSICR_LSION		BIT(0)
+#define RCC_RDLSICR_LSIRDY		BIT(1)
+
+/* Used for all RCC_PLL<n>CR registers */
+#define RCC_PLLNCR_PLLON		BIT(0)
+#define RCC_PLLNCR_PLLRDY		BIT(1)
+#define RCC_PLLNCR_DIVPEN		BIT(4)
+#define RCC_PLLNCR_DIVQEN		BIT(5)
+#define RCC_PLLNCR_DIVREN		BIT(6)
+#define RCC_PLLNCR_DIVEN_SHIFT		4
+
+/* Used for all RCC_PLL<n>CFGR1 registers */
+#define RCC_PLLNCFGR1_DIVM_SHIFT	16
+#define RCC_PLLNCFGR1_DIVM_MASK		GENMASK(21, 16)
+#define RCC_PLLNCFGR1_DIVN_SHIFT	0
+#define RCC_PLLNCFGR1_DIVN_MASK		GENMASK(8, 0)
+/* Only for PLL3 and PLL4 */
+#define RCC_PLLNCFGR1_IFRGE_SHIFT	24
+#define RCC_PLLNCFGR1_IFRGE_MASK	GENMASK(25, 24)
+
+/* Used for all RCC_PLL<n>CFGR2 registers */
+#define RCC_PLLNCFGR2_DIVX_MASK		GENMASK(6, 0)
+#define RCC_PLLNCFGR2_DIVP_SHIFT	0
+#define RCC_PLLNCFGR2_DIVP_MASK		GENMASK(6, 0)
+#define RCC_PLLNCFGR2_DIVQ_SHIFT	8
+#define RCC_PLLNCFGR2_DIVQ_MASK		GENMASK(14, 8)
+#define RCC_PLLNCFGR2_DIVR_SHIFT	16
+#define RCC_PLLNCFGR2_DIVR_MASK		GENMASK(22, 16)
+
+/* Used for all RCC_PLL<n>FRACR registers */
+#define RCC_PLLNFRACR_FRACV_SHIFT	3
+#define RCC_PLLNFRACR_FRACV_MASK	GENMASK(15, 3)
+#define RCC_PLLNFRACR_FRACLE		BIT(16)
+
+/* Used for all RCC_PLL<n>CSGR registers */
+#define RCC_PLLNCSGR_INC_STEP_SHIFT	16
+#define RCC_PLLNCSGR_INC_STEP_MASK	GENMASK(30, 16)
+#define RCC_PLLNCSGR_MOD_PER_SHIFT	0
+#define RCC_PLLNCSGR_MOD_PER_MASK	GENMASK(12, 0)
+#define RCC_PLLNCSGR_SSCG_MODE_SHIFT	15
+#define RCC_PLLNCSGR_SSCG_MODE_MASK	BIT(15)
+
+/* Used for RCC_OCENSETR and RCC_OCENCLRR registers */
+#define RCC_OCENR_HSION			BIT(0)
+#define RCC_OCENR_CSION			BIT(4)
+#define RCC_OCENR_HSEON			BIT(8)
+#define RCC_OCENR_HSEBYP		BIT(10)
+#define RCC_OCENR_HSECSSON		BIT(11)
+
+/* Fields of RCC_OCRDYR register */
+#define RCC_OCRDYR_HSIRDY		BIT(0)
+#define RCC_OCRDYR_HSIDIVRDY		BIT(2)
+#define RCC_OCRDYR_CSIRDY		BIT(4)
+#define RCC_OCRDYR_HSERDY		BIT(8)
+
+/* Fields of RCC_DDRITFCR register */
+#define RCC_DDRITFCR_DDRC1EN		BIT(0)
+#define RCC_DDRITFCR_DDRC1LPEN		BIT(1)
+#define RCC_DDRITFCR_DDRC2EN		BIT(2)
+#define RCC_DDRITFCR_DDRC2LPEN		BIT(3)
+#define RCC_DDRITFCR_DDRPHYCEN		BIT(4)
+#define RCC_DDRITFCR_DDRPHYCLPEN	BIT(5)
+#define RCC_DDRITFCR_DDRCAPBEN		BIT(6)
+#define RCC_DDRITFCR_DDRCAPBLPEN	BIT(7)
+#define RCC_DDRITFCR_AXIDCGEN		BIT(8)
+#define RCC_DDRITFCR_DDRPHYCAPBEN	BIT(9)
+#define RCC_DDRITFCR_DDRPHYCAPBLPEN	BIT(10)
+#define RCC_DDRITFCR_DDRCAPBRST		BIT(14)
+#define RCC_DDRITFCR_DDRCAXIRST		BIT(15)
+#define RCC_DDRITFCR_DDRCORERST		BIT(16)
+#define RCC_DDRITFCR_DPHYAPBRST		BIT(17)
+#define RCC_DDRITFCR_DPHYRST		BIT(18)
+#define RCC_DDRITFCR_DPHYCTLRST		BIT(19)
+#define RCC_DDRITFCR_DDRCKMOD_MASK	GENMASK(22, 20)
+#define RCC_DDRITFCR_DDRCKMOD_SHIFT	20
+#define RCC_DDRITFCR_DDRCKMOD_SSR	0
+#define RCC_DDRITFCR_DDRCKMOD_ASR1	BIT(20)
+#define RCC_DDRITFCR_DDRCKMOD_HSR1	BIT(21)
+#define RCC_DDRITFCR_GSKPCTRL		BIT(24)
+
+/* Fields of RCC_HSICFGR register */
+#define RCC_HSICFGR_HSIDIV_MASK		GENMASK(1, 0)
+
+/* Used for RCC_MCO related operations */
+#define RCC_MCOCFG_MCOON		BIT(12)
+#define RCC_MCOCFG_MCODIV_MASK		GENMASK(7, 4)
+#define RCC_MCOCFG_MCODIV_SHIFT		4
+#define RCC_MCOCFG_MCOSRC_MASK		GENMASK(2, 0)
+
+/* Fields of RCC_DBGCFGR register */
+#define RCC_DBGCFGR_DBGCKEN		BIT(8)
+
+/* RCC register fields for reset reasons */
+#define  RCC_MP_RSTSCLRR_PORRSTF	BIT(0)
+#define  RCC_MP_RSTSCLRR_BORRSTF	BIT(1)
+#define  RCC_MP_RSTSCLRR_PADRSTF	BIT(2)
+#define  RCC_MP_RSTSCLRR_HCSSRSTF	BIT(3)
+#define  RCC_MP_RSTSCLRR_VCORERSTF	BIT(4)
+#define  RCC_MP_RSTSCLRR_MPSYSRSTF	BIT(6)
+#define  RCC_MP_RSTSCLRR_IWDG1RSTF	BIT(8)
+#define  RCC_MP_RSTSCLRR_IWDG2RSTF	BIT(9)
+#define  RCC_MP_RSTSCLRR_STDBYRSTF	BIT(11)
+#define  RCC_MP_RSTSCLRR_CSTDBYRSTF	BIT(12)
+
+/* Global Reset Register */
+#define RCC_MP_GRSTCSETR_MPSYSRST	BIT(0)
+
+/* Clock Source Interrupt Flag Register */
+#define RCC_MP_CIFR_MASK		U(0x110F1F)
+#define RCC_MP_CIFR_WKUPF		BIT(20)
+
+/* Stop Request Set Register */
+#define RCC_MP_SREQSETR_STPREQ_P0	BIT(0)
+#define RCC_MP_SREQSETR_STPREQ_P1	BIT(1)
+
+/* Stop Request Clear Register */
+#define RCC_MP_SREQCLRR_STPREQ_P0	BIT(0)
+#define RCC_MP_SREQCLRR_STPREQ_P1	BIT(1)
+
+/* Values of RCC_UART24CKSELR register */
+#define RCC_UART24CKSELR_HSI		0x00000002
+
+/* Values of RCC_MP_APB1ENSETR register */
+#define RCC_MP_APB1ENSETR_UART4EN	BIT(16)
+
+/* Values of RCC_MP_AHB4ENSETR register */
+#define RCC_MP_AHB4ENSETR_GPIOGEN	BIT(6)
+
+#endif /* __STM32MP1_RCC_H__ */
diff --git a/include/drivers/st/stm32mp1_reset.h b/include/drivers/st/stm32mp1_reset.h
new file mode 100644
index 0000000..76ee09d
--- /dev/null
+++ b/include/drivers/st/stm32mp1_reset.h
@@ -0,0 +1,15 @@
+/*
+ * Copyright (c) 2018, STMicroelectronics - All Rights Reserved
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef __STM32MP1_RESET_H__
+#define __STM32MP1_RESET_H__
+
+#include <stdint.h>
+
+void stm32mp1_reset_assert(uint32_t reset_id);
+void stm32mp1_reset_deassert(uint32_t reset_id);
+
+#endif /* __STM32MP1_RESET_H__ */
diff --git a/include/drivers/st/stpmu1.h b/include/drivers/st/stpmu1.h
new file mode 100644
index 0000000..1b93ab2
--- /dev/null
+++ b/include/drivers/st/stpmu1.h
@@ -0,0 +1,141 @@
+/*
+ * Copyright (c) 2016-2018, STMicroelectronics - All Rights Reserved
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+
+#ifndef __STPMU1_H__
+#define __STPMU1_H__
+
+#include <stm32_i2c.h>
+#include <utils_def.h>
+
+#define TURN_ON_REG			0x1U
+#define TURN_OFF_REG			0x2U
+#define ICC_LDO_TURN_OFF_REG		0x3U
+#define ICC_BUCK_TURN_OFF_REG		0x4U
+#define RESET_STATUS_REG		0x5U
+#define VERSION_STATUS_REG		0x6U
+#define MAIN_CONTROL_REG		0x10U
+#define PADS_PULL_REG			0x11U
+#define BUCK_PULL_DOWN_REG		0x12U
+#define LDO14_PULL_DOWN_REG		0x13U
+#define LDO56_PULL_DOWN_REG		0x14U
+#define VIN_CONTROL_REG			0x15U
+#define PONKEY_TIMER_REG		0x16U
+#define MASK_RANK_BUCK_REG		0x17U
+#define MASK_RESET_BUCK_REG		0x18U
+#define MASK_RANK_LDO_REG		0x19U
+#define MASK_RESET_LDO_REG		0x1AU
+#define WATCHDOG_CONTROL_REG		0x1BU
+#define WATCHDOG_TIMER_REG		0x1CU
+#define BUCK_ICC_TURNOFF_REG		0x1DU
+#define LDO_ICC_TURNOFF_REG		0x1EU
+#define BUCK_APM_CONTROL_REG		0x1FU
+#define BUCK1_CONTROL_REG		0x20U
+#define BUCK2_CONTROL_REG		0x21U
+#define BUCK3_CONTROL_REG		0x22U
+#define BUCK4_CONTROL_REG		0x23U
+#define VREF_DDR_CONTROL_REG		0x24U
+#define LDO1_CONTROL_REG		0x25U
+#define LDO2_CONTROL_REG		0x26U
+#define LDO3_CONTROL_REG		0x27U
+#define LDO4_CONTROL_REG		0x28U
+#define LDO5_CONTROL_REG		0x29U
+#define LDO6_CONTROL_REG		0x2AU
+#define BUCK1_PWRCTRL_REG		0x30U
+#define BUCK2_PWRCTRL_REG		0x31U
+#define BUCK3_PWRCTRL_REG		0x32U
+#define BUCK4_PWRCTRL_REG		0x33U
+#define VREF_DDR_PWRCTRL_REG		0x34U
+#define LDO1_PWRCTRL_REG		0x35U
+#define LDO2_PWRCTRL_REG		0x36U
+#define LDO3_PWRCTRL_REG		0x37U
+#define LDO4_PWRCTRL_REG		0x38U
+#define LDO5_PWRCTRL_REG		0x39U
+#define LDO6_PWRCTRL_REG		0x3AU
+#define FREQUENCY_SPREADING_REG		0x3BU
+#define USB_CONTROL_REG			0x40U
+#define ITLATCH1_REG			0x50U
+#define ITLATCH2_REG			0x51U
+#define ITLATCH3_REG			0x52U
+#define ITLATCH4_REG			0x53U
+#define ITSETLATCH1_REG			0x60U
+#define ITSETLATCH2_REG			0x61U
+#define ITSETLATCH3_REG			0x62U
+#define ITSETLATCH4_REG			0x63U
+#define ITCLEARLATCH1_REG		0x70U
+#define ITCLEARLATCH2_REG		0x71U
+#define ITCLEARLATCH3_REG		0x72U
+#define ITCLEARLATCH4_REG		0x73U
+#define ITMASK1_REG			0x80U
+#define ITMASK2_REG			0x81U
+#define ITMASK3_REG			0x82U
+#define ITMASK4_REG			0x83U
+#define ITSETMASK1_REG			0x90U
+#define ITSETMASK2_REG			0x91U
+#define ITSETMASK3_REG			0x92U
+#define ITSETMASK4_REG			0x93U
+#define ITCLEARMASK1_REG		0xA0U
+#define ITCLEARMASK2_REG		0xA1U
+#define ITCLEARMASK3_REG		0xA2U
+#define ITCLEARMASK4_REG		0xA3U
+#define ITSOURCE1_REG			0xB0U
+#define ITSOURCE2_REG			0xB1U
+#define ITSOURCE3_REG			0xB2U
+#define ITSOURCE4_REG			0xB3U
+#define LDO_VOLTAGE_MASK		0x7CU
+#define BUCK_VOLTAGE_MASK		0xFCU
+#define LDO_BUCK_VOLTAGE_SHIFT		2
+#define LDO_ENABLE_MASK			0x01U
+#define BUCK_ENABLE_MASK		0x01U
+#define BUCK_HPLP_ENABLE_MASK		0x02U
+#define LDO_HPLP_ENABLE_MASK		0x02U
+#define LDO_BUCK_HPLP_SHIFT		1
+#define LDO_BUCK_RANK_MASK		0x01U
+#define LDO_BUCK_RESET_MASK		0x01U
+#define LDO_BUCK_PULL_DOWN_MASK		0x03U
+
+/* Main PMIC Control Register (MAIN_CONTROL_REG) */
+#define ICC_EVENT_ENABLED		BIT(4)
+#define PWRCTRL_POLARITY_HIGH		BIT(3)
+#define PWRCTRL_PIN_VALID		BIT(2)
+#define RESTART_REQUEST_ENABLED		BIT(1)
+#define SOFTWARE_SWITCH_OFF_ENABLED	BIT(0)
+
+/* Main PMIC PADS Control Register (PADS_PULL_REG) */
+#define WAKEUP_DETECTOR_DISABLED	BIT(4)
+#define PWRCTRL_PD_ACTIVE		BIT(3)
+#define PWRCTRL_PU_ACTIVE		BIT(2)
+#define WAKEUP_PD_ACTIVE		BIT(1)
+#define PONKEY_PU_ACTIVE		BIT(0)
+
+/* Main PMIC VINLOW Control Register (VIN_CONTROL_REGC DMSC) */
+#define SWIN_DETECTOR_ENABLED		BIT(7)
+#define SWOUT_DETECTOR_ENABLED          BIT(6)
+#define VINLOW_HYST_MASK		0x3
+#define VINLOW_HYST_SHIFT		4
+#define VINLOW_THRESHOLD_MASK		0x7
+#define VINLOW_THRESHOLD_SHIFT		1
+#define VINLOW_ENABLED			0x01
+#define VINLOW_CTRL_REG_MASK		0xFF
+
+/* USB Control Register */
+#define BOOST_OVP_DISABLED		BIT(7)
+#define VBUS_OTG_DETECTION_DISABLED	BIT(6)
+#define OCP_LIMIT_HIGH			BIT(3)
+#define SWIN_SWOUT_ENABLED		BIT(2)
+#define USBSW_OTG_SWITCH_ENABLED	BIT(1)
+
+int stpmu1_switch_off(void);
+int stpmu1_register_read(uint8_t register_id, uint8_t *value);
+int stpmu1_register_write(uint8_t register_id, uint8_t value);
+int stpmu1_register_update(uint8_t register_id, uint8_t value, uint8_t mask);
+int stpmu1_regulator_enable(const char *name);
+int stpmu1_regulator_disable(const char *name);
+uint8_t stpmu1_is_regulator_enabled(const char *name);
+int stpmu1_regulator_voltage_set(const char *name, uint16_t millivolts);
+void stpmu1_bind_i2c(struct i2c_handle_s *i2c_handle, uint16_t i2c_addr);
+
+#endif /* __STPMU1_H__ */
diff --git a/include/dt-bindings/clock/stm32mp1-clks.h b/include/dt-bindings/clock/stm32mp1-clks.h
new file mode 100644
index 0000000..18bdb57
--- /dev/null
+++ b/include/dt-bindings/clock/stm32mp1-clks.h
@@ -0,0 +1,251 @@
+/* SPDX-License-Identifier: GPL-2.0+ OR BSD-3-Clause */
+/*
+ * Copyright (C) STMicroelectronics 2018 - All Rights Reserved
+ * Author: Gabriel Fernandez <gabriel.fernandez@st.com> for STMicroelectronics.
+ */
+
+#ifndef _DT_BINDINGS_STM32MP1_CLKS_H_
+#define _DT_BINDINGS_STM32MP1_CLKS_H_
+
+/* OSCILLATOR clocks */
+#define CK_HSE		0
+#define CK_CSI		1
+#define CK_LSI		2
+#define CK_LSE		3
+#define CK_HSI		4
+#define CK_HSE_DIV2	5
+
+/* Bus clocks */
+#define TIM2		6
+#define TIM3		7
+#define TIM4		8
+#define TIM5		9
+#define TIM6		10
+#define TIM7		11
+#define TIM12		12
+#define TIM13		13
+#define TIM14		14
+#define LPTIM1		15
+#define SPI2		16
+#define SPI3		17
+#define USART2		18
+#define USART3		19
+#define UART4		20
+#define UART5		21
+#define UART7		22
+#define UART8		23
+#define I2C1		24
+#define I2C2		25
+#define I2C3		26
+#define I2C5		27
+#define SPDIF		28
+#define CEC		29
+#define DAC12		30
+#define MDIO		31
+#define TIM1		32
+#define TIM8		33
+#define TIM15		34
+#define TIM16		35
+#define TIM17		36
+#define SPI1		37
+#define SPI4		38
+#define SPI5		39
+#define USART6		40
+#define SAI1		41
+#define SAI2		42
+#define SAI3		43
+#define DFSDM		44
+#define FDCAN		45
+#define LPTIM2		46
+#define LPTIM3		47
+#define LPTIM4		48
+#define LPTIM5		49
+#define SAI4		50
+#define SYSCFG		51
+#define VREF		52
+#define TMPSENS		53
+#define PMBCTRL		54
+#define HDP		55
+#define LTDC		56
+#define DSI		57
+#define IWDG2		58
+#define USBPHY		59
+#define STGENRO		60
+#define SPI6		61
+#define I2C4		62
+#define I2C6		63
+#define USART1		64
+#define RTCAPB		65
+#define TZC1		66
+#define TZPC		67
+#define IWDG1		68
+#define BSEC		69
+#define STGEN		70
+#define DMA1		71
+#define DMA2		72
+#define DMAMUX		73
+#define ADC12		74
+#define USBO		75
+#define SDMMC3		76
+#define DCMI		77
+#define CRYP2		78
+#define HASH2		79
+#define RNG2		80
+#define CRC2		81
+#define HSEM		82
+#define IPCC		83
+#define GPIOA		84
+#define GPIOB		85
+#define GPIOC		86
+#define GPIOD		87
+#define GPIOE		88
+#define GPIOF		89
+#define GPIOG		90
+#define GPIOH		91
+#define GPIOI		92
+#define GPIOJ		93
+#define GPIOK		94
+#define GPIOZ		95
+#define CRYP1		96
+#define HASH1		97
+#define RNG1		98
+#define BKPSRAM		99
+#define MDMA		100
+#define GPU		101
+#define ETHCK		102
+#define ETHTX		103
+#define ETHRX		104
+#define ETHMAC		105
+#define FMC		106
+#define QSPI		107
+#define SDMMC1		108
+#define SDMMC2		109
+#define CRC1		110
+#define USBH		111
+#define ETHSTP		112
+#define TZC2		113
+
+/* Kernel clocks */
+#define SDMMC1_K	118
+#define SDMMC2_K	119
+#define SDMMC3_K	120
+#define FMC_K		121
+#define QSPI_K		122
+#define ETHCK_K		123
+#define RNG1_K		124
+#define RNG2_K		125
+#define GPU_K		126
+#define USBPHY_K	127
+#define STGEN_K		128
+#define SPDIF_K		129
+#define SPI1_K		130
+#define SPI2_K		131
+#define SPI3_K		132
+#define SPI4_K		133
+#define SPI5_K		134
+#define SPI6_K		135
+#define CEC_K		136
+#define I2C1_K		137
+#define I2C2_K		138
+#define I2C3_K		139
+#define I2C4_K		140
+#define I2C5_K		141
+#define I2C6_K		142
+#define LPTIM1_K	143
+#define LPTIM2_K	144
+#define LPTIM3_K	145
+#define LPTIM4_K	146
+#define LPTIM5_K	147
+#define USART1_K	148
+#define USART2_K	149
+#define USART3_K	150
+#define UART4_K		151
+#define UART5_K		152
+#define USART6_K	153
+#define UART7_K		154
+#define UART8_K		155
+#define DFSDM_K		156
+#define FDCAN_K		157
+#define SAI1_K		158
+#define SAI2_K		159
+#define SAI3_K		160
+#define SAI4_K		161
+#define ADC12_K		162
+#define DSI_K		163
+#define DSI_PX		164
+#define ADFSDM_K	165
+#define USBO_K		166
+#define LTDC_PX		167
+#define DAC12_K		168
+#define ETHPTP_K	169
+
+/* PLL */
+#define PLL1		176
+#define PLL2		177
+#define PLL3		178
+#define PLL4		179
+
+/* ODF */
+#define PLL1_P		180
+#define PLL1_Q		181
+#define PLL1_R		182
+#define PLL2_P		183
+#define PLL2_Q		184
+#define PLL2_R		185
+#define PLL3_P		186
+#define PLL3_Q		187
+#define PLL3_R		188
+#define PLL4_P		189
+#define PLL4_Q		190
+#define PLL4_R		191
+
+/* AUX */
+#define RTC		192
+
+/* MCLK */
+#define CK_PER		193
+#define CK_MPU		194
+#define CK_AXI		195
+#define CK_MCU		196
+
+/* Time base */
+#define TIM2_K		197
+#define TIM3_K		198
+#define TIM4_K		199
+#define TIM5_K		200
+#define TIM6_K		201
+#define TIM7_K		202
+#define TIM12_K		203
+#define TIM13_K		204
+#define TIM14_K		205
+#define TIM1_K		206
+#define TIM8_K		207
+#define TIM15_K		208
+#define TIM16_K		209
+#define TIM17_K		210
+
+/* MCO clocks */
+#define CK_MCO1		211
+#define CK_MCO2		212
+
+/* TRACE & DEBUG clocks */
+#define CK_DBG		214
+#define CK_TRACE	215
+
+/* DDR */
+#define DDRC1		220
+#define DDRC1LP		221
+#define DDRC2		222
+#define DDRC2LP		223
+#define DDRPHYC		224
+#define DDRPHYCLP	225
+#define DDRCAPB		226
+#define DDRCAPBLP	227
+#define AXIDCG		228
+#define DDRPHYCAPB	229
+#define DDRPHYCAPBLP	230
+#define DDRPERFM	231
+
+#define STM32MP1_LAST_CLK 232
+
+#endif /* _DT_BINDINGS_STM32MP1_CLKS_H_ */
diff --git a/include/dt-bindings/clock/stm32mp1-clksrc.h b/include/dt-bindings/clock/stm32mp1-clksrc.h
new file mode 100644
index 0000000..818f4b7
--- /dev/null
+++ b/include/dt-bindings/clock/stm32mp1-clksrc.h
@@ -0,0 +1,283 @@
+/* SPDX-License-Identifier: GPL-2.0+ OR BSD-3-Clause */
+/*
+ * Copyright (C) 2017, STMicroelectronics - All Rights Reserved
+ */
+
+#ifndef _DT_BINDINGS_CLOCK_STM32MP1_CLKSRC_H_
+#define _DT_BINDINGS_CLOCK_STM32MP1_CLKSRC_H_
+
+/* PLL output is enable when x=1, with x=p,q or r */
+#define PQR(p, q, r)	(((p) & 1) | (((q) & 1) << 1) | (((r) & 1) << 2))
+
+/* st,clksrc: mandatory clock source */
+
+#define CLK_MPU_HSI		0x00000200
+#define CLK_MPU_HSE		0x00000201
+#define CLK_MPU_PLL1P		0x00000202
+#define CLK_MPU_PLL1P_DIV	0x00000203
+
+#define CLK_AXI_HSI		0x00000240
+#define CLK_AXI_HSE		0x00000241
+#define CLK_AXI_PLL2P		0x00000242
+
+#define CLK_MCU_HSI		0x00000480
+#define CLK_MCU_HSE		0x00000481
+#define CLK_MCU_CSI		0x00000482
+#define CLK_MCU_PLL3P		0x00000483
+
+#define CLK_PLL12_HSI		0x00000280
+#define CLK_PLL12_HSE		0x00000281
+
+#define CLK_PLL3_HSI		0x00008200
+#define CLK_PLL3_HSE		0x00008201
+#define CLK_PLL3_CSI		0x00008202
+
+#define CLK_PLL4_HSI		0x00008240
+#define CLK_PLL4_HSE		0x00008241
+#define CLK_PLL4_CSI		0x00008242
+#define CLK_PLL4_I2SCKIN	0x00008243
+
+#define CLK_RTC_DISABLED	0x00001400
+#define CLK_RTC_LSE		0x00001401
+#define CLK_RTC_LSI		0x00001402
+#define CLK_RTC_HSE		0x00001403
+
+#define CLK_MCO1_HSI		0x00008000
+#define CLK_MCO1_HSE		0x00008001
+#define CLK_MCO1_CSI		0x00008002
+#define CLK_MCO1_LSI		0x00008003
+#define CLK_MCO1_LSE		0x00008004
+#define CLK_MCO1_DISABLED	0x0000800F
+
+#define CLK_MCO2_MPU		0x00008040
+#define CLK_MCO2_AXI		0x00008041
+#define CLK_MCO2_MCU		0x00008042
+#define CLK_MCO2_PLL4P		0x00008043
+#define CLK_MCO2_HSE		0x00008044
+#define CLK_MCO2_HSI		0x00008045
+#define CLK_MCO2_DISABLED	0x0000804F
+
+/* st,pkcs: peripheral kernel clock source */
+
+#define CLK_I2C12_PCLK1		0x00008C00
+#define CLK_I2C12_PLL4R		0x00008C01
+#define CLK_I2C12_HSI		0x00008C02
+#define CLK_I2C12_CSI		0x00008C03
+#define CLK_I2C12_DISABLED	0x00008C07
+
+#define CLK_I2C35_PCLK1		0x00008C40
+#define CLK_I2C35_PLL4R		0x00008C41
+#define CLK_I2C35_HSI		0x00008C42
+#define CLK_I2C35_CSI		0x00008C43
+#define CLK_I2C35_DISABLED	0x00008C47
+
+#define CLK_I2C46_PCLK5		0x00000C00
+#define CLK_I2C46_PLL3Q		0x00000C01
+#define CLK_I2C46_HSI		0x00000C02
+#define CLK_I2C46_CSI		0x00000C03
+#define CLK_I2C46_DISABLED	0x00000C07
+
+#define CLK_SAI1_PLL4Q		0x00008C80
+#define CLK_SAI1_PLL3Q		0x00008C81
+#define CLK_SAI1_I2SCKIN	0x00008C82
+#define CLK_SAI1_CKPER		0x00008C83
+#define CLK_SAI1_PLL3R		0x00008C84
+#define CLK_SAI1_DISABLED	0x00008C87
+
+#define CLK_SAI2_PLL4Q		0x00008CC0
+#define CLK_SAI2_PLL3Q		0x00008CC1
+#define CLK_SAI2_I2SCKIN	0x00008CC2
+#define CLK_SAI2_CKPER		0x00008CC3
+#define CLK_SAI2_SPDIF		0x00008CC4
+#define CLK_SAI2_PLL3R		0x00008CC5
+#define CLK_SAI2_DISABLED	0x00008CC7
+
+#define CLK_SAI3_PLL4Q		0x00008D00
+#define CLK_SAI3_PLL3Q		0x00008D01
+#define CLK_SAI3_I2SCKIN	0x00008D02
+#define CLK_SAI3_CKPER		0x00008D03
+#define CLK_SAI3_PLL3R		0x00008D04
+#define CLK_SAI3_DISABLED	0x00008D07
+
+#define CLK_SAI4_PLL4Q		0x00008D40
+#define CLK_SAI4_PLL3Q		0x00008D41
+#define CLK_SAI4_I2SCKIN	0x00008D42
+#define CLK_SAI4_CKPER		0x00008D43
+#define CLK_SAI4_PLL3R		0x00008D44
+#define CLK_SAI4_DISABLED	0x00008D47
+
+#define CLK_SPI2S1_PLL4P	0x00008D80
+#define CLK_SPI2S1_PLL3Q	0x00008D81
+#define CLK_SPI2S1_I2SCKIN	0x00008D82
+#define CLK_SPI2S1_CKPER	0x00008D83
+#define CLK_SPI2S1_PLL3R	0x00008D84
+#define CLK_SPI2S1_DISABLED	0x00008D87
+
+#define CLK_SPI2S23_PLL4P	0x00008DC0
+#define CLK_SPI2S23_PLL3Q	0x00008DC1
+#define CLK_SPI2S23_I2SCKIN	0x00008DC2
+#define CLK_SPI2S23_CKPER	0x00008DC3
+#define CLK_SPI2S23_PLL3R	0x00008DC4
+#define CLK_SPI2S23_DISABLED	0x00008DC7
+
+#define CLK_SPI45_PCLK2		0x00008E00
+#define CLK_SPI45_PLL4Q		0x00008E01
+#define CLK_SPI45_HSI		0x00008E02
+#define CLK_SPI45_CSI		0x00008E03
+#define CLK_SPI45_HSE		0x00008E04
+#define CLK_SPI45_DISABLED	0x00008E07
+
+#define CLK_SPI6_PCLK5		0x00000C40
+#define CLK_SPI6_PLL4Q		0x00000C41
+#define CLK_SPI6_HSI		0x00000C42
+#define CLK_SPI6_CSI		0x00000C43
+#define CLK_SPI6_HSE		0x00000C44
+#define CLK_SPI6_PLL3Q		0x00000C45
+#define CLK_SPI6_DISABLED	0x00000C47
+
+#define CLK_UART6_PCLK2		0x00008E40
+#define CLK_UART6_PLL4Q		0x00008E41
+#define CLK_UART6_HSI		0x00008E42
+#define CLK_UART6_CSI		0x00008E43
+#define CLK_UART6_HSE		0x00008E44
+#define CLK_UART6_DISABLED	0x00008E47
+
+#define CLK_UART24_PCLK1	0x00008E80
+#define CLK_UART24_PLL4Q	0x00008E81
+#define CLK_UART24_HSI		0x00008E82
+#define CLK_UART24_CSI		0x00008E83
+#define CLK_UART24_HSE		0x00008E84
+#define CLK_UART24_DISABLED	0x00008E87
+
+#define CLK_UART35_PCLK1	0x00008EC0
+#define CLK_UART35_PLL4Q	0x00008EC1
+#define CLK_UART35_HSI		0x00008EC2
+#define CLK_UART35_CSI		0x00008EC3
+#define CLK_UART35_HSE		0x00008EC4
+#define CLK_UART35_DISABLED	0x00008EC7
+
+#define CLK_UART78_PCLK1	0x00008F00
+#define CLK_UART78_PLL4Q	0x00008F01
+#define CLK_UART78_HSI		0x00008F02
+#define CLK_UART78_CSI		0x00008F03
+#define CLK_UART78_HSE		0x00008F04
+#define CLK_UART78_DISABLED	0x00008F07
+
+#define CLK_UART1_PCLK5		0x00000C80
+#define CLK_UART1_PLL3Q		0x00000C81
+#define CLK_UART1_HSI		0x00000C82
+#define CLK_UART1_CSI		0x00000C83
+#define CLK_UART1_PLL4Q		0x00000C84
+#define CLK_UART1_HSE		0x00000C85
+#define CLK_UART1_DISABLED	0x00000C87
+
+#define CLK_SDMMC12_HCLK6	0x00008F40
+#define CLK_SDMMC12_PLL3R	0x00008F41
+#define CLK_SDMMC12_PLL4P	0x00008F42
+#define CLK_SDMMC12_HSI		0x00008F43
+#define CLK_SDMMC12_DISABLED	0x00008F47
+
+#define CLK_SDMMC3_HCLK2	0x00008F80
+#define CLK_SDMMC3_PLL3R	0x00008F81
+#define CLK_SDMMC3_PLL4P	0x00008F82
+#define CLK_SDMMC3_HSI		0x00008F83
+#define CLK_SDMMC3_DISABLED	0x00008F87
+
+#define CLK_ETH_PLL4P		0x00008FC0
+#define CLK_ETH_PLL3Q		0x00008FC1
+#define CLK_ETH_DISABLED	0x00008FC3
+
+#define CLK_QSPI_ACLK		0x00009000
+#define CLK_QSPI_PLL3R		0x00009001
+#define CLK_QSPI_PLL4P		0x00009002
+#define CLK_QSPI_CKPER		0x00009003
+
+#define CLK_FMC_ACLK		0x00009040
+#define CLK_FMC_PLL3R		0x00009041
+#define CLK_FMC_PLL4P		0x00009042
+#define CLK_FMC_CKPER		0x00009043
+
+#define CLK_FDCAN_HSE		0x000090C0
+#define CLK_FDCAN_PLL3Q		0x000090C1
+#define CLK_FDCAN_PLL4Q		0x000090C2
+#define CLK_FDCAN_PLL4R		0x000090C3
+
+#define CLK_SPDIF_PLL4P		0x00009140
+#define CLK_SPDIF_PLL3Q		0x00009141
+#define CLK_SPDIF_HSI		0x00009142
+#define CLK_SPDIF_DISABLED	0x00009143
+
+#define CLK_CEC_LSE		0x00009180
+#define CLK_CEC_LSI		0x00009181
+#define CLK_CEC_CSI_DIV122	0x00009182
+#define CLK_CEC_DISABLED	0x00009183
+
+#define CLK_USBPHY_HSE		0x000091C0
+#define CLK_USBPHY_PLL4R	0x000091C1
+#define CLK_USBPHY_HSE_DIV2	0x000091C2
+#define CLK_USBPHY_DISABLED	0x000091C3
+
+#define CLK_USBO_PLL4R		0x800091C0
+#define CLK_USBO_USBPHY		0x800091C1
+
+#define CLK_RNG1_CSI		0x00000CC0
+#define CLK_RNG1_PLL4R		0x00000CC1
+#define CLK_RNG1_LSE		0x00000CC2
+#define CLK_RNG1_LSI		0x00000CC3
+
+#define CLK_RNG2_CSI		0x00009200
+#define CLK_RNG2_PLL4R		0x00009201
+#define CLK_RNG2_LSE		0x00009202
+#define CLK_RNG2_LSI		0x00009203
+
+#define CLK_CKPER_HSI		0x00000D00
+#define CLK_CKPER_CSI		0x00000D01
+#define CLK_CKPER_HSE		0x00000D02
+#define CLK_CKPER_DISABLED	0x00000D03
+
+#define CLK_STGEN_HSI		0x00000D40
+#define CLK_STGEN_HSE		0x00000D41
+#define CLK_STGEN_DISABLED	0x00000D43
+
+#define CLK_DSI_DSIPLL		0x00009240
+#define CLK_DSI_PLL4P		0x00009241
+
+#define CLK_ADC_PLL4R		0x00009280
+#define CLK_ADC_CKPER		0x00009281
+#define CLK_ADC_PLL3Q		0x00009282
+#define CLK_ADC_DISABLED	0x00009283
+
+#define CLK_LPTIM45_PCLK3	0x000092C0
+#define CLK_LPTIM45_PLL4P	0x000092C1
+#define CLK_LPTIM45_PLL3Q	0x000092C2
+#define CLK_LPTIM45_LSE		0x000092C3
+#define CLK_LPTIM45_LSI		0x000092C4
+#define CLK_LPTIM45_CKPER	0x000092C5
+#define CLK_LPTIM45_DISABLED	0x000092C7
+
+#define CLK_LPTIM23_PCLK3	0x00009300
+#define CLK_LPTIM23_PLL4Q	0x00009301
+#define CLK_LPTIM23_CKPER	0x00009302
+#define CLK_LPTIM23_LSE		0x00009303
+#define CLK_LPTIM23_LSI		0x00009304
+#define CLK_LPTIM23_DISABLED	0x00009307
+
+#define CLK_LPTIM1_PCLK1	0x00009340
+#define CLK_LPTIM1_PLL4P	0x00009341
+#define CLK_LPTIM1_PLL3Q	0x00009342
+#define CLK_LPTIM1_LSE		0x00009343
+#define CLK_LPTIM1_LSI		0x00009344
+#define CLK_LPTIM1_CKPER	0x00009345
+#define CLK_LPTIM1_DISABLED	0x00009347
+
+/* define for st,pll /csg */
+#define SSCG_MODE_CENTER_SPREAD	0
+#define SSCG_MODE_DOWN_SPREAD	1
+
+/* define for st,drive */
+#define LSEDRV_LOWEST		0
+#define LSEDRV_MEDIUM_LOW	1
+#define LSEDRV_MEDIUM_HIGH	2
+#define LSEDRV_HIGHEST		3
+
+#endif
diff --git a/include/dt-bindings/pinctrl/stm32-pinfunc.h b/include/dt-bindings/pinctrl/stm32-pinfunc.h
new file mode 100644
index 0000000..e2f1f1b
--- /dev/null
+++ b/include/dt-bindings/pinctrl/stm32-pinfunc.h
@@ -0,0 +1,35 @@
+/* SPDX-License-Identifier: (GPL-2.0+ OR BSD-3-Clause) */
+/*
+ * Copyright (C) STMicroelectronics 2017 - All Rights Reserved
+ * Author: Torgue Alexandre <alexandre.torgue@st.com> for STMicroelectronics.
+ */
+
+#ifndef _DT_BINDINGS_STM32_PINFUNC_H
+#define _DT_BINDINGS_STM32_PINFUNC_H
+
+/*  define PIN modes */
+#define GPIO	0x0
+#define AF0	0x1
+#define AF1	0x2
+#define AF2	0x3
+#define AF3	0x4
+#define AF4	0x5
+#define AF5	0x6
+#define AF6	0x7
+#define AF7	0x8
+#define AF8	0x9
+#define AF9	0xa
+#define AF10	0xb
+#define AF11	0xc
+#define AF12	0xd
+#define AF13	0xe
+#define AF14	0xf
+#define AF15	0x10
+#define ANALOG	0x11
+
+/* define Pins number*/
+#define PIN_NO(port, line)	(((port) - 'A') * 0x10 + (line))
+
+#define STM32_PINMUX(port, line, mode) (((PIN_NO(port, line)) << 8) | (mode))
+
+#endif /* _DT_BINDINGS_STM32_PINFUNC_H */
diff --git a/include/dt-bindings/reset/stm32mp1-resets.h b/include/dt-bindings/reset/stm32mp1-resets.h
new file mode 100644
index 0000000..f0c3aae
--- /dev/null
+++ b/include/dt-bindings/reset/stm32mp1-resets.h
@@ -0,0 +1,108 @@
+/* SPDX-License-Identifier: GPL-2.0 or BSD-3-Clause */
+/*
+ * Copyright (C) STMicroelectronics 2018 - All Rights Reserved
+ * Author: Gabriel Fernandez <gabriel.fernandez@st.com> for STMicroelectronics.
+ */
+
+#ifndef _DT_BINDINGS_STM32MP1_RESET_H_
+#define _DT_BINDINGS_STM32MP1_RESET_H_
+
+#define LTDC_R		3072
+#define DSI_R		3076
+#define DDRPERFM_R	3080
+#define USBPHY_R	3088
+#define SPI6_R		3136
+#define I2C4_R		3138
+#define I2C6_R		3139
+#define USART1_R	3140
+#define STGEN_R		3156
+#define GPIOZ_R		3200
+#define CRYP1_R		3204
+#define HASH1_R		3205
+#define RNG1_R		3206
+#define AXIM_R		3216
+#define GPU_R		3269
+#define ETHMAC_R	3274
+#define FMC_R		3276
+#define QSPI_R		3278
+#define SDMMC1_R	3280
+#define SDMMC2_R	3281
+#define CRC1_R		3284
+#define USBH_R		3288
+#define MDMA_R		3328
+#define MCU_R		8225
+#define TIM2_R		19456
+#define TIM3_R		19457
+#define TIM4_R		19458
+#define TIM5_R		19459
+#define TIM6_R		19460
+#define TIM7_R		19461
+#define TIM12_R		16462
+#define TIM13_R		16463
+#define TIM14_R		16464
+#define LPTIM1_R	19465
+#define SPI2_R		19467
+#define SPI3_R		19468
+#define USART2_R	19470
+#define USART3_R	19471
+#define UART4_R		19472
+#define UART5_R		19473
+#define UART7_R		19474
+#define UART8_R		19475
+#define I2C1_R		19477
+#define I2C2_R		19478
+#define I2C3_R		19479
+#define I2C5_R		19480
+#define SPDIF_R		19482
+#define CEC_R		19483
+#define DAC12_R		19485
+#define MDIO_R		19847
+#define TIM1_R		19520
+#define TIM8_R		19521
+#define TIM15_R		19522
+#define TIM16_R		19523
+#define TIM17_R		19524
+#define SPI1_R		19528
+#define SPI4_R		19529
+#define SPI5_R		19530
+#define USART6_R	19533
+#define SAI1_R		19536
+#define SAI2_R		19537
+#define SAI3_R		19538
+#define DFSDM_R		19540
+#define FDCAN_R		19544
+#define LPTIM2_R	19584
+#define LPTIM3_R	19585
+#define LPTIM4_R	19586
+#define LPTIM5_R	19587
+#define SAI4_R		19592
+#define SYSCFG_R	19595
+#define VREF_R		19597
+#define TMPSENS_R	19600
+#define PMBCTRL_R	19601
+#define DMA1_R		19648
+#define DMA2_R		19649
+#define DMAMUX_R	19650
+#define ADC12_R		19653
+#define USBO_R		19656
+#define SDMMC3_R	19664
+#define CAMITF_R	19712
+#define CRYP2_R		19716
+#define HASH2_R		19717
+#define RNG2_R		19718
+#define CRC2_R		19719
+#define HSEM_R		19723
+#define MBOX_R		19724
+#define GPIOA_R		19776
+#define GPIOB_R		19777
+#define GPIOC_R		19778
+#define GPIOD_R		19779
+#define GPIOE_R		19780
+#define GPIOF_R		19781
+#define GPIOG_R		19782
+#define GPIOH_R		19783
+#define GPIOI_R		19784
+#define GPIOJ_R		19785
+#define GPIOK_R		19786
+
+#endif /* _DT_BINDINGS_STM32MP1_RESET_H_ */
diff --git a/include/lib/aarch64/arch.h b/include/lib/aarch64/arch.h
index 7385b5d..397013e 100644
--- a/include/lib/aarch64/arch.h
+++ b/include/lib/aarch64/arch.h
@@ -4,8 +4,8 @@
  * SPDX-License-Identifier: BSD-3-Clause
  */
 
-#ifndef __ARCH_H__
-#define __ARCH_H__
+#ifndef ARCH_H
+#define ARCH_H
 
 #include <utils_def.h>
 
@@ -37,10 +37,10 @@
 #define MPIDR_AFF3_SHIFT	U(32)
 #define MPIDR_AFFINITY_MASK	ULL(0xff00ffffff)
 #define MPIDR_AFFLVL_SHIFT	U(3)
-#define MPIDR_AFFLVL0		ULL(0x0)
-#define MPIDR_AFFLVL1		ULL(0x1)
-#define MPIDR_AFFLVL2		ULL(0x2)
-#define MPIDR_AFFLVL3		ULL(0x3)
+#define MPIDR_AFFLVL0		U(0x0)
+#define MPIDR_AFFLVL1		U(0x1)
+#define MPIDR_AFFLVL2		U(0x2)
+#define MPIDR_AFFLVL3		U(0x3)
 #define MPIDR_AFFLVL0_VAL(mpidr) \
 		(((mpidr) >> MPIDR_AFF0_SHIFT) & MPIDR_AFFLVL_MASK)
 #define MPIDR_AFFLVL1_VAL(mpidr) \
@@ -739,4 +739,4 @@
 #define ERXMISC0_EL1		S3_0_C5_C4_4
 #define ERXMISC1_EL1		S3_0_C5_C4_5
 
-#endif /* __ARCH_H__ */
+#endif /* ARCH_H */
diff --git a/include/lib/pmf/pmf.h b/include/lib/pmf/pmf.h
index 2320760..a3812fb 100644
--- a/include/lib/pmf/pmf.h
+++ b/include/lib/pmf/pmf.h
@@ -4,8 +4,8 @@
  * SPDX-License-Identifier: BSD-3-Clause
  */
 
-#ifndef __PMF_H__
-#define __PMF_H__
+#ifndef PMF_H
+#define PMF_H
 
 #include <cassert.h>
 #include <pmf_helpers.h>
@@ -31,8 +31,8 @@
  * Flags passed to PMF_GET_TIMESTAMP_XXX
  * and PMF_CAPTURE_TIMESTAMP
  */
-#define PMF_CACHE_MAINT		(1 << 0)
-#define PMF_NO_CACHE_MAINT	0
+#define PMF_CACHE_MAINT		(U(1) << 0)
+#define PMF_NO_CACHE_MAINT	U(0)
 
 /*
  * Defines for PMF SMC function ids.
@@ -68,7 +68,7 @@
 #define PMF_CAPTURE_TIMESTAMP(_name, _tid, _flags)			\
 	do {								\
 		unsigned long long ts = read_cntpct_el0();		\
-		if ((_flags) & PMF_CACHE_MAINT)				\
+		if (((_flags) & PMF_CACHE_MAINT) != 0U)			\
 			pmf_capture_timestamp_with_cache_maint_ ## _name((_tid), ts);\
 		else							\
 			pmf_capture_timestamp_ ## _name((_tid), ts);	\
@@ -78,7 +78,7 @@
 	do {								\
 		(_tsval) = read_cntpct_el0();				\
 		CASSERT(sizeof(_tsval) == sizeof(unsigned long long), invalid_tsval_size);\
-		if ((_flags) & PMF_CACHE_MAINT)				\
+		if (((_flags) & PMF_CACHE_MAINT) != 0U)			\
 			pmf_capture_timestamp_with_cache_maint_ ## _name((_tid), (_tsval));\
 		else							\
 			pmf_capture_timestamp_ ## _name((_tid), (_tsval));\
@@ -87,7 +87,7 @@
 #define PMF_WRITE_TIMESTAMP(_name, _tid, _flags, _wrval)		\
 	do {								\
 		CASSERT(sizeof(_wrval) == sizeof(unsigned long long), invalid_wrval_size);\
-		if ((_flags) & PMF_CACHE_MAINT)				\
+		if (((_flags) & PMF_CACHE_MAINT) != 0U)			\
 			pmf_capture_timestamp_with_cache_maint_ ## _name((_tid), (_wrval));\
 		else							\
 			pmf_capture_timestamp_ ## _name((_tid), (_wrval));\
@@ -173,4 +173,4 @@
 		void *handle,
 		u_register_t flags);
 
-#endif /* __PMF_H__ */
+#endif /* PMF_H */
diff --git a/include/lib/pmf/pmf_helpers.h b/include/lib/pmf/pmf_helpers.h
index 829ad6c..b9757de 100644
--- a/include/lib/pmf/pmf_helpers.h
+++ b/include/lib/pmf/pmf_helpers.h
@@ -4,8 +4,8 @@
  * SPDX-License-Identifier: BSD-3-Clause
  */
 
-#ifndef __PMF_HELPERS_H__
-#define __PMF_HELPERS_H__
+#ifndef PMF_HELPERS_H
+#define PMF_HELPERS_H
 
 #include <arch_helpers.h>
 #include <assert.h>
@@ -77,9 +77,9 @@
 		CASSERT(_flags, select_proper_config);			\
 		PMF_VALIDATE_TID(_name, tid);				\
 		uintptr_t base_addr = (uintptr_t) pmf_ts_mem_ ## _name;	\
-		if ((_flags) & PMF_STORE_ENABLE)			\
+		if (((_flags) & PMF_STORE_ENABLE) != 0)			\
 			__pmf_store_timestamp(base_addr, tid, ts);	\
-		if ((_flags) & PMF_DUMP_ENABLE)				\
+		if (((_flags) & PMF_DUMP_ENABLE) != 0)			\
 			__pmf_dump_timestamp(tid, ts);			\
 	}								\
 	void pmf_capture_timestamp_with_cache_maint_ ## _name(		\
@@ -92,9 +92,9 @@
 		CASSERT(_flags, select_proper_config);			\
 		PMF_VALIDATE_TID(_name, tid);				\
 		uintptr_t base_addr = (uintptr_t) pmf_ts_mem_ ## _name;	\
-		if ((_flags) & PMF_STORE_ENABLE)			\
+		if (((_flags) & PMF_STORE_ENABLE) != 0)			\
 			__pmf_store_timestamp_with_cache_maint(base_addr, tid, ts);\
-		if ((_flags) & PMF_DUMP_ENABLE)				\
+		if (((_flags) & PMF_DUMP_ENABLE) != 0)			\
 			__pmf_dump_timestamp(tid, ts);			\
 	}
 
@@ -159,4 +159,4 @@
 		unsigned int tid,
 		unsigned int cpuid,
 		unsigned int flags);
-#endif /* __PMF_HELPERS_H__ */
+#endif /* PMF_HELPERS_H */
diff --git a/include/lib/psci/psci.h b/include/lib/psci/psci.h
index 06434f9..71d605d 100644
--- a/include/lib/psci/psci.h
+++ b/include/lib/psci/psci.h
@@ -1,11 +1,11 @@
 /*
- * Copyright (c) 2013-2017, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2013-2018, ARM Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
 
-#ifndef __PSCI_H__
-#define __PSCI_H__
+#ifndef PSCI_H
+#define PSCI_H
 
 #include <bakery_lock.h>
 #include <bl_common.h>
@@ -22,14 +22,14 @@
 #ifdef PLAT_NUM_PWR_DOMAINS
 #define PSCI_NUM_PWR_DOMAINS	PLAT_NUM_PWR_DOMAINS
 #else
-#define PSCI_NUM_PWR_DOMAINS	(U(2) * PLATFORM_CORE_COUNT)
+#define PSCI_NUM_PWR_DOMAINS	(2 * PLATFORM_CORE_COUNT)
 #endif
 
 #define PSCI_NUM_NON_CPU_PWR_DOMAINS	(PSCI_NUM_PWR_DOMAINS - \
 					 PLATFORM_CORE_COUNT)
 
 /* This is the power level corresponding to a CPU */
-#define PSCI_CPU_PWR_LVL	(0)
+#define PSCI_CPU_PWR_LVL	U(0)
 
 /*
  * The maximum power level supported by PSCI. Since PSCI CPU_SUSPEND
@@ -71,9 +71,6 @@
 #define PSCI_MEM_CHK_RANGE_AARCH32	U(0x84000014)
 #define PSCI_MEM_CHK_RANGE_AARCH64	U(0xc4000014)
 
-/* Macro to help build the psci capabilities bitfield */
-#define define_psci_cap(x)		(U(1) << (x & U(0x1f)))
-
 /*
  * Number of PSCI calls (above) implemented
  */
@@ -92,9 +89,9 @@
 /*******************************************************************************
  * PSCI Migrate and friends
  ******************************************************************************/
-#define PSCI_TOS_UP_MIG_CAP	U(0)
-#define PSCI_TOS_NOT_UP_MIG_CAP	U(1)
-#define PSCI_TOS_NOT_PRESENT_MP	U(2)
+#define PSCI_TOS_UP_MIG_CAP	0
+#define PSCI_TOS_NOT_UP_MIG_CAP	1
+#define PSCI_TOS_NOT_PRESENT_MP	2
 
 /*******************************************************************************
  * PSCI CPU_SUSPEND 'power_state' parameter specific defines
@@ -124,12 +121,6 @@
 #define PSTATE_TYPE_POWERDOWN	U(0x1)
 #define PSTATE_TYPE_MASK	U(0x1)
 
-#define psci_get_pstate_id(pstate)	(((pstate) >> PSTATE_ID_SHIFT) & \
-					PSTATE_ID_MASK)
-#define psci_get_pstate_type(pstate)	(((pstate) >> PSTATE_TYPE_SHIFT) & \
-					PSTATE_TYPE_MASK)
-#define psci_check_power_state(pstate)	((pstate) & PSTATE_VALID_MASK)
-
 /*******************************************************************************
  * PSCI CPU_FEATURES feature flag specific defines
  ******************************************************************************/
@@ -172,16 +163,41 @@
 /*
  * SYSTEM_RESET2 macros
  */
-#define PSCI_RESET2_TYPE_VENDOR_SHIFT	31
-#define PSCI_RESET2_TYPE_VENDOR		(1U << PSCI_RESET2_TYPE_VENDOR_SHIFT)
-#define PSCI_RESET2_TYPE_ARCH		(0U << PSCI_RESET2_TYPE_VENDOR_SHIFT)
-#define PSCI_RESET2_SYSTEM_WARM_RESET	(PSCI_RESET2_TYPE_ARCH | 0)
+#define PSCI_RESET2_TYPE_VENDOR_SHIFT	U(31)
+#define PSCI_RESET2_TYPE_VENDOR		(U(1) << PSCI_RESET2_TYPE_VENDOR_SHIFT)
+#define PSCI_RESET2_TYPE_ARCH		(U(0) << PSCI_RESET2_TYPE_VENDOR_SHIFT)
+#define PSCI_RESET2_SYSTEM_WARM_RESET	(PSCI_RESET2_TYPE_ARCH | U(0))
 
 #ifndef __ASSEMBLY__
 
 #include <stdint.h>
 #include <types.h>
 
+/* Function to help build the psci capabilities bitfield */
+
+static inline unsigned int define_psci_cap(unsigned int x)
+{
+	return U(1) << (x & U(0x1f));
+}
+
+
+/* Power state helper functions */
+
+static inline unsigned int psci_get_pstate_id(unsigned int power_state)
+{
+	return ((power_state) >> PSTATE_ID_SHIFT) & PSTATE_ID_MASK;
+}
+
+static inline unsigned int psci_get_pstate_type(unsigned int power_state)
+{
+	return ((power_state) >> PSTATE_TYPE_SHIFT) & PSTATE_TYPE_MASK;
+}
+
+static inline unsigned int psci_check_power_state(unsigned int power_state)
+{
+	return ((power_state) & PSTATE_VALID_MASK);
+}
+
 /*
  * These are the states reported by the PSCI_AFFINITY_INFO API for the specified
  * CPU. The definitions of these states can be found in Section 5.7.1 in the
@@ -198,11 +214,9 @@
  * specified CPU. The definitions of these states can be found in Section 5.15.3
  * of PSCI specification (ARM DEN 0022C).
  */
-typedef enum {
-	HW_ON = U(0),
-	HW_OFF = U(1),
-	HW_STANDBY = U(2)
-} node_hw_state_t;
+#define HW_ON		0
+#define HW_OFF		1
+#define HW_STANDBY	2
 
 /*
  * Macro to represent invalid affinity level within PSCI.
@@ -215,27 +229,33 @@
 typedef uint8_t plat_local_state_t;
 
 /* The local state macro used to represent RUN state. */
-#define PSCI_LOCAL_STATE_RUN  	U(0)
+#define PSCI_LOCAL_STATE_RUN	U(0)
 
 /*
- * Macro to test whether the plat_local_state is RUN state
+ * Function to test whether the plat_local_state is RUN state
  */
-#define is_local_state_run(plat_local_state) \
-			((plat_local_state) == PSCI_LOCAL_STATE_RUN)
+static inline int is_local_state_run(unsigned int plat_local_state)
+{
+	return (plat_local_state == PSCI_LOCAL_STATE_RUN) ? 1 : 0;
+}
 
 /*
- * Macro to test whether the plat_local_state is RETENTION state
+ * Function to test whether the plat_local_state is RETENTION state
  */
-#define is_local_state_retn(plat_local_state) \
-			(((plat_local_state) > PSCI_LOCAL_STATE_RUN) && \
-			((plat_local_state) <= PLAT_MAX_RET_STATE))
+static inline int is_local_state_retn(unsigned int plat_local_state)
+{
+	return ((plat_local_state > PSCI_LOCAL_STATE_RUN) &&
+		(plat_local_state <= PLAT_MAX_RET_STATE)) ? 1 : 0;
+}
 
 /*
- * Macro to test whether the plat_local_state is OFF state
+ * Function to test whether the plat_local_state is OFF state
  */
-#define is_local_state_off(plat_local_state) \
-			(((plat_local_state) > PLAT_MAX_RET_STATE) && \
-			((plat_local_state) <= PLAT_MAX_OFF_STATE))
+static inline int is_local_state_off(unsigned int plat_local_state)
+{
+	return ((plat_local_state > PLAT_MAX_RET_STATE) &&
+		(plat_local_state <= PLAT_MAX_OFF_STATE)) ? 1 : 0;
+}
 
 /*****************************************************************************
  * This data structure defines the representation of the power state parameter
@@ -266,7 +286,7 @@
 	 * Highest power level which takes part in a power management
 	 * operation.
 	 */
-	unsigned char target_pwrlvl;
+	unsigned int target_pwrlvl;
 
 	/* The local power state of this CPU */
 	plat_local_state_t local_state;
@@ -324,7 +344,7 @@
 		       unsigned int lowest_affinity_level);
 int psci_migrate(u_register_t target_cpu);
 int psci_migrate_info_type(void);
-long psci_migrate_info_up_cpu(void);
+u_register_t psci_migrate_info_up_cpu(void);
 int psci_node_hw_state(u_register_t target_cpu,
 		       unsigned int power_level);
 int psci_features(unsigned int psci_fid);
@@ -339,4 +359,4 @@
 
 #endif /*__ASSEMBLY__*/
 
-#endif /* __PSCI_H__ */
+#endif /* PSCI_H */
diff --git a/include/lib/psci/psci_compat.h b/include/lib/psci/psci_compat.h
index 65ac15f..11ed16d 100644
--- a/include/lib/psci/psci_compat.h
+++ b/include/lib/psci/psci_compat.h
@@ -1,14 +1,15 @@
 /*
- * Copyright (c) 2015-2016, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2015-2018, ARM Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
 
-#ifndef __PSCI_COMPAT_H__
-#define __PSCI_COMPAT_H__
+#ifndef PSCI_COMPAT_H
+#define PSCI_COMPAT_H
 
 #include <arch.h>
 #include <platform_def.h>
+#include <utils_def.h>
 
 #ifndef __ASSEMBLY__
 /*
@@ -25,10 +26,10 @@
 #define PSCI_AFF_ABSENT		0x0
 #define PSCI_AFF_PRESENT	0x1
 
-#define PSCI_STATE_ON		0x0
-#define PSCI_STATE_OFF		0x1
-#define PSCI_STATE_ON_PENDING	0x2
-#define PSCI_STATE_SUSPEND	0x3
+#define PSCI_STATE_ON		U(0x0)
+#define PSCI_STATE_OFF		U(0x1)
+#define PSCI_STATE_ON_PENDING	U(0x2)
+#define PSCI_STATE_SUSPEND	U(0x3)
 
 /*
  * Using the compatibility platform interfaces means that the local states
@@ -38,8 +39,8 @@
  * involved. Hence if we assume 3 generic states viz, run, standby and
  * power down, we can assign 1 and 2 to standby and power down respectively.
  */
-#define PLAT_MAX_RET_STATE	1
-#define PLAT_MAX_OFF_STATE	2
+#define PLAT_MAX_RET_STATE	U(1)
+#define PLAT_MAX_OFF_STATE	U(2)
 
 /*
  * Macro to represent invalid affinity level within PSCI.
@@ -89,4 +90,4 @@
 int psci_get_suspend_afflvl(void);
 
 #endif /* ____ASSEMBLY__ */
-#endif /* __PSCI_COMPAT_H__ */
+#endif /* PSCI_COMPAT_H */
diff --git a/include/lib/psci/psci_lib.h b/include/lib/psci/psci_lib.h
index 4697f17..5b30f55 100644
--- a/include/lib/psci/psci_lib.h
+++ b/include/lib/psci/psci_lib.h
@@ -1,11 +1,11 @@
 /*
- * Copyright (c) 2017, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2017-2018, ARM Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
 
-#ifndef __PSCI_LIB_H__
-#define __PSCI_LIB_H__
+#ifndef PSCI_LIB_H
+#define PSCI_LIB_H
 
 #include <ep_info.h>
 
@@ -20,9 +20,9 @@
  ******************************************************************************/
 typedef struct spd_pm_ops {
 	void (*svc_on)(u_register_t target_cpu);
-	int32_t (*svc_off)(u_register_t __unused);
+	int32_t (*svc_off)(u_register_t __unused unused);
 	void (*svc_suspend)(u_register_t max_off_pwrlvl);
-	void (*svc_on_finish)(u_register_t __unused);
+	void (*svc_on_finish)(u_register_t __unused unused);
 	void (*svc_suspend_finish)(u_register_t max_off_pwrlvl);
 	int32_t (*svc_migrate)(u_register_t from_cpu, u_register_t to_cpu);
 	int32_t (*svc_migrate_info)(u_register_t *resident_cpu);
@@ -58,17 +58,17 @@
 		.h.type = (uint8_t)PARAM_PSCI_LIB_ARGS,		\
 		.h.version = (uint8_t)VERSION_1,		\
 		.h.size = (uint16_t)sizeof(_name),		\
-		.h.attr = 0,					\
+		.h.attr = 0U,					\
 		.mailbox_ep = (_entry)				\
 	}
 
 /* Helper macro to verify the pointer to psci_lib_args_t structure */
-#define VERIFY_PSCI_LIB_ARGS_V1(_p)	((_p)			\
+#define VERIFY_PSCI_LIB_ARGS_V1(_p)	(((_p) != NULL)		\
 		&& ((_p)->h.type == PARAM_PSCI_LIB_ARGS)	\
 		&& ((_p)->h.version == VERSION_1)		\
 		&& ((_p)->h.size == sizeof(*(_p)))		\
 		&& ((_p)->h.attr == 0)				\
-		&& ((_p)->mailbox_ep))
+		&& ((_p)->mailbox_ep != NULL))
 
 /******************************************************************************
  * PSCI Library Interfaces
@@ -89,5 +89,4 @@
 			  entry_point_info_t *next_image_info);
 #endif /* __ASSEMBLY__ */
 
-#endif /* __PSCI_LIB_H */
-
+#endif /* PSCI_LIB_H */
diff --git a/include/lib/utils_def.h b/include/lib/utils_def.h
index 1bdf3c4..5b4fd78 100644
--- a/include/lib/utils_def.h
+++ b/include/lib/utils_def.h
@@ -4,8 +4,8 @@
  * SPDX-License-Identifier: BSD-3-Clause
  */
 
-#ifndef __UTILS_DEF_H__
-#define __UTILS_DEF_H__
+#ifndef UTILS_DEF_H
+#define UTILS_DEF_H
 
 /* Compute the number of elements in the given array */
 #define ARRAY_SIZE(a)				\
@@ -88,31 +88,37 @@
  * Evaluates to 1 if (ptr + inc) overflows, 0 otherwise.
  * Both arguments must be unsigned pointer values (i.e. uintptr_t).
  */
-#define check_uptr_overflow(ptr, inc)		\
-	(((ptr) > UINTPTR_MAX - (inc)) ? 1 : 0)
+#define check_uptr_overflow(_ptr, _inc)		\
+	((_ptr) > (UINTPTR_MAX - (_inc)))
 
 /*
  * Evaluates to 1 if (u32 + inc) overflows, 0 otherwise.
  * Both arguments must be 32-bit unsigned integers (i.e. effectively uint32_t).
  */
-#define check_u32_overflow(u32, inc) \
-	((u32) > (UINT32_MAX - (inc)) ? 1 : 0)
+#define check_u32_overflow(_u32, _inc) \
+	((_u32) > (UINT32_MAX - (_inc)))
 
 /*
- * For those constants to be shared between C and other sources, apply a 'u'
- * or 'ull' suffix to the argument only in C, to avoid undefined or unintended
- * behaviour.
+ * For those constants to be shared between C and other sources, apply a 'U',
+ * 'UL', 'ULL', 'L' or 'LL' suffix to the argument only in C, to avoid
+ * undefined or unintended behaviour.
  *
- * The GNU assembler and linker do not support the 'u' and 'ull' suffix (it
- * causes the build process to fail) therefore the suffix is omitted when used
- * in linker scripts and assembler files.
+ * The GNU assembler and linker do not support these suffixes (it causes the
+ * build process to fail) therefore the suffix is omitted when used in linker
+ * scripts and assembler files.
 */
 #if defined(__LINKER__) || defined(__ASSEMBLY__)
-# define  U(_x)		(_x)
+# define   U(_x)	(_x)
+# define  UL(_x)	(_x)
 # define ULL(_x)	(_x)
+# define   L(_x)	(_x)
+# define  LL(_x)	(_x)
 #else
-# define  U(_x)		(_x##U)
+# define   U(_x)	(_x##U)
+# define  UL(_x)	(_x##UL)
 # define ULL(_x)	(_x##ULL)
+# define   L(_x)	(_x##L)
+# define  LL(_x)	(_x##LL)
 #endif
 
 /* Register size of the current architecture. */
@@ -147,4 +153,4 @@
 #define ASSERT_SYM_PTR_ALIGN(sym) assert(((size_t)(sym) % __alignof__(*(sym))) == 0)
 
 
-#endif /* __UTILS_DEF_H__ */
+#endif /* UTILS_DEF_H */
diff --git a/include/plat/arm/board/common/board_arm_def.h b/include/plat/arm/board/common/board_arm_def.h
index 5e1d680..c3ae564 100644
--- a/include/plat/arm/board/common/board_arm_def.h
+++ b/include/plat/arm/board/common/board_arm_def.h
@@ -28,7 +28,7 @@
 #  define PLATFORM_STACK_SIZE 0x400
 # endif
 #elif defined(IMAGE_BL2U)
-# define PLATFORM_STACK_SIZE 0x200
+# define PLATFORM_STACK_SIZE 0x400
 #elif defined(IMAGE_BL31)
 #if ENABLE_SPM
 # define PLATFORM_STACK_SIZE 0x500
diff --git a/include/plat/arm/common/arm_def.h b/include/plat/arm/common/arm_def.h
index e3d0edb..9a661d7 100644
--- a/include/plat/arm/common/arm_def.h
+++ b/include/plat/arm/common/arm_def.h
@@ -3,8 +3,8 @@
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
-#ifndef __ARM_DEF_H__
-#define __ARM_DEF_H__
+#ifndef ARM_DEF_H
+#define ARM_DEF_H
 
 #include <arch.h>
 #include <common_def.h>
@@ -40,12 +40,12 @@
  *  within the power-state parameter.
  */
 /* Local power state for power domains in Run state. */
-#define ARM_LOCAL_STATE_RUN	0
+#define ARM_LOCAL_STATE_RUN	U(0)
 /* Local power state for retention. Valid only for CPU power domains */
-#define ARM_LOCAL_STATE_RET	1
+#define ARM_LOCAL_STATE_RET	U(1)
 /* Local power state for OFF/power-down. Valid for CPU and cluster power
    domains */
-#define ARM_LOCAL_STATE_OFF	2
+#define ARM_LOCAL_STATE_OFF	U(2)
 
 /* Memory location options for TSP */
 #define ARM_TRUSTED_SRAM_ID		0
@@ -241,6 +241,25 @@
 						ARM_EL3_TZC_DRAM1_SIZE,	\
 						MT_MEMORY | MT_RW | MT_SECURE)
 
+#if SEPARATE_CODE_AND_RODATA
+#define ARM_MAP_BL_CODE			MAP_REGION_FLAT(			\
+						BL_CODE_BASE,			\
+						BL_CODE_END - BL_CODE_BASE,	\
+						MT_CODE | MT_SECURE)
+#define ARM_MAP_BL_RO_DATA		MAP_REGION_FLAT(			\
+						BL_RO_DATA_BASE,		\
+						BL_RO_DATA_END			\
+							- BL_RO_DATA_BASE,	\
+						MT_RO_DATA | MT_SECURE)
+#endif
+#if USE_COHERENT_MEM
+#define ARM_MAP_BL_COHERENT_RAM		MAP_REGION_FLAT(			\
+						BL_COHERENT_RAM_BASE,		\
+						BL_COHERENT_RAM_END		\
+							- BL_COHERENT_RAM_BASE, \
+						MT_DEVICE | MT_RW | MT_SECURE)
+#endif
+
 /*
  * The number of regions like RO(code), coherent and data required by
  * different BL stages which need to be mapped in the MMU.
@@ -509,4 +528,4 @@
 	SDEI_SHARED_EVENT(ARM_SDEI_DS_EVENT_1, SDEI_DYN_IRQ, SDEI_MAPF_DYNAMIC), \
 	SDEI_SHARED_EVENT(ARM_SDEI_DS_EVENT_2, SDEI_DYN_IRQ, SDEI_MAPF_DYNAMIC)
 
-#endif /* __ARM_DEF_H__ */
+#endif /* ARM_DEF_H */
diff --git a/include/plat/arm/common/plat_arm.h b/include/plat/arm/common/plat_arm.h
index 42bbf38..506bed3 100644
--- a/include/plat/arm/common/plat_arm.h
+++ b/include/plat/arm/common/plat_arm.h
@@ -69,17 +69,8 @@
 /*
  * Utility functions common to ARM standard platforms
  */
-void arm_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
-#if USE_COHERENT_MEM
-			, uintptr_t coh_start,
-			uintptr_t coh_limit
-#endif
-);
+void arm_setup_page_tables(const mmap_region_t bl_regions[],
+			   const mmap_region_t plat_regions[]);
 
 #if defined(IMAGE_BL31) || (defined(AARCH32) && defined(IMAGE_BL32))
 /*
@@ -292,5 +283,6 @@
 /* global variables */
 extern plat_psci_ops_t plat_arm_psci_pm_ops;
 extern const mmap_region_t plat_arm_mmap[];
+extern const unsigned int arm_pm_idle_states[];
 
 #endif /* __PLAT_ARM_H__ */
diff --git a/include/plat/arm/css/common/css_def.h b/include/plat/arm/css/common/css_def.h
index 725c27c..048c58a 100644
--- a/include/plat/arm/css/common/css_def.h
+++ b/include/plat/arm/css/common/css_def.h
@@ -101,6 +101,14 @@
 						NSRAM_SIZE,	\
 						MT_DEVICE | MT_RW | MT_NS)
 
+#if defined(IMAGE_BL2U)
+#define CSS_MAP_SCP_BL2U		MAP_REGION_FLAT(		\
+						SCP_BL2U_BASE,		\
+						SCP_BL2U_LIMIT		\
+							- SCP_BL2U_BASE,\
+						MT_RW_DATA | MT_SECURE)
+#endif
+
 /* Platform ID address */
 #define SSC_VERSION_OFFSET			0x040
 
diff --git a/include/plat/common/platform.h b/include/plat/common/platform.h
index cd17a00..12eac60 100644
--- a/include/plat/common/platform.h
+++ b/include/plat/common/platform.h
@@ -4,8 +4,8 @@
  * SPDX-License-Identifier: BSD-3-Clause
  */
 
-#ifndef __PLATFORM_H__
-#define __PLATFORM_H__
+#ifndef PLATFORM_H
+#define PLATFORM_H
 
 #include <psci.h>
 #include <stdint.h>
@@ -401,5 +401,4 @@
 
 #endif /* __ENABLE_PLAT_COMPAT__ */
 
-#endif /* __PLATFORM_H__ */
-
+#endif /* PLATFORM_H */
diff --git a/lib/psci/psci_common.c b/lib/psci/psci_common.c
index 2220a74..59c9c68 100644
--- a/lib/psci/psci_common.c
+++ b/lib/psci/psci_common.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2013-2017, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2013-2018, ARM Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -68,9 +68,9 @@
 /******************************************************************************
  * Check that the maximum power level supported by the platform makes sense
  *****************************************************************************/
-CASSERT(PLAT_MAX_PWR_LVL <= PSCI_MAX_PWR_LVL && \
-		PLAT_MAX_PWR_LVL >= PSCI_CPU_PWR_LVL, \
-		assert_platform_max_pwrlvl_check);
+CASSERT((PLAT_MAX_PWR_LVL <= PSCI_MAX_PWR_LVL) &&
+	(PLAT_MAX_PWR_LVL >= PSCI_CPU_PWR_LVL),
+	assert_platform_max_pwrlvl_check);
 
 /*
  * The plat_local_state used by the platform is one of these types: RUN,
@@ -93,17 +93,25 @@
 	STATE_TYPE_OFF
 } plat_local_state_type_t;
 
-/* The macro used to categorize plat_local_state. */
-#define find_local_state_type(plat_local_state)					\
-		((plat_local_state) ? ((plat_local_state > PLAT_MAX_RET_STATE)	\
-		? STATE_TYPE_OFF : STATE_TYPE_RETN)				\
-		: STATE_TYPE_RUN)
+/* Function used to categorize plat_local_state. */
+static plat_local_state_type_t find_local_state_type(plat_local_state_t state)
+{
+	if (state != 0U) {
+		if (state > PLAT_MAX_RET_STATE) {
+			return STATE_TYPE_OFF;
+		} else {
+			return STATE_TYPE_RETN;
+		}
+	} else {
+		return STATE_TYPE_RUN;
+	}
+}
 
 /******************************************************************************
  * Check that the maximum retention level supported by the platform is less
  * than the maximum off level.
  *****************************************************************************/
-CASSERT(PLAT_MAX_RET_STATE < PLAT_MAX_OFF_STATE, \
+CASSERT(PLAT_MAX_RET_STATE < PLAT_MAX_OFF_STATE,
 		assert_platform_max_off_and_retn_state_check);
 
 /******************************************************************************
@@ -114,10 +122,10 @@
 			      psci_power_state_t *state_info)
 {
 	/* Check SBZ bits in power state are zero */
-	if (psci_check_power_state(power_state))
+	if (psci_check_power_state(power_state) != 0U)
 		return PSCI_E_INVALID_PARAMS;
 
-	assert(psci_plat_pm_ops->validate_power_state);
+	assert(psci_plat_pm_ops->validate_power_state != NULL);
 
 	/* Validate the power_state using platform pm_ops */
 	return psci_plat_pm_ops->validate_power_state(power_state, state_info);
@@ -133,7 +141,7 @@
 	 * Assert that the required pm_ops hook is implemented to ensure that
 	 * the capability detected during psci_setup() is valid.
 	 */
-	assert(psci_plat_pm_ops->get_sys_suspend_power_state);
+	assert(psci_plat_pm_ops->get_sys_suspend_power_state != NULL);
 
 	/*
 	 * Query the platform for the power_state required for system suspend
@@ -149,7 +157,7 @@
  ******************************************************************************/
 unsigned int psci_is_last_on_cpu(void)
 {
-	unsigned int cpu_idx, my_idx = plat_my_core_pos();
+	int cpu_idx, my_idx = (int) plat_my_core_pos();
 
 	for (cpu_idx = 0; cpu_idx < PLATFORM_CORE_COUNT; cpu_idx++) {
 		if (cpu_idx == my_idx) {
@@ -201,7 +209,7 @@
 	assert(pwrlvl > PSCI_CPU_PWR_LVL);
 #pragma GCC diagnostic push
 #pragma GCC diagnostic ignored "-Warray-bounds"
-	psci_req_local_pwr_states[pwrlvl - 1][cpu_idx] = req_pwr_state;
+	psci_req_local_pwr_states[pwrlvl - 1U][cpu_idx] = req_pwr_state;
 #pragma GCC diagnostic pop
 }
 
@@ -211,8 +219,15 @@
 void psci_init_req_local_pwr_states(void)
 {
 	/* Initialize the requested state of all non CPU power domains as OFF */
-	memset(&psci_req_local_pwr_states, PLAT_MAX_OFF_STATE,
-			sizeof(psci_req_local_pwr_states));
+	unsigned int pwrlvl;
+	int core;
+
+	for (pwrlvl = 0U; pwrlvl < PLAT_MAX_PWR_LVL; pwrlvl++) {
+		for (core = 0; core < PLATFORM_CORE_COUNT; core++) {
+			psci_req_local_pwr_states[pwrlvl][core] =
+				PLAT_MAX_OFF_STATE;
+		}
+	}
 }
 
 /******************************************************************************
@@ -224,11 +239,11 @@
  * assertion is added to prevent us from accessing the CPU power level.
  *****************************************************************************/
 static plat_local_state_t *psci_get_req_local_pwr_states(unsigned int pwrlvl,
-							 unsigned int cpu_idx)
+							 int cpu_idx)
 {
 	assert(pwrlvl > PSCI_CPU_PWR_LVL);
 
-	return &psci_req_local_pwr_states[pwrlvl - 1][cpu_idx];
+	return &psci_req_local_pwr_states[pwrlvl - 1U][cpu_idx];
 }
 
 /*
@@ -291,7 +306,7 @@
 	parent_idx = psci_cpu_pd_nodes[plat_my_core_pos()].parent_node;
 
 	/* Copy the local power state from node to state_info */
-	for (lvl = PSCI_CPU_PWR_LVL + 1; lvl <= end_pwrlvl; lvl++) {
+	for (lvl = PSCI_CPU_PWR_LVL + 1U; lvl <= end_pwrlvl; lvl++) {
 		pd_state[lvl] = get_non_cpu_pd_node_local_state(parent_idx);
 		parent_idx = psci_non_cpu_pd_nodes[parent_idx].parent_node;
 	}
@@ -324,7 +339,7 @@
 	parent_idx = psci_cpu_pd_nodes[plat_my_core_pos()].parent_node;
 
 	/* Copy the local_state from state_info */
-	for (lvl = 1; lvl <= end_pwrlvl; lvl++) {
+	for (lvl = 1U; lvl <= end_pwrlvl; lvl++) {
 		set_non_cpu_pd_node_local_state(parent_idx, pd_state[lvl]);
 		parent_idx = psci_non_cpu_pd_nodes[parent_idx].parent_node;
 	}
@@ -334,15 +349,17 @@
 /*******************************************************************************
  * PSCI helper function to get the parent nodes corresponding to a cpu_index.
  ******************************************************************************/
-void psci_get_parent_pwr_domain_nodes(unsigned int cpu_idx,
+void psci_get_parent_pwr_domain_nodes(int cpu_idx,
 				      unsigned int end_lvl,
-				      unsigned int node_index[])
+				      unsigned int *node_index)
 {
 	unsigned int parent_node = psci_cpu_pd_nodes[cpu_idx].parent_node;
 	unsigned int i;
+	unsigned int *node = node_index;
 
-	for (i = PSCI_CPU_PWR_LVL + 1; i <= end_lvl; i++) {
-		*node_index++ = parent_node;
+	for (i = PSCI_CPU_PWR_LVL + 1U; i <= end_lvl; i++) {
+		*node = parent_node;
+		node++;
 		parent_node = psci_non_cpu_pd_nodes[parent_node].parent_node;
 	}
 }
@@ -358,7 +375,7 @@
 	parent_idx = psci_cpu_pd_nodes[cpu_idx].parent_node;
 
 	/* Reset the local_state to RUN for the non cpu power domains. */
-	for (lvl = PSCI_CPU_PWR_LVL + 1; lvl <= end_pwrlvl; lvl++) {
+	for (lvl = PSCI_CPU_PWR_LVL + 1U; lvl <= end_pwrlvl; lvl++) {
 		set_non_cpu_pd_node_local_state(parent_idx,
 				PSCI_LOCAL_STATE_RUN);
 		psci_set_req_local_pwr_state(lvl,
@@ -398,7 +415,8 @@
 				psci_power_state_t *state_info)
 {
 	unsigned int lvl, parent_idx, cpu_idx = plat_my_core_pos();
-	unsigned int start_idx, ncpus;
+	int start_idx;
+	unsigned int ncpus;
 	plat_local_state_t target_state, *req_states;
 
 	assert(end_pwrlvl <= PLAT_MAX_PWR_LVL);
@@ -406,7 +424,7 @@
 
 	/* For level 0, the requested state will be equivalent
 	   to target state */
-	for (lvl = PSCI_CPU_PWR_LVL + 1; lvl <= end_pwrlvl; lvl++) {
+	for (lvl = PSCI_CPU_PWR_LVL + 1U; lvl <= end_pwrlvl; lvl++) {
 
 		/* First update the requested power state */
 		psci_set_req_local_pwr_state(lvl, cpu_idx,
@@ -428,7 +446,7 @@
 		state_info->pwr_domain_state[lvl] = target_state;
 
 		/* Break early if the negotiated target power state is RUN */
-		if (is_local_state_run(state_info->pwr_domain_state[lvl]))
+		if (is_local_state_run(state_info->pwr_domain_state[lvl]) != 0)
 			break;
 
 		parent_idx = psci_non_cpu_pd_nodes[parent_idx].parent_node;
@@ -440,7 +458,7 @@
 	 * We update the requested power state from state_info and then
 	 * set the target state as RUN.
 	 */
-	for (lvl = lvl + 1; lvl <= end_pwrlvl; lvl++) {
+	for (lvl = lvl + 1U; lvl <= end_pwrlvl; lvl++) {
 		psci_set_req_local_pwr_state(lvl, cpu_idx,
 					     state_info->pwr_domain_state[lvl]);
 		state_info->pwr_domain_state[lvl] = PSCI_LOCAL_STATE_RUN;
@@ -478,7 +496,7 @@
 	/* All power domain levels are in a RUN state to begin with */
 	deepest_state_type = STATE_TYPE_RUN;
 
-	for (i = target_lvl; i >= PSCI_CPU_PWR_LVL; i--) {
+	for (i = (int) target_lvl; i >= (int) PSCI_CPU_PWR_LVL; i--) {
 		state = state_info->pwr_domain_state[i];
 		req_state_type = find_local_state_type(state);
 
@@ -507,8 +525,9 @@
 	 * has to be invalid and max retention level has to be a valid power
 	 * level.
 	 */
-	if (!is_power_down_state && (max_off_lvl != PSCI_INVALID_PWR_LVL ||
-				    max_retn_lvl == PSCI_INVALID_PWR_LVL))
+	if ((is_power_down_state == 0U) &&
+			((max_off_lvl != PSCI_INVALID_PWR_LVL) ||
+			 (max_retn_lvl == PSCI_INVALID_PWR_LVL)))
 		return PSCI_E_INVALID_PARAMS;
 
 	return PSCI_E_SUCCESS;
@@ -522,9 +541,9 @@
 {
 	int i;
 
-	for (i = PLAT_MAX_PWR_LVL; i >= PSCI_CPU_PWR_LVL; i--) {
-		if (is_local_state_off(state_info->pwr_domain_state[i]))
-			return i;
+	for (i = (int) PLAT_MAX_PWR_LVL; i >= (int) PSCI_CPU_PWR_LVL; i--) {
+		if (is_local_state_off(state_info->pwr_domain_state[i]) != 0)
+			return (unsigned int) i;
 	}
 
 	return PSCI_INVALID_PWR_LVL;
@@ -538,9 +557,9 @@
 {
 	int i;
 
-	for (i = PLAT_MAX_PWR_LVL; i >= PSCI_CPU_PWR_LVL; i--) {
-		if (!is_local_state_run(state_info->pwr_domain_state[i]))
-			return i;
+	for (i = (int) PLAT_MAX_PWR_LVL; i >= (int) PSCI_CPU_PWR_LVL; i--) {
+		if (is_local_state_run(state_info->pwr_domain_state[i]) == 0)
+			return (unsigned int) i;
 	}
 
 	return PSCI_INVALID_PWR_LVL;
@@ -551,14 +570,13 @@
  * tree that the operation should be applied to. It picks up locks in order of
  * increasing power domain level in the range specified.
  ******************************************************************************/
-void psci_acquire_pwr_domain_locks(unsigned int end_pwrlvl,
-				   unsigned int cpu_idx)
+void psci_acquire_pwr_domain_locks(unsigned int end_pwrlvl, int cpu_idx)
 {
 	unsigned int parent_idx = psci_cpu_pd_nodes[cpu_idx].parent_node;
 	unsigned int level;
 
 	/* No locking required for level 0. Hence start locking from level 1 */
-	for (level = PSCI_CPU_PWR_LVL + 1; level <= end_pwrlvl; level++) {
+	for (level = PSCI_CPU_PWR_LVL + 1U; level <= end_pwrlvl; level++) {
 		psci_lock_get(&psci_non_cpu_pd_nodes[parent_idx]);
 		parent_idx = psci_non_cpu_pd_nodes[parent_idx].parent_node;
 	}
@@ -569,18 +587,17 @@
  * tree that the operation should be applied to. It releases the locks in order
  * of decreasing power domain level in the range specified.
  ******************************************************************************/
-void psci_release_pwr_domain_locks(unsigned int end_pwrlvl,
-				   unsigned int cpu_idx)
+void psci_release_pwr_domain_locks(unsigned int end_pwrlvl, int cpu_idx)
 {
 	unsigned int parent_idx, parent_nodes[PLAT_MAX_PWR_LVL] = {0};
-	int level;
+	unsigned int level;
 
 	/* Get the parent nodes */
 	psci_get_parent_pwr_domain_nodes(cpu_idx, end_pwrlvl, parent_nodes);
 
 	/* Unlock top down. No unlocking required for level 0. */
-	for (level = end_pwrlvl; level >= PSCI_CPU_PWR_LVL + 1; level--) {
-		parent_idx = parent_nodes[level - 1];
+	for (level = end_pwrlvl; level >= PSCI_CPU_PWR_LVL + 1U; level--) {
+		parent_idx = parent_nodes[level - 1U];
 		psci_lock_release(&psci_non_cpu_pd_nodes[parent_idx]);
 	}
 }
@@ -656,11 +673,12 @@
 	u_register_t ns_scr_el3 = read_scr_el3();
 	u_register_t ns_sctlr_el1 = read_sctlr_el1();
 
-	sctlr = ns_scr_el3 & SCR_HCE_BIT ? read_sctlr_el2() : ns_sctlr_el1;
+	sctlr = ((ns_scr_el3 & SCR_HCE_BIT) != 0U) ?
+		read_sctlr_el2() : ns_sctlr_el1;
 	ee = 0;
 
 	ep_attr = NON_SECURE | EP_ST_DISABLE;
-	if (sctlr & SCTLR_EE_BIT) {
+	if ((sctlr & SCTLR_EE_BIT) != 0U) {
 		ep_attr |= EP_EE_BIG;
 		ee = 1;
 	}
@@ -674,21 +692,22 @@
 	 * Figure out whether the cpu enters the non-secure address space
 	 * in aarch32 or aarch64
 	 */
-	if (ns_scr_el3 & SCR_RW_BIT) {
+	if ((ns_scr_el3 & SCR_RW_BIT) != 0U) {
 
 		/*
 		 * Check whether a Thumb entry point has been provided for an
 		 * aarch64 EL
 		 */
-		if (entrypoint & 0x1)
+		if ((entrypoint & 0x1UL) != 0UL)
 			return PSCI_E_INVALID_ADDRESS;
 
-		mode = ns_scr_el3 & SCR_HCE_BIT ? MODE_EL2 : MODE_EL1;
+		mode = ((ns_scr_el3 & SCR_HCE_BIT) != 0U) ? MODE_EL2 : MODE_EL1;
 
 		ep->spsr = SPSR_64(mode, MODE_SP_ELX, DISABLE_ALL_EXCEPTIONS);
 	} else {
 
-		mode = ns_scr_el3 & SCR_HCE_BIT ? MODE32_hyp : MODE32_svc;
+		mode = ((ns_scr_el3 & SCR_HCE_BIT) != 0U) ?
+			MODE32_hyp : MODE32_svc;
 
 		/*
 		 * TODO: Choose async. exception bits if HYP mode is not
@@ -715,7 +734,7 @@
 	int rc;
 
 	/* Validate the entrypoint using platform psci_ops */
-	if (psci_plat_pm_ops->validate_ns_entrypoint) {
+	if (psci_plat_pm_ops->validate_ns_entrypoint != NULL) {
 		rc = psci_plat_pm_ops->validate_ns_entrypoint(entrypoint);
 		if (rc != PSCI_E_SUCCESS)
 			return PSCI_E_INVALID_ADDRESS;
@@ -741,7 +760,8 @@
  ******************************************************************************/
 void psci_warmboot_entrypoint(void)
 {
-	unsigned int end_pwrlvl, cpu_idx = plat_my_core_pos();
+	unsigned int end_pwrlvl;
+	int cpu_idx = (int) plat_my_core_pos();
 	psci_power_state_t state_info = { {PSCI_LOCAL_STATE_RUN} };
 
 	/*
@@ -764,8 +784,7 @@
 	 * that by the time all locks are taken, the system topology is snapshot
 	 * and state management can be done safely.
 	 */
-	psci_acquire_pwr_domain_locks(end_pwrlvl,
-				      cpu_idx);
+	psci_acquire_pwr_domain_locks(end_pwrlvl, cpu_idx);
 
 	psci_get_target_local_pwr_states(end_pwrlvl, &state_info);
 
@@ -810,8 +829,7 @@
 	 * This loop releases the lock corresponding to each power level
 	 * in the reverse order to which they were acquired.
 	 */
-	psci_release_pwr_domain_locks(end_pwrlvl,
-				      cpu_idx);
+	psci_release_pwr_domain_locks(end_pwrlvl, cpu_idx);
 }
 
 /*******************************************************************************
@@ -821,13 +839,13 @@
  ******************************************************************************/
 void psci_register_spd_pm_hook(const spd_pm_ops_t *pm)
 {
-	assert(pm);
+	assert(pm != NULL);
 	psci_spd_pm = pm;
 
-	if (pm->svc_migrate)
+	if (pm->svc_migrate != NULL)
 		psci_caps |= define_psci_cap(PSCI_MIG_AARCH64);
 
-	if (pm->svc_migrate_info)
+	if (pm->svc_migrate_info != NULL)
 		psci_caps |= define_psci_cap(PSCI_MIG_INFO_UP_CPU_AARCH64)
 				| define_psci_cap(PSCI_MIG_INFO_TYPE);
 }
@@ -843,13 +861,13 @@
 {
 	int rc;
 
-	if (!psci_spd_pm || !psci_spd_pm->svc_migrate_info)
+	if ((psci_spd_pm == NULL) || (psci_spd_pm->svc_migrate_info == NULL))
 		return PSCI_E_NOT_SUPPORTED;
 
 	rc = psci_spd_pm->svc_migrate_info(mpidr);
 
-	assert(rc == PSCI_TOS_UP_MIG_CAP || rc == PSCI_TOS_NOT_UP_MIG_CAP \
-		|| rc == PSCI_TOS_NOT_PRESENT_MP || rc == PSCI_E_NOT_SUPPORTED);
+	assert((rc == PSCI_TOS_UP_MIG_CAP) || (rc == PSCI_TOS_NOT_UP_MIG_CAP) ||
+	       (rc == PSCI_TOS_NOT_PRESENT_MP) || (rc == PSCI_E_NOT_SUPPORTED));
 
 	return rc;
 }
@@ -862,7 +880,7 @@
 void psci_print_power_domain_map(void)
 {
 #if LOG_LEVEL >= LOG_LEVEL_INFO
-	unsigned int idx;
+	int idx;
 	plat_local_state_t state;
 	plat_local_state_type_t state_type;
 
@@ -908,16 +926,16 @@
  *****************************************************************************/
 int psci_secondaries_brought_up(void)
 {
-	unsigned int idx, n_valid = 0;
+	unsigned int idx, n_valid = 0U;
 
-	for (idx = 0; idx < ARRAY_SIZE(psci_cpu_pd_nodes); idx++) {
+	for (idx = 0U; idx < ARRAY_SIZE(psci_cpu_pd_nodes); idx++) {
 		if (psci_cpu_pd_nodes[idx].mpidr != PSCI_INVALID_MPIDR)
 			n_valid++;
 	}
 
-	assert(n_valid);
+	assert(n_valid > 0U);
 
-	return (n_valid > 1);
+	return (n_valid > 1U) ? 1 : 0;
 }
 
 #if ENABLE_PLAT_COMPAT
@@ -964,8 +982,8 @@
 		return PSCI_INVALID_DATA;
 
 	/* Sanity check to verify that the CPU is in CPU_SUSPEND */
-	if (psci_get_aff_info_state_by_idx(cpu_idx) == AFF_STATE_ON &&
-		!is_local_state_run(psci_get_cpu_local_state_by_idx(cpu_idx)))
+	if ((psci_get_aff_info_state_by_idx(cpu_idx) == AFF_STATE_ON) &&
+		(!is_local_state_run(psci_get_cpu_local_state_by_idx(cpu_idx))))
 		return psci_get_pstate_id(psci_power_state_compat[cpu_idx]);
 
 	return PSCI_INVALID_DATA;
diff --git a/lib/psci/psci_main.c b/lib/psci/psci_main.c
index 607d0cd..6a35ff6 100644
--- a/lib/psci/psci_main.c
+++ b/lib/psci/psci_main.c
@@ -82,8 +82,8 @@
 	}
 
 	/* Fast path for CPU standby.*/
-	if (is_cpu_standby_req(is_power_down_state, target_pwrlvl)) {
-		if  (!psci_plat_pm_ops->cpu_standby)
+	if (is_cpu_standby_req(is_power_down_state, target_pwrlvl) != 0) {
+		if  (psci_plat_pm_ops->cpu_standby == NULL)
 			return PSCI_E_INVALID_PARAMS;
 
 		/*
@@ -128,7 +128,7 @@
 	 * If a power down state has been requested, we need to verify entry
 	 * point and program entry information.
 	 */
-	if (is_power_down_state) {
+	if (is_power_down_state != 0U) {
 		rc = psci_validate_entry_point(&ep, entrypoint, context_id);
 		if (rc != PSCI_E_SUCCESS)
 			return rc;
@@ -156,7 +156,7 @@
 	entry_point_info_t ep;
 
 	/* Check if the current CPU is the last ON CPU in the system */
-	if (!psci_is_last_on_cpu())
+	if (psci_is_last_on_cpu() == 0U)
 		return PSCI_E_DENIED;
 
 	/* Validate the entry point and get the entry_point_info */
@@ -171,7 +171,8 @@
 	assert(psci_find_target_suspend_lvl(&state_info) == PLAT_MAX_PWR_LVL);
 	assert(psci_validate_suspend_req(&state_info, PSTATE_TYPE_POWERDOWN)
 						== PSCI_E_SUCCESS);
-	assert(is_local_state_off(state_info.pwr_domain_state[PLAT_MAX_PWR_LVL]));
+	assert(is_local_state_off(
+			state_info.pwr_domain_state[PLAT_MAX_PWR_LVL]) != 0);
 
 	/*
 	 * Do what is needed to enter the system suspend state. This function
@@ -236,7 +237,8 @@
 	 * target CPUs shutdown was not seen by the current CPU's cluster. And
 	 * so the cache may contain stale data for the target CPU.
 	 */
-	flush_cpu_data_by_index(target_idx, psci_svc_cpu_data.aff_info_state);
+	flush_cpu_data_by_index((unsigned int)target_idx,
+				psci_svc_cpu_data.aff_info_state);
 
 	return psci_get_aff_info_state_by_idx(target_idx);
 }
@@ -263,10 +265,10 @@
 	if (rc != PSCI_E_SUCCESS)
 		return PSCI_E_INVALID_PARAMS;
 
-	assert(psci_spd_pm && psci_spd_pm->svc_migrate);
+	assert((psci_spd_pm != NULL) && (psci_spd_pm->svc_migrate != NULL));
 
 	rc = psci_spd_pm->svc_migrate(read_mpidr_el1(), target_cpu);
-	assert(rc == PSCI_E_SUCCESS || rc == PSCI_E_INTERN_FAIL);
+	assert((rc == PSCI_E_SUCCESS) || (rc == PSCI_E_INTERN_FAIL));
 
 	return rc;
 }
@@ -278,7 +280,7 @@
 	return psci_spd_migrate_info(&resident_cpu_mpidr);
 }
 
-long psci_migrate_info_up_cpu(void)
+u_register_t psci_migrate_info_up_cpu(void)
 {
 	u_register_t resident_cpu_mpidr;
 	int rc;
@@ -288,8 +290,8 @@
 	 * psci_spd_migrate_info() returns.
 	 */
 	rc = psci_spd_migrate_info(&resident_cpu_mpidr);
-	if (rc != PSCI_TOS_NOT_UP_MIG_CAP && rc != PSCI_TOS_UP_MIG_CAP)
-		return PSCI_E_INVALID_PARAMS;
+	if ((rc != PSCI_TOS_NOT_UP_MIG_CAP) && (rc != PSCI_TOS_UP_MIG_CAP))
+		return (u_register_t)(register_t) PSCI_E_INVALID_PARAMS;
 
 	return resident_cpu_mpidr;
 }
@@ -312,10 +314,11 @@
 	 * Dispatch this call to platform to query power controller, and pass on
 	 * to the caller what it returns
 	 */
-	assert(psci_plat_pm_ops->get_node_hw_state);
+	assert(psci_plat_pm_ops->get_node_hw_state != NULL);
 	rc = psci_plat_pm_ops->get_node_hw_state(target_cpu, power_level);
-	assert((rc >= HW_ON && rc <= HW_STANDBY) || rc == PSCI_E_NOT_SUPPORTED
-			|| rc == PSCI_E_INVALID_PARAMS);
+	assert(((rc >= HW_ON) && (rc <= HW_STANDBY))
+		|| (rc == PSCI_E_NOT_SUPPORTED)
+		|| (rc == PSCI_E_INVALID_PARAMS));
 	return rc;
 }
 
@@ -337,17 +340,19 @@
 
 
 	/* Check if the psci fid is supported or not */
-	if (!(local_caps & define_psci_cap(psci_fid)))
+	if ((local_caps & define_psci_cap(psci_fid)) == 0U)
 		return PSCI_E_NOT_SUPPORTED;
 
 	/* Format the feature flags */
-	if (psci_fid == PSCI_CPU_SUSPEND_AARCH32 ||
-			psci_fid == PSCI_CPU_SUSPEND_AARCH64) {
+	if ((psci_fid == PSCI_CPU_SUSPEND_AARCH32) ||
+	    (psci_fid == PSCI_CPU_SUSPEND_AARCH64)) {
 		/*
 		 * The trusted firmware does not support OS Initiated Mode.
 		 */
-		return (FF_PSTATE << FF_PSTATE_SHIFT) |
-			((!FF_SUPPORTS_OS_INIT_MODE) << FF_MODE_SUPPORT_SHIFT);
+		unsigned int ret = ((FF_PSTATE << FF_PSTATE_SHIFT) |
+			(((FF_SUPPORTS_OS_INIT_MODE == 1U) ? 0U : 1U)
+				<< FF_MODE_SUPPORT_SHIFT));
+		return (int) ret;
 	}
 
 	/* Return 0 for all other fid's */
@@ -366,50 +371,62 @@
 			  void *handle,
 			  u_register_t flags)
 {
+	u_register_t ret;
+
 	if (is_caller_secure(flags))
-		return SMC_UNK;
+		return (u_register_t)SMC_UNK;
 
 	/* Check the fid against the capabilities */
-	if (!(psci_caps & define_psci_cap(smc_fid)))
-		return SMC_UNK;
+	if ((psci_caps & define_psci_cap(smc_fid)) == 0U)
+		return (u_register_t)SMC_UNK;
 
 	if (((smc_fid >> FUNCID_CC_SHIFT) & FUNCID_CC_MASK) == SMC_32) {
 		/* 32-bit PSCI function, clear top parameter bits */
 
-		x1 = (uint32_t)x1;
-		x2 = (uint32_t)x2;
-		x3 = (uint32_t)x3;
+		uint32_t r1 = (uint32_t)x1;
+		uint32_t r2 = (uint32_t)x2;
+		uint32_t r3 = (uint32_t)x3;
 
 		switch (smc_fid) {
 		case PSCI_VERSION:
-			return psci_version();
+			ret = (u_register_t)psci_version();
+			break;
 
 		case PSCI_CPU_OFF:
-			return psci_cpu_off();
+			ret = (u_register_t)psci_cpu_off();
+			break;
 
 		case PSCI_CPU_SUSPEND_AARCH32:
-			return psci_cpu_suspend(x1, x2, x3);
+			ret = (u_register_t)psci_cpu_suspend(r1, r2, r3);
+			break;
 
 		case PSCI_CPU_ON_AARCH32:
-			return psci_cpu_on(x1, x2, x3);
+			ret = (u_register_t)psci_cpu_on(r1, r2, r3);
+			break;
 
 		case PSCI_AFFINITY_INFO_AARCH32:
-			return psci_affinity_info(x1, x2);
+			ret = (u_register_t)psci_affinity_info(r1, r2);
+			break;
 
 		case PSCI_MIG_AARCH32:
-			return psci_migrate(x1);
+			ret = (u_register_t)psci_migrate(r1);
+			break;
 
 		case PSCI_MIG_INFO_TYPE:
-			return psci_migrate_info_type();
+			ret = (u_register_t)psci_migrate_info_type();
+			break;
 
 		case PSCI_MIG_INFO_UP_CPU_AARCH32:
-			return psci_migrate_info_up_cpu();
+			ret = psci_migrate_info_up_cpu();
+			break;
 
 		case PSCI_NODE_HW_STATE_AARCH32:
-			return psci_node_hw_state(x1, x2);
+			ret = (u_register_t)psci_node_hw_state(r1, r2);
+			break;
 
 		case PSCI_SYSTEM_SUSPEND_AARCH32:
-			return psci_system_suspend(x1, x2);
+			ret = (u_register_t)psci_system_suspend(r1, r2);
+			break;
 
 		case PSCI_SYSTEM_OFF:
 			psci_system_off();
@@ -422,26 +439,34 @@
 			break;
 
 		case PSCI_FEATURES:
-			return psci_features(x1);
+			ret = (u_register_t)psci_features(r1);
+			break;
 
 #if ENABLE_PSCI_STAT
 		case PSCI_STAT_RESIDENCY_AARCH32:
-			return psci_stat_residency(x1, x2);
+			ret = psci_stat_residency(r1, r2);
+			break;
 
 		case PSCI_STAT_COUNT_AARCH32:
-			return psci_stat_count(x1, x2);
+			ret = psci_stat_count(r1, r2);
+			break;
 #endif
 		case PSCI_MEM_PROTECT:
-			return psci_mem_protect(x1);
+			ret = psci_mem_protect(r1);
+			break;
 
 		case PSCI_MEM_CHK_RANGE_AARCH32:
-			return psci_mem_chk_range(x1, x2);
+			ret = psci_mem_chk_range(r1, r2);
+			break;
 
 		case PSCI_SYSTEM_RESET2_AARCH32:
 			/* We should never return from psci_system_reset2() */
-			return psci_system_reset2(x1, x2);
+			ret = psci_system_reset2(r1, r2);
+			break;
 
 		default:
+			WARN("Unimplemented PSCI Call: 0x%x\n", smc_fid);
+			ret = (u_register_t)SMC_UNK;
 			break;
 		}
 	} else {
@@ -449,46 +474,61 @@
 
 		switch (smc_fid) {
 		case PSCI_CPU_SUSPEND_AARCH64:
-			return psci_cpu_suspend(x1, x2, x3);
+			ret = (u_register_t)
+				psci_cpu_suspend((unsigned int)x1, x2, x3);
+			break;
 
 		case PSCI_CPU_ON_AARCH64:
-			return psci_cpu_on(x1, x2, x3);
+			ret = (u_register_t)psci_cpu_on(x1, x2, x3);
+			break;
 
 		case PSCI_AFFINITY_INFO_AARCH64:
-			return psci_affinity_info(x1, x2);
+			ret = (u_register_t)
+				psci_affinity_info(x1, (unsigned int)x2);
+			break;
 
 		case PSCI_MIG_AARCH64:
-			return psci_migrate(x1);
+			ret = (u_register_t)psci_migrate(x1);
+			break;
 
 		case PSCI_MIG_INFO_UP_CPU_AARCH64:
-			return psci_migrate_info_up_cpu();
+			ret = psci_migrate_info_up_cpu();
+			break;
 
 		case PSCI_NODE_HW_STATE_AARCH64:
-			return psci_node_hw_state(x1, x2);
+			ret = (u_register_t)psci_node_hw_state(
+					x1, (unsigned int) x2);
+			break;
 
 		case PSCI_SYSTEM_SUSPEND_AARCH64:
-			return psci_system_suspend(x1, x2);
+			ret = (u_register_t)psci_system_suspend(x1, x2);
+			break;
 
 #if ENABLE_PSCI_STAT
 		case PSCI_STAT_RESIDENCY_AARCH64:
-			return psci_stat_residency(x1, x2);
+			ret = psci_stat_residency(x1, (unsigned int) x2);
+			break;
 
 		case PSCI_STAT_COUNT_AARCH64:
-			return psci_stat_count(x1, x2);
+			ret = psci_stat_count(x1, (unsigned int) x2);
+			break;
 #endif
 
 		case PSCI_MEM_CHK_RANGE_AARCH64:
-			return psci_mem_chk_range(x1, x2);
+			ret = psci_mem_chk_range(x1, x2);
+			break;
 
 		case PSCI_SYSTEM_RESET2_AARCH64:
 			/* We should never return from psci_system_reset2() */
-			return psci_system_reset2(x1, x2);
+			ret = psci_system_reset2((uint32_t) x1, x2);
+			break;
 
 		default:
+			WARN("Unimplemented PSCI Call: 0x%x\n", smc_fid);
+			ret = (u_register_t)SMC_UNK;
 			break;
 		}
 	}
 
-	WARN("Unimplemented PSCI Call: 0x%x \n", smc_fid);
-	return SMC_UNK;
+	return ret;
 }
diff --git a/lib/psci/psci_mem_protect.c b/lib/psci/psci_mem_protect.c
index fca84e9..857146b 100644
--- a/lib/psci/psci_mem_protect.c
+++ b/lib/psci/psci_mem_protect.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2017, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2017-2018, ARM Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -9,30 +9,31 @@
 #include <utils.h>
 #include "psci_private.h"
 
-int psci_mem_protect(unsigned int enable)
+u_register_t psci_mem_protect(unsigned int enable)
 {
 	int val;
 
-	assert(psci_plat_pm_ops->read_mem_protect);
-	assert(psci_plat_pm_ops->write_mem_protect);
+	assert(psci_plat_pm_ops->read_mem_protect != NULL);
+	assert(psci_plat_pm_ops->write_mem_protect != NULL);
 
 	if (psci_plat_pm_ops->read_mem_protect(&val) < 0)
-		return PSCI_E_NOT_SUPPORTED;
+		return (u_register_t) PSCI_E_NOT_SUPPORTED;
 	if (psci_plat_pm_ops->write_mem_protect(enable) < 0)
-		return PSCI_E_NOT_SUPPORTED;
+		return (u_register_t) PSCI_E_NOT_SUPPORTED;
 
-	return val != 0;
+	return (val != 0) ? 1U : 0U;
 }
 
-int psci_mem_chk_range(uintptr_t base, u_register_t length)
+u_register_t psci_mem_chk_range(uintptr_t base, u_register_t length)
 {
 	int ret;
 
-	assert(psci_plat_pm_ops->mem_protect_chk);
+	assert(psci_plat_pm_ops->mem_protect_chk != NULL);
 
-	if (length == 0 || check_uptr_overflow(base, length-1))
-		return PSCI_E_DENIED;
+	if ((length == 0U) || check_uptr_overflow(base, length - 1U))
+		return (u_register_t) PSCI_E_DENIED;
 
 	ret = psci_plat_pm_ops->mem_protect_chk(base, length);
-	return (ret < 0) ? PSCI_E_DENIED : PSCI_E_SUCCESS;
+	return (ret < 0) ?
+	       (u_register_t) PSCI_E_DENIED : (u_register_t) PSCI_E_SUCCESS;
 }
diff --git a/lib/psci/psci_off.c b/lib/psci/psci_off.c
index 231deea..944f8bf 100644
--- a/lib/psci/psci_off.c
+++ b/lib/psci/psci_off.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2013-2017, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2013-2018, ARM Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -40,14 +40,15 @@
  ******************************************************************************/
 int psci_do_cpu_off(unsigned int end_pwrlvl)
 {
-	int rc = PSCI_E_SUCCESS, idx = plat_my_core_pos();
+	int rc = PSCI_E_SUCCESS;
+	int idx = (int) plat_my_core_pos();
 	psci_power_state_t state_info;
 
 	/*
 	 * This function must only be called on platforms where the
 	 * CPU_OFF platform hooks have been implemented.
 	 */
-	assert(psci_plat_pm_ops->pwr_domain_off);
+	assert(psci_plat_pm_ops->pwr_domain_off != NULL);
 
 	/* Construct the psci_power_state for CPU_OFF */
 	psci_set_power_off_state(&state_info);
@@ -57,17 +58,16 @@
 	 * level so that by the time all locks are taken, the system topology
 	 * is snapshot and state management can be done safely.
 	 */
-	psci_acquire_pwr_domain_locks(end_pwrlvl,
-				      idx);
+	psci_acquire_pwr_domain_locks(end_pwrlvl, idx);
 
 	/*
 	 * Call the cpu off handler registered by the Secure Payload Dispatcher
 	 * to let it do any bookkeeping. Assume that the SPD always reports an
 	 * E_DENIED error if SP refuse to power down
 	 */
-	if (psci_spd_pm && psci_spd_pm->svc_off) {
+	if ((psci_spd_pm != NULL) && (psci_spd_pm->svc_off != NULL)) {
 		rc = psci_spd_pm->svc_off(0);
-		if (rc)
+		if (rc != 0)
 			goto exit;
 	}
 
@@ -120,8 +120,7 @@
 	 * Release the locks corresponding to each power level in the
 	 * reverse order to which they were acquired.
 	 */
-	psci_release_pwr_domain_locks(end_pwrlvl,
-				      idx);
+	psci_release_pwr_domain_locks(end_pwrlvl, idx);
 
 	/*
 	 * Check if all actions needed to safely power down this cpu have
@@ -154,7 +153,7 @@
 		    PMF_NO_CACHE_MAINT);
 #endif
 
-		if (psci_plat_pm_ops->pwr_domain_pwr_down_wfi) {
+		if (psci_plat_pm_ops->pwr_domain_pwr_down_wfi != NULL) {
 			/* This function must not return */
 			psci_plat_pm_ops->pwr_domain_pwr_down_wfi(&state_info);
 		} else {
diff --git a/lib/psci/psci_on.c b/lib/psci/psci_on.c
index 53b044e..f38900c 100644
--- a/lib/psci/psci_on.c
+++ b/lib/psci/psci_on.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2013-2017, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2013-2018, ARM Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -15,6 +15,19 @@
 #include <stddef.h>
 #include "psci_private.h"
 
+/*
+ * Helper functions for the CPU level spinlocks
+ */
+static inline void psci_spin_lock_cpu(int idx)
+{
+	spin_lock(&psci_cpu_pd_nodes[idx].cpu_lock);
+}
+
+static inline void psci_spin_unlock_cpu(int idx)
+{
+	spin_unlock(&psci_cpu_pd_nodes[idx].cpu_lock);
+}
+
 /*******************************************************************************
  * This function checks whether a cpu which has been requested to be turned on
  * is OFF to begin with.
@@ -42,22 +55,22 @@
  * platform handler as it can return error.
  ******************************************************************************/
 int psci_cpu_on_start(u_register_t target_cpu,
-		      entry_point_info_t *ep)
+		      const entry_point_info_t *ep)
 {
 	int rc;
-	unsigned int target_idx = plat_core_pos_by_mpidr(target_cpu);
 	aff_info_state_t target_aff_state;
+	int target_idx = plat_core_pos_by_mpidr(target_cpu);
 
 	/* Calling function must supply valid input arguments */
-	assert((int) target_idx >= 0);
+	assert(target_idx >= 0);
 	assert(ep != NULL);
 
 	/*
 	 * This function must only be called on platforms where the
 	 * CPU_ON platform hooks have been implemented.
 	 */
-	assert(psci_plat_pm_ops->pwr_domain_on &&
-			psci_plat_pm_ops->pwr_domain_on_finish);
+	assert((psci_plat_pm_ops->pwr_domain_on != NULL) &&
+	       (psci_plat_pm_ops->pwr_domain_on_finish != NULL));
 
 	/* Protect against multiple CPUs trying to turn ON the same target CPU */
 	psci_spin_lock_cpu(target_idx);
@@ -78,7 +91,8 @@
 	 * target CPUs shutdown was not seen by the current CPU's cluster. And
 	 * so the cache may contain stale data for the target CPU.
 	 */
-	flush_cpu_data_by_index(target_idx, psci_svc_cpu_data.aff_info_state);
+	flush_cpu_data_by_index((unsigned int)target_idx,
+				psci_svc_cpu_data.aff_info_state);
 	rc = cpu_on_validate_state(psci_get_aff_info_state_by_idx(target_idx));
 	if (rc != PSCI_E_SUCCESS)
 		goto exit;
@@ -88,7 +102,7 @@
 	 * to let it do any bookeeping. If the handler encounters an error, it's
 	 * expected to assert within
 	 */
-	if (psci_spd_pm && psci_spd_pm->svc_on)
+	if ((psci_spd_pm != NULL) && (psci_spd_pm->svc_on != NULL))
 		psci_spd_pm->svc_on(target_cpu);
 
 	/*
@@ -97,7 +111,8 @@
 	 * turned OFF.
 	 */
 	psci_set_aff_info_state_by_idx(target_idx, AFF_STATE_ON_PENDING);
-	flush_cpu_data_by_index(target_idx, psci_svc_cpu_data.aff_info_state);
+	flush_cpu_data_by_index((unsigned int)target_idx,
+				psci_svc_cpu_data.aff_info_state);
 
 	/*
 	 * The cache line invalidation by the target CPU after setting the
@@ -109,9 +124,11 @@
 	if (target_aff_state != AFF_STATE_ON_PENDING) {
 		assert(target_aff_state == AFF_STATE_OFF);
 		psci_set_aff_info_state_by_idx(target_idx, AFF_STATE_ON_PENDING);
-		flush_cpu_data_by_index(target_idx, psci_svc_cpu_data.aff_info_state);
+		flush_cpu_data_by_index((unsigned int)target_idx,
+					psci_svc_cpu_data.aff_info_state);
 
-		assert(psci_get_aff_info_state_by_idx(target_idx) == AFF_STATE_ON_PENDING);
+		assert(psci_get_aff_info_state_by_idx(target_idx) ==
+		       AFF_STATE_ON_PENDING);
 	}
 
 	/*
@@ -123,15 +140,16 @@
 	 * steps to power on.
 	 */
 	rc = psci_plat_pm_ops->pwr_domain_on(target_cpu);
-	assert(rc == PSCI_E_SUCCESS || rc == PSCI_E_INTERN_FAIL);
+	assert((rc == PSCI_E_SUCCESS) || (rc == PSCI_E_INTERN_FAIL));
 
 	if (rc == PSCI_E_SUCCESS)
 		/* Store the re-entry information for the non-secure world. */
-		cm_init_context_by_index(target_idx, ep);
+		cm_init_context_by_index((unsigned int)target_idx, ep);
 	else {
 		/* Restore the state on error. */
 		psci_set_aff_info_state_by_idx(target_idx, AFF_STATE_OFF);
-		flush_cpu_data_by_index(target_idx, psci_svc_cpu_data.aff_info_state);
+		flush_cpu_data_by_index((unsigned int)target_idx,
+					psci_svc_cpu_data.aff_info_state);
 	}
 
 exit:
@@ -144,8 +162,7 @@
  * are called by the common finisher routine in psci_common.c. The `state_info`
  * is the psci_power_state from which this CPU has woken up from.
  ******************************************************************************/
-void psci_cpu_on_finish(unsigned int cpu_idx,
-			psci_power_state_t *state_info)
+void psci_cpu_on_finish(int cpu_idx, const psci_power_state_t *state_info)
 {
 	/*
 	 * Plat. management: Perform the platform specific actions
@@ -186,7 +203,7 @@
 	 * Dispatcher to let it do any bookeeping. If the handler encounters an
 	 * error, it's expected to assert within
 	 */
-	if (psci_spd_pm && psci_spd_pm->svc_on_finish)
+	if ((psci_spd_pm != NULL) && (psci_spd_pm->svc_on_finish != NULL))
 		psci_spd_pm->svc_on_finish(0);
 
 	PUBLISH_EVENT(psci_cpu_on_finish);
diff --git a/lib/psci/psci_private.h b/lib/psci/psci_private.h
index d452e2a..2ea9f76 100644
--- a/lib/psci/psci_private.h
+++ b/lib/psci/psci_private.h
@@ -4,70 +4,17 @@
  * SPDX-License-Identifier: BSD-3-Clause
  */
 
-#ifndef __PSCI_PRIVATE_H__
-#define __PSCI_PRIVATE_H__
+#ifndef PSCI_PRIVATE_H
+#define PSCI_PRIVATE_H
 
 #include <arch.h>
+#include <arch_helpers.h>
 #include <bakery_lock.h>
 #include <bl_common.h>
 #include <cpu_data.h>
 #include <psci.h>
 #include <spinlock.h>
 
-#if HW_ASSISTED_COHERENCY
-
-/*
- * On systems with hardware-assisted coherency, make PSCI cache operations NOP,
- * as PSCI participants are cache-coherent, and there's no need for explicit
- * cache maintenance operations or barriers to coordinate their state.
- */
-#define psci_flush_dcache_range(addr, size)
-#define psci_flush_cpu_data(member)
-#define psci_inv_cpu_data(member)
-
-#define psci_dsbish()
-
-/*
- * On systems where participant CPUs are cache-coherent, we can use spinlocks
- * instead of bakery locks.
- */
-#define DEFINE_PSCI_LOCK(_name)		spinlock_t _name
-#define DECLARE_PSCI_LOCK(_name)	extern DEFINE_PSCI_LOCK(_name)
-
-#define psci_lock_get(non_cpu_pd_node)				\
-	spin_lock(&psci_locks[(non_cpu_pd_node)->lock_index])
-#define psci_lock_release(non_cpu_pd_node)			\
-	spin_unlock(&psci_locks[(non_cpu_pd_node)->lock_index])
-
-#else
-
-/*
- * If not all PSCI participants are cache-coherent, perform cache maintenance
- * and issue barriers wherever required to coordinate state.
- */
-#define psci_flush_dcache_range(addr, size)	flush_dcache_range(addr, size)
-#define psci_flush_cpu_data(member)		flush_cpu_data(member)
-#define psci_inv_cpu_data(member)		inv_cpu_data(member)
-
-#define psci_dsbish()				dsbish()
-
-/*
- * Use bakery locks for state coordination as not all PSCI participants are
- * cache coherent.
- */
-#define DEFINE_PSCI_LOCK(_name)		DEFINE_BAKERY_LOCK(_name)
-#define DECLARE_PSCI_LOCK(_name)	DECLARE_BAKERY_LOCK(_name)
-
-#define psci_lock_get(non_cpu_pd_node)				\
-	bakery_lock_get(&psci_locks[(non_cpu_pd_node)->lock_index])
-#define psci_lock_release(non_cpu_pd_node)			\
-	bakery_lock_release(&psci_locks[(non_cpu_pd_node)->lock_index])
-
-#endif
-
-#define psci_lock_init(_non_cpu_pd_node, _idx)			\
-	((_non_cpu_pd_node)[(_idx)].lock_index = (_idx))
-
 /*
  * The PSCI capability which are provided by the generic code but does not
  * depend on the platform or spd capabilities.
@@ -94,37 +41,63 @@
 			define_psci_cap(PSCI_MEM_CHK_RANGE_AARCH64))
 
 /*
- * Helper macros to get/set the fields of PSCI per-cpu data.
+ * Helper functions to get/set the fields of PSCI per-cpu data.
  */
-#define psci_set_aff_info_state(_aff_state) \
-		set_cpu_data(psci_svc_cpu_data.aff_info_state, _aff_state)
-#define psci_get_aff_info_state() \
-		get_cpu_data(psci_svc_cpu_data.aff_info_state)
-#define psci_get_aff_info_state_by_idx(_idx) \
-		get_cpu_data_by_index(_idx, psci_svc_cpu_data.aff_info_state)
-#define psci_set_aff_info_state_by_idx(_idx, _aff_state) \
-		set_cpu_data_by_index(_idx, psci_svc_cpu_data.aff_info_state,\
-					_aff_state)
-#define psci_get_suspend_pwrlvl() \
-		get_cpu_data(psci_svc_cpu_data.target_pwrlvl)
-#define psci_set_suspend_pwrlvl(_target_lvl) \
-		set_cpu_data(psci_svc_cpu_data.target_pwrlvl, _target_lvl)
-#define psci_set_cpu_local_state(_state) \
-		set_cpu_data(psci_svc_cpu_data.local_state, _state)
-#define psci_get_cpu_local_state() \
-		get_cpu_data(psci_svc_cpu_data.local_state)
-#define psci_get_cpu_local_state_by_idx(_idx) \
-		get_cpu_data_by_index(_idx, psci_svc_cpu_data.local_state)
+static inline void psci_set_aff_info_state(aff_info_state_t aff_state)
+{
+	set_cpu_data(psci_svc_cpu_data.aff_info_state, aff_state);
+}
 
-/*
- * Helper macros for the CPU level spinlocks
- */
-#define psci_spin_lock_cpu(_idx) spin_lock(&psci_cpu_pd_nodes[_idx].cpu_lock)
-#define psci_spin_unlock_cpu(_idx) spin_unlock(&psci_cpu_pd_nodes[_idx].cpu_lock)
+static inline aff_info_state_t psci_get_aff_info_state(void)
+{
+	return get_cpu_data(psci_svc_cpu_data.aff_info_state);
+}
 
-/* Helper macro to identify a CPU standby request in PSCI Suspend call */
-#define is_cpu_standby_req(_is_power_down_state, _retn_lvl) \
-		(((!(_is_power_down_state)) && ((_retn_lvl) == 0)) ? 1 : 0)
+static inline aff_info_state_t psci_get_aff_info_state_by_idx(int idx)
+{
+	return get_cpu_data_by_index((unsigned int)idx,
+				     psci_svc_cpu_data.aff_info_state);
+}
+
+static inline void psci_set_aff_info_state_by_idx(int idx,
+						  aff_info_state_t aff_state)
+{
+	set_cpu_data_by_index((unsigned int)idx,
+			      psci_svc_cpu_data.aff_info_state, aff_state);
+}
+
+static inline unsigned int psci_get_suspend_pwrlvl(void)
+{
+	return get_cpu_data(psci_svc_cpu_data.target_pwrlvl);
+}
+
+static inline void psci_set_suspend_pwrlvl(unsigned int target_lvl)
+{
+	set_cpu_data(psci_svc_cpu_data.target_pwrlvl, target_lvl);
+}
+
+static inline void psci_set_cpu_local_state(plat_local_state_t state)
+{
+	set_cpu_data(psci_svc_cpu_data.local_state, state);
+}
+
+static inline plat_local_state_t psci_get_cpu_local_state(void)
+{
+	return get_cpu_data(psci_svc_cpu_data.local_state);
+}
+
+static inline plat_local_state_t psci_get_cpu_local_state_by_idx(int idx)
+{
+	return get_cpu_data_by_index((unsigned int)idx,
+				     psci_svc_cpu_data.local_state);
+}
+
+/* Helper function to identify a CPU standby request in PSCI Suspend call */
+static inline int is_cpu_standby_req(unsigned int is_power_down_state,
+				     unsigned int retn_lvl)
+{
+	return ((is_power_down_state == 0U) && (retn_lvl == 0U)) ? 1 : 0;
+}
 
 /*******************************************************************************
  * The following two data structures implement the power domain tree. The tree
@@ -138,7 +111,7 @@
 	 * Index of the first CPU power domain node level 0 which has this node
 	 * as its parent.
 	 */
-	unsigned int cpu_start_idx;
+	int cpu_start_idx;
 
 	/*
 	 * Number of CPU power domains which are siblings of the domain indexed
@@ -180,6 +153,95 @@
 } cpu_pd_node_t;
 
 /*******************************************************************************
+ * The following are helpers and declarations of locks.
+ ******************************************************************************/
+#if HW_ASSISTED_COHERENCY
+/*
+ * On systems where participant CPUs are cache-coherent, we can use spinlocks
+ * instead of bakery locks.
+ */
+#define DEFINE_PSCI_LOCK(_name)		spinlock_t _name
+#define DECLARE_PSCI_LOCK(_name)	extern DEFINE_PSCI_LOCK(_name)
+
+/* One lock is required per non-CPU power domain node */
+DECLARE_PSCI_LOCK(psci_locks[PSCI_NUM_NON_CPU_PWR_DOMAINS]);
+
+/*
+ * On systems with hardware-assisted coherency, make PSCI cache operations NOP,
+ * as PSCI participants are cache-coherent, and there's no need for explicit
+ * cache maintenance operations or barriers to coordinate their state.
+ */
+static inline void psci_flush_dcache_range(uintptr_t __unused addr,
+					   size_t __unused size)
+{
+	/* Empty */
+}
+
+#define psci_flush_cpu_data(member)
+#define psci_inv_cpu_data(member)
+
+static inline void psci_dsbish(void)
+{
+	/* Empty */
+}
+
+static inline void psci_lock_get(non_cpu_pd_node_t *non_cpu_pd_node)
+{
+	spin_lock(&psci_locks[non_cpu_pd_node->lock_index]);
+}
+
+static inline void psci_lock_release(non_cpu_pd_node_t *non_cpu_pd_node)
+{
+	spin_unlock(&psci_locks[non_cpu_pd_node->lock_index]);
+}
+
+#else /* if HW_ASSISTED_COHERENCY == 0 */
+/*
+ * Use bakery locks for state coordination as not all PSCI participants are
+ * cache coherent.
+ */
+#define DEFINE_PSCI_LOCK(_name)		DEFINE_BAKERY_LOCK(_name)
+#define DECLARE_PSCI_LOCK(_name)	DECLARE_BAKERY_LOCK(_name)
+
+/* One lock is required per non-CPU power domain node */
+DECLARE_PSCI_LOCK(psci_locks[PSCI_NUM_NON_CPU_PWR_DOMAINS]);
+
+/*
+ * If not all PSCI participants are cache-coherent, perform cache maintenance
+ * and issue barriers wherever required to coordinate state.
+ */
+static inline void psci_flush_dcache_range(uintptr_t addr, size_t size)
+{
+	flush_dcache_range(addr, size);
+}
+
+#define psci_flush_cpu_data(member)		flush_cpu_data(member)
+#define psci_inv_cpu_data(member)		inv_cpu_data(member)
+
+static inline void psci_dsbish(void)
+{
+	dsbish();
+}
+
+static inline void psci_lock_get(non_cpu_pd_node_t *non_cpu_pd_node)
+{
+	bakery_lock_get(&psci_locks[non_cpu_pd_node->lock_index]);
+}
+
+static inline void psci_lock_release(non_cpu_pd_node_t *non_cpu_pd_node)
+{
+	bakery_lock_release(&psci_locks[non_cpu_pd_node->lock_index]);
+}
+
+#endif /* HW_ASSISTED_COHERENCY */
+
+static inline void psci_lock_init(non_cpu_pd_node_t *non_cpu_pd_node,
+				  unsigned char idx)
+{
+	non_cpu_pd_node[idx].lock_index = idx;
+}
+
+/*******************************************************************************
  * Data prototypes
  ******************************************************************************/
 extern const plat_psci_ops_t *psci_plat_pm_ops;
@@ -187,9 +249,6 @@
 extern cpu_pd_node_t psci_cpu_pd_nodes[PLATFORM_CORE_COUNT];
 extern unsigned int psci_caps;
 
-/* One lock is required per non-CPU power domain node */
-DECLARE_PSCI_LOCK(psci_locks[PSCI_NUM_NON_CPU_PWR_DOMAINS]);
-
 /*******************************************************************************
  * SPD's power management hooks registered with PSCI
  ******************************************************************************/
@@ -208,15 +267,13 @@
 				      psci_power_state_t *target_state);
 int psci_validate_entry_point(entry_point_info_t *ep,
 			uintptr_t entrypoint, u_register_t context_id);
-void psci_get_parent_pwr_domain_nodes(unsigned int cpu_idx,
+void psci_get_parent_pwr_domain_nodes(int cpu_idx,
 				      unsigned int end_lvl,
-				      unsigned int node_index[]);
+				      unsigned int *node_index);
 void psci_do_state_coordination(unsigned int end_pwrlvl,
 				psci_power_state_t *state_info);
-void psci_acquire_pwr_domain_locks(unsigned int end_pwrlvl,
-				   unsigned int cpu_idx);
-void psci_release_pwr_domain_locks(unsigned int end_pwrlvl,
-				   unsigned int cpu_idx);
+void psci_acquire_pwr_domain_locks(unsigned int end_pwrlvl, int cpu_idx);
+void psci_release_pwr_domain_locks(unsigned int end_pwrlvl, int cpu_idx);
 int psci_validate_suspend_req(const psci_power_state_t *state_info,
 			      unsigned int is_power_down_state);
 unsigned int psci_find_max_off_lvl(const psci_power_state_t *state_info);
@@ -236,22 +293,20 @@
 
 /* Private exported functions from psci_on.c */
 int psci_cpu_on_start(u_register_t target_cpu,
-		      entry_point_info_t *ep);
+		      const entry_point_info_t *ep);
 
-void psci_cpu_on_finish(unsigned int cpu_idx,
-			psci_power_state_t *state_info);
+void psci_cpu_on_finish(int cpu_idx, const psci_power_state_t *state_info);
 
 /* Private exported functions from psci_off.c */
 int psci_do_cpu_off(unsigned int end_pwrlvl);
 
 /* Private exported functions from psci_suspend.c */
-void psci_cpu_suspend_start(entry_point_info_t *ep,
+void psci_cpu_suspend_start(const entry_point_info_t *ep,
 			unsigned int end_pwrlvl,
 			psci_power_state_t *state_info,
 			unsigned int is_power_down_state);
 
-void psci_cpu_suspend_finish(unsigned int cpu_idx,
-			psci_power_state_t *state_info);
+void psci_cpu_suspend_finish(int cpu_idx, const psci_power_state_t *state_info);
 
 /* Private exported functions from psci_helpers.S */
 void psci_do_pwrdown_cache_maintenance(unsigned int pwr_level);
@@ -260,7 +315,7 @@
 /* Private exported functions from psci_system_off.c */
 void __dead2 psci_system_off(void);
 void __dead2 psci_system_reset(void);
-int psci_system_reset2(uint32_t reset_type, u_register_t cookie);
+u_register_t psci_system_reset2(uint32_t reset_type, u_register_t cookie);
 
 /* Private exported functions from psci_stat.c */
 void psci_stats_update_pwr_down(unsigned int end_pwrlvl,
@@ -273,7 +328,7 @@
 			unsigned int power_state);
 
 /* Private exported functions from psci_mem_protect.c */
-int psci_mem_protect(unsigned int enable);
-int psci_mem_chk_range(uintptr_t base, u_register_t length);
+u_register_t psci_mem_protect(unsigned int enable);
+u_register_t psci_mem_chk_range(uintptr_t base, u_register_t length);
 
-#endif /* __PSCI_PRIVATE_H__ */
+#endif /* PSCI_PRIVATE_H */
diff --git a/lib/psci/psci_setup.c b/lib/psci/psci_setup.c
index c00bd94..e59e163 100644
--- a/lib/psci/psci_setup.c
+++ b/lib/psci/psci_setup.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2013-2017, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2013-2018, ARM Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -32,9 +32,9 @@
  * Function which initializes the 'psci_non_cpu_pd_nodes' or the
  * 'psci_cpu_pd_nodes' corresponding to the power level.
  ******************************************************************************/
-static void psci_init_pwr_domain_node(unsigned int node_idx,
+static void psci_init_pwr_domain_node(unsigned char node_idx,
 					unsigned int parent_idx,
-					unsigned int level)
+					unsigned char level)
 {
 	if (level > PSCI_CPU_PWR_LVL) {
 		psci_non_cpu_pd_nodes[node_idx].level = level;
@@ -82,15 +82,15 @@
  *******************************************************************************/
 static void psci_update_pwrlvl_limits(void)
 {
-	int j;
+	int j, cpu_idx;
 	unsigned int nodes_idx[PLAT_MAX_PWR_LVL] = {0};
-	unsigned int temp_index[PLAT_MAX_PWR_LVL], cpu_idx;
+	unsigned int temp_index[PLAT_MAX_PWR_LVL];
 
 	for (cpu_idx = 0; cpu_idx < PLATFORM_CORE_COUNT; cpu_idx++) {
 		psci_get_parent_pwr_domain_nodes(cpu_idx,
-						 PLAT_MAX_PWR_LVL,
+						 (unsigned int)PLAT_MAX_PWR_LVL,
 						 temp_index);
-		for (j = PLAT_MAX_PWR_LVL - 1; j >= 0; j--) {
+		for (j = (int) PLAT_MAX_PWR_LVL - 1; j >= 0; j--) {
 			if (temp_index[j] != nodes_idx[j]) {
 				nodes_idx[j] = temp_index[j];
 				psci_non_cpu_pd_nodes[nodes_idx[j]].cpu_start_idx
@@ -109,9 +109,10 @@
  ******************************************************************************/
 static void populate_power_domain_tree(const unsigned char *topology)
 {
-	unsigned int i, j = 0, num_nodes_at_lvl = 1, num_nodes_at_next_lvl;
-	unsigned int node_index = 0, parent_node_index = 0, num_children;
-	int level = PLAT_MAX_PWR_LVL;
+	unsigned int i, j = 0U, num_nodes_at_lvl = 1U, num_nodes_at_next_lvl;
+	unsigned int node_index = 0U, num_children;
+	int parent_node_index = 0;
+	int level = (int) PLAT_MAX_PWR_LVL;
 
 	/*
 	 * For each level the inputs are:
@@ -122,8 +123,8 @@
 	 * - Index of first free entry in psci_non_cpu_pd_nodes[] or
 	 *   psci_cpu_pd_nodes[] i.e. node_index depending upon the level.
 	 */
-	while (level >= PSCI_CPU_PWR_LVL) {
-		num_nodes_at_next_lvl = 0;
+	while (level >= (int) PSCI_CPU_PWR_LVL) {
+		num_nodes_at_next_lvl = 0U;
 		/*
 		 * For each entry (parent node) at this level in the plat_array:
 		 * - Find the number of children
@@ -132,16 +133,16 @@
 		 * - Increment parent_node_index to point to the next parent
 		 * - Accumulate the number of children at next level.
 		 */
-		for (i = 0; i < num_nodes_at_lvl; i++) {
+		for (i = 0U; i < num_nodes_at_lvl; i++) {
 			assert(parent_node_index <=
 					PSCI_NUM_NON_CPU_PWR_DOMAINS);
 			num_children = topology[parent_node_index];
 
 			for (j = node_index;
-				j < node_index + num_children; j++)
-				psci_init_pwr_domain_node(j,
+				j < (node_index + num_children); j++)
+				psci_init_pwr_domain_node((unsigned char)j,
 							  parent_node_index - 1,
-							  level);
+							  (unsigned char)level);
 
 			node_index = j;
 			num_nodes_at_next_lvl += num_children;
@@ -152,12 +153,12 @@
 		level--;
 
 		/* Reset the index for the cpu power domain array */
-		if (level == PSCI_CPU_PWR_LVL)
+		if (level == (int) PSCI_CPU_PWR_LVL)
 			node_index = 0;
 	}
 
 	/* Validate the sanity of array exported by the platform */
-	assert(j == PLATFORM_CORE_COUNT);
+	assert((int) j == PLATFORM_CORE_COUNT);
 }
 
 /*******************************************************************************
@@ -213,8 +214,9 @@
 	 */
 	psci_set_pwr_domains_to_run(PLAT_MAX_PWR_LVL);
 
-	plat_setup_psci_ops((uintptr_t)lib_args->mailbox_ep, &psci_plat_pm_ops);
-	assert(psci_plat_pm_ops);
+	(void) plat_setup_psci_ops((uintptr_t)lib_args->mailbox_ep,
+				   &psci_plat_pm_ops);
+	assert(psci_plat_pm_ops != NULL);
 
 	/*
 	 * Flush `psci_plat_pm_ops` as it will be accessed by secondary CPUs
@@ -226,29 +228,29 @@
 	/* Initialize the psci capability */
 	psci_caps = PSCI_GENERIC_CAP;
 
-	if (psci_plat_pm_ops->pwr_domain_off)
+	if (psci_plat_pm_ops->pwr_domain_off != NULL)
 		psci_caps |=  define_psci_cap(PSCI_CPU_OFF);
-	if (psci_plat_pm_ops->pwr_domain_on &&
-			psci_plat_pm_ops->pwr_domain_on_finish)
+	if ((psci_plat_pm_ops->pwr_domain_on != NULL) &&
+	    (psci_plat_pm_ops->pwr_domain_on_finish != NULL))
 		psci_caps |=  define_psci_cap(PSCI_CPU_ON_AARCH64);
-	if (psci_plat_pm_ops->pwr_domain_suspend &&
-			psci_plat_pm_ops->pwr_domain_suspend_finish) {
+	if ((psci_plat_pm_ops->pwr_domain_suspend != NULL) &&
+	    (psci_plat_pm_ops->pwr_domain_suspend_finish != NULL)) {
 		psci_caps |=  define_psci_cap(PSCI_CPU_SUSPEND_AARCH64);
-		if (psci_plat_pm_ops->get_sys_suspend_power_state)
+		if (psci_plat_pm_ops->get_sys_suspend_power_state != NULL)
 			psci_caps |=  define_psci_cap(PSCI_SYSTEM_SUSPEND_AARCH64);
 	}
-	if (psci_plat_pm_ops->system_off)
+	if (psci_plat_pm_ops->system_off != NULL)
 		psci_caps |=  define_psci_cap(PSCI_SYSTEM_OFF);
-	if (psci_plat_pm_ops->system_reset)
+	if (psci_plat_pm_ops->system_reset != NULL)
 		psci_caps |=  define_psci_cap(PSCI_SYSTEM_RESET);
-	if (psci_plat_pm_ops->get_node_hw_state)
+	if (psci_plat_pm_ops->get_node_hw_state != NULL)
 		psci_caps |= define_psci_cap(PSCI_NODE_HW_STATE_AARCH64);
-	if (psci_plat_pm_ops->read_mem_protect &&
-			psci_plat_pm_ops->write_mem_protect)
+	if ((psci_plat_pm_ops->read_mem_protect != NULL) &&
+			(psci_plat_pm_ops->write_mem_protect != NULL))
 		psci_caps |= define_psci_cap(PSCI_MEM_PROTECT);
-	if (psci_plat_pm_ops->mem_protect_chk)
+	if (psci_plat_pm_ops->mem_protect_chk != NULL)
 		psci_caps |= define_psci_cap(PSCI_MEM_CHK_RANGE_AARCH64);
-	if (psci_plat_pm_ops->system_reset2)
+	if (psci_plat_pm_ops->system_reset2 != NULL)
 		psci_caps |= define_psci_cap(PSCI_SYSTEM_RESET2_AARCH64);
 
 #if ENABLE_PSCI_STAT
@@ -266,7 +268,7 @@
  ******************************************************************************/
 void psci_arch_setup(void)
 {
-#if ARM_ARCH_MAJOR > 7 || defined(ARMV7_SUPPORTS_GENERIC_TIMER)
+#if (ARM_ARCH_MAJOR > 7) || defined(ARMV7_SUPPORTS_GENERIC_TIMER)
 	/* Program the counter frequency */
 	write_cntfrq_el0(plat_get_syscnt_freq2());
 #endif
diff --git a/lib/psci/psci_stat.c b/lib/psci/psci_stat.c
index e925d34..421db44 100644
--- a/lib/psci/psci_stat.c
+++ b/lib/psci/psci_stat.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2016-2017, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2016-2018, ARM Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -11,7 +11,7 @@
 #include "psci_private.h"
 
 #ifndef PLAT_MAX_PWR_LVL_STATES
-#define PLAT_MAX_PWR_LVL_STATES 2
+#define PLAT_MAX_PWR_LVL_STATES		2U
 #endif
 
 /* Following structure is used for PSCI STAT */
@@ -25,7 +25,7 @@
  * that goes to power down in non cpu power domains.
  */
 static int last_cpu_in_non_cpu_pd[PSCI_NUM_NON_CPU_PWR_DOMAINS] = {
-		[0 ... PSCI_NUM_NON_CPU_PWR_DOMAINS-1] = -1};
+		[0 ... PSCI_NUM_NON_CPU_PWR_DOMAINS - 1] = -1};
 
 /*
  * Following are used to store PSCI STAT values for
@@ -41,21 +41,21 @@
  * local power state and power domain level. If the platform implements the
  * `get_pwr_lvl_state_idx` pm hook, then that will be used to return the index.
  */
-static int get_stat_idx(plat_local_state_t local_state, int pwr_lvl)
+static int get_stat_idx(plat_local_state_t local_state, unsigned int pwr_lvl)
 {
 	int idx;
 
 	if (psci_plat_pm_ops->get_pwr_lvl_state_idx == NULL) {
-		assert(PLAT_MAX_PWR_LVL_STATES == 2);
-		if (is_local_state_retn(local_state))
+		assert(PLAT_MAX_PWR_LVL_STATES == 2U);
+		if (is_local_state_retn(local_state) != 0)
 			return 0;
 
-		assert(is_local_state_off(local_state));
+		assert(is_local_state_off(local_state) != 0);
 		return 1;
 	}
 
 	idx = psci_plat_pm_ops->get_pwr_lvl_state_idx(local_state, pwr_lvl);
-	assert((idx >= 0) && (idx < PLAT_MAX_PWR_LVL_STATES));
+	assert((idx >= 0) && (idx < (int) PLAT_MAX_PWR_LVL_STATES));
 	return idx;
 }
 
@@ -73,17 +73,18 @@
 void psci_stats_update_pwr_down(unsigned int end_pwrlvl,
 			const psci_power_state_t *state_info)
 {
-	unsigned int lvl, parent_idx, cpu_idx = plat_my_core_pos();
+	unsigned int lvl, parent_idx;
+	int cpu_idx = (int) plat_my_core_pos();
 
 	assert(end_pwrlvl <= PLAT_MAX_PWR_LVL);
-	assert(state_info);
+	assert(state_info != NULL);
 
 	parent_idx = psci_cpu_pd_nodes[cpu_idx].parent_node;
 
-	for (lvl = PSCI_CPU_PWR_LVL + 1; lvl <= end_pwrlvl; lvl++) {
+	for (lvl = PSCI_CPU_PWR_LVL + 1U; lvl <= end_pwrlvl; lvl++) {
 
 		/* Break early if the target power state is RUN */
-		if (is_local_state_run(state_info->pwr_domain_state[lvl]))
+		if (is_local_state_run(state_info->pwr_domain_state[lvl]) != 0)
 			break;
 
 		/*
@@ -105,13 +106,14 @@
 void psci_stats_update_pwr_up(unsigned int end_pwrlvl,
 			const psci_power_state_t *state_info)
 {
-	unsigned int lvl, parent_idx, cpu_idx = plat_my_core_pos();
+	unsigned int lvl, parent_idx;
+	int cpu_idx = (int) plat_my_core_pos();
 	int stat_idx;
 	plat_local_state_t local_state;
 	u_register_t residency;
 
 	assert(end_pwrlvl <= PLAT_MAX_PWR_LVL);
-	assert(state_info);
+	assert(state_info != NULL);
 
 	/* Get the index into the stats array */
 	local_state = state_info->pwr_domain_state[PSCI_CPU_PWR_LVL];
@@ -134,9 +136,9 @@
 	if (last_cpu_in_non_cpu_pd[parent_idx] == -1)
 		return;
 
-	for (lvl = PSCI_CPU_PWR_LVL + 1; lvl <= end_pwrlvl; lvl++) {
+	for (lvl = PSCI_CPU_PWR_LVL + 1U; lvl <= end_pwrlvl; lvl++) {
 		local_state = state_info->pwr_domain_state[lvl];
-		if (is_local_state_run(local_state)) {
+		if (is_local_state_run(local_state) != 0) {
 			/* Break early */
 			break;
 		}
@@ -145,7 +147,7 @@
 
 		/* Call into platform interface to calculate residency. */
 		residency = plat_psci_stat_get_residency(lvl, state_info,
-		    last_cpu_in_non_cpu_pd[parent_idx]);
+					last_cpu_in_non_cpu_pd[parent_idx]);
 
 		/* Initialize back to reset value */
 		last_cpu_in_non_cpu_pd[parent_idx] = -1;
@@ -171,17 +173,18 @@
 			 psci_stat_t *psci_stat)
 {
 	int rc;
-	unsigned int pwrlvl, lvl, parent_idx, stat_idx, target_idx;
+	unsigned int pwrlvl, lvl, parent_idx, target_idx;
+	int stat_idx;
 	psci_power_state_t state_info = { {PSCI_LOCAL_STATE_RUN} };
 	plat_local_state_t local_state;
 
 	/* Validate the target_cpu parameter and determine the cpu index */
-	target_idx = plat_core_pos_by_mpidr(target_cpu);
-	if (target_idx == -1)
+	target_idx = (unsigned int) plat_core_pos_by_mpidr(target_cpu);
+	if (target_idx == (unsigned int) -1)
 		return PSCI_E_INVALID_PARAMS;
 
 	/* Validate the power_state parameter */
-	if (!psci_plat_pm_ops->translate_power_state_by_mpidr)
+	if (psci_plat_pm_ops->translate_power_state_by_mpidr == NULL)
 		rc = psci_validate_power_state(power_state, &state_info);
 	else
 		rc = psci_plat_pm_ops->translate_power_state_by_mpidr(
@@ -204,7 +207,7 @@
 	if (pwrlvl > PSCI_CPU_PWR_LVL) {
 		/* Get the power domain index */
 		parent_idx = psci_cpu_pd_nodes[target_idx].parent_node;
-		for (lvl = PSCI_CPU_PWR_LVL + 1; lvl < pwrlvl; lvl++)
+		for (lvl = PSCI_CPU_PWR_LVL + 1U; lvl < pwrlvl; lvl++)
 			parent_idx = psci_non_cpu_pd_nodes[parent_idx].parent_node;
 
 		/* Get the non cpu power domain stats */
diff --git a/lib/psci/psci_suspend.c b/lib/psci/psci_suspend.c
index a77972d..e00819d 100644
--- a/lib/psci/psci_suspend.c
+++ b/lib/psci/psci_suspend.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2013-2017, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2013-2018, ARM Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -23,7 +23,7 @@
  * This function does generic and platform specific operations after a wake-up
  * from standby/retention states at multiple power levels.
  ******************************************************************************/
-static void psci_suspend_to_standby_finisher(unsigned int cpu_idx,
+static void psci_suspend_to_standby_finisher(int cpu_idx,
 					     unsigned int end_pwrlvl)
 {
 	psci_power_state_t state_info;
@@ -64,8 +64,8 @@
  * operations.
  ******************************************************************************/
 static void psci_suspend_to_pwrdown_start(unsigned int end_pwrlvl,
-					  entry_point_info_t *ep,
-					  psci_power_state_t *state_info)
+					  const entry_point_info_t *ep,
+					  const psci_power_state_t *state_info)
 {
 	unsigned int max_off_lvl = psci_find_max_off_lvl(state_info);
 
@@ -85,7 +85,7 @@
 	 * Dispatcher to let it do any book-keeping. If the handler encounters an
 	 * error, it's expected to assert within
 	 */
-	if (psci_spd_pm && psci_spd_pm->svc_suspend)
+	if ((psci_spd_pm != NULL) && (psci_spd_pm->svc_suspend != NULL))
 		psci_spd_pm->svc_suspend(max_off_lvl);
 
 #if !HW_ASSISTED_COHERENCY
@@ -95,7 +95,7 @@
 	 * HW_ASSISTED_COHERENCY = 0 platforms that can safely perform these
 	 * actions with data caches enabled.
 	 */
-	if (psci_plat_pm_ops->pwr_domain_suspend_pwrdown_early)
+	if (psci_plat_pm_ops->pwr_domain_suspend_pwrdown_early != NULL)
 		psci_plat_pm_ops->pwr_domain_suspend_pwrdown_early(state_info);
 #endif
 
@@ -147,20 +147,20 @@
  * the state transition has been done, no further error is expected and it is
  * not possible to undo any of the actions taken beyond that point.
  ******************************************************************************/
-void psci_cpu_suspend_start(entry_point_info_t *ep,
+void psci_cpu_suspend_start(const entry_point_info_t *ep,
 			    unsigned int end_pwrlvl,
 			    psci_power_state_t *state_info,
 			    unsigned int is_power_down_state)
 {
 	int skip_wfi = 0;
-	unsigned int idx = plat_my_core_pos();
+	int idx = (int) plat_my_core_pos();
 
 	/*
 	 * This function must only be called on platforms where the
 	 * CPU_SUSPEND platform hooks have been implemented.
 	 */
-	assert(psci_plat_pm_ops->pwr_domain_suspend &&
-			psci_plat_pm_ops->pwr_domain_suspend_finish);
+	assert((psci_plat_pm_ops->pwr_domain_suspend != NULL) &&
+	       (psci_plat_pm_ops->pwr_domain_suspend_finish != NULL));
 
 	/*
 	 * This function acquires the lock corresponding to each power
@@ -175,7 +175,7 @@
 	 * introduced by lock contention to increase the chances of early
 	 * detection that a wake-up interrupt has fired.
 	 */
-	if (read_isr_el1()) {
+	if (read_isr_el1() != 0U) {
 		skip_wfi = 1;
 		goto exit;
 	}
@@ -192,7 +192,7 @@
 	psci_stats_update_pwr_down(end_pwrlvl, state_info);
 #endif
 
-	if (is_power_down_state)
+	if (is_power_down_state != 0U)
 		psci_suspend_to_pwrdown_start(end_pwrlvl, ep, state_info);
 
 	/*
@@ -214,10 +214,10 @@
 	 */
 	psci_release_pwr_domain_locks(end_pwrlvl,
 				  idx);
-	if (skip_wfi)
+	if (skip_wfi == 1)
 		return;
 
-	if (is_power_down_state) {
+	if (is_power_down_state != 0U) {
 #if ENABLE_RUNTIME_INSTRUMENTATION
 
 		/*
@@ -232,7 +232,7 @@
 #endif
 
 		/* The function calls below must not return */
-		if (psci_plat_pm_ops->pwr_domain_pwr_down_wfi)
+		if (psci_plat_pm_ops->pwr_domain_pwr_down_wfi != NULL)
 			psci_plat_pm_ops->pwr_domain_pwr_down_wfi(state_info);
 		else
 			psci_power_down_wfi();
@@ -269,15 +269,15 @@
  * are called by the common finisher routine in psci_common.c. The `state_info`
  * is the psci_power_state from which this CPU has woken up from.
  ******************************************************************************/
-void psci_cpu_suspend_finish(unsigned int cpu_idx,
-			     psci_power_state_t *state_info)
+void psci_cpu_suspend_finish(int cpu_idx, const psci_power_state_t *state_info)
 {
 	unsigned int counter_freq;
 	unsigned int max_off_lvl;
 
 	/* Ensure we have been woken up from a suspended state */
-	assert(psci_get_aff_info_state() == AFF_STATE_ON && is_local_state_off(\
-			state_info->pwr_domain_state[PSCI_CPU_PWR_LVL]));
+	assert((psci_get_aff_info_state() == AFF_STATE_ON) &&
+		(is_local_state_off(
+			state_info->pwr_domain_state[PSCI_CPU_PWR_LVL]) != 0));
 
 	/*
 	 * Plat. management: Perform the platform specific actions
@@ -302,9 +302,9 @@
 	 * Dispatcher to let it do any bookeeping. If the handler encounters an
 	 * error, it's expected to assert within
 	 */
-	if (psci_spd_pm && psci_spd_pm->svc_suspend_finish) {
+	if ((psci_spd_pm != NULL) && (psci_spd_pm->svc_suspend_finish != NULL)) {
 		max_off_lvl = psci_find_max_off_lvl(state_info);
-		assert (max_off_lvl != PSCI_INVALID_PWR_LVL);
+		assert(max_off_lvl != PSCI_INVALID_PWR_LVL);
 		psci_spd_pm->svc_suspend_finish(max_off_lvl);
 	}
 
diff --git a/lib/psci/psci_system_off.c b/lib/psci/psci_system_off.c
index 13e9f4a..7cac4e9 100644
--- a/lib/psci/psci_system_off.c
+++ b/lib/psci/psci_system_off.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2014-2017, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2014-2018, ARM Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -16,14 +16,14 @@
 {
 	psci_print_power_domain_map();
 
-	assert(psci_plat_pm_ops->system_off);
+	assert(psci_plat_pm_ops->system_off != NULL);
 
 	/* Notify the Secure Payload Dispatcher */
-	if (psci_spd_pm && psci_spd_pm->svc_system_off) {
+	if ((psci_spd_pm != NULL) && (psci_spd_pm->svc_system_off != NULL)) {
 		psci_spd_pm->svc_system_off();
 	}
 
-	console_flush();
+	(void) console_flush();
 
 	/* Call the platform specific hook */
 	psci_plat_pm_ops->system_off();
@@ -35,14 +35,14 @@
 {
 	psci_print_power_domain_map();
 
-	assert(psci_plat_pm_ops->system_reset);
+	assert(psci_plat_pm_ops->system_reset != NULL);
 
 	/* Notify the Secure Payload Dispatcher */
-	if (psci_spd_pm && psci_spd_pm->svc_system_reset) {
+	if ((psci_spd_pm != NULL) && (psci_spd_pm->svc_system_reset != NULL)) {
 		psci_spd_pm->svc_system_reset();
 	}
 
-	console_flush();
+	(void) console_flush();
 
 	/* Call the platform specific hook */
 	psci_plat_pm_ops->system_reset();
@@ -50,32 +50,34 @@
 	/* This function does not return. We should never get here */
 }
 
-int psci_system_reset2(uint32_t reset_type, u_register_t cookie)
+u_register_t psci_system_reset2(uint32_t reset_type, u_register_t cookie)
 {
-	int is_vendor;
+	unsigned int is_vendor;
 
 	psci_print_power_domain_map();
 
-	assert(psci_plat_pm_ops->system_reset2);
+	assert(psci_plat_pm_ops->system_reset2 != NULL);
 
-	is_vendor = (reset_type >> PSCI_RESET2_TYPE_VENDOR_SHIFT) & 1;
-	if (!is_vendor) {
+	is_vendor = (reset_type >> PSCI_RESET2_TYPE_VENDOR_SHIFT) & 1U;
+	if (is_vendor == 0U) {
 		/*
 		 * Only WARM_RESET is allowed for architectural type resets.
 		 */
 		if (reset_type != PSCI_RESET2_SYSTEM_WARM_RESET)
-			return PSCI_E_INVALID_PARAMS;
-		if (psci_plat_pm_ops->write_mem_protect &&
-		    psci_plat_pm_ops->write_mem_protect(0) < 0) {
-			return PSCI_E_NOT_SUPPORTED;
+			return (u_register_t) PSCI_E_INVALID_PARAMS;
+		if ((psci_plat_pm_ops->write_mem_protect != NULL) &&
+		    (psci_plat_pm_ops->write_mem_protect(0) < 0)) {
+			return (u_register_t) PSCI_E_NOT_SUPPORTED;
 		}
 	}
 
 	/* Notify the Secure Payload Dispatcher */
-	if (psci_spd_pm && psci_spd_pm->svc_system_reset) {
+	if ((psci_spd_pm != NULL) && (psci_spd_pm->svc_system_reset != NULL)) {
 		psci_spd_pm->svc_system_reset();
 	}
-	console_flush();
+	(void) console_flush();
 
-	return psci_plat_pm_ops->system_reset2(is_vendor, reset_type, cookie);
+	return (u_register_t)
+		psci_plat_pm_ops->system_reset2((int) is_vendor, reset_type,
+						cookie);
 }
diff --git a/maintainers.rst b/maintainers.rst
index 76fede8..28127f8 100644
--- a/maintainers.rst
+++ b/maintainers.rst
@@ -125,6 +125,16 @@
 :G: `rockchip-linux`_
 :F: plat/rockchip/
 
+STM32MP1 platform port
+----------------------
+:M: Yann Gautier <yann.gautier@st.com>
+:G: `Yann-lms`_
+:F: docs/plat/stm32mp1.rst
+:F: fdts/stm32\*
+:F: include/dt-bindings/\*/stm32\*
+:F: plat/st/
+:F: tools/stm32image/
+
 Synquacer platform port
 -----------------------
 :M: Sumit Garg <sumit.garg@linaro.org>
@@ -184,3 +194,4 @@
 .. _soby-mathew: https://github.com/soby-mathew
 .. _TonyXie06: https://github.com/TonyXie06
 .. _vwadekar: https://github.com/vwadekar
+.. _Yann-lms: https://github.com/Yann-lms
diff --git a/plat/allwinner/common/include/platform_def.h b/plat/allwinner/common/include/platform_def.h
index d039188..b46d410 100644
--- a/plat/allwinner/common/include/platform_def.h
+++ b/plat/allwinner/common/include/platform_def.h
@@ -4,12 +4,13 @@
  * SPDX-License-Identifier: BSD-3-Clause
  */
 
-#ifndef __PLATFORM_DEF_H__
-#define __PLATFORM_DEF_H__
+#ifndef PLATFORM_DEF_H
+#define PLATFORM_DEF_H
 
 #include <common_def.h>
 #include <sunxi_mmap.h>
 #include <tbbr/tbbr_img_def.h>
+#include <utils_def.h>
 
 #define BL31_BASE			SUNXI_SRAM_A2_BASE
 #define BL31_LIMIT			(SUNXI_SRAM_A2_BASE + SUNXI_SRAM_A2_SIZE)
@@ -23,11 +24,11 @@
 #define MAX_MMAP_REGIONS		(4 + PLATFORM_MMAP_REGIONS)
 #define MAX_XLAT_TABLES			2
 
-#define PLAT_MAX_PWR_LVL_STATES		2
-#define PLAT_MAX_RET_STATE		1
-#define PLAT_MAX_OFF_STATE		2
+#define PLAT_MAX_PWR_LVL_STATES		U(2)
+#define PLAT_MAX_RET_STATE		U(1)
+#define PLAT_MAX_OFF_STATE		U(2)
 
-#define PLAT_MAX_PWR_LVL		2
+#define PLAT_MAX_PWR_LVL		U(2)
 #define PLAT_NUM_PWR_DOMAINS		(1 + \
 					 PLATFORM_CLUSTER_COUNT + \
 					 PLATFORM_CORE_COUNT)
@@ -48,4 +49,4 @@
 #endif
 #endif
 
-#endif /* __PLATFORM_DEF_H__ */
+#endif /* PLATFORM_DEF_H */
diff --git a/plat/arm/board/common/board_css_common.c b/plat/arm/board/common/board_css_common.c
index c4e83a4..40b1a27 100644
--- a/plat/arm/board/common/board_css_common.c
+++ b/plat/arm/board/common/board_css_common.c
@@ -53,6 +53,8 @@
 const mmap_region_t plat_arm_mmap[] = {
 	ARM_MAP_SHARED_RAM,
 	CSS_MAP_DEVICE,
+	CSS_MAP_SCP_BL2U,
+	V2M_MAP_IOFPGA,
 	SOC_CSS_MAP_DEVICE,
 	{0}
 };
diff --git a/plat/arm/board/fvp/fvp_def.h b/plat/arm/board/fvp/fvp_def.h
index acf3cf4..4e20c31 100644
--- a/plat/arm/board/fvp/fvp_def.h
+++ b/plat/arm/board/fvp/fvp_def.h
@@ -4,8 +4,10 @@
  * SPDX-License-Identifier: BSD-3-Clause
  */
 
-#ifndef __FVP_DEF_H__
-#define __FVP_DEF_H__
+#ifndef FVP_DEF_H
+#define FVP_DEF_H
+
+#include <utils_def.h>
 
 #ifndef FVP_CLUSTER_COUNT
 #define FVP_CLUSTER_COUNT		2
@@ -153,4 +155,4 @@
 #define PLAT_ARM_MEM_PROT_ADDR		(V2M_FLASH0_BASE + \
 					 V2M_FLASH0_SIZE - V2M_FLASH_BLOCK_SIZE)
 
-#endif /* __FVP_DEF_H__ */
+#endif /* FVP_DEF_H */
diff --git a/plat/arm/board/juno/include/platform_def.h b/plat/arm/board/juno/include/platform_def.h
index 80d4ba8..a781c4f 100644
--- a/plat/arm/board/juno/include/platform_def.h
+++ b/plat/arm/board/juno/include/platform_def.h
@@ -98,7 +98,7 @@
 #endif
 
 #ifdef IMAGE_BL2U
-# define PLAT_ARM_MMAP_ENTRIES		4
+# define PLAT_ARM_MMAP_ENTRIES		5
 # define MAX_XLAT_TABLES		3
 #endif
 
diff --git a/plat/arm/board/juno/juno_def.h b/plat/arm/board/juno/juno_def.h
index 63e2456..95f2b39 100644
--- a/plat/arm/board/juno/juno_def.h
+++ b/plat/arm/board/juno/juno_def.h
@@ -1,12 +1,13 @@
 /*
- * Copyright (c) 2014-2017, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2014-2018, ARM Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
 
-#ifndef __JUNO_DEF_H__
-#define __JUNO_DEF_H__
+#ifndef JUNO_DEF_H
+#define JUNO_DEF_H
 
+#include <utils_def.h>
 
 /*******************************************************************************
  * Juno memory map related constants
@@ -90,4 +91,4 @@
 #define PLAT_ARM_MEM_PROT_ADDR		(V2M_FLASH0_BASE + \
 					 V2M_FLASH0_SIZE - V2M_FLASH_BLOCK_SIZE)
 
-#endif /* __JUNO_DEF_H__ */
+#endif /* JUNO_DEF_H */
diff --git a/plat/arm/common/arm_bl1_setup.c b/plat/arm/common/arm_bl1_setup.c
index c9b1a68..9483976 100644
--- a/plat/arm/common/arm_bl1_setup.c
+++ b/plat/arm/common/arm_bl1_setup.c
@@ -7,6 +7,7 @@
 #include <arch.h>
 #include <arm_def.h>
 #include <arm_xlat_tables.h>
+#include <assert.h>
 #include <bl1.h>
 #include <bl_common.h>
 #include <plat_arm.h>
@@ -23,6 +24,19 @@
 #pragma weak bl1_plat_sec_mem_layout
 #pragma weak bl1_plat_prepare_exit
 
+#define MAP_BL1_TOTAL		MAP_REGION_FLAT(			\
+					bl1_tzram_layout.total_base,	\
+					bl1_tzram_layout.total_size,	\
+					MT_MEMORY | MT_RW | MT_SECURE)
+#define MAP_BL1_CODE		MAP_REGION_FLAT(			\
+					BL_CODE_BASE,			\
+					BL1_CODE_END - BL_CODE_BASE,	\
+					MT_CODE | MT_SECURE)
+#define MAP_BL1_RO_DATA		MAP_REGION_FLAT(			\
+					BL1_RO_DATA_BASE,		\
+					BL1_RO_DATA_END			\
+						- BL_RO_DATA_BASE,	\
+					MT_RO_DATA | MT_SECURE)
 
 /* Data structure which holds the extents of the trusted SRAM for BL1*/
 static meminfo_t bl1_tzram_layout;
@@ -84,17 +98,19 @@
  *****************************************************************************/
 void arm_bl1_plat_arch_setup(void)
 {
-	arm_setup_page_tables(bl1_tzram_layout.total_base,
-			      bl1_tzram_layout.total_size,
-			      BL_CODE_BASE,
-			      BL1_CODE_END,
-			      BL1_RO_DATA_BASE,
-			      BL1_RO_DATA_END
 #if USE_COHERENT_MEM
-			      , BL_COHERENT_RAM_BASE,
-			      BL_COHERENT_RAM_END
+	/* ARM platforms dont use coherent memory in BL1 */
+	assert((BL_COHERENT_RAM_END - BL_COHERENT_RAM_BASE) == 0U);
 #endif
-			     );
+
+	const mmap_region_t bl_regions[] = {
+		MAP_BL1_TOTAL,
+		MAP_BL1_CODE,
+		MAP_BL1_RO_DATA,
+		{0}
+	};
+
+	arm_setup_page_tables(bl_regions, plat_arm_get_mmap());
 #ifdef AARCH32
 	enable_mmu_secure(0);
 #else
diff --git a/plat/arm/common/arm_bl2_el3_setup.c b/plat/arm/common/arm_bl2_el3_setup.c
index e7247c6..1d602bb 100644
--- a/plat/arm/common/arm_bl2_el3_setup.c
+++ b/plat/arm/common/arm_bl2_el3_setup.c
@@ -3,6 +3,8 @@
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
+#include <arm_def.h>
+#include <assert.h>
 #include <generic_delay_timer.h>
 #include <plat_arm.h>
 #include <platform.h>
@@ -11,6 +13,11 @@
 #pragma weak bl2_el3_plat_arch_setup
 #pragma weak bl2_el3_plat_prepare_exit
 
+#define MAP_BL2_EL3_TOTAL	MAP_REGION_FLAT(				\
+					bl2_el3_tzram_layout.total_base,	\
+					bl2_el3_tzram_layout.total_size,	\
+					MT_MEMORY | MT_RW | MT_SECURE)
+
 static meminfo_t bl2_el3_tzram_layout;
 
 /*
@@ -60,17 +67,20 @@
  ******************************************************************************/
 void arm_bl2_el3_plat_arch_setup(void)
 {
-	arm_setup_page_tables(bl2_el3_tzram_layout.total_base,
-			      bl2_el3_tzram_layout.total_size,
-			      BL_CODE_BASE,
-			      BL_CODE_END,
-			      BL_RO_DATA_BASE,
-			      BL_RO_DATA_END
+
 #if USE_COHERENT_MEM
-			      , BL_COHERENT_RAM_BASE,
-			      BL_COHERENT_RAM_END
+	/* Ensure ARM platforms dont use coherent memory in BL2_AT_EL3 */
+	assert(BL_COHERENT_RAM_END - BL_COHERENT_RAM_BASE == 0U);
 #endif
-			      );
+
+	const mmap_region_t bl_regions[] = {
+		MAP_BL2_EL3_TOTAL,
+		ARM_MAP_BL_CODE,
+		ARM_MAP_BL_RO_DATA,
+		{0}
+	};
+
+	arm_setup_page_tables(bl_regions, plat_arm_get_mmap());
 
 #ifdef AARCH32
 	enable_mmu_secure(0);
diff --git a/plat/arm/common/arm_bl2_setup.c b/plat/arm/common/arm_bl2_setup.c
index 33c2fe8..88c0bc9 100644
--- a/plat/arm/common/arm_bl2_setup.c
+++ b/plat/arm/common/arm_bl2_setup.c
@@ -35,6 +35,11 @@
 #pragma weak bl2_plat_arch_setup
 #pragma weak bl2_plat_sec_mem_layout
 
+#define MAP_BL2_TOTAL		MAP_REGION_FLAT(			\
+					bl2_tzram_layout.total_base,	\
+					bl2_tzram_layout.total_size,	\
+					MT_MEMORY | MT_RW | MT_SECURE)
+
 #if LOAD_IMAGE_V2
 
 #pragma weak bl2_plat_handle_post_image_load
@@ -232,17 +237,20 @@
  ******************************************************************************/
 void arm_bl2_plat_arch_setup(void)
 {
-	arm_setup_page_tables(bl2_tzram_layout.total_base,
-			      bl2_tzram_layout.total_size,
-			      BL_CODE_BASE,
-			      BL_CODE_END,
-			      BL_RO_DATA_BASE,
-			      BL_RO_DATA_END
+
 #if USE_COHERENT_MEM
-			      , BL_COHERENT_RAM_BASE,
-			      BL_COHERENT_RAM_END
+	/* Ensure ARM platforms dont use coherent memory in BL2 */
+	assert((BL_COHERENT_RAM_END - BL_COHERENT_RAM_BASE) == 0U);
 #endif
-			      );
+
+	const mmap_region_t bl_regions[] = {
+		MAP_BL2_TOTAL,
+		ARM_MAP_BL_CODE,
+		ARM_MAP_BL_RO_DATA,
+		{0}
+	};
+
+	arm_setup_page_tables(bl_regions, plat_arm_get_mmap());
 
 #ifdef AARCH32
 	enable_mmu_secure(0);
diff --git a/plat/arm/common/arm_bl2u_setup.c b/plat/arm/common/arm_bl2u_setup.c
index dce00e5..2bf8a93 100644
--- a/plat/arm/common/arm_bl2u_setup.c
+++ b/plat/arm/common/arm_bl2u_setup.c
@@ -6,6 +6,7 @@
 
 #include <arch_helpers.h>
 #include <arm_def.h>
+#include <assert.h>
 #include <bl_common.h>
 #include <generic_delay_timer.h>
 #include <plat_arm.h>
@@ -18,6 +19,11 @@
 #pragma weak bl2u_early_platform_setup
 #pragma weak bl2u_plat_arch_setup
 
+#define MAP_BL2U_TOTAL		MAP_REGION_FLAT(			\
+					BL2U_BASE,			\
+					BL2U_LIMIT - BL2U_BASE,		\
+					MT_MEMORY | MT_RW | MT_SECURE)
+
 /*
  * Perform ARM standard platform setup for BL2U
  */
@@ -58,18 +64,21 @@
  ******************************************************************************/
 void arm_bl2u_plat_arch_setup(void)
 {
-	arm_setup_page_tables(BL2U_BASE,
-			      BL31_LIMIT,
-			      BL_CODE_BASE,
-			      BL_CODE_END,
-			      BL_RO_DATA_BASE,
-			      BL_RO_DATA_END
+
 #if USE_COHERENT_MEM
-			      ,
-			      BL_COHERENT_RAM_BASE,
-			      BL_COHERENT_RAM_END
+	/* Ensure ARM platforms dont use coherent memory in BL2U */
+	assert((BL_COHERENT_RAM_END - BL_COHERENT_RAM_BASE) == 0U);
 #endif
-		);
+
+	const mmap_region_t bl_regions[] = {
+		MAP_BL2U_TOTAL,
+		ARM_MAP_BL_CODE,
+		ARM_MAP_BL_RO_DATA,
+		{0}
+	};
+
+	arm_setup_page_tables(bl_regions, plat_arm_get_mmap());
+
 #ifdef AARCH32
 	enable_mmu_secure(0);
 #else
diff --git a/plat/arm/common/arm_bl31_setup.c b/plat/arm/common/arm_bl31_setup.c
index b1f95c9..557854c 100644
--- a/plat/arm/common/arm_bl31_setup.c
+++ b/plat/arm/common/arm_bl31_setup.c
@@ -37,6 +37,10 @@
 #pragma weak bl31_plat_arch_setup
 #pragma weak bl31_plat_get_next_image_ep_info
 
+#define MAP_BL31_TOTAL	MAP_REGION_FLAT(			\
+					BL31_BASE,			\
+					BL31_END - BL31_BASE,		\
+					MT_MEMORY | MT_RW | MT_SECURE)
 
 /*******************************************************************************
  * Return a pointer to the 'entry_point_info' structure of the next image for the
@@ -280,17 +284,19 @@
  ******************************************************************************/
 void arm_bl31_plat_arch_setup(void)
 {
-	arm_setup_page_tables(BL31_BASE,
-			      BL31_END - BL31_BASE,
-			      BL_CODE_BASE,
-			      BL_CODE_END,
-			      BL_RO_DATA_BASE,
-			      BL_RO_DATA_END
+
+	const mmap_region_t bl_regions[] = {
+		MAP_BL31_TOTAL,
+		ARM_MAP_BL_CODE,
+		ARM_MAP_BL_RO_DATA,
 #if USE_COHERENT_MEM
-			      , BL_COHERENT_RAM_BASE,
-			      BL_COHERENT_RAM_END
+		ARM_MAP_BL_COHERENT_RAM,
 #endif
-			      );
+		{0}
+	};
+
+	arm_setup_page_tables(bl_regions, plat_arm_get_mmap());
+
 	enable_mmu_el3(0);
 }
 
diff --git a/plat/arm/common/arm_common.c b/plat/arm/common/arm_common.c
index 270abb2..f83005f 100644
--- a/plat/arm/common/arm_common.c
+++ b/plat/arm/common/arm_common.c
@@ -26,61 +26,34 @@
 
 /*
  * 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;
+ * The size of the Trusted SRAM seen by the BL image must be specified as well
+ * as an array specifying the generic memory regions which can be;
  * - Code section;
  * - Read-only data section;
  * - Coherent memory region, if applicable.
  */
-void arm_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
-#if USE_COHERENT_MEM
-			   ,
-			   uintptr_t coh_start,
-			   uintptr_t coh_limit
-#endif
-			   )
+
+void arm_setup_page_tables(const mmap_region_t bl_regions[],
+			   const mmap_region_t plat_regions[])
 {
+#if LOG_LEVEL >= LOG_LEVEL_VERBOSE
+	const mmap_region_t *regions = bl_regions;
+
+	while (regions->size != 0U) {
+		VERBOSE("Region: 0x%lx - 0x%lx has attributes 0x%x\n",
+				regions->base_va,
+				(regions->base_va + regions->size),
+				regions->attr);
+		regions++;
+	}
+#endif
 	/*
 	 * 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);
-
-#if USE_COHERENT_MEM
-	/* 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);
-#endif
-
+	mmap_add(bl_regions);
 	/* Now (re-)map the platform-specific memory regions */
-	mmap_add(plat_arm_get_mmap());
+	mmap_add(plat_regions);
 
 	/* Create the page tables to reflect the above mappings */
 	init_xlat_tables();
diff --git a/plat/arm/common/arm_nor_psci_mem_protect.c b/plat/arm/common/arm_nor_psci_mem_protect.c
index c01e4ed..1b0b1da 100644
--- a/plat/arm/common/arm_nor_psci_mem_protect.c
+++ b/plat/arm/common/arm_nor_psci_mem_protect.c
@@ -51,14 +51,14 @@
  ******************************************************************************/
 int arm_nor_psci_write_mem_protect(int val)
 {
-	int enable = (val != 0);
+	int enable = (val != 0) ? 1 : 0;
 
 	if (nor_unlock(PLAT_ARM_MEM_PROT_ADDR) != 0) {
 		ERROR("unlocking memory protect variable\n");
 		return -1;
 	}
 
-	if (enable != 0) {
+	if (enable == 1) {
 		/*
 		 * If we want to write a value different than 0
 		 * then we have to erase the full block because
@@ -117,14 +117,14 @@
 {
 	int enable;
 
-	arm_psci_read_mem_protect(&enable);
+	(void) arm_psci_read_mem_protect(&enable);
 	if (enable == 0)
 		return;
 
 	INFO("PSCI: Overwriting non secure memory\n");
 	clear_mem_regions(arm_ram_ranges,
 			  ARRAY_SIZE(arm_ram_ranges));
-	arm_nor_psci_write_mem_protect(0);
+	(void) arm_nor_psci_write_mem_protect(0);
 }
 
 /*******************************************************************************
diff --git a/plat/arm/common/arm_pm.c b/plat/arm/common/arm_pm.c
index d0350d6..4257d3c 100644
--- a/plat/arm/common/arm_pm.c
+++ b/plat/arm/common/arm_pm.c
@@ -18,10 +18,6 @@
 #pragma weak plat_arm_psci_override_pm_ops
 #pragma weak plat_arm_program_trusted_mailbox
 
-#if ARM_RECOM_STATE_ID_ENC
-extern unsigned int arm_pm_idle_states[];
-#endif /* __ARM_RECOM_STATE_ID_ENC__ */
-
 #if !ARM_RECOM_STATE_ID_ENC
 /*******************************************************************************
  * ARM standard platform handler called to check the validity of the power state
@@ -30,11 +26,11 @@
 int arm_validate_power_state(unsigned int power_state,
 			    psci_power_state_t *req_state)
 {
-	int pstate = psci_get_pstate_type(power_state);
-	int pwr_lvl = psci_get_pstate_pwrlvl(power_state);
-	int i;
+	unsigned int pstate = psci_get_pstate_type(power_state);
+	unsigned int pwr_lvl = psci_get_pstate_pwrlvl(power_state);
+	unsigned int i;
 
-	assert(req_state);
+	assert(req_state > 0U);
 
 	if (pwr_lvl > PLAT_MAX_PWR_LVL)
 		return PSCI_E_INVALID_PARAMS;
@@ -59,7 +55,7 @@
 	/*
 	 * We expect the 'state id' to be zero.
 	 */
-	if (psci_get_pstate_id(power_state))
+	if (psci_get_pstate_id(power_state) != 0U)
 		return PSCI_E_INVALID_PARAMS;
 
 	return PSCI_E_SUCCESS;
diff --git a/plat/arm/common/sp_min/arm_sp_min_setup.c b/plat/arm/common/sp_min/arm_sp_min_setup.c
index b42e35f..c7f317c 100644
--- a/plat/arm/common/sp_min/arm_sp_min_setup.c
+++ b/plat/arm/common/sp_min/arm_sp_min_setup.c
@@ -22,6 +22,11 @@
 #pragma weak sp_min_plat_arch_setup
 #pragma weak plat_arm_sp_min_early_platform_setup
 
+#define MAP_BL_SP_MIN_TOTAL	MAP_REGION_FLAT(			\
+					BL32_BASE,			\
+					BL32_END - BL32_BASE,		\
+					MT_MEMORY | MT_RW | MT_SECURE)
+
 /*
  * Check that BL32_BASE is above ARM_TB_FW_CONFIG_LIMIT. The reserved page
  * is required for SOC_FW_CONFIG/TOS_FW_CONFIG passed from BL2.
@@ -196,18 +201,17 @@
  ******************************************************************************/
 void sp_min_plat_arch_setup(void)
 {
-
-	arm_setup_page_tables(BL32_BASE,
-			      (BL32_END - BL32_BASE),
-			      BL_CODE_BASE,
-			      BL_CODE_END,
-			      BL_RO_DATA_BASE,
-			      BL_RO_DATA_END
+	const mmap_region_t bl_regions[] = {
+		MAP_BL_SP_MIN_TOTAL,
+		ARM_MAP_BL_CODE,
+		ARM_MAP_BL_RO_DATA,
 #if USE_COHERENT_MEM
-			      , BL_COHERENT_RAM_BASE,
-			      BL_COHERENT_RAM_END
+		ARM_MAP_BL_COHERENT_RAM,
 #endif
-			      );
+		{0}
+	};
+
+	arm_setup_page_tables(bl_regions, plat_arm_get_mmap());
 
 	enable_mmu_secure(0);
 }
diff --git a/plat/arm/common/tsp/arm_tsp_setup.c b/plat/arm/common/tsp/arm_tsp_setup.c
index 16125ad..491705d 100644
--- a/plat/arm/common/tsp/arm_tsp_setup.c
+++ b/plat/arm/common/tsp/arm_tsp_setup.c
@@ -5,6 +5,7 @@
  */
 
 #include <arm_def.h>
+#include <assert.h>
 #include <bl_common.h>
 #include <console.h>
 #include <debug.h>
@@ -20,6 +21,10 @@
 #pragma weak tsp_platform_setup
 #pragma weak tsp_plat_arch_setup
 
+#define MAP_BL_TSP_TOTAL	MAP_REGION_FLAT(			\
+					BL32_BASE,			\
+					BL32_END - BL32_BASE,		\
+					MT_MEMORY | MT_RW | MT_SECURE)
 
 /*******************************************************************************
  * Initialize the UART
@@ -69,16 +74,18 @@
  ******************************************************************************/
 void tsp_plat_arch_setup(void)
 {
-	arm_setup_page_tables(BL32_BASE,
-			      (BL32_END - BL32_BASE),
-			      BL_CODE_BASE,
-			      BL_CODE_END,
-			      BL_RO_DATA_BASE,
-			      BL_RO_DATA_END
 #if USE_COHERENT_MEM
-			      , BL_COHERENT_RAM_BASE,
-			      BL_COHERENT_RAM_END
+	/* Ensure ARM platforms dont use coherent memory in TSP */
+	assert((BL_COHERENT_RAM_END - BL_COHERENT_RAM_BASE) == 0U);
 #endif
-			      );
+
+	const mmap_region_t bl_regions[] = {
+		MAP_BL_TSP_TOTAL,
+		ARM_MAP_BL_CODE,
+		ARM_MAP_BL_RO_DATA,
+		{0}
+	};
+
+	arm_setup_page_tables(bl_regions, plat_arm_get_mmap());
 	enable_mmu_el1(0);
 }
diff --git a/plat/arm/css/sgi/include/platform_def.h b/plat/arm/css/sgi/include/platform_def.h
index 84ef2c4..7a2a6bd 100644
--- a/plat/arm/css/sgi/include/platform_def.h
+++ b/plat/arm/css/sgi/include/platform_def.h
@@ -4,8 +4,8 @@
  * SPDX-License-Identifier: BSD-3-Clause
  */
 
-#ifndef __PLATFORM_DEF_H__
-#define __PLATFORM_DEF_H__
+#ifndef PLATFORM_DEF_H
+#define PLATFORM_DEF_H
 
 #include <arm_def.h>
 #include <board_arm_def.h>
@@ -13,6 +13,7 @@
 #include <common_def.h>
 #include <css_def.h>
 #include <soc_css_def.h>
+#include <utils_def.h>
 
 #define CSS_SGI_MAX_CPUS_PER_CLUSTER	4
 
@@ -57,7 +58,7 @@
 #define PLAT_ARM_NSRAM_BASE		0x06000000
 #define PLAT_ARM_NSRAM_SIZE		0x00080000	/* 512KB */
 
-#define PLAT_MAX_PWR_LVL		1
+#define PLAT_MAX_PWR_LVL		U(1)
 
 #define PLAT_ARM_G1S_IRQS		ARM_G1S_IRQS,			\
 					CSS_IRQ_MHU
@@ -108,4 +109,4 @@
 					 V2M_FLASH0_SIZE - V2M_FLASH_BLOCK_SIZE)
 
 
-#endif /* __PLATFORM_DEF_H__ */
+#endif /* PLATFORM_DEF_H */
diff --git a/plat/common/plat_psci_common.c b/plat/common/plat_psci_common.c
index 0e818d0..fab3c77 100644
--- a/plat/common/plat_psci_common.c
+++ b/plat/common/plat_psci_common.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2016-2017, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2016-2018, ARM Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -16,7 +16,7 @@
 #pragma weak plat_psci_stat_get_residency
 
 /* Ticks elapsed in one second by a signal of 1 MHz */
-#define MHZ_TICKS_PER_SEC 1000000
+#define MHZ_TICKS_PER_SEC 1000000U
 
 /* Maximum time-stamp value read from architectural counters */
 #ifdef AARCH32
@@ -49,7 +49,7 @@
 	 * convert time-stamp into microseconds.
 	 */
 	residency_div = read_cntfrq_el0() / MHZ_TICKS_PER_SEC;
-	assert(residency_div);
+	assert(residency_div > 0U);
 
 	if (pwrupts < pwrdnts)
 		res = MAX_TS - pwrdnts + pwrupts;
@@ -67,7 +67,7 @@
 void plat_psci_stat_accounting_start(
 	__unused const psci_power_state_t *state_info)
 {
-	assert(state_info);
+	assert(state_info != NULL);
 	PMF_CAPTURE_TIMESTAMP(psci_svc, PSCI_STAT_ID_ENTER_LOW_PWR,
 		PMF_NO_CACHE_MAINT);
 }
@@ -80,7 +80,7 @@
 void plat_psci_stat_accounting_stop(
 	__unused const psci_power_state_t *state_info)
 {
-	assert(state_info);
+	assert(state_info != NULL);
 	PMF_CAPTURE_TIMESTAMP(psci_svc, PSCI_STAT_ID_EXIT_LOW_PWR,
 		PMF_NO_CACHE_MAINT);
 }
@@ -97,12 +97,12 @@
 	unsigned long long pwrup_ts = 0, pwrdn_ts = 0;
 	unsigned int pmf_flags;
 
-	assert(lvl >= PSCI_CPU_PWR_LVL && lvl <= PLAT_MAX_PWR_LVL);
-	assert(state_info);
-	assert(last_cpu_idx >= 0 && last_cpu_idx <= PLATFORM_CORE_COUNT);
+	assert((lvl >= PSCI_CPU_PWR_LVL) && (lvl <= PLAT_MAX_PWR_LVL));
+	assert(state_info != NULL);
+	assert(last_cpu_idx <= PLATFORM_CORE_COUNT);
 
 	if (lvl == PSCI_CPU_PWR_LVL)
-		assert(last_cpu_idx == plat_my_core_pos());
+		assert((unsigned int)last_cpu_idx == plat_my_core_pos());
 
 	/*
 	 * If power down is requested, then timestamp capture will
@@ -110,10 +110,10 @@
 	 * when reading the timestamp.
 	 */
 	state = state_info->pwr_domain_state[PSCI_CPU_PWR_LVL];
-	if (is_local_state_off(state)) {
+	if (is_local_state_off(state) != 0) {
 		pmf_flags = PMF_CACHE_MAINT;
 	} else {
-		assert(is_local_state_retn(state));
+		assert(is_local_state_retn(state) == 1);
 		pmf_flags = PMF_NO_CACHE_MAINT;
 	}
 
@@ -150,14 +150,18 @@
 					     unsigned int ncpu)
 {
 	plat_local_state_t target = PLAT_MAX_OFF_STATE, temp;
+	const plat_local_state_t *st = states;
+	unsigned int n = ncpu;
 
-	assert(ncpu);
+	assert(ncpu > 0U);
 
 	do {
-		temp = *states++;
+		temp = *st;
+		st++;
 		if (temp < target)
 			target = temp;
-	} while (--ncpu);
+		n--;
+	} while (n > 0U);
 
 	return target;
 }
diff --git a/plat/hisilicon/hikey/include/platform_def.h b/plat/hisilicon/hikey/include/platform_def.h
index b240448..54be978 100644
--- a/plat/hisilicon/hikey/include/platform_def.h
+++ b/plat/hisilicon/hikey/include/platform_def.h
@@ -4,14 +4,15 @@
  * SPDX-License-Identifier: BSD-3-Clause
  */
 
-#ifndef __PLATFORM_DEF_H__
-#define __PLATFORM_DEF_H__
+#ifndef PLATFORM_DEF_H
+#define PLATFORM_DEF_H
 
 #include <arch.h>
 #include <common_def.h>
 #include <hikey_def.h>
 #include <hikey_layout.h>		/* BL memory region sizes, etc */
 #include <tbbr_img_def.h>
+#include <utils_def.h>
 
 /* Special value used to verify platform parameters from BL2 to BL3-1 */
 #define HIKEY_BL31_PLAT_PARAM_VAL	0x0f1e2d3c4b5a6978ULL
@@ -34,8 +35,8 @@
 #define PLAT_NUM_PWR_DOMAINS		(PLATFORM_CORE_COUNT + \
 					 PLATFORM_CLUSTER_COUNT + 1)
 
-#define PLAT_MAX_RET_STATE		1
-#define PLAT_MAX_OFF_STATE		2
+#define PLAT_MAX_RET_STATE		U(1)
+#define PLAT_MAX_OFF_STATE		U(2)
 
 #define MAX_IO_DEVICES			3
 #define MAX_IO_HANDLES			4
@@ -79,4 +80,4 @@
 #define CACHE_WRITEBACK_SHIFT		6
 #define CACHE_WRITEBACK_GRANULE		(1 << CACHE_WRITEBACK_SHIFT)
 
-#endif /* __PLATFORM_DEF_H__ */
+#endif /* PLATFORM_DEF_H */
diff --git a/plat/hisilicon/hikey960/include/platform_def.h b/plat/hisilicon/hikey960/include/platform_def.h
index beff47c..5a6021a 100644
--- a/plat/hisilicon/hikey960/include/platform_def.h
+++ b/plat/hisilicon/hikey960/include/platform_def.h
@@ -4,10 +4,11 @@
  * SPDX-License-Identifier: BSD-3-Clause
  */
 
-#ifndef __PLATFORM_DEF_H__
-#define __PLATFORM_DEF_H__
+#ifndef PLATFORM_DEF_H
+#define PLATFORM_DEF_H
 
 #include <arch.h>
+#include <utils_def.h>
 #include "../hikey960_def.h"
 
 /* Special value used to verify platform parameters from BL2 to BL3-1 */
@@ -31,8 +32,8 @@
 #define PLAT_NUM_PWR_DOMAINS		(PLATFORM_CORE_COUNT + \
 					 PLATFORM_CLUSTER_COUNT + 1)
 
-#define PLAT_MAX_RET_STATE		1
-#define PLAT_MAX_OFF_STATE		2
+#define PLAT_MAX_RET_STATE		U(1)
+#define PLAT_MAX_OFF_STATE		U(2)
 
 #define MAX_IO_DEVICES			3
 #define MAX_IO_HANDLES			4
@@ -140,4 +141,4 @@
 #define CACHE_WRITEBACK_SHIFT		6
 #define CACHE_WRITEBACK_GRANULE		(1 << CACHE_WRITEBACK_SHIFT)
 
-#endif /* __PLATFORM_DEF_H__ */
+#endif /* PLATFORM_DEF_H */
diff --git a/plat/hisilicon/poplar/include/platform_def.h b/plat/hisilicon/poplar/include/platform_def.h
index 8e8f009..824ca34 100644
--- a/plat/hisilicon/poplar/include/platform_def.h
+++ b/plat/hisilicon/poplar/include/platform_def.h
@@ -1,11 +1,11 @@
 /*
- * Copyright (c) 2017, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2017-2018, ARM Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
 
-#ifndef __PLATFORM_DEF_H__
-#define __PLATFORM_DEF_H__
+#ifndef PLATFORM_DEF_H
+#define PLATFORM_DEF_H
 
 #include <arch.h>
 #include <common_def.h>
@@ -131,8 +131,8 @@
 
 /* Power states */
 #define PLAT_MAX_PWR_LVL		(MPIDR_AFFLVL1)
-#define PLAT_MAX_OFF_STATE		2
-#define PLAT_MAX_RET_STATE		1
+#define PLAT_MAX_OFF_STATE		U(2)
+#define PLAT_MAX_RET_STATE		U(1)
 
 /* Interrupt controller */
 #define PLAT_ARM_GICD_BASE	GICD_BASE
@@ -168,4 +168,4 @@
 
 #define PLAT_ARM_G0_IRQ_PROPS(grp)
 
-#endif /* __PLATFORM_DEF_H__ */
+#endif /* PLATFORM_DEF_H */
diff --git a/plat/imx/imx8qm/include/platform_def.h b/plat/imx/imx8qm/include/platform_def.h
index 51c2e1e..1cf7511 100644
--- a/plat/imx/imx8qm/include/platform_def.h
+++ b/plat/imx/imx8qm/include/platform_def.h
@@ -4,6 +4,11 @@
  * SPDX-License-Identifier: BSD-3-Clause
  */
 
+#ifndef PLATFORM_DEF_H
+#define PLATFORM_DEF_H
+
+#include <utils_def.h>
+
 #define PLATFORM_LINKER_FORMAT		"elf64-littleaarch64"
 #define PLATFORM_LINKER_ARCH		aarch64
 
@@ -22,10 +27,10 @@
 #define IMX_PWR_LVL1			MPIDR_AFFLVL1
 #define IMX_PWR_LVL2			MPIDR_AFFLVL2
 
-#define PWR_DOMAIN_AT_MAX_LVL		1
-#define PLAT_MAX_PWR_LVL		2
-#define PLAT_MAX_OFF_STATE		2
-#define PLAT_MAX_RET_STATE		1
+#define PWR_DOMAIN_AT_MAX_LVL		U(1)
+#define PLAT_MAX_PWR_LVL		U(2)
+#define PLAT_MAX_OFF_STATE		U(2)
+#define PLAT_MAX_RET_STATE		U(1)
 
 #define BL31_BASE			0x80000000
 #define BL31_LIMIT			0x80020000
@@ -62,3 +67,5 @@
 #define DEBUG_CONSOLE			0
 #define DEBUG_CONSOLE_A53		0
 #define PLAT_IMX8QM			1
+
+#endif /* PLATFORM_DEF_H */
diff --git a/plat/imx/imx8qx/include/platform_def.h b/plat/imx/imx8qx/include/platform_def.h
index 8c86174..b9fd96c 100644
--- a/plat/imx/imx8qx/include/platform_def.h
+++ b/plat/imx/imx8qx/include/platform_def.h
@@ -4,8 +4,10 @@
  * SPDX-License-Identifier: BSD-3-Clause
  */
 
-#ifndef __PLATFORM_DEF_H__
-#define __PLATFORM_DEF_H__
+#ifndef PLATFORM_DEF_H
+#define PLATFORM_DEF_H
+
+#include <utils_def.h>
 
 #define PLATFORM_LINKER_FORMAT		"elf64-littleaarch64"
 #define PLATFORM_LINKER_ARCH		aarch64
@@ -20,10 +22,10 @@
 #define PLATFORM_CLUSTER0_CORE_COUNT	4
 #define PLATFORM_CLUSTER1_CORE_COUNT	0
 
-#define PWR_DOMAIN_AT_MAX_LVL           1
-#define PLAT_MAX_PWR_LVL                2
-#define PLAT_MAX_OFF_STATE              2
-#define PLAT_MAX_RET_STATE              1
+#define PWR_DOMAIN_AT_MAX_LVL           U(1)
+#define PLAT_MAX_PWR_LVL                U(2)
+#define PLAT_MAX_OFF_STATE              U(2)
+#define PLAT_MAX_RET_STATE              U(1)
 
 #define BL31_BASE			0x80000000
 #define BL31_LIMIT			0x80020000
@@ -57,4 +59,4 @@
 #define DEBUG_CONSOLE_A35		0
 #define PLAT_IMX8QX			1
 
-#endif /* __PLATFORM_DEF_H__ */
+#endif /* PLATFORM_DEF_H */
diff --git a/plat/layerscape/board/ls1043/include/ls_def.h b/plat/layerscape/board/ls1043/include/ls_def.h
index 1015129..9c83720 100644
--- a/plat/layerscape/board/ls1043/include/ls_def.h
+++ b/plat/layerscape/board/ls1043/include/ls_def.h
@@ -4,8 +4,8 @@
  * SPDX-License-Identifier: BSD-3-Clause
  */
 
-#ifndef __LS_DEF_H__
-#define __LS_DEF_H__
+#ifndef LS_DEF_H
+#define LS_DEF_H
 
 #include <arch.h>
 #include <common_def.h>
@@ -36,14 +36,14 @@
  *  within the power-state parameter.
  */
 /* Local power state for power domains in Run state. */
-#define LS_LOCAL_STATE_RUN	0
+#define LS_LOCAL_STATE_RUN	U(0)
 /* Local power state for retention. Valid only for CPU power domains */
-#define LS_LOCAL_STATE_RET	1
+#define LS_LOCAL_STATE_RET	U(1)
 /*
  * Local power state for OFF/power-down. Valid for CPU and cluster power
  * domains
  */
-#define LS_LOCAL_STATE_OFF	2
+#define LS_LOCAL_STATE_OFF	U(2)
 
 #define LS_MAP_NS_DRAM		MAP_REGION_FLAT( \
 					(LS_NS_DRAM_BASE), \
@@ -104,4 +104,4 @@
  */
 #define PLAT_PERCPU_BAKERY_LOCK_SIZE		(1 * CACHE_WRITEBACK_GRANULE)
 
-#endif /* __LS_DEF_H__ */
+#endif /* LS_DEF_H */
diff --git a/plat/layerscape/board/ls1043/include/platform_def.h b/plat/layerscape/board/ls1043/include/platform_def.h
index 0e1cae6..46b2031 100644
--- a/plat/layerscape/board/ls1043/include/platform_def.h
+++ b/plat/layerscape/board/ls1043/include/platform_def.h
@@ -4,8 +4,8 @@
  * SPDX-License-Identifier: BSD-3-Clause
  */
 
-#ifndef __PLATFORM_DEF_H__
-#define __PLATFORM_DEF_H__
+#ifndef PLATFORM_DEF_H
+#define PLATFORM_DEF_H
 
 #include <common_def.h>
 #include <tzc400.h>
@@ -209,4 +209,4 @@
 #define MAX_IO_DEVICES			3
 #define MAX_IO_HANDLES			4
 
-#endif /* __PLATFORM_DEF_H__ */
+#endif /* PLATFORM_DEF_H */
diff --git a/plat/mediatek/mt6795/include/platform_def.h b/plat/mediatek/mt6795/include/platform_def.h
index 6c64ba5..0fa63a1 100644
--- a/plat/mediatek/mt6795/include/platform_def.h
+++ b/plat/mediatek/mt6795/include/platform_def.h
@@ -1,11 +1,13 @@
 /*
- * Copyright (c) 2016, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2016-2018, ARM Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
 
-#ifndef __PLATFORM_DEF_H__
-#define __PLATFORM_DEF_H__
+#ifndef PLATFORM_DEF_H
+#define PLATFORM_DEF_H
+
+#include <utils_def.h>
 
 #define PLAT_PRIMARY_CPU  0x0
 
@@ -146,7 +148,7 @@
 #if ENABLE_PLAT_COMPAT
 #define PLATFORM_MAX_AFFLVL     MPIDR_AFFLVL2
 #else
-#define PLAT_MAX_PWR_LVL        2 /* MPIDR_AFFLVL2 */
+#define PLAT_MAX_PWR_LVL        U(2) /* MPIDR_AFFLVL2 */
 #endif
 
 #define PLATFORM_CACHE_LINE_SIZE      64
@@ -239,4 +241,4 @@
 #define PAGE_SIZE_2MB               (1 << PAGE_SIZE_2MB_SHIFT)
 #define PAGE_SIZE_2MB_SHIFT         TWO_MB_SHIFT
 
-#endif /* __PLATFORM_DEF_H__ */
+#endif /* PLATFORM_DEF_H */
diff --git a/plat/mediatek/mt8173/include/platform_def.h b/plat/mediatek/mt8173/include/platform_def.h
index 5e79df2..6e3f4a3 100644
--- a/plat/mediatek/mt8173/include/platform_def.h
+++ b/plat/mediatek/mt8173/include/platform_def.h
@@ -1,17 +1,17 @@
 /*
- * Copyright (c) 2014-2017, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2014-2018, ARM Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
 
-#ifndef __PLATFORM_DEF_H__
-#define __PLATFORM_DEF_H__
+#ifndef PLATFORM_DEF_H
+#define PLATFORM_DEF_H
 
 #include <gic_common.h>
 #include <interrupt_props.h>
+#include <utils_def.h>
 #include "mt8173_def.h"
 
-
 /*******************************************************************************
  * Platform binary types for linking
  ******************************************************************************/
@@ -37,9 +37,9 @@
 
 #define PLATFORM_MAX_AFFLVL		MPIDR_AFFLVL2
 #if !ENABLE_PLAT_COMPAT
-#define PLAT_MAX_PWR_LVL		2
-#define PLAT_MAX_RET_STATE		1
-#define PLAT_MAX_OFF_STATE		2
+#define PLAT_MAX_PWR_LVL		U(2)
+#define PLAT_MAX_RET_STATE		U(1)
+#define PLAT_MAX_OFF_STATE		U(2)
 #endif
 #define PLATFORM_SYSTEM_COUNT		1
 #define PLATFORM_CLUSTER_COUNT		2
@@ -137,4 +137,4 @@
 
 #define PLAT_ARM_G0_IRQ_PROPS(grp)
 
-#endif /* __PLATFORM_DEF_H__ */
+#endif /* PLATFORM_DEF_H */
diff --git a/plat/qemu/include/platform_def.h b/plat/qemu/include/platform_def.h
index 2f2ca6f..55252c3 100644
--- a/plat/qemu/include/platform_def.h
+++ b/plat/qemu/include/platform_def.h
@@ -1,15 +1,16 @@
 /*
- * Copyright (c) 2015-2016, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2015-2018, ARM Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
 
-#ifndef __PLATFORM_DEF_H__
-#define __PLATFORM_DEF_H__
+#ifndef PLATFORM_DEF_H
+#define PLATFORM_DEF_H
 
 #include <arch.h>
 #include <common_def.h>
 #include <tbbr_img_def.h>
+#include <utils_def.h>
 
 /* Special value used to verify platform parameters from BL2 to BL3-1 */
 #define QEMU_BL31_PLAT_PARAM_VAL	0x0f1e2d3c4b5a6978ULL
@@ -36,13 +37,13 @@
 					PLATFORM_CORE_COUNT)
 #define PLAT_MAX_PWR_LVL		MPIDR_AFFLVL1
 
-#define PLAT_MAX_RET_STATE		1
-#define PLAT_MAX_OFF_STATE		2
+#define PLAT_MAX_RET_STATE		U(1)
+#define PLAT_MAX_OFF_STATE		U(2)
 
 /* Local power state for power domains in Run state. */
-#define PLAT_LOCAL_STATE_RUN		0
+#define PLAT_LOCAL_STATE_RUN		U(0)
 /* Local power state for retention. Valid only for CPU power domains */
-#define PLAT_LOCAL_STATE_RET		1
+#define PLAT_LOCAL_STATE_RET		U(1)
 /*
  * Local power state for OFF/power-down. Valid for CPU and cluster power
  * domains.
@@ -229,4 +230,4 @@
  */
 #define SYS_COUNTER_FREQ_IN_TICKS	((1000 * 1000 * 1000) / 16)
 
-#endif /* __PLATFORM_DEF_H__ */
+#endif /* PLATFORM_DEF_H */
diff --git a/plat/rockchip/rk3328/include/platform_def.h b/plat/rockchip/rk3328/include/platform_def.h
index 019f4e1..56d51ee 100644
--- a/plat/rockchip/rk3328/include/platform_def.h
+++ b/plat/rockchip/rk3328/include/platform_def.h
@@ -1,11 +1,11 @@
 /*
- * Copyright (c) 2017, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2017-2018, ARM Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
 
-#ifndef __PLATFORM_DEF_H__
-#define __PLATFORM_DEF_H__
+#ifndef PLATFORM_DEF_H
+#define PLATFORM_DEF_H
 
 #include <arch.h>
 #include <common_def.h>
@@ -58,13 +58,13 @@
  * 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		1
+#define PLAT_MAX_RET_STATE		U(1)
 
 /*
  * This macro defines the deepest power down states possible. Any state ID
  * higher than this is invalid.
  */
-#define PLAT_MAX_OFF_STATE		2
+#define PLAT_MAX_OFF_STATE		U(2)
 
 /*******************************************************************************
  * Platform memory map related constants
@@ -123,4 +123,4 @@
 #define PSRAM_DO_DDR_RESUME	0
 #define PSRAM_CHECK_WAKEUP_CPU	0
 
-#endif /* __PLATFORM_DEF_H__ */
+#endif /* PLATFORM_DEF_H */
diff --git a/plat/rockchip/rk3368/include/platform_def.h b/plat/rockchip/rk3368/include/platform_def.h
index a61663c..d9a80a7 100644
--- a/plat/rockchip/rk3368/include/platform_def.h
+++ b/plat/rockchip/rk3368/include/platform_def.h
@@ -1,15 +1,16 @@
 /*
- * Copyright (c) 2014-2016, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2014-2018, ARM Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
 
-#ifndef __PLATFORM_DEF_H__
-#define __PLATFORM_DEF_H__
+#ifndef PLATFORM_DEF_H
+#define PLATFORM_DEF_H
 
 #include <arch.h>
 #include <common_def.h>
 #include <rk3368_def.h>
+#include <utils_def.h>
 
 #define DEBUG_XLAT_TABLE 0
 
@@ -58,13 +59,13 @@
  * 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		1
+#define PLAT_MAX_RET_STATE		U(1)
 
 /*
  * This macro defines the deepest power down states possible. Any state ID
  * higher than this is invalid.
  */
-#define PLAT_MAX_OFF_STATE		2
+#define PLAT_MAX_OFF_STATE		U(2)
 
 /*******************************************************************************
  * Platform memory map related constants
@@ -125,4 +126,4 @@
 #define PSRAM_DO_DDR_RESUME	0
 #define PSRAM_CHECK_WAKEUP_CPU	0
 
-#endif /* __PLATFORM_DEF_H__ */
+#endif /* PLATFORM_DEF_H */
diff --git a/plat/rockchip/rk3399/include/platform_def.h b/plat/rockchip/rk3399/include/platform_def.h
index 7139b41..26204a1 100644
--- a/plat/rockchip/rk3399/include/platform_def.h
+++ b/plat/rockchip/rk3399/include/platform_def.h
@@ -1,16 +1,17 @@
 /*
- * Copyright (c) 2014-2016, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2014-2018, ARM Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
 
-#ifndef __PLATFORM_DEF_H__
-#define __PLATFORM_DEF_H__
+#ifndef PLATFORM_DEF_H
+#define PLATFORM_DEF_H
 
 #include <arch.h>
 #include <bl31_param.h>
 #include <common_def.h>
 #include <rk3399_def.h>
+#include <utils_def.h>
 
 #define DEBUG_XLAT_TABLE 0
 
@@ -57,13 +58,13 @@
  * 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		1
+#define PLAT_MAX_RET_STATE		U(1)
 
 /*
  * This macro defines the deepest power down states possible. Any state ID
  * higher than this is invalid.
  */
-#define PLAT_MAX_OFF_STATE		2
+#define PLAT_MAX_OFF_STATE		U(2)
 
 /*******************************************************************************
  * Platform specific page table and MMU setup constants
@@ -110,4 +111,4 @@
 #define PSRAM_DO_DDR_RESUME	1
 #define PSRAM_CHECK_WAKEUP_CPU	0
 
-#endif /* __PLATFORM_DEF_H__ */
+#endif /* PLATFORM_DEF_H */
diff --git a/plat/socionext/synquacer/include/platform_def.h b/plat/socionext/synquacer/include/platform_def.h
index 3e16642..bde7348 100644
--- a/plat/socionext/synquacer/include/platform_def.h
+++ b/plat/socionext/synquacer/include/platform_def.h
@@ -4,10 +4,11 @@
  * SPDX-License-Identifier: BSD-3-Clause
  */
 
-#ifndef __PLATFORM_DEF_H__
-#define __PLATFORM_DEF_H__
+#ifndef PLATFORM_DEF_H
+#define PLATFORM_DEF_H
 
 #include <common_def.h>
+#include <utils_def.h>
 
 /* CPU topology */
 #define PLAT_MAX_CORES_PER_CLUSTER	2
@@ -15,9 +16,9 @@
 #define PLATFORM_CORE_COUNT		(PLAT_CLUSTER_COUNT *	\
 					 PLAT_MAX_CORES_PER_CLUSTER)
 
-#define PLAT_MAX_PWR_LVL		1
-#define PLAT_MAX_RET_STATE		1
-#define PLAT_MAX_OFF_STATE		2
+#define PLAT_MAX_PWR_LVL		U(1)
+#define PLAT_MAX_RET_STATE		U(1)
+#define PLAT_MAX_OFF_STATE		U(2)
 
 #define SQ_LOCAL_STATE_RUN		0
 #define SQ_LOCAL_STATE_RET		1
@@ -78,4 +79,4 @@
 
 #define PLAT_SQ_GPIO_BASE		0x51000000
 
-#endif /* __PLATFORM_DEF_H__ */
+#endif /* PLATFORM_DEF_H */
diff --git a/plat/socionext/uniphier/include/platform_def.h b/plat/socionext/uniphier/include/platform_def.h
index 301aa14..3d71db2 100644
--- a/plat/socionext/uniphier/include/platform_def.h
+++ b/plat/socionext/uniphier/include/platform_def.h
@@ -4,8 +4,8 @@
  * SPDX-License-Identifier: BSD-3-Clause
  */
 
-#ifndef __PLATFORM_DEF_H__
-#define __PLATFORM_DEF_H__
+#ifndef PLATFORM_DEF_H
+#define PLATFORM_DEF_H
 
 #include <common_def.h>
 #include <tbbr/tbbr_img_def.h>
@@ -23,10 +23,10 @@
 #define PLATFORM_CORE_COUNT		\
 	((UNIPHIER_MAX_CPUS_PER_CLUSTER) * (UNIPHIER_CLUSTER_COUNT))
 
-#define PLAT_MAX_PWR_LVL		1
+#define PLAT_MAX_PWR_LVL		U(1)
 
-#define PLAT_MAX_OFF_STATE		2
-#define PLAT_MAX_RET_STATE		1
+#define PLAT_MAX_OFF_STATE		U(2)
+#define PLAT_MAX_RET_STATE		U(1)
 
 #define BL2_BASE			ULL(0x80000000)
 #define BL2_LIMIT			ULL(0x80080000)
@@ -59,4 +59,4 @@
 #define TSP_SEC_MEM_SIZE		((BL32_LIMIT) - (BL32_BASE))
 #define TSP_IRQ_SEC_PHY_TIMER		29
 
-#endif /* __PLATFORM_DEF_H__ */
+#endif /* PLATFORM_DEF_H */
diff --git a/plat/st/stm32mp1/bl2_io_storage.c b/plat/st/stm32mp1/bl2_io_storage.c
new file mode 100644
index 0000000..7346c0c
--- /dev/null
+++ b/plat/st/stm32mp1/bl2_io_storage.c
@@ -0,0 +1,193 @@
+/*
+ * Copyright (c) 2015-2018, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <arch_helpers.h>
+#include <assert.h>
+#include <boot_api.h>
+#include <debug.h>
+#include <io_driver.h>
+#include <io_dummy.h>
+#include <io_storage.h>
+#include <mmio.h>
+#include <platform.h>
+#include <platform_def.h>
+#include <stm32mp1_private.h>
+#include <stm32mp1_rcc.h>
+#include <string.h>
+#include <utils.h>
+
+/* IO devices */
+static const io_dev_connector_t *dummy_dev_con;
+static uintptr_t dummy_dev_handle;
+static uintptr_t dummy_dev_spec;
+
+static const io_block_spec_t bl32_block_spec = {
+	.offset = BL32_BASE,
+	.length = STM32MP1_BL32_SIZE
+};
+
+static const io_block_spec_t bl2_block_spec = {
+	.offset = BL2_BASE,
+	.length = STM32MP1_BL2_SIZE,
+};
+
+static int open_dummy(const uintptr_t spec);
+
+struct plat_io_policy {
+	uintptr_t *dev_handle;
+	uintptr_t image_spec;
+	int (*check)(const uintptr_t spec);
+};
+
+static const struct plat_io_policy policies[] = {
+	[BL2_IMAGE_ID] = {
+		.dev_handle = &dummy_dev_handle,
+		.image_spec = (uintptr_t)&bl2_block_spec,
+		.check = open_dummy
+	},
+	[BL32_IMAGE_ID] = {
+		.dev_handle = &dummy_dev_handle,
+		.image_spec = (uintptr_t)&bl32_block_spec,
+		.check = open_dummy
+	},
+};
+
+static int open_dummy(const uintptr_t spec)
+{
+	return io_dev_init(dummy_dev_handle, 0);
+}
+
+static void print_boot_device(boot_api_context_t *boot_context)
+{
+	switch (boot_context->boot_interface_selected) {
+	case BOOT_API_CTX_BOOT_INTERFACE_SEL_FLASH_SD:
+		INFO("Using SDMMC\n");
+		break;
+	case BOOT_API_CTX_BOOT_INTERFACE_SEL_FLASH_EMMC:
+		INFO("Using EMMC\n");
+		break;
+	default:
+		ERROR("Boot interface not found\n");
+		panic();
+		break;
+	}
+
+	if (boot_context->boot_interface_instance != 0U) {
+		INFO("  Instance %d\n", boot_context->boot_interface_instance);
+	}
+}
+
+static void print_reset_reason(void)
+{
+	uint32_t rstsr = mmio_read_32(RCC_BASE + RCC_MP_RSTSCLRR);
+
+	if (rstsr == 0U) {
+		WARN("Reset reason unknown\n");
+		return;
+	}
+
+	INFO("Reset reason (0x%x):\n", rstsr);
+
+	if ((rstsr & RCC_MP_RSTSCLRR_PADRSTF) == 0U) {
+		if ((rstsr & RCC_MP_RSTSCLRR_STDBYRSTF) != 0U) {
+			INFO("System exits from STANDBY\n");
+			return;
+		}
+
+		if ((rstsr & RCC_MP_RSTSCLRR_CSTDBYRSTF) != 0U) {
+			INFO("MPU exits from CSTANDBY\n");
+			return;
+		}
+	}
+
+	if ((rstsr & RCC_MP_RSTSCLRR_PORRSTF) != 0U) {
+		INFO("  Power-on Reset (rst_por)\n");
+		return;
+	}
+
+	if ((rstsr & RCC_MP_RSTSCLRR_BORRSTF) != 0U) {
+		INFO("  Brownout Reset (rst_bor)\n");
+		return;
+	}
+
+	if ((rstsr & RCC_MP_RSTSCLRR_MPSYSRSTF) != 0U) {
+		INFO("  System reset generated by MPU (MPSYSRST)\n");
+		return;
+	}
+
+	if ((rstsr & RCC_MP_RSTSCLRR_HCSSRSTF) != 0U) {
+		INFO("  Reset due to a clock failure on HSE\n");
+		return;
+	}
+
+	if ((rstsr & RCC_MP_RSTSCLRR_IWDG1RSTF) != 0U) {
+		INFO("  IWDG1 Reset (rst_iwdg1)\n");
+		return;
+	}
+
+	if ((rstsr & RCC_MP_RSTSCLRR_IWDG2RSTF) != 0U) {
+		INFO("  IWDG2 Reset (rst_iwdg2)\n");
+		return;
+	}
+
+	if ((rstsr & RCC_MP_RSTSCLRR_PADRSTF) != 0U) {
+		INFO("  Pad Reset from NRST\n");
+		return;
+	}
+
+	if ((rstsr & RCC_MP_RSTSCLRR_VCORERSTF) != 0U) {
+		INFO("  Reset due to a failure of VDD_CORE\n");
+		return;
+	}
+
+	ERROR("  Unidentified reset reason\n");
+}
+
+void stm32mp1_io_setup(void)
+{
+	int io_result __unused;
+	boot_api_context_t *boot_context =
+		(boot_api_context_t *)stm32mp1_get_boot_ctx_address();
+
+	print_reset_reason();
+
+	print_boot_device(boot_context);
+
+	if ((boot_context->boot_partition_used_toboot == 1U) ||
+	    (boot_context->boot_partition_used_toboot == 2U)) {
+		INFO("Boot used partition fsbl%d\n",
+		     boot_context->boot_partition_used_toboot);
+	}
+
+	io_result = register_io_dev_dummy(&dummy_dev_con);
+	assert(io_result == 0);
+
+	io_result = io_dev_open(dummy_dev_con, dummy_dev_spec,
+				&dummy_dev_handle);
+	assert(io_result == 0);
+}
+
+/*
+ * Return an IO device handle and specification which can be used to access
+ * an image. Use this to enforce platform load policy.
+ */
+int plat_get_image_source(unsigned int image_id, uintptr_t *dev_handle,
+			  uintptr_t *image_spec)
+{
+	int rc;
+	const struct plat_io_policy *policy;
+
+	assert(image_id < ARRAY_SIZE(policies));
+
+	policy = &policies[image_id];
+	rc = policy->check(policy->image_spec);
+	if (rc == 0) {
+		*image_spec = policy->image_spec;
+		*dev_handle = *(policy->dev_handle);
+	}
+
+	return rc;
+}
diff --git a/plat/st/stm32mp1/bl2_plat_setup.c b/plat/st/stm32mp1/bl2_plat_setup.c
new file mode 100644
index 0000000..9f2d8bd
--- /dev/null
+++ b/plat/st/stm32mp1/bl2_plat_setup.c
@@ -0,0 +1,161 @@
+/*
+ * Copyright (c) 2015-2018, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <arch_helpers.h>
+#include <assert.h>
+#include <bl_common.h>
+#include <boot_api.h>
+#include <console.h>
+#include <debug.h>
+#include <delay_timer.h>
+#include <desc_image_load.h>
+#include <generic_delay_timer.h>
+#include <mmio.h>
+#include <platform.h>
+#include <platform_def.h>
+#include <stm32mp1_clk.h>
+#include <stm32mp1_dt.h>
+#include <stm32mp1_pmic.h>
+#include <stm32mp1_private.h>
+#include <stm32mp1_context.h>
+#include <stm32mp1_pwr.h>
+#include <stm32mp1_ram.h>
+#include <stm32mp1_rcc.h>
+#include <stm32mp1_reset.h>
+#include <string.h>
+#include <xlat_tables_v2.h>
+
+void bl2_el3_early_platform_setup(u_register_t arg0, u_register_t arg1,
+				  u_register_t arg2, u_register_t arg3)
+{
+	stm32mp1_save_boot_ctx_address(arg0);
+}
+
+void bl2_platform_setup(void)
+{
+	int ret;
+
+	if (dt_check_pmic()) {
+		initialize_pmic();
+	}
+
+	ret = stm32mp1_ddr_probe();
+	if (ret < 0) {
+		ERROR("Invalid DDR init: error %d\n", ret);
+		panic();
+	}
+
+	INFO("BL2 runs SP_MIN setup\n");
+}
+
+void bl2_el3_plat_arch_setup(void)
+{
+	int32_t result;
+	struct dt_node_info dt_dev_info;
+	const char *board_model;
+	boot_api_context_t *boot_context =
+		(boot_api_context_t *)stm32mp1_get_boot_ctx_address();
+	uint32_t clk_rate;
+
+	/*
+	 * Disable the backup domain write protection.
+	 * The protection is enable at each reset by hardware
+	 * and must be disabled by software.
+	 */
+	mmio_setbits_32(PWR_BASE + PWR_CR1, PWR_CR1_DBP);
+
+	while ((mmio_read_32(PWR_BASE + PWR_CR1) & PWR_CR1_DBP) == 0U) {
+		;
+	}
+
+	/* Reset backup domain on cold boot cases */
+	if ((mmio_read_32(RCC_BASE + RCC_BDCR) & RCC_BDCR_RTCSRC_MASK) == 0U) {
+		mmio_setbits_32(RCC_BASE + RCC_BDCR, RCC_BDCR_VSWRST);
+
+		while ((mmio_read_32(RCC_BASE + RCC_BDCR) & RCC_BDCR_VSWRST) ==
+		       0U) {
+			;
+		}
+
+		mmio_clrbits_32(RCC_BASE + RCC_BDCR, RCC_BDCR_VSWRST);
+	}
+
+	mmap_add_region(BL_CODE_BASE, BL_CODE_BASE,
+			BL_CODE_END - BL_CODE_BASE,
+			MT_CODE | MT_SECURE);
+
+	/* Prevent corruption of preloaded BL32 */
+	mmap_add_region(BL32_BASE, BL32_BASE,
+			BL32_LIMIT - BL32_BASE,
+			MT_MEMORY | MT_RO | MT_SECURE);
+
+	/* Prevent corruption of preloaded Device Tree */
+	mmap_add_region(DTB_BASE, DTB_BASE,
+			DTB_LIMIT - DTB_BASE,
+			MT_MEMORY | MT_RO | MT_SECURE);
+
+	configure_mmu();
+
+	generic_delay_timer_init();
+
+	if (dt_open_and_check() < 0) {
+		panic();
+	}
+
+	if (stm32mp1_clk_probe() < 0) {
+		panic();
+	}
+
+	if (stm32mp1_clk_init() < 0) {
+		panic();
+	}
+
+	result = dt_get_stdout_uart_info(&dt_dev_info);
+
+	if ((result <= 0) ||
+	    (dt_dev_info.status == 0U) ||
+	    (dt_dev_info.clock < 0) ||
+	    (dt_dev_info.reset < 0)) {
+		goto skip_console_init;
+	}
+
+	if (dt_set_stdout_pinctrl() != 0) {
+		goto skip_console_init;
+	}
+
+	if (stm32mp1_clk_enable((unsigned long)dt_dev_info.clock) != 0) {
+		goto skip_console_init;
+	}
+
+	stm32mp1_reset_assert((uint32_t)dt_dev_info.reset);
+	udelay(2);
+	stm32mp1_reset_deassert((uint32_t)dt_dev_info.reset);
+	mdelay(1);
+
+	clk_rate = stm32mp1_clk_get_rate((unsigned long)dt_dev_info.clock);
+
+	if (console_init(dt_dev_info.base, clk_rate,
+			 STM32MP1_UART_BAUDRATE) == 0) {
+		panic();
+	}
+
+	board_model = dt_get_board_model();
+	if (board_model != NULL) {
+		NOTICE("%s\n", board_model);
+	}
+
+skip_console_init:
+
+	if (stm32_save_boot_interface(boot_context->boot_interface_selected,
+				      boot_context->boot_interface_instance) !=
+	    0) {
+		ERROR("Cannot save boot interface\n");
+	}
+
+	stm32mp1_arch_security_setup();
+
+	stm32mp1_io_setup();
+}
diff --git a/plat/st/stm32mp1/include/boot_api.h b/plat/st/stm32mp1/include/boot_api.h
new file mode 100644
index 0000000..71c3593
--- /dev/null
+++ b/plat/st/stm32mp1/include/boot_api.h
@@ -0,0 +1,235 @@
+/*
+ * Copyright (c) 2017, STMicroelectronics - All Rights Reserved
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef __BOOT_API_H
+#define __BOOT_API_H
+
+#include <stdint.h>
+
+/*
+ * Possible value of boot context field 'boot_interface_sel'
+ */
+
+/* Value of field 'boot_interface_sel' when no boot occurred */
+#define BOOT_API_CTX_BOOT_INTERFACE_SEL_NO			0x0U
+
+/* Boot occurred on SD */
+#define BOOT_API_CTX_BOOT_INTERFACE_SEL_FLASH_SD		0x1U
+
+/* Boot occurred on EMMC */
+#define BOOT_API_CTX_BOOT_INTERFACE_SEL_FLASH_EMMC		0x2U
+
+/**
+ * @brief  Possible value of boot context field 'EmmcXferStatus'
+ */
+/*
+ * Possible value of boot context field 'emmc_xfer_status'
+ */
+#define BOOT_API_CTX_EMMC_XFER_STATUS_NOT_STARTED			0x0U
+#define BOOT_API_CTX_EMMC_XFER_STATUS_DATAEND_DETECTED			0x1U
+#define BOOT_API_CTX_EMMC_XFER_STATUS_XFER_OVERALL_TIMEOUT_DETECTED	0x2U
+#define BOOT_API_CTX_EMMC_XFER_STATUS_XFER_DATA_TIMEOUT			0x3U
+
+/*
+ * Possible value of boot context field 'emmc_error_status'
+ */
+#define BOOT_API_CTX_EMMC_ERROR_STATUS_NONE                     0x0U
+#define BOOT_API_CTX_EMMC_ERROR_STATUS_CMD_TIMEOUT              0x1U
+#define BOOT_API_CTX_EMMC_ERROR_STATUS_ACK_TIMEOUT              0x2U
+#define BOOT_API_CTX_EMMC_ERROR_STATUS_DATA_CRC_FAIL            0x3U
+#define BOOT_API_CTX_EMMC_ERROR_STATUS_NOT_ENOUGH_BOOT_DATA_RX  0x4U
+#define BOOT_API_CTX_EMMC_ERROR_STATUS_HEADER_NOT_FOUND         0x5U
+#define BOOT_API_CTX_EMMC_ERROR_STATUS_HEADER_SIZE_ZERO         0x6U
+#define BOOT_API_CTX_EMMC_ERROR_STATUS_IMAGE_NOT_COMPLETE       0x7U
+
+/* Image Header related definitions */
+
+/* Definition of header version */
+#define BOOT_API_HEADER_VERSION					0x00010000U
+
+/*
+ * Magic number used to detect header in memory
+ * Its value must be 'S' 'T' 'M' 0x32, i.e 0x324D5453 as field
+ * 'bootapi_image_header_t.magic'
+ * This identifies the start of a boot image.
+ */
+#define BOOT_API_IMAGE_HEADER_MAGIC_NB				0x324D5453U
+
+/* Definitions related to Authentication used in image header structure */
+#define BOOT_API_ECDSA_PUB_KEY_LEN_IN_BYTES			64
+#define BOOT_API_ECDSA_SIGNATURE_LEN_IN_BYTES			64
+#define BOOT_API_SHA256_DIGEST_SIZE_IN_BYTES			32
+
+/* Possible values of the field 'boot_api_image_header_t.ecc_algo_type' */
+#define BOOT_API_ECDSA_ALGO_TYPE_P256NIST			1
+#define BOOT_API_ECDSA_ALGO_TYPE_BRAINPOOL256			2
+
+/*
+ * Cores secure magic numbers
+ * Constant to be stored in bakcup register
+ * BOOT_API_MAGIC_NUMBER_TAMP_BCK_REG_IDX
+ */
+#define BOOT_API_A7_CORE0_MAGIC_NUMBER				0xCA7FACE0U
+#define BOOT_API_A7_CORE1_MAGIC_NUMBER				0xCA7FACE1U
+
+/*
+ * TAMP_BCK4R register index
+ * This register is used to write a Magic Number in order to restart
+ * Cortex A7 Core 1 and make it execute @ branch address from TAMP_BCK5R
+ */
+#define BOOT_API_CORE1_MAGIC_NUMBER_TAMP_BCK_REG_IDX		4U
+
+/*
+ * TAMP_BCK5R register index
+ * This register is used to contain the branch address of
+ * Cortex A7 Core 1 when restarted by a TAMP_BCK4R magic number writing
+ */
+#define BOOT_API_CORE1_BRANCH_ADDRESS_TAMP_BCK_REG_IDX		5U
+
+/*
+ * Possible value of boot context field 'hse_clock_value_in_hz'
+ */
+#define BOOT_API_CTX_HSE_CLOCK_VALUE_UNDEFINED			0U
+#define BOOT_API_CTX_HSE_CLOCK_VALUE_24_MHZ			24000000U
+#define BOOT_API_CTX_HSE_CLOCK_VALUE_25_MHZ			25000000U
+#define BOOT_API_CTX_HSE_CLOCK_VALUE_26_MHZ			26000000U
+
+/*
+ * Possible value of boot context field 'boot_partition_used_toboot'
+ */
+#define BOOT_API_CTX_BOOT_PARTITION_UNDEFINED			0U
+
+/* Used FSBL1 to boot */
+#define BOOT_API_CTX_BOOT_PARTITION_FSBL1			1U
+
+/* Used FSBL2 to boot */
+#define BOOT_API_CTX_BOOT_PARTITION_FSBL2			2U
+
+/* OTP_CFG0 */
+#define BOOT_API_OTP_MODE_WORD_NB				0
+/* Closed = OTP_CFG0[6] */
+#define BOOT_API_OTP_MODE_CLOSED_BIT_POS			6
+
+/*
+ * Boot Context related definitions
+ */
+
+/*
+ * Boot core boot configuration structure
+ * Specifies all items of the cold boot configuration
+ * Memory and peripheral part.
+ */
+typedef struct {
+	/*
+	 * Boot interface used to boot : take values from defines
+	 * BOOT_API_CTX_BOOT_INTERFACE_SEL_XXX above
+	 */
+	uint16_t boot_interface_selected;
+	uint16_t boot_interface_instance;
+	uint32_t reserved1[13];
+	uint32_t otp_afmux_values[3];
+	uint32_t reserved[9];
+	/*
+	 * Information specific to an SD boot
+	 * Updated each time an SD boot is at least attempted,
+	 * even if not successful
+	 * Note : This is useful to understand why an SD boot failed
+	 * in particular
+	 */
+	uint32_t sd_err_internal_timeout_cnt;
+	uint32_t sd_err_dcrc_fail_cnt;
+	uint32_t sd_err_dtimeout_cnt;
+	uint32_t sd_err_ctimeout_cnt;
+	uint32_t sd_err_ccrc_fail_cnt;
+	uint32_t sd_overall_retry_cnt;
+	/*
+	 * Information specific to an eMMC boot
+	 * Updated each time an eMMC boot is at least attempted,
+	 * even if not successful
+	 * Note : This is useful to understand why an eMMC boot failed
+	 * in particular
+	 */
+	uint32_t emmc_xfer_status;
+	uint32_t emmc_error_status;
+	uint32_t emmc_nbbytes_rxcopied_tosysram_download_area;
+	uint32_t hse_clock_value_in_hz;
+	/*
+	 * Boot partition :
+	 * ie FSBL partition on which the boot was successful
+	 */
+	uint32_t boot_partition_used_toboot;
+
+} __packed boot_api_context_t;
+
+/*
+ * Image Header related definitions
+ */
+
+/*
+ * Structure used to define the common Header format used for FSBL, xloader,
+ * ... and in particular used by bootROM for FSBL header readout.
+ * FSBL header size is 256 Bytes = 0x100
+ */
+typedef struct {
+	/* BOOT_API_IMAGE_HEADER_MAGIC_NB */
+	uint32_t magic;
+	uint8_t image_signature[BOOT_API_ECDSA_SIGNATURE_LEN_IN_BYTES];
+	/*
+	 * Checksum of payload
+	 * 32-bit sum all all payload bytes considered as 8 bit unigned numbers,
+	 * discarding any overflow bits.
+	 * Use to check UART/USB downloaded image integrity when signature
+	 * is not used (i.e bit 0 : 'No_sig_check' = 1 in option flags)
+	 */
+	uint32_t payload_checksum;
+	/* Image header version : should have value BOOT_API_HEADER_VERSION */
+	uint32_t header_version;
+	/* Image length in bytes */
+	uint32_t image_length;
+	/*
+	 * Image Entry point address : should be in the SYSRAM area
+	 * and at least within the download area range
+	 */
+	uint32_t image_entry_point;
+	/* Reserved */
+	uint32_t reserved1;
+	/*
+	 * Image load address : not used by bootROM but to be consistent
+	 * with header format for other packages (xloader, ...)
+	 */
+	uint32_t load_address;
+	/* Reserved */
+	uint32_t reserved2;
+	/* Image version to be compared by bootROM with monotonic
+	 * counter value in OTP_CFG4 prior executing the downloaded image
+	 */
+	uint32_t image_version;
+	/*
+	 * Option flags:
+	 * Bit 0 : No signature check request : 'No_sig_check'
+	 *      value 1 : for No signature check request
+	 *      value 0 : No request to bypass the signature check
+	 * Note : No signature check is never allowed on a Secured chip
+	 */
+	uint32_t option_flags;
+	/*
+	 * Type of ECC algorithm to use  :
+	 * value 1 : for P-256 NIST algorithm
+	 * value 2 : for Brainpool 256 algorithm
+	 * See definitions 'BOOT_API_ECDSA_ALGO_TYPE_XXX' above.
+	 */
+	uint32_t ecc_algo_type;
+	/*
+	 * OEM ECC Public Key (aka Root pubk) provided in header on 512 bits.
+	 * The SHA-256 hash of the OEM ECC pubk must match the one stored
+	 * in OTP cells.
+	 */
+	uint8_t ecc_pubk[BOOT_API_ECDSA_PUB_KEY_LEN_IN_BYTES];
+	/* Pad up to 256 byte total size */
+	uint8_t pad[84];
+} __packed boot_api_image_header_t;
+
+#endif /* __BOOT_API_H */
diff --git a/plat/st/stm32mp1/include/platform_def.h b/plat/st/stm32mp1/include/platform_def.h
new file mode 100644
index 0000000..47e1ffc
--- /dev/null
+++ b/plat/st/stm32mp1/include/platform_def.h
@@ -0,0 +1,187 @@
+/*
+ * Copyright (c) 2015-2018, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef PLATFORM_DEF_H
+#define PLATFORM_DEF_H
+
+#include <arch.h>
+#include <common_def.h>
+#include <gic_common.h>
+#include <utils_def.h>
+#include "../stm32mp1_def.h"
+
+/*******************************************************************************
+ * Generic platform constants
+ ******************************************************************************/
+
+/* Size of cacheable stacks */
+#if defined(IMAGE_BL32)
+#define PLATFORM_STACK_SIZE		0x600
+#else
+#define PLATFORM_STACK_SIZE		0xC00
+#endif
+
+/* SSBL = second stage boot loader */
+#define BL33_IMAGE_NAME			"ssbl"
+
+#define STM32MP1_PRIMARY_CPU		U(0x0)
+
+#define PLATFORM_CACHE_LINE_SIZE	64
+#define PLATFORM_CLUSTER_COUNT		ULL(1)
+#define PLATFORM_CLUSTER0_CORE_COUNT	U(2)
+#define PLATFORM_CLUSTER1_CORE_COUNT	U(0)
+#define PLATFORM_CORE_COUNT		(PLATFORM_CLUSTER1_CORE_COUNT + \
+					 PLATFORM_CLUSTER0_CORE_COUNT)
+#define PLATFORM_MAX_CPUS_PER_CLUSTER	2
+
+#define MAX_IO_DEVICES			4
+#define MAX_IO_HANDLES			4
+
+/*******************************************************************************
+ * BL2 specific defines.
+ ******************************************************************************/
+/*
+ * Put BL2 just below BL3-1. BL2_BASE is calculated using the current BL2 debug
+ * size plus a little space for growth.
+ */
+#define BL2_BASE			STM32MP1_BL2_BASE
+#define BL2_LIMIT			(STM32MP1_BL2_BASE + \
+					 STM32MP1_BL2_SIZE)
+
+/*******************************************************************************
+ * BL32 specific defines.
+ ******************************************************************************/
+#define BL32_BASE			STM32MP1_BL32_BASE
+#define BL32_LIMIT			(STM32MP1_BL32_BASE + \
+					 STM32MP1_BL32_SIZE)
+
+/*******************************************************************************
+ * BL33 specific defines.
+ ******************************************************************************/
+#define BL33_BASE			STM32MP1_BL33_BASE
+
+/*
+ * Load address of BL33 for this platform port
+ */
+#define PLAT_STM32MP1_NS_IMAGE_OFFSET	BL33_BASE
+
+/*******************************************************************************
+ * DTB specific defines.
+ ******************************************************************************/
+#define DTB_BASE			STM32MP1_DTB_BASE
+#define DTB_LIMIT			(STM32MP1_DTB_BASE + \
+					 STM32MP1_DTB_SIZE)
+
+/*******************************************************************************
+ * Platform specific page table and MMU setup constants
+ ******************************************************************************/
+#define PLAT_PHY_ADDR_SPACE_SIZE	(1ULL << 32)
+#define PLAT_VIRT_ADDR_SPACE_SIZE	(1ULL << 32)
+
+/*******************************************************************************
+ * Declarations and constants to access the mailboxes safely. Each mailbox is
+ * aligned on the biggest cache line size in the platform. This is known only
+ * to the platform as it might have a combination of integrated and external
+ * caches. Such alignment ensures that two maiboxes do not sit on the same cache
+ * line at any cache level. They could belong to different cpus/clusters &
+ * get written while being protected by different locks causing corruption of
+ * a valid mailbox address.
+ ******************************************************************************/
+#define CACHE_WRITEBACK_SHIFT		6
+#define CACHE_WRITEBACK_GRANULE		(U(1) << CACHE_WRITEBACK_SHIFT)
+
+/*
+ * Secure Interrupt: based on the standard ARM mapping
+ */
+#define ARM_IRQ_SEC_PHY_TIMER		U(29)
+
+#define ARM_IRQ_SEC_SGI_0		U(8)
+#define ARM_IRQ_SEC_SGI_1		U(9)
+#define ARM_IRQ_SEC_SGI_2		U(10)
+#define ARM_IRQ_SEC_SGI_3		U(11)
+#define ARM_IRQ_SEC_SGI_4		U(12)
+#define ARM_IRQ_SEC_SGI_5		U(13)
+#define ARM_IRQ_SEC_SGI_6		U(14)
+#define ARM_IRQ_SEC_SGI_7		U(15)
+
+#define STM32MP1_IRQ_TZC400		U(36)
+#define STM32MP1_IRQ_TAMPSERRS		U(229)
+#define STM32MP1_IRQ_AXIERRIRQ		U(244)
+
+/*
+ * Define a list of Group 1 Secure and Group 0 interrupts as per GICv3
+ * terminology. On a GICv2 system or mode, the lists will be merged and treated
+ * as Group 0 interrupts.
+ */
+#define PLATFORM_G1S_PROPS(grp) \
+	INTR_PROP_DESC(ARM_IRQ_SEC_PHY_TIMER,		\
+		       GIC_HIGHEST_SEC_PRIORITY,	\
+		       grp, GIC_INTR_CFG_LEVEL),	\
+	INTR_PROP_DESC(STM32MP1_IRQ_TAMPSERRS,		\
+		       GIC_HIGHEST_SEC_PRIORITY,	\
+		       grp, GIC_INTR_CFG_LEVEL),	\
+	INTR_PROP_DESC(STM32MP1_IRQ_AXIERRIRQ,		\
+		       GIC_HIGHEST_SEC_PRIORITY,	\
+		       grp, GIC_INTR_CFG_LEVEL),	\
+	INTR_PROP_DESC(STM32MP1_IRQ_TZC400,		\
+		       GIC_HIGHEST_SEC_PRIORITY,	\
+		       grp, GIC_INTR_CFG_LEVEL),	\
+	INTR_PROP_DESC(ARM_IRQ_SEC_SGI_1,		\
+		       GIC_HIGHEST_SEC_PRIORITY,	\
+		       grp, GIC_INTR_CFG_EDGE),		\
+	INTR_PROP_DESC(ARM_IRQ_SEC_SGI_2,		\
+		       GIC_HIGHEST_SEC_PRIORITY,	\
+		       grp, GIC_INTR_CFG_EDGE),		\
+	INTR_PROP_DESC(ARM_IRQ_SEC_SGI_3,		\
+		       GIC_HIGHEST_SEC_PRIORITY,	\
+		       grp, GIC_INTR_CFG_EDGE),		\
+	INTR_PROP_DESC(ARM_IRQ_SEC_SGI_4,		\
+		       GIC_HIGHEST_SEC_PRIORITY,	\
+		       grp, GIC_INTR_CFG_EDGE),		\
+	INTR_PROP_DESC(ARM_IRQ_SEC_SGI_5,		\
+		       GIC_HIGHEST_SEC_PRIORITY,	\
+		       grp, GIC_INTR_CFG_EDGE),		\
+	INTR_PROP_DESC(ARM_IRQ_SEC_SGI_7,		\
+		       GIC_HIGHEST_SEC_PRIORITY,	\
+		       grp, GIC_INTR_CFG_EDGE)
+
+#define PLATFORM_G0_PROPS(grp) \
+	INTR_PROP_DESC(ARM_IRQ_SEC_SGI_0,		\
+		       GIC_HIGHEST_SEC_PRIORITY,	\
+		       grp, GIC_INTR_CFG_EDGE),		\
+	INTR_PROP_DESC(ARM_IRQ_SEC_SGI_6,		\
+		       GIC_HIGHEST_SEC_PRIORITY,	\
+		       grp, GIC_INTR_CFG_EDGE)
+
+/*
+ * Power
+ */
+#define PLAT_MAX_PWR_LVL	U(1)
+
+/* Local power state for power domains in Run state. */
+#define ARM_LOCAL_STATE_RUN	U(0)
+/* Local power state for retention. Valid only for CPU power domains */
+#define ARM_LOCAL_STATE_RET	U(1)
+/* Local power state for power-down. Valid for CPU and cluster power domains */
+#define ARM_LOCAL_STATE_OFF	U(2)
+/*
+ * 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		ARM_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		ARM_LOCAL_STATE_OFF
+
+/*******************************************************************************
+ * Size of the per-cpu data in bytes that should be reserved in the generic
+ * per-cpu data structure for the FVP port.
+ ******************************************************************************/
+#define PLAT_PCPU_DATA_SIZE	2
+
+#endif /* PLATFORM_DEF_H */
diff --git a/plat/st/stm32mp1/include/stm32mp1_context.h b/plat/st/stm32mp1/include/stm32mp1_context.h
new file mode 100644
index 0000000..fd08afc
--- /dev/null
+++ b/plat/st/stm32mp1/include/stm32mp1_context.h
@@ -0,0 +1,14 @@
+/*
+ * Copyright (c) 2017-2018, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef __STM32MP1_CONTEXT_H__
+#define __STM32MP1_CONTEXT_H__
+
+#include <stdint.h>
+
+int stm32_save_boot_interface(uint32_t interface, uint32_t instance);
+
+#endif /* __STM32MP1_CONTEXT_H__ */
diff --git a/plat/st/stm32mp1/include/stm32mp1_dt.h b/plat/st/stm32mp1/include/stm32mp1_dt.h
new file mode 100644
index 0000000..58e10d1
--- /dev/null
+++ b/plat/st/stm32mp1/include/stm32mp1_dt.h
@@ -0,0 +1,41 @@
+/*
+ * Copyright (c) 2017-2018, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef __STM32MP1_DT_H__
+#define __STM32MP1_DT_H__
+
+#include <stdbool.h>
+
+struct dt_node_info {
+	uint32_t base;
+	int32_t clock;
+	int32_t reset;
+	bool status;
+	bool sec_status;
+};
+
+/*******************************************************************************
+ * Function and variable prototypes
+ ******************************************************************************/
+int dt_open_and_check(void);
+int fdt_get_address(void **fdt_addr);
+bool fdt_check_node(int node);
+bool fdt_check_status(int node);
+bool fdt_check_secure_status(int node);
+uint32_t fdt_read_uint32_default(int node, const char *prop_name,
+				 uint32_t dflt_value);
+int fdt_read_uint32_array(int node, const char *prop_name,
+			  uint32_t *array, uint32_t count);
+int dt_set_pinctrl_config(int node);
+int dt_set_stdout_pinctrl(void);
+void dt_fill_device_info(struct dt_node_info *info, int node);
+int dt_get_node(struct dt_node_info *info, int offset, const char *compat);
+int dt_get_stdout_uart_info(struct dt_node_info *info);
+int dt_get_stdout_node_offset(void);
+uint32_t dt_get_ddr_size(void);
+const char *dt_get_board_model(void);
+
+#endif /* __STM32MP1_DT_H__ */
diff --git a/plat/st/stm32mp1/include/stm32mp1_private.h b/plat/st/stm32mp1/include/stm32mp1_private.h
new file mode 100644
index 0000000..a789d53
--- /dev/null
+++ b/plat/st/stm32mp1/include/stm32mp1_private.h
@@ -0,0 +1,22 @@
+/*
+ * Copyright (c) 2015-2018, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef __STM32MP1_PRIVATE_H__
+#define __STM32MP1_PRIVATE_H__
+
+void stm32mp1_io_setup(void);
+void configure_mmu(void);
+
+void stm32mp1_arch_security_setup(void);
+void stm32mp1_security_setup(void);
+
+void stm32mp1_save_boot_ctx_address(uintptr_t address);
+uintptr_t stm32mp1_get_boot_ctx_address(void);
+
+void stm32mp1_gic_pcpu_init(void);
+void stm32mp1_gic_init(void);
+
+#endif /* __STM32MP1_PRIVATE_H__ */
diff --git a/plat/st/stm32mp1/plat_bl2_mem_params_desc.c b/plat/st/stm32mp1/plat_bl2_mem_params_desc.c
new file mode 100644
index 0000000..6f5bc4c
--- /dev/null
+++ b/plat/st/stm32mp1/plat_bl2_mem_params_desc.c
@@ -0,0 +1,68 @@
+/*
+ * Copyright (c) 2016-2018, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <bl_common.h>
+#include <desc_image_load.h>
+#include <platform.h>
+#include <platform_def.h>
+
+/*******************************************************************************
+ * Following descriptor provides BL image/ep information that gets used
+ * by BL2 to load the images and also subset of this information is
+ * passed to next BL image. The image loading sequence is managed by
+ * populating the images in required loading order. The image execution
+ * sequence is managed by populating the `next_handoff_image_id` with
+ * the next executable image id.
+ ******************************************************************************/
+static bl_mem_params_node_t bl2_mem_params_descs[] = {
+	/* Fill BL32 related information */
+	{
+		.image_id = BL32_IMAGE_ID,
+
+		SET_STATIC_PARAM_HEAD(ep_info, PARAM_EP,
+				      VERSION_2, entry_point_info_t,
+				      SECURE | EXECUTABLE | EP_FIRST_EXE),
+
+		.ep_info.pc = BL32_BASE,
+		.ep_info.spsr = SPSR_MODE32(MODE32_svc, SPSR_T_ARM,
+					    SPSR_E_LITTLE,
+					    DISABLE_ALL_EXCEPTIONS),
+
+		SET_STATIC_PARAM_HEAD(image_info, PARAM_EP,
+				      VERSION_2, image_info_t,
+				      IMAGE_ATTRIB_PLAT_SETUP),
+
+		.image_info.image_base = BL32_BASE,
+		.image_info.image_max_size = BL32_LIMIT - BL32_BASE,
+
+		.next_handoff_image_id = BL33_IMAGE_ID,
+	},
+
+	/* Fill BL33 related information */
+	{
+		.image_id = BL33_IMAGE_ID,
+
+		SET_STATIC_PARAM_HEAD(ep_info, PARAM_EP,
+				      VERSION_2, entry_point_info_t,
+				      NON_SECURE | EXECUTABLE),
+
+		.ep_info.pc = PLAT_STM32MP1_NS_IMAGE_OFFSET,
+		.ep_info.spsr = SPSR_MODE32(MODE32_svc, SPSR_T_ARM,
+					    SPSR_E_LITTLE,
+					    DISABLE_ALL_EXCEPTIONS),
+
+		SET_STATIC_PARAM_HEAD(image_info, PARAM_EP,
+				      VERSION_2, image_info_t, 0),
+
+		.image_info.image_base = PLAT_STM32MP1_NS_IMAGE_OFFSET,
+		.image_info.image_max_size = STM32MP1_DDR_MAX_SIZE -
+			(PLAT_STM32MP1_NS_IMAGE_OFFSET - STM32MP1_DDR_BASE),
+
+		.next_handoff_image_id = INVALID_IMAGE_ID,
+	}
+};
+
+REGISTER_BL_IMAGE_DESCS(bl2_mem_params_descs)
diff --git a/plat/st/stm32mp1/plat_image_load.c b/plat/st/stm32mp1/plat_image_load.c
new file mode 100644
index 0000000..3c6d677
--- /dev/null
+++ b/plat/st/stm32mp1/plat_image_load.c
@@ -0,0 +1,32 @@
+/*
+ * Copyright (c) 2016-2018, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <desc_image_load.h>
+
+/*******************************************************************************
+ * This function flushes the data structures so that they are visible
+ * in memory for the next BL image.
+ ******************************************************************************/
+void plat_flush_next_bl_params(void)
+{
+	flush_bl_params_desc();
+}
+
+/*******************************************************************************
+ * This function returns the list of loadable images.
+ ******************************************************************************/
+bl_load_info_t *plat_get_bl_image_load_info(void)
+{
+	return get_bl_load_info_from_mem_params_desc();
+}
+
+/*******************************************************************************
+ * This function returns the list of executable images.
+ ******************************************************************************/
+bl_params_t *plat_get_next_bl_params(void)
+{
+	return get_next_bl_params_from_mem_params_desc();
+}
diff --git a/plat/st/stm32mp1/platform.mk b/plat/st/stm32mp1/platform.mk
new file mode 100644
index 0000000..3f938d9
--- /dev/null
+++ b/plat/st/stm32mp1/platform.mk
@@ -0,0 +1,148 @@
+#
+# Copyright (c) 2015-2018, ARM Limited and Contributors. All rights reserved.
+#
+# SPDX-License-Identifier: BSD-3-Clause
+#
+
+ARM_CORTEX_A7		:=	yes
+ARM_WITH_NEON		:=	yes
+LOAD_IMAGE_V2		:=	1
+BL2_AT_EL3		:=	1
+ENABLE_PLAT_COMPAT	:=	0
+USE_COHERENT_MEM	:=	0
+
+STM32_TF_VERSION	?=	0
+
+# Not needed for Cortex-A7
+WORKAROUND_CVE_2017_5715:=	0
+
+PLAT_INCLUDES		:=	-Iplat/st/stm32mp1/include/
+PLAT_INCLUDES		+=	-Iinclude/common/tbbr
+PLAT_INCLUDES		+=	-Iinclude/drivers/st
+
+# Device tree
+STM32_DTB_FILE_NAME	?=	stm32mp157c-ev1.dtb
+FDT_SOURCES		:=	$(addprefix fdts/, $(patsubst %.dtb,%.dts,$(STM32_DTB_FILE_NAME)))
+DTC_FLAGS		+=	-Wno-unit_address_vs_reg
+
+include lib/libfdt/libfdt.mk
+
+PLAT_BL_COMMON_SOURCES	:=	plat/st/stm32mp1/stm32mp1_common.c
+
+PLAT_BL_COMMON_SOURCES	+=	drivers/console/aarch32/console.S			\
+				drivers/st/uart/aarch32/stm32_console.S
+
+ifneq (${ENABLE_STACK_PROTECTOR},0)
+PLAT_BL_COMMON_SOURCES	+=	plat/st/stm32mp1/stm32mp1_stack_protector.c
+endif
+
+include lib/xlat_tables_v2/xlat_tables.mk
+PLAT_BL_COMMON_SOURCES	+=	${XLAT_TABLES_LIB_SRCS}
+
+PLAT_BL_COMMON_SOURCES	+=	lib/cpus/aarch32/cortex_a7.S
+
+PLAT_BL_COMMON_SOURCES	+=	${LIBFDT_SRCS}						\
+				drivers/arm/tzc/tzc400.c				\
+				drivers/delay_timer/delay_timer.c			\
+				drivers/delay_timer/generic_delay_timer.c		\
+				drivers/st/clk/stm32mp1_clk.c				\
+				drivers/st/clk/stm32mp1_clkfunc.c			\
+				drivers/st/ddr/stm32mp1_ddr_helpers.c			\
+				drivers/st/gpio/stm32_gpio.c				\
+				drivers/st/pmic/stm32_i2c.c				\
+				drivers/st/pmic/stm32mp1_pmic.c				\
+				drivers/st/pmic/stpmu1.c				\
+				drivers/st/reset/stm32mp1_reset.c			\
+				plat/st/stm32mp1/stm32mp1_context.c			\
+				plat/st/stm32mp1/stm32mp1_dt.c				\
+				plat/st/stm32mp1/stm32mp1_helper.S			\
+				plat/st/stm32mp1/stm32mp1_security.c
+
+BL2_SOURCES		+=	drivers/io/io_dummy.c					\
+				drivers/io/io_storage.c					\
+				plat/st/stm32mp1/bl2_io_storage.c			\
+				plat/st/stm32mp1/bl2_plat_setup.c
+
+BL2_SOURCES		+=	drivers/st/ddr/stm32mp1_ddr.c				\
+				drivers/st/ddr/stm32mp1_ram.c
+
+BL2_SOURCES		+=	common/desc_image_load.c				\
+				plat/st/stm32mp1/plat_bl2_mem_params_desc.c		\
+				plat/st/stm32mp1/plat_image_load.c
+
+# For memory footprint optimization, build with thumb and interwork support
+ASFLAGS			+=	-mthumb -mthumb-interwork
+TF_CFLAGS		+=	-mthumb -mthumb-interwork
+
+# Macros and rules to build TF binary
+STM32_TF_ELF_LDFLAGS	:=	--hash-style=gnu --as-needed
+STM32_DT_BASENAME	:=	$(STM32_DTB_FILE_NAME:.dtb=)
+STM32_TF_STM32		:=	${BUILD_PLAT}/tf-a-${STM32_DT_BASENAME}.stm32
+STM32_TF_BINARY		:=	$(STM32_TF_STM32:.stm32=.bin)
+STM32_TF_MAPFILE	:=	$(STM32_TF_STM32:.stm32=.map)
+STM32_TF_LINKERFILE	:=	$(STM32_TF_STM32:.stm32=.ld)
+STM32_TF_ELF		:=	$(STM32_TF_STM32:.stm32=.elf)
+STM32_TF_DTBFILE	:=      ${BUILD_PLAT}/fdts/${STM32_DTB_FILE_NAME}
+STM32_TF_OBJS		:=	${BUILD_PLAT}/stm32mp1.o
+
+# Variables for use with stm32image
+STM32IMAGEPATH		?= tools/stm32image
+STM32IMAGE		?= ${STM32IMAGEPATH}/stm32image${BIN_EXT}
+
+.PHONY:			${STM32_TF_STM32}
+.SUFFIXES:
+
+all: check_dtc_version ${STM32_TF_STM32} stm32image
+
+ifeq ($(AARCH32_SP),sp_min)
+# BL32 is built only if using SP_MIN
+BL32_DEP		:= bl32
+BL32_PATH		:= -DBL32_BIN_PATH=\"${BUILD_PLAT}/bl32.bin\"
+endif
+
+distclean realclean clean: clean_stm32image
+
+stm32image:
+	${Q}${MAKE} CPPFLAGS="" --no-print-directory -C ${STM32IMAGEPATH}
+
+clean_stm32image:
+	${Q}${MAKE} --no-print-directory -C ${STM32IMAGEPATH} clean
+
+check_dtc_version:
+	$(eval DTC_V = $(shell $(DTC) -v | awk '{print $$NF}'))
+	$(eval DTC_VERSION = $(shell printf "%d" $(shell echo ${DTC_V} | cut -d- -f1 | sed "s/\./0/g")))
+	@if [ ${DTC_VERSION} -lt 10404 ]; then \
+		echo "dtc version too old (${DTC_V}), you need at least version 1.4.4"; \
+		false; \
+	fi
+
+
+${STM32_TF_OBJS}:	plat/st/stm32mp1/stm32mp1.S bl2 ${BL32_DEP} ${STM32_TF_DTBFILE}
+			@echo "  AS      $<"
+			${Q}${AS} ${ASFLAGS} ${TF_CFLAGS} \
+				${BL32_PATH} \
+				-DBL2_BIN_PATH=\"${BUILD_PLAT}/bl2.bin\" \
+				-DDTB_BIN_PATH=\"${STM32_TF_DTBFILE}\" \
+				-c plat/st/stm32mp1/stm32mp1.S -o $@
+
+${STM32_TF_LINKERFILE}:	plat/st/stm32mp1/stm32mp1.ld.S
+			@echo "  LDS     $<"
+			${Q}${AS} ${ASFLAGS} ${TF_CFLAGS} -P -E $< -o $@
+
+${STM32_TF_ELF}:	${STM32_TF_OBJS} ${STM32_TF_LINKERFILE}
+			@echo "  LDS     $<"
+			${Q}${LD} -o $@ ${STM32_TF_ELF_LDFLAGS} -Map=${STM32_TF_MAPFILE} --script ${STM32_TF_LINKERFILE} ${STM32_TF_OBJS}
+
+${STM32_TF_BINARY}:	${STM32_TF_ELF}
+			${Q}${OC} -O binary ${STM32_TF_ELF} $@
+			@echo
+			@echo "Built $@ successfully"
+			@echo
+
+${STM32_TF_STM32}:	stm32image ${STM32_TF_BINARY}
+			@echo
+			@echo "Generated $@"
+			$(eval LOADADDR =  $(shell cat ${STM32_TF_MAPFILE} | grep RAM | awk '{print $$2}'))
+			$(eval ENTRY =  $(shell cat ${STM32_TF_MAPFILE} | grep "__BL2_IMAGE_START" | awk '{print $$1}'))
+			${STM32IMAGE} -s ${STM32_TF_BINARY} -d $@ -l $(LOADADDR) -e ${ENTRY} -v ${STM32_TF_VERSION}
+			@echo
diff --git a/plat/st/stm32mp1/sp_min/sp_min-stm32mp1.mk b/plat/st/stm32mp1/sp_min/sp_min-stm32mp1.mk
new file mode 100644
index 0000000..9fde153
--- /dev/null
+++ b/plat/st/stm32mp1/sp_min/sp_min-stm32mp1.mk
@@ -0,0 +1,21 @@
+#
+# Copyright (c) 2017-2018, ARM Limited and Contributors. All rights reserved.
+#
+# SPDX-License-Identifier: BSD-3-Clause
+#
+
+SP_MIN_WITH_SECURE_FIQ	:=	1
+
+BL32_SOURCES		+=	plat/common/aarch32/platform_mp_stack.S		\
+				plat/st/stm32mp1/sp_min/sp_min_setup.c		\
+				plat/st/stm32mp1/stm32mp1_pm.c			\
+				plat/st/stm32mp1/stm32mp1_topology.c
+# Generic GIC v2
+BL32_SOURCES		+=	drivers/arm/gic/common/gic_common.c	\
+				drivers/arm/gic/v2/gicv2_helpers.c	\
+				drivers/arm/gic/v2/gicv2_main.c		\
+				plat/common/plat_gicv2.c		\
+				plat/st/stm32mp1/stm32mp1_gic.c
+
+# Generic PSCI
+BL32_SOURCES		+=	plat/common/plat_psci_common.c
diff --git a/plat/st/stm32mp1/sp_min/sp_min_setup.c b/plat/st/stm32mp1/sp_min/sp_min_setup.c
new file mode 100644
index 0000000..1329bdb
--- /dev/null
+++ b/plat/st/stm32mp1/sp_min/sp_min_setup.c
@@ -0,0 +1,144 @@
+/*
+ * Copyright (c) 2015-2018, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <arch_helpers.h>
+#include <arm_gic.h>
+#include <assert.h>
+#include <bl_common.h>
+#include <console.h>
+#include <context.h>
+#include <context_mgmt.h>
+#include <debug.h>
+#include <dt-bindings/clock/stm32mp1-clks.h>
+#include <generic_delay_timer.h>
+#include <mmio.h>
+#include <platform.h>
+#include <platform_def.h>
+#include <platform_sp_min.h>
+#include <stm32mp1_clk.h>
+#include <stm32mp1_dt.h>
+#include <stm32mp1_private.h>
+#include <string.h>
+#include <tzc400.h>
+#include <xlat_tables_v2.h>
+
+/******************************************************************************
+ * Placeholder variables for copying the arguments that have been passed to
+ * BL32 from BL2.
+ ******************************************************************************/
+static entry_point_info_t bl33_image_ep_info;
+
+/*******************************************************************************
+ * Interrupt handler for FIQ (secure IRQ)
+ ******************************************************************************/
+void sp_min_plat_fiq_handler(uint32_t id)
+{
+	switch (id) {
+	case STM32MP1_IRQ_TZC400:
+		ERROR("STM32MP1_IRQ_TZC400 generated\n");
+		panic();
+		break;
+	case STM32MP1_IRQ_AXIERRIRQ:
+		ERROR("STM32MP1_IRQ_AXIERRIRQ generated\n");
+		panic();
+		break;
+	default:
+		ERROR("SECURE IT handler not define for it : %i", id);
+		break;
+	}
+}
+
+/*******************************************************************************
+ * 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 *sp_min_plat_get_bl33_ep_info(void)
+{
+	entry_point_info_t *next_image_info;
+
+	next_image_info = &bl33_image_ep_info;
+
+	if (next_image_info->pc == 0U) {
+		return NULL;
+	}
+
+	return next_image_info;
+}
+
+/*******************************************************************************
+ * Perform any BL32 specific platform actions.
+ ******************************************************************************/
+void sp_min_early_platform_setup2(u_register_t arg0, u_register_t arg1,
+				  u_register_t arg2, u_register_t arg3)
+{
+	struct dt_node_info dt_dev_info;
+	int result;
+	bl_params_t *params_from_bl2 = (bl_params_t *)arg0;
+
+	/* Imprecise aborts can be masked in NonSecure */
+	write_scr(read_scr() | SCR_AW_BIT);
+
+	assert(params_from_bl2 != NULL);
+	assert(params_from_bl2->h.type == PARAM_BL_PARAMS);
+	assert(params_from_bl2->h.version >= VERSION_2);
+
+	bl_params_node_t *bl_params = params_from_bl2->head;
+
+	/*
+	 * Copy BL33 entry point information.
+	 * They are stored in Secure RAM, in BL2's address space.
+	 */
+	while (bl_params != NULL) {
+		if (bl_params->image_id == BL33_IMAGE_ID) {
+			bl33_image_ep_info = *bl_params->ep_info;
+			break;
+		}
+
+		bl_params = bl_params->next_params_info;
+	}
+
+	if (dt_open_and_check() < 0) {
+		panic();
+	}
+
+	if (stm32mp1_clk_probe() < 0) {
+		panic();
+	}
+
+	result = dt_get_stdout_uart_info(&dt_dev_info);
+
+	if ((result > 0) && dt_dev_info.status) {
+		if (console_init(dt_dev_info.base, 0, STM32MP1_UART_BAUDRATE)
+		    == 0) {
+			panic();
+		}
+	}
+}
+
+/*******************************************************************************
+ * Initialize the MMU, security and the GIC.
+ ******************************************************************************/
+void sp_min_platform_setup(void)
+{
+	mmap_add_region(BL_CODE_BASE, BL_CODE_BASE,
+			BL_CODE_END - BL_CODE_BASE,
+			MT_CODE | MT_SECURE);
+
+	configure_mmu();
+
+	/* Initialize tzc400 after DDR initialization */
+	stm32mp1_security_setup();
+
+	generic_delay_timer_init();
+
+	stm32mp1_gic_init();
+}
+
+void sp_min_plat_arch_setup(void)
+{
+}
diff --git a/plat/st/stm32mp1/stm32mp1.S b/plat/st/stm32mp1/stm32mp1.S
new file mode 100644
index 0000000..7255fe5
--- /dev/null
+++ b/plat/st/stm32mp1/stm32mp1.S
@@ -0,0 +1,16 @@
+/*
+ * Copyright (c) 2016-2018, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifdef BL32_BIN_PATH
+.section .bl32_image
+.incbin BL32_BIN_PATH
+#endif
+
+.section .bl2_image
+.incbin BL2_BIN_PATH
+
+.section .dtb_image
+.incbin DTB_BIN_PATH
diff --git a/plat/st/stm32mp1/stm32mp1.ld.S b/plat/st/stm32mp1/stm32mp1.ld.S
new file mode 100644
index 0000000..0d7a8bb
--- /dev/null
+++ b/plat/st/stm32mp1/stm32mp1.ld.S
@@ -0,0 +1,76 @@
+/*
+ * Copyright (c) 2015-2018, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef __STM32MP1_LD_S__
+#define __STM32MP1_LD_S__
+#include <platform_def.h>
+#include <xlat_tables_defs.h>
+
+OUTPUT_FORMAT(PLATFORM_LINKER_FORMAT)
+OUTPUT_ARCH(PLATFORM_LINKER_ARCH)
+
+ENTRY(__BL2_IMAGE_START__)
+
+MEMORY {
+	HEADER (rw) : ORIGIN = 0x00000000, LENGTH = 0x3000
+	RAM (rwx) : ORIGIN = STM32MP1_BINARY_BASE, LENGTH = STM32MP1_BINARY_SIZE
+}
+
+SECTIONS
+{
+    /*
+     * TF mapping must conform to ROM code specification.
+     */
+    .header : {
+        __HEADER_START__ = .;
+        KEEP(*(.header))
+        . = ALIGN(4);
+        __HEADER_END__ = .;
+    } >HEADER
+
+    . = STM32MP1_BINARY_BASE;
+    .data . : {
+        . = ALIGN(PAGE_SIZE);
+        __DATA_START__ = .;
+        *(.data*)
+
+        /*
+         * dtb.
+         * The strongest and only alignment contraint is MMU 4K page.
+         * Indeed as images below will be removed, 4K pages will be re-used.
+         */
+        . = ( STM32MP1_DTB_BASE - STM32MP1_BINARY_BASE );
+        __DTB_IMAGE_START__ = .;
+        *(.dtb_image*)
+        __DTB_IMAGE_END__ = .;
+
+        /*
+         * bl2.
+         * The strongest and only alignment contraint is MMU 4K page.
+         * Indeed as images below will be removed, 4K pages will be re-used.
+         */
+        . = ( STM32MP1_BL2_BASE - STM32MP1_BINARY_BASE );
+        __BL2_IMAGE_START__ = .;
+        *(.bl2_image*)
+        __BL2_IMAGE_END__ = .;
+
+        /*
+         * bl32 will be settled by bl2.
+         * The strongest and only alignment constraint is 8 words to simplify
+         * memraise8 assembly code.
+         */
+        . = ( STM32MP1_BL32_BASE - STM32MP1_BINARY_BASE );
+        __BL32_IMAGE_START__ = .;
+        *(.bl32_image*)
+        __BL32_IMAGE_END__ = .;
+
+        __DATA_END__ = .;
+    } >RAM
+
+    __TF_END__ = .;
+
+}
+#endif /*__STM32MP1_LD_S__*/
diff --git a/plat/st/stm32mp1/stm32mp1_common.c b/plat/st/stm32mp1/stm32mp1_common.c
new file mode 100644
index 0000000..68ca7db
--- /dev/null
+++ b/plat/st/stm32mp1/stm32mp1_common.c
@@ -0,0 +1,101 @@
+/*
+ * Copyright (c) 2015-2018, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <arch_helpers.h>
+#include <assert.h>
+#include <bl_common.h>
+#include <debug.h>
+#include <gicv2.h>
+#include <mmio.h>
+#include <platform_def.h>
+#include <platform.h>
+#include <stm32mp1_private.h>
+#include <xlat_tables_v2.h>
+
+#define MAP_SRAM	MAP_REGION_FLAT(STM32MP1_SRAM_BASE, \
+					STM32MP1_SRAM_SIZE, \
+					MT_MEMORY | \
+					MT_RW | \
+					MT_SECURE | \
+					MT_EXECUTE_NEVER)
+
+#define MAP_DEVICE1	MAP_REGION_FLAT(STM32MP1_DEVICE1_BASE, \
+					STM32MP1_DEVICE1_SIZE, \
+					MT_DEVICE | \
+					MT_RW | \
+					MT_SECURE | \
+					MT_EXECUTE_NEVER)
+
+#define MAP_DEVICE2	MAP_REGION_FLAT(STM32MP1_DEVICE2_BASE, \
+					STM32MP1_DEVICE2_SIZE, \
+					MT_DEVICE | \
+					MT_RW | \
+					MT_SECURE | \
+					MT_EXECUTE_NEVER)
+
+#define MAP_DDR		MAP_REGION_FLAT(STM32MP1_DDR_BASE, \
+					STM32MP1_DDR_MAX_SIZE, \
+					MT_MEMORY | \
+					MT_RW | \
+					MT_SECURE | \
+					MT_EXECUTE_NEVER)
+
+#define MAP_DDR_NS	MAP_REGION_FLAT(STM32MP1_DDR_BASE, \
+					STM32MP1_DDR_MAX_SIZE, \
+					MT_MEMORY | \
+					MT_RW | \
+					MT_NS | \
+					MT_EXECUTE_NEVER)
+
+#if defined(IMAGE_BL2)
+static const mmap_region_t stm32mp1_mmap[] = {
+	MAP_SRAM,
+	MAP_DEVICE1,
+	MAP_DEVICE2,
+	MAP_DDR,
+	{0}
+};
+#endif
+#if defined(IMAGE_BL32)
+static const mmap_region_t stm32mp1_mmap[] = {
+	MAP_SRAM,
+	MAP_DEVICE1,
+	MAP_DEVICE2,
+	MAP_DDR_NS,
+	{0}
+};
+#endif
+
+void configure_mmu(void)
+{
+	mmap_add(stm32mp1_mmap);
+	init_xlat_tables();
+
+	enable_mmu_secure(0);
+}
+
+uintptr_t plat_get_ns_image_entrypoint(void)
+{
+	return BL33_BASE;
+}
+
+unsigned int plat_get_syscnt_freq2(void)
+{
+	return read_cntfrq_el0();
+}
+
+/* Functions to save and get boot context address given by ROM code */
+static uintptr_t boot_ctx_address;
+
+void stm32mp1_save_boot_ctx_address(uintptr_t address)
+{
+	boot_ctx_address = address;
+}
+
+uintptr_t stm32mp1_get_boot_ctx_address(void)
+{
+	return boot_ctx_address;
+}
diff --git a/plat/st/stm32mp1/stm32mp1_context.c b/plat/st/stm32mp1/stm32mp1_context.c
new file mode 100644
index 0000000..245fd17
--- /dev/null
+++ b/plat/st/stm32mp1/stm32mp1_context.c
@@ -0,0 +1,42 @@
+/*
+ * Copyright (c) 2017-2018, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <dt-bindings/clock/stm32mp1-clks.h>
+#include <errno.h>
+#include <mmio.h>
+#include <platform_def.h>
+#include <stm32mp1_clk.h>
+#include <stm32mp1_context.h>
+
+#define TAMP_BOOT_ITF_BACKUP_REG_ID	U(20)
+#define TAMP_BOOT_ITF_MASK		U(0x0000FF00)
+#define TAMP_BOOT_ITF_SHIFT		8
+
+int stm32_save_boot_interface(uint32_t interface, uint32_t instance)
+{
+	uint32_t tamp_clk_off = 0;
+	uint32_t bkpr_itf_idx = tamp_bkpr(TAMP_BOOT_ITF_BACKUP_REG_ID);
+
+	if (!stm32mp1_clk_is_enabled(RTCAPB)) {
+		tamp_clk_off = 1;
+		if (stm32mp1_clk_enable(RTCAPB) != 0) {
+			return -EINVAL;
+		}
+	}
+
+	mmio_clrsetbits_32(bkpr_itf_idx,
+			   TAMP_BOOT_ITF_MASK,
+			   ((interface << 4) | (instance & 0xFU)) <<
+			   TAMP_BOOT_ITF_SHIFT);
+
+	if (tamp_clk_off != 0U) {
+		if (stm32mp1_clk_disable(RTCAPB) != 0) {
+			return -EINVAL;
+		}
+	}
+
+	return 0;
+}
diff --git a/plat/st/stm32mp1/stm32mp1_def.h b/plat/st/stm32mp1/stm32mp1_def.h
new file mode 100644
index 0000000..bb3fecf
--- /dev/null
+++ b/plat/st/stm32mp1/stm32mp1_def.h
@@ -0,0 +1,193 @@
+/*
+ * Copyright (c) 2015-2018, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef STM32MP1_DEF_H
+#define STM32MP1_DEF_H
+
+#include <tbbr_img_def.h>
+#include <utils_def.h>
+#include <xlat_tables_defs.h>
+
+/*******************************************************************************
+ * STM32MP1 memory map related constants
+ ******************************************************************************/
+
+#define STM32MP1_SRAM_BASE		U(0x2FFC0000)
+#define STM32MP1_SRAM_SIZE		U(0x00040000)
+
+/* DDR configuration */
+#define STM32MP1_DDR_BASE		U(0xC0000000)
+#define STM32MP1_DDR_SIZE_DFLT		U(0x20000000)	/* 512 MB */
+#define STM32MP1_DDR_MAX_SIZE		U(0x40000000)	/* Max 1GB */
+#define STM32MP1_DDR_SPEED_DFLT		528
+
+/* DDR power initializations */
+#ifndef __ASSEMBLY__
+enum ddr_type {
+	STM32MP_DDR3,
+	STM32MP_LPDDR2,
+};
+#endif
+
+/* Section used inside TF binaries */
+#define STM32MP1_PARAM_LOAD_SIZE	U(0x00002400)	/* 9 Ko for param */
+/* 256 Octets reserved for header */
+#define STM32MP1_HEADER_SIZE		U(0x00000100)
+
+#define STM32MP1_BINARY_BASE		(STM32MP1_SRAM_BASE +		\
+					 STM32MP1_PARAM_LOAD_SIZE +	\
+					 STM32MP1_HEADER_SIZE)
+
+#define STM32MP1_BINARY_SIZE		(STM32MP1_SRAM_SIZE -		\
+					 (STM32MP1_PARAM_LOAD_SIZE +	\
+					  STM32MP1_HEADER_SIZE))
+
+#if STACK_PROTECTOR_ENABLED
+#define STM32MP1_BL32_SIZE		U(0x00012000)	/* 72 Ko for BL32 */
+#else
+#define STM32MP1_BL32_SIZE		U(0x00011000)	/* 68 Ko for BL32 */
+#endif
+
+#define STM32MP1_BL32_BASE		(STM32MP1_SRAM_BASE + \
+					 STM32MP1_SRAM_SIZE - \
+					 STM32MP1_BL32_SIZE)
+
+#if STACK_PROTECTOR_ENABLED
+#define STM32MP1_BL2_SIZE		U(0x00015000)	/* 84 Ko for BL2 */
+#else
+#define STM32MP1_BL2_SIZE		U(0x00013000)	/* 76 Ko for BL2 */
+#endif
+
+#define STM32MP1_BL2_BASE		(STM32MP1_BL32_BASE - \
+					 STM32MP1_BL2_SIZE)
+
+/* BL2 and BL32/sp_min require 5 tables */
+#define MAX_XLAT_TABLES			5
+
+/*
+ * MAX_MMAP_REGIONS is usually:
+ * BL stm32mp1_mmap size + mmap regions in *_plat_arch_setup
+ */
+#if defined(IMAGE_BL2)
+  #define MAX_MMAP_REGIONS		11
+#endif
+#if defined(IMAGE_BL32)
+  #define MAX_MMAP_REGIONS		6
+#endif
+
+/* DTB initialization value */
+#define STM32MP1_DTB_SIZE		U(0x00004000)	/* 16Ko for DTB */
+
+#define STM32MP1_DTB_BASE		(STM32MP1_BL2_BASE - \
+					 STM32MP1_DTB_SIZE)
+
+#define STM32MP1_BL33_BASE		(STM32MP1_DDR_BASE + U(0x100000))
+
+/*******************************************************************************
+ * STM32MP1 device/io map related constants (used for MMU)
+ ******************************************************************************/
+#define STM32MP1_DEVICE1_BASE		U(0x40000000)
+#define STM32MP1_DEVICE1_SIZE		U(0x40000000)
+
+#define STM32MP1_DEVICE2_BASE		U(0x80000000)
+#define STM32MP1_DEVICE2_SIZE		U(0x40000000)
+
+/*******************************************************************************
+ * STM32MP1 RCC
+ ******************************************************************************/
+#define RCC_BASE			U(0x50000000)
+
+/*******************************************************************************
+ * STM32MP1 PWR
+ ******************************************************************************/
+#define PWR_BASE			U(0x50001000)
+
+/*******************************************************************************
+ * STM32MP1 UART
+ ******************************************************************************/
+#define USART1_BASE			U(0x5C000000)
+#define USART2_BASE			U(0x4000E000)
+#define USART3_BASE			U(0x4000F000)
+#define UART4_BASE			U(0x40010000)
+#define UART5_BASE			U(0x40011000)
+#define USART6_BASE			U(0x44003000)
+#define UART7_BASE			U(0x40018000)
+#define UART8_BASE			U(0x40019000)
+#define STM32MP1_DEBUG_USART_BASE	UART4_BASE
+#define STM32MP1_UART_BAUDRATE		115200
+
+/*******************************************************************************
+ * STM32MP1 GIC-400
+ ******************************************************************************/
+#define STM32MP1_GICD_BASE		U(0xA0021000)
+#define STM32MP1_GICC_BASE		U(0xA0022000)
+#define STM32MP1_GICH_BASE		U(0xA0024000)
+#define STM32MP1_GICV_BASE		U(0xA0026000)
+
+/*******************************************************************************
+ * STM32MP1 TZC (TZ400)
+ ******************************************************************************/
+#define STM32MP1_TZC_BASE		U(0x5C006000)
+
+#define STM32MP1_TZC_A7_ID		U(0)
+#define STM32MP1_TZC_LCD_ID		U(3)
+#define STM32MP1_TZC_GPU_ID		U(4)
+#define STM32MP1_TZC_MDMA_ID		U(5)
+#define STM32MP1_TZC_DMA_ID		U(6)
+#define STM32MP1_TZC_USB_HOST_ID	U(7)
+#define STM32MP1_TZC_USB_OTG_ID		U(8)
+#define STM32MP1_TZC_SDMMC_ID		U(9)
+#define STM32MP1_TZC_ETH_ID		U(10)
+#define STM32MP1_TZC_DAP_ID		U(15)
+
+#define STM32MP1_MEMORY_NS		0
+#define STM32MP1_MEMORY_SECURE		1
+
+#define STM32MP1_FILTER_BIT_ALL		3
+
+/*******************************************************************************
+ * STM32MP1 SDMMC
+ ******************************************************************************/
+#define STM32MP1_SDMMC1_BASE		U(0x58005000)
+#define STM32MP1_SDMMC2_BASE		U(0x58007000)
+#define STM32MP1_SDMMC3_BASE		U(0x48004000)
+
+#define STM32MP1_SD_INIT_FREQ			400000		/*400 KHz*/
+#define STM32MP1_SD_NORMAL_SPEED_MAX_FREQ	25000000	/*25 MHz*/
+#define STM32MP1_SD_HIGH_SPEED_MAX_FREQ		50000000	/*50 MHz*/
+#define STM32MP1_EMMC_INIT_FREQ			STM32MP1_SD_INIT_FREQ
+#define STM32MP1_EMMC_NORMAL_SPEED_MAX_FREQ	26000000	/*26 MHz*/
+#define STM32MP1_EMMC_HIGH_SPEED_MAX_FREQ	52000000	/*52 MHz*/
+
+/*******************************************************************************
+ * STM32MP1 TAMP
+ ******************************************************************************/
+#define TAMP_BASE			U(0x5C00A000)
+#define TAMP_BKP_REGISTER_BASE		(TAMP_BASE + U(0x100))
+
+#if !(defined(__LINKER__) || defined(__ASSEMBLY__))
+static inline uint32_t tamp_bkpr(uint32_t idx)
+{
+	return TAMP_BKP_REGISTER_BASE + (idx << 2);
+}
+#endif
+
+/*******************************************************************************
+ * STM32MP1 DDRCTRL
+ ******************************************************************************/
+#define DDRCTRL_BASE			U(0x5A003000)
+
+/*******************************************************************************
+ * STM32MP1 DDRPHYC
+ ******************************************************************************/
+#define DDRPHYC_BASE			U(0x5A004000)
+
+/*******************************************************************************
+ * STM32MP1 I2C4
+ ******************************************************************************/
+#define I2C4_BASE			U(0x5C002000)
+
+#endif /* STM32MP1_DEF_H */
diff --git a/plat/st/stm32mp1/stm32mp1_dt.c b/plat/st/stm32mp1/stm32mp1_dt.c
new file mode 100644
index 0000000..bde968a
--- /dev/null
+++ b/plat/st/stm32mp1/stm32mp1_dt.c
@@ -0,0 +1,476 @@
+/*
+ * Copyright (c) 2017-2018, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <assert.h>
+#include <debug.h>
+#include <libfdt.h>
+#include <platform_def.h>
+#include <stm32_gpio.h>
+#include <stm32mp1_clk.h>
+#include <stm32mp1_clkfunc.h>
+#include <stm32mp1_ddr.h>
+#include <stm32mp1_dt.h>
+#include <stm32mp1_ram.h>
+
+#define DT_GPIO_BANK_SHIFT	12
+#define DT_GPIO_BANK_MASK	0x1F000U
+#define DT_GPIO_PIN_SHIFT	8
+#define DT_GPIO_PIN_MASK	0xF00U
+#define DT_GPIO_MODE_MASK	0xFFU
+
+static int fdt_checked;
+
+static void *fdt = (void *)(uintptr_t)STM32MP1_DTB_BASE;
+
+/*******************************************************************************
+ * This function gets the pin settings from DT information.
+ * When analyze and parsing is done, set the GPIO registers.
+ * Return 0 on success, else return a negative FDT_ERR_xxx error code.
+ ******************************************************************************/
+static int dt_set_gpio_config(int node)
+{
+	const fdt32_t *cuint, *slewrate;
+	int len, pinctrl_node, pinctrl_subnode;
+	uint32_t i;
+	uint32_t speed = GPIO_SPEED_LOW;
+	uint32_t pull = GPIO_NO_PULL;
+
+	cuint = fdt_getprop(fdt, node, "pinmux", &len);
+	if (cuint == NULL) {
+		return -FDT_ERR_NOTFOUND;
+	}
+
+	pinctrl_node = fdt_parent_offset(fdt, fdt_parent_offset(fdt, node));
+	if (pinctrl_node < 0) {
+		return -FDT_ERR_NOTFOUND;
+	}
+
+	slewrate = fdt_getprop(fdt, node, "slew-rate", NULL);
+	if (slewrate != NULL) {
+		speed = fdt32_to_cpu(*slewrate);
+	}
+
+	if (fdt_getprop(fdt, node, "bias-pull-up", NULL) != NULL) {
+		pull = GPIO_PULL_UP;
+	} else if (fdt_getprop(fdt, node, "bias-pull-down", NULL) != NULL) {
+		pull = GPIO_PULL_DOWN;
+	} else {
+		VERBOSE("No bias configured in node %d\n", node);
+	}
+
+	for (i = 0; i < ((uint32_t)len / sizeof(uint32_t)); i++) {
+		uint32_t pincfg;
+		uint32_t bank;
+		uint32_t pin;
+		uint32_t mode;
+		uint32_t alternate = GPIO_ALTERNATE_0;
+
+		pincfg = fdt32_to_cpu(*cuint);
+		cuint++;
+
+		bank = (pincfg & DT_GPIO_BANK_MASK) >> DT_GPIO_BANK_SHIFT;
+
+		pin = (pincfg & DT_GPIO_PIN_MASK) >> DT_GPIO_PIN_SHIFT;
+
+		mode = pincfg & DT_GPIO_MODE_MASK;
+
+		switch (mode) {
+		case 0:
+			mode = GPIO_MODE_INPUT;
+			break;
+		case 1 ... 16:
+			alternate = mode - 1U;
+			mode = GPIO_MODE_ALTERNATE;
+			break;
+		case 17:
+			mode = GPIO_MODE_ANALOG;
+			break;
+		default:
+			mode = GPIO_MODE_OUTPUT;
+			break;
+		}
+
+		if (fdt_getprop(fdt, node, "drive-open-drain", NULL) != NULL) {
+			mode |= GPIO_OPEN_DRAIN;
+		}
+
+		fdt_for_each_subnode(pinctrl_subnode, fdt, pinctrl_node) {
+			uint32_t bank_offset;
+			const fdt32_t *cuint2;
+
+			if (fdt_getprop(fdt, pinctrl_subnode,
+					"gpio-controller", NULL) == NULL) {
+				continue;
+			}
+
+			cuint2 = fdt_getprop(fdt, pinctrl_subnode, "reg", NULL);
+			if (cuint2 == NULL) {
+				continue;
+			}
+
+			if (bank == GPIO_BANK_Z) {
+				bank_offset = 0;
+			} else {
+				bank_offset = bank * STM32_GPIO_BANK_OFFSET;
+			}
+
+			if (fdt32_to_cpu(*cuint2) == bank_offset) {
+				int clk_id = fdt_get_clock_id(pinctrl_subnode);
+
+				if (clk_id < 0) {
+					return -FDT_ERR_NOTFOUND;
+				}
+
+				if (stm32mp1_clk_enable((unsigned long)clk_id) <
+				    0) {
+					return -FDT_ERR_BADVALUE;
+				}
+
+				break;
+			}
+		}
+
+		set_gpio(bank, pin, mode, speed, pull, alternate);
+	}
+
+	return 0;
+}
+
+/*******************************************************************************
+ * This function checks device tree file with its header.
+ * Returns 0 if success, and a negative value else.
+ ******************************************************************************/
+int dt_open_and_check(void)
+{
+	int ret = fdt_check_header(fdt);
+
+	if (ret == 0) {
+		fdt_checked = 1;
+	}
+
+	return ret;
+}
+
+/*******************************************************************************
+ * This function gets the address of the DT.
+ * If DT is OK, fdt_addr is filled with DT address.
+ * Returns 1 if success, 0 otherwise.
+ ******************************************************************************/
+int fdt_get_address(void **fdt_addr)
+{
+	if (fdt_checked == 1) {
+		*fdt_addr = fdt;
+	}
+
+	return fdt_checked;
+}
+
+/*******************************************************************************
+ * This function check the presence of a node (generic use of fdt library).
+ * Returns true if present, false else.
+ ******************************************************************************/
+bool fdt_check_node(int node)
+{
+	int len;
+	const char *cchar;
+
+	cchar = fdt_get_name(fdt, node, &len);
+
+	return (cchar != NULL) && (len >= 0);
+}
+
+/*******************************************************************************
+ * This function check the status of a node (generic use of fdt library).
+ * Returns true if "okay" or missing, false else.
+ ******************************************************************************/
+bool fdt_check_status(int node)
+{
+	int len;
+	const char *cchar;
+
+	cchar = fdt_getprop(fdt, node, "status", &len);
+	if (cchar == NULL) {
+		return true;
+	}
+
+	return strncmp(cchar, "okay", (size_t)len) == 0;
+}
+
+/*******************************************************************************
+ * This function check the secure-status of a node (generic use of fdt library).
+ * Returns true if "okay" or missing, false else.
+ ******************************************************************************/
+bool fdt_check_secure_status(int node)
+{
+	int len;
+	const char *cchar;
+
+	cchar = fdt_getprop(fdt, node, "secure-status", &len);
+	if (cchar == NULL) {
+		return true;
+	}
+
+	return strncmp(cchar, "okay", (size_t)len) == 0;
+}
+
+/*******************************************************************************
+ * This function reads a value of a node property (generic use of fdt
+ * library).
+ * Returns value if success, and a default value if property not found.
+ * Default value is passed as parameter.
+ ******************************************************************************/
+uint32_t fdt_read_uint32_default(int node, const char *prop_name,
+				 uint32_t dflt_value)
+{
+	const fdt32_t *cuint;
+	int lenp;
+
+	cuint = fdt_getprop(fdt, node, prop_name, &lenp);
+	if (cuint == NULL) {
+		return dflt_value;
+	}
+
+	return fdt32_to_cpu(*cuint);
+}
+
+/*******************************************************************************
+ * This function reads a series of parameters in a node property
+ * (generic use of fdt library).
+ * It reads the values inside the device tree, from property name and node.
+ * The number of parameters is also indicated as entry parameter.
+ * Returns 0 if success, and a negative value else.
+ * If success, values are stored at the third parameter address.
+ ******************************************************************************/
+int fdt_read_uint32_array(int node, const char *prop_name, uint32_t *array,
+			  uint32_t count)
+{
+	const fdt32_t *cuint;
+	int len;
+	uint32_t i;
+
+	cuint = fdt_getprop(fdt, node, prop_name, &len);
+	if (cuint == NULL) {
+		return -FDT_ERR_NOTFOUND;
+	}
+
+	if ((uint32_t)len != (count * sizeof(uint32_t))) {
+		return -FDT_ERR_BADLAYOUT;
+	}
+
+	for (i = 0; i < ((uint32_t)len / sizeof(uint32_t)); i++) {
+		*array = fdt32_to_cpu(*cuint);
+		array++;
+		cuint++;
+	}
+
+	return 0;
+}
+
+/*******************************************************************************
+ * This function gets the pin settings from DT information.
+ * When analyze and parsing is done, set the GPIO registers.
+ * Returns 0 if success, and a negative value else.
+ ******************************************************************************/
+int dt_set_pinctrl_config(int node)
+{
+	const fdt32_t *cuint;
+	int lenp = 0;
+	uint32_t i;
+
+	if (!fdt_check_status(node)) {
+		return -FDT_ERR_NOTFOUND;
+	}
+
+	cuint = fdt_getprop(fdt, node, "pinctrl-0", &lenp);
+	if (cuint == NULL) {
+		return -FDT_ERR_NOTFOUND;
+	}
+
+	for (i = 0; i < ((uint32_t)lenp / 4U); i++) {
+		int phandle_node, phandle_subnode;
+
+		phandle_node =
+			fdt_node_offset_by_phandle(fdt, fdt32_to_cpu(*cuint));
+		if (phandle_node < 0) {
+			return -FDT_ERR_NOTFOUND;
+		}
+
+		fdt_for_each_subnode(phandle_subnode, fdt, phandle_node) {
+			int ret = dt_set_gpio_config(phandle_subnode);
+
+			if (ret < 0) {
+				return ret;
+			}
+		}
+
+		cuint++;
+	}
+
+	return 0;
+}
+
+/*******************************************************************************
+ * This function gets the stdout pin configuration information from the DT.
+ * And then calls the sub-function to treat it and set GPIO registers.
+ * Returns 0 if success, and a negative value else.
+ ******************************************************************************/
+int dt_set_stdout_pinctrl(void)
+{
+	int node;
+
+	node = dt_get_stdout_node_offset();
+	if (node < 0) {
+		return -FDT_ERR_NOTFOUND;
+	}
+
+	return dt_set_pinctrl_config(node);
+}
+
+/*******************************************************************************
+ * This function fills the generic information from a given node.
+ ******************************************************************************/
+void dt_fill_device_info(struct dt_node_info *info, int node)
+{
+	const fdt32_t *cuint;
+
+	cuint = fdt_getprop(fdt, node, "reg", NULL);
+	if (cuint != NULL) {
+		info->base = fdt32_to_cpu(*cuint);
+	} else {
+		info->base = 0;
+	}
+
+	cuint = fdt_getprop(fdt, node, "clocks", NULL);
+	if (cuint != NULL) {
+		cuint++;
+		info->clock = (int)fdt32_to_cpu(*cuint);
+	} else {
+		info->clock = -1;
+	}
+
+	cuint = fdt_getprop(fdt, node, "resets", NULL);
+	if (cuint != NULL) {
+		cuint++;
+		info->reset = (int)fdt32_to_cpu(*cuint);
+	} else {
+		info->reset = -1;
+	}
+
+	info->status = fdt_check_status(node);
+	info->sec_status = fdt_check_secure_status(node);
+}
+
+/*******************************************************************************
+ * This function retrieve the generic information from DT.
+ * Returns node if success, and a negative value else.
+ ******************************************************************************/
+int dt_get_node(struct dt_node_info *info, int offset, const char *compat)
+{
+	int node;
+
+	node = fdt_node_offset_by_compatible(fdt, offset, compat);
+	if (node < 0) {
+		return -FDT_ERR_NOTFOUND;
+	}
+
+	dt_fill_device_info(info, node);
+
+	return node;
+}
+
+/*******************************************************************************
+ * This function gets the UART instance info of stdout from the DT.
+ * Returns node if success, and a negative value else.
+ ******************************************************************************/
+int dt_get_stdout_uart_info(struct dt_node_info *info)
+{
+	int node;
+
+	node = dt_get_stdout_node_offset();
+	if (node < 0) {
+		return -FDT_ERR_NOTFOUND;
+	}
+
+	dt_fill_device_info(info, node);
+
+	return node;
+}
+
+/*******************************************************************************
+ * This function gets the stdout path node.
+ * It reads the value indicated inside the device tree.
+ * Returns node if success, and a negative value else.
+ ******************************************************************************/
+int dt_get_stdout_node_offset(void)
+{
+	int node;
+	const char *cchar;
+
+	node = fdt_path_offset(fdt, "/chosen");
+	if (node < 0) {
+		return -FDT_ERR_NOTFOUND;
+	}
+
+	cchar = fdt_getprop(fdt, node, "stdout-path", NULL);
+	if (cchar == NULL) {
+		return -FDT_ERR_NOTFOUND;
+	}
+
+	node = -FDT_ERR_NOTFOUND;
+	if (strchr(cchar, (int)':') != NULL) {
+		const char *name;
+		char *str = (char *)cchar;
+		int len = 0;
+
+		while (strncmp(":", str, 1)) {
+			len++;
+			str++;
+		}
+
+		name = fdt_get_alias_namelen(fdt, cchar, len);
+
+		if (name != NULL) {
+			node = fdt_path_offset(fdt, name);
+		}
+	} else {
+		node = fdt_path_offset(fdt, cchar);
+	}
+
+	return node;
+}
+
+/*******************************************************************************
+ * This function gets DDR size information from the DT.
+ * Returns value in bytes if success, and STM32MP1_DDR_SIZE_DFLT else.
+ ******************************************************************************/
+uint32_t dt_get_ddr_size(void)
+{
+	int node;
+
+	node = fdt_node_offset_by_compatible(fdt, -1, DT_DDR_COMPAT);
+	if (node < 0) {
+		INFO("%s: Cannot read DDR node in DT\n", __func__);
+		return STM32MP1_DDR_SIZE_DFLT;
+	}
+
+	return fdt_read_uint32_default(node, "st,mem-size",
+				       STM32MP1_DDR_SIZE_DFLT);
+}
+
+/*******************************************************************************
+ * This function retrieves board model from DT
+ * Returns string taken from model node, NULL otherwise
+ ******************************************************************************/
+const char *dt_get_board_model(void)
+{
+	int node = fdt_path_offset(fdt, "/");
+
+	if (node < 0) {
+		return NULL;
+	}
+
+	return (const char *)fdt_getprop(fdt, node, "model", NULL);
+}
diff --git a/plat/st/stm32mp1/stm32mp1_gic.c b/plat/st/stm32mp1/stm32mp1_gic.c
new file mode 100644
index 0000000..11eb0a3
--- /dev/null
+++ b/plat/st/stm32mp1/stm32mp1_gic.c
@@ -0,0 +1,48 @@
+/*
+ * Copyright (c) 2016-2018, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <bl_common.h>
+#include <gicv2.h>
+#include <platform.h>
+#include <platform_def.h>
+#include <utils.h>
+
+#include <stm32mp1_private.h>
+
+/******************************************************************************
+ * On a GICv2 system, the Group 1 secure interrupts are treated as Group 0
+ * interrupts.
+ *****************************************************************************/
+static const interrupt_prop_t stm32mp1_interrupt_props[] = {
+	PLATFORM_G1S_PROPS(GICV2_INTR_GROUP0),
+	PLATFORM_G0_PROPS(GICV2_INTR_GROUP0)
+};
+
+static unsigned int target_mask_array[PLATFORM_CORE_COUNT];
+
+static const gicv2_driver_data_t platform_gic_data = {
+	.gicd_base = STM32MP1_GICD_BASE,
+	.gicc_base = STM32MP1_GICC_BASE,
+	.interrupt_props = stm32mp1_interrupt_props,
+	.interrupt_props_num = ARRAY_SIZE(stm32mp1_interrupt_props),
+	.target_masks = target_mask_array,
+	.target_masks_num = ARRAY_SIZE(target_mask_array),
+};
+
+void stm32mp1_gic_init(void)
+{
+	gicv2_driver_init(&platform_gic_data);
+	gicv2_distif_init();
+
+	stm32mp1_gic_pcpu_init();
+}
+
+void stm32mp1_gic_pcpu_init(void)
+{
+	gicv2_pcpu_distif_init();
+	gicv2_set_pe_target_mask(plat_my_core_pos());
+	gicv2_cpuif_enable();
+}
diff --git a/plat/st/stm32mp1/stm32mp1_helper.S b/plat/st/stm32mp1/stm32mp1_helper.S
new file mode 100644
index 0000000..b0ea0d8
--- /dev/null
+++ b/plat/st/stm32mp1/stm32mp1_helper.S
@@ -0,0 +1,180 @@
+/*
+ * Copyright (c) 2015-2018, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <arch.h>
+#include <asm_macros.S>
+#include <bl_common.h>
+#include <platform_def.h>
+#include <stm32_gpio.h>
+#include <stm32mp1_rcc.h>
+
+#define GPIO_BANK_G_ADDRESS	0x50008000
+#define GPIO_TX_PORT		11
+#define GPIO_TX_SHIFT		(GPIO_TX_PORT << 1)
+#define GPIO_TX_ALT_SHIFT	((GPIO_TX_PORT - GPIO_ALT_LOWER_LIMIT) << 2)
+#define STM32MP1_HSI_CLK	64000000
+
+	.globl	platform_mem_init
+	.globl	plat_report_exception
+	.globl	plat_get_my_entrypoint
+	.globl	plat_secondary_cold_boot_setup
+	.globl	plat_reset_handler
+	.globl	plat_is_my_cpu_primary
+	.globl	plat_my_core_pos
+	.globl	plat_crash_console_init
+	.globl	plat_crash_console_flush
+	.globl	plat_crash_console_putc
+	.globl	plat_panic_handler
+
+func platform_mem_init
+	/* Nothing to do, don't need to init SYSRAM */
+	bx	lr
+endfunc platform_mem_init
+
+func plat_report_exception
+	bx	lr
+endfunc plat_report_exception
+
+func plat_reset_handler
+	bx	lr
+endfunc plat_reset_handler
+
+	/* ------------------------------------------------------------------
+	 * unsigned long plat_get_my_entrypoint (void);
+	 *
+	 * Main job of this routine is to distinguish between a cold and warm
+	 * boot.
+	 *
+	 * Currently supports only cold boot
+	 * ------------------------------------------------------------------
+	 */
+func plat_get_my_entrypoint
+	mov	r0, #0
+	bx	lr
+endfunc plat_get_my_entrypoint
+
+	/* ---------------------------------------------
+	 * void plat_secondary_cold_boot_setup (void);
+	 *
+	 * Cold-booting secondary CPUs is not supported.
+	 * ---------------------------------------------
+	 */
+func plat_secondary_cold_boot_setup
+	b	.
+endfunc plat_secondary_cold_boot_setup
+
+	/* -----------------------------------------------------
+	 * unsigned int plat_is_my_cpu_primary (void);
+	 *
+	 * Find out whether the current cpu is the primary cpu.
+	 * -----------------------------------------------------
+	 */
+func plat_is_my_cpu_primary
+	ldcopr	r0, MPIDR
+	ldr	r1, =(MPIDR_CLUSTER_MASK | MPIDR_CPU_MASK)
+	and	r0, r1
+	cmp	r0, #STM32MP1_PRIMARY_CPU
+	moveq	r0, #1
+	movne	r0, #0
+	bx	lr
+endfunc plat_is_my_cpu_primary
+
+	/* -------------------------------------------
+	 *  int plat_stm32mp1_get_core_pos(int mpidr);
+	 *
+	 *  Return CorePos = (ClusterId * 4) + CoreId
+	 * -------------------------------------------
+	 */
+func plat_stm32mp1_get_core_pos
+	and	r1, r0, #MPIDR_CPU_MASK
+	and	r0, r0, #MPIDR_CLUSTER_MASK
+	add	r0, r1, r0, LSR #6
+	bx	lr
+endfunc plat_stm32mp1_get_core_pos
+
+	/* ------------------------------------
+	 *  unsigned int plat_my_core_pos(void)
+	 * ------------------------------------
+	 */
+func plat_my_core_pos
+	ldcopr	r0, MPIDR
+	b	plat_stm32mp1_get_core_pos
+endfunc plat_my_core_pos
+
+	/* ---------------------------------------------
+	 * int plat_crash_console_init(void)
+	 *
+	 * Initialize the crash console without a C Runtime stack.
+	 * ---------------------------------------------
+	 */
+func plat_crash_console_init
+	/* Enable GPIOs for UART4 TX */
+	ldr	r1, =(RCC_BASE + RCC_MP_AHB4ENSETR)
+	ldr	r2, [r1]
+	/* Configure GPIO G11 */
+	orr	r2, r2, #RCC_MP_AHB4ENSETR_GPIOGEN
+	str	r2, [r1]
+	ldr	r1, =GPIO_BANK_G_ADDRESS
+	/* Set GPIO mode alternate */
+	ldr	r2, [r1, #GPIO_MODE_OFFSET]
+	bic	r2, r2, #(GPIO_MODE_MASK << GPIO_TX_SHIFT)
+	orr	r2, r2, #(GPIO_MODE_ALTERNATE << GPIO_TX_SHIFT)
+	str	r2, [r1, #GPIO_MODE_OFFSET]
+	/* Set GPIO speed low */
+	ldr	r2, [r1, #GPIO_SPEED_OFFSET]
+	bic	r2, r2, #(GPIO_SPEED_MASK << GPIO_TX_SHIFT)
+	str	r2, [r1, #GPIO_SPEED_OFFSET]
+	/* Set no-pull */
+	ldr	r2, [r1, #GPIO_PUPD_OFFSET]
+	bic	r2, r2, #(GPIO_PULL_MASK << GPIO_TX_SHIFT)
+	str	r2, [r1, #GPIO_PUPD_OFFSET]
+	/* Set alternate AF6 */
+	ldr	r2, [r1, #GPIO_AFRH_OFFSET]
+	bic	r2, r2, #(GPIO_ALTERNATE_MASK << GPIO_TX_ALT_SHIFT)
+	orr	r2, r2, #(GPIO_ALTERNATE_6 << GPIO_TX_ALT_SHIFT)
+	str	r2, [r1, #GPIO_AFRH_OFFSET]
+
+	/* Enable UART clock, with HSI source */
+	ldr	r1, =(RCC_BASE + RCC_UART24CKSELR)
+	mov	r2, #RCC_UART24CKSELR_HSI
+	str	r2, [r1]
+	ldr	r1, =(RCC_BASE + RCC_MP_APB1ENSETR)
+	ldr	r2, [r1]
+	orr	r2, r2, #RCC_MP_APB1ENSETR_UART4EN
+	str	r2, [r1]
+
+	ldr	r0, =STM32MP1_DEBUG_USART_BASE
+	ldr	r1, =STM32MP1_HSI_CLK
+	ldr	r2, =STM32MP1_UART_BAUDRATE
+	b	console_core_init
+endfunc plat_crash_console_init
+
+	/* ---------------------------------------------
+	 * int plat_crash_console_flush(void)
+	 *
+	 * Flush the crash console without a C Runtime stack.
+	 * ---------------------------------------------
+	 */
+func plat_crash_console_flush
+	ldr	r1, =STM32MP1_DEBUG_USART_BASE
+	b	console_core_flush
+endfunc plat_crash_console_flush
+
+	/* ---------------------------------------------
+	 * int plat_crash_console_putc(int c)
+	 *
+	 * Print a character on the crash console without a C Runtime stack.
+	 * Clobber list : r1 - r3
+	 *
+	 * In case of bootloading through uart, we keep console crash as this.
+	 * Characters could be sent to the programmer, but will be ignored.
+	 * No specific code in that case.
+	 * ---------------------------------------------
+	 */
+func plat_crash_console_putc
+	ldr	r1, =STM32MP1_DEBUG_USART_BASE
+	b	console_core_putc
+endfunc plat_crash_console_putc
diff --git a/plat/st/stm32mp1/stm32mp1_pm.c b/plat/st/stm32mp1/stm32mp1_pm.c
new file mode 100644
index 0000000..e24af0e
--- /dev/null
+++ b/plat/st/stm32mp1/stm32mp1_pm.c
@@ -0,0 +1,255 @@
+/*
+ * Copyright (c) 2015-2018, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <arch_helpers.h>
+#include <assert.h>
+#include <boot_api.h>
+#include <debug.h>
+#include <dt-bindings/clock/stm32mp1-clks.h>
+#include <errno.h>
+#include <gic_common.h>
+#include <gicv2.h>
+#include <mmio.h>
+#include <platform_def.h>
+#include <platform.h>
+#include <psci.h>
+#include <stm32mp1_clk.h>
+#include <stm32mp1_private.h>
+#include <stm32mp1_rcc.h>
+
+static uint32_t stm32_sec_entrypoint;
+static uint32_t cntfrq_core0;
+
+#define SEND_SECURE_IT_TO_CORE_1	0x20000U
+
+/*******************************************************************************
+ * STM32MP1 handler called when a CPU is about to enter standby.
+ * call by core 1 to enter in wfi
+ ******************************************************************************/
+static void stm32_cpu_standby(plat_local_state_t cpu_state)
+{
+	uint32_t interrupt = GIC_SPURIOUS_INTERRUPT;
+
+	assert(cpu_state == ARM_LOCAL_STATE_RET);
+
+	/*
+	 * Enter standby state
+	 * dsb is good practice before using wfi to enter low power states
+	 */
+	dsb();
+	while (interrupt == GIC_SPURIOUS_INTERRUPT) {
+		wfi();
+
+		/* Acknoledge IT */
+		interrupt = gicv2_acknowledge_interrupt();
+		/* If Interrupt == 1022 it will be acknowledged by non secure */
+		if ((interrupt != PENDING_G1_INTID) &&
+		    (interrupt != GIC_SPURIOUS_INTERRUPT)) {
+			gicv2_end_of_interrupt(interrupt);
+		}
+	}
+}
+
+/*******************************************************************************
+ * STM32MP1 handler called when a power domain is about to be turned on. The
+ * mpidr determines the CPU to be turned on.
+ * call by core  0 to activate core 1
+ ******************************************************************************/
+static int stm32_pwr_domain_on(u_register_t mpidr)
+{
+	unsigned long current_cpu_mpidr = read_mpidr_el1();
+	uint32_t tamp_clk_off = 0;
+	uint32_t bkpr_core1_addr =
+		tamp_bkpr(BOOT_API_CORE1_BRANCH_ADDRESS_TAMP_BCK_REG_IDX);
+	uint32_t bkpr_core1_magic =
+		tamp_bkpr(BOOT_API_CORE1_MAGIC_NUMBER_TAMP_BCK_REG_IDX);
+
+	if (mpidr == current_cpu_mpidr) {
+		return PSCI_E_INVALID_PARAMS;
+	}
+
+	if ((stm32_sec_entrypoint < STM32MP1_SRAM_BASE) ||
+	    (stm32_sec_entrypoint > (STM32MP1_SRAM_BASE +
+				     (STM32MP1_SRAM_SIZE - 1)))) {
+		return PSCI_E_INVALID_ADDRESS;
+	}
+
+	if (!stm32mp1_clk_is_enabled(RTCAPB)) {
+		tamp_clk_off = 1;
+		if (stm32mp1_clk_enable(RTCAPB) != 0) {
+			panic();
+		}
+	}
+
+	cntfrq_core0 = read_cntfrq_el0();
+
+	/* Write entrypoint in backup RAM register */
+	mmio_write_32(bkpr_core1_addr, stm32_sec_entrypoint);
+
+	/* Write magic number in backup register */
+	mmio_write_32(bkpr_core1_magic, BOOT_API_A7_CORE1_MAGIC_NUMBER);
+
+	if (tamp_clk_off != 0U) {
+		if (stm32mp1_clk_disable(RTCAPB) != 0) {
+			panic();
+		}
+	}
+
+	/* Generate an IT to core 1 */
+	mmio_write_32(STM32MP1_GICD_BASE + GICD_SGIR,
+		      SEND_SECURE_IT_TO_CORE_1 | ARM_IRQ_SEC_SGI_0);
+
+	return PSCI_E_SUCCESS;
+}
+
+/*******************************************************************************
+ * STM32MP1 handler called when a power domain is about to be turned off. The
+ * target_state encodes the power state that each level should transition to.
+ ******************************************************************************/
+static void stm32_pwr_domain_off(const psci_power_state_t *target_state)
+{
+	/* Nothing to do */
+}
+
+/*******************************************************************************
+ * STM32MP1 handler called when a power domain is about to be suspended. The
+ * target_state encodes the power state that each level should transition to.
+ ******************************************************************************/
+static void stm32_pwr_domain_suspend(const psci_power_state_t *target_state)
+{
+	/* Nothing to do, power domain is not disabled */
+}
+
+/*******************************************************************************
+ * STM32MP1 handler called when a power domain has just been powered on after
+ * being turned off earlier. The target_state encodes the low power state that
+ * each level has woken up from.
+ * call by core 1 just after wake up
+ ******************************************************************************/
+static void stm32_pwr_domain_on_finish(const psci_power_state_t *target_state)
+{
+	stm32mp1_gic_pcpu_init();
+
+	write_cntfrq_el0(cntfrq_core0);
+}
+
+/*******************************************************************************
+ * STM32MP1 handler called when a power domain has just been powered on after
+ * having been suspended earlier. The target_state encodes the low power state
+ * that each level has woken up from.
+ ******************************************************************************/
+static void stm32_pwr_domain_suspend_finish(const psci_power_state_t
+					    *target_state)
+{
+	/* Nothing to do, power domain is not disabled */
+}
+
+static void __dead2 stm32_pwr_domain_pwr_down_wfi(const psci_power_state_t
+						  *target_state)
+{
+	ERROR("stm32mpu1 Power Down WFI: operation not handled.\n");
+	panic();
+}
+
+static void __dead2 stm32_system_off(void)
+{
+	ERROR("stm32mpu1 System Off: operation not handled.\n");
+	panic();
+}
+
+static void __dead2 stm32_system_reset(void)
+{
+	mmio_setbits_32(RCC_BASE + RCC_MP_GRSTCSETR, RCC_MP_GRSTCSETR_MPSYSRST);
+
+	/* Loop in case system reset is not immediately caught */
+	for ( ; ; ) {
+		;
+	}
+}
+
+static int stm32_validate_power_state(unsigned int power_state,
+				      psci_power_state_t *req_state)
+{
+	int pstate = psci_get_pstate_type(power_state);
+
+	if (pstate != 0) {
+		return PSCI_E_INVALID_PARAMS;
+	}
+
+	if (psci_get_pstate_pwrlvl(power_state)) {
+		return PSCI_E_INVALID_PARAMS;
+	}
+
+	if (psci_get_pstate_id(power_state)) {
+		return PSCI_E_INVALID_PARAMS;
+	}
+
+	req_state->pwr_domain_state[0] = ARM_LOCAL_STATE_RET;
+	req_state->pwr_domain_state[1] = ARM_LOCAL_STATE_RUN;
+
+	return PSCI_E_SUCCESS;
+}
+
+static int stm32_validate_ns_entrypoint(uintptr_t entrypoint)
+{
+	/* The non-secure entry point must be in DDR */
+	if (entrypoint < STM32MP1_DDR_BASE) {
+		return PSCI_E_INVALID_ADDRESS;
+	}
+
+	return PSCI_E_SUCCESS;
+}
+
+static int stm32_node_hw_state(u_register_t target_cpu,
+			       unsigned int power_level)
+{
+	/*
+	 * The format of 'power_level' is implementation-defined, but 0 must
+	 * mean a CPU. Only allow level 0.
+	 */
+	if (power_level != MPIDR_AFFLVL0) {
+		return PSCI_E_INVALID_PARAMS;
+	}
+
+	/*
+	 * From psci view the CPU 0 is always ON,
+	 * CPU 1 can be SUSPEND or RUNNING.
+	 * Therefore do not manage POWER OFF state and always return HW_ON.
+	 */
+
+	return (int)HW_ON;
+}
+
+/*******************************************************************************
+ * Export the platform handlers. The ARM Standard platform layer will take care
+ * of registering the handlers with PSCI.
+ ******************************************************************************/
+static const plat_psci_ops_t stm32_psci_ops = {
+	.cpu_standby = stm32_cpu_standby,
+	.pwr_domain_on = stm32_pwr_domain_on,
+	.pwr_domain_off = stm32_pwr_domain_off,
+	.pwr_domain_suspend = stm32_pwr_domain_suspend,
+	.pwr_domain_on_finish = stm32_pwr_domain_on_finish,
+	.pwr_domain_suspend_finish = stm32_pwr_domain_suspend_finish,
+	.pwr_domain_pwr_down_wfi = stm32_pwr_domain_pwr_down_wfi,
+	.system_off = stm32_system_off,
+	.system_reset = stm32_system_reset,
+	.validate_power_state = stm32_validate_power_state,
+	.validate_ns_entrypoint = stm32_validate_ns_entrypoint,
+	.get_node_hw_state = stm32_node_hw_state
+};
+
+/*******************************************************************************
+ * Export the platform specific power ops.
+ ******************************************************************************/
+int plat_setup_psci_ops(uintptr_t sec_entrypoint,
+			const plat_psci_ops_t **psci_ops)
+{
+	stm32_sec_entrypoint = sec_entrypoint;
+	*psci_ops = &stm32_psci_ops;
+
+	return 0;
+}
diff --git a/plat/st/stm32mp1/stm32mp1_security.c b/plat/st/stm32mp1/stm32mp1_security.c
new file mode 100644
index 0000000..e783c14
--- /dev/null
+++ b/plat/st/stm32mp1/stm32mp1_security.c
@@ -0,0 +1,127 @@
+/*
+ * Copyright (c) 2015-2018, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <debug.h>
+#include <dt-bindings/clock/stm32mp1-clks.h>
+#include <mmio.h>
+#include <stdint.h>
+#include <stm32mp1_clk.h>
+#include <stm32mp1_dt.h>
+#include <stm32mp1_private.h>
+#include <stm32mp1_rcc.h>
+#include <tzc400.h>
+#include "platform_def.h"
+
+/*******************************************************************************
+ * Initialize the TrustZone Controller. Configure Region 0 with Secure RW access
+ * and allow Non-Secure masters full access.
+ ******************************************************************************/
+static void init_tzc400(void)
+{
+	unsigned long long region_base, region_top;
+	unsigned long long ddr_base = STM32MP1_DDR_BASE;
+	unsigned long long ddr_size = (unsigned long long)dt_get_ddr_size();
+
+	tzc400_init(STM32MP1_TZC_BASE);
+
+	tzc400_disable_filters();
+
+	/* Region 1 set to cover all DRAM at 0xC000_0000. Apply the
+	 * same configuration to all filters in the TZC.
+	 */
+	region_base = ddr_base;
+	region_top = ddr_base + (ddr_size - 1U);
+	tzc400_configure_region(STM32MP1_FILTER_BIT_ALL, 1,
+			region_base,
+			region_top,
+			TZC_REGION_S_RDWR,
+			TZC_REGION_ACCESS_RDWR(STM32MP1_TZC_A7_ID) |
+			TZC_REGION_ACCESS_RDWR(STM32MP1_TZC_GPU_ID) |
+			TZC_REGION_ACCESS_RDWR(STM32MP1_TZC_LCD_ID) |
+			TZC_REGION_ACCESS_RDWR(STM32MP1_TZC_MDMA_ID) |
+			TZC_REGION_ACCESS_RDWR(STM32MP1_TZC_DMA_ID) |
+			TZC_REGION_ACCESS_RDWR(STM32MP1_TZC_USB_HOST_ID) |
+			TZC_REGION_ACCESS_RDWR(STM32MP1_TZC_USB_OTG_ID) |
+			TZC_REGION_ACCESS_RDWR(STM32MP1_TZC_SDMMC_ID) |
+			TZC_REGION_ACCESS_RDWR(STM32MP1_TZC_ETH_ID) |
+			TZC_REGION_ACCESS_RDWR(STM32MP1_TZC_DAP_ID));
+
+	/* Raise an exception if a NS device tries to access secure memory */
+	tzc400_set_action(TZC_ACTION_ERR);
+
+	tzc400_enable_filters();
+}
+
+/*******************************************************************************
+ * Initialize the TrustZone Controller.
+ * Early initialization create only one region with full access to secure.
+ * This setting is used before and during DDR initialization.
+ ******************************************************************************/
+static void early_init_tzc400(void)
+{
+	uint32_t rstsr, rst_standby;
+
+	rstsr = mmio_read_32(RCC_BASE + RCC_MP_RSTSCLRR);
+
+	/* No warning if return from (C)STANDBY */
+	rst_standby = rstsr &
+		(RCC_MP_RSTSCLRR_STDBYRSTF | RCC_MP_RSTSCLRR_CSTDBYRSTF);
+
+	if (stm32mp1_clk_is_enabled(TZC1) && (rst_standby == 0U)) {
+		WARN("TZC400 port 1 clock already enable\n");
+	}
+
+	if (stm32mp1_clk_is_enabled(TZC2) && (rst_standby == 0U)) {
+		WARN("TZC400 port 2 clock already enable\n");
+	}
+
+	if (stm32mp1_clk_enable(TZC1) != 0) {
+		ERROR("Cannot enable TZC1 clock\n");
+		panic();
+	}
+	if (stm32mp1_clk_enable(TZC2) != 0) {
+		ERROR("Cannot enable TZC2 clock\n");
+		panic();
+	}
+
+	tzc400_init(STM32MP1_TZC_BASE);
+
+	tzc400_disable_filters();
+
+	/*
+	 * Region 1 set to cover Non-Secure DRAM at 0x8000_0000. Apply the
+	 * same configuration to all filters in the TZC.
+	 */
+	tzc400_configure_region(STM32MP1_FILTER_BIT_ALL, 1,
+				STM32MP1_DDR_BASE,
+				STM32MP1_DDR_BASE +
+				(STM32MP1_DDR_MAX_SIZE - 1U),
+				TZC_REGION_S_RDWR,
+				TZC_REGION_ACCESS_RDWR(STM32MP1_TZC_SDMMC_ID));
+
+	/* Raise an exception if a NS device tries to access secure memory */
+	tzc400_set_action(TZC_ACTION_ERR);
+
+	tzc400_enable_filters();
+}
+
+/*******************************************************************************
+ * Initialize the secure environment. At this moment only the TrustZone
+ * Controller is initialized.
+ ******************************************************************************/
+void stm32mp1_arch_security_setup(void)
+{
+	early_init_tzc400();
+}
+
+/*******************************************************************************
+ * Initialize the secure environment. At this moment only the TrustZone
+ * Controller is initialized.
+ ******************************************************************************/
+void stm32mp1_security_setup(void)
+{
+	init_tzc400();
+}
diff --git a/plat/st/stm32mp1/stm32mp1_stack_protector.c b/plat/st/stm32mp1/stm32mp1_stack_protector.c
new file mode 100644
index 0000000..c681300
--- /dev/null
+++ b/plat/st/stm32mp1/stm32mp1_stack_protector.c
@@ -0,0 +1,21 @@
+/*
+ * Copyright (c) 2018, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <arch_helpers.h>
+#include <platform.h>
+#include <stdint.h>
+
+#define RANDOM_CANARY_VALUE	2144346116U
+
+u_register_t plat_get_stack_protector_canary(void)
+{
+	/*
+	 * Ideally, a random number should be returned instead of the
+	 * combination of a timer's value and a compile-time constant.
+	 */
+	return RANDOM_CANARY_VALUE ^ (u_register_t)read_cntpct_el0();
+}
+
diff --git a/plat/st/stm32mp1/stm32mp1_topology.c b/plat/st/stm32mp1/stm32mp1_topology.c
new file mode 100644
index 0000000..405aa33
--- /dev/null
+++ b/plat/st/stm32mp1/stm32mp1_topology.c
@@ -0,0 +1,56 @@
+/*
+ * Copyright (c) 2015-2018, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <platform_def.h>
+#include <platform.h>
+#include <psci.h>
+
+/* 1 cluster, all cores into */
+static const unsigned char stm32mp1_power_domain_tree_desc[] = {
+	PLATFORM_CLUSTER_COUNT,
+	PLATFORM_CORE_COUNT,
+};
+
+/* This function returns the platform topology */
+const unsigned char *plat_get_power_domain_tree_desc(void)
+{
+	return stm32mp1_power_domain_tree_desc;
+}
+
+/*******************************************************************************
+ * 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)
+{
+	unsigned int cluster_id, cpu_id;
+	u_register_t mpidr_copy = mpidr;
+
+	mpidr_copy &= MPIDR_AFFINITY_MASK;
+
+	if ((mpidr_copy & ~(MPIDR_CLUSTER_MASK | MPIDR_CPU_MASK)) != 0U) {
+		return -1;
+	}
+
+	cluster_id = (mpidr_copy >> MPIDR_AFF1_SHIFT) & MPIDR_AFFLVL_MASK;
+	cpu_id = (mpidr_copy >> MPIDR_AFF0_SHIFT) & MPIDR_AFFLVL_MASK;
+
+	if (cluster_id >= PLATFORM_CLUSTER_COUNT) {
+		return -1;
+	}
+
+	/*
+	 * Validate cpu_id by checking whether it represents a CPU in one
+	 * of the two clusters present on the platform.
+	 */
+	if (cpu_id >= PLATFORM_CORE_COUNT) {
+		return -1;
+	}
+
+	return (int)cpu_id;
+}
diff --git a/plat/ti/k3/board/generic/include/board_def.h b/plat/ti/k3/board/generic/include/board_def.h
index 4c59c75..fe0a062 100644
--- a/plat/ti/k3/board/generic/include/board_def.h
+++ b/plat/ti/k3/board/generic/include/board_def.h
@@ -4,8 +4,10 @@
  * SPDX-License-Identifier: BSD-3-Clause
  */
 
-#ifndef __BOARD_DEF_H__
-#define __BOARD_DEF_H__
+#ifndef BOARD_DEF_H
+#define BOARD_DEF_H
+
+#include <utils_def.h>
 
 /* The ports must be in order and contiguous */
 #define K3_CLUSTER0_CORE_COUNT		2
@@ -27,7 +29,7 @@
 #define SEC_SRAM_BASE			0x70000000 /* Base of MSMC SRAM */
 #define SEC_SRAM_SIZE			0x00020000 /* 128k */
 
-#define PLAT_MAX_OFF_STATE		2
-#define PLAT_MAX_RET_STATE		1
+#define PLAT_MAX_OFF_STATE		U(2)
+#define PLAT_MAX_RET_STATE		U(1)
 
-#endif /* __BOARD_DEF_H__ */
+#endif /* BOARD_DEF_H */
diff --git a/plat/ti/k3/common/k3_bl31_setup.c b/plat/ti/k3/common/k3_bl31_setup.c
index ca7d214..3de57a7 100644
--- a/plat/ti/k3/common/k3_bl31_setup.c
+++ b/plat/ti/k3/common/k3_bl31_setup.c
@@ -99,12 +99,18 @@
 
 void bl31_plat_arch_setup(void)
 {
-	arm_setup_page_tables(BL31_BASE,
-			      BL31_END - BL31_BASE,
-			      BL_CODE_BASE,
-			      BL_CODE_END,
-			      BL_RO_DATA_BASE,
-			      BL_RO_DATA_END);
+
+	const mmap_region_t bl_regions[] = {
+		MAP_REGION_FLAT(BL31_BASE, BL31_END - BL31_BASE,
+				MT_MEMORY | MT_RW | MT_SECURE),
+		MAP_REGION_FLAT(BL_CODE_BASE, BL_CODE_END - BL_CODE_BASE,
+				MT_CODE | MT_SECURE),
+		MAP_REGION_FLAT(BL_RO_DATA_BASE, BL_RO_DATA_END - BL_RO_DATA_END,
+				MT_RO_DATA | MT_SECURE),
+		{0}
+	};
+
+	arm_setup_page_tables(bl_regions, plat_arm_get_mmap());
 	enable_mmu_el3(0);
 }
 
diff --git a/plat/xilinx/zynqmp/bl31_zynqmp_setup.c b/plat/xilinx/zynqmp/bl31_zynqmp_setup.c
index 0b3106f..abfb8c6 100644
--- a/plat/xilinx/zynqmp/bl31_zynqmp_setup.c
+++ b/plat/xilinx/zynqmp/bl31_zynqmp_setup.c
@@ -179,13 +179,20 @@
 	plat_arm_interconnect_init();
 	plat_arm_interconnect_enter_coherency();
 
-	arm_setup_page_tables(BL31_BASE,
-			      BL31_END - BL31_BASE,
-			      BL_CODE_BASE,
-			      BL_CODE_END,
-			      BL_RO_DATA_BASE,
-			      BL_RO_DATA_END,
-			      BL_COHERENT_RAM_BASE,
-			      BL_COHERENT_RAM_END);
+
+	const mmap_region_t bl_regions[] = {
+		MAP_REGION_FLAT(BL31_BASE, BL31_END - BL31_BASE,
+			MT_MEMORY | MT_RW | MT_SECURE),
+		MAP_REGION_FLAT(BL_CODE_BASE, BL_CODE_END - BL_CODE_BASE,
+				MT_CODE | MT_SECURE),
+		MAP_REGION_FLAT(BL_RO_DATA_BASE, BL_RO_DATA_END - BL_RO_DATA_BASE,
+				MT_RO_DATA | MT_SECURE),
+		MAP_REGION_FLAT(BL_COHERENT_RAM_BASE,
+				BL_COHERENT_RAM_END - BL_COHERENT_RAM_BASE,
+				MT_DEVICE | MT_RW | MT_SECURE),
+		{0}
+	};
+
+	arm_setup_page_tables(bl_regions, plat_arm_get_mmap());
 	enable_mmu_el3(0);
 }
diff --git a/plat/xilinx/zynqmp/include/platform_def.h b/plat/xilinx/zynqmp/include/platform_def.h
index 49766cc..d721778 100644
--- a/plat/xilinx/zynqmp/include/platform_def.h
+++ b/plat/xilinx/zynqmp/include/platform_def.h
@@ -1,15 +1,16 @@
 /*
- * Copyright (c) 2014-2017, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2014-2018, ARM Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
 
-#ifndef __PLATFORM_DEF_H__
-#define __PLATFORM_DEF_H__
+#ifndef PLATFORM_DEF_H
+#define PLATFORM_DEF_H
 
 #include <arch.h>
 #include <gic_common.h>
 #include <interrupt_props.h>
+#include <utils_def.h>
 #include "../zynqmp_def.h"
 
 /*******************************************************************************
@@ -21,9 +22,9 @@
 
 #define PLATFORM_CORE_COUNT		4
 #define PLAT_NUM_POWER_DOMAINS		5
-#define PLAT_MAX_PWR_LVL		1
-#define PLAT_MAX_RET_STATE		1
-#define PLAT_MAX_OFF_STATE		2
+#define PLAT_MAX_PWR_LVL		U(1)
+#define PLAT_MAX_RET_STATE		U(1)
+#define PLAT_MAX_OFF_STATE		U(2)
 
 /*******************************************************************************
  * BL31 specific defines.
@@ -142,4 +143,4 @@
 
 #define PLAT_ARM_G0_IRQ_PROPS(grp)
 
-#endif /* __PLATFORM_DEF_H__ */
+#endif /* PLATFORM_DEF_H */
diff --git a/plat/xilinx/zynqmp/tsp/tsp_plat_setup.c b/plat/xilinx/zynqmp/tsp/tsp_plat_setup.c
index ecc4d0a..52d4bf8 100644
--- a/plat/xilinx/zynqmp/tsp/tsp_plat_setup.c
+++ b/plat/xilinx/zynqmp/tsp/tsp_plat_setup.c
@@ -44,14 +44,19 @@
  ******************************************************************************/
 void tsp_plat_arch_setup(void)
 {
-	arm_setup_page_tables(BL32_BASE,
-			      BL32_END - BL32_BASE,
-			      BL_CODE_BASE,
-			      BL_CODE_END,
-			      BL_RO_DATA_BASE,
-			      BL_RO_DATA_END,
-			      BL_COHERENT_RAM_BASE,
-			      BL_COHERENT_RAM_END
-			      );
+	const mmap_region_t bl_regions[] = {
+		MAP_REGION_FLAT(BL32_BASE, BL32_END - BL32_BASE,
+			MT_MEMORY | MT_RW | MT_SECURE),
+		MAP_REGION_FLAT(BL_CODE_BASE, BL_CODE_END - BL_CODE_BASE,
+			MT_CODE | MT_SECURE),
+		MAP_REGION_FLAT(BL_RO_DATA_BASE, BL_RO_DATA_END - BL_RO_DATA_BASE,
+			MT_RO_DATA | MT_SECURE),
+		MAP_REGION_FLAT(BL_COHERENT_RAM_BASE,
+			BL_COHERENT_RAM_END - BL_COHERENT_RAM_BASE,
+			MT_DEVICE | MT_RW | MT_SECURE),
+		{0}
+	};
+
+	arm_setup_page_tables(bl_regions, plat_arm_get_mmap());
 	enable_mmu_el1(0);
 }
diff --git a/tools/stm32image/Makefile b/tools/stm32image/Makefile
new file mode 100644
index 0000000..80dfbec
--- /dev/null
+++ b/tools/stm32image/Makefile
@@ -0,0 +1,49 @@
+#
+# Copyright (c) 2017-2018, ARM Limited and Contributors. All rights reserved.
+#
+# SPDX-License-Identifier: BSD-3-Clause
+#
+
+MAKE_HELPERS_DIRECTORY := ../../make_helpers/
+include ${MAKE_HELPERS_DIRECTORY}build_macros.mk
+include ${MAKE_HELPERS_DIRECTORY}build_env.mk
+
+PROJECT := stm32image${BIN_EXT}
+OBJECTS := stm32image.o
+V := 0
+
+override CPPFLAGS += -D_GNU_SOURCE
+CFLAGS := -Wall -Werror -pedantic -std=c99
+ifeq (${DEBUG},1)
+  CFLAGS += -g -O0 -DDEBUG
+else
+  CFLAGS += -O2
+endif
+
+ifeq (${V},0)
+  Q := @
+else
+  Q :=
+endif
+
+CC := gcc
+
+.PHONY: all clean distclean
+
+all: ${PROJECT}
+
+${PROJECT}: ${OBJECTS} Makefile
+	@echo "  LD      $@"
+	${Q}${CC} ${OBJECTS} -o $@
+	@${ECHO_BLANK_LINE}
+	@echo "Built $@ successfully"
+	@${ECHO_BLANK_LINE}
+
+%.o: %.c %.h Makefile
+	@echo "  CC      $<"
+	${Q}${CC} -c ${CFLAGS} $< -o $@
+
+clean:
+	$(call SHELL_DELETE_ALL, ${PROJECT} ${OBJECTS})
+
+distclean: clean
diff --git a/tools/stm32image/stm32image.c b/tools/stm32image/stm32image.c
new file mode 100644
index 0000000..2607928
--- /dev/null
+++ b/tools/stm32image/stm32image.c
@@ -0,0 +1,247 @@
+/*
+ * Copyright (c) 2017-2018, STMicroelectronics - All Rights Reserved
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <asm/byteorder.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <stdint.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sys/mman.h>
+#include <sys/stat.h>
+#include <sys/types.h>
+#include <unistd.h>
+
+/* Magic = 'S' 'T' 'M' 0x32 */
+#define HEADER_MAGIC		__be32_to_cpu(0x53544D32)
+#define VER_MAJOR		2
+#define VER_MINOR		1
+#define VER_VARIANT		0
+#define HEADER_VERSION_V1	0x1
+#define TF_BINARY_TYPE		0x0
+
+/* Default option : bit0 => no signature */
+#define HEADER_DEFAULT_OPTION	(__cpu_to_le32(0x00000001))
+
+struct stm32_header {
+	uint32_t magic_number;
+	uint8_t image_signature[64];
+	uint32_t image_checksum;
+	uint8_t  header_version[4];
+	uint32_t image_length;
+	uint32_t image_entry_point;
+	uint32_t reserved1;
+	uint32_t load_address;
+	uint32_t reserved2;
+	uint32_t version_number;
+	uint32_t option_flags;
+	uint32_t ecdsa_algorithm;
+	uint8_t ecdsa_public_key[64];
+	uint8_t padding[83];
+	uint8_t binary_type;
+};
+
+static struct stm32_header stm32image_header;
+
+static void stm32image_default_header(struct stm32_header *ptr)
+{
+	if (!ptr) {
+		return;
+	}
+
+	ptr->magic_number = HEADER_MAGIC;
+	ptr->header_version[VER_MAJOR] = HEADER_VERSION_V1;
+	ptr->option_flags = HEADER_DEFAULT_OPTION;
+	ptr->ecdsa_algorithm = 1;
+	ptr->version_number = 0;
+	ptr->binary_type = TF_BINARY_TYPE;
+}
+
+static uint32_t stm32image_checksum(void *start, uint32_t len)
+{
+	uint32_t csum = 0;
+	uint32_t hdr_len = sizeof(struct stm32_header);
+	uint8_t *p;
+
+	if (len < hdr_len) {
+		return 0;
+	}
+
+	p = (unsigned char *)start + hdr_len;
+	len -= hdr_len;
+
+	while (len > 0) {
+		csum += *p;
+		p++;
+		len--;
+	}
+
+	return csum;
+}
+
+static void stm32image_print_header(const void *ptr)
+{
+	struct stm32_header *stm32hdr = (struct stm32_header *)ptr;
+
+	printf("Image Type   : ST Microelectronics STM32 V%d.%d\n",
+	       stm32hdr->header_version[VER_MAJOR],
+	       stm32hdr->header_version[VER_MINOR]);
+	printf("Image Size   : %lu bytes\n",
+	       (unsigned long)__le32_to_cpu(stm32hdr->image_length));
+	printf("Image Load   : 0x%08x\n",
+	       __le32_to_cpu(stm32hdr->load_address));
+	printf("Entry Point  : 0x%08x\n",
+	       __le32_to_cpu(stm32hdr->image_entry_point));
+	printf("Checksum     : 0x%08x\n",
+	       __le32_to_cpu(stm32hdr->image_checksum));
+	printf("Option     : 0x%08x\n",
+	       __le32_to_cpu(stm32hdr->option_flags));
+	printf("Version	   : 0x%08x\n",
+	       __le32_to_cpu(stm32hdr->version_number));
+}
+
+static void stm32image_set_header(void *ptr, struct stat *sbuf, int ifd,
+				  uint32_t loadaddr, uint32_t ep, uint32_t ver)
+{
+	struct stm32_header *stm32hdr = (struct stm32_header *)ptr;
+
+	stm32image_default_header(stm32hdr);
+
+	stm32hdr->load_address = __cpu_to_le32(loadaddr);
+	stm32hdr->image_entry_point = __cpu_to_le32(ep);
+	stm32hdr->image_length = __cpu_to_le32((uint32_t)sbuf->st_size -
+					     sizeof(struct stm32_header));
+	stm32hdr->image_checksum = stm32image_checksum(ptr, sbuf->st_size);
+	stm32hdr->version_number = __cpu_to_le32(ver);
+}
+
+static int stm32image_create_header_file(char *srcname, char *destname,
+					 uint32_t loadaddr, uint32_t entry,
+					 uint32_t version)
+{
+	int src_fd, dest_fd;
+	struct stat sbuf;
+	unsigned char *ptr;
+
+	dest_fd = open(destname, O_RDWR | O_CREAT | O_TRUNC | O_APPEND, 0666);
+	if (dest_fd == -1) {
+		fprintf(stderr, "Can't open %s: %s\n", destname,
+			strerror(errno));
+		return -1;
+	}
+
+	src_fd = open(srcname, O_RDONLY);
+	if (src_fd == -1) {
+		fprintf(stderr, "Can't open %s: %s\n", srcname,
+			strerror(errno));
+		return -1;
+	}
+
+	if (fstat(src_fd, &sbuf) < 0) {
+		return -1;
+	}
+
+	ptr = mmap(NULL, sbuf.st_size, PROT_READ, MAP_SHARED, src_fd, 0);
+	if (ptr == MAP_FAILED) {
+		fprintf(stderr, "Can't read %s\n", srcname);
+		return -1;
+	}
+
+	memset(&stm32image_header, 0, sizeof(struct stm32_header));
+
+	if (write(dest_fd, &stm32image_header, sizeof(struct stm32_header)) !=
+	    sizeof(struct stm32_header)) {
+		fprintf(stderr, "Write error %s: %s\n", destname,
+			strerror(errno));
+		return -1;
+	}
+
+	if (write(dest_fd, ptr, sbuf.st_size) != sbuf.st_size) {
+		fprintf(stderr, "Write error on %s: %s\n", destname,
+			strerror(errno));
+		return -1;
+	}
+
+	munmap((void *)ptr, sbuf.st_size);
+	close(src_fd);
+
+	if (fstat(dest_fd, &sbuf) < 0) {
+		return -1;
+	}
+
+	ptr = mmap(0, sbuf.st_size, PROT_READ | PROT_WRITE, MAP_SHARED,
+		   dest_fd, 0);
+
+	if (ptr == MAP_FAILED) {
+		fprintf(stderr, "Can't read %s\n", srcname);
+		return -1;
+	}
+
+	stm32image_set_header(ptr, &sbuf, dest_fd, loadaddr, entry, version);
+
+	stm32image_print_header(ptr);
+
+	munmap((void *)ptr, sbuf.st_size);
+	close(dest_fd);
+	return 0;
+}
+
+int main(int argc, char *argv[])
+{
+	int opt, loadaddr = -1, entry = -1, err = 0, version = 0;
+	char *dest = NULL, *src = NULL;
+
+	while ((opt = getopt(argc, argv, ":s:d:l:e:v:")) != -1) {
+		switch (opt) {
+		case 's':
+			src = optarg;
+			break;
+		case 'd':
+			dest = optarg;
+			break;
+		case 'l':
+			loadaddr = strtol(optarg, NULL, 16);
+			break;
+		case 'e':
+			entry = strtol(optarg, NULL, 16);
+			break;
+		case 'v':
+			version = strtol(optarg, NULL, 10);
+			break;
+		default:
+			fprintf(stderr,
+				"Usage : %s [-s srcfile] [-d destfile] [-l loadaddr] [-e entry_point]\n",
+					argv[0]);
+			return -1;
+		}
+	}
+
+	if (!src) {
+		fprintf(stderr, "Missing -s option\n");
+		return -1;
+	}
+
+	if (!dest) {
+		fprintf(stderr, "Missing -d option\n");
+		return -1;
+	}
+
+	if (loadaddr == -1) {
+		fprintf(stderr, "Missing -l option\n");
+		return -1;
+	}
+
+	if (entry == -1) {
+		fprintf(stderr, "Missing -e option\n");
+		return -1;
+	}
+
+	err = stm32image_create_header_file(src, dest, loadaddr,
+					    entry, version);
+
+	return err;
+}