aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorRobert Jarzmik <robert.jarzmik@free.fr>2011-11-19 10:02:57 -0500
committerDavid Woodhouse <David.Woodhouse@intel.com>2012-01-09 13:07:29 -0500
commitc3de8a8a5a28603f8d318245992dbcda2e88a007 (patch)
tree3486d10cb537fd62cc5940b821944dc6c7b513f1 /drivers
parente4b2a96aeb2b3dfee8d19d0335c6151d4cca4631 (diff)
mtd: docg3: add fast mode
Docg3 chips can work in 3 modes : normal MLC mode, fast mode and reliable mode. Normally, as docg3 is a MLC chip, it should be configured to work in normal mode. In both normal mode, each page is distinct. This means that writing to page 12 of blocks 14,15 writes only to that page, and reading from page 12 of blocks 14,15 reads only from that page. In reliable and fast modes, pages are coupled by pairs, and are clones one of each other. This means that the available capacity of the chip is halved. Pages are coupled in each block, and page of index 2*n contains the same data as page 2*n+1 of the same block. In fast mode, the reads occur a bit faster, but are a bit less reliable that in normal mode. When reading from page 2*n, the chip reads bytes from both page 2*n and page 2*n+1, makes a logical and for each byte, and returns the result. As programming a page means "clearing bits", even if a bit was not cleared on one page because the flash is worn out, the other page has the bit cleared, and the result of the "AND" gives a correct result. When writing to page 2*n, the chip writes data to both page 2*n and page 2*n+1. Signed-off-by: Robert Jarzmik <robert.jarzmik@free.fr> Reviewed-by: Ivan Djelic <ivan.djelic@parrot.com> Reviewed-by: Mike Dunn <mikedunn@newsguy.com> Signed-off-by: David Woodhouse <David.Woodhouse@intel.com>
Diffstat (limited to 'drivers')
-rw-r--r--drivers/mtd/devices/docg3.c86
-rw-r--r--drivers/mtd/devices/docg3.h9
2 files changed, 75 insertions, 20 deletions
diff --git a/drivers/mtd/devices/docg3.c b/drivers/mtd/devices/docg3.c
index d94c759d3ea7..35df3778f8fd 100644
--- a/drivers/mtd/devices/docg3.c
+++ b/drivers/mtd/devices/docg3.c
@@ -61,6 +61,11 @@
61 * 61 *
62 */ 62 */
63 63
64static unsigned int reliable_mode = 0;
65module_param(reliable_mode, uint, 0);
66MODULE_PARM_DESC(reliable_mode, "Set the docg3 mode (0=normal MLC, 1=fast, "
67 "2=reliable) : MLC normal operations are in normal mode");
68
64/** 69/**
65 * struct docg3_oobinfo - DiskOnChip G3 OOB layout 70 * struct docg3_oobinfo - DiskOnChip G3 OOB layout
66 * @eccbytes: 8 bytes are used (1 for Hamming ECC, 7 for BCH ECC) 71 * @eccbytes: 8 bytes are used (1 for Hamming ECC, 7 for BCH ECC)
@@ -291,19 +296,41 @@ static void doc_write_data_area(struct docg3 *docg3, const void *buf, int len)
291} 296}
292 297
293/** 298/**
294 * doc_set_data_mode - Sets the flash to reliable data mode 299 * doc_set_data_mode - Sets the flash to normal or reliable data mode
295 * @docg3: the device 300 * @docg3: the device
296 * 301 *
297 * The reliable data mode is a bit slower than the fast mode, but less errors 302 * The reliable data mode is a bit slower than the fast mode, but less errors
298 * occur. Entering the reliable mode cannot be done without entering the fast 303 * occur. Entering the reliable mode cannot be done without entering the fast
299 * mode first. 304 * mode first.
305 *
306 * In reliable mode, pages 2*n and 2*n+1 are clones. Writing to page 0 of blocks
307 * (4,5) make the hardware write also to page 1 of blocks blocks(4,5). Reading
308 * from page 0 of blocks (4,5) or from page 1 of blocks (4,5) gives the same
309 * result, which is a logical and between bytes from page 0 and page 1 (which is
310 * consistent with the fact that writing to a page is _clearing_ bits of that
311 * page).
300 */ 312 */
301static void doc_set_reliable_mode(struct docg3 *docg3) 313static void doc_set_reliable_mode(struct docg3 *docg3)
302{ 314{
303 doc_dbg("doc_set_reliable_mode()\n"); 315 static char *strmode[] = { "normal", "fast", "reliable", "invalid" };
304 doc_flash_sequence(docg3, DOC_SEQ_SET_MODE); 316
305 doc_flash_command(docg3, DOC_CMD_FAST_MODE); 317 doc_dbg("doc_set_reliable_mode(%s)\n", strmode[docg3->reliable]);
306 doc_flash_command(docg3, DOC_CMD_RELIABLE_MODE); 318 switch (docg3->reliable) {
319 case 0:
320 break;
321 case 1:
322 doc_flash_sequence(docg3, DOC_SEQ_SET_FASTMODE);
323 doc_flash_command(docg3, DOC_CMD_FAST_MODE);
324 break;
325 case 2:
326 doc_flash_sequence(docg3, DOC_SEQ_SET_RELIABLEMODE);
327 doc_flash_command(docg3, DOC_CMD_FAST_MODE);
328 doc_flash_command(docg3, DOC_CMD_RELIABLE_MODE);
329 break;
330 default:
331 doc_err("doc_set_reliable_mode(): invalid mode\n");
332 break;
333 }
307 doc_delay(docg3, 2); 334 doc_delay(docg3, 2);
308} 335}
309 336
@@ -778,18 +805,29 @@ static void doc_read_page_finish(struct docg3 *docg3)
778 * @block1: second plane block index calculated 805 * @block1: second plane block index calculated
779 * @page: page calculated 806 * @page: page calculated
780 * @ofs: offset in page 807 * @ofs: offset in page
808 * @reliable: 0 if docg3 in normal mode, 1 if docg3 in fast mode, 2 if docg3 in
809 * reliable mode.
810 *
811 * The calculation is based on the reliable/normal mode. In normal mode, the 64
812 * pages of a block are available. In reliable mode, as pages 2*n and 2*n+1 are
813 * clones, only 32 pages per block are available.
781 */ 814 */
782static void calc_block_sector(loff_t from, int *block0, int *block1, int *page, 815static void calc_block_sector(loff_t from, int *block0, int *block1, int *page,
783 int *ofs) 816 int *ofs, int reliable)
784{ 817{
785 uint sector; 818 uint sector, pages_biblock;
819
820 pages_biblock = DOC_LAYOUT_PAGES_PER_BLOCK * DOC_LAYOUT_NBPLANES;
821 if (reliable == 1 || reliable == 2)
822 pages_biblock /= 2;
786 823
787 sector = from / DOC_LAYOUT_PAGE_SIZE; 824 sector = from / DOC_LAYOUT_PAGE_SIZE;
788 *block0 = sector / (DOC_LAYOUT_PAGES_PER_BLOCK * DOC_LAYOUT_NBPLANES) 825 *block0 = sector / pages_biblock * DOC_LAYOUT_NBPLANES;
789 * DOC_LAYOUT_NBPLANES;
790 *block1 = *block0 + 1; 826 *block1 = *block0 + 1;
791 *page = sector % (DOC_LAYOUT_PAGES_PER_BLOCK * DOC_LAYOUT_NBPLANES); 827 *page = sector % pages_biblock;
792 *page /= DOC_LAYOUT_NBPLANES; 828 *page /= DOC_LAYOUT_NBPLANES;
829 if (reliable == 1 || reliable == 2)
830 *page *= 2;
793 if (sector % 2) 831 if (sector % 2)
794 *ofs = DOC_LAYOUT_PAGE_OOB_SIZE; 832 *ofs = DOC_LAYOUT_PAGE_OOB_SIZE;
795 else 833 else
@@ -836,7 +874,8 @@ static int doc_read_oob(struct mtd_info *mtd, loff_t from,
836 return -EINVAL; 874 return -EINVAL;
837 875
838 ret = -EINVAL; 876 ret = -EINVAL;
839 calc_block_sector(from + len, &block0, &block1, &page, &ofs); 877 calc_block_sector(from + len, &block0, &block1, &page, &ofs,
878 docg3->reliable);
840 if (block1 > docg3->max_block) 879 if (block1 > docg3->max_block)
841 goto err; 880 goto err;
842 881
@@ -844,7 +883,8 @@ static int doc_read_oob(struct mtd_info *mtd, loff_t from,
844 ops->retlen = 0; 883 ops->retlen = 0;
845 ret = 0; 884 ret = 0;
846 while (!ret && (len > 0 || ooblen > 0)) { 885 while (!ret && (len > 0 || ooblen > 0)) {
847 calc_block_sector(from, &block0, &block1, &page, &ofs); 886 calc_block_sector(from, &block0, &block1, &page, &ofs,
887 docg3->reliable);
848 nbdata = min_t(size_t, len, (size_t)DOC_LAYOUT_PAGE_SIZE); 888 nbdata = min_t(size_t, len, (size_t)DOC_LAYOUT_PAGE_SIZE);
849 nboob = min_t(size_t, ooblen, (size_t)DOC_LAYOUT_OOB_SIZE); 889 nboob = min_t(size_t, ooblen, (size_t)DOC_LAYOUT_OOB_SIZE);
850 ret = doc_read_page_prepare(docg3, block0, block1, page, ofs); 890 ret = doc_read_page_prepare(docg3, block0, block1, page, ofs);
@@ -983,7 +1023,8 @@ static int doc_block_isbad(struct mtd_info *mtd, loff_t from)
983 struct docg3 *docg3 = mtd->priv; 1023 struct docg3 *docg3 = mtd->priv;
984 int block0, block1, page, ofs, is_good; 1024 int block0, block1, page, ofs, is_good;
985 1025
986 calc_block_sector(from, &block0, &block1, &page, &ofs); 1026 calc_block_sector(from, &block0, &block1, &page, &ofs,
1027 docg3->reliable);
987 doc_dbg("doc_block_isbad(from=%lld) => block=(%d,%d), page=%d, ofs=%d\n", 1028 doc_dbg("doc_block_isbad(from=%lld) => block=(%d,%d), page=%d, ofs=%d\n",
988 from, block0, block1, page, ofs); 1029 from, block0, block1, page, ofs);
989 1030
@@ -1015,7 +1056,7 @@ static int doc_get_erase_count(struct docg3 *docg3, loff_t from)
1015 doc_dbg("doc_get_erase_count(from=%lld, buf=%p)\n", from, buf); 1056 doc_dbg("doc_get_erase_count(from=%lld, buf=%p)\n", from, buf);
1016 if (from % DOC_LAYOUT_PAGE_SIZE) 1057 if (from % DOC_LAYOUT_PAGE_SIZE)
1017 return -EINVAL; 1058 return -EINVAL;
1018 calc_block_sector(from, &block0, &block1, &page, &ofs); 1059 calc_block_sector(from, &block0, &block1, &page, &ofs, docg3->reliable);
1019 if (block1 > docg3->max_block) 1060 if (block1 > docg3->max_block)
1020 return -EINVAL; 1061 return -EINVAL;
1021 1062
@@ -1156,14 +1197,15 @@ static int doc_erase(struct mtd_info *mtd, struct erase_info *info)
1156 doc_set_device_id(docg3, docg3->device_id); 1197 doc_set_device_id(docg3, docg3->device_id);
1157 1198
1158 info->state = MTD_ERASE_PENDING; 1199 info->state = MTD_ERASE_PENDING;
1159 calc_block_sector(info->addr + info->len, 1200 calc_block_sector(info->addr + info->len, &block0, &block1, &page,
1160 &block0, &block1, &page, &ofs); 1201 &ofs, docg3->reliable);
1161 ret = -EINVAL; 1202 ret = -EINVAL;
1162 if (block1 > docg3->max_block || page || ofs) 1203 if (block1 > docg3->max_block || page || ofs)
1163 goto reset_err; 1204 goto reset_err;
1164 1205
1165 ret = 0; 1206 ret = 0;
1166 calc_block_sector(info->addr, &block0, &block1, &page, &ofs); 1207 calc_block_sector(info->addr, &block0, &block1, &page, &ofs,
1208 docg3->reliable);
1167 doc_set_reliable_mode(docg3); 1209 doc_set_reliable_mode(docg3);
1168 for (len = info->len; !ret && len > 0; len -= mtd->erasesize) { 1210 for (len = info->len; !ret && len > 0; len -= mtd->erasesize) {
1169 info->state = MTD_ERASING; 1211 info->state = MTD_ERASING;
@@ -1209,7 +1251,7 @@ static int doc_write_page(struct docg3 *docg3, loff_t to, const u_char *buf,
1209 u8 syn[DOC_ECC_BCH_SIZE], hamming; 1251 u8 syn[DOC_ECC_BCH_SIZE], hamming;
1210 1252
1211 doc_dbg("doc_write_page(to=%lld)\n", to); 1253 doc_dbg("doc_write_page(to=%lld)\n", to);
1212 calc_block_sector(to, &block0, &block1, &page, &ofs); 1254 calc_block_sector(to, &block0, &block1, &page, &ofs, docg3->reliable);
1213 1255
1214 doc_set_device_id(docg3, docg3->device_id); 1256 doc_set_device_id(docg3, docg3->device_id);
1215 ret = doc_reset_seq(docg3); 1257 ret = doc_reset_seq(docg3);
@@ -1396,7 +1438,8 @@ static int doc_write_oob(struct mtd_info *mtd, loff_t ofs,
1396 return -EINVAL; 1438 return -EINVAL;
1397 1439
1398 ret = -EINVAL; 1440 ret = -EINVAL;
1399 calc_block_sector(ofs + len, &block0, &block1, &page, &pofs); 1441 calc_block_sector(ofs + len, &block0, &block1, &page, &pofs,
1442 docg3->reliable);
1400 if (block1 > docg3->max_block) 1443 if (block1 > docg3->max_block)
1401 goto err; 1444 goto err;
1402 1445
@@ -1638,6 +1681,7 @@ static void __init doc_set_driver_info(int chip_id, struct mtd_info *mtd)
1638 1681
1639 cfg = doc_register_readb(docg3, DOC_CONFIGURATION); 1682 cfg = doc_register_readb(docg3, DOC_CONFIGURATION);
1640 docg3->if_cfg = (cfg & DOC_CONF_IF_CFG ? 1 : 0); 1683 docg3->if_cfg = (cfg & DOC_CONF_IF_CFG ? 1 : 0);
1684 docg3->reliable = reliable_mode;
1641 1685
1642 switch (chip_id) { 1686 switch (chip_id) {
1643 case DOC_CHIPID_G3: 1687 case DOC_CHIPID_G3:
@@ -1649,7 +1693,11 @@ static void __init doc_set_driver_info(int chip_id, struct mtd_info *mtd)
1649 mtd->type = MTD_NANDFLASH; 1693 mtd->type = MTD_NANDFLASH;
1650 mtd->flags = MTD_CAP_NANDFLASH; 1694 mtd->flags = MTD_CAP_NANDFLASH;
1651 mtd->size = (docg3->max_block + 1) * DOC_LAYOUT_BLOCK_SIZE; 1695 mtd->size = (docg3->max_block + 1) * DOC_LAYOUT_BLOCK_SIZE;
1696 if (docg3->reliable == 2)
1697 mtd->size /= 2;
1652 mtd->erasesize = DOC_LAYOUT_BLOCK_SIZE * DOC_LAYOUT_NBPLANES; 1698 mtd->erasesize = DOC_LAYOUT_BLOCK_SIZE * DOC_LAYOUT_NBPLANES;
1699 if (docg3->reliable == 2)
1700 mtd->erasesize /= 2;
1653 mtd->writesize = DOC_LAYOUT_PAGE_SIZE; 1701 mtd->writesize = DOC_LAYOUT_PAGE_SIZE;
1654 mtd->oobsize = DOC_LAYOUT_OOB_SIZE; 1702 mtd->oobsize = DOC_LAYOUT_OOB_SIZE;
1655 mtd->owner = THIS_MODULE; 1703 mtd->owner = THIS_MODULE;
diff --git a/drivers/mtd/devices/docg3.h b/drivers/mtd/devices/docg3.h
index cd70b181f797..07182f9d484d 100644
--- a/drivers/mtd/devices/docg3.h
+++ b/drivers/mtd/devices/docg3.h
@@ -135,7 +135,8 @@
135 */ 135 */
136#define DOC_SEQ_RESET 0x00 136#define DOC_SEQ_RESET 0x00
137#define DOC_SEQ_PAGE_SIZE_532 0x03 137#define DOC_SEQ_PAGE_SIZE_532 0x03
138#define DOC_SEQ_SET_MODE 0x09 138#define DOC_SEQ_SET_FASTMODE 0x05
139#define DOC_SEQ_SET_RELIABLEMODE 0x09
139#define DOC_SEQ_READ 0x12 140#define DOC_SEQ_READ 0x12
140#define DOC_SEQ_SET_PLANE1 0x0e 141#define DOC_SEQ_SET_PLANE1 0x0e
141#define DOC_SEQ_SET_PLANE2 0x10 142#define DOC_SEQ_SET_PLANE2 0x10
@@ -257,6 +258,11 @@
257 * @base: mapped IO space 258 * @base: mapped IO space
258 * @device_id: number of the cascaded DoCG3 device (0, 1, 2 or 3) 259 * @device_id: number of the cascaded DoCG3 device (0, 1, 2 or 3)
259 * @if_cfg: if true, reads are on 16bits, else reads are on 8bits 260 * @if_cfg: if true, reads are on 16bits, else reads are on 8bits
261
262 * @reliable: if 0, docg3 in normal mode, if 1 docg3 in fast mode, if 2 in
263 * reliable mode
264 * Fast mode implies more errors than normal mode.
265 * Reliable mode implies that page 2*n and 2*n+1 are clones.
260 * @bbt: bad block table cache 266 * @bbt: bad block table cache
261 * @oob_write_ofs: offset of the MTD where this OOB should belong (ie. in next 267 * @oob_write_ofs: offset of the MTD where this OOB should belong (ie. in next
262 * page_write) 268 * page_write)
@@ -270,6 +276,7 @@ struct docg3 {
270 void __iomem *base; 276 void __iomem *base;
271 unsigned int device_id:4; 277 unsigned int device_id:4;
272 unsigned int if_cfg:1; 278 unsigned int if_cfg:1;
279 unsigned int reliable:2;
273 int max_block; 280 int max_block;
274 u8 *bbt; 281 u8 *bbt;
275 loff_t oob_write_ofs; 282 loff_t oob_write_ofs;