S3C64XX support
PATCH 1/1 S3C64XX support
PLEASE DON'T COMMIT IT
Hi,
It's OneNAND support on New Samsung Mobile CPU S3C64XX series Now it's only tested with s3c6410 with UBI & UBIFS.
If you want to use it on s3c6400, you should change some values.
There's some ugly hack for support s3c64xx. It will be handled more fancy later.
Any comments are welcome
Thank you,
Kyungmin Park
---
drivers/mtd/onenand/Kconfig +6 -0
@@ -27,6 +27,12 @@ config MTD_ONENAND_GENERIC help Support for OneNAND flash via platform device driver. +config MTD_ONENAND_S3C64XX + tristate "S3C64XX OneNAND Controller support" + depends on CPU_S3C64XX + help + The S3C64XX has own OneNAND controller. + config MTD_ONENAND_OTP bool "OneNAND OTP Support" help
drivers/mtd/onenand/Makefile +1 -0
@@ -7,6 +7,7 @@ obj-$(CONFIG_MTD_ONENAND) += onenand.o # Board specific. obj-$(CONFIG_MTD_ONENAND_GENERIC) += generic.o +obj-$(CONFIG_MTD_ONENAND_S3C64XX) += s3c64xx.o # Simulator obj-$(CONFIG_MTD_ONENAND_SIM) += onenand_sim.o
drivers/mtd/onenand/onenand_base.c +26 -14
@@ -636,6 +636,9 @@ static int onenand_check_bufferram(struct mtd_info *mtd, loff_t addr)int blockpage, found =0 ;unsigned int i; +if (this->options &ONENAND_DONT_USE_BUFFERRAM ) +return 0 ; +if (ONENAND_IS_2PLANE (this)) blockpage =onenand_get_2x_blockpage (mtd, addr);else
@@ -832,7 +835,7 @@ static int onenand_read_ops_nolock(struct mtd_info *mtd, loff_t from,size_t ooblen = ops->ooblen;u_char *buf = ops->datbuf;u_char *oobbuf = ops->oobbuf; -int read =0 , column, thislen; +int read =0 , column, thislen, nextlen;int oobread =0 , oobcolumn, thisooblen, oobsize;int ret =0 , boundary =0 ;int writesize = this->writesize;
@@ -858,10 +861,16 @@ static int onenand_read_ops_nolock(struct mtd_info *mtd, loff_t from,/* Read-while-load method */ + thislen =min_t (int, writesize, len - read); + column = from & (writesize -1 ); +if (column + thislen > writesize) + thislen = writesize - column; +/* Do first load to bufferRAM */ if (read < len) {if (!onenand_check_bufferram (mtd, from)) { - this->command (mtd,ONENAND_CMD_READ , from, writesize); + this->main_buf = buf; + this->command (mtd,ONENAND_CMD_READ , from, thislen); ret = this->wait (mtd,FL_READING );onenand_update_bufferram (mtd, from, !ret);if (ret == -EBADMSG )
@@ -869,16 +878,13 @@ static int onenand_read_ops_nolock(struct mtd_info *mtd, loff_t from, } } - thislen =min_t (int, writesize, len - read); - column = from & (writesize -1 ); -if (column + thislen > writesize) - thislen = writesize - column; -while (!ret) {/* If there is more to load then start next load */ from += thislen;if (read + thislen < len) { - this->command (mtd,ONENAND_CMD_READ , from, writesize); + this->main_buf = buf + thislen; + nextlen =min_t (int, writesize, len - thislen - read); + this->command (mtd,ONENAND_CMD_READ , from, nextlen);/* * Chip boundary handling in DDP * Now we issued chip 1 read and pointed chip 1
@@ -999,6 +1005,7 @@ static int onenand_read_oob_nolock(struct mtd_info *mtd, loff_t from, thislen = oobsize - column; thislen =min_t (int, thislen, len); + this->spare_buf = buf; this->command (mtd,ONENAND_CMD_READOOB , from, mtd->oobsize);onenand_update_bufferram (mtd, from,0 );
@@ -1129,11 +1136,8 @@ static int onenand_bbt_wait(struct mtd_info *mtd, int state)if (interrupt &ONENAND_INT_READ ) {int ecc = this->read_word (this->base +ONENAND_REG_ECC_STATUS ); -if (ecc &ONENAND_ECC_2BIT_ALL ) { -printk (KERN_INFO "onenand_bbt_wait: ecc error = 0x%04x" -", controller error 0x%04x\n" , ecc, ctrl); +if (ecc &ONENAND_ECC_2BIT_ALL )return ONENAND_BBT_READ_ERROR ; - } }else {printk (KERN_ERR "onenand_bbt_wait: read timeout!" "ctrl=0x%04x intr=0x%04x\n" , ctrl, interrupt);
@@ -1189,11 +1193,12 @@ int onenand_bbt_read_oob(struct mtd_info *mtd, loff_t from, thislen = mtd->oobsize - column; thislen =min_t (int, thislen, len); + this->spare_buf = buf; this->command (mtd,ONENAND_CMD_READOOB , from, mtd->oobsize);onenand_update_bufferram (mtd, from,0 ); - ret =onenand_bbt_wait (mtd,FL_READING ); + ret = this->bbt_wait (mtd,FL_READING );if (ret)break ;
@@ -2116,6 +2121,9 @@ static void onenand_unlock_all(struct mtd_info *mtd) & ONENAND_CTRL_ONGO)continue ; +if (this->options &ONENAND_SKIP_UNLOCK_CHECK ) +return ; +/* Check lock status */ if (onenand_check_lock_status (this))return ;
@@ -2699,6 +2707,10 @@ int onenand_scan(struct mtd_info *mtd, int maxchips) this->command = onenand_command;if (!this->wait)onenand_setup_wait (mtd); +if (!this->bbt_wait) + this->bbt_wait = onenand_bbt_wait; +if (!this->unlock_all) + this->unlock_all = onenand_unlock_all;if (!this->read_bufferram) this->read_bufferram = onenand_read_bufferram;
@@ -2812,7 +2824,7 @@ int onenand_scan(struct mtd_info *mtd, int maxchips) mtd->owner =THIS_MODULE ;/* Unlock whole block */ -onenand_unlock_all (mtd); + this->unlock_all (mtd);return this->scan_bbt (mtd); }
drivers/mtd/onenand/s3c64xx.c new file +652 -0
652 lines not on this page · raw message
include/asm-arm/plat-s3c/s3c64xx-onenand.h new file +77 -0
77 lines not on this page · raw message
include/linux/mtd/onenand.h +7 -0
@@ -108,6 +108,8 @@ struct onenand_chip {int (*command)(struct mtd_info *mtd,int cmd,loff_t address,size_t len);int (*wait)(struct mtd_info *mtd,int state); +int (*bbt_wait)(struct mtd_info *mtd,int state); +void (*unlock_all)(struct mtd_info *mtd);int (*read_bufferram)(struct mtd_info *mtd,int area,unsigned char *buffer,int offset,size_t count); int (*write_bufferram)(struct mtd_info *mtd, int area,
@@ -121,6 +123,9 @@ struct onenand_chip {struct completion complete;int irq; +unsigned char *main_buf; +unsigned char *spare_buf; +spinlock_t chip_lock;wait_queue_head_t wq;onenand_state_t state;
@@ -169,6 +174,8 @@ struct onenand_chip {#define ONENAND_HAS_CONT_LOCK (0x0001)#define ONENAND_HAS_UNLOCK_ALL (0x0002)#define ONENAND_HAS_2PLANE (0x0004) +#define ONENAND_SKIP_UNLOCK_CHECK (0x0010) +#define ONENAND_DONT_USE_BUFFERRAM (0x0020)#define ONENAND_PAGEBUF_ALLOC (0x1000)#define ONENAND_OOBBUF_ALLOC (0x2000)
Quoted 6 lines · Kyungmin Park
It's OneNAND support on New Samsung Mobile CPU S3C64XX series Now it's only tested with s3c6410 with UBI & UBIFS. If you want to use it on s3c6400, you should change some values.
There's some ugly hack for support s3c64xx. It will be handled more fancy later.
Any comments are welcome
Why not just make it a separate driver and skip using onenand_base etc?
Quoted 6 lines · Adrian Hunter
Quoted 5 lines · Kyungmin Park
It's OneNAND support on New Samsung Mobile CPU S3C64XX series Now it's only tested with s3c6410 with UBI & UBIFS.
If you want to use it on s3c6400, you should change some values.
Quoted 7 lines
Quoted 4 lines
There's some ugly hack for support s3c64xx. It will be handled more fancy later.
Any comments are welcome
Why not just make it a separate driver and skip using
onenand_baseetc?
DId you see the s3c64xx OneNAND controller?. It has its own OneNAND controller and don't use the OneNAND memory access method as OMAP.
Yes it's possible to make an own OneNAND driver for s3c64xx, but maybe a half of codes are redundant except the access method so I want to use default onenand_base and just redefine the OneNAND function for s3c64xx.
Thank you,
Kyungmin Park
Quoted 14 lines · Kyungmin Park
Quoted 11 lines · Adrian Hunter
Quoted 8 lines · Kyungmin Park
It's OneNAND support on New Samsung Mobile CPU S3C64XX series Now it's only tested with s3c6410 with UBI & UBIFS.
If you want to use it on s3c6400, you should change some values.There's some ugly hack for support s3c64xx. It will be handled more fancy later.
Any comments are welcome
Why not just make it a separate driver and skip using
onenand_baseetc?
Quoted 7 lines
DId you see the s3c64xx OneNAND controller?. It has its own OneNAND controller and don't use the OneNAND memory access method as OMAP.
Yes it's possible to make an own OneNAND driver for s3c64xx, but maybe a half of codes are redundant except the access method so I want to use default
onenand_baseand just redefine the OneNAND function for s3c64xx.
I glanced at the code. It did not look like there was much code from onenand_base that was needed, so wouldn't it be cleaner to just copy those bits?