diff --git a/drivers/mtd/spi/Kconfig b/drivers/mtd/spi/Kconfig
index 1dd2e3175b0d188e293a5cd5daa0bce3e1b2c4fb..48f02a22973ad4f67a414116eadf91971f88f58d 100644
--- a/drivers/mtd/spi/Kconfig
+++ b/drivers/mtd/spi/Kconfig
@@ -239,4 +239,13 @@ config SPL_SPI_FLASH_MTD
 
 	  If unsure, say N
 
+config SPI_FLASH_AUTO_MERGE
+	bool "SPI flash auto merge two flash in one"
+	default n
+	depends on SPI_FLASH
+	help
+          Enable the auto merge the two SPI flash in one.
+
+	  If unsure, say N
+
 endmenu # menu "SPI Flash Support"
diff --git a/drivers/mtd/spi/spi-nor-core.c b/drivers/mtd/spi/spi-nor-core.c
index 8a454bfe2bc629bc4cb9d2f87444dea639c7a405..2253d42169d53273af7be23d373205293ff39879 100644
--- a/drivers/mtd/spi/spi-nor-core.c
+++ b/drivers/mtd/spi/spi-nor-core.c
@@ -556,7 +556,7 @@ static int spi_nor_erase_sector(struct spi_nor *nor, u32 addr)
 static int spi_nor_erase(struct mtd_info *mtd, struct erase_info *instr)
 {
 	struct spi_nor *nor = mtd_to_spi_nor(mtd);
-	u32 addr, len, rem;
+	u32 addr, len, rem, target;
 	int ret;
 
 	dev_dbg(nor->dev, "at 0x%llx, len %lld\n", (long long)instr->addr,
@@ -570,14 +570,20 @@ static int spi_nor_erase(struct mtd_info *mtd, struct erase_info *instr)
 	len = instr->len;
 
 	while (len) {
+#if defined(CONFIG_SPI_FLASH_AUTO_MERGE)
+		nor->spi->auto_merge_cs_cur = addr < nor->auto_merge_single_chip_size ? 0 : 1;
+		target = addr - nor->spi->auto_merge_cs_cur * nor->auto_merge_single_chip_size;
+#else
+		target = addr;
+#endif
 #ifdef CONFIG_SPI_FLASH_BAR
-		ret = write_bar(nor, addr);
+		ret = write_bar(nor, target);
 		if (ret < 0)
 			return ret;
 #endif
 		write_enable(nor);
 
-		ret = spi_nor_erase_sector(nor, addr);
+		ret = spi_nor_erase_sector(nor, target);
 		if (ret)
 			goto erase_err;
 
@@ -923,6 +929,13 @@ static int spi_nor_read(struct mtd_info *mtd, loff_t from, size_t len,
 		loff_t addr = from;
 		size_t read_len = len;
 
+#if defined(CONFIG_SPI_FLASH_AUTO_MERGE)
+		if (addr < nor->auto_merge_single_chip_size && (addr + len) > nor->auto_merge_single_chip_size)
+			read_len = nor->auto_merge_single_chip_size - addr;
+		nor->spi->auto_merge_cs_cur = addr < nor->auto_merge_single_chip_size ? 0 : 1;
+		addr -= nor->spi->auto_merge_cs_cur * nor->auto_merge_single_chip_size;
+#endif
+
 #ifdef CONFIG_SPI_FLASH_BAR
 		u32 remain_len;
 
@@ -1246,6 +1259,11 @@ static int spi_nor_write(struct mtd_info *mtd, loff_t to, size_t len,
 		ssize_t written;
 		loff_t addr = to + i;
 
+#if defined(CONFIG_SPI_FLASH_AUTO_MERGE)
+		nor->spi->auto_merge_cs_cur = addr < nor->auto_merge_single_chip_size ? 0 : 1;
+		addr -= nor->spi->auto_merge_cs_cur * nor->auto_merge_single_chip_size;
+#endif
+
 		/*
 		 * If page_size is a power of two, the offset can be quickly
 		 * calculated with an AND operation. On the other cases we
@@ -2691,6 +2709,21 @@ int spi_nor_scan(struct spi_nor *nor)
 	puts("\n");
 #endif
 
+#if defined(CONFIG_SPI_FLASH_AUTO_MERGE)
+	nor->auto_merge_single_chip_size = nor->size;
+	nor->spi->auto_merge_cs_cur = 1;
+	if (IS_ERR(spi_nor_read_id(nor))) {
+		printf("spinor enable auto_merge, but only cs0 valid\n");
+		return 0;
+	}
+	ret = spi_nor_init(nor);
+	if (!ret) {
+		mtd->size = mtd->size * 2;
+		nor->size = nor->size * 2;
+		printf("spinor enable auto_merge\n");
+	}
+#endif
+
 	return 0;
 }
 
diff --git a/include/linux/mtd/spi-nor.h b/include/linux/mtd/spi-nor.h
index 10b53592e58bb119f829518ab0b3365703416881..c37c323bd5c1ceab1e60d4ecc5e569a703a12603 100644
--- a/include/linux/mtd/spi-nor.h
+++ b/include/linux/mtd/spi-nor.h
@@ -315,6 +315,9 @@ struct spi_nor {
 	u8			bank_read_cmd;
 	u8			bank_write_cmd;
 	u8			bank_curr;
+#endif
+#ifdef CONFIG_SPI_FLASH_AUTO_MERGE
+	u32			auto_merge_single_chip_size;
 #endif
 	enum spi_nor_protocol	read_proto;
 	enum spi_nor_protocol	write_proto;
diff --git a/include/spi.h b/include/spi.h
index df99ec5c77b40e0dbfe616d6c9ebcf03cfb3cf9d..77691031565076f291b00d7367764c239afcfe7e 100644
--- a/include/spi.h
+++ b/include/spi.h
@@ -113,6 +113,9 @@ struct spi_slave {
 #else
 	unsigned int bus;
 	unsigned int cs;
+#endif
+#ifdef CONFIG_SPI_FLASH_AUTO_MERGE
+	unsigned int auto_merge_cs_cur;
 #endif
 	uint mode;
 	unsigned int wordlen;