Flex-OneNAND driver support
This patch adds support for Flex-OneNAND devices. Signed-off-by: Rohit Hagargundgi <h.rohit@samsung.com> Signed-off-by: Amul Kumar Saha <amul.saha@samsung.com>
This commit is contained in:
parent
35209cbcee
commit
cacbe91958
File diff suppressed because it is too large
Load Diff
@ -69,6 +69,7 @@ static int create_bbt(struct mtd_info *mtd, uint8_t * buf,
|
||||
loff_t from;
|
||||
size_t readlen, ooblen;
|
||||
struct mtd_oob_ops ops;
|
||||
int rgn;
|
||||
|
||||
printk(KERN_INFO "Scanning device for bad blocks\n");
|
||||
|
||||
@ -82,7 +83,7 @@ static int create_bbt(struct mtd_info *mtd, uint8_t * buf,
|
||||
/* Note that numblocks is 2 * (real numblocks) here;
|
||||
* see i += 2 below as it makses shifting and masking less painful
|
||||
*/
|
||||
numblocks = mtd->size >> (bbm->bbt_erase_shift - 1);
|
||||
numblocks = this->chipsize >> (bbm->bbt_erase_shift - 1);
|
||||
startblock = 0;
|
||||
from = 0;
|
||||
|
||||
@ -115,7 +116,12 @@ static int create_bbt(struct mtd_info *mtd, uint8_t * buf,
|
||||
}
|
||||
}
|
||||
i += 2;
|
||||
from += (1 << bbm->bbt_erase_shift);
|
||||
|
||||
if (FLEXONENAND(this)) {
|
||||
rgn = flexonenand_region(mtd, from);
|
||||
from += mtd->eraseregions[rgn].erasesize;
|
||||
} else
|
||||
from += (1 << bbm->bbt_erase_shift);
|
||||
}
|
||||
|
||||
return 0;
|
||||
@ -152,7 +158,7 @@ static int onenand_isbad_bbt(struct mtd_info *mtd, loff_t offs, int allowbbt)
|
||||
uint8_t res;
|
||||
|
||||
/* Get block number * 2 */
|
||||
block = (int)(offs >> (bbm->bbt_erase_shift - 1));
|
||||
block = (int) (onenand_block(this, offs) << 1);
|
||||
res = (bbm->bbt[block >> 3] >> (block & 0x06)) & 0x03;
|
||||
|
||||
MTDDEBUG (MTD_DEBUG_LEVEL2,
|
||||
@ -191,7 +197,7 @@ int onenand_scan_bbt(struct mtd_info *mtd, struct nand_bbt_descr *bd)
|
||||
struct bbm_info *bbm = this->bbm;
|
||||
int len, ret = 0;
|
||||
|
||||
len = mtd->size >> (this->erase_shift + 2);
|
||||
len = this->chipsize >> (this->erase_shift + 2);
|
||||
/* Allocate memory (2bit per block) */
|
||||
bbm->bbt = malloc(len);
|
||||
if (!bbm->bbt) {
|
||||
|
@ -40,8 +40,10 @@ void onenand_init(void)
|
||||
|
||||
onenand_scan(&onenand_mtd, 1);
|
||||
|
||||
if (onenand_chip.device_id & DEVICE_IS_FLEXONENAND)
|
||||
puts("Flex-");
|
||||
puts("OneNAND: ");
|
||||
print_size(onenand_mtd.size, "\n");
|
||||
print_size(onenand_chip.chipsize, "\n");
|
||||
|
||||
#ifdef CONFIG_MTD_DEVICE
|
||||
/*
|
||||
|
@ -20,8 +20,9 @@
|
||||
#include <linux/mtd/compat.h>
|
||||
#include <linux/mtd/bbm.h>
|
||||
|
||||
#define MAX_DIES 2
|
||||
#define MAX_BUFFERRAM 2
|
||||
#define MAX_ONENAND_PAGESIZE (2048 + 64)
|
||||
#define MAX_ONENAND_PAGESIZE (4096 + 128)
|
||||
|
||||
/* Scan and identify a OneNAND device */
|
||||
extern int onenand_scan (struct mtd_info *mtd, int max_chips);
|
||||
@ -39,9 +40,14 @@ struct onenand_bufferram {
|
||||
/**
|
||||
* struct onenand_chip - OneNAND Private Flash Chip Data
|
||||
* @param base [BOARDSPECIFIC] address to access OneNAND
|
||||
* @dies: [INTERN][FLEXONENAND] number of dies on chip
|
||||
* @boundary: [INTERN][FLEXONENAND] Boundary of the dies
|
||||
* @diesize: [INTERN][FLEXONENAND] Size of the dies
|
||||
* @param chipsize [INTERN] the size of one chip for multichip arrays
|
||||
* @param device_id [INTERN] device ID
|
||||
* @param verstion_id [INTERN] version ID
|
||||
* @technology [INTERN] describes the internal NAND array technology such as SLC or MLC.
|
||||
* @density_mask: [INTERN] chip density, used for DDP devices
|
||||
* @param options [BOARDSPECIFIC] various chip options. They can partly be set to inform onenand_scan about
|
||||
* @param erase_shift [INTERN] number of address bits in a block
|
||||
* @param page_shift [INTERN] number of address bits in a page
|
||||
@ -64,9 +70,13 @@ struct onenand_bufferram {
|
||||
*/
|
||||
struct onenand_chip {
|
||||
void __iomem *base;
|
||||
unsigned int dies;
|
||||
unsigned int boundary[MAX_DIES];
|
||||
unsigned int diesize[MAX_DIES];
|
||||
unsigned int chipsize;
|
||||
unsigned int device_id;
|
||||
unsigned int version_id;
|
||||
unsigned int technology;
|
||||
unsigned int density_mask;
|
||||
unsigned int options;
|
||||
|
||||
@ -124,6 +134,8 @@ struct onenand_chip {
|
||||
#define ONENAND_SET_BUFFERRAM0(this) (this->bufferram_index = 0)
|
||||
#define ONENAND_SET_BUFFERRAM1(this) (this->bufferram_index = 1)
|
||||
|
||||
#define FLEXONENAND(this) (this->device_id & DEVICE_IS_FLEXONENAND)
|
||||
#define ONENAND_IS_MLC(this) (this->technology & ONENAND_TECHNOLOGY_IS_MLC)
|
||||
#define ONENAND_IS_DDP(this) \
|
||||
(this->device_id & ONENAND_DEVICE_IS_DDP)
|
||||
|
||||
@ -157,4 +169,6 @@ struct onenand_manufacturers {
|
||||
int onenand_bbt_read_oob(struct mtd_info *mtd, loff_t from,
|
||||
struct mtd_oob_ops *ops);
|
||||
|
||||
unsigned int onenand_block(struct onenand_chip *this, loff_t addr);
|
||||
int flexonenand_region(struct mtd_info *mtd, loff_t addr);
|
||||
#endif /* __LINUX_MTD_ONENAND_H */
|
||||
|
@ -67,6 +67,9 @@
|
||||
/*
|
||||
* Device ID Register F001h (R)
|
||||
*/
|
||||
#define DEVICE_IS_FLEXONENAND (1 << 9)
|
||||
#define FLEXONENAND_PI_MASK (0x3ff)
|
||||
#define FLEXONENAND_PI_UNLOCK_SHIFT (14)
|
||||
#define ONENAND_DEVICE_DENSITY_MASK (0xf)
|
||||
#define ONENAND_DEVICE_DENSITY_SHIFT (4)
|
||||
#define ONENAND_DEVICE_IS_DDP (1 << 3)
|
||||
@ -83,6 +86,11 @@
|
||||
*/
|
||||
#define ONENAND_VERSION_PROCESS_SHIFT (8)
|
||||
|
||||
/*
|
||||
* Technology Register F006h (R)
|
||||
*/
|
||||
#define ONENAND_TECHNOLOGY_IS_MLC (1 << 0)
|
||||
|
||||
/*
|
||||
* Start Address 1 F100h (R/W)
|
||||
*/
|
||||
@ -93,7 +101,7 @@
|
||||
/*
|
||||
* Start Address 8 F107h (R/W)
|
||||
*/
|
||||
#define ONENAND_FPA_MASK (0x3f)
|
||||
#define ONENAND_FPA_MASK (0x7f)
|
||||
#define ONENAND_FPA_SHIFT (2)
|
||||
#define ONENAND_FSA_MASK (0x03)
|
||||
|
||||
@ -105,7 +113,7 @@
|
||||
#define ONENAND_BSA_BOOTRAM (0 << 2)
|
||||
#define ONENAND_BSA_DATARAM0 (2 << 2)
|
||||
#define ONENAND_BSA_DATARAM1 (3 << 2)
|
||||
#define ONENAND_BSC_MASK (0x03)
|
||||
#define ONENAND_BSC_MASK (0x07)
|
||||
|
||||
/*
|
||||
* Command Register F220h (R/W)
|
||||
@ -125,9 +133,14 @@
|
||||
#define ONENAND_CMD_ERASE_VERIFY (0x71)
|
||||
#define ONENAND_CMD_RESET (0xF0)
|
||||
#define ONENAND_CMD_READID (0x90)
|
||||
#define FLEXONENAND_CMD_RESET (0xF3)
|
||||
#define FLEXONENAND_CMD_PI_UPDATE (0x05)
|
||||
#define FLEXONENAND_CMD_PI_ACCESS (0x66)
|
||||
#define FLEXONENAND_CMD_RECOVER_LSB (0x05)
|
||||
|
||||
/* NOTE: Those are not *REAL* commands */
|
||||
#define ONENAND_CMD_BUFFERRAM (0x1978)
|
||||
#define FLEXONENAND_CMD_READ_PI (0x1985)
|
||||
|
||||
/*
|
||||
* System Configuration 1 Register F221h (R, R/W)
|
||||
@ -190,5 +203,6 @@
|
||||
#define ONENAND_ECC_2BIT (1 << 1)
|
||||
#define ONENAND_ECC_2BIT_ALL (0xAAAA)
|
||||
#define ONENAND_ECC_4BIT_UNCORRECTABLE (0x1010)
|
||||
#define FLEXONENAND_UNCORRECTABLE_ERROR (0x1010)
|
||||
|
||||
#endif /* __ONENAND_REG_H */
|
||||
|
@ -23,6 +23,7 @@ struct erase_info;
|
||||
struct onenand_chip;
|
||||
|
||||
extern struct mtd_info onenand_mtd;
|
||||
extern struct onenand_chip onenand_chip;
|
||||
|
||||
/* board */
|
||||
extern void onenand_board_init(struct mtd_info *);
|
||||
@ -38,6 +39,15 @@ extern int onenand_erase(struct mtd_info *mtd, struct erase_info *instr);
|
||||
|
||||
extern char *onenand_print_device_info(int device, int version);
|
||||
|
||||
extern unsigned onenand_block(struct onenand_chip *this, loff_t addr);
|
||||
|
||||
extern loff_t onenand_addr(struct onenand_chip *this, int block);
|
||||
|
||||
extern int flexonenand_region(struct mtd_info *mtd, loff_t addr);
|
||||
|
||||
extern int flexonenand_set_boundary(struct mtd_info *mtd, int die,
|
||||
int boundary, int lock);
|
||||
|
||||
/* S3C64xx */
|
||||
extern void s3c64xx_onenand_init(struct mtd_info *);
|
||||
extern void s3c64xx_set_width_regs(struct onenand_chip *);
|
||||
|
Loading…
Reference in New Issue
Block a user