diff mbox series

[05/17] mtd: rawnand: cafe: Demistify register fields

Message ID 20200427082028.394719-6-boris.brezillon@collabora.com
State Changes Requested
Delegated to: Miquel Raynal
Headers show
Series mtd: rawnand: cafe: Convert to exec_op() (and more) | expand

Commit Message

Boris Brezillon April 27, 2020, 8:20 a.m. UTC
The driver has a bunch of magic values. Let's define proper register
fields based on the this spec
http://wiki.laptop.org/images/5/5c/88ALP01_Datasheet_July_2007.pdf and
use them.

Signed-off-by: Boris Brezillon <boris.brezillon@collabora.com>
---
 drivers/mtd/nand/raw/cafe_nand.c | 351 ++++++++++++++++++++++++-------
 1 file changed, 270 insertions(+), 81 deletions(-)

Comments

Miquel Raynal April 27, 2020, 7:42 p.m. UTC | #1
Hi Boris,

Boris Brezillon <boris.brezillon@collabora.com> wrote on Mon, 27 Apr
2020 10:20:15 +0200:

> The driver has a bunch of magic values. Let's define proper register
> fields based on the this spec

                  ^^^/^^^^
either one or the other

> http://wiki.laptop.org/images/5/5c/88ALP01_Datasheet_July_2007.pdf and
> use them.
> 
> Signed-off-by: Boris Brezillon <boris.brezillon@collabora.com>
> ---
>  drivers/mtd/nand/raw/cafe_nand.c | 351 ++++++++++++++++++++++++-------
>  1 file changed, 270 insertions(+), 81 deletions(-)
> 

[...]

> +#define CAFE_GLOBAL_IRQ				0x3008
> +#define CAFE_GLOBAL_IRQ_MASK			0x300c
> +#define CAFE_GLOBAL_IRQ_PCI_ERROR		BIT(31)
> +#define CAFE_GLOBAL_IRQ_VPD_TWSI		BIT(26)
> +#define CAFE_GLOBAL_IRQ_CCIC			BIT(2)
> +#define CAFE_GLOBAL_IRQ_SDH			BIT(1)
> +#define CAFE_GLOBAL_IRQ_NAND			BIT(0)
> +
> +#define CAFE_GLOBAL_RESET			0x3034
> +#define CAFE_GLOBAL_RESET_CCIC			BIT(2)
> +#define CAFE_GLOBAL_RESET_SDH			BIT(1)
> +#define CAFE_GLOBAL_RESET_NAND			BIT(0)
> +
> +#define CAFE_FIELD_PREP(reg, field, val)	FIELD_PREP(CAFE_##reg##_##field, val)
> +#define CAFE_FIELD_GET(reg, field, val)		FIELD_GET(CAFE_##reg##_##field, val)

hehe :)

>  
>  struct cafe_priv {
>  	struct nand_chip nand;
> @@ -104,7 +195,8 @@ static const char *part_probes[] = { "cmdlinepart", "RedBoot", NULL };
>  static int cafe_device_ready(struct nand_chip *chip)
>  {
>  	struct cafe_priv *cafe = nand_get_controller_data(chip);
> -	int result = !!(cafe_readl(cafe, NAND_STATUS) & 0x40000000);
> +	int result = !!(cafe_readl(cafe, NAND_STATUS) &
> +			CAFE_NAND_STATUS_FLASH_BUSY);
>  	uint32_t irqs = cafe_readl(cafe, NAND_IRQ);
>  
>  	cafe_writel(cafe, irqs, NAND_IRQ);

[...]

> @@ -318,14 +430,14 @@ static void cafe_select_chip(struct nand_chip *chip, int chipnr)
>  {
>  	struct cafe_priv *cafe = nand_get_controller_data(chip);
>  
> +	if (chipnr < 0 || chipnr > 1)
> +		return;
> +

I think this change should not be part of this patch?

>  	cafe_dev_dbg(&cafe->pdev->dev, "select_chip %d\n", chipnr);
>  
>  	/* Mask the appropriate bit into the stored value of ctl1
>  	   which will be used by cafe_nand_cmdfunc() */
> -	if (chipnr)
> -		cafe->ctl1 |= CTRL1_CHIPSELECT;
> -	else
> -		cafe->ctl1 &= ~CTRL1_CHIPSELECT;
> +	cafe->ctl1 |= CAFE_FIELD_PREP(NAND_CTRL1, CE, chipnr);

I don't master these macros yet, but are you sure CTRL1_CHIPSELECT will
actually get cleared if (!chipnr) ?

>  }
>  
>  static irqreturn_t cafe_nand_interrupt(int irq, void *id)
> @@ -334,7 +446,9 @@ static irqreturn_t cafe_nand_interrupt(int irq, void *id)
>  	struct nand_chip *chip = mtd_to_nand(mtd);
>  	struct cafe_priv *cafe = nand_get_controller_data(chip);
>  	uint32_t irqs = cafe_readl(cafe, NAND_IRQ);
> -	cafe_writel(cafe, irqs & ~0x90000000, NAND_IRQ);
> +	cafe_writel(cafe,
> +		    irqs & ~(CAFE_NAND_IRQ_CMD_DONE | CAFE_NAND_IRQ_DMA_DONE),
> +		    NAND_IRQ);
>  	if (!irqs)
>  		return IRQ_NONE;
>  


Thanks,
Miquèl
Boris Brezillon April 28, 2020, 6:06 a.m. UTC | #2
On Mon, 27 Apr 2020 21:42:11 +0200
Miquel Raynal <miquel.raynal@bootlin.com> wrote:

> >  struct cafe_priv {
> >  	struct nand_chip nand;
> > @@ -104,7 +195,8 @@ static const char *part_probes[] = { "cmdlinepart", "RedBoot", NULL };
> >  static int cafe_device_ready(struct nand_chip *chip)
> >  {
> >  	struct cafe_priv *cafe = nand_get_controller_data(chip);
> > -	int result = !!(cafe_readl(cafe, NAND_STATUS) & 0x40000000);
> > +	int result = !!(cafe_readl(cafe, NAND_STATUS) &
> > +			CAFE_NAND_STATUS_FLASH_BUSY);
> >  	uint32_t irqs = cafe_readl(cafe, NAND_IRQ);
> >  
> >  	cafe_writel(cafe, irqs, NAND_IRQ);  
> 
> [...]
> 
> > @@ -318,14 +430,14 @@ static void cafe_select_chip(struct nand_chip *chip, int chipnr)
> >  {
> >  	struct cafe_priv *cafe = nand_get_controller_data(chip);
> >  
> > +	if (chipnr < 0 || chipnr > 1)
> > +		return;
> > +  
> 
> I think this change should not be part of this patch?

Or dropped entirely, since we're getting rid of this function anyway.

> 
> >  	cafe_dev_dbg(&cafe->pdev->dev, "select_chip %d\n", chipnr);
> >  
> >  	/* Mask the appropriate bit into the stored value of ctl1
> >  	   which will be used by cafe_nand_cmdfunc() */
> > -	if (chipnr)
> > -		cafe->ctl1 |= CTRL1_CHIPSELECT;
> > -	else
> > -		cafe->ctl1 &= ~CTRL1_CHIPSELECT;
> > +	cafe->ctl1 |= CAFE_FIELD_PREP(NAND_CTRL1, CE, chipnr);  
> 
> I don't master these macros yet, but are you sure CTRL1_CHIPSELECT will
> actually get cleared if (!chipnr) ?

You're correct, I only ever set the field. I'll fix that.
diff mbox series

Patch

diff --git a/drivers/mtd/nand/raw/cafe_nand.c b/drivers/mtd/nand/raw/cafe_nand.c
index 156a308b530b..fbc18bc3d46b 100644
--- a/drivers/mtd/nand/raw/cafe_nand.c
+++ b/drivers/mtd/nand/raw/cafe_nand.c
@@ -9,6 +9,7 @@ 
  * Copyright © 2006 David Woodhouse <dwmw2@infradead.org>
  */
 
+#include <linux/bitfield.h>
 #define DEBUG
 
 #include <linux/device.h>
@@ -25,37 +26,127 @@ 
 #include <linux/module.h>
 #include <linux/io.h>
 
-#define CAFE_NAND_CTRL1		0x00
-#define CAFE_NAND_CTRL2		0x04
-#define CAFE_NAND_CTRL3		0x08
-#define CAFE_NAND_STATUS	0x0c
-#define CAFE_NAND_IRQ		0x10
-#define CAFE_NAND_IRQ_MASK	0x14
-#define CAFE_NAND_DATA_LEN	0x18
-#define CAFE_NAND_ADDR1		0x1c
-#define CAFE_NAND_ADDR2		0x20
-#define CAFE_NAND_TIMING1	0x24
-#define CAFE_NAND_TIMING2	0x28
-#define CAFE_NAND_TIMING3	0x2c
-#define CAFE_NAND_NONMEM	0x30
-#define CAFE_NAND_ECC_RESULT	0x3C
-#define CAFE_NAND_DMA_CTRL	0x40
-#define CAFE_NAND_DMA_ADDR0	0x44
-#define CAFE_NAND_DMA_ADDR1	0x48
-#define CAFE_NAND_ECC_SYN01	0x50
-#define CAFE_NAND_ECC_SYN23	0x54
-#define CAFE_NAND_ECC_SYN45	0x58
-#define CAFE_NAND_ECC_SYN67	0x5c
-#define CAFE_NAND_READ_DATA	0x1000
-#define CAFE_NAND_WRITE_DATA	0x2000
+#define CAFE_NAND_CTRL1				0x00
+#define CAFE_NAND_CTRL1_HAS_CMD			BIT(31)
+#define CAFE_NAND_CTRL1_HAS_ADDR		BIT(30)
+#define CAFE_NAND_CTRL1_NUM_ADDR_CYC		GENMASK(29, 27)
+#define CAFE_NAND_CTRL1_HAS_DATA_IN		BIT(26)
+#define CAFE_NAND_CTRL1_HAS_DATA_OUT		BIT(25)
+#define CAFE_NAND_CTRL1_NUM_NONMEM_READ_HIGH	GENMASK(24, 22)
+#define CAFE_NAND_CTRL1_WAIT_BSY_AFTER_SEQ	BIT(21)
+#define CAFE_NAND_CTRL1_NUM_NONMEM_READ_LOW	BIT(20)
+#define CAFE_NAND_CTRL1_CE			BIT(19)
+#define CAFE_NAND_CTRL1_CMD			GENMASK(7, 0)
 
-#define CAFE_GLOBAL_CTRL	0x3004
-#define CAFE_GLOBAL_IRQ		0x3008
-#define CAFE_GLOBAL_IRQ_MASK	0x300c
-#define CAFE_NAND_RESET		0x3034
+#define CAFE_NAND_CTRL2				0x04
+#define CAFE_NAND_CTRL2_AUTO_WRITE_ECC		BIT(30)
+#define CAFE_NAND_CTRL2_PAGE_SIZE		GENMASK(29, 28)
+#define CAFE_NAND_CTRL2_ECC_ALG_RS		BIT(27)
+#define CAFE_NAND_CTRL2_HAS_CMD2		BIT(8)
+#define CAFE_NAND_CTRL2_CMD2			GENMASK(7, 0)
 
-/* Missing from the datasheet: bit 19 of CTRL1 sets CE0 vs. CE1 */
-#define CTRL1_CHIPSELECT	(1<<19)
+#define CAFE_NAND_CTRL3				0x08
+#define CAFE_NAND_CTRL3_READ_BUSY_RESET		BIT(31)
+#define CAFE_NAND_CTRL3_WP			BIT(30)
+
+#define CAFE_NAND_STATUS			0x0c
+#define CAFE_NAND_STATUS_CONTROLLER_BUSY	BIT(31)
+#define CAFE_NAND_STATUS_FLASH_BUSY		BIT(30)
+
+#define CAFE_NAND_IRQ				0x10
+#define CAFE_NAND_IRQ_MASK			0x14
+#define CAFE_NAND_IRQ_CMD_DONE			BIT(31)
+#define CAFE_NAND_IRQ_FLASH_RDY			BIT(30)
+#define CAFE_NAND_IRQ_DMA_DONE			BIT(28)
+#define CAFE_NAND_IRQ_BOOT_DONE			BIT(27)
+
+#define CAFE_NAND_DATA_LEN			0x18
+#define CAFE_NAND_ADDR1				0x1c
+#define CAFE_NAND_ADDR2				0x20
+
+#define CAFE_NAND_TIMING1			0x24
+#define CAFE_NAND_TIMING1_TCLS			GENMASK(31, 28)
+#define CAFE_NAND_TIMING1_TCLH			GENMASK(27, 24)
+#define CAFE_NAND_TIMING1_TALS			GENMASK(23, 20)
+#define CAFE_NAND_TIMING1_TALH			GENMASK(19, 16)
+#define CAFE_NAND_TIMING1_TWB			GENMASK(15, 8)
+#define CAFE_NAND_TIMING1_TRB			GENMASK(7, 0)
+
+#define CAFE_NAND_TIMING2			0x28
+#define CAFE_NAND_TIMING2_TRR			GENMASK(31, 28)
+#define CAFE_NAND_TIMING2_TREA			GENMASK(27, 24)
+#define CAFE_NAND_TIMING2_TDH			GENMASK(23, 20)
+#define CAFE_NAND_TIMING2_TDS			GENMASK(19, 16)
+#define CAFE_NAND_TIMING2_TRH			GENMASK(15, 12)
+#define CAFE_NAND_TIMING2_TRP			GENMASK(11, 8)
+#define CAFE_NAND_TIMING2_TWH			GENMASK(7, 4)
+#define CAFE_NAND_TIMING2_TWP			GENMASK(3, 0)
+
+#define CAFE_NAND_TIMING3			0x2c
+#define CAFE_NAND_TIMING3_TAR			GENMASK(31, 28)
+#define CAFE_NAND_TIMING3_TCLR			GENMASK(27, 24)
+
+#define CAFE_NAND_NONMEM_READ_DATA		0x30
+#define CAFE_NAND_ECC_READ_CODE			0x38
+
+#define CAFE_NAND_ECC_RESULT			0x3C
+#define CAFE_NAND_ECC_RESULT_RS_ERRORS		BIT(18)
+#define CAFE_NAND_ECC_RESULT_STATUS		GENMASK(17, 16)
+#define CAFE_NAND_ECC_RESULT_NO_ERROR		(0 << 16)
+#define CAFE_NAND_ECC_RESULT_CORRECTABLE_ERRS	(1 << 16)
+#define CAFE_NAND_ECC_RESULT_UNCORRECTABLE_ERRS	(2 << 16)
+#define CAFE_NAND_ECC_RESULT_FAIL_BIT_LOC	GENMASK(13, 0)
+
+#define CAFE_NAND_DMA_CTRL			0x40
+#define CAFE_NAND_DMA_CTRL_ENABLE		BIT(31)
+#define CAFE_NAND_DMA_CTRL_RESERVED		BIT(30)
+#define CAFE_NAND_DMA_CTRL_DATA_IN		BIT(29)
+#define CAFE_NAND_DMA_CTRL_DATA_LEN		GENMASK(11, 0)
+
+#define CAFE_NAND_DMA_ADDR0			0x44
+#define CAFE_NAND_DMA_ADDR1			0x48
+#define CAFE_NAND_ECC_SYN_REG(x)		(((x) / 2) + 0x50)
+#define CAFE_NAND_ECC_SYN_FIELD(x)		(((x) % 2) ? GENMASK(31, 16) : GENMASK(15, 0))
+
+#define CAFE_NAND_CTRL4				0x60
+#define CAFE_NAND_CTRL4_NO_READ_DELAY		BIT(8)
+
+#define CAFE_NAND_DRIVE_STRENGTH		0x64
+#define CAFE_NAND_DRIVE_STRENGTH_VAL		GENMASK(4, 0)
+
+#define CAFE_NAND_READ_DATA			0x1000
+#define CAFE_NAND_WRITE_DATA			0x2000
+
+#define CAFE_GLOBAL_CTRL			0x3004
+#define CAFE_GLOBAL_CCIC_CLK_ENABLE		BIT(14)
+#define CAFE_GLOBAL_SDH_CLK_ENABLE		BIT(13)
+#define CAFE_GLOBAL_NAND_CLK_ENABLE		BIT(12)
+#define CAFE_GLOBAL_CLKRUN_ENABLE_SET		BIT(11)
+#define CAFE_GLOBAL_CLKRUN_ENABLE_CLEAR		BIT(10)
+#define CAFE_GLOBAL_SW_IRQ_SET			BIT(7)
+#define CAFE_GLOBAL_SW_IRQ_CLEAR		BIT(6)
+#define CAFE_GLOBAL_STOP_MASTER_DONE		BIT(5)
+#define CAFE_GLOBAL_STOP_MASTER			BIT(4)
+#define CAFE_GLOBAL_MASTER_RESET_CLEAR		BIT(3)
+#define CAFE_GLOBAL_MASTER_RESET_SET		BIT(2)
+#define CAFE_GLOBAL_SW_RESET_CLEAR		BIT(1)
+#define CAFE_GLOBAL_SW_RESET_SET		BIT(0)
+
+#define CAFE_GLOBAL_IRQ				0x3008
+#define CAFE_GLOBAL_IRQ_MASK			0x300c
+#define CAFE_GLOBAL_IRQ_PCI_ERROR		BIT(31)
+#define CAFE_GLOBAL_IRQ_VPD_TWSI		BIT(26)
+#define CAFE_GLOBAL_IRQ_CCIC			BIT(2)
+#define CAFE_GLOBAL_IRQ_SDH			BIT(1)
+#define CAFE_GLOBAL_IRQ_NAND			BIT(0)
+
+#define CAFE_GLOBAL_RESET			0x3034
+#define CAFE_GLOBAL_RESET_CCIC			BIT(2)
+#define CAFE_GLOBAL_RESET_SDH			BIT(1)
+#define CAFE_GLOBAL_RESET_NAND			BIT(0)
+
+#define CAFE_FIELD_PREP(reg, field, val)	FIELD_PREP(CAFE_##reg##_##field, val)
+#define CAFE_FIELD_GET(reg, field, val)		FIELD_GET(CAFE_##reg##_##field, val)
 
 struct cafe_priv {
 	struct nand_chip nand;
@@ -104,7 +195,8 @@  static const char *part_probes[] = { "cmdlinepart", "RedBoot", NULL };
 static int cafe_device_ready(struct nand_chip *chip)
 {
 	struct cafe_priv *cafe = nand_get_controller_data(chip);
-	int result = !!(cafe_readl(cafe, NAND_STATUS) & 0x40000000);
+	int result = !!(cafe_readl(cafe, NAND_STATUS) &
+			CAFE_NAND_STATUS_FLASH_BUSY);
 	uint32_t irqs = cafe_readl(cafe, NAND_IRQ);
 
 	cafe_writel(cafe, irqs, NAND_IRQ);
@@ -164,16 +256,20 @@  static void cafe_nand_cmdfunc(struct nand_chip *chip, unsigned command,
 	struct cafe_priv *cafe = nand_get_controller_data(chip);
 	int adrbytes = 0;
 	uint32_t ctl1;
-	uint32_t doneint = 0x80000000;
+	uint32_t doneint = CAFE_NAND_IRQ_CMD_DONE;
 
 	cafe_dev_dbg(&cafe->pdev->dev, "cmdfunc %02x, 0x%x, 0x%x\n",
 		command, column, page_addr);
 
 	if (command == NAND_CMD_ERASE2 || command == NAND_CMD_PAGEPROG) {
 		/* Second half of a command we already calculated */
-		cafe_writel(cafe, cafe->ctl2 | 0x100 | command, NAND_CTRL2);
+		cafe_writel(cafe,
+			    cafe->ctl2 |
+			    CAFE_NAND_CTRL2_CMD2 |
+			    CAFE_FIELD_PREP(NAND_CTRL2, CMD2, command),
+			    NAND_CTRL2);
 		ctl1 = cafe->ctl1;
-		cafe->ctl2 &= ~(1<<30);
+		cafe->ctl2 &= ~CAFE_NAND_CTRL2_AUTO_WRITE_ECC;
 		cafe_dev_dbg(&cafe->pdev->dev, "Continue command, ctl1 %08x, #data %d\n",
 			  cafe->ctl1, cafe->nr_data);
 		goto do_command;
@@ -209,26 +305,29 @@  static void cafe_nand_cmdfunc(struct nand_chip *chip, unsigned command,
 	cafe->data_pos = cafe->datalen = 0;
 
 	/* Set command valid bit, mask in the chip select bit  */
-	ctl1 = 0x80000000 | command | (cafe->ctl1 & CTRL1_CHIPSELECT);
+	ctl1 = CAFE_NAND_CTRL1_HAS_CMD |
+	       CAFE_FIELD_PREP(NAND_CTRL1, CMD, command) |
+	       (cafe->ctl1 & CAFE_NAND_CTRL1_CE);
 
 	/* Set RD or WR bits as appropriate */
 	if (command == NAND_CMD_READID || command == NAND_CMD_STATUS) {
-		ctl1 |= (1<<26); /* rd */
+		ctl1 |= CAFE_NAND_CTRL1_HAS_DATA_IN;
 		/* Always 5 bytes, for now */
 		cafe->datalen = 4;
 		/* And one address cycle -- even for STATUS, since the controller doesn't work without */
 		adrbytes = 1;
 	} else if (command == NAND_CMD_READ0 || command == NAND_CMD_READ1 ||
 		   command == NAND_CMD_READOOB || command == NAND_CMD_RNDOUT) {
-		ctl1 |= 1<<26; /* rd */
+		ctl1 |= CAFE_NAND_CTRL1_HAS_DATA_IN;
 		/* For now, assume just read to end of page */
 		cafe->datalen = mtd->writesize + mtd->oobsize - column;
 	} else if (command == NAND_CMD_SEQIN)
-		ctl1 |= 1<<25; /* wr */
+		ctl1 |= CAFE_NAND_CTRL1_HAS_DATA_OUT;
 
 	/* Set number of address bytes */
 	if (adrbytes)
-		ctl1 |= ((adrbytes-1)|8) << 27;
+		ctl1 |= CAFE_NAND_CTRL1_HAS_ADDR |
+			CAFE_FIELD_PREP(NAND_CTRL1, NUM_ADDR_CYC, adrbytes - 1);
 
 	if (command == NAND_CMD_SEQIN || command == NAND_CMD_ERASE1) {
 		/* Ignore the first command of a pair; the hardware
@@ -240,9 +339,15 @@  static void cafe_nand_cmdfunc(struct nand_chip *chip, unsigned command,
 	}
 	/* RNDOUT and READ0 commands need a following byte */
 	if (command == NAND_CMD_RNDOUT)
-		cafe_writel(cafe, cafe->ctl2 | 0x100 | NAND_CMD_RNDOUTSTART, NAND_CTRL2);
+		cafe_writel(cafe,
+			    cafe->ctl2 | CAFE_NAND_CTRL2_CMD2 |
+			    CAFE_FIELD_PREP(NAND_CTRL2, CMD2, NAND_CMD_RNDOUTSTART),
+			    NAND_CTRL2);
 	else if (command == NAND_CMD_READ0 && mtd->writesize > 512)
-		cafe_writel(cafe, cafe->ctl2 | 0x100 | NAND_CMD_READSTART, NAND_CTRL2);
+		cafe_writel(cafe,
+			    cafe->ctl2 | CAFE_NAND_CTRL2_CMD2 |
+			    CAFE_FIELD_PREP(NAND_CTRL2, CMD2, NAND_CMD_READSTART),
+			    NAND_CTRL2);
 
  do_command:
 	cafe_dev_dbg(&cafe->pdev->dev, "dlen %x, ctl1 %x, ctl2 %x\n",
@@ -250,16 +355,23 @@  static void cafe_nand_cmdfunc(struct nand_chip *chip, unsigned command,
 
 	/* NB: The datasheet lies -- we really should be subtracting 1 here */
 	cafe_writel(cafe, cafe->datalen, NAND_DATA_LEN);
-	cafe_writel(cafe, 0x90000000, NAND_IRQ);
-	if (cafe->usedma && (ctl1 & (3<<25))) {
-		uint32_t dmactl = 0xc0000000 + cafe->datalen;
+	cafe_writel(cafe, CAFE_NAND_IRQ_CMD_DONE | CAFE_NAND_IRQ_DMA_DONE,
+		    NAND_IRQ);
+	if (cafe->usedma &&
+	    (ctl1 & (CAFE_NAND_CTRL1_HAS_DATA_IN |
+		     CAFE_NAND_CTRL1_HAS_DATA_OUT))) {
+		uint32_t dmactl = CAFE_NAND_DMA_CTRL_ENABLE |
+				  CAFE_NAND_DMA_CTRL_RESERVED;
+
+		dmactl |= CAFE_FIELD_PREP(NAND_DMA_CTRL, DATA_LEN,
+					  cafe->datalen);
 		/* If WR or RD bits set, set up DMA */
-		if (ctl1 & (1<<26)) {
+		if (ctl1 & CAFE_NAND_CTRL1_HAS_DATA_IN) {
 			/* It's a read */
-			dmactl |= (1<<29);
+			dmactl |= CAFE_NAND_DMA_CTRL_DATA_IN;
 			/* ... so it's done when the DMA is done, not just
 			   the command. */
-			doneint = 0x10000000;
+			doneint = CAFE_NAND_IRQ_DMA_DONE;
 		}
 		cafe_writel(cafe, dmactl, NAND_DMA_CTRL);
 	}
@@ -295,7 +407,7 @@  static void cafe_nand_cmdfunc(struct nand_chip *chip, unsigned command,
 			     command, 500000-c, irqs, cafe_readl(cafe, NAND_IRQ));
 	}
 
-	WARN_ON(cafe->ctl2 & (1<<30));
+	WARN_ON(cafe->ctl2 & CAFE_NAND_CTRL2_AUTO_WRITE_ECC);
 
 	switch (command) {
 
@@ -318,14 +430,14 @@  static void cafe_select_chip(struct nand_chip *chip, int chipnr)
 {
 	struct cafe_priv *cafe = nand_get_controller_data(chip);
 
+	if (chipnr < 0 || chipnr > 1)
+		return;
+
 	cafe_dev_dbg(&cafe->pdev->dev, "select_chip %d\n", chipnr);
 
 	/* Mask the appropriate bit into the stored value of ctl1
 	   which will be used by cafe_nand_cmdfunc() */
-	if (chipnr)
-		cafe->ctl1 |= CTRL1_CHIPSELECT;
-	else
-		cafe->ctl1 &= ~CTRL1_CHIPSELECT;
+	cafe->ctl1 |= CAFE_FIELD_PREP(NAND_CTRL1, CE, chipnr);
 }
 
 static irqreturn_t cafe_nand_interrupt(int irq, void *id)
@@ -334,7 +446,9 @@  static irqreturn_t cafe_nand_interrupt(int irq, void *id)
 	struct nand_chip *chip = mtd_to_nand(mtd);
 	struct cafe_priv *cafe = nand_get_controller_data(chip);
 	uint32_t irqs = cafe_readl(cafe, NAND_IRQ);
-	cafe_writel(cafe, irqs & ~0x90000000, NAND_IRQ);
+	cafe_writel(cafe,
+		    irqs & ~(CAFE_NAND_IRQ_CMD_DONE | CAFE_NAND_IRQ_DMA_DONE),
+		    NAND_IRQ);
 	if (!irqs)
 		return IRQ_NONE;
 
@@ -368,25 +482,31 @@  static int cafe_nand_read_page(struct nand_chip *chip, uint8_t *buf,
 	struct mtd_info *mtd = nand_to_mtd(chip);
 	struct cafe_priv *cafe = nand_get_controller_data(chip);
 	unsigned int max_bitflips = 0;
+	u32 ecc_result, status;
 
 	cafe_dev_dbg(&cafe->pdev->dev, "ECC result %08x SYN1,2 %08x\n",
 		     cafe_readl(cafe, NAND_ECC_RESULT),
-		     cafe_readl(cafe, NAND_ECC_SYN01));
+		     cafe_readl(cafe, NAND_ECC_SYN_REG(0)));
 
 	nand_read_page_op(chip, page, 0, buf, mtd->writesize);
 	chip->legacy.read_buf(chip, chip->oob_poi, mtd->oobsize);
 
-	if (checkecc && cafe_readl(cafe, NAND_ECC_RESULT) & (1<<18)) {
+	ecc_result = cafe_readl(cafe, NAND_ECC_RESULT);
+	status = CAFE_FIELD_GET(NAND_ECC_RESULT, STATUS, ecc_result);
+	if (checkecc && status == CAFE_NAND_ECC_RESULT_CORRECTABLE_ERRS) {
 		unsigned short syn[8], pat[4];
 		int pos[4];
 		u8 *oob = chip->oob_poi;
 		int i, n;
 
 		for (i=0; i<8; i+=2) {
-			uint32_t tmp = cafe_readl(cafe, NAND_ECC_SYN01 + (i*2));
+			uint32_t tmp = cafe_readl(cafe, NAND_ECC_SYN_REG(i));
+			uint16_t idx;
 
-			syn[i] = cafe->rs->codec->index_of[tmp & 0xfff];
-			syn[i+1] = cafe->rs->codec->index_of[(tmp >> 16) & 0xfff];
+			idx = FIELD_GET(CAFE_NAND_ECC_SYN_FIELD(i), tmp);
+			syn[i] = cafe->rs->codec->index_of[idx];
+			idx = FIELD_GET(CAFE_NAND_ECC_SYN_FIELD(i + 1), tmp);
+			syn[i+1] = cafe->rs->codec->index_of[idx];
 		}
 
 		n = decode_rs16(cafe->rs, NULL, NULL, 1367, syn, 0, pos, 0,
@@ -536,7 +656,7 @@  static int cafe_nand_write_page(struct nand_chip *chip,
 	chip->legacy.write_buf(chip, chip->oob_poi, mtd->oobsize);
 
 	/* Set up ECC autogeneration */
-	cafe->ctl2 |= (1<<30);
+	cafe->ctl2 |= CAFE_NAND_CTRL2_AUTO_WRITE_ECC;
 
 	return nand_prog_page_end_op(chip);
 }
@@ -604,9 +724,9 @@  static int cafe_nand_attach_chip(struct nand_chip *chip)
 	/* Restore the DMA flag */
 	cafe->usedma = usedma;
 
-	cafe->ctl2 = BIT(27); /* Reed-Solomon ECC */
-	if (mtd->writesize == 2048)
-		cafe->ctl2 |= BIT(29); /* 2KiB page size */
+	cafe->ctl2 = CAFE_NAND_CTRL2_ECC_ALG_RS |
+		     CAFE_FIELD_PREP(NAND_CTRL2, PAGE_SIZE,
+				     mtd->writesize / 512);
 
 	/* Set up ECC according to the type of chip we found */
 	mtd_set_ooblayout(mtd, &cafe_ooblayout_ops);
@@ -734,8 +854,8 @@  static int cafe_nand_probe(struct pci_dev *pdev,
 	}
 
 	/* Start off by resetting the NAND controller completely */
-	cafe_writel(cafe, 1, NAND_RESET);
-	cafe_writel(cafe, 0, NAND_RESET);
+	cafe_writel(cafe, CAFE_GLOBAL_RESET_NAND, GLOBAL_RESET);
+	cafe_writel(cafe, 0, GLOBAL_RESET);
 
 	cafe_writel(cafe, timing[0], NAND_TIMING1);
 	cafe_writel(cafe, timing[1], NAND_TIMING2);
@@ -751,17 +871,49 @@  static int cafe_nand_probe(struct pci_dev *pdev,
 
 	/* Disable master reset, enable NAND clock */
 	ctrl = cafe_readl(cafe, GLOBAL_CTRL);
-	ctrl &= 0xffffeff0;
-	ctrl |= 0x00007000;
-	cafe_writel(cafe, ctrl | 0x05, GLOBAL_CTRL);
-	cafe_writel(cafe, ctrl | 0x0a, GLOBAL_CTRL);
+	ctrl &= ~(CAFE_GLOBAL_SW_RESET_SET |
+		  CAFE_GLOBAL_SW_RESET_CLEAR |
+		  CAFE_GLOBAL_MASTER_RESET_SET |
+		  CAFE_GLOBAL_MASTER_RESET_CLEAR |
+		  CAFE_GLOBAL_NAND_CLK_ENABLE);
+	ctrl |= CAFE_GLOBAL_NAND_CLK_ENABLE |
+		CAFE_GLOBAL_SDH_CLK_ENABLE |
+		CAFE_GLOBAL_CCIC_CLK_ENABLE;
+	cafe_writel(cafe,
+		    ctrl |
+		    CAFE_GLOBAL_MASTER_RESET_SET |
+		    CAFE_GLOBAL_SW_RESET_SET,
+		    GLOBAL_CTRL);
+	cafe_writel(cafe,
+		    ctrl |
+		    CAFE_GLOBAL_MASTER_RESET_CLEAR |
+		    CAFE_GLOBAL_SW_RESET_CLEAR,
+		    GLOBAL_CTRL);
+
 	cafe_writel(cafe, 0, NAND_DMA_CTRL);
 
-	cafe_writel(cafe, 0x7006, GLOBAL_CTRL);
-	cafe_writel(cafe, 0x700a, GLOBAL_CTRL);
+	cafe_writel(cafe,
+		    CAFE_GLOBAL_NAND_CLK_ENABLE |
+		    CAFE_GLOBAL_SDH_CLK_ENABLE |
+		    CAFE_GLOBAL_CCIC_CLK_ENABLE |
+		    CAFE_GLOBAL_MASTER_RESET_SET |
+		    CAFE_GLOBAL_SW_RESET_CLEAR,
+		    GLOBAL_CTRL);
+	cafe_writel(cafe,
+		    CAFE_GLOBAL_NAND_CLK_ENABLE |
+		    CAFE_GLOBAL_SDH_CLK_ENABLE |
+		    CAFE_GLOBAL_CCIC_CLK_ENABLE |
+		    CAFE_GLOBAL_MASTER_RESET_CLEAR |
+		    CAFE_GLOBAL_SW_RESET_CLEAR,
+		    GLOBAL_CTRL);
 
 	/* Enable NAND IRQ in global IRQ mask register */
-	cafe_writel(cafe, 0x80000007, GLOBAL_IRQ_MASK);
+	cafe_writel(cafe,
+		    CAFE_GLOBAL_IRQ_PCI_ERROR |
+		    CAFE_GLOBAL_IRQ_CCIC |
+		    CAFE_GLOBAL_IRQ_SDH |
+		    CAFE_GLOBAL_IRQ_NAND,
+		    GLOBAL_IRQ_MASK);
 	cafe_dev_dbg(&cafe->pdev->dev, "Control %x, IRQ mask %x\n",
 		cafe_readl(cafe, GLOBAL_CTRL),
 		cafe_readl(cafe, GLOBAL_IRQ_MASK));
@@ -788,7 +940,9 @@  static int cafe_nand_probe(struct pci_dev *pdev,
 	nand_cleanup(&cafe->nand);
  out_irq:
 	/* Disable NAND IRQ in global IRQ mask register */
-	cafe_writel(cafe, ~1 & cafe_readl(cafe, GLOBAL_IRQ_MASK), GLOBAL_IRQ_MASK);
+	cafe_writel(cafe,
+		    cafe_readl(cafe, GLOBAL_IRQ_MASK) & ~CAFE_GLOBAL_IRQ_NAND,
+		    GLOBAL_IRQ_MASK);
 	free_irq(pdev->irq, mtd);
  out_ior:
 	pci_iounmap(pdev, cafe->mmio);
@@ -805,7 +959,9 @@  static void cafe_nand_remove(struct pci_dev *pdev)
 	struct cafe_priv *cafe = nand_get_controller_data(chip);
 
 	/* Disable NAND IRQ in global IRQ mask register */
-	cafe_writel(cafe, ~1 & cafe_readl(cafe, GLOBAL_IRQ_MASK), GLOBAL_IRQ_MASK);
+	cafe_writel(cafe,
+		    cafe_readl(cafe, GLOBAL_IRQ_MASK) & ~CAFE_GLOBAL_IRQ_NAND,
+		    GLOBAL_IRQ_MASK);
 	free_irq(pdev->irq, mtd);
 	nand_release(chip);
 	free_rs(cafe->rs);
@@ -830,8 +986,8 @@  static int cafe_nand_resume(struct pci_dev *pdev)
 	struct cafe_priv *cafe = nand_get_controller_data(chip);
 
        /* Start off by resetting the NAND controller completely */
-	cafe_writel(cafe, 1, NAND_RESET);
-	cafe_writel(cafe, 0, NAND_RESET);
+	cafe_writel(cafe, CAFE_GLOBAL_RESET_NAND, GLOBAL_RESET);
+	cafe_writel(cafe, 0, GLOBAL_RESET);
 	cafe_writel(cafe, 0xffffffff, NAND_IRQ_MASK);
 
 	/* Restore timing configuration */
@@ -841,13 +997,41 @@  static int cafe_nand_resume(struct pci_dev *pdev)
 
         /* Disable master reset, enable NAND clock */
 	ctrl = cafe_readl(cafe, GLOBAL_CTRL);
-	ctrl &= 0xffffeff0;
-	ctrl |= 0x00007000;
-	cafe_writel(cafe, ctrl | 0x05, GLOBAL_CTRL);
-	cafe_writel(cafe, ctrl | 0x0a, GLOBAL_CTRL);
+	ctrl &= ~(CAFE_GLOBAL_SW_RESET_SET |
+		  CAFE_GLOBAL_SW_RESET_CLEAR |
+		  CAFE_GLOBAL_MASTER_RESET_SET |
+		  CAFE_GLOBAL_MASTER_RESET_CLEAR |
+		  CAFE_GLOBAL_NAND_CLK_ENABLE);
+	ctrl |= CAFE_GLOBAL_NAND_CLK_ENABLE |
+		CAFE_GLOBAL_SDH_CLK_ENABLE |
+		CAFE_GLOBAL_CCIC_CLK_ENABLE;
+	cafe_writel(cafe,
+		    ctrl |
+		    CAFE_GLOBAL_MASTER_RESET_SET |
+		    CAFE_GLOBAL_SW_RESET_SET,
+		    GLOBAL_CTRL);
+	cafe_writel(cafe,
+		    ctrl |
+		    CAFE_GLOBAL_MASTER_RESET_CLEAR |
+		    CAFE_GLOBAL_SW_RESET_CLEAR,
+		    GLOBAL_CTRL);
+
 	cafe_writel(cafe, 0, NAND_DMA_CTRL);
-	cafe_writel(cafe, 0x7006, GLOBAL_CTRL);
-	cafe_writel(cafe, 0x700a, GLOBAL_CTRL);
+
+	cafe_writel(cafe,
+		    CAFE_GLOBAL_NAND_CLK_ENABLE |
+		    CAFE_GLOBAL_SDH_CLK_ENABLE |
+		    CAFE_GLOBAL_CCIC_CLK_ENABLE |
+		    CAFE_GLOBAL_MASTER_RESET_SET |
+		    CAFE_GLOBAL_SW_RESET_CLEAR,
+		    GLOBAL_CTRL);
+	cafe_writel(cafe,
+		    CAFE_GLOBAL_NAND_CLK_ENABLE |
+		    CAFE_GLOBAL_SDH_CLK_ENABLE |
+		    CAFE_GLOBAL_CCIC_CLK_ENABLE |
+		    CAFE_GLOBAL_MASTER_RESET_CLEAR |
+		    CAFE_GLOBAL_SW_RESET_CLEAR,
+		    GLOBAL_CTRL);
 
 	/* Set up DMA address */
 	cafe_writel(cafe, cafe->dmaaddr & 0xffffffff, NAND_DMA_ADDR0);
@@ -858,7 +1042,12 @@  static int cafe_nand_resume(struct pci_dev *pdev)
 		cafe_writel(cafe, 0, NAND_DMA_ADDR1);
 
 	/* Enable NAND IRQ in global IRQ mask register */
-	cafe_writel(cafe, 0x80000007, GLOBAL_IRQ_MASK);
+	cafe_writel(cafe,
+		    CAFE_GLOBAL_IRQ_PCI_ERROR |
+		    CAFE_GLOBAL_IRQ_CCIC |
+		    CAFE_GLOBAL_IRQ_SDH |
+		    CAFE_GLOBAL_IRQ_NAND,
+		    GLOBAL_IRQ_MASK);
 	return 0;
 }