]> www.pilppa.org Git - linux-2.6-omap-h63xx.git/commitdiff
[MTD] OneNAND: Enhanced support for DDP (Dual Densitiy Packages)
authorKyungmin Park <kyungmin.park@samsung.com>
Thu, 29 Sep 2005 03:53:16 +0000 (04:53 +0100)
committerThomas Gleixner <tglx@mtd.linutronix.de>
Sun, 6 Nov 2005 21:59:48 +0000 (22:59 +0100)
Add density mask for better support of DDP chips.

Signed-off-by: Kyungmin Park <kyungmin.park@samsung.com>
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
drivers/mtd/onenand/onenand_base.c
include/linux/mtd/onenand.h

index a002d4025b2945771b7f85eda40882002d341be2..99de2f055eb13d4aff94b31504cd4f5d025278b0 100644 (file)
@@ -84,25 +84,23 @@ static void onenand_writew(unsigned short value, void __iomem *addr)
 
 /**
  * onenand_block_address - [DEFAULT] Get block address
- * @param device       the device id
+ * @param this         onenand chip data structure
  * @param block                the block
  * @return             translated block address if DDP, otherwise same
  *
  * Setup Start Address 1 Register (F100h)
  */
-static int onenand_block_address(int device, int block)
+static int onenand_block_address(struct onenand_chip *this, int block)
 {
-       if (device & ONENAND_DEVICE_IS_DDP) {
+       if (this->device_id & ONENAND_DEVICE_IS_DDP) {
                /* Device Flash Core select, NAND Flash Block Address */
-               int dfs = 0, density, mask;
+               int dfs = 0;
 
-               density = device >> ONENAND_DEVICE_DENSITY_SHIFT;
-               mask = (1 << (density + 6));
-
-               if (block & mask)
+               if (block & this->density_mask)
                        dfs = 1;
 
-               return (dfs << ONENAND_DDP_SHIFT) | (block & (mask - 1));
+               return (dfs << ONENAND_DDP_SHIFT) |
+                       (block & (this->density_mask - 1));
        }
 
        return block;
@@ -110,22 +108,19 @@ static int onenand_block_address(int device, int block)
 
 /**
  * onenand_bufferram_address - [DEFAULT] Get bufferram address
- * @param device       the device id
+ * @param this         onenand chip data structure
  * @param block                the block
  * @return             set DBS value if DDP, otherwise 0
  *
  * Setup Start Address 2 Register (F101h) for DDP
  */
-static int onenand_bufferram_address(int device, int block)
+static int onenand_bufferram_address(struct onenand_chip *this, int block)
 {
-       if (device & ONENAND_DEVICE_IS_DDP) {
+       if (this->device_id & ONENAND_DEVICE_IS_DDP) {
                /* Device BufferRAM Select */
-               int dbs = 0, density, mask;
-
-               density = device >> ONENAND_DEVICE_DENSITY_SHIFT;
-               mask = (1 << (density + 6));
+               int dbs = 0;
 
-               if (block & mask)
+               if (block & this->density_mask)
                        dbs = 1;
 
                return (dbs << ONENAND_DDP_SHIFT);
@@ -223,7 +218,7 @@ static int onenand_command(struct mtd_info *mtd, int cmd, loff_t addr, size_t le
        /* NOTE: The setting order of the registers is very important! */
        if (cmd == ONENAND_CMD_BUFFERRAM) {
                /* Select DataRAM for DDP */
-               value = onenand_bufferram_address(this->device_id, block);
+               value = onenand_bufferram_address(this, block);
                this->write_word(value, this->base + ONENAND_REG_START_ADDRESS2);
 
                /* Switch to the next data buffer */
@@ -234,7 +229,7 @@ static int onenand_command(struct mtd_info *mtd, int cmd, loff_t addr, size_t le
 
        if (block != -1) {
                /* Write 'DFS, FBA' of Flash */
-               value = onenand_block_address(this->device_id, block);
+               value = onenand_block_address(this, block);
                this->write_word(value, this->base + ONENAND_REG_START_ADDRESS1);
        }
 
@@ -263,7 +258,7 @@ static int onenand_command(struct mtd_info *mtd, int cmd, loff_t addr, size_t le
                        
                if (readcmd) {
                        /* Select DataRAM for DDP */
-                       value = onenand_bufferram_address(this->device_id, block);
+                       value = onenand_bufferram_address(this, block);
                        this->write_word(value, this->base + ONENAND_REG_START_ADDRESS2);
                }
        }
@@ -1313,7 +1308,7 @@ static int onenand_unlock(struct mtd_info *mtd, loff_t ofs, size_t len)
                        continue;
 
                /* Set block address for read block status */
-               value = onenand_block_address(this->device_id, block);
+               value = onenand_block_address(this, block);
                this->write_word(value, this->base + ONENAND_REG_START_ADDRESS1);
 
                /* Check lock status */
@@ -1415,6 +1410,8 @@ static int onenand_probe(struct mtd_info *mtd)
 
        density = dev_id >> ONENAND_DEVICE_DENSITY_SHIFT;
        this->chipsize = (16 << density) << 20;
+       /* Set density mask. it is used for DDP */
+       this->density_mask = (1 << (density + 6));
 
        /* OneNAND page size & block size */
        /* The data buffer size is equal to page size */
index afaa6342aa7f5ac9544b1b93ee9ace9c81fb7aed..d27fd12d096ddfd616bb016bd798f6af817d0f2f 100644 (file)
@@ -84,6 +84,7 @@ struct onenand_chip {
        void __iomem            *base;
        unsigned int            chipsize;
        unsigned int            device_id;
+       unsigned int            density_mask;
        unsigned int            options;
 
        unsigned int            erase_shift;