Merge git://git.denx.de/u-boot-rockchip

This includes support for rk3188 from Heiko Stübner and and rk3328 from
Kever Yang.  Also included is SPL support for rk3399 and a fix for
rk3288 to get it booting again (spl_early_init()).
diff --git a/Kconfig b/Kconfig
index 81b4226..e0744d1 100644
--- a/Kconfig
+++ b/Kconfig
@@ -144,6 +144,7 @@
 
 config FIT
 	bool "Support Flattened Image Tree"
+	select MD5
 	help
 	  This option allows you to boot the new uImage structure,
 	  Flattened Image Tree.  FIT is formally a FDT, which can include
diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
index 20434dc..7c5012ac 100644
--- a/arch/arm/Kconfig
+++ b/arch/arm/Kconfig
@@ -825,6 +825,9 @@
 	select SPL_SEPARATE_BSS if SPL
 	select DM_USB if USB
 	select BLK
+	select CLK
+	select SPL_CLK
+	select CLK_ZYNQ
 
 config ARCH_ZYNQMP
 	bool "Support Xilinx ZynqMP Platform"
diff --git a/arch/arm/cpu/armv8/cache_v8.c b/arch/arm/cpu/armv8/cache_v8.c
index 6c5630c..bd1c3e0 100644
--- a/arch/arm/cpu/armv8/cache_v8.c
+++ b/arch/arm/cpu/armv8/cache_v8.c
@@ -501,7 +501,8 @@
 	return !(addr & (align - 1)) && !(size & (align - 1));
 }
 
-static u64 set_one_region(u64 start, u64 size, u64 attrs, int level)
+/* Use flag to indicate if attrs has more than d-cache attributes */
+static u64 set_one_region(u64 start, u64 size, u64 attrs, bool flag, int level)
 {
 	int levelshift = level2shift(level);
 	u64 levelsize = 1ULL << levelshift;
@@ -509,8 +510,13 @@
 
 	/* Can we can just modify the current level block PTE? */
 	if (is_aligned(start, size, levelsize)) {
-		*pte &= ~PMD_ATTRINDX_MASK;
-		*pte |= attrs;
+		if (flag) {
+			*pte &= ~PMD_ATTRMASK;
+			*pte |= attrs & PMD_ATTRMASK;
+		} else {
+			*pte &= ~PMD_ATTRINDX_MASK;
+			*pte |= attrs & PMD_ATTRINDX_MASK;
+		}
 		debug("Set attrs=%llx pte=%p level=%d\n", attrs, pte, level);
 
 		return levelsize;
@@ -560,7 +566,8 @@
 		u64 r;
 
 		for (level = 1; level < 4; level++) {
-			r = set_one_region(start, size, attrs, level);
+			/* Set d-cache attributes only */
+			r = set_one_region(start, size, attrs, false, level);
 			if (r) {
 				/* PTE successfully replaced */
 				size -= r;
@@ -581,6 +588,63 @@
 	flush_dcache_range(real_start, real_start + real_size);
 }
 
+/*
+ * Modify MMU table for a region with updated PXN/UXN/Memory type/valid bits.
+ * The procecess is break-before-make. The target region will be marked as
+ * invalid during the process of changing.
+ */
+void mmu_change_region_attr(phys_addr_t addr, size_t siz, u64 attrs)
+{
+	int level;
+	u64 r, size, start;
+
+	start = addr;
+	size = siz;
+	/*
+	 * Loop through the address range until we find a page granule that fits
+	 * our alignment constraints, then set it to "invalid".
+	 */
+	while (size > 0) {
+		for (level = 1; level < 4; level++) {
+			/* Set PTE to fault */
+			r = set_one_region(start, size, PTE_TYPE_FAULT, true,
+					   level);
+			if (r) {
+				/* PTE successfully invalidated */
+				size -= r;
+				start += r;
+				break;
+			}
+		}
+	}
+
+	flush_dcache_range(gd->arch.tlb_addr,
+			   gd->arch.tlb_addr + gd->arch.tlb_size);
+	__asm_invalidate_tlb_all();
+
+	/*
+	 * Loop through the address range until we find a page granule that fits
+	 * our alignment constraints, then set it to the new cache attributes
+	 */
+	start = addr;
+	size = siz;
+	while (size > 0) {
+		for (level = 1; level < 4; level++) {
+			/* Set PTE to new attributes */
+			r = set_one_region(start, size, attrs, true, level);
+			if (r) {
+				/* PTE successfully updated */
+				size -= r;
+				start += r;
+				break;
+			}
+		}
+	}
+	flush_dcache_range(gd->arch.tlb_addr,
+			   gd->arch.tlb_addr + gd->arch.tlb_size);
+	__asm_invalidate_tlb_all();
+}
+
 #else	/* CONFIG_SYS_DCACHE_OFF */
 
 /*
diff --git a/arch/arm/cpu/armv8/fsl-layerscape/Kconfig b/arch/arm/cpu/armv8/fsl-layerscape/Kconfig
index b5609ff..a99b1c6 100644
--- a/arch/arm/cpu/armv8/fsl-layerscape/Kconfig
+++ b/arch/arm/cpu/armv8/fsl-layerscape/Kconfig
@@ -89,6 +89,14 @@
 	select SYS_FSL_SRDS_1
 	select SYS_HAS_SERDES
 
+config FSL_MC_ENET
+	bool "Management Complex network"
+	depends on ARCH_LS2080A
+	default y
+	select RESV_RAM
+	help
+	  Enable Management Complex (MC) network
+
 menu "Layerscape architecture"
 	depends on FSL_LSCH2 || FSL_LSCH3
 
@@ -277,6 +285,16 @@
 	  clock, in another word SDHC_clk = Platform_clk / this_divider.
 endmenu
 
+config RESV_RAM
+	bool
+	help
+	  Reserve memory from the top, tracked by gd->arch.resv_ram. This
+	  reserved RAM can be used by special driver that resides in memory
+	  after U-Boot exits. It's up to implementation to allocate and allow
+	  access to this reserved memory. For example, the reserved RAM can
+	  be at the high end of physical memory. The reserve RAM may be
+	  excluded from memory bank(s) passed to OS, or marked as reserved.
+
 config SYS_FSL_ERRATUM_A008336
 	bool
 
@@ -297,3 +315,11 @@
 
 config SYS_FSL_ERRATUM_A009929
 	bool
+
+config SYS_MC_RSV_MEM_ALIGN
+	hex "Management Complex reserved memory alignment"
+	depends on RESV_RAM
+	default 0x20000000
+	help
+	  Reserved memory needs to be aligned for MC to use. Default value
+	  is 512MB.
diff --git a/arch/arm/cpu/armv8/fsl-layerscape/cpu.c b/arch/arm/cpu/armv8/fsl-layerscape/cpu.c
index 335f225..7e66ee0 100644
--- a/arch/arm/cpu/armv8/fsl-layerscape/cpu.c
+++ b/arch/arm/cpu/armv8/fsl-layerscape/cpu.c
@@ -101,12 +101,50 @@
 {
 	u64 tlb_addr_save = gd->arch.tlb_addr;
 	unsigned int el = current_el();
-#ifdef CONFIG_SYS_MEM_RESERVE_SECURE
 	int index;
-#endif
 
 	mem_map = final_map;
 
+	/* Update mapping for DDR to actual size */
+	for (index = 0; index < ARRAY_SIZE(final_map) - 2; index++) {
+		/*
+		 * Find the entry for DDR mapping and update the address and
+		 * size. Zero-sized mapping will be skipped when creating MMU
+		 * table.
+		 */
+		switch (final_map[index].virt) {
+		case CONFIG_SYS_FSL_DRAM_BASE1:
+			final_map[index].virt = gd->bd->bi_dram[0].start;
+			final_map[index].phys = gd->bd->bi_dram[0].start;
+			final_map[index].size = gd->bd->bi_dram[0].size;
+			break;
+#ifdef CONFIG_SYS_FSL_DRAM_BASE2
+		case CONFIG_SYS_FSL_DRAM_BASE2:
+#if (CONFIG_NR_DRAM_BANKS >= 2)
+			final_map[index].virt = gd->bd->bi_dram[1].start;
+			final_map[index].phys = gd->bd->bi_dram[1].start;
+			final_map[index].size = gd->bd->bi_dram[1].size;
+#else
+			final_map[index].size = 0;
+#endif
+		break;
+#endif
+#ifdef CONFIG_SYS_FSL_DRAM_BASE3
+		case CONFIG_SYS_FSL_DRAM_BASE3:
+#if (CONFIG_NR_DRAM_BANKS >= 3)
+			final_map[index].virt = gd->bd->bi_dram[2].start;
+			final_map[index].phys = gd->bd->bi_dram[2].start;
+			final_map[index].size = gd->bd->bi_dram[2].size;
+#else
+			final_map[index].size = 0;
+#endif
+		break;
+#endif
+		default:
+			break;
+		}
+	}
+
 #ifdef CONFIG_SYS_MEM_RESERVE_SECURE
 	if (gd->arch.secure_ram & MEM_RESERVE_SECURE_MAINTAINED) {
 		if (el == 3) {
@@ -143,21 +181,14 @@
 	setup_pgtables();
 	gd->arch.tlb_addr = tlb_addr_save;
 
-	/* flush new MMU table */
-	flush_dcache_range(gd->arch.tlb_addr,
-			   gd->arch.tlb_addr + gd->arch.tlb_size);
+	/* Disable cache and MMU */
+	dcache_disable();	/* TLBs are invalidated */
+	invalidate_icache_all();
 
 	/* point TTBR to the new table */
 	set_ttbr_tcr_mair(el, gd->arch.tlb_addr, get_tcr(el, NULL, NULL),
 			  MEMORY_ATTRIBUTES);
-	/*
-	 * EL3 MMU is already enabled, just need to invalidate TLB to load the
-	 * new table. The new table is compatible with the current table, if
-	 * MMU somehow walks through the new table before invalidation TLB,
-	 * it still works. So we don't need to turn off MMU here.
-	 * When EL2 MMU table is created by calling this function, MMU needs
-	 * to be enabled.
-	 */
+
 	set_sctlr(get_sctlr() | CR_M);
 }
 
@@ -524,15 +555,277 @@
 {
 	phys_size_t ram_top = ram_size;
 
-#ifdef CONFIG_SYS_MEM_TOP_HIDE
-#error CONFIG_SYS_MEM_TOP_HIDE not to be used together with this function
-#endif
-
-/* Carve the MC private DRAM block from the end of DRAM */
 #ifdef CONFIG_FSL_MC_ENET
+	/* The start address of MC reserved memory needs to be aligned. */
 	ram_top -= mc_get_dram_block_size();
 	ram_top &= ~(CONFIG_SYS_MC_RSV_MEM_ALIGN - 1);
 #endif
+
+	return ram_size - ram_top;
+}
+
+phys_size_t get_effective_memsize(void)
+{
+	phys_size_t ea_size, rem = 0;
+
+	/*
+	 * For ARMv8 SoCs, DDR memory is split into two or three regions. The
+	 * first region is 2GB space at 0x8000_0000. If the memory extends to
+	 * the second region (or the third region if applicable), the secure
+	 * memory and Management Complex (MC) memory should be put into the
+	 * highest region, i.e. the end of DDR memory. CONFIG_MAX_MEM_MAPPED
+	 * is set to the size of first region so U-Boot doesn't relocate itself
+	 * into higher address. Should DDR be configured to skip the first
+	 * region, this function needs to be adjusted.
+	 */
+	if (gd->ram_size > CONFIG_MAX_MEM_MAPPED) {
+		ea_size = CONFIG_MAX_MEM_MAPPED;
+		rem = gd->ram_size - ea_size;
+	} else {
+		ea_size = gd->ram_size;
+	}
+
+#ifdef CONFIG_SYS_MEM_RESERVE_SECURE
+	/* Check if we have enough space for secure memory */
+	if (rem > CONFIG_SYS_MEM_RESERVE_SECURE) {
+		rem -= CONFIG_SYS_MEM_RESERVE_SECURE;
+	} else {
+		if (ea_size > CONFIG_SYS_MEM_RESERVE_SECURE) {
+			ea_size -= CONFIG_SYS_MEM_RESERVE_SECURE;
+			rem = 0;	/* Presume MC requires more memory */
+		} else {
+			printf("Error: No enough space for secure memory.\n");
+		}
+	}
+#endif
+	/* Check if we have enough memory for MC */
+	if (rem < board_reserve_ram_top(rem)) {
+		/* Not enough memory in high region to reserve */
+		if (ea_size > board_reserve_ram_top(rem))
+			ea_size -= board_reserve_ram_top(rem);
+		else
+			printf("Error: No enough space for reserved memory.\n");
+	}
 
-	return ram_top;
+	return ea_size;
+}
+
+void dram_init_banksize(void)
+{
+#ifdef CONFIG_SYS_DP_DDR_BASE_PHY
+	phys_size_t dp_ddr_size;
+#endif
+
+	/*
+	 * gd->ram_size has the total size of DDR memory, less reserved secure
+	 * memory. The DDR extends from low region to high region(s) presuming
+	 * no hole is created with DDR configuration. gd->arch.secure_ram tracks
+	 * the location of secure memory. gd->arch.resv_ram tracks the location
+	 * of reserved memory for Management Complex (MC).
+	 */
+	gd->bd->bi_dram[0].start = CONFIG_SYS_SDRAM_BASE;
+	if (gd->ram_size > CONFIG_SYS_DDR_BLOCK1_SIZE) {
+		gd->bd->bi_dram[0].size = CONFIG_SYS_DDR_BLOCK1_SIZE;
+		gd->bd->bi_dram[1].start = CONFIG_SYS_DDR_BLOCK2_BASE;
+		gd->bd->bi_dram[1].size = gd->ram_size -
+					  CONFIG_SYS_DDR_BLOCK1_SIZE;
+#ifdef CONFIG_SYS_DDR_BLOCK3_BASE
+		if (gd->bi_dram[1].size > CONFIG_SYS_DDR_BLOCK2_SIZE) {
+			gd->bd->bi_dram[2].start = CONFIG_SYS_DDR_BLOCK3_BASE;
+			gd->bd->bi_dram[2].size = gd->bd->bi_dram[1].size -
+						  CONFIG_SYS_DDR_BLOCK2_SIZE;
+			gd->bd->bi_dram[1].size = CONFIG_SYS_DDR_BLOCK2_SIZE;
+		}
+#endif
+	} else {
+		gd->bd->bi_dram[0].size = gd->ram_size;
+	}
+#ifdef CONFIG_SYS_MEM_RESERVE_SECURE
+#ifdef CONFIG_SYS_DDR_BLOCK3_BASE
+	if (gd->bd->bi_dram[2].size >= CONFIG_SYS_MEM_RESERVE_SECURE) {
+		gd->bd->bi_dram[2].size -= CONFIG_SYS_MEM_RESERVE_SECURE;
+		gd->arch.secure_ram = gd->bd->bi_dram[2].start +
+				      gd->bd->bi_dram[2].size;
+		gd->arch.secure_ram |= MEM_RESERVE_SECURE_MAINTAINED;
+		gd->ram_size -= CONFIG_SYS_MEM_RESERVE_SECURE;
+	} else
+#endif
+	{
+		if (gd->bd->bi_dram[1].size >= CONFIG_SYS_MEM_RESERVE_SECURE) {
+			gd->bd->bi_dram[1].size -=
+					CONFIG_SYS_MEM_RESERVE_SECURE;
+			gd->arch.secure_ram = gd->bd->bi_dram[1].start +
+					      gd->bd->bi_dram[1].size;
+			gd->arch.secure_ram |= MEM_RESERVE_SECURE_MAINTAINED;
+			gd->ram_size -= CONFIG_SYS_MEM_RESERVE_SECURE;
+		} else if (gd->bd->bi_dram[0].size >
+					CONFIG_SYS_MEM_RESERVE_SECURE) {
+			gd->bd->bi_dram[0].size -=
+					CONFIG_SYS_MEM_RESERVE_SECURE;
+			gd->arch.secure_ram = gd->bd->bi_dram[0].start +
+					      gd->bd->bi_dram[0].size;
+			gd->arch.secure_ram |= MEM_RESERVE_SECURE_MAINTAINED;
+			gd->ram_size -= CONFIG_SYS_MEM_RESERVE_SECURE;
+		}
+	}
+#endif	/* CONFIG_SYS_MEM_RESERVE_SECURE */
+
+#ifdef CONFIG_FSL_MC_ENET
+	/* Assign memory for MC */
+#ifdef CONFIG_SYS_DDR_BLOCK3_BASE
+	if (gd->bd->bi_dram[2].size >=
+	    board_reserve_ram_top(gd->bd->bi_dram[2].size)) {
+		gd->arch.resv_ram = gd->bd->bi_dram[2].start +
+			    gd->bd->bi_dram[2].size -
+			    board_reserve_ram_top(gd->bd->bi_dram[2].size);
+	} else
+#endif
+	{
+		if (gd->bd->bi_dram[1].size >=
+		    board_reserve_ram_top(gd->bd->bi_dram[1].size)) {
+			gd->arch.resv_ram = gd->bd->bi_dram[1].start +
+				gd->bd->bi_dram[1].size -
+				board_reserve_ram_top(gd->bd->bi_dram[1].size);
+		} else if (gd->bd->bi_dram[0].size >
+			   board_reserve_ram_top(gd->bd->bi_dram[0].size)) {
+			gd->arch.resv_ram = gd->bd->bi_dram[0].start +
+				gd->bd->bi_dram[0].size -
+				board_reserve_ram_top(gd->bd->bi_dram[0].size);
+		}
+	}
+#endif	/* CONFIG_FSL_MC_ENET */
+
+#ifdef CONFIG_SYS_DP_DDR_BASE_PHY
+#ifdef CONFIG_SYS_DDR_BLOCK3_BASE
+#error "This SoC shouldn't have DP DDR"
+#endif
+	if (soc_has_dp_ddr()) {
+		/* initialize DP-DDR here */
+		puts("DP-DDR:  ");
+		/*
+		 * DDR controller use 0 as the base address for binding.
+		 * It is mapped to CONFIG_SYS_DP_DDR_BASE for core to access.
+		 */
+		dp_ddr_size = fsl_other_ddr_sdram(CONFIG_SYS_DP_DDR_BASE_PHY,
+					  CONFIG_DP_DDR_CTRL,
+					  CONFIG_DP_DDR_NUM_CTRLS,
+					  CONFIG_DP_DDR_DIMM_SLOTS_PER_CTLR,
+					  NULL, NULL, NULL);
+		if (dp_ddr_size) {
+			gd->bd->bi_dram[2].start = CONFIG_SYS_DP_DDR_BASE;
+			gd->bd->bi_dram[2].size = dp_ddr_size;
+		} else {
+			puts("Not detected");
+		}
+	}
+#endif
+}
+
+#if defined(CONFIG_EFI_LOADER) && !defined(CONFIG_SPL_BUILD)
+void efi_add_known_memory(void)
+{
+	int i;
+	phys_addr_t ram_start, start;
+	phys_size_t ram_size;
+	u64 pages;
+
+	/* Add RAM */
+	for (i = 0; i < CONFIG_NR_DRAM_BANKS; i++) {
+#ifdef CONFIG_SYS_DP_DDR_BASE_PHY
+#ifdef CONFIG_SYS_DDR_BLOCK3_BASE
+#error "This SoC shouldn't have DP DDR"
+#endif
+		if (i == 2)
+			continue;	/* skip DP-DDR */
+#endif
+		ram_start = gd->bd->bi_dram[i].start;
+		ram_size = gd->bd->bi_dram[i].size;
+#ifdef CONFIG_RESV_RAM
+		if (gd->arch.resv_ram >= ram_start &&
+		    gd->arch.resv_ram < ram_start + ram_size)
+			ram_size = gd->arch.resv_ram - ram_start;
+#endif
+		start = (ram_start + EFI_PAGE_MASK) & ~EFI_PAGE_MASK;
+		pages = (ram_size + EFI_PAGE_MASK) >> EFI_PAGE_SHIFT;
+
+		efi_add_memory_map(start, pages, EFI_CONVENTIONAL_MEMORY,
+				   false);
+	}
+}
+#endif
+
+/*
+ * Before DDR size is known, early MMU table have DDR mapped as device memory
+ * to avoid speculative access. To relocate U-Boot to DDR, "normal memory"
+ * needs to be set for these mappings.
+ * If a special case configures DDR with holes in the mapping, the holes need
+ * to be marked as invalid. This is not implemented in this function.
+ */
+void update_early_mmu_table(void)
+{
+	if (!gd->arch.tlb_addr)
+		return;
+
+	if (gd->ram_size <= CONFIG_SYS_FSL_DRAM_SIZE1) {
+		mmu_change_region_attr(
+					CONFIG_SYS_SDRAM_BASE,
+					gd->ram_size,
+					PTE_BLOCK_MEMTYPE(MT_NORMAL)	|
+					PTE_BLOCK_OUTER_SHARE		|
+					PTE_BLOCK_NS			|
+					PTE_TYPE_VALID);
+	} else {
+		mmu_change_region_attr(
+					CONFIG_SYS_SDRAM_BASE,
+					CONFIG_SYS_DDR_BLOCK1_SIZE,
+					PTE_BLOCK_MEMTYPE(MT_NORMAL)	|
+					PTE_BLOCK_OUTER_SHARE		|
+					PTE_BLOCK_NS			|
+					PTE_TYPE_VALID);
+#ifdef CONFIG_SYS_DDR_BLOCK3_BASE
+#ifndef CONFIG_SYS_DDR_BLOCK2_SIZE
+#error "Missing CONFIG_SYS_DDR_BLOCK2_SIZE"
+#endif
+		if (gd->ram_size - CONFIG_SYS_DDR_BLOCK1_SIZE >
+		    CONFIG_SYS_DDR_BLOCK2_SIZE) {
+			mmu_change_region_attr(
+					CONFIG_SYS_DDR_BLOCK2_BASE,
+					CONFIG_SYS_DDR_BLOCK2_SIZE,
+					PTE_BLOCK_MEMTYPE(MT_NORMAL)	|
+					PTE_BLOCK_OUTER_SHARE		|
+					PTE_BLOCK_NS			|
+					PTE_TYPE_VALID);
+			mmu_change_region_attr(
+					CONFIG_SYS_DDR_BLOCK3_BASE,
+					gd->ram_size -
+					CONFIG_SYS_DDR_BLOCK1_SIZE -
+					CONFIG_SYS_DDR_BLOCK2_SIZE,
+					PTE_BLOCK_MEMTYPE(MT_NORMAL)	|
+					PTE_BLOCK_OUTER_SHARE		|
+					PTE_BLOCK_NS			|
+					PTE_TYPE_VALID);
+		} else
+#endif
+		{
+			mmu_change_region_attr(
+					CONFIG_SYS_DDR_BLOCK2_BASE,
+					gd->ram_size -
+					CONFIG_SYS_DDR_BLOCK1_SIZE,
+					PTE_BLOCK_MEMTYPE(MT_NORMAL)	|
+					PTE_BLOCK_OUTER_SHARE		|
+					PTE_BLOCK_NS			|
+					PTE_TYPE_VALID);
+		}
+	}
+}
+
+__weak int dram_init(void)
+{
+	gd->ram_size = initdram(0);
+#if !defined(CONFIG_SPL) || defined(CONFIG_SPL_BUILD)
+	/* This will break-before-make MMU for DDR */
+	update_early_mmu_table();
+#endif
+
+	return 0;
 }
diff --git a/arch/arm/cpu/armv8/fsl-layerscape/soc.c b/arch/arm/cpu/armv8/fsl-layerscape/soc.c
index 9489f85..b54a937 100644
--- a/arch/arm/cpu/armv8/fsl-layerscape/soc.c
+++ b/arch/arm/cpu/armv8/fsl-layerscape/soc.c
@@ -233,10 +233,8 @@
 {
 	struct ccsr_ahci __iomem *ccsr_ahci = (void *)CONFIG_SYS_SATA;
 
-#ifdef CONFIG_ARCH_LS1046A
 	/* Disable SATA ECC */
 	out_le32((void *)CONFIG_SYS_DCSR_DCFG_ADDR + 0x520, 0x80000000);
-#endif
 	out_le32(&ccsr_ahci->ppcfg, AHCI_PORT_PHY_1_CFG);
 	out_le32(&ccsr_ahci->ptc, AHCI_PORT_TRANS_CFG);
 	out_le32(&ccsr_ahci->axicc, AHCI_PORT_AXICC_CFG);
diff --git a/arch/arm/cpu/armv8/fsl-layerscape/spl.c b/arch/arm/cpu/armv8/fsl-layerscape/spl.c
index 1dabdbb..73a8680 100644
--- a/arch/arm/cpu/armv8/fsl-layerscape/spl.c
+++ b/arch/arm/cpu/armv8/fsl-layerscape/spl.c
@@ -45,9 +45,6 @@
 {
 	/* Clear global data */
 	memset((void *)gd, 0, sizeof(gd_t));
-#ifdef CONFIG_LS2080A
-	arch_cpu_init();
-#endif
 	board_early_init_f();
 	timer_init();
 #ifdef CONFIG_LS2080A
diff --git a/arch/arm/dts/stm32f746-disco.dts b/arch/arm/dts/stm32f746-disco.dts
index bad0698..07e0ca7 100644
--- a/arch/arm/dts/stm32f746-disco.dts
+++ b/arch/arm/dts/stm32f746-disco.dts
@@ -61,12 +61,24 @@
 	};
 
 	aliases {
+		serial0 = &usart1;
 		spi0 = &qspi;
 	};
 };
 
+&clk_hse {
+	clock-frequency = <25000000>;
+};
+
+&usart1 {
+	pinctrl-0 = <&usart1_pins_a>;
+	pinctrl-names = "default";
+	status = "okay";
+};
+
 &mac {
 	status = "okay";
+	pinctrl-0 = <&ethernet_mii>;
 	phy-mode = "rmii";
 	phy-handle = <&phy0>;
 
@@ -81,6 +93,7 @@
 };
 
 &qspi {
+	pinctrl-0 = <&qspi_pins>;
 	status = "okay";
 
 	qflash0: n25q128a {
diff --git a/arch/arm/dts/stm32f746.dtsi b/arch/arm/dts/stm32f746.dtsi
index 3902e76..b2b0b5f 100644
--- a/arch/arm/dts/stm32f746.dtsi
+++ b/arch/arm/dts/stm32f746.dtsi
@@ -48,7 +48,16 @@
 #include <dt-bindings/pinctrl/stm32f746-pinfunc.h>
 
 / {
+	clocks {
+		clk_hse: clk-hse {
+			#clock-cells = <0>;
+			compatible = "fixed-clock";
+			clock-frequency = <0>;
+		};
+};
+
 	soc {
+		u-boot,dm-pre-reloc;
 		mac: ethernet@40028000 {
 			compatible = "st,stm32-dwmac";
 			reg = <0x40028000 0x8000>;
@@ -71,6 +80,69 @@
 			spi-max-frequency = <108000000>;
 			status = "disabled";
 		};
+		usart1: serial@40011000 {
+			compatible = "st,stm32-usart", "st,stm32-uart";
+			reg = <0x40011000 0x400>;
+			interrupts = <37>;
+			clocks = <&rcc 0 164>;
+			status = "disabled";
+			u-boot,dm-pre-reloc;
+		};
+		rcc: rcc@40023810 {
+			#reset-cells = <1>;
+			#clock-cells = <2>;
+			compatible = "st,stm32f42xx-rcc", "st,stm32-rcc";
+			reg = <0x40023800 0x400>;
+			clocks = <&clk_hse>;
+			u-boot,dm-pre-reloc;
+		};
+
+		pinctrl: pin-controller {
+			#address-cells = <1>;
+			#size-cells = <1>;
+			compatible = "st,stm32f746-pinctrl";
+			ranges = <0 0x40020000 0x3000>;
+			u-boot,dm-pre-reloc;
+			pins-are-numbered;
+
+			usart1_pins_a: usart1@0 {
+				pins1 {
+					pinmux = <STM32F746_PA9_FUNC_USART1_TX>;
+					bias-disable;
+					drive-push-pull;
+					slew-rate = <2>;
+				};
+				pins2 {
+					pinmux = <STM32F746_PB7_FUNC_USART1_RX>;
+					bias-disable;
+				};
+			};
+			ethernet_mii: mii@0 {
+				pins {
+					pinmux = <STM32F746_PG13_FUNC_ETH_MII_TXD0_ETH_RMII_TXD0>,
+						 <STM32F746_PG14_FUNC_ETH_MII_TXD1_ETH_RMII_TXD1>,
+						 <STM32F746_PG11_FUNC_ETH_MII_TX_EN_ETH_RMII_TX_EN>,
+						 <STM32F746_PA2_FUNC_ETH_MDIO>,
+						 <STM32F746_PC1_FUNC_ETH_MDC>,
+						 <STM32F746_PA1_FUNC_ETH_MII_RX_CLK_ETH_RMII_REF_CLK>,
+						 <STM32F746_PA7_FUNC_ETH_MII_RX_DV_ETH_RMII_CRS_DV>,
+						 <STM32F746_PC4_FUNC_ETH_MII_RXD0_ETH_RMII_RXD0>,
+						 <STM32F746_PC5_FUNC_ETH_MII_RXD1_ETH_RMII_RXD1>;
+					slew-rate = <2>;
+				};
+			};
+			qspi_pins: qspi@0{
+				pins {
+					pinmux = <STM32F746_PB2_FUNC_QUADSPI_CLK>,
+						 <STM32F746_PB6_FUNC_QUADSPI_BK1_NCS>,
+						 <STM32F746_PD11_FUNC_QUADSPI_BK1_IO0>,
+						 <STM32F746_PD12_FUNC_QUADSPI_BK1_IO1>,
+						 <STM32F746_PD13_FUNC_QUADSPI_BK1_IO3>,
+						 <STM32F746_PE2_FUNC_QUADSPI_BK1_IO2>;
+					slew-rate = <2>;
+				};
+			};
+		};
 	};
 };
 
diff --git a/arch/arm/dts/zynq-7000.dtsi b/arch/arm/dts/zynq-7000.dtsi
index fa9ee27..34fc6e5 100644
--- a/arch/arm/dts/zynq-7000.dtsi
+++ b/arch/arm/dts/zynq-7000.dtsi
@@ -248,12 +248,14 @@
 		};
 
 		slcr: slcr@f8000000 {
+			u-boot,dm-pre-reloc;
 			#address-cells = <1>;
 			#size-cells = <1>;
 			compatible = "xlnx,zynq-slcr", "syscon", "simple-mfd";
 			reg = <0xF8000000 0x1000>;
 			ranges;
 			clkc: clkc@100 {
+				u-boot,dm-pre-reloc;
 				#clock-cells = <1>;
 				compatible = "xlnx,ps7-clkc";
 				fclk-enable = <0>;
diff --git a/arch/arm/include/asm/arch-fsl-layerscape/config.h b/arch/arm/include/asm/arch-fsl-layerscape/config.h
index 586ce17..b5b08aa 100644
--- a/arch/arm/include/asm/arch-fsl-layerscape/config.h
+++ b/arch/arm/include/asm/arch-fsl-layerscape/config.h
@@ -33,8 +33,8 @@
 #define CONFIG_SYS_FSL_OCRAM_SIZE	0x00020000 /* Real size 128K */
 
 /* DDR */
-#define CONFIG_SYS_LS2_DDR_BLOCK1_SIZE	((phys_size_t)2 << 30)
-#define CONFIG_MAX_MEM_MAPPED		CONFIG_SYS_LS2_DDR_BLOCK1_SIZE
+#define CONFIG_SYS_DDR_BLOCK1_SIZE	((phys_size_t)2 << 30)
+#define CONFIG_MAX_MEM_MAPPED		CONFIG_SYS_DDR_BLOCK1_SIZE
 
 #define CONFIG_SYS_FSL_CCSR_GUR_LE
 #define CONFIG_SYS_FSL_CCSR_SCFG_LE
diff --git a/arch/arm/include/asm/arch-fsl-layerscape/cpu.h b/arch/arm/include/asm/arch-fsl-layerscape/cpu.h
index 4ea4aeaf..bcf3e38 100644
--- a/arch/arm/include/asm/arch-fsl-layerscape/cpu.h
+++ b/arch/arm/include/asm/arch-fsl-layerscape/cpu.h
@@ -115,7 +115,11 @@
 	},
 	{ CONFIG_SYS_FSL_DRAM_BASE1, CONFIG_SYS_FSL_DRAM_BASE1,
 	  CONFIG_SYS_FSL_DRAM_SIZE1,
+#if defined(CONFIG_SPL) && !defined(CONFIG_SPL_BUILD)
 	  PTE_BLOCK_MEMTYPE(MT_NORMAL) |
+#else	/* Start with nGnRnE and PXN and UXN to prevent speculative access */
+	  PTE_BLOCK_MEMTYPE(MT_DEVICE_NGNRNE) | PTE_BLOCK_PXN | PTE_BLOCK_UXN |
+#endif
 	  PTE_BLOCK_OUTER_SHARE | PTE_BLOCK_NS
 	},
 	/* Map IFC region #2 up to CONFIG_SYS_FLASH_BASE for NAND boot */
@@ -130,7 +134,7 @@
 	},
 	{ CONFIG_SYS_FSL_DRAM_BASE2, CONFIG_SYS_FSL_DRAM_BASE2,
 	  CONFIG_SYS_FSL_DRAM_SIZE2,
-	  PTE_BLOCK_MEMTYPE(MT_NORMAL) |
+	  PTE_BLOCK_MEMTYPE(MT_DEVICE_NGNRNE) | PTE_BLOCK_PXN | PTE_BLOCK_UXN |
 	  PTE_BLOCK_OUTER_SHARE | PTE_BLOCK_NS
 	},
 #elif defined(CONFIG_FSL_LSCH2)
@@ -158,12 +162,16 @@
 	},
 	{ CONFIG_SYS_FSL_DRAM_BASE1, CONFIG_SYS_FSL_DRAM_BASE1,
 	  CONFIG_SYS_FSL_DRAM_SIZE1,
+#if defined(CONFIG_SPL) && !defined(CONFIG_SPL_BUILD)
 	  PTE_BLOCK_MEMTYPE(MT_NORMAL) |
+#else	/* Start with nGnRnE and PXN and UXN to prevent speculative access */
+	  PTE_BLOCK_MEMTYPE(MT_DEVICE_NGNRNE) | PTE_BLOCK_PXN | PTE_BLOCK_UXN |
+#endif
 	  PTE_BLOCK_OUTER_SHARE | PTE_BLOCK_NS
 	},
 	{ CONFIG_SYS_FSL_DRAM_BASE2, CONFIG_SYS_FSL_DRAM_BASE2,
 	  CONFIG_SYS_FSL_DRAM_SIZE2,
-	  PTE_BLOCK_MEMTYPE(MT_NORMAL) |
+	  PTE_BLOCK_MEMTYPE(MT_DEVICE_NGNRNE) | PTE_BLOCK_PXN | PTE_BLOCK_UXN |
 	  PTE_BLOCK_OUTER_SHARE | PTE_BLOCK_NS
 	},
 #endif
diff --git a/arch/arm/include/asm/arch-fsl-layerscape/immap_lsch3.h b/arch/arm/include/asm/arch-fsl-layerscape/immap_lsch3.h
index 43ae686..08ea8fb 100644
--- a/arch/arm/include/asm/arch-fsl-layerscape/immap_lsch3.h
+++ b/arch/arm/include/asm/arch-fsl-layerscape/immap_lsch3.h
@@ -177,21 +177,23 @@
 	u8	res_008[0x20-0x8];
 	u32	gpporcr1;	/* General-purpose POR configuration */
 	u32	gpporcr2;	/* General-purpose POR configuration 2 */
-#define FSL_CHASSIS3_DCFG_FUSESR_VID_SHIFT	25
+	u32	gpporcr3;
+	u32	gpporcr4;
+	u8	res_030[0x60-0x30];
+#define FSL_CHASSIS3_DCFG_FUSESR_VID_SHIFT	2
 #define FSL_CHASSIS3_DCFG_FUSESR_VID_MASK	0x1F
-#define FSL_CHASSIS3_DCFG_FUSESR_ALTVID_SHIFT	20
+#define FSL_CHASSIS3_DCFG_FUSESR_ALTVID_SHIFT	7
 #define FSL_CHASSIS3_DCFG_FUSESR_ALTVID_MASK	0x1F
 	u32	dcfg_fusesr;	/* Fuse status register */
-	u32	gpporcr3;
-	u32	gpporcr4;
-	u8	res_034[0x70-0x34];
-	u32	devdisr;	/* Device disable control */
+	u8	res_064[0x70-0x64];
+	u32	devdisr;	/* Device disable control 1 */
 	u32	devdisr2;	/* Device disable control 2 */
 	u32	devdisr3;	/* Device disable control 3 */
 	u32	devdisr4;	/* Device disable control 4 */
 	u32	devdisr5;	/* Device disable control 5 */
 	u32	devdisr6;	/* Device disable control 6 */
-	u32	devdisr7;	/* Device disable control 7 */
+	u8	res_088[0x94-0x88];
+	u32	coredisr;	/* Device disable control 7 */
 #define FSL_CHASSIS3_DEVDISR2_DPMAC1	0x00000001
 #define FSL_CHASSIS3_DEVDISR2_DPMAC2	0x00000002
 #define FSL_CHASSIS3_DEVDISR2_DPMAC3	0x00000004
@@ -216,15 +218,11 @@
 #define FSL_CHASSIS3_DEVDISR2_DPMAC22	0x00200000
 #define FSL_CHASSIS3_DEVDISR2_DPMAC23	0x00400000
 #define FSL_CHASSIS3_DEVDISR2_DPMAC24	0x00800000
-	u8	res_08c[0x90-0x8c];
-	u32	coredisru;	/* uppper portion for support of 64 cores */
-	u32	coredisrl;	/* lower portion for support of 64 cores */
 	u8	res_098[0xa0-0x98];
 	u32	pvr;		/* Processor version */
 	u32	svr;		/* System version */
-	u32	mvr;		/* Manufacturing version */
-	u8	res_0ac[0x100-0xac];
-	u32	rcwsr[32];	/* Reset control word status */
+	u8	res_0a8[0x100-0xa8];
+	u32	rcwsr[30];	/* Reset control word status */
 
 #define FSL_CHASSIS3_RCWSR0_SYS_PLL_RAT_SHIFT	2
 #define FSL_CHASSIS3_RCWSR0_SYS_PLL_RAT_MASK	0x1f
@@ -239,24 +237,53 @@
 #define RCW_SB_EN_REG_INDEX	9
 #define RCW_SB_EN_MASK		0x00000400
 
-	u8	res_180[0x200-0x180];
-	u32	scratchrw[32];	/* Scratch Read/Write */
-	u8	res_280[0x300-0x280];
+	u8	res_178[0x200-0x178];
+	u32	scratchrw[16];	/* Scratch Read/Write */
+	u8	res_240[0x300-0x240];
 	u32	scratchw1r[4];	/* Scratch Read (Write once) */
 	u8	res_310[0x400-0x310];
 	u32	bootlocptrl;	/* Boot location pointer low-order addr */
 	u32	bootlocptrh;	/* Boot location pointer high-order addr */
-	u8	res_408[0x500-0x408];
-	u8	res_500[0x740-0x500];	/* add more registers when needed */
+	u8	res_408[0x520-0x408];
+	u32	usb1_amqr;
+	u32	usb2_amqr;
+	u8	res_528[0x530-0x528];	/* add more registers when needed */
+	u32	sdmm1_amqr;
+	u8	res_534[0x550-0x534];	/* add more registers when needed */
+	u32	sata1_amqr;
+	u32	sata2_amqr;
+	u8	res_558[0x570-0x558];	/* add more registers when needed */
+	u32	misc1_amqr;
+	u8	res_574[0x590-0x574];	/* add more registers when needed */
+	u32	spare1_amqr;
+	u32	spare2_amqr;
+	u8	res_598[0x620-0x598];	/* add more registers when needed */
+	u32	gencr[7];	/* General Control Registers */
+	u8	res_63c[0x640-0x63c];	/* add more registers when needed */
+	u32	cgensr1;	/* Core General Status Register */
+	u8	res_644[0x660-0x644];	/* add more registers when needed */
+	u32	cgencr1;	/* Core General Control Register */
+	u8	res_664[0x740-0x664];	/* add more registers when needed */
 	u32	tp_ityp[64];	/* Topology Initiator Type Register */
 	struct {
 		u32	upper;
 		u32	lower;
-	} tp_cluster[3];	/* Core Cluster n Topology Register */
-	u8	res_858[0x1000-0x858];
+	} tp_cluster[4];	/* Core cluster n Topology Register */
+	u8	res_864[0x920-0x864];	/* add more registers when needed */
+	u32 ioqoscr[8];	/*I/O Quality of Services Register */
+	u32 uccr;
+	u8	res_944[0x960-0x944];	/* add more registers when needed */
+	u32 ftmcr;
+	u8	res_964[0x990-0x964];	/* add more registers when needed */
+	u32 coredisablesr;
+	u8	res_994[0xa00-0x994];	/* add more registers when needed */
+	u32 sdbgcr; /*Secure Debug Confifuration Register */
+	u8	res_a04[0xbf8-0xa04];	/* add more registers when needed */
+	u32 ipbrr1;
+	u32 ipbrr2;
+	u8	res_858[0x1000-0xc00];
 };
 
-
 struct ccsr_clk_cluster_group {
 	struct {
 		u8	res_00[0x10];
diff --git a/arch/arm/include/asm/arch-fsl-layerscape/mmu.h b/arch/arm/include/asm/arch-fsl-layerscape/mmu.h
index d54eacd..d232bec 100644
--- a/arch/arm/include/asm/arch-fsl-layerscape/mmu.h
+++ b/arch/arm/include/asm/arch-fsl-layerscape/mmu.h
@@ -6,5 +6,5 @@
 
 #ifndef _ASM_ARMV8_FSL_LAYERSCAPE_MMU_H_
 #define _ASM_ARMV8_FSL_LAYERSCAPE_MMU_H_
-#include <asm/arch-armv8/mmu.h>
+void update_early_mmu_table(void);
 #endif /* _ASM_ARMV8_FSL_LAYERSCAPE_MMU_H_ */
diff --git a/arch/arm/include/asm/arch-zynqmp/sys_proto.h b/arch/arm/include/asm/arch-zynqmp/sys_proto.h
index 8c54fce..7b11895 100644
--- a/arch/arm/include/asm/arch-zynqmp/sys_proto.h
+++ b/arch/arm/include/asm/arch-zynqmp/sys_proto.h
@@ -8,13 +8,6 @@
 #ifndef _ASM_ARCH_SYS_PROTO_H
 #define _ASM_ARCH_SYS_PROTO_H
 
-#ifndef CONFIG_CLK_ZYNQMP
-/* Setup clk for network */
-static inline void zynq_slcr_gem_clk_setup(u32 gem_id, unsigned long clk_rate)
-{
-}
-#endif
-
 int zynq_slcr_get_mio_pin_status(const char *periph);
 
 unsigned int zynqmp_get_silicon_version(void);
diff --git a/arch/arm/include/asm/armv8/mmu.h b/arch/arm/include/asm/armv8/mmu.h
index e9b4cdb..a349903 100644
--- a/arch/arm/include/asm/armv8/mmu.h
+++ b/arch/arm/include/asm/armv8/mmu.h
@@ -53,6 +53,7 @@
 #define PTE_TYPE_FAULT		(0 << 0)
 #define PTE_TYPE_TABLE		(3 << 0)
 #define PTE_TYPE_BLOCK		(1 << 0)
+#define PTE_TYPE_VALID		(1 << 0)
 
 #define PTE_TABLE_PXN		(1UL << 59)
 #define PTE_TABLE_XN		(1UL << 60)
@@ -77,6 +78,10 @@
  */
 #define PMD_ATTRINDX(t)		((t) << 2)
 #define PMD_ATTRINDX_MASK	(7 << 2)
+#define PMD_ATTRMASK		(PTE_BLOCK_PXN		| \
+				 PTE_BLOCK_UXN		| \
+				 PMD_ATTRINDX_MASK	| \
+				 PTE_TYPE_VALID)
 
 /*
  * TCR flags.
diff --git a/arch/arm/include/asm/assembler.h b/arch/arm/include/asm/assembler.h
index c56daf2..d24be2d 100644
--- a/arch/arm/include/asm/assembler.h
+++ b/arch/arm/include/asm/assembler.h
@@ -57,17 +57,17 @@
 #define PLD(code...)
 #endif
 
+/*
+ * We only support cores that support at least Thumb-1 and thus we use
+ * 'bx lr'
+ */
 	.irp	c,,eq,ne,cs,cc,mi,pl,vs,vc,hi,ls,ge,lt,gt,le,hs,lo
 	.macro	ret\c, reg
-#if defined(__ARM_ARCH_5E__)
-	mov\c	pc, \reg
-#else
 	.ifeqs	"\reg", "lr"
 	bx\c	\reg
 	.else
 	mov\c	pc, \reg
 	.endif
-#endif
 	.endm
 	.endr
 
diff --git a/arch/arm/include/asm/fsl_secure_boot.h b/arch/arm/include/asm/fsl_secure_boot.h
index ccb513f..fd627c0 100644
--- a/arch/arm/include/asm/fsl_secure_boot.h
+++ b/arch/arm/include/asm/fsl_secure_boot.h
@@ -86,8 +86,8 @@
 /* For SD boot address and size are assigned in terms of sector
  * offset and no. of sectors respectively.
  */
-#define CONFIG_BS_HDR_ADDR_DEVICE	0x00000800
-#define CONFIG_BS_ADDR_DEVICE		0x00000840
+#define CONFIG_BS_HDR_ADDR_DEVICE	0x00000900
+#define CONFIG_BS_ADDR_DEVICE		0x00000940
 #define CONFIG_BS_HDR_SIZE		0x00000010
 #define CONFIG_BS_SIZE			0x00000008
 #else
diff --git a/arch/arm/include/asm/global_data.h b/arch/arm/include/asm/global_data.h
index aee87cd..dfcbcce 100644
--- a/arch/arm/include/asm/global_data.h
+++ b/arch/arm/include/asm/global_data.h
@@ -59,6 +59,13 @@
 	phys_addr_t secure_ram;
 	unsigned long tlb_allocated;
 #endif
+#ifdef CONFIG_RESV_RAM
+	/*
+	 * Reserved RAM for memory resident, eg. Management Complex (MC)
+	 * driver which continues to run after U-Boot exits.
+	 */
+	phys_addr_t resv_ram;
+#endif
 
 #ifdef CONFIG_ARCH_OMAP2
 	u32 omap_boot_device;
diff --git a/arch/arm/include/asm/system.h b/arch/arm/include/asm/system.h
index 766e929..9c3261c 100644
--- a/arch/arm/include/asm/system.h
+++ b/arch/arm/include/asm/system.h
@@ -226,6 +226,7 @@
 void smp_kick_all_cpus(void);
 
 void flush_l3_cache(void);
+void mmu_change_region_attr(phys_addr_t start, size_t size, u64 attrs);
 
 /*
  *Issue a secure monitor call in accordance with ARM "SMC Calling convention",
diff --git a/arch/arm/lib/crt0.S b/arch/arm/lib/crt0.S
index 8415f77..2c4867a 100644
--- a/arch/arm/lib/crt0.S
+++ b/arch/arm/lib/crt0.S
@@ -71,18 +71,12 @@
  */
 
 #if defined(CONFIG_SPL_BUILD) && defined(CONFIG_SPL_STACK)
-	ldr	sp, =(CONFIG_SPL_STACK)
+	ldr	r0, =(CONFIG_SPL_STACK)
 #else
-	ldr	sp, =(CONFIG_SYS_INIT_SP_ADDR)
+	ldr	r0, =(CONFIG_SYS_INIT_SP_ADDR)
 #endif
-#if defined(CONFIG_CPU_V7M)	/* v7M forbids using SP as BIC destination */
-	mov	r3, sp
-	bic	r3, r3, #7
-	mov	sp, r3
-#else
-	bic	sp, sp, #7	/* 8-byte alignment for ABI compliance */
-#endif
-	mov	r0, sp
+	bic	r0, r0, #7	/* 8-byte alignment for ABI compliance */
+	mov	sp, r0
 	bl	board_init_f_alloc_reserve
 	mov	sp, r0
 	/* set up gd here, outside any C code */
@@ -100,14 +94,9 @@
  * 'here' but relocated.
  */
 
-	ldr	sp, [r9, #GD_START_ADDR_SP]	/* sp = gd->start_addr_sp */
-#if defined(CONFIG_CPU_V7M)	/* v7M forbids using SP as BIC destination */
-	mov	r3, sp
-	bic	r3, r3, #7
-	mov	sp, r3
-#else
-	bic	sp, sp, #7	/* 8-byte alignment for ABI compliance */
-#endif
+	ldr	r0, [r9, #GD_START_ADDR_SP]	/* sp = gd->start_addr_sp */
+	bic	r0, r0, #7	/* 8-byte alignment for ABI compliance */
+	mov	sp, r0
 	ldr	r9, [r9, #GD_BD]		/* r9 = gd->bd */
 	sub	r9, r9, #GD_SIZE		/* new GD is below bd */
 
diff --git a/arch/arm/mach-kirkwood/include/mach/config.h b/arch/arm/mach-kirkwood/include/mach/config.h
index 446457f..b786df0 100644
--- a/arch/arm/mach-kirkwood/include/mach/config.h
+++ b/arch/arm/mach-kirkwood/include/mach/config.h
@@ -24,7 +24,6 @@
 #endif /* CONFIG_KW88F6281 */
 
 #include <asm/arch/soc.h>
-#define CONFIG_MD5	/* get_random_hex on krikwood needs MD5 support */
 #define CONFIG_KIRKWOOD_EGIGA_INIT	/* Enable GbePort0/1 for kernel */
 #define CONFIG_KIRKWOOD_RGMII_PAD_1V8	/* Set RGMII Pad voltage to 1.8V */
 #define CONFIG_KIRKWOOD_PCIE_INIT       /* Enable PCIE Port0 for kernel */
diff --git a/arch/arm/mach-kirkwood/include/mach/cpu.h b/arch/arm/mach-kirkwood/include/mach/cpu.h
index 926d347..ab704d9 100644
--- a/arch/arm/mach-kirkwood/include/mach/cpu.h
+++ b/arch/arm/mach-kirkwood/include/mach/cpu.h
@@ -139,7 +139,6 @@
 /*
  * functions
  */
-unsigned char get_random_hex(void);
 unsigned int mvebu_sdram_bar(enum memory_bank bank);
 unsigned int mvebu_sdram_bs(enum memory_bank bank);
 void mvebu_sdram_size_adjust(enum memory_bank bank);
diff --git a/arch/arm/mach-stm32/stm32f7/Makefile b/arch/arm/mach-stm32/stm32f7/Makefile
index 643d4d9..03269bd 100644
--- a/arch/arm/mach-stm32/stm32f7/Makefile
+++ b/arch/arm/mach-stm32/stm32f7/Makefile
@@ -5,4 +5,4 @@
 # SPDX-License-Identifier:	GPL-2.0+
 #
 
-obj-y += timer.o clock.o soc.o
+obj-y += timer.o soc.o
diff --git a/arch/arm/mach-stm32/stm32f7/soc.c b/arch/arm/mach-stm32/stm32f7/soc.c
index 8baee99..06af631 100644
--- a/arch/arm/mach-stm32/stm32f7/soc.c
+++ b/arch/arm/mach-stm32/stm32f7/soc.c
@@ -17,8 +17,6 @@
 
 int arch_cpu_init(void)
 {
-	configure_clocks();
-
 	/*
 		* Configure the memory protection unit (MPU)
 		* 0x00000000 - 0xffffffff: Strong-order, Shareable
diff --git a/arch/arm/mach-zynq/clk.c b/arch/arm/mach-zynq/clk.c
index 40383c1..1369cd0 100644
--- a/arch/arm/mach-zynq/clk.c
+++ b/arch/arm/mach-zynq/clk.c
@@ -4,645 +4,65 @@
  *
  * SPDX-License-Identifier:	GPL-2.0+
  */
+#include <clk.h>
 #include <common.h>
-#include <errno.h>
-#include <asm/io.h>
-#include <asm/arch/hardware.h>
+#include <dm.h>
 #include <asm/arch/clk.h>
 
-/* Board oscillator frequency */
-#ifndef CONFIG_ZYNQ_PS_CLK_FREQ
-# define CONFIG_ZYNQ_PS_CLK_FREQ	33333333UL
-#endif
-
-/* Register bitfield defines */
-#define PLLCTRL_FBDIV_MASK	0x7f000
-#define PLLCTRL_FBDIV_SHIFT	12
-#define PLLCTRL_BPFORCE_MASK	(1 << 4)
-#define PLLCTRL_PWRDWN_MASK	2
-#define PLLCTRL_PWRDWN_SHIFT	1
-#define PLLCTRL_RESET_MASK	1
-#define PLLCTRL_RESET_SHIFT	0
-
-#define ZYNQ_CLK_MAXDIV		0x3f
-#define CLK_CTRL_DIV1_SHIFT	20
-#define CLK_CTRL_DIV1_MASK	(ZYNQ_CLK_MAXDIV << CLK_CTRL_DIV1_SHIFT)
-#define CLK_CTRL_DIV0_SHIFT	8
-#define CLK_CTRL_DIV0_MASK	(ZYNQ_CLK_MAXDIV << CLK_CTRL_DIV0_SHIFT)
-#define CLK_CTRL_SRCSEL_SHIFT	4
-#define CLK_CTRL_SRCSEL_MASK	(0x3 << CLK_CTRL_SRCSEL_SHIFT)
-
-#define CLK_CTRL_DIV2X_SHIFT	26
-#define CLK_CTRL_DIV2X_MASK	(ZYNQ_CLK_MAXDIV << CLK_CTRL_DIV2X_SHIFT)
-#define CLK_CTRL_DIV3X_SHIFT	20
-#define CLK_CTRL_DIV3X_MASK	(ZYNQ_CLK_MAXDIV << CLK_CTRL_DIV3X_SHIFT)
-
-#define ZYNQ_CLKMUX_SEL_0	0
-#define ZYNQ_CLKMUX_SEL_1	1
-#define ZYNQ_CLKMUX_SEL_2	2
-#define ZYNQ_CLKMUX_SEL_3	3
-
 DECLARE_GLOBAL_DATA_PTR;
 
-struct clk;
-
-/**
- * struct zynq_clk_ops:
- * @set_rate:	Function pointer to set_rate() implementation
- * @get_rate:	Function pointer to get_rate() implementation
- */
-struct zynq_clk_ops {
-	int (*set_rate)(struct clk *clk, unsigned long rate);
-	unsigned long (*get_rate)(struct clk *clk);
-};
-
-/**
- * struct clk:
- * @name:	Clock name
- * @frequency:	Currenct frequency
- * @parent:	Parent clock
- * @flags:	Clock flags
- * @reg:	Clock control register
- * @ops:	Clock operations
- */
-struct clk {
-	char		*name;
-	unsigned long	frequency;
-	enum zynq_clk	parent;
-	unsigned int	flags;
-	u32		*reg;
-	struct zynq_clk_ops	ops;
+static const char * const clk_names[clk_max] = {
+	"armpll", "ddrpll", "iopll",
+	"cpu_6or4x", "cpu_3or2x", "cpu_2x", "cpu_1x",
+	"ddr2x", "ddr3x", "dci",
+	"lqspi", "smc", "pcap", "gem0", "gem1",
+	"fclk0", "fclk1", "fclk2", "fclk3", "can0", "can1",
+	"sdio0", "sdio1", "uart0", "uart1", "spi0", "spi1", "dma",
+	"usb0_aper", "usb1_aper", "gem0_aper", "gem1_aper",
+	"sdio0_aper", "sdio1_aper", "spi0_aper", "spi1_aper",
+	"can0_aper", "can1_aper", "i2c0_aper", "i2c1_aper",
+	"uart0_aper", "uart1_aper", "gpio_aper", "lqspi_aper",
+	"smc_aper", "swdt", "dbg_trc", "dbg_apb"
 };
-#define ZYNQ_CLK_FLAGS_HAS_2_DIVS	1
-
-static struct clk clks[clk_max];
-
-/**
- * __zynq_clk_cpu_get_parent() - Decode clock multiplexer
- * @srcsel:	Mux select value
- * Returns the clock identifier associated with the selected mux input.
- */
-static int __zynq_clk_cpu_get_parent(unsigned int srcsel)
-{
-	unsigned int ret;
-
-	switch (srcsel) {
-	case ZYNQ_CLKMUX_SEL_0:
-	case ZYNQ_CLKMUX_SEL_1:
-		ret = armpll_clk;
-		break;
-	case ZYNQ_CLKMUX_SEL_2:
-		ret = ddrpll_clk;
-		break;
-	case ZYNQ_CLKMUX_SEL_3:
-		ret = iopll_clk;
-		break;
-	default:
-		ret = armpll_clk;
-		break;
-	}
-
-	return ret;
-}
-
-/**
- * ddr2x_get_rate() - Get clock rate of DDR2x clock
- * @clk:	Clock handle
- * Returns the current clock rate of @clk.
- */
-static unsigned long ddr2x_get_rate(struct clk *clk)
-{
-	u32 clk_ctrl = readl(clk->reg);
-	u32 div = (clk_ctrl & CLK_CTRL_DIV2X_MASK) >> CLK_CTRL_DIV2X_SHIFT;
-
-	return DIV_ROUND_CLOSEST(zynq_clk_get_rate(clk->parent), div);
-}
-
-/**
- * ddr3x_get_rate() - Get clock rate of DDR3x clock
- * @clk:	Clock handle
- * Returns the current clock rate of @clk.
- */
-static unsigned long ddr3x_get_rate(struct clk *clk)
-{
-	u32 clk_ctrl = readl(clk->reg);
-	u32 div = (clk_ctrl & CLK_CTRL_DIV3X_MASK) >> CLK_CTRL_DIV3X_SHIFT;
-
-	return DIV_ROUND_CLOSEST(zynq_clk_get_rate(clk->parent), div);
-}
-
-static void init_ddr_clocks(void)
-{
-	u32 div0, div1;
-	unsigned long prate = zynq_clk_get_rate(ddrpll_clk);
-	u32 clk_ctrl = readl(&slcr_base->ddr_clk_ctrl);
-
-	/* DDR2x */
-	clks[ddr2x_clk].reg = &slcr_base->ddr_clk_ctrl;
-	clks[ddr2x_clk].parent = ddrpll_clk;
-	clks[ddr2x_clk].name = "ddr_2x";
-	clks[ddr2x_clk].frequency = ddr2x_get_rate(&clks[ddr2x_clk]);
-	clks[ddr2x_clk].ops.get_rate = ddr2x_get_rate;
-
-	/* DDR3x */
-	clks[ddr3x_clk].reg = &slcr_base->ddr_clk_ctrl;
-	clks[ddr3x_clk].parent = ddrpll_clk;
-	clks[ddr3x_clk].name = "ddr_3x";
-	clks[ddr3x_clk].frequency = ddr3x_get_rate(&clks[ddr3x_clk]);
-	clks[ddr3x_clk].ops.get_rate = ddr3x_get_rate;
-
-	/* DCI */
-	clk_ctrl = readl(&slcr_base->dci_clk_ctrl);
-	div0 = (clk_ctrl & CLK_CTRL_DIV0_MASK) >> CLK_CTRL_DIV0_SHIFT;
-	div1 = (clk_ctrl & CLK_CTRL_DIV1_MASK) >> CLK_CTRL_DIV1_SHIFT;
-	clks[dci_clk].reg = &slcr_base->dci_clk_ctrl;
-	clks[dci_clk].parent = ddrpll_clk;
-	clks[dci_clk].frequency = DIV_ROUND_CLOSEST(
-			DIV_ROUND_CLOSEST(prate, div0), div1);
-	clks[dci_clk].name = "dci";
-
-	gd->bd->bi_ddr_freq = clks[ddr3x_clk].frequency / 1000000;
-}
-
-static void init_cpu_clocks(void)
-{
-	int clk_621;
-	u32 reg, div, srcsel;
-	enum zynq_clk parent;
-
-	reg = readl(&slcr_base->arm_clk_ctrl);
-	clk_621 = readl(&slcr_base->clk_621_true) & 1;
-	div = (reg & CLK_CTRL_DIV0_MASK) >> CLK_CTRL_DIV0_SHIFT;
-	srcsel = (reg & CLK_CTRL_SRCSEL_MASK) >> CLK_CTRL_SRCSEL_SHIFT;
-	parent = __zynq_clk_cpu_get_parent(srcsel);
-
-	/* cpu clocks */
-	clks[cpu_6or4x_clk].reg = &slcr_base->arm_clk_ctrl;
-	clks[cpu_6or4x_clk].parent = parent;
-	clks[cpu_6or4x_clk].frequency = DIV_ROUND_CLOSEST(
-			zynq_clk_get_rate(parent), div);
-	clks[cpu_6or4x_clk].name = "cpu_6or4x";
-
-	clks[cpu_3or2x_clk].reg = &slcr_base->arm_clk_ctrl;
-	clks[cpu_3or2x_clk].parent = cpu_6or4x_clk;
-	clks[cpu_3or2x_clk].frequency = zynq_clk_get_rate(cpu_6or4x_clk) / 2;
-	clks[cpu_3or2x_clk].name = "cpu_3or2x";
-
-	clks[cpu_2x_clk].reg = &slcr_base->arm_clk_ctrl;
-	clks[cpu_2x_clk].parent = cpu_6or4x_clk;
-	clks[cpu_2x_clk].frequency = zynq_clk_get_rate(cpu_6or4x_clk) /
-			(2 + clk_621);
-	clks[cpu_2x_clk].name = "cpu_2x";
-
-	clks[cpu_1x_clk].reg = &slcr_base->arm_clk_ctrl;
-	clks[cpu_1x_clk].parent = cpu_6or4x_clk;
-	clks[cpu_1x_clk].frequency = zynq_clk_get_rate(cpu_6or4x_clk) /
-			(4 + 2 * clk_621);
-	clks[cpu_1x_clk].name = "cpu_1x";
-}
 
 /**
- * periph_calc_two_divs() - Calculate clock dividers
- * @cur_rate:	Current clock rate
- * @tgt_rate:	Target clock rate
- * @prate:	Parent clock rate
- * @div0:	First divider (output)
- * @div1:	Second divider (output)
- * Returns the actual clock rate possible.
+ * set_cpu_clk_info() - Setup clock information
  *
- * Calculates clock dividers for clocks with two 6-bit dividers.
- */
-static unsigned long periph_calc_two_divs(unsigned long cur_rate,
-		unsigned long tgt_rate, unsigned long prate, u32 *div0,
-		u32 *div1)
-{
-	long err, best_err = (long)(~0UL >> 1);
-	unsigned long rate, best_rate = 0;
-	u32 d0, d1;
-
-	for (d0 = 1; d0 <= ZYNQ_CLK_MAXDIV; d0++) {
-		for (d1 = 1; d1 <= ZYNQ_CLK_MAXDIV >> 1; d1++) {
-			rate = DIV_ROUND_CLOSEST(DIV_ROUND_CLOSEST(prate, d0),
-					d1);
-			err = abs(rate - tgt_rate);
-
-			if (err < best_err) {
-				*div0 = d0;
-				*div1 = d1;
-				best_err = err;
-				best_rate = rate;
-			}
-		}
-	}
-
-	return best_rate;
-}
-
-/**
- * zynq_clk_periph_set_rate() - Set clock rate
- * @clk:	Handle of the peripheral clock
- * @rate:	New clock rate
- * Sets the clock frequency of @clk to @rate. Returns zero on success.
- */
-static int zynq_clk_periph_set_rate(struct clk *clk,
-		unsigned long rate)
-{
-	u32 ctrl, div0 = 0, div1 = 0;
-	unsigned long prate, new_rate, cur_rate = clk->frequency;
-
-	ctrl = readl(clk->reg);
-	prate = zynq_clk_get_rate(clk->parent);
-	ctrl &= ~CLK_CTRL_DIV0_MASK;
-
-	if (clk->flags & ZYNQ_CLK_FLAGS_HAS_2_DIVS) {
-		ctrl &= ~CLK_CTRL_DIV1_MASK;
-		new_rate = periph_calc_two_divs(cur_rate, rate, prate, &div0,
-				&div1);
-		ctrl |= div1 << CLK_CTRL_DIV1_SHIFT;
-	} else {
-		div0 = DIV_ROUND_CLOSEST(prate, rate);
-		div0 &= ZYNQ_CLK_MAXDIV;
-		new_rate = DIV_ROUND_CLOSEST(rate, div0);
-	}
-
-	/* write new divs to hardware */
-	ctrl |= div0 << CLK_CTRL_DIV0_SHIFT;
-	writel(ctrl, clk->reg);
-
-	/* update frequency in clk framework */
-	clk->frequency = new_rate;
-
-	return 0;
-}
-
-/**
- * zynq_clk_periph_get_rate() - Get clock rate
- * @clk:	Handle of the peripheral clock
- * Returns the current clock rate of @clk.
- */
-static unsigned long zynq_clk_periph_get_rate(struct clk *clk)
-{
-	u32 clk_ctrl = readl(clk->reg);
-	u32 div0 = (clk_ctrl & CLK_CTRL_DIV0_MASK) >> CLK_CTRL_DIV0_SHIFT;
-	u32 div1 = 1;
-
-	if (clk->flags & ZYNQ_CLK_FLAGS_HAS_2_DIVS)
-		div1 = (clk_ctrl & CLK_CTRL_DIV1_MASK) >> CLK_CTRL_DIV1_SHIFT;
-
-	/* a register value of zero == division by 1 */
-	if (!div0)
-		div0 = 1;
-	if (!div1)
-		div1 = 1;
-
-	return
-		DIV_ROUND_CLOSEST(
-			DIV_ROUND_CLOSEST(zynq_clk_get_rate(clk->parent), div0),
-			div1);
-}
-
-/**
- * __zynq_clk_periph_get_parent() - Decode clock multiplexer
- * @srcsel:	Mux select value
- * Returns the clock identifier associated with the selected mux input.
- */
-static enum zynq_clk __zynq_clk_periph_get_parent(u32 srcsel)
-{
-	switch (srcsel) {
-	case ZYNQ_CLKMUX_SEL_0:
-	case ZYNQ_CLKMUX_SEL_1:
-		return iopll_clk;
-	case ZYNQ_CLKMUX_SEL_2:
-		return armpll_clk;
-	case ZYNQ_CLKMUX_SEL_3:
-		return ddrpll_clk;
-	default:
-		return 0;
-	}
-}
-
-/**
- * zynq_clk_periph_get_parent() - Decode clock multiplexer
- * @clk:	Clock handle
- * Returns the clock identifier associated with the selected mux input.
- */
-static enum zynq_clk zynq_clk_periph_get_parent(struct clk *clk)
-{
-	u32 clk_ctrl = readl(clk->reg);
-	u32 srcsel = (clk_ctrl & CLK_CTRL_SRCSEL_MASK) >> CLK_CTRL_SRCSEL_SHIFT;
-
-	return __zynq_clk_periph_get_parent(srcsel);
-}
-
-/**
- * zynq_clk_register_periph_clk() - Set up a peripheral clock with the framework
- * @clk:	Pointer to struct clk for the clock
- * @ctrl:	Clock control register
- * @name:	PLL name
- * @two_divs:	Indicates whether the clock features one or two dividers
- */
-static int zynq_clk_register_periph_clk(struct clk *clk, u32 *ctrl, char *name,
-		bool two_divs)
-{
-	clk->name = name;
-	clk->reg = ctrl;
-	if (two_divs)
-		clk->flags = ZYNQ_CLK_FLAGS_HAS_2_DIVS;
-	clk->parent = zynq_clk_periph_get_parent(clk);
-	clk->frequency = zynq_clk_periph_get_rate(clk);
-	clk->ops.get_rate = zynq_clk_periph_get_rate;
-	clk->ops.set_rate = zynq_clk_periph_set_rate;
-
-	return 0;
-}
-
-static void init_periph_clocks(void)
-{
-	zynq_clk_register_periph_clk(&clks[gem0_clk], &slcr_base->gem0_clk_ctrl,
-				     "gem0", 1);
-	zynq_clk_register_periph_clk(&clks[gem1_clk], &slcr_base->gem1_clk_ctrl,
-				     "gem1", 1);
-
-	zynq_clk_register_periph_clk(&clks[smc_clk], &slcr_base->smc_clk_ctrl,
-				     "smc", 0);
-
-	zynq_clk_register_periph_clk(&clks[lqspi_clk],
-				     &slcr_base->lqspi_clk_ctrl, "lqspi", 0);
-
-	zynq_clk_register_periph_clk(&clks[sdio0_clk],
-				     &slcr_base->sdio_clk_ctrl, "sdio0", 0);
-	zynq_clk_register_periph_clk(&clks[sdio1_clk],
-				     &slcr_base->sdio_clk_ctrl, "sdio1", 0);
-
-	zynq_clk_register_periph_clk(&clks[spi0_clk], &slcr_base->spi_clk_ctrl,
-				     "spi0", 0);
-	zynq_clk_register_periph_clk(&clks[spi1_clk], &slcr_base->spi_clk_ctrl,
-				     "spi1", 0);
-
-	zynq_clk_register_periph_clk(&clks[uart0_clk],
-				     &slcr_base->uart_clk_ctrl, "uart0", 0);
-	zynq_clk_register_periph_clk(&clks[uart1_clk],
-				     &slcr_base->uart_clk_ctrl, "uart1", 0);
-
-	zynq_clk_register_periph_clk(&clks[dbg_trc_clk],
-				     &slcr_base->dbg_clk_ctrl, "dbg_trc", 0);
-	zynq_clk_register_periph_clk(&clks[dbg_apb_clk],
-				     &slcr_base->dbg_clk_ctrl, "dbg_apb", 0);
-
-	zynq_clk_register_periph_clk(&clks[pcap_clk],
-				     &slcr_base->pcap_clk_ctrl, "pcap", 0);
-
-	zynq_clk_register_periph_clk(&clks[fclk0_clk],
-				     &slcr_base->fpga0_clk_ctrl, "fclk0", 1);
-	zynq_clk_register_periph_clk(&clks[fclk1_clk],
-				     &slcr_base->fpga1_clk_ctrl, "fclk1", 1);
-	zynq_clk_register_periph_clk(&clks[fclk2_clk],
-				     &slcr_base->fpga2_clk_ctrl, "fclk2", 1);
-	zynq_clk_register_periph_clk(&clks[fclk3_clk],
-				     &slcr_base->fpga3_clk_ctrl, "fclk3", 1);
-}
-
-/**
- * zynq_clk_register_aper_clk() - Set up a APER clock with the framework
- * @clk:	Pointer to struct clk for the clock
- * @ctrl:	Clock control register
- * @name:	PLL name
- */
-static void zynq_clk_register_aper_clk(struct clk *clk, u32 *ctrl, char *name)
-{
-	clk->name = name;
-	clk->reg = ctrl;
-	clk->parent = cpu_1x_clk;
-	clk->frequency = zynq_clk_get_rate(clk->parent);
-}
-
-static void init_aper_clocks(void)
-{
-	zynq_clk_register_aper_clk(&clks[usb0_aper_clk],
-				   &slcr_base->aper_clk_ctrl, "usb0_aper");
-	zynq_clk_register_aper_clk(&clks[usb1_aper_clk],
-				   &slcr_base->aper_clk_ctrl, "usb1_aper");
-
-	zynq_clk_register_aper_clk(&clks[gem0_aper_clk],
-				   &slcr_base->aper_clk_ctrl, "gem0_aper");
-	zynq_clk_register_aper_clk(&clks[gem1_aper_clk],
-				   &slcr_base->aper_clk_ctrl, "gem1_aper");
-
-	zynq_clk_register_aper_clk(&clks[sdio0_aper_clk],
-				   &slcr_base->aper_clk_ctrl, "sdio0_aper");
-	zynq_clk_register_aper_clk(&clks[sdio1_aper_clk],
-				   &slcr_base->aper_clk_ctrl, "sdio1_aper");
-
-	zynq_clk_register_aper_clk(&clks[spi0_aper_clk],
-				   &slcr_base->aper_clk_ctrl, "spi0_aper");
-	zynq_clk_register_aper_clk(&clks[spi1_aper_clk],
-				   &slcr_base->aper_clk_ctrl, "spi1_aper");
-
-	zynq_clk_register_aper_clk(&clks[can0_aper_clk],
-				   &slcr_base->aper_clk_ctrl, "can0_aper");
-	zynq_clk_register_aper_clk(&clks[can1_aper_clk],
-				   &slcr_base->aper_clk_ctrl, "can1_aper");
-
-	zynq_clk_register_aper_clk(&clks[i2c0_aper_clk],
-				   &slcr_base->aper_clk_ctrl, "i2c0_aper");
-	zynq_clk_register_aper_clk(&clks[i2c1_aper_clk],
-				   &slcr_base->aper_clk_ctrl, "i2c1_aper");
-
-	zynq_clk_register_aper_clk(&clks[uart0_aper_clk],
-				   &slcr_base->aper_clk_ctrl, "uart0_aper");
-	zynq_clk_register_aper_clk(&clks[uart1_aper_clk],
-				   &slcr_base->aper_clk_ctrl, "uart1_aper");
-
-	zynq_clk_register_aper_clk(&clks[gpio_aper_clk],
-				   &slcr_base->aper_clk_ctrl, "gpio_aper");
-
-	zynq_clk_register_aper_clk(&clks[lqspi_aper_clk],
-				   &slcr_base->aper_clk_ctrl, "lqspi_aper");
-
-	zynq_clk_register_aper_clk(&clks[smc_aper_clk],
-				   &slcr_base->aper_clk_ctrl, "smc_aper");
-}
-
-/**
- * __zynq_clk_pll_get_rate() - Get PLL rate
- * @addr:	Address of the PLL's control register
- * Returns the current PLL output rate.
+ * This function is called from common code after relocation and sets up the
+ * clock information.
  */
-static unsigned long __zynq_clk_pll_get_rate(u32 *addr)
+int set_cpu_clk_info(void)
 {
-	u32 reg, mul, bypass;
-
-	reg = readl(addr);
-	bypass = reg & PLLCTRL_BPFORCE_MASK;
-	if (bypass)
-		mul = 1;
-	else
-		mul = (reg & PLLCTRL_FBDIV_MASK) >> PLLCTRL_FBDIV_SHIFT;
+	struct clk clk;
+	struct udevice *dev;
+	ulong rate;
+	int i, ret;
 
-	return CONFIG_ZYNQ_PS_CLK_FREQ * mul;
-}
+	ret = uclass_get_device_by_driver(UCLASS_CLK,
+		DM_GET_DRIVER(zynq_clk), &dev);
+	if (ret)
+		return ret;
 
-/**
- * zynq_clk_pll_get_rate() - Get PLL rate
- * @pll:	Handle of the PLL
- * Returns the current clock rate of @pll.
- */
-static unsigned long zynq_clk_pll_get_rate(struct clk *pll)
-{
-	return __zynq_clk_pll_get_rate(pll->reg);
-}
+	for (i = 0; i < 2; i++) {
+		clk.id = i ? ddr3x_clk : cpu_6or4x_clk;
+		ret = clk_request(dev, &clk);
+		if (ret < 0)
+			return ret;
 
-/**
- * zynq_clk_register_pll() - Set up a PLL with the framework
- * @clk:	Pointer to struct clk for the PLL
- * @ctrl:	PLL control register
- * @name:	PLL name
- * @prate:	PLL input clock rate
- */
-static void zynq_clk_register_pll(struct clk *clk, u32 *ctrl, char *name,
-		unsigned long prate)
-{
-	clk->name = name;
-	clk->reg = ctrl;
-	clk->frequency = zynq_clk_pll_get_rate(clk);
-	clk->ops.get_rate = zynq_clk_pll_get_rate;
-}
+		rate = clk_get_rate(&clk) / 1000000;
+		if (i)
+			gd->bd->bi_ddr_freq = rate;
+		else
+			gd->bd->bi_arm_freq = rate;
 
-/**
- * clkid_2_register() - Get clock control register
- * @id:	Clock identifier of one of the PLLs
- * Returns the address of the requested PLL's control register.
- */
-static u32 *clkid_2_register(enum zynq_clk id)
-{
-	switch (id) {
-	case armpll_clk:
-		return &slcr_base->arm_pll_ctrl;
-	case ddrpll_clk:
-		return &slcr_base->ddr_pll_ctrl;
-	case iopll_clk:
-		return &slcr_base->io_pll_ctrl;
-	default:
-		return &slcr_base->io_pll_ctrl;
+		clk_free(&clk);
 	}
-}
-
-/* API */
-/**
- * zynq_clk_early_init() - Early init for the clock framework
- *
- * This function is called from before relocation and sets up the CPU clock
- * frequency in the global data struct.
- */
-void zynq_clk_early_init(void)
-{
-	u32 reg = readl(&slcr_base->arm_clk_ctrl);
-	u32 div = (reg & CLK_CTRL_DIV0_MASK) >> CLK_CTRL_DIV0_SHIFT;
-	u32 srcsel = (reg & CLK_CTRL_SRCSEL_MASK) >> CLK_CTRL_SRCSEL_SHIFT;
-	enum zynq_clk parent = __zynq_clk_cpu_get_parent(srcsel);
-	u32 *pllreg = clkid_2_register(parent);
-	unsigned long prate = __zynq_clk_pll_get_rate(pllreg);
-
-	if (!div)
-		div = 1;
-
-	gd->cpu_clk = DIV_ROUND_CLOSEST(prate, div);
-}
-
-/**
- * get_uart_clk() - Get UART input frequency
- * @dev_index:	UART ID
- * Returns UART input clock frequency in Hz.
- *
- * Compared to zynq_clk_get_rate() this function is designed to work before
- * relocation and can be called when the serial UART is set up.
- */
-unsigned long get_uart_clk(int dev_index)
-{
-	u32 reg = readl(&slcr_base->uart_clk_ctrl);
-	u32 div = (reg & CLK_CTRL_DIV0_MASK) >> CLK_CTRL_DIV0_SHIFT;
-	u32 srcsel = (reg & CLK_CTRL_SRCSEL_MASK) >> CLK_CTRL_SRCSEL_SHIFT;
-	enum zynq_clk parent = __zynq_clk_periph_get_parent(srcsel);
-	u32 *pllreg = clkid_2_register(parent);
-	unsigned long prate = __zynq_clk_pll_get_rate(pllreg);
-
-	if (!div)
-		div = 1;
-
-	return DIV_ROUND_CLOSEST(prate, div);
-}
-
-/**
- * set_cpu_clk_info() - Initialize clock framework
- * Always returns zero.
- *
- * This function is called from common code after relocation and sets up the
- * clock framework. The framework must not be used before this function had been
- * called.
- */
-int set_cpu_clk_info(void)
-{
-	zynq_clk_register_pll(&clks[armpll_clk], &slcr_base->arm_pll_ctrl,
-			      "armpll", CONFIG_ZYNQ_PS_CLK_FREQ);
-	zynq_clk_register_pll(&clks[ddrpll_clk], &slcr_base->ddr_pll_ctrl,
-			      "ddrpll", CONFIG_ZYNQ_PS_CLK_FREQ);
-	zynq_clk_register_pll(&clks[iopll_clk], &slcr_base->io_pll_ctrl,
-			      "iopll", CONFIG_ZYNQ_PS_CLK_FREQ);
-
-	init_ddr_clocks();
-	init_cpu_clocks();
-	init_periph_clocks();
-	init_aper_clocks();
-
-	gd->bd->bi_arm_freq = gd->cpu_clk / 1000000;
 	gd->bd->bi_dsp_freq = 0;
 
 	return 0;
 }
 
 /**
- * zynq_clk_get_rate() - Get clock rate
- * @clk:	Clock identifier
- * Returns the current clock rate of @clk on success or zero for an invalid
- * clock id.
- */
-unsigned long zynq_clk_get_rate(enum zynq_clk clk)
-{
-	if (clk < 0 || clk >= clk_max)
-		return 0;
-
-	return clks[clk].frequency;
-}
-
-/**
- * zynq_clk_set_rate() - Set clock rate
- * @clk:	Clock identifier
- * @rate:	Requested clock rate
- * Passes on the return value from the clock's set_rate() function or negative
- * errno.
- */
-int zynq_clk_set_rate(enum zynq_clk clk, unsigned long rate)
-{
-	if (clk < 0 || clk >= clk_max)
-		return -ENODEV;
-
-	if (clks[clk].ops.set_rate)
-		return clks[clk].ops.set_rate(&clks[clk], rate);
-
-	return -ENXIO;
-}
-
-/**
- * zynq_clk_get_name() - Get clock name
- * @clk:	Clock identifier
- * Returns the name of @clk.
- */
-const char *zynq_clk_get_name(enum zynq_clk clk)
-{
-	return clks[clk].name;
-}
-
-/**
  * soc_clk_dump() - Print clock frequencies
  * Returns zero on success
  *
@@ -650,13 +70,35 @@
  */
 int soc_clk_dump(void)
 {
-	int i;
+	struct udevice *dev;
+	int i, ret;
+
+	ret = uclass_get_device_by_driver(UCLASS_CLK,
+		DM_GET_DRIVER(zynq_clk), &dev);
+	if (ret)
+		return ret;
 
 	printf("clk\t\tfrequency\n");
 	for (i = 0; i < clk_max; i++) {
-		const char *name = zynq_clk_get_name(i);
-		if (name)
-			printf("%10s%20lu\n", name, zynq_clk_get_rate(i));
+		const char *name = clk_names[i];
+		if (name) {
+			struct clk clk;
+			unsigned long rate;
+
+			clk.id = i;
+			ret = clk_request(dev, &clk);
+			if (ret < 0)
+				return ret;
+
+			rate = clk_get_rate(&clk);
+
+			clk_free(&clk);
+
+			if (rate == (unsigned long)-ENOSYS)
+				printf("%10s%20s\n", name, "unknown");
+			else
+				printf("%10s%20lu\n", name, rate);
+		}
 	}
 
 	return 0;
diff --git a/arch/arm/mach-zynq/cpu.c b/arch/arm/mach-zynq/cpu.c
index ba9171e..ee1c1a9 100644
--- a/arch/arm/mach-zynq/cpu.c
+++ b/arch/arm/mach-zynq/cpu.c
@@ -35,7 +35,6 @@
 	writel(0xC, &slcr_base->ddr_urgent);
 #endif
 #endif
-	zynq_clk_early_init();
 	zynq_slcr_lock();
 
 	return 0;
diff --git a/arch/arm/mach-zynq/include/mach/clk.h b/arch/arm/mach-zynq/include/mach/clk.h
index 250c5bc..8a039ae 100644
--- a/arch/arm/mach-zynq/include/mach/clk.h
+++ b/arch/arm/mach-zynq/include/mach/clk.h
@@ -20,10 +20,4 @@
 	uart0_aper_clk, uart1_aper_clk, gpio_aper_clk, lqspi_aper_clk,
 	smc_aper_clk, swdt_clk, dbg_trc_clk, dbg_apb_clk, clk_max};
 
-void zynq_clk_early_init(void);
-int zynq_clk_set_rate(enum zynq_clk clk, unsigned long rate);
-unsigned long zynq_clk_get_rate(enum zynq_clk clk);
-const char *zynq_clk_get_name(enum zynq_clk clk);
-unsigned long get_uart_clk(int dev_id);
-
 #endif
diff --git a/arch/arm/mach-zynq/include/mach/sys_proto.h b/arch/arm/mach-zynq/include/mach/sys_proto.h
index 44c9b50..67238e7 100644
--- a/arch/arm/mach-zynq/include/mach/sys_proto.h
+++ b/arch/arm/mach-zynq/include/mach/sys_proto.h
@@ -10,7 +10,6 @@
 extern void zynq_slcr_lock(void);
 extern void zynq_slcr_unlock(void);
 extern void zynq_slcr_cpu_reset(void);
-extern void zynq_slcr_gem_clk_setup(u32 gem_id, unsigned long clk_rate);
 extern void zynq_slcr_devcfg_disable(void);
 extern void zynq_slcr_devcfg_enable(void);
 extern u32 zynq_slcr_get_boot_mode(void);
diff --git a/arch/arm/mach-zynq/slcr.c b/arch/arm/mach-zynq/slcr.c
index 2d3bf2a..2a207ae 100644
--- a/arch/arm/mach-zynq/slcr.c
+++ b/arch/arm/mach-zynq/slcr.c
@@ -9,7 +9,6 @@
 #include <malloc.h>
 #include <asm/arch/hardware.h>
 #include <asm/arch/sys_proto.h>
-#include <asm/arch/clk.h>
 
 #define SLCR_LOCK_MAGIC		0x767B
 #define SLCR_UNLOCK_MAGIC	0xDF0D
@@ -124,34 +123,6 @@
 	writel(1, &slcr_base->pss_rst_ctrl);
 }
 
-/* Setup clk for network */
-void zynq_slcr_gem_clk_setup(u32 gem_id, unsigned long clk_rate)
-{
-	int ret;
-
-	zynq_slcr_unlock();
-
-	if (gem_id > 1) {
-		printf("Non existing GEM id %d\n", gem_id);
-		goto out;
-	}
-
-	ret = zynq_clk_set_rate(gem0_clk + gem_id, clk_rate);
-	if (ret)
-		goto out;
-
-	if (gem_id) {
-		/* Configure GEM_RCLK_CTRL */
-		writel(1, &slcr_base->gem1_rclk_ctrl);
-	} else {
-		/* Configure GEM_RCLK_CTRL */
-		writel(1, &slcr_base->gem0_rclk_ctrl);
-	}
-	udelay(100000);
-out:
-	zynq_slcr_lock();
-}
-
 void zynq_slcr_devcfg_disable(void)
 {
 	u32 reg_val;
diff --git a/arch/arm/mach-zynq/timer.c b/arch/arm/mach-zynq/timer.c
index 8ff82dc..b1bb3b8 100644
--- a/arch/arm/mach-zynq/timer.c
+++ b/arch/arm/mach-zynq/timer.c
@@ -1,4 +1,7 @@
 /*
+ * Copyright (C) 2017 Weidmüller Interface GmbH & Co. KG
+ * Stefan Herbrechtsmeier <stefan.herbrechtsmeier@weidmueller.com>
+ *
  * Copyright (C) 2012 Michal Simek <monstr@monstr.eu>
  * Copyright (C) 2011-2012 Xilinx, Inc. All rights reserved.
  *
@@ -25,8 +28,10 @@
  * SPDX-License-Identifier:	GPL-2.0+
  */
 
+#include <clk.h>
 #include <common.h>
 #include <div64.h>
+#include <dm.h>
 #include <asm/io.h>
 #include <asm/arch/hardware.h>
 #include <asm/arch/clk.h>
@@ -56,6 +61,24 @@
 			(TIMER_PRESCALE << SCUTIMER_CONTROL_PRESCALER_SHIFT) |
 			SCUTIMER_CONTROL_ENABLE_MASK;
 
+	struct udevice *dev;
+	struct clk clk;
+	int ret;
+
+	ret = uclass_get_device_by_driver(UCLASS_CLK,
+		DM_GET_DRIVER(zynq_clk), &dev);
+	if (ret)
+		return ret;
+
+	clk.id = cpu_6or4x_clk;
+	ret = clk_request(dev, &clk);
+	if (ret < 0)
+		return ret;
+
+	gd->cpu_clk = clk_get_rate(&clk);
+
+	clk_free(&clk);
+
 	gd->arch.timer_rate_hz = (gd->cpu_clk / 2) / (TIMER_PRESCALE + 1);
 
 	/* Load the timer counter register */
diff --git a/board/freescale/common/vid.c b/board/freescale/common/vid.c
index 1a50304..9b65c13 100644
--- a/board/freescale/common/vid.c
+++ b/board/freescale/common/vid.c
@@ -284,10 +284,170 @@
 	return vdd_last;
 }
 
+#ifdef CONFIG_FSL_LSCH3
+int adjust_vdd(ulong vdd_override)
+{
+	int re_enable = disable_interrupts();
+	struct ccsr_gur *gur = (void *)(CONFIG_SYS_FSL_GUTS_ADDR);
+	u32 fusesr;
+	u8 vid, buf;
+	int vdd_target, vdd_current, vdd_last;
+	int ret, i2caddress;
+	unsigned long vdd_string_override;
+	char *vdd_string;
+	static const uint16_t vdd[32] = {
+		10500,
+		0,      /* reserved */
+		9750,
+		0,      /* reserved */
+		9500,
+		0,      /* reserved */
+		0,      /* reserved */
+		0,      /* reserved */
+		0,      /* reserved */
+		0,      /* reserved */
+		0,      /* reserved */
+		0,      /* reserved */
+		0,      /* reserved */
+		0,      /* reserved */
+		0,      /* reserved */
+		0,      /* reserved */
+		10000,  /* 1.0000V */
+		0,      /* reserved */
+		10250,
+		0,      /* reserved */
+		10500,
+		0,      /* reserved */
+		0,      /* reserved */
+		0,      /* reserved */
+		0,      /* reserved */
+		0,      /* reserved */
+		0,      /* reserved */
+		0,      /* reserved */
+		0,      /* reserved */
+		0,      /* reserved */
+		0,      /* reserved */
+		0,      /* reserved */
+	};
+	struct vdd_drive {
+		u8 vid;
+		unsigned voltage;
+	};
+
+	ret = i2c_multiplexer_select_vid_channel(I2C_MUX_CH_VOL_MONITOR);
+	if (ret) {
+		debug("VID: I2C failed to switch channel\n");
+		ret = -1;
+		goto exit;
+	}
+	ret = find_ir_chip_on_i2c();
+	if (ret < 0) {
+		printf("VID: Could not find voltage regulator on I2C.\n");
+		ret = -1;
+		goto exit;
+	} else {
+		i2caddress = ret;
+		debug("VID: IR Chip found on I2C address 0x%02x\n", i2caddress);
+	}
+
+	/* check IR chip work on Intel mode*/
+	ret = i2c_read(i2caddress,
+		       IR36021_INTEL_MODE_OOFSET,
+		       1, (void *)&buf, 1);
+	if (ret) {
+		printf("VID: failed to read IR chip mode.\n");
+		ret = -1;
+		goto exit;
+	}
+	if ((buf & IR36021_MODE_MASK) != IR36021_INTEL_MODE) {
+		printf("VID: IR Chip is not used in Intel mode.\n");
+		ret = -1;
+		goto exit;
+	}
+
+	/* get the voltage ID from fuse status register */
+	fusesr = in_le32(&gur->dcfg_fusesr);
+	vid = (fusesr >> FSL_CHASSIS3_DCFG_FUSESR_ALTVID_SHIFT) &
+		FSL_CHASSIS3_DCFG_FUSESR_ALTVID_MASK;
+	if ((vid == 0) || (vid == FSL_CHASSIS3_DCFG_FUSESR_ALTVID_MASK)) {
+		vid = (fusesr >> FSL_CHASSIS3_DCFG_FUSESR_VID_SHIFT) &
+			FSL_CHASSIS3_DCFG_FUSESR_VID_MASK;
+	}
+	vdd_target = vdd[vid];
+
+	/* check override variable for overriding VDD */
+	vdd_string = getenv(CONFIG_VID_FLS_ENV);
+	if (vdd_override == 0 && vdd_string &&
+	    !strict_strtoul(vdd_string, 10, &vdd_string_override))
+		vdd_override = vdd_string_override;
+
+	if (vdd_override >= VDD_MV_MIN && vdd_override <= VDD_MV_MAX) {
+		vdd_target = vdd_override * 10; /* convert to 1/10 mV */
+		debug("VDD override is %lu\n", vdd_override);
+	} else if (vdd_override != 0) {
+		printf("Invalid value.\n");
+	}
+
+	/* divide and round up by 10 to get a value in mV */
+	vdd_target = DIV_ROUND_UP(vdd_target, 10);
+	if (vdd_target == 0) {
+		debug("VID: VID not used\n");
+		ret = 0;
+		goto exit;
+	} else if (vdd_target < VDD_MV_MIN || vdd_target > VDD_MV_MAX) {
+		/* Check vdd_target is in valid range */
+		printf("VID: Target VID %d mV is not in range.\n",
+		       vdd_target);
+		ret = -1;
+		goto exit;
+	} else {
+		debug("VID: vid = %d mV\n", vdd_target);
+	}
+
+	/*
+	 * Read voltage monitor to check real voltage.
+	 */
+	vdd_last = read_voltage(i2caddress);
+	if (vdd_last < 0) {
+		printf("VID: Couldn't read sensor abort VID adjustment\n");
+		ret = -1;
+		goto exit;
+	}
+	vdd_current = vdd_last;
+	debug("VID: Core voltage is currently at %d mV\n", vdd_last);
+	/*
+	  * Adjust voltage to at or one step above target.
+	  * As measurements are less precise than setting the values
+	  * we may run through dummy steps that cancel each other
+	  * when stepping up and then down.
+	  */
+	while (vdd_last > 0 &&
+	       vdd_last < vdd_target) {
+		vdd_current += IR_VDD_STEP_UP;
+		vdd_last = set_voltage(i2caddress, vdd_current);
+	}
+	while (vdd_last > 0 &&
+	       vdd_last > vdd_target + (IR_VDD_STEP_DOWN - 1)) {
+		vdd_current -= IR_VDD_STEP_DOWN;
+		vdd_last = set_voltage(i2caddress, vdd_current);
+	}
+
+	if (vdd_last > 0)
+		printf("VID: Core voltage after adjustment is at %d mV\n",
+		       vdd_last);
+	else
+		ret = -1;
+exit:
+	if (re_enable)
+		enable_interrupts();
+	i2c_multiplexer_select_vid_channel(I2C_MUX_CH_DEFAULT);
+	return ret;
+}
+#else /* !CONFIG_FSL_LSCH3 */
 int adjust_vdd(ulong vdd_override)
 {
 	int re_enable = disable_interrupts();
-#if defined(CONFIG_FSL_LSCH2) || defined(CONFIG_FSL_LSCH3)
+#if defined(CONFIG_FSL_LSCH2)
 	struct ccsr_gur *gur = (void *)(CONFIG_SYS_FSL_GUTS_ADDR);
 #else
 	ccsr_gur_t __iomem *gur =
@@ -364,11 +524,7 @@
 	}
 
 	/* get the voltage ID from fuse status register */
-#ifdef CONFIG_FSL_LSCH3
-	fusesr = in_le32(&gur->dcfg_fusesr);
-#else
 	fusesr = in_be32(&gur->dcfg_fusesr);
-#endif
 	/*
 	 * VID is used according to the table below
 	 *                ---------------------------------------
@@ -393,13 +549,6 @@
 		vid = (fusesr >> FSL_CHASSIS2_DCFG_FUSESR_VID_SHIFT) &
 			FSL_CHASSIS2_DCFG_FUSESR_VID_MASK;
 	}
-#elif defined(CONFIG_FSL_LSCH3)
-	vid = (fusesr >> FSL_CHASSIS3_DCFG_FUSESR_ALTVID_SHIFT) &
-		FSL_CHASSIS3_DCFG_FUSESR_ALTVID_MASK;
-	if ((vid == 0) || (vid == FSL_CHASSIS3_DCFG_FUSESR_ALTVID_MASK)) {
-		vid = (fusesr >> FSL_CHASSIS3_DCFG_FUSESR_VID_SHIFT) &
-			FSL_CHASSIS3_DCFG_FUSESR_VID_MASK;
-	}
 #else
 	vid = (fusesr >> FSL_CORENET_DCFG_FUSESR_ALTVID_SHIFT) &
 		FSL_CORENET_DCFG_FUSESR_ALTVID_MASK;
@@ -472,6 +621,7 @@
 
 	return ret;
 }
+#endif
 
 static int print_vdd(void)
 {
diff --git a/board/freescale/ls1012afrdm/ls1012afrdm.c b/board/freescale/ls1012afrdm/ls1012afrdm.c
index 789cae2..25d22d2 100644
--- a/board/freescale/ls1012afrdm/ls1012afrdm.c
+++ b/board/freescale/ls1012afrdm/ls1012afrdm.c
@@ -12,6 +12,7 @@
 #ifdef CONFIG_FSL_LS_PPA
 #include <asm/arch/ppa.h>
 #endif
+#include <asm/arch/mmu.h>
 #include <asm/arch/soc.h>
 #include <hwconfig.h>
 #include <environment.h>
@@ -48,6 +49,10 @@
 	mmdc_init(&mparam);
 
 	gd->ram_size = CONFIG_SYS_SDRAM_SIZE;
+#if !defined(CONFIG_SPL) || defined(CONFIG_SPL_BUILD)
+	/* This will break-before-make MMU for DDR */
+	update_early_mmu_table();
+#endif
 
 	return 0;
 }
@@ -91,32 +96,3 @@
 
 	return 0;
 }
-
-void dram_init_banksize(void)
-{
-	/*
-	 * gd->arch.secure_ram tracks the location of secure memory.
-	 * It was set as if the memory starts from 0.
-	 * The address needs to add the offset of its bank.
-	 */
-	gd->bd->bi_dram[0].start = CONFIG_SYS_SDRAM_BASE;
-	if (gd->ram_size > CONFIG_SYS_DDR_BLOCK1_SIZE) {
-		gd->bd->bi_dram[0].size = CONFIG_SYS_DDR_BLOCK1_SIZE;
-		gd->bd->bi_dram[1].start = CONFIG_SYS_DDR_BLOCK2_BASE;
-		gd->bd->bi_dram[1].size = gd->ram_size -
-			CONFIG_SYS_DDR_BLOCK1_SIZE;
-#ifdef CONFIG_SYS_MEM_RESERVE_SECURE
-		gd->arch.secure_ram = gd->bd->bi_dram[1].start +
-			gd->arch.secure_ram -
-			CONFIG_SYS_DDR_BLOCK1_SIZE;
-		gd->arch.secure_ram |= MEM_RESERVE_SECURE_MAINTAINED;
-#endif
-	} else {
-		gd->bd->bi_dram[0].size = gd->ram_size;
-#ifdef CONFIG_SYS_MEM_RESERVE_SECURE
-		gd->arch.secure_ram = gd->bd->bi_dram[0].start +
-			gd->arch.secure_ram;
-		gd->arch.secure_ram |= MEM_RESERVE_SECURE_MAINTAINED;
-#endif
-	}
-}
diff --git a/board/freescale/ls1012aqds/ls1012aqds.c b/board/freescale/ls1012aqds/ls1012aqds.c
index 4281790..97ab340 100644
--- a/board/freescale/ls1012aqds/ls1012aqds.c
+++ b/board/freescale/ls1012aqds/ls1012aqds.c
@@ -14,6 +14,7 @@
 #include <asm/arch/ppa.h>
 #endif
 #include <asm/arch/fdt.h>
+#include <asm/arch/mmu.h>
 #include <asm/arch/soc.h>
 #include <ahci.h>
 #include <hwconfig.h>
@@ -76,6 +77,10 @@
 	mmdc_init(&mparam);
 
 	gd->ram_size = CONFIG_SYS_SDRAM_SIZE;
+#if !defined(CONFIG_SPL) || defined(CONFIG_SPL_BUILD)
+	/* This will break-before-make MMU for DDR */
+	update_early_mmu_table();
+#endif
 
 	return 0;
 }
@@ -166,32 +171,3 @@
 	return 0;
 }
 #endif
-
-void dram_init_banksize(void)
-{
-	/*
-	 * gd->arch.secure_ram tracks the location of secure memory.
-	 * It was set as if the memory starts from 0.
-	 * The address needs to add the offset of its bank.
-	 */
-	gd->bd->bi_dram[0].start = CONFIG_SYS_SDRAM_BASE;
-	if (gd->ram_size > CONFIG_SYS_DDR_BLOCK1_SIZE) {
-		gd->bd->bi_dram[0].size = CONFIG_SYS_DDR_BLOCK1_SIZE;
-		gd->bd->bi_dram[1].start = CONFIG_SYS_DDR_BLOCK2_BASE;
-		gd->bd->bi_dram[1].size = gd->ram_size -
-			CONFIG_SYS_DDR_BLOCK1_SIZE;
-#ifdef CONFIG_SYS_MEM_RESERVE_SECURE
-		gd->arch.secure_ram = gd->bd->bi_dram[1].start +
-			gd->arch.secure_ram -
-			CONFIG_SYS_DDR_BLOCK1_SIZE;
-		gd->arch.secure_ram |= MEM_RESERVE_SECURE_MAINTAINED;
-#endif
-	} else {
-		gd->bd->bi_dram[0].size = gd->ram_size;
-#ifdef CONFIG_SYS_MEM_RESERVE_SECURE
-		gd->arch.secure_ram = gd->bd->bi_dram[0].start +
-			gd->arch.secure_ram;
-		gd->arch.secure_ram |= MEM_RESERVE_SECURE_MAINTAINED;
-#endif
-	}
-}
diff --git a/board/freescale/ls1012ardb/ls1012ardb.c b/board/freescale/ls1012ardb/ls1012ardb.c
index e3a8a76..a23a23b 100644
--- a/board/freescale/ls1012ardb/ls1012ardb.c
+++ b/board/freescale/ls1012ardb/ls1012ardb.c
@@ -12,6 +12,7 @@
 #ifdef CONFIG_FSL_LS_PPA
 #include <asm/arch/ppa.h>
 #endif
+#include <asm/arch/mmu.h>
 #include <asm/arch/soc.h>
 #include <hwconfig.h>
 #include <ahci.h>
@@ -80,6 +81,10 @@
 	mmdc_init(&mparam);
 
 	gd->ram_size = CONFIG_SYS_SDRAM_SIZE;
+#if !defined(CONFIG_SPL) || defined(CONFIG_SPL_BUILD)
+	/* This will break-before-make MMU for DDR */
+	update_early_mmu_table();
+#endif
 
 	return 0;
 }
@@ -165,32 +170,3 @@
 
 	return 0;
 }
-
-void dram_init_banksize(void)
-{
-	/*
-	 * gd->secure_ram tracks the location of secure memory.
-	 * It was set as if the memory starts from 0.
-	 * The address needs to add the offset of its bank.
-	 */
-	gd->bd->bi_dram[0].start = CONFIG_SYS_SDRAM_BASE;
-	if (gd->ram_size > CONFIG_SYS_DDR_BLOCK1_SIZE) {
-		gd->bd->bi_dram[0].size = CONFIG_SYS_DDR_BLOCK1_SIZE;
-		gd->bd->bi_dram[1].start = CONFIG_SYS_DDR_BLOCK2_BASE;
-		gd->bd->bi_dram[1].size = gd->ram_size -
-			CONFIG_SYS_DDR_BLOCK1_SIZE;
-#ifdef CONFIG_SYS_MEM_RESERVE_SECURE
-		gd->arch.secure_ram = gd->bd->bi_dram[1].start +
-			gd->arch.secure_ram -
-			CONFIG_SYS_DDR_BLOCK1_SIZE;
-		gd->arch.secure_ram |= MEM_RESERVE_SECURE_MAINTAINED;
-#endif
-	} else {
-		gd->bd->bi_dram[0].size = gd->ram_size;
-#ifdef CONFIG_SYS_MEM_RESERVE_SECURE
-		gd->arch.secure_ram = gd->bd->bi_dram[0].start +
-			gd->arch.secure_ram;
-		gd->arch.secure_ram |= MEM_RESERVE_SECURE_MAINTAINED;
-#endif
-	}
-}
diff --git a/board/freescale/ls1043aqds/ddr.c b/board/freescale/ls1043aqds/ddr.c
index 7882a9a..c740062 100644
--- a/board/freescale/ls1043aqds/ddr.c
+++ b/board/freescale/ls1043aqds/ddr.c
@@ -127,32 +127,3 @@
 
 	return dram_size;
 }
-
-void dram_init_banksize(void)
-{
-	/*
-	 * gd->arch.secure_ram tracks the location of secure memory.
-	 * It was set as if the memory starts from 0.
-	 * The address needs to add the offset of its bank.
-	 */
-	gd->bd->bi_dram[0].start = CONFIG_SYS_SDRAM_BASE;
-	if (gd->ram_size > CONFIG_SYS_DDR_BLOCK1_SIZE) {
-		gd->bd->bi_dram[0].size = CONFIG_SYS_DDR_BLOCK1_SIZE;
-		gd->bd->bi_dram[1].start = CONFIG_SYS_DDR_BLOCK2_BASE;
-		gd->bd->bi_dram[1].size = gd->ram_size -
-					  CONFIG_SYS_DDR_BLOCK1_SIZE;
-#ifdef CONFIG_SYS_MEM_RESERVE_SECURE
-		gd->arch.secure_ram = gd->bd->bi_dram[1].start +
-				      gd->arch.secure_ram -
-				      CONFIG_SYS_DDR_BLOCK1_SIZE;
-		gd->arch.secure_ram |= MEM_RESERVE_SECURE_MAINTAINED;
-#endif
-	} else {
-		gd->bd->bi_dram[0].size = gd->ram_size;
-#ifdef CONFIG_SYS_MEM_RESERVE_SECURE
-		gd->arch.secure_ram = gd->bd->bi_dram[0].start +
-				      gd->arch.secure_ram;
-		gd->arch.secure_ram |= MEM_RESERVE_SECURE_MAINTAINED;
-#endif
-	}
-}
diff --git a/board/freescale/ls1043aqds/ls1043aqds.c b/board/freescale/ls1043aqds/ls1043aqds.c
index 8835a49..6507c09 100644
--- a/board/freescale/ls1043aqds/ls1043aqds.c
+++ b/board/freescale/ls1043aqds/ls1043aqds.c
@@ -11,6 +11,7 @@
 #include <asm/arch/clock.h>
 #include <asm/arch/fsl_serdes.h>
 #include <asm/arch/fdt.h>
+#include <asm/arch/mmu.h>
 #include <asm/arch/soc.h>
 #include <ahci.h>
 #include <hwconfig.h>
@@ -153,6 +154,10 @@
 	 */
 	select_i2c_ch_pca9547(I2C_MUX_CH_DEFAULT);
 	gd->ram_size = initdram(0);
+#if !defined(CONFIG_SPL) || defined(CONFIG_SPL_BUILD)
+	/* This will break-before-make MMU for DDR */
+	update_early_mmu_table();
+#endif
 
 	return 0;
 }
diff --git a/board/freescale/ls1043ardb/ddr.c b/board/freescale/ls1043ardb/ddr.c
index 849f1d1..f90b85d 100644
--- a/board/freescale/ls1043ardb/ddr.c
+++ b/board/freescale/ls1043ardb/ddr.c
@@ -188,32 +188,3 @@
 
 	return dram_size;
 }
-
-void dram_init_banksize(void)
-{
-	/*
-	 * gd->arch.secure_ram tracks the location of secure memory.
-	 * It was set as if the memory starts from 0.
-	 * The address needs to add the offset of its bank.
-	 */
-	gd->bd->bi_dram[0].start = CONFIG_SYS_SDRAM_BASE;
-	if (gd->ram_size > CONFIG_SYS_DDR_BLOCK1_SIZE) {
-		gd->bd->bi_dram[0].size = CONFIG_SYS_DDR_BLOCK1_SIZE;
-		gd->bd->bi_dram[1].start = CONFIG_SYS_DDR_BLOCK2_BASE;
-		gd->bd->bi_dram[1].size = gd->ram_size -
-					  CONFIG_SYS_DDR_BLOCK1_SIZE;
-#ifdef CONFIG_SYS_MEM_RESERVE_SECURE
-		gd->arch.secure_ram = gd->bd->bi_dram[1].start +
-				      gd->arch.secure_ram -
-				      CONFIG_SYS_DDR_BLOCK1_SIZE;
-		gd->arch.secure_ram |= MEM_RESERVE_SECURE_MAINTAINED;
-#endif
-	} else {
-		gd->bd->bi_dram[0].size = gd->ram_size;
-#ifdef CONFIG_SYS_MEM_RESERVE_SECURE
-		gd->arch.secure_ram = gd->bd->bi_dram[0].start +
-				      gd->arch.secure_ram;
-		gd->arch.secure_ram |= MEM_RESERVE_SECURE_MAINTAINED;
-#endif
-	}
-}
diff --git a/board/freescale/ls1043ardb/ls1043ardb.c b/board/freescale/ls1043ardb/ls1043ardb.c
index e213128..2333843 100644
--- a/board/freescale/ls1043ardb/ls1043ardb.c
+++ b/board/freescale/ls1043ardb/ls1043ardb.c
@@ -67,13 +67,6 @@
 	return 0;
 }
 
-int dram_init(void)
-{
-	gd->ram_size = initdram(0);
-
-	return 0;
-}
-
 int board_early_init_f(void)
 {
 	fsl_lsch2_early_init_f();
diff --git a/board/freescale/ls1046aqds/ddr.c b/board/freescale/ls1046aqds/ddr.c
index 4ea8b23..dc4d689 100644
--- a/board/freescale/ls1046aqds/ddr.c
+++ b/board/freescale/ls1046aqds/ddr.c
@@ -112,32 +112,3 @@
 
 	return dram_size;
 }
-
-void dram_init_banksize(void)
-{
-	/*
-	 * gd->arch.secure_ram tracks the location of secure memory.
-	 * It was set as if the memory starts from 0.
-	 * The address needs to add the offset of its bank.
-	 */
-	gd->bd->bi_dram[0].start = CONFIG_SYS_SDRAM_BASE;
-	if (gd->ram_size > CONFIG_SYS_DDR_BLOCK1_SIZE) {
-		gd->bd->bi_dram[0].size = CONFIG_SYS_DDR_BLOCK1_SIZE;
-		gd->bd->bi_dram[1].start = CONFIG_SYS_DDR_BLOCK2_BASE;
-		gd->bd->bi_dram[1].size = gd->ram_size -
-					  CONFIG_SYS_DDR_BLOCK1_SIZE;
-#ifdef CONFIG_SYS_MEM_RESERVE_SECURE
-		gd->arch.secure_ram = gd->bd->bi_dram[1].start +
-				 gd->arch.secure_ram -
-				 CONFIG_SYS_DDR_BLOCK1_SIZE;
-		gd->arch.secure_ram |= MEM_RESERVE_SECURE_MAINTAINED;
-#endif
-	} else {
-		gd->bd->bi_dram[0].size = gd->ram_size;
-#ifdef CONFIG_SYS_MEM_RESERVE_SECURE
-		gd->arch.secure_ram = gd->bd->bi_dram[0].start +
-				 gd->arch.secure_ram;
-		gd->arch.secure_ram |= MEM_RESERVE_SECURE_MAINTAINED;
-#endif
-	}
-}
diff --git a/board/freescale/ls1046aqds/ls1046aqds.c b/board/freescale/ls1046aqds/ls1046aqds.c
index 552365b..af3f70a 100644
--- a/board/freescale/ls1046aqds/ls1046aqds.c
+++ b/board/freescale/ls1046aqds/ls1046aqds.c
@@ -11,6 +11,7 @@
 #include <asm/arch/clock.h>
 #include <asm/arch/fsl_serdes.h>
 #include <asm/arch/fdt.h>
+#include <asm/arch/mmu.h>
 #include <asm/arch/soc.h>
 #include <ahci.h>
 #include <hwconfig.h>
@@ -149,6 +150,10 @@
 	 */
 	select_i2c_ch_pca9547(I2C_MUX_CH_DEFAULT);
 	gd->ram_size = initdram(0);
+#if !defined(CONFIG_SPL) || defined(CONFIG_SPL_BUILD)
+	/* This will break-before-make MMU for DDR */
+	update_early_mmu_table();
+#endif
 
 	return 0;
 }
diff --git a/board/freescale/ls1046ardb/ddr.c b/board/freescale/ls1046ardb/ddr.c
index dd3b5d0..efe2ba6 100644
--- a/board/freescale/ls1046ardb/ddr.c
+++ b/board/freescale/ls1046ardb/ddr.c
@@ -112,32 +112,3 @@
 
 	return dram_size;
 }
-
-void dram_init_banksize(void)
-{
-	/*
-	 * gd->arch.secure_ram tracks the location of secure memory.
-	 * It was set as if the memory starts from 0.
-	 * The address needs to add the offset of its bank.
-	 */
-	gd->bd->bi_dram[0].start = CONFIG_SYS_SDRAM_BASE;
-	if (gd->ram_size > CONFIG_SYS_DDR_BLOCK1_SIZE) {
-		gd->bd->bi_dram[0].size = CONFIG_SYS_DDR_BLOCK1_SIZE;
-		gd->bd->bi_dram[1].start = CONFIG_SYS_DDR_BLOCK2_BASE;
-		gd->bd->bi_dram[1].size = gd->ram_size -
-					  CONFIG_SYS_DDR_BLOCK1_SIZE;
-#ifdef CONFIG_SYS_MEM_RESERVE_SECURE
-		gd->arch.secure_ram = gd->bd->bi_dram[1].start +
-				 gd->arch.secure_ram -
-				 CONFIG_SYS_DDR_BLOCK1_SIZE;
-		gd->arch.secure_ram |= MEM_RESERVE_SECURE_MAINTAINED;
-#endif
-	} else {
-		gd->bd->bi_dram[0].size = gd->ram_size;
-#ifdef CONFIG_SYS_MEM_RESERVE_SECURE
-		gd->arch.secure_ram = gd->bd->bi_dram[0].start +
-				 gd->arch.secure_ram;
-		gd->arch.secure_ram |= MEM_RESERVE_SECURE_MAINTAINED;
-#endif
-	}
-}
diff --git a/board/freescale/ls1046ardb/ls1046ardb.c b/board/freescale/ls1046ardb/ls1046ardb.c
index 33a58cf..02b6c4c 100644
--- a/board/freescale/ls1046ardb/ls1046ardb.c
+++ b/board/freescale/ls1046ardb/ls1046ardb.c
@@ -56,13 +56,6 @@
 	return 0;
 }
 
-int dram_init(void)
-{
-	gd->ram_size = initdram(0);
-
-	return 0;
-}
-
 int board_early_init_f(void)
 {
 	fsl_lsch2_early_init_f();
diff --git a/board/freescale/ls2080a/ddr.c b/board/freescale/ls2080a/ddr.c
index e6130ec..5ed9e14 100644
--- a/board/freescale/ls2080a/ddr.c
+++ b/board/freescale/ls2080a/ddr.c
@@ -169,58 +169,3 @@
 
 	return dram_size;
 }
-
-void dram_init_banksize(void)
-{
-#ifdef CONFIG_SYS_DP_DDR_BASE_PHY
-	phys_size_t dp_ddr_size;
-#endif
-
-	/*
-	 * gd->arch.secure_ram tracks the location of secure memory.
-	 * It was set as if the memory starts from 0.
-	 * The address needs to add the offset of its bank.
-	 */
-	gd->bd->bi_dram[0].start = CONFIG_SYS_SDRAM_BASE;
-	if (gd->ram_size > CONFIG_SYS_LS2_DDR_BLOCK1_SIZE) {
-		gd->bd->bi_dram[0].size = CONFIG_SYS_LS2_DDR_BLOCK1_SIZE;
-		gd->bd->bi_dram[1].start = CONFIG_SYS_DDR_BLOCK2_BASE;
-		gd->bd->bi_dram[1].size = gd->ram_size -
-					  CONFIG_SYS_LS2_DDR_BLOCK1_SIZE;
-#ifdef CONFIG_SYS_MEM_RESERVE_SECURE
-		gd->arch.secure_ram = gd->bd->bi_dram[1].start +
-				      gd->arch.secure_ram -
-				      CONFIG_SYS_LS2_DDR_BLOCK1_SIZE;
-		gd->arch.secure_ram |= MEM_RESERVE_SECURE_MAINTAINED;
-#endif
-	} else {
-		gd->bd->bi_dram[0].size = gd->ram_size;
-#ifdef CONFIG_SYS_MEM_RESERVE_SECURE
-		gd->arch.secure_ram = gd->bd->bi_dram[0].start +
-				      gd->arch.secure_ram;
-		gd->arch.secure_ram |= MEM_RESERVE_SECURE_MAINTAINED;
-#endif
-	}
-
-#ifdef CONFIG_SYS_DP_DDR_BASE_PHY
-	if (soc_has_dp_ddr()) {
-		/* initialize DP-DDR here */
-		puts("DP-DDR:  ");
-		/*
-		 * DDR controller use 0 as the base address for binding.
-		 * It is mapped to CONFIG_SYS_DP_DDR_BASE for core to access.
-		 */
-		dp_ddr_size = fsl_other_ddr_sdram(CONFIG_SYS_DP_DDR_BASE_PHY,
-					  CONFIG_DP_DDR_CTRL,
-					  CONFIG_DP_DDR_NUM_CTRLS,
-					  CONFIG_DP_DDR_DIMM_SLOTS_PER_CTLR,
-					  NULL, NULL, NULL);
-		if (dp_ddr_size) {
-			gd->bd->bi_dram[2].start = CONFIG_SYS_DP_DDR_BASE;
-			gd->bd->bi_dram[2].size = dp_ddr_size;
-		} else {
-			puts("Not detected");
-		}
-	}
-#endif
-}
diff --git a/board/freescale/ls2080a/ls2080a.c b/board/freescale/ls2080a/ls2080a.c
index 4f9b9c8..9e7701d 100644
--- a/board/freescale/ls2080a/ls2080a.c
+++ b/board/freescale/ls2080a/ls2080a.c
@@ -49,13 +49,6 @@
 #endif
 }
 
-int dram_init(void)
-{
-	gd->ram_size = initdram(0);
-
-	return 0;
-}
-
 #if defined(CONFIG_ARCH_MISC_INIT)
 int arch_misc_init(void)
 {
@@ -123,6 +116,16 @@
 	base[1] = gd->bd->bi_dram[1].start;
 	size[1] = gd->bd->bi_dram[1].size;
 
+#ifdef CONFIG_RESV_RAM
+	/* reduce size if reserved memory is within this bank */
+	if (gd->arch.resv_ram >= base[0] &&
+	    gd->arch.resv_ram < base[0] + size[0])
+		size[0] = gd->arch.resv_ram - base[0];
+	else if (gd->arch.resv_ram >= base[1] &&
+		 gd->arch.resv_ram < base[1] + size[1])
+		size[1] = gd->arch.resv_ram - base[1];
+#endif
+
 	fdt_fixup_memory_banks(blob, base, size, 2);
 
 #ifdef CONFIG_FSL_MC_ENET
diff --git a/board/freescale/ls2080aqds/ddr.c b/board/freescale/ls2080aqds/ddr.c
index 9c6f477..0408c0f 100644
--- a/board/freescale/ls2080aqds/ddr.c
+++ b/board/freescale/ls2080aqds/ddr.c
@@ -169,58 +169,3 @@
 
 	return dram_size;
 }
-
-void dram_init_banksize(void)
-{
-#ifdef CONFIG_SYS_DP_DDR_BASE_PHY
-	phys_size_t dp_ddr_size;
-#endif
-
-	/*
-	 * gd->arch.secure_ram tracks the location of secure memory.
-	 * It was set as if the memory starts from 0.
-	 * The address needs to add the offset of its bank.
-	 */
-	gd->bd->bi_dram[0].start = CONFIG_SYS_SDRAM_BASE;
-	if (gd->ram_size > CONFIG_SYS_LS2_DDR_BLOCK1_SIZE) {
-		gd->bd->bi_dram[0].size = CONFIG_SYS_LS2_DDR_BLOCK1_SIZE;
-		gd->bd->bi_dram[1].start = CONFIG_SYS_DDR_BLOCK2_BASE;
-		gd->bd->bi_dram[1].size = gd->ram_size -
-					  CONFIG_SYS_LS2_DDR_BLOCK1_SIZE;
-#ifdef CONFIG_SYS_MEM_RESERVE_SECURE
-		gd->arch.secure_ram = gd->bd->bi_dram[1].start +
-				      gd->arch.secure_ram -
-				      CONFIG_SYS_LS2_DDR_BLOCK1_SIZE;
-		gd->arch.secure_ram |= MEM_RESERVE_SECURE_MAINTAINED;
-#endif
-	} else {
-		gd->bd->bi_dram[0].size = gd->ram_size;
-#ifdef CONFIG_SYS_MEM_RESERVE_SECURE
-		gd->arch.secure_ram = gd->bd->bi_dram[0].start +
-				      gd->arch.secure_ram;
-		gd->arch.secure_ram |= MEM_RESERVE_SECURE_MAINTAINED;
-#endif
-	}
-
-#ifdef CONFIG_SYS_DP_DDR_BASE_PHY
-	if (soc_has_dp_ddr()) {
-		/* initialize DP-DDR here */
-		puts("DP-DDR:  ");
-		/*
-		 * DDR controller use 0 as the base address for binding.
-		 * It is mapped to CONFIG_SYS_DP_DDR_BASE for core to access.
-		 */
-		dp_ddr_size = fsl_other_ddr_sdram(CONFIG_SYS_DP_DDR_BASE_PHY,
-					  CONFIG_DP_DDR_CTRL,
-					  CONFIG_DP_DDR_NUM_CTRLS,
-					  CONFIG_DP_DDR_DIMM_SLOTS_PER_CTLR,
-					  NULL, NULL, NULL);
-		if (dp_ddr_size) {
-			gd->bd->bi_dram[2].start = CONFIG_SYS_DP_DDR_BASE;
-			gd->bd->bi_dram[2].size = dp_ddr_size;
-		} else {
-			puts("Not detected");
-		}
-	}
-#endif
-}
diff --git a/board/freescale/ls2080aqds/ls2080aqds.c b/board/freescale/ls2080aqds/ls2080aqds.c
index 73a61fd..277013b 100644
--- a/board/freescale/ls2080aqds/ls2080aqds.c
+++ b/board/freescale/ls2080aqds/ls2080aqds.c
@@ -22,6 +22,7 @@
 
 #include "../common/qixis.h"
 #include "ls2080aqds_qixis.h"
+#include "../common/vid.h"
 
 #define PIN_MUX_SEL_SDHC	0x00
 #define PIN_MUX_SEL_DSPI	0x0a
@@ -240,6 +241,14 @@
 	return 0;
 }
 
+int misc_init_r(void)
+{
+	if (adjust_vdd(0))
+		printf("Warning: Adjusting core voltage failed.\n");
+
+	return 0;
+}
+
 void detail_board_ddr_info(void)
 {
 	puts("\nDDR    ");
@@ -254,13 +263,6 @@
 #endif
 }
 
-int dram_init(void)
-{
-	gd->ram_size = initdram(0);
-
-	return 0;
-}
-
 #if defined(CONFIG_ARCH_MISC_INIT)
 int arch_misc_init(void)
 {
@@ -313,6 +315,16 @@
 	base[1] = gd->bd->bi_dram[1].start;
 	size[1] = gd->bd->bi_dram[1].size;
 
+#ifdef CONFIG_RESV_RAM
+	/* reduce size if reserved memory is within this bank */
+	if (gd->arch.resv_ram >= base[0] &&
+	    gd->arch.resv_ram < base[0] + size[0])
+		size[0] = gd->arch.resv_ram - base[0];
+	else if (gd->arch.resv_ram >= base[1] &&
+		 gd->arch.resv_ram < base[1] + size[1])
+		size[1] = gd->arch.resv_ram - base[1];
+#endif
+
 	fdt_fixup_memory_banks(blob, base, size, 2);
 
 	fsl_fdt_fixup_dr_usb(blob, bd);
diff --git a/board/freescale/ls2080ardb/ddr.c b/board/freescale/ls2080ardb/ddr.c
index 959dfeb..2851d5b 100644
--- a/board/freescale/ls2080ardb/ddr.c
+++ b/board/freescale/ls2080ardb/ddr.c
@@ -172,58 +172,3 @@
 
 	return dram_size;
 }
-
-void dram_init_banksize(void)
-{
-#ifdef CONFIG_SYS_DP_DDR_BASE_PHY
-	phys_size_t dp_ddr_size;
-#endif
-
-	/*
-	 * gd->arch.secure_ram tracks the location of secure memory.
-	 * It was set as if the memory starts from 0.
-	 * The address needs to add the offset of its bank.
-	 */
-	gd->bd->bi_dram[0].start = CONFIG_SYS_SDRAM_BASE;
-	if (gd->ram_size > CONFIG_SYS_LS2_DDR_BLOCK1_SIZE) {
-		gd->bd->bi_dram[0].size = CONFIG_SYS_LS2_DDR_BLOCK1_SIZE;
-		gd->bd->bi_dram[1].start = CONFIG_SYS_DDR_BLOCK2_BASE;
-		gd->bd->bi_dram[1].size = gd->ram_size -
-					  CONFIG_SYS_LS2_DDR_BLOCK1_SIZE;
-#ifdef CONFIG_SYS_MEM_RESERVE_SECURE
-		gd->arch.secure_ram = gd->bd->bi_dram[1].start +
-				      gd->arch.secure_ram -
-				      CONFIG_SYS_LS2_DDR_BLOCK1_SIZE;
-		gd->arch.secure_ram |= MEM_RESERVE_SECURE_MAINTAINED;
-#endif
-	} else {
-		gd->bd->bi_dram[0].size = gd->ram_size;
-#ifdef CONFIG_SYS_MEM_RESERVE_SECURE
-		gd->arch.secure_ram = gd->bd->bi_dram[0].start +
-				      gd->arch.secure_ram;
-		gd->arch.secure_ram |= MEM_RESERVE_SECURE_MAINTAINED;
-#endif
-	}
-
-#ifdef CONFIG_SYS_DP_DDR_BASE_PHY
-	if (soc_has_dp_ddr()) {
-		/* initialize DP-DDR here */
-		puts("DP-DDR:  ");
-		/*
-		 * DDR controller use 0 as the base address for binding.
-		 * It is mapped to CONFIG_SYS_DP_DDR_BASE for core to access.
-		 */
-		dp_ddr_size = fsl_other_ddr_sdram(CONFIG_SYS_DP_DDR_BASE_PHY,
-					  CONFIG_DP_DDR_CTRL,
-					  CONFIG_DP_DDR_NUM_CTRLS,
-					  CONFIG_DP_DDR_DIMM_SLOTS_PER_CTLR,
-					  NULL, NULL, NULL);
-		if (dp_ddr_size) {
-			gd->bd->bi_dram[2].start = CONFIG_SYS_DP_DDR_BASE;
-			gd->bd->bi_dram[2].size = dp_ddr_size;
-		} else {
-			puts("Not detected");
-		}
-	}
-#endif
-}
diff --git a/board/freescale/ls2080ardb/ls2080ardb.c b/board/freescale/ls2080ardb/ls2080ardb.c
index 02954ef..4c01f56 100644
--- a/board/freescale/ls2080ardb/ls2080ardb.c
+++ b/board/freescale/ls2080ardb/ls2080ardb.c
@@ -17,6 +17,7 @@
 #include <environment.h>
 #include <efi_loader.h>
 #include <i2c.h>
+#include <asm/arch/mmu.h>
 #include <asm/arch/soc.h>
 #include <fsl_sec.h>
 
@@ -202,14 +203,6 @@
 	if (adjust_vdd(0))
 		printf("Warning: Adjusting core voltage failed.\n");
 
-#if defined(CONFIG_EFI_LOADER) && !defined(CONFIG_SPL_BUILD)
-	if (soc_has_dp_ddr() && gd->bd->bi_dram[2].size) {
-		efi_add_memory_map(gd->bd->bi_dram[2].start,
-				   gd->bd->bi_dram[2].size >> EFI_PAGE_SHIFT,
-				   EFI_RESERVED_MEMORY_TYPE, false);
-	}
-#endif
-
 	return 0;
 }
 
@@ -227,13 +220,6 @@
 #endif
 }
 
-int dram_init(void)
-{
-	gd->ram_size = initdram(0);
-
-	return 0;
-}
-
 #if defined(CONFIG_ARCH_MISC_INIT)
 int arch_misc_init(void)
 {
@@ -286,6 +272,16 @@
 	base[1] = gd->bd->bi_dram[1].start;
 	size[1] = gd->bd->bi_dram[1].size;
 
+#ifdef CONFIG_RESV_RAM
+	/* reduce size if reserved memory is within this bank */
+	if (gd->arch.resv_ram >= base[0] &&
+	    gd->arch.resv_ram < base[0] + size[0])
+		size[0] = gd->arch.resv_ram - base[0];
+	else if (gd->arch.resv_ram >= base[1] &&
+		 gd->arch.resv_ram < base[1] + size[1])
+		size[1] = gd->arch.resv_ram - base[1];
+#endif
+
 	fdt_fixup_memory_banks(blob, base, size, 2);
 
 	fsl_fdt_fixup_dr_usb(blob, bd);
diff --git a/board/st/stm32f746-disco/stm32f746-disco.c b/board/st/stm32f746-disco/stm32f746-disco.c
index 7ed7bf7..fdad8d1 100644
--- a/board/st/stm32f746-disco/stm32f746-disco.c
+++ b/board/st/stm32f746-disco/stm32f746-disco.c
@@ -27,14 +27,6 @@
 	.af = STM32_GPIO_AF0
 };
 
-const struct stm32_gpio_ctl gpio_ctl_usart = {
-	.mode = STM32_GPIO_MODE_AF,
-	.otype = STM32_GPIO_OTYPE_PP,
-	.speed = STM32_GPIO_SPEED_50M,
-	.pupd = STM32_GPIO_PUPD_UP,
-	.af = STM32_GPIO_AF7
-};
-
 const struct stm32_gpio_ctl gpio_ctl_fmc = {
 	.mode = STM32_GPIO_MODE_AF,
 	.otype = STM32_GPIO_OTYPE_PP,
@@ -245,81 +237,24 @@
 	return rv;
 }
 
-static const struct stm32_gpio_dsc usart_gpio[] = {
-	{STM32_GPIO_PORT_A, STM32_GPIO_PIN_9},	/* TX */
-	{STM32_GPIO_PORT_B, STM32_GPIO_PIN_7},	/* RX */
-};
-
 int uart_setup_gpio(void)
 {
-	int i;
-	int rv = 0;
-
 	clock_setup(GPIO_A_CLOCK_CFG);
 	clock_setup(GPIO_B_CLOCK_CFG);
-	for (i = 0; i < ARRAY_SIZE(usart_gpio); i++) {
-		rv = stm32_gpio_config(&usart_gpio[i], &gpio_ctl_usart);
-		if (rv)
-			goto out;
-	}
-
-out:
-	return rv;
+	return 0;
 }
 
-static const struct stm32x7_serial_platdata serial_platdata = {
-	.base = (struct stm32_usart *)USART1_BASE,
-	.clock = CONFIG_SYS_CLK_FREQ,
-};
-
-U_BOOT_DEVICE(stm32x7_serials) = {
-	.name = "serial_stm32x7",
-	.platdata = &serial_platdata,
-};
-
 #ifdef CONFIG_ETH_DESIGNWARE
-const struct stm32_gpio_ctl gpio_ctl_eth = {
-	.mode = STM32_GPIO_MODE_AF,
-	.otype = STM32_GPIO_OTYPE_PP,
-	.speed = STM32_GPIO_SPEED_100M,
-	.pupd = STM32_GPIO_PUPD_NO,
-	.af = STM32_GPIO_AF11
-};
-
-static const struct stm32_gpio_dsc eth_gpio[] = {
-	{STM32_GPIO_PORT_A, STM32_GPIO_PIN_1},	/* ETH_RMII_REF_CLK */
-	{STM32_GPIO_PORT_A, STM32_GPIO_PIN_2},	/* ETH_MDIO */
-	{STM32_GPIO_PORT_A, STM32_GPIO_PIN_7},	/* ETH_RMII_CRS_DV */
-
-	{STM32_GPIO_PORT_C, STM32_GPIO_PIN_1},	/* ETH_MDC */
-	{STM32_GPIO_PORT_C, STM32_GPIO_PIN_4},	/* ETH_RMII_RXD0 */
-	{STM32_GPIO_PORT_C, STM32_GPIO_PIN_5},	/* ETH_RMII_RXD1 */
-
-	{STM32_GPIO_PORT_G, STM32_GPIO_PIN_11},	/* ETH_RMII_TX_EN */
-	{STM32_GPIO_PORT_G, STM32_GPIO_PIN_13},	/* ETH_RMII_TXD0 */
-	{STM32_GPIO_PORT_G, STM32_GPIO_PIN_14},	/* ETH_RMII_TXD1 */
-};
 
 static int stmmac_setup(void)
 {
-	int res = 0;
-	int i;
-
 	clock_setup(SYSCFG_CLOCK_CFG);
-
 	/* Set >RMII mode */
 	STM32_SYSCFG->pmc |= SYSCFG_PMC_MII_RMII_SEL;
 
 	clock_setup(GPIO_A_CLOCK_CFG);
 	clock_setup(GPIO_C_CLOCK_CFG);
 	clock_setup(GPIO_G_CLOCK_CFG);
-
-	for (i = 0; i < ARRAY_SIZE(eth_gpio); i++) {
-		res = stm32_gpio_config(&eth_gpio[i], &gpio_ctl_eth);
-		if (res)
-			return res;
-	}
-
 	clock_setup(STMMAC_CLOCK_CFG);
 
 	return 0;
@@ -327,55 +262,12 @@
 #endif
 
 #ifdef CONFIG_STM32_QSPI
-const struct stm32_gpio_ctl gpio_ctl_qspi_9 = {
-	.mode = STM32_GPIO_MODE_AF,
-	.otype = STM32_GPIO_OTYPE_PP,
-	.speed = STM32_GPIO_SPEED_100M,
-	.pupd = STM32_GPIO_PUPD_NO,
-	.af = STM32_GPIO_AF9
-};
-
-const struct stm32_gpio_ctl gpio_ctl_qspi_10 = {
-	.mode = STM32_GPIO_MODE_AF,
-	.otype = STM32_GPIO_OTYPE_PP,
-	.speed = STM32_GPIO_SPEED_100M,
-	.pupd = STM32_GPIO_PUPD_NO,
-	.af = STM32_GPIO_AF10
-};
-
-static const struct stm32_gpio_dsc qspi_af9_gpio[] = {
-	{STM32_GPIO_PORT_B, STM32_GPIO_PIN_2},	/* QUADSPI_CLK */
-	{STM32_GPIO_PORT_D, STM32_GPIO_PIN_11},	/* QUADSPI_BK1_IO0 */
-	{STM32_GPIO_PORT_D, STM32_GPIO_PIN_12},	/* QUADSPI_BK1_IO1 */
-	{STM32_GPIO_PORT_D, STM32_GPIO_PIN_13},	/* QUADSPI_BK1_IO3 */
-	{STM32_GPIO_PORT_E, STM32_GPIO_PIN_2},	/* QUADSPI_BK1_IO2 */
-};
-
-static const struct stm32_gpio_dsc qspi_af10_gpio[] = {
-	{STM32_GPIO_PORT_B, STM32_GPIO_PIN_6},	/* QUADSPI_BK1_NCS */
-};
 
 static int qspi_setup(void)
 {
-	int res = 0;
-	int i;
-
 	clock_setup(GPIO_B_CLOCK_CFG);
 	clock_setup(GPIO_D_CLOCK_CFG);
 	clock_setup(GPIO_E_CLOCK_CFG);
-
-	for (i = 0; i < ARRAY_SIZE(qspi_af9_gpio); i++) {
-		res = stm32_gpio_config(&qspi_af9_gpio[i], &gpio_ctl_qspi_9);
-		if (res)
-			return res;
-	}
-
-	for (i = 0; i < ARRAY_SIZE(qspi_af10_gpio); i++) {
-		res = stm32_gpio_config(&qspi_af10_gpio[i], &gpio_ctl_qspi_10);
-		if (res)
-			return res;
-	}
-
 	return 0;
 }
 #endif
@@ -390,7 +282,6 @@
 	int res;
 
 	res = uart_setup_gpio();
-	clock_setup(USART1_CLOCK_CFG);
 	if (res)
 		return res;
 
diff --git a/cmd/Kconfig b/cmd/Kconfig
index ef53156..25e3b78 100644
--- a/cmd/Kconfig
+++ b/cmd/Kconfig
@@ -338,6 +338,20 @@
 	help
 	  Compute CRC32.
 
+config CMD_MD5SUM
+	bool "md5sum"
+	default n
+	select MD5
+	help
+	  Compute MD5 checksum.
+
+config MD5SUM_VERFIY
+	bool "md5sum -v"
+	default n
+	depends on CMD_MD5SUM
+	help
+	  Add -v option to verify data against an MD5 checksum.
+
 config LOOPW
 	bool "loopw"
 	help
diff --git a/cmd/bdinfo.c b/cmd/bdinfo.c
index ae3027a..19b8fd8 100644
--- a/cmd/bdinfo.c
+++ b/cmd/bdinfo.c
@@ -392,6 +392,10 @@
 			  gd->arch.secure_ram & MEM_RESERVE_SECURE_ADDR_MASK);
 	}
 #endif
+#ifdef CONFIG_RESV_RAM
+	if (gd->arch.resv_ram)
+		print_num("Reserved ram", gd->arch.resv_ram);
+#endif
 #if defined(CONFIG_CMD_NET) && !defined(CONFIG_DM_ETH)
 	print_eths();
 #endif
diff --git a/cmd/gpt.c b/cmd/gpt.c
index 196f506..3e98821 100644
--- a/cmd/gpt.c
+++ b/cmd/gpt.c
@@ -54,7 +54,7 @@
 	if (e == NULL) {
 #ifdef CONFIG_RANDOM_UUID
 		debug("%s unset. ", str);
-		gen_rand_uuid_str(uuid_str, UUID_STR_FORMAT_STD);
+		gen_rand_uuid_str(uuid_str, UUID_STR_FORMAT_GUID);
 		setenv(s, uuid_str);
 
 		e = getenv(s);
diff --git a/cmd/itest.c b/cmd/itest.c
index 60626c7..e1896d9 100644
--- a/cmd/itest.c
+++ b/cmd/itest.c
@@ -80,7 +80,8 @@
 		l = simple_strtoul(s, NULL, 16);
 	}
 
-	return l & ((1UL << (w * 8)) - 1);
+	/* avoid overflow on mask calculus */
+	return (w >= sizeof(long)) ? l : (l & ((1UL << (w * 8)) - 1));
 }
 
 static char * evalstr(char *s)
diff --git a/common/board_f.c b/common/board_f.c
index ae6cd85..7d1ede0 100644
--- a/common/board_f.c
+++ b/common/board_f.c
@@ -325,15 +325,6 @@
 	return gd->ram_top;
 }
 
-__weak phys_size_t board_reserve_ram_top(phys_size_t ram_size)
-{
-#ifdef CONFIG_SYS_MEM_TOP_HIDE
-	return ram_size - CONFIG_SYS_MEM_TOP_HIDE;
-#else
-	return ram_size;
-#endif
-}
-
 static int setup_dest_addr(void)
 {
 	debug("Monitor len: %08lX\n", gd->mon_len);
@@ -341,26 +332,19 @@
 	 * Ram is setup, size stored in gd !!
 	 */
 	debug("Ram size: %08lX\n", (ulong)gd->ram_size);
-#ifdef CONFIG_SYS_MEM_RESERVE_SECURE
-	/* Reserve memory for secure MMU tables, and/or security monitor */
-	gd->ram_size -= CONFIG_SYS_MEM_RESERVE_SECURE;
-	/*
-	 * Record secure memory location. Need recalcuate if memory splits
-	 * into banks, or the ram base is not zero.
-	 */
-	gd->arch.secure_ram = gd->ram_size;
-#endif
+#if defined(CONFIG_SYS_MEM_TOP_HIDE)
 	/*
 	 * Subtract specified amount of memory to hide so that it won't
 	 * get "touched" at all by U-Boot. By fixing up gd->ram_size
 	 * the Linux kernel should now get passed the now "corrected"
-	 * memory size and won't touch it either. This has been used
-	 * by arch/powerpc exclusively. Now ARMv8 takes advantage of
-	 * thie mechanism. If memory is split into banks, addresses
-	 * need to be calculated.
+	 * memory size and won't touch it either. This should work
+	 * for arch/ppc and arch/powerpc. Only Linux board ports in
+	 * arch/powerpc with bootwrapper support, that recalculate the
+	 * memory size from the SDRAM controller setup will have to
+	 * get fixed.
 	 */
-	gd->ram_size = board_reserve_ram_top(gd->ram_size);
-
+	gd->ram_size -= CONFIG_SYS_MEM_TOP_HIDE;
+#endif
 #ifdef CONFIG_SYS_SDRAM_BASE
 	gd->ram_top = CONFIG_SYS_SDRAM_BASE;
 #endif
diff --git a/configs/dragonboard410c_defconfig b/configs/dragonboard410c_defconfig
index 7435818..6b50964 100644
--- a/configs/dragonboard410c_defconfig
+++ b/configs/dragonboard410c_defconfig
@@ -36,3 +36,4 @@
 CONFIG_USB_ULPI_VIEWPORT=y
 CONFIG_USB_ULPI=y
 CONFIG_USB_STORAGE=y
+CONFIG_CMD_MD5SUM=y
diff --git a/configs/sandbox_defconfig b/configs/sandbox_defconfig
index 01f6f5d..7f3f5ac 100644
--- a/configs/sandbox_defconfig
+++ b/configs/sandbox_defconfig
@@ -22,6 +22,7 @@
 # CONFIG_CMD_IMLS is not set
 CONFIG_CMD_ASKENV=y
 CONFIG_CMD_GREPENV=y
+CONFIG_CMD_MD5SUM=y
 CONFIG_LOOPW=y
 CONFIG_CMD_MEMTEST=y
 CONFIG_CMD_MX_CYCLIC=y
diff --git a/configs/sandbox_noblk_defconfig b/configs/sandbox_noblk_defconfig
index 10e12bf..3f8e70d 100644
--- a/configs/sandbox_noblk_defconfig
+++ b/configs/sandbox_noblk_defconfig
@@ -22,6 +22,7 @@
 # CONFIG_CMD_IMLS is not set
 CONFIG_CMD_ASKENV=y
 CONFIG_CMD_GREPENV=y
+CONFIG_CMD_MD5SUM=y
 CONFIG_LOOPW=y
 CONFIG_CMD_MEMTEST=y
 CONFIG_CMD_MX_CYCLIC=y
diff --git a/configs/sandbox_spl_defconfig b/configs/sandbox_spl_defconfig
index 281e441..ade6714 100644
--- a/configs/sandbox_spl_defconfig
+++ b/configs/sandbox_spl_defconfig
@@ -29,6 +29,7 @@
 # CONFIG_CMD_IMLS is not set
 CONFIG_CMD_ASKENV=y
 CONFIG_CMD_GREPENV=y
+CONFIG_CMD_MD5SUM=y
 CONFIG_LOOPW=y
 CONFIG_CMD_MEMTEST=y
 CONFIG_CMD_MX_CYCLIC=y
diff --git a/configs/sh7752evb_defconfig b/configs/sh7752evb_defconfig
index ace7553..224b55b 100644
--- a/configs/sh7752evb_defconfig
+++ b/configs/sh7752evb_defconfig
@@ -27,6 +27,7 @@
 CONFIG_MAC_PARTITION=y
 CONFIG_DOS_PARTITION=y
 CONFIG_MMC=y
+CONFIG_CMD_MD5SUM=y
 CONFIG_SPI_FLASH=y
 CONFIG_SPI_FLASH_MACRONIX=y
 CONFIG_SPI_FLASH_STMICRO=y
diff --git a/configs/sh7753evb_defconfig b/configs/sh7753evb_defconfig
index 48e3d55..7bf8862 100644
--- a/configs/sh7753evb_defconfig
+++ b/configs/sh7753evb_defconfig
@@ -26,6 +26,7 @@
 CONFIG_MAC_PARTITION=y
 CONFIG_DOS_PARTITION=y
 CONFIG_MMC=y
+CONFIG_CMD_MD5SUM=y
 CONFIG_SPI_FLASH=y
 CONFIG_SPI_FLASH_MACRONIX=y
 CONFIG_SPI_FLASH_STMICRO=y
diff --git a/configs/sh7757lcr_defconfig b/configs/sh7757lcr_defconfig
index dc6f4e1..00870ac 100644
--- a/configs/sh7757lcr_defconfig
+++ b/configs/sh7757lcr_defconfig
@@ -27,6 +27,7 @@
 CONFIG_MAC_PARTITION=y
 CONFIG_DOS_PARTITION=y
 CONFIG_MMC=y
+CONFIG_CMD_MD5SUM=y
 CONFIG_SPI_FLASH=y
 CONFIG_SPI_FLASH_STMICRO=y
 CONFIG_USE_PRIVATE_LIBGCC=y
diff --git a/configs/stm32f746-disco_defconfig b/configs/stm32f746-disco_defconfig
index f638ca0..b5457c6 100644
--- a/configs/stm32f746-disco_defconfig
+++ b/configs/stm32f746-disco_defconfig
@@ -39,3 +39,7 @@
 CONFIG_STM32_QSPI=y
 CONFIG_OF_LIBFDT_OVERLAY=y
 # CONFIG_EFI_LOADER is not set
+CONFIG_CLK=y
+CONFIG_PINCTRL=y
+# CONFIG_PINCTRL_FULL is not set
+CONFIG_PINCTRL_STM32=y
diff --git a/disk/part_efi.c b/disk/part_efi.c
index 893cbbd..db0c890 100644
--- a/disk/part_efi.c
+++ b/disk/part_efi.c
@@ -463,7 +463,7 @@
 		str_uuid = partitions[i].uuid;
 		bin_uuid = gpt_e[i].unique_partition_guid.b;
 
-		if (uuid_str_to_bin(str_uuid, bin_uuid, UUID_STR_FORMAT_STD)) {
+		if (uuid_str_to_bin(str_uuid, bin_uuid, UUID_STR_FORMAT_GUID)) {
 			printf("Partition no. %d: invalid guid: %s\n",
 				i, str_uuid);
 			return -1;
diff --git a/doc/device-tree-bindings/clock/st,stm32-rcc.txt b/doc/device-tree-bindings/clock/st,stm32-rcc.txt
new file mode 100644
index 0000000..0532d81
--- /dev/null
+++ b/doc/device-tree-bindings/clock/st,stm32-rcc.txt
@@ -0,0 +1,95 @@
+STMicroelectronics STM32 Reset and Clock Controller
+===================================================
+
+The RCC IP is both a reset and a clock controller.
+
+Please refer to clock-bindings.txt for common clock controller binding usage.
+Please also refer to reset.txt for common reset controller binding usage.
+
+Required properties:
+- compatible: Should be:
+  "st,stm32f42xx-rcc"
+  "st,stm32f469-rcc"
+- reg: should be register base and length as documented in the
+  datasheet
+- #reset-cells: 1, see below
+- #clock-cells: 2, device nodes should specify the clock in their "clocks"
+  property, containing a phandle to the clock device node, an index selecting
+  between gated clocks and other clocks and an index specifying the clock to
+  use.
+
+Example:
+
+	rcc: rcc@40023800 {
+		#reset-cells = <1>;
+		#clock-cells = <2>
+		compatible = "st,stm32f42xx-rcc", "st,stm32-rcc";
+		reg = <0x40023800 0x400>;
+	};
+
+Specifying gated clocks
+=======================
+
+The primary index must be set to 0.
+
+The secondary index is the bit number within the RCC register bank, starting
+from the first RCC clock enable register (RCC_AHB1ENR, address offset 0x30).
+
+It is calculated as: index = register_offset / 4 * 32 + bit_offset.
+Where bit_offset is the bit offset within the register (LSB is 0, MSB is 31).
+
+To simplify the usage and to share bit definition with the reset and clock
+drivers of the RCC IP, macros are available to generate the index in
+human-readble format.
+
+For STM32F4 series, the macro are available here:
+ - include/dt-bindings/mfd/stm32f4-rcc.h
+
+Example:
+
+	/* Gated clock, AHB1 bit 0 (GPIOA) */
+	... {
+		clocks = <&rcc 0 STM32F4_AHB1_CLOCK(GPIOA)>
+	};
+
+	/* Gated clock, AHB2 bit 4 (CRYP) */
+	... {
+		clocks = <&rcc 0 STM32F4_AHB2_CLOCK(CRYP)>
+	};
+
+Specifying other clocks
+=======================
+
+The primary index must be set to 1.
+
+The secondary index is bound with the following magic numbers:
+
+	0	SYSTICK
+	1	FCLK
+
+Example:
+
+	/* Misc clock, FCLK */
+	... {
+		clocks = <&rcc 1 STM32F4_APB1_CLOCK(TIM2)>
+	};
+
+
+Specifying softreset control of devices
+=======================================
+
+Device nodes should specify the reset channel required in their "resets"
+property, containing a phandle to the reset device node and an index specifying
+which channel to use.
+The index is the bit number within the RCC registers bank, starting from RCC
+base address.
+It is calculated as: index = register_offset / 4 * 32 + bit_offset.
+Where bit_offset is the bit offset within the register.
+For example, for CRC reset:
+  crc = AHB1RSTR_offset / 4 * 32 + CRCRST_bit_offset = 0x10 / 4 * 32 + 12 = 140
+
+example:
+
+	timer2 {
+		resets	= <&rcc STM32F4_APB1_RESET(TIM2)>;
+	};
diff --git a/doc/device-tree-bindings/pinctrl/st,stm32-pinctrl.txt b/doc/device-tree-bindings/pinctrl/st,stm32-pinctrl.txt
new file mode 100644
index 0000000..c41ae91
--- /dev/null
+++ b/doc/device-tree-bindings/pinctrl/st,stm32-pinctrl.txt
@@ -0,0 +1,133 @@
+* STM32 GPIO and Pin Mux/Config controller
+
+STMicroelectronics's STM32 MCUs intregrate a GPIO and Pin mux/config hardware
+controller. It controls the input/output settings on the available pins and
+also provides ability to multiplex and configure the output of various on-chip
+controllers onto these pads.
+
+Pin controller node:
+Required properies:
+ - compatible: value should be one of the following:
+   (a) "st,stm32f429-pinctrl"
+   (b) "st,stm32f746-pinctrl"
+ - #address-cells: The value of this property must be 1
+ - #size-cells	: The value of this property must be 1
+ - ranges	: defines mapping between pin controller node (parent) to
+   gpio-bank node (children).
+ - pins-are-numbered: Specify the subnodes are using numbered pinmux to
+   specify pins.
+
+GPIO controller/bank node:
+Required properties:
+ - gpio-controller : Indicates this device is a GPIO controller
+ - #gpio-cells	  : Should be two.
+			The first cell is the pin number
+			The second one is the polarity:
+				- 0 for active high
+				- 1 for active low
+ - reg		  : The gpio address range, relative to the pinctrl range
+ - clocks	  : clock that drives this bank
+ - st,bank-name	  : Should be a name string for this bank as specified in
+   the datasheet
+
+Optional properties:
+ - reset:	  : Reference to the reset controller
+ - interrupt-parent: phandle of the interrupt parent to which the external
+   GPIO interrupts are forwarded to.
+ - st,syscfg: Should be phandle/offset pair. The phandle to the syscon node
+   which includes IRQ mux selection register, and the offset of the IRQ mux
+   selection register.
+
+Example:
+#include <dt-bindings/pinctrl/stm32f429-pinfunc.h>
+...
+
+	pin-controller {
+		#address-cells = <1>;
+		#size-cells = <1>;
+		compatible = "st,stm32f429-pinctrl";
+		ranges = <0 0x40020000 0x3000>;
+		pins-are-numbered;
+
+		gpioa: gpio@40020000 {
+			gpio-controller;
+			#gpio-cells = <2>;
+			reg = <0x0 0x400>;
+			resets = <&reset_ahb1 0>;
+			st,bank-name = "GPIOA";
+		};
+		...
+		pin-functions nodes follow...
+	};
+
+Contents of function subnode node:
+----------------------------------
+Subnode format
+A pinctrl node should contain at least one subnode representing the
+pinctrl group available on the machine. Each subnode will list the
+pins it needs, and how they should be configured, with regard to muxer
+configuration, pullups, drive, output high/low and output speed.
+
+    node {
+	pinmux = <PIN_NUMBER_PINMUX>;
+	GENERIC_PINCONFIG;
+    };
+
+Required properties:
+- pinmux: integer array, represents gpio pin number and mux setting.
+  Supported pin number and mux varies for different SoCs, and are defined in
+  dt-bindings/pinctrl/<soc>-pinfunc.h directly.
+  These defines are calculated as:
+    ((port * 16 + line) << 8) | function
+  With:
+    - port: The gpio port index (PA = 0, PB = 1, ..., PK = 11)
+    - line: The line offset within the port (PA0 = 0, PA1 = 1, ..., PA15 = 15)
+    - function: The function number, can be:
+      * 0 : GPIO IN
+      * 1 : Alternate Function 0
+      * 2 : Alternate Function 1
+      * 3 : Alternate Function 2
+      * ...
+      * 16 : Alternate Function 15
+      * 17 : Analog
+      * 18 : GPIO OUT
+
+Optional properties:
+- GENERIC_PINCONFIG: is the generic pinconfig options to use.
+  Available options are:
+   - bias-disable,
+   - bias-pull-down,
+   - bias-pull-up,
+   - drive-push-pull,
+   - drive-open-drain,
+   - output-low
+   - output-high
+   - slew-rate = <x>, with x being:
+       < 0 > : Low speed
+       < 1 > : Medium speed
+       < 2 > : Fast speed
+       < 3 > : High speed
+
+Example:
+
+pin-controller {
+...
+	usart1_pins_a: usart1@0 {
+		pins1 {
+			pinmux = <STM32F429_PA9_FUNC_USART1_TX>;
+			bias-disable;
+			drive-push-pull;
+			slew-rate = <0>;
+		};
+		pins2 {
+			pinmux = <STM32F429_PA10_FUNC_USART1_RX>;
+			bias-disable;
+		};
+	};
+};
+
+&usart1 {
+	pinctrl-0 = <&usart1_pins_a>;
+	pinctrl-names = "default";
+	status = "okay";
+};
diff --git a/drivers/clk/Kconfig b/drivers/clk/Kconfig
index 335ef9e..5ca958c 100644
--- a/drivers/clk/Kconfig
+++ b/drivers/clk/Kconfig
@@ -28,6 +28,14 @@
 	help
 	  Enable this to support the clocks
 
+config CLK_ZYNQ
+	bool "Enable clock driver support for Zynq"
+	depends on CLK && ARCH_ZYNQ
+	default y
+	help
+	  This clock driver adds support for clock realted settings for
+	  Zynq platform.
+
 config CLK_ZYNQMP
 	bool "Enable clock driver support for ZynqMP"
 	depends on ARCH_ZYNQMP
diff --git a/drivers/clk/Makefile b/drivers/clk/Makefile
index 884c21c..01a8cd6 100644
--- a/drivers/clk/Makefile
+++ b/drivers/clk/Makefile
@@ -10,6 +10,7 @@
 obj-$(CONFIG_SANDBOX) += clk_sandbox.o
 obj-$(CONFIG_SANDBOX) += clk_sandbox_test.o
 obj-$(CONFIG_MACH_PIC32) += clk_pic32.o
+obj-$(CONFIG_CLK_ZYNQ) += clk_zynq.o
 obj-$(CONFIG_CLK_ZYNQMP) += clk_zynqmp.o
 
 obj-y += tegra/
@@ -17,5 +18,5 @@
 obj-$(CONFIG_CLK_EXYNOS) += exynos/
 obj-$(CONFIG_CLK_AT91) += at91/
 obj-$(CONFIG_CLK_BOSTON) += clk_boston.o
-
 obj-$(CONFIG_ARCH_ASPEED) += aspeed/
+obj-$(CONFIG_STM32F7) += clk_stm32f7.o
diff --git a/arch/arm/mach-stm32/stm32f7/clock.c b/drivers/clk/clk_stm32f7.c
similarity index 85%
rename from arch/arm/mach-stm32/stm32f7/clock.c
rename to drivers/clk/clk_stm32f7.c
index e1ee173..0d86395 100644
--- a/arch/arm/mach-stm32/stm32f7/clock.c
+++ b/drivers/clk/clk_stm32f7.c
@@ -1,11 +1,12 @@
 /*
- * (C) Copyright 2016
+ * (C) Copyright 2017
  * Vikas Manocha, <vikas.manocha@st.com>
  *
  * SPDX-License-Identifier:	GPL-2.0+
  */
-
 #include <common.h>
+#include <clk-uclass.h>
+#include <dm.h>
 #include <asm/io.h>
 #include <asm/arch/rcc.h>
 #include <asm/arch/stm32.h>
@@ -212,13 +213,21 @@
 	}
 }
 
+static int stm32_clk_enable(struct clk *clk)
+{
+	u32 offset = clk->id / 32;
+	u32 bit_index = clk->id % 32;
+
+	debug("%s: clkid = %ld, offset from AHB1ENR is %d, bit_index = %d\n",
+	      __func__, clk->id, offset, bit_index);
+	setbits_le32(&STM32_RCC->ahb1enr + offset, BIT(bit_index));
+
+	return 0;
+}
 
 void clock_setup(int peripheral)
 {
 	switch (peripheral) {
-	case USART1_CLOCK_CFG:
-		setbits_le32(&STM32_RCC->apb2enr, RCC_APB2ENR_USART1EN);
-		break;
 	case GPIO_A_CLOCK_CFG:
 		setbits_le32(&STM32_RCC->ahb1enr, RCC_AHB1ENR_GPIO_A_EN);
 		break;
@@ -272,4 +281,49 @@
 	default:
 		break;
 	}
+}
+
+static int stm32_clk_probe(struct udevice *dev)
+{
+	debug("%s: stm32_clk_probe\n", __func__);
+	configure_clocks();
+
+	return 0;
+}
+
+static int stm32_clk_of_xlate(struct clk *clk,
+			struct fdtdec_phandle_args *args)
+{
+	debug("%s(clk=%p)\n", __func__, clk);
+
+	if (args->args_count != 2) {
+		debug("Invaild args_count: %d\n", args->args_count);
+		return -EINVAL;
+	}
+
+	if (args->args_count)
+		clk->id = args->args[1];
+	else
+		clk->id = 0;
+
+	return 0;
 }
+
+static struct clk_ops stm32_clk_ops = {
+	.of_xlate	= stm32_clk_of_xlate,
+	.enable		= stm32_clk_enable,
+};
+
+static const struct udevice_id stm32_clk_ids[] = {
+	{ .compatible = "st,stm32f42xx-rcc"},
+	{}
+};
+
+U_BOOT_DRIVER(stm32f7_clk) = {
+	.name		= "stm32f7_clk",
+	.id		= UCLASS_CLK,
+	.of_match	= stm32_clk_ids,
+	.ops		= &stm32_clk_ops,
+	.probe		= stm32_clk_probe,
+	.flags		= DM_FLAG_PRE_RELOC,
+};
diff --git a/drivers/clk/clk_zynq.c b/drivers/clk/clk_zynq.c
new file mode 100644
index 0000000..6edc4dc
--- /dev/null
+++ b/drivers/clk/clk_zynq.c
@@ -0,0 +1,488 @@
+/*
+ * Copyright (C) 2017 Weidmüller Interface GmbH & Co. KG
+ * Stefan Herbrechtsmeier <stefan.herbrechtsmeier@weidmueller.com>
+ *
+ * Copyright (C) 2013 Soren Brinkmann <soren.brinkmann@xilinx.com>
+ * Copyright (C) 2013 Xilinx, Inc. All rights reserved.
+ *
+ * SPDX-License-Identifier:	GPL-2.0+
+ */
+
+#include <common.h>
+#include <clk-uclass.h>
+#include <dm.h>
+#include <dm/lists.h>
+#include <errno.h>
+#include <asm/io.h>
+#include <asm/arch/clk.h>
+#include <asm/arch/hardware.h>
+#include <asm/arch/sys_proto.h>
+
+/* Register bitfield defines */
+#define PLLCTRL_FBDIV_MASK	0x7f000
+#define PLLCTRL_FBDIV_SHIFT	12
+#define PLLCTRL_BPFORCE_MASK	(1 << 4)
+#define PLLCTRL_PWRDWN_MASK	2
+#define PLLCTRL_PWRDWN_SHIFT	1
+#define PLLCTRL_RESET_MASK	1
+#define PLLCTRL_RESET_SHIFT	0
+
+#define ZYNQ_CLK_MAXDIV		0x3f
+#define CLK_CTRL_DIV1_SHIFT	20
+#define CLK_CTRL_DIV1_MASK	(ZYNQ_CLK_MAXDIV << CLK_CTRL_DIV1_SHIFT)
+#define CLK_CTRL_DIV0_SHIFT	8
+#define CLK_CTRL_DIV0_MASK	(ZYNQ_CLK_MAXDIV << CLK_CTRL_DIV0_SHIFT)
+#define CLK_CTRL_SRCSEL_SHIFT	4
+#define CLK_CTRL_SRCSEL_MASK	(0x3 << CLK_CTRL_SRCSEL_SHIFT)
+
+#define CLK_CTRL_DIV2X_SHIFT	26
+#define CLK_CTRL_DIV2X_MASK	(ZYNQ_CLK_MAXDIV << CLK_CTRL_DIV2X_SHIFT)
+#define CLK_CTRL_DIV3X_SHIFT	20
+#define CLK_CTRL_DIV3X_MASK	(ZYNQ_CLK_MAXDIV << CLK_CTRL_DIV3X_SHIFT)
+
+DECLARE_GLOBAL_DATA_PTR;
+
+#ifndef CONFIG_SPL_BUILD
+enum zynq_clk_rclk {mio_clk, emio_clk};
+#endif
+
+struct zynq_clk_priv {
+	ulong ps_clk_freq;
+#ifndef CONFIG_SPL_BUILD
+	struct clk gem_emio_clk[2];
+#endif
+};
+
+static void *zynq_clk_get_register(enum zynq_clk id)
+{
+	switch (id) {
+	case armpll_clk:
+		return &slcr_base->arm_pll_ctrl;
+	case ddrpll_clk:
+		return &slcr_base->ddr_pll_ctrl;
+	case iopll_clk:
+		return &slcr_base->io_pll_ctrl;
+	case lqspi_clk:
+		return &slcr_base->lqspi_clk_ctrl;
+	case smc_clk:
+		return &slcr_base->smc_clk_ctrl;
+	case pcap_clk:
+		return &slcr_base->pcap_clk_ctrl;
+	case sdio0_clk ... sdio1_clk:
+		return &slcr_base->sdio_clk_ctrl;
+	case uart0_clk ... uart1_clk:
+		return &slcr_base->uart_clk_ctrl;
+	case spi0_clk ... spi1_clk:
+		return &slcr_base->spi_clk_ctrl;
+#ifndef CONFIG_SPL_BUILD
+	case dci_clk:
+		return &slcr_base->dci_clk_ctrl;
+	case gem0_clk:
+		return &slcr_base->gem0_clk_ctrl;
+	case gem1_clk:
+		return &slcr_base->gem1_clk_ctrl;
+	case fclk0_clk:
+		return &slcr_base->fpga0_clk_ctrl;
+	case fclk1_clk:
+		return &slcr_base->fpga1_clk_ctrl;
+	case fclk2_clk:
+		return &slcr_base->fpga2_clk_ctrl;
+	case fclk3_clk:
+		return &slcr_base->fpga3_clk_ctrl;
+	case can0_clk ... can1_clk:
+		return &slcr_base->can_clk_ctrl;
+	case dbg_trc_clk ... dbg_apb_clk:
+		/* fall through */
+#endif
+	default:
+		return &slcr_base->dbg_clk_ctrl;
+	}
+}
+
+static enum zynq_clk zynq_clk_get_cpu_pll(u32 clk_ctrl)
+{
+	u32 srcsel = (clk_ctrl & CLK_CTRL_SRCSEL_MASK) >> CLK_CTRL_SRCSEL_SHIFT;
+
+	switch (srcsel) {
+	case 2:
+		return ddrpll_clk;
+	case 3:
+		return iopll_clk;
+	case 0 ... 1:
+	default:
+		return armpll_clk;
+	}
+}
+
+static enum zynq_clk zynq_clk_get_peripheral_pll(u32 clk_ctrl)
+{
+	u32 srcsel = (clk_ctrl & CLK_CTRL_SRCSEL_MASK) >> CLK_CTRL_SRCSEL_SHIFT;
+
+	switch (srcsel) {
+	case 2:
+		return armpll_clk;
+	case 3:
+		return ddrpll_clk;
+	case 0 ... 1:
+	default:
+		return iopll_clk;
+	}
+}
+
+static ulong zynq_clk_get_pll_rate(struct zynq_clk_priv *priv, enum zynq_clk id)
+{
+	u32 clk_ctrl, reset, pwrdwn, mul, bypass;
+
+	clk_ctrl = readl(zynq_clk_get_register(id));
+
+	reset = (clk_ctrl & PLLCTRL_RESET_MASK) >> PLLCTRL_RESET_SHIFT;
+	pwrdwn = (clk_ctrl & PLLCTRL_PWRDWN_MASK) >> PLLCTRL_PWRDWN_SHIFT;
+	if (reset || pwrdwn)
+		return 0;
+
+	bypass = clk_ctrl & PLLCTRL_BPFORCE_MASK;
+	if (bypass)
+		mul = 1;
+	else
+		mul = (clk_ctrl & PLLCTRL_FBDIV_MASK) >> PLLCTRL_FBDIV_SHIFT;
+
+	return priv->ps_clk_freq * mul;
+}
+
+#ifndef CONFIG_SPL_BUILD
+static enum zynq_clk_rclk zynq_clk_get_gem_rclk(enum zynq_clk id)
+{
+	u32 clk_ctrl, srcsel;
+
+	if (id == gem0_clk)
+		clk_ctrl = readl(&slcr_base->gem0_rclk_ctrl);
+	else
+		clk_ctrl = readl(&slcr_base->gem1_rclk_ctrl);
+
+	srcsel = (clk_ctrl & CLK_CTRL_SRCSEL_MASK) >> CLK_CTRL_SRCSEL_SHIFT;
+	if (srcsel)
+		return emio_clk;
+	else
+		return mio_clk;
+}
+#endif
+
+static ulong zynq_clk_get_cpu_rate(struct zynq_clk_priv *priv, enum zynq_clk id)
+{
+	u32 clk_621, clk_ctrl, div;
+	enum zynq_clk pll;
+
+	clk_ctrl = readl(&slcr_base->arm_clk_ctrl);
+
+	div = (clk_ctrl & CLK_CTRL_DIV0_MASK) >> CLK_CTRL_DIV0_SHIFT;
+
+	switch (id) {
+	case cpu_1x_clk:
+		div *= 2;
+		/* fall through */
+	case cpu_2x_clk:
+		clk_621 = readl(&slcr_base->clk_621_true) & 1;
+		div *= 2 + clk_621;
+		break;
+	case cpu_3or2x_clk:
+		div *= 2;
+		/* fall through */
+	case cpu_6or4x_clk:
+		break;
+	default:
+		return 0;
+	}
+
+	pll = zynq_clk_get_cpu_pll(clk_ctrl);
+
+	return DIV_ROUND_CLOSEST(zynq_clk_get_pll_rate(priv, pll), div);
+}
+
+#ifndef CONFIG_SPL_BUILD
+static ulong zynq_clk_get_ddr2x_rate(struct zynq_clk_priv *priv)
+{
+	u32 clk_ctrl, div;
+
+	clk_ctrl = readl(&slcr_base->ddr_clk_ctrl);
+
+	div = (clk_ctrl & CLK_CTRL_DIV2X_MASK) >> CLK_CTRL_DIV2X_SHIFT;
+
+	return DIV_ROUND_CLOSEST(zynq_clk_get_pll_rate(priv, ddrpll_clk), div);
+}
+#endif
+
+static ulong zynq_clk_get_ddr3x_rate(struct zynq_clk_priv *priv)
+{
+	u32 clk_ctrl, div;
+
+	clk_ctrl = readl(&slcr_base->ddr_clk_ctrl);
+
+	div = (clk_ctrl & CLK_CTRL_DIV3X_MASK) >> CLK_CTRL_DIV3X_SHIFT;
+
+	return DIV_ROUND_CLOSEST(zynq_clk_get_pll_rate(priv, ddrpll_clk), div);
+}
+
+#ifndef CONFIG_SPL_BUILD
+static ulong zynq_clk_get_dci_rate(struct zynq_clk_priv *priv)
+{
+	u32 clk_ctrl, div0, div1;
+
+	clk_ctrl = readl(&slcr_base->dci_clk_ctrl);
+
+	div0 = (clk_ctrl & CLK_CTRL_DIV0_MASK) >> CLK_CTRL_DIV0_SHIFT;
+	div1 = (clk_ctrl & CLK_CTRL_DIV1_MASK) >> CLK_CTRL_DIV1_SHIFT;
+
+	return DIV_ROUND_CLOSEST(DIV_ROUND_CLOSEST(
+		zynq_clk_get_pll_rate(priv, ddrpll_clk), div0), div1);
+}
+#endif
+
+static ulong zynq_clk_get_peripheral_rate(struct zynq_clk_priv *priv,
+					  enum zynq_clk id, bool two_divs)
+{
+	enum zynq_clk pll;
+	u32 clk_ctrl, div0;
+	u32 div1 = 1;
+
+	clk_ctrl = readl(zynq_clk_get_register(id));
+
+	div0 = (clk_ctrl & CLK_CTRL_DIV0_MASK) >> CLK_CTRL_DIV0_SHIFT;
+	if (!div0)
+		div0 = 1;
+
+#ifndef CONFIG_SPL_BUILD
+	if (two_divs) {
+		div1 = (clk_ctrl & CLK_CTRL_DIV1_MASK) >> CLK_CTRL_DIV1_SHIFT;
+		if (!div1)
+			div1 = 1;
+	}
+#endif
+
+	pll = zynq_clk_get_peripheral_pll(clk_ctrl);
+
+	return
+		DIV_ROUND_CLOSEST(
+			DIV_ROUND_CLOSEST(
+				zynq_clk_get_pll_rate(priv, pll), div0),
+			div1);
+}
+
+#ifndef CONFIG_SPL_BUILD
+static ulong zynq_clk_get_gem_rate(struct zynq_clk_priv *priv, enum zynq_clk id)
+{
+	struct clk *parent;
+
+	if (zynq_clk_get_gem_rclk(id) == mio_clk)
+		return zynq_clk_get_peripheral_rate(priv, id, true);
+
+	parent = &priv->gem_emio_clk[id - gem0_clk];
+	if (parent->dev)
+		return clk_get_rate(parent);
+
+	debug("%s: gem%d emio rx clock source unknown\n", __func__,
+	      id - gem0_clk);
+
+	return -ENOSYS;
+}
+
+static unsigned long zynq_clk_calc_peripheral_two_divs(ulong rate,
+						       ulong pll_rate,
+						       u32 *div0, u32 *div1)
+{
+	long new_err, best_err = (long)(~0UL >> 1);
+	ulong new_rate, best_rate = 0;
+	u32 d0, d1;
+
+	for (d0 = 1; d0 <= ZYNQ_CLK_MAXDIV; d0++) {
+		for (d1 = 1; d1 <= ZYNQ_CLK_MAXDIV >> 1; d1++) {
+			new_rate = DIV_ROUND_CLOSEST(
+					DIV_ROUND_CLOSEST(pll_rate, d0), d1);
+			new_err = abs(new_rate - rate);
+
+			if (new_err < best_err) {
+				*div0 = d0;
+				*div1 = d1;
+				best_err = new_err;
+				best_rate = new_rate;
+			}
+		}
+	}
+
+	return best_rate;
+}
+
+static ulong zynq_clk_set_peripheral_rate(struct zynq_clk_priv *priv,
+					  enum zynq_clk id, ulong rate,
+					  bool two_divs)
+{
+	enum zynq_clk pll;
+	u32 clk_ctrl, div0 = 0, div1 = 0;
+	ulong pll_rate, new_rate;
+	u32 *reg;
+
+	reg = zynq_clk_get_register(id);
+	clk_ctrl = readl(reg);
+
+	pll = zynq_clk_get_peripheral_pll(clk_ctrl);
+	pll_rate = zynq_clk_get_pll_rate(priv, pll);
+	clk_ctrl &= ~CLK_CTRL_DIV0_MASK;
+	if (two_divs) {
+		clk_ctrl &= ~CLK_CTRL_DIV1_MASK;
+		new_rate = zynq_clk_calc_peripheral_two_divs(rate, pll_rate,
+				&div0, &div1);
+		clk_ctrl |= div1 << CLK_CTRL_DIV1_SHIFT;
+	} else {
+		div0 = DIV_ROUND_CLOSEST(pll_rate, rate);
+		if (div0 > ZYNQ_CLK_MAXDIV)
+			div0 = ZYNQ_CLK_MAXDIV;
+		new_rate = DIV_ROUND_CLOSEST(rate, div0);
+	}
+	clk_ctrl |= div0 << CLK_CTRL_DIV0_SHIFT;
+
+	zynq_slcr_unlock();
+	writel(clk_ctrl, reg);
+	zynq_slcr_lock();
+
+	return new_rate;
+}
+
+static ulong zynq_clk_set_gem_rate(struct zynq_clk_priv *priv, enum zynq_clk id,
+				   ulong rate)
+{
+	struct clk *parent;
+
+	if (zynq_clk_get_gem_rclk(id) == mio_clk)
+		return zynq_clk_set_peripheral_rate(priv, id, rate, true);
+
+	parent = &priv->gem_emio_clk[id - gem0_clk];
+	if (parent->dev)
+		return clk_set_rate(parent, rate);
+
+	debug("%s: gem%d emio rx clock source unknown\n", __func__,
+	      id - gem0_clk);
+
+	return -ENOSYS;
+}
+#endif
+
+#ifndef CONFIG_SPL_BUILD
+static ulong zynq_clk_get_rate(struct clk *clk)
+{
+	struct zynq_clk_priv *priv = dev_get_priv(clk->dev);
+	enum zynq_clk id = clk->id;
+	bool two_divs = false;
+
+	switch (id) {
+	case armpll_clk ... iopll_clk:
+		return zynq_clk_get_pll_rate(priv, id);
+	case cpu_6or4x_clk ... cpu_1x_clk:
+		return zynq_clk_get_cpu_rate(priv, id);
+	case ddr2x_clk:
+		return zynq_clk_get_ddr2x_rate(priv);
+	case ddr3x_clk:
+		return zynq_clk_get_ddr3x_rate(priv);
+	case dci_clk:
+		return zynq_clk_get_dci_rate(priv);
+	case gem0_clk ... gem1_clk:
+		return zynq_clk_get_gem_rate(priv, id);
+	case fclk0_clk ... can1_clk:
+		two_divs = true;
+		/* fall through */
+	case dbg_trc_clk ... dbg_apb_clk:
+	case lqspi_clk ... pcap_clk:
+	case sdio0_clk ... spi1_clk:
+		return zynq_clk_get_peripheral_rate(priv, id, two_divs);
+	case dma_clk:
+		return zynq_clk_get_cpu_rate(priv, cpu_2x_clk);
+	case usb0_aper_clk ... smc_aper_clk:
+		return zynq_clk_get_cpu_rate(priv, cpu_1x_clk);
+	default:
+		return -ENXIO;
+	}
+}
+
+static ulong zynq_clk_set_rate(struct clk *clk, ulong rate)
+{
+	struct zynq_clk_priv *priv = dev_get_priv(clk->dev);
+	enum zynq_clk id = clk->id;
+	bool two_divs = false;
+
+	switch (id) {
+	case gem0_clk ... gem1_clk:
+		return zynq_clk_set_gem_rate(priv, id, rate);
+	case fclk0_clk ... can1_clk:
+		two_divs = true;
+		/* fall through */
+	case lqspi_clk ... pcap_clk:
+	case sdio0_clk ... spi1_clk:
+	case dbg_trc_clk ... dbg_apb_clk:
+		return zynq_clk_set_peripheral_rate(priv, id, rate, two_divs);
+	default:
+		return -ENXIO;
+	}
+}
+#else
+static ulong zynq_clk_get_rate(struct clk *clk)
+{
+	struct zynq_clk_priv *priv = dev_get_priv(clk->dev);
+	enum zynq_clk id = clk->id;
+
+	switch (id) {
+	case cpu_6or4x_clk ... cpu_1x_clk:
+		return zynq_clk_get_cpu_rate(priv, id);
+	case ddr3x_clk:
+		return zynq_clk_get_ddr3x_rate(priv);
+	case lqspi_clk ... pcap_clk:
+	case sdio0_clk ... spi1_clk:
+		return zynq_clk_get_peripheral_rate(priv, id, 0);
+	default:
+		return -ENXIO;
+	}
+}
+#endif
+
+static struct clk_ops zynq_clk_ops = {
+	.get_rate = zynq_clk_get_rate,
+#ifndef CONFIG_SPL_BUILD
+	.set_rate = zynq_clk_set_rate,
+#endif
+};
+
+static int zynq_clk_probe(struct udevice *dev)
+{
+	struct zynq_clk_priv *priv = dev_get_priv(dev);
+#ifndef CONFIG_SPL_BUILD
+	unsigned int i;
+	char name[16];
+	int ret;
+
+	for (i = 0; i < 2; i++) {
+		sprintf(name, "gem%d_emio_clk", i);
+		ret = clk_get_by_name(dev, name, &priv->gem_emio_clk[i]);
+		if (ret < 0 && ret != -FDT_ERR_NOTFOUND) {
+			dev_err(dev, "failed to get %s clock\n", name);
+			return ret;
+		}
+	}
+#endif
+
+	priv->ps_clk_freq = fdtdec_get_uint(gd->fdt_blob, dev->of_offset,
+					    "ps-clk-frequency", 33333333UL);
+
+	return 0;
+}
+
+static const struct udevice_id zynq_clk_ids[] = {
+	{ .compatible = "xlnx,ps7-clkc"},
+	{}
+};
+
+U_BOOT_DRIVER(zynq_clk) = {
+	.name		= "zynq_clk",
+	.id		= UCLASS_CLK,
+	.of_match	= zynq_clk_ids,
+	.flags		= DM_FLAG_PRE_RELOC,
+	.ops		= &zynq_clk_ops,
+	.priv_auto_alloc_size = sizeof(struct zynq_clk_priv),
+	.probe		= zynq_clk_probe,
+};
diff --git a/drivers/mmc/zynq_sdhci.c b/drivers/mmc/zynq_sdhci.c
index 69efa38..28cedf0 100644
--- a/drivers/mmc/zynq_sdhci.c
+++ b/drivers/mmc/zynq_sdhci.c
@@ -6,6 +6,7 @@
  * SPDX-License-Identifier:	GPL-2.0+
  */
 
+#include <clk.h>
 #include <common.h>
 #include <dm.h>
 #include <fdtdec.h>
@@ -13,6 +14,8 @@
 #include <malloc.h>
 #include <sdhci.h>
 
+DECLARE_GLOBAL_DATA_PTR;
+
 #ifndef CONFIG_ZYNQ_SDHCI_MIN_FREQ
 # define CONFIG_ZYNQ_SDHCI_MIN_FREQ	0
 #endif
@@ -20,6 +23,7 @@
 struct arasan_sdhci_plat {
 	struct mmc_config cfg;
 	struct mmc mmc;
+	unsigned int f_max;
 };
 
 static int arasan_sdhci_probe(struct udevice *dev)
@@ -27,8 +31,29 @@
 	struct arasan_sdhci_plat *plat = dev_get_platdata(dev);
 	struct mmc_uclass_priv *upriv = dev_get_uclass_priv(dev);
 	struct sdhci_host *host = dev_get_priv(dev);
+	struct clk clk;
+	unsigned long clock;
 	int ret;
 
+	ret = clk_get_by_index(dev, 0, &clk);
+	if (ret < 0) {
+		dev_err(dev, "failed to get clock\n");
+		return ret;
+	}
+
+	clock = clk_get_rate(&clk);
+	if (IS_ERR_VALUE(clock)) {
+		dev_err(dev, "failed to get rate\n");
+		return clock;
+	}
+	debug("%s: CLK %ld\n", __func__, clock);
+
+	ret = clk_enable(&clk);
+	if (ret && ret != -ENOSYS) {
+		dev_err(dev, "failed to enable clock\n");
+		return ret;
+	}
+
 	host->quirks = SDHCI_QUIRK_WAIT_SEND_CMD |
 		       SDHCI_QUIRK_BROKEN_R1B;
 
@@ -36,9 +61,9 @@
 	host->quirks |= SDHCI_QUIRK_NO_HISPD_BIT;
 #endif
 
-	host->max_clk = CONFIG_ZYNQ_SDHCI_MAX_FREQ;
+	host->max_clk = clock;
 
-	ret = sdhci_setup_cfg(&plat->cfg, host, 0,
+	ret = sdhci_setup_cfg(&plat->cfg, host, plat->f_max,
 			      CONFIG_ZYNQ_SDHCI_MIN_FREQ);
 	host->mmc = &plat->mmc;
 	if (ret)
@@ -52,11 +77,15 @@
 
 static int arasan_sdhci_ofdata_to_platdata(struct udevice *dev)
 {
+	struct arasan_sdhci_plat *plat = dev_get_platdata(dev);
 	struct sdhci_host *host = dev_get_priv(dev);
 
 	host->name = dev->name;
 	host->ioaddr = (void *)dev_get_addr(dev);
 
+	plat->f_max = fdtdec_get_int(gd->fdt_blob, dev->of_offset,
+				"max-frequency", CONFIG_ZYNQ_SDHCI_MAX_FREQ);
+
 	return 0;
 }
 
diff --git a/drivers/net/fsl-mc/mc.c b/drivers/net/fsl-mc/mc.c
index 079082a..9f69d75 100644
--- a/drivers/net/fsl-mc/mc.c
+++ b/drivers/net/fsl-mc/mc.c
@@ -154,48 +154,6 @@
 }
 #endif
 
-/*
- * Calculates the values to be used to specify the address range
- * for the MC private DRAM block, in the MCFBALR/MCFBAHR registers.
- * It returns the highest 512MB-aligned address within the given
- * address range, in '*aligned_base_addr', and the number of 256 MiB
- * blocks in it, in 'num_256mb_blocks'.
- */
-static int calculate_mc_private_ram_params(u64 mc_private_ram_start_addr,
-					   size_t mc_ram_size,
-					   u64 *aligned_base_addr,
-					   u8 *num_256mb_blocks)
-{
-	u64 addr;
-	u16 num_blocks;
-
-	if (mc_ram_size % MC_RAM_SIZE_ALIGNMENT != 0) {
-		printf("fsl-mc: ERROR: invalid MC private RAM size (%lu)\n",
-		       mc_ram_size);
-		return -EINVAL;
-	}
-
-	num_blocks = mc_ram_size / MC_RAM_SIZE_ALIGNMENT;
-	if (num_blocks < 1 || num_blocks > 0xff) {
-		printf("fsl-mc: ERROR: invalid MC private RAM size (%lu)\n",
-		       mc_ram_size);
-		return -EINVAL;
-	}
-
-	addr = (mc_private_ram_start_addr + mc_ram_size - 1) &
-		MC_RAM_BASE_ADDR_ALIGNMENT_MASK;
-
-	if (addr < mc_private_ram_start_addr) {
-		printf("fsl-mc: ERROR: bad start address %#llx\n",
-		       mc_private_ram_start_addr);
-		return -EFAULT;
-	}
-
-	*aligned_base_addr = addr;
-	*num_256mb_blocks = num_blocks;
-	return 0;
-}
-
 static int mc_fixup_dpc_mac_addr(void *blob, int noff, int dpmac_id,
 		struct eth_device *eth_dev)
 {
@@ -550,17 +508,16 @@
 	size_t raw_image_size = 0;
 #endif
 	struct mc_version mc_ver_info;
-	u64 mc_ram_aligned_base_addr;
 	u8 mc_ram_num_256mb_blocks;
 	size_t mc_ram_size = mc_get_dram_block_size();
 
-
-	error = calculate_mc_private_ram_params(mc_ram_addr,
-						mc_ram_size,
-						&mc_ram_aligned_base_addr,
-						&mc_ram_num_256mb_blocks);
-	if (error != 0)
+	mc_ram_num_256mb_blocks = mc_ram_size / MC_RAM_SIZE_ALIGNMENT;
+	if (mc_ram_num_256mb_blocks < 1 || mc_ram_num_256mb_blocks > 0xff) {
+		error = -EINVAL;
+		printf("fsl-mc: ERROR: invalid MC private RAM size (%lu)\n",
+		       mc_ram_size);
 		goto out;
+	}
 
 	/*
 	 * Management Complex cores should be held at reset out of POR.
@@ -602,11 +559,11 @@
 	/*
 	 * Tell MC what is the address range of the DRAM block assigned to it:
 	 */
-	reg_mcfbalr = (u32)mc_ram_aligned_base_addr |
+	reg_mcfbalr = (u32)mc_ram_addr |
 		      (mc_ram_num_256mb_blocks - 1);
 	out_le32(&mc_ccsr_regs->reg_mcfbalr, reg_mcfbalr);
 	out_le32(&mc_ccsr_regs->reg_mcfbahr,
-		 (u32)(mc_ram_aligned_base_addr >> 32));
+		 (u32)(mc_ram_addr >> 32));
 	out_le32(&mc_ccsr_regs->reg_mcfapr, FSL_BYPASS_AMQ);
 
 	/*
@@ -714,21 +671,7 @@
  */
 u64 mc_get_dram_addr(void)
 {
-	u64 mc_ram_addr;
-
-	/*
-	 * The MC private DRAM block was already carved at the end of DRAM
-	 * by board_init_f() using CONFIG_SYS_MEM_TOP_HIDE:
-	 */
-	if (gd->bd->bi_dram[1].start) {
-		mc_ram_addr =
-			gd->bd->bi_dram[1].start + gd->bd->bi_dram[1].size;
-	} else {
-		mc_ram_addr =
-			gd->bd->bi_dram[0].start + gd->bd->bi_dram[0].size;
-	}
-
-	return mc_ram_addr;
+	return gd->arch.resv_ram;
 }
 
 /**
diff --git a/drivers/net/zynq_gem.c b/drivers/net/zynq_gem.c
index a160564..357f8c2 100644
--- a/drivers/net/zynq_gem.c
+++ b/drivers/net/zynq_gem.c
@@ -175,16 +175,13 @@
 	u32 rxbd_current;
 	u32 rx_first_buf;
 	int phyaddr;
-	u32 emio;
 	int init;
 	struct zynq_gem_regs *iobase;
 	phy_interface_t interface;
 	struct phy_device *phydev;
 	int phy_of_handle;
 	struct mii_dev *bus;
-#ifdef CONFIG_CLK_ZYNQMP
 	struct clk clk;
-#endif
 };
 
 static u32 phy_setup_op(struct zynq_gem_priv *priv, u32 phy_addr, u32 regnum,
@@ -457,16 +454,17 @@
 		break;
 	}
 
-	/* Change the rclk and clk only not using EMIO interface */
-	if (!priv->emio)
-#ifndef CONFIG_CLK_ZYNQMP
-		zynq_slcr_gem_clk_setup((ulong)priv->iobase !=
-					ZYNQ_GEM_BASEADDR0, clk_rate);
-#else
-		ret = clk_set_rate(&priv->clk, clk_rate);
-		if (IS_ERR_VALUE(ret))
-			return -1;
-#endif
+	ret = clk_set_rate(&priv->clk, clk_rate);
+	if (IS_ERR_VALUE(ret) && ret != (unsigned long)-ENOSYS) {
+		dev_err(dev, "failed to set tx clock rate\n");
+		return ret;
+	}
+
+	ret = clk_enable(&priv->clk);
+	if (ret && ret != -ENOSYS) {
+		dev_err(dev, "failed to enable tx clock\n");
+		return ret;
+	}
 
 	setbits_le32(&regs->nwctrl, ZYNQ_GEM_NWCTRL_RXEN_MASK |
 					ZYNQ_GEM_NWCTRL_TXEN_MASK);
@@ -639,13 +637,11 @@
 	priv->tx_bd = (struct emac_bd *)bd_space;
 	priv->rx_bd = (struct emac_bd *)((ulong)bd_space + BD_SEPRN_SPACE);
 
-#ifdef CONFIG_CLK_ZYNQMP
 	ret = clk_get_by_name(dev, "tx_clk", &priv->clk);
 	if (ret < 0) {
 		dev_err(dev, "failed to get clock\n");
 		return -EINVAL;
 	}
-#endif
 
 	priv->bus = mdio_alloc();
 	priv->bus->read = zynq_gem_miiphy_read;
@@ -690,7 +686,6 @@
 	pdata->iobase = (phys_addr_t)dev_get_addr(dev);
 	priv->iobase = (struct zynq_gem_regs *)pdata->iobase;
 	/* Hardcode for now */
-	priv->emio = 0;
 	priv->phyaddr = -1;
 
 	priv->phy_of_handle = fdtdec_lookup_phandle(gd->fdt_blob, node,
@@ -708,8 +703,6 @@
 	}
 	priv->interface = pdata->phy_interface;
 
-	priv->emio = fdtdec_get_bool(gd->fdt_blob, node, "xlnx,emio");
-
 	printf("ZYNQ GEM: %lx, phyaddr %x, interface %s\n", (ulong)priv->iobase,
 	       priv->phyaddr, phy_string_for_interface(priv->interface));
 
diff --git a/drivers/pinctrl/Kconfig b/drivers/pinctrl/Kconfig
index 2eab9bd..f3e3072 100644
--- a/drivers/pinctrl/Kconfig
+++ b/drivers/pinctrl/Kconfig
@@ -203,6 +203,15 @@
 	  the GPIO definitions and pin control functions for each available multiplex
 	  function.
 
+config PINCTRL_STM32
+	bool "ST STM32 pin control driver"
+	depends on DM
+	help
+	  Supports pin multiplexing control on stm32 SoCs. The driver is
+	  controlled by a device tree node which contains both the GPIO
+	  definitions and pin control functions for each available multiplex
+	  function.
+
 endif
 
 source "drivers/pinctrl/meson/Kconfig"
diff --git a/drivers/pinctrl/Makefile b/drivers/pinctrl/Makefile
index a2f8101..b04ca86 100644
--- a/drivers/pinctrl/Makefile
+++ b/drivers/pinctrl/Makefile
@@ -17,3 +17,4 @@
 obj-$(CONFIG_PINCTRL_MESON)	+= meson/
 obj-$(CONFIG_PINCTRL_MVEBU)	+= mvebu/
 obj-$(CONFIG_PINCTRL_STI)	+= pinctrl-sti.o
+obj-$(CONFIG_PINCTRL_STM32)	+= pinctrl_stm32.o
diff --git a/drivers/pinctrl/pinctrl_stm32.c b/drivers/pinctrl/pinctrl_stm32.c
new file mode 100644
index 0000000..aa2c440
--- /dev/null
+++ b/drivers/pinctrl/pinctrl_stm32.c
@@ -0,0 +1,117 @@
+#include <common.h>
+#include <asm/arch/gpio.h>
+#include <dm.h>
+#include <dm/pinctrl.h>
+
+DECLARE_GLOBAL_DATA_PTR;
+
+static int prep_gpio_dsc(struct stm32_gpio_dsc *gpio_dsc, u32 port_pin)
+{
+	gpio_dsc->port = (port_pin & 0xF000) >> 12;
+	gpio_dsc->pin = (port_pin & 0x0F00) >> 8;
+	debug("%s: GPIO:port= %d, pin= %d\n", __func__, gpio_dsc->port,
+	      gpio_dsc->pin);
+
+	return 0;
+}
+
+static int prep_gpio_ctl(struct stm32_gpio_ctl *gpio_ctl, u32 gpio_fn, int node)
+{
+	gpio_fn &= 0x00FF;
+
+	switch (gpio_fn) {
+	case 0:
+		gpio_ctl->mode = STM32_GPIO_MODE_IN;
+		break;
+	case 1 ... 16:
+		gpio_ctl->mode = STM32_GPIO_MODE_AF;
+		gpio_ctl->af = gpio_fn - 1;
+		break;
+	case 17:
+		gpio_ctl->mode = STM32_GPIO_MODE_AN;
+		break;
+	default:
+		gpio_ctl->mode = STM32_GPIO_MODE_OUT;
+		break;
+	}
+
+	gpio_ctl->speed = fdtdec_get_int(gd->fdt_blob, node, "slew-rate", 0);
+
+	if (fdtdec_get_bool(gd->fdt_blob, node, "drive-open-drain"))
+		gpio_ctl->otype = STM32_GPIO_OTYPE_OD;
+	else
+		gpio_ctl->otype = STM32_GPIO_OTYPE_PP;
+
+	if (fdtdec_get_bool(gd->fdt_blob, node, "bias-pull-up"))
+		gpio_ctl->pupd = STM32_GPIO_PUPD_UP;
+	else if (fdtdec_get_bool(gd->fdt_blob, node, "bias-pull-down"))
+		gpio_ctl->pupd = STM32_GPIO_PUPD_DOWN;
+	else
+		gpio_ctl->pupd = STM32_GPIO_PUPD_NO;
+
+	debug("%s: gpio fn= %d, slew-rate= %x, op type= %x, pull-upd is = %x\n",
+	      __func__,  gpio_fn, gpio_ctl->speed, gpio_ctl->otype,
+	     gpio_ctl->pupd);
+
+	return 0;
+}
+
+static int stm32_pinctrl_set_state_simple(struct udevice *dev,
+					  struct udevice *periph)
+{
+	u32 pin_mux[50];
+	struct fdtdec_phandle_args args;
+	int rv, len;
+
+	/* Get node pinctrl-0 */
+	rv = fdtdec_parse_phandle_with_args(gd->fdt_blob, periph->of_offset,
+					   "pinctrl-0", 0, 0, 0, &args);
+	if (rv)
+		return rv;
+	/*
+	 * check for "pinmux" property in each subnode (e.g. pins1 and pins2 for
+	 * usart1) of pin controller phandle "pinctrl-0"
+	 * */
+	fdt_for_each_subnode(args.node, gd->fdt_blob, args.node) {
+		struct stm32_gpio_dsc gpio_dsc;
+		struct stm32_gpio_ctl gpio_ctl;
+		int i;
+
+		len = fdtdec_get_int_array_count(gd->fdt_blob, args.node,
+						 "pinmux", pin_mux,
+						 ARRAY_SIZE(pin_mux));
+		debug("%s: periph->name = %s, no of pinmux entries= %d\n",
+		      __func__, periph->name, len);
+		if (len < 0)
+			return -EINVAL;
+		for (i = 0; i < len; i++) {
+			debug("%s: pinmux = %x\n", __func__, *(pin_mux + i));
+			prep_gpio_dsc(&gpio_dsc, *(pin_mux + i));
+			prep_gpio_ctl(&gpio_ctl, *(pin_mux + i), args.node);
+
+			rv = stm32_gpio_config(&gpio_dsc, &gpio_ctl);
+			debug("%s: rv = %d\n\n", __func__, rv);
+			if (rv)
+				return rv;
+		}
+	}
+
+	return 0;
+}
+
+static struct pinctrl_ops stm32_pinctrl_ops = {
+	.set_state_simple	= stm32_pinctrl_set_state_simple,
+};
+
+static const struct udevice_id stm32_pinctrl_ids[] = {
+	{ .compatible = "st,stm32f746-pinctrl" },
+	{ }
+};
+
+U_BOOT_DRIVER(pinctrl_stm32) = {
+	.name		= "pinctrl_stm32",
+	.id		= UCLASS_PINCTRL,
+	.of_match	= stm32_pinctrl_ids,
+	.ops		= &stm32_pinctrl_ops,
+	.bind		= dm_scan_fdt_dev,
+};
diff --git a/drivers/serial/serial_stm32x7.c b/drivers/serial/serial_stm32x7.c
index 592c0bd..1907cef 100644
--- a/drivers/serial/serial_stm32x7.c
+++ b/drivers/serial/serial_stm32x7.c
@@ -6,6 +6,7 @@
  */
 
 #include <common.h>
+#include <clk.h>
 #include <dm.h>
 #include <asm/io.h>
 #include <serial.h>
@@ -76,10 +77,48 @@
 {
 	struct stm32x7_serial_platdata *plat = dev->platdata;
 	struct stm32_usart *const usart = plat->base;
+
+#ifdef CONFIG_CLK
+	int ret;
+	struct clk clk;
+
+	ret = clk_get_by_index(dev, 0, &clk);
+	if (ret < 0)
+		return ret;
+
+	ret = clk_enable(&clk);
+	if (ret) {
+		dev_err(dev, "failed to enable clock\n");
+		return ret;
+	}
+#endif
+
 	setbits_le32(&usart->cr1, USART_CR1_RE | USART_CR1_TE | USART_CR1_UE);
 
 	return 0;
 }
+
+#if CONFIG_IS_ENABLED(OF_CONTROL)
+static const struct udevice_id stm32_serial_id[] = {
+	{.compatible = "st,stm32-usart"},
+	{.compatible = "st,stm32-uart"},
+	{}
+};
+
+static int stm32_serial_ofdata_to_platdata(struct udevice *dev)
+{
+	struct stm32x7_serial_platdata *plat = dev_get_platdata(dev);
+	fdt_addr_t addr;
+
+	addr = dev_get_addr(dev);
+	if (addr == FDT_ADDR_T_NONE)
+		return -EINVAL;
+
+	plat->base = (struct stm32_usart *)addr;
+
+	return 0;
+}
+#endif
 
 static const struct dm_serial_ops stm32_serial_ops = {
 	.putc = stm32_serial_putc,
@@ -91,6 +130,9 @@
 U_BOOT_DRIVER(serial_stm32) = {
 	.name = "serial_stm32x7",
 	.id = UCLASS_SERIAL,
+	.of_match = of_match_ptr(stm32_serial_id),
+	.ofdata_to_platdata = of_match_ptr(stm32_serial_ofdata_to_platdata),
+	.platdata_auto_alloc_size = sizeof(struct stm32x7_serial_platdata),
 	.ops = &stm32_serial_ops,
 	.probe = stm32_serial_probe,
 	.flags = DM_FLAG_PRE_RELOC,
diff --git a/drivers/serial/serial_zynq.c b/drivers/serial/serial_zynq.c
index 4f6e7e4..a2967c0 100644
--- a/drivers/serial/serial_zynq.c
+++ b/drivers/serial/serial_zynq.c
@@ -15,7 +15,6 @@
 #include <asm/io.h>
 #include <linux/compiler.h>
 #include <serial.h>
-#include <asm/arch/clk.h>
 #include <asm/arch/hardware.h>
 
 DECLARE_GLOBAL_DATA_PTR;
@@ -111,7 +110,6 @@
 	struct zynq_uart_priv *priv = dev_get_priv(dev);
 	unsigned long clock;
 
-#if defined(CONFIG_CLK) || defined(CONFIG_SPL_CLK)
 	int ret;
 	struct clk clk;
 
@@ -133,9 +131,7 @@
 		dev_err(dev, "failed to enable clock\n");
 		return ret;
 	}
-#else
-	clock = get_uart_clk(0);
-#endif
+
 	_uart_zynq_serial_setbrg(priv->regs, clock, baudrate);
 
 	return 0;
diff --git a/include/configs/dragonboard410c.h b/include/configs/dragonboard410c.h
index 7f0742a..238f4cd 100644
--- a/include/configs/dragonboard410c.h
+++ b/include/configs/dragonboard410c.h
@@ -46,12 +46,8 @@
 #define CONFIG_USB_ETHER_MCS7830
 #define CONFIG_USB_ETHER_SMSC95XX
 
-/* Libraries  */
-#define CONFIG_MD5
-
 /* Extra Commands */
 #define CONFIG_CMD_ENV
-#define CONFIG_CMD_MD5SUM
 /* Enable that for switching of boot partitions */
 /* Disabled by default as some sub-commands can brick eMMC */
 /*#define CONFIG_SUPPORT_EMMC_BOOT */
diff --git a/include/configs/ls1021atwr.h b/include/configs/ls1021atwr.h
index 7279c89..fe87ab3 100644
--- a/include/configs/ls1021atwr.h
+++ b/include/configs/ls1021atwr.h
@@ -133,9 +133,9 @@
  * size increases then increase this size in case of secure boot as
  * it uses raw u-boot image instead of fit image.
  */
-#define CONFIG_SYS_MONITOR_LEN		(0x80000 + CONFIG_U_BOOT_HDR_SIZE)
+#define CONFIG_SYS_MONITOR_LEN		(0x100000 + CONFIG_U_BOOT_HDR_SIZE)
 #else
-#define CONFIG_SYS_MONITOR_LEN		0x80000
+#define CONFIG_SYS_MONITOR_LEN		0x100000
 #endif /* ifdef CONFIG_U_BOOT_HDR_SIZE */
 #endif
 
diff --git a/include/configs/ls1043aqds.h b/include/configs/ls1043aqds.h
index f3b521d..6a345c0 100644
--- a/include/configs/ls1043aqds.h
+++ b/include/configs/ls1043aqds.h
@@ -38,7 +38,9 @@
 #define SPD_EEPROM_ADDRESS		0x51
 #define CONFIG_SYS_SPD_BUS_NUM		0
 
+#ifndef CONFIG_SPL
 #define CONFIG_FSL_DDR_INTERACTIVE	/* Interactive debugging */
+#endif
 
 #define CONFIG_DDR_ECC
 #ifdef CONFIG_DDR_ECC
diff --git a/include/configs/ls1043ardb.h b/include/configs/ls1043ardb.h
index 8fa3bb3..f185380 100644
--- a/include/configs/ls1043ardb.h
+++ b/include/configs/ls1043ardb.h
@@ -29,7 +29,9 @@
 #define CONFIG_SYS_SPD_BUS_NUM		0
 
 #define CONFIG_FSL_DDR_BIST
+#ifndef CONFIG_SPL
 #define CONFIG_FSL_DDR_INTERACTIVE	/* Interactive debugging */
+#endif
 #define CONFIG_SYS_DDR_RAW_TIMING
 #define CONFIG_ECC_INIT_VIA_DDRCONTROLLER
 #define CONFIG_MEM_INIT_VALUE           0xdeadbeef
diff --git a/include/configs/ls1046aqds.h b/include/configs/ls1046aqds.h
index cba22ca..4b3b21e 100644
--- a/include/configs/ls1046aqds.h
+++ b/include/configs/ls1046aqds.h
@@ -38,7 +38,9 @@
 #define SPD_EEPROM_ADDRESS		0x51
 #define CONFIG_SYS_SPD_BUS_NUM		0
 
+#ifndef CONFIG_SPL
 #define CONFIG_FSL_DDR_INTERACTIVE	/* Interactive debugging */
+#endif
 
 #define CONFIG_DDR_ECC
 #ifdef CONFIG_DDR_ECC
diff --git a/include/configs/ls1046ardb.h b/include/configs/ls1046ardb.h
index a96aa65..2141b82 100644
--- a/include/configs/ls1046ardb.h
+++ b/include/configs/ls1046ardb.h
@@ -34,7 +34,9 @@
 #define CONFIG_ECC_INIT_VIA_DDRCONTROLLER
 #define CONFIG_MEM_INIT_VALUE           0xdeadbeef
 #define CONFIG_FSL_DDR_BIST	/* enable built-in memory test */
+#ifndef CONFIG_SPL
 #define CONFIG_FSL_DDR_INTERACTIVE	/* Interactive debugging */
+#endif
 
 #ifdef CONFIG_RAMBOOT_PBL
 #define CONFIG_SYS_FSL_PBL_PBI board/freescale/ls1046ardb/ls1046ardb_pbi.cfg
diff --git a/include/configs/ls2080a_common.h b/include/configs/ls2080a_common.h
index 4ba273a..816d7f5 100644
--- a/include/configs/ls2080a_common.h
+++ b/include/configs/ls2080a_common.h
@@ -141,7 +141,6 @@
 #define CONFIG_SYS_NAND_BASE_PHYS		0x30000000
 
 /* MC firmware */
-#define CONFIG_FSL_MC_ENET
 /* TODO Actual DPL max length needs to be confirmed with the MC FW team */
 #define CONFIG_SYS_LS_MC_DPC_MAX_LENGTH	    0x20000
 #define CONFIG_SYS_LS_MC_DRAM_DPC_OFFSET    0x00F00000
@@ -159,7 +158,6 @@
  */
 #ifdef CONFIG_FSL_MC_ENET
 #define CONFIG_SYS_LS_MC_DRAM_BLOCK_MIN_SIZE		(512UL * 1024 * 1024)
-#define CONFIG_SYS_MC_RSV_MEM_ALIGN			(512UL * 1024 * 1024)
 #endif
 
 /* Command line configuration */
diff --git a/include/configs/sandbox.h b/include/configs/sandbox.h
index ac7973c..ad687b1 100644
--- a/include/configs/sandbox.h
+++ b/include/configs/sandbox.h
@@ -44,7 +44,6 @@
 #define CONFIG_CMD_CBFS
 #define CONFIG_CMD_CRAMFS
 #define CONFIG_HOST_MAX_DEVICES 4
-#define CONFIG_CMD_MD5SUM
 
 /*
  * Size of malloc() pool, before and after relocation
diff --git a/include/configs/sh7752evb.h b/include/configs/sh7752evb.h
index d818981..9b12324 100644
--- a/include/configs/sh7752evb.h
+++ b/include/configs/sh7752evb.h
@@ -16,8 +16,6 @@
 
 #define CONFIG_CMD_DFL
 #define CONFIG_CMD_SDRAM
-#define CONFIG_CMD_MD5SUM
-#define CONFIG_MD5
 
 #define CONFIG_BAUDRATE		115200
 #define CONFIG_BOOTARGS		"console=ttySC2,115200 root=/dev/nfs ip=dhcp"
diff --git a/include/configs/sh7753evb.h b/include/configs/sh7753evb.h
index a7d8de4..a4818ff 100644
--- a/include/configs/sh7753evb.h
+++ b/include/configs/sh7753evb.h
@@ -16,8 +16,6 @@
 
 #define CONFIG_CMD_DFL
 #define CONFIG_CMD_SDRAM
-#define CONFIG_CMD_MD5SUM
-#define CONFIG_MD5
 
 #define CONFIG_BAUDRATE		115200
 #define CONFIG_BOOTARGS		"console=ttySC2,115200 root=/dev/nfs ip=dhcp"
diff --git a/include/configs/sh7757lcr.h b/include/configs/sh7757lcr.h
index c21a5f8..8b33998 100644
--- a/include/configs/sh7757lcr.h
+++ b/include/configs/sh7757lcr.h
@@ -16,8 +16,6 @@
 #define CONFIG_SYS_TEXT_BASE	0x8ef80000
 
 #define CONFIG_CMD_SDRAM
-#define CONFIG_CMD_MD5SUM
-#define CONFIG_MD5
 
 #define CONFIG_BAUDRATE		115200
 #define CONFIG_BOOTARGS		"console=ttySC2,115200 root=/dev/nfs ip=dhcp"
diff --git a/include/configs/stih410-b2260.h b/include/configs/stih410-b2260.h
index 28e2f7f..c7785b3 100644
--- a/include/configs/stih410-b2260.h
+++ b/include/configs/stih410-b2260.h
@@ -22,9 +22,6 @@
 
 #define CONFIG_SYS_HZ_CLOCK		1000000000	/* 1 GHz */
 
-/* Libraries */
-#define CONFIG_MD5
-
 #define CONFIG_BOOTARGS							\
 	"console=ttyS0,115200 earlyprintk consoleblank=0 ignore_loglevel"
 
diff --git a/include/configs/topic_miami.h b/include/configs/topic_miami.h
index 42cfbb0..a56ceef 100644
--- a/include/configs/topic_miami.h
+++ b/include/configs/topic_miami.h
@@ -10,8 +10,6 @@
 #ifndef __CONFIG_TOPIC_MIAMI_H
 #define __CONFIG_TOPIC_MIAMI_H
 
-#define CONFIG_ZYNQ_PS_CLK_FREQ		33333333UL
-
 #define CONFIG_ZYNQ_I2C0
 #define CONFIG_ZYNQ_I2C1
 
diff --git a/include/configs/zynq_zybo.h b/include/configs/zynq_zybo.h
index b9ff391..1488fd8 100644
--- a/include/configs/zynq_zybo.h
+++ b/include/configs/zynq_zybo.h
@@ -20,9 +20,6 @@
 #define CONFIG_DISPLAY
 #define CONFIG_I2C_EDID
 
-/* Define ZYBO PS Clock Frequency to 50MHz */
-#define CONFIG_ZYNQ_PS_CLK_FREQ	50000000UL
-
 #include <configs/zynq-common.h>
 
 #endif /* __CONFIG_ZYNQ_ZYBO_H */
diff --git a/include/image.h b/include/image.h
index 1e686b7..2372518 100644
--- a/include/image.h
+++ b/include/image.h
@@ -67,7 +67,6 @@
 #  endif
 # else
 #  define CONFIG_CRC32		/* FIT images need CRC32 support */
-#  define CONFIG_MD5		/* and MD5 */
 #  define CONFIG_SHA1		/* and SHA1 */
 #  define CONFIG_SHA256		/* and SHA256 */
 #  define IMAGE_ENABLE_CRC32	1
diff --git a/lib/Kconfig b/lib/Kconfig
index b16062f..65c0157 100644
--- a/lib/Kconfig
+++ b/lib/Kconfig
@@ -101,6 +101,10 @@
 	  SHA1/SHA256 progressive hashing.
 	  Data can be streamed in a block at a time and the hashing
 	  is performed in hardware.
+
+config MD5
+	bool
+
 endmenu
 
 menu "Compression Support"
diff --git a/lib/efi_loader/efi_memory.c b/lib/efi_loader/efi_memory.c
index 95aa590..db2ae19 100644
--- a/lib/efi_loader/efi_memory.c
+++ b/lib/efi_loader/efi_memory.c
@@ -431,11 +431,8 @@
 	return EFI_SUCCESS;
 }
 
-int efi_memory_init(void)
+__weak void efi_add_known_memory(void)
 {
-	unsigned long runtime_start, runtime_end, runtime_pages;
-	unsigned long uboot_start, uboot_pages;
-	unsigned long uboot_stack_size = 16 * 1024 * 1024;
 	int i;
 
 	/* Add RAM */
@@ -448,6 +445,15 @@
 		efi_add_memory_map(start, pages, EFI_CONVENTIONAL_MEMORY,
 				   false);
 	}
+}
+
+int efi_memory_init(void)
+{
+	unsigned long runtime_start, runtime_end, runtime_pages;
+	unsigned long uboot_start, uboot_pages;
+	unsigned long uboot_stack_size = 16 * 1024 * 1024;
+
+	efi_add_known_memory();
 
 	/* Add U-Boot */
 	uboot_start = (gd->start_addr_sp - uboot_stack_size) & ~EFI_PAGE_MASK;
diff --git a/scripts/config_whitelist.txt b/scripts/config_whitelist.txt
index f38e56c..668f238 100644
--- a/scripts/config_whitelist.txt
+++ b/scripts/config_whitelist.txt
@@ -509,7 +509,6 @@
 CONFIG_CMD_LOADY
 CONFIG_CMD_LZMADEC
 CONFIG_CMD_MAX6957
-CONFIG_CMD_MD5SUM
 CONFIG_CMD_MEM
 CONFIG_CMD_MFSL
 CONFIG_CMD_MMC_SPI
@@ -1163,7 +1162,6 @@
 CONFIG_FSL_LBC
 CONFIG_FSL_LINFLEXUART
 CONFIG_FSL_MC9SDZ60
-CONFIG_FSL_MC_ENET
 CONFIG_FSL_MEMAC
 CONFIG_FSL_NFC_CHIPS
 CONFIG_FSL_NFC_SPARE_SIZE
@@ -1882,8 +1880,6 @@
 CONFIG_MCFTMR
 CONFIG_MCFUART
 CONFIG_MCLK_DIS
-CONFIG_MD5
-CONFIG_MD5SUM_VERIFY
 CONFIG_MDIO_TIMEOUT
 CONFIG_MECP5123
 CONFIG_MEMSIZE
@@ -4976,7 +4972,6 @@
 CONFIG_SYS_MCLINK_MAX
 CONFIG_SYS_MCMEM0_VAL
 CONFIG_SYS_MCMEM1_VAL
-CONFIG_SYS_MC_RSV_MEM_ALIGN
 CONFIG_SYS_MDC1_PIN
 CONFIG_SYS_MDCNFG_VAL
 CONFIG_SYS_MDC_PIN
@@ -6850,7 +6845,6 @@
 CONFIG_ZYNQ_HISPD_BROKEN
 CONFIG_ZYNQ_I2C0
 CONFIG_ZYNQ_I2C1
-CONFIG_ZYNQ_PS_CLK_FREQ
 CONFIG_ZYNQ_SDHCI0
 CONFIG_ZYNQ_SDHCI1
 CONFIG_ZYNQ_SDHCI_MAX_FREQ