23 #include <linux/kernel.h>
24 #include <linux/module.h>
26 #include <linux/slab.h>
28 #include <linux/sched.h>
42 #define MB_ERASE_MIN_BLK_COUNT 2
43 #define MB_ERASE_MAX_BLK_COUNT 64
46 static int flex_bdry[
MAX_DIES * 2] = { -1, 0, -1, 0 };
50 "Syntax:flex_bdry=DIE_BDRY,LOCK,..."
51 "DIE_BDRY: SLC boundary of the die"
52 "LOCK: Locking information for SLC boundary"
53 " : 0->Set boundary in unlocked status"
54 " : 1->Set boundary in locked status");
61 "Syntax : otp=LOCK_TYPE"
62 "LOCK_TYPE : Keys issued, for specific OTP Lock type"
63 " : 0 -> Default (No Blocks Locked)"
64 " : 1 -> OTP Block lock"
65 " : 2 -> 1st Block lock"
66 " : 3 -> BOTH OTP Block and 1st Block lock");
75 6, 7, 8, 9, 10, 11, 12, 13, 14, 15,
76 22, 23, 24, 25, 26, 27, 28, 29, 30, 31,
77 38, 39, 40, 41, 42, 43, 44, 45, 46, 47,
78 54, 55, 56, 57, 58, 59, 60, 61, 62, 63,
79 70, 71, 72, 73, 74, 75, 76, 77, 78, 79,
80 86, 87, 88, 89, 90, 91, 92, 93, 94, 95,
84 {2, 4}, {18, 4}, {34, 4}, {50, 4},
85 {66, 4}, {82, 4}, {98, 4}, {114, 4}
103 7, 8, 9, 10, 11, 12, 13, 14, 15,
104 23, 24, 25, 26, 27, 28, 29, 30, 31,
105 39, 40, 41, 42, 43, 44, 45, 46, 47,
106 55, 56, 57, 58, 59, 60, 61, 62, 63,
107 71, 72, 73, 74, 75, 76, 77, 78, 79,
108 87, 88, 89, 90, 91, 92, 93, 94, 95,
109 103, 104, 105, 106, 107, 108, 109, 110, 111,
113 {2, 3}, {18, 3}, {34, 3}, {50, 3},
114 {66, 3}, {82, 3}, {98, 3}, {114, 3}
130 {2, 3}, {14, 2}, {18, 3}, {30, 2},
131 {34, 3}, {46, 2}, {50, 3}, {62, 2}
144 .oobfree = { {2, 3}, {14, 2}, {18, 3}, {30, 2} }
147 static const unsigned char ffchars[] = {
148 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
149 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
150 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
151 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
152 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
153 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
154 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
155 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
156 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
157 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
158 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
159 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
160 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
161 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
162 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
163 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
172 static unsigned short onenand_readw(
void __iomem *
addr)
200 if (block & this->density_mask)
214 static int onenand_bufferram_address(
struct onenand_chip *
this,
int block)
217 if (block & this->density_mask)
231 static int onenand_page_address(
int page,
int sector)
251 static int onenand_buffer_address(
int dataram1,
int sectors,
int count)
276 unsigned boundary,
blk,
die = 0;
280 addr -= this->diesize[0];
283 boundary = this->boundary[
die];
285 blk = addr >> (this->erase_shift - 1);
287 blk = (blk + boundary + 1) >> 1;
289 blk += die ? this->density_mask : 0;
296 return addr >> this->erase_shift;
297 return flexonenand_block(
this, addr);
307 static loff_t flexonenand_addr(
struct onenand_chip *
this,
int block)
310 int die = 0, boundary;
313 block -= this->density_mask;
315 ofs = this->diesize[0];
318 boundary = this->boundary[
die];
319 ofs += (loff_t)block << (this->erase_shift - 1);
320 if (block > (boundary + 1))
321 ofs += (loff_t)(block - boundary - 1) << (this->erase_shift - 1);
328 return (loff_t)block << this->erase_shift;
329 return flexonenand_addr(
this, block);
339 static inline int onenand_get_density(
int dev_id)
355 if (addr < mtd->eraseregions[i].
offset)
371 static int onenand_command(
struct mtd_info *mtd,
int cmd, loff_t addr,
size_t len)
429 value = onenand_bufferram_address(
this, block);
444 value = onenand_block_address(
this, block);
448 value = onenand_bufferram_address(
this, block);
454 int sectors = 0, count = 0;
476 value = onenand_page_address(page, sectors);
480 value = onenand_buffer_address(dataram, sectors, count);
497 static inline int onenand_read_ecc(
struct onenand_chip *
this)
504 for (i = 0; i < 4; i++) {
539 if (interrupt & flags)
556 int ecc = onenand_read_ecc(
this);
571 __func__, ctrl, interrupt);
576 printk(
KERN_ERR "%s: mb erase timeout! ctrl=0x%04x intr=0x%04x\n",
577 __func__, ctrl, interrupt);
583 __func__, ctrl, interrupt);
624 static int onenand_interrupt_wait(
struct mtd_info *mtd,
int state)
630 return onenand_wait(mtd, state);
640 static int onenand_try_interrupt_wait(
struct mtd_info *mtd,
int state)
643 unsigned long remain, timeout;
646 this->
wait = onenand_interrupt_wait;
652 "We use the normal wait\n");
657 this->
wait = onenand_wait;
660 return onenand_wait(mtd, state);
671 static void onenand_setup_wait(
struct mtd_info *mtd)
678 if (this->irq <= 0) {
679 this->
wait = onenand_wait;
686 this->
wait = onenand_wait;
695 this->
wait = onenand_try_interrupt_wait;
706 static inline int onenand_bufferram_offset(
struct mtd_info *mtd,
int area)
731 static int onenand_read_bufferram(
struct mtd_info *mtd,
int area,
737 bufferram = this->
base + area;
739 bufferram += onenand_bufferram_offset(mtd, area);
748 word = this->
read_word(bufferram + offset + count);
749 buffer[
count] = (word & 0xff);
752 memcpy(buffer, bufferram + offset, count);
767 static int onenand_sync_read_bufferram(
struct mtd_info *mtd,
int area,
768 unsigned char *buffer,
int offset,
size_t count)
773 bufferram = this->
base + area;
775 bufferram += onenand_bufferram_offset(mtd, area);
786 word = this->
read_word(bufferram + offset + count);
787 buffer[
count] = (word & 0xff);
790 memcpy(buffer, bufferram + offset, count);
807 static int onenand_write_bufferram(
struct mtd_info *mtd,
int area,
808 const unsigned char *buffer,
int offset,
size_t count)
813 bufferram = this->
base + area;
815 bufferram += onenand_bufferram_offset(mtd, area);
825 byte_offset = offset +
count;
828 word = this->
read_word(bufferram + byte_offset);
829 word = (word & ~0xff) | buffer[count];
830 this->
write_word(word, bufferram + byte_offset);
833 memcpy(bufferram + offset, buffer, count);
846 static int onenand_get_2x_blockpage(
struct mtd_info *mtd, loff_t addr)
857 blockpage = (block << 7) | page;
870 static int onenand_check_bufferram(
struct mtd_info *mtd, loff_t addr)
873 int blockpage, found = 0;
877 blockpage = onenand_get_2x_blockpage(mtd, addr);
883 if (this->bufferram[i].blockpage == blockpage)
888 if (this->bufferram[i].blockpage == blockpage) {
897 int value = onenand_bufferram_address(
this, block);
912 static void onenand_update_bufferram(
struct mtd_info *mtd, loff_t addr,
920 blockpage = onenand_get_2x_blockpage(mtd, addr);
926 if (this->bufferram[i].blockpage == blockpage)
927 this->bufferram[
i].blockpage = -1;
932 this->bufferram[
i].blockpage = blockpage;
934 this->bufferram[
i].blockpage = -1;
945 static void onenand_invalidate_bufferram(
struct mtd_info *mtd, loff_t addr,
950 loff_t end_addr = addr + len;
955 if (buf_addr >= addr && buf_addr < end_addr)
956 this->bufferram[
i].blockpage = -1;
1004 static void onenand_release_device(
struct mtd_info *mtd)
1029 int readcol = column;
1030 int readend = column + thislen;
1033 uint8_t *oob_buf = this->oob_buf;
1035 free = this->ecclayout->oobfree;
1037 if (readcol >= lastgap)
1038 readcol += free->
offset - lastgap;
1039 if (readend >= lastgap)
1040 readend += free->
offset - lastgap;
1044 free = this->ecclayout->oobfree;
1047 if (free->
offset < readend && free_end > readcol) {
1049 int ed =
min_t(
int,free_end,readend);
1051 memcpy(buf, oob_buf + st, n);
1053 }
else if (column == 0)
1072 static int onenand_recover_lsb(
struct mtd_info *mtd, loff_t addr,
int status)
1087 if (mtd->
eraseregions[i].erasesize < (1 << this->erase_shift))
1093 printk(
KERN_INFO "%s: Attempting to recover from uncorrectable read\n",
1111 static int onenand_mlc_read_ops_nolock(
struct mtd_info *mtd, loff_t
from,
1116 size_t len = ops->
len;
1117 size_t ooblen = ops->
ooblen;
1120 int read = 0, column, thislen;
1121 int oobread = 0, oobcolumn, thisooblen, oobsize;
1123 int writesize = this->writesize;
1125 pr_debug(
"%s: from = 0x%08x, len = %i\n", __func__, (
unsigned int)from,
1129 oobsize = this->ecclayout->oobavail;
1133 oobcolumn = from & (mtd->
oobsize - 1);
1136 if (from + len > mtd->
size) {
1146 while (read < len) {
1149 thislen =
min_t(
int, writesize, len - read);
1151 column = from & (writesize - 1);
1152 if (column + thislen > writesize)
1153 thislen = writesize - column;
1155 if (!onenand_check_bufferram(mtd, from)) {
1160 ret = onenand_recover_lsb(mtd, from, ret);
1161 onenand_update_bufferram(mtd, from, !ret);
1162 if (mtd_is_eccerr(ret))
1170 thisooblen = oobsize - oobcolumn;
1171 thisooblen =
min_t(
int, thisooblen, ooblen - oobread);
1174 onenand_transfer_auto_oob(mtd, oobbuf, oobcolumn, thisooblen);
1176 this->read_bufferram(mtd,
ONENAND_SPARERAM, oobbuf, oobcolumn, thisooblen);
1177 oobread += thisooblen;
1178 oobbuf += thisooblen;
1216 static int onenand_read_ops_nolock(
struct mtd_info *mtd, loff_t from,
1221 size_t len = ops->
len;
1222 size_t ooblen = ops->
ooblen;
1225 int read = 0, column, thislen;
1226 int oobread = 0, oobcolumn, thisooblen, oobsize;
1227 int ret = 0, boundary = 0;
1228 int writesize = this->writesize;
1230 pr_debug(
"%s: from = 0x%08x, len = %i\n", __func__, (
unsigned int)from,
1234 oobsize = this->ecclayout->oobavail;
1238 oobcolumn = from & (mtd->
oobsize - 1);
1241 if ((from + len) > mtd->
size) {
1255 if (!onenand_check_bufferram(mtd, from)) {
1258 onenand_update_bufferram(mtd, from, !ret);
1259 if (mtd_is_eccerr(ret))
1264 thislen =
min_t(
int, writesize, len - read);
1265 column = from & (writesize - 1);
1266 if (column + thislen > writesize)
1267 thislen = writesize - column;
1272 if (read + thislen < len) {
1280 unlikely(from == (this->chipsize >> 1))) {
1292 thisooblen = oobsize - oobcolumn;
1293 thisooblen =
min_t(
int, thisooblen, ooblen - oobread);
1296 onenand_transfer_auto_oob(mtd, oobbuf, oobcolumn, thisooblen);
1298 this->read_bufferram(mtd,
ONENAND_SPARERAM, oobbuf, oobcolumn, thisooblen);
1299 oobread += thisooblen;
1300 oobbuf += thisooblen;
1313 thislen =
min_t(
int, writesize, len - read);
1318 onenand_update_bufferram(mtd, from, !ret);
1319 if (mtd_is_eccerr(ret))
1349 static int onenand_read_oob_nolock(
struct mtd_info *mtd, loff_t from,
1354 int read = 0, thislen, column, oobsize;
1355 size_t len = ops->
ooblen;
1358 int ret = 0, readcmd;
1362 pr_debug(
"%s: from = 0x%08x, len = %i\n", __func__, (
unsigned int)from,
1369 oobsize = this->ecclayout->oobavail;
1373 column = from & (mtd->
oobsize - 1);
1383 column + len > ((mtd->
size >> this->page_shift) -
1384 (from >> this->page_shift)) * oobsize)) {
1394 while (read < len) {
1397 thislen = oobsize - column;
1398 thislen =
min_t(
int, thislen, len);
1402 onenand_update_bufferram(mtd, from, 0);
1406 ret = onenand_recover_lsb(mtd, from, ret);
1408 if (ret && !mtd_is_eccerr(ret)) {
1415 onenand_transfer_auto_oob(mtd, buf, column, thislen);
1455 static int onenand_read(
struct mtd_info *mtd, loff_t from,
size_t len,
1456 size_t *retlen,
u_char *buf)
1469 onenand_mlc_read_ops_nolock(mtd, from, &ops) :
1470 onenand_read_ops_nolock(mtd, from, &ops);
1471 onenand_release_device(mtd);
1485 static int onenand_read_oob(
struct mtd_info *mtd, loff_t from,
1491 switch (ops->
mode) {
1504 onenand_mlc_read_ops_nolock(mtd, from, ops) :
1505 onenand_read_ops_nolock(mtd, from, ops);
1507 ret = onenand_read_oob_nolock(mtd, from, ops);
1508 onenand_release_device(mtd);
1520 static int onenand_bbt_wait(
struct mtd_info *mtd,
int state)
1523 unsigned long timeout;
1530 if (interrupt & ONENAND_INT_MASTER)
1539 if (interrupt & ONENAND_INT_READ) {
1540 ecc = onenand_read_ecc(
this);
1543 "intr 0x%04x addr1 %#x addr8 %#x\n",
1544 __func__, ecc, ctrl, interrupt, addr1, addr8);
1549 "intr 0x%04x addr1 %#x addr8 %#x\n",
1550 __func__, ctrl, interrupt, addr1, addr8);
1555 if (ctrl & ONENAND_CTRL_ERROR) {
1557 "addr8 %#x\n", __func__, ctrl, interrupt, addr1, addr8);
1576 int read = 0, thislen, column;
1577 int ret = 0, readcmd;
1578 size_t len = ops->
ooblen;
1581 pr_debug(
"%s: from = 0x%08x, len = %zi\n", __func__, (
unsigned int)from,
1597 column = from & (mtd->
oobsize - 1);
1601 while (read < len) {
1604 thislen = mtd->
oobsize - column;
1605 thislen =
min_t(
int, thislen, len);
1609 onenand_update_bufferram(mtd, from, 0);
1613 ret = onenand_recover_lsb(mtd, from, ret);
1634 onenand_release_device(mtd);
1640 #ifdef CONFIG_MTD_ONENAND_VERIFY_WRITE
1656 onenand_update_bufferram(mtd, to, 0);
1662 for (i = 0; i < mtd->
oobsize; i++)
1663 if (buf[i] != 0xFF && buf[i] != oob_buf[i])
1680 int thislen, column;
1682 column = addr & (this->writesize - 1);
1685 thislen =
min_t(
int, this->writesize - column, len);
1689 onenand_update_bufferram(mtd, addr, 0);
1695 onenand_update_bufferram(mtd, addr, 1);
1699 if (
memcmp(buf, this->verify_buf + column, thislen))
1711 #define onenand_verify(...) (0)
1712 #define onenand_verify_oob(...) (0)
1715 #define NOTALIGNED(x) ((x & (this->subpagesize - 1)) != 0)
1717 static void onenand_panic_wait(
struct mtd_info *mtd)
1723 for (i = 0; i < 2000; i++) {
1725 if (interrupt & ONENAND_INT_MASTER)
1741 static int onenand_panic_write(
struct mtd_info *mtd, loff_t to,
size_t len,
1742 size_t *retlen,
const u_char *buf)
1745 int column, subpage;
1753 onenand_panic_wait(mtd);
1755 pr_debug(
"%s: to = 0x%08x, len = %i\n", __func__, (
unsigned int)to,
1768 while (written < len) {
1769 int thislen =
min_t(
int, mtd->
writesize - column, len - written);
1787 onenand_panic_wait(mtd);
1790 onenand_update_bufferram(mtd, to, !ret && !subpage);
1793 onenand_update_bufferram(mtd, to + this->writesize, !ret && !subpage);
1823 static int onenand_fill_auto_oob(
struct mtd_info *mtd,
u_char *oob_buf,
1824 const u_char *buf,
int column,
int thislen)
1828 int writecol = column;
1829 int writeend = column + thislen;
1833 free = this->ecclayout->oobfree;
1835 if (writecol >= lastgap)
1836 writecol += free->
offset - lastgap;
1837 if (writeend >= lastgap)
1838 writeend += free->
offset - lastgap;
1841 free = this->ecclayout->oobfree;
1844 if (free->
offset < writeend && free_end > writecol) {
1846 int ed =
min_t(
int,free_end,writeend);
1848 memcpy(oob_buf + st, buf, n);
1850 }
else if (column == 0)
1864 static int onenand_write_ops_nolock(
struct mtd_info *mtd, loff_t to,
1868 int written = 0, column, thislen = 0, subpage = 0;
1869 int prev = 0, prevlen = 0, prev_subpage = 0,
first = 1;
1870 int oobwritten = 0, oobcolumn, thisooblen, oobsize;
1871 size_t len = ops->
len;
1872 size_t ooblen = ops->
ooblen;
1878 pr_debug(
"%s: to = 0x%08x, len = %i\n", __func__, (
unsigned int)to,
1901 oobcolumn = to & (mtd->
oobsize - 1);
1907 if (written < len) {
1911 thisooblen =
min_t(
int, oobsize - oobcolumn, ooblen - oobwritten);
1934 onenand_fill_auto_oob(mtd, oobbuf, oob, oobcolumn, thisooblen);
1936 memcpy(oobbuf + oobcolumn, oob, thisooblen);
1938 oobwritten += thisooblen;
1942 oobbuf = (
u_char *) ffchars;
1958 onenand_update_bufferram(mtd, prev, !ret && !prev_subpage);
1966 if (written == len) {
1985 ((written + thislen) < len)) {
1999 onenand_update_bufferram(mtd, to, !ret && !subpage);
2023 prev_subpage = subpage;
2033 onenand_invalidate_bufferram(mtd, 0, -1);
2053 static int onenand_write_oob_nolock(
struct mtd_info *mtd, loff_t to,
2057 int column, ret = 0, oobsize;
2058 int written = 0, oobcmd;
2060 size_t len = ops->
ooblen;
2062 unsigned int mode = ops->
mode;
2066 pr_debug(
"%s: to = 0x%08x, len = %i\n", __func__, (
unsigned int)to,
2077 column = to & (mtd->
oobsize - 1);
2086 if (
unlikely(column + len > oobsize)) {
2094 column + len > ((mtd->
size >> this->page_shift) -
2095 (to >> this->page_shift)) * oobsize)) {
2106 while (written < len) {
2107 int thislen =
min_t(
int, oobsize, len - written);
2117 onenand_fill_auto_oob(mtd, oobbuf, buf, column, thislen);
2119 memcpy(oobbuf + column, buf, thislen);
2131 onenand_update_bufferram(mtd, to, 0);
2134 onenand_update_bufferram(mtd, to + this->writesize, 0);
2174 static int onenand_write(
struct mtd_info *mtd, loff_t to,
size_t len,
2175 size_t *retlen,
const u_char *buf)
2180 .datbuf = (
u_char *) buf,
2186 ret = onenand_write_ops_nolock(mtd, to, &ops);
2187 onenand_release_device(mtd);
2199 static int onenand_write_oob(
struct mtd_info *mtd, loff_t to,
2204 switch (ops->
mode) {
2216 ret = onenand_write_ops_nolock(mtd, to, ops);
2218 ret = onenand_write_oob_nolock(mtd, to, ops);
2219 onenand_release_device(mtd);
2233 static int onenand_block_isbad_nolock(
struct mtd_info *mtd, loff_t ofs,
int allowbbt)
2239 return bbm->
isbad_bbt(mtd, ofs, allowbbt);
2243 static int onenand_multiblock_erase_verify(
struct mtd_info *mtd,
2247 loff_t addr = instr->
addr;
2248 int len = instr->
len;
2276 static int onenand_multiblock_erase(
struct mtd_info *mtd,
2278 unsigned int block_size)
2281 loff_t addr = instr->
addr;
2282 int len = instr->
len;
2290 loff_t bdry_addr = this->
chipsize >> 1;
2291 if (addr < bdry_addr && (addr + len) > bdry_addr)
2298 if (onenand_block_isbad_nolock(mtd, addr, 0)) {
2300 "at addr 0x%012llx\n",
2301 __func__, (
unsigned long long) addr);
2318 verify_instr.
len = 0;
2322 int this_block = (addr >> this->erase_shift);
2324 if (this_block < bdry_block) {
2325 max_eb_count =
min(max_eb_count,
2326 (bdry_block - this_block));
2332 while (len > block_size && eb_count < (max_eb_count - 1)) {
2335 onenand_invalidate_bufferram(mtd, addr, block_size);
2340 "block %d\n", __func__,
2355 onenand_invalidate_bufferram(mtd, addr, block_size);
2373 if (onenand_multiblock_erase_verify(mtd, &verify_instr)) {
2393 static int onenand_block_by_block_erase(
struct mtd_info *mtd,
2396 unsigned int block_size)
2399 loff_t addr = instr->
addr;
2400 int len = instr->
len;
2401 loff_t region_end = 0;
2416 if (onenand_block_isbad_nolock(mtd, addr, 0)) {
2418 "at addr 0x%012llx\n",
2419 __func__, (
unsigned long long) addr);
2426 onenand_invalidate_bufferram(mtd, addr, block_size);
2441 if (region && addr == region_end) {
2449 if (len & (block_size - 1)) {
2471 loff_t addr = instr->
addr;
2472 loff_t len = instr->
len;
2475 loff_t region_offset = 0;
2477 pr_debug(
"%s: start=0x%012llx, len=%llu\n", __func__,
2478 (
unsigned long long)instr->
addr,
2479 (
unsigned long long)instr->
len);
2491 region_offset = region->
offset;
2493 block_size = 1 << this->erase_shift;
2496 if (
unlikely((addr - region_offset) & (block_size - 1))) {
2502 if (
unlikely(len & (block_size - 1))) {
2513 ret = onenand_block_by_block_erase(mtd, instr,
2514 region, block_size);
2516 ret = onenand_multiblock_erase(mtd, instr, block_size);
2520 onenand_release_device(mtd);
2537 static void onenand_sync(
struct mtd_info *mtd)
2539 pr_debug(
"%s: called\n", __func__);
2545 onenand_release_device(mtd);
2555 static int onenand_block_isbad(
struct mtd_info *mtd, loff_t ofs)
2560 if (ofs > mtd->
size)
2564 ret = onenand_block_isbad_nolock(mtd, ofs, 0);
2565 onenand_release_device(mtd);
2577 static int onenand_default_block_markbad(
struct mtd_info *mtd, loff_t ofs)
2593 bbm->
bbt[block >> 2] |= 0x01 << ((block & 0x03) << 1);
2601 return onenand_write_oob_nolock(mtd, ofs, &ops);
2611 static int onenand_block_markbad(
struct mtd_info *mtd, loff_t ofs)
2615 ret = onenand_block_isbad(mtd, ofs);
2625 onenand_release_device(mtd);
2638 static int onenand_do_lock_cmd(
struct mtd_info *mtd, loff_t ofs,
size_t len,
int cmd)
2659 this->
command(mtd, cmd, 0, 0);
2671 if (!(status & wp_status_mask))
2679 for (block = start; block < end + 1; block++) {
2681 value = onenand_block_address(
this, block);
2684 value = onenand_bufferram_address(
this, block);
2689 this->
command(mtd, cmd, 0, 0);
2696 & ONENAND_CTRL_ONGO)
2701 if (!(status & wp_status_mask))
2703 __func__, block, status);
2723 onenand_release_device(mtd);
2741 onenand_release_device(mtd);
2751 static int onenand_check_lock_status(
struct onenand_chip *
this)
2757 for (block = 0; block <
end; block++) {
2759 value = onenand_block_address(
this, block);
2762 value = onenand_bufferram_address(
this, block);
2771 __func__, block, status);
2785 static void onenand_unlock_all(
struct mtd_info *mtd)
2789 loff_t len = mtd->
size;
2802 & ONENAND_CTRL_ONGO)
2810 if (onenand_check_lock_status(
this))
2824 #ifdef CONFIG_MTD_ONENAND_OTP
2833 static int onenand_otp_command(
struct mtd_info *mtd,
int cmd, loff_t addr,
2842 block = (
int) (addr >> this->erase_shift);
2847 block = (
int) (addr >> this->erase_shift);
2854 if (addr & this->writesize)
2864 value = onenand_block_address(
this, block);
2871 int sectors = 4, count = 4;
2883 value = onenand_page_address(page, sectors);
2888 value = onenand_buffer_address(dataram, sectors, count);
2911 static int onenand_otp_write_oob_nolock(
struct mtd_info *mtd, loff_t to,
2915 int column, ret = 0, oobsize;
2918 size_t len = ops->
ooblen;
2929 column = to & (mtd->
oobsize - 1);
2934 while (written < len) {
2935 int thislen =
min_t(
int, oobsize, len - written);
2939 block = (
int) (to >> this->erase_shift);
2945 value = onenand_block_address(
this, block);
2954 value = onenand_bufferram_address(
this, block);
2967 memcpy(oobbuf + column, buf, thislen);
2979 onenand_update_bufferram(mtd, to, 0);
2982 onenand_update_bufferram(mtd, to + this->writesize, 0);
2998 if (status == 0x60) {
3002 }
else if (status == 0x20) {
3006 }
else if (status == 0x40) {
3029 typedef int (*otp_op_t)(
struct mtd_info *mtd, loff_t
form,
size_t len,
3042 static int do_otp_read(
struct mtd_info *mtd, loff_t from,
size_t len,
3043 size_t *retlen,
u_char *buf)
3059 onenand_mlc_read_ops_nolock(mtd, from, &ops) :
3060 onenand_read_ops_nolock(mtd, from, &ops);
3079 static int do_otp_write(
struct mtd_info *mtd, loff_t to,
size_t len,
3080 size_t *retlen,
u_char *buf)
3083 unsigned char *pbuf =
buf;
3088 if (len < mtd->writesize) {
3089 memcpy(this->page_buf, buf, len);
3091 pbuf = this->page_buf;
3103 ret = onenand_write_ops_nolock(mtd, to, &ops);
3123 static int do_otp_lock(
struct mtd_info *mtd, loff_t from,
size_t len,
3124 size_t *retlen,
u_char *buf)
3143 ret = onenand_write_ops_nolock(mtd, mtd->
writesize * 49, &ops);
3154 ret = onenand_otp_write_oob_nolock(mtd, from, &ops);
3173 static int onenand_otp_walk(
struct mtd_info *mtd, loff_t from,
size_t len,
3174 size_t *retlen,
u_char *buf,
3175 otp_op_t
action,
int mode)
3184 density = onenand_get_density(this->
device_id);
3197 if (mtd->
writesize * otp_pages < from + len)
3205 while (len > 0 && otp_pages > 0) {
3222 *retlen +=
sizeof(
struct otp_info);
3226 ret =
action(mtd, from, len, &tmp_retlen, buf);
3230 *retlen += tmp_retlen;
3237 onenand_release_device(mtd);
3250 static int onenand_get_fact_prot_info(
struct mtd_info *mtd,
3258 return ret ? : retlen;
3271 static int onenand_read_fact_prot_reg(
struct mtd_info *mtd, loff_t from,
3272 size_t len,
size_t *retlen,
u_char *buf)
3274 return onenand_otp_walk(mtd, from, len, retlen, buf, do_otp_read,
MTD_OTP_FACTORY);
3285 static int onenand_get_user_prot_info(
struct mtd_info *mtd,
3293 return ret ? : retlen;
3306 static int onenand_read_user_prot_reg(
struct mtd_info *mtd, loff_t from,
3307 size_t len,
size_t *retlen,
u_char *buf)
3309 return onenand_otp_walk(mtd, from, len, retlen, buf, do_otp_read,
MTD_OTP_USER);
3322 static int onenand_write_user_prot_reg(
struct mtd_info *mtd, loff_t from,
3323 size_t len,
size_t *retlen,
u_char *buf)
3325 return onenand_otp_walk(mtd, from, len, retlen, buf, do_otp_write,
MTD_OTP_USER);
3336 static int onenand_lock_user_prot_reg(
struct mtd_info *mtd, loff_t from,
3368 buf[otp_lock_offset] = 0xFC;
3370 buf[otp_lock_offset] = 0xF3;
3372 buf[otp_lock_offset] = 0xF0;
3376 ret = onenand_otp_walk(mtd, from, len, &retlen, buf, do_otp_lock,
MTD_OTP_USER);
3378 return ret ? : retlen;
3391 static void onenand_check_features(
struct mtd_info *mtd)
3394 unsigned int density, process, numbufs;
3397 density = onenand_get_density(this->
device_id);
3406 else if (numbufs == 1) {
3451 this->
options &= ~ONENAND_HAS_CONT_LOCK;
3455 if (this->
options & ONENAND_HAS_CONT_LOCK)
3457 if (this->
options & ONENAND_HAS_UNLOCK_ALL)
3474 static void onenand_print_device_info(
int device,
int version)
3476 int vcc, demuxed, ddp, density, flexonenand;
3481 density = onenand_get_density(device);
3484 demuxed ?
"" :
"Muxed ",
3485 flexonenand ?
"Flex-" :
"",
3488 vcc ?
"2.65/3.3" :
"1.8",
3504 static int onenand_check_maf(
int manuf)
3510 for (i = 0; i <
size; i++)
3511 if (manuf == onenand_manuf_ids[i].
id)
3515 name = onenand_manuf_ids[
i].
name;
3528 static int flexonenand_get_boundary(
struct mtd_info *mtd)
3538 for (die = 0; die < this->
dies; die++) {
3556 this->boundary[die], locked ?
"(Locked)" :
"(Unlocked)");
3569 static void flexonenand_get_size(
struct mtd_info *mtd)
3572 int die,
i, eraseshift, density;
3573 int blksperdie, maxbdry;
3576 density = onenand_get_density(this->
device_id);
3577 blksperdie = ((loff_t)(16 << density) << 20) >> (this->erase_shift);
3579 maxbdry = blksperdie - 1;
3580 eraseshift = this->erase_shift - 1;
3585 flexonenand_get_boundary(mtd);
3588 for (; die < this->
dies; die++) {
3589 if (!die || this->boundary[die-1] != maxbdry) {
3594 this->boundary[
die] + 1;
3600 this->boundary[
die] + 1;
3601 ofs += (this->boundary[
die] + 1) << (eraseshift - 1);
3603 if (this->boundary[die] != maxbdry) {
3608 this->boundary[
die];
3623 " numblocks: %04u]\n",
3628 for (die = 0, mtd->
size = 0; die < this->dies; die++) {
3629 this->
diesize[
die] = (loff_t)blksperdie << this->erase_shift;
3630 this->
diesize[
die] -= (loff_t)(this->boundary[die] + 1)
3631 << (this->erase_shift - 1);
3650 static int flexonenand_check_blocks_erased(
struct mtd_info *mtd,
int start,
int end)
3660 .oobbuf = this->oob_buf,
3666 for (block = start; block <=
end; block++) {
3667 addr = flexonenand_addr(
this, block);
3668 if (onenand_block_isbad_nolock(mtd, addr, 0))
3675 ret = onenand_read_oob_nolock(mtd, addr, &ops);
3679 for (i = 0; i < mtd->
oobsize; i++)
3680 if (this->oob_buf[i] != 0xff)
3697 static int flexonenand_set_boundary(
struct mtd_info *mtd,
int die,
3698 int boundary,
int lock)
3701 int ret, density, blksperdie, old,
new, thisboundary;
3709 if (boundary < 0 || boundary == this->boundary[die])
3712 density = onenand_get_density(this->
device_id);
3713 blksperdie = ((16 << density) << 20) >> this->
erase_shift;
3716 if (boundary >= blksperdie) {
3718 "Boundary not changed.\n", __func__);
3725 ret = flexonenand_check_blocks_erased(mtd,
min(old,
new) + 1,
max(old,
new));
3728 "before boundary change\n", __func__);
3747 die, boundary, lock ?
"(Locked)" :
"(Unlocked)");
3749 addr = die ? this->
diesize[0] : 0;
3778 flexonenand_get_size(mtd);
3790 static int onenand_chip_probe(
struct mtd_info *mtd)
3793 int bram_maf_id, bram_dev_id, maf_id,
dev_id;
3817 if (onenand_check_maf(bram_maf_id))
3825 if (maf_id != bram_maf_id || dev_id != bram_dev_id)
3835 static int onenand_probe(
struct mtd_info *mtd)
3838 int maf_id,
dev_id, ver_id;
3853 onenand_print_device_info(dev_id, ver_id);
3858 onenand_check_features(mtd);
3860 density = onenand_get_density(dev_id);
3875 this->
chipsize = (16 << density) << 20;
3900 this->density_mask = this->
chipsize >> (this->erase_shift + 1);
3907 flexonenand_get_size(mtd);
3929 static int onenand_suspend(
struct mtd_info *mtd)
3938 static void onenand_resume(
struct mtd_info *mtd)
3943 onenand_release_device(mtd);
3946 "in suspended state\n", __func__);
3970 this->
command = onenand_command;
3972 onenand_setup_wait(mtd);
3991 if (onenand_probe(mtd))
4008 #ifdef CONFIG_MTD_ONENAND_VERIFY_WRITE
4010 if (!this->verify_buf) {
4017 if (!this->oob_buf) {
4019 if (!this->oob_buf) {
4023 this->
options &= ~ONENAND_PAGEBUF_ALLOC;
4079 this->ecclayout->oobfree[i].length;
4080 mtd->
oobavail = this->ecclayout->oobavail;
4088 mtd->
_erase = onenand_erase;
4091 mtd->
_read = onenand_read;
4092 mtd->
_write = onenand_write;
4096 #ifdef CONFIG_MTD_ONENAND_OTP
4104 mtd->
_sync = onenand_sync;
4105 mtd->
_lock = onenand_lock;
4106 mtd->
_unlock = onenand_unlock;
4108 mtd->
_resume = onenand_resume;
4124 flexonenand_set_boundary(mtd, i, flex_bdry[2 * i],
4125 flex_bdry[(2 * i) + 1]);
4149 kfree(this->page_buf);
4150 #ifdef CONFIG_MTD_ONENAND_VERIFY_WRITE
4151 kfree(this->verify_buf);
4155 kfree(this->oob_buf);