Merge branch 'master' of git://git.denx.de/u-boot-socfpga
diff --git a/arch/arm/dts/socfpga_arria10.dtsi b/arch/arm/dts/socfpga_arria10.dtsi
index ce00051..46f2fd4 100644
--- a/arch/arm/dts/socfpga_arria10.dtsi
+++ b/arch/arm/dts/socfpga_arria10.dtsi
@@ -21,6 +21,11 @@
 	#address-cells = <1>;
 	#size-cells = <1>;
 
+	chosen {
+		tick-timer = &timer2;
+		u-boot,dm-pre-reloc;
+	};
+
 	cpus {
 		#address-cells = <1>;
 		#size-cells = <0>;
@@ -147,6 +152,7 @@
 							compatible = "altr,socfpga-a10-perip-clk";
 							clocks = <&main_pll>;
 							div-reg = <0x144 0 11>;
+							u-boot,dm-pre-reloc;
 						};
 
 						main_emaca_clk: main_emaca_clk@68 {
@@ -236,6 +242,7 @@
 							compatible = "altr,socfpga-a10-perip-clk";
 							clocks = <&periph_pll>;
 							div-reg = <0x144 16 11>;
+							u-boot,dm-pre-reloc;
 						};
 
 						peri_emaca_clk: peri_emaca_clk@e8 {
@@ -311,6 +318,7 @@
 							 <&osc1>, <&cb_intosc_hs_div2_clk>,
 							 <&f2s_free_clk>;
 						reg = <0x64>;
+						u-boot,dm-pre-reloc;
 					};
 
 					s2f_user1_free_clk: s2f_user1_free_clk@104 {
@@ -337,6 +345,7 @@
 						compatible = "altr,socfpga-a10-perip-clk";
 						clocks = <&noc_free_clk>;
 						fixed-divider = <4>;
+						u-boot,dm-pre-reloc;
 					};
 
 					l4_main_clk: l4_main_clk {
@@ -664,6 +673,7 @@
 			interrupts = <0 99 4>;
 			dma-mask = <0xffffffff>;
 			clocks = <&nand_clk>;
+			resets = <&rst NAND_RESET>;
 			status = "disabled";
 		};
 
@@ -800,6 +810,7 @@
 			reg = <0xffd00000 0x100>;
 			clocks = <&l4_sys_free_clk>;
 			clock-names = "timer";
+			u-boot,dm-pre-reloc;
 		};
 
 		timer3: timer3@ffd00100 {
diff --git a/arch/arm/dts/socfpga_arria10_socdk.dtsi b/arch/arm/dts/socfpga_arria10_socdk.dtsi
index 9160c20..42e8885 100644
--- a/arch/arm/dts/socfpga_arria10_socdk.dtsi
+++ b/arch/arm/dts/socfpga_arria10_socdk.dtsi
@@ -154,7 +154,6 @@
 };
 
 &uart1 {
-	clock-frequency = <50000000>;
 	u-boot,dm-pre-reloc;
 	status = "okay";
 };
@@ -169,22 +168,10 @@
 };
 
 /* Clock available early */
-&main_noc_base_clk {
-	u-boot,dm-pre-reloc;
-};
-
 &main_periph_ref_clk {
 	u-boot,dm-pre-reloc;
 };
 
-&peri_noc_base_clk {
-	u-boot,dm-pre-reloc;
-};
-
-&noc_free_clk {
-	u-boot,dm-pre-reloc;
-};
-
 &l4_mp_clk {
 	u-boot,dm-pre-reloc;
 };
diff --git a/arch/arm/mach-socfpga/Makefile b/arch/arm/mach-socfpga/Makefile
index 654999c..e667204 100644
--- a/arch/arm/mach-socfpga/Makefile
+++ b/arch/arm/mach-socfpga/Makefile
@@ -26,7 +26,6 @@
 obj-y	+= misc_arria10.o
 obj-y	+= pinmux_arria10.o
 obj-y	+= reset_manager_arria10.o
-obj-y	+= timer.o
 endif
 
 ifdef CONFIG_TARGET_SOCFPGA_STRATIX10
diff --git a/arch/arm/mach-socfpga/board.c b/arch/arm/mach-socfpga/board.c
index e8c7503..7c8c05c 100644
--- a/arch/arm/mach-socfpga/board.c
+++ b/arch/arm/mach-socfpga/board.c
@@ -43,14 +43,6 @@
 	/* Address of boot parameters for ATAG (if ATAG is used) */
 	gd->bd->bi_boot_params = CONFIG_SYS_SDRAM_BASE + 0x100;
 
-#if defined(CONFIG_TARGET_SOCFPGA_ARRIA10)
-	/* configuring the clock based on handoff */
-	cm_basic_init(gd->fdt_blob);
-
-	/* Add device descriptor to FPGA device table */
-	socfpga_fpga_add();
-#endif
-
 	return 0;
 }
 
diff --git a/arch/arm/mach-socfpga/clock_manager_arria10.c b/arch/arm/mach-socfpga/clock_manager_arria10.c
index 1b4052c..334a79f 100644
--- a/arch/arm/mach-socfpga/clock_manager_arria10.c
+++ b/arch/arm/mach-socfpga/clock_manager_arria10.c
@@ -11,8 +11,7 @@
 #include <dm/device-internal.h>
 #include <asm/arch/clock_manager.h>
 
-static const struct socfpga_clock_manager *clock_manager_base =
-	(struct socfpga_clock_manager *)SOCFPGA_CLKMGR_ADDRESS;
+#ifdef CONFIG_SPL_BUILD
 
 static u32 eosc1_hz;
 static u32 cb_intosc_hz;
@@ -232,6 +231,9 @@
 	return 0;
 }
 
+static const struct socfpga_clock_manager *clock_manager_base =
+	(struct socfpga_clock_manager *)SOCFPGA_CLKMGR_ADDRESS;
+
 /* calculate the intended main VCO frequency based on handoff */
 static unsigned int cm_calc_handoff_main_vco_clk_hz
 					(struct mainpll_cfg *main_cfg)
@@ -897,7 +899,7 @@
 	return 0;
 }
 
-void cm_use_intosc(void)
+static void cm_use_intosc(void)
 {
 	setbits_le32(&clock_manager_base->ctrl,
 		     CLKMGR_CLKMGR_CTL_BOOTCLK_INTOSC_SET_MSK);
@@ -917,8 +919,11 @@
 	if (rval)
 		return rval;
 
+	cm_use_intosc();
+
 	return cm_full_cfg(&main_cfg, &per_cfg);
 }
+#endif
 
 static u32 cm_get_rate_dm(char *name)
 {
diff --git a/arch/arm/mach-socfpga/include/mach/clock_manager_arria10.h b/arch/arm/mach-socfpga/include/mach/clock_manager_arria10.h
index b3c8853..de8c225 100644
--- a/arch/arm/mach-socfpga/include/mach/clock_manager_arria10.h
+++ b/arch/arm/mach-socfpga/include/mach/clock_manager_arria10.h
@@ -89,8 +89,9 @@
 	struct socfpga_clock_manager_altera altera;
 };
 
-void cm_use_intosc(void);
+#ifdef CONFIG_SPL_BUILD
 int cm_basic_init(const void *blob);
+#endif
 
 unsigned int cm_get_l4_sp_clk_hz(void);
 unsigned long cm_get_mpu_clk_hz(void);
diff --git a/arch/arm/mach-socfpga/include/mach/misc.h b/arch/arm/mach-socfpga/include/mach/misc.h
index e7e08b7..4fc9570 100644
--- a/arch/arm/mach-socfpga/include/mach/misc.h
+++ b/arch/arm/mach-socfpga/include/mach/misc.h
@@ -25,6 +25,11 @@
 void socfpga_sdram_remap_zero(void);
 #endif
 
+#ifdef CONFIG_TARGET_SOCFPGA_ARRIA10
+void socfpga_init_security_policies(void);
+void socfpga_sdram_remap_zero(void);
+#endif
+
 void do_bridge_reset(int enable);
 
 #endif /* _MISC_H_ */
diff --git a/arch/arm/mach-socfpga/mailbox_s10.c b/arch/arm/mach-socfpga/mailbox_s10.c
index cccd1a4..0d906c3 100644
--- a/arch/arm/mach-socfpga/mailbox_s10.c
+++ b/arch/arm/mach-socfpga/mailbox_s10.c
@@ -160,15 +160,15 @@
 	u32 buf_len;
 	int ret;
 
-	ret = mbox_prepare_cmd_only(id, cmd, is_indirect, len, arg);
-	if (ret)
-		return ret;
-
 	if (urgent) {
 		/* Read status because it is toggled */
 		status = MBOX_READL(MBOX_STATUS) & MBOX_STATUS_UA_MSK;
-		/* Send command as urgent command */
-		MBOX_WRITEL(1, MBOX_URG);
+		/* Write urgent command to urgent register */
+		MBOX_WRITEL(cmd, MBOX_URG);
+	} else {
+		ret = mbox_prepare_cmd_only(id, cmd, is_indirect, len, arg);
+		if (ret)
+			return ret;
 	}
 
 	/* write doorbell */
@@ -188,8 +188,7 @@
 
 		if (urgent) {
 			u32 new_status = MBOX_READL(MBOX_STATUS);
-			/* urgent command doesn't have response */
-			MBOX_WRITEL(0, MBOX_URG);
+
 			/* Urgent ACK is toggled */
 			if ((new_status & MBOX_STATUS_UA_MSK) ^ status)
 				return 0;
diff --git a/arch/arm/mach-socfpga/misc_arria10.c b/arch/arm/mach-socfpga/misc_arria10.c
index 284e076..f347ae8 100644
--- a/arch/arm/mach-socfpga/misc_arria10.c
+++ b/arch/arm/mach-socfpga/misc_arria10.c
@@ -28,17 +28,14 @@
 #define PINMUX_UART1_TX_SHARED_IO_OFFSET_Q3_7	0x78
 #define PINMUX_UART1_TX_SHARED_IO_OFFSET_Q4_3	0x98
 
+static struct socfpga_system_manager *sysmgr_regs =
+	(struct socfpga_system_manager *)SOCFPGA_SYSMGR_ADDRESS;
 #if defined(CONFIG_SPL_BUILD)
 static struct pl310_regs *const pl310 =
 	(struct pl310_regs *)CONFIG_SYS_PL310_BASE;
 static const struct socfpga_noc_fw_ocram *noc_fw_ocram_base =
 	(void *)SOCFPGA_SDR_FIREWALL_OCRAM_ADDRESS;
-#endif
-
-static struct socfpga_system_manager *sysmgr_regs =
-	(struct socfpga_system_manager *)SOCFPGA_SYSMGR_ADDRESS;
 
-#if defined(CONFIG_SPL_BUILD)
 /*
 + * This function initializes security policies to be consistent across
 + * all logic units in the Arria 10.
@@ -46,7 +43,7 @@
 + * The idea is to set all security policies to be normal, nonsecure
 + * for all units.
 + */
-static void initialize_security_policies(void)
+void socfpga_init_security_policies(void)
 {
 	/* Put OCRAM in non-secure */
 	writel(0x003f0000, &noc_fw_ocram_base->region0);
@@ -66,24 +63,20 @@
 	writel(0x0007FFFF, &sysmgr_regs->ecc_intmask_set);
 }
 
-int arch_early_init_r(void)
+void socfpga_sdram_remap_zero(void)
 {
-	initialize_security_policies();
-
 	/* Configure the L2 controller to make SDRAM start at 0 */
 	writel(0x1, &pl310->pl310_addr_filter_start);
-
-	/* assert reset to all except L4WD0 and L4TIMER0 */
-	socfpga_per_reset_all();
-
-	return 0;
 }
-#else
+#endif
+
 int arch_early_init_r(void)
 {
+	/* Add device descriptor to FPGA device table */
+	socfpga_fpga_add();
+
 	return 0;
 }
-#endif
 
 /*
  * Print CPU information
diff --git a/arch/arm/mach-socfpga/spl_a10.c b/arch/arm/mach-socfpga/spl_a10.c
index 7d35e9d..3ea64f7 100644
--- a/arch/arm/mach-socfpga/spl_a10.c
+++ b/arch/arm/mach-socfpga/spl_a10.c
@@ -68,33 +68,26 @@
 
 void spl_board_init(void)
 {
-	/* configuring the clock based on handoff */
-	cm_basic_init(gd->fdt_blob);
-	WATCHDOG_RESET();
-
-	config_dedicated_pins(gd->fdt_blob);
-	WATCHDOG_RESET();
-
 	/* enable console uart printing */
 	preloader_console_init();
-
 	WATCHDOG_RESET();
 
-	/* Add device descriptor to FPGA device table */
-	socfpga_fpga_add();
+	arch_early_init_r();
 }
 
 void board_init_f(ulong dummy)
 {
-	/*
-	 * Configure Clock Manager to use intosc clock instead external osc to
-	 * ensure success watchdog operation. We do it as early as possible.
-	 */
-	cm_use_intosc();
+	socfpga_init_security_policies();
+	socfpga_sdram_remap_zero();
 
+	/* Assert reset to all except L4WD0 and L4TIMER0 */
+	socfpga_per_reset_all();
 	socfpga_watchdog_disable();
 
-	arch_early_init_r();
+	spl_early_init();
+
+	/* Configure the clock based on handoff */
+	cm_basic_init(gd->fdt_blob);
 
 #ifdef CONFIG_HW_WATCHDOG
 	/* release osc1 watchdog timer 0 from reset */
@@ -104,4 +97,7 @@
 	hw_watchdog_init();
 	WATCHDOG_RESET();
 #endif /* CONFIG_HW_WATCHDOG */
+
+	config_dedicated_pins(gd->fdt_blob);
+	WATCHDOG_RESET();
 }
diff --git a/arch/arm/mach-socfpga/spl_s10.c b/arch/arm/mach-socfpga/spl_s10.c
index 69d6e91..cc5dc4f 100644
--- a/arch/arm/mach-socfpga/spl_s10.c
+++ b/arch/arm/mach-socfpga/spl_s10.c
@@ -136,7 +136,7 @@
 	socfpga_per_reset(SOCFPGA_RESET(OSC1TIMER0), 0);
 	timer_init();
 
-	populate_sysmgr_pinmux();
+	sysmgr_pinmux_init();
 
 	/* configuring the HPS clocks */
 	cm_basic_init(cm_default_cfg);
diff --git a/configs/socfpga_arria10_defconfig b/configs/socfpga_arria10_defconfig
index 4b0d474..a504035 100644
--- a/configs/socfpga_arria10_defconfig
+++ b/configs/socfpga_arria10_defconfig
@@ -39,4 +39,7 @@
 CONFIG_ETH_DESIGNWARE=y
 CONFIG_MII=y
 CONFIG_SPI=y
+CONFIG_TIMER=y
+CONFIG_SPL_TIMER=y
+CONFIG_DESIGNWARE_APB_TIMER=y
 CONFIG_USE_TINY_PRINTF=y
diff --git a/drivers/timer/Kconfig b/drivers/timer/Kconfig
index 8a31397..5ab6749 100644
--- a/drivers/timer/Kconfig
+++ b/drivers/timer/Kconfig
@@ -59,6 +59,13 @@
 	  Enables support for the cadence ttc driver. This driver is present
 	  on Xilinx Zynq and ZynqMP SoCs.
 
+config DESIGNWARE_APB_TIMER
+	bool "Designware APB Timer"
+	depends on TIMER
+	help
+	  Enables support for the Designware APB Timer driver. This timer is
+	  present on Altera SoCFPGA SoCs.
+
 config SANDBOX_TIMER
 	bool "Sandbox timer support"
 	depends on SANDBOX && TIMER
diff --git a/drivers/timer/Makefile b/drivers/timer/Makefile
index ee2fcb1..0c8a627 100644
--- a/drivers/timer/Makefile
+++ b/drivers/timer/Makefile
@@ -5,6 +5,7 @@
 obj-y += timer-uclass.o
 obj-$(CONFIG_ALTERA_TIMER)	+= altera_timer.o
 obj-$(CONFIG_CADENCE_TTC_TIMER)	+= cadence-ttc.o
+obj-$(CONFIG_DESIGNWARE_APB_TIMER)	+= dw-apb-timer.o
 obj-$(CONFIG_SANDBOX_TIMER)	+= sandbox_timer.o
 obj-$(CONFIG_X86_TSC_TIMER)	+= tsc_timer.o
 obj-$(CONFIG_OMAP_TIMER)	+= omap-timer.o
diff --git a/drivers/timer/dw-apb-timer.c b/drivers/timer/dw-apb-timer.c
new file mode 100644
index 0000000..031f429
--- /dev/null
+++ b/drivers/timer/dw-apb-timer.c
@@ -0,0 +1,90 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Designware APB Timer driver
+ *
+ * Copyright (C) 2018 Marek Vasut <marex@denx.de>
+ */
+
+#include <common.h>
+#include <dm.h>
+#include <clk.h>
+#include <timer.h>
+
+#include <asm/io.h>
+#include <asm/arch/timer.h>
+
+#define DW_APB_LOAD_VAL		0x0
+#define DW_APB_CURR_VAL		0x4
+#define DW_APB_CTRL		0x8
+
+DECLARE_GLOBAL_DATA_PTR;
+
+struct dw_apb_timer_priv {
+	fdt_addr_t	regs;
+};
+
+static int dw_apb_timer_get_count(struct udevice *dev, u64 *count)
+{
+	struct dw_apb_timer_priv *priv = dev_get_priv(dev);
+
+	/*
+	 * The DW APB counter counts down, but this function
+	 * requires the count to be incrementing. Invert the
+	 * result.
+	 */
+	*count = ~readl(priv->regs + DW_APB_CURR_VAL);
+
+	return 0;
+}
+
+static int dw_apb_timer_probe(struct udevice *dev)
+{
+	struct timer_dev_priv *uc_priv = dev_get_uclass_priv(dev);
+	struct dw_apb_timer_priv *priv = dev_get_priv(dev);
+	struct clk clk;
+	int ret;
+
+	ret = clk_get_by_index(dev, 0, &clk);
+	if (ret)
+		return ret;
+
+	uc_priv->clock_rate = clk_get_rate(&clk);
+
+	clk_free(&clk);
+
+	/* init timer */
+	writel(0xffffffff, priv->regs + DW_APB_LOAD_VAL);
+	writel(0xffffffff, priv->regs + DW_APB_CURR_VAL);
+	setbits_le32(priv->regs + DW_APB_CTRL, 0x3);
+
+	return 0;
+}
+
+static int dw_apb_timer_ofdata_to_platdata(struct udevice *dev)
+{
+	struct dw_apb_timer_priv *priv = dev_get_priv(dev);
+
+	priv->regs = dev_read_addr(dev);
+
+	return 0;
+}
+
+static const struct timer_ops dw_apb_timer_ops = {
+	.get_count	= dw_apb_timer_get_count,
+};
+
+static const struct udevice_id dw_apb_timer_ids[] = {
+	{ .compatible = "snps,dw-apb-timer" },
+	{}
+};
+
+U_BOOT_DRIVER(dw_apb_timer) = {
+	.name		= "dw_apb_timer",
+	.id		= UCLASS_TIMER,
+	.ops		= &dw_apb_timer_ops,
+	.probe		= dw_apb_timer_probe,
+	.flags		= DM_FLAG_PRE_RELOC,
+	.of_match	= dw_apb_timer_ids,
+	.ofdata_to_platdata = dw_apb_timer_ofdata_to_platdata,
+	.priv_auto_alloc_size = sizeof(struct dw_apb_timer_priv),
+};
diff --git a/include/configs/socfpga_common.h b/include/configs/socfpga_common.h
index 440a918..2330143 100644
--- a/include/configs/socfpga_common.h
+++ b/include/configs/socfpga_common.h
@@ -86,11 +86,13 @@
 /*
  * L4 OSC1 Timer 0
  */
+#ifndef CONFIG_TIMER
 /* This timer uses eosc1, whose clock frequency is fixed at any condition. */
 #define CONFIG_SYS_TIMERBASE		SOCFPGA_OSC1TIMER0_ADDRESS
 #define CONFIG_SYS_TIMER_COUNTS_DOWN
 #define CONFIG_SYS_TIMER_COUNTER	(CONFIG_SYS_TIMERBASE + 0x4)
 #define CONFIG_SYS_TIMER_RATE		25000000
+#endif
 
 /*
  * L4 Watchdog