aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/mtd/nand/rtc_from4.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/mtd/nand/rtc_from4.c')
-rw-r--r--drivers/mtd/nand/rtc_from4.c351
1 files changed, 163 insertions, 188 deletions
diff --git a/drivers/mtd/nand/rtc_from4.c b/drivers/mtd/nand/rtc_from4.c
index 4129c03dfd90..f8c49645324d 100644
--- a/drivers/mtd/nand/rtc_from4.c
+++ b/drivers/mtd/nand/rtc_from4.c
@@ -97,12 +97,12 @@ static struct mtd_info *rtc_from4_mtd = NULL;
97static void __iomem *rtc_from4_fio_base = (void *)P2SEGADDR(RTC_FROM4_FIO_BASE); 97static void __iomem *rtc_from4_fio_base = (void *)P2SEGADDR(RTC_FROM4_FIO_BASE);
98 98
99static const struct mtd_partition partition_info[] = { 99static const struct mtd_partition partition_info[] = {
100 { 100 {
101 .name = "Renesas flash partition 1", 101 .name = "Renesas flash partition 1",
102 .offset = 0, 102 .offset = 0,
103 .size = MTDPART_SIZ_FULL 103 .size = MTDPART_SIZ_FULL},
104 },
105}; 104};
105
106#define NUM_PARTITIONS 1 106#define NUM_PARTITIONS 1
107 107
108/* 108/*
@@ -111,8 +111,8 @@ static const struct mtd_partition partition_info[] = {
111 * NAND_BBT_CREATE and/or NAND_BBT_WRITE 111 * NAND_BBT_CREATE and/or NAND_BBT_WRITE
112 * 112 *
113 */ 113 */
114static uint8_t bbt_pattern[] = {'B', 'b', 't', '0' }; 114static uint8_t bbt_pattern[] = { 'B', 'b', 't', '0' };
115static uint8_t mirror_pattern[] = {'1', 't', 'b', 'B' }; 115static uint8_t mirror_pattern[] = { '1', 't', 'b', 'B' };
116 116
117static struct nand_bbt_descr rtc_from4_bbt_main_descr = { 117static struct nand_bbt_descr rtc_from4_bbt_main_descr = {
118 .options = NAND_BBT_LASTBLOCK | NAND_BBT_CREATE | NAND_BBT_WRITE 118 .options = NAND_BBT_LASTBLOCK | NAND_BBT_CREATE | NAND_BBT_WRITE
@@ -134,8 +134,6 @@ static struct nand_bbt_descr rtc_from4_bbt_mirror_descr = {
134 .pattern = mirror_pattern 134 .pattern = mirror_pattern
135}; 135};
136 136
137
138
139#ifdef RTC_FROM4_HWECC 137#ifdef RTC_FROM4_HWECC
140 138
141/* the Reed Solomon control structure */ 139/* the Reed Solomon control structure */
@@ -144,15 +142,14 @@ static struct rs_control *rs_decoder;
144/* 142/*
145 * hardware specific Out Of Band information 143 * hardware specific Out Of Band information
146 */ 144 */
147static struct nand_oobinfo rtc_from4_nand_oobinfo = { 145static struct nand_ecclayout rtc_from4_nand_oobinfo = {
148 .useecc = MTD_NANDECC_AUTOPLACE,
149 .eccbytes = 32, 146 .eccbytes = 32,
150 .eccpos = { 147 .eccpos = {
151 0, 1, 2, 3, 4, 5, 6, 7, 148 0, 1, 2, 3, 4, 5, 6, 7,
152 8, 9, 10, 11, 12, 13, 14, 15, 149 8, 9, 10, 11, 12, 13, 14, 15,
153 16, 17, 18, 19, 20, 21, 22, 23, 150 16, 17, 18, 19, 20, 21, 22, 23,
154 24, 25, 26, 27, 28, 29, 30, 31}, 151 24, 25, 26, 27, 28, 29, 30, 31},
155 .oobfree = { {32, 32} } 152 .oobfree = {{32, 32}}
156}; 153};
157 154
158/* Aargh. I missed the reversed bit order, when I 155/* Aargh. I missed the reversed bit order, when I
@@ -162,44 +159,42 @@ static struct nand_oobinfo rtc_from4_nand_oobinfo = {
162 * of the ecc byte which we get from the FPGA 159 * of the ecc byte which we get from the FPGA
163 */ 160 */
164static uint8_t revbits[256] = { 161static uint8_t revbits[256] = {
165 0x00, 0x80, 0x40, 0xc0, 0x20, 0xa0, 0x60, 0xe0, 162 0x00, 0x80, 0x40, 0xc0, 0x20, 0xa0, 0x60, 0xe0,
166 0x10, 0x90, 0x50, 0xd0, 0x30, 0xb0, 0x70, 0xf0, 163 0x10, 0x90, 0x50, 0xd0, 0x30, 0xb0, 0x70, 0xf0,
167 0x08, 0x88, 0x48, 0xc8, 0x28, 0xa8, 0x68, 0xe8, 164 0x08, 0x88, 0x48, 0xc8, 0x28, 0xa8, 0x68, 0xe8,
168 0x18, 0x98, 0x58, 0xd8, 0x38, 0xb8, 0x78, 0xf8, 165 0x18, 0x98, 0x58, 0xd8, 0x38, 0xb8, 0x78, 0xf8,
169 0x04, 0x84, 0x44, 0xc4, 0x24, 0xa4, 0x64, 0xe4, 166 0x04, 0x84, 0x44, 0xc4, 0x24, 0xa4, 0x64, 0xe4,
170 0x14, 0x94, 0x54, 0xd4, 0x34, 0xb4, 0x74, 0xf4, 167 0x14, 0x94, 0x54, 0xd4, 0x34, 0xb4, 0x74, 0xf4,
171 0x0c, 0x8c, 0x4c, 0xcc, 0x2c, 0xac, 0x6c, 0xec, 168 0x0c, 0x8c, 0x4c, 0xcc, 0x2c, 0xac, 0x6c, 0xec,
172 0x1c, 0x9c, 0x5c, 0xdc, 0x3c, 0xbc, 0x7c, 0xfc, 169 0x1c, 0x9c, 0x5c, 0xdc, 0x3c, 0xbc, 0x7c, 0xfc,
173 0x02, 0x82, 0x42, 0xc2, 0x22, 0xa2, 0x62, 0xe2, 170 0x02, 0x82, 0x42, 0xc2, 0x22, 0xa2, 0x62, 0xe2,
174 0x12, 0x92, 0x52, 0xd2, 0x32, 0xb2, 0x72, 0xf2, 171 0x12, 0x92, 0x52, 0xd2, 0x32, 0xb2, 0x72, 0xf2,
175 0x0a, 0x8a, 0x4a, 0xca, 0x2a, 0xaa, 0x6a, 0xea, 172 0x0a, 0x8a, 0x4a, 0xca, 0x2a, 0xaa, 0x6a, 0xea,
176 0x1a, 0x9a, 0x5a, 0xda, 0x3a, 0xba, 0x7a, 0xfa, 173 0x1a, 0x9a, 0x5a, 0xda, 0x3a, 0xba, 0x7a, 0xfa,
177 0x06, 0x86, 0x46, 0xc6, 0x26, 0xa6, 0x66, 0xe6, 174 0x06, 0x86, 0x46, 0xc6, 0x26, 0xa6, 0x66, 0xe6,
178 0x16, 0x96, 0x56, 0xd6, 0x36, 0xb6, 0x76, 0xf6, 175 0x16, 0x96, 0x56, 0xd6, 0x36, 0xb6, 0x76, 0xf6,
179 0x0e, 0x8e, 0x4e, 0xce, 0x2e, 0xae, 0x6e, 0xee, 176 0x0e, 0x8e, 0x4e, 0xce, 0x2e, 0xae, 0x6e, 0xee,
180 0x1e, 0x9e, 0x5e, 0xde, 0x3e, 0xbe, 0x7e, 0xfe, 177 0x1e, 0x9e, 0x5e, 0xde, 0x3e, 0xbe, 0x7e, 0xfe,
181 0x01, 0x81, 0x41, 0xc1, 0x21, 0xa1, 0x61, 0xe1, 178 0x01, 0x81, 0x41, 0xc1, 0x21, 0xa1, 0x61, 0xe1,
182 0x11, 0x91, 0x51, 0xd1, 0x31, 0xb1, 0x71, 0xf1, 179 0x11, 0x91, 0x51, 0xd1, 0x31, 0xb1, 0x71, 0xf1,
183 0x09, 0x89, 0x49, 0xc9, 0x29, 0xa9, 0x69, 0xe9, 180 0x09, 0x89, 0x49, 0xc9, 0x29, 0xa9, 0x69, 0xe9,
184 0x19, 0x99, 0x59, 0xd9, 0x39, 0xb9, 0x79, 0xf9, 181 0x19, 0x99, 0x59, 0xd9, 0x39, 0xb9, 0x79, 0xf9,
185 0x05, 0x85, 0x45, 0xc5, 0x25, 0xa5, 0x65, 0xe5, 182 0x05, 0x85, 0x45, 0xc5, 0x25, 0xa5, 0x65, 0xe5,
186 0x15, 0x95, 0x55, 0xd5, 0x35, 0xb5, 0x75, 0xf5, 183 0x15, 0x95, 0x55, 0xd5, 0x35, 0xb5, 0x75, 0xf5,
187 0x0d, 0x8d, 0x4d, 0xcd, 0x2d, 0xad, 0x6d, 0xed, 184 0x0d, 0x8d, 0x4d, 0xcd, 0x2d, 0xad, 0x6d, 0xed,
188 0x1d, 0x9d, 0x5d, 0xdd, 0x3d, 0xbd, 0x7d, 0xfd, 185 0x1d, 0x9d, 0x5d, 0xdd, 0x3d, 0xbd, 0x7d, 0xfd,
189 0x03, 0x83, 0x43, 0xc3, 0x23, 0xa3, 0x63, 0xe3, 186 0x03, 0x83, 0x43, 0xc3, 0x23, 0xa3, 0x63, 0xe3,
190 0x13, 0x93, 0x53, 0xd3, 0x33, 0xb3, 0x73, 0xf3, 187 0x13, 0x93, 0x53, 0xd3, 0x33, 0xb3, 0x73, 0xf3,
191 0x0b, 0x8b, 0x4b, 0xcb, 0x2b, 0xab, 0x6b, 0xeb, 188 0x0b, 0x8b, 0x4b, 0xcb, 0x2b, 0xab, 0x6b, 0xeb,
192 0x1b, 0x9b, 0x5b, 0xdb, 0x3b, 0xbb, 0x7b, 0xfb, 189 0x1b, 0x9b, 0x5b, 0xdb, 0x3b, 0xbb, 0x7b, 0xfb,
193 0x07, 0x87, 0x47, 0xc7, 0x27, 0xa7, 0x67, 0xe7, 190 0x07, 0x87, 0x47, 0xc7, 0x27, 0xa7, 0x67, 0xe7,
194 0x17, 0x97, 0x57, 0xd7, 0x37, 0xb7, 0x77, 0xf7, 191 0x17, 0x97, 0x57, 0xd7, 0x37, 0xb7, 0x77, 0xf7,
195 0x0f, 0x8f, 0x4f, 0xcf, 0x2f, 0xaf, 0x6f, 0xef, 192 0x0f, 0x8f, 0x4f, 0xcf, 0x2f, 0xaf, 0x6f, 0xef,
196 0x1f, 0x9f, 0x5f, 0xdf, 0x3f, 0xbf, 0x7f, 0xff, 193 0x1f, 0x9f, 0x5f, 0xdf, 0x3f, 0xbf, 0x7f, 0xff,
197}; 194};
198 195
199#endif 196#endif
200 197
201
202
203/* 198/*
204 * rtc_from4_hwcontrol - hardware specific access to control-lines 199 * rtc_from4_hwcontrol - hardware specific access to control-lines
205 * @mtd: MTD device structure 200 * @mtd: MTD device structure
@@ -212,35 +207,20 @@ static uint8_t revbits[256] = {
212 * Address lines (A24-A22), so no action is required here. 207 * Address lines (A24-A22), so no action is required here.
213 * 208 *
214 */ 209 */
215static void rtc_from4_hwcontrol(struct mtd_info *mtd, int cmd) 210static void rtc_from4_hwcontrol(struct mtd_info *mtd, int cmd,
211 unsigned int ctrl)
216{ 212{
217 struct nand_chip* this = (struct nand_chip *) (mtd->priv); 213 struct nand_chip *chip = (mtd->priv);
218
219 switch(cmd) {
220 214
221 case NAND_CTL_SETCLE: 215 if (cmd == NAND_CMD_NONE)
222 this->IO_ADDR_W = (void __iomem *)((unsigned long)this->IO_ADDR_W | RTC_FROM4_CLE); 216 return;
223 break;
224 case NAND_CTL_CLRCLE:
225 this->IO_ADDR_W = (void __iomem *)((unsigned long)this->IO_ADDR_W & ~RTC_FROM4_CLE);
226 break;
227
228 case NAND_CTL_SETALE:
229 this->IO_ADDR_W = (void __iomem *)((unsigned long)this->IO_ADDR_W | RTC_FROM4_ALE);
230 break;
231 case NAND_CTL_CLRALE:
232 this->IO_ADDR_W = (void __iomem *)((unsigned long)this->IO_ADDR_W & ~RTC_FROM4_ALE);
233 break;
234 217
235 case NAND_CTL_SETNCE: 218 if (ctrl & NAND_CLE)
236 break; 219 writeb(cmd, chip->IO_ADDR_W | RTC_FROM4_CLE);
237 case NAND_CTL_CLRNCE: 220 else
238 break; 221 writeb(cmd, chip->IO_ADDR_W | RTC_FROM4_ALE);
239
240 }
241} 222}
242 223
243
244/* 224/*
245 * rtc_from4_nand_select_chip - hardware specific chip select 225 * rtc_from4_nand_select_chip - hardware specific chip select
246 * @mtd: MTD device structure 226 * @mtd: MTD device structure
@@ -252,26 +232,25 @@ static void rtc_from4_hwcontrol(struct mtd_info *mtd, int cmd)
252 */ 232 */
253static void rtc_from4_nand_select_chip(struct mtd_info *mtd, int chip) 233static void rtc_from4_nand_select_chip(struct mtd_info *mtd, int chip)
254{ 234{
255 struct nand_chip *this = mtd->priv; 235 struct nand_chip *this = mtd->priv;
256 236
257 this->IO_ADDR_R = (void __iomem *)((unsigned long)this->IO_ADDR_R & ~RTC_FROM4_NAND_ADDR_MASK); 237 this->IO_ADDR_R = (void __iomem *)((unsigned long)this->IO_ADDR_R & ~RTC_FROM4_NAND_ADDR_MASK);
258 this->IO_ADDR_W = (void __iomem *)((unsigned long)this->IO_ADDR_W & ~RTC_FROM4_NAND_ADDR_MASK); 238 this->IO_ADDR_W = (void __iomem *)((unsigned long)this->IO_ADDR_W & ~RTC_FROM4_NAND_ADDR_MASK);
259 239
260 switch(chip) { 240 switch (chip) {
261 241
262 case 0: /* select slot 3 chip */ 242 case 0: /* select slot 3 chip */
263 this->IO_ADDR_R = (void __iomem *)((unsigned long)this->IO_ADDR_R | RTC_FROM4_NAND_ADDR_SLOT3); 243 this->IO_ADDR_R = (void __iomem *)((unsigned long)this->IO_ADDR_R | RTC_FROM4_NAND_ADDR_SLOT3);
264 this->IO_ADDR_W = (void __iomem *)((unsigned long)this->IO_ADDR_W | RTC_FROM4_NAND_ADDR_SLOT3); 244 this->IO_ADDR_W = (void __iomem *)((unsigned long)this->IO_ADDR_W | RTC_FROM4_NAND_ADDR_SLOT3);
265 break; 245 break;
266 case 1: /* select slot 4 chip */ 246 case 1: /* select slot 4 chip */
267 this->IO_ADDR_R = (void __iomem *)((unsigned long)this->IO_ADDR_R | RTC_FROM4_NAND_ADDR_SLOT4); 247 this->IO_ADDR_R = (void __iomem *)((unsigned long)this->IO_ADDR_R | RTC_FROM4_NAND_ADDR_SLOT4);
268 this->IO_ADDR_W = (void __iomem *)((unsigned long)this->IO_ADDR_W | RTC_FROM4_NAND_ADDR_SLOT4); 248 this->IO_ADDR_W = (void __iomem *)((unsigned long)this->IO_ADDR_W | RTC_FROM4_NAND_ADDR_SLOT4);
269 break; 249 break;
270 250
271 } 251 }
272} 252}
273 253
274
275/* 254/*
276 * rtc_from4_nand_device_ready - hardware specific ready/busy check 255 * rtc_from4_nand_device_ready - hardware specific ready/busy check
277 * @mtd: MTD device structure 256 * @mtd: MTD device structure
@@ -290,7 +269,6 @@ static int rtc_from4_nand_device_ready(struct mtd_info *mtd)
290 269
291} 270}
292 271
293
294/* 272/*
295 * deplete - code to perform device recovery in case there was a power loss 273 * deplete - code to perform device recovery in case there was a power loss
296 * @mtd: MTD device structure 274 * @mtd: MTD device structure
@@ -306,24 +284,23 @@ static int rtc_from4_nand_device_ready(struct mtd_info *mtd)
306 */ 284 */
307static void deplete(struct mtd_info *mtd, int chip) 285static void deplete(struct mtd_info *mtd, int chip)
308{ 286{
309 struct nand_chip *this = mtd->priv; 287 struct nand_chip *this = mtd->priv;
310 288
311 /* wait until device is ready */ 289 /* wait until device is ready */
312 while (!this->dev_ready(mtd)); 290 while (!this->dev_ready(mtd)) ;
313 291
314 this->select_chip(mtd, chip); 292 this->select_chip(mtd, chip);
315 293
316 /* Send the commands for device recovery, phase 1 */ 294 /* Send the commands for device recovery, phase 1 */
317 this->cmdfunc (mtd, NAND_CMD_DEPLETE1, 0x0000, 0x0000); 295 this->cmdfunc(mtd, NAND_CMD_DEPLETE1, 0x0000, 0x0000);
318 this->cmdfunc (mtd, NAND_CMD_DEPLETE2, -1, -1); 296 this->cmdfunc(mtd, NAND_CMD_DEPLETE2, -1, -1);
319 297
320 /* Send the commands for device recovery, phase 2 */ 298 /* Send the commands for device recovery, phase 2 */
321 this->cmdfunc (mtd, NAND_CMD_DEPLETE1, 0x0000, 0x0004); 299 this->cmdfunc(mtd, NAND_CMD_DEPLETE1, 0x0000, 0x0004);
322 this->cmdfunc (mtd, NAND_CMD_DEPLETE2, -1, -1); 300 this->cmdfunc(mtd, NAND_CMD_DEPLETE2, -1, -1);
323 301
324} 302}
325 303
326
327#ifdef RTC_FROM4_HWECC 304#ifdef RTC_FROM4_HWECC
328/* 305/*
329 * rtc_from4_enable_hwecc - hardware specific hardware ECC enable function 306 * rtc_from4_enable_hwecc - hardware specific hardware ECC enable function
@@ -335,39 +312,35 @@ static void deplete(struct mtd_info *mtd, int chip)
335 */ 312 */
336static void rtc_from4_enable_hwecc(struct mtd_info *mtd, int mode) 313static void rtc_from4_enable_hwecc(struct mtd_info *mtd, int mode)
337{ 314{
338 volatile unsigned short * rs_ecc_ctl = (volatile unsigned short *)(rtc_from4_fio_base + RTC_FROM4_RS_ECC_CTL); 315 volatile unsigned short *rs_ecc_ctl = (volatile unsigned short *)(rtc_from4_fio_base + RTC_FROM4_RS_ECC_CTL);
339 unsigned short status; 316 unsigned short status;
340 317
341 switch (mode) { 318 switch (mode) {
342 case NAND_ECC_READ : 319 case NAND_ECC_READ:
343 status = RTC_FROM4_RS_ECC_CTL_CLR 320 status = RTC_FROM4_RS_ECC_CTL_CLR | RTC_FROM4_RS_ECC_CTL_FD_E;
344 | RTC_FROM4_RS_ECC_CTL_FD_E;
345 321
346 *rs_ecc_ctl = status; 322 *rs_ecc_ctl = status;
347 break; 323 break;
348 324
349 case NAND_ECC_READSYN : 325 case NAND_ECC_READSYN:
350 status = 0x00; 326 status = 0x00;
351 327
352 *rs_ecc_ctl = status; 328 *rs_ecc_ctl = status;
353 break; 329 break;
354 330
355 case NAND_ECC_WRITE : 331 case NAND_ECC_WRITE:
356 status = RTC_FROM4_RS_ECC_CTL_CLR 332 status = RTC_FROM4_RS_ECC_CTL_CLR | RTC_FROM4_RS_ECC_CTL_GEN | RTC_FROM4_RS_ECC_CTL_FD_E;
357 | RTC_FROM4_RS_ECC_CTL_GEN
358 | RTC_FROM4_RS_ECC_CTL_FD_E;
359 333
360 *rs_ecc_ctl = status; 334 *rs_ecc_ctl = status;
361 break; 335 break;
362 336
363 default: 337 default:
364 BUG(); 338 BUG();
365 break; 339 break;
366 } 340 }
367 341
368} 342}
369 343
370
371/* 344/*
372 * rtc_from4_calculate_ecc - hardware specific code to read ECC code 345 * rtc_from4_calculate_ecc - hardware specific code to read ECC code
373 * @mtd: MTD device structure 346 * @mtd: MTD device structure
@@ -383,7 +356,7 @@ static void rtc_from4_enable_hwecc(struct mtd_info *mtd, int mode)
383 */ 356 */
384static void rtc_from4_calculate_ecc(struct mtd_info *mtd, const u_char *dat, u_char *ecc_code) 357static void rtc_from4_calculate_ecc(struct mtd_info *mtd, const u_char *dat, u_char *ecc_code)
385{ 358{
386 volatile unsigned short * rs_eccn = (volatile unsigned short *)(rtc_from4_fio_base + RTC_FROM4_RS_ECCN); 359 volatile unsigned short *rs_eccn = (volatile unsigned short *)(rtc_from4_fio_base + RTC_FROM4_RS_ECCN);
387 unsigned short value; 360 unsigned short value;
388 int i; 361 int i;
389 362
@@ -395,7 +368,6 @@ static void rtc_from4_calculate_ecc(struct mtd_info *mtd, const u_char *dat, u_c
395 ecc_code[7] |= 0x0f; /* set the last four bits (not used) */ 368 ecc_code[7] |= 0x0f; /* set the last four bits (not used) */
396} 369}
397 370
398
399/* 371/*
400 * rtc_from4_correct_data - hardware specific code to correct data using ECC code 372 * rtc_from4_correct_data - hardware specific code to correct data using ECC code
401 * @mtd: MTD device structure 373 * @mtd: MTD device structure
@@ -414,7 +386,7 @@ static int rtc_from4_correct_data(struct mtd_info *mtd, const u_char *buf, u_cha
414 unsigned short status; 386 unsigned short status;
415 uint16_t par[6], syn[6]; 387 uint16_t par[6], syn[6];
416 uint8_t ecc[8]; 388 uint8_t ecc[8];
417 volatile unsigned short *rs_ecc; 389 volatile unsigned short *rs_ecc;
418 390
419 status = *((volatile unsigned short *)(rtc_from4_fio_base + RTC_FROM4_RS_ECC_CHK)); 391 status = *((volatile unsigned short *)(rtc_from4_fio_base + RTC_FROM4_RS_ECC_CHK));
420 392
@@ -424,23 +396,18 @@ static int rtc_from4_correct_data(struct mtd_info *mtd, const u_char *buf, u_cha
424 396
425 /* Read the syndrom pattern from the FPGA and correct the bitorder */ 397 /* Read the syndrom pattern from the FPGA and correct the bitorder */
426 rs_ecc = (volatile unsigned short *)(rtc_from4_fio_base + RTC_FROM4_RS_ECC); 398 rs_ecc = (volatile unsigned short *)(rtc_from4_fio_base + RTC_FROM4_RS_ECC);
427 for (i = 0; i < 8; i++) { 399 for (i = 0; i < 8; i++) {
428 ecc[i] = revbits[(*rs_ecc) & 0xFF]; 400 ecc[i] = revbits[(*rs_ecc) & 0xFF];
429 rs_ecc++; 401 rs_ecc++;
430 } 402 }
431 403
432 /* convert into 6 10bit syndrome fields */ 404 /* convert into 6 10bit syndrome fields */
433 par[5] = rs_decoder->index_of[(((uint16_t)ecc[0] >> 0) & 0x0ff) | 405 par[5] = rs_decoder->index_of[(((uint16_t) ecc[0] >> 0) & 0x0ff) | (((uint16_t) ecc[1] << 8) & 0x300)];
434 (((uint16_t)ecc[1] << 8) & 0x300)]; 406 par[4] = rs_decoder->index_of[(((uint16_t) ecc[1] >> 2) & 0x03f) | (((uint16_t) ecc[2] << 6) & 0x3c0)];
435 par[4] = rs_decoder->index_of[(((uint16_t)ecc[1] >> 2) & 0x03f) | 407 par[3] = rs_decoder->index_of[(((uint16_t) ecc[2] >> 4) & 0x00f) | (((uint16_t) ecc[3] << 4) & 0x3f0)];
436 (((uint16_t)ecc[2] << 6) & 0x3c0)]; 408 par[2] = rs_decoder->index_of[(((uint16_t) ecc[3] >> 6) & 0x003) | (((uint16_t) ecc[4] << 2) & 0x3fc)];
437 par[3] = rs_decoder->index_of[(((uint16_t)ecc[2] >> 4) & 0x00f) | 409 par[1] = rs_decoder->index_of[(((uint16_t) ecc[5] >> 0) & 0x0ff) | (((uint16_t) ecc[6] << 8) & 0x300)];
438 (((uint16_t)ecc[3] << 4) & 0x3f0)]; 410 par[0] = (((uint16_t) ecc[6] >> 2) & 0x03f) | (((uint16_t) ecc[7] << 6) & 0x3c0);
439 par[2] = rs_decoder->index_of[(((uint16_t)ecc[3] >> 6) & 0x003) |
440 (((uint16_t)ecc[4] << 2) & 0x3fc)];
441 par[1] = rs_decoder->index_of[(((uint16_t)ecc[5] >> 0) & 0x0ff) |
442 (((uint16_t)ecc[6] << 8) & 0x300)];
443 par[0] = (((uint16_t)ecc[6] >> 2) & 0x03f) | (((uint16_t)ecc[7] << 6) & 0x3c0);
444 411
445 /* Convert to computable syndrome */ 412 /* Convert to computable syndrome */
446 for (i = 0; i < 6; i++) { 413 for (i = 0; i < 6; i++) {
@@ -453,16 +420,14 @@ static int rtc_from4_correct_data(struct mtd_info *mtd, const u_char *buf, u_cha
453 syn[i] = rs_decoder->index_of[syn[i]]; 420 syn[i] = rs_decoder->index_of[syn[i]];
454 } 421 }
455 422
456 /* Let the library code do its magic.*/ 423 /* Let the library code do its magic. */
457 res = decode_rs8(rs_decoder, (uint8_t *)buf, par, 512, syn, 0, NULL, 0xff, NULL); 424 res = decode_rs8(rs_decoder, (uint8_t *) buf, par, 512, syn, 0, NULL, 0xff, NULL);
458 if (res > 0) { 425 if (res > 0) {
459 DEBUG (MTD_DEBUG_LEVEL0, "rtc_from4_correct_data: " 426 DEBUG(MTD_DEBUG_LEVEL0, "rtc_from4_correct_data: " "ECC corrected %d errors on read\n", res);
460 "ECC corrected %d errors on read\n", res);
461 } 427 }
462 return res; 428 return res;
463} 429}
464 430
465
466/** 431/**
467 * rtc_from4_errstat - perform additional error status checks 432 * rtc_from4_errstat - perform additional error status checks
468 * @mtd: MTD device structure 433 * @mtd: MTD device structure
@@ -478,54 +443,66 @@ static int rtc_from4_correct_data(struct mtd_info *mtd, const u_char *buf, u_cha
478 * note: see pages 34..37 of data sheet for details. 443 * note: see pages 34..37 of data sheet for details.
479 * 444 *
480 */ 445 */
481static int rtc_from4_errstat(struct mtd_info *mtd, struct nand_chip *this, int state, int status, int page) 446static int rtc_from4_errstat(struct mtd_info *mtd, struct nand_chip *this,
447 int state, int status, int page)
482{ 448{
483 int er_stat=0; 449 int er_stat = 0;
484 int rtn, retlen; 450 int rtn, retlen;
485 size_t len; 451 size_t len;
486 uint8_t *buf; 452 uint8_t *buf;
487 int i; 453 int i;
488 454
489 this->cmdfunc (mtd, NAND_CMD_STATUS_CLEAR, -1, -1); 455 this->cmdfunc(mtd, NAND_CMD_STATUS_CLEAR, -1, -1);
490 456
491 if (state == FL_ERASING) { 457 if (state == FL_ERASING) {
492 for (i=0; i<4; i++) { 458
493 if (status & 1<<(i+1)) { 459 for (i = 0; i < 4; i++) {
494 this->cmdfunc (mtd, (NAND_CMD_STATUS_ERROR + i + 1), -1, -1); 460 if (!(status & 1 << (i + 1)))
495 rtn = this->read_byte(mtd); 461 continue;
496 this->cmdfunc (mtd, NAND_CMD_STATUS_RESET, -1, -1); 462 this->cmdfunc(mtd, (NAND_CMD_STATUS_ERROR + i + 1),
497 if (!(rtn & ERR_STAT_ECC_AVAILABLE)) { 463 -1, -1);
498 er_stat |= 1<<(i+1); /* err_ecc_not_avail */ 464 rtn = this->read_byte(mtd);
499 } 465 this->cmdfunc(mtd, NAND_CMD_STATUS_RESET, -1, -1);
500 } 466
467 /* err_ecc_not_avail */
468 if (!(rtn & ERR_STAT_ECC_AVAILABLE))
469 er_stat |= 1 << (i + 1);
501 } 470 }
471
502 } else if (state == FL_WRITING) { 472 } else if (state == FL_WRITING) {
473
474 unsigned long corrected = mtd->ecc_stats.corrected;
475
503 /* single bank write logic */ 476 /* single bank write logic */
504 this->cmdfunc (mtd, NAND_CMD_STATUS_ERROR, -1, -1); 477 this->cmdfunc(mtd, NAND_CMD_STATUS_ERROR, -1, -1);
505 rtn = this->read_byte(mtd); 478 rtn = this->read_byte(mtd);
506 this->cmdfunc (mtd, NAND_CMD_STATUS_RESET, -1, -1); 479 this->cmdfunc(mtd, NAND_CMD_STATUS_RESET, -1, -1);
480
507 if (!(rtn & ERR_STAT_ECC_AVAILABLE)) { 481 if (!(rtn & ERR_STAT_ECC_AVAILABLE)) {
508 er_stat |= 1<<1; /* err_ecc_not_avail */ 482 /* err_ecc_not_avail */
509 } else { 483 er_stat |= 1 << 1;
510 len = mtd->oobblock; 484 goto out;
511 buf = kmalloc (len, GFP_KERNEL); 485 }
512 if (!buf) { 486
513 printk (KERN_ERR "rtc_from4_errstat: Out of memory!\n"); 487 len = mtd->writesize;
514 er_stat = 1; /* if we can't check, assume failed */ 488 buf = kmalloc(len, GFP_KERNEL);
515 } else { 489 if (!buf) {
516 /* recovery read */ 490 printk(KERN_ERR "rtc_from4_errstat: Out of memory!\n");
517 /* page read */ 491 er_stat = 1;
518 rtn = nand_do_read_ecc (mtd, page, len, &retlen, buf, NULL, this->autooob, 1); 492 goto out;
519 if (rtn) { /* if read failed or > 1-bit error corrected */
520 er_stat |= 1<<1; /* ECC read failed */
521 }
522 kfree(buf);
523 }
524 } 493 }
494
495 /* recovery read */
496 rtn = nand_do_read(mtd, page, len, &retlen, buf);
497
498 /* if read failed or > 1-bit error corrected */
499 if (rtn || (mtd->ecc_stats.corrected - corrected) > 1) {
500 er_stat |= 1 << 1;
501 kfree(buf);
525 } 502 }
526 503
527 rtn = status; 504 rtn = status;
528 if (er_stat == 0) { /* if ECC is available */ 505 if (er_stat == 0) { /* if ECC is available */
529 rtn = (status & ~NAND_STATUS_FAIL); /* clear the error bit */ 506 rtn = (status & ~NAND_STATUS_FAIL); /* clear the error bit */
530 } 507 }
531 508
@@ -533,33 +510,32 @@ static int rtc_from4_errstat(struct mtd_info *mtd, struct nand_chip *this, int s
533} 510}
534#endif 511#endif
535 512
536
537/* 513/*
538 * Main initialization routine 514 * Main initialization routine
539 */ 515 */
540int __init rtc_from4_init (void) 516static int __init rtc_from4_init(void)
541{ 517{
542 struct nand_chip *this; 518 struct nand_chip *this;
543 unsigned short bcr1, bcr2, wcr2; 519 unsigned short bcr1, bcr2, wcr2;
544 int i; 520 int i;
545 521
546 /* Allocate memory for MTD device structure and private data */ 522 /* Allocate memory for MTD device structure and private data */
547 rtc_from4_mtd = kmalloc(sizeof(struct mtd_info) + sizeof (struct nand_chip), 523 rtc_from4_mtd = kmalloc(sizeof(struct mtd_info) + sizeof(struct nand_chip), GFP_KERNEL);
548 GFP_KERNEL);
549 if (!rtc_from4_mtd) { 524 if (!rtc_from4_mtd) {
550 printk ("Unable to allocate Renesas NAND MTD device structure.\n"); 525 printk("Unable to allocate Renesas NAND MTD device structure.\n");
551 return -ENOMEM; 526 return -ENOMEM;
552 } 527 }
553 528
554 /* Get pointer to private data */ 529 /* Get pointer to private data */
555 this = (struct nand_chip *) (&rtc_from4_mtd[1]); 530 this = (struct nand_chip *)(&rtc_from4_mtd[1]);
556 531
557 /* Initialize structures */ 532 /* Initialize structures */
558 memset((char *) rtc_from4_mtd, 0, sizeof(struct mtd_info)); 533 memset(rtc_from4_mtd, 0, sizeof(struct mtd_info));
559 memset((char *) this, 0, sizeof(struct nand_chip)); 534 memset(this, 0, sizeof(struct nand_chip));
560 535
561 /* Link the private data with the MTD structure */ 536 /* Link the private data with the MTD structure */
562 rtc_from4_mtd->priv = this; 537 rtc_from4_mtd->priv = this;
538 rtc_from4_mtd->owner = THIS_MODULE;
563 539
564 /* set area 5 as PCMCIA mode to clear the spec of tDH(Data hold time;9ns min) */ 540 /* set area 5 as PCMCIA mode to clear the spec of tDH(Data hold time;9ns min) */
565 bcr1 = *SH77X9_BCR1 & ~0x0002; 541 bcr1 = *SH77X9_BCR1 & ~0x0002;
@@ -580,9 +556,9 @@ int __init rtc_from4_init (void)
580 this->IO_ADDR_R = rtc_from4_fio_base; 556 this->IO_ADDR_R = rtc_from4_fio_base;
581 this->IO_ADDR_W = rtc_from4_fio_base; 557 this->IO_ADDR_W = rtc_from4_fio_base;
582 /* Set address of hardware control function */ 558 /* Set address of hardware control function */
583 this->hwcontrol = rtc_from4_hwcontrol; 559 this->cmd_ctrl = rtc_from4_hwcontrol;
584 /* Set address of chip select function */ 560 /* Set address of chip select function */
585 this->select_chip = rtc_from4_nand_select_chip; 561 this->select_chip = rtc_from4_nand_select_chip;
586 /* command delay time (in us) */ 562 /* command delay time (in us) */
587 this->chip_delay = 100; 563 this->chip_delay = 100;
588 /* return the status of the Ready/Busy line */ 564 /* return the status of the Ready/Busy line */
@@ -591,19 +567,20 @@ int __init rtc_from4_init (void)
591#ifdef RTC_FROM4_HWECC 567#ifdef RTC_FROM4_HWECC
592 printk(KERN_INFO "rtc_from4_init: using hardware ECC detection.\n"); 568 printk(KERN_INFO "rtc_from4_init: using hardware ECC detection.\n");
593 569
594 this->eccmode = NAND_ECC_HW8_512; 570 this->ecc.mode = NAND_ECC_HW_SYNDROME;
595 this->options |= NAND_HWECC_SYNDROME; 571 this->ecc.size = 512;
572 this->ecc.bytes = 8;
596 /* return the status of extra status and ECC checks */ 573 /* return the status of extra status and ECC checks */
597 this->errstat = rtc_from4_errstat; 574 this->errstat = rtc_from4_errstat;
598 /* set the nand_oobinfo to support FPGA H/W error detection */ 575 /* set the nand_oobinfo to support FPGA H/W error detection */
599 this->autooob = &rtc_from4_nand_oobinfo; 576 this->ecc.layout = &rtc_from4_nand_oobinfo;
600 this->enable_hwecc = rtc_from4_enable_hwecc; 577 this->ecc.hwctl = rtc_from4_enable_hwecc;
601 this->calculate_ecc = rtc_from4_calculate_ecc; 578 this->ecc.calculate = rtc_from4_calculate_ecc;
602 this->correct_data = rtc_from4_correct_data; 579 this->ecc.correct = rtc_from4_correct_data;
603#else 580#else
604 printk(KERN_INFO "rtc_from4_init: using software ECC detection.\n"); 581 printk(KERN_INFO "rtc_from4_init: using software ECC detection.\n");
605 582
606 this->eccmode = NAND_ECC_SOFT; 583 this->ecc.mode = NAND_ECC_SOFT;
607#endif 584#endif
608 585
609 /* set the bad block tables to support debugging */ 586 /* set the bad block tables to support debugging */
@@ -617,7 +594,7 @@ int __init rtc_from4_init (void)
617 } 594 }
618 595
619 /* Perform 'device recovery' for each chip in case there was a power loss. */ 596 /* Perform 'device recovery' for each chip in case there was a power loss. */
620 for (i=0; i < this->numchips; i++) { 597 for (i = 0; i < this->numchips; i++) {
621 deplete(rtc_from4_mtd, i); 598 deplete(rtc_from4_mtd, i);
622 } 599 }
623 600
@@ -643,7 +620,7 @@ int __init rtc_from4_init (void)
643 */ 620 */
644 rs_decoder = init_rs(10, 0x409, 0, 1, 6); 621 rs_decoder = init_rs(10, 0x409, 0, 1, 6);
645 if (!rs_decoder) { 622 if (!rs_decoder) {
646 printk (KERN_ERR "Could not create a RS decoder\n"); 623 printk(KERN_ERR "Could not create a RS decoder\n");
647 nand_release(rtc_from4_mtd); 624 nand_release(rtc_from4_mtd);
648 kfree(rtc_from4_mtd); 625 kfree(rtc_from4_mtd);
649 return -ENOMEM; 626 return -ENOMEM;
@@ -652,20 +629,19 @@ int __init rtc_from4_init (void)
652 /* Return happy */ 629 /* Return happy */
653 return 0; 630 return 0;
654} 631}
655module_init(rtc_from4_init);
656 632
633module_init(rtc_from4_init);
657 634
658/* 635/*
659 * Clean up routine 636 * Clean up routine
660 */ 637 */
661#ifdef MODULE 638static void __exit rtc_from4_cleanup(void)
662static void __exit rtc_from4_cleanup (void)
663{ 639{
664 /* Release resource, unregister partitions */ 640 /* Release resource, unregister partitions */
665 nand_release(rtc_from4_mtd); 641 nand_release(rtc_from4_mtd);
666 642
667 /* Free the MTD device structure */ 643 /* Free the MTD device structure */
668 kfree (rtc_from4_mtd); 644 kfree(rtc_from4_mtd);
669 645
670#ifdef RTC_FROM4_HWECC 646#ifdef RTC_FROM4_HWECC
671 /* Free the reed solomon resources */ 647 /* Free the reed solomon resources */
@@ -674,10 +650,9 @@ static void __exit rtc_from4_cleanup (void)
674 } 650 }
675#endif 651#endif
676} 652}
653
677module_exit(rtc_from4_cleanup); 654module_exit(rtc_from4_cleanup);
678#endif
679 655
680MODULE_LICENSE("GPL"); 656MODULE_LICENSE("GPL");
681MODULE_AUTHOR("d.marlin <dmarlin@redhat.com"); 657MODULE_AUTHOR("d.marlin <dmarlin@redhat.com");
682MODULE_DESCRIPTION("Board-specific glue layer for AG-AND flash on Renesas FROM_BOARD4"); 658MODULE_DESCRIPTION("Board-specific glue layer for AG-AND flash on Renesas FROM_BOARD4");
683