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 \
|
||||
davinci.c \
|
||||
lpc3180.c \
|
||||
lpc32xx.c \
|
||||
mx2.c \
|
||||
mx3.c \
|
||||
orion.c \
|
||||
|
@ -35,6 +36,7 @@ noinst_HEADERS = \
|
|||
fileio.h \
|
||||
imp.h \
|
||||
lpc3180.h \
|
||||
lpc32xx.h \
|
||||
mx2.h \
|
||||
mx3.h \
|
||||
s3c24xx.h \
|
||||
|
|
|
@ -31,6 +31,7 @@
|
|||
extern struct nand_flash_controller nonce_nand_controller;
|
||||
extern struct nand_flash_controller davinci_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 s3c2410_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,
|
||||
&davinci_nand_controller,
|
||||
&lpc3180_nand_controller,
|
||||
&lpc32xx_nand_controller,
|
||||
&orion_nand_controller,
|
||||
&s3c2410_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;
|
||||
}
|
||||
|
||||
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