Creation of Cybook 2416 (actually Gen4) repository
This commit is contained in:
46
drivers/mtd/onenand/Kconfig
Normal file
46
drivers/mtd/onenand/Kconfig
Normal file
@@ -0,0 +1,46 @@
|
||||
#
|
||||
# linux/drivers/mtd/onenand/Kconfig
|
||||
#
|
||||
|
||||
menu "OneNAND Flash Device Drivers"
|
||||
depends on MTD != n
|
||||
|
||||
config MTD_ONENAND
|
||||
tristate "OneNAND Device Support"
|
||||
depends on MTD
|
||||
help
|
||||
This enables support for accessing all type of OneNAND flash
|
||||
devices. For further information see
|
||||
<http://www.samsung.com/Products/Semiconductor/Flash/OneNAND_TM/index.htm>.
|
||||
|
||||
config MTD_ONENAND_VERIFY_WRITE
|
||||
bool "Verify OneNAND page writes"
|
||||
depends on MTD_ONENAND
|
||||
help
|
||||
This adds an extra check when data is written to the flash. The
|
||||
OneNAND flash device internally checks only bits transitioning
|
||||
from 1 to 0. There is a rare possibility that even though the
|
||||
device thinks the write was successful, a bit could have been
|
||||
flipped accidentally due to device wear or something else.
|
||||
|
||||
config MTD_ONENAND_GENERIC
|
||||
tristate "OneNAND Flash device via platform device driver"
|
||||
depends on MTD_ONENAND && ARM
|
||||
help
|
||||
Support for OneNAND flash via platform device driver.
|
||||
|
||||
config MTD_ONENAND_OTP
|
||||
bool "OneNAND OTP Support"
|
||||
depends on MTD_ONENAND
|
||||
help
|
||||
One Block of the NAND Flash Array memory is reserved as
|
||||
a One-Time Programmable Block memory area.
|
||||
Also, 1st Block of NAND Flash Array can be used as OTP.
|
||||
|
||||
The OTP block can be read, programmed and locked using the same
|
||||
operations as any other NAND Flash Array memory block.
|
||||
OTP block cannot be erased.
|
||||
|
||||
OTP block is fully-guaranteed to be a valid block.
|
||||
|
||||
endmenu
|
||||
17
drivers/mtd/onenand/Makefile
Normal file
17
drivers/mtd/onenand/Makefile
Normal file
@@ -0,0 +1,17 @@
|
||||
#
|
||||
# Makefile for the OneNAND MTD
|
||||
#
|
||||
|
||||
# Core functionality.
|
||||
obj-$(CONFIG_MTD_ONENAND) += onenand.o onenand_bbt.o
|
||||
|
||||
# Board specific.
|
||||
obj-$(CONFIG_MTD_ONENAND_GENERIC) += generic.o
|
||||
|
||||
ifeq ($(CONFIG_CPU_S3C6400),y)
|
||||
onenand-objs = s3c_onenand.o
|
||||
else ifeq ($(CONFIG_CPU_S3C6410),y)
|
||||
onenand-objs = s3c_onenand.o
|
||||
else
|
||||
onenand-objs = onenand_base.o
|
||||
endif
|
||||
149
drivers/mtd/onenand/generic.c
Normal file
149
drivers/mtd/onenand/generic.c
Normal file
@@ -0,0 +1,149 @@
|
||||
/*
|
||||
* linux/drivers/mtd/onenand/generic.c
|
||||
*
|
||||
* Copyright (c) 2005 Samsung Electronics
|
||||
* Kyungmin Park <kyungmin.park@samsung.com>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* Overview:
|
||||
* This is a device driver for the OneNAND flash for generic boards.
|
||||
*/
|
||||
|
||||
#include <linux/module.h>
|
||||
#include <linux/init.h>
|
||||
#include <linux/slab.h>
|
||||
#include <linux/platform_device.h>
|
||||
#include <linux/mtd/mtd.h>
|
||||
#include <linux/mtd/onenand.h>
|
||||
#include <linux/mtd/partitions.h>
|
||||
|
||||
#include <asm/io.h>
|
||||
#include <asm/mach/flash.h>
|
||||
|
||||
#define DRIVER_NAME "onenand"
|
||||
|
||||
|
||||
#ifdef CONFIG_MTD_PARTITIONS
|
||||
static const char *part_probes[] = { "cmdlinepart", NULL, };
|
||||
#endif
|
||||
|
||||
struct onenand_info {
|
||||
struct mtd_info mtd;
|
||||
struct mtd_partition *parts;
|
||||
struct onenand_chip onenand;
|
||||
};
|
||||
|
||||
static int __devinit generic_onenand_probe(struct device *dev)
|
||||
{
|
||||
struct onenand_info *info;
|
||||
struct platform_device *pdev = to_platform_device(dev);
|
||||
struct flash_platform_data *pdata = pdev->dev.platform_data;
|
||||
struct resource *res = pdev->resource;
|
||||
unsigned long size = res->end - res->start + 1;
|
||||
int err;
|
||||
|
||||
info = kzalloc(sizeof(struct onenand_info), GFP_KERNEL);
|
||||
if (!info)
|
||||
return -ENOMEM;
|
||||
|
||||
if (!request_mem_region(res->start, size, dev->driver->name)) {
|
||||
err = -EBUSY;
|
||||
goto out_free_info;
|
||||
}
|
||||
|
||||
info->onenand.base = ioremap(res->start, size);
|
||||
if (!info->onenand.base) {
|
||||
err = -ENOMEM;
|
||||
goto out_release_mem_region;
|
||||
}
|
||||
|
||||
#if !defined(CONFIG_CPU_S3C6400) && !defined(CONFIG_CPU_S3C6410)
|
||||
info->onenand.mmcontrol = pdata->mmcontrol;
|
||||
#endif
|
||||
info->onenand.irq = platform_get_irq(pdev, 0);
|
||||
|
||||
info->mtd.name = pdev->dev.bus_id;
|
||||
info->mtd.priv = &info->onenand;
|
||||
info->mtd.owner = THIS_MODULE;
|
||||
|
||||
if (onenand_scan(&info->mtd, 1)) {
|
||||
err = -ENXIO;
|
||||
goto out_iounmap;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_MTD_PARTITIONS
|
||||
err = parse_mtd_partitions(&info->mtd, part_probes, &info->parts, 0);
|
||||
if (err > 0)
|
||||
add_mtd_partitions(&info->mtd, info->parts, err);
|
||||
else if (err < 0 && pdata->parts)
|
||||
add_mtd_partitions(&info->mtd, pdata->parts, pdata->nr_parts);
|
||||
else
|
||||
#endif
|
||||
err = add_mtd_device(&info->mtd);
|
||||
|
||||
dev_set_drvdata(&pdev->dev, info);
|
||||
|
||||
return 0;
|
||||
|
||||
out_iounmap:
|
||||
iounmap(info->onenand.base);
|
||||
out_release_mem_region:
|
||||
release_mem_region(res->start, size);
|
||||
out_free_info:
|
||||
kfree(info);
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
static int __devexit generic_onenand_remove(struct device *dev)
|
||||
{
|
||||
struct platform_device *pdev = to_platform_device(dev);
|
||||
struct onenand_info *info = dev_get_drvdata(&pdev->dev);
|
||||
struct resource *res = pdev->resource;
|
||||
unsigned long size = res->end - res->start + 1;
|
||||
|
||||
dev_set_drvdata(&pdev->dev, NULL);
|
||||
|
||||
if (info) {
|
||||
if (info->parts)
|
||||
del_mtd_partitions(&info->mtd);
|
||||
else
|
||||
del_mtd_device(&info->mtd);
|
||||
|
||||
onenand_release(&info->mtd);
|
||||
release_mem_region(res->start, size);
|
||||
iounmap(info->onenand.base);
|
||||
kfree(info);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static struct device_driver generic_onenand_driver = {
|
||||
.name = DRIVER_NAME,
|
||||
.bus = &platform_bus_type,
|
||||
.probe = generic_onenand_probe,
|
||||
.remove = __devexit_p(generic_onenand_remove),
|
||||
};
|
||||
|
||||
MODULE_ALIAS(DRIVER_NAME);
|
||||
|
||||
static int __init generic_onenand_init(void)
|
||||
{
|
||||
return driver_register(&generic_onenand_driver);
|
||||
}
|
||||
|
||||
static void __exit generic_onenand_exit(void)
|
||||
{
|
||||
driver_unregister(&generic_onenand_driver);
|
||||
}
|
||||
|
||||
module_init(generic_onenand_init);
|
||||
module_exit(generic_onenand_exit);
|
||||
|
||||
MODULE_LICENSE("GPL");
|
||||
MODULE_AUTHOR("Kyungmin Park <kyungmin.park@samsung.com>");
|
||||
MODULE_DESCRIPTION("Glue layer for OneNAND flash on generic boards");
|
||||
2462
drivers/mtd/onenand/onenand_base.c
Normal file
2462
drivers/mtd/onenand/onenand_base.c
Normal file
File diff suppressed because it is too large
Load Diff
256
drivers/mtd/onenand/onenand_bbt.c
Normal file
256
drivers/mtd/onenand/onenand_bbt.c
Normal file
@@ -0,0 +1,256 @@
|
||||
/*
|
||||
* linux/drivers/mtd/onenand/onenand_bbt.c
|
||||
*
|
||||
* Bad Block Table support for the OneNAND driver
|
||||
*
|
||||
* Copyright(c) 2005 Samsung Electronics
|
||||
* Kyungmin Park <kyungmin.park@samsung.com>
|
||||
*
|
||||
* Derived from nand_bbt.c
|
||||
*
|
||||
* TODO:
|
||||
* Split BBT core and chip specific BBT.
|
||||
*/
|
||||
|
||||
#include <linux/slab.h>
|
||||
#include <linux/mtd/mtd.h>
|
||||
|
||||
#if defined(CONFIG_CPU_S3C6400) || defined(CONFIG_CPU_S3C6410)
|
||||
#include "s3c_onenand.h"
|
||||
#else
|
||||
#include <linux/mtd/onenand.h>
|
||||
#endif
|
||||
|
||||
#include <linux/mtd/compatmac.h>
|
||||
|
||||
extern int onenand_bbt_read_oob(struct mtd_info *mtd, loff_t from,
|
||||
struct mtd_oob_ops *ops);
|
||||
|
||||
/**
|
||||
* check_short_pattern - [GENERIC] check if a pattern is in the buffer
|
||||
* @param buf the buffer to search
|
||||
* @param len the length of buffer to search
|
||||
* @param paglen the pagelength
|
||||
* @param td search pattern descriptor
|
||||
*
|
||||
* Check for a pattern at the given place. Used to search bad block
|
||||
* tables and good / bad block identifiers. Same as check_pattern, but
|
||||
* no optional empty check and the pattern is expected to start
|
||||
* at offset 0.
|
||||
*
|
||||
*/
|
||||
static int check_short_pattern(uint8_t *buf, int len, int paglen, struct nand_bbt_descr *td)
|
||||
{
|
||||
int i;
|
||||
uint8_t *p = buf;
|
||||
|
||||
/* Compare the pattern */
|
||||
for (i = 0; i < td->len; i++) {
|
||||
if (p[i] != td->pattern[i])
|
||||
return -1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* create_bbt - [GENERIC] Create a bad block table by scanning the device
|
||||
* @param mtd MTD device structure
|
||||
* @param buf temporary buffer
|
||||
* @param bd descriptor for the good/bad block search pattern
|
||||
* @param chip create the table for a specific chip, -1 read all chips.
|
||||
* Applies only if NAND_BBT_PERCHIP option is set
|
||||
*
|
||||
* Create a bad block table by scanning the device
|
||||
* for the given good/bad block identify pattern
|
||||
*/
|
||||
static int create_bbt(struct mtd_info *mtd, uint8_t *buf, struct nand_bbt_descr *bd, int chip)
|
||||
{
|
||||
struct onenand_chip *this = mtd->priv;
|
||||
struct bbm_info *bbm = this->bbm;
|
||||
int i, j, numblocks, len, scanlen;
|
||||
int startblock;
|
||||
loff_t from;
|
||||
size_t readlen, ooblen;
|
||||
struct mtd_oob_ops ops;
|
||||
|
||||
printk(KERN_INFO "Scanning device for bad blocks\n");
|
||||
|
||||
len = 2;
|
||||
|
||||
/* We need only read few bytes from the OOB area */
|
||||
scanlen = ooblen = 0;
|
||||
readlen = bd->len;
|
||||
|
||||
/* chip == -1 case only */
|
||||
/* 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);
|
||||
startblock = 0;
|
||||
from = 0;
|
||||
|
||||
ops.mode = MTD_OOB_PLACE;
|
||||
ops.ooblen = readlen;
|
||||
ops.oobbuf = buf;
|
||||
ops.len = ops.ooboffs = ops.retlen = ops.oobretlen = 0;
|
||||
|
||||
for (i = startblock; i < numblocks; ) {
|
||||
int ret;
|
||||
|
||||
for (j = 0; j < len; j++) {
|
||||
/* No need to read pages fully,
|
||||
* just read required OOB bytes */
|
||||
ret = onenand_bbt_read_oob(mtd, from + j * mtd->writesize + bd->offs, &ops);
|
||||
|
||||
/* If it is a initial bad block, just ignore it */
|
||||
if (ret == ONENAND_BBT_READ_FATAL_ERROR)
|
||||
return -EIO;
|
||||
|
||||
if (ret || check_short_pattern(&buf[j * scanlen], scanlen, mtd->writesize, bd)) {
|
||||
bbm->bbt[i >> 3] |= 0x03 << (i & 0x6);
|
||||
printk(KERN_WARNING "Bad eraseblock %d at 0x%08x\n",
|
||||
i >> 1, (unsigned int) from);
|
||||
mtd->ecc_stats.badblocks++;
|
||||
break;
|
||||
}
|
||||
}
|
||||
i += 2;
|
||||
from += (1 << bbm->bbt_erase_shift);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* onenand_memory_bbt - [GENERIC] create a memory based bad block table
|
||||
* @param mtd MTD device structure
|
||||
* @param bd descriptor for the good/bad block search pattern
|
||||
*
|
||||
* The function creates a memory based bbt by scanning the device
|
||||
* for manufacturer / software marked good / bad blocks
|
||||
*/
|
||||
static inline int onenand_memory_bbt (struct mtd_info *mtd, struct nand_bbt_descr *bd)
|
||||
{
|
||||
struct onenand_chip *this = mtd->priv;
|
||||
|
||||
bd->options &= ~NAND_BBT_SCANEMPTY;
|
||||
return create_bbt(mtd, this->page_buf, bd, -1);
|
||||
}
|
||||
|
||||
/**
|
||||
* onenand_isbad_bbt - [OneNAND Interface] Check if a block is bad
|
||||
* @param mtd MTD device structure
|
||||
* @param offs offset in the device
|
||||
* @param allowbbt allow access to bad block table region
|
||||
*/
|
||||
static int onenand_isbad_bbt(struct mtd_info *mtd, loff_t offs, int allowbbt)
|
||||
{
|
||||
struct onenand_chip *this = mtd->priv;
|
||||
struct bbm_info *bbm = this->bbm;
|
||||
int block;
|
||||
uint8_t res;
|
||||
|
||||
/* Get block number * 2 */
|
||||
block = (int) (offs >> (bbm->bbt_erase_shift - 1));
|
||||
res = (bbm->bbt[block >> 3] >> (block & 0x06)) & 0x03;
|
||||
|
||||
DEBUG(MTD_DEBUG_LEVEL2, "onenand_isbad_bbt: bbt info for offs 0x%08x: (block %d) 0x%02x\n",
|
||||
(unsigned int) offs, block >> 1, res);
|
||||
|
||||
switch ((int) res) {
|
||||
case 0x00: return 0;
|
||||
case 0x01: return 1;
|
||||
case 0x02: return allowbbt ? 0 : 1;
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
/**
|
||||
* onenand_scan_bbt - [OneNAND Interface] scan, find, read and maybe create bad block table(s)
|
||||
* @param mtd MTD device structure
|
||||
* @param bd descriptor for the good/bad block search pattern
|
||||
*
|
||||
* The function checks, if a bad block table(s) is/are already
|
||||
* available. If not it scans the device for manufacturer
|
||||
* marked good / bad blocks and writes the bad block table(s) to
|
||||
* the selected place.
|
||||
*
|
||||
* The bad block table memory is allocated here. It is freed
|
||||
* by the onenand_release function.
|
||||
*
|
||||
*/
|
||||
int onenand_scan_bbt(struct mtd_info *mtd, struct nand_bbt_descr *bd)
|
||||
{
|
||||
struct onenand_chip *this = mtd->priv;
|
||||
struct bbm_info *bbm = this->bbm;
|
||||
int len, ret = 0;
|
||||
|
||||
len = mtd->size >> (this->erase_shift + 2);
|
||||
/* Allocate memory (2bit per block) and clear the memory bad block table */
|
||||
bbm->bbt = kzalloc(len, GFP_KERNEL);
|
||||
if (!bbm->bbt) {
|
||||
printk(KERN_ERR "onenand_scan_bbt: Out of memory\n");
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
/* Set the bad block position */
|
||||
bbm->badblockpos = ONENAND_BADBLOCK_POS;
|
||||
|
||||
/* Set erase shift */
|
||||
bbm->bbt_erase_shift = this->erase_shift;
|
||||
|
||||
if (!bbm->isbad_bbt)
|
||||
bbm->isbad_bbt = onenand_isbad_bbt;
|
||||
|
||||
/* Scan the device to build a memory based bad block table */
|
||||
if ((ret = onenand_memory_bbt(mtd, bd))) {
|
||||
printk(KERN_ERR "onenand_scan_bbt: Can't scan flash and build the RAM-based BBT\n");
|
||||
kfree(bbm->bbt);
|
||||
bbm->bbt = NULL;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/*
|
||||
* Define some generic bad / good block scan pattern which are used
|
||||
* while scanning a device for factory marked good / bad blocks.
|
||||
*/
|
||||
static uint8_t scan_ff_pattern[] = { 0xff, 0xff };
|
||||
|
||||
static struct nand_bbt_descr largepage_memorybased = {
|
||||
.options = 0,
|
||||
.offs = 0,
|
||||
.len = 2,
|
||||
.pattern = scan_ff_pattern,
|
||||
};
|
||||
|
||||
/**
|
||||
* onenand_default_bbt - [OneNAND Interface] Select a default bad block table for the device
|
||||
* @param mtd MTD device structure
|
||||
*
|
||||
* This function selects the default bad block table
|
||||
* support for the device and calls the onenand_scan_bbt function
|
||||
*/
|
||||
int onenand_default_bbt(struct mtd_info *mtd)
|
||||
{
|
||||
struct onenand_chip *this = mtd->priv;
|
||||
struct bbm_info *bbm;
|
||||
|
||||
this->bbm = kzalloc(sizeof(struct bbm_info), GFP_KERNEL);
|
||||
if (!this->bbm)
|
||||
return -ENOMEM;
|
||||
|
||||
bbm = this->bbm;
|
||||
|
||||
/* 1KB page has same configuration as 2KB page */
|
||||
if (!bbm->badblock_pattern)
|
||||
bbm->badblock_pattern = &largepage_memorybased;
|
||||
|
||||
return onenand_scan_bbt(mtd, bbm->badblock_pattern);
|
||||
}
|
||||
|
||||
EXPORT_SYMBOL(onenand_scan_bbt);
|
||||
EXPORT_SYMBOL(onenand_default_bbt);
|
||||
2625
drivers/mtd/onenand/s3c_onenand.c
Normal file
2625
drivers/mtd/onenand/s3c_onenand.c
Normal file
File diff suppressed because it is too large
Load Diff
158
drivers/mtd/onenand/s3c_onenand.h
Normal file
158
drivers/mtd/onenand/s3c_onenand.h
Normal file
@@ -0,0 +1,158 @@
|
||||
#ifndef __LINUX_MTD_S3C_ONENAND_H
|
||||
#define __LINUX_MTD_S3C_ONENAND_H
|
||||
|
||||
#include <linux/spinlock.h>
|
||||
#include <linux/completion.h>
|
||||
#include <asm/arch/regs-onenand.h>
|
||||
#include <linux/mtd/bbm.h>
|
||||
#include <asm/dma.h>
|
||||
#include <asm/arch/dma.h>
|
||||
|
||||
#define MAX_BUFFERRAM 2
|
||||
|
||||
/* Scan and identify a OneNAND device */
|
||||
extern int onenand_scan(struct mtd_info *mtd, int max_chips);
|
||||
/* Free resources held by the OneNAND device */
|
||||
extern void onenand_release(struct mtd_info *mtd);
|
||||
|
||||
/*
|
||||
* onenand_state_t - chip states
|
||||
* Enumeration for OneNAND flash chip state
|
||||
*/
|
||||
typedef enum {
|
||||
FL_READY,
|
||||
FL_READING,
|
||||
FL_WRITING,
|
||||
FL_ERASING,
|
||||
FL_SYNCING,
|
||||
FL_LOCKING,
|
||||
FL_RESETING,
|
||||
FL_OTPING,
|
||||
FL_PM_SUSPENDED,
|
||||
} onenand_state_t;
|
||||
|
||||
/**
|
||||
* struct onenand_bufferram - OneNAND BufferRAM Data
|
||||
* @block: block address in BufferRAM
|
||||
* @page: page address in BufferRAM
|
||||
* @valid: valid flag
|
||||
*/
|
||||
struct onenand_bufferram {
|
||||
int block;
|
||||
int page;
|
||||
int valid;
|
||||
};
|
||||
|
||||
/**
|
||||
* struct onenand_chip - OneNAND Private Flash Chip Data
|
||||
* @base: [BOARDSPECIFIC] address to access OneNAND
|
||||
* @chipsize: [INTERN] the size of one chip for multichip arrays
|
||||
* @device_id: [INTERN] device ID
|
||||
* @density_mask: chip density, used for DDP devices
|
||||
* @verstion_id: [INTERN] version ID
|
||||
* @options: [BOARDSPECIFIC] various chip options. They can
|
||||
* partly be set to inform onenand_scan about
|
||||
* @erase_shift: [INTERN] number of address bits in a block
|
||||
* @page_shift: [INTERN] number of address bits in a page
|
||||
* @page_mask: [INTERN] a page per block mask
|
||||
* @bufferram_index: [INTERN] BufferRAM index
|
||||
* @bufferram: [INTERN] BufferRAM info
|
||||
* @readw: [REPLACEABLE] hardware specific function for read short
|
||||
* @writew: [REPLACEABLE] hardware specific function for write short
|
||||
* @command: [REPLACEABLE] hardware specific function for writing
|
||||
* commands to the chip
|
||||
* @wait: [REPLACEABLE] hardware specific function for wait on ready
|
||||
* @read_bufferram: [REPLACEABLE] hardware specific function for BufferRAM Area
|
||||
* @write_bufferram: [REPLACEABLE] hardware specific function for BufferRAM Area
|
||||
* @read_word: [REPLACEABLE] hardware specific function for read
|
||||
* register of OneNAND
|
||||
* @write_word: [REPLACEABLE] hardware specific function for write
|
||||
* register of OneNAND
|
||||
* @mmcontrol: sync burst read function
|
||||
* @block_markbad: function to mark a block as bad
|
||||
* @scan_bbt: [REPLACEALBE] hardware specific function for scanning
|
||||
* Bad block Table
|
||||
* @chip_lock: [INTERN] spinlock used to protect access to this
|
||||
* structure and the chip
|
||||
* @wq: [INTERN] wait queue to sleep on if a OneNAND
|
||||
* operation is in progress
|
||||
* @state: [INTERN] the current state of the OneNAND device
|
||||
* @page_buf: data buffer
|
||||
* @subpagesize: [INTERN] holds the subpagesize
|
||||
* @ecclayout: [REPLACEABLE] the default ecc placement scheme
|
||||
* @bbm: [REPLACEABLE] pointer to Bad Block Management
|
||||
* @priv: [OPTIONAL] pointer to private chip date
|
||||
*/
|
||||
struct onenand_chip {
|
||||
void __iomem *base; /* SFR base address (0x7010_0000 ~) */
|
||||
void __iomem *dev_base; /* virtual address base for AHB Port Address (0x2000_0000 ~ 0x20FF_FFFF) */
|
||||
unsigned int chipsize;
|
||||
unsigned int device_id;
|
||||
unsigned int version_id;
|
||||
unsigned int density_mask;
|
||||
unsigned int options;
|
||||
|
||||
unsigned int erase_shift;
|
||||
unsigned int page_shift;
|
||||
unsigned int page_mask;
|
||||
|
||||
unsigned int bufferram_index;
|
||||
struct onenand_bufferram bufferram[MAX_BUFFERRAM];
|
||||
|
||||
uint (*command)(struct mtd_info *mtd, int cmd, loff_t address);
|
||||
unsigned int (*read)(void __iomem *addr);
|
||||
void (*write)(unsigned int value, void __iomem *addr);
|
||||
int (*block_markbad)(struct mtd_info *mtd, loff_t ofs);
|
||||
int (*scan_bbt)(struct mtd_info *mtd);
|
||||
|
||||
int irq;
|
||||
|
||||
spinlock_t chip_lock;
|
||||
wait_queue_head_t wq;
|
||||
onenand_state_t state;
|
||||
|
||||
unsigned char *page_buf;
|
||||
unsigned char *oob_buf;
|
||||
|
||||
int subpagesize;
|
||||
struct nand_ecclayout *ecclayout;
|
||||
|
||||
void *bbm;
|
||||
void *priv;
|
||||
|
||||
int dma;
|
||||
unsigned int dma_ch;
|
||||
void *done; /* completion */
|
||||
};
|
||||
|
||||
/*
|
||||
* Options bits
|
||||
*/
|
||||
#define ONENAND_HAS_CONT_LOCK (0x0001)
|
||||
#define ONENAND_HAS_UNLOCK_ALL (0x0002)
|
||||
#define ONENAND_CHECK_BAD (0x0004)
|
||||
#define ONENAND_READ_POLLING (0x0010)
|
||||
#define ONENAND_READ_BURST (0x0020)
|
||||
#define ONENAND_READ_DMA (0x0040)
|
||||
#define ONENAND_PIPELINE_AHEAD (0x0100)
|
||||
#define ONENAND_READ_MASK (0x00F0)
|
||||
#define ONENAND_PAGEBUF_ALLOC (0x1000)
|
||||
#define ONENAND_OOBBUF_ALLOC (0x2000)
|
||||
|
||||
/*
|
||||
* OneNAND Flash Manufacturer ID Codes
|
||||
*/
|
||||
#define ONENAND_MFR_SAMSUNG 0xec
|
||||
|
||||
/**
|
||||
* struct onenand_manufacturers - NAND Flash Manufacturer ID Structure
|
||||
* @name: Manufacturer name
|
||||
* @id: manufacturer ID code of device.
|
||||
*/
|
||||
struct onenand_manufacturers {
|
||||
int id;
|
||||
char *name;
|
||||
};
|
||||
|
||||
#endif /* __LINUX_MTD_ONENAND_H */
|
||||
|
||||
Reference in New Issue
Block a user