diff --git a/arch/nds32/dts/ag101p.dts b/arch/nds32/dts/ag101p.dts
index 19dc36fa157e87fbdffe1de9960cb0c395ee998e..7832efb12fbea6e273c0858f8b906a00d8077b2f 100644
--- a/arch/nds32/dts/ag101p.dts
+++ b/arch/nds32/dts/ag101p.dts
@@ -67,5 +67,6 @@
 		fifo-depth = <0x10>;
 		reg = <0x98e00000 0x1000>;
 		interrupts = <5 4>;
+		cap-sd-highspeed;
 	};
 };
diff --git a/arch/nds32/include/asm/arch-ae3xx/ae3xx.h b/arch/nds32/include/asm/arch-ae3xx/ae3xx.h
index b074e8489a186ef1a658a2f76781810ee6e2f0b5..9d55c9784c58aae46e635cd7183729c2719b693d 100644
--- a/arch/nds32/include/asm/arch-ae3xx/ae3xx.h
+++ b/arch/nds32/include/asm/arch-ae3xx/ae3xx.h
@@ -44,8 +44,6 @@
 #define CONFIG_FTGPIO010_BASE		0xf0700000
 /* I2C */
 #define CONFIG_FTIIC010_BASE		0xf0a00000
-/* SD Controller */
-#define CONFIG_FTSDC010_BASE		0xf0e00000
 
 /* The following address was not defined in Linux */
 
diff --git a/arch/nds32/include/asm/arch-ag101/ag101.h b/arch/nds32/include/asm/arch-ag101/ag101.h
index 490f28b62d847c6c8f455a23fbc8fe2957e929fd..0f4c3efbd4dccdcfcc87de8ef84f07b7da8084d2 100644
--- a/arch/nds32/include/asm/arch-ag101/ag101.h
+++ b/arch/nds32/include/asm/arch-ag101/ag101.h
@@ -69,8 +69,6 @@
 #define CONFIG_RESERVED_04_BASE		0x98C00000
 /* Compat Flash Controller */
 #define CONFIG_FTCFC010_BASE		0x98D00000
-/* SD Controller */
-#define CONFIG_FTSDC010_BASE		0x98E00000
 
 /* Synchronous Serial Port Controller (SSP) I2S/AC97 */
 #define CONFIG_FTSSP010_02_BASE		0x99400000
diff --git a/arch/nds32/include/asm/arch-ag102/ag102.h b/arch/nds32/include/asm/arch-ag102/ag102.h
index c5ee3d94985b9fbb5dcd21b336b711bbd8a6a5ec..a8aef9381f4ab099013302b130e0d11afd992c22 100644
--- a/arch/nds32/include/asm/arch-ag102/ag102.h
+++ b/arch/nds32/include/asm/arch-ag102/ag102.h
@@ -56,8 +56,6 @@
 #define CONFIG_FTSSP010_01_BASE		0x94100000
 /* UART1 - APB STUART Controller (UART0 in Linux) */
 #define CONFIG_FTUART010_01_BASE	0x94200000
-/* FTSDC010 SD Controller */
-#define CONFIG_FTSDC010_BASE		0x94400000
 /* APB - SSP with HDA/AC97 Controller */
 #define CONFIG_FTSSP010_02_BASE		0x94500000
 /* UART2 - APB STUART Controller (UART1 in Linux) */
diff --git a/arch/riscv/cpu/nx25/start.S b/arch/riscv/cpu/nx25/start.S
index 6a076639d34191f9f423a66062c64b78c5551842..cd0a66360de3da6800036e38619abbd5ff81e99c 100644
--- a/arch/riscv/cpu/nx25/start.S
+++ b/arch/riscv/cpu/nx25/start.S
@@ -45,6 +45,8 @@ trap_vector:
 
 .global trap_entry
 handle_reset:
+	li t0, CONFIG_SYS_SDRAM_BASE
+	SREG a2, 0(t0)
 	la t0, trap_entry
 	csrw mtvec, t0
 	csrwi mstatus, 0
diff --git a/arch/riscv/dts/ae250.dts b/arch/riscv/dts/ae250.dts
index 5dc4fb04be62a4c506bbd0b309f8c48a2a2ed8dd..9a38345e36058ae88687ec88108683c11d3e1d1c 100644
--- a/arch/riscv/dts/ae250.dts
+++ b/arch/riscv/dts/ae250.dts
@@ -74,6 +74,7 @@
 		fifo-depth = <0x10>;
 		reg = <0xf0e00000 0x1000>;
 		interrupts = <17 4>;
+		cap-sd-highspeed;
 	};
 
 	spi: spi@f0b00000 {
diff --git a/arch/riscv/include/asm/bootm.h b/arch/riscv/include/asm/bootm.h
index 0a644bb58bb62d138c68d24ddf3b4eaa6aba123b..9a90f23a22e49c5f99a83a19c5743af2519e12d5 100644
--- a/arch/riscv/include/asm/bootm.h
+++ b/arch/riscv/include/asm/bootm.h
@@ -13,53 +13,4 @@
 
 #include <asm/setup.h>
 
-#if defined(CONFIG_SETUP_MEMORY_TAGS) || \
-		defined(CONFIG_CMDLINE_TAG) || \
-		defined(CONFIG_INITRD_TAG) || \
-		defined(CONFIG_SERIAL_TAG) || \
-		defined(CONFIG_REVISION_TAG)
-# define BOOTM_ENABLE_TAGS		1
-#else
-# define BOOTM_ENABLE_TAGS		0
-#endif
-
-#ifdef CONFIG_SETUP_MEMORY_TAGS
-# define BOOTM_ENABLE_MEMORY_TAGS	1
-#else
-# define BOOTM_ENABLE_MEMORY_TAGS	0
-#endif
-
-#ifdef CONFIG_CMDLINE_TAG
- #define BOOTM_ENABLE_CMDLINE_TAG	1
-#else
- #define BOOTM_ENABLE_CMDLINE_TAG	0
-#endif
-
-#ifdef CONFIG_INITRD_TAG
- #define BOOTM_ENABLE_INITRD_TAG	1
-#else
- #define BOOTM_ENABLE_INITRD_TAG	0
-#endif
-
-#ifdef CONFIG_SERIAL_TAG
- #define BOOTM_ENABLE_SERIAL_TAG	1
-void get_board_serial(struct tag_serialnr *serialnr);
-#else
- #define BOOTM_ENABLE_SERIAL_TAG	0
-static inline void get_board_serial(struct tag_serialnr *serialnr)
-{
-}
-#endif
-
-#ifdef CONFIG_REVISION_TAG
- #define BOOTM_ENABLE_REVISION_TAG	1
-u32 get_board_rev(void);
-#else
- #define BOOTM_ENABLE_REVISION_TAG	0
-static inline u32 get_board_rev(void)
-{
-	return 0;
-}
-#endif
-
 #endif
diff --git a/arch/riscv/include/asm/encoding.h b/arch/riscv/include/asm/encoding.h
index 5ff6d591499fd7497c3dd51d6d7573e7a18a76d1..dbf8d45fb72f3dc6a2a7d13f7a3d06369835fd81 100644
--- a/arch/riscv/include/asm/encoding.h
+++ b/arch/riscv/include/asm/encoding.h
@@ -121,7 +121,9 @@
 #define PTE_SW(PTE)	((0x88888880U >> ((PTE) & 0x1F)) & 1)
 #define PTE_SX(PTE)	((0xA0A0A000U >> ((PTE) & 0x1F)) & 1)
 
-#define PTE_CHECK_PERM(PTE, SUPERVISOR, STORE, FETCH) \
+#define PTE_CHECK_PERM(_PTE, _SUPERVISOR, STORE, FETCH) \
+	typeof(_PTE) (PTE) = (_PTE); \
+	typeof(_SUPERVISOR) (SUPERVISOR) = (_SUPERVISOR); \
 	((STORE) ? ((SUPERVISOR) ? PTE_SW(PTE) : PTE_UW(PTE)) : \
 	(FETCH) ? ((SUPERVISOR) ? PTE_SX(PTE) : PTE_UX(PTE)) : \
 	((SUPERVISOR) ? PTE_SR(PTE) : PTE_UR(PTE)))
@@ -151,27 +153,31 @@
 	asm volatile ("csrr %0, " #reg : "=r"(__tmp)); \
 	__tmp; })
 
-#define write_csr(reg, val) ({ \
+#define write_csr(reg, _val) ({ \
+typeof(_val) (val) = (_val); \
 if (__builtin_constant_p(val) && (unsigned long)(val) < 32) \
 	asm volatile ("csrw " #reg ", %0" :: "i"(val)); \
 else \
 	asm volatile ("csrw " #reg ", %0" :: "r"(val)); })
 
-#define swap_csr(reg, val) ({ unsigned long __tmp; \
+#define swap_csr(reg, _val) ({ unsigned long __tmp; \
+typeof(_val) (val) = (_val); \
 if (__builtin_constant_p(val) && (unsigned long)(val) < 32) \
 	asm volatile ("csrrw %0, " #reg ", %1" : "=r"(__tmp) : "i"(val)); \
 else \
 	asm volatile ("csrrw %0, " #reg ", %1" : "=r"(__tmp) : "r"(val)); \
 	__tmp; })
 
-#define set_csr(reg, bit) ({ unsigned long __tmp; \
+#define set_csr(reg, _bit) ({ unsigned long __tmp; \
+typeof(_bit) (bit) = (_bit); \
 if (__builtin_constant_p(bit) && (unsigned long)(bit) < 32) \
 	asm volatile ("csrrs %0, " #reg ", %1" : "=r"(__tmp) : "i"(bit)); \
 else \
 	asm volatile ("csrrs %0, " #reg ", %1" : "=r"(__tmp) : "r"(bit)); \
 	__tmp; })
 
-#define clear_csr(reg, bit) ({ unsigned long __tmp; \
+#define clear_csr(reg, _bit) ({ unsigned long __tmp; \
+typeof(_bit) (bit) = (_bit); \
 if (__builtin_constant_p(bit) && (unsigned long)(bit) < 32) \
 	asm volatile ("csrrc %0, " #reg ", %1" : "=r"(__tmp) : "i"(bit)); \
 else \
diff --git a/arch/riscv/include/asm/global_data.h b/arch/riscv/include/asm/global_data.h
index 0cce98ab531a8ad2248a91a2093b00053b8cb144..bd352c2cda951531f19f441514c98f8b7fa883f5 100644
--- a/arch/riscv/include/asm/global_data.h
+++ b/arch/riscv/include/asm/global_data.h
@@ -17,6 +17,6 @@ struct arch_global_data {
 
 #include <asm-generic/global_data.h>
 
-#define DECLARE_GLOBAL_DATA_PTR register volatile gd_t *gd asm ("gp")
+#define DECLARE_GLOBAL_DATA_PTR register gd_t *gd asm ("gp")
 
 #endif /* __ASM_GBL_DATA_H */
diff --git a/arch/riscv/include/asm/io.h b/arch/riscv/include/asm/io.h
index e7f63ed8a9d6d9e12204d67838f503a76dd64b5d..1df6b1b2bf0ed2f9fce25ce99368690e683d4d48 100644
--- a/arch/riscv/include/asm/io.h
+++ b/arch/riscv/include/asm/io.h
@@ -416,19 +416,17 @@ static inline void writesl(unsigned int *addr, const void *data, int longlen)
 #define eth_io_copy_and_sum(s, c, l, b) \
 	eth_copy_and_sum((s), __mem_pci(c), (l), (b))
 
-static inline int
-check_signature(unsigned long io_addr, const unsigned char *signature,
-		  int length)
+static inline int check_signature(ulong io_addr, const uchar *s, int len)
 {
 	int retval = 0;
 
 	do {
-		if (readb(io_addr) != *signature)
+		if (readb(io_addr) != *s)
 			goto out;
 		io_addr++;
-		signature++;
-		length--;
-	} while (length);
+		s++;
+		len--;
+	} while (len);
 	retval = 1;
 out:
 	return retval;
@@ -455,18 +453,17 @@ out:
 	eth_copy_and_sum((a), __mem_isa(b), (c), (d))
 
 static inline int
-isa_check_signature(unsigned long io_addr, const unsigned char *signature,
-		       int length)
+isa_check_signature(ulong io_addr, const uchar *s, int len)
 {
 	int retval = 0;
 
 	do {
-		if (isa_readb(io_addr) != *signature)
+		if (isa_readb(io_addr) != *s)
 			goto out;
 		io_addr++;
-		signature++;
-		length--;
-	} while (length);
+		s++;
+		len--;
+	} while (len);
 	retval = 1;
 out:
 	return retval;
diff --git a/arch/riscv/include/asm/posix_types.h b/arch/riscv/include/asm/posix_types.h
index 6892b6681430f445d08a121c5d1b323f3bc867fe..7438dbeb03f8ba8e1d50a83a9d5b426382a76584 100644
--- a/arch/riscv/include/asm/posix_types.h
+++ b/arch/riscv/include/asm/posix_types.h
@@ -69,19 +69,23 @@ typedef struct {
 #if defined(__KERNEL__) || !defined(__GLIBC__) || (__GLIBC__ < 2)
 
 #undef	__FD_SET
-#define __FD_SET(fd, fdsetp) \
+#define __FD_SET(_fd, fdsetp) \
+	typeof(_fd) (fd) = (_fd); \
 	(((fd_set *)fdsetp)->fds_bits[fd >> 5] |= (1 << (fd & 31)))
 
 #undef	__FD_CLR
-#define __FD_CLR(fd, fdsetp) \
+#define __FD_CLR(_fd, fdsetp) \
+	typeof(_fd) (fd) = (_fd); \
 	(((fd_set *)fdsetp)->fds_bits[fd >> 5] &= ~(1 << (fd & 31)))
 
 #undef	__FD_ISSET
-#define __FD_ISSET(fd, fdsetp) \
+#define __FD_ISSET(_fd, fdsetp) \
+	typeof(_fd) (fd) = (_fd); \
 	((((fd_set *)fdsetp)->fds_bits[fd >> 5] & (1 << (fd & 31))) != 0)
 
 #undef	__FD_ZERO
-#define __FD_ZERO(fdsetp) \
+#define __FD_ZERO(_fdsetp) \
+	typeof(_fdsetp) (fd) = (_fdsetp); \
 	(memset(fdsetp, 0, sizeof(*(fd_set *)fdsetp)))
 
 #endif
diff --git a/arch/riscv/include/asm/ptrace.h b/arch/riscv/include/asm/ptrace.h
index 76d68698bb4e4a8ae93237edcf1c73ae59a4b34e..651078fcfda39ba012896c6761d5396a3d89fd4e 100644
--- a/arch/riscv/include/asm/ptrace.h
+++ b/arch/riscv/include/asm/ptrace.h
@@ -65,8 +65,7 @@ static inline unsigned long instruction_pointer(struct pt_regs *regs)
 	return GET_IP(regs);
 }
 
-static inline void instruction_pointer_set(struct pt_regs *regs,
-					     unsigned long val)
+static inline void instruction_pointer_set(struct pt_regs *regs, ulong val)
 {
 	SET_IP(regs, val);
 }
@@ -82,8 +81,7 @@ static inline unsigned long user_stack_pointer(struct pt_regs *regs)
 	return GET_USP(regs);
 }
 
-static inline void user_stack_pointer_set(struct pt_regs *regs,
-					     unsigned long val)
+static inline void user_stack_pointer_set(struct pt_regs *regs, ulong val)
 {
 	SET_USP(regs, val);
 }
@@ -97,8 +95,7 @@ static inline unsigned long frame_pointer(struct pt_regs *regs)
 	return GET_FP(regs);
 }
 
-static inline void frame_pointer_set(struct pt_regs *regs,
-				       unsigned long val)
+static inline void frame_pointer_set(struct pt_regs *regs, ulong val)
 {
 	SET_FP(regs, val);
 }
diff --git a/arch/riscv/include/asm/setup.h b/arch/riscv/include/asm/setup.h
index 731b0d96aaae3c0d4b5f93e58d88567331326f4a..4b182432f1e8128aa99f43f9dcdf5395c64f0d7d 100644
--- a/arch/riscv/include/asm/setup.h
+++ b/arch/riscv/include/asm/setup.h
@@ -145,14 +145,18 @@ struct tagtable {
 	int (*parse)(const struct tag *);
 };
 
-#define tag_member_present(tag, member)				\
+#define tag_member_present(_tag, member)				\
+	typeof(_tag) (tag) = (_tag); \
 	((unsigned long)(&((struct tag *)0L)->member + 1)	\
 		<= (tag)->hdr.size * 4)
 
-#define tag_next(t)	((struct tag *)((u32 *)(t) + (t)->hdr.size))
+#define tag_next(_t)	\
+	typeof(_t) (t) = (_t); \
+	((struct tag *)((u32 *)(t) + (t)->hdr.size))
 #define tag_size(type)	((sizeof(struct tag_header) + sizeof(struct type)) >> 2)
 
-#define for_each_tag(t, base) \
+#define for_each_tag(_t, base) \
+	typeof(_t) (t) = (_t); \
 	for (t = base; t->hdr.size; t = tag_next(t))
 
 #ifdef __KERNEL__
diff --git a/arch/riscv/include/asm/string.h b/arch/riscv/include/asm/string.h
index 038cdaea72901ffd09388f35171bb05980a2b9eb..0fc3424a2f1a670b786fe091f9681ec0e06829c6 100644
--- a/arch/riscv/include/asm/string.h
+++ b/arch/riscv/include/asm/string.h
@@ -26,8 +26,11 @@
 #undef __HAVE_ARCH_MEMSET
 
 #ifdef CONFIG_MARCO_MEMSET
-#define memset(p, v, n)							\
-	({								\
+#define memset(_p, _v, _n)	\
+	(typeof(_p) (p) = (_p); \
+	 typeof(_v) (v) = (_v); \
+	 typeof(_n) (n) = (_n); \
+	 {								\
 		if ((n) != 0) {						\
 			if (__builtin_constant_p((v)) && (v) == 0)	\
 				__memzero((p), (n));			\
@@ -37,7 +40,10 @@
 		(p);							\
 	})
 
-#define memzero(p, n) ({ if ((n) != 0) __memzero((p), (n)); (p); })
+#define memzero(_p, _n) \
+	(typeof(_p) (p) = (_p); \
+	 typeof(_n) (n) = (_n); \
+	 { if ((n) != 0) __memzero((p), (n)); (p); })
 #endif
 
 #endif /* __ASM_RISCV_STRING_H */
diff --git a/arch/riscv/lib/bootm.c b/arch/riscv/lib/bootm.c
index 44ce38b614281a3a9e91b3e216958de800d945cd..9242fa891ac25795067dc3ede0c635342a258921 100644
--- a/arch/riscv/lib/bootm.c
+++ b/arch/riscv/lib/bootm.c
@@ -21,36 +21,12 @@ int arch_fixup_fdt(void *blob)
 	return 0;
 }
 
-#if defined(CONFIG_SETUP_MEMORY_TAGS) || \
-	defined(CONFIG_CMDLINE_TAG) || \
-	defined(CONFIG_INITRD_TAG) || \
-	defined(CONFIG_SERIAL_TAG) || \
-	defined(CONFIG_REVISION_TAG)
-static void setup_start_tag(bd_t *bd);
-
-# ifdef CONFIG_SETUP_MEMORY_TAGS
-static void setup_memory_tags(bd_t *bd);
-# endif
-static void setup_commandline_tag(bd_t *bd, char *commandline);
-
-# ifdef CONFIG_INITRD_TAG
-static void setup_initrd_tag(bd_t *bd, ulong initrd_start, ulong initrd_end);
-# endif
-static void setup_end_tag(bd_t *bd);
-
-static struct tag *params;
-#endif /* CONFIG_SETUP_MEMORY_TAGS || CONFIG_CMDLINE_TAG || CONFIG_INITRD_TAG */
-
 int do_bootm_linux(int flag, int argc, char *argv[], bootm_headers_t *images)
 {
 	bd_t	*bd = gd->bd;
 	char	*s;
 	int	machid = bd->bi_arch_number;
-	void	(*theKernel)(int zero, int arch, uint params);
-
-#ifdef CONFIG_CMDLINE_TAG
-	char *commandline = env_get("bootargs");
-#endif
+	void	(*theKernel)(int arch, uint params);
 
 	/*
 	 * allow the PREP bootm subcommand, it is required for bootm to work
@@ -61,7 +37,7 @@ int do_bootm_linux(int flag, int argc, char *argv[], bootm_headers_t *images)
 	if ((flag != 0) && (flag != BOOTM_STATE_OS_GO))
 		return 1;
 
-	theKernel = (void (*)(int, int, uint))images->ep;
+	theKernel = (void (*)(int, uint))images->ep;
 
 	s = env_get("machid");
 	if (s) {
@@ -82,167 +58,16 @@ int do_bootm_linux(int flag, int argc, char *argv[], bootm_headers_t *images)
 			hang();
 		}
 #endif
-	} else if (BOOTM_ENABLE_TAGS) {
-#if defined(CONFIG_SETUP_MEMORY_TAGS) || \
-	defined(CONFIG_CMDLINE_TAG) || \
-	defined(CONFIG_INITRD_TAG) || \
-	defined(CONFIG_SERIAL_TAG) || \
-	defined(CONFIG_REVISION_TAG)
-	setup_start_tag(bd);
-#ifdef CONFIG_SERIAL_TAG
-	setup_serial_tag(&params);
-#endif
-#ifdef CONFIG_REVISION_TAG
-	setup_revision_tag(&params);
-#endif
-#ifdef CONFIG_SETUP_MEMORY_TAGS
-	setup_memory_tags(bd);
-#endif
-#ifdef CONFIG_CMDLINE_TAG
-	setup_commandline_tag(bd, commandline);
-#endif
-#ifdef CONFIG_INITRD_TAG
-	if (images->rd_start && images->rd_end)
-		setup_initrd_tag(bd, images->rd_start, images->rd_end);
-#endif
-	setup_end_tag(bd);
-#endif
+	}
 
 	/* we assume that the kernel is in place */
 	printf("\nStarting kernel ...\n\n");
 
-#ifdef CONFIG_USB_DEVICE
-	{
-		extern void udc_disconnect(void);
-		udc_disconnect();
-	}
-#endif
-	}
 	cleanup_before_linux();
 	if (IMAGE_ENABLE_OF_LIBFDT && images->ft_len)
-		theKernel(0, machid, (unsigned long)images->ft_addr);
-	else
-	theKernel(0, machid, bd->bi_boot_params);
+		theKernel(machid, (unsigned long)images->ft_addr);
+
 	/* does not return */
 
 	return 1;
 }
-
-#if defined(CONFIG_SETUP_MEMORY_TAGS) || \
-	defined(CONFIG_CMDLINE_TAG) || \
-	defined(CONFIG_INITRD_TAG) || \
-	defined(CONFIG_SERIAL_TAG) || \
-	defined(CONFIG_REVISION_TAG)
-static void setup_start_tag(bd_t *bd)
-{
-	params = (struct tag *)bd->bi_boot_params;
-
-	params->hdr.tag = ATAG_CORE;
-	params->hdr.size = tag_size(tag_core);
-
-	params->u.core.flags = 0;
-	params->u.core.pagesize = 0;
-	params->u.core.rootdev = 0;
-
-	params = tag_next(params);
-}
-
-#ifdef CONFIG_SETUP_MEMORY_TAGS
-static void setup_memory_tags(bd_t *bd)
-{
-	int i;
-
-	for (i = 0; i < CONFIG_NR_DRAM_BANKS; i++) {
-		params->hdr.tag = ATAG_MEM;
-		params->hdr.size = tag_size(tag_mem32);
-
-		params->u.mem.start = bd->bi_dram[i].start;
-		params->u.mem.size = bd->bi_dram[i].size;
-
-		params = tag_next(params);
-	}
-}
-#endif /* CONFIG_SETUP_MEMORY_TAGS */
-
-static void setup_commandline_tag(bd_t *bd, char *commandline)
-{
-	char *p;
-
-	if (!commandline)
-		return;
-
-	/* eat leading white space */
-	for (p = commandline; *p == ' '; p++)
-		;
-
-	/* skip non-existent command lines so the kernel will still
-	 * use its default command line.
-	 */
-	if (*p == '\0')
-		return;
-
-	params->hdr.tag = ATAG_CMDLINE;
-	params->hdr.size =
-		(sizeof(struct tag_header) + strlen(p) + 1 + 4) >> 2;
-
-	strcpy(params->u.cmdline.cmdline, p)
-		;
-
-	params = tag_next(params);
-}
-
-#ifdef CONFIG_INITRD_TAG
-static void setup_initrd_tag(bd_t *bd, ulong initrd_start, ulong initrd_end)
-{
-	/* an ATAG_INITRD node tells the kernel where the compressed
-	 * ramdisk can be found. ATAG_RDIMG is a better name, actually.
-	 */
-	params->hdr.tag = ATAG_INITRD2;
-	params->hdr.size = tag_size(tag_initrd);
-
-	params->u.initrd.start = initrd_start;
-	params->u.initrd.size = initrd_end - initrd_start;
-
-	params = tag_next(params);
-}
-#endif /* CONFIG_INITRD_TAG */
-
-#ifdef CONFIG_SERIAL_TAG
-void setup_serial_tag(struct tag **tmp)
-{
-	struct tag *params;
-	struct tag_serialnr serialnr;
-	void get_board_serial(struct tag_serialnr *serialnr);
-
-	params = *tmp;
-	get_board_serial(&serialnr);
-	params->hdr.tag = ATAG_SERIAL;
-	params->hdr.size = tag_size(tag_serialnr);
-	params->u.serialnr.low = serialnr.low;
-	params->u.serialnr.high = serialnr.high;
-	params = tag_next(params);
-	*tmp = params;
-}
-#endif
-
-#ifdef CONFIG_REVISION_TAG
-void setup_revision_tag(struct tag **in_params)
-{
-	u32 rev;
-	u32 get_board_rev(void);
-
-	rev = get_board_rev();
-	params->hdr.tag = ATAG_REVISION;
-	params->hdr.size = tag_size(tag_revision);
-	params->u.revision.rev = rev;
-	params = tag_next(params);
-}
-#endif  /* CONFIG_REVISION_TAG */
-
-static void setup_end_tag(bd_t *bd)
-{
-	params->hdr.tag = ATAG_NONE;
-	params->hdr.size = 0;
-}
-
-#endif /* CONFIG_SETUP_MEMORY_TAGS || CONFIG_CMDLINE_TAG || CONFIG_INITRD_TAG */
diff --git a/arch/riscv/lib/interrupts.c b/arch/riscv/lib/interrupts.c
index 075db8ba464dd9898888b397ce9c782cfea10737..923f75275bd4bd52c2d7156358f9224b5d279b6e 100644
--- a/arch/riscv/lib/interrupts.c
+++ b/arch/riscv/lib/interrupts.c
@@ -63,7 +63,7 @@ __attribute__((weak)) void timer_interrupt(struct pt_regs *regs)
 
 static void _exit_trap(int code, uint epc, struct pt_regs *regs)
 {
-	static const char *exception_code[] = {
+	static const char * const exception_code[] = {
 		"Instruction address misaligned",
 		"Instruction access fault",
 		"Illegal instruction",
diff --git a/board/AndesTech/adp-ae3xx/adp-ae3xx.c b/board/AndesTech/adp-ae3xx/adp-ae3xx.c
index 8cffb6ba8bc45e453dcdef66c98224b855753401..52a89dc7a0008786240abc1dd8c13e2ce96720c1 100644
--- a/board/AndesTech/adp-ae3xx/adp-ae3xx.c
+++ b/board/AndesTech/adp-ae3xx/adp-ae3xx.c
@@ -12,7 +12,6 @@
 #include <netdev.h>
 #endif
 #include <linux/io.h>
-#include <faraday/ftsdc010.h>
 #include <faraday/ftsmc020.h>
 
 DECLARE_GLOBAL_DATA_PTR;
@@ -75,13 +74,3 @@ ulong board_flash_get_legacy(ulong base, int banknum, flash_info_t *info)
 		return 0;
 	}
 }
-
-int board_mmc_init(bd_t *bis)
-{
-#ifndef CONFIG_DM_MMC
-#ifdef CONFIG_FTSDC010
-	ftsdc010_mmc_init(0);
-#endif
-#endif
-	return 0;
-}
diff --git a/board/AndesTech/adp-ag101p/adp-ag101p.c b/board/AndesTech/adp-ag101p/adp-ag101p.c
index f918c630c1720669f7564e7ca535012558663422..82928e78a4fca82f2601d70bef69d788b838c7c6 100644
--- a/board/AndesTech/adp-ag101p/adp-ag101p.c
+++ b/board/AndesTech/adp-ag101p/adp-ag101p.c
@@ -14,7 +14,6 @@
 #include <asm/io.h>
 #include <asm/mach-types.h>
 
-#include <faraday/ftsdc010.h>
 #include <faraday/ftsmc020.h>
 
 DECLARE_GLOBAL_DATA_PTR;
@@ -82,13 +81,3 @@ ulong board_flash_get_legacy(ulong base, int banknum, flash_info_t *info)
 		return 0;
 	}
 }
-
-int board_mmc_init(bd_t *bis)
-{
-#ifndef CONFIG_DM_MMC
-#ifdef CONFIG_FTSDC010
-	ftsdc010_mmc_init(0);
-#endif
-#endif
-	return 0;
-}
diff --git a/board/AndesTech/nx25-ae250/nx25-ae250.c b/board/AndesTech/nx25-ae250/nx25-ae250.c
index 12f2d3520bfbb23e8cf04bfed5577deedb495e62..6e31be35052328fe8861679d9bc44639795b99c5 100644
--- a/board/AndesTech/nx25-ae250/nx25-ae250.c
+++ b/board/AndesTech/nx25-ae250/nx25-ae250.c
@@ -11,7 +11,6 @@
 #include <netdev.h>
 #endif
 #include <linux/io.h>
-#include <faraday/ftsdc010.h>
 
 DECLARE_GLOBAL_DATA_PTR;
 
@@ -66,12 +65,11 @@ ulong board_flash_get_legacy(ulong base, int banknum, flash_info_t *info)
 	return 0;
 }
 
-int board_mmc_init(bd_t *bis)
+void *board_fdt_blob_setup(void)
 {
-#ifndef CONFIG_DM_MMC
-#ifdef CONFIG_FTSDC010
-	ftsdc010_mmc_init(0);
-#endif
-#endif
-	return 0;
+	void **ptr = (void *)CONFIG_SYS_SDRAM_BASE;
+	if (fdt_magic(*ptr) == FDT_MAGIC)
+			return (void *)*ptr;
+
+	return (void *)CONFIG_SYS_FDT_BASE;
 }
diff --git a/common/image.c b/common/image.c
index f5278a0df4512320ef92294be615aa20c181e89a..e1c50eb25d0e5e2814c200a3e8c025ac17cf756b 100644
--- a/common/image.c
+++ b/common/image.c
@@ -86,6 +86,7 @@ static const table_entry_t uimage_arch[] = {
 	{	IH_ARCH_ARC,		"arc",		"ARC",		},
 	{	IH_ARCH_X86_64,		"x86_64",	"AMD x86_64",	},
 	{	IH_ARCH_XTENSA,		"xtensa",	"Xtensa",	},
+	{	IH_ARCH_RISCV,		"riscv",	"RISC-V",	},
 	{	-1,			"",		"",		},
 };
 
diff --git a/configs/adp-ae3xx_defconfig b/configs/adp-ae3xx_defconfig
index f3eabea70e55560551e552448f58959a6a122b9c..af17718f90173b3d1c11f1c134187918fba498f9 100644
--- a/configs/adp-ae3xx_defconfig
+++ b/configs/adp-ae3xx_defconfig
@@ -24,8 +24,8 @@ CONFIG_DM=y
 CONFIG_CLK=y
 CONFIG_MMC=y
 CONFIG_DM_MMC=y
-CONFIG_MMC_NDS32=y
 CONFIG_FTSDC010=y
+CONFIG_FTSDC010_SDIO=y
 CONFIG_MTD=y
 CONFIG_MTD_NOR_FLASH=y
 CONFIG_CFI_FLASH=y
diff --git a/configs/adp-ag101p_defconfig b/configs/adp-ag101p_defconfig
index 742d9046ad075bc98ceee062696de899fefc6f93..481ef5b8706da95b5b268d3a8eecb860b94888cc 100644
--- a/configs/adp-ag101p_defconfig
+++ b/configs/adp-ag101p_defconfig
@@ -21,8 +21,8 @@ CONFIG_NET_RANDOM_ETHADDR=y
 CONFIG_DM=y
 CONFIG_MMC=y
 CONFIG_DM_MMC=y
-CONFIG_MMC_NDS32=y
 CONFIG_FTSDC010=y
+CONFIG_FTSDC010_SDIO=y
 CONFIG_MTD_NOR_FLASH=y
 CONFIG_DM_ETH=y
 CONFIG_FTMAC100=y
diff --git a/configs/nx25-ae250_defconfig b/configs/nx25-ae250_defconfig
index 47b83db5eaef8fe30f8513437a85a81014b0dd25..4f9bd58f75568341970fbdfff7c542e346d433b7 100644
--- a/configs/nx25-ae250_defconfig
+++ b/configs/nx25-ae250_defconfig
@@ -16,14 +16,15 @@ CONFIG_CMD_CACHE=y
 CONFIG_CMD_EXT2=y
 CONFIG_CMD_FAT=y
 CONFIG_OF_CONTROL=y
+CONFIG_OF_BOARD=y
 CONFIG_ENV_IS_IN_SPI_FLASH=y
 CONFIG_NET_RANDOM_ETHADDR=y
 CONFIG_DM=y
 CONFIG_CLK=y
 CONFIG_MMC=y
 CONFIG_DM_MMC=y
-CONFIG_MMC_NDS32=y
 CONFIG_FTSDC010=y
+CONFIG_FTSDC010_SDIO=y
 CONFIG_DM_SPI_FLASH=y
 CONFIG_SPI_FLASH=y
 CONFIG_SPI_FLASH_MACRONIX=y
diff --git a/doc/README.ae250 b/doc/README.ae250
index a80bb39b15750b84c6c9577adeba13f624070aa5..77c168af34c1d446b56314ca83a2080e3885e020 100644
--- a/doc/README.ae250
+++ b/doc/README.ae250
@@ -49,8 +49,8 @@ Steps
 5. Burn this u-boot image to spi rom by spi driver
 6. Re-boot u-boot from spi flash with power off and power on.
 
-Messages
-====================
+Messages of U-Boot boot on AE250 board
+======================================
 U-Boot 2018.01-rc2-00033-g824f89a (Dec 21 2017 - 16:51:26 +0800)
 
 DRAM:  1 GiB
@@ -131,7 +131,145 @@ Warning: mac@e0100000 (eth0) using random MAC address - ee:4c:58:29:32:f5
 eth0: mac@e0100000
 RISC-V #
 
-TODO
-====================
 
-Boot bbl and riscv-linux
+Boot bbl and riscv-linux via U-Boot on QEMU
+===========================================
+1. Build riscv-linux
+2. Build bbl and riscv-linux with --with-payload
+3. Prepare ae250.dtb
+4. Creating OS-kernel images
+	./mkimage -A riscv -O linux -T kernel -C none -a 0x0000 -e 0x0000 -d bbl.bin bootmImage-bbl.bin
+	Image Name:
+	Created:      Tue Mar 13 10:06:42 2018
+	Image Type:   RISC-V Linux Kernel Image (uncompressed)
+	Data Size:    17901204 Bytes = 17481.64 KiB = 17.07 MiB
+	Load Address: 00000000
+	Entry Point:  00000000
+
+4. Copy bootmImage-bbl.bin and ae250.dtb to qemu sd card image
+5. Message of booting riscv-linux from bbl via u-boot on qemu
+
+U-Boot 2018.03-rc4-00031-g2631273 (Mar 13 2018 - 15:02:55 +0800)
+
+DRAM:  1 GiB
+main-loop: WARNING: I/O thread spun for 1000 iterations
+MMC:   mmc@f0e00000: 0
+Loading Environment from SPI Flash... *** Warning - spi_flash_probe_bus_cs() failed, using default environment
+
+Failed (-22)
+In:    serial@f0300000
+Out:   serial@f0300000
+Err:   serial@f0300000
+Net:
+Warning: mac@e0100000 (eth0) using random MAC address - 02:00:00:00:00:00
+eth0: mac@e0100000
+RISC-V # mmc rescan
+RISC-V # mmc part
+
+Partition Map for MMC device 0  --   Partition Type: DOS
+
+Part    Start Sector    Num Sectors     UUID            Type
+RISC-V # fatls mmc 0:0
+ 17901268   bootmImage-bbl.bin
+     1954   ae2xx.dtb
+
+2 file(s), 0 dir(s)
+
+RISC-V # fatload mmc 0:0 0x00600000 bootmImage-bbl.bin
+17901268 bytes read in 4642 ms (3.7 MiB/s)
+RISC-V # fatload mmc 0:0 0x2000000 ae250.dtb
+1954 bytes read in 1 ms (1.9 MiB/s)
+RISC-V # setenv bootm_size 0x2000000
+RISC-V # setenv fdt_high 0x1f00000
+RISC-V # bootm 0x00600000 - 0x2000000
+## Booting kernel from Legacy Image at 00600000 ...
+   Image Name:
+   Image Type:   RISC-V Linux Kernel Image (uncompressed)
+   Data Size:    17901204 Bytes = 17.1 MiB
+   Load Address: 00000000
+   Entry Point:  00000000
+   Verifying Checksum ... OK
+## Flattened Device Tree blob at 02000000
+   Booting using the fdt blob at 0x2000000
+   Loading Kernel Image ... OK
+   Loading Device Tree to 0000000001efc000, end 0000000001eff7a1 ... OK
+[    0.000000] OF: fdt: Ignoring memory range 0x0 - 0x200000
+[    0.000000] Linux version 4.14.0-00046-gf3e439f-dirty (rick@atcsqa06) (gcc version 7.1.1 20170509 (GCC)) #1 Tue Jan 9 16:34:25 CST 2018
+[    0.000000] bootconsole [early0] enabled
+[    0.000000] Initial ramdisk at: 0xffffffe000016a98 (12267008 bytes)
+[    0.000000] Zone ranges:
+[    0.000000]   DMA      [mem 0x0000000000200000-0x000000007fffffff]
+[    0.000000]   Normal   empty
+[    0.000000] Movable zone start for each node
+[    0.000000] Early memory node ranges
+[    0.000000]   node   0: [mem 0x0000000000200000-0x000000007fffffff]
+[    0.000000] Initmem setup node 0 [mem 0x0000000000200000-0x000000007fffffff]
+[    0.000000] elf_hwcap is 0x112d
+[    0.000000] random: fast init done
+[    0.000000] Built 1 zonelists, mobility grouping on.  Total pages: 516615
+[    0.000000] Kernel command line: console=ttyS0,38400n8 earlyprintk=uart8250-32bit,0xf0300000 debug loglevel=7
+[    0.000000] PID hash table entries: 4096 (order: 3, 32768 bytes)
+[    0.000000] Dentry cache hash table entries: 262144 (order: 9, 2097152 bytes)
+[    0.000000] Inode-cache hash table entries: 131072 (order: 8, 1048576 bytes)
+[    0.000000] Sorting __ex_table...
+[    0.000000] Memory: 2047832K/2095104K available (1856K kernel code, 204K rwdata, 532K rodata, 12076K init, 756K bss, 47272K reserved, 0K cma-reserved)
+[    0.000000] SLUB: HWalign=64, Order=0-3, MinObjects=0, CPUs=1, Nodes=1
+[    0.000000] NR_IRQS: 0, nr_irqs: 0, preallocated irqs: 0
+[    0.000000] riscv,cpu_intc,0: 64 local interrupts mapped
+[    0.000000] riscv,plic0,e4000000: mapped 31 interrupts to 1/2 handlers
+[    0.000000] clocksource: riscv_clocksource: mask: 0xffffffffffffffff max_cycles: 0x24e6a1710, max_idle_ns: 440795202120 ns
+[    0.000000] Calibrating delay loop (skipped), value calculated using timer frequency.. 20.00 BogoMIPS (lpj=40000)
+[    0.000000] pid_max: default: 32768 minimum: 301
+[    0.004000] Mount-cache hash table entries: 4096 (order: 3, 32768 bytes)
+[    0.004000] Mountpoint-cache hash table entries: 4096 (order: 3, 32768 bytes)
+[    0.056000] devtmpfs: initialized
+[    0.060000] clocksource: jiffies: mask: 0xffffffff max_cycles: 0xffffffff, max_idle_ns: 7645041785100000 ns
+[    0.064000] futex hash table entries: 256 (order: 0, 6144 bytes)
+[    0.068000] NET: Registered protocol family 16
+[    0.080000] vgaarb: loaded
+[    0.084000] clocksource: Switched to clocksource riscv_clocksource
+[    0.088000] NET: Registered protocol family 2
+[    0.092000] TCP established hash table entries: 16384 (order: 5, 131072 bytes)
+[    0.096000] TCP bind hash table entries: 16384 (order: 5, 131072 bytes)
+[    0.096000] TCP: Hash tables configured (established 16384 bind 16384)
+[    0.100000] UDP hash table entries: 1024 (order: 3, 32768 bytes)
+[    0.100000] UDP-Lite hash table entries: 1024 (order: 3, 32768 bytes)
+[    0.104000] NET: Registered protocol family 1
+[    0.616000] Unpacking initramfs...
+[    1.220000] workingset: timestamp_bits=62 max_order=19 bucket_order=0
+[    1.244000] io scheduler noop registered
+[    1.244000] io scheduler cfq registered (default)
+[    1.244000] io scheduler mq-deadline registered
+[    1.248000] io scheduler kyber registered
+[    1.360000] Serial: 8250/16550 driver, 4 ports, IRQ sharing disabled
+[    1.368000] console [ttyS0] disabled
+[    1.372000] f0300000.serial: ttyS0 at MMIO 0xf0300020 (irq = 10, base_baud = 1228800) is a 16550A
+[    1.392000] console [ttyS0] enabled
+[    1.392000] ftmac100: Loading version 0.2 ...
+[    1.396000] ftmac100 e0100000.mac eth0: irq 8, mapped at ffffffd002005000
+[    1.400000] ftmac100 e0100000.mac eth0: generated random MAC address 6e:ac:c3:92:36:c0
+[    1.404000] IR NEC protocol handler initialized
+[    1.404000] IR RC5(x/sz) protocol handler initialized
+[    1.404000] IR RC6 protocol handler initialized
+[    1.404000] IR JVC protocol handler initialized
+[    1.408000] IR Sony protocol handler initialized
+[    1.408000] IR SANYO protocol handler initialized
+[    1.408000] IR Sharp protocol handler initialized
+[    1.408000] IR MCE Keyboard/mouse protocol handler initialized
+[    1.412000] IR XMP protocol handler initialized
+[    1.456000] ftsdc010 f0e00000.mmc: mmc0 - using hw SDIO IRQ
+[    1.464000] bootconsole [early0] uses init memory and must be disabled even before the real one is ready
+[    1.464000] bootconsole [early0] disabled
+[    1.508000] Freeing unused kernel memory: 12076K
+[    1.512000] This architecture does not have kernel memory protection.
+[    1.520000] mmc0: new SD card at address 4567
+[    1.524000] mmcblk0: mmc0:4567 QEMU! 20.0 MiB
+[    1.844000]  mmcblk0:
+Wed Dec  1 10:00:00 CST 2010
+/ #
+
+
+
+TODO
+==================================================
+Boot bbl and riscv-linux via U-Boot on AE250 board
diff --git a/drivers/mmc/Kconfig b/drivers/mmc/Kconfig
index 5f67e336dba58f04056087fc9d1741f09537e179..3a79cbf16578a1c8ea3cfaa51e6c707bfde6b498 100644
--- a/drivers/mmc/Kconfig
+++ b/drivers/mmc/Kconfig
@@ -523,18 +523,18 @@ config STM32_SDMMC2
 	  If you have a board based on such a SoC and with a SD/MMC slot,
 	  say Y or M here.
 
-config MMC_NDS32
-	bool "Andestech SD/MMC controller support"
-	depends on DM_MMC && OF_CONTROL && BLK && FTSDC010
-	help
-	  This enables support for the Andestech SD/MMM controller, which is
-	  based on Faraday IP.
-
 config FTSDC010
 	bool "Ftsdc010 SD/MMC controller Support"
 	help
 	  This SD/MMC controller is present in Andestech SoCs which is based on Faraday IP.
 
+config FTSDC010_SDIO
+	bool "Support ftsdc010 sdio"
+	default n
+	depends on FTSDC010
+	help
+		This can enable ftsdc010 sdio function.
+
 endif
 
 config TEGRA124_MMC_DISABLE_EXT_LOOPBACK
diff --git a/drivers/mmc/Makefile b/drivers/mmc/Makefile
index 42113e260324a6454e7cee3b989767a4fa76a395..958341017c7830d7511d7fa1d467da95c0892bda 100644
--- a/drivers/mmc/Makefile
+++ b/drivers/mmc/Makefile
@@ -42,7 +42,6 @@ obj-$(CONFIG_MMC_SANDBOX)		+= sandbox_mmc.o
 obj-$(CONFIG_SH_MMCIF) += sh_mmcif.o
 obj-$(CONFIG_SH_SDHI) += sh_sdhi.o
 obj-$(CONFIG_STM32_SDMMC2) += stm32_sdmmc2.o
-obj-$(CONFIG_MMC_NDS32) += nds32_mmc.o
 
 # SDHCI
 obj-$(CONFIG_MMC_SDHCI)			+= sdhci.o
diff --git a/drivers/mmc/ftsdc010_mci.c b/drivers/mmc/ftsdc010_mci.c
index 6ac4f83bd1cf34c38cae3aa8a1d6f19fbc567e8f..9de3a1503dee8ed9a2bdb785187e354fb877fe62 100644
--- a/drivers/mmc/ftsdc010_mci.c
+++ b/drivers/mmc/ftsdc010_mci.c
@@ -4,23 +4,63 @@
  * (C) Copyright 2010 Faraday Technology
  * Dante Su <dantesu@faraday-tech.com>
  *
+ * Copyright 2018 Andes Technology, Inc.
+ * Author: Rick Chen (rick@andestech.com)
+ *
  * SPDX-License-Identifier:	GPL-2.0+
  */
 
 #include <common.h>
+#include <clk.h>
 #include <malloc.h>
 #include <part.h>
 #include <mmc.h>
-
 #include <linux/io.h>
 #include <linux/errno.h>
 #include <asm/byteorder.h>
 #include <faraday/ftsdc010.h>
 #include "ftsdc010_mci.h"
+#include <dm.h>
+#include <dt-structs.h>
+#include <errno.h>
+#include <mapmem.h>
+#include <pwrseq.h>
+#include <syscon.h>
+#include <linux/err.h>
+
+DECLARE_GLOBAL_DATA_PTR;
 
 #define CFG_CMD_TIMEOUT (CONFIG_SYS_HZ >> 4) /* 250 ms */
 #define CFG_RST_TIMEOUT CONFIG_SYS_HZ /* 1 sec reset timeout */
 
+#if CONFIG_IS_ENABLED(OF_PLATDATA)
+struct ftsdc010 {
+	fdt32_t		bus_width;
+	bool		cap_mmc_highspeed;
+	bool		cap_sd_highspeed;
+	fdt32_t		clock_freq_min_max[2];
+	struct phandle_2_cell	clocks[4];
+	fdt32_t		fifo_depth;
+	fdt32_t		reg[2];
+};
+#endif
+
+struct ftsdc010_plat {
+#if CONFIG_IS_ENABLED(OF_PLATDATA)
+	struct ftsdc010 dtplat;
+#endif
+	struct mmc_config cfg;
+	struct mmc mmc;
+};
+
+struct ftsdc_priv {
+	struct clk clk;
+	struct ftsdc010_chip chip;
+	int fifo_depth;
+	bool fifo_mode;
+	u32 minmax[2];
+};
+
 static inline int ftsdc010_send_cmd(struct mmc *mmc, struct mmc_cmd *mmc_cmd)
 {
 	struct ftsdc010_chip *chip = mmc->priv;
@@ -138,16 +178,10 @@ static int ftsdc010_wait(struct ftsdc010_mmc __iomem *regs, uint32_t mask)
 /*
  * u-boot mmc api
  */
-#ifdef CONFIG_DM_MMC
 static int ftsdc010_request(struct udevice *dev, struct mmc_cmd *cmd,
 	struct mmc_data *data)
 {
 	struct mmc *mmc = mmc_get_mmc_dev(dev);
-#else
-static int ftsdc010_request(struct mmc *mmc, struct mmc_cmd *cmd,
-	struct mmc_data *data)
-{
-#endif
 	int ret = -EOPNOTSUPP;
 	uint32_t len = 0;
 	struct ftsdc010_chip *chip = mmc->priv;
@@ -248,14 +282,9 @@ static int ftsdc010_request(struct mmc *mmc, struct mmc_cmd *cmd,
 	return ret;
 }
 
-#ifdef CONFIG_DM_MMC
 static int ftsdc010_set_ios(struct udevice *dev)
 {
 	struct mmc *mmc = mmc_get_mmc_dev(dev);
-#else
-static int ftsdc010_set_ios(struct mmc *mmc)
-{
-#endif
 	struct ftsdc010_chip *chip = mmc->priv;
 	struct ftsdc010_mmc __iomem *regs = chip->regs;
 
@@ -277,27 +306,17 @@ static int ftsdc010_set_ios(struct mmc *mmc)
 	return 0;
 }
 
-#ifdef CONFIG_DM_MMC
 static int ftsdc010_get_cd(struct udevice *dev)
 {
 	struct mmc *mmc = mmc_get_mmc_dev(dev);
-#else
-static int ftsdc010_get_cd(struct mmc *mmc)
-{
-#endif
 	struct ftsdc010_chip *chip = mmc->priv;
 	struct ftsdc010_mmc __iomem *regs = chip->regs;
 	return !(readl(&regs->status) & FTSDC010_STATUS_CARD_DETECT);
 }
 
-#ifdef CONFIG_DM_MMC
 static int ftsdc010_get_wp(struct udevice *dev)
 {
 	struct mmc *mmc = mmc_get_mmc_dev(dev);
-#else
-static int ftsdc010_get_wp(struct mmc *mmc)
-{
-#endif
 	struct ftsdc010_chip *chip = mmc->priv;
 	struct ftsdc010_mmc __iomem *regs = chip->regs;
 	if (readl(&regs->status) & FTSDC010_STATUS_WRITE_PROT) {
@@ -337,31 +356,20 @@ static int ftsdc010_init(struct mmc *mmc)
 	return 0;
 }
 
-#ifdef CONFIG_DM_MMC
-int ftsdc010_probe(struct udevice *dev)
+static int ftsdc010_probe(struct udevice *dev)
 {
 	struct mmc *mmc = mmc_get_mmc_dev(dev);
 	return ftsdc010_init(mmc);
 }
 
-const struct dm_mmc_ops dm_ftsdc010_ops = {
+const struct dm_mmc_ops dm_ftsdc010_mmc_ops = {
 	.send_cmd	= ftsdc010_request,
 	.set_ios	= ftsdc010_set_ios,
 	.get_cd		= ftsdc010_get_cd,
 	.get_wp		= ftsdc010_get_wp,
 };
 
-#else
-static const struct mmc_ops ftsdc010_ops = {
-	.send_cmd	= ftsdc010_request,
-	.set_ios	= ftsdc010_set_ios,
-	.getcd		= ftsdc010_get_cd,
-	.getwp		= ftsdc010_get_wp,
-	.init		= ftsdc010_init,
-};
-#endif
-
-void ftsdc_setup_cfg(struct mmc_config *cfg, const char *name, int buswidth,
+static void ftsdc_setup_cfg(struct mmc_config *cfg, const char *name, int buswidth,
 		     uint caps, u32 max_clk, u32 min_clk)
 {
 	cfg->name = name;
@@ -380,73 +388,94 @@ void ftsdc_setup_cfg(struct mmc_config *cfg, const char *name, int buswidth,
 	cfg->b_max = CONFIG_SYS_MMC_MAX_BLK_COUNT;
 }
 
-void set_bus_width(struct ftsdc010_mmc __iomem *regs, struct mmc_config *cfg)
+static int ftsdc010_mmc_ofdata_to_platdata(struct udevice *dev)
 {
-	switch (readl(&regs->bwr) & FTSDC010_BWR_CAPS_MASK) {
-	case FTSDC010_BWR_CAPS_4BIT:
-		cfg->host_caps |= MMC_MODE_4BIT;
-		break;
-	case FTSDC010_BWR_CAPS_8BIT:
-		cfg->host_caps |= MMC_MODE_4BIT | MMC_MODE_8BIT;
-		break;
-	default:
-		break;
+#if !CONFIG_IS_ENABLED(OF_PLATDATA)
+	struct ftsdc_priv *priv = dev_get_priv(dev);
+	struct ftsdc010_chip *chip = &priv->chip;
+	chip->name = dev->name;
+	chip->ioaddr = (void *)devfdt_get_addr(dev);
+	chip->buswidth = fdtdec_get_int(gd->fdt_blob, dev_of_offset(dev),
+					"bus-width", 4);
+	chip->priv = dev;
+	priv->fifo_depth = fdtdec_get_int(gd->fdt_blob, dev_of_offset(dev),
+				    "fifo-depth", 0);
+	priv->fifo_mode = fdtdec_get_bool(gd->fdt_blob, dev_of_offset(dev),
+					  "fifo-mode");
+	if (fdtdec_get_int_array(gd->fdt_blob, dev_of_offset(dev),
+			 "clock-freq-min-max", priv->minmax, 2)) {
+		int val = fdtdec_get_int(gd->fdt_blob, dev_of_offset(dev),
+				  "max-frequency", -EINVAL);
+		if (val < 0)
+			return val;
+
+		priv->minmax[0] = 400000;  /* 400 kHz */
+		priv->minmax[1] = val;
+	} else {
+		debug("%s: 'clock-freq-min-max' property was deprecated.\n",
+		__func__);
 	}
+#endif
+	chip->sclk = priv->minmax[1];
+	chip->regs = chip->ioaddr;
+	return 0;
 }
 
-#ifdef CONFIG_BLK
-int ftsdc010_bind(struct udevice *dev, struct mmc *mmc, struct mmc_config *cfg)
+static int ftsdc010_mmc_probe(struct udevice *dev)
 {
-	return mmc_bind(dev, mmc, cfg);
+	struct ftsdc010_plat *plat = dev_get_platdata(dev);
+	struct mmc_uclass_priv *upriv = dev_get_uclass_priv(dev);
+	struct ftsdc_priv *priv = dev_get_priv(dev);
+	struct ftsdc010_chip *chip = &priv->chip;
+	struct udevice *pwr_dev __maybe_unused;
+
+#if CONFIG_IS_ENABLED(OF_PLATDATA)
+	int ret;
+	struct ftsdc010 *dtplat = &plat->dtplat;
+	chip->name = dev->name;
+	chip->ioaddr = map_sysmem(dtplat->reg[0], dtplat->reg[1]);
+	chip->buswidth = dtplat->bus_width;
+	chip->priv = dev;
+	chip->dev_index = 1;
+	memcpy(priv->minmax, dtplat->clock_freq_min_max, sizeof(priv->minmax));
+	ret = clk_get_by_index_platdata(dev, 0, dtplat->clocks, &priv->clk);
+	if (ret < 0)
+		return ret;
+#endif
+
+	if (dev_read_bool(dev, "cap-mmc-highspeed") || \
+		  dev_read_bool(dev, "cap-sd-highspeed"))
+		chip->caps |= MMC_MODE_HS | MMC_MODE_HS_52MHz;
+
+	ftsdc_setup_cfg(&plat->cfg, dev->name, chip->buswidth, chip->caps,
+			priv->minmax[1] , priv->minmax[0]);
+	chip->mmc = &plat->mmc;
+	chip->mmc->priv = &priv->chip;
+	chip->mmc->dev = dev;
+	upriv->mmc = chip->mmc;
+	return ftsdc010_probe(dev);
 }
-#else
 
-int ftsdc010_mmc_init(int devid)
+int ftsdc010_mmc_bind(struct udevice *dev)
 {
-	struct mmc *mmc;
-	struct ftsdc010_chip *chip;
-	struct ftsdc010_mmc __iomem *regs;
-#ifdef CONFIG_FTSDC010_BASE_LIST
-	uint32_t base_list[] = CONFIG_FTSDC010_BASE_LIST;
-
-	if (devid < 0 || devid >= ARRAY_SIZE(base_list))
-		return -1;
-	regs = (void __iomem *)base_list[devid];
-#else
-	regs = (void __iomem *)(CONFIG_FTSDC010_BASE + (devid << 20));
-#endif
-
-	chip = malloc(sizeof(struct ftsdc010_chip));
-	if (!chip)
-		return -ENOMEM;
-	memset(chip, 0, sizeof(struct ftsdc010_chip));
+	struct ftsdc010_plat *plat = dev_get_platdata(dev);
 
-	chip->regs = regs;
-#ifdef CONFIG_SYS_CLK_FREQ
-	chip->sclk = CONFIG_SYS_CLK_FREQ;
-#else
-	chip->sclk = clk_get_rate("SDC");
-#endif
+	return mmc_bind(dev, &plat->mmc, &plat->cfg);
+}
 
-	chip->cfg.name = "ftsdc010";
-#ifndef CONFIG_DM_MMC
-	chip->cfg.ops = &ftsdc010_ops;
-#endif
-	chip->cfg.host_caps = MMC_MODE_HS | MMC_MODE_HS_52MHz;
-	set_bus_width(regs , &chip->cfg);
-	chip->cfg.voltages  = MMC_VDD_32_33 | MMC_VDD_33_34;
-	chip->cfg.f_max     = chip->sclk / 2;
-	chip->cfg.f_min     = chip->sclk / 0x100;
-
-	chip->cfg.part_type = PART_TYPE_DOS;
-	chip->cfg.b_max	    = CONFIG_SYS_MMC_MAX_BLK_COUNT;
-
-	mmc = mmc_create(&chip->cfg, chip);
-	if (mmc == NULL) {
-		free(chip);
-		return -ENOMEM;
-	}
+static const struct udevice_id ftsdc010_mmc_ids[] = {
+	{ .compatible = "andestech,atsdc010" },
+	{ }
+};
 
-	return 0;
-}
-#endif
+U_BOOT_DRIVER(ftsdc010_mmc) = {
+	.name		= "ftsdc010_mmc",
+	.id		= UCLASS_MMC,
+	.of_match	= ftsdc010_mmc_ids,
+	.ofdata_to_platdata = ftsdc010_mmc_ofdata_to_platdata,
+	.ops		= &dm_ftsdc010_mmc_ops,
+	.bind		= ftsdc010_mmc_bind,
+	.probe		= ftsdc010_mmc_probe,
+	.priv_auto_alloc_size = sizeof(struct ftsdc_priv),
+	.platdata_auto_alloc_size = sizeof(struct ftsdc010_plat),
+};
diff --git a/drivers/mmc/ftsdc010_mci.h b/drivers/mmc/ftsdc010_mci.h
index 31a27fd77281136cef04750c55332a3dc2c20cea..e41736066217c0a88b71b2b2f8d558ab00506e14 100644
--- a/drivers/mmc/ftsdc010_mci.h
+++ b/drivers/mmc/ftsdc010_mci.h
@@ -35,19 +35,4 @@ struct ftsdc010_chip {
 	bool fifo_mode;
 };
 
-
-#ifdef CONFIG_DM_MMC
-/* Export the operations to drivers */
-int ftsdc010_probe(struct udevice *dev);
-extern const struct dm_mmc_ops dm_ftsdc010_ops;
-#endif
-void ftsdc_setup_cfg(struct mmc_config *cfg, const char *name, int buswidth,
-		     uint caps, u32 max_clk, u32 min_clk);
-void set_bus_width(struct ftsdc010_mmc __iomem *regs, struct mmc_config *cfg);
-
-#ifdef CONFIG_BLK
-int ftsdc010_bind(struct udevice *dev, struct mmc *mmc, struct mmc_config *cfg);
-#endif
-
-
 #endif /* __FTSDC010_MCI_H */
diff --git a/drivers/mmc/nds32_mmc.c b/drivers/mmc/nds32_mmc.c
deleted file mode 100644
index 6d3c8572e503650f8c88134b09f7ca41e0ad9595..0000000000000000000000000000000000000000
--- a/drivers/mmc/nds32_mmc.c
+++ /dev/null
@@ -1,136 +0,0 @@
-/*
- * Andestech ATFSDC010 SD/MMC driver
- *
- * (C) Copyright 2017
- * Rick Chen, NDS32 Software Engineering, rick@andestech.com
-
- * SPDX-License-Identifier:	GPL-2.0+
- */
-
-#include <common.h>
-#include <clk.h>
-#include <dm.h>
-#include <dt-structs.h>
-#include <errno.h>
-#include <mapmem.h>
-#include <mmc.h>
-#include <pwrseq.h>
-#include <syscon.h>
-#include <linux/err.h>
-#include <faraday/ftsdc010.h>
-#include "ftsdc010_mci.h"
-
-DECLARE_GLOBAL_DATA_PTR;
-
-#if CONFIG_IS_ENABLED(OF_PLATDATA)
-struct nds_mmc {
-	fdt32_t		bus_width;
-	bool		cap_mmc_highspeed;
-	bool		cap_sd_highspeed;
-	fdt32_t		clock_freq_min_max[2];
-	struct phandle_2_cell	clocks[4];
-	fdt32_t		fifo_depth;
-	fdt32_t		reg[2];
-};
-#endif
-
-struct nds_mmc_plat {
-#if CONFIG_IS_ENABLED(OF_PLATDATA)
-	struct nds_mmc dtplat;
-#endif
-	struct mmc_config cfg;
-	struct mmc mmc;
-};
-
-struct ftsdc_priv {
-	struct clk clk;
-	struct ftsdc010_chip chip;
-	int fifo_depth;
-	bool fifo_mode;
-	u32 minmax[2];
-};
-
-static int nds32_mmc_ofdata_to_platdata(struct udevice *dev)
-{
-#if !CONFIG_IS_ENABLED(OF_PLATDATA)
-	struct ftsdc_priv *priv = dev_get_priv(dev);
-	struct ftsdc010_chip *chip = &priv->chip;
-	chip->name = dev->name;
-	chip->ioaddr = (void *)devfdt_get_addr(dev);
-	chip->buswidth = fdtdec_get_int(gd->fdt_blob, dev_of_offset(dev),
-					"bus-width", 4);
-	chip->priv = dev;
-	priv->fifo_depth = fdtdec_get_int(gd->fdt_blob, dev_of_offset(dev),
-				    "fifo-depth", 0);
-	priv->fifo_mode = fdtdec_get_bool(gd->fdt_blob, dev_of_offset(dev),
-					  "fifo-mode");
-	if (fdtdec_get_int_array(gd->fdt_blob, dev_of_offset(dev),
-			 "clock-freq-min-max", priv->minmax, 2)) {
-		int val = fdtdec_get_int(gd->fdt_blob, dev_of_offset(dev),
-				  "max-frequency", -EINVAL);
-		if (val < 0)
-			return val;
-
-		priv->minmax[0] = 400000;  /* 400 kHz */
-		priv->minmax[1] = val;
-	} else {
-		debug("%s: 'clock-freq-min-max' property was deprecated.\n",
-		__func__);
-	}
-#endif
-	chip->sclk = priv->minmax[1];
-	chip->regs = chip->ioaddr;
-	return 0;
-}
-
-static int nds32_mmc_probe(struct udevice *dev)
-{
-	struct nds_mmc_plat *plat = dev_get_platdata(dev);
-	struct mmc_uclass_priv *upriv = dev_get_uclass_priv(dev);
-	struct ftsdc_priv *priv = dev_get_priv(dev);
-	struct ftsdc010_chip *chip = &priv->chip;
-	struct udevice *pwr_dev __maybe_unused;
-#if CONFIG_IS_ENABLED(OF_PLATDATA)
-	int ret;
-	struct nds_mmc *dtplat = &plat->dtplat;
-	chip->name = dev->name;
-	chip->ioaddr = map_sysmem(dtplat->reg[0], dtplat->reg[1]);
-	chip->buswidth = dtplat->bus_width;
-	chip->priv = dev;
-	chip->dev_index = 1;
-	memcpy(priv->minmax, dtplat->clock_freq_min_max, sizeof(priv->minmax));
-	ret = clk_get_by_index_platdata(dev, 0, dtplat->clocks, &priv->clk);
-	if (ret < 0)
-		return ret;
-#endif
-	ftsdc_setup_cfg(&plat->cfg, dev->name, chip->buswidth, chip->caps,
-			priv->minmax[1] , priv->minmax[0]);
-	chip->mmc = &plat->mmc;
-	chip->mmc->priv = &priv->chip;
-	chip->mmc->dev = dev;
-	upriv->mmc = chip->mmc;
-	return ftsdc010_probe(dev);
-}
-
-static int nds32_mmc_bind(struct udevice *dev)
-{
-	struct nds_mmc_plat *plat = dev_get_platdata(dev);
-	return ftsdc010_bind(dev, &plat->mmc, &plat->cfg);
-}
-
-static const struct udevice_id nds32_mmc_ids[] = {
-	{ .compatible = "andestech,atsdc010" },
-	{ }
-};
-
-U_BOOT_DRIVER(nds32_mmc_drv) = {
-	.name		= "nds32_mmc",
-	.id		= UCLASS_MMC,
-	.of_match	= nds32_mmc_ids,
-	.ofdata_to_platdata = nds32_mmc_ofdata_to_platdata,
-	.ops		= &dm_ftsdc010_ops,
-	.bind		= nds32_mmc_bind,
-	.probe		= nds32_mmc_probe,
-	.priv_auto_alloc_size = sizeof(struct ftsdc_priv),
-	.platdata_auto_alloc_size = sizeof(struct nds_mmc_plat),
-};
diff --git a/include/configs/adp-ae3xx.h b/include/configs/adp-ae3xx.h
index f5a8dec24a3f0fa49a26e3708e818f8771260661..1ebbc4c9e254ae450541650acd99d92b02fe1a22 100644
--- a/include/configs/adp-ae3xx.h
+++ b/include/configs/adp-ae3xx.h
@@ -80,12 +80,6 @@
 #endif
 #define CONFIG_SYS_NS16550_CLK		((18432000 * 20) / 25)	/* AG101P */
 
-/*
- * SD (MMC) controller
- */
-#define CONFIG_FTSDC010_NUMBER		1
-#define CONFIG_FTSDC010_SDIO
-
 /*
  * Miscellaneous configurable options
  */
diff --git a/include/configs/adp-ag101p.h b/include/configs/adp-ag101p.h
index 6ae6fb454509af6c38e811a0804564c0a1cc8981..ff365c464e52c8f02445026e08eceeb518db6f70 100644
--- a/include/configs/adp-ag101p.h
+++ b/include/configs/adp-ag101p.h
@@ -82,12 +82,6 @@
 #endif
 #define CONFIG_SYS_NS16550_CLK		((18432000 * 20) / 25)	/* AG101P */
 
-/*
- * SD (MMC) controller
- */
-#define CONFIG_FTSDC010_NUMBER		1
-#define CONFIG_FTSDC010_SDIO
-
 /*
  * Miscellaneous configurable options
  */
diff --git a/include/configs/nx25-ae250.h b/include/configs/nx25-ae250.h
index 73c3c33ffa5a181cf6d8cb5100b3a2c01ecb0b89..0e4c431cabf7cb88b5c22d152521b35db5c2418f 100644
--- a/include/configs/nx25-ae250.h
+++ b/include/configs/nx25-ae250.h
@@ -11,18 +11,9 @@
 /*
  * CPU and Board Configuration Options
  */
-#define CONFIG_SKIP_LOWLEVEL_INIT
-
 #define CONFIG_BOOTP_SEND_HOSTNAME
 #define CONFIG_BOOTP_SERVERIP
 
-#ifdef CONFIG_SKIP_LOWLEVEL_INIT
-#ifdef CONFIG_OF_CONTROL
-#undef CONFIG_OF_SEPARATE
-#define CONFIG_OF_EMBED
-#endif
-#endif
-
 /*
  * Miscellaneous configurable options
  */
@@ -50,6 +41,9 @@
  */
 #define CONFIG_SYS_MALLOC_LEN   (512 << 10)
 
+/* DT blob (fdt) address */
+#define CONFIG_SYS_FDT_BASE		0x000f0000
+
 /*
  * Physical Memory Map
  */
@@ -70,12 +64,6 @@
 #endif
 #define CONFIG_SYS_NS16550_CLK		19660800
 
-/*
- * SD (MMC) controller
- */
-#define CONFIG_FTSDC010_NUMBER		1
-#define CONFIG_FTSDC010_SDIO
-
 /* Init Stack Pointer */
 #define CONFIG_SYS_INIT_SP_ADDR		(CONFIG_SYS_SDRAM_BASE + 0x1000000 - \
 					GENERATED_GBL_DATA_SIZE)
diff --git a/scripts/config_whitelist.txt b/scripts/config_whitelist.txt
index 0c7db05274f6ae2b4d7d9aedf5f4e3207ebdacc9..2c26d34ce4f000a8f6d56c615aaa901c84bdf82f 100644
--- a/scripts/config_whitelist.txt
+++ b/scripts/config_whitelist.txt
@@ -741,10 +741,6 @@ CONFIG_FTPWM010_BASE
 CONFIG_FTRTC010_BASE
 CONFIG_FTRTC010_EXTCLK
 CONFIG_FTRTC010_PCLK
-CONFIG_FTSDC010_BASE
-CONFIG_FTSDC010_BASE_LIST
-CONFIG_FTSDC010_NUMBER
-CONFIG_FTSDC010_SDIO
 CONFIG_FTSDMC021
 CONFIG_FTSDMC021_BASE
 CONFIG_FTSMC020