diff --git a/arch/arm/plat-pxa/include/plat/pxa3xx_nand.h
b/arch/arm/plat-pxa/include/plat/pxa3xx_nand.h
index 76ebd21..7c99390 100644
--- a/arch/arm/plat-pxa/include/plat/pxa3xx_nand.h
+++ b/arch/arm/plat-pxa/include/plat/pxa3xx_nand.h
@@ -13,8 +13,8 @@ struct pxa3xx_nand_platform_data {
 	 */
 	int	enable_arbiter;

-	/* allow platform code to keep OBM/bootloader defined NFC config */
-	int	keep_config;
+	/* Whether the controller support using naked command set */
+	int	naked_cmd_support;

 	const struct mtd_partition		*parts[NUM_CHIP_SELECT];
 	unsigned int				nr_parts[NUM_CHIP_SELECT];
diff --git a/drivers/mtd/nand/pxa3xx_nand.c b/drivers/mtd/nand/pxa3xx_nand.c
index 0674b52..94702df 100644
--- a/drivers/mtd/nand/pxa3xx_nand.c
+++ b/drivers/mtd/nand/pxa3xx_nand.c
@@ -30,6 +30,7 @@
 #define NAND_STOP_DELAY		(2 * HZ/50)
 #define PAGE_CHUNK_SIZE		(2048)
 #define BCH_THRESHOLD           (8)
+#define CMD_POOL_SIZE           (5)
 #undef PXA3XX_NAND_DEBUG
 #ifdef PXA3XX_NAND_DEBUG
 #define DBG_NAND(x)	do{x;}while(0)
@@ -45,7 +46,9 @@
 #define NDPCR		(0x18) /* Page Count Register */
 #define NDBDR0		(0x1C) /* Bad Block Register 0 */
 #define NDBDR1		(0x20) /* Bad Block Register 1 */
+#define NDREDEL		(0x24) /* Read Enable Return Delay Register */
 #define NDECCCTRL	(0x28) /* ECC Control Register */
+#define NDBZCNT		(0x2C) /* Timer for NDRnB0 and NDRnB1 */
 #define NDDB		(0x40) /* Data Buffer */
 #define NDCB0		(0x48) /* Command Buffer0 */
 #define NDCB1		(0x4C) /* Command Buffer1 */
@@ -59,19 +62,32 @@
 #define NDCR_ND_RUN		(0x1 << 28)
 #define NDCR_DWIDTH_C		(0x1 << 27)
 #define NDCR_DWIDTH_M		(0x1 << 26)
-#define NDCR_PAGE_SZ		(0x1 << 24)
-#define NDCR_NCSX		(0x1 << 23)
-#define NDCR_STOP_ON_UNCOR	(0x1 << 22)
-#define NDCR_ND_MODE		(0x3 << 21)
-#define NDCR_NAND_MODE   	(0x0)
+#define NDCR_PAGE_SZ_MASK	(0x3 << 24)
+#define NDCR_PAGE_SZ(x)		(((x) << 24) & NDCR_PAGE_SZ_MASK)
+#define NDCR_SEQ_DIS		(0x1 << 23)
+#define NDCR_ND_STOP		(0x1 << 22)
+#define NDCR_FORCE_CSX		(0x1 << 21)
 #define NDCR_CLR_PG_CNT		(0x1 << 20)
-#define NDCR_CLR_ECC		(0x1 << 19)
+#define NDCR_STOP_ON_UNCOR	(0x1 << 19)
 #define NDCR_RD_ID_CNT_MASK	(0x7 << 16)
 #define NDCR_RD_ID_CNT(x)	(((x) << 16) & NDCR_RD_ID_CNT_MASK)

 #define NDCR_RA_START		(0x1 << 15)
-#define NDCR_PG_PER_BLK		(0x1 << 14)
+#define NDCR_PG_PER_BLK_MASK	(0x3 << 13)
+#define NDCR_PG_PER_BLK(x)	(((x) << 13) & NDCR_PG_PER_BLK_MASK)
 #define NDCR_ND_ARB_EN		(0x1 << 12)
+#define NDCR_RDYM               (0x1 << 11)
+#define NDCR_CS0_PAGEDM         (0x1 << 10)
+#define NDCR_CS1_PAGEDM         (0x1 << 9)
+#define NDCR_CS0_CMDDM          (0x1 << 8)
+#define NDCR_CS1_CMDDM          (0x1 << 7)
+#define NDCR_CS0_BBDM           (0x1 << 6)
+#define NDCR_CS1_BBDM           (0x1 << 5)
+#define NDCR_UNCERRM            (0x1 << 4)
+#define NDCR_CORERRM            (0x1 << 3)
+#define NDCR_WRDREQM            (0x1 << 2)
+#define NDCR_RDDREQM            (0x1 << 1)
+#define NDCR_WRCMDREQM          (0x1)
 #define NDCR_INT_MASK           (0xFFF)

 #define NDSR_MASK		(0xfff)
@@ -89,6 +105,8 @@
 #define NDSR_RDDREQ		(0x1 << 1)
 #define NDSR_WRCMDREQ		(0x1)

+#define NDCB0_CMD_XTYPE_MASK    (0x7 << 29)
+#define NDCB0_CMD_XTYPE(x)      (((x) << 29) & NDCB0_CMD_XTYPE_MASK)
 #define NDCB0_ST_ROW_EN         (0x1 << 26)
 #define NDCB0_AUTO_RS		(0x1 << 25)
 #define NDCB0_CSEL		(0x1 << 24)
@@ -139,6 +157,7 @@ enum {
 	STATE_IS_WRITE		= (1 << 7),
 };

+#define STATE_MASK		(0x3f)
 /* error code and state */
 enum {
 	ECC_NONE = 0,
@@ -153,9 +172,9 @@ struct pxa3xx_nand_timing {
 	uint32_t	tWP;  /* ND_nWE pulse time */
 	uint32_t	tRH;  /* ND_nRE high duration */
 	uint32_t	tRP;  /* ND_nRE pulse width */
-	uint32_t	tAR;  /* ND_ALE low to ND_nRE low delay */
-	uint32_t	tWHR; /* ND_nWE high to ND_nRE low for status read */
 	uint32_t	tR;   /* ND_nWE high to ND_nRE low for read */
+	uint32_t	tWHR; /* ND_nWE high to ND_nRE low for status read */
+	uint32_t	tAR;  /* ND_ALE low to ND_nRE low delay */
 };

 struct pxa3xx_nand_cmdset {
@@ -185,7 +204,9 @@ struct pxa3xx_nand_flash {
 struct pxa3xx_nand_info {
 	struct nand_chip	nand_chip;

-	uint32_t		page_size;	/* page size of attached chip */
+	uint16_t		page_size;	/* page size of attached chip */
+	uint16_t		data_column;
+	uint16_t		oob_column;
 	unsigned char		*data_buff;
 	unsigned char		*oob_buff;
 	uint32_t		buf_start;
@@ -208,12 +229,15 @@ struct pxa3xx_nand_info {
 	uint8_t			read_id_bytes;

 	/* cached register value */
+	uint8_t			cmd_seqs;
+	uint8_t			total_cmds;
+	uint8_t			wait_ready[CMD_POOL_SIZE];
+	uint32_t		ndcb0[CMD_POOL_SIZE];
+	uint32_t		ndcb1;
+	uint32_t		ndcb2;
 	uint32_t		reg_ndcr;
 	uint32_t		ndtr0cs0;
 	uint32_t		ndtr1cs0;
-	uint32_t		ndcb0;
-	uint32_t		ndcb1;
-	uint32_t		ndcb2;

 	void			*nand_data;
 };
@@ -250,6 +274,10 @@ static int use_dma = 1;
 module_param(use_dma, bool, 0444);
 MODULE_PARM_DESC(use_dma, "enable DMA for data transfering to/from NAND HW");

+static int naked_cmd_support = 0;
+module_param(naked_cmd_support, bool, 0444);
+MODULE_PARM_DESC(naked_cmd_support, "Whether the controller support
using naked command set");
+
 const static struct pxa3xx_nand_cmdset cmdset = {
 	.read1		= 0x3000,
