Merge "a8k: Implement platform specific power off" into integration
diff --git a/docs/plat/rpi4.rst b/docs/plat/rpi4.rst
index 0f529c1..beb0227 100644
--- a/docs/plat/rpi4.rst
+++ b/docs/plat/rpi4.rst
@@ -24,11 +24,10 @@
 
     CROSS_COMPILE=aarch64-linux-gnu- make PLAT=rpi4 DEBUG=1
 
-Copy the generated build/rpi4/debug/bl31.bin to the SD card, either
-renaming it to ``armstub8.bin`` or adding an entry starting with ``armstub=``,
-then followed by the respective file name to ``config.txt``.
-You should have AArch64 code in the file loaded as the "kernel", as BL31
-will drop into AArch64/EL2 to the respective load address.
+Copy the generated build/rpi4/debug/bl31.bin to the SD card, adding an entry
+starting with ``armstub=``, then followed by the respective file name to
+``config.txt``. You should have AArch64 code in the file loaded as the
+"kernel", as BL31 will drop into AArch64/EL2 to the respective load address.
 arm64 Linux kernels are known to work this way.
 
 Other options that should be set in ``config.txt`` to properly boot 64-bit
diff --git a/drivers/ti/uart/aarch32/16550_console.S b/drivers/ti/uart/aarch32/16550_console.S
index 6921884..5cd9b30 100644
--- a/drivers/ti/uart/aarch32/16550_console.S
+++ b/drivers/ti/uart/aarch32/16550_console.S
@@ -89,16 +89,19 @@
 	.globl console_16550_register
 
 	/* -------------------------------------------------------
-	 * int console_stm32_register(uintptr_t baseaddr,
+	 * int console_16550_register(uintptr_t baseaddr,
 	 *     uint32_t clock, uint32_t baud,
-	 *     struct console_stm32 *console);
-	 * Function to initialize and register a new STM32
+	 *     console_16550_t *console);
+	 * Function to initialize and register a new 16550
 	 * console. Storage passed in for the console struct
 	 * *must* be persistent (i.e. not from the stack).
+	 * If r1 (UART clock) is 0, initialisation will be
+         * skipped, relying on previous code to have done
+         * this already. r2 is ignored then as well.
 	 * In: r0 - UART register base address
 	 *     r1 - UART clock in Hz
-	 *     r2 - Baud rate
-	 *     r3 - pointer to empty console_stm32 struct
+	 *     r2 - Baud rate (ignored if r1 is 0)
+	 *     r3 - pointer to empty console_16550_t struct
 	 * Out: return 1 on success, 0 on error
 	 * Clobber list : r0, r1, r2
 	 * -------------------------------------------------------
@@ -110,10 +113,15 @@
 	beq	register_fail
 	str	r0, [r4, #CONSOLE_T_16550_BASE]
 
+	/* A clock rate of zero means to skip the initialisation. */
+	cmp	r1, #0
+	beq	register_16550
+
 	bl	console_16550_core_init
 	cmp	r0, #0
 	beq	register_fail
 
+register_16550:
 	mov	r0, r4
 	pop	{r4, lr}
 	finish_console_register 16550 putc=1, getc=1, flush=1
diff --git a/drivers/ti/uart/aarch64/16550_console.S b/drivers/ti/uart/aarch64/16550_console.S
index dab46e8..80c1b86 100644
--- a/drivers/ti/uart/aarch64/16550_console.S
+++ b/drivers/ti/uart/aarch64/16550_console.S
@@ -92,9 +92,12 @@
 	 * Function to initialize and register a new 16550
 	 * console. Storage passed in for the console struct
 	 * *must* be persistent (i.e. not from the stack).
+	 * If w1 (UART clock) is 0, initialisation will be
+	 * skipped, relying on previous code to have done
+	 * this already. w2 is ignored then as well.
 	 * In: x0 - UART register base address
 	 *     w1 - UART clock in Hz
-	 *     w2 - Baud rate
+	 *     w2 - Baud rate (ignored if w1 is 0)
 	 *     x3 - pointer to empty console_16550_t struct
 	 * Out: return 1 on success, 0 on error
 	 * Clobber list : x0, x1, x2, x6, x7, x14
@@ -106,9 +109,13 @@
 	cbz	x6, register_fail
 	str	x0, [x6, #CONSOLE_T_16550_BASE]
 
+	/* A clock rate of zero means to skip the initialisation. */
+	cbz	w1, register_16550
+
 	bl	console_16550_core_init
 	cbz	x0, register_fail
 
+register_16550:
 	mov	x0, x6
 	mov	x30, x7
 	finish_console_register 16550 putc=1, getc=1, flush=1
diff --git a/include/drivers/ti/uart/uart_16550.h b/include/drivers/ti/uart/uart_16550.h
index 32e38f0..2b95fa3 100644
--- a/include/drivers/ti/uart/uart_16550.h
+++ b/include/drivers/ti/uart/uart_16550.h
@@ -87,6 +87,11 @@
  * framework. The |console| pointer must point to storage that will be valid
  * for the lifetime of the console, such as a global or static local variable.
  * Its contents will be reinitialized from scratch.
+ * When |clock| has a value of 0, the UART will *not* be initialised. This
+ * means the UART should already be enabled and the baudrate and clock setup
+ * should have been done already, either by platform specific code or by
+ * previous firmware stages. The |baud| parameter will be ignored in this
+ * case as well.
  */
 int console_16550_register(uintptr_t baseaddr, uint32_t clock, uint32_t baud,
 			   console_16550_t *console);
diff --git a/plat/allwinner/common/allwinner-common.mk b/plat/allwinner/common/allwinner-common.mk
index d281011..98bcf3e 100644
--- a/plat/allwinner/common/allwinner-common.mk
+++ b/plat/allwinner/common/allwinner-common.mk
@@ -55,11 +55,11 @@
 # Allow mapping read-only data as execute-never.
 SEPARATE_CODE_AND_RODATA	:=	1
 
+# Put NOBITS memory in SRAM A1, overwriting U-Boot's SPL.
+SEPARATE_NOBITS_REGION		:=	1
+
 # BL31 gets loaded alongside BL33 (U-Boot) by U-Boot's SPL
 RESET_TO_BL31			:=	1
 
-# We are short on memory, so save 3.5KB by not having an extra coherent page.
-USE_COHERENT_MEM		:=	0
-
 # This platform is single-cluster and does not require coherency setup.
 WARMBOOT_ENABLE_DCACHE_EARLY	:=	1
diff --git a/plat/allwinner/common/include/platform_def.h b/plat/allwinner/common/include/platform_def.h
index ede3881..0a00076 100644
--- a/plat/allwinner/common/include/platform_def.h
+++ b/plat/allwinner/common/include/platform_def.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2017-2018, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2017-2019, ARM Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -16,6 +16,10 @@
 #define BL31_BASE			SUNXI_SRAM_A2_BASE
 #define BL31_LIMIT			(SUNXI_SRAM_A2_BASE + SUNXI_SRAM_A2_SIZE)
 
+/* Overwrite U-Boot SPL, but reserve the first page for the SPL header. */
+#define BL31_NOBITS_BASE		(SUNXI_SRAM_A1_BASE + 0x1000)
+#define BL31_NOBITS_LIMIT		(SUNXI_SRAM_A1_BASE + SUNXI_SRAM_A1_SIZE)
+
 /* The traditional U-Boot load address is 160MB into DRAM, so at 0x4a000000 */
 #define PLAT_SUNXI_NS_IMAGE_OFFSET	(SUNXI_DRAM_BASE + (160U << 20))
 
@@ -28,7 +32,7 @@
 #define CACHE_WRITEBACK_SHIFT		6
 #define CACHE_WRITEBACK_GRANULE		(1 << CACHE_WRITEBACK_SHIFT)
 
-#define MAX_MMAP_REGIONS		(3 + PLATFORM_MMAP_REGIONS)
+#define MAX_MMAP_REGIONS		(4 + PLATFORM_MMAP_REGIONS)
 #define MAX_XLAT_TABLES			1
 
 #define PLAT_MAX_PWR_LVL_STATES		U(2)
diff --git a/plat/allwinner/common/sunxi_common.c b/plat/allwinner/common/sunxi_common.c
index 1e21a42..cff8268 100644
--- a/plat/allwinner/common/sunxi_common.c
+++ b/plat/allwinner/common/sunxi_common.c
@@ -57,6 +57,10 @@
 	mmap_add_region(BL_RO_DATA_BASE, BL_RO_DATA_BASE,
 			BL_RO_DATA_END - BL_RO_DATA_BASE,
 			MT_RO_DATA | MT_SECURE);
+	mmap_add_region(BL_COHERENT_RAM_BASE, BL_COHERENT_RAM_BASE,
+			BL_COHERENT_RAM_END - BL_COHERENT_RAM_BASE,
+			MT_DEVICE | MT_RW | MT_SECURE | MT_EXECUTE_NEVER);
+
 	mmap_add(sunxi_mmap);
 	init_xlat_tables();
 
diff --git a/plat/intel/soc/agilex/soc/agilex_memory_controller.c b/plat/intel/soc/agilex/soc/agilex_memory_controller.c
index 5f3cae7..2aabe87 100644
--- a/plat/intel/soc/agilex/soc/agilex_memory_controller.c
+++ b/plat/intel/soc/agilex/soc/agilex_memory_controller.c
@@ -20,9 +20,8 @@
 #define PRE_CALIBRATION_DELAY		1
 #define POST_CALIBRATION_DELAY		1
 #define TIMEOUT_EMIF_CALIBRATION	1000
-#define CLEAR_EMIF_DELAY		50000
-#define CLEAR_EMIF_TIMEOUT		0x100000
-#define TIMEOUT_INT_RESP		10000
+#define CLEAR_EMIF_DELAY		1000
+#define CLEAR_EMIF_TIMEOUT		1000
 
 #define DDR_CONFIG(A, B, C, R)	(((A) << 24) | ((B) << 16) | ((C) << 8) | (R))
 #define DDR_CONFIG_ELEMENTS	(sizeof(ddr_config)/sizeof(uint32_t))
@@ -125,7 +124,7 @@
 			data = mmio_read_32(AGX_MPFE_HMC_ADP_DDRCALSTAT);
 			if (AGX_MPFE_HMC_ADP_DDRCALSTAT_CAL(data) == 1)
 				break;
-			mdelay(1);
+			udelay(500);
 		} while (++timeout < TIMEOUT_EMIF_CALIBRATION);
 
 		if (AGX_MPFE_HMC_ADP_DDRCALSTAT_CAL(data) == 0) {
diff --git a/plat/intel/soc/common/aarch64/plat_helpers.S b/plat/intel/soc/common/aarch64/plat_helpers.S
index 27b538a..5cb9b69 100644
--- a/plat/intel/soc/common/aarch64/plat_helpers.S
+++ b/plat/intel/soc/common/aarch64/plat_helpers.S
@@ -66,12 +66,34 @@
 	ret
 endfunc plat_my_core_pos
 
+func warm_reset_req
+	str	xzr, [x4]
+	bl	plat_is_my_cpu_primary
+	cbz	x0, cpu_in_wfi
+	mov_imm x1, PLAT_SEC_ENTRY
+	str	xzr, [x1]
+	mrs	x1, rmr_el3
+	orr	x1, x1, #0x02
+	msr	rmr_el3, x1
+	isb
+	dsb	sy
+cpu_in_wfi:
+	wfi
+	b	cpu_in_wfi
+endfunc warm_reset_req
+
 func plat_get_my_entrypoint
+	ldr	x4, =L2_RESET_DONE_REG
+	ldr	x5, [x4]
+	ldr	x1, =L2_RESET_DONE_STATUS
+	cmp	x1, x5
+	b.eq	warm_reset_req
 	mov_imm	x1, PLAT_SEC_ENTRY
 	ldr	x0, [x1]
 	ret
 endfunc plat_get_my_entrypoint
 
+
 	/* ---------------------------------------------
 	 * int plat_crash_console_init(void)
 	 * Function to initialize the crash console
diff --git a/plat/intel/soc/common/include/platform_def.h b/plat/intel/soc/common/include/platform_def.h
index d6014d3..06f3a1b 100644
--- a/plat/intel/soc/common/include/platform_def.h
+++ b/plat/intel/soc/common/include/platform_def.h
@@ -19,6 +19,15 @@
 /* sysmgr.boot_scratch_cold4 & 5 used for CPU release address for SPL */
 #define PLAT_CPU_RELEASE_ADDR			0xffd12210
 
+/*
+ * sysmgr.boot_scratch_cold6 & 7 (64bit) are used to indicate L2 reset
+ * is done and HPS should trigger warm reset via RMR_EL3.
+ */
+#define L2_RESET_DONE_REG			0xFFD12218
+
+/* Magic word to indicate L2 reset is completed */
+#define L2_RESET_DONE_STATUS			0x1228E5E7
+
 /* Define next boot image name and offset */
 #define PLAT_NS_IMAGE_OFFSET			0x50000
 #define PLAT_HANDOFF_OFFSET			0xFFE3F000
diff --git a/plat/intel/soc/common/include/socfpga_reset_manager.h b/plat/intel/soc/common/include/socfpga_reset_manager.h
new file mode 100644
index 0000000..3fbf242
--- /dev/null
+++ b/plat/intel/soc/common/include/socfpga_reset_manager.h
@@ -0,0 +1,18 @@
+/*
+ * Copyright (c) 2019, Intel Corporation. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef SOCFPGA_RESETMANAGER_H
+#define SOCFPGA_RESETMANAGER_H
+
+#define SOCFPGA_RSTMGR_STAT				0xffd11000
+#define SOCFPGA_RSTMGR_HDSKEN				0xffd11010
+#define SOCFPGA_RSTMGR_COLDMODRST			0xffd11034
+#define SOCFPGA_RSTMGR_HDSKTIMEOUT			0xffd11064
+
+#define SOCFPGA_RSTMGR_HDSKEN_SET			0x0000010D
+#define SOCFPGA_RSTMGR_SDMWARMRST			0x00000002
+
+#endif /* SOCFPGA_RESETMANAGER_H */
diff --git a/plat/intel/soc/common/socfpga_image_load.c b/plat/intel/soc/common/socfpga_image_load.c
index 67c02bc..a5c3279 100644
--- a/plat/intel/soc/common/socfpga_image_load.c
+++ b/plat/intel/soc/common/socfpga_image_load.c
@@ -28,5 +28,31 @@
  ******************************************************************************/
 bl_params_t *plat_get_next_bl_params(void)
 {
+	unsigned int count;
+	unsigned int img_id = 0U;
+	unsigned int link_index = 0U;
+	bl_params_node_t *bl_exec_node = NULL;
+	bl_mem_params_node_t *desc_ptr;
+
+	/* If there is no image to start with, return NULL */
+	if (bl_mem_params_desc_num == 0U)
+		return NULL;
+
+	/* Clean next_params_info in BL image node */
+	for (count = 0U; count < bl_mem_params_desc_num; count++) {
+
+		desc_ptr = &bl_mem_params_desc_ptr[link_index];
+		bl_exec_node = &desc_ptr->params_node_mem;
+		bl_exec_node->next_params_info = NULL;
+
+		/* If no next hand-off image then break out */
+		img_id = desc_ptr->next_handoff_image_id;
+		if (img_id == INVALID_IMAGE_ID)
+			break;
+
+		/* Get the index for the next hand-off image */
+		link_index = get_bl_params_node_index(img_id);
+	}
+
 	return get_next_bl_params_from_mem_params_desc();
 }
diff --git a/plat/intel/soc/common/socfpga_psci.c b/plat/intel/soc/common/socfpga_psci.c
index 65a4b09..1ba48ea 100644
--- a/plat/intel/soc/common/socfpga_psci.c
+++ b/plat/intel/soc/common/socfpga_psci.c
@@ -13,6 +13,7 @@
 
 #include "socfpga_mailbox.h"
 #include "socfpga_plat_def.h"
+#include "socfpga_reset_manager.h"
 
 
 
@@ -75,6 +76,7 @@
 	for (size_t i = 0; i <= PLAT_MAX_PWR_LVL; i++)
 		VERBOSE("%s: target_state->pwr_domain_state[%lu]=%x\n",
 			__func__, i, target_state->pwr_domain_state[i]);
+
 	/* assert core reset */
 	mmio_setbits_32(SOCFPGA_RSTMGR_MPUMODRST_OFST, 1 << cpu_id);
 
@@ -136,6 +138,31 @@
 		wfi();
 }
 
+static int socfpga_system_reset2(int is_vendor, int reset_type,
+					u_register_t cookie)
+{
+	/* disable cpuif */
+	gicv2_cpuif_disable();
+
+	/* Store magic number */
+	mmio_write_32(L2_RESET_DONE_REG, L2_RESET_DONE_STATUS);
+
+	/* Increase timeout */
+	mmio_write_32(SOCFPGA_RSTMGR_HDSKTIMEOUT, 0xffffff);
+
+	/* Enable handshakes */
+	mmio_setbits_32(SOCFPGA_RSTMGR_HDSKEN, SOCFPGA_RSTMGR_HDSKEN_SET);
+
+	/* Reset L2 module */
+	mmio_setbits_32(SOCFPGA_RSTMGR_COLDMODRST, 0x100);
+
+	while (1)
+		wfi();
+
+	/* Should not reach here */
+	return 0;
+}
+
 int socfpga_validate_power_state(unsigned int power_state,
 				psci_power_state_t *req_state)
 {
@@ -169,6 +196,7 @@
 	.pwr_domain_suspend_finish = socfpga_pwr_domain_suspend_finish,
 	.system_off = socfpga_system_off,
 	.system_reset = socfpga_system_reset,
+	.system_reset2 = socfpga_system_reset2,
 	.validate_power_state = socfpga_validate_power_state,
 	.validate_ns_entrypoint = socfpga_validate_ns_entrypoint,
 	.get_sys_suspend_power_state = socfpga_get_sys_suspend_power_state
diff --git a/plat/intel/soc/common/socfpga_sip_svc.c b/plat/intel/soc/common/socfpga_sip_svc.c
index c3c6ae0..f58b58f 100644
--- a/plat/intel/soc/common/socfpga_sip_svc.c
+++ b/plat/intel/soc/common/socfpga_sip_svc.c
@@ -7,6 +7,7 @@
 #include <assert.h>
 #include <common/debug.h>
 #include <common/runtime_svc.h>
+#include <lib/mmio.h>
 #include <tools_share/uuid.h>
 
 #include "socfpga_mailbox.h"
@@ -270,6 +271,79 @@
 	return INTEL_SIP_SMC_STATUS_OK;
 }
 
+static int is_out_of_sec_range(uint64_t reg_addr)
+{
+	switch (reg_addr) {
+	case(0xF8011100):	/* ECCCTRL1 */
+	case(0xF8011104):	/* ECCCTRL2 */
+	case(0xF8011110):	/* ERRINTEN */
+	case(0xF8011114):	/* ERRINTENS */
+	case(0xF8011118):	/* ERRINTENR */
+	case(0xF801111C):	/* INTMODE */
+	case(0xF8011120):	/* INTSTAT */
+	case(0xF8011124):	/* DIAGINTTEST */
+	case(0xF801112C):	/* DERRADDRA */
+	case(0xFFD12028):	/* SDMMCGRP_CTRL */
+	case(0xFFD12044):	/* EMAC0 */
+	case(0xFFD12048):	/* EMAC1 */
+	case(0xFFD1204C):	/* EMAC2 */
+	case(0xFFD12090):	/* ECC_INT_MASK_VALUE */
+	case(0xFFD12094):	/* ECC_INT_MASK_SET */
+	case(0xFFD12098):	/* ECC_INT_MASK_CLEAR */
+	case(0xFFD1209C):	/* ECC_INTSTATUS_SERR */
+	case(0xFFD120A0):	/* ECC_INTSTATUS_DERR */
+	case(0xFFD120C0):	/* NOC_TIMEOUT */
+	case(0xFFD120C4):	/* NOC_IDLEREQ_SET */
+	case(0xFFD120C8):	/* NOC_IDLEREQ_CLR */
+	case(0xFFD120D0):	/* NOC_IDLEACK */
+	case(0xFFD120D4):	/* NOC_IDLESTATUS */
+	case(0xFFD12200):	/* BOOT_SCRATCH_COLD0 */
+	case(0xFFD12204):	/* BOOT_SCRATCH_COLD1 */
+	case(0xFFD12220):	/* BOOT_SCRATCH_COLD8 */
+	case(0xFFD12224):	/* BOOT_SCRATCH_COLD9 */
+		return 0;
+
+	default:
+		break;
+	}
+
+	return -1;
+}
+
+/* Secure register access */
+uint32_t intel_secure_reg_read(uint64_t reg_addr, uint32_t *retval)
+{
+	if (is_out_of_sec_range(reg_addr))
+		return INTEL_SIP_SMC_STATUS_ERROR;
+
+	*retval = mmio_read_32(reg_addr);
+
+	return INTEL_SIP_SMC_STATUS_OK;
+}
+
+uint32_t intel_secure_reg_write(uint64_t reg_addr, uint32_t val,
+				uint32_t *retval)
+{
+	if (is_out_of_sec_range(reg_addr))
+		return INTEL_SIP_SMC_STATUS_ERROR;
+
+	mmio_write_32(reg_addr, val);
+
+	return intel_secure_reg_read(reg_addr, retval);
+}
+
+uint32_t intel_secure_reg_update(uint64_t reg_addr, uint32_t mask,
+				 uint32_t val, uint32_t *retval)
+{
+	if (!intel_secure_reg_read(reg_addr, retval)) {
+		*retval &= ~mask;
+		*retval |= val;
+		return intel_secure_reg_write(reg_addr, *retval, retval);
+	}
+
+	return INTEL_SIP_SMC_STATUS_ERROR;
+}
+
 /*
  * This function is responsible for handling all SiP calls from the NS world
  */
@@ -283,6 +357,7 @@
 			 void *handle,
 			 u_register_t flags)
 {
+	uint32_t val = 0;
 	uint32_t status = INTEL_SIP_SMC_STATUS_OK;
 	uint32_t completed_addr[3];
 	uint32_t count = 0;
@@ -291,25 +366,25 @@
 	case SIP_SVC_UID:
 		/* Return UID to the caller */
 		SMC_UUID_RET(handle, intl_svc_uid);
-		break;
+
 	case INTEL_SIP_SMC_FPGA_CONFIG_ISDONE:
 		status = intel_mailbox_fpga_config_isdone();
 		SMC_RET4(handle, status, 0, 0, 0);
-		break;
+
 	case INTEL_SIP_SMC_FPGA_CONFIG_GET_MEM:
 		SMC_RET3(handle, INTEL_SIP_SMC_STATUS_OK,
 			INTEL_SIP_SMC_FPGA_CONFIG_ADDR,
 			INTEL_SIP_SMC_FPGA_CONFIG_SIZE -
 				INTEL_SIP_SMC_FPGA_CONFIG_ADDR);
-		break;
+
 	case INTEL_SIP_SMC_FPGA_CONFIG_START:
 		status = intel_fpga_config_start(x1);
 		SMC_RET4(handle, status, 0, 0, 0);
-		break;
+
 	case INTEL_SIP_SMC_FPGA_CONFIG_WRITE:
 		status = intel_fpga_config_write(x1, x2);
 		SMC_RET4(handle, status, 0, 0, 0);
-		break;
+
 	case INTEL_SIP_SMC_FPGA_CONFIG_COMPLETED_WRITE:
 		status = intel_fpga_config_completed_write(completed_addr,
 								&count);
@@ -317,26 +392,38 @@
 		case 1:
 			SMC_RET4(handle, INTEL_SIP_SMC_STATUS_OK,
 				completed_addr[0], 0, 0);
-			break;
+
 		case 2:
 			SMC_RET4(handle, INTEL_SIP_SMC_STATUS_OK,
 				completed_addr[0],
 				completed_addr[1], 0);
-			break;
+
 		case 3:
 			SMC_RET4(handle, INTEL_SIP_SMC_STATUS_OK,
 				completed_addr[0],
 				completed_addr[1],
 				completed_addr[2]);
-			break;
+
 		case 0:
 			SMC_RET4(handle, status, 0, 0, 0);
-			break;
+
 		default:
 			mailbox_clear_response();
 			SMC_RET1(handle, INTEL_SIP_SMC_STATUS_ERROR);
 		}
-		break;
+
+	case INTEL_SIP_SMC_REG_READ:
+		status = intel_secure_reg_read(x1, &val);
+		SMC_RET3(handle, status, val, x1);
+
+	case INTEL_SIP_SMC_REG_WRITE:
+		status = intel_secure_reg_write(x1, (uint32_t)x2, &val);
+		SMC_RET3(handle, status, val, x1);
+
+	case INTEL_SIP_SMC_REG_UPDATE:
+		status = intel_secure_reg_update(x1, (uint32_t)x2,
+						 (uint32_t)x3, &val);
+		SMC_RET3(handle, status, val, x1);
 
 	default:
 		return socfpga_sip_handler(smc_fid, x1, x2, x3, x4,
diff --git a/plat/intel/soc/stratix10/soc/s10_memory_controller.c b/plat/intel/soc/stratix10/soc/s10_memory_controller.c
index ed06f54..cb45251 100644
--- a/plat/intel/soc/stratix10/soc/s10_memory_controller.c
+++ b/plat/intel/soc/stratix10/soc/s10_memory_controller.c
@@ -22,10 +22,9 @@
 #define MAX_MEM_CAL_RETRY		3
 #define PRE_CALIBRATION_DELAY		1
 #define POST_CALIBRATION_DELAY		1
-#define TIMEOUT_EMIF_CALIBRATION	100
-#define CLEAR_EMIF_DELAY		50000
-#define CLEAR_EMIF_TIMEOUT		0x100000
-#define TIMEOUT_INT_RESP		10000
+#define TIMEOUT_EMIF_CALIBRATION	1000
+#define CLEAR_EMIF_DELAY		1000
+#define CLEAR_EMIF_TIMEOUT		1000
 
 #define DDR_CONFIG(A, B, C, R)	(((A) << 24) | ((B) << 16) | ((C) << 8) | (R))
 #define DDR_CONFIG_ELEMENTS	(sizeof(ddr_config)/sizeof(uint32_t))
@@ -128,13 +127,13 @@
 			data = mmio_read_32(S10_MPFE_HMC_ADP_DDRCALSTAT);
 			if (S10_MPFE_HMC_ADP_DDRCALSTAT_CAL(data) == 1)
 				break;
-			udelay(1);
+			udelay(500);
 		} while (++timeout < TIMEOUT_EMIF_CALIBRATION);
 
 		if (S10_MPFE_HMC_ADP_DDRCALSTAT_CAL(data) == 0) {
 			status = clear_emif();
-		if (status)
-			ERROR("Failed to clear Emif\n");
+			if (status)
+				ERROR("Failed to clear Emif\n");
 		} else {
 			break;
 		}
diff --git a/plat/rpi/rpi4/aarch64/plat_helpers.S b/plat/rpi/rpi4/aarch64/plat_helpers.S
index 46073b7..083c30e 100644
--- a/plat/rpi/rpi4/aarch64/plat_helpers.S
+++ b/plat/rpi/rpi4/aarch64/plat_helpers.S
@@ -136,8 +136,8 @@
 	 */
 func plat_crash_console_init
 	mov_imm	x0, PLAT_RPI3_UART_BASE
-	mov_imm	x1, PLAT_RPI4_VPU_CLK_RATE
-	mov_imm	x2, PLAT_RPI3_UART_BAUDRATE
+	mov	x1, xzr
+	mov	x2, xzr
 	b	console_16550_core_init
 endfunc plat_crash_console_init
 
diff --git a/plat/rpi/rpi4/include/rpi_hw.h b/plat/rpi/rpi4/include/rpi_hw.h
index ed367ee..b1dd4e9 100644
--- a/plat/rpi/rpi4/include/rpi_hw.h
+++ b/plat/rpi/rpi4/include/rpi_hw.h
@@ -59,13 +59,6 @@
 #define RPI3_PM_RSTS_WRCFG_HALT		U(0x00000555)
 
 /*
- * Clock controller
- */
-#define RPI4_IO_CLOCK_OFFSET		ULL(0x00101000)
-#define RPI4_CLOCK_BASE			(RPI_IO_BASE + RPI4_IO_CLOCK_OFFSET)
-#define RPI4_VPU_CLOCK_DIVIDER		ULL(0x0000000c)
-
-/*
  * Hardware random number generator.
  */
 #define RPI3_IO_RNG_OFFSET		ULL(0x00104000)
@@ -88,7 +81,6 @@
  */
 #define RPI3_IO_MINI_UART_OFFSET	ULL(0x00215040)
 #define RPI3_MINI_UART_BASE		(RPI_IO_BASE + RPI3_IO_MINI_UART_OFFSET)
-#define PLAT_RPI4_VPU_CLK_RATE		ULL(1000000000)
 
 /*
  * GPIO controller
diff --git a/plat/rpi/rpi4/rpi4_bl31_setup.c b/plat/rpi/rpi4/rpi4_bl31_setup.c
index 53ab0c2..9e3b539 100644
--- a/plat/rpi/rpi4/rpi4_bl31_setup.c
+++ b/plat/rpi/rpi4/rpi4_bl31_setup.c
@@ -119,8 +119,6 @@
 				u_register_t arg2, u_register_t arg3)
 
 {
-	uint32_t div_reg;
-
 	/*
 	 * LOCAL_CONTROL:
 	 * Bit 9 clear: Increment by 1 (vs. 2).
@@ -136,16 +134,12 @@
 
 	/*
 	 * Initialize the console to provide early debug support.
-	 * Different GPU firmware revisions set up the VPU divider differently,
-	 * so read the actual divider register to learn the UART base clock
-	 * rate. The divider is encoded as a 12.12 fixed point number, but we
-	 * just care about the integer part of it.
+	 * We rely on the GPU firmware to have initialised the UART correctly,
+	 * as the baud base clock rate differs across GPU firmware revisions.
+	 * Providing a base clock of 0 lets the 16550 UART init routine skip
+	 * the initial enablement and baud rate setup.
 	 */
-	div_reg = mmio_read_32(RPI4_CLOCK_BASE + RPI4_VPU_CLOCK_DIVIDER);
-	div_reg = (div_reg >> 12) & 0xfff;
-	if (div_reg == 0)
-		div_reg = 1;
-	rpi3_console_init(PLAT_RPI4_VPU_CLK_RATE / div_reg);
+	rpi3_console_init(0);
 
 	bl33_image_ep_info.pc = plat_get_ns_image_entrypoint();
 	bl33_image_ep_info.spsr = rpi3_get_spsr_for_bl33_entry();
diff --git a/plat/socionext/uniphier/platform.mk b/plat/socionext/uniphier/platform.mk
index d974584..d31fbe8 100644
--- a/plat/socionext/uniphier/platform.mk
+++ b/plat/socionext/uniphier/platform.mk
@@ -60,6 +60,7 @@
 				plat/common/plat_gicv3.c		\
 				plat/common/plat_psci_common.c		\
 				$(PLAT_PATH)/uniphier_bl31_setup.c	\
+				$(PLAT_PATH)/uniphier_boot_device.c	\
 				$(PLAT_PATH)/uniphier_cci.c		\
 				$(PLAT_PATH)/uniphier_gicv3.c		\
 				$(PLAT_PATH)/uniphier_psci.c		\
diff --git a/plat/socionext/uniphier/uniphier_psci.c b/plat/socionext/uniphier/uniphier_psci.c
index 464252d..2acc874 100644
--- a/plat/socionext/uniphier/uniphier_psci.c
+++ b/plat/socionext/uniphier/uniphier_psci.c
@@ -6,6 +6,7 @@
 
 #include <arch_helpers.h>
 #include <common/debug.h>
+#include <errno.h>
 #include <lib/mmio.h>
 #include <lib/psci/psci.h>
 
@@ -113,17 +114,27 @@
 int plat_setup_psci_ops(uintptr_t sec_entrypoint,
 			const struct plat_psci_ops **psci_ops)
 {
+	unsigned int soc;
+
+	soc = uniphier_get_soc_id();
+	if (soc == UNIPHIER_SOC_UNKNOWN) {
+		ERROR("unsupported SoC\n");
+		return -ENOTSUP;
+	}
+
+	if (uniphier_get_boot_master(soc) == UNIPHIER_BOOT_MASTER_SCP) {
+		uniphier_psci_scp_mode = uniphier_scp_is_running();
+		flush_dcache_range((uint64_t)&uniphier_psci_scp_mode,
+				   sizeof(uniphier_psci_scp_mode));
+
+		if (uniphier_psci_scp_mode)
+			uniphier_scp_open_com();
+	}
+
 	uniphier_sec_entrypoint = sec_entrypoint;
 	flush_dcache_range((uint64_t)&uniphier_sec_entrypoint,
 			   sizeof(uniphier_sec_entrypoint));
 
-	uniphier_psci_scp_mode = uniphier_scp_is_running();
-	flush_dcache_range((uint64_t)&uniphier_psci_scp_mode,
-			   sizeof(uniphier_psci_scp_mode));
-
-	if (uniphier_psci_scp_mode)
-		uniphier_scp_open_com();
-
 	*psci_ops = &uniphier_psci_ops;
 
 	return 0;
diff --git a/plat/xilinx/zynqmp/aarch64/zynqmp_common.c b/plat/xilinx/zynqmp/aarch64/zynqmp_common.c
index ab5d95d..d6313a6 100644
--- a/plat/xilinx/zynqmp/aarch64/zynqmp_common.c
+++ b/plat/xilinx/zynqmp/aarch64/zynqmp_common.c
@@ -189,6 +189,18 @@
 		.id = 0x65,
 		.name = "25DR",
 	},
+	{
+		.id = 0x66,
+		.name = "39DR",
+	},
+	{
+		.id = 0x7b,
+		.name = "48DR",
+	},
+	{
+		.id = 0x7e,
+		.name = "49DR",
+	},
 };
 
 #define ZYNQMP_PL_STATUS_BIT	9
@@ -338,7 +350,7 @@
 	unsigned int ver = zynqmp_get_silicon_ver();
 
 	if (ver == ZYNQMP_CSU_VERSION_QEMU)
-		return 50000000;
+		return 65000000;
 	else
 		return mmio_read_32(IOU_SCNTRS_BASEFREQ);
 }
diff --git a/plat/xilinx/zynqmp/include/zynqmp_def.h b/plat/xilinx/zynqmp/include/zynqmp_def.h
index 8648b9a..5d335d9 100644
--- a/plat/xilinx/zynqmp/include/zynqmp_def.h
+++ b/plat/xilinx/zynqmp/include/zynqmp_def.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2014-2018, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2014-2019, ARM Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -330,6 +330,7 @@
 #define IOU_SLCR_GEM_CLK_CTRL		(IOU_SLCR_BASEADDR + 0x308)
 #define IOU_SLCR_CAN_MIO_CTRL		(IOU_SLCR_BASEADDR + 0x304)
 #define FPD_SLCR_WDT_CLK_SEL		(FPD_SLCR_BASEADDR + 0x100)
+#define IOU_SLCR_WDT_CLK_SEL		(IOU_SLCR_BASEADDR + 0x300)
 
 /* Global general storage register base address */
 #define GGS_BASEADDR		(0xFFD80030U)
diff --git a/plat/xilinx/zynqmp/pm_service/pm_api_clock.c b/plat/xilinx/zynqmp/pm_service/pm_api_clock.c
index 85cffcb..e305072 100644
--- a/plat/xilinx/zynqmp/pm_service/pm_api_clock.c
+++ b/plat/xilinx/zynqmp/pm_service/pm_api_clock.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2018, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2018-2019, ARM Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -562,13 +562,13 @@
 	},
 };
 
-static struct pm_clock_node gem_nodes[] = {
+static struct pm_clock_node gem_ref_ungated_nodes[] = {
 	GENERIC_MUX,
 	{
 		.type = TYPE_DIV1,
 		.offset = 8,
 		.width = 6,
-		.clkflags = CLK_IS_BASIC,
+		.clkflags = CLK_SET_RATE_NO_REPARENT | CLK_IS_BASIC,
 		.typeflags = CLK_DIVIDER_ONE_BASED | CLK_DIVIDER_ALLOW_ZERO,
 		.mult = NA_MULT,
 		.div = NA_DIV,
@@ -577,77 +577,73 @@
 		.type = TYPE_DIV2,
 		.offset = 16,
 		.width = 6,
-		.clkflags = CLK_IS_BASIC,
+		.clkflags = CLK_SET_RATE_NO_REPARENT | CLK_IS_BASIC,
 		.typeflags = CLK_DIVIDER_ONE_BASED | CLK_DIVIDER_ALLOW_ZERO,
 		.mult = NA_MULT,
 		.div = NA_DIV,
 	},
-	{
-		.type = TYPE_GATE,
-		.offset = 25,
-		.width = PERIPH_GATE_WIDTH,
-		.clkflags = CLK_SET_RATE_PARENT | CLK_IS_BASIC,
-		.typeflags = NA_TYPE_FLAGS,
-		.mult = NA_MULT,
-		.div = NA_DIV,
-	},
 };
 
-static struct pm_clock_node gem0_tx_nodes[] = {
+static struct pm_clock_node gem0_ref_nodes[] = {
 	{
 		.type = TYPE_MUX,
 		.offset = 1,
 		.width = 1,
-		.clkflags = CLK_SET_RATE_NO_REPARENT | CLK_IS_BASIC,
-		.typeflags = NA_TYPE_FLAGS,
-		.mult = NA_MULT,
-		.div = NA_DIV,
-	},
-	{
-		.type = TYPE_GATE,
-		.offset = 26,
-		.width = PERIPH_GATE_WIDTH,
-		.clkflags = CLK_SET_RATE_PARENT | CLK_IS_BASIC,
+		.clkflags = CLK_SET_RATE_PARENT |
+			    CLK_SET_RATE_NO_REPARENT |
+			    CLK_IS_BASIC,
 		.typeflags = NA_TYPE_FLAGS,
 		.mult = NA_MULT,
 		.div = NA_DIV,
 	},
 };
 
-static struct pm_clock_node gem1_tx_nodes[] = {
+static struct pm_clock_node gem1_ref_nodes[] = {
 	{
 		.type = TYPE_MUX,
 		.offset = 6,
 		.width = 1,
-		.clkflags = CLK_SET_RATE_NO_REPARENT | CLK_IS_BASIC,
+		.clkflags = CLK_SET_RATE_PARENT |
+			    CLK_SET_RATE_NO_REPARENT |
+			    CLK_IS_BASIC,
 		.typeflags = NA_TYPE_FLAGS,
 		.mult = NA_MULT,
 		.div = NA_DIV,
 	},
+};
+
+static struct pm_clock_node gem2_ref_nodes[] = {
 	{
-		.type = TYPE_GATE,
-		.offset = 26,
-		.width = PERIPH_GATE_WIDTH,
-		.clkflags = CLK_SET_RATE_PARENT | CLK_IS_BASIC,
+		.type = TYPE_MUX,
+		.offset = 11,
+		.width = 1,
+		.clkflags = CLK_SET_RATE_PARENT |
+			    CLK_SET_RATE_NO_REPARENT |
+			    CLK_IS_BASIC,
 		.typeflags = NA_TYPE_FLAGS,
 		.mult = NA_MULT,
 		.div = NA_DIV,
 	},
 };
 
-static struct pm_clock_node gem2_tx_nodes[] = {
+static struct pm_clock_node gem3_ref_nodes[] = {
 	{
 		.type = TYPE_MUX,
-		.offset = 11,
+		.offset = 16,
 		.width = 1,
-		.clkflags = CLK_SET_RATE_NO_REPARENT | CLK_IS_BASIC,
+		.clkflags = CLK_SET_RATE_PARENT |
+			    CLK_SET_RATE_NO_REPARENT |
+			    CLK_IS_BASIC,
 		.typeflags = NA_TYPE_FLAGS,
 		.mult = NA_MULT,
 		.div = NA_DIV,
 	},
+};
+
+static struct pm_clock_node gem_tx_nodes[] = {
 	{
 		.type = TYPE_GATE,
-		.offset = 26,
+		.offset = 25,
 		.width = PERIPH_GATE_WIDTH,
 		.clkflags = CLK_SET_RATE_PARENT | CLK_IS_BASIC,
 		.typeflags = NA_TYPE_FLAGS,
@@ -656,21 +652,12 @@
 	},
 };
 
-static struct pm_clock_node gem3_tx_nodes[] = {
-	{
-		.type = TYPE_MUX,
-		.offset = 16,
-		.width = 1,
-		.clkflags = CLK_SET_RATE_NO_REPARENT | CLK_IS_BASIC,
-		.typeflags = NA_TYPE_FLAGS,
-		.mult = NA_MULT,
-		.div = NA_DIV,
-	},
+static struct pm_clock_node gem_rx_nodes[] = {
 	{
 		.type = TYPE_GATE,
 		.offset = 26,
 		.width = PERIPH_GATE_WIDTH,
-		.clkflags = CLK_SET_RATE_PARENT | CLK_IS_BASIC,
+		.clkflags = CLK_IS_BASIC,
 		.typeflags = NA_TYPE_FLAGS,
 		.mult = NA_MULT,
 		.div = NA_DIV,
@@ -1442,8 +1429,8 @@
 		.nodes = &generic_mux_div_unused_gate_nodes,
 		.num_nodes = ARRAY_SIZE(generic_mux_div_unused_gate_nodes),
 	},
-	[CLK_GEM0_REF] = {
-		.name = "gem0_ref",
+	[CLK_GEM0_REF_UNGATED] = {
+		.name = "gem0_ref_ung",
 		.control_reg = CRL_APB_GEM0_REF_CTRL,
 		.status_reg = 0,
 		.parents = &((int32_t []) {
@@ -1453,11 +1440,11 @@
 			CLK_DPLL_TO_LPD,
 			CLK_NA_PARENT
 		}),
-		.nodes = &gem_nodes,
-		.num_nodes = ARRAY_SIZE(gem_nodes),
+		.nodes = &gem_ref_ungated_nodes,
+		.num_nodes = ARRAY_SIZE(gem_ref_ungated_nodes),
 	},
-	[CLK_GEM1_REF] = {
-		.name = "gem1_ref",
+	[CLK_GEM1_REF_UNGATED] = {
+		.name = "gem1_ref_ung",
 		.control_reg = CRL_APB_GEM1_REF_CTRL,
 		.status_reg = 0,
 		.parents = &((int32_t []) {
@@ -1467,11 +1454,11 @@
 			CLK_DPLL_TO_LPD,
 			CLK_NA_PARENT
 		}),
-		.nodes = &gem_nodes,
-		.num_nodes = ARRAY_SIZE(gem_nodes),
+		.nodes = &gem_ref_ungated_nodes,
+		.num_nodes = ARRAY_SIZE(gem_ref_ungated_nodes),
 	},
-	[CLK_GEM2_REF] = {
-		.name = "gem2_ref",
+	[CLK_GEM2_REF_UNGATED] = {
+		.name = "gem2_ref_ung",
 		.control_reg = CRL_APB_GEM2_REF_CTRL,
 		.status_reg = 0,
 		.parents = &((int32_t []) {
@@ -1481,11 +1468,11 @@
 			CLK_DPLL_TO_LPD,
 			CLK_NA_PARENT
 		}),
-		.nodes = &gem_nodes,
-		.num_nodes = ARRAY_SIZE(gem_nodes),
+		.nodes = &gem_ref_ungated_nodes,
+		.num_nodes = ARRAY_SIZE(gem_ref_ungated_nodes),
 	},
-	[CLK_GEM3_REF] = {
-		.name = "gem3_ref",
+	[CLK_GEM3_REF_UNGATED] = {
+		.name = "gem3_ref_ung",
 		.control_reg = CRL_APB_GEM3_REF_CTRL,
 		.status_reg = 0,
 		.parents = &((int32_t []) {
@@ -1495,8 +1482,60 @@
 			CLK_DPLL_TO_LPD,
 			CLK_NA_PARENT
 		}),
+		.nodes = &gem_ref_ungated_nodes,
+		.num_nodes = ARRAY_SIZE(gem_ref_ungated_nodes),
+	},
+	[CLK_GEM0_REF] = {
+		.name = "gem0_ref",
+		.control_reg = IOU_SLCR_GEM_CLK_CTRL,
+		.status_reg = 0,
+		.parents = &((int32_t []) {
+			CLK_GEM0_REF_UNGATED |
+			(PARENT_CLK_NODE3 << CLK_PARENTS_ID_LEN),
+			EXT_CLK_GEM0_TX_EMIO | CLK_EXTERNAL_PARENT,
+			CLK_NA_PARENT
+		}),
+		.nodes = &gem0_ref_nodes,
+		.num_nodes = ARRAY_SIZE(gem0_ref_nodes),
+	},
+	[CLK_GEM1_REF] = {
+		.name = "gem1_ref",
+		.control_reg = IOU_SLCR_GEM_CLK_CTRL,
+		.status_reg = 0,
+		.parents = &((int32_t []) {
+			CLK_GEM1_REF_UNGATED |
+			(PARENT_CLK_NODE3 << CLK_PARENTS_ID_LEN),
+			EXT_CLK_GEM1_TX_EMIO | CLK_EXTERNAL_PARENT,
+			CLK_NA_PARENT
+		}),
+		.nodes = &gem1_ref_nodes,
+		.num_nodes = ARRAY_SIZE(gem1_ref_nodes),
+	},
+	[CLK_GEM2_REF] = {
+		.name = "gem2_ref",
+		.control_reg = IOU_SLCR_GEM_CLK_CTRL,
+		.status_reg = 0,
+		.parents = &((int32_t []) {
+			CLK_GEM2_REF_UNGATED |
+			(PARENT_CLK_NODE3 << CLK_PARENTS_ID_LEN),
+			EXT_CLK_GEM2_TX_EMIO | CLK_EXTERNAL_PARENT,
+			CLK_NA_PARENT
+		}),
+		.nodes = &gem2_ref_nodes,
+		.num_nodes = ARRAY_SIZE(gem2_ref_nodes),
+	},
+	[CLK_GEM3_REF] = {
+		.name = "gem3_ref",
+		.control_reg = IOU_SLCR_GEM_CLK_CTRL,
+		.status_reg = 0,
+		.parents = &((int32_t []) {
+			CLK_GEM3_REF_UNGATED |
+			(PARENT_CLK_NODE3 << CLK_PARENTS_ID_LEN),
+			EXT_CLK_GEM3_TX_EMIO | CLK_EXTERNAL_PARENT,
+			CLK_NA_PARENT
+		}),
-		.nodes = &gem_nodes,
-		.num_nodes = ARRAY_SIZE(gem_nodes),
+		.nodes = &gem3_ref_nodes,
+		.num_nodes = ARRAY_SIZE(gem3_ref_nodes),
 	},
 	[CLK_USB0_BUS_REF] = {
 		.name = "usb0_bus_ref",
@@ -1960,69 +1999,93 @@
 		.nodes = &generic_domain_crossing_nodes,
 		.num_nodes = ARRAY_SIZE(generic_domain_crossing_nodes),
 	},
-	/*
-	 * This clock control requires different registers for mux and gate.
-	 * Use control and status registers for the same.
-	 */
 	[CLK_GEM0_TX] = {
 		.name = "gem0_tx",
-		.control_reg = IOU_SLCR_GEM_CLK_CTRL,
-		.status_reg = CRL_APB_GEM0_REF_CTRL,
+		.control_reg = CRL_APB_GEM0_REF_CTRL,
+		.status_reg = 0,
 		.parents = &((int32_t []) {
-			CLK_GEM0_REF | (PARENT_CLK_NODE3 << CLK_PARENTS_ID_LEN),
-			EXT_CLK_GEM0_EMIO | CLK_EXTERNAL_PARENT,
+			CLK_GEM0_REF,
 			CLK_NA_PARENT
 		}),
-		.nodes = &gem0_tx_nodes,
-		.num_nodes = ARRAY_SIZE(gem0_tx_nodes),
+		.nodes = &gem_tx_nodes,
+		.num_nodes = ARRAY_SIZE(gem_tx_nodes),
 	},
-	/*
-	 * This clock control requires different registers for mux and gate.
-	 * Use control and status registers for the same.
-	 */
 	[CLK_GEM1_TX] = {
 		.name = "gem1_tx",
-		.control_reg = IOU_SLCR_GEM_CLK_CTRL,
-		.status_reg = CRL_APB_GEM1_REF_CTRL,
+		.control_reg = CRL_APB_GEM1_REF_CTRL,
+		.status_reg = 0,
 		.parents = &((int32_t []) {
-			CLK_GEM1_REF | (PARENT_CLK_NODE3 << CLK_PARENTS_ID_LEN),
-			EXT_CLK_GEM1_EMIO | CLK_EXTERNAL_PARENT,
+			CLK_GEM1_REF,
 			CLK_NA_PARENT
 		}),
-		.nodes = &gem1_tx_nodes,
-		.num_nodes = ARRAY_SIZE(gem1_tx_nodes),
+		.nodes = &gem_tx_nodes,
+		.num_nodes = ARRAY_SIZE(gem_tx_nodes),
 	},
-	/*
-	 * This clock control requires different registers for mux and gate.
-	 * Use control and status registers for the same.
-	 */
 	[CLK_GEM2_TX] = {
 		.name = "gem2_tx",
-		.control_reg = IOU_SLCR_GEM_CLK_CTRL,
-		.status_reg = CRL_APB_GEM2_REF_CTRL,
+		.control_reg = CRL_APB_GEM2_REF_CTRL,
+		.status_reg = 0,
 		.parents = &((int32_t []) {
-			CLK_GEM2_REF | (PARENT_CLK_NODE3 << CLK_PARENTS_ID_LEN),
-			EXT_CLK_GEM2_EMIO | CLK_EXTERNAL_PARENT,
+			CLK_GEM2_REF,
 			CLK_NA_PARENT
 		}),
-		.nodes = &gem2_tx_nodes,
-		.num_nodes = ARRAY_SIZE(gem2_tx_nodes),
+		.nodes = &gem_tx_nodes,
+		.num_nodes = ARRAY_SIZE(gem_tx_nodes),
 	},
-	/*
-	 * This clock control requires different registers for mux and gate.
-	 * Use control and status registers for the same.
-	 */
 	[CLK_GEM3_TX] = {
 		.name = "gem3_tx",
-		.control_reg = IOU_SLCR_GEM_CLK_CTRL,
-		.status_reg = CRL_APB_GEM3_REF_CTRL,
+		.control_reg = CRL_APB_GEM3_REF_CTRL,
+		.status_reg = 0,
+		.parents = &((int32_t []) {
+			CLK_GEM3_REF,
+			CLK_NA_PARENT
+		}),
+		.nodes = &gem_tx_nodes,
+		.num_nodes = ARRAY_SIZE(gem_tx_nodes),
+	},
+	[CLK_GEM0_RX] = {
+		.name = "gem0_rx",
+		.control_reg = CRL_APB_GEM0_REF_CTRL,
+		.status_reg = 0,
 		.parents = &((int32_t []) {
-			CLK_GEM3_REF | (PARENT_CLK_NODE3 << CLK_PARENTS_ID_LEN),
-			EXT_CLK_GEM3_EMIO | CLK_EXTERNAL_PARENT,
+			EXT_CLK_GEM0_RX_EMIO | CLK_EXTERNAL_PARENT,
 			CLK_NA_PARENT
 		}),
-		.nodes = &gem3_tx_nodes,
-		.num_nodes = ARRAY_SIZE(gem3_tx_nodes),
+		.nodes = &gem_rx_nodes,
+		.num_nodes = ARRAY_SIZE(gem_rx_nodes),
+	},
+	[CLK_GEM1_RX] = {
+		.name = "gem1_rx",
+		.control_reg = CRL_APB_GEM1_REF_CTRL,
+		.status_reg = 0,
+		.parents = &((int32_t []) {
+			EXT_CLK_GEM1_RX_EMIO | CLK_EXTERNAL_PARENT,
+			CLK_NA_PARENT
+		}),
+		.nodes = &gem_rx_nodes,
+		.num_nodes = ARRAY_SIZE(gem_rx_nodes),
+	},
+	[CLK_GEM2_RX] = {
+		.name = "gem2_rx",
+		.control_reg = CRL_APB_GEM2_REF_CTRL,
+		.status_reg = 0,
+		.parents = &((int32_t []) {
+			EXT_CLK_GEM2_RX_EMIO | CLK_EXTERNAL_PARENT,
+			CLK_NA_PARENT
+		}),
+		.nodes = &gem_rx_nodes,
+		.num_nodes = ARRAY_SIZE(gem_rx_nodes),
+	},
+	[CLK_GEM3_RX] = {
+		.name = "gem3_rx",
+		.control_reg = CRL_APB_GEM3_REF_CTRL,
+		.status_reg = 0,
+		.parents = &((int32_t []) {
+			EXT_CLK_GEM3_RX_EMIO | CLK_EXTERNAL_PARENT,
+			CLK_NA_PARENT
+		}),
+		.nodes = &gem_rx_nodes,
+		.num_nodes = ARRAY_SIZE(gem_rx_nodes),
 	},
 	[CLK_ACPU_HALF] = {
 		.name = "acpu_half",
@@ -2035,8 +2098,8 @@
 		.nodes = &acpu_half_nodes,
 		.num_nodes = ARRAY_SIZE(acpu_half_nodes),
 	},
-	[CLK_WDT] = {
-		.name = "wdt",
+	[CLK_FPD_WDT] = {
+		.name = "fpd_wdt",
 		.control_reg = FPD_SLCR_WDT_CLK_SEL,
 		.status_reg = 0,
 		.parents = &((int32_t []) {
@@ -2135,6 +2198,18 @@
 		.nodes = &can1_nodes,
 		.num_nodes = ARRAY_SIZE(can1_nodes),
 	},
+	[CLK_LPD_WDT] = {
+		.name = "lpd_wdt",
+		.control_reg = IOU_SLCR_WDT_CLK_SEL,
+		.status_reg = 0,
+		.parents = &((int32_t []) {
+			CLK_LPD_LSBUS,
+			EXT_CLK_SWDT1 | CLK_EXTERNAL_PARENT,
+			CLK_NA_PARENT
+		}),
+		.nodes = &wdt_nodes,
+		.num_nodes = ARRAY_SIZE(wdt_nodes),
+	},
 };
 
 static struct pm_ext_clock ext_clocks[] = {
@@ -2159,17 +2234,29 @@
 	[EXT_CLK_INDEX(EXT_CLK_SWDT1)] = {
 		.name = "swdt1_ext_clk",
 	},
-	[EXT_CLK_INDEX(EXT_CLK_GEM0_EMIO)] = {
-		.name = "gem0_emio_clk",
+	[EXT_CLK_INDEX(EXT_CLK_GEM0_TX_EMIO)] = {
+		.name = "gem0_tx_ext",
 	},
-	[EXT_CLK_INDEX(EXT_CLK_GEM1_EMIO)] = {
-		.name = "gem1_emio_clk",
+	[EXT_CLK_INDEX(EXT_CLK_GEM1_TX_EMIO)] = {
+		.name = "gem1_tx_ext",
 	},
-	[EXT_CLK_INDEX(EXT_CLK_GEM2_EMIO)] = {
-		.name = "gem2_emio_clk",
+	[EXT_CLK_INDEX(EXT_CLK_GEM2_TX_EMIO)] = {
+		.name = "gem2_tx_ext",
 	},
-	[EXT_CLK_INDEX(EXT_CLK_GEM3_EMIO)] = {
-		.name = "gem3_emio_clk",
+	[EXT_CLK_INDEX(EXT_CLK_GEM3_TX_EMIO)] = {
+		.name = "gem3_tx_ext",
+	},
+	[EXT_CLK_INDEX(EXT_CLK_GEM0_RX_EMIO)] = {
+		.name = "gem0_rx_ext",
+	},
+	[EXT_CLK_INDEX(EXT_CLK_GEM1_RX_EMIO)] = {
+		.name = "gem1_rx_ext",
+	},
+	[EXT_CLK_INDEX(EXT_CLK_GEM2_RX_EMIO)] = {
+		.name = "gem2_rx_ext",
+	},
+	[EXT_CLK_INDEX(EXT_CLK_GEM3_RX_EMIO)] = {
+		.name = "gem3_rx_ext",
 	},
 	[EXT_CLK_INDEX(EXT_CLK_MIO50_OR_MIO51)] = {
 		.name = "mio_clk_50_51",
@@ -2268,7 +2355,6 @@
 	CLK_TOPSW_LSBUS,
 	CLK_GTGREF0_REF,
 	CLK_LPD_SWITCH,
-	CLK_LPD_LSBUS,
 	CLK_CPU_R5,
 	CLK_CPU_R5_CORE,
 	CLK_CSU_SPB,
diff --git a/plat/xilinx/zynqmp/pm_service/pm_api_clock.h b/plat/xilinx/zynqmp/pm_service/pm_api_clock.h
index 9717ca8..5bed5a6 100644
--- a/plat/xilinx/zynqmp/pm_service/pm_api_clock.h
+++ b/plat/xilinx/zynqmp/pm_service/pm_api_clock.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2018, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2018-2019, ARM Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -102,14 +102,14 @@
 	CLK_IOU_SWITCH,
 	CLK_GEM_TSU_REF,
 	CLK_GEM_TSU,
-	CLK_GEM0_REF,
-	CLK_GEM1_REF,
-	CLK_GEM2_REF,
-	CLK_GEM3_REF,
 	CLK_GEM0_TX,
 	CLK_GEM1_TX,
 	CLK_GEM2_TX,
 	CLK_GEM3_TX,
+	CLK_GEM0_RX,
+	CLK_GEM1_RX,
+	CLK_GEM2_RX,
+	CLK_GEM3_RX,
 	CLK_QSPI_REF,
 	CLK_SDIO0_REF,
 	CLK_SDIO1_REF,
@@ -132,7 +132,7 @@
 	CLK_PL1_REF,
 	CLK_PL2_REF,
 	CLK_PL3_REF,
-	CLK_WDT,
+	CLK_FPD_WDT,
 	CLK_IOPLL_INT,
 	CLK_IOPLL_PRE_SRC,
 	CLK_IOPLL_HALF,
@@ -161,6 +161,15 @@
 	CLK_CAN0_MIO,
 	CLK_CAN1_MIO,
 	CLK_ACPU_FULL,
+	CLK_GEM0_REF,
+	CLK_GEM1_REF,
+	CLK_GEM2_REF,
+	CLK_GEM3_REF,
+	CLK_GEM0_REF_UNGATED,
+	CLK_GEM1_REF_UNGATED,
+	CLK_GEM2_REF_UNGATED,
+	CLK_GEM3_REF_UNGATED,
+	CLK_LPD_WDT,
 	END_OF_OUTPUT_CLKS,
 };
 
@@ -175,10 +184,14 @@
 	EXT_CLK_GT_CRX_REF,
 	EXT_CLK_SWDT0,
 	EXT_CLK_SWDT1,
-	EXT_CLK_GEM0_EMIO,
-	EXT_CLK_GEM1_EMIO,
-	EXT_CLK_GEM2_EMIO,
-	EXT_CLK_GEM3_EMIO,
+	EXT_CLK_GEM0_TX_EMIO,
+	EXT_CLK_GEM1_TX_EMIO,
+	EXT_CLK_GEM2_TX_EMIO,
+	EXT_CLK_GEM3_TX_EMIO,
+	EXT_CLK_GEM0_RX_EMIO,
+	EXT_CLK_GEM1_RX_EMIO,
+	EXT_CLK_GEM2_RX_EMIO,
+	EXT_CLK_GEM3_RX_EMIO,
 	EXT_CLK_MIO50_OR_MIO51,
 	EXT_CLK_MIO0,
 	EXT_CLK_MIO1,