Skip to content

Instantly share code, notes, and snippets.

@erikcas
Created April 27, 2013 18:37
Show Gist options
  • Save erikcas/5474123 to your computer and use it in GitHub Desktop.
Save erikcas/5474123 to your computer and use it in GitHub Desktop.
Ouano's patch applied drivers/mtd/devices/msm_nand.c
@@ -17,7 +17,6 @@
17 17 #include <linux/kernel.h>
18 18 #include <linux/module.h>
19 19 #include <linux/mtd/mtd.h>
20 -#include <linux/mtd/nand.h>
21 20 #include <linux/mtd/partitions.h>
22 21 #include <linux/platform_device.h>
23 22 #include <linux/sched.h>
... ... @@ -62,7 +61,7 @@
62 61 #define FLASH_READ_ONFI_PARAMETERS_COMMAND 0xEC
63 62 #define FLASH_READ_ONFI_PARAMETERS_ADDRESS 0x00
64 63
65 -#define VERBOSE 0
64 +#define VERBOSE 1
66 65
67 66 struct msm_nand_chip {
68 67 struct device *dev;
... ... @@ -78,6 +77,10 @@
78 77 unsigned cw_size;
79 78 };
80 79
80 +struct mtd_info *current_mtd = NULL;
81 +unsigned param_start_block;
82 +unsigned param_end_block;
83 +
81 84 #define CFG1_WIDE_FLASH (1U << 1)
82 85
83 86 /* TODO: move datamover code out */
... ... @@ -88,7 +91,7 @@
88 91 #define DST_CRCI_NAND_DATA CMD_DST_CRCI(DMOV_NAND_CRCI_DATA)
89 92
90 93 #define msm_virt_to_dma(chip, vaddr) \
91 - ((chip)->dma_addr + \
94 + ((void)(*(vaddr)), (chip)->dma_addr + \
92 95 ((uint8_t *)(vaddr) - (chip)->dma_buffer))
93 96
94 97 /**
... ... @@ -200,6 +203,58 @@
200 203 }
201 204 };
202 205
206 +/*
207 + * flexonenand_oob_128 - oob info for Flex-Onenand with 4KB page
208 + * For now, we expose only 64 out of 80 ecc bytes
209 + */
210 +static struct nand_ecclayout msm_flexonenand_oob_128 = {
211 + .eccbytes = 64,
212 + .eccpos = {
213 + 6, 7, 8, 9, 10, 11, 12, 13, 14, 15,
214 + 22, 23, 24, 25, 26, 27, 28, 29, 30, 31,
215 + 38, 39, 40, 41, 42, 43, 44, 45, 46, 47,
216 + 54, 55, 56, 57, 58, 59, 60, 61, 62, 63,
217 + 70, 71, 72, 73, 74, 75, 76, 77, 78, 79,
218 + 86, 87, 88, 89, 90, 91, 92, 93, 94, 95,
219 + 102, 103, 104, 105
220 + },
221 + .oobavail = 32,
222 + .oobfree = {
223 + {2, 4}, {18, 4}, {34, 4}, {50, 4},
224 + {66, 4}, {82, 4}, {98, 4}, {114, 4}
225 + }
226 +};
227 +
228 +/*
229 + * onenand_oob_128 - oob info for OneNAND with 4KB page
230 + *
231 + * Based on specification:
232 + * 4Gb M-die OneNAND Flash (KFM4G16Q4M, KFN8G16Q4M). Rev. 1.3, Apr. 2010
233 + *
234 + * For eccpos we expose only 64 bytes out of 72 (see struct nand_ecclayout)
235 + *
236 + * oobfree uses the spare area fields marked as
237 + * "Managed by internal ECC logic for Logical Sector Number area"
238 + */
239 +static struct nand_ecclayout msm_onenand_oob_128 = {
240 + .eccbytes = 64,
241 + .eccpos = {
242 + 7, 8, 9, 10, 11, 12, 13, 14, 15,
243 + 23, 24, 25, 26, 27, 28, 29, 30, 31,
244 + 39, 40, 41, 42, 43, 44, 45, 46, 47,
245 + 55, 56, 57, 58, 59, 60, 61, 62, 63,
246 + 71, 72, 73, 74, 75, 76, 77, 78, 79,
247 + 87, 88, 89, 90, 91, 92, 93, 94, 95,
248 + 103, 104, 105, 106, 107, 108, 109, 110, 111,
249 + 119
250 + },
251 + .oobavail = 24,
252 + .oobfree = {
253 + {2, 3}, {18, 3}, {34, 3}, {50, 3},
254 + {66, 3}, {82, 3}, {98, 3}, {114, 3}
255 + }
256 +};
257 +
203 258 /**
204 259 * msm_onenand_oob_64 - oob info for large (2KB) page
205 260 */
206 261
207 262
... ... @@ -427,14 +482,35 @@
427 482
428 483 struct flash_identification {
429 484 uint32_t flash_id;
485 + uint32_t mask;
430 486 uint32_t density;
431 487 uint32_t widebus;
432 488 uint32_t pagesize;
433 489 uint32_t blksize;
434 490 uint32_t oobsize;
435 491 uint32_t ecc_correctability;
436 -} supported_flash;
492 +};
437 493
494 +static struct flash_identification supported_flash[] =
495 +{
496 + /* Flash ID ID Mask Density(MB) Wid Pgsz Blksz oobsz Manuf */
497 + {0x00000000, 0xFFFFFFFF, 0, 0, 0, 0, 0, }, /*ONFI*/
498 + {0x5590bc2c, 0xFFFFFFFF, (512<<20), 1, 2048, (2048<<6), 64, }, /*Micr*/
499 + {0x1500aaec, 0xFF00FFFF, (256<<20), 0, 2048, (2048<<6), 64, }, /*Sams*/
500 + {0x5500baec, 0xFF00FFFF, (256<<20), 1, 2048, (2048<<6), 64, }, /*Sams*/
501 + {0x6600bcec, 0xFF00FFFF, (512<<20), 1, 4096, (4096<<6), 128,}, /*Sams*/
502 + {0x1500aa98, 0xFFFFFFFF, (256<<20), 0, 2048, (2048<<6), 64, }, /*Tosh*/
503 + {0x5500ba98, 0xFFFFFFFF, (256<<20), 1, 2048, (2048<<6), 64, }, /*Tosh*/
504 + {0xd580b12c, 0xFFFFFFFF, (128<<20), 1, 2048, (2048<<6), 64, }, /*Micr*/
505 + {0x5580baad, 0xFFFFFFFF, (256<<20), 1, 2048, (2048<<6), 64, }, /*Hynx*/
506 + {0x5510baad, 0xFFFFFFFF, (256<<20), 1, 2048, (2048<<6), 64, }, /*Hynx*/
507 + {0x1590ac2c, 0xFFFFFFFF, (512<<20), 1, 2048, (2048<<6), 64, }, /*Micr*/
508 + {0x6601b3ec, 0xFF00FFFF, (1024<<20), 1, 4096, (4096<<6), 128,}, /*Sams*/
509 + {0x55d1b32c, 0xFFFFFFFF, (1024<<20), 1, 2048, (2048<<6), 64, }, /*Micr*/
510 + /* Note: Width flag is 0 for 8 bit Flash and 1 for 16 bit flash */
511 + /* Note: The First row will be filled at runtime during ONFI probe */
512 +};
513 +
438 514 uint16_t flash_onfi_crc_check(uint8_t *buffer, uint16_t count)
439 515 {
440 516 int i;
441 517
442 518
443 519
444 520
445 521
446 522
... ... @@ -726,26 +802,26 @@
726 802 err = -EIO;
727 803 break;
728 804 } else {
729 - supported_flash.flash_id =
805 + supported_flash[0].flash_id =
730 806 flash_read_id(chip);
731 - supported_flash.widebus =
807 + supported_flash[0].widebus =
732 808 onfi_param_page_ptr->
733 809 features_supported & 0x01;
734 - supported_flash.pagesize =
810 + supported_flash[0].pagesize =
735 811 onfi_param_page_ptr->
736 812 number_of_data_bytes_per_page;
737 - supported_flash.blksize =
813 + supported_flash[0].blksize =
738 814 onfi_param_page_ptr->
739 815 number_of_pages_per_block *
740 - supported_flash.pagesize;
741 - supported_flash.oobsize =
816 + supported_flash[0].pagesize;
817 + supported_flash[0].oobsize =
742 818 onfi_param_page_ptr->
743 819 number_of_spare_bytes_per_page;
744 - supported_flash.density =
820 + supported_flash[0].density =
745 821 onfi_param_page_ptr->
746 822 number_of_blocks_per_logical_unit
747 - * supported_flash.blksize;
748 - supported_flash.ecc_correctability =
823 + * supported_flash[0].blksize;
824 + supported_flash[0].ecc_correctability =
749 825 onfi_param_page_ptr->
750 826 number_of_bits_ecc_correctability;
751 827
... ... @@ -758,9 +834,9 @@
758 834 * to ONFi specification it is reporting
759 835 * as 16 bit device though it is 8 bit device!!!
760 836 */
761 - if (!strncmp(onfi_param_page_ptr->device_model,
762 - "MT29F4G08ABC", 12))
763 - supported_flash.widebus = 0;
837 + if (!strcmp(onfi_param_page_ptr->device_model,
838 + "MT29F4G08ABC"))
839 + supported_flash[0].widebus = 0;
764 840 }
765 841 }
766 842 }
... ... @@ -816,14 +892,6 @@
816 892 uint32_t ecc_errors;
817 893 uint32_t total_ecc_errors = 0;
818 894 unsigned cwperpage;
819 -#if VERBOSE
820 - pr_info("================================================="
821 - "================\n");
822 - pr_info("%s:\nfrom 0x%llx mode %d\ndatbuf 0x%p datlen 0x%x"
823 - "\noobbuf 0x%p ooblen 0x%x\n",
824 - __func__, from, ops->mode, ops->datbuf, ops->len,
825 - ops->oobbuf, ops->ooblen);
826 -#endif
827 895
828 896 if (mtd->writesize == 2048)
829 897 page = from >> 11;
... ... @@ -874,6 +942,19 @@
874 942 else
875 943 page_count = ops->len / (mtd->writesize + mtd->oobsize);
876 944
945 +#if 0 /* yaffs reads more oob data than it needs */
946 + if (ops->ooblen >= sectoroobsize * 4) {
947 + pr_err("%s: unsupported ops->ooblen, %d\n",
948 + __func__, ops->ooblen);
949 + return -EINVAL;
950 + }
951 +#endif
952 +
953 +#if VERBOSE
954 + pr_info("msm_nand_read_oob %llx %p %x %p %x\n",
955 + from, ops->datbuf, ops->len, ops->oobbuf, ops->ooblen);
956 +#endif
957 +
877 958 if (ops->datbuf) {
878 959 data_dma_addr_curr = data_dma_addr =
879 960 msm_nand_dma_map(chip->dev, ops->datbuf, ops->len,
... ... @@ -1144,11 +1225,24 @@
1144 1225 (loff_t)page * mtd->writesize, ops->len,
1145 1226 ops->ooblen);
1146 1227 } else {
1147 - for (n = start_sector; n < cwperpage; n++)
1148 - pr_info("flash_status[%d] = %x,\
1149 - buffr_status[%d] = %x\n",
1150 - n, dma_buffer->data.result[n].flash_status,
1151 - n, dma_buffer->data.result[n].buffer_status);
1228 + pr_info("status: %x %x %x %x %x %x %x %x %x \
1229 + %x %x %x %x %x %x %x \n",
1230 + dma_buffer->data.result[0].flash_status,
1231 + dma_buffer->data.result[0].buffer_status,
1232 + dma_buffer->data.result[1].flash_status,
1233 + dma_buffer->data.result[1].buffer_status,
1234 + dma_buffer->data.result[2].flash_status,
1235 + dma_buffer->data.result[2].buffer_status,
1236 + dma_buffer->data.result[3].flash_status,
1237 + dma_buffer->data.result[3].buffer_status,
1238 + dma_buffer->data.result[4].flash_status,
1239 + dma_buffer->data.result[4].buffer_status,
1240 + dma_buffer->data.result[5].flash_status,
1241 + dma_buffer->data.result[5].buffer_status,
1242 + dma_buffer->data.result[6].flash_status,
1243 + dma_buffer->data.result[6].buffer_status,
1244 + dma_buffer->data.result[7].flash_status,
1245 + dma_buffer->data.result[7].buffer_status);
1152 1246 }
1153 1247 #endif
1154 1248 if (err && err != -EUCLEAN && err != -EBADMSG)
... ... @@ -1178,13 +1272,6 @@
1178 1272 pr_err("msm_nand_read_oob %llx %x %x failed %d, corrected %d\n",
1179 1273 from, ops->datbuf ? ops->len : 0, ops->ooblen, err,
1180 1274 total_ecc_errors);
1181 -#if VERBOSE
1182 - pr_info("\n%s: ret %d, retlen %d oobretlen %d\n",
1183 - __func__, err, ops->retlen, ops->oobretlen);
1184 -
1185 - pr_info("==================================================="
1186 - "==============\n");
1187 -#endif
1188 1275 return err;
1189 1276 }
1190 1277
1191 1278
1192 1279
... ... @@ -1203,11 +1290,12 @@
1203 1290 uint32_t nandc11_addr1;
1204 1291 uint32_t chipsel_cs0;
1205 1292 uint32_t chipsel_cs1;
1293 + uint32_t eccbchcfg;
1206 1294 uint32_t cfg0;
1207 1295 uint32_t cfg1;
1208 - uint32_t eccbchcfg;
1209 1296 uint32_t exec;
1210 1297 uint32_t ecccfg;
1298 + uint32_t ebi2_cfg;
1211 1299 uint32_t ebi2_chip_select_cfg0;
1212 1300 uint32_t adm_mux_data_ack_req_nc01;
1213 1301 uint32_t adm_mux_cmd_ack_req_nc01;
... ... @@ -1219,6 +1307,7 @@
1219 1307 uint32_t nc10_flash_dev_cmd1;
1220 1308 uint32_t nc10_flash_dev_cmd_vld_default;
1221 1309 uint32_t nc10_flash_dev_cmd1_default;
1310 + uint32_t ebi2_cfg_default;
1222 1311 struct {
1223 1312 uint32_t flash_status;
1224 1313 uint32_t buffer_status;
... ... @@ -1243,15 +1332,6 @@
1243 1332 uint32_t ecc_errors;
1244 1333 uint32_t total_ecc_errors = 0;
1245 1334 unsigned cwperpage;
1246 - unsigned cw_offset = chip->cw_size;
1247 -#if VERBOSE
1248 - pr_info("================================================="
1249 - "============\n");
1250 - pr_info("%s:\nfrom 0x%llx mode %d\ndatbuf 0x%p datlen 0x%x"
1251 - "\noobbuf 0x%p ooblen 0x%x\n\n",
1252 - __func__, from, ops->mode, ops->datbuf,
1253 - ops->len, ops->oobbuf, ops->ooblen);
1254 -#endif
1255 1335
1256 1336 if (mtd->writesize == 2048)
1257 1337 page = from >> 11;
... ... @@ -1304,6 +1384,11 @@
1304 1384 else
1305 1385 page_count = ops->len / (mtd->writesize + mtd->oobsize);
1306 1386
1387 +#if VERBOSE
1388 + pr_info("msm_nand_read_oob_dualnandc %llx %p %x %p %x\n",
1389 + from, ops->datbuf, ops->len, ops->oobbuf, ops->ooblen);
1390 +#endif
1391 +
1307 1392 if (ops->datbuf) {
1308 1393 data_dma_addr_curr = data_dma_addr =
1309 1394 msm_nand_dma_map(chip->dev, ops->datbuf, ops->len,
1310 1395
... ... @@ -1333,11 +1418,9 @@
1333 1418 (dma_buffer = msm_nand_get_dma_buffer(
1334 1419 chip, sizeof(*dma_buffer))));
1335 1420
1336 - oob_col = start_sector * chip->cw_size;
1337 - if (chip->CFG1 & CFG1_WIDE_FLASH) {
1421 + oob_col = start_sector * 0x210;
1422 + if (chip->CFG1 & CFG1_WIDE_FLASH)
1338 1423 oob_col >>= 1;
1339 - cw_offset >>= 1;
1340 - }
1341 1424
1342 1425 err = 0;
1343 1426 while (page_count-- > 0) {
... ... @@ -1372,10 +1455,9 @@
1372 1455 dma_buffer->data.nc10_flash_dev_cmd1 =
1373 1456 0xF00F3000;
1374 1457 } else {
1375 - dma_buffer->data.nandc01_addr0 = page << 16;
1376 - /* NC10 ADDR0 points to the next code word */
1377 - dma_buffer->data.nandc10_addr0 = (page << 16) |
1378 - cw_offset;
1458 + dma_buffer->data.nandc01_addr0 =
1459 + (page << 16) | oob_col;
1460 + dma_buffer->data.nandc10_addr0 = 0x108;
1379 1461 dma_buffer->data.nc10_flash_dev_cmd_vld = 0x1D;
1380 1462 dma_buffer->data.nc10_flash_dev_cmd1 =
1381 1463 0xF00FE005;
1382 1464
1383 1465
... ... @@ -1396,12 +1478,14 @@
1396 1478 dma_buffer->data.nc10_flash_dev_cmd_vld_default = 0x1D;
1397 1479 dma_buffer->data.nc10_flash_dev_cmd1_default = 0xF00F3000;
1398 1480
1481 + /* config ebi2 cfg reg for pingpong ( 0xA000_0004 ) */
1482 + dma_buffer->data.ebi2_cfg = 0x4010080;
1483 + dma_buffer->data.ebi2_cfg_default = 0x4010000;
1399 1484 dma_buffer->data.ebi2_chip_select_cfg0 = 0x00000805;
1400 1485 dma_buffer->data.default_ebi2_chip_select_cfg0 = 0x00000801;
1401 1486
1402 - /* chipsel_0 + enable DM interface */
1487 + /* flash0 + undoc bit */
1403 1488 dma_buffer->data.chipsel_cs0 = (1<<4) | 4;
1404 - /* chipsel_1 + enable DM interface */
1405 1489 dma_buffer->data.chipsel_cs1 = (1<<4) | 5;
1406 1490
1407 1491 /* GO bit for the EXEC register */
1408 1492
... ... @@ -1416,8 +1500,16 @@
1416 1500
1417 1501 if (n == start_sector) {
1418 1502 if (!interleave_enable) {
1503 + /* config ebi2 cfg reg */
1419 1504 cmd->cmd = 0;
1420 1505 cmd->src = msm_virt_to_dma(chip,
1506 + &dma_buffer->data.ebi2_cfg);
1507 + cmd->dst = EBI2_CFG_REG;
1508 + cmd->len = 4;
1509 + cmd++;
1510 +
1511 + cmd->cmd = 0;
1512 + cmd->src = msm_virt_to_dma(chip,
1421 1513 &dma_buffer->
1422 1514 data.nc10_flash_dev_cmd_vld);
1423 1515 cmd->dst = NC10(MSM_NAND_DEV_CMD_VLD);
... ... @@ -1566,6 +1658,17 @@
1566 1658 cmd->len = 8;
1567 1659 cmd++;
1568 1660 } else {
1661 + if (!interleave_enable) {
1662 + cmd->cmd = 0;
1663 + cmd->src =
1664 + msm_virt_to_dma(chip,
1665 + &dma_buffer->
1666 + data.nc10_flash_dev_cmd1);
1667 + cmd->dst =
1668 + NC10(MSM_NAND_DEV_CMD1);
1669 + cmd->len = 4;
1670 + cmd++;
1671 + }
1569 1672 /* NC01 --> ADDR0 */
1570 1673 cmd->cmd = 0;
1571 1674 cmd->src = msm_virt_to_dma(chip,
1572 1675
1573 1676
... ... @@ -1612,37 +1715,14 @@
1612 1715 /* read data block
1613 1716 * (only valid if status says success)
1614 1717 */
1615 - if (ops->datbuf || (ops->oobbuf &&
1616 - ops->mode != MTD_OOB_AUTO)) {
1718 + if (ops->datbuf) {
1617 1719 if (ops->mode != MTD_OOB_RAW)
1618 1720 sectordatasize = (n < (cwperpage - 1))
1619 1721 ? 516 : (512 - ((cwperpage - 1) << 2));
1620 1722 else
1621 - sectordatasize = chip->cw_size;
1723 + sectordatasize = 528;
1622 1724
1623 1725 if (n % 2 == 0) {
1624 - /* MASK DATA ACK/REQ --> NC10 (0xF28)*/
1625 - cmd->cmd = 0;
1626 - cmd->src = msm_virt_to_dma(chip,
1627 - &dma_buffer->
1628 - data.adm_mux_data_ack_req_nc10);
1629 - cmd->dst = EBI2_NAND_ADM_MUX;
1630 - cmd->len = 4;
1631 - cmd++;
1632 -
1633 - /* block on data ready from NC01, then
1634 - * read the status register
1635 - */
1636 - cmd->cmd = SRC_CRCI_NAND_DATA;
1637 - cmd->src = NC01(MSM_NAND_FLASH_STATUS);
1638 - cmd->dst = msm_virt_to_dma(chip,
1639 - &dma_buffer->data.result[n]);
1640 - /* MSM_NAND_FLASH_STATUS +
1641 - * MSM_NAND_BUFFER_STATUS
1642 - */
1643 - cmd->len = 8;
1644 - cmd++;
1645 -
1646 1726 /* MASK CMD ACK/REQ --> NC01 (0x53C)*/
1647 1727 cmd->cmd = 0;
1648 1728 cmd->src = msm_virt_to_dma(chip,
1649 1729
1650 1730
1651 1731
1652 1732
1653 1733
... ... @@ -1668,44 +1748,35 @@
1668 1748 cmd->len = 4;
1669 1749 cmd++;
1670 1750
1671 - /* Read only when there is data
1672 - * buffer
1673 - */
1674 - if (ops->datbuf) {
1675 - cmd->cmd = 0;
1676 - cmd->src =
1677 - NC01(MSM_NAND_FLASH_BUFFER);
1678 - cmd->dst = data_dma_addr_curr;
1679 - data_dma_addr_curr +=
1680 - sectordatasize;
1681 - cmd->len = sectordatasize;
1682 - cmd++;
1683 - }
1684 - } else {
1685 - /* MASK DATA ACK/REQ -->
1686 - * NC01 (0xA3C)
1687 - */
1751 + /* MASK DATA ACK/REQ --> NC10 (0xF28)*/
1688 1752 cmd->cmd = 0;
1689 1753 cmd->src = msm_virt_to_dma(chip,
1690 1754 &dma_buffer->
1691 - data.adm_mux_data_ack_req_nc01);
1755 + data.adm_mux_data_ack_req_nc10);
1692 1756 cmd->dst = EBI2_NAND_ADM_MUX;
1693 1757 cmd->len = 4;
1694 1758 cmd++;
1695 1759
1696 - /* block on data ready from NC10
1697 - * then read the status register
1760 + /* block on data ready from NC01, then
1761 + * read the status register
1698 1762 */
1699 1763 cmd->cmd = SRC_CRCI_NAND_DATA;
1700 - cmd->src =
1701 - NC10(MSM_NAND_FLASH_STATUS);
1764 + cmd->src = NC01(MSM_NAND_FLASH_STATUS);
1702 1765 cmd->dst = msm_virt_to_dma(chip,
1703 - &dma_buffer->data.result[n]);
1766 + &dma_buffer->data.result[n]);
1704 1767 /* MSM_NAND_FLASH_STATUS +
1705 1768 * MSM_NAND_BUFFER_STATUS
1706 1769 */
1707 1770 cmd->len = 8;
1708 1771 cmd++;
1772 +
1773 + cmd->cmd = 0;
1774 + cmd->src = NC01(MSM_NAND_FLASH_BUFFER);
1775 + cmd->dst = data_dma_addr_curr;
1776 + data_dma_addr_curr += sectordatasize;
1777 + cmd->len = sectordatasize;
1778 + cmd++;
1779 + } else {
1709 1780 if (n != cwperpage - 1) {
1710 1781 /* MASK CMD ACK/REQ -->
1711 1782 * NC10 (0xF14)
1712 1783
1713 1784
1714 1785
1715 1786
1716 1787
... ... @@ -1736,21 +1807,63 @@
1736 1807 NC01(MSM_NAND_EXEC_CMD);
1737 1808 cmd->len = 4;
1738 1809 cmd++;
1739 - }
1740 1810
1741 - /* Read only when there is data
1742 - * buffer
1743 - */
1744 - if (ops->datbuf) {
1811 + /* MASK DATA ACK/REQ -->
1812 + * NC01 (0xA3C)
1813 + */
1745 1814 cmd->cmd = 0;
1815 + cmd->src = msm_virt_to_dma(chip,
1816 + &dma_buffer->
1817 + data.adm_mux_data_ack_req_nc01);
1818 + cmd->dst = EBI2_NAND_ADM_MUX;
1819 + cmd->len = 4;
1820 + cmd++;
1821 +
1822 + /* block on data ready from NC10
1823 + * then read the status register
1824 + */
1825 + cmd->cmd = SRC_CRCI_NAND_DATA;
1746 1826 cmd->src =
1747 - NC10(MSM_NAND_FLASH_BUFFER);
1748 - cmd->dst = data_dma_addr_curr;
1749 - data_dma_addr_curr +=
1750 - sectordatasize;
1751 - cmd->len = sectordatasize;
1827 + NC10(MSM_NAND_FLASH_STATUS);
1828 + cmd->dst = msm_virt_to_dma(chip,
1829 + &dma_buffer->data.result[n]);
1830 + /* MSM_NAND_FLASH_STATUS +
1831 + * MSM_NAND_BUFFER_STATUS
1832 + */
1833 + cmd->len = 8;
1752 1834 cmd++;
1835 + } else {
1836 + /* MASK DATA ACK/REQ ->
1837 + * NC01 (0xA3C)
1838 + */
1839 + cmd->cmd = 0;
1840 + cmd->src = msm_virt_to_dma(chip,
1841 + &dma_buffer->
1842 + data.adm_mux_data_ack_req_nc01);
1843 + cmd->dst = EBI2_NAND_ADM_MUX;
1844 + cmd->len = 4;
1845 + cmd++;
1846 +
1847 + /* block on data ready from NC10
1848 + * then read the status register
1849 + */
1850 + cmd->cmd = SRC_CRCI_NAND_DATA;
1851 + cmd->src =
1852 + NC10(MSM_NAND_FLASH_STATUS);
1853 + cmd->dst = msm_virt_to_dma(chip,
1854 + &dma_buffer->data.result[n]);
1855 + /* MSM_NAND_FLASH_STATUS +
1856 + * MSM_NAND_BUFFER_STATUS
1857 + */
1858 + cmd->len = 8;
1859 + cmd++;
1753 1860 }
1861 + cmd->cmd = 0;
1862 + cmd->src = NC10(MSM_NAND_FLASH_BUFFER);
1863 + cmd->dst = data_dma_addr_curr;
1864 + data_dma_addr_curr += sectordatasize;
1865 + cmd->len = sectordatasize;
1866 + cmd++;
1754 1867 }
1755 1868 }
1756 1869
1757 1870
1758 1871
1759 1872
... ... @@ -1765,18 +1878,19 @@
1765 1878 (512 - ((cwperpage - 1) << 2));
1766 1879 sectoroobsize = (cwperpage << 2);
1767 1880 if (ops->mode != MTD_OOB_AUTO)
1768 - sectoroobsize +=
1769 - chip->ecc_parity_bytes;
1881 + sectoroobsize += 10;
1770 1882 } else {
1771 - if (n % 2 == 0)
1883 + if (n % 2 == 0) {
1772 1884 cmd->src =
1773 1885 NC01(MSM_NAND_FLASH_BUFFER)
1774 1886 + 516;
1775 - else
1887 + sectoroobsize = 10;
1888 + } else {
1776 1889 cmd->src =
1777 1890 NC10(MSM_NAND_FLASH_BUFFER)
1778 1891 + 516;
1779 - sectoroobsize = chip->ecc_parity_bytes;
1892 + sectoroobsize = 10;
1893 + }
1780 1894 }
1781 1895 cmd->dst = oob_dma_addr_curr;
1782 1896 if (sectoroobsize < oob_len)
... ... @@ -1811,6 +1925,13 @@
1811 1925 cmd->dst = NC10(MSM_NAND_DEV_CMD1);
1812 1926 cmd->len = 4;
1813 1927 cmd++;
1928 +
1929 + cmd->cmd = 0;
1930 + cmd->src = msm_virt_to_dma(chip,
1931 + &dma_buffer->data.ebi2_cfg_default);
1932 + cmd->dst = EBI2_CFG_REG;
1933 + cmd->len = 4;
1934 + cmd++;
1814 1935 } else {
1815 1936 /* disable CS1 */
1816 1937 cmd->cmd = 0;
... ... @@ -1859,8 +1980,7 @@
1859 1980 /* empty blocks read 0x54 at
1860 1981 * these offsets
1861 1982 */
1862 - if ((n % 516 == 3 || n % 516 == 175)
1863 - && datbuf[n] == 0x54)
1983 + if (n % 516 == 3 && datbuf[n] == 0x54)
1864 1984 datbuf[n] = 0xff;
1865 1985 if (datbuf[n] != 0xff) {
1866 1986 pageerr = rawerr;
1867 1987
1868 1988
... ... @@ -1874,26 +1994,18 @@
1874 1994
1875 1995 }
1876 1996 if (ops->oobbuf) {
1877 - dma_sync_single_for_cpu(chip->dev,
1878 - oob_dma_addr_curr - (ops->ooblen - oob_len),
1879 - ops->ooblen - oob_len, DMA_BIDIRECTIONAL);
1880 -
1881 1997 for (n = 0; n < ops->ooblen; n++) {
1882 1998 if (ops->oobbuf[n] != 0xff) {
1883 1999 pageerr = rawerr;
1884 2000 break;
1885 2001 }
1886 2002 }
1887 -
1888 - dma_sync_single_for_device(chip->dev,
1889 - oob_dma_addr_curr - (ops->ooblen - oob_len),
1890 - ops->ooblen - oob_len, DMA_BIDIRECTIONAL);
1891 2003 }
1892 2004 }
1893 2005 if (pageerr) {
1894 2006 for (n = start_sector; n < cwperpage; n++) {
1895 2007 if (dma_buffer->data.result[n].buffer_status
1896 - & MSM_NAND_BUF_STAT_UNCRCTBL_ERR) {
2008 + & 0x8) {
1897 2009 /* not thread safe */
1898 2010 mtd->ecc_stats.failed++;
1899 2011 pageerr = -EBADMSG;
... ... @@ -1904,8 +2016,7 @@
1904 2016 if (!rawerr) { /* check for corretable errors */
1905 2017 for (n = start_sector; n < cwperpage; n++) {
1906 2018 ecc_errors = dma_buffer->data.
1907 - result[n].buffer_status
1908 - & MSM_NAND_BUF_STAT_NUM_ERR_MASK;
2019 + result[n].buffer_status & 0x7;
1909 2020 if (ecc_errors) {
1910 2021 total_ecc_errors += ecc_errors;
1911 2022 /* not thread safe */
1912 2023
... ... @@ -1924,24 +2035,63 @@
1924 2035 "%llx %x %x empty page\n",
1925 2036 (loff_t)page * mtd->writesize, ops->len,
1926 2037 ops->ooblen);
2038 + } else if (!interleave_enable) {
2039 + pr_info("status: %x %x %x %x %x %x %x %x %x \
2040 + %x %x %x %x %x %x %x \n",
2041 + dma_buffer->data.result[0].flash_status,
2042 + dma_buffer->data.result[0].buffer_status,
2043 + dma_buffer->data.result[1].flash_status,
2044 + dma_buffer->data.result[1].buffer_status,
2045 + dma_buffer->data.result[2].flash_status,
2046 + dma_buffer->data.result[2].buffer_status,
2047 + dma_buffer->data.result[3].flash_status,
2048 + dma_buffer->data.result[3].buffer_status,
2049 + dma_buffer->data.result[4].flash_status,
2050 + dma_buffer->data.result[4].buffer_status,
2051 + dma_buffer->data.result[5].flash_status,
2052 + dma_buffer->data.result[5].buffer_status,
2053 + dma_buffer->data.result[6].flash_status,
2054 + dma_buffer->data.result[6].buffer_status,
2055 + dma_buffer->data.result[7].flash_status,
2056 + dma_buffer->data.result[7].buffer_status);
1927 2057 } else {
1928 - for (n = start_sector; n < cwperpage; n++) {
1929 - if (n%2) {
1930 - pr_info("NC10: flash_status[%d] = %x, "
1931 - "buffr_status[%d] = %x\n",
1932 - n, dma_buffer->
1933 - data.result[n].flash_status,
1934 - n, dma_buffer->
1935 - data.result[n].buffer_status);
1936 - } else {
1937 - pr_info("NC01: flash_status[%d] = %x, "
1938 - "buffr_status[%d] = %x\n",
1939 - n, dma_buffer->
1940 - data.result[n].flash_status,
1941 - n, dma_buffer->
1942 - data.result[n].buffer_status);
1943 - }
1944 - }
2058 + pr_info("status: %x %x %x %x %x %x %x %x %x \
2059 + %x %x %x %x %x %x %x \
2060 + %x %x %x %x %x %x %x %x %x \
2061 + %x %x %x %x %x %x %x \n",
2062 + dma_buffer->data.result[0].flash_status,
2063 + dma_buffer->data.result[0].buffer_status,
2064 + dma_buffer->data.result[1].flash_status,
2065 + dma_buffer->data.result[1].buffer_status,
2066 + dma_buffer->data.result[2].flash_status,
2067 + dma_buffer->data.result[2].buffer_status,
2068 + dma_buffer->data.result[3].flash_status,
2069 + dma_buffer->data.result[3].buffer_status,
2070 + dma_buffer->data.result[4].flash_status,
2071 + dma_buffer->data.result[4].buffer_status,
2072 + dma_buffer->data.result[5].flash_status,
2073 + dma_buffer->data.result[5].buffer_status,
2074 + dma_buffer->data.result[6].flash_status,
2075 + dma_buffer->data.result[6].buffer_status,
2076 + dma_buffer->data.result[7].flash_status,
2077 + dma_buffer->data.result[7].buffer_status,
2078 + dma_buffer->data.result[8].flash_status,
2079 + dma_buffer->data.result[8].buffer_status,
2080 + dma_buffer->data.result[9].flash_status,
2081 + dma_buffer->data.result[9].buffer_status,
2082 + dma_buffer->data.result[10].flash_status,
2083 + dma_buffer->data.result[10].buffer_status,
2084 + dma_buffer->data.result[11].flash_status,
2085 + dma_buffer->data.result[11].buffer_status,
2086 + dma_buffer->data.result[12].flash_status,
2087 + dma_buffer->data.result[12].buffer_status,
2088 + dma_buffer->data.result[13].flash_status,
2089 + dma_buffer->data.result[13].buffer_status,
2090 + dma_buffer->data.result[14].flash_status,
2091 + dma_buffer->data.result[14].buffer_status,
2092 + dma_buffer->data.result[15].flash_status,
2093 + dma_buffer->data.result[15].buffer_status);
2094 +
1945 2095 }
1946 2096 #endif
1947 2097 if (err && err != -EUCLEAN && err != -EBADMSG)
... ... @@ -1973,13 +2123,6 @@
1973 2123 "%llx %x %x failed %d, corrected %d\n",
1974 2124 from, ops->datbuf ? ops->len : 0, ops->ooblen, err,
1975 2125 total_ecc_errors);
1976 -#if VERBOSE
1977 - pr_info("\n%s: ret %d, retlen %d oobretlen %d\n",
1978 - __func__, err, ops->retlen, ops->oobretlen);
1979 -
1980 - pr_info("==================================================="
1981 - "==========\n");
1982 -#endif
1983 2126 return err;
1984 2127 }
1985 2128
... ... @@ -1989,6 +2132,9 @@
1989 2132 {
1990 2133 int ret;
1991 2134 struct mtd_oob_ops ops;
2135 + uint8_t *org_buf = NULL;
2136 + size_t org_len = len;
2137 + loff_t org_from = from;
1992 2138
1993 2139 /* printk("msm_nand_read %llx %x\n", from, len); */
1994 2140
1995 2141
... ... @@ -1998,10 +2144,37 @@
1998 2144 ops.ooblen = 0;
1999 2145 ops.datbuf = buf;
2000 2146 ops.oobbuf = NULL;
2147 +
2148 + /* support for non page alligned read */
2149 + if (ops.datbuf != NULL && (ops.len % mtd->writesize) != 0) {
2150 + ops.len += mtd->writesize;
2151 + ops.len ^= ops.len & (mtd->writesize - 1);
2152 + org_buf = ops.datbuf;
2153 + from ^= from & (mtd->writesize - 1);
2154 + ops.datbuf = kmalloc(ops.len, GFP_KERNEL);
2155 + if (!ops.datbuf){
2156 + ops.datbuf = org_buf;
2157 + org_buf = NULL;
2158 + ops.len = org_len;
2159 + pr_err("%s: allocation of temporary buffer has failed",
2160 + __func__);
2161 + }
2162 + }
2163 +
2001 2164 if (!dual_nand_ctlr_present)
2002 2165 ret = msm_nand_read_oob(mtd, from, &ops);
2003 2166 else
2004 2167 ret = msm_nand_read_oob_dualnandc(mtd, from, &ops);
2168 +
2169 + if (org_buf)
2170 + {
2171 + memcpy(org_buf, ops.datbuf + (org_from - from), org_len);
2172 + ops.len = org_len;
2173 + kfree(ops.datbuf);
2174 + ops.datbuf = org_buf;
2175 + ops.retlen = org_len;
2176 + }
2177 +
2005 2178 *retlen = ops.retlen;
2006 2179 return ret;
2007 2180 }
... ... @@ -2041,14 +2214,6 @@
2041 2214 unsigned page_count;
2042 2215 unsigned pages_written = 0;
2043 2216 unsigned cwperpage;
2044 -#if VERBOSE
2045 - pr_info("================================================="
2046 - "================\n");
2047 - pr_info("%s:\nto 0x%llx mode %d\ndatbuf 0x%p datlen 0x%x"
2048 - "\noobbuf 0x%p ooblen 0x%x\n",
2049 - __func__, to, ops->mode, ops->datbuf, ops->len,
2050 - ops->oobbuf, ops->ooblen);
2051 -#endif
2052 2217
2053 2218 if (mtd->writesize == 2048)
2054 2219 page = to >> 11;
... ... @@ -2088,6 +2253,13 @@
2088 2253 pr_err("%s: unsupported ops->datbuf == NULL\n", __func__);
2089 2254 return -EINVAL;
2090 2255 }
2256 +#if 0 /* yaffs writes more oob data than it needs */
2257 + if (ops->ooblen >= sectoroobsize * 4) {
2258 + pr_err("%s: unsupported ops->ooblen, %d\n",
2259 + __func__, ops->ooblen);
2260 + return -EINVAL;
2261 + }
2262 +#endif
2091 2263 if (ops->mode != MTD_OOB_RAW && ops->ooblen != 0 && ops->ooboffs != 0) {
2092 2264 pr_err("%s: unsupported ops->ooboffs, %d\n",
2093 2265 __func__, ops->ooboffs);
... ... @@ -2297,10 +2469,15 @@
2297 2469 }
2298 2470
2299 2471 #if VERBOSE
2300 - for (n = 0; n < cwperpage; n++)
2301 - pr_info("write pg %d: flash_status[%d] = %x\n", page,
2302 - n, dma_buffer->data.flash_status[n]);
2303 -
2472 + pr_info("write pg %d: status: %x %x %x %x %x %x %x %x\n", page,
2473 + dma_buffer->data.flash_status[0],
2474 + dma_buffer->data.flash_status[1],
2475 + dma_buffer->data.flash_status[2],
2476 + dma_buffer->data.flash_status[3],
2477 + dma_buffer->data.flash_status[4],
2478 + dma_buffer->data.flash_status[5],
2479 + dma_buffer->data.flash_status[6],
2480 + dma_buffer->data.flash_status[7]);
2304 2481 #endif
2305 2482 if (err)
2306 2483 break;
... ... @@ -2327,13 +2504,6 @@
2327 2504 pr_err("msm_nand_write_oob %llx %x %x failed %d\n",
2328 2505 to, ops->len, ops->ooblen, err);
2329 2506
2330 -#if VERBOSE
2331 - pr_info("\n%s: ret %d, retlen %d oobretlen %d\n",
2332 - __func__, err, ops->retlen, ops->oobretlen);
2333 -
2334 - pr_info("==================================================="
2335 - "==============\n");
2336 -#endif
2337 2507 return err;
2338 2508 }
2339 2509
... ... @@ -2357,7 +2527,7 @@
2357 2527 uint32_t eccbchcfg;
2358 2528 uint32_t exec;
2359 2529 uint32_t ecccfg;
2360 - uint32_t cfg0_nc01;
2530 + uint32_t ebi2_cfg;
2361 2531 uint32_t ebi2_chip_select_cfg0;
2362 2532 uint32_t adm_mux_data_ack_req_nc01;
2363 2533 uint32_t adm_mux_cmd_ack_req_nc01;
... ... @@ -2369,6 +2539,7 @@
2369 2539 uint32_t nc10_flash_dev_cmd0;
2370 2540 uint32_t nc01_flash_dev_cmd_vld_default;
2371 2541 uint32_t nc10_flash_dev_cmd0_default;
2542 + uint32_t ebi2_cfg_default;
2372 2543 uint32_t flash_status[16];
2373 2544 uint32_t clrfstatus;
2374 2545 uint32_t clrrstatus;
... ... @@ -2388,14 +2559,6 @@
2388 2559 unsigned pages_written = 0;
2389 2560 unsigned cwperpage;
2390 2561 unsigned cw_offset = chip->cw_size;
2391 -#if VERBOSE
2392 - pr_info("================================================="
2393 - "============\n");
2394 - pr_info("%s:\nto 0x%llx mode %d\ndatbuf 0x%p datlen 0x%x"
2395 - "\noobbuf 0x%p ooblen 0x%x\n\n",
2396 - __func__, to, ops->mode, ops->datbuf, ops->len,
2397 - ops->oobbuf, ops->ooblen);
2398 -#endif
2399 2562
2400 2563 if (mtd->writesize == 2048)
2401 2564 page = to >> 11;
... ... @@ -2445,6 +2608,11 @@
2445 2608 return -EINVAL;
2446 2609 }
2447 2610
2611 +#if VERBOSE
2612 + pr_info("msm_nand_write_oob_dualnandc %llx %p %x %p %x\n",
2613 + to, ops->datbuf, ops->len, ops->oobbuf, ops->ooblen);
2614 +#endif
2615 +
2448 2616 if (ops->datbuf) {
2449 2617 data_dma_addr_curr = data_dma_addr =
2450 2618 msm_nand_dma_map(chip->dev, ops->datbuf,
2451 2619
2452 2620
... ... @@ -2498,26 +2666,17 @@
2498 2666
2499 2667 if (ops->mode != MTD_OOB_RAW) {
2500 2668 dma_buffer->data.cfg0 = ((chip->CFG0 & ~(7U << 6))
2501 - & ~(1 << 4)) | ((((cwperpage >> 1)-1)) << 6);
2669 + | (1 << 4)) | ((((cwperpage >> 1)-1)) << 6);
2502 2670 dma_buffer->data.cfg1 = chip->CFG1;
2503 2671 if (enable_bch_ecc)
2504 2672 dma_buffer->data.eccbchcfg = chip->ecc_bch_cfg;
2505 2673 } else {
2506 2674 dma_buffer->data.cfg0 = ((chip->CFG0_RAW &
2507 - ~(7U << 6)) & ~(1 << 4)) | (((cwperpage >> 1)-1) << 6);
2675 + ~(7U << 6)) | (1<<4)) | (((cwperpage >> 1)-1) << 6);
2508 2676 dma_buffer->data.cfg1 = chip->CFG1_RAW |
2509 2677 (chip->CFG1 & CFG1_WIDE_FLASH);
2510 2678 }
2511 2679
2512 - /* Disables the automatic issuing of the read
2513 - * status command for first NAND controller.
2514 - */
2515 - if (!interleave_enable)
2516 - dma_buffer->data.cfg0_nc01 = dma_buffer->data.cfg0
2517 - | (1 << 4);
2518 - else
2519 - dma_buffer->data.cfg0 |= (1 << 4);
2520 -
2521 2680 dma_buffer->data.cmd = MSM_NAND_CMD_PRG_PAGE;
2522 2681 dma_buffer->data.chipsel_cs0 = (1<<4) | 4;
2523 2682 dma_buffer->data.chipsel_cs1 = (1<<4) | 5;
... ... @@ -2525,6 +2684,10 @@
2525 2684 /* GO bit for the EXEC register */
2526 2685 dma_buffer->data.exec = 1;
2527 2686
2687 + /* config ebi2 cfg reg ( 0xA000_0004 ) */
2688 + dma_buffer->data.ebi2_cfg = 0x4010080;
2689 + dma_buffer->data.ebi2_cfg_default = 0x4010000;
2690 +
2528 2691 if (!interleave_enable) {
2529 2692 dma_buffer->data.nandc01_addr0 = (page << 16) | 0x0;
2530 2693 /* NC10 ADDR0 points to the next code word */
2531 2694
... ... @@ -2545,8 +2708,16 @@
2545 2708
2546 2709 if (n == 0) {
2547 2710 if (!interleave_enable) {
2711 + /* config ebi2 cfg reg */
2548 2712 cmd->cmd = 0;
2549 2713 cmd->src = msm_virt_to_dma(chip,
2714 + &dma_buffer->data.ebi2_cfg);
2715 + cmd->dst = EBI2_CFG_REG;
2716 + cmd->len = 4;
2717 + cmd++;
2718 +
2719 + cmd->cmd = 0;
2720 + cmd->src = msm_virt_to_dma(chip,
2550 2721 &dma_buffer->
2551 2722 data.nc01_flash_dev_cmd_vld);
2552 2723 cmd->dst = NC01(MSM_NAND_DEV_CMD_VLD);
2553 2724
2554 2725
2555 2726
... ... @@ -2570,33 +2741,12 @@
2570 2741 cmd->len = 8;
2571 2742 cmd++;
2572 2743
2573 - /* Disables the automatic issue of the
2574 - * read status command after the write
2575 - * operation.
2576 - */
2577 2744 cmd->cmd = 0;
2578 2745 cmd->src = msm_virt_to_dma(chip,
2579 - &dma_buffer->data.cfg0_nc01);
2580 - cmd->dst = NC01(MSM_NAND_DEV0_CFG0);
2581 - cmd->len = 4;
2582 - cmd++;
2583 -
2584 - cmd->cmd = 0;
2585 - cmd->src = msm_virt_to_dma(chip,
2586 2746 &dma_buffer->data.cfg0);
2587 - cmd->dst = NC10(MSM_NAND_DEV0_CFG0);
2588 - cmd->len = 4;
2747 + cmd->dst = NC11(MSM_NAND_DEV0_CFG0);
2748 + cmd->len = 8;
2589 2749 cmd++;
2590 -
2591 - cmd->cmd = 0;
2592 - cmd->src = msm_virt_to_dma(chip,
2593 - &dma_buffer->data.cfg1);
2594 - cmd->dst = NC11(MSM_NAND_DEV0_CFG1);
2595 - if (enable_bch_ecc)
2596 - cmd->len = 8;
2597 - else
2598 - cmd->len = 4;
2599 - cmd++;
2600 2750 } else {
2601 2751 /* enable CS1 */
2602 2752 cmd->cmd = 0;
... ... @@ -2756,6 +2906,13 @@
2756 2906 }
2757 2907
2758 2908 if (n % 2 == 0) {
2909 + /* kick the NC01 execute register */
2910 + cmd->cmd = 0;
2911 + cmd->src = msm_virt_to_dma(chip,
2912 + &dma_buffer->data.exec);
2913 + cmd->dst = NC01(MSM_NAND_EXEC_CMD);
2914 + cmd->len = 4;
2915 + cmd++;
2759 2916 if (n != 0) {
2760 2917 /* MASK DATA ACK/REQ --> NC01 (0xA3C)*/
2761 2918 cmd->cmd = 0;
... ... @@ -2784,6 +2941,14 @@
2784 2941 cmd->len = 4;
2785 2942 cmd++;
2786 2943 } else {
2944 + /* kick the execute register */
2945 + cmd->cmd = 0;
2946 + cmd->src =
2947 + msm_virt_to_dma(chip, &dma_buffer->data.exec);
2948 + cmd->dst = NC10(MSM_NAND_EXEC_CMD);
2949 + cmd->len = 4;
2950 + cmd++;
2951 +
2787 2952 /* MASK DATA ACK/REQ --> NC10 (0xF28)*/
2788 2953 cmd->cmd = 0;
2789 2954 cmd->src = msm_virt_to_dma(chip,
... ... @@ -2801,14 +2966,6 @@
2801 2966 &dma_buffer->data.flash_status[n-1]);
2802 2967 cmd->len = 4;
2803 2968 cmd++;
2804 -
2805 - /* kick the execute register */
2806 - cmd->cmd = 0;
2807 - cmd->src =
2808 - msm_virt_to_dma(chip, &dma_buffer->data.exec);
2809 - cmd->dst = NC10(MSM_NAND_EXEC_CMD);
2810 - cmd->len = 4;
2811 - cmd++;
2812 2969 }
2813 2970 }
2814 2971
... ... @@ -2866,6 +3023,13 @@
2866 3023 cmd->dst = NC10(MSM_NAND_DEV_CMD0);
2867 3024 cmd->len = 4;
2868 3025 cmd++;
3026 +
3027 + cmd->cmd = 0;
3028 + cmd->src = msm_virt_to_dma(chip,
3029 + &dma_buffer->data.ebi2_cfg_default);
3030 + cmd->dst = EBI2_CFG_REG;
3031 + cmd->len = 4;
3032 + cmd++;
2869 3033 } else {
2870 3034 /* disable CS1 */
2871 3035 cmd->cmd = 0;
... ... @@ -2912,14 +3076,35 @@
2912 3076 break;
2913 3077 }
2914 3078 #if VERBOSE
2915 - for (n = 0; n < cwperpage; n++) {
2916 - if (n%2) {
2917 - pr_info("NC10: write pg %d: flash_status[%d] = %x\n",
2918 - page, n, dma_buffer->data.flash_status[n]);
2919 - } else {
2920 - pr_info("NC01: write pg %d: flash_status[%d] = %x\n",
2921 - page, n, dma_buffer->data.flash_status[n]);
2922 - }
3079 + if (!interleave_enable) {
3080 + pr_info("write pg %d: status: %x %x %x %x %x %x %x %x\n", page,
3081 + dma_buffer->data.flash_status[0],
3082 + dma_buffer->data.flash_status[1],
3083 + dma_buffer->data.flash_status[2],
3084 + dma_buffer->data.flash_status[3],
3085 + dma_buffer->data.flash_status[4],
3086 + dma_buffer->data.flash_status[5],
3087 + dma_buffer->data.flash_status[6],
3088 + dma_buffer->data.flash_status[7]);
3089 + } else {
3090 + pr_info("write pg %d: status: %x %x %x %x %x %x %x %x \
3091 + %x %x %x %x %x %x %x %x \n", page,
3092 + dma_buffer->data.flash_status[0],
3093 + dma_buffer->data.flash_status[1],
3094 + dma_buffer->data.flash_status[2],
3095 + dma_buffer->data.flash_status[3],
3096 + dma_buffer->data.flash_status[4],
3097 + dma_buffer->data.flash_status[5],
3098 + dma_buffer->data.flash_status[6],
3099 + dma_buffer->data.flash_status[7],
3100 + dma_buffer->data.flash_status[8],
3101 + dma_buffer->data.flash_status[9],
3102 + dma_buffer->data.flash_status[10],
3103 + dma_buffer->data.flash_status[11],
3104 + dma_buffer->data.flash_status[12],
3105 + dma_buffer->data.flash_status[13],
3106 + dma_buffer->data.flash_status[14],
3107 + dma_buffer->data.flash_status[15]);
2923 3108 }
2924 3109 #endif
2925 3110 if (err)
2926 3111
... ... @@ -2985,20 +3170,8 @@
2985 3170 struct {
2986 3171 dmov_s cmd[6];
2987 3172 unsigned cmdptr;
2988 - struct {
2989 - uint32_t cmd;
2990 - uint32_t addr0;
2991 - uint32_t addr1;
2992 - uint32_t chipsel;
2993 - uint32_t cfg0;
2994 - uint32_t cfg1;
2995 - uint32_t exec;
2996 - uint32_t flash_status;
2997 - uint32_t clrfstatus;
2998 - uint32_t clrrstatus;
2999 - } data;
3173 + unsigned data[10];
3000 3174 } *dma_buffer;
3001 - dmov_s *cmd;
3002 3175 unsigned page = 0;
3003 3176
3004 3177 if (mtd->writesize == 2048)
3005 3178
3006 3179
3007 3180
3008 3181
3009 3182
3010 3183
3011 3184
3012 3185
... ... @@ -3022,57 +3195,50 @@
3022 3195 (dma_buffer = msm_nand_get_dma_buffer(
3023 3196 chip, sizeof(*dma_buffer))));
3024 3197
3025 - cmd = dma_buffer->cmd;
3198 + dma_buffer->data[0] = MSM_NAND_CMD_BLOCK_ERASE;
3199 + dma_buffer->data[1] = page;
3200 + dma_buffer->data[2] = 0;
3201 + dma_buffer->data[3] = 0 | 4;
3202 + dma_buffer->data[4] = 1;
3203 + dma_buffer->data[5] = 0xeeeeeeee;
3204 + dma_buffer->data[6] = chip->CFG0 & (~(7 << 6)); /* CW_PER_PAGE = 0 */
3205 + dma_buffer->data[7] = chip->CFG1;
3206 + dma_buffer->data[8] = 0x00000020;
3207 + dma_buffer->data[9] = 0x000000C0;
3208 + BUILD_BUG_ON(9 != ARRAY_SIZE(dma_buffer->data) - 1);
3026 3209
3027 - dma_buffer->data.cmd = MSM_NAND_CMD_BLOCK_ERASE;
3028 - dma_buffer->data.addr0 = page;
3029 - dma_buffer->data.addr1 = 0;
3030 - dma_buffer->data.chipsel = 0 | 4;
3031 - dma_buffer->data.exec = 1;
3032 - dma_buffer->data.flash_status = 0xeeeeeeee;
3033 - dma_buffer->data.cfg0 = chip->CFG0 & (~(7 << 6)); /* CW_PER_PAGE = 0 */
3034 - dma_buffer->data.cfg1 = chip->CFG1;
3035 - dma_buffer->data.clrfstatus = 0x00000020;
3036 - dma_buffer->data.clrrstatus = 0x000000C0;
3210 + dma_buffer->cmd[0].cmd = DST_CRCI_NAND_CMD | CMD_OCB;
3211 + dma_buffer->cmd[0].src = msm_virt_to_dma(chip, &dma_buffer->data[0]);
3212 + dma_buffer->cmd[0].dst = MSM_NAND_FLASH_CMD;
3213 + dma_buffer->cmd[0].len = 16;
3037 3214
3038 - cmd->cmd = DST_CRCI_NAND_CMD | CMD_OCB;
3039 - cmd->src = msm_virt_to_dma(chip, &dma_buffer->data.cmd);
3040 - cmd->dst = MSM_NAND_FLASH_CMD;
3041 - cmd->len = 16;
3042 - cmd++;
3215 + dma_buffer->cmd[1].cmd = 0;
3216 + dma_buffer->cmd[1].src = msm_virt_to_dma(chip, &dma_buffer->data[6]);
3217 + dma_buffer->cmd[1].dst = MSM_NAND_DEV0_CFG0;
3218 + dma_buffer->cmd[1].len = 8;
3043 3219
3044 - cmd->cmd = 0;
3045 - cmd->src = msm_virt_to_dma(chip, &dma_buffer->data.cfg0);
3046 - cmd->dst = MSM_NAND_DEV0_CFG0;
3047 - cmd->len = 8;
3048 - cmd++;
3220 + dma_buffer->cmd[2].cmd = 0;
3221 + dma_buffer->cmd[2].src = msm_virt_to_dma(chip, &dma_buffer->data[4]);
3222 + dma_buffer->cmd[2].dst = MSM_NAND_EXEC_CMD;
3223 + dma_buffer->cmd[2].len = 4;
3049 3224
3050 - cmd->cmd = 0;
3051 - cmd->src = msm_virt_to_dma(chip, &dma_buffer->data.exec);
3052 - cmd->dst = MSM_NAND_EXEC_CMD;
3053 - cmd->len = 4;
3054 - cmd++;
3225 + dma_buffer->cmd[3].cmd = SRC_CRCI_NAND_DATA;
3226 + dma_buffer->cmd[3].src = MSM_NAND_FLASH_STATUS;
3227 + dma_buffer->cmd[3].dst = msm_virt_to_dma(chip, &dma_buffer->data[5]);
3228 + dma_buffer->cmd[3].len = 4;
3055 3229
3056 - cmd->cmd = SRC_CRCI_NAND_DATA;
3057 - cmd->src = MSM_NAND_FLASH_STATUS;
3058 - cmd->dst = msm_virt_to_dma(chip, &dma_buffer->data.flash_status);
3059 - cmd->len = 4;
3060 - cmd++;
3230 + dma_buffer->cmd[4].cmd = 0;
3231 + dma_buffer->cmd[4].src = msm_virt_to_dma(chip, &dma_buffer->data[8]);
3232 + dma_buffer->cmd[4].dst = MSM_NAND_FLASH_STATUS;
3233 + dma_buffer->cmd[4].len = 4;
3061 3234
3062 - cmd->cmd = 0;
3063 - cmd->src = msm_virt_to_dma(chip, &dma_buffer->data.clrfstatus);
3064 - cmd->dst = MSM_NAND_FLASH_STATUS;
3065 - cmd->len = 4;
3066 - cmd++;
3235 + dma_buffer->cmd[5].cmd = CMD_OCU | CMD_LC;
3236 + dma_buffer->cmd[5].src = msm_virt_to_dma(chip, &dma_buffer->data[9]);
3237 + dma_buffer->cmd[5].dst = MSM_NAND_READ_STATUS;
3238 + dma_buffer->cmd[5].len = 4;
3067 3239
3068 - cmd->cmd = CMD_OCU | CMD_LC;
3069 - cmd->src = msm_virt_to_dma(chip, &dma_buffer->data.clrrstatus);
3070 - cmd->dst = MSM_NAND_READ_STATUS;
3071 - cmd->len = 4;
3072 - cmd++;
3073 -
3074 3240 BUILD_BUG_ON(5 != ARRAY_SIZE(dma_buffer->cmd) - 1);
3075 3241 - BUG_ON(cmd - dma_buffer->cmd > ARRAY_SIZE(dma_buffer->cmd));
3076 3242 +
3077 3243 dma_buffer->cmdptr =
3078 3244 (msm_virt_to_dma(chip, dma_buffer->cmd) >> 3) | CMD_PTR_LP;
3079 3245
... ... @@ -3086,8 +3252,7 @@
3086 3252 * erase success bit was not set.
3087 3253 */
3088 3254
3089 - if (dma_buffer->data.flash_status & 0x110 ||
3090 - !(dma_buffer->data.flash_status & 0x80))
3255 + if (dma_buffer->data[5] & 0x110 || !(dma_buffer->data[5] & 0x80))
3091 3256 err = -EIO;
3092 3257 else
3093 3258 err = 0;
3094 3259
... ... @@ -3113,31 +3278,15 @@
3113 3278 struct {
3114 3279 dmov_s cmd[18];
3115 3280 unsigned cmdptr;
3116 - struct {
3117 - uint32_t cmd;
3118 - uint32_t addr0;
3119 - uint32_t addr1;
3120 - uint32_t chipsel_cs0;
3121 - uint32_t chipsel_cs1;
3122 - uint32_t cfg0;
3123 - uint32_t cfg1;
3124 - uint32_t exec;
3125 - uint32_t ecccfg;
3126 - uint32_t ebi2_chip_select_cfg0;
3127 - uint32_t adm_mux_data_ack_req_nc01;
3128 - uint32_t adm_mux_cmd_ack_req_nc01;
3129 - uint32_t adm_mux_data_ack_req_nc10;
3130 - uint32_t adm_mux_cmd_ack_req_nc10;
3131 - uint32_t adm_default_mux;
3132 - uint32_t default_ebi2_chip_select_cfg0;
3133 - uint32_t nc01_flash_dev_cmd0;
3134 - uint32_t nc01_flash_dev_cmd0_default;
3135 - uint32_t flash_status[2];
3136 - uint32_t clrfstatus;
3137 - uint32_t clrrstatus;
3138 - } data;
3281 + uint32_t ebi2_chip_select_cfg0;
3282 + uint32_t adm_mux_data_ack_req_nc01;
3283 + uint32_t adm_mux_cmd_ack_req_nc01;
3284 + uint32_t adm_mux_data_ack_req_nc10;
3285 + uint32_t adm_mux_cmd_ack_req_nc10;
3286 + uint32_t adm_default_mux;
3287 + uint32_t default_ebi2_chip_select_cfg0;
3288 + unsigned data[12];
3139 3289 } *dma_buffer;
3140 - dmov_s *cmd;
3141 3290 unsigned page = 0;
3142 3291
3143 3292 if (mtd->writesize == 2048)
3144 3293
3145 3294
3146 3295
3147 3296
3148 3297
3149 3298
3150 3299
3151 3300
3152 3301
3153 3302
3154 3303
3155 3304
3156 3305
3157 3306
3158 3307
3159 3308
3160 3309
3161 3310
3162 3311
3163 3312
3164 3313
... ... @@ -3164,153 +3313,135 @@
3164 3313 (dma_buffer = msm_nand_get_dma_buffer(
3165 3314 chip, sizeof(*dma_buffer))));
3166 3315
3167 - cmd = dma_buffer->cmd;
3316 + dma_buffer->data[0] = MSM_NAND_CMD_BLOCK_ERASE;
3317 + dma_buffer->data[1] = page;
3318 + dma_buffer->data[2] = 0;
3319 + dma_buffer->data[3] = (1<<4) | 4;
3320 + dma_buffer->data[4] = (1<<4) | 5;
3321 + dma_buffer->data[5] = 1;
3322 + dma_buffer->data[6] = 0xeeeeeeee;
3323 + dma_buffer->data[7] = 0xeeeeeeee;
3324 + dma_buffer->data[8] = chip->CFG0 & (~(7 << 6)); /* CW_PER_PAGE = 0 */
3325 + dma_buffer->data[9] = chip->CFG1;
3326 + dma_buffer->data[10] = 0x00000020;
3327 + dma_buffer->data[11] = 0x000000C0;
3168 3328
3169 - dma_buffer->data.cmd = MSM_NAND_CMD_BLOCK_ERASE;
3170 - dma_buffer->data.addr0 = page;
3171 - dma_buffer->data.addr1 = 0;
3172 - dma_buffer->data.chipsel_cs0 = (1<<4) | 4;
3173 - dma_buffer->data.chipsel_cs1 = (1<<4) | 5;
3174 - dma_buffer->data.exec = 1;
3175 - dma_buffer->data.flash_status[0] = 0xeeeeeeee;
3176 - dma_buffer->data.flash_status[1] = 0xeeeeeeee;
3177 - dma_buffer->data.cfg0 = chip->CFG0 & (~(7 << 6)); /* CW_PER_PAGE = 0 */
3178 - dma_buffer->data.cfg1 = chip->CFG1;
3179 - dma_buffer->data.clrfstatus = 0x00000020;
3180 - dma_buffer->data.clrrstatus = 0x000000C0;
3329 + dma_buffer->ebi2_chip_select_cfg0 = 0x00000805;
3330 + dma_buffer->adm_mux_data_ack_req_nc01 = 0x00000A3C;
3331 + dma_buffer->adm_mux_cmd_ack_req_nc01 = 0x0000053C;
3332 + dma_buffer->adm_mux_data_ack_req_nc10 = 0x00000F28;
3333 + dma_buffer->adm_mux_cmd_ack_req_nc10 = 0x00000F14;
3334 + dma_buffer->adm_default_mux = 0x00000FC0;
3335 + dma_buffer->default_ebi2_chip_select_cfg0 = 0x00000801;
3181 3336
3182 - dma_buffer->data.ebi2_chip_select_cfg0 = 0x00000805;
3183 - dma_buffer->data.adm_mux_data_ack_req_nc01 = 0x00000A3C;
3184 - dma_buffer->data.adm_mux_cmd_ack_req_nc01 = 0x0000053C;
3185 - dma_buffer->data.adm_mux_data_ack_req_nc10 = 0x00000F28;
3186 - dma_buffer->data.adm_mux_cmd_ack_req_nc10 = 0x00000F14;
3187 - dma_buffer->data.adm_default_mux = 0x00000FC0;
3188 - dma_buffer->data.default_ebi2_chip_select_cfg0 = 0x00000801;
3337 + BUILD_BUG_ON(11 != ARRAY_SIZE(dma_buffer->data) - 1);
3189 3338
3190 3339 /* enable CS1 */
3191 - cmd->cmd = 0 | CMD_OCB;
3192 - cmd->src = msm_virt_to_dma(chip,
3193 - &dma_buffer->data.ebi2_chip_select_cfg0);
3194 - cmd->dst = EBI2_CHIP_SELECT_CFG0;
3195 - cmd->len = 4;
3196 - cmd++;
3340 + dma_buffer->cmd[0].cmd = 0 | CMD_OCB;
3341 + dma_buffer->cmd[0].src = msm_virt_to_dma(chip,
3342 + &dma_buffer->ebi2_chip_select_cfg0);
3343 + dma_buffer->cmd[0].dst = EBI2_CHIP_SELECT_CFG0;
3344 + dma_buffer->cmd[0].len = 4;
3197 3345
3198 3346 /* erase CS0 block now !!! */
3199 3347 /* 0xF14 */
3200 - cmd->cmd = 0;
3201 - cmd->src = msm_virt_to_dma(chip,
3202 - &dma_buffer->data.adm_mux_cmd_ack_req_nc10);
3203 - cmd->dst = EBI2_NAND_ADM_MUX;
3204 - cmd->len = 4;
3205 - cmd++;
3348 + dma_buffer->cmd[1].cmd = 0;
3349 + dma_buffer->cmd[1].src = msm_virt_to_dma(chip,
3350 + &dma_buffer->adm_mux_cmd_ack_req_nc10);
3351 + dma_buffer->cmd[1].dst = EBI2_NAND_ADM_MUX;
3352 + dma_buffer->cmd[1].len = 4;
3206 3353
3207 - cmd->cmd = DST_CRCI_NAND_CMD;
3208 - cmd->src = msm_virt_to_dma(chip, &dma_buffer->data.cmd);
3209 - cmd->dst = NC01(MSM_NAND_FLASH_CMD);
3210 - cmd->len = 16;
3211 - cmd++;
3354 + dma_buffer->cmd[2].cmd = DST_CRCI_NAND_CMD;
3355 + dma_buffer->cmd[2].src = msm_virt_to_dma(chip, &dma_buffer->data[0]);
3356 + dma_buffer->cmd[2].dst = NC01(MSM_NAND_FLASH_CMD);
3357 + dma_buffer->cmd[2].len = 16;
3212 3358
3213 - cmd->cmd = 0;
3214 - cmd->src = msm_virt_to_dma(chip, &dma_buffer->data.cfg0);
3215 - cmd->dst = NC01(MSM_NAND_DEV0_CFG0);
3216 - cmd->len = 8;
3217 - cmd++;
3359 + dma_buffer->cmd[3].cmd = 0;
3360 + dma_buffer->cmd[3].src = msm_virt_to_dma(chip, &dma_buffer->data[8]);
3361 + dma_buffer->cmd[3].dst = NC01(MSM_NAND_DEV0_CFG0);
3362 + dma_buffer->cmd[3].len = 8;
3218 3363
3219 - cmd->cmd = 0;
3220 - cmd->src = msm_virt_to_dma(chip, &dma_buffer->data.exec);
3221 - cmd->dst = NC01(MSM_NAND_EXEC_CMD);
3222 - cmd->len = 4;
3223 - cmd++;
3364 + dma_buffer->cmd[4].cmd = 0;
3365 + dma_buffer->cmd[4].src = msm_virt_to_dma(chip, &dma_buffer->data[5]);
3366 + dma_buffer->cmd[4].dst = NC01(MSM_NAND_EXEC_CMD);
3367 + dma_buffer->cmd[4].len = 4;
3224 3368
3225 3369 /* 0xF28 */
3226 - cmd->cmd = 0;
3227 - cmd->src = msm_virt_to_dma(chip,
3228 - &dma_buffer->data.adm_mux_data_ack_req_nc10);
3229 - cmd->dst = EBI2_NAND_ADM_MUX;
3230 - cmd->len = 4;
3231 - cmd++;
3370 + dma_buffer->cmd[5].cmd = 0;
3371 + dma_buffer->cmd[5].src = msm_virt_to_dma(chip,
3372 + &dma_buffer->adm_mux_data_ack_req_nc10);
3373 + dma_buffer->cmd[5].dst = EBI2_NAND_ADM_MUX;
3374 + dma_buffer->cmd[5].len = 4;
3232 3375
3233 - cmd->cmd = SRC_CRCI_NAND_DATA;
3234 - cmd->src = NC01(MSM_NAND_FLASH_STATUS);
3235 - cmd->dst = msm_virt_to_dma(chip, &dma_buffer->data.flash_status[0]);
3236 - cmd->len = 4;
3237 - cmd++;
3376 + dma_buffer->cmd[6].cmd = SRC_CRCI_NAND_DATA;
3377 + dma_buffer->cmd[6].src = NC01(MSM_NAND_FLASH_STATUS);
3378 + dma_buffer->cmd[6].dst = msm_virt_to_dma(chip, &dma_buffer->data[6]);
3379 + dma_buffer->cmd[6].len = 4;
3238 3380
3239 3381 /* erase CS1 block now !!! */
3240 3382 /* 0x53C */
3241 - cmd->cmd = 0;
3242 - cmd->src = msm_virt_to_dma(chip,
3243 - &dma_buffer->data.adm_mux_cmd_ack_req_nc01);
3244 - cmd->dst = EBI2_NAND_ADM_MUX;
3245 - cmd->len = 4;
3246 - cmd++;
3383 + dma_buffer->cmd[7].cmd = 0;
3384 + dma_buffer->cmd[7].src = msm_virt_to_dma(chip,
3385 + &dma_buffer->adm_mux_cmd_ack_req_nc01);
3386 + dma_buffer->cmd[7].dst = EBI2_NAND_ADM_MUX;
3387 + dma_buffer->cmd[7].len = 4;
3247 3388
3248 - cmd->cmd = DST_CRCI_NAND_CMD;
3249 - cmd->src = msm_virt_to_dma(chip, &dma_buffer->data.cmd);
3250 - cmd->dst = NC10(MSM_NAND_FLASH_CMD);
3251 - cmd->len = 12;
3252 - cmd++;
3389 + dma_buffer->cmd[8].cmd = DST_CRCI_NAND_CMD;
3390 + dma_buffer->cmd[8].src = msm_virt_to_dma(chip, &dma_buffer->data[0]);
3391 + dma_buffer->cmd[8].dst = NC10(MSM_NAND_FLASH_CMD);
3392 + dma_buffer->cmd[8].len = 12;
3253 3393
3254 - cmd->cmd = 0;
3255 - cmd->src = msm_virt_to_dma(chip, &dma_buffer->data.chipsel_cs1);
3256 - cmd->dst = NC10(MSM_NAND_FLASH_CHIP_SELECT);
3257 - cmd->len = 4;
3258 - cmd++;
3394 + dma_buffer->cmd[9].cmd = 0;
3395 + dma_buffer->cmd[9].src = msm_virt_to_dma(chip, &dma_buffer->data[4]);
3396 + dma_buffer->cmd[9].dst = NC10(MSM_NAND_FLASH_CHIP_SELECT);
3397 + dma_buffer->cmd[9].len = 4;
3259 3398
3260 - cmd->cmd = 0;
3261 - cmd->src = msm_virt_to_dma(chip, &dma_buffer->data.cfg0);
3262 - cmd->dst = NC10(MSM_NAND_DEV1_CFG0);
3263 - cmd->len = 8;
3399 + dma_buffer->cmd[10].cmd = 0;
3400 + dma_buffer->cmd[10].src = msm_virt_to_dma(chip, &dma_buffer->data[8]);
3401 + dma_buffer->cmd[10].dst = NC10(MSM_NAND_DEV1_CFG0);
3402 + dma_buffer->cmd[10].len = 8;
3264 3403
3265 - cmd->cmd = 0;
3266 - cmd->src = msm_virt_to_dma(chip, &dma_buffer->data.exec);
3267 - cmd->dst = NC10(MSM_NAND_EXEC_CMD);
3268 - cmd->len = 4;
3269 - cmd++;
3404 + dma_buffer->cmd[11].cmd = 0;
3405 + dma_buffer->cmd[11].src = msm_virt_to_dma(chip, &dma_buffer->data[5]);
3406 + dma_buffer->cmd[11].dst = NC10(MSM_NAND_EXEC_CMD);
3407 + dma_buffer->cmd[11].len = 4;
3270 3408
3271 3409 /* 0xA3C */
3272 - cmd->cmd = 0;
3273 - cmd->src = msm_virt_to_dma(chip,
3274 - &dma_buffer->data.adm_mux_data_ack_req_nc01);
3275 - cmd->dst = EBI2_NAND_ADM_MUX;
3276 - cmd->len = 4;
3277 - cmd++;
3410 + dma_buffer->cmd[12].cmd = 0;
3411 + dma_buffer->cmd[12].src = msm_virt_to_dma(chip,
3412 + &dma_buffer->adm_mux_data_ack_req_nc01);
3413 + dma_buffer->cmd[12].dst = EBI2_NAND_ADM_MUX;
3414 + dma_buffer->cmd[12].len = 4;
3278 3415
3279 - cmd->cmd = SRC_CRCI_NAND_DATA;
3280 - cmd->src = NC10(MSM_NAND_FLASH_STATUS);
3281 - cmd->dst = msm_virt_to_dma(chip, &dma_buffer->data.flash_status[1]);
3282 - cmd->len = 4;
3283 - cmd++;
3416 + dma_buffer->cmd[13].cmd = SRC_CRCI_NAND_DATA;
3417 + dma_buffer->cmd[13].src = NC10(MSM_NAND_FLASH_STATUS);
3418 + dma_buffer->cmd[13].dst = msm_virt_to_dma(chip, &dma_buffer->data[7]);
3419 + dma_buffer->cmd[13].len = 4;
3284 3420
3285 - cmd->cmd = 0;
3286 - cmd->src = msm_virt_to_dma(chip, &dma_buffer->data.clrfstatus);
3287 - cmd->dst = NC11(MSM_NAND_FLASH_STATUS);
3288 - cmd->len = 4;
3289 - cmd++;
3421 + dma_buffer->cmd[14].cmd = 0;
3422 + dma_buffer->cmd[14].src = msm_virt_to_dma(chip, &dma_buffer->data[8]);
3423 + dma_buffer->cmd[14].dst = NC11(MSM_NAND_FLASH_STATUS);
3424 + dma_buffer->cmd[14].len = 4;
3290 3425
3291 - cmd->cmd = 0;
3292 - cmd->src = msm_virt_to_dma(chip, &dma_buffer->data.clrrstatus);
3293 - cmd->dst = NC11(MSM_NAND_READ_STATUS);
3294 - cmd->len = 4;
3295 - cmd++;
3426 + dma_buffer->cmd[15].cmd = 0;
3427 + dma_buffer->cmd[15].src = msm_virt_to_dma(chip, &dma_buffer->data[9]);
3428 + dma_buffer->cmd[15].dst = NC11(MSM_NAND_READ_STATUS);
3429 + dma_buffer->cmd[15].len = 4;
3296 3430
3297 - cmd->cmd = 0;
3298 - cmd->src = msm_virt_to_dma(chip,
3299 - &dma_buffer->data.adm_default_mux);
3300 - cmd->dst = EBI2_NAND_ADM_MUX;
3301 - cmd->len = 4;
3302 - cmd++;
3431 + dma_buffer->cmd[16].cmd = 0;
3432 + dma_buffer->cmd[16].src = msm_virt_to_dma(chip,
3433 + &dma_buffer->adm_default_mux);
3434 + dma_buffer->cmd[16].dst = EBI2_NAND_ADM_MUX;
3435 + dma_buffer->cmd[16].len = 4;
3303 3436
3304 3437 /* disable CS1 */
3305 - cmd->cmd = CMD_OCU | CMD_LC;
3306 - cmd->src = msm_virt_to_dma(chip,
3307 - &dma_buffer->data.default_ebi2_chip_select_cfg0);
3308 - cmd->dst = EBI2_CHIP_SELECT_CFG0;
3309 - cmd->len = 4;
3310 - cmd++;
3438 + dma_buffer->cmd[17].cmd = CMD_OCU | CMD_LC;
3439 + dma_buffer->cmd[17].src = msm_virt_to_dma(chip,
3440 + &dma_buffer->default_ebi2_chip_select_cfg0);
3441 + dma_buffer->cmd[17].dst = EBI2_CHIP_SELECT_CFG0;
3442 + dma_buffer->cmd[17].len = 4;
3311 3443
3312 3444 BUILD_BUG_ON(17 != ARRAY_SIZE(dma_buffer->cmd) - 1);
3313 - BUG_ON(cmd - dma_buffer->cmd > ARRAY_SIZE(dma_buffer->cmd));
3314 3445
3315 3446 dma_buffer->cmdptr =
3316 3447 (msm_virt_to_dma(chip, dma_buffer->cmd) >> 3) | CMD_PTR_LP;
... ... @@ -3325,10 +3456,8 @@
3325 3456 * erase success bit was not set.
3326 3457 */
3327 3458
3328 - if (dma_buffer->data.flash_status[0] & 0x110 ||
3329 - !(dma_buffer->data.flash_status[0] & 0x80) ||
3330 - dma_buffer->data.flash_status[1] & 0x110 ||
3331 - !(dma_buffer->data.flash_status[1] & 0x80))
3459 + if (dma_buffer->data[6] & 0x110 || !(dma_buffer->data[6] & 0x80)
3460 + || dma_buffer->data[6] & 0x110 || !(dma_buffer->data[6] & 0x80))
3332 3461 err = -EIO;
3333 3462 else
3334 3463 err = 0;
... ... @@ -3387,8 +3516,8 @@
3387 3516 if (ofs > mtd->size)
3388 3517 return -EINVAL;
3389 3518 if (ofs & (mtd->erasesize - 1)) {
3390 - pr_err("%s: unsupported block address, 0x%x\n",
3391 - __func__, (uint32_t)ofs);
3519 + pr_err("%s: unsupported block address, 0x%x ( & 0x%x )\n",
3520 + __func__, (uint32_t)ofs, mtd->erasesize - 1);
3392 3521 return -EINVAL;
3393 3522 }
3394 3523
... ... @@ -3786,6 +3915,121 @@
3786 3915 return ret;
3787 3916 }
3788 3917
3918 +int msm_nand_read_dpram(char *mBuf, unsigned size)
3919 +{
3920 + char spare_buf[128] = { 0, };
3921 + struct mtd_oob_ops ops = { 0, };
3922 + unsigned offset = 0;
3923 +
3924 + if(NULL == current_mtd)
3925 + {
3926 + printk("[msm_nand_read_dpram] MTD not initialized\n");
3927 + return -1;
3928 + }
3929 + if(size < current_mtd->writesize)
3930 + {
3931 + printk("[msm_nand_read_dpram] given buffer has invalid size\n");
3932 + return -1;
3933 + }
3934 +
3935 + /* needed data is hardcoded at 5th page of the last block */
3936 + offset = ((5 * current_mtd->writesize) + (current_mtd->erasesize * (((unsigned )current_mtd->size / (unsigned )current_mtd->erasesize) - 1)));
3937 +
3938 + ops.mode = MTD_OOB_RAW;
3939 + ops.len = current_mtd->writesize + current_mtd->oobsize;
3940 + ops.ooblen = current_mtd->oobsize;
3941 + ops.datbuf = mBuf;
3942 + ops.oobbuf = spare_buf;
3943 +
3944 + printk("[msm_nand_read_dpram] number of blocks = %u, offset = %u, page size = %u, block size = %u\n", (unsigned )current_mtd->size / (unsigned )current_mtd->erasesize, offset, current_mtd->writesize, current_mtd->erasesize);
3945 +
3946 + return msm_nand_read_oob(current_mtd, offset, &ops);
3947 +}
3948 +EXPORT_SYMBOL(msm_nand_read_dpram);
3949 +
3950 +void msm_read_param(char *mBuf)
3951 +{
3952 + char data_buf[4096] = { 0, };
3953 + char spare_buf[128] = { 0, };
3954 + struct mtd_oob_ops ops = { 0, };
3955 + int data_size = 0;
3956 +
3957 + if (current_mtd->oobsize == 64) {
3958 + data_size = 2048;
3959 + }
3960 + else if (current_mtd->oobsize == 128) {
3961 + data_size = 4096;
3962 + }
3963 +
3964 + ops.mode = MTD_OOB_RAW;
3965 + ops.len = data_size+current_mtd->oobsize;
3966 + ops.retlen = 0;
3967 + ops.ooblen = current_mtd->oobsize;
3968 + ops.datbuf = data_buf;
3969 + ops.oobbuf = spare_buf;
3970 +
3971 + /* erasize == size of entire block == page size * pages per block */
3972 + while(msm_nand_block_isbad(current_mtd, (param_start_block * current_mtd->erasesize)))
3973 + {
3974 + printk("msm_read_param: bad block\n");
3975 + param_start_block++;
3976 + }
3977 +
3978 + if ( param_start_block >= param_end_block) {
3979 + param_start_block = param_end_block - 1;
3980 + printk("All nand block in param partition has been crashed\n");
3981 + }
3982 +
3983 + msm_nand_read_oob(current_mtd, (param_start_block * current_mtd->erasesize), &ops);
3984 + memcpy(mBuf,data_buf,sizeof(data_buf));
3985 +}
3986 +EXPORT_SYMBOL(msm_read_param);
3987 +
3988 +void msm_write_param(char *mBuf)
3989 +{
3990 + char data_buf[4096] = { 0, };
3991 + char spare_buf[128] = { 0, };
3992 + struct mtd_oob_ops ops = { 0, };
3993 + struct erase_info *param_erase_info = 0;
3994 + int data_size = 0;
3995 +
3996 + if (current_mtd->oobsize == 64) {
3997 + data_size = 2048;
3998 + }
3999 + else if (current_mtd->oobsize == 128) {
4000 + data_size = 4096;
4001 + }
4002 +
4003 + param_erase_info = kzalloc(sizeof(struct erase_info), GFP_KERNEL);
4004 + if(0 == param_erase_info)
4005 + {
4006 + printk("msm_write_param: memory allocation error\n");
4007 + return;
4008 + }
4009 + param_erase_info->mtd = current_mtd;
4010 + /* erasize == size of entire block == page size * pages per block */
4011 + param_erase_info->addr = param_start_block * current_mtd->erasesize;
4012 + param_erase_info->len = current_mtd->erasesize;
4013 + if(!msm_nand_erase(current_mtd, param_erase_info)) {
4014 + pr_info("parameter block erase success\n");
4015 + }
4016 +
4017 + memset(spare_buf,0xFF,current_mtd->oobsize);
4018 + memcpy(data_buf,mBuf,sizeof(data_buf));
4019 +
4020 + ops.mode = MTD_OOB_RAW;
4021 + ops.len = data_size+current_mtd->oobsize;
4022 + ops.retlen = 0;
4023 + ops.ooblen = current_mtd->oobsize;
4024 + ops.datbuf = data_buf;
4025 + ops.oobbuf = spare_buf;
4026 +
4027 + msm_nand_write_oob(current_mtd, param_erase_info->addr, &ops);
4028 +
4029 + kfree(param_erase_info);
4030 +}
4031 +EXPORT_SYMBOL(msm_write_param);
4032 +
3789 4033 /**
3790 4034 * msm_nand_suspend - [MTD Interface] Suspend the msm_nand flash
3791 4035 * @param mtd MTD device structure
3792 4036
... ... @@ -3991,10 +4235,10 @@
3991 4235 "==========================\n");
3992 4236
3993 4237 if ((onenand_info.manufacturer_id != 0x00EC)
3994 - || ((onenand_info.device_id & 0x0040) != 0x0040)
4238 + || ((onenand_info.device_id & 0x0050) != 0x0050)
3995 4239 || (onenand_info.data_buf_size != 0x0800)
3996 4240 || (onenand_info.boot_buf_size != 0x0200)
3997 - || (onenand_info.num_of_buffers != 0x0201)
4241 + || (onenand_info.num_of_buffers != 0x0101)
3998 4242 || (onenand_info.technology != 0)) {
3999 4243
4000 4244 pr_info("%s: Detected an unsupported device\n"
4001 4245
4002 4246
... ... @@ -4014,13 +4258,13 @@
4014 4258 struct msm_nand_chip *chip = mtd->priv;
4015 4259
4016 4260 struct {
4017 - dmov_s cmd[53];
4261 + dmov_s cmd[78];
4018 4262 unsigned cmdptr;
4019 4263 struct {
4020 4264 uint32_t sfbcfg;
4021 - uint32_t sfcmd[9];
4265 + uint32_t sfcmd[14];
4022 4266 uint32_t sfexec;
4023 - uint32_t sfstat[9];
4267 + uint32_t sfstat[14];
4024 4268 uint32_t addr0;
4025 4269 uint32_t addr1;
4026 4270 uint32_t addr2;
... ... @@ -4035,7 +4279,7 @@
4035 4279 uint32_t data4;
4036 4280 uint32_t data5;
4037 4281 uint32_t data6;
4038 - uint32_t macro[5];
4282 + uint32_t macro[10];
4039 4283 } data;
4040 4284 } *dma_buffer;
4041 4285 dmov_s *cmd;
4042 4286
4043 4287
... ... @@ -4127,16 +4371,22 @@
4127 4371 return -EINVAL;
4128 4372 }
4129 4373
4130 - if (ops->oobbuf && !ops->datbuf) {
4374 + if (ops->oobbuf && !ops->datbuf)
4131 4375 page_count = ops->ooblen / ((ops->mode == MTD_OOB_AUTO) ?
4132 4376 mtd->oobavail : mtd->oobsize);
4133 - if ((page_count == 0) && (ops->ooblen))
4134 - page_count = 1;
4135 - } else if (ops->mode != MTD_OOB_RAW)
4136 - page_count = ops->len / mtd->writesize;
4137 - else
4138 - page_count = ops->len / (mtd->writesize + mtd->oobsize);
4377 + else if (ops->mode != MTD_OOB_RAW)
4378 + page_count = ops->len / mtd->writesize;
4379 + else
4380 + page_count = ops->len / (mtd->writesize + mtd->oobsize);
4139 4381
4382 + if ((ops->mode == MTD_OOB_AUTO) && (ops->oobbuf != NULL)) {
4383 + if (page_count * mtd->oobavail > ops->ooblen) {
4384 + pr_err("%s: unsupported ops->ooblen for "
4385 + "AUTO, %d\n", __func__, ops->ooblen);
4386 + return -EINVAL;
4387 + }
4388 + }
4389 +
4140 4390 if ((ops->mode == MTD_OOB_PLACE) && (ops->oobbuf != NULL)) {
4141 4391 if (page_count * mtd->oobsize > ops->ooblen) {
4142 4392 pr_err("%s: unsupported ops->ooblen for "
4143 4393
4144 4394
... ... @@ -4232,14 +4482,34 @@
4232 4482 MSM_NAND_SFCMD_DATXS,
4233 4483 nand_sfcmd_mode,
4234 4484 MSM_NAND_SFCMD_DATRD);
4235 - dma_buffer->data.sfcmd[7] = SFLASH_PREPCMD(32, 0, 0,
4485 + dma_buffer->data.sfcmd[7] = SFLASH_PREPCMD(256, 0, 0,
4236 4486 MSM_NAND_SFCMD_DATXS,
4237 4487 nand_sfcmd_mode,
4238 4488 MSM_NAND_SFCMD_DATRD);
4239 - dma_buffer->data.sfcmd[8] = SFLASH_PREPCMD(4, 10, 0,
4489 + dma_buffer->data.sfcmd[8] = SFLASH_PREPCMD(256, 0, 0,
4490 + MSM_NAND_SFCMD_DATXS,
4491 + nand_sfcmd_mode,
4492 + MSM_NAND_SFCMD_DATRD);
4493 + dma_buffer->data.sfcmd[9] = SFLASH_PREPCMD(256, 0, 0,
4494 + MSM_NAND_SFCMD_DATXS,
4495 + nand_sfcmd_mode,
4496 + MSM_NAND_SFCMD_DATRD);
4497 + dma_buffer->data.sfcmd[10] = SFLASH_PREPCMD(256, 0, 0,
4498 + MSM_NAND_SFCMD_DATXS,
4499 + nand_sfcmd_mode,
4500 + MSM_NAND_SFCMD_DATRD);
4501 + dma_buffer->data.sfcmd[11] = SFLASH_PREPCMD(32, 0, 0,
4502 + MSM_NAND_SFCMD_DATXS,
4503 + nand_sfcmd_mode,
4504 + MSM_NAND_SFCMD_DATRD);
4505 + dma_buffer->data.sfcmd[12] = SFLASH_PREPCMD(4, 10, 0,
4240 4506 MSM_NAND_SFCMD_CMDXS,
4241 4507 nand_sfcmd_mode,
4242 4508 MSM_NAND_SFCMD_REGWR);
4509 + dma_buffer->data.sfcmd[13] = SFLASH_PREPCMD(32, 0, 0,
4510 + MSM_NAND_SFCMD_DATXS,
4511 + nand_sfcmd_mode,
4512 + MSM_NAND_SFCMD_DATRD);
4243 4513 dma_buffer->data.sfexec = 1;
4244 4514 dma_buffer->data.sfstat[0] = CLEAN_DATA_32;
4245 4515 dma_buffer->data.sfstat[1] = CLEAN_DATA_32;
... ... @@ -4250,6 +4520,11 @@
4250 4520 dma_buffer->data.sfstat[6] = CLEAN_DATA_32;
4251 4521 dma_buffer->data.sfstat[7] = CLEAN_DATA_32;
4252 4522 dma_buffer->data.sfstat[8] = CLEAN_DATA_32;
4523 + dma_buffer->data.sfstat[9] = CLEAN_DATA_32;
4524 + dma_buffer->data.sfstat[10] = CLEAN_DATA_32;
4525 + dma_buffer->data.sfstat[11] = CLEAN_DATA_32;
4526 + dma_buffer->data.sfstat[12] = CLEAN_DATA_32;
4527 + dma_buffer->data.sfstat[13] = CLEAN_DATA_32;
4253 4528 dma_buffer->data.addr0 = (ONENAND_INTERRUPT_STATUS << 16) |
4254 4529 (ONENAND_SYSTEM_CONFIG_1);
4255 4530 dma_buffer->data.addr1 = (ONENAND_START_ADDRESS_8 << 16) |
... ... @@ -4282,7 +4557,12 @@
4282 4557 dma_buffer->data.macro[1] = 0x0300;
4283 4558 dma_buffer->data.macro[2] = 0x0400;
4284 4559 dma_buffer->data.macro[3] = 0x0500;
4285 - dma_buffer->data.macro[4] = 0x8010;
4560 + dma_buffer->data.macro[4] = 0x0600;
4561 + dma_buffer->data.macro[5] = 0x0700;
4562 + dma_buffer->data.macro[6] = 0x0800;
4563 + dma_buffer->data.macro[7] = 0x0900;
4564 + dma_buffer->data.macro[8] = 0x8010;
4565 + dma_buffer->data.macro[9] = 0x8030;
4286 4566
4287 4567 /*************************************************************/
4288 4568 /* Write necessary address registers in the onenand device */
... ... @@ -4424,7 +4704,7 @@
4424 4704 dma_buffer->data.data3 = (CLEAN_DATA_16 << 16) |
4425 4705 (ONENAND_CMDLOAD);
4426 4706
4427 - for (i = 0; i < 4; i++) {
4707 + for (i = 0; i < 8; i++) {
4428 4708
4429 4709 /* Block on cmd ready and write CMD register */
4430 4710 cmd->cmd = DST_CRCI_NAND_CMD;
... ... @@ -4473,7 +4753,7 @@
4473 4753 /* Block on cmd ready and write CMD register */
4474 4754 cmd->cmd = DST_CRCI_NAND_CMD;
4475 4755 cmd->src = msm_virt_to_dma(chip,
4476 - &dma_buffer->data.sfcmd[7]);
4756 + &dma_buffer->data.sfcmd[11]);
4477 4757 cmd->dst = MSM_NAND_SFLASHC_CMD;
4478 4758 cmd->len = 4;
4479 4759 cmd++;
... ... @@ -4481,7 +4761,7 @@
4481 4761 /* Write the MACRO1 register */
4482 4762 cmd->cmd = 0;
4483 4763 cmd->src = msm_virt_to_dma(chip,
4484 - &dma_buffer->data.macro[4]);
4764 + &dma_buffer->data.macro[8]);
4485 4765 cmd->dst = MSM_NAND_MACRO1_REG;
4486 4766 cmd->len = 4;
4487 4767 cmd++;
4488 4768
... ... @@ -4498,13 +4778,13 @@
4498 4778 cmd->cmd = SRC_CRCI_NAND_DATA;
4499 4779 cmd->src = MSM_NAND_SFLASHC_STATUS;
4500 4780 cmd->dst = msm_virt_to_dma(chip,
4501 - &dma_buffer->data.sfstat[7]);
4781 + &dma_buffer->data.sfstat[11]);
4502 4782 cmd->len = 4;
4503 4783 cmd++;
4504 4784
4505 4785 /* Transfer nand ctlr buffer contents into usr buf */
4506 4786 if (ops->mode == MTD_OOB_AUTO) {
4507 - for (i = 0; i < MTD_MAX_OOBFREE_ENTRIES; i++) {
4787 + for (i = 0; i < 4; i++) {
4508 4788 cmd->cmd = 0;
4509 4789 cmd->src = MSM_NAND_FLASH_BUFFER +
4510 4790 mtd->ecclayout->oobfree[i].offset;
4511 4791
4512 4792
4513 4793
4514 4794
... ... @@ -4520,27 +4800,93 @@
4520 4800 cmd->cmd = 0;
4521 4801 cmd->src = MSM_NAND_FLASH_BUFFER;
4522 4802 cmd->dst = oob_dma_addr_curr;
4523 - cmd->len = mtd->oobsize;
4524 - oob_dma_addr_curr += mtd->oobsize;
4803 + cmd->len = 64;
4804 + oob_dma_addr_curr += 64;
4525 4805 cmd++;
4526 4806 }
4527 4807 if (ops->mode == MTD_OOB_RAW) {
4528 4808 cmd->cmd = 0;
4529 4809 cmd->src = MSM_NAND_FLASH_BUFFER;
4530 4810 cmd->dst = data_dma_addr_curr;
4531 - cmd->len = mtd->oobsize;
4532 - data_dma_addr_curr += mtd->oobsize;
4811 + cmd->len = 64;
4812 + data_dma_addr_curr += 64;
4533 4813 cmd++;
4534 4814 }
4535 4815 }
4816 + // read second spareRAM
4817 + if ((ops->oobbuf) || (ops->mode == MTD_OOB_RAW)) {
4536 4818
4819 + /* Block on cmd ready and write CMD register */
4820 + cmd->cmd = DST_CRCI_NAND_CMD;
4821 + cmd->src = msm_virt_to_dma(chip,
4822 + &dma_buffer->data.sfcmd[13]);
4823 + cmd->dst = MSM_NAND_SFLASHC_CMD;
4824 + cmd->len = 4;
4825 + cmd++;
4826 +
4827 + /* Write the MACRO1 register */
4828 + cmd->cmd = 0;
4829 + cmd->src = msm_virt_to_dma(chip,
4830 + &dma_buffer->data.macro[9]);
4831 + cmd->dst = MSM_NAND_MACRO1_REG;
4832 + cmd->len = 4;
4833 + cmd++;
4834 +
4835 + /* Kick the execute command */
4836 + cmd->cmd = 0;
4837 + cmd->src = msm_virt_to_dma(chip,
4838 + &dma_buffer->data.sfexec);
4839 + cmd->dst = MSM_NAND_SFLASHC_EXEC_CMD;
4840 + cmd->len = 4;
4841 + cmd++;
4842 +
4843 + /* Block on data ready, and read status register */
4844 + cmd->cmd = SRC_CRCI_NAND_DATA;
4845 + cmd->src = MSM_NAND_SFLASHC_STATUS;
4846 + cmd->dst = msm_virt_to_dma(chip,
4847 + &dma_buffer->data.sfstat[13]);
4848 + cmd->len = 4;
4849 + cmd++;
4850 +
4851 + /* Transfer nand ctlr buffer contents into usr buf */
4852 + if (ops->mode == MTD_OOB_AUTO) {
4853 + for (i = 4; i < 8; i++) {
4854 + cmd->cmd = 0;
4855 + cmd->src = MSM_NAND_FLASH_BUFFER +
4856 + (mtd->ecclayout->oobfree[i].offset - 64);
4857 + cmd->dst = oob_dma_addr_curr;
4858 + cmd->len =
4859 + mtd->ecclayout->oobfree[i].length;
4860 + oob_dma_addr_curr +=
4861 + mtd->ecclayout->oobfree[i].length;
4862 + cmd++;
4863 + }
4864 + }
4865 + if (ops->mode == MTD_OOB_PLACE) {
4866 + cmd->cmd = 0;
4867 + cmd->src = MSM_NAND_FLASH_BUFFER;
4868 + cmd->dst = oob_dma_addr_curr;
4869 + cmd->len = 64;
4870 + oob_dma_addr_curr += 64;
4871 + cmd++;
4872 + }
4873 + if (ops->mode == MTD_OOB_RAW) {
4874 + cmd->cmd = 0;
4875 + cmd->src = MSM_NAND_FLASH_BUFFER;
4876 + cmd->dst = data_dma_addr_curr;
4877 + cmd->len = 64;
4878 + data_dma_addr_curr += 64;
4879 + cmd++;
4880 + }
4881 + }
4882 +
4537 4883 /*************************************************************/
4538 4884 /* Restore the necessary registers to proper values */
4539 4885 /*************************************************************/
4540 4886
4541 4887 /* Block on cmd ready and write CMD register */
4542 4888 cmd->cmd = DST_CRCI_NAND_CMD;
4543 - cmd->src = msm_virt_to_dma(chip, &dma_buffer->data.sfcmd[8]);
4889 + cmd->src = msm_virt_to_dma(chip, &dma_buffer->data.sfcmd[12]);
4544 4890 cmd->dst = MSM_NAND_SFLASHC_CMD;
4545 4891 cmd->len = 4;
4546 4892 cmd++;
4547 4893
... ... @@ -4555,12 +4901,12 @@
4555 4901 /* Block on data ready, and read the status register */
4556 4902 cmd->cmd = SRC_CRCI_NAND_DATA;
4557 4903 cmd->src = MSM_NAND_SFLASHC_STATUS;
4558 - cmd->dst = msm_virt_to_dma(chip, &dma_buffer->data.sfstat[8]);
4904 + cmd->dst = msm_virt_to_dma(chip, &dma_buffer->data.sfstat[12]);
4559 4905 cmd->len = 4;
4560 4906 cmd++;
4561 4907
4562 4908
4563 - BUILD_BUG_ON(53 != ARRAY_SIZE(dma_buffer->cmd));
4909 + BUILD_BUG_ON(78 != ARRAY_SIZE(dma_buffer->cmd));
4564 4910 BUG_ON(cmd - dma_buffer->cmd > ARRAY_SIZE(dma_buffer->cmd));
4565 4911 dma_buffer->cmd[0].cmd |= CMD_OCB;
4566 4912 cmd[-1].cmd |= CMD_OCU | CMD_LC;
... ... @@ -4583,7 +4929,7 @@
4583 4929
4584 4930 #if VERBOSE
4585 4931 pr_info("\n%s: sflash status %x %x %x %x %x %x %x"
4586 - "%x %x\n", __func__,
4932 + "%x %x %x %x %x %x %x\n", __func__,
4587 4933 dma_buffer->data.sfstat[0],
4588 4934 dma_buffer->data.sfstat[1],
4589 4935 dma_buffer->data.sfstat[2],
... ... @@ -4592,7 +4938,12 @@
4592 4938 dma_buffer->data.sfstat[5],
4593 4939 dma_buffer->data.sfstat[6],
4594 4940 dma_buffer->data.sfstat[7],
4595 - dma_buffer->data.sfstat[8]);
4941 + dma_buffer->data.sfstat[8],
4942 + dma_buffer->data.sfstat[9],
4943 + dma_buffer->data.sfstat[10],
4944 + dma_buffer->data.sfstat[11],
4945 + dma_buffer->data.sfstat[12],
4946 + dma_buffer->data.sfstat[13]);
4596 4947
4597 4948 pr_info("%s: controller_status = %x\n", __func__,
4598 4949 controller_status);
... ... @@ -4606,7 +4957,7 @@
4606 4957 || (dma_buffer->data.sfstat[0] & 0x110)
4607 4958 || (dma_buffer->data.sfstat[1] & 0x110)
4608 4959 || (dma_buffer->data.sfstat[2] & 0x110)
4609 - || (dma_buffer->data.sfstat[8] & 0x110)
4960 + || (dma_buffer->data.sfstat[12] & 0x110)
4610 4961 || ((dma_buffer->data.sfstat[3] & 0x110) &&
4611 4962 (ops->datbuf))
4612 4963 || ((dma_buffer->data.sfstat[4] & 0x110) &&
4613 4964
... ... @@ -4616,7 +4967,18 @@
4616 4967 || ((dma_buffer->data.sfstat[6] & 0x110) &&
4617 4968 (ops->datbuf))
4618 4969 || ((dma_buffer->data.sfstat[7] & 0x110) &&
4970 + (ops->datbuf))
4971 + || ((dma_buffer->data.sfstat[8] & 0x110) &&
4972 + (ops->datbuf))
4973 + || ((dma_buffer->data.sfstat[9] & 0x110) &&
4974 + (ops->datbuf))
4975 + || ((dma_buffer->data.sfstat[10] & 0x110) &&
4976 + (ops->datbuf))
4977 + || ((dma_buffer->data.sfstat[11] & 0x110) &&
4619 4978 ((ops->oobbuf)
4979 + || (ops->mode == MTD_OOB_RAW)))
4980 + || ((dma_buffer->data.sfstat[13] & 0x110) &&
4981 + ((ops->oobbuf)
4620 4982 || (ops->mode == MTD_OOB_RAW)))) {
4621 4983 pr_info("%s: ECC/MPU/OP error\n", __func__);
4622 4984 err = -EIO;
4623 4985
4624 4986
... ... @@ -4695,13 +5057,13 @@
4695 5057 struct msm_nand_chip *chip = mtd->priv;
4696 5058
4697 5059 struct {
4698 - dmov_s cmd[53];
5060 + dmov_s cmd[78];
4699 5061 unsigned cmdptr;
4700 5062 struct {
4701 5063 uint32_t sfbcfg;
4702 - uint32_t sfcmd[10];
5064 + uint32_t sfcmd[15];
4703 5065 uint32_t sfexec;
4704 - uint32_t sfstat[10];
5066 + uint32_t sfstat[15];
4705 5067 uint32_t addr0;
4706 5068 uint32_t addr1;
4707 5069 uint32_t addr2;
... ... @@ -4716,7 +5078,7 @@
4716 5078 uint32_t data4;
4717 5079 uint32_t data5;
4718 5080 uint32_t data6;
4719 - uint32_t macro[5];
5081 + uint32_t macro[10];
4720 5082 } data;
4721 5083 } *dma_buffer;
4722 5084 dmov_s *cmd;
4723 5085
... ... @@ -4811,15 +5173,13 @@
4811 5173 return -EINVAL;
4812 5174 }
4813 5175
4814 - if (ops->oobbuf && !ops->datbuf) {
5176 + if (ops->oobbuf && !ops->datbuf)
4815 5177 page_count = ops->ooblen / ((ops->mode == MTD_OOB_AUTO) ?
4816 5178 mtd->oobavail : mtd->oobsize);
4817 - if ((page_count == 0) && (ops->ooblen))
4818 - page_count = 1;
4819 - } else if (ops->mode != MTD_OOB_RAW)
4820 - page_count = ops->len / mtd->writesize;
4821 - else
4822 - page_count = ops->len / (mtd->writesize + mtd->oobsize);
5179 + else if (ops->mode != MTD_OOB_RAW)
5180 + page_count = ops->len / mtd->writesize;
5181 + else
5182 + page_count = ops->len / (mtd->writesize + mtd->oobsize);
4823 5183
4824 5184 if ((ops->mode == MTD_OOB_AUTO) && (ops->oobbuf != NULL)) {
4825 5185 if (page_count > 1) {
4826 5186
... ... @@ -4844,13 +5204,13 @@
4844 5204 return -EINVAL;
4845 5205 }
4846 5206
4847 - init_spare_bytes = kmalloc(64, GFP_KERNEL);
5207 + init_spare_bytes = kmalloc(mtd->oobsize, GFP_KERNEL);
4848 5208 if (!init_spare_bytes) {
4849 5209 pr_err("%s: failed to alloc init_spare_bytes buffer\n",
4850 5210 __func__);
4851 5211 return -ENOMEM;
4852 5212 }
4853 - for (i = 0; i < 64; i++)
5213 + for (i = 0; i < mtd->oobsize; i++)
4854 5214 init_spare_bytes[i] = 0xFF;
4855 5215
4856 5216 if ((ops->oobbuf) && (ops->mode == MTD_OOB_AUTO)) {
... ... @@ -4884,7 +5244,7 @@
4884 5244 }
4885 5245 }
4886 5246
4887 - init_dma_addr = msm_nand_dma_map(chip->dev, init_spare_bytes, 64,
5247 + init_dma_addr = msm_nand_dma_map(chip->dev, init_spare_bytes, mtd->oobsize,
4888 5248 DMA_TO_DEVICE);
4889 5249 if (dma_mapping_error(chip->dev, init_dma_addr)) {
4890 5250 pr_err("%s: failed to get dma addr for %p\n",
4891 5251
4892 5252
4893 5253
4894 5254
4895 5255
4896 5256
... ... @@ -4943,26 +5303,46 @@
4943 5303 MSM_NAND_SFCMD_CMDXS,
4944 5304 nand_sfcmd_mode,
4945 5305 MSM_NAND_SFCMD_DATWR);
4946 - dma_buffer->data.sfcmd[5] = SFLASH_PREPCMD(32, 0, 0,
5306 + dma_buffer->data.sfcmd[5] = SFLASH_PREPCMD(256, 0, 0,
4947 5307 MSM_NAND_SFCMD_CMDXS,
4948 5308 nand_sfcmd_mode,
4949 5309 MSM_NAND_SFCMD_DATWR);
4950 - dma_buffer->data.sfcmd[6] = SFLASH_PREPCMD(1, 6, 0,
5310 + dma_buffer->data.sfcmd[6] = SFLASH_PREPCMD(256, 0, 0,
4951 5311 MSM_NAND_SFCMD_CMDXS,
4952 5312 nand_sfcmd_mode,
5313 + MSM_NAND_SFCMD_DATWR);
5314 + dma_buffer->data.sfcmd[7] = SFLASH_PREPCMD(256, 0, 0,
5315 + MSM_NAND_SFCMD_CMDXS,
5316 + nand_sfcmd_mode,
5317 + MSM_NAND_SFCMD_DATWR);
5318 + dma_buffer->data.sfcmd[8] = SFLASH_PREPCMD(256, 0, 0,
5319 + MSM_NAND_SFCMD_CMDXS,
5320 + nand_sfcmd_mode,
5321 + MSM_NAND_SFCMD_DATWR);
5322 + dma_buffer->data.sfcmd[9] = SFLASH_PREPCMD(32, 0, 0,
5323 + MSM_NAND_SFCMD_CMDXS,
5324 + nand_sfcmd_mode,
5325 + MSM_NAND_SFCMD_DATWR);
5326 + dma_buffer->data.sfcmd[10] = SFLASH_PREPCMD(1, 6, 0,
5327 + MSM_NAND_SFCMD_CMDXS,
5328 + nand_sfcmd_mode,
4953 5329 MSM_NAND_SFCMD_REGWR);
4954 - dma_buffer->data.sfcmd[7] = SFLASH_PREPCMD(0, 0, 32,
5330 + dma_buffer->data.sfcmd[11] = SFLASH_PREPCMD(0, 0, 32,
4955 5331 MSM_NAND_SFCMD_CMDXS,
4956 5332 nand_sfcmd_mode,
4957 5333 MSM_NAND_SFCMD_INTHI);
4958 - dma_buffer->data.sfcmd[8] = SFLASH_PREPCMD(3, 7, 0,
5334 + dma_buffer->data.sfcmd[12] = SFLASH_PREPCMD(3, 7, 0,
4959 5335 MSM_NAND_SFCMD_DATXS,
4960 5336 nand_sfcmd_mode,
4961 5337 MSM_NAND_SFCMD_REGRD);
4962 - dma_buffer->data.sfcmd[9] = SFLASH_PREPCMD(4, 10, 0,
5338 + dma_buffer->data.sfcmd[13] = SFLASH_PREPCMD(4, 10, 0,
4963 5339 MSM_NAND_SFCMD_CMDXS,
4964 5340 nand_sfcmd_mode,
4965 5341 MSM_NAND_SFCMD_REGWR);
5342 + dma_buffer->data.sfcmd[14] = SFLASH_PREPCMD(32, 0, 0,
5343 + MSM_NAND_SFCMD_CMDXS,
5344 + nand_sfcmd_mode,
5345 + MSM_NAND_SFCMD_DATWR);
4966 5346 dma_buffer->data.sfexec = 1;
4967 5347 dma_buffer->data.sfstat[0] = CLEAN_DATA_32;
4968 5348 dma_buffer->data.sfstat[1] = CLEAN_DATA_32;
... ... @@ -4974,6 +5354,11 @@
4974 5354 dma_buffer->data.sfstat[7] = CLEAN_DATA_32;
4975 5355 dma_buffer->data.sfstat[8] = CLEAN_DATA_32;
4976 5356 dma_buffer->data.sfstat[9] = CLEAN_DATA_32;
5357 + dma_buffer->data.sfstat[10] = CLEAN_DATA_32;
5358 + dma_buffer->data.sfstat[11] = CLEAN_DATA_32;
5359 + dma_buffer->data.sfstat[12] = CLEAN_DATA_32;
5360 + dma_buffer->data.sfstat[13] = CLEAN_DATA_32;
5361 + dma_buffer->data.sfstat[14] = CLEAN_DATA_32;
4977 5362 dma_buffer->data.addr0 = (ONENAND_INTERRUPT_STATUS << 16) |
4978 5363 (ONENAND_SYSTEM_CONFIG_1);
4979 5364 dma_buffer->data.addr1 = (ONENAND_START_ADDRESS_8 << 16) |
... ... @@ -5006,7 +5391,12 @@
5006 5391 dma_buffer->data.macro[1] = 0x0300;
5007 5392 dma_buffer->data.macro[2] = 0x0400;
5008 5393 dma_buffer->data.macro[3] = 0x0500;
5009 - dma_buffer->data.macro[4] = 0x8010;
5394 + dma_buffer->data.macro[4] = 0x0600;
5395 + dma_buffer->data.macro[5] = 0x0700;
5396 + dma_buffer->data.macro[6] = 0x0800;
5397 + dma_buffer->data.macro[7] = 0x0900;
5398 + dma_buffer->data.macro[8] = 0x8010;
5399 + dma_buffer->data.macro[9] = 0x8030;
5010 5400
5011 5401
5012 5402 /*************************************************************/
... ... @@ -5084,7 +5474,7 @@
5084 5474 dma_buffer->data.data3 = (CLEAN_DATA_16 << 16) |
5085 5475 (ONENAND_CMDPROG);
5086 5476
5087 - for (i = 0; i < 4; i++) {
5477 + for (i = 0; i < 8; i++) {
5088 5478
5089 5479 /* Block on cmd ready and write CMD register */
5090 5480 cmd->cmd = DST_CRCI_NAND_CMD;
... ... @@ -5131,7 +5521,7 @@
5131 5521
5132 5522 /* Block on cmd ready and write CMD register */
5133 5523 cmd->cmd = DST_CRCI_NAND_CMD;
5134 - cmd->src = msm_virt_to_dma(chip, &dma_buffer->data.sfcmd[5]);
5524 + cmd->src = msm_virt_to_dma(chip, &dma_buffer->data.sfcmd[9]);
5135 5525 cmd->dst = MSM_NAND_SFLASHC_CMD;
5136 5526 cmd->len = 4;
5137 5527 cmd++;
5138 5528
5139 5529
5140 5530
5141 5531
... ... @@ -5143,36 +5533,36 @@
5143 5533 cmd->cmd = 0;
5144 5534 cmd->src = init_dma_addr;
5145 5535 cmd->dst = MSM_NAND_FLASH_BUFFER;
5146 - cmd->len = mtd->oobsize;
5536 + cmd->len = 64;
5147 5537 cmd++;
5148 5538 }
5149 5539 if (ops->mode == MTD_OOB_PLACE) {
5150 5540 cmd->cmd = 0;
5151 5541 cmd->src = oob_dma_addr_curr;
5152 5542 cmd->dst = MSM_NAND_FLASH_BUFFER;
5153 - cmd->len = mtd->oobsize;
5154 - oob_dma_addr_curr += mtd->oobsize;
5543 + cmd->len = 64;
5544 + oob_dma_addr_curr += 64;
5155 5545 cmd++;
5156 5546 }
5157 5547 if (ops->mode == MTD_OOB_RAW) {
5158 5548 cmd->cmd = 0;
5159 5549 cmd->src = data_dma_addr_curr;
5160 5550 cmd->dst = MSM_NAND_FLASH_BUFFER;
5161 - cmd->len = mtd->oobsize;
5162 - data_dma_addr_curr += mtd->oobsize;
5551 + cmd->len = 64;
5552 + data_dma_addr_curr += 64;
5163 5553 cmd++;
5164 5554 }
5165 5555 } else {
5166 5556 cmd->cmd = 0;
5167 5557 cmd->src = init_dma_addr;
5168 5558 cmd->dst = MSM_NAND_FLASH_BUFFER;
5169 - cmd->len = mtd->oobsize;
5559 + cmd->len = 64;
5170 5560 cmd++;
5171 5561 }
5172 5562
5173 5563 /* Write the MACRO1 register */
5174 5564 cmd->cmd = 0;
5175 - cmd->src = msm_virt_to_dma(chip, &dma_buffer->data.macro[4]);
5565 + cmd->src = msm_virt_to_dma(chip, &dma_buffer->data.macro[8]);
5176 5566 cmd->dst = MSM_NAND_MACRO1_REG;
5177 5567 cmd->len = 4;
5178 5568 cmd++;
5179 5569
5180 5570
... ... @@ -5187,17 +5577,80 @@
5187 5577 /* Block on data ready, and read the status register */
5188 5578 cmd->cmd = SRC_CRCI_NAND_DATA;
5189 5579 cmd->src = MSM_NAND_SFLASHC_STATUS;
5190 - cmd->dst = msm_virt_to_dma(chip, &dma_buffer->data.sfstat[5]);
5580 + cmd->dst = msm_virt_to_dma(chip, &dma_buffer->data.sfstat[9]);
5191 5581 cmd->len = 4;
5192 5582 cmd++;
5193 5583
5584 + //write the 2o spareRAM
5585 + /* Block on cmd ready and write CMD register */
5586 + cmd->cmd = DST_CRCI_NAND_CMD;
5587 + cmd->src = msm_virt_to_dma(chip, &dma_buffer->data.sfcmd[14]);
5588 + cmd->dst = MSM_NAND_SFLASHC_CMD;
5589 + cmd->len = 4;
5590 + cmd++;
5591 +
5592 + if ((ops->oobbuf) || (ops->mode == MTD_OOB_RAW)) {
5593 +
5594 + /* Transfer user buf contents into nand ctlr buffer */
5595 + if (ops->mode == MTD_OOB_AUTO) {
5596 + cmd->cmd = 0;
5597 + cmd->src = (init_dma_addr + 64);
5598 + cmd->dst = MSM_NAND_FLASH_BUFFER;
5599 + cmd->len = 64;
5600 + cmd++;
5601 + }
5602 + if (ops->mode == MTD_OOB_PLACE) {
5603 + cmd->cmd = 0;
5604 + cmd->src = oob_dma_addr_curr;
5605 + cmd->dst = MSM_NAND_FLASH_BUFFER;
5606 + cmd->len = 64;
5607 + oob_dma_addr_curr += 64;
5608 + cmd++;
5609 + }
5610 + if (ops->mode == MTD_OOB_RAW) {
5611 + cmd->cmd = 0;
5612 + cmd->src = data_dma_addr_curr;
5613 + cmd->dst = MSM_NAND_FLASH_BUFFER;
5614 + cmd->len = 64;
5615 + data_dma_addr_curr += 64;
5616 + cmd++;
5617 + }
5618 + } else {
5619 + cmd->cmd = 0;
5620 + cmd->src = init_dma_addr;
5621 + cmd->dst = MSM_NAND_FLASH_BUFFER;
5622 + cmd->len = 64;
5623 + cmd++;
5624 + }
5625 +
5626 + /* Write the MACRO1 register */
5627 + cmd->cmd = 0;
5628 + cmd->src = msm_virt_to_dma(chip, &dma_buffer->data.macro[9]);
5629 + cmd->dst = MSM_NAND_MACRO1_REG;
5630 + cmd->len = 4;
5631 + cmd++;
5632 +
5633 + /* Kick the execute command */
5634 + cmd->cmd = 0;
5635 + cmd->src = msm_virt_to_dma(chip, &dma_buffer->data.sfexec);
5636 + cmd->dst = MSM_NAND_SFLASHC_EXEC_CMD;
5637 + cmd->len = 4;
5638 + cmd++;
5639 +
5640 + /* Block on data ready, and read the status register */
5641 + cmd->cmd = SRC_CRCI_NAND_DATA;
5642 + cmd->src = MSM_NAND_SFLASHC_STATUS;
5643 + cmd->dst = msm_virt_to_dma(chip, &dma_buffer->data.sfstat[14]);
5644 + cmd->len = 4;
5645 + cmd++;
5646 +
5194 5647 /*********************************************************/
5195 5648 /* Issuing write command */
5196 5649 /*********************************************************/
5197 5650
5198 5651 /* Block on cmd ready and write CMD register */
5199 5652 cmd->cmd = DST_CRCI_NAND_CMD;
5200 - cmd->src = msm_virt_to_dma(chip, &dma_buffer->data.sfcmd[6]);
5653 + cmd->src = msm_virt_to_dma(chip, &dma_buffer->data.sfcmd[10]);
5201 5654 cmd->dst = MSM_NAND_SFLASHC_CMD;
5202 5655 cmd->len = 4;
5203 5656 cmd++;
... ... @@ -5212,7 +5665,7 @@
5212 5665 /* Block on data ready, and read the status register */
5213 5666 cmd->cmd = SRC_CRCI_NAND_DATA;
5214 5667 cmd->src = MSM_NAND_SFLASHC_STATUS;
5215 - cmd->dst = msm_virt_to_dma(chip, &dma_buffer->data.sfstat[6]);
5668 + cmd->dst = msm_virt_to_dma(chip, &dma_buffer->data.sfstat[10]);
5216 5669 cmd->len = 4;
5217 5670 cmd++;
5218 5671
... ... @@ -5222,7 +5675,7 @@
5222 5675
5223 5676 /* Block on cmd ready and write CMD register */
5224 5677 cmd->cmd = DST_CRCI_NAND_CMD;
5225 - cmd->src = msm_virt_to_dma(chip, &dma_buffer->data.sfcmd[7]);
5678 + cmd->src = msm_virt_to_dma(chip, &dma_buffer->data.sfcmd[11]);
5226 5679 cmd->dst = MSM_NAND_SFLASHC_CMD;
5227 5680 cmd->len = 4;
5228 5681 cmd++;
... ... @@ -5237,7 +5690,7 @@
5237 5690 /* Block on data ready, and read the status register */
5238 5691 cmd->cmd = SRC_CRCI_NAND_DATA;
5239 5692 cmd->src = MSM_NAND_SFLASHC_STATUS;
5240 - cmd->dst = msm_virt_to_dma(chip, &dma_buffer->data.sfstat[7]);
5693 + cmd->dst = msm_virt_to_dma(chip, &dma_buffer->data.sfstat[11]);
5241 5694 cmd->len = 4;
5242 5695 cmd++;
5243 5696
... ... @@ -5247,7 +5700,7 @@
5247 5700
5248 5701 /* Block on cmd ready and write CMD register */
5249 5702 cmd->cmd = DST_CRCI_NAND_CMD;
5250 - cmd->src = msm_virt_to_dma(chip, &dma_buffer->data.sfcmd[8]);
5703 + cmd->src = msm_virt_to_dma(chip, &dma_buffer->data.sfcmd[12]);
5251 5704 cmd->dst = MSM_NAND_SFLASHC_CMD;
5252 5705 cmd->len = 4;
5253 5706 cmd++;
... ... @@ -5262,7 +5715,7 @@
5262 5715 /* Block on data ready, and read the status register */
5263 5716 cmd->cmd = SRC_CRCI_NAND_DATA;
5264 5717 cmd->src = MSM_NAND_SFLASHC_STATUS;
5265 - cmd->dst = msm_virt_to_dma(chip, &dma_buffer->data.sfstat[8]);
5718 + cmd->dst = msm_virt_to_dma(chip, &dma_buffer->data.sfstat[12]);
5266 5719 cmd->len = 4;
5267 5720 cmd++;
5268 5721
... ... @@ -5286,7 +5739,7 @@
5286 5739
5287 5740 /* Block on cmd ready and write CMD register */
5288 5741 cmd->cmd = DST_CRCI_NAND_CMD;
5289 - cmd->src = msm_virt_to_dma(chip, &dma_buffer->data.sfcmd[9]);
5742 + cmd->src = msm_virt_to_dma(chip, &dma_buffer->data.sfcmd[13]);
5290 5743 cmd->dst = MSM_NAND_SFLASHC_CMD;
5291 5744 cmd->len = 4;
5292 5745 cmd++;
... ... @@ -5306,7 +5759,7 @@
5306 5759 cmd++;
5307 5760
5308 5761
5309 - BUILD_BUG_ON(53 != ARRAY_SIZE(dma_buffer->cmd));
5762 + BUILD_BUG_ON(78 != ARRAY_SIZE(dma_buffer->cmd));
5310 5763 BUG_ON(cmd - dma_buffer->cmd > ARRAY_SIZE(dma_buffer->cmd));
5311 5764 dma_buffer->cmd[0].cmd |= CMD_OCB;
5312 5765 cmd[-1].cmd |= CMD_OCU | CMD_LC;
... ... @@ -5326,7 +5779,7 @@
5326 5779
5327 5780 #if VERBOSE
5328 5781 pr_info("\n%s: sflash status %x %x %x %x %x %x %x"
5329 - " %x %x %x\n", __func__,
5782 + " %x %x %x %x %x %x %x %x\n", __func__,
5330 5783 dma_buffer->data.sfstat[0],
5331 5784 dma_buffer->data.sfstat[1],
5332 5785 dma_buffer->data.sfstat[2],
... ... @@ -5336,7 +5789,12 @@
5336 5789 dma_buffer->data.sfstat[6],
5337 5790 dma_buffer->data.sfstat[7],
5338 5791 dma_buffer->data.sfstat[8],
5339 - dma_buffer->data.sfstat[9]);
5792 + dma_buffer->data.sfstat[9],
5793 + dma_buffer->data.sfstat[10],
5794 + dma_buffer->data.sfstat[11],
5795 + dma_buffer->data.sfstat[12],
5796 + dma_buffer->data.sfstat[13],
5797 + dma_buffer->data.sfstat[14]);
5340 5798
5341 5799 pr_info("%s: controller_status = %x\n", __func__,
5342 5800 controller_status);
... ... @@ -5348,10 +5806,10 @@
5348 5806 /* Check for errors, protection violations etc */
5349 5807 if ((controller_status != 0)
5350 5808 || (dma_buffer->data.sfstat[0] & 0x110)
5351 - || (dma_buffer->data.sfstat[6] & 0x110)
5352 - || (dma_buffer->data.sfstat[7] & 0x110)
5353 - || (dma_buffer->data.sfstat[8] & 0x110)
5354 - || (dma_buffer->data.sfstat[9] & 0x110)
5809 + || (dma_buffer->data.sfstat[10] & 0x110)
5810 + || (dma_buffer->data.sfstat[11] & 0x110)
5811 + || (dma_buffer->data.sfstat[12] & 0x110)
5812 + || (dma_buffer->data.sfstat[13] & 0x110)
5355 5813 || ((dma_buffer->data.sfstat[1] & 0x110) &&
5356 5814 (ops->datbuf))
5357 5815 || ((dma_buffer->data.sfstat[2] & 0x110) &&
5358 5816
... ... @@ -5361,7 +5819,18 @@
5361 5819 || ((dma_buffer->data.sfstat[4] & 0x110) &&
5362 5820 (ops->datbuf))
5363 5821 || ((dma_buffer->data.sfstat[5] & 0x110) &&
5822 + (ops->datbuf))
5823 + || ((dma_buffer->data.sfstat[6] & 0x110) &&
5824 + (ops->datbuf))
5825 + || ((dma_buffer->data.sfstat[7] & 0x110) &&
5826 + (ops->datbuf))
5827 + || ((dma_buffer->data.sfstat[8] & 0x110) &&
5828 + (ops->datbuf))
5829 + || ((dma_buffer->data.sfstat[9] & 0x110) &&
5364 5830 ((ops->oobbuf)
5831 + || (ops->mode == MTD_OOB_RAW)))
5832 + || ((dma_buffer->data.sfstat[14] & 0x110) &&
5833 + ((ops->oobbuf)
5365 5834 || (ops->mode == MTD_OOB_RAW)))) {
5366 5835 pr_info("%s: ECC/MPU/OP error\n", __func__);
5367 5836 err = -EIO;
... ... @@ -5375,7 +5844,7 @@
5375 5844
5376 5845 msm_nand_release_dma_buffer(chip, dma_buffer, sizeof(*dma_buffer));
5377 5846
5378 - dma_unmap_page(chip->dev, init_dma_addr, 64, DMA_TO_DEVICE);
5847 + dma_unmap_page(chip->dev, init_dma_addr, mtd->oobsize, DMA_TO_DEVICE);
5379 5848
5380 5849 err_dma_map_initbuf_failed:
5381 5850 if (ops->oobbuf) {
5382 5851
5383 5852
... ... @@ -5806,18 +6275,18 @@
5806 6275 return -EINVAL;
5807 6276 }
5808 6277
5809 - buffer = kmalloc(2112, GFP_KERNEL|GFP_DMA);
6278 + buffer = kmalloc(4224, GFP_KERNEL|GFP_DMA);
5810 6279 if (buffer == 0) {
5811 6280 pr_err("%s: Could not kmalloc for buffer\n",
5812 6281 __func__);
5813 6282 return -ENOMEM;
5814 6283 }
5815 6284
5816 - memset(buffer, 0x00, 2112);
5817 - oobptr = &(buffer[2048]);
6285 + memset(buffer, 0x00, 4224);
6286 + oobptr = &(buffer[4096]);
5818 6287
5819 6288 ops.mode = MTD_OOB_RAW;
5820 - ops.len = 2112;
6289 + ops.len = 4224;
5821 6290 ops.retlen = 0;
5822 6291 ops.ooblen = 0;
5823 6292 ops.oobretlen = 0;
... ... @@ -5837,7 +6306,11 @@
5837 6306 if ((oobptr[0] != 0xFF) || (oobptr[1] != 0xFF) ||
5838 6307 (oobptr[16] != 0xFF) || (oobptr[17] != 0xFF) ||
5839 6308 (oobptr[32] != 0xFF) || (oobptr[33] != 0xFF) ||
5840 - (oobptr[48] != 0xFF) || (oobptr[49] != 0xFF)
6309 + (oobptr[48] != 0xFF) || (oobptr[49] != 0xFF) ||
6310 + (oobptr[64] != 0xFF) || (oobptr[65] != 0xFF) ||
6311 + (oobptr[80] != 0xFF) || (oobptr[81] != 0xFF) ||
6312 + (oobptr[96] != 0xFF) || (oobptr[97] != 0xFF) ||
6313 + (oobptr[112] != 0xFF) || (oobptr[113] != 0xFF)
5841 6314 ) {
5842 6315 ret = 1;
5843 6316 break;
... ... @@ -5870,7 +6343,7 @@
5870 6343 buffer = page_address(ZERO_PAGE());
5871 6344
5872 6345 ops.mode = MTD_OOB_RAW;
5873 - ops.len = 2112;
6346 + ops.len = 4224;
5874 6347 ops.retlen = 0;
5875 6348 ops.ooblen = 0;
5876 6349 ops.oobretlen = 0;
5877 6350
... ... @@ -6638,11 +7111,11 @@
6638 7111 return -ENODEV;
6639 7112
6640 7113 mtd->size = 0x1000000 << ((onenand_info.device_id & 0xF0) >> 4);
6641 - mtd->writesize = onenand_info.data_buf_size;
7114 + mtd->writesize = onenand_info.data_buf_size << 1;
6642 7115 mtd->oobsize = mtd->writesize >> 5;
6643 7116 mtd->erasesize = mtd->writesize << 6;
6644 - mtd->oobavail = msm_onenand_oob_64.oobavail;
6645 - mtd->ecclayout = &msm_onenand_oob_64;
7117 + mtd->oobavail = msm_onenand_oob_128.oobavail;
7118 + mtd->ecclayout = &msm_onenand_oob_128;
6646 7119
6647 7120 mtd->type = MTD_NANDFLASH;
6648 7121 mtd->flags = MTD_CAP_NANDFLASH;
6649 7122
6650 7123
6651 7124
6652 7125
6653 7126
6654 7127
... ... @@ -6679,65 +7152,46 @@
6679 7152 int msm_nand_scan(struct mtd_info *mtd, int maxchips)
6680 7153 {
6681 7154 struct msm_nand_chip *chip = mtd->priv;
6682 - uint32_t flash_id = 0, i, mtd_writesize;
7155 + uint32_t flash_id = 0, i = 1, mtd_writesize;
6683 7156 uint8_t dev_found = 0;
6684 7157 uint8_t wide_bus;
6685 - uint32_t manid;
6686 - uint32_t devid;
6687 - uint32_t devcfg;
6688 - struct nand_flash_dev *flashdev = NULL;
6689 - struct nand_manufacturers *flashman = NULL;
7158 + uint8_t index;
6690 7159
6691 7160 /* Probe the Flash device for ONFI compliance */
7161 +#if defined (CONFIG_MACH_COOPER) || defined (CONFIG_MACH_EUROPA) || (CONFIG_MACH_GIO)
7162 + /* Read the Flash ID from the Nand Flash Device */
7163 + flash_id = flash_read_id(chip);
7164 + for (index = 1; index < ARRAY_SIZE(supported_flash); index++)
7165 + if ((flash_id & supported_flash[index].mask) ==
7166 + (supported_flash[index].flash_id &
7167 + (supported_flash[index].mask))) {
7168 + dev_found = 1;
7169 + break;
7170 + }
7171 +#else
6692 7172 if (!flash_onfi_probe(chip)) {
7173 + index = 0;
6693 7174 dev_found = 1;
6694 7175 } else {
6695 7176 /* Read the Flash ID from the Nand Flash Device */
6696 7177 flash_id = flash_read_id(chip);
6697 - manid = flash_id & 0xFF;
6698 - devid = (flash_id >> 8) & 0xFF;
6699 - devcfg = (flash_id >> 24) & 0xFF;
6700 -
6701 - for (i = 0; !flashman && nand_manuf_ids[i].id; ++i)
6702 - if (nand_manuf_ids[i].id == manid)
6703 - flashman = &nand_manuf_ids[i];
6704 - for (i = 0; !flashdev && nand_flash_ids[i].id; ++i)
6705 - if (nand_flash_ids[i].id == devid)
6706 - flashdev = &nand_flash_ids[i];
6707 - if (!flashdev || !flashman) {
6708 - pr_err("ERROR: unknown nand device manuf=%x devid=%x\n",
6709 - manid, devid);
6710 - return -ENOENT;
6711 - } else
6712 - dev_found = 1;
6713 -
6714 - if (!flashdev->pagesize) {
6715 - supported_flash.flash_id = flash_id;
6716 - supported_flash.density = flashdev->chipsize << 20;
6717 - supported_flash.widebus = devcfg & (1 << 6) ? 1 : 0;
6718 - supported_flash.pagesize = 1024 << (devcfg & 0x3);
6719 - supported_flash.blksize = (64 * 1024) <<
6720 - ((devcfg >> 4) & 0x3);
6721 - supported_flash.oobsize = (8 << ((devcfg >> 2) & 1)) *
6722 - (supported_flash.pagesize >> 9);
6723 - } else {
6724 - supported_flash.flash_id = flash_id;
6725 - supported_flash.density = flashdev->chipsize << 20;
6726 - supported_flash.widebus = flashdev->options &
6727 - NAND_BUSWIDTH_16 ? 1 : 0;
6728 - supported_flash.pagesize = flashdev->pagesize;
6729 - supported_flash.blksize = flashdev->erasesize;
6730 - supported_flash.oobsize = flashdev->pagesize >> 5;
6731 - }
7178 + for (index = 1; index < ARRAY_SIZE(supported_flash); index++)
7179 + if ((flash_id & supported_flash[index].mask) ==
7180 + (supported_flash[index].flash_id &
7181 + (supported_flash[index].mask))) {
7182 + dev_found = 1;
7183 + break;
7184 + }
6732 7185 }
7186 +#endif
6733 7187
6734 7188 if (dev_found) {
6735 7189 (!interleave_enable) ? (i = 1) : (i = 2);
6736 - wide_bus = supported_flash.widebus;
6737 - mtd->size = supported_flash.density * i;
6738 - mtd->writesize = supported_flash.pagesize * i;
6739 - mtd->oobsize = supported_flash.oobsize * i;
6740 - mtd->erasesize = supported_flash.blksize * i;
7190 + wide_bus = supported_flash[index].widebus;
7191 + mtd->size = supported_flash[index].density * i;
7192 + mtd->writesize = supported_flash[index].pagesize * i;
7193 + mtd->oobsize = supported_flash[index].oobsize * i;
7194 + mtd->erasesize = supported_flash[index].blksize * i;
6741 7195
6742 7196 if (!interleave_enable)
6743 7197 mtd_writesize = mtd->writesize;
6744 7198
6745 7199
... ... @@ -6746,15 +7200,15 @@
6746 7200
6747 7201 /* Check whether controller and NAND device support 8bit ECC*/
6748 7202 if ((flash_rd_reg(chip, MSM_NAND_HW_INFO) == 0x307)
6749 - && (supported_flash.ecc_correctability >= 8)) {
7203 + && (supported_flash[index].ecc_correctability >= 8)) {
6750 7204 pr_info("Found supported NAND device for %dbit ECC\n",
6751 - supported_flash.ecc_correctability);
7205 + supported_flash[index].ecc_correctability);
6752 7206 enable_bch_ecc = 1;
6753 7207 } else {
6754 7208 pr_info("Found a supported NAND device\n");
6755 7209 }
6756 - pr_info("NAND Id : 0x%x\n", supported_flash.flash_id);
6757 - pr_info("Buswidth : %d Bits\n", (wide_bus) ? 16 : 8);
7210 + pr_info("NAND Id : 0x%x\n", supported_flash[index].flash_id);
7211 + pr_info("Buswidth : %d Bits \n", (wide_bus) ? 16 : 8);
6758 7212 pr_info("Density : %lld MByte\n", (mtd->size>>20));
6759 7213 pr_info("Pagesize : %d Bytes\n", mtd->writesize);
6760 7214 pr_info("Erasesize: %d Bytes\n", mtd->erasesize);
... ... @@ -6783,7 +7237,7 @@
6783 7237 (mtd_writesize >> 9) - 1)) + 1) << 6)
6784 7238 | (0 << 16) /* Bad block in user data area */
6785 7239 | (2 << 17) /* 6 cycle tWB/tRB */
6786 - | ((wide_bus) ? CFG1_WIDE_FLASH : 0); /* Wide flash bit */
7240 + | (wide_bus << 1); /* Wide flash bit */
6787 7241
6788 7242 chip->ecc_buf_cfg = 0x203;
6789 7243 chip->CFG0_RAW = 0xA80420C0;
... ... @@ -6863,6 +7317,16 @@
6863 7317 /* msm_nand_unlock_all(mtd); */
6864 7318
6865 7319 /* return this->scan_bbt(mtd); */
7320 +
7321 + current_mtd = mtd; // for PARAMETER block
7322 +
7323 + for ( i = 0 ; i < msm_nand_data.nr_parts ; i++) {
7324 + if (!strcmp(msm_nand_data.parts[i].name , "parameter")) {
7325 + param_start_block = msm_nand_data.parts[i].offset;
7326 + param_end_block = msm_nand_data.parts[i].offset + msm_nand_data.parts[i].size; // should match with bootloader
7327 + }
7328 + }
7329 +
6866 7330 return 0;
6867 7331 }
6868 7332 EXPORT_SYMBOL_GPL(msm_nand_scan);
6869 7333
... ... @@ -6989,13 +7453,16 @@
6989 7453 if (!res || !res->start)
6990 7454 goto no_dual_nand_ctlr_support;
6991 7455 ebi2_register_base = res->start;
6992 -
7456 +#if defined (CONFIG_MACH_COOPER) || defined (CONFIG_MACH_GIO)
7457 + dual_nand_ctlr_present = 0;
7458 + interleave_enable = 0;
7459 +#else
6993 7460 dual_nand_ctlr_present = 1;
6994 7461 if (plat_data != NULL)
6995 7462 interleave_enable = plat_data->interleave;
6996 7463 else
6997 7464 interleave_enable = 0;
6998 7465 -
6999 7466 +#endif
7000 7467 if (!interleave_enable)
7001 7468 pr_info("%s: Dual Nand Ctrl in ping-pong mode\n", __func__);
7002 7469 else
... ... @@ -7038,10 +7505,6 @@
7038 7505 info->mtd.name = dev_name(&pdev->dev);
7039 7506 info->mtd.priv = &info->msm_nand;
7040 7507 info->mtd.owner = THIS_MODULE;
7041 -
7042 - /* config ebi2_cfg register only for ping pong mode!!! */
7043 - if (!interleave_enable && dual_nand_ctlr_present)
7044 - flash_wr_reg(&info->msm_nand, EBI2_CFG_REG, 0x4010080);
7045 7508
7046 7509 if (dual_nand_ctlr_present)
7047 7510 msm_nand_nc10_xfr_settings(&info->mtd);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment