diff --git a/cpu/arm_cortexm3/stm32/soc.c b/cpu/arm_cortexm3/stm32/soc.c
index 5d435012607efb71b44e8944b88e9dc44f34acf9..8ed716bfa3a73738e4d2f5906b4868ad7e88e5f2 100644
--- a/cpu/arm_cortexm3/stm32/soc.c
+++ b/cpu/arm_cortexm3/stm32/soc.c
@@ -191,6 +191,17 @@ static void stm32f7_mpu_config(void)
 #endif
 		0 <<  8 | 24 <<  1 | 1 <<  0);
 
+#if defined(CONFIG_STM32F7_DCACHE_ON)
+	/*
+	 * Configure DMAMEM as non-cacheable
+	 */
+	cortex_m3_mpu_set_region(MPU_RGN_SDRAM_NC,
+		CONFIG_DMAMEM_BASE | 1 << 4 | MPU_RGN_SDRAM_NC << 0,
+		0 << 28 | 3 << 24 |
+		1 << 19 | 0 << 18 | 0 << 17 | 0 << 16 |
+		0 <<  8 | ((ffs(CONFIG_DMAMEM_SZ_ALL) - 2) <<  1) | 1 <<  0);
+#endif
+
 #if defined(CONFIG_STM32F7_DCACHE_ON) || defined(CONFIG_STM32F7_ICACHE_ON)
 	stm32f7_envm_mpu_cfg(0, 0);
 #endif
@@ -202,40 +213,6 @@ static void stm32f7_mpu_config(void)
 	cortex_m3_mpu_enable(1);
 }
 
-#if defined(CONFIG_STM32F7_DCACHE_ON)
-/*
- * Use 'dmamem' from cmdline passed to kernel to configure non-cacheable
- * region appropriately ('dmamem' is in MB)
- */
-void arch_preboot_os(void)
-{
-	char	buf[256], *s, *e;
-	char	*cmdline = getenv ("bootargs");
-	int	dmamem = 0;
-
-	if (!cmdline)
-		return;
-	s = strstr(cmdline, "dmamem=");
-	if (!s)
-		return;
-	s += strlen("dmamem=");
-	e = strchr(s, ' ');
-	strncpy(buf, s, e - s);
-	dmamem = simple_strtoul(buf, NULL, 10);
-	if (!dmamem)
-		return;
-
-	cortex_m3_mpu_enable(0);
-	cortex_m3_mpu_set_region(MPU_RGN_SDRAM_NC,
-		(CONFIG_SYS_RAM_BASE + CONFIG_SYS_RAM_SIZE -
-		 (dmamem * 1024 * 1024)) | 1 << 4 | MPU_RGN_SDRAM_NC << 0,
-		0 << 28 | 3 << 24 |
-		1 << 19 | 0 << 18 | 0 << 17 | 0 << 16 |
-		0 <<  8 | ((ffs(dmamem) + 18) <<  1) | 1 <<  0);
-	cortex_m3_mpu_enable(1);
-}
-#endif
-
 #if defined(CONFIG_STM32F7_ICACHE_ON) || defined(CONFIG_STM32F7_DCACHE_ON)
 /*
  * Enable Data and/or Instruction caches
diff --git a/include/asm-arm/setup.h b/include/asm-arm/setup.h
index 89df4dc708f19d829b346dd61403316062b12e08..bf4cc2d039a46a7e20651528b77cd8b1032152d6 100644
--- a/include/asm-arm/setup.h
+++ b/include/asm-arm/setup.h
@@ -188,6 +188,15 @@ struct tag_cmdline {
 	char	cmdline[1];	/* this is the minimum size */
 };
 
+/* dmamem parameters, all must be PAGE_SIZE aligned */
+#define ATAG_DMAMEM     0x5441000A
+
+struct tag_dmamem {
+	unsigned long	base;	/* base address of dmamem */
+	unsigned long	sz_all;	/* size of dmamem */
+	unsigned long	sz_fb;	/* size of fb at start of dmamem */
+};
+
 /* acorn RiscPC specific information */
 #define ATAG_ACORN	0x41000101
 
@@ -217,6 +226,7 @@ struct tag {
 		struct tag_revision	revision;
 		struct tag_videolfb	videolfb;
 		struct tag_cmdline	cmdline;
+		struct tag_dmamem	dmamem;
 
 		/*
 		 * Acorn specific
diff --git a/include/configs/stm32f7-som.h b/include/configs/stm32f7-som.h
index 21457caa86fbd53f3dc7a63f65477488bdcc1132..ee48fa1baae8c0329c0b2a39f835c44ad2afb695 100644
--- a/include/configs/stm32f7-som.h
+++ b/include/configs/stm32f7-som.h
@@ -120,10 +120,19 @@
 #define CONFIG_STM32F7_DCACHE_ON
 /* #undef CONFIG_STM32F7_DCACHE_ON */
 
-#ifdef CONFIG_STM32F7_DCACHE_ON
-# define CONFIG_DMAMEM_SIZE		1	/* 1MB, must be a pwr of 2 */
-#else
-# define CONFIG_DMAMEM_SIZE		0
+/*
+ * Actually we don't need DMAMEM if DCACHE is off. But we
+ * want to be able to run the same kernel image with or
+ * without DCACHE. So, pass DMAMEM tag always.
+ * Note, SZ_ALL must be power of 2 (to program MPU correctly)!
+ */
+#define CONFIG_DMAMEM_TAG
+#if defined(CONFIG_DMAMEM_TAG)
+# define CONFIG_DMAMEM_SZ_ALL		(1 << 20)	/* 1MB */
+# define CONFIG_DMAMEM_SZ_FB		(640 * 1024)
+# define CONFIG_DMAMEM_BASE		(CONFIG_SYS_RAM_BASE + \
+					 (CONFIG_SYS_RAM_SIZE / 2) - \
+					 CONFIG_DMAMEM_SZ_ALL)
 #endif
 
 #define CONFIG_ARMCORTEXM3_SOC_INIT
@@ -339,8 +348,7 @@
 /* boot args and env */
 #define CONFIG_HOSTNAME			stm32f7-som
 #define CONFIG_BOOTARGS			"stm32_platform=stm32f7-som "	\
-					"console=ttyS0,115200 panic=10 "\
-					"dmamem=" MK_STR(CONFIG_DMAMEM_SIZE)
+					"console=ttyS0,115200 panic=10"
 
 #define LOADADDR			"0xC0007FC0"
 
diff --git a/lib_arm/bootm.c b/lib_arm/bootm.c
index 4e32350ec5a405d40865e1e3566403ec345848a7..dd18c255eec1fa95cd8659ff7d9e18bdd01d3df1 100644
--- a/lib_arm/bootm.c
+++ b/lib_arm/bootm.c
@@ -35,7 +35,8 @@ DECLARE_GLOBAL_DATA_PTR;
     defined (CONFIG_SERIAL_TAG) || \
     defined (CONFIG_REVISION_TAG) || \
     defined (CONFIG_VFD) || \
-    defined (CONFIG_LCD)
+    defined (CONFIG_LCD) || \
+    defined (CONFIG_DMAMEM_TAG)
 static void setup_start_tag (bd_t *bd);
 
 # ifdef CONFIG_SETUP_MEMORY_TAGS
@@ -53,6 +54,10 @@ static void setup_end_tag (bd_t *bd);
 static void setup_videolfb_tag (gd_t *gd);
 # endif
 
+# ifdef CONFIG_DMAMEM_TAG
+static void setup_dmamem_tag (void);
+# endif
+
 static struct tag *params;
 #endif /* CONFIG_SETUP_MEMORY_TAGS || CONFIG_CMDLINE_TAG || CONFIG_INITRD_TAG */
 
@@ -89,7 +94,8 @@ int do_bootm_linux(int flag, int argc, char *argv[], bootm_headers_t *images)
     defined (CONFIG_SERIAL_TAG) || \
     defined (CONFIG_REVISION_TAG) || \
     defined (CONFIG_LCD) || \
-    defined (CONFIG_VFD)
+    defined (CONFIG_VFD) || \
+    defined (CONFIG_DMAMEM_TAG)
 	setup_start_tag (bd);
 #ifdef CONFIG_SERIAL_TAG
 	setup_serial_tag (&params);
@@ -109,6 +115,9 @@ int do_bootm_linux(int flag, int argc, char *argv[], bootm_headers_t *images)
 #endif
 #if defined (CONFIG_VFD) || defined (CONFIG_LCD)
 	setup_videolfb_tag ((gd_t *) gd);
+#endif
+#ifdef CONFIG_DMAMEM_TAG
+	setup_dmamem_tag();
 #endif
 	setup_end_tag (bd);
 #endif
@@ -285,6 +294,18 @@ void setup_revision_tag(struct tag **in_params)
 }
 #endif  /* CONFIG_REVISION_TAG */
 
+#ifdef CONFIG_DMAMEM_TAG
+void setup_dmamem_tag (void)
+{
+	params->hdr.tag = ATAG_DMAMEM;
+	params->hdr.size = tag_size(tag_dmamem);
+	params->u.dmamem.base = CONFIG_DMAMEM_BASE;
+	params->u.dmamem.sz_all = CONFIG_DMAMEM_SZ_ALL;
+	params->u.dmamem.sz_fb = CONFIG_DMAMEM_SZ_FB;
+	params = tag_next(params);
+}
+#endif
+
 
 static void setup_end_tag (bd_t *bd)
 {