lpc32xx: Flash driver
Based on the lpc3180 driver, but released as a separate driver for two reasons: 1) I don't have an lpc3180 to test it against, so it might unintentionally break compatibility. 2) It's using a different OOB layout than lpc3180. Rewritten so that it no longer borrows code from the NXP CDL library. Instead borrowing code from the u-boot port to lpc32xx, written by Kevin Wells. Tested on lpc3250 (Hitex LPC3250-Stick). OOB layout is compatible with LPCLinux.
This commit is contained in:
parent
fe0894015f
commit
3f4b9e334b
|
@ -16,6 +16,7 @@ NAND_DRIVERS = \
|
||||||
nonce.c \
|
nonce.c \
|
||||||
davinci.c \
|
davinci.c \
|
||||||
lpc3180.c \
|
lpc3180.c \
|
||||||
|
lpc32xx.c \
|
||||||
mx2.c \
|
mx2.c \
|
||||||
mx3.c \
|
mx3.c \
|
||||||
orion.c \
|
orion.c \
|
||||||
|
@ -35,6 +36,7 @@ noinst_HEADERS = \
|
||||||
fileio.h \
|
fileio.h \
|
||||||
imp.h \
|
imp.h \
|
||||||
lpc3180.h \
|
lpc3180.h \
|
||||||
|
lpc32xx.h \
|
||||||
mx2.h \
|
mx2.h \
|
||||||
mx3.h \
|
mx3.h \
|
||||||
s3c24xx.h \
|
s3c24xx.h \
|
||||||
|
|
|
@ -31,6 +31,7 @@
|
||||||
extern struct nand_flash_controller nonce_nand_controller;
|
extern struct nand_flash_controller nonce_nand_controller;
|
||||||
extern struct nand_flash_controller davinci_nand_controller;
|
extern struct nand_flash_controller davinci_nand_controller;
|
||||||
extern struct nand_flash_controller lpc3180_nand_controller;
|
extern struct nand_flash_controller lpc3180_nand_controller;
|
||||||
|
extern struct nand_flash_controller lpc32xx_nand_controller;
|
||||||
extern struct nand_flash_controller orion_nand_controller;
|
extern struct nand_flash_controller orion_nand_controller;
|
||||||
extern struct nand_flash_controller s3c2410_nand_controller;
|
extern struct nand_flash_controller s3c2410_nand_controller;
|
||||||
extern struct nand_flash_controller s3c2412_nand_controller;
|
extern struct nand_flash_controller s3c2412_nand_controller;
|
||||||
|
@ -49,6 +50,7 @@ static struct nand_flash_controller *nand_flash_controllers[] =
|
||||||
&nonce_nand_controller,
|
&nonce_nand_controller,
|
||||||
&davinci_nand_controller,
|
&davinci_nand_controller,
|
||||||
&lpc3180_nand_controller,
|
&lpc3180_nand_controller,
|
||||||
|
&lpc32xx_nand_controller,
|
||||||
&orion_nand_controller,
|
&orion_nand_controller,
|
||||||
&s3c2410_nand_controller,
|
&s3c2410_nand_controller,
|
||||||
&s3c2412_nand_controller,
|
&s3c2412_nand_controller,
|
||||||
|
|
|
@ -120,3 +120,64 @@ int nand_calculate_ecc(struct nand_device *nand, const uint8_t *dat, uint8_t *ec
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static inline int countbits(uint32_t byte)
|
||||||
|
{
|
||||||
|
int res = 0;
|
||||||
|
|
||||||
|
for (;byte; byte >>= 1)
|
||||||
|
res += byte & 0x01;
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* nand_correct_data - Detect and correct a 1 bit error for 256 byte block
|
||||||
|
*/
|
||||||
|
int nand_correct_data(struct nand_device *nand, u_char *dat,
|
||||||
|
u_char *read_ecc, u_char *calc_ecc)
|
||||||
|
{
|
||||||
|
uint8_t s0, s1, s2;
|
||||||
|
|
||||||
|
#ifdef NAND_ECC_SMC
|
||||||
|
s0 = calc_ecc[0] ^ read_ecc[0];
|
||||||
|
s1 = calc_ecc[1] ^ read_ecc[1];
|
||||||
|
s2 = calc_ecc[2] ^ read_ecc[2];
|
||||||
|
#else
|
||||||
|
s1 = calc_ecc[0] ^ read_ecc[0];
|
||||||
|
s0 = calc_ecc[1] ^ read_ecc[1];
|
||||||
|
s2 = calc_ecc[2] ^ read_ecc[2];
|
||||||
|
#endif
|
||||||
|
if ((s0 | s1 | s2) == 0)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
/* Check for a single bit error */
|
||||||
|
if( ((s0 ^ (s0 >> 1)) & 0x55) == 0x55 &&
|
||||||
|
((s1 ^ (s1 >> 1)) & 0x55) == 0x55 &&
|
||||||
|
((s2 ^ (s2 >> 1)) & 0x54) == 0x54) {
|
||||||
|
|
||||||
|
uint32_t byteoffs, bitnum;
|
||||||
|
|
||||||
|
byteoffs = (s1 << 0) & 0x80;
|
||||||
|
byteoffs |= (s1 << 1) & 0x40;
|
||||||
|
byteoffs |= (s1 << 2) & 0x20;
|
||||||
|
byteoffs |= (s1 << 3) & 0x10;
|
||||||
|
|
||||||
|
byteoffs |= (s0 >> 4) & 0x08;
|
||||||
|
byteoffs |= (s0 >> 3) & 0x04;
|
||||||
|
byteoffs |= (s0 >> 2) & 0x02;
|
||||||
|
byteoffs |= (s0 >> 1) & 0x01;
|
||||||
|
|
||||||
|
bitnum = (s2 >> 5) & 0x04;
|
||||||
|
bitnum |= (s2 >> 4) & 0x02;
|
||||||
|
bitnum |= (s2 >> 3) & 0x01;
|
||||||
|
|
||||||
|
dat[byteoffs] ^= (1 << bitnum);
|
||||||
|
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(countbits(s0 | ((uint32_t)s1 << 8) | ((uint32_t)s2 <<16)) == 1)
|
||||||
|
return 1;
|
||||||
|
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,39 @@
|
||||||
|
/***************************************************************************
|
||||||
|
* Copyright (C) 2007 by Dominic Rath *
|
||||||
|
* Dominic.Rath@gmx.de *
|
||||||
|
* *
|
||||||
|
* This program is free software; you can redistribute it and/or modify *
|
||||||
|
* it under the terms of the GNU General Public License as published by *
|
||||||
|
* the Free Software Foundation; either version 2 of the License, or *
|
||||||
|
* (at your option) any later version. *
|
||||||
|
* *
|
||||||
|
* This program is distributed in the hope that it will be useful, *
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
|
||||||
|
* GNU General Public License for more details. *
|
||||||
|
* *
|
||||||
|
* You should have received a copy of the GNU General Public License *
|
||||||
|
* along with this program; if not, write to the *
|
||||||
|
* Free Software Foundation, Inc., *
|
||||||
|
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
|
||||||
|
***************************************************************************/
|
||||||
|
#ifndef LPC32xx_NAND_CONTROLLER_H
|
||||||
|
#define LPC32xx_NAND_CONTROLLER_H
|
||||||
|
|
||||||
|
enum lpc32xx_selected_controller
|
||||||
|
{
|
||||||
|
LPC32xx_NO_CONTROLLER,
|
||||||
|
LPC32xx_MLC_CONTROLLER,
|
||||||
|
LPC32xx_SLC_CONTROLLER,
|
||||||
|
};
|
||||||
|
|
||||||
|
struct lpc32xx_nand_controller
|
||||||
|
{
|
||||||
|
int osc_freq;
|
||||||
|
enum lpc32xx_selected_controller selected_controller;
|
||||||
|
int sw_write_protection;
|
||||||
|
uint32_t sw_wp_lower_bound;
|
||||||
|
uint32_t sw_wp_upper_bound;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif /*LPC32xx_NAND_CONTROLLER_H */
|
Loading…
Reference in New Issue