mirror of
https://github.com/brain-hackers/u-boot-brain
synced 2024-09-30 08:30:50 +09:00
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;
|
loff_t from;
|
||||||
size_t readlen, ooblen;
|
size_t readlen, ooblen;
|
||||||
struct mtd_oob_ops ops;
|
struct mtd_oob_ops ops;
|
||||||
|
int rgn;
|
||||||
|
|
||||||
printk(KERN_INFO "Scanning device for bad blocks\n");
|
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;
|
/* Note that numblocks is 2 * (real numblocks) here;
|
||||||
* see i += 2 below as it makses shifting and masking less painful
|
* 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;
|
startblock = 0;
|
||||||
from = 0;
|
from = 0;
|
||||||
|
|
||||||
@ -115,6 +116,11 @@ static int create_bbt(struct mtd_info *mtd, uint8_t * buf,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
i += 2;
|
i += 2;
|
||||||
|
|
||||||
|
if (FLEXONENAND(this)) {
|
||||||
|
rgn = flexonenand_region(mtd, from);
|
||||||
|
from += mtd->eraseregions[rgn].erasesize;
|
||||||
|
} else
|
||||||
from += (1 << bbm->bbt_erase_shift);
|
from += (1 << bbm->bbt_erase_shift);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -152,7 +158,7 @@ static int onenand_isbad_bbt(struct mtd_info *mtd, loff_t offs, int allowbbt)
|
|||||||
uint8_t res;
|
uint8_t res;
|
||||||
|
|
||||||
/* Get block number * 2 */
|
/* 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;
|
res = (bbm->bbt[block >> 3] >> (block & 0x06)) & 0x03;
|
||||||
|
|
||||||
MTDDEBUG (MTD_DEBUG_LEVEL2,
|
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;
|
struct bbm_info *bbm = this->bbm;
|
||||||
int len, ret = 0;
|
int len, ret = 0;
|
||||||
|
|
||||||
len = mtd->size >> (this->erase_shift + 2);
|
len = this->chipsize >> (this->erase_shift + 2);
|
||||||
/* Allocate memory (2bit per block) */
|
/* Allocate memory (2bit per block) */
|
||||||
bbm->bbt = malloc(len);
|
bbm->bbt = malloc(len);
|
||||||
if (!bbm->bbt) {
|
if (!bbm->bbt) {
|
||||||
|
@ -40,8 +40,10 @@ void onenand_init(void)
|
|||||||
|
|
||||||
onenand_scan(&onenand_mtd, 1);
|
onenand_scan(&onenand_mtd, 1);
|
||||||
|
|
||||||
|
if (onenand_chip.device_id & DEVICE_IS_FLEXONENAND)
|
||||||
|
puts("Flex-");
|
||||||
puts("OneNAND: ");
|
puts("OneNAND: ");
|
||||||
print_size(onenand_mtd.size, "\n");
|
print_size(onenand_chip.chipsize, "\n");
|
||||||
|
|
||||||
#ifdef CONFIG_MTD_DEVICE
|
#ifdef CONFIG_MTD_DEVICE
|
||||||
/*
|
/*
|
||||||
|
@ -20,8 +20,9 @@
|
|||||||
#include <linux/mtd/compat.h>
|
#include <linux/mtd/compat.h>
|
||||||
#include <linux/mtd/bbm.h>
|
#include <linux/mtd/bbm.h>
|
||||||
|
|
||||||
|
#define MAX_DIES 2
|
||||||
#define MAX_BUFFERRAM 2
|
#define MAX_BUFFERRAM 2
|
||||||
#define MAX_ONENAND_PAGESIZE (2048 + 64)
|
#define MAX_ONENAND_PAGESIZE (4096 + 128)
|
||||||
|
|
||||||
/* Scan and identify a OneNAND device */
|
/* Scan and identify a OneNAND device */
|
||||||
extern int onenand_scan (struct mtd_info *mtd, int max_chips);
|
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
|
* struct onenand_chip - OneNAND Private Flash Chip Data
|
||||||
* @param base [BOARDSPECIFIC] address to access OneNAND
|
* @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 chipsize [INTERN] the size of one chip for multichip arrays
|
||||||
* @param device_id [INTERN] device ID
|
* @param device_id [INTERN] device ID
|
||||||
* @param verstion_id [INTERN] version 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 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 erase_shift [INTERN] number of address bits in a block
|
||||||
* @param page_shift [INTERN] number of address bits in a page
|
* @param page_shift [INTERN] number of address bits in a page
|
||||||
@ -64,9 +70,13 @@ struct onenand_bufferram {
|
|||||||
*/
|
*/
|
||||||
struct onenand_chip {
|
struct onenand_chip {
|
||||||
void __iomem *base;
|
void __iomem *base;
|
||||||
|
unsigned int dies;
|
||||||
|
unsigned int boundary[MAX_DIES];
|
||||||
|
unsigned int diesize[MAX_DIES];
|
||||||
unsigned int chipsize;
|
unsigned int chipsize;
|
||||||
unsigned int device_id;
|
unsigned int device_id;
|
||||||
unsigned int version_id;
|
unsigned int version_id;
|
||||||
|
unsigned int technology;
|
||||||
unsigned int density_mask;
|
unsigned int density_mask;
|
||||||
unsigned int options;
|
unsigned int options;
|
||||||
|
|
||||||
@ -124,6 +134,8 @@ struct onenand_chip {
|
|||||||
#define ONENAND_SET_BUFFERRAM0(this) (this->bufferram_index = 0)
|
#define ONENAND_SET_BUFFERRAM0(this) (this->bufferram_index = 0)
|
||||||
#define ONENAND_SET_BUFFERRAM1(this) (this->bufferram_index = 1)
|
#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) \
|
#define ONENAND_IS_DDP(this) \
|
||||||
(this->device_id & ONENAND_DEVICE_IS_DDP)
|
(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,
|
int onenand_bbt_read_oob(struct mtd_info *mtd, loff_t from,
|
||||||
struct mtd_oob_ops *ops);
|
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 */
|
#endif /* __LINUX_MTD_ONENAND_H */
|
||||||
|
@ -67,6 +67,9 @@
|
|||||||
/*
|
/*
|
||||||
* Device ID Register F001h (R)
|
* 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_MASK (0xf)
|
||||||
#define ONENAND_DEVICE_DENSITY_SHIFT (4)
|
#define ONENAND_DEVICE_DENSITY_SHIFT (4)
|
||||||
#define ONENAND_DEVICE_IS_DDP (1 << 3)
|
#define ONENAND_DEVICE_IS_DDP (1 << 3)
|
||||||
@ -83,6 +86,11 @@
|
|||||||
*/
|
*/
|
||||||
#define ONENAND_VERSION_PROCESS_SHIFT (8)
|
#define ONENAND_VERSION_PROCESS_SHIFT (8)
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Technology Register F006h (R)
|
||||||
|
*/
|
||||||
|
#define ONENAND_TECHNOLOGY_IS_MLC (1 << 0)
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Start Address 1 F100h (R/W)
|
* Start Address 1 F100h (R/W)
|
||||||
*/
|
*/
|
||||||
@ -93,7 +101,7 @@
|
|||||||
/*
|
/*
|
||||||
* Start Address 8 F107h (R/W)
|
* Start Address 8 F107h (R/W)
|
||||||
*/
|
*/
|
||||||
#define ONENAND_FPA_MASK (0x3f)
|
#define ONENAND_FPA_MASK (0x7f)
|
||||||
#define ONENAND_FPA_SHIFT (2)
|
#define ONENAND_FPA_SHIFT (2)
|
||||||
#define ONENAND_FSA_MASK (0x03)
|
#define ONENAND_FSA_MASK (0x03)
|
||||||
|
|
||||||
@ -105,7 +113,7 @@
|
|||||||
#define ONENAND_BSA_BOOTRAM (0 << 2)
|
#define ONENAND_BSA_BOOTRAM (0 << 2)
|
||||||
#define ONENAND_BSA_DATARAM0 (2 << 2)
|
#define ONENAND_BSA_DATARAM0 (2 << 2)
|
||||||
#define ONENAND_BSA_DATARAM1 (3 << 2)
|
#define ONENAND_BSA_DATARAM1 (3 << 2)
|
||||||
#define ONENAND_BSC_MASK (0x03)
|
#define ONENAND_BSC_MASK (0x07)
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Command Register F220h (R/W)
|
* Command Register F220h (R/W)
|
||||||
@ -125,9 +133,14 @@
|
|||||||
#define ONENAND_CMD_ERASE_VERIFY (0x71)
|
#define ONENAND_CMD_ERASE_VERIFY (0x71)
|
||||||
#define ONENAND_CMD_RESET (0xF0)
|
#define ONENAND_CMD_RESET (0xF0)
|
||||||
#define ONENAND_CMD_READID (0x90)
|
#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 */
|
/* NOTE: Those are not *REAL* commands */
|
||||||
#define ONENAND_CMD_BUFFERRAM (0x1978)
|
#define ONENAND_CMD_BUFFERRAM (0x1978)
|
||||||
|
#define FLEXONENAND_CMD_READ_PI (0x1985)
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* System Configuration 1 Register F221h (R, R/W)
|
* System Configuration 1 Register F221h (R, R/W)
|
||||||
@ -190,5 +203,6 @@
|
|||||||
#define ONENAND_ECC_2BIT (1 << 1)
|
#define ONENAND_ECC_2BIT (1 << 1)
|
||||||
#define ONENAND_ECC_2BIT_ALL (0xAAAA)
|
#define ONENAND_ECC_2BIT_ALL (0xAAAA)
|
||||||
#define ONENAND_ECC_4BIT_UNCORRECTABLE (0x1010)
|
#define ONENAND_ECC_4BIT_UNCORRECTABLE (0x1010)
|
||||||
|
#define FLEXONENAND_UNCORRECTABLE_ERROR (0x1010)
|
||||||
|
|
||||||
#endif /* __ONENAND_REG_H */
|
#endif /* __ONENAND_REG_H */
|
||||||
|
@ -23,6 +23,7 @@ struct erase_info;
|
|||||||
struct onenand_chip;
|
struct onenand_chip;
|
||||||
|
|
||||||
extern struct mtd_info onenand_mtd;
|
extern struct mtd_info onenand_mtd;
|
||||||
|
extern struct onenand_chip onenand_chip;
|
||||||
|
|
||||||
/* board */
|
/* board */
|
||||||
extern void onenand_board_init(struct mtd_info *);
|
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 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 */
|
/* S3C64xx */
|
||||||
extern void s3c64xx_onenand_init(struct mtd_info *);
|
extern void s3c64xx_onenand_init(struct mtd_info *);
|
||||||
extern void s3c64xx_set_width_regs(struct onenand_chip *);
|
extern void s3c64xx_set_width_regs(struct onenand_chip *);
|
||||||
|
Loading…
Reference in New Issue
Block a user