[U-Boot] [PATCH] TI: Davinci: NAND Driver Cleanup

From: Cyril Chemparathy cyril@ti.com
Modified to use IO accessor routines consistently. Eliminated volatile usage to keep checkpatch.pl happy. Patch was tested on DM355, DM365 and DM6446 EVMs
Signed-off-by: Cyril Chemparathy cyril@ti.com Tested-by: Sandeep Paulraj s-paulraj@ti.com --- drivers/mtd/nand/davinci_nand.c | 126 ++++++++++++++++-------------- include/asm-arm/arch-davinci/emif_defs.h | 80 +++++++++---------- 2 files changed, 104 insertions(+), 102 deletions(-)
diff --git a/drivers/mtd/nand/davinci_nand.c b/drivers/mtd/nand/davinci_nand.c index bfc2acf..61cba14 100644 --- a/drivers/mtd/nand/davinci_nand.c +++ b/drivers/mtd/nand/davinci_nand.c @@ -57,7 +57,8 @@ #define ECC_STATE_ERR_CORR_COMP_P 0x2 #define ECC_STATE_ERR_CORR_COMP_N 0x3
-static emif_registers *const emif_regs = (void *) DAVINCI_ASYNC_EMIF_CNTRL_BASE; +static struct davinci_emif_regs *emif_regs = + (struct davinci_emif_regs *) DAVINCI_ASYNC_EMIF_CNTRL_BASE;
/* * Exploit the little endianness of the ARM to do multi-byte transfers @@ -93,7 +94,7 @@ static void nand_davinci_read_buf(struct mtd_info *mtd, uint8_t *buf, int len)
/* copy aligned data */ while (len >= 4) { - *(u32 *)buf = readl(nand); + *(u32 *)buf = __raw_readl(nand); buf += 4; len -= 4; } @@ -138,7 +139,7 @@ static void nand_davinci_write_buf(struct mtd_info *mtd, const uint8_t *buf,
/* copy aligned data */ while (len >= 4) { - writel(*(u32 *)buf, nand); + __raw_writel(*(u32 *)buf, nand); buf += 4; len -= 4; } @@ -156,7 +157,8 @@ static void nand_davinci_write_buf(struct mtd_info *mtd, const uint8_t *buf, } }
-static void nand_davinci_hwcontrol(struct mtd_info *mtd, int cmd, unsigned int ctrl) +static void nand_davinci_hwcontrol(struct mtd_info *mtd, int cmd, + unsigned int ctrl) { struct nand_chip *this = mtd->priv; u_int32_t IO_ADDR_W = (u_int32_t)this->IO_ADDR_W; @@ -164,9 +166,9 @@ static void nand_davinci_hwcontrol(struct mtd_info *mtd, int cmd, unsigned int c if (ctrl & NAND_CTRL_CHANGE) { IO_ADDR_W &= ~(MASK_ALE|MASK_CLE);
- if ( ctrl & NAND_CLE ) + if (ctrl & NAND_CLE) IO_ADDR_W |= MASK_CLE; - if ( ctrl & NAND_ALE ) + if (ctrl & NAND_ALE) IO_ADDR_W |= MASK_ALE; this->IO_ADDR_W = (void __iomem *) IO_ADDR_W; } @@ -181,24 +183,25 @@ static void nand_davinci_enable_hwecc(struct mtd_info *mtd, int mode) { u_int32_t val;
- (void)readl(&(emif_regs->NANDFECC[CONFIG_SYS_NAND_CS - 2])); + (void)__raw_readl(&(emif_regs->nandfecc[CONFIG_SYS_NAND_CS - 2]));
- val = readl(&emif_regs->NANDFCR); + val = __raw_readl(&emif_regs->nandfcr); val |= DAVINCI_NANDFCR_NAND_ENABLE(CONFIG_SYS_NAND_CS); val |= DAVINCI_NANDFCR_1BIT_ECC_START(CONFIG_SYS_NAND_CS); - writel(val, &emif_regs->NANDFCR); + __raw_writel(val, &emif_regs->nandfcr); }
static u_int32_t nand_davinci_readecc(struct mtd_info *mtd, u_int32_t region) { u_int32_t ecc = 0;
- ecc = readl(&(emif_regs->NANDFECC[region - 1])); + ecc = __raw_readl(&(emif_regs->nandfecc[region - 1]));
- return(ecc); + return ecc; }
-static int nand_davinci_calculate_ecc(struct mtd_info *mtd, const u_char *dat, u_char *ecc_code) +static int nand_davinci_calculate_ecc(struct mtd_info *mtd, const u_char *dat, + u_char *ecc_code) { u_int32_t tmp; const int region = 1; @@ -232,7 +235,8 @@ static int nand_davinci_calculate_ecc(struct mtd_info *mtd, const u_char *dat, u return 0; }
-static int nand_davinci_correct_data(struct mtd_info *mtd, u_char *dat, u_char *read_ecc, u_char *calc_ecc) +static int nand_davinci_correct_data(struct mtd_info *mtd, u_char *dat, + u_char *read_ecc, u_char *calc_ecc) { struct nand_chip *this = mtd->priv; u_int32_t ecc_nand = read_ecc[0] | (read_ecc[1] << 8) | @@ -268,7 +272,7 @@ static int nand_davinci_correct_data(struct mtd_info *mtd, u_char *dat, u_char * return -1; } } - return(0); + return 0; } #endif /* CONFIG_SYS_NAND_HW_ECC */
@@ -315,15 +319,15 @@ static void nand_davinci_4bit_enable_hwecc(struct mtd_info *mtd, int mode) * Start a new ECC calculation for reading or writing 512 bytes * of data. */ - val = readl(&emif_regs->NANDFCR); + val = __raw_readl(&emif_regs->nandfcr); val &= ~DAVINCI_NANDFCR_4BIT_ECC_SEL_MASK; val |= DAVINCI_NANDFCR_NAND_ENABLE(CONFIG_SYS_NAND_CS); val |= DAVINCI_NANDFCR_4BIT_ECC_SEL(CONFIG_SYS_NAND_CS); val |= DAVINCI_NANDFCR_4BIT_ECC_START; - writel(val, &emif_regs->NANDFCR); + __raw_writel(val, &emif_regs->nandfcr); break; case NAND_ECC_READSYN: - val = emif_regs->NAND4BITECC1; + val = __raw_readl(&emif_regs->nand4bitecc[0]); break; default: break; @@ -332,10 +336,12 @@ static void nand_davinci_4bit_enable_hwecc(struct mtd_info *mtd, int mode)
static u32 nand_davinci_4bit_readecc(struct mtd_info *mtd, unsigned int ecc[4]) { - ecc[0] = emif_regs->NAND4BITECC1 & NAND_4BITECC_MASK; - ecc[1] = emif_regs->NAND4BITECC2 & NAND_4BITECC_MASK; - ecc[2] = emif_regs->NAND4BITECC3 & NAND_4BITECC_MASK; - ecc[3] = emif_regs->NAND4BITECC4 & NAND_4BITECC_MASK; + int i; + + for (i = 0; i < 4; i++) { + ecc[i] = __raw_readl(&emif_regs->nand4bitecc[i]) & + NAND_4BITECC_MASK; + }
return 0; } @@ -418,32 +424,36 @@ static int nand_davinci_4bit_correct_data(struct mtd_info *mtd, uint8_t *dat, */
/*Take 2 bits from 8th byte and 8 bits from 9th byte */ - writel(((ecc16[4]) >> 6) & 0x3FF, &emif_regs->NAND4BITECCLOAD); + __raw_writel(((ecc16[4]) >> 6) & 0x3FF, + &emif_regs->nand4biteccload);
/* Take 4 bits from 7th byte and 6 bits from 8th byte */ - writel((((ecc16[3]) >> 12) & 0xF) | ((((ecc16[4])) << 4) & 0x3F0), - &emif_regs->NAND4BITECCLOAD); + __raw_writel((((ecc16[3]) >> 12) & 0xF) | ((((ecc16[4])) << 4) & 0x3F0), + &emif_regs->nand4biteccload);
/* Take 6 bits from 6th byte and 4 bits from 7th byte */ - writel((ecc16[3] >> 2) & 0x3FF, &emif_regs->NAND4BITECCLOAD); + __raw_writel((ecc16[3] >> 2) & 0x3FF, + &emif_regs->nand4biteccload);
/* Take 8 bits from 5th byte and 2 bits from 6th byte */ - writel(((ecc16[2]) >> 8) | ((((ecc16[3])) << 8) & 0x300), - &emif_regs->NAND4BITECCLOAD); + __raw_writel(((ecc16[2]) >> 8) | ((((ecc16[3])) << 8) & 0x300), + &emif_regs->nand4biteccload);
/*Take 2 bits from 3rd byte and 8 bits from 4th byte */ - writel((((ecc16[1]) >> 14) & 0x3) | ((((ecc16[2])) << 2) & 0x3FC), - &emif_regs->NAND4BITECCLOAD); + __raw_writel((((ecc16[1]) >> 14) & 0x3) | ((((ecc16[2])) << 2) & 0x3FC), + &emif_regs->nand4biteccload);
/* Take 4 bits form 2nd bytes and 6 bits from 3rd bytes */ - writel(((ecc16[1]) >> 4) & 0x3FF, &emif_regs->NAND4BITECCLOAD); + __raw_writel(((ecc16[1]) >> 4) & 0x3FF, + &emif_regs->nand4biteccload);
/* Take 6 bits from 1st byte and 4 bits from 2nd byte */ - writel((((ecc16[0]) >> 10) & 0x3F) | (((ecc16[1]) << 6) & 0x3C0), - &emif_regs->NAND4BITECCLOAD); + __raw_writel((((ecc16[0]) >> 10) & 0x3F) | (((ecc16[1]) << 6) & 0x3C0), + &emif_regs->nand4biteccload);
/* Take 10 bits from 0th and 1st bytes */ - writel((ecc16[0]) & 0x3FF, &emif_regs->NAND4BITECCLOAD); + __raw_writel((ecc16[0]) & 0x3FF, + &emif_regs->nand4biteccload);
/* * Perform a dummy read to the EMIF Revision Code and Status register. @@ -451,7 +461,7 @@ static int nand_davinci_4bit_correct_data(struct mtd_info *mtd, uint8_t *dat, * writing the ECC values in previous step. */
- val = emif_regs->NANDFSR; + val = __raw_readl(&emif_regs->nandfsr);
/* * Read the syndrome from the NAND Flash 4-Bit ECC 1-4 registers. @@ -467,13 +477,13 @@ static int nand_davinci_4bit_correct_data(struct mtd_info *mtd, uint8_t *dat, * Clear any previous address calculation by doing a dummy read of an * error address register. */ - val = emif_regs->NANDERRADD1; + val = __raw_readl(&emif_regs->nanderradd1);
/* * Set the addr_calc_st bit(bit no 13) in the NAND Flash Control * register to 1. */ - emif_regs->NANDFCR |= 1 << 13; + __raw_writel(1 << 13, &emif_regs->nandfcr);
/* * Wait for the corr_state field (bits 8 to 11)in the @@ -481,12 +491,12 @@ static int nand_davinci_4bit_correct_data(struct mtd_info *mtd, uint8_t *dat, */ i = NAND_TIMEOUT; do { - val = emif_regs->NANDFSR; + val = __raw_readl(&emif_regs->nandfsr); val &= 0xc00; i--; } while ((i > 0) && val);
- iserror = emif_regs->NANDFSR; + iserror = __raw_readl(&emif_regs->nandfsr); iserror &= EMIF_NANDFSR_ECC_STATE_MASK; iserror = iserror >> 8;
@@ -501,32 +511,32 @@ static int nand_davinci_4bit_correct_data(struct mtd_info *mtd, uint8_t *dat, */
if (iserror == ECC_STATE_NO_ERR) { - val = emif_regs->NANDERRVAL1; + val = __raw_readl(&emif_regs->nanderrval1); return 0; } else if (iserror == ECC_STATE_TOO_MANY_ERRS) { - val = emif_regs->NANDERRVAL1; + val = __raw_readl(&emif_regs->nanderrval1); return -1; }
- numerrors = ((emif_regs->NANDFSR >> 16) & 0x3) + 1; + numerrors = ((__raw_readl(&emif_regs->nandfsr) >> 16) & 0x3) + 1;
/* Read the error address, error value and correct */ for (i = 0; i < numerrors; i++) { if (i > 1) { erroraddress = - ((emif_regs->NANDERRADD2 >> + ((__raw_readl(&emif_regs->nanderradd2) >> (16 * (i & 1))) & 0x3FF); erroraddress = ((512 + 7) - erroraddress); errorvalue = - ((emif_regs->NANDERRVAL2 >> + ((__raw_readl(&emif_regs->nanderrval2) >> (16 * (i & 1))) & 0xFF); } else { erroraddress = - ((emif_regs->NANDERRADD1 >> + ((__raw_readl(&emif_regs->nanderradd1) >> (16 * (i & 1))) & 0x3FF); erroraddress = ((512 + 7) - erroraddress); errorvalue = - ((emif_regs->NANDERRVAL1 >> + ((__raw_readl(&emif_regs->nanderrval1) >> (16 * (i & 1))) & 0xFF); } /* xor the corrupt data with error value */ @@ -540,7 +550,7 @@ static int nand_davinci_4bit_correct_data(struct mtd_info *mtd, uint8_t *dat,
static int nand_davinci_dev_ready(struct mtd_info *mtd) { - return emif_regs->NANDFSR & 0x1; + return __raw_readl(&emif_regs->nandfsr) & 0x1; }
static void nand_flash_init(void) @@ -561,21 +571,21 @@ static void nand_flash_init(void) * * *------------------------------------------------------------------*/ acfg1 = 0 - | (0 << 31 ) /* selectStrobe */ - | (0 << 30 ) /* extWait */ - | (1 << 26 ) /* writeSetup 10 ns */ - | (3 << 20 ) /* writeStrobe 40 ns */ - | (1 << 17 ) /* writeHold 10 ns */ - | (1 << 13 ) /* readSetup 10 ns */ - | (5 << 7 ) /* readStrobe 60 ns */ - | (1 << 4 ) /* readHold 10 ns */ - | (3 << 2 ) /* turnAround ?? ns */ - | (0 << 0 ) /* asyncSize 8-bit bus */ + | (0 << 31) /* selectStrobe */ + | (0 << 30) /* extWait */ + | (1 << 26) /* writeSetup 10 ns */ + | (3 << 20) /* writeStrobe 40 ns */ + | (1 << 17) /* writeHold 10 ns */ + | (1 << 13) /* readSetup 10 ns */ + | (5 << 7) /* readStrobe 60 ns */ + | (1 << 4) /* readHold 10 ns */ + | (3 << 2) /* turnAround ?? ns */ + | (0 << 0) /* asyncSize 8-bit bus */ ;
- emif_regs->AB1CR = acfg1; /* CS2 */ + __raw_writel(acfg1, &emif_regs->AB1CR); /* CS2 */
- emif_regs->NANDFCR = 0x00000101; /* NAND flash on CS2 */ + __raw_writel(0x00000101, &emif_regs->nandfcr); /* NAND flash on CS2 */ #endif }
diff --git a/include/asm-arm/arch-davinci/emif_defs.h b/include/asm-arm/arch-davinci/emif_defs.h index aa57703..3d77bfc 100644 --- a/include/asm-arm/arch-davinci/emif_defs.h +++ b/include/asm-arm/arch-davinci/emif_defs.h @@ -24,50 +24,42 @@
#include <asm/arch/hardware.h>
-typedef struct davinci_emif_regs { - dv_reg ERCSR; - dv_reg AWCCR; - dv_reg SDBCR; - dv_reg SDRCR; - dv_reg AB1CR; - dv_reg AB2CR; - dv_reg AB3CR; - dv_reg AB4CR; - dv_reg SDTIMR; - dv_reg DDRSR; - dv_reg DDRPHYCR; - dv_reg DDRPHYSR; - dv_reg TOTAR; - dv_reg TOTACTR; - dv_reg DDRPHYID_REV; - dv_reg SDSRETR; - dv_reg EIRR; - dv_reg EIMR; - dv_reg EIMSR; - dv_reg EIMCR; - dv_reg IOCTRLR; - dv_reg IOSTATR; - u_int8_t RSVD0[8]; - dv_reg NANDFCR; - dv_reg NANDFSR; - u_int8_t RSVD1[8]; - dv_reg NANDFECC[4]; - u_int8_t RSVD2[60]; - dv_reg NAND4BITECCLOAD; - dv_reg NAND4BITECC1; - dv_reg NAND4BITECC2; - dv_reg NAND4BITECC3; - dv_reg NAND4BITECC4; - dv_reg NANDERRADD1; - dv_reg NANDERRADD2; - dv_reg NANDERRVAL1; - dv_reg NANDERRVAL2; -} emif_registers; - -typedef emif_registers *emifregs; - -#define davinci_emif_regs \ - ((struct davinci_emif_regs *)DAVINCI_ASYNC_EMIF_CNTRL_BASE) +struct davinci_emif_regs { + u_int32_t ercsr; + u_int32_t awccr; + u_int32_t sdbcr; + u_int32_t sdrcr; + u_int32_t ab1cr; + u_int32_t ab2cr; + u_int32_t ab3cr; + u_int32_t ab4cr; + u_int32_t sdtimr; + u_int32_t ddrsr; + u_int32_t ddrphycr; + u_int32_t ddrphysr; + u_int32_t totar; + u_int32_t totactr; + u_int32_t ddrphyid_rev; + u_int32_t sdsretr; + u_int32_t eirr; + u_int32_t eimr; + u_int32_t eimsr; + u_int32_t eimcr; + u_int32_t ioctrlr; + u_int32_t iostatr; + u_int8_t rsvd0[8]; + u_int32_t nandfcr; + u_int32_t nandfsr; + u_int8_t rsvd1[8]; + u_int32_t nandfecc[4]; + u_int8_t rsvd2[60]; + u_int32_t nand4biteccload; + u_int32_t nand4bitecc[4]; + u_int32_t nanderradd1; + u_int32_t nanderradd2; + u_int32_t nanderrval1; + u_int32_t nanderrval2; +};
#define DAVINCI_NANDFCR_NAND_ENABLE(n) (1 << (n-2)) #define DAVINCI_NANDFCR_4BIT_ECC_SEL_MASK (3 << 4)

On Sun, Mar 14, 2010 at 05:14:31PM -0400, s-paulraj@ti.com wrote:
- emif_regs->AB1CR = acfg1; /* CS2 */
- __raw_writel(acfg1, &emif_regs->AB1CR); /* CS2 */
Configuring for davinci_schmoogie board... davinci_nand.c: In function ‘nand_flash_init’: davinci_nand.c:586: error: ‘struct davinci_emif_regs’ has no member named ‘AB1CR’ make[1]: *** [davinci_nand.o] Error 1 make: *** [drivers/mtd/nand/libnand.a] Error 2
Should be lowercase?
Also, any particular reason to use the raw version of the accessors?
-Scott

Hi Scott,
Configuring for davinci_schmoogie board... ... Should be lowercase?
Thank you. I will be sending out a v2 shortly, and this time around all 8 davinci based boards build fine.
Also, any particular reason to use the raw version of the accessors?
Please correct me if I am wrong here, but my understanding is that the raw variants are for native-endian access, while the non-raw ones could potentially force little-endian conversions for PCI.
If so, since these on-chip registers must always be accessed native-endian, I felt that the raw accessors would be appropriate.
Any thoughts?
Regards Cyril.

Chemparathy, Cyril wrote:
Please correct me if I am wrong here, but my understanding is that the raw variants are for native-endian access, while the non-raw ones could potentially force little-endian conversions for PCI.
The non-raw ones also provide ordering on some architectures, though I don't think this matters on ARM. Unfortunately there doesn't seem to be an arch-neutral way to unbundle these.
If so, since these on-chip registers must always be accessed native-endian, I felt that the raw accessors would be appropriate.
OK.
-Scott

On 14/03/10 21:14, s-paulraj@ti.com wrote:
From: Cyril Chemparathy cyril@ti.com
Modified to use IO accessor routines consistently. Eliminated volatile usage to keep checkpatch.pl happy. Patch was tested on DM355, DM365 and DM6446 EVMs
Signed-off-by: Cyril Chemparathy cyril@ti.com Tested-by: Sandeep Paulraj s-paulraj@ti.com
drivers/mtd/nand/davinci_nand.c | 126 ++++++++++++++++-------------- include/asm-arm/arch-davinci/emif_defs.h | 80 +++++++++---------- 2 files changed, 104 insertions(+), 102 deletions(-)
diff --git a/drivers/mtd/nand/davinci_nand.c b/drivers/mtd/nand/davinci_nand.c index bfc2acf..61cba14 100644 --- a/drivers/mtd/nand/davinci_nand.c +++ b/drivers/mtd/nand/davinci_nand.c @@ -57,7 +57,8 @@ #define ECC_STATE_ERR_CORR_COMP_P 0x2 #define ECC_STATE_ERR_CORR_COMP_N 0x3
-static emif_registers *const emif_regs = (void *) DAVINCI_ASYNC_EMIF_CNTRL_BASE; +static struct davinci_emif_regs *emif_regs =
- (struct davinci_emif_regs *) DAVINCI_ASYNC_EMIF_CNTRL_BASE;
Since this is really just a constant, why setup a variable locally where ever EMIF registers are accessed? What's wrong with the define you removed below? ...
diff --git a/include/asm-arm/arch-davinci/emif_defs.h b/include/asm-arm/arch-davinci/emif_defs.h index aa57703..3d77bfc 100644 --- a/include/asm-arm/arch-davinci/emif_defs.h +++ b/include/asm-arm/arch-davinci/emif_defs.h @@ -24,50 +24,42 @@
#include <asm/arch/hardware.h>
-typedef struct davinci_emif_regs {
- dv_reg ERCSR;
- dv_reg AWCCR;
- dv_reg SDBCR;
- dv_reg SDRCR;
- dv_reg AB1CR;
- dv_reg AB2CR;
- dv_reg AB3CR;
- dv_reg AB4CR;
- dv_reg SDTIMR;
- dv_reg DDRSR;
- dv_reg DDRPHYCR;
- dv_reg DDRPHYSR;
- dv_reg TOTAR;
- dv_reg TOTACTR;
- dv_reg DDRPHYID_REV;
- dv_reg SDSRETR;
- dv_reg EIRR;
- dv_reg EIMR;
- dv_reg EIMSR;
- dv_reg EIMCR;
- dv_reg IOCTRLR;
- dv_reg IOSTATR;
- u_int8_t RSVD0[8];
- dv_reg NANDFCR;
- dv_reg NANDFSR;
- u_int8_t RSVD1[8];
- dv_reg NANDFECC[4];
- u_int8_t RSVD2[60];
- dv_reg NAND4BITECCLOAD;
- dv_reg NAND4BITECC1;
- dv_reg NAND4BITECC2;
- dv_reg NAND4BITECC3;
- dv_reg NAND4BITECC4;
- dv_reg NANDERRADD1;
- dv_reg NANDERRADD2;
- dv_reg NANDERRVAL1;
- dv_reg NANDERRVAL2;
-} emif_registers;
-typedef emif_registers *emifregs;
-#define davinci_emif_regs \
- ((struct davinci_emif_regs *)DAVINCI_ASYNC_EMIF_CNTRL_BASE)
...This one.
Nick.

Nick,
Since this is really just a constant, why setup a variable locally where ever EMIF registers are accessed? What's wrong with the define you removed below? ...
-#define davinci_emif_regs \
- ((struct davinci_emif_regs *)DAVINCI_ASYNC_EMIF_CNTRL_BASE)
...This one.
Thanks. I'll incorporate this change and send out an update.
Also, it turns out that getting rid of this macro definition would also break DA830 EVM.
I have put in fixes for these issues, run a MAKEALL and send out an updated patch shortly.
Regards Cyril.
participants (4)
-
Chemparathy, Cyril
-
Nick Thompson
-
s-paulraj@ti.com
-
Scott Wood