diff --git a/arch/arm/dts/socfpga.dtsi b/arch/arm/dts/socfpga.dtsi
index ec1966480f2f0376522bda05d1e7347821238a46..51a6a51b5380e920b6db44e095b096fbfbca81a5 100644
--- a/arch/arm/dts/socfpga.dtsi
+++ b/arch/arm/dts/socfpga.dtsi
@@ -791,9 +791,9 @@
 			reg = <0xfffec000 0x100>;
 		};
 
-		sdr: sdr@ffc25000 {
+		sdr: sdr@ffc20000 {
 			compatible = "altr,sdr-ctl", "syscon";
-			reg = <0xffc25000 0x1000>;
+			reg = <0xffc20000 0x6000>;
 			resets = <&rst SDR_RESET>;
 		};
 
diff --git a/arch/arm/mach-socfpga/include/mach/sdram_gen5.h b/arch/arm/mach-socfpga/include/mach/sdram_gen5.h
index a238d5d17fe92a1f2dbe390b33fc9f0ffc278e74..c41208591a1f03523afe8e9155bbafd3fde12c44 100644
--- a/arch/arm/mach-socfpga/include/mach/sdram_gen5.h
+++ b/arch/arm/mach-socfpga/include/mach/sdram_gen5.h
@@ -7,10 +7,6 @@
 
 #ifndef __ASSEMBLY__
 
-unsigned long sdram_calculate_size(void);
-int sdram_mmr_init_full(unsigned int sdr_phy_reg);
-int sdram_calibration_full(void);
-
 const struct socfpga_sdram_config *socfpga_get_sdram_config(void);
 
 void socfpga_get_seq_ac_init(const u32 **init, unsigned int *nelem);
diff --git a/arch/arm/mach-socfpga/spl_gen5.c b/arch/arm/mach-socfpga/spl_gen5.c
index 142b60f887d3edce87ba0fdad105b54a086c8388..c5399bb69792c40e64b636c47d1b585dbcd39f6d 100644
--- a/arch/arm/mach-socfpga/spl_gen5.c
+++ b/arch/arm/mach-socfpga/spl_gen5.c
@@ -21,6 +21,7 @@
 #include <debug_uart.h>
 #include <fdtdec.h>
 #include <watchdog.h>
+#include <dm/uclass.h>
 
 DECLARE_GLOBAL_DATA_PTR;
 
@@ -123,9 +124,9 @@ static void socfpga_pl310_clear(void)
 void board_init_f(ulong dummy)
 {
 	const struct cm_config *cm_default_cfg = cm_get_default_config();
-	unsigned long sdram_size;
 	unsigned long reg;
 	int ret;
+	struct udevice *dev;
 
 	/*
 	 * First C code to run. Clear fake OCRAM ECC first as SBE
@@ -156,7 +157,6 @@ void board_init_f(ulong dummy)
 		socfpga_bridges_reset(1);
 	}
 
-	socfpga_per_reset(SOCFPGA_RESET(SDR), 0);
 	socfpga_per_reset(SOCFPGA_RESET(UART0), 0);
 	socfpga_per_reset(SOCFPGA_RESET(OSC1TIMER0), 0);
 
@@ -200,27 +200,16 @@ void board_init_f(ulong dummy)
 		hang();
 	}
 
+	ret = uclass_get_device(UCLASS_RESET, 0, &dev);
+	if (ret)
+		debug("Reset init failed: %d\n", ret);
+
 	/* enable console uart printing */
 	preloader_console_init();
 
-	if (sdram_mmr_init_full(0xffffffff) != 0) {
-		puts("SDRAM init failed.\n");
-		hang();
-	}
-
-	debug("SDRAM: Calibrating PHY\n");
-	/* SDRAM calibration */
-	if (sdram_calibration_full() == 0) {
-		puts("SDRAM calibration failed.\n");
-		hang();
-	}
-
-	sdram_size = sdram_calculate_size();
-	debug("SDRAM: %ld MiB\n", sdram_size >> 20);
-
-	/* Sanity check ensure correct SDRAM size specified */
-	if (get_ram_size(0, sdram_size) != sdram_size) {
-		puts("SDRAM size check failed!\n");
+	ret = uclass_get_device(UCLASS_RAM, 0, &dev);
+	if (ret) {
+		debug("DRAM init failed: %d\n", ret);
 		hang();
 	}
 
diff --git a/drivers/ddr/altera/Kconfig b/drivers/ddr/altera/Kconfig
index 2b28a97f6e7fb866fcfeea65e97eeef4065882ef..8f60b56eb84886f534e663373ffff2e392612e1d 100644
--- a/drivers/ddr/altera/Kconfig
+++ b/drivers/ddr/altera/Kconfig
@@ -1,5 +1,7 @@
 config ALTERA_SDRAM
 	bool "SoCFPGA DDR SDRAM driver"
 	depends on TARGET_SOCFPGA_GEN5 || TARGET_SOCFPGA_ARRIA10
+	select RAM if TARGET_SOCFPGA_GEN5
+	select SPL_RAM if TARGET_SOCFPGA_GEN5
 	help
 	  Enable DDR SDRAM controller for the SoCFPGA devices.
diff --git a/drivers/ddr/altera/sdram_gen5.c b/drivers/ddr/altera/sdram_gen5.c
index 821060459cf143af860ef749666f71af9f90772c..fcd89b619dbe2bf5e7ab379170891c3bb52e21c3 100644
--- a/drivers/ddr/altera/sdram_gen5.c
+++ b/drivers/ddr/altera/sdram_gen5.c
@@ -3,14 +3,30 @@
  * Copyright Altera Corporation (C) 2014-2015
  */
 #include <common.h>
+#include <dm.h>
 #include <errno.h>
 #include <div64.h>
+#include <ram.h>
+#include <reset.h>
 #include <watchdog.h>
 #include <asm/arch/fpga_manager.h>
+#include <asm/arch/reset_manager.h>
 #include <asm/arch/sdram.h>
 #include <asm/arch/system_manager.h>
 #include <asm/io.h>
 
+#include "sequencer.h"
+
+#ifdef CONFIG_SPL_BUILD
+
+struct altera_gen5_sdram_priv {
+	struct ram_info info;
+};
+
+struct altera_gen5_sdram_platdata {
+	struct socfpga_sdr *sdr;
+};
+
 struct sdram_prot_rule {
 	u32	sdram_start;	/* SDRAM start address */
 	u32	sdram_end;	/* SDRAM end address */
@@ -26,8 +42,8 @@ struct sdram_prot_rule {
 
 static struct socfpga_system_manager *sysmgr_regs =
 	(struct socfpga_system_manager *)SOCFPGA_SYSMGR_ADDRESS;
-static struct socfpga_sdr_ctrl *sdr_ctrl =
-	(struct socfpga_sdr_ctrl *)SDR_CTRLGRP_ADDRESS;
+
+static unsigned long sdram_calculate_size(struct socfpga_sdr_ctrl *sdr_ctrl);
 
 /**
  * get_errata_rows() - Up the number of DRAM rows to cover entire address space
@@ -104,7 +120,8 @@ static int get_errata_rows(const struct socfpga_sdram_config *cfg)
 }
 
 /* SDRAM protection rules vary from 0-19, a total of 20 rules. */
-static void sdram_set_rule(struct sdram_prot_rule *prule)
+static void sdram_set_rule(struct socfpga_sdr_ctrl *sdr_ctrl,
+			   struct sdram_prot_rule *prule)
 {
 	u32 lo_addr_bits;
 	u32 hi_addr_bits;
@@ -141,7 +158,8 @@ static void sdram_set_rule(struct sdram_prot_rule *prule)
 	writel(0, &sdr_ctrl->prot_rule_rdwr);
 }
 
-static void sdram_get_rule(struct sdram_prot_rule *prule)
+static void sdram_get_rule(struct socfpga_sdr_ctrl *sdr_ctrl,
+			   struct sdram_prot_rule *prule)
 {
 	u32 addr;
 	u32 id;
@@ -172,7 +190,8 @@ static void sdram_get_rule(struct sdram_prot_rule *prule)
 }
 
 static void
-sdram_set_protection_config(const u32 sdram_start, const u32 sdram_end)
+sdram_set_protection_config(struct socfpga_sdr_ctrl *sdr_ctrl,
+			    const u32 sdram_start, const u32 sdram_end)
 {
 	struct sdram_prot_rule rule;
 	int rules;
@@ -185,7 +204,7 @@ sdram_set_protection_config(const u32 sdram_start, const u32 sdram_end)
 
 	for (rules = 0; rules < 20; rules++) {
 		rule.rule = rules;
-		sdram_set_rule(&rule);
+		sdram_set_rule(sdr_ctrl, &rule);
 	}
 
 	/* new rule: accept SDRAM */
@@ -200,13 +219,13 @@ sdram_set_protection_config(const u32 sdram_start, const u32 sdram_end)
 	rule.rule = 0;
 
 	/* set new rule */
-	sdram_set_rule(&rule);
+	sdram_set_rule(sdr_ctrl, &rule);
 
 	/* default rule: reject everything */
 	writel(0x3ff, &sdr_ctrl->protport_default);
 }
 
-static void sdram_dump_protection_config(void)
+static void sdram_dump_protection_config(struct socfpga_sdr_ctrl *sdr_ctrl)
 {
 	struct sdram_prot_rule rule;
 	int rules;
@@ -216,7 +235,7 @@ static void sdram_dump_protection_config(void)
 
 	for (rules = 0; rules < 20; rules++) {
 		rule.rule = rules;
-		sdram_get_rule(&rule);
+		sdram_get_rule(sdr_ctrl, &rule);
 		debug("Rule %d, rules ...\n", rules);
 		debug("    sdram start %x\n", rule.sdram_start);
 		debug("    sdram end   %x\n", rule.sdram_end);
@@ -322,7 +341,8 @@ static u32 sdr_get_addr_rw(const struct socfpga_sdram_config *cfg)
  *
  * This function loads the register values into the SDRAM controller block.
  */
-static void sdr_load_regs(const struct socfpga_sdram_config *cfg)
+static void sdr_load_regs(struct socfpga_sdr_ctrl *sdr_ctrl,
+			  const struct socfpga_sdram_config *cfg)
 {
 	const u32 ctrl_cfg = sdr_get_ctrlcfg(cfg);
 	const u32 dram_addrw = sdr_get_addr_rw(cfg);
@@ -426,7 +446,8 @@ static void sdr_load_regs(const struct socfpga_sdram_config *cfg)
  *
  * Initialize the SDRAM MMR.
  */
-int sdram_mmr_init_full(unsigned int sdr_phy_reg)
+int sdram_mmr_init_full(struct socfpga_sdr_ctrl *sdr_ctrl,
+			unsigned int sdr_phy_reg)
 {
 	const struct socfpga_sdram_config *cfg = socfpga_get_sdram_config();
 	const unsigned int rows =
@@ -436,7 +457,7 @@ int sdram_mmr_init_full(unsigned int sdr_phy_reg)
 
 	writel(rows, &sysmgr_regs->iswgrp_handoff[4]);
 
-	sdr_load_regs(cfg);
+	sdr_load_regs(sdr_ctrl, cfg);
 
 	/* saving this value to SYSMGR.ISWGRP.HANDOFF.FPGA2SDR */
 	writel(cfg->fpgaport_rst, &sysmgr_regs->iswgrp_handoff[3]);
@@ -459,9 +480,10 @@ int sdram_mmr_init_full(unsigned int sdr_phy_reg)
 			SDR_CTRLGRP_STATICCFG_APPLYCFG_MASK,
 			1 << SDR_CTRLGRP_STATICCFG_APPLYCFG_LSB);
 
-	sdram_set_protection_config(0, sdram_calculate_size() - 1);
+	sdram_set_protection_config(sdr_ctrl, 0,
+				    sdram_calculate_size(sdr_ctrl) - 1);
 
-	sdram_dump_protection_config();
+	sdram_dump_protection_config(sdr_ctrl);
 
 	return 0;
 }
@@ -472,7 +494,7 @@ int sdram_mmr_init_full(unsigned int sdr_phy_reg)
  * Calculate SDRAM device size based on SDRAM controller parameters.
  * Size is specified in bytes.
  */
-unsigned long sdram_calculate_size(void)
+static unsigned long sdram_calculate_size(struct socfpga_sdr_ctrl *sdr_ctrl)
 {
 	unsigned long temp;
 	unsigned long row, bank, col, cs, width;
@@ -534,3 +556,94 @@ unsigned long sdram_calculate_size(void)
 
 	return temp;
 }
+
+static int altera_gen5_sdram_ofdata_to_platdata(struct udevice *dev)
+{
+	struct altera_gen5_sdram_platdata *plat = dev->platdata;
+
+	plat->sdr = (struct socfpga_sdr *)devfdt_get_addr_index(dev, 0);
+	if (!plat->sdr)
+		return -ENODEV;
+
+	return 0;
+}
+
+static int altera_gen5_sdram_probe(struct udevice *dev)
+{
+	int ret;
+	unsigned long sdram_size;
+	struct altera_gen5_sdram_platdata *plat = dev->platdata;
+	struct altera_gen5_sdram_priv *priv = dev_get_priv(dev);
+	struct socfpga_sdr_ctrl *sdr_ctrl = &plat->sdr->sdr_ctrl;
+	struct reset_ctl_bulk resets;
+
+	ret = reset_get_bulk(dev, &resets);
+	if (ret) {
+		dev_err(dev, "Can't get reset: %d\n", ret);
+		return -ENODEV;
+	}
+	reset_deassert_bulk(&resets);
+
+	if (sdram_mmr_init_full(sdr_ctrl, 0xffffffff) != 0) {
+		puts("SDRAM init failed.\n");
+		goto failed;
+	}
+
+	debug("SDRAM: Calibrating PHY\n");
+	/* SDRAM calibration */
+	if (sdram_calibration_full(plat->sdr) == 0) {
+		puts("SDRAM calibration failed.\n");
+		goto failed;
+	}
+
+	sdram_size = sdram_calculate_size(sdr_ctrl);
+	debug("SDRAM: %ld MiB\n", sdram_size >> 20);
+
+	/* Sanity check ensure correct SDRAM size specified */
+	if (get_ram_size(0, sdram_size) != sdram_size) {
+		puts("SDRAM size check failed!\n");
+		goto failed;
+	}
+
+	priv->info.base = 0;
+	priv->info.size = sdram_size;
+
+	return 0;
+
+failed:
+	reset_release_bulk(&resets);
+	return -ENODEV;
+}
+
+static int altera_gen5_sdram_get_info(struct udevice *dev,
+				      struct ram_info *info)
+{
+	struct altera_gen5_sdram_priv *priv = dev_get_priv(dev);
+
+	info->base = priv->info.base;
+	info->size = priv->info.size;
+
+	return 0;
+}
+
+static struct ram_ops altera_gen5_sdram_ops = {
+	.get_info = altera_gen5_sdram_get_info,
+};
+
+static const struct udevice_id altera_gen5_sdram_ids[] = {
+	{ .compatible = "altr,sdr-ctl" },
+	{ /* sentinel */ }
+};
+
+U_BOOT_DRIVER(altera_gen5_sdram) = {
+	.name = "altr_sdr_ctl",
+	.id = UCLASS_RAM,
+	.of_match = altera_gen5_sdram_ids,
+	.ops = &altera_gen5_sdram_ops,
+	.ofdata_to_platdata = altera_gen5_sdram_ofdata_to_platdata,
+	.platdata_auto_alloc_size = sizeof(struct altera_gen5_sdram_platdata),
+	.probe = altera_gen5_sdram_probe,
+	.priv_auto_alloc_size = sizeof(struct altera_gen5_sdram_priv),
+};
+
+#endif /* CONFIG_SPL_BUILD */
diff --git a/drivers/ddr/altera/sequencer.c b/drivers/ddr/altera/sequencer.c
index 5e7a943b680c9b0a8776e064655c98c61d862768..0e4526288e2aaec22c56b09121381e78c3b4af03 100644
--- a/drivers/ddr/altera/sequencer.c
+++ b/drivers/ddr/altera/sequencer.c
@@ -3705,12 +3705,19 @@ static void initialize_tracking(void)
 	       &sdr_reg_file->trk_rfsh);
 }
 
-int sdram_calibration_full(void)
+int sdram_calibration_full(struct socfpga_sdr *sdr)
 {
 	struct param_type my_param;
 	struct gbl_type my_gbl;
 	u32 pass;
 
+	/*
+	 * For size reasons, this file uses hard coded addresses.
+	 * Check if we are called with the correct address.
+	 */
+	if (sdr != (struct socfpga_sdr *)SOCFPGA_SDR_ADDRESS)
+		return -ENODEV;
+
 	memset(&my_param, 0, sizeof(my_param));
 	memset(&my_gbl, 0, sizeof(my_gbl));
 
diff --git a/drivers/ddr/altera/sequencer.h b/drivers/ddr/altera/sequencer.h
index a5760b03a55bb0113cc8bfc89d2368088868b12d..d7f6935201fdad5210b9e0e4ee8528255eaa3bde 100644
--- a/drivers/ddr/altera/sequencer.h
+++ b/drivers/ddr/altera/sequencer.h
@@ -223,4 +223,39 @@ struct socfpga_data_mgr {
 	u32	mem_t_add;
 	u32	t_rl_add;
 };
+
+/* This struct describes the controller @ SOCFPGA_SDR_ADDRESS */
+struct socfpga_sdr {
+	/* SDR_PHYGRP_SCCGRP_ADDRESS */
+	u8 _align1[0xe00];
+	/* SDR_PHYGRP_SCCGRP_ADDRESS | 0xe00 */
+	struct socfpga_sdr_scc_mgr sdr_scc_mgr;
+	u8 _align2[0x1bc];
+	/* SDR_PHYGRP_PHYMGRGRP_ADDRESS */
+	struct socfpga_phy_mgr_cmd phy_mgr_cmd;
+	u8 _align3[0x2c];
+	/* SDR_PHYGRP_PHYMGRGRP_ADDRESS | 0x40 */
+	struct socfpga_phy_mgr_cfg phy_mgr_cfg;
+	u8 _align4[0xfa0];
+	/* SDR_PHYGRP_RWMGRGRP_ADDRESS */
+	u8 rwmgr_grp[0x800];
+	/* SDR_PHYGRP_RWMGRGRP_ADDRESS | 0x800 */
+	struct socfpga_sdr_rw_load_manager sdr_rw_load_mgr_regs;
+	u8 _align5[0x3f0];
+	/* SDR_PHYGRP_RWMGRGRP_ADDRESS | 0xC00 */
+	struct socfpga_sdr_rw_load_jump_manager sdr_rw_load_jump_mgr_regs;
+	u8 _align6[0x13f0];
+	/* SDR_PHYGRP_DATAMGRGRP_ADDRESS */
+	struct socfpga_data_mgr data_mgr;
+	u8 _align7[0x7f0];
+	/* SDR_PHYGRP_REGFILEGRP_ADDRESS */
+	struct socfpga_sdr_reg_file sdr_reg_file;
+	u8 _align8[0x7c8];
+	/* SDR_CTRLGRP_ADDRESS */
+	struct socfpga_sdr_ctrl sdr_ctrl;
+	u8 _align9[0xea4];
+};
+
+int sdram_calibration_full(struct socfpga_sdr *sdr);
+
 #endif /* _SEQUENCER_H_ */