Lines Matching +full:on +full:- +full:die
4 * Copyright (C) 2005-2007 Samsung Electronics
8 * Adrian Hunter <ext-adrian.hunter@nokia.com>:
9 * auto-placement support, read-while load support, various fixes
14 * Flex-OneNAND support
33 /* It should access 16-bit instead of 8-bit */
41 while (len-- > 0) in memcpy_16()
47 * onenand_oob_128 - oob info for Flex-Onenand with 4KB page
68 * onenand_oob_64 - oob info for large (2KB) page
85 * onenand_oob_32 - oob info for middle (1KB) page
122 * onenand_readw - [OneNAND Interface] Read OneNAND register
133 * onenand_writew - [OneNAND Interface] Write OneNAND register with value
145 * onenand_block_address - [DEFAULT] Get block address
155 if (block & this->density_mask) in onenand_block_address()
156 return ONENAND_DDP_CHIP1 | (block ^ this->density_mask); in onenand_block_address()
162 * onenand_bufferram_address - [DEFAULT] Get bufferram address
172 if (block & this->density_mask) in onenand_bufferram_address()
179 * onenand_page_address - [DEFAULT] Get page address
198 * onenand_buffer_address - [DEFAULT] Get buffer address
225 * flexonenand_block - Return block number for flash address
226 * @param this - OneNAND device structure
227 * @param addr - Address for which block number is needed
231 unsigned int boundary, blk, die = 0; in flexonenand_block() local
233 if (ONENAND_IS_DDP(this) && addr >= this->diesize[0]) { in flexonenand_block()
234 die = 1; in flexonenand_block()
235 addr -= this->diesize[0]; in flexonenand_block()
238 boundary = this->boundary[die]; in flexonenand_block()
240 blk = addr >> (this->erase_shift - 1); in flexonenand_block()
244 blk += die ? this->density_mask : 0; in flexonenand_block()
251 return addr >> this->erase_shift; in onenand_block()
256 * flexonenand_addr - Return address of the block
258 * @block: Block number on Flex-OneNAND
265 int die = 0, boundary; in flexonenand_addr() local
267 if (ONENAND_IS_DDP(this) && block >= this->density_mask) { in flexonenand_addr()
268 block -= this->density_mask; in flexonenand_addr()
269 die = 1; in flexonenand_addr()
270 ofs = this->diesize[0]; in flexonenand_addr()
273 boundary = this->boundary[die]; in flexonenand_addr()
274 ofs += (loff_t) block << (this->erase_shift - 1); in flexonenand_addr()
276 ofs += (loff_t) (block - boundary - 1) in flexonenand_addr()
277 << (this->erase_shift - 1); in flexonenand_addr()
284 return (loff_t) block << this->erase_shift; in onenand_addr()
289 * flexonenand_region - [Flex-OneNAND] Return erase region of addr
297 for (i = 0; i < mtd->numeraseregions; i++) in flexonenand_region()
298 if (addr < mtd->eraseregions[i].offset) in flexonenand_region()
300 return i - 1; in flexonenand_region()
304 * onenand_get_density - [DEFAULT] Get OneNAND density
316 * onenand_command - [DEFAULT] Send command to OneNAND device
328 struct onenand_chip *this = mtd->priv; in onenand_command()
341 block = -1; in onenand_command()
342 page = -1; in onenand_command()
346 /* addr contains die index */ in onenand_command()
347 block = addr * this->density_mask; in onenand_command()
348 page = -1; in onenand_command()
354 page = -1; in onenand_command()
359 block = addr * this->density_mask; in onenand_command()
366 - onenand_addr(this, block)) >> this->page_shift; in onenand_command()
367 page &= this->page_mask; in onenand_command()
375 this->write_word(value, in onenand_command()
376 this->base + ONENAND_REG_START_ADDRESS2); in onenand_command()
387 if (block != -1) { in onenand_command()
390 this->write_word(value, in onenand_command()
391 this->base + ONENAND_REG_START_ADDRESS1); in onenand_command()
395 this->write_word(value, in onenand_command()
396 this->base + ONENAND_REG_START_ADDRESS2); in onenand_command()
399 if (page != -1) { in onenand_command()
420 this->write_word(value, in onenand_command()
421 this->base + ONENAND_REG_START_ADDRESS8); in onenand_command()
425 this->write_word(value, this->base + ONENAND_REG_START_BUFFER); in onenand_command()
429 this->write_word(ONENAND_INT_CLEAR, this->base + ONENAND_REG_INTERRUPT); in onenand_command()
431 this->write_word(cmd, this->base + ONENAND_REG_COMMAND); in onenand_command()
437 * onenand_read_ecc - return ecc status
445 return this->read_word(this->base + ONENAND_REG_ECC_STATUS); in onenand_read_ecc()
448 ecc = this->read_word(this->base in onenand_read_ecc()
460 * onenand_wait - [DEFAULT] wait until the command is done
470 struct onenand_chip *this = mtd->priv; in onenand_wait()
480 return -EIO; in onenand_wait()
481 interrupt = this->read_word(this->base + ONENAND_REG_INTERRUPT); in onenand_wait()
484 ctrl = this->read_word(this->base + ONENAND_REG_CTRL_STATUS); in onenand_wait()
490 return -EBADMSG; in onenand_wait()
500 return -EIO; in onenand_wait()
508 * onenand_bufferram_offset - [DEFAULT] BufferRAM offset
517 struct onenand_chip *this = mtd->priv; in onenand_bufferram_offset()
521 return mtd->writesize; in onenand_bufferram_offset()
523 return mtd->oobsize; in onenand_bufferram_offset()
530 * onenand_read_bufferram - [OneNAND Interface] Read the bufferram area
543 struct onenand_chip *this = mtd->priv; in onenand_read_bufferram()
546 bufferram = this->base + area; in onenand_read_bufferram()
555 * onenand_sync_read_bufferram - [OneNAND Interface] Read the bufferram area with Sync. Burst mode
568 struct onenand_chip *this = mtd->priv; in onenand_sync_read_bufferram()
571 bufferram = this->base + area; in onenand_sync_read_bufferram()
574 this->mmcontrol(mtd, ONENAND_SYS_CFG1_SYNC_READ); in onenand_sync_read_bufferram()
578 this->mmcontrol(mtd, 0); in onenand_sync_read_bufferram()
584 * onenand_write_bufferram - [OneNAND Interface] Write the bufferram area
597 struct onenand_chip *this = mtd->priv; in onenand_write_bufferram()
600 bufferram = this->base + area; in onenand_write_bufferram()
609 * onenand_get_2x_blockpage - [GENERIC] Get blockpage at 2x program mode
618 struct onenand_chip *this = mtd->priv; in onenand_get_2x_blockpage()
622 block = (int) (addr >> this->erase_shift) & ~1; in onenand_get_2x_blockpage()
624 if (addr & this->writesize) in onenand_get_2x_blockpage()
626 page = (int) (addr >> (this->page_shift + 1)) & this->page_mask; in onenand_get_2x_blockpage()
633 * onenand_check_bufferram - [GENERIC] Check BufferRAM information
642 struct onenand_chip *this = mtd->priv; in onenand_check_bufferram()
649 blockpage = (int) (addr >> this->page_shift); in onenand_check_bufferram()
653 if (this->bufferram[i].blockpage == blockpage) in onenand_check_bufferram()
658 if (this->bufferram[i].blockpage == blockpage) { in onenand_check_bufferram()
668 this->write_word(value, this->base + ONENAND_REG_START_ADDRESS2); in onenand_check_bufferram()
675 * onenand_update_bufferram - [GENERIC] Update BufferRAM information
685 struct onenand_chip *this = mtd->priv; in onenand_update_bufferram()
692 blockpage = (int)(addr >> this->page_shift); in onenand_update_bufferram()
696 if (this->bufferram[i].blockpage == blockpage) in onenand_update_bufferram()
697 this->bufferram[i].blockpage = -1; in onenand_update_bufferram()
702 this->bufferram[i].blockpage = blockpage; in onenand_update_bufferram()
704 this->bufferram[i].blockpage = -1; in onenand_update_bufferram()
710 * onenand_invalidate_bufferram - [GENERIC] Invalidate BufferRAM information
720 struct onenand_chip *this = mtd->priv; in onenand_invalidate_bufferram()
726 loff_t buf_addr = this->bufferram[i].blockpage << this->page_shift; in onenand_invalidate_bufferram()
729 this->bufferram[i].blockpage = -1; in onenand_invalidate_bufferram()
734 * onenand_get_device - [GENERIC] Get chip for selected access
746 * onenand_release_device - [GENERIC] release chip
749 * Deselect, release chip lock and wake up anyone waiting on the device
757 * onenand_transfer_auto_oob - [INTERN] oob auto-placement transfer
766 struct onenand_chip *this = mtd->priv; in onenand_transfer_auto_oob()
772 uint8_t *oob_buf = this->oob_buf; in onenand_transfer_auto_oob()
774 free = this->ecclayout->oobfree; in onenand_transfer_auto_oob()
775 for (i = 0; i < MTD_MAX_OOBFREE_ENTRIES_LARGE && free->length; in onenand_transfer_auto_oob()
778 readcol += free->offset - lastgap; in onenand_transfer_auto_oob()
780 readend += free->offset - lastgap; in onenand_transfer_auto_oob()
781 lastgap = free->offset + free->length; in onenand_transfer_auto_oob()
783 this->read_bufferram(mtd, 0, ONENAND_SPARERAM, oob_buf, 0, mtd->oobsize); in onenand_transfer_auto_oob()
784 free = this->ecclayout->oobfree; in onenand_transfer_auto_oob()
785 for (i = 0; i < MTD_MAX_OOBFREE_ENTRIES_LARGE && free->length; in onenand_transfer_auto_oob()
787 int free_end = free->offset + free->length; in onenand_transfer_auto_oob()
788 if (free->offset < readend && free_end > readcol) { in onenand_transfer_auto_oob()
789 int st = max_t(int,free->offset,readcol); in onenand_transfer_auto_oob()
791 int n = ed - st; in onenand_transfer_auto_oob()
801 * onenand_recover_lsb - [Flex-OneNAND] Recover LSB page data
806 * MLC NAND Flash cell has paired pages - LSB page and MSB page. LSB page has
815 struct onenand_chip *this = mtd->priv; in onenand_recover_lsb()
818 /* Recovery is only for Flex-OneNAND */ in onenand_recover_lsb()
828 if (mtd->eraseregions[i].erasesize < (1 << this->erase_shift)) in onenand_recover_lsb()
835 this->command(mtd, FLEXONENAND_CMD_RECOVER_LSB, addr, this->writesize); in onenand_recover_lsb()
836 return this->wait(mtd, FL_READING); in onenand_recover_lsb()
840 * onenand_read_ops_nolock - [OneNAND Interface] OneNAND read main and/or out-of-band
845 * OneNAND read main and/or out-of-band data
850 struct onenand_chip *this = mtd->priv; in onenand_read_ops_nolock()
852 size_t len = ops->len; in onenand_read_ops_nolock()
853 size_t ooblen = ops->ooblen; in onenand_read_ops_nolock()
854 u_char *buf = ops->datbuf; in onenand_read_ops_nolock()
855 u_char *oobbuf = ops->oobbuf; in onenand_read_ops_nolock()
859 int writesize = this->writesize; in onenand_read_ops_nolock()
864 if (ops->mode == MTD_OPS_AUTO_OOB) in onenand_read_ops_nolock()
865 oobsize = this->ecclayout->oobavail; in onenand_read_ops_nolock()
867 oobsize = mtd->oobsize; in onenand_read_ops_nolock()
869 oobcolumn = from & (mtd->oobsize - 1); in onenand_read_ops_nolock()
872 if ((from + len) > mtd->size) { in onenand_read_ops_nolock()
874 ops->retlen = 0; in onenand_read_ops_nolock()
875 ops->oobretlen = 0; in onenand_read_ops_nolock()
876 return -EINVAL; in onenand_read_ops_nolock()
879 stats = mtd->ecc_stats; in onenand_read_ops_nolock()
881 /* Read-while-load method */ in onenand_read_ops_nolock()
887 this->main_buf = buf; in onenand_read_ops_nolock()
888 this->command(mtd, ONENAND_CMD_READ, from, writesize); in onenand_read_ops_nolock()
889 ret = this->wait(mtd, FL_READING); in onenand_read_ops_nolock()
893 if (ret == -EBADMSG) in onenand_read_ops_nolock()
898 thislen = min_t(int, writesize, len - read); in onenand_read_ops_nolock()
899 column = from & (writesize - 1); in onenand_read_ops_nolock()
901 thislen = writesize - column; in onenand_read_ops_nolock()
907 this->main_buf = buf + thislen; in onenand_read_ops_nolock()
908 this->command(mtd, ONENAND_CMD_READ, from, writesize); in onenand_read_ops_nolock()
915 unlikely(from == (this->chipsize >> 1))) { in onenand_read_ops_nolock()
916 this->write_word(ONENAND_DDP_CHIP0, this->base + ONENAND_REG_START_ADDRESS2); in onenand_read_ops_nolock()
924 this->read_bufferram(mtd, from - thislen, ONENAND_DATARAM, buf, column, thislen); in onenand_read_ops_nolock()
928 thisooblen = oobsize - oobcolumn; in onenand_read_ops_nolock()
929 thisooblen = min_t(int, thisooblen, ooblen - oobread); in onenand_read_ops_nolock()
931 if (ops->mode == MTD_OPS_AUTO_OOB) in onenand_read_ops_nolock()
934 this->read_bufferram(mtd, 0, ONENAND_SPARERAM, oobbuf, oobcolumn, thisooblen); in onenand_read_ops_nolock()
941 this->command(mtd, ONENAND_CMD_READ, from, writesize); in onenand_read_ops_nolock()
942 ret = this->wait(mtd, FL_READING); in onenand_read_ops_nolock()
956 this->write_word(ONENAND_DDP_CHIP1, this->base + ONENAND_REG_START_ADDRESS2); in onenand_read_ops_nolock()
960 thislen = min_t(int, writesize, len - read); in onenand_read_ops_nolock()
965 ret = this->wait(mtd, FL_READING); in onenand_read_ops_nolock()
973 * Return success, if no ECC failures, else -EBADMSG in onenand_read_ops_nolock()
975 * retlen == desired len and result == -EBADMSG in onenand_read_ops_nolock()
977 ops->retlen = read; in onenand_read_ops_nolock()
978 ops->oobretlen = oobread; in onenand_read_ops_nolock()
983 if (mtd->ecc_stats.failed - stats.failed) in onenand_read_ops_nolock()
984 return -EBADMSG; in onenand_read_ops_nolock()
987 return mtd->ecc_stats.corrected != stats.corrected ? 1 : 0; in onenand_read_ops_nolock()
991 * onenand_read_oob_nolock - [MTD Interface] OneNAND read out-of-band
996 * OneNAND read out-of-band data from the spare area
1001 struct onenand_chip *this = mtd->priv; in onenand_read_oob_nolock()
1004 size_t len = ops->ooblen; in onenand_read_oob_nolock()
1005 unsigned int mode = ops->mode; in onenand_read_oob_nolock()
1006 u_char *buf = ops->oobbuf; in onenand_read_oob_nolock()
1009 from += ops->ooboffs; in onenand_read_oob_nolock()
1015 ops->oobretlen = 0; in onenand_read_oob_nolock()
1018 oobsize = this->ecclayout->oobavail; in onenand_read_oob_nolock()
1020 oobsize = mtd->oobsize; in onenand_read_oob_nolock()
1022 column = from & (mtd->oobsize - 1); in onenand_read_oob_nolock()
1026 return -EINVAL; in onenand_read_oob_nolock()
1030 if (unlikely(from >= mtd->size || in onenand_read_oob_nolock()
1031 column + len > ((mtd->size >> this->page_shift) - in onenand_read_oob_nolock()
1032 (from >> this->page_shift)) * oobsize)) { in onenand_read_oob_nolock()
1034 return -EINVAL; in onenand_read_oob_nolock()
1037 stats = mtd->ecc_stats; in onenand_read_oob_nolock()
1043 thislen = oobsize - column; in onenand_read_oob_nolock()
1046 this->spare_buf = buf; in onenand_read_oob_nolock()
1047 this->command(mtd, readcmd, from, mtd->oobsize); in onenand_read_oob_nolock()
1051 ret = this->wait(mtd, FL_READING); in onenand_read_oob_nolock()
1055 if (ret && ret != -EBADMSG) { in onenand_read_oob_nolock()
1063 this->read_bufferram(mtd, 0, ONENAND_SPARERAM, buf, column, thislen); in onenand_read_oob_nolock()
1075 from += mtd->writesize; in onenand_read_oob_nolock()
1080 ops->oobretlen = read; in onenand_read_oob_nolock()
1085 if (mtd->ecc_stats.failed - stats.failed) in onenand_read_oob_nolock()
1086 return -EBADMSG; in onenand_read_oob_nolock()
1092 * onenand_read - [MTD Interface] MTD compability function for onenand_read_ecc
1121 * onenand_read_oob - [MTD Interface] OneNAND read out-of-band
1126 * OneNAND main and/or out-of-band
1133 switch (ops->mode) { in onenand_read_oob()
1140 return -EINVAL; in onenand_read_oob()
1144 if (ops->datbuf) in onenand_read_oob()
1154 * onenand_bbt_wait - [DEFAULT] wait until the command is done
1162 struct onenand_chip *this = mtd->priv; in onenand_bbt_wait()
1173 interrupt = this->read_word(this->base + ONENAND_REG_INTERRUPT); in onenand_bbt_wait()
1177 interrupt = this->read_word(this->base + ONENAND_REG_INTERRUPT); in onenand_bbt_wait()
1178 ctrl = this->read_word(this->base + ONENAND_REG_CTRL_STATUS); in onenand_bbt_wait()
1203 * onenand_bbt_read_oob - [MTD Interface] OneNAND read out-of-band for bbt scan
1208 * OneNAND read out-of-band data from the spare area for bbt scan
1213 struct onenand_chip *this = mtd->priv; in onenand_bbt_read_oob()
1216 size_t len = ops->ooblen; in onenand_bbt_read_oob()
1217 u_char *buf = ops->oobbuf; in onenand_bbt_read_oob()
1226 ops->oobretlen = 0; in onenand_bbt_read_oob()
1229 if (unlikely((from + len) > mtd->size)) { in onenand_bbt_read_oob()
1237 column = from & (mtd->oobsize - 1); in onenand_bbt_read_oob()
1241 thislen = mtd->oobsize - column; in onenand_bbt_read_oob()
1244 this->spare_buf = buf; in onenand_bbt_read_oob()
1245 this->command(mtd, readcmd, from, mtd->oobsize); in onenand_bbt_read_oob()
1249 ret = this->bbt_wait(mtd, FL_READING); in onenand_bbt_read_oob()
1256 this->read_bufferram(mtd, 0, ONENAND_SPARERAM, buf, column, thislen); in onenand_bbt_read_oob()
1266 from += this->writesize; in onenand_bbt_read_oob()
1271 /* Deselect and wake up anyone waiting on the device */ in onenand_bbt_read_oob()
1274 ops->oobretlen = read; in onenand_bbt_read_oob()
1281 * onenand_verify_oob - [GENERIC] verify the oob contents after a write
1288 struct onenand_chip *this = mtd->priv; in onenand_verify_oob()
1289 u_char *oob_buf = this->oob_buf; in onenand_verify_oob()
1295 this->command(mtd, readcmd, to, mtd->oobsize); in onenand_verify_oob()
1297 status = this->wait(mtd, FL_READING); in onenand_verify_oob()
1301 this->read_bufferram(mtd, 0, ONENAND_SPARERAM, oob_buf, 0, mtd->oobsize); in onenand_verify_oob()
1302 for (i = 0; i < mtd->oobsize; i++) in onenand_verify_oob()
1304 return -EBADMSG; in onenand_verify_oob()
1310 * onenand_verify - [GENERIC] verify the chip contents after a write
1318 struct onenand_chip *this = mtd->priv; in onenand_verify()
1324 thislen = min_t(int, this->writesize, len); in onenand_verify()
1325 column = addr & (this->writesize - 1); in onenand_verify()
1326 if (column + thislen > this->writesize) in onenand_verify()
1327 thislen = this->writesize - column; in onenand_verify()
1329 this->command(mtd, ONENAND_CMD_READ, addr, this->writesize); in onenand_verify()
1333 ret = this->wait(mtd, FL_READING); in onenand_verify()
1339 dataram = this->base + ONENAND_DATARAM; in onenand_verify()
1343 return -EBADMSG; in onenand_verify()
1345 len -= thislen; in onenand_verify()
1357 #define NOTALIGNED(x) ((x & (this->subpagesize - 1)) != 0)
1360 * onenand_fill_auto_oob - [INTERN] oob auto-placement transfer
1370 struct onenand_chip *this = mtd->priv; in onenand_fill_auto_oob()
1377 free = this->ecclayout->oobfree; in onenand_fill_auto_oob()
1378 for (i = 0; i < MTD_MAX_OOBFREE_ENTRIES_LARGE && free->length; in onenand_fill_auto_oob()
1381 writecol += free->offset - lastgap; in onenand_fill_auto_oob()
1383 writeend += free->offset - lastgap; in onenand_fill_auto_oob()
1384 lastgap = free->offset + free->length; in onenand_fill_auto_oob()
1386 free = this->ecclayout->oobfree; in onenand_fill_auto_oob()
1387 for (i = 0; i < MTD_MAX_OOBFREE_ENTRIES_LARGE && free->length; in onenand_fill_auto_oob()
1389 int free_end = free->offset + free->length; in onenand_fill_auto_oob()
1390 if (free->offset < writeend && free_end > writecol) { in onenand_fill_auto_oob()
1391 int st = max_t(int,free->offset,writecol); in onenand_fill_auto_oob()
1393 int n = ed - st; in onenand_fill_auto_oob()
1403 * onenand_write_ops_nolock - [OneNAND Interface] write main and/or out-of-band
1413 struct onenand_chip *this = mtd->priv; in onenand_write_ops_nolock()
1416 size_t len = ops->len; in onenand_write_ops_nolock()
1417 size_t ooblen = ops->ooblen; in onenand_write_ops_nolock()
1418 const u_char *buf = ops->datbuf; in onenand_write_ops_nolock()
1419 const u_char *oob = ops->oobbuf; in onenand_write_ops_nolock()
1427 ops->retlen = 0; in onenand_write_ops_nolock()
1428 ops->oobretlen = 0; in onenand_write_ops_nolock()
1433 return -EINVAL; in onenand_write_ops_nolock()
1436 if (ops->mode == MTD_OPS_AUTO_OOB) in onenand_write_ops_nolock()
1437 oobsize = this->ecclayout->oobavail; in onenand_write_ops_nolock()
1439 oobsize = mtd->oobsize; in onenand_write_ops_nolock()
1441 oobcolumn = to & (mtd->oobsize - 1); in onenand_write_ops_nolock()
1443 column = to & (mtd->writesize - 1); in onenand_write_ops_nolock()
1449 thislen = min_t(int, mtd->writesize - column, len - written); in onenand_write_ops_nolock()
1450 thisooblen = min_t(int, oobsize - oobcolumn, ooblen - oobwritten); in onenand_write_ops_nolock()
1452 this->command(mtd, ONENAND_CMD_BUFFERRAM, to, thislen); in onenand_write_ops_nolock()
1455 subpage = thislen < mtd->writesize; in onenand_write_ops_nolock()
1457 memset(this->page_buf, 0xff, mtd->writesize); in onenand_write_ops_nolock()
1458 memcpy(this->page_buf + column, buf, thislen); in onenand_write_ops_nolock()
1459 wbuf = this->page_buf; in onenand_write_ops_nolock()
1462 this->write_bufferram(mtd, to, ONENAND_DATARAM, wbuf, 0, mtd->writesize); in onenand_write_ops_nolock()
1465 oobbuf = this->oob_buf; in onenand_write_ops_nolock()
1469 memset(oobbuf, 0xff, mtd->oobsize); in onenand_write_ops_nolock()
1470 if (ops->mode == MTD_OPS_AUTO_OOB) in onenand_write_ops_nolock()
1481 this->write_bufferram(mtd, 0, ONENAND_SPARERAM, oobbuf, 0, mtd->oobsize); in onenand_write_ops_nolock()
1483 this->command(mtd, ONENAND_CMD_PROG, to, mtd->writesize); in onenand_write_ops_nolock()
1485 ret = this->wait(mtd, FL_WRITING); in onenand_write_ops_nolock()
1491 onenand_update_bufferram(mtd, to + this->writesize, !ret && !subpage); in onenand_write_ops_nolock()
1499 /* Only check verify write turn on */ in onenand_write_ops_nolock()
1516 ops->retlen = written; in onenand_write_ops_nolock()
1522 * onenand_write_oob_nolock - [INTERN] OneNAND write out-of-band
1530 * OneNAND write out-of-band
1535 struct onenand_chip *this = mtd->priv; in onenand_write_oob_nolock()
1539 size_t len = ops->ooblen; in onenand_write_oob_nolock()
1540 const u_char *buf = ops->oobbuf; in onenand_write_oob_nolock()
1541 unsigned int mode = ops->mode; in onenand_write_oob_nolock()
1543 to += ops->ooboffs; in onenand_write_oob_nolock()
1549 ops->oobretlen = 0; in onenand_write_oob_nolock()
1552 oobsize = this->ecclayout->oobavail; in onenand_write_oob_nolock()
1554 oobsize = mtd->oobsize; in onenand_write_oob_nolock()
1556 column = to & (mtd->oobsize - 1); in onenand_write_oob_nolock()
1560 return -EINVAL; in onenand_write_oob_nolock()
1567 return -EINVAL; in onenand_write_oob_nolock()
1571 if (unlikely(to >= mtd->size || in onenand_write_oob_nolock()
1572 column + len > ((mtd->size >> this->page_shift) - in onenand_write_oob_nolock()
1573 (to >> this->page_shift)) * oobsize)) { in onenand_write_oob_nolock()
1575 return -EINVAL; in onenand_write_oob_nolock()
1578 oobbuf = this->oob_buf; in onenand_write_oob_nolock()
1585 int thislen = min_t(int, oobsize, len - written); in onenand_write_oob_nolock()
1587 this->command(mtd, ONENAND_CMD_BUFFERRAM, to, mtd->oobsize); in onenand_write_oob_nolock()
1591 memset(oobbuf, 0xff, mtd->oobsize); in onenand_write_oob_nolock()
1596 this->write_bufferram(mtd, 0, ONENAND_SPARERAM, oobbuf, 0, mtd->oobsize); in onenand_write_oob_nolock()
1600 memset(this->page_buf, 0xff, mtd->writesize); in onenand_write_oob_nolock()
1601 this->write_bufferram(mtd, 0, ONENAND_DATARAM, in onenand_write_oob_nolock()
1602 this->page_buf, 0, mtd->writesize); in onenand_write_oob_nolock()
1605 this->command(mtd, oobcmd, to, mtd->oobsize); in onenand_write_oob_nolock()
1610 onenand_update_bufferram(mtd, to + this->writesize, 0); in onenand_write_oob_nolock()
1613 ret = this->wait(mtd, FL_WRITING); in onenand_write_oob_nolock()
1629 to += mtd->writesize; in onenand_write_oob_nolock()
1634 ops->oobretlen = written; in onenand_write_oob_nolock()
1640 * onenand_write - [MTD Interface] compability function for onenand_write_ecc
1669 * onenand_write_oob - [MTD Interface] OneNAND write out-of-band
1674 * OneNAND write main and/or out-of-band
1681 switch (ops->mode) { in onenand_write_oob()
1688 return -EINVAL; in onenand_write_oob()
1692 if (ops->datbuf) in onenand_write_oob()
1703 * onenand_block_isbad_nolock - [GENERIC] Check if a block is marked bad
1713 struct onenand_chip *this = mtd->priv; in onenand_block_isbad_nolock()
1714 struct bbm_info *bbm = this->bbm; in onenand_block_isbad_nolock()
1717 return bbm->isbad_bbt(mtd, ofs, allowbbt); in onenand_block_isbad_nolock()
1722 * onenand_erase - [MTD Interface] erase block(s)
1730 struct onenand_chip *this = mtd->priv; in onenand_erase()
1732 loff_t addr = instr->addr; in onenand_erase()
1733 unsigned int len = instr->len; in onenand_erase()
1744 region = &mtd->eraseregions[i]; in onenand_erase()
1746 block_size = region->erasesize; in onenand_erase()
1747 region_end = region->offset in onenand_erase()
1748 + region->erasesize * region->numblocks; in onenand_erase()
1750 /* Start address within region must align on block boundary. in onenand_erase()
1753 if (unlikely((addr - region->offset) & (block_size - 1))) { in onenand_erase()
1755 return -EINVAL; in onenand_erase()
1758 block_size = 1 << this->erase_shift; in onenand_erase()
1760 /* Start address must align on block boundary */ in onenand_erase()
1761 if (unlikely(addr & (block_size - 1))) { in onenand_erase()
1763 return -EINVAL; in onenand_erase()
1767 /* Length must align on block boundary */ in onenand_erase()
1768 if (unlikely(len & (block_size - 1))) { in onenand_erase()
1770 return -EINVAL; in onenand_erase()
1777 instr->state = MTD_ERASING; in onenand_erase()
1782 if (instr->priv == 0 && onenand_block_isbad_nolock(mtd, addr, 0)) { in onenand_erase()
1786 instr->state = MTD_ERASE_FAILED; in onenand_erase()
1790 this->command(mtd, ONENAND_CMD_ERASE, addr, block_size); in onenand_erase()
1794 ret = this->wait(mtd, FL_ERASING); in onenand_erase()
1797 if (ret == -EPERM) in onenand_erase()
1804 instr->state = MTD_ERASE_FAILED; in onenand_erase()
1805 instr->fail_addr = addr; in onenand_erase()
1810 len -= block_size; in onenand_erase()
1818 block_size = region->erasesize; in onenand_erase()
1819 region_end = region->offset in onenand_erase()
1820 + region->erasesize * region->numblocks; in onenand_erase()
1822 if (len & (block_size - 1)) { in onenand_erase()
1831 instr->state = MTD_ERASE_DONE; in onenand_erase()
1835 ret = instr->state == MTD_ERASE_DONE ? 0 : -EIO; in onenand_erase()
1840 /* Deselect and wake up anyone waiting on the device */ in onenand_erase()
1847 * onenand_sync - [MTD Interface] sync
1864 * onenand_block_isbad - [MTD Interface] Check whether the block at the given offset is bad
1875 if (ofs > mtd->size) in onenand_block_isbad()
1876 return -EINVAL; in onenand_block_isbad()
1885 * onenand_default_block_markbad - [DEFAULT] mark a block bad
1894 struct onenand_chip *this = mtd->priv; in onenand_default_block_markbad()
1895 struct bbm_info *bbm = this->bbm; in onenand_default_block_markbad()
1907 if (bbm->bbt) in onenand_default_block_markbad()
1908 bbm->bbt[block >> 2] |= 0x01 << ((block & 0x03) << 1); in onenand_default_block_markbad()
1911 ofs += mtd->oobsize + (bbm->badblockpos & ~0x01); in onenand_default_block_markbad()
1916 * onenand_block_markbad - [MTD Interface] Mark the block at the given offset as bad
1924 struct onenand_chip *this = mtd->priv; in onenand_block_markbad()
1936 ret = this->block_markbad(mtd, ofs); in onenand_block_markbad()
1943 * onenand_do_lock_cmd - [OneNAND Interface] Lock or unlock block(s)
1953 struct onenand_chip *this = mtd->priv; in onenand_do_lock_cmd()
1960 if (this->options & ONENAND_HAS_CONT_LOCK) { in onenand_do_lock_cmd()
1962 this->write_word(start, in onenand_do_lock_cmd()
1963 this->base + ONENAND_REG_START_BLOCK_ADDRESS); in onenand_do_lock_cmd()
1965 this->write_word(end - 1, in onenand_do_lock_cmd()
1966 this->base + ONENAND_REG_END_BLOCK_ADDRESS); in onenand_do_lock_cmd()
1968 this->command(mtd, cmd, 0, 0); in onenand_do_lock_cmd()
1971 this->wait(mtd, FL_UNLOCKING); in onenand_do_lock_cmd()
1974 while (this->read_word(this->base + ONENAND_REG_CTRL_STATUS) in onenand_do_lock_cmd()
1979 status = this->read_word(this->base + ONENAND_REG_WP_STATUS); in onenand_do_lock_cmd()
1990 this->write_word(value, this->base + ONENAND_REG_START_ADDRESS1); in onenand_do_lock_cmd()
1993 this->write_word(value, this->base + ONENAND_REG_START_ADDRESS2); in onenand_do_lock_cmd()
1996 this->write_word(block, in onenand_do_lock_cmd()
1997 this->base + ONENAND_REG_START_BLOCK_ADDRESS); in onenand_do_lock_cmd()
1999 this->command(mtd, ONENAND_CMD_UNLOCK, 0, 0); in onenand_do_lock_cmd()
2002 this->wait(mtd, FL_UNLOCKING); in onenand_do_lock_cmd()
2005 while (this->read_word(this->base + ONENAND_REG_CTRL_STATUS) in onenand_do_lock_cmd()
2010 status = this->read_word(this->base + ONENAND_REG_WP_STATUS); in onenand_do_lock_cmd()
2021 * onenand_lock - [MTD Interface] Lock block(s)
2039 * onenand_unlock - [MTD Interface] Unlock block(s)
2058 * onenand_check_lock_status - [OneNAND Interface] Check lock status
2068 end = this->chipsize >> this->erase_shift; in onenand_check_lock_status()
2072 this->write_word(value, this->base + ONENAND_REG_START_ADDRESS1); in onenand_check_lock_status()
2075 this->write_word(value, this->base + ONENAND_REG_START_ADDRESS2); in onenand_check_lock_status()
2077 this->write_word(block, this->base + ONENAND_REG_START_BLOCK_ADDRESS); in onenand_check_lock_status()
2080 status = this->read_word(this->base + ONENAND_REG_WP_STATUS); in onenand_check_lock_status()
2091 * onenand_unlock_all - [OneNAND Interface] unlock all blocks
2098 struct onenand_chip *this = mtd->priv; in onenand_unlock_all()
2100 size_t len = mtd->size; in onenand_unlock_all()
2102 if (this->options & ONENAND_HAS_UNLOCK_ALL) { in onenand_unlock_all()
2104 this->write_word(0, this->base + ONENAND_REG_START_BLOCK_ADDRESS); in onenand_unlock_all()
2106 this->command(mtd, ONENAND_CMD_UNLOCK_ALL, 0, 0); in onenand_unlock_all()
2109 this->wait(mtd, FL_LOCKING); in onenand_unlock_all()
2112 while (this->read_word(this->base + ONENAND_REG_CTRL_STATUS) in onenand_unlock_all()
2122 /* All blocks on another chip */ in onenand_unlock_all()
2123 ofs = this->chipsize >> 1; in onenand_unlock_all()
2124 len = this->chipsize >> 1; in onenand_unlock_all()
2133 * onenand_check_features - Check and set OneNAND features
2137 * - lock scheme
2138 * - two plane
2142 struct onenand_chip *this = mtd->priv; in onenand_check_features()
2145 /* Lock scheme depends on density and process */ in onenand_check_features()
2146 density = onenand_get_density(this->device_id); in onenand_check_features()
2147 process = this->version_id >> ONENAND_VERSION_PROCESS_SHIFT; in onenand_check_features()
2153 this->options |= ONENAND_HAS_2PLANE; in onenand_check_features()
2155 this->options |= ONENAND_HAS_4KB_PAGE; in onenand_check_features()
2160 this->options |= ONENAND_HAS_2PLANE; in onenand_check_features()
2161 this->options |= ONENAND_HAS_UNLOCK_ALL; in onenand_check_features()
2164 /* A-Die has all block unlock */ in onenand_check_features()
2166 this->options |= ONENAND_HAS_UNLOCK_ALL; in onenand_check_features()
2172 this->options |= ONENAND_HAS_CONT_LOCK; in onenand_check_features()
2177 this->options |= ONENAND_HAS_4KB_PAGE; in onenand_check_features()
2180 this->options &= ~ONENAND_HAS_2PLANE; in onenand_check_features()
2183 this->options &= ~ONENAND_HAS_CONT_LOCK; in onenand_check_features()
2184 this->options |= ONENAND_HAS_UNLOCK_ALL; in onenand_check_features()
2187 if (this->options & ONENAND_HAS_CONT_LOCK) in onenand_check_features()
2189 if (this->options & ONENAND_HAS_UNLOCK_ALL) in onenand_check_features()
2191 if (this->options & ONENAND_HAS_2PLANE) in onenand_check_features()
2193 if (this->options & ONENAND_HAS_4KB_PAGE) in onenand_check_features()
2199 * onenand_print_device_info - Print device ID
2215 p += sprintf(dev_info, "%s%sOneNAND%s %dMB %sV 16-bit (0x%02x)", in onenand_print_device_info()
2217 flexonenand ? "Flex-" : "", in onenand_print_device_info()
2233 * onenand_check_maf - Check manufacturer ID
2263 * flexonenand_get_boundary - Reads the SLC boundary
2264 * @param onenand_info - onenand info structure
2270 struct onenand_chip *this = mtd->priv; in flexonenand_get_boundary()
2271 unsigned int die, bdry; in flexonenand_get_boundary() local
2275 syscfg = this->read_word(this->base + ONENAND_REG_SYS_CFG1); in flexonenand_get_boundary()
2276 this->write_word((syscfg | 0x0100), this->base + ONENAND_REG_SYS_CFG1); in flexonenand_get_boundary()
2278 for (die = 0; die < this->dies; die++) { in flexonenand_get_boundary()
2279 this->command(mtd, FLEXONENAND_CMD_PI_ACCESS, die, 0); in flexonenand_get_boundary()
2280 this->wait(mtd, FL_SYNCING); in flexonenand_get_boundary()
2282 this->command(mtd, FLEXONENAND_CMD_READ_PI, die, 0); in flexonenand_get_boundary()
2283 this->wait(mtd, FL_READING); in flexonenand_get_boundary()
2285 bdry = this->read_word(this->base + ONENAND_DATARAM); in flexonenand_get_boundary()
2290 this->boundary[die] = bdry & FLEXONENAND_PI_MASK; in flexonenand_get_boundary()
2292 this->command(mtd, ONENAND_CMD_RESET, 0, 0); in flexonenand_get_boundary()
2293 this->wait(mtd, FL_RESETING); in flexonenand_get_boundary()
2295 printk(KERN_INFO "Die %d boundary: %d%s\n", die, in flexonenand_get_boundary()
2296 this->boundary[die], locked ? "(Locked)" : "(Unlocked)"); in flexonenand_get_boundary()
2300 this->write_word(syscfg, this->base + ONENAND_REG_SYS_CFG1); in flexonenand_get_boundary()
2305 * flexonenand_get_size - Fill up fields in onenand_chip and mtd_info
2306 * boundary[], diesize[], mtd->size, mtd->erasesize,
2307 * mtd->eraseregions
2308 * @param mtd - MTD device structure
2312 struct onenand_chip *this = mtd->priv; in flexonenand_get_size()
2313 int die, i, eraseshift, density; in flexonenand_get_size() local
2317 density = onenand_get_density(this->device_id); in flexonenand_get_size()
2318 blksperdie = ((loff_t)(16 << density) << 20) >> (this->erase_shift); in flexonenand_get_size()
2320 maxbdry = blksperdie - 1; in flexonenand_get_size()
2321 eraseshift = this->erase_shift - 1; in flexonenand_get_size()
2323 mtd->numeraseregions = this->dies << 1; in flexonenand_get_size()
2327 die = 0; in flexonenand_get_size()
2329 i = -1; in flexonenand_get_size()
2330 for (; die < this->dies; die++) { in flexonenand_get_size()
2331 if (!die || this->boundary[die-1] != maxbdry) { in flexonenand_get_size()
2333 mtd->eraseregions[i].offset = ofs; in flexonenand_get_size()
2334 mtd->eraseregions[i].erasesize = 1 << eraseshift; in flexonenand_get_size()
2335 mtd->eraseregions[i].numblocks = in flexonenand_get_size()
2336 this->boundary[die] + 1; in flexonenand_get_size()
2337 ofs += mtd->eraseregions[i].numblocks << eraseshift; in flexonenand_get_size()
2340 mtd->numeraseregions -= 1; in flexonenand_get_size()
2341 mtd->eraseregions[i].numblocks += in flexonenand_get_size()
2342 this->boundary[die] + 1; in flexonenand_get_size()
2343 ofs += (this->boundary[die] + 1) << (eraseshift - 1); in flexonenand_get_size()
2345 if (this->boundary[die] != maxbdry) { in flexonenand_get_size()
2347 mtd->eraseregions[i].offset = ofs; in flexonenand_get_size()
2348 mtd->eraseregions[i].erasesize = 1 << eraseshift; in flexonenand_get_size()
2349 mtd->eraseregions[i].numblocks = maxbdry ^ in flexonenand_get_size()
2350 this->boundary[die]; in flexonenand_get_size()
2351 ofs += mtd->eraseregions[i].numblocks << eraseshift; in flexonenand_get_size()
2352 eraseshift--; in flexonenand_get_size()
2354 mtd->numeraseregions -= 1; in flexonenand_get_size()
2358 mtd->erasesize = 1 << this->erase_shift; in flexonenand_get_size()
2359 if (mtd->numeraseregions == 1) in flexonenand_get_size()
2360 mtd->erasesize >>= 1; in flexonenand_get_size()
2362 printk(KERN_INFO "Device has %d eraseregions\n", mtd->numeraseregions); in flexonenand_get_size()
2363 for (i = 0; i < mtd->numeraseregions; i++) in flexonenand_get_size()
2365 " numblocks: %04u]\n", mtd->eraseregions[i].offset, in flexonenand_get_size()
2366 mtd->eraseregions[i].erasesize, in flexonenand_get_size()
2367 mtd->eraseregions[i].numblocks); in flexonenand_get_size()
2369 for (die = 0, mtd->size = 0; die < this->dies; die++) { in flexonenand_get_size()
2370 this->diesize[die] = (loff_t) (blksperdie << this->erase_shift); in flexonenand_get_size()
2371 this->diesize[die] -= (loff_t) (this->boundary[die] + 1) in flexonenand_get_size()
2372 << (this->erase_shift - 1); in flexonenand_get_size()
2373 mtd->size += this->diesize[die]; in flexonenand_get_size()
2378 * flexonenand_check_blocks_erased - Check if blocks are erased
2379 * @param mtd_info - mtd info structure
2380 * @param start - first erase block to check
2381 * @param end - last erase block to check
2385 * have changed, reads on the block give uncorrectable error.
2394 struct onenand_chip *this = mtd->priv; in flexonenand_check_blocks_erased()
2400 .ooblen = mtd->oobsize, in flexonenand_check_blocks_erased()
2402 .oobbuf = this->oob_buf, in flexonenand_check_blocks_erased()
2421 for (i = 0; i < mtd->oobsize; i++) in flexonenand_check_blocks_erased()
2422 if (this->oob_buf[i] != 0xff) in flexonenand_check_blocks_erased()
2425 if (i != mtd->oobsize) { in flexonenand_check_blocks_erased()
2435 * flexonenand_set_boundary - Writes the SLC boundary
2436 * @param mtd - mtd info structure
2438 int flexonenand_set_boundary(struct mtd_info *mtd, int die, in flexonenand_set_boundary() argument
2441 struct onenand_chip *this = mtd->priv; in flexonenand_set_boundary()
2445 if (die >= this->dies) in flexonenand_set_boundary()
2446 return -EINVAL; in flexonenand_set_boundary()
2448 if (boundary == this->boundary[die]) in flexonenand_set_boundary()
2451 density = onenand_get_density(this->device_id); in flexonenand_set_boundary()
2452 blksperdie = ((16 << density) << 20) >> this->erase_shift; in flexonenand_set_boundary()
2459 return -EINVAL; in flexonenand_set_boundary()
2463 old = this->boundary[die] + (die * this->density_mask); in flexonenand_set_boundary()
2464 new = boundary + (die * this->density_mask); in flexonenand_set_boundary()
2472 this->command(mtd, FLEXONENAND_CMD_PI_ACCESS, die, 0); in flexonenand_set_boundary()
2473 this->wait(mtd, FL_SYNCING); in flexonenand_set_boundary()
2476 this->command(mtd, FLEXONENAND_CMD_READ_PI, die, 0); in flexonenand_set_boundary()
2477 ret = this->wait(mtd, FL_READING); in flexonenand_set_boundary()
2479 thisboundary = this->read_word(this->base + ONENAND_DATARAM); in flexonenand_set_boundary()
2485 printk(KERN_INFO "flexonenand_set_boundary: Changing die %d boundary: %d%s\n", in flexonenand_set_boundary()
2486 die, boundary, lock ? "(Locked)" : "(Unlocked)"); in flexonenand_set_boundary()
2491 addr = die ? this->diesize[0] : 0; in flexonenand_set_boundary()
2492 this->command(mtd, ONENAND_CMD_ERASE, addr, 0); in flexonenand_set_boundary()
2493 ret = this->wait(mtd, FL_ERASING); in flexonenand_set_boundary()
2496 "Failed PI erase for Die %d\n", die); in flexonenand_set_boundary()
2500 this->write_word(boundary, this->base + ONENAND_DATARAM); in flexonenand_set_boundary()
2501 this->command(mtd, ONENAND_CMD_PROG, addr, 0); in flexonenand_set_boundary()
2502 ret = this->wait(mtd, FL_WRITING); in flexonenand_set_boundary()
2505 "Failed PI write for Die %d\n", die); in flexonenand_set_boundary()
2509 this->command(mtd, FLEXONENAND_CMD_PI_UPDATE, die, 0); in flexonenand_set_boundary()
2510 ret = this->wait(mtd, FL_WRITING); in flexonenand_set_boundary()
2512 this->write_word(ONENAND_CMD_RESET, this->base + ONENAND_REG_COMMAND); in flexonenand_set_boundary()
2513 this->wait(mtd, FL_RESETING); in flexonenand_set_boundary()
2515 /* Recalculate device size on boundary change*/ in flexonenand_set_boundary()
2522 * onenand_chip_probe - [OneNAND Interface] Probe the OneNAND chip
2530 struct onenand_chip *this = mtd->priv; in onenand_chip_probe()
2535 syscfg = this->read_word(this->base + ONENAND_REG_SYS_CFG1); in onenand_chip_probe()
2538 this->write_word((syscfg & ~ONENAND_SYS_CFG1_SYNC_READ), in onenand_chip_probe()
2539 this->base + ONENAND_REG_SYS_CFG1); in onenand_chip_probe()
2542 this->write_word(ONENAND_CMD_READID, this->base + ONENAND_BOOTRAM); in onenand_chip_probe()
2545 bram_maf_id = this->read_word(this->base + ONENAND_BOOTRAM + 0x0); in onenand_chip_probe()
2546 bram_dev_id = this->read_word(this->base + ONENAND_BOOTRAM + 0x2); in onenand_chip_probe()
2549 this->write_word(ONENAND_CMD_RESET, this->base + ONENAND_BOOTRAM); in onenand_chip_probe()
2552 if (this->wait(mtd, FL_RESETING)) in onenand_chip_probe()
2553 return -ENXIO; in onenand_chip_probe()
2556 this->write_word(syscfg, this->base + ONENAND_REG_SYS_CFG1); in onenand_chip_probe()
2560 return -ENXIO; in onenand_chip_probe()
2563 maf_id = this->read_word(this->base + ONENAND_REG_MANUFACTURER_ID); in onenand_chip_probe()
2564 dev_id = this->read_word(this->base + ONENAND_REG_DEVICE_ID); in onenand_chip_probe()
2568 return -ENXIO; in onenand_chip_probe()
2574 * onenand_probe - [OneNAND Interface] Probe the OneNAND device
2582 struct onenand_chip *this = mtd->priv; in onenand_probe()
2587 ret = this->chip_probe(mtd); in onenand_probe()
2592 dev_id = this->read_word(this->base + ONENAND_REG_DEVICE_ID); in onenand_probe()
2593 ver_id = this->read_word(this->base + ONENAND_REG_VERSION_ID); in onenand_probe()
2594 this->technology = this->read_word(this->base + ONENAND_REG_TECHNOLOGY); in onenand_probe()
2597 mtd->name = onenand_print_device_info(dev_id, ver_id); in onenand_probe()
2598 this->device_id = dev_id; in onenand_probe()
2599 this->version_id = ver_id; in onenand_probe()
2606 this->dies = ONENAND_IS_DDP(this) ? 2 : 1; in onenand_probe()
2608 mtd->numeraseregions = this->dies << 1; in onenand_probe()
2609 mtd->eraseregions = malloc(sizeof(struct mtd_erase_region_info) in onenand_probe()
2610 * (this->dies << 1)); in onenand_probe()
2611 if (!mtd->eraseregions) in onenand_probe()
2612 return -ENOMEM; in onenand_probe()
2616 * For Flex-OneNAND, chipsize represents maximum possible device size. in onenand_probe()
2617 * mtd->size represents the actual device size. in onenand_probe()
2619 this->chipsize = (16 << density) << 20; in onenand_probe()
2623 mtd->writesize = in onenand_probe()
2624 this->read_word(this->base + ONENAND_REG_DATA_BUFFER_SIZE); in onenand_probe()
2627 mtd->writesize <<= 1; in onenand_probe()
2629 mtd->oobsize = mtd->writesize >> 5; in onenand_probe()
2631 mtd->erasesize = mtd->writesize << 6; in onenand_probe()
2633 * Flex-OneNAND SLC area has 64 pages per block. in onenand_probe()
2634 * Flex-OneNAND MLC area has 128 pages per block. in onenand_probe()
2638 mtd->erasesize <<= 1; in onenand_probe()
2640 this->erase_shift = ffs(mtd->erasesize) - 1; in onenand_probe()
2641 this->page_shift = ffs(mtd->writesize) - 1; in onenand_probe()
2642 this->ppb_shift = (this->erase_shift - this->page_shift); in onenand_probe()
2643 this->page_mask = (mtd->erasesize / mtd->writesize) - 1; in onenand_probe()
2646 this->density_mask = this->chipsize >> (this->erase_shift + 1); in onenand_probe()
2648 this->writesize = mtd->writesize; in onenand_probe()
2655 mtd->size = this->chipsize; in onenand_probe()
2657 mtd->flags = MTD_CAP_NANDFLASH; in onenand_probe()
2658 mtd->_erase = onenand_erase; in onenand_probe()
2659 mtd->_read_oob = onenand_read_oob; in onenand_probe()
2660 mtd->_write_oob = onenand_write_oob; in onenand_probe()
2661 mtd->_sync = onenand_sync; in onenand_probe()
2662 mtd->_block_isbad = onenand_block_isbad; in onenand_probe()
2663 mtd->_block_markbad = onenand_block_markbad; in onenand_probe()
2664 mtd->writebufsize = mtd->writesize; in onenand_probe()
2670 * onenand_scan - [OneNAND Interface] Scan for the OneNAND device
2682 struct onenand_chip *this = mtd->priv; in onenand_scan()
2684 if (!this->read_word) in onenand_scan()
2685 this->read_word = onenand_readw; in onenand_scan()
2686 if (!this->write_word) in onenand_scan()
2687 this->write_word = onenand_writew; in onenand_scan()
2689 if (!this->command) in onenand_scan()
2690 this->command = onenand_command; in onenand_scan()
2691 if (!this->wait) in onenand_scan()
2692 this->wait = onenand_wait; in onenand_scan()
2693 if (!this->bbt_wait) in onenand_scan()
2694 this->bbt_wait = onenand_bbt_wait; in onenand_scan()
2696 if (!this->read_bufferram) in onenand_scan()
2697 this->read_bufferram = onenand_read_bufferram; in onenand_scan()
2698 if (!this->write_bufferram) in onenand_scan()
2699 this->write_bufferram = onenand_write_bufferram; in onenand_scan()
2701 if (!this->chip_probe) in onenand_scan()
2702 this->chip_probe = onenand_chip_probe; in onenand_scan()
2704 if (!this->block_markbad) in onenand_scan()
2705 this->block_markbad = onenand_default_block_markbad; in onenand_scan()
2706 if (!this->scan_bbt) in onenand_scan()
2707 this->scan_bbt = onenand_default_bbt; in onenand_scan()
2710 return -ENXIO; in onenand_scan()
2713 if (this->mmcontrol) { in onenand_scan()
2715 this->read_bufferram = onenand_sync_read_bufferram; in onenand_scan()
2719 if (!this->page_buf) { in onenand_scan()
2720 this->page_buf = kzalloc(mtd->writesize, GFP_KERNEL); in onenand_scan()
2721 if (!this->page_buf) { in onenand_scan()
2723 return -ENOMEM; in onenand_scan()
2725 this->options |= ONENAND_PAGEBUF_ALLOC; in onenand_scan()
2727 if (!this->oob_buf) { in onenand_scan()
2728 this->oob_buf = kzalloc(mtd->oobsize, GFP_KERNEL); in onenand_scan()
2729 if (!this->oob_buf) { in onenand_scan()
2731 if (this->options & ONENAND_PAGEBUF_ALLOC) { in onenand_scan()
2732 this->options &= ~ONENAND_PAGEBUF_ALLOC; in onenand_scan()
2733 kfree(this->page_buf); in onenand_scan()
2735 return -ENOMEM; in onenand_scan()
2737 this->options |= ONENAND_OOBBUF_ALLOC; in onenand_scan()
2740 this->state = FL_READY; in onenand_scan()
2745 switch (mtd->oobsize) { in onenand_scan()
2747 this->ecclayout = &onenand_oob_128; in onenand_scan()
2748 mtd->subpage_sft = 0; in onenand_scan()
2752 this->ecclayout = &onenand_oob_64; in onenand_scan()
2753 mtd->subpage_sft = 2; in onenand_scan()
2757 this->ecclayout = &onenand_oob_32; in onenand_scan()
2758 mtd->subpage_sft = 1; in onenand_scan()
2763 mtd->oobsize); in onenand_scan()
2764 mtd->subpage_sft = 0; in onenand_scan()
2766 this->ecclayout = &onenand_oob_32; in onenand_scan()
2770 this->subpagesize = mtd->writesize >> mtd->subpage_sft; in onenand_scan()
2776 this->ecclayout->oobavail = 0; in onenand_scan()
2779 this->ecclayout->oobfree[i].length; i++) in onenand_scan()
2780 this->ecclayout->oobavail += in onenand_scan()
2781 this->ecclayout->oobfree[i].length; in onenand_scan()
2782 mtd->oobavail = this->ecclayout->oobavail; in onenand_scan()
2784 mtd->ecclayout = this->ecclayout; in onenand_scan()
2789 return this->scan_bbt(mtd); in onenand_scan()
2793 * onenand_release - [OneNAND Interface] Free resources held by the OneNAND device