diff --git a/arch/arm/cpu/arm926ejs/lpc32xx/devices.c b/arch/arm/cpu/arm926ejs/lpc32xx/devices.c
index 5a453e303d958d826b55fd1c9433e8b05495e856..b0287be62f718eb03a0df60c95422234dd1e862f 100644
--- a/arch/arm/cpu/arm926ejs/lpc32xx/devices.c
+++ b/arch/arm/cpu/arm926ejs/lpc32xx/devices.c
@@ -54,6 +54,12 @@ void lpc32xx_mlc_nand_init(void)
 	writel(CLK_NAND_MLC | CLK_NAND_MLC_INT, &clk->flashclk_ctrl);
 }
 
+void lpc32xx_slc_nand_init(void)
+{
+	/* Enable SLC NAND interface */
+	writel(CLK_NAND_SLC | CLK_NAND_SLC_SELECT, &clk->flashclk_ctrl);
+}
+
 void lpc32xx_i2c_init(unsigned int devnum)
 {
 	/* Enable I2C interface */
diff --git a/arch/arm/include/asm/arch-lpc32xx/clk.h b/arch/arm/include/asm/arch-lpc32xx/clk.h
index 94498695a0291814478db80cb3ba1198eca927c5..010211a7e102b0ef1b3a72304147007952ec5684 100644
--- a/arch/arm/include/asm/arch-lpc32xx/clk.h
+++ b/arch/arm/include/asm/arch-lpc32xx/clk.h
@@ -153,7 +153,9 @@ struct clk_pm_regs {
 #define CLK_DMA_ENABLE			(1 << 0)
 
 /* NAND Clock Control Register bits */
+#define CLK_NAND_SLC			(1 << 0)
 #define CLK_NAND_MLC			(1 << 1)
+#define CLK_NAND_SLC_SELECT		(1 << 2)
 #define CLK_NAND_MLC_INT		(1 << 5)
 
 /* SSP Clock Control Register bits */
diff --git a/arch/arm/include/asm/arch-lpc32xx/sys_proto.h b/arch/arm/include/asm/arch-lpc32xx/sys_proto.h
index c3d890dde437f1502e470bcc947da2147948f090..0845f83e86f36df827060a613f2092d53537d9a0 100644
--- a/arch/arm/include/asm/arch-lpc32xx/sys_proto.h
+++ b/arch/arm/include/asm/arch-lpc32xx/sys_proto.h
@@ -12,6 +12,7 @@
 void lpc32xx_uart_init(unsigned int uart_id);
 void lpc32xx_mac_init(void);
 void lpc32xx_mlc_nand_init(void);
+void lpc32xx_slc_nand_init(void);
 void lpc32xx_i2c_init(unsigned int devnum);
 void lpc32xx_ssp_init(void);
 #if defined(CONFIG_SPL_BUILD)
diff --git a/drivers/mtd/nand/Makefile b/drivers/mtd/nand/Makefile
index b40dda890e8fd0a9586a5213eec822815846f7c6..46dce72bfebe417975a5727a3fdbf6d3981cc451 100644
--- a/drivers/mtd/nand/Makefile
+++ b/drivers/mtd/nand/Makefile
@@ -54,6 +54,7 @@ obj-$(CONFIG_NAND_KB9202) += kb9202_nand.o
 obj-$(CONFIG_NAND_KIRKWOOD) += kirkwood_nand.o
 obj-$(CONFIG_NAND_KMETER1) += kmeter1_nand.o
 obj-$(CONFIG_NAND_LPC32XX_MLC) += lpc32xx_nand_mlc.o
+obj-$(CONFIG_NAND_LPC32XX_SLC) += lpc32xx_nand_slc.o
 obj-$(CONFIG_NAND_MPC5121_NFC) += mpc5121_nfc.o
 obj-$(CONFIG_NAND_VF610_NFC) += vf610_nfc.o
 obj-$(CONFIG_NAND_MXC) += mxc_nand.o
diff --git a/drivers/mtd/nand/lpc32xx_nand_slc.c b/drivers/mtd/nand/lpc32xx_nand_slc.c
new file mode 100644
index 0000000000000000000000000000000000000000..719a74d2f688641b3d86f65c271b4294289388aa
--- /dev/null
+++ b/drivers/mtd/nand/lpc32xx_nand_slc.c
@@ -0,0 +1,176 @@
+/*
+ * LPC32xx SLC NAND flash controller driver
+ *
+ * (C) Copyright 2015 Vladimir Zapolskiy <vz@mleia.com>
+ *
+ * SPDX-License-Identifier:	GPL-2.0+
+ */
+
+#include <common.h>
+#include <nand.h>
+#include <asm/errno.h>
+#include <asm/io.h>
+#include <asm/arch/clk.h>
+#include <asm/arch/sys_proto.h>
+
+struct lpc32xx_nand_slc_regs {
+	u32 data;
+	u32 addr;
+	u32 cmd;
+	u32 stop;
+	u32 ctrl;
+	u32 cfg;
+	u32 stat;
+	u32 int_stat;
+	u32 ien;
+	u32 isr;
+	u32 icr;
+	u32 tac;
+	u32 tc;
+	u32 ecc;
+	u32 dma_data;
+};
+
+/* CFG register */
+#define CFG_CE_LOW		(1 << 5)
+
+/* CTRL register */
+#define CTRL_SW_RESET		(1 << 2)
+
+/* STAT register */
+#define STAT_NAND_READY		(1 << 0)
+
+/* INT_STAT register */
+#define INT_STAT_TC		(1 << 1)
+#define INT_STAT_RDY		(1 << 0)
+
+/* TAC register bits, be aware of overflows */
+#define TAC_W_RDY(n)		(max_t(uint32_t, (n), 0xF) << 28)
+#define TAC_W_WIDTH(n)		(max_t(uint32_t, (n), 0xF) << 24)
+#define TAC_W_HOLD(n)		(max_t(uint32_t, (n), 0xF) << 20)
+#define TAC_W_SETUP(n)		(max_t(uint32_t, (n), 0xF) << 16)
+#define TAC_R_RDY(n)		(max_t(uint32_t, (n), 0xF) << 12)
+#define TAC_R_WIDTH(n)		(max_t(uint32_t, (n), 0xF) << 8)
+#define TAC_R_HOLD(n)		(max_t(uint32_t, (n), 0xF) << 4)
+#define TAC_R_SETUP(n)		(max_t(uint32_t, (n), 0xF) << 0)
+
+static struct lpc32xx_nand_slc_regs __iomem *lpc32xx_nand_slc_regs
+	= (struct lpc32xx_nand_slc_regs __iomem *)SLC_NAND_BASE;
+
+static void lpc32xx_nand_init(void)
+{
+	uint32_t hclk = get_hclk_clk_rate();
+
+	/* Reset SLC NAND controller */
+	writel(CTRL_SW_RESET, &lpc32xx_nand_slc_regs->ctrl);
+
+	/* 8-bit bus, no DMA, no ECC, ordinary CE signal */
+	writel(0, &lpc32xx_nand_slc_regs->cfg);
+
+	/* Interrupts disabled and cleared */
+	writel(0, &lpc32xx_nand_slc_regs->ien);
+	writel(INT_STAT_TC | INT_STAT_RDY,
+	       &lpc32xx_nand_slc_regs->icr);
+
+	/* Configure NAND flash timings */
+	writel(TAC_W_RDY(CONFIG_LPC32XX_NAND_SLC_WDR_CLKS) |
+	       TAC_W_WIDTH(hclk / CONFIG_LPC32XX_NAND_SLC_WWIDTH) |
+	       TAC_W_HOLD(hclk / CONFIG_LPC32XX_NAND_SLC_WHOLD) |
+	       TAC_W_SETUP(hclk / CONFIG_LPC32XX_NAND_SLC_WSETUP) |
+	       TAC_R_RDY(CONFIG_LPC32XX_NAND_SLC_RDR_CLKS) |
+	       TAC_R_WIDTH(hclk / CONFIG_LPC32XX_NAND_SLC_RWIDTH) |
+	       TAC_R_HOLD(hclk / CONFIG_LPC32XX_NAND_SLC_RHOLD) |
+	       TAC_R_SETUP(hclk / CONFIG_LPC32XX_NAND_SLC_RSETUP),
+	       &lpc32xx_nand_slc_regs->tac);
+}
+
+static void lpc32xx_nand_cmd_ctrl(struct mtd_info *mtd,
+				  int cmd, unsigned int ctrl)
+{
+	debug("ctrl: 0x%08x, cmd: 0x%08x\n", ctrl, cmd);
+
+	if (ctrl & NAND_NCE)
+		setbits_le32(&lpc32xx_nand_slc_regs->cfg, CFG_CE_LOW);
+	else
+		clrbits_le32(&lpc32xx_nand_slc_regs->cfg, CFG_CE_LOW);
+
+	if (cmd == NAND_CMD_NONE)
+		return;
+
+	if (ctrl & NAND_CLE)
+		writel(cmd & 0xFF, &lpc32xx_nand_slc_regs->cmd);
+	else if (ctrl & NAND_ALE)
+		writel(cmd & 0xFF, &lpc32xx_nand_slc_regs->addr);
+}
+
+static int lpc32xx_nand_dev_ready(struct mtd_info *mtd)
+{
+	return readl(&lpc32xx_nand_slc_regs->stat) & STAT_NAND_READY;
+}
+
+static void lpc32xx_read_buf(struct mtd_info *mtd, uint8_t *buf, int len)
+{
+	while (len-- > 0)
+		*buf++ = readl(&lpc32xx_nand_slc_regs->data);
+}
+
+static uint8_t lpc32xx_read_byte(struct mtd_info *mtd)
+{
+	return readl(&lpc32xx_nand_slc_regs->data);
+}
+
+static void lpc32xx_write_buf(struct mtd_info *mtd, const uint8_t *buf, int len)
+{
+	while (len-- > 0)
+		writel(*buf++, &lpc32xx_nand_slc_regs->data);
+}
+
+static void lpc32xx_write_byte(struct mtd_info *mtd, uint8_t byte)
+{
+	writel(byte, &lpc32xx_nand_slc_regs->data);
+}
+
+/*
+ * LPC32xx has only one SLC NAND controller, don't utilize
+ * CONFIG_SYS_NAND_SELF_INIT to be able to reuse this function
+ * both in SPL NAND and U-boot images.
+ */
+int board_nand_init(struct nand_chip *lpc32xx_chip)
+{
+	lpc32xx_chip->cmd_ctrl  = lpc32xx_nand_cmd_ctrl;
+	lpc32xx_chip->dev_ready = lpc32xx_nand_dev_ready;
+
+	/*
+	 * Hardware ECC calculation is not supported by the driver,
+	 * because it requires DMA support, see LPC32x0 User Manual,
+	 * note after SLC_ECC register description (UM10326, p.198)
+	 */
+	lpc32xx_chip->ecc.mode = NAND_ECC_SOFT;
+
+	/*
+	 * The implementation of these functions is quite common, but
+	 * they MUST be defined, because access to data register
+	 * is strictly 32-bit aligned.
+	 */
+	lpc32xx_chip->read_buf   = lpc32xx_read_buf;
+	lpc32xx_chip->read_byte  = lpc32xx_read_byte;
+	lpc32xx_chip->write_buf  = lpc32xx_write_buf;
+	lpc32xx_chip->write_byte = lpc32xx_write_byte;
+
+	/*
+	 * Use default ECC layout, but these values are predefined
+	 * for both small and large page NAND flash devices.
+	 */
+	lpc32xx_chip->ecc.size     = 256;
+	lpc32xx_chip->ecc.bytes    = 3;
+	lpc32xx_chip->ecc.strength = 1;
+
+#if defined(CONFIG_SYS_NAND_USE_FLASH_BBT)
+	lpc32xx_chip->bbt_options |= NAND_BBT_USE_FLASH;
+#endif
+
+	/* Initialize NAND interface */
+	lpc32xx_nand_init();
+
+	return 0;
+}