diff options
author | Bhavna Yadav <bhavna.yadav@st.com> | 2012-03-07 06:30:50 -0500 |
---|---|---|
committer | David Woodhouse <David.Woodhouse@intel.com> | 2012-03-26 19:45:11 -0400 |
commit | e29ee57b1d33abf119cb332a3d8fa69c9cd39096 (patch) | |
tree | f8881c9d9da82ac69c9348fa5860811d10d437bd /drivers/mtd | |
parent | 519300cfe18ee8dcf0b1e7a38564b61b70e4ee86 (diff) |
mtd: fsmc_nand: ECC1 & ECC4 layout separated for different page sizes
ECC1 & ECC4 layout for NAND of different pages sizes for e.g. 512bytes,
2KiB, 4KiB and 8KiB are separated. Previously there existed one ECC4
layout for 2KiB & 4KiB page size due to which oob test module available
in drivers/mtd/nand/test was failing.
Signed-off-by: Bhavna Yadav <bhavna.yadav@st.com>
Signed-off-by: Artem Bityutskiy <artem.bityutskiy@linux.intel.com>
Signed-off-by: David Woodhouse <David.Woodhouse@intel.com>
Diffstat (limited to 'drivers/mtd')
-rw-r--r-- | drivers/mtd/nand/fsmc_nand.c | 176 |
1 files changed, 159 insertions, 17 deletions
diff --git a/drivers/mtd/nand/fsmc_nand.c b/drivers/mtd/nand/fsmc_nand.c index 9c7d9d85f756..abbff77fd106 100644 --- a/drivers/mtd/nand/fsmc_nand.c +++ b/drivers/mtd/nand/fsmc_nand.c | |||
@@ -34,7 +34,7 @@ | |||
34 | #include <linux/amba/bus.h> | 34 | #include <linux/amba/bus.h> |
35 | #include <mtd/mtd-abi.h> | 35 | #include <mtd/mtd-abi.h> |
36 | 36 | ||
37 | static struct nand_ecclayout fsmc_ecc1_layout = { | 37 | static struct nand_ecclayout fsmc_ecc1_128_layout = { |
38 | .eccbytes = 24, | 38 | .eccbytes = 24, |
39 | .eccpos = {2, 3, 4, 18, 19, 20, 34, 35, 36, 50, 51, 52, | 39 | .eccpos = {2, 3, 4, 18, 19, 20, 34, 35, 36, 50, 51, 52, |
40 | 66, 67, 68, 82, 83, 84, 98, 99, 100, 114, 115, 116}, | 40 | 66, 67, 68, 82, 83, 84, 98, 99, 100, 114, 115, 116}, |
@@ -50,7 +50,91 @@ static struct nand_ecclayout fsmc_ecc1_layout = { | |||
50 | } | 50 | } |
51 | }; | 51 | }; |
52 | 52 | ||
53 | static struct nand_ecclayout fsmc_ecc4_lp_layout = { | 53 | static struct nand_ecclayout fsmc_ecc1_64_layout = { |
54 | .eccbytes = 12, | ||
55 | .eccpos = {2, 3, 4, 18, 19, 20, 34, 35, 36, 50, 51, 52}, | ||
56 | .oobfree = { | ||
57 | {.offset = 8, .length = 8}, | ||
58 | {.offset = 24, .length = 8}, | ||
59 | {.offset = 40, .length = 8}, | ||
60 | {.offset = 56, .length = 8}, | ||
61 | } | ||
62 | }; | ||
63 | |||
64 | static struct nand_ecclayout fsmc_ecc1_16_layout = { | ||
65 | .eccbytes = 3, | ||
66 | .eccpos = {2, 3, 4}, | ||
67 | .oobfree = { | ||
68 | {.offset = 8, .length = 8}, | ||
69 | } | ||
70 | }; | ||
71 | |||
72 | /* | ||
73 | * ECC4 layout for NAND of pagesize 8192 bytes & OOBsize 256 bytes. 13*16 bytes | ||
74 | * of OB size is reserved for ECC, Byte no. 0 & 1 reserved for bad block and 46 | ||
75 | * bytes are free for use. | ||
76 | */ | ||
77 | static struct nand_ecclayout fsmc_ecc4_256_layout = { | ||
78 | .eccbytes = 208, | ||
79 | .eccpos = { 2, 3, 4, 5, 6, 7, 8, | ||
80 | 9, 10, 11, 12, 13, 14, | ||
81 | 18, 19, 20, 21, 22, 23, 24, | ||
82 | 25, 26, 27, 28, 29, 30, | ||
83 | 34, 35, 36, 37, 38, 39, 40, | ||
84 | 41, 42, 43, 44, 45, 46, | ||
85 | 50, 51, 52, 53, 54, 55, 56, | ||
86 | 57, 58, 59, 60, 61, 62, | ||
87 | 66, 67, 68, 69, 70, 71, 72, | ||
88 | 73, 74, 75, 76, 77, 78, | ||
89 | 82, 83, 84, 85, 86, 87, 88, | ||
90 | 89, 90, 91, 92, 93, 94, | ||
91 | 98, 99, 100, 101, 102, 103, 104, | ||
92 | 105, 106, 107, 108, 109, 110, | ||
93 | 114, 115, 116, 117, 118, 119, 120, | ||
94 | 121, 122, 123, 124, 125, 126, | ||
95 | 130, 131, 132, 133, 134, 135, 136, | ||
96 | 137, 138, 139, 140, 141, 142, | ||
97 | 146, 147, 148, 149, 150, 151, 152, | ||
98 | 153, 154, 155, 156, 157, 158, | ||
99 | 162, 163, 164, 165, 166, 167, 168, | ||
100 | 169, 170, 171, 172, 173, 174, | ||
101 | 178, 179, 180, 181, 182, 183, 184, | ||
102 | 185, 186, 187, 188, 189, 190, | ||
103 | 194, 195, 196, 197, 198, 199, 200, | ||
104 | 201, 202, 203, 204, 205, 206, | ||
105 | 210, 211, 212, 213, 214, 215, 216, | ||
106 | 217, 218, 219, 220, 221, 222, | ||
107 | 226, 227, 228, 229, 230, 231, 232, | ||
108 | 233, 234, 235, 236, 237, 238, | ||
109 | 242, 243, 244, 245, 246, 247, 248, | ||
110 | 249, 250, 251, 252, 253, 254 | ||
111 | }, | ||
112 | .oobfree = { | ||
113 | {.offset = 15, .length = 3}, | ||
114 | {.offset = 31, .length = 3}, | ||
115 | {.offset = 47, .length = 3}, | ||
116 | {.offset = 63, .length = 3}, | ||
117 | {.offset = 79, .length = 3}, | ||
118 | {.offset = 95, .length = 3}, | ||
119 | {.offset = 111, .length = 3}, | ||
120 | {.offset = 127, .length = 3}, | ||
121 | {.offset = 143, .length = 3}, | ||
122 | {.offset = 159, .length = 3}, | ||
123 | {.offset = 175, .length = 3}, | ||
124 | {.offset = 191, .length = 3}, | ||
125 | {.offset = 207, .length = 3}, | ||
126 | {.offset = 223, .length = 3}, | ||
127 | {.offset = 239, .length = 3}, | ||
128 | {.offset = 255, .length = 1} | ||
129 | } | ||
130 | }; | ||
131 | |||
132 | /* | ||
133 | * ECC4 layout for NAND of pagesize 4096 bytes & OOBsize 128 bytes. 13*8 bytes | ||
134 | * of OOB size is reserved for ECC, Byte no. 0 & 1 reserved for bad block & 22 | ||
135 | * bytes are free for use. | ||
136 | */ | ||
137 | static struct nand_ecclayout fsmc_ecc4_128_layout = { | ||
54 | .eccbytes = 104, | 138 | .eccbytes = 104, |
55 | .eccpos = { 2, 3, 4, 5, 6, 7, 8, | 139 | .eccpos = { 2, 3, 4, 5, 6, 7, 8, |
56 | 9, 10, 11, 12, 13, 14, | 140 | 9, 10, 11, 12, 13, 14, |
@@ -82,6 +166,45 @@ static struct nand_ecclayout fsmc_ecc4_lp_layout = { | |||
82 | }; | 166 | }; |
83 | 167 | ||
84 | /* | 168 | /* |
169 | * ECC4 layout for NAND of pagesize 2048 bytes & OOBsize 64 bytes. 13*4 bytes of | ||
170 | * OOB size is reserved for ECC, Byte no. 0 & 1 reserved for bad block and 10 | ||
171 | * bytes are free for use. | ||
172 | */ | ||
173 | static struct nand_ecclayout fsmc_ecc4_64_layout = { | ||
174 | .eccbytes = 52, | ||
175 | .eccpos = { 2, 3, 4, 5, 6, 7, 8, | ||
176 | 9, 10, 11, 12, 13, 14, | ||
177 | 18, 19, 20, 21, 22, 23, 24, | ||
178 | 25, 26, 27, 28, 29, 30, | ||
179 | 34, 35, 36, 37, 38, 39, 40, | ||
180 | 41, 42, 43, 44, 45, 46, | ||
181 | 50, 51, 52, 53, 54, 55, 56, | ||
182 | 57, 58, 59, 60, 61, 62, | ||
183 | }, | ||
184 | .oobfree = { | ||
185 | {.offset = 15, .length = 3}, | ||
186 | {.offset = 31, .length = 3}, | ||
187 | {.offset = 47, .length = 3}, | ||
188 | {.offset = 63, .length = 1}, | ||
189 | } | ||
190 | }; | ||
191 | |||
192 | /* | ||
193 | * ECC4 layout for NAND of pagesize 512 bytes & OOBsize 16 bytes. 13 bytes of | ||
194 | * OOB size is reserved for ECC, Byte no. 4 & 5 reserved for bad block and One | ||
195 | * byte is free for use. | ||
196 | */ | ||
197 | static struct nand_ecclayout fsmc_ecc4_16_layout = { | ||
198 | .eccbytes = 13, | ||
199 | .eccpos = { 0, 1, 2, 3, 6, 7, 8, | ||
200 | 9, 10, 11, 12, 13, 14 | ||
201 | }, | ||
202 | .oobfree = { | ||
203 | {.offset = 15, .length = 1}, | ||
204 | } | ||
205 | }; | ||
206 | |||
207 | /* | ||
85 | * ECC placement definitions in oobfree type format. | 208 | * ECC placement definitions in oobfree type format. |
86 | * There are 13 bytes of ecc for every 512 byte block and it has to be read | 209 | * There are 13 bytes of ecc for every 512 byte block and it has to be read |
87 | * consecutively and immediately after the 512 byte data block for hardware to | 210 | * consecutively and immediately after the 512 byte data block for hardware to |
@@ -103,16 +226,6 @@ static struct fsmc_eccplace fsmc_ecc4_lp_place = { | |||
103 | } | 226 | } |
104 | }; | 227 | }; |
105 | 228 | ||
106 | static struct nand_ecclayout fsmc_ecc4_sp_layout = { | ||
107 | .eccbytes = 13, | ||
108 | .eccpos = { 0, 1, 2, 3, 6, 7, 8, | ||
109 | 9, 10, 11, 12, 13, 14 | ||
110 | }, | ||
111 | .oobfree = { | ||
112 | {.offset = 15, .length = 1}, | ||
113 | } | ||
114 | }; | ||
115 | |||
116 | static struct fsmc_eccplace fsmc_ecc4_sp_place = { | 229 | static struct fsmc_eccplace fsmc_ecc4_sp_place = { |
117 | .eccplace = { | 230 | .eccplace = { |
118 | {.offset = 0, .length = 4}, | 231 | {.offset = 0, .length = 4}, |
@@ -733,15 +846,44 @@ static int __init fsmc_nand_probe(struct platform_device *pdev) | |||
733 | } | 846 | } |
734 | 847 | ||
735 | if (AMBA_REV_BITS(host->pid) >= 8) { | 848 | if (AMBA_REV_BITS(host->pid) >= 8) { |
736 | if (host->mtd.writesize == 512) { | 849 | switch (host->mtd.oobsize) { |
737 | nand->ecc.layout = &fsmc_ecc4_sp_layout; | 850 | case 16: |
851 | nand->ecc.layout = &fsmc_ecc4_16_layout; | ||
738 | host->ecc_place = &fsmc_ecc4_sp_place; | 852 | host->ecc_place = &fsmc_ecc4_sp_place; |
739 | } else { | 853 | break; |
740 | nand->ecc.layout = &fsmc_ecc4_lp_layout; | 854 | case 64: |
855 | nand->ecc.layout = &fsmc_ecc4_64_layout; | ||
856 | host->ecc_place = &fsmc_ecc4_lp_place; | ||
857 | break; | ||
858 | case 128: | ||
859 | nand->ecc.layout = &fsmc_ecc4_128_layout; | ||
860 | host->ecc_place = &fsmc_ecc4_lp_place; | ||
861 | break; | ||
862 | case 256: | ||
863 | nand->ecc.layout = &fsmc_ecc4_256_layout; | ||
741 | host->ecc_place = &fsmc_ecc4_lp_place; | 864 | host->ecc_place = &fsmc_ecc4_lp_place; |
865 | break; | ||
866 | default: | ||
867 | printk(KERN_WARNING "No oob scheme defined for " | ||
868 | "oobsize %d\n", mtd->oobsize); | ||
869 | BUG(); | ||
742 | } | 870 | } |
743 | } else { | 871 | } else { |
744 | nand->ecc.layout = &fsmc_ecc1_layout; | 872 | switch (host->mtd.oobsize) { |
873 | case 16: | ||
874 | nand->ecc.layout = &fsmc_ecc1_16_layout; | ||
875 | break; | ||
876 | case 64: | ||
877 | nand->ecc.layout = &fsmc_ecc1_64_layout; | ||
878 | break; | ||
879 | case 128: | ||
880 | nand->ecc.layout = &fsmc_ecc1_128_layout; | ||
881 | break; | ||
882 | default: | ||
883 | printk(KERN_WARNING "No oob scheme defined for " | ||
884 | "oobsize %d\n", mtd->oobsize); | ||
885 | BUG(); | ||
886 | } | ||
745 | } | 887 | } |
746 | 888 | ||
747 | /* Second stage of scan to fill MTD data-structures */ | 889 | /* Second stage of scan to fill MTD data-structures */ |