diff --git a/arch/arm/cpu/armv7/omap4/emif.c b/arch/arm/cpu/armv7/omap4/emif.c
index baa5ed6..b09aa8f 100644
--- a/arch/arm/cpu/armv7/omap4/emif.c
+++ b/arch/arm/cpu/armv7/omap4/emif.c
@@ -166,7 +166,8 @@ static const struct lpddr2_min_tck min_tck_jedec = {
 	.tFAW = 8
 };
 
-static const struct lpddr2_ac_timings *jedec_ac_timings[MAX_NUM_SPEEDBINS] = {
+static const struct lpddr2_ac_timings const*
+			jedec_ac_timings[MAX_NUM_SPEEDBINS] = {
 	&timings_jedec_200_mhz,
 	&timings_jedec_333_mhz,
 	&timings_jedec_400_mhz
@@ -780,6 +781,146 @@ void emif_reset_phy(u32 base)
 	writel(iodft, &emif->emif_iodft_tlgc);
 }
 
+#ifdef CONFIG_SYS_AUTOMATIC_SDRAM_DETECTION
+static void display_sdram_details(u32 emif_nr, u32 cs,
+				  struct lpddr2_device_details *device)
+{
+	const char *mfg_str;
+	const char *type_str;
+	char density_str[10];
+	u32 density;
+
+	debug("EMIF%d CS%d\t", emif_nr, cs);
+
+	if (!device) {
+		debug("None\n");
+		return;
+	}
+
+	mfg_str = get_lpddr2_manufacturer(device->manufacturer);
+	type_str = get_lpddr2_type(device->type);
+
+	density = lpddr2_density_2_size_in_mbytes[device->density];
+	if ((density / 1024 * 1024) == density) {
+		density /= 1024;
+		sprintf(density_str, "%d GB", density);
+	} else
+		sprintf(density_str, "%d MB", density);
+	if (mfg_str && type_str)
+		debug("%s\t\t%s\t%s\n", mfg_str, type_str, density_str);
+}
+
+static u8 is_lpddr2_sdram_present(u32 base, u32 cs,
+				  struct lpddr2_device_details *lpddr2_device)
+{
+	u32 mr = 0, temp;
+
+	mr = get_mr(base, cs, LPDDR2_MR0);
+	if (mr > 0xFF) {
+		/* Mode register value bigger than 8 bit */
+		return 0;
+	}
+
+	temp = get_bit_field(mr, LPDDR2_MR0_DI_SHIFT, LPDDR2_MR0_DI_MASK);
+	if (temp) {
+		/* Not SDRAM */
+		return 0;
+	}
+	temp = get_bit_field(mr, LPDDR2_MR0_DNVI_SHIFT, LPDDR2_MR0_DNVI_MASK);
+
+	if (temp) {
+		/* DNV supported - But DNV is only supported for NVM */
+		return 0;
+	}
+
+	mr = get_mr(base, cs, LPDDR2_MR4);
+	if (mr > 0xFF) {
+		/* Mode register value bigger than 8 bit */
+		return 0;
+	}
+
+	mr = get_mr(base, cs, LPDDR2_MR5);
+	if (mr >= 0xFF) {
+		/* Mode register value bigger than 8 bit */
+		return 0;
+	}
+
+	if (!get_lpddr2_manufacturer(mr)) {
+		/* Manufacturer not identified */
+		return 0;
+	}
+	lpddr2_device->manufacturer = mr;
+
+	mr = get_mr(base, cs, LPDDR2_MR6);
+	if (mr >= 0xFF) {
+		/* Mode register value bigger than 8 bit */
+		return 0;
+	}
+
+	mr = get_mr(base, cs, LPDDR2_MR7);
+	if (mr >= 0xFF) {
+		/* Mode register value bigger than 8 bit */
+		return 0;
+	}
+
+	mr = get_mr(base, cs, LPDDR2_MR8);
+	if (mr >= 0xFF) {
+		/* Mode register value bigger than 8 bit */
+		return 0;
+	}
+
+	temp = get_bit_field(mr, MR8_TYPE_SHIFT, MR8_TYPE_MASK);
+	if (!get_lpddr2_type(temp)) {
+		/* Not SDRAM */
+		return 0;
+	}
+	lpddr2_device->type = temp;
+
+	temp = get_bit_field(mr, MR8_DENSITY_SHIFT, MR8_DENSITY_MASK);
+	if (temp > LPDDR2_DENSITY_32Gb) {
+		/* Density not supported */
+		return 0;
+	}
+	lpddr2_device->density = temp;
+
+	temp = get_bit_field(mr, MR8_IO_WIDTH_SHIFT, MR8_IO_WIDTH_MASK);
+	if (!get_lpddr2_io_width(temp)) {
+		/* IO width unsupported value */
+		return 0;
+	}
+	lpddr2_device->io_width = temp;
+
+	/*
+	 * If all the above tests pass we should
+	 * have a device on this chip-select
+	 */
+	return 1;
+}
+
+static struct lpddr2_device_details *get_lpddr2_details(u32 base, u8 cs,
+			struct lpddr2_device_details *lpddr2_dev_details)
+{
+	u32 phy;
+	struct emif_reg_struct *emif = (struct emif_reg_struct *)base;
+
+	if (!lpddr2_dev_details)
+		return NULL;
+
+	/* Do the minimum init for mode register accesses */
+	if (!running_from_sdram()) {
+		phy = get_ddr_phy_ctrl_1(get_sys_clk_freq() / 2, RL_BOOT);
+		writel(phy, &emif->emif_ddr_phy_ctrl_1);
+	}
+
+	if (!(is_lpddr2_sdram_present(base, cs, lpddr2_dev_details)))
+		return NULL;
+
+	display_sdram_details(emif_num(base), cs, lpddr2_dev_details);
+
+	return lpddr2_dev_details;
+}
+#endif /* CONFIG_SYS_AUTOMATIC_SDRAM_DETECTION */
+
 static void do_lpddr2_init(u32 base, u32 cs)
 {
 	u32 mr_addr;
@@ -879,9 +1020,7 @@ static void emif_update_timings(u32 base, const struct emif_regs *regs)
 
 static void do_sdram_init(u32 base)
 {
-	struct emif_device_details dev_details;
 	const struct emif_regs *regs;
-
 	u32 in_sdram, emif_nr;
 
 	in_sdram = running_from_sdram();
@@ -889,6 +1028,7 @@ static void do_sdram_init(u32 base)
 
 #ifdef CONFIG_SYS_EMIF_PRECALCULATED_TIMING_REGS
 	const struct emif_regs *tmp_regs;
+
 	emif_get_reg_dump(&regs, &tmp_regs);
 	regs = (emif_nr == 1) ? regs : tmp_regs;
 #else
@@ -896,23 +1036,48 @@ static void do_sdram_init(u32 base)
 	 * The user has not provided the register values. We need to
 	 * calculate it based on the timings and the DDR frequency
 	 */
+	struct emif_device_details dev_details = { NULL, NULL };
+	struct emif_regs calculated_regs;
 
+#if !defined(CONFIG_SYS_AUTOMATIC_SDRAM_DETECTION) || \
+	!defined(CONFIG_SYS_DEFAULT_LPDDR2_TIMINGS)
+
+	/* We need some input about the devices from the user */
 	const struct emif_device_details *dev_details_user_provided;
 	const struct emif_device_details *tmp_details;
-	struct emif_regs calculated_regs;
 
-	/* We need some input about the devices from the user */
 	emif_get_device_details(&dev_details_user_provided, &tmp_details);
 	dev_details_user_provided = (emif_nr == 1) ? dev_details_user_provided
 						   : tmp_details;
 	if (!dev_details_user_provided)
 		return;
+#endif
 
+#ifdef CONFIG_SYS_AUTOMATIC_SDRAM_DETECTION
+	struct lpddr2_device_details cs0_dev_details, cs1_dev_details;
+
+	/* Automatically find the device details */
+	if (!in_sdram) {
+		dev_details.cs0_device_details =
+		    get_lpddr2_details(base, CS0, &cs0_dev_details);
+		dev_details.cs1_device_details =
+		    get_lpddr2_details(base, CS1, &cs1_dev_details);
+		/*
+		 * Reset the PHY - if there is nothing connected on any
+		 * of the chip selects(typically CS1) mode register reads
+		 * will mess up with the PHY state and subsequent
+		 * initialization won't work. PHY reset brings back PHY to
+		 * a good state.
+		 */
+		emif_reset_phy(base);
+	}
+#else
 	dev_details.cs0_device_details =
 			dev_details_user_provided->cs0_device_details;
 	dev_details.cs1_device_details =
 			dev_details_user_provided->cs1_device_details;
 
+#endif
 	/* Return if no devices on this EMIF */
 	if (!dev_details.cs0_device_details &&
 	    !dev_details.cs1_device_details) {
diff --git a/arch/arm/cpu/armv7/omap4/sdram_elpida.c b/arch/arm/cpu/armv7/omap4/sdram_elpida.c
index e7d2bd5..8dfe6f9 100644
--- a/arch/arm/cpu/armv7/omap4/sdram_elpida.c
+++ b/arch/arm/cpu/armv7/omap4/sdram_elpida.c
@@ -86,10 +86,8 @@ const struct dmm_lisa_map_regs lisa_map_2G_x_2_x_2 = {
 	.dmm_lisa_map_3 = 0x80640300
 };
 
-void emif_get_reg_dump_sdp(const struct emif_regs **emif1_regs,
-			const struct emif_regs **emif2_regs)
-
-#else
+#elif !defined(CONFIG_SYS_AUTOMATIC_SDRAM_DETECTION) || \
+	!defined(CONFIG_SYS_DEFAULT_LPDDR2_TIMINGS)
 
 static const struct lpddr2_ac_timings timings_elpida_400_mhz = {
 	.max_freq	= 400000000,
@@ -245,7 +243,8 @@ static void emif_get_dmm_regs_sdp(const struct dmm_lisa_map_regs
 void emif_get_dmm_regs(const struct dmm_lisa_map_regs **dmm_lisa_regs)
 	__attribute__((weak, alias("emif_get_dmm_regs_sdp")));
 
-#else
+#elif !defined(CONFIG_SYS_AUTOMATIC_SDRAM_DETECTION) || \
+	!defined(CONFIG_SYS_DEFAULT_LPDDR2_TIMINGS)
 
 static void emif_get_device_details_sdp(
 			const struct emif_device_details **emif1_details,
diff --git a/include/configs/omap4_sdp4430.h b/include/configs/omap4_sdp4430.h
index d5f98dc..13e7623 100644
--- a/include/configs/omap4_sdp4430.h
+++ b/include/configs/omap4_sdp4430.h
@@ -251,6 +251,7 @@
 
 /* Defines for SDRAM init */
 #ifndef CONFIG_SYS_EMIF_PRECALCULATED_TIMING_REGS
+#define CONFIG_SYS_AUTOMATIC_SDRAM_DETECTION	1
 #define CONFIG_SYS_DEFAULT_LPDDR2_TIMINGS	1
 #endif
 
