]> git.sur5r.net Git - openocd/blobdiff - src/flash/nand/davinci.c
Remove FSF address from GPL notices
[openocd] / src / flash / nand / davinci.c
index 96cbfeae75b23ce09a9f106956872932ebe62491..17e6f680da4dc7f7442e92bb6ea8092c64471a85 100644 (file)
@@ -12,9 +12,7 @@
  *   GNU General Public License for more details.                          *
  *                                                                         *
  *   You should have received a copy of the GNU General Public License     *
- *   along with this program; if not, write to the                         *
- *   Free Software Foundation, Inc.,                                       *
- *   59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
+ *   along with this program.  If not, see <http://www.gnu.org/licenses/>. *
  ***************************************************************************/
 
 /*
@@ -39,36 +37,34 @@ enum ecc {
 };
 
 struct davinci_nand {
-       struct target   *target;
-
-       uint8_t         chipsel;        /* chipselect 0..3 == CS2..CS5 */
-       uint8_t         eccmode;
+       uint8_t chipsel;                /* chipselect 0..3 == CS2..CS5 */
+       uint8_t eccmode;
 
        /* Async EMIF controller base */
-       uint32_t                aemif;
+       uint32_t aemif;
 
        /* NAND chip addresses */
-       uint32_t                data;           /* without CLE or ALE */
-       uint32_t                cmd;            /* with CLE */
-       uint32_t                addr;           /* with ALE */
+       uint32_t data;                          /* without CLE or ALE */
+       uint32_t cmd;                           /* with CLE */
+       uint32_t addr;                          /* with ALE */
 
        /* write acceleration */
-       struct arm_nand_data    io;
+       struct arm_nand_data io;
 
        /* page i/o for the relevant flavor of hardware ECC */
        int (*read_page)(struct nand_device *nand, uint32_t page,
-                       uint8_t *data, uint32_t data_size, uint8_t *oob, uint32_t oob_size);
+                        uint8_t *data, uint32_t data_size, uint8_t *oob, uint32_t oob_size);
        int (*write_page)(struct nand_device *nand, uint32_t page,
-                       uint8_t *data, uint32_t data_size, uint8_t *oob, uint32_t oob_size);
+                         uint8_t *data, uint32_t data_size, uint8_t *oob, uint32_t oob_size);
 };
 
-#define NANDFCR                0x60            /* flash control register */
-#define NANDFSR                0x64            /* flash status register */
-#define NANDFECC       0x70            /* 1-bit ECC data, CS0, 1st of 4 */
-#define NAND4BITECCLOAD        0xbc            /* 4-bit ECC, load saved values */
-#define NAND4BITECC    0xc0            /* 4-bit ECC data, 1st of 4 */
-#define NANDERRADDR    0xd0            /* 4-bit ECC err addr, 1st of 2 */
-#define NANDERRVAL     0xd8            /* 4-bit ECC err value, 1st of 2 */
+#define NANDFCR         0x60           /* flash control register */
+#define NANDFSR         0x64           /* flash status register */
+#define NANDFECC        0x70           /* 1-bit ECC data, CS0, 1st of 4 */
+#define NAND4BITECCLOAD 0xbc           /* 4-bit ECC, load saved values */
+#define NAND4BITECC     0xc0           /* 4-bit ECC data, 1st of 4 */
+#define NANDERRADDR     0xd0           /* 4-bit ECC err addr, 1st of 2 */
+#define NANDERRVAL      0xd8           /* 4-bit ECC err value, 1st of 2 */
 
 static int halted(struct target *target, const char *label)
 {
@@ -82,7 +78,7 @@ static int halted(struct target *target, const char *label)
 static int davinci_init(struct nand_device *nand)
 {
        struct davinci_nand *info = nand->controller_priv;
-       struct target *target = info->target;
+       struct target *target = nand->target;
        uint32_t nandfcr;
 
        if (!halted(target, "init"))
@@ -112,7 +108,7 @@ static int davinci_reset(struct nand_device *nand)
 static int davinci_nand_ready(struct nand_device *nand, int timeout)
 {
        struct davinci_nand *info = nand->controller_priv;
-       struct target *target = info->target;
+       struct target *target = nand->target;
        uint32_t nandfsr;
 
        /* NOTE: return code is zero/error, else success; not ERROR_* */
@@ -135,7 +131,7 @@ static int davinci_nand_ready(struct nand_device *nand, int timeout)
 static int davinci_command(struct nand_device *nand, uint8_t command)
 {
        struct davinci_nand *info = nand->controller_priv;
-       struct target *target = info->target;
+       struct target *target = nand->target;
 
        if (!halted(target, "command"))
                return ERROR_NAND_OPERATION_FAILED;
@@ -147,7 +143,7 @@ static int davinci_command(struct nand_device *nand, uint8_t command)
 static int davinci_address(struct nand_device *nand, uint8_t address)
 {
        struct davinci_nand *info = nand->controller_priv;
-       struct target *target = info->target;
+       struct target *target = nand->target;
 
        if (!halted(target, "address"))
                return ERROR_NAND_OPERATION_FAILED;
@@ -159,7 +155,7 @@ static int davinci_address(struct nand_device *nand, uint8_t address)
 static int davinci_write_data(struct nand_device *nand, uint16_t data)
 {
        struct davinci_nand *info = nand->controller_priv;
-       struct target *target = info->target;
+       struct target *target = nand->target;
 
        if (!halted(target, "write_data"))
                return ERROR_NAND_OPERATION_FAILED;
@@ -171,7 +167,7 @@ static int davinci_write_data(struct nand_device *nand, uint16_t data)
 static int davinci_read_data(struct nand_device *nand, void *data)
 {
        struct davinci_nand *info = nand->controller_priv;
-       struct target *target = info->target;
+       struct target *target = nand->target;
 
        if (!halted(target, "read_data"))
                return ERROR_NAND_OPERATION_FAILED;
@@ -183,10 +179,10 @@ static int davinci_read_data(struct nand_device *nand, void *data)
 /* REVISIT a bit of native code should let block reads be MUCH faster */
 
 static int davinci_read_block_data(struct nand_device *nand,
-               uint8_t *data, int data_size)
+       uint8_t *data, int data_size)
 {
        struct davinci_nand *info = nand->controller_priv;
-       struct target *target = info->target;
+       struct target *target = nand->target;
        uint32_t nfdata = info->data;
        uint32_t tmp;
 
@@ -216,10 +212,10 @@ static int davinci_read_block_data(struct nand_device *nand,
 }
 
 static int davinci_write_block_data(struct nand_device *nand,
-               uint8_t *data, int data_size)
+       uint8_t *data, int data_size)
 {
        struct davinci_nand *info = nand->controller_priv;
-       struct target *target = info->target;
+       struct target *target = nand->target;
        uint32_t nfdata = info->data;
        uint32_t tmp;
        int status;
@@ -252,7 +248,7 @@ static int davinci_write_block_data(struct nand_device *nand,
 }
 
 static int davinci_write_page(struct nand_device *nand, uint32_t page,
-               uint8_t *data, uint32_t data_size, uint8_t *oob, uint32_t oob_size)
+       uint8_t *data, uint32_t data_size, uint8_t *oob, uint32_t oob_size)
 {
        struct davinci_nand *info = nand->controller_priv;
        uint8_t *ooballoc = NULL;
@@ -260,28 +256,28 @@ static int davinci_write_page(struct nand_device *nand, uint32_t page,
 
        if (!nand->device)
                return ERROR_NAND_DEVICE_NOT_PROBED;
-       if (!halted(info->target, "write_page"))
+       if (!halted(nand->target, "write_page"))
                return ERROR_NAND_OPERATION_FAILED;
 
        /* Always write both data and OOB ... we are not "raw" I/O! */
        if (!data) {
-               LOG_ERROR("Missing NAND data; try 'nand raw_access enable'\n");
+               LOG_ERROR("Missing NAND data; try 'nand raw_access enable'");
                return ERROR_NAND_OPERATION_FAILED;
        }
 
        /* If we're not given OOB, write 0xff where we don't write ECC codes. */
        switch (nand->page_size) {
-       case 512:
-               oob_size = 16;
-               break;
-       case 2048:
-               oob_size = 64;
-               break;
-       case 4096:
-               oob_size = 128;
-               break;
-       default:
-               return ERROR_NAND_OPERATION_FAILED;
+               case 512:
+                       oob_size = 16;
+                       break;
+               case 2048:
+                       oob_size = 64;
+                       break;
+               case 4096:
+                       oob_size = 128;
+                       break;
+               default:
+                       return ERROR_NAND_OPERATION_FAILED;
        }
        if (!oob) {
                ooballoc = malloc(oob_size);
@@ -303,13 +299,13 @@ static int davinci_write_page(struct nand_device *nand, uint32_t page,
 }
 
 static int davinci_read_page(struct nand_device *nand, uint32_t page,
-               uint8_t *data, uint32_t data_size, uint8_t *oob, uint32_t oob_size)
+       uint8_t *data, uint32_t data_size, uint8_t *oob, uint32_t oob_size)
 {
        struct davinci_nand *info = nand->controller_priv;
 
        if (!nand->device)
                return ERROR_NAND_DEVICE_NOT_PROBED;
-       if (!halted(info->target, "read_page"))
+       if (!halted(nand->target, "read_page"))
                return ERROR_NAND_OPERATION_FAILED;
 
        return info->read_page(nand, page, data, data_size, oob, oob_size);
@@ -318,7 +314,7 @@ static int davinci_read_page(struct nand_device *nand, uint32_t page,
 static void davinci_write_pagecmd(struct nand_device *nand, uint8_t cmd, uint32_t page)
 {
        struct davinci_nand *info = nand->controller_priv;
-       struct target *target = info->target;
+       struct target *target = nand->target;
        int page3 = nand->address_cycles - (nand->page_size == 512);
 
        /* write command ({page,otp}x{read,program} */
@@ -338,11 +334,32 @@ static void davinci_write_pagecmd(struct nand_device *nand, uint8_t cmd, uint32_
                target_write_u8(target, info->addr, page >> 24);
 }
 
+static int davinci_seek_column(struct nand_device *nand, uint16_t column)
+{
+       struct davinci_nand *info = nand->controller_priv;
+       struct target *target = nand->target;
+
+       /* Random read, we must have issued a page read already */
+       target_write_u8(target, info->cmd, NAND_CMD_RNDOUT);
+
+       target_write_u8(target, info->addr, column);
+
+       if (nand->page_size > 512) {
+               target_write_u8(target, info->addr, column >> 8);
+               target_write_u8(target, info->cmd, NAND_CMD_RNDOUTSTART);
+       }
+
+       if (!davinci_nand_ready(nand, 100))
+               return ERROR_NAND_OPERATION_TIMEOUT;
+
+       return ERROR_OK;
+}
+
 static int davinci_writepage_tail(struct nand_device *nand,
-               uint8_t *oob, uint32_t oob_size)
+       uint8_t *oob, uint32_t oob_size)
 {
        struct davinci_nand *info = nand->controller_priv;
-       struct target *target = info->target;
+       struct target *target = nand->target;
        uint8_t status;
 
        if (oob_size)
@@ -371,11 +388,11 @@ static int davinci_writepage_tail(struct nand_device *nand,
  * All DaVinci family chips support 1-bit ECC on a per-chipselect basis.
  */
 static int davinci_write_page_ecc1(struct nand_device *nand, uint32_t page,
-               uint8_t *data, uint32_t data_size, uint8_t *oob, uint32_t oob_size)
+       uint8_t *data, uint32_t data_size, uint8_t *oob, uint32_t oob_size)
 {
        unsigned oob_offset;
        struct davinci_nand *info = nand->controller_priv;
-       struct target *target = info->target;
+       struct target *target = nand->target;
        const uint32_t fcr_addr = info->aemif + NANDFCR;
        const uint32_t ecc1_addr = info->aemif + NANDFECC + (4 * info->chipsel);
        uint32_t fcr, ecc1;
@@ -385,15 +402,15 @@ static int davinci_write_page_ecc1(struct nand_device *nand, uint32_t page,
         * for 16-bit OOB, those extra bytes are discontiguous.
         */
        switch (nand->page_size) {
-       case 512:
-               oob_offset = 0;
-               break;
-       case 2048:
-               oob_offset = 40;
-               break;
-       default:
-               oob_offset = 80;
-               break;
+               case 512:
+                       oob_offset = 0;
+                       break;
+               case 2048:
+                       oob_offset = 40;
+                       break;
+               default:
+                       oob_offset = 80;
+                       break;
        }
 
        davinci_write_pagecmd(nand, NAND_CMD_SEQIN, page);
@@ -438,10 +455,10 @@ static int davinci_write_page_ecc1(struct nand_device *nand, uint32_t page,
  * manufacturer bad block markers are safe.  Contrast:  old "infix" style.
  */
 static int davinci_write_page_ecc4(struct nand_device *nand, uint32_t page,
-               uint8_t *data, uint32_t data_size, uint8_t *oob, uint32_t oob_size)
+       uint8_t *data, uint32_t data_size, uint8_t *oob, uint32_t oob_size)
 {
        static const uint8_t ecc512[] = {
-               0, 1, 2, 3, 4, /* 5== mfr badblock */
+               0, 1, 2, 3, 4,  /* 5== mfr badblock */
                6, 7, /* 8..12 for BBT or JFFS2 */ 13, 14, 15,
        };
        static const uint8_t ecc2048[] = {
@@ -451,19 +468,19 @@ static int davinci_write_page_ecc4(struct nand_device *nand, uint32_t page,
                54, 55, 56, 57, 58, 59, 60, 61, 62, 63,
        };
        static const uint8_t ecc4096[] = {
-                48,  49,  50,  51,  52,  53,  54,  55,  56,  57,
-                58,  59,  60,  61,  62,  63,  64,  65,  66,  67,
-                68,  69,  70,  71,  72,  73,  74,  75,  76,  77,
-                78,  79,  80,  81,  82,  83,  84,  85,  86,  87,
-                88,  89,  90,  91,  92,  93,  94,  95,  96,  97,
-                98,  99, 100, 101, 102, 103, 104, 105, 106, 107,
+               48,  49,  50,  51,  52,  53,  54,  55,  56,  57,
+               58,  59,  60,  61,  62,  63,  64,  65,  66,  67,
+               68,  69,  70,  71,  72,  73,  74,  75,  76,  77,
+               78,  79,  80,  81,  82,  83,  84,  85,  86,  87,
+               88,  89,  90,  91,  92,  93,  94,  95,  96,  97,
+               98,  99, 100, 101, 102, 103, 104, 105, 106, 107,
                108, 109, 110, 111, 112, 113, 114, 115, 116, 117,
                118, 119, 120, 121, 122, 123, 124, 125, 126, 127,
        };
 
        struct davinci_nand *info = nand->controller_priv;
        const uint8_t *l;
-       struct target *target = info->target;
+       struct target *target = nand->target;
        const uint32_t fcr_addr = info->aemif + NANDFCR;
        const uint32_t ecc4_addr = info->aemif + NAND4BITECC;
        uint32_t fcr, ecc4;
@@ -476,15 +493,15 @@ static int davinci_write_page_ecc4(struct nand_device *nand, uint32_t page,
         * the standard ECC logic can't handle.
         */
        switch (nand->page_size) {
-       case 512:
-               l = ecc512;
-               break;
-       case 2048:
-               l = ecc2048;
-               break;
-       default:
-               l = ecc4096;
-               break;
+               case 512:
+                       l = ecc512;
+                       break;
+               case 2048:
+                       l = ecc2048;
+                       break;
+               default:
+                       l = ecc4096;
+                       break;
        }
 
        davinci_write_pagecmd(nand, NAND_CMD_SEQIN, page);
@@ -514,11 +531,11 @@ static int davinci_write_page_ecc4(struct nand_device *nand, uint32_t page,
                        raw_ecc[i] &= 0x03ff03ff;
                }
                for (i = 0, p = raw_ecc; i < 2; i++, p += 2) {
-                       oob[*l++] =   p[0]        & 0xff;
+                       oob[*l++] = p[0]        & 0xff;
                        oob[*l++] = ((p[0] >>  8) & 0x03) | ((p[0] >> 14) & 0xfc);
                        oob[*l++] = ((p[0] >> 22) & 0x0f) | ((p[1] <<  4) & 0xf0);
                        oob[*l++] = ((p[1] >>  4) & 0x3f) | ((p[1] >> 10) & 0xc0);
-                       oob[*l++] =  (p[1] >> 18) & 0xff;
+                       oob[*l++] = (p[1] >> 18) & 0xff;
                }
 
        } while (data_size);
@@ -540,10 +557,10 @@ static int davinci_write_page_ecc4(struct nand_device *nand, uint32_t page,
  * (MVL 4.x/5.x kernels, filesystems, etc) may need it more generally.
  */
 static int davinci_write_page_ecc4infix(struct nand_device *nand, uint32_t page,
-               uint8_t *data, uint32_t data_size, uint8_t *oob, uint32_t oob_size)
+       uint8_t *data, uint32_t data_size, uint8_t *oob, uint32_t oob_size)
 {
        struct davinci_nand *info = nand->controller_priv;
-       struct target *target = info->target;
+       struct target *target = nand->target;
        const uint32_t fcr_addr = info->aemif + NANDFCR;
        const uint32_t ecc4_addr = info->aemif + NAND4BITECC;
        uint32_t fcr, ecc4;
@@ -578,11 +595,11 @@ static int davinci_write_page_ecc4infix(struct nand_device *nand, uint32_t page,
 
                /* skip 6 bytes of prepad, then pack 10 packed ecc bytes */
                for (i = 0, l = oob + 6, p = raw_ecc; i < 2; i++, p += 2) {
-                       *l++ =   p[0]        & 0xff;
+                       *l++ = p[0]        & 0xff;
                        *l++ = ((p[0] >>  8) & 0x03) | ((p[0] >> 14) & 0xfc);
                        *l++ = ((p[0] >> 22) & 0x0f) | ((p[1] <<  4) & 0xf0);
                        *l++ = ((p[1] >>  4) & 0x3f) | ((p[1] >> 10) & 0xc0);
-                       *l++ =  (p[1] >> 18) & 0xff;
+                       *l++ = (p[1] >> 18) & 0xff;
                }
 
                /* write this "out-of-band" data -- infix */
@@ -597,8 +614,12 @@ static int davinci_write_page_ecc4infix(struct nand_device *nand, uint32_t page,
 }
 
 static int davinci_read_page_ecc4infix(struct nand_device *nand, uint32_t page,
-               uint8_t *data, uint32_t data_size, uint8_t *oob, uint32_t oob_size)
+       uint8_t *data, uint32_t data_size, uint8_t *oob, uint32_t oob_size)
 {
+       int read_size;
+       int want_col, at_col;
+       int ret;
+
        davinci_write_pagecmd(nand, NAND_CMD_READ0, page);
 
        /* large page devices need a start command */
@@ -610,25 +631,49 @@ static int davinci_read_page_ecc4infix(struct nand_device *nand, uint32_t page,
 
        /* NOTE:  not bothering to compute and use ECC data for now */
 
-       do {
-               /* write 512 bytes */
-               davinci_read_block_data(nand, data, 512);
-               data += 512;
-               data_size -= 512;
-
-               /* read this "out-of-band" data -- infix */
-               davinci_read_block_data(nand, oob, 16);
-               oob += 16;
-               oob_size -= 16;
-       } while (data_size);
-
+       want_col = 0;
+       at_col = 0;
+       while ((data && data_size) || (oob && oob_size)) {
+
+               if (data && data_size) {
+                       if (want_col != at_col) {
+                               /* Reads are slow, so seek past them when we can */
+                               ret  = davinci_seek_column(nand, want_col);
+                               if (ret != ERROR_OK)
+                                       return ret;
+                               at_col = want_col;
+                       }
+                       /* read 512 bytes or data_size, whichever is smaller*/
+                       read_size = data_size > 512 ? 512 : data_size;
+                       davinci_read_block_data(nand, data, read_size);
+                       data += read_size;
+                       data_size -= read_size;
+                       at_col += read_size;
+               }
+               want_col += 512;
+
+               if (oob && oob_size) {
+                       if (want_col != at_col) {
+                               ret  = davinci_seek_column(nand, want_col);
+                               if (ret != ERROR_OK)
+                                       return ret;
+                               at_col = want_col;
+                       }
+                       /* read this "out-of-band" data -- infix */
+                       read_size = oob_size > 16 ? 16 : oob_size;
+                       davinci_read_block_data(nand, oob, read_size);
+                       oob += read_size;
+                       oob_size -= read_size;
+                       at_col += read_size;
+               }
+               want_col += 16;
+       }
        return ERROR_OK;
 }
 
 NAND_DEVICE_COMMAND_HANDLER(davinci_nand_device_command)
 {
        struct davinci_nand *info;
-       struct target *target;
        unsigned long chip, aemif;
        enum ecc eccmode;
        int chipsel;
@@ -641,18 +686,8 @@ NAND_DEVICE_COMMAND_HANDLER(davinci_nand_device_command)
         *  - aemif address
         * Plus someday, optionally, ALE and CLE masks.
         */
-       if (CMD_ARGC < 5) {
-               LOG_ERROR("parameters: %s target "
-                               "chip_addr hwecc_mode aemif_addr",
-                               CMD_ARGV[0]);
-               goto fail;
-       }
-
-       target = get_target(CMD_ARGV[1]);
-       if (!target) {
-               LOG_ERROR("invalid target %s", CMD_ARGV[1]);
-               goto fail;
-       }
+       if (CMD_ARGC < 5)
+               return ERROR_COMMAND_SYNTAX_ERROR;
 
        COMMAND_PARSE_NUMBER(ulong, CMD_ARGV[2], chip);
        if (chip == 0) {
@@ -682,9 +717,9 @@ NAND_DEVICE_COMMAND_HANDLER(davinci_nand_device_command)
         * AEMIF controller address.
         */
        if (aemif == 0x01e00000                 /* dm6446, dm357 */
-                       || aemif == 0x01e10000  /* dm335, dm355 */
-                       || aemif == 0x01d10000  /* dm365 */
-                       ) {
+                       || aemif == 0x01e10000          /* dm335, dm355 */
+                       || aemif == 0x01d10000          /* dm365 */
+               ) {
                if (chip < 0x02000000 || chip >= 0x0a000000) {
                        LOG_ERROR("NAND address %08lx out of range?", chip);
                        goto fail;
@@ -699,7 +734,6 @@ NAND_DEVICE_COMMAND_HANDLER(davinci_nand_device_command)
        if (info == NULL)
                goto fail;
 
-       info->target = target;
        info->eccmode = eccmode;
        info->chipsel = chipsel;
        info->aemif = aemif;
@@ -709,7 +743,7 @@ NAND_DEVICE_COMMAND_HANDLER(davinci_nand_device_command)
 
        nand->controller_priv = info;
 
-       info->io.target = target;
+       info->io.target = nand->target;
        info->io.data = info->data;
        info->io.op = ARM_NAND_NONE;
 
@@ -720,19 +754,19 @@ NAND_DEVICE_COMMAND_HANDLER(davinci_nand_device_command)
        info->read_page = nand_read_page_raw;
 
        switch (eccmode) {
-       case HWECC1:
-               /* ECC_HW, 1-bit corrections, 3 bytes ECC per 512 data bytes */
-               info->write_page = davinci_write_page_ecc1;
-               break;
-       case HWECC4:
-               /* ECC_HW, 4-bit corrections, 10 bytes ECC per 512 data bytes */
-               info->write_page = davinci_write_page_ecc4;
-               break;
-       case HWECC4_INFIX:
-               /* Same 4-bit ECC HW, with problematic page/ecc layout */
-               info->read_page = davinci_read_page_ecc4infix;
-               info->write_page = davinci_write_page_ecc4infix;
-               break;
+               case HWECC1:
+                       /* ECC_HW, 1-bit corrections, 3 bytes ECC per 512 data bytes */
+                       info->write_page = davinci_write_page_ecc1;
+                       break;
+               case HWECC4:
+                       /* ECC_HW, 4-bit corrections, 10 bytes ECC per 512 data bytes */
+                       info->write_page = davinci_write_page_ecc4;
+                       break;
+               case HWECC4_INFIX:
+                       /* Same 4-bit ECC HW, with problematic page/ecc layout */
+                       info->read_page = davinci_read_page_ecc4infix;
+                       info->write_page = davinci_write_page_ecc4infix;
+                       break;
        }
 
        return ERROR_OK;
@@ -742,17 +776,18 @@ fail:
 }
 
 struct nand_flash_controller davinci_nand_controller = {
-       .name                   = "davinci",
-       .nand_device_command    = davinci_nand_device_command,
-       .init                   = davinci_init,
-       .reset                  = davinci_reset,
-       .command                = davinci_command,
-       .address                = davinci_address,
-       .write_data             = davinci_write_data,
-       .read_data              = davinci_read_data,
-       .write_page             = davinci_write_page,
-       .read_page              = davinci_read_page,
-       .write_block_data       = davinci_write_block_data,
-       .read_block_data        = davinci_read_block_data,
-       .nand_ready             = davinci_nand_ready,
+       .name                   = "davinci",
+       .usage                  = "chip_addr hwecc_mode aemif_addr",
+       .nand_device_command    = davinci_nand_device_command,
+       .init                   = davinci_init,
+       .reset                  = davinci_reset,
+       .command                = davinci_command,
+       .address                = davinci_address,
+       .write_data             = davinci_write_data,
+       .read_data              = davinci_read_data,
+       .write_page             = davinci_write_page,
+       .read_page              = davinci_read_page,
+       .write_block_data       = davinci_write_block_data,
+       .read_block_data        = davinci_read_block_data,
+       .nand_ready             = davinci_nand_ready,
 };