1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22#include <linux/kernel.h>
23#include <linux/module.h>
24#include <linux/errno.h>
25#include <linux/platform_device.h>
26#include <linux/string.h>
27#include <linux/slab.h>
28#include <linux/io.h>
29#include <linux/delay.h>
30#include <linux/mtd/mtd.h>
31#include <linux/mtd/partitions.h>
32
33#include <linux/debugfs.h>
34#include <linux/seq_file.h>
35
36#define CREATE_TRACE_POINTS
37#include "docg3.h"
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66static inline u8 doc_readb(struct docg3 *docg3, u16 reg)
67{
68 u8 val = readb(docg3->base + reg);
69
70 trace_docg3_io(0, 8, reg, (int)val);
71 return val;
72}
73
74static inline u16 doc_readw(struct docg3 *docg3, u16 reg)
75{
76 u16 val = readw(docg3->base + reg);
77
78 trace_docg3_io(0, 16, reg, (int)val);
79 return val;
80}
81
82static inline void doc_writeb(struct docg3 *docg3, u8 val, u16 reg)
83{
84 writeb(val, docg3->base + reg);
85 trace_docg3_io(1, 16, reg, val);
86}
87
88static inline void doc_writew(struct docg3 *docg3, u16 val, u16 reg)
89{
90 writew(val, docg3->base + reg);
91 trace_docg3_io(1, 16, reg, val);
92}
93
94static inline void doc_flash_command(struct docg3 *docg3, u8 cmd)
95{
96 doc_writeb(docg3, cmd, DOC_FLASHCOMMAND);
97}
98
99static inline void doc_flash_sequence(struct docg3 *docg3, u8 seq)
100{
101 doc_writeb(docg3, seq, DOC_FLASHSEQUENCE);
102}
103
104static inline void doc_flash_address(struct docg3 *docg3, u8 addr)
105{
106 doc_writeb(docg3, addr, DOC_FLASHADDRESS);
107}
108
109static char const *part_probes[] = { "cmdlinepart", "saftlpart", NULL };
110
111static int doc_register_readb(struct docg3 *docg3, int reg)
112{
113 u8 val;
114
115 doc_writew(docg3, reg, DOC_READADDRESS);
116 val = doc_readb(docg3, reg);
117 doc_vdbg("Read register %04x : %02x\n", reg, val);
118 return val;
119}
120
121static int doc_register_readw(struct docg3 *docg3, int reg)
122{
123 u16 val;
124
125 doc_writew(docg3, reg, DOC_READADDRESS);
126 val = doc_readw(docg3, reg);
127 doc_vdbg("Read register %04x : %04x\n", reg, val);
128 return val;
129}
130
131
132
133
134
135
136
137
138
139
140
141
142static void doc_delay(struct docg3 *docg3, int nbNOPs)
143{
144 int i;
145
146 doc_dbg("NOP x %d\n", nbNOPs);
147 for (i = 0; i < nbNOPs; i++)
148 doc_writeb(docg3, 0, DOC_NOP);
149}
150
151static int is_prot_seq_error(struct docg3 *docg3)
152{
153 int ctrl;
154
155 ctrl = doc_register_readb(docg3, DOC_FLASHCONTROL);
156 return ctrl & (DOC_CTRL_PROTECTION_ERROR | DOC_CTRL_SEQUENCE_ERROR);
157}
158
159static int doc_is_ready(struct docg3 *docg3)
160{
161 int ctrl;
162
163 ctrl = doc_register_readb(docg3, DOC_FLASHCONTROL);
164 return ctrl & DOC_CTRL_FLASHREADY;
165}
166
167static int doc_wait_ready(struct docg3 *docg3)
168{
169 int maxWaitCycles = 100;
170
171 do {
172 doc_delay(docg3, 4);
173 cpu_relax();
174 } while (!doc_is_ready(docg3) && maxWaitCycles--);
175 doc_delay(docg3, 2);
176 if (maxWaitCycles > 0)
177 return 0;
178 else
179 return -EIO;
180}
181
182static int doc_reset_seq(struct docg3 *docg3)
183{
184 int ret;
185
186 doc_writeb(docg3, 0x10, DOC_FLASHCONTROL);
187 doc_flash_sequence(docg3, DOC_SEQ_RESET);
188 doc_flash_command(docg3, DOC_CMD_RESET);
189 doc_delay(docg3, 2);
190 ret = doc_wait_ready(docg3);
191
192 doc_dbg("doc_reset_seq() -> isReady=%s\n", ret ? "false" : "true");
193 return ret;
194}
195
196
197
198
199
200
201
202
203
204
205static void doc_read_data_area(struct docg3 *docg3, void *buf, int len,
206 int first)
207{
208 int i, cdr, len4;
209 u16 data16, *dst16;
210 u8 data8, *dst8;
211
212 doc_dbg("doc_read_data_area(buf=%p, len=%d)\n", buf, len);
213 cdr = len & 0x3;
214 len4 = len - cdr;
215
216 if (first)
217 doc_writew(docg3, DOC_IOSPACE_DATA, DOC_READADDRESS);
218 dst16 = buf;
219 for (i = 0; i < len4; i += 2) {
220 data16 = doc_readw(docg3, DOC_IOSPACE_DATA);
221 *dst16 = data16;
222 dst16++;
223 }
224
225 if (cdr) {
226 doc_writew(docg3, DOC_IOSPACE_DATA | DOC_READADDR_ONE_BYTE,
227 DOC_READADDRESS);
228 doc_delay(docg3, 1);
229 dst8 = (u8 *)dst16;
230 for (i = 0; i < cdr; i++) {
231 data8 = doc_readb(docg3, DOC_IOSPACE_DATA);
232 *dst8 = data8;
233 dst8++;
234 }
235 }
236}
237
238
239
240
241
242
243
244
245
246static void doc_set_reliable_mode(struct docg3 *docg3)
247{
248 doc_dbg("doc_set_reliable_mode()\n");
249 doc_flash_sequence(docg3, DOC_SEQ_SET_MODE);
250 doc_flash_command(docg3, DOC_CMD_FAST_MODE);
251 doc_flash_command(docg3, DOC_CMD_RELIABLE_MODE);
252 doc_delay(docg3, 2);
253}
254
255
256
257
258
259
260
261
262
263
264
265static void doc_set_asic_mode(struct docg3 *docg3, u8 mode)
266{
267 int i;
268
269 for (i = 0; i < 12; i++)
270 doc_readb(docg3, DOC_IOSPACE_IPL);
271
272 mode |= DOC_ASICMODE_MDWREN;
273 doc_dbg("doc_set_asic_mode(%02x)\n", mode);
274 doc_writeb(docg3, mode, DOC_ASICMODE);
275 doc_writeb(docg3, ~mode, DOC_ASICMODECONFIRM);
276 doc_delay(docg3, 1);
277}
278
279
280
281
282
283
284
285
286
287static void doc_set_device_id(struct docg3 *docg3, int id)
288{
289 u8 ctrl;
290
291 doc_dbg("doc_set_device_id(%d)\n", id);
292 doc_writeb(docg3, id, DOC_DEVICESELECT);
293 ctrl = doc_register_readb(docg3, DOC_FLASHCONTROL);
294
295 ctrl &= ~DOC_CTRL_VIOLATION;
296 ctrl |= DOC_CTRL_CE;
297 doc_writeb(docg3, ctrl, DOC_FLASHCONTROL);
298}
299
300
301
302
303
304
305
306
307
308
309
310
311static int doc_set_extra_page_mode(struct docg3 *docg3)
312{
313 int fctrl;
314
315 doc_dbg("doc_set_extra_page_mode()\n");
316 doc_flash_sequence(docg3, DOC_SEQ_PAGE_SIZE_532);
317 doc_flash_command(docg3, DOC_CMD_PAGE_SIZE_532);
318 doc_delay(docg3, 2);
319
320 fctrl = doc_register_readb(docg3, DOC_FLASHCONTROL);
321 if (fctrl & (DOC_CTRL_PROTECTION_ERROR | DOC_CTRL_SEQUENCE_ERROR))
322 return -EIO;
323 else
324 return 0;
325}
326
327
328
329
330
331
332
333
334
335
336
337
338
339static int doc_read_seek(struct docg3 *docg3, int block0, int block1, int page,
340 int wear, int ofs)
341{
342 int sector, ret = 0;
343
344 doc_dbg("doc_seek(blocks=(%d,%d), page=%d, ofs=%d, wear=%d)\n",
345 block0, block1, page, ofs, wear);
346
347 if (!wear && (ofs < 2 * DOC_LAYOUT_PAGE_SIZE)) {
348 doc_flash_sequence(docg3, DOC_SEQ_SET_PLANE1);
349 doc_flash_command(docg3, DOC_CMD_READ_PLANE1);
350 doc_delay(docg3, 2);
351 } else {
352 doc_flash_sequence(docg3, DOC_SEQ_SET_PLANE2);
353 doc_flash_command(docg3, DOC_CMD_READ_PLANE2);
354 doc_delay(docg3, 2);
355 }
356
357 doc_set_reliable_mode(docg3);
358 if (wear)
359 ret = doc_set_extra_page_mode(docg3);
360 if (ret)
361 goto out;
362
363 sector = (block0 << DOC_ADDR_BLOCK_SHIFT) + (page & DOC_ADDR_PAGE_MASK);
364 doc_flash_sequence(docg3, DOC_SEQ_READ);
365 doc_flash_command(docg3, DOC_CMD_PROG_BLOCK_ADDR);
366 doc_delay(docg3, 1);
367 doc_flash_address(docg3, sector & 0xff);
368 doc_flash_address(docg3, (sector >> 8) & 0xff);
369 doc_flash_address(docg3, (sector >> 16) & 0xff);
370 doc_delay(docg3, 1);
371
372 sector = (block1 << DOC_ADDR_BLOCK_SHIFT) + (page & DOC_ADDR_PAGE_MASK);
373 doc_flash_command(docg3, DOC_CMD_PROG_BLOCK_ADDR);
374 doc_delay(docg3, 1);
375 doc_flash_address(docg3, sector & 0xff);
376 doc_flash_address(docg3, (sector >> 8) & 0xff);
377 doc_flash_address(docg3, (sector >> 16) & 0xff);
378 doc_delay(docg3, 2);
379
380out:
381 return ret;
382}
383
384
385
386
387
388
389
390
391
392
393
394static int doc_read_page_ecc_init(struct docg3 *docg3, int len)
395{
396 doc_writew(docg3, DOC_ECCCONF0_READ_MODE
397 | DOC_ECCCONF0_BCH_ENABLE | DOC_ECCCONF0_HAMMING_ENABLE
398 | (len & DOC_ECCCONF0_DATA_BYTES_MASK),
399 DOC_ECCCONF0);
400 doc_delay(docg3, 4);
401 doc_register_readb(docg3, DOC_FLASHCONTROL);
402 return doc_wait_ready(docg3);
403}
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431static int doc_read_page_prepare(struct docg3 *docg3, int block0, int block1,
432 int page, int offset)
433{
434 int wear_area = 0, ret = 0;
435
436 doc_dbg("doc_read_page_prepare(blocks=(%d,%d), page=%d, ofsInPage=%d)\n",
437 block0, block1, page, offset);
438 if (offset >= DOC_LAYOUT_WEAR_OFFSET)
439 wear_area = 1;
440 if (!wear_area && offset > (DOC_LAYOUT_PAGE_OOB_SIZE * 2))
441 return -EINVAL;
442
443 doc_set_device_id(docg3, docg3->device_id);
444 ret = doc_reset_seq(docg3);
445 if (ret)
446 goto err;
447
448
449 ret = doc_read_seek(docg3, block0, block1, page, wear_area, offset);
450 if (ret)
451 goto err;
452
453 doc_flash_command(docg3, DOC_CMD_READ_ALL_PLANES);
454 doc_delay(docg3, 2);
455 doc_wait_ready(docg3);
456
457 doc_flash_command(docg3, DOC_CMD_SET_ADDR_READ);
458 doc_delay(docg3, 1);
459 if (offset >= DOC_LAYOUT_PAGE_SIZE * 2)
460 offset -= 2 * DOC_LAYOUT_PAGE_SIZE;
461 doc_flash_address(docg3, offset >> 2);
462 doc_delay(docg3, 1);
463 doc_wait_ready(docg3);
464
465 doc_flash_command(docg3, DOC_CMD_READ_FLASH);
466
467 return 0;
468err:
469 doc_writeb(docg3, 0, DOC_DATAEND);
470 doc_delay(docg3, 2);
471 return -EIO;
472}
473
474
475
476
477
478
479
480
481
482static int doc_read_page_getbytes(struct docg3 *docg3, int len, u_char *buf,
483 int first)
484{
485 doc_read_data_area(docg3, buf, len, first);
486 doc_delay(docg3, 2);
487 return len;
488}
489
490
491
492
493
494
495static void doc_get_hw_bch_syndroms(struct docg3 *docg3, int *syns)
496{
497 int i;
498
499 for (i = 0; i < DOC_ECC_BCH_SIZE; i++)
500 syns[i] = doc_register_readb(docg3, DOC_BCH_SYNDROM(i));
501}
502
503
504
505
506
507
508
509
510
511static void doc_read_page_finish(struct docg3 *docg3)
512{
513 doc_writeb(docg3, 0, DOC_DATAEND);
514 doc_delay(docg3, 2);
515 doc_set_device_id(docg3, 0);
516}
517
518
519
520
521
522
523
524
525
526
527static void calc_block_sector(loff_t from, int *block0, int *block1, int *page,
528 int *ofs)
529{
530 uint sector;
531
532 sector = from / DOC_LAYOUT_PAGE_SIZE;
533 *block0 = sector / (DOC_LAYOUT_PAGES_PER_BLOCK * DOC_LAYOUT_NBPLANES)
534 * DOC_LAYOUT_NBPLANES;
535 *block1 = *block0 + 1;
536 *page = sector % (DOC_LAYOUT_PAGES_PER_BLOCK * DOC_LAYOUT_NBPLANES);
537 *page /= DOC_LAYOUT_NBPLANES;
538 if (sector % 2)
539 *ofs = DOC_LAYOUT_PAGE_OOB_SIZE;
540 else
541 *ofs = 0;
542}
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558static int doc_read(struct mtd_info *mtd, loff_t from, size_t len,
559 size_t *retlen, u_char *buf)
560{
561 struct docg3 *docg3 = mtd->priv;
562 int block0, block1, page, readlen, ret, ofs = 0;
563 int syn[DOC_ECC_BCH_SIZE], eccconf1;
564 u8 oob[DOC_LAYOUT_OOB_SIZE];
565
566 ret = -EINVAL;
567 doc_dbg("doc_read(from=%lld, len=%zu, buf=%p)\n", from, len, buf);
568 if (from % DOC_LAYOUT_PAGE_SIZE)
569 goto err;
570 if (len % 4)
571 goto err;
572 calc_block_sector(from, &block0, &block1, &page, &ofs);
573 if (block1 > docg3->max_block)
574 goto err;
575
576 *retlen = 0;
577 ret = 0;
578 readlen = min_t(size_t, len, (size_t)DOC_LAYOUT_PAGE_SIZE);
579 while (!ret && len > 0) {
580 readlen = min_t(size_t, len, (size_t)DOC_LAYOUT_PAGE_SIZE);
581 ret = doc_read_page_prepare(docg3, block0, block1, page, ofs);
582 if (ret < 0)
583 goto err;
584 ret = doc_read_page_ecc_init(docg3, DOC_ECC_BCH_COVERED_BYTES);
585 if (ret < 0)
586 goto err_in_read;
587 ret = doc_read_page_getbytes(docg3, readlen, buf, 1);
588 if (ret < readlen)
589 goto err_in_read;
590 ret = doc_read_page_getbytes(docg3, DOC_LAYOUT_OOB_SIZE,
591 oob, 0);
592 if (ret < DOC_LAYOUT_OOB_SIZE)
593 goto err_in_read;
594
595 *retlen += readlen;
596 buf += readlen;
597 len -= readlen;
598
599 ofs ^= DOC_LAYOUT_PAGE_OOB_SIZE;
600 if (ofs == 0)
601 page += 2;
602 if (page > DOC_ADDR_PAGE_MASK) {
603 page = 0;
604 block0 += 2;
605 block1 += 2;
606 }
607
608
609
610
611
612 doc_get_hw_bch_syndroms(docg3, syn);
613 eccconf1 = doc_register_readb(docg3, DOC_ECCCONF1);
614
615 doc_dbg("OOB - INFO: %02x:%02x:%02x:%02x:%02x:%02x:%02x\n",
616 oob[0], oob[1], oob[2], oob[3], oob[4],
617 oob[5], oob[6]);
618 doc_dbg("OOB - HAMMING: %02x\n", oob[7]);
619 doc_dbg("OOB - BCH_ECC: %02x:%02x:%02x:%02x:%02x:%02x:%02x\n",
620 oob[8], oob[9], oob[10], oob[11], oob[12],
621 oob[13], oob[14]);
622 doc_dbg("OOB - UNUSED: %02x\n", oob[15]);
623 doc_dbg("ECC checks: ECCConf1=%x\n", eccconf1);
624 doc_dbg("ECC BCH syndrom: %02x:%02x:%02x:%02x:%02x:%02x:%02x\n",
625 syn[0], syn[1], syn[2], syn[3], syn[4], syn[5], syn[6]);
626
627 ret = -EBADMSG;
628 if (block0 >= DOC_LAYOUT_BLOCK_FIRST_DATA) {
629 if (eccconf1 & DOC_ECCCONF1_BCH_SYNDROM_ERR)
630 goto err_in_read;
631 if (is_prot_seq_error(docg3))
632 goto err_in_read;
633 }
634 doc_read_page_finish(docg3);
635 }
636
637 return 0;
638err_in_read:
639 doc_read_page_finish(docg3);
640err:
641 return ret;
642}
643
644
645
646
647
648
649
650
651
652
653
654
655static int doc_read_oob(struct mtd_info *mtd, loff_t from,
656 struct mtd_oob_ops *ops)
657{
658 struct docg3 *docg3 = mtd->priv;
659 int block0, block1, page, ofs, ret;
660 u8 *buf = ops->oobbuf;
661 size_t len = ops->ooblen;
662
663 doc_dbg("doc_read_oob(from=%lld, buf=%p, len=%zu)\n", from, buf, len);
664 if (len != DOC_LAYOUT_OOB_SIZE)
665 return -EINVAL;
666
667 switch (ops->mode) {
668 case MTD_OPS_PLACE_OOB:
669 buf += ops->ooboffs;
670 break;
671 default:
672 break;
673 }
674
675 calc_block_sector(from, &block0, &block1, &page, &ofs);
676 if (block1 > docg3->max_block)
677 return -EINVAL;
678
679 ret = doc_read_page_prepare(docg3, block0, block1, page,
680 ofs + DOC_LAYOUT_PAGE_SIZE);
681 if (!ret)
682 ret = doc_read_page_ecc_init(docg3, DOC_LAYOUT_OOB_SIZE);
683 if (!ret)
684 ret = doc_read_page_getbytes(docg3, DOC_LAYOUT_OOB_SIZE,
685 buf, 1);
686 doc_read_page_finish(docg3);
687
688 if (ret > 0)
689 ops->oobretlen = ret;
690 else
691 ops->oobretlen = 0;
692 return (ret > 0) ? 0 : ret;
693}
694
695static int doc_reload_bbt(struct docg3 *docg3)
696{
697 int block = DOC_LAYOUT_BLOCK_BBT;
698 int ret = 0, nbpages, page;
699 u_char *buf = docg3->bbt;
700
701 nbpages = DIV_ROUND_UP(docg3->max_block + 1, 8 * DOC_LAYOUT_PAGE_SIZE);
702 for (page = 0; !ret && (page < nbpages); page++) {
703 ret = doc_read_page_prepare(docg3, block, block + 1,
704 page + DOC_LAYOUT_PAGE_BBT, 0);
705 if (!ret)
706 ret = doc_read_page_ecc_init(docg3,
707 DOC_LAYOUT_PAGE_SIZE);
708 if (!ret)
709 doc_read_page_getbytes(docg3, DOC_LAYOUT_PAGE_SIZE,
710 buf, 1);
711 buf += DOC_LAYOUT_PAGE_SIZE;
712 }
713 doc_read_page_finish(docg3);
714 return ret;
715}
716
717
718
719
720
721
722
723
724static int doc_block_isbad(struct mtd_info *mtd, loff_t from)
725{
726 struct docg3 *docg3 = mtd->priv;
727 int block0, block1, page, ofs, is_good;
728
729 calc_block_sector(from, &block0, &block1, &page, &ofs);
730 doc_dbg("doc_block_isbad(from=%lld) => block=(%d,%d), page=%d, ofs=%d\n",
731 from, block0, block1, page, ofs);
732
733 if (block0 < DOC_LAYOUT_BLOCK_FIRST_DATA)
734 return 0;
735 if (block1 > docg3->max_block)
736 return -EINVAL;
737
738 is_good = docg3->bbt[block0 >> 3] & (1 << (block0 & 0x7));
739 return !is_good;
740}
741
742
743
744
745
746
747
748
749
750
751
752static int doc_get_erase_count(struct docg3 *docg3, loff_t from)
753{
754 u8 buf[DOC_LAYOUT_WEAR_SIZE];
755 int ret, plane1_erase_count, plane2_erase_count;
756 int block0, block1, page, ofs;
757
758 doc_dbg("doc_get_erase_count(from=%lld, buf=%p)\n", from, buf);
759 if (from % DOC_LAYOUT_PAGE_SIZE)
760 return -EINVAL;
761 calc_block_sector(from, &block0, &block1, &page, &ofs);
762 if (block1 > docg3->max_block)
763 return -EINVAL;
764
765 ret = doc_reset_seq(docg3);
766 if (!ret)
767 ret = doc_read_page_prepare(docg3, block0, block1, page,
768 ofs + DOC_LAYOUT_WEAR_OFFSET);
769 if (!ret)
770 ret = doc_read_page_getbytes(docg3, DOC_LAYOUT_WEAR_SIZE,
771 buf, 1);
772 doc_read_page_finish(docg3);
773
774 if (ret || (buf[0] != DOC_ERASE_MARK) || (buf[2] != DOC_ERASE_MARK))
775 return -EIO;
776 plane1_erase_count = (u8)(~buf[1]) | ((u8)(~buf[4]) << 8)
777 | ((u8)(~buf[5]) << 16);
778 plane2_erase_count = (u8)(~buf[3]) | ((u8)(~buf[6]) << 8)
779 | ((u8)(~buf[7]) << 16);
780
781 return max(plane1_erase_count, plane2_erase_count);
782}
783
784
785
786
787static int dbg_flashctrl_show(struct seq_file *s, void *p)
788{
789 struct docg3 *docg3 = (struct docg3 *)s->private;
790
791 int pos = 0;
792 u8 fctrl = doc_register_readb(docg3, DOC_FLASHCONTROL);
793
794 pos += seq_printf(s,
795 "FlashControl : 0x%02x (%s,CE# %s,%s,%s,flash %s)\n",
796 fctrl,
797 fctrl & DOC_CTRL_VIOLATION ? "protocol violation" : "-",
798 fctrl & DOC_CTRL_CE ? "active" : "inactive",
799 fctrl & DOC_CTRL_PROTECTION_ERROR ? "protection error" : "-",
800 fctrl & DOC_CTRL_SEQUENCE_ERROR ? "sequence error" : "-",
801 fctrl & DOC_CTRL_FLASHREADY ? "ready" : "not ready");
802 return pos;
803}
804DEBUGFS_RO_ATTR(flashcontrol, dbg_flashctrl_show);
805
806static int dbg_asicmode_show(struct seq_file *s, void *p)
807{
808 struct docg3 *docg3 = (struct docg3 *)s->private;
809
810 int pos = 0;
811 int pctrl = doc_register_readb(docg3, DOC_ASICMODE);
812 int mode = pctrl & 0x03;
813
814 pos += seq_printf(s,
815 "%04x : RAM_WE=%d,RSTIN_RESET=%d,BDETCT_RESET=%d,WRITE_ENABLE=%d,POWERDOWN=%d,MODE=%d%d (",
816 pctrl,
817 pctrl & DOC_ASICMODE_RAM_WE ? 1 : 0,
818 pctrl & DOC_ASICMODE_RSTIN_RESET ? 1 : 0,
819 pctrl & DOC_ASICMODE_BDETCT_RESET ? 1 : 0,
820 pctrl & DOC_ASICMODE_MDWREN ? 1 : 0,
821 pctrl & DOC_ASICMODE_POWERDOWN ? 1 : 0,
822 mode >> 1, mode & 0x1);
823
824 switch (mode) {
825 case DOC_ASICMODE_RESET:
826 pos += seq_printf(s, "reset");
827 break;
828 case DOC_ASICMODE_NORMAL:
829 pos += seq_printf(s, "normal");
830 break;
831 case DOC_ASICMODE_POWERDOWN:
832 pos += seq_printf(s, "powerdown");
833 break;
834 }
835 pos += seq_printf(s, ")\n");
836 return pos;
837}
838DEBUGFS_RO_ATTR(asic_mode, dbg_asicmode_show);
839
840static int dbg_device_id_show(struct seq_file *s, void *p)
841{
842 struct docg3 *docg3 = (struct docg3 *)s->private;
843 int pos = 0;
844 int id = doc_register_readb(docg3, DOC_DEVICESELECT);
845
846 pos += seq_printf(s, "DeviceId = %d\n", id);
847 return pos;
848}
849DEBUGFS_RO_ATTR(device_id, dbg_device_id_show);
850
851static int dbg_protection_show(struct seq_file *s, void *p)
852{
853 struct docg3 *docg3 = (struct docg3 *)s->private;
854 int pos = 0;
855 int protect = doc_register_readb(docg3, DOC_PROTECTION);
856 int dps0 = doc_register_readb(docg3, DOC_DPS0_STATUS);
857 int dps0_low = doc_register_readb(docg3, DOC_DPS0_ADDRLOW);
858 int dps0_high = doc_register_readb(docg3, DOC_DPS0_ADDRHIGH);
859 int dps1 = doc_register_readb(docg3, DOC_DPS1_STATUS);
860 int dps1_low = doc_register_readb(docg3, DOC_DPS1_ADDRLOW);
861 int dps1_high = doc_register_readb(docg3, DOC_DPS1_ADDRHIGH);
862
863 pos += seq_printf(s, "Protection = 0x%02x (",
864 protect);
865 if (protect & DOC_PROTECT_FOUNDRY_OTP_LOCK)
866 pos += seq_printf(s, "FOUNDRY_OTP_LOCK,");
867 if (protect & DOC_PROTECT_CUSTOMER_OTP_LOCK)
868 pos += seq_printf(s, "CUSTOMER_OTP_LOCK,");
869 if (protect & DOC_PROTECT_LOCK_INPUT)
870 pos += seq_printf(s, "LOCK_INPUT,");
871 if (protect & DOC_PROTECT_STICKY_LOCK)
872 pos += seq_printf(s, "STICKY_LOCK,");
873 if (protect & DOC_PROTECT_PROTECTION_ENABLED)
874 pos += seq_printf(s, "PROTECTION ON,");
875 if (protect & DOC_PROTECT_IPL_DOWNLOAD_LOCK)
876 pos += seq_printf(s, "IPL_DOWNLOAD_LOCK,");
877 if (protect & DOC_PROTECT_PROTECTION_ERROR)
878 pos += seq_printf(s, "PROTECT_ERR,");
879 else
880 pos += seq_printf(s, "NO_PROTECT_ERR");
881 pos += seq_printf(s, ")\n");
882
883 pos += seq_printf(s, "DPS0 = 0x%02x : "
884 "Protected area [0x%x - 0x%x] : OTP=%d, READ=%d, "
885 "WRITE=%d, HW_LOCK=%d, KEY_OK=%d\n",
886 dps0, dps0_low, dps0_high,
887 !!(dps0 & DOC_DPS_OTP_PROTECTED),
888 !!(dps0 & DOC_DPS_READ_PROTECTED),
889 !!(dps0 & DOC_DPS_WRITE_PROTECTED),
890 !!(dps0 & DOC_DPS_HW_LOCK_ENABLED),
891 !!(dps0 & DOC_DPS_KEY_OK));
892 pos += seq_printf(s, "DPS1 = 0x%02x : "
893 "Protected area [0x%x - 0x%x] : OTP=%d, READ=%d, "
894 "WRITE=%d, HW_LOCK=%d, KEY_OK=%d\n",
895 dps1, dps1_low, dps1_high,
896 !!(dps1 & DOC_DPS_OTP_PROTECTED),
897 !!(dps1 & DOC_DPS_READ_PROTECTED),
898 !!(dps1 & DOC_DPS_WRITE_PROTECTED),
899 !!(dps1 & DOC_DPS_HW_LOCK_ENABLED),
900 !!(dps1 & DOC_DPS_KEY_OK));
901 return pos;
902}
903DEBUGFS_RO_ATTR(protection, dbg_protection_show);
904
905static int __init doc_dbg_register(struct docg3 *docg3)
906{
907 struct dentry *root, *entry;
908
909 root = debugfs_create_dir("docg3", NULL);
910 if (!root)
911 return -ENOMEM;
912
913 entry = debugfs_create_file("flashcontrol", S_IRUSR, root, docg3,
914 &flashcontrol_fops);
915 if (entry)
916 entry = debugfs_create_file("asic_mode", S_IRUSR, root,
917 docg3, &asic_mode_fops);
918 if (entry)
919 entry = debugfs_create_file("device_id", S_IRUSR, root,
920 docg3, &device_id_fops);
921 if (entry)
922 entry = debugfs_create_file("protection", S_IRUSR, root,
923 docg3, &protection_fops);
924 if (entry) {
925 docg3->debugfs_root = root;
926 return 0;
927 } else {
928 debugfs_remove_recursive(root);
929 return -ENOMEM;
930 }
931}
932
933static void __exit doc_dbg_unregister(struct docg3 *docg3)
934{
935 debugfs_remove_recursive(docg3->debugfs_root);
936}
937
938
939
940
941
942
943static void __init doc_set_driver_info(int chip_id, struct mtd_info *mtd)
944{
945 struct docg3 *docg3 = mtd->priv;
946 int cfg;
947
948 cfg = doc_register_readb(docg3, DOC_CONFIGURATION);
949 docg3->if_cfg = (cfg & DOC_CONF_IF_CFG ? 1 : 0);
950
951 switch (chip_id) {
952 case DOC_CHIPID_G3:
953 mtd->name = "DiskOnChip G3";
954 docg3->max_block = 2047;
955 break;
956 }
957 mtd->type = MTD_NANDFLASH;
958
959
960
961
962 mtd->flags = MTD_CAP_ROM;
963 mtd->size = (docg3->max_block + 1) * DOC_LAYOUT_BLOCK_SIZE;
964 mtd->erasesize = DOC_LAYOUT_BLOCK_SIZE * DOC_LAYOUT_NBPLANES;
965 mtd->writesize = DOC_LAYOUT_PAGE_SIZE;
966 mtd->oobsize = DOC_LAYOUT_OOB_SIZE;
967 mtd->owner = THIS_MODULE;
968 mtd->erase = NULL;
969 mtd->point = NULL;
970 mtd->unpoint = NULL;
971 mtd->read = doc_read;
972 mtd->write = NULL;
973 mtd->read_oob = doc_read_oob;
974 mtd->write_oob = NULL;
975 mtd->sync = NULL;
976 mtd->block_isbad = doc_block_isbad;
977}
978
979
980
981
982
983
984
985
986
987
988static int __init docg3_probe(struct platform_device *pdev)
989{
990 struct device *dev = &pdev->dev;
991 struct docg3 *docg3;
992 struct mtd_info *mtd;
993 struct resource *ress;
994 int ret, bbt_nbpages;
995 u16 chip_id, chip_id_inv;
996
997 ret = -ENOMEM;
998 docg3 = kzalloc(sizeof(struct docg3), GFP_KERNEL);
999 if (!docg3)
1000 goto nomem1;
1001 mtd = kzalloc(sizeof(struct mtd_info), GFP_KERNEL);
1002 if (!mtd)
1003 goto nomem2;
1004 mtd->priv = docg3;
1005
1006 ret = -ENXIO;
1007 ress = platform_get_resource(pdev, IORESOURCE_MEM, 0);
1008 if (!ress) {
1009 dev_err(dev, "No I/O memory resource defined\n");
1010 goto noress;
1011 }
1012 docg3->base = ioremap(ress->start, DOC_IOSPACE_SIZE);
1013
1014 docg3->dev = &pdev->dev;
1015 docg3->device_id = 0;
1016 doc_set_device_id(docg3, docg3->device_id);
1017 doc_set_asic_mode(docg3, DOC_ASICMODE_RESET);
1018 doc_set_asic_mode(docg3, DOC_ASICMODE_NORMAL);
1019
1020 chip_id = doc_register_readw(docg3, DOC_CHIPID);
1021 chip_id_inv = doc_register_readw(docg3, DOC_CHIPID_INV);
1022
1023 ret = -ENODEV;
1024 if (chip_id != (u16)(~chip_id_inv)) {
1025 doc_info("No device found at IO addr %p\n",
1026 (void *)ress->start);
1027 goto nochipfound;
1028 }
1029
1030 switch (chip_id) {
1031 case DOC_CHIPID_G3:
1032 doc_info("Found a G3 DiskOnChip at addr %p\n",
1033 (void *)ress->start);
1034 break;
1035 default:
1036 doc_err("Chip id %04x is not a DiskOnChip G3 chip\n", chip_id);
1037 goto nochipfound;
1038 }
1039
1040 doc_set_driver_info(chip_id, mtd);
1041 platform_set_drvdata(pdev, mtd);
1042
1043 ret = -ENOMEM;
1044 bbt_nbpages = DIV_ROUND_UP(docg3->max_block + 1,
1045 8 * DOC_LAYOUT_PAGE_SIZE);
1046 docg3->bbt = kzalloc(bbt_nbpages * DOC_LAYOUT_PAGE_SIZE, GFP_KERNEL);
1047 if (!docg3->bbt)
1048 goto nochipfound;
1049 doc_reload_bbt(docg3);
1050
1051 ret = mtd_device_parse_register(mtd, part_probes,
1052 NULL, NULL, 0);
1053 if (ret)
1054 goto register_error;
1055
1056 doc_dbg_register(docg3);
1057 return 0;
1058
1059register_error:
1060 kfree(docg3->bbt);
1061nochipfound:
1062 iounmap(docg3->base);
1063noress:
1064 kfree(mtd);
1065nomem2:
1066 kfree(docg3);
1067nomem1:
1068 return ret;
1069}
1070
1071
1072
1073
1074
1075
1076
1077static int __exit docg3_release(struct platform_device *pdev)
1078{
1079 struct mtd_info *mtd = platform_get_drvdata(pdev);
1080 struct docg3 *docg3 = mtd->priv;
1081
1082 doc_dbg_unregister(docg3);
1083 mtd_device_unregister(mtd);
1084 iounmap(docg3->base);
1085 kfree(docg3->bbt);
1086 kfree(docg3);
1087 kfree(mtd);
1088 return 0;
1089}
1090
1091static struct platform_driver g3_driver = {
1092 .driver = {
1093 .name = "docg3",
1094 .owner = THIS_MODULE,
1095 },
1096 .remove = __exit_p(docg3_release),
1097};
1098
1099static int __init docg3_init(void)
1100{
1101 return platform_driver_probe(&g3_driver, docg3_probe);
1102}
1103module_init(docg3_init);
1104
1105
1106static void __exit docg3_exit(void)
1107{
1108 platform_driver_unregister(&g3_driver);
1109}
1110module_exit(docg3_exit);
1111
1112MODULE_LICENSE("GPL");
1113MODULE_AUTHOR("Robert Jarzmik <robert.jarzmik@free.fr>");
1114MODULE_DESCRIPTION("MTD driver for DiskOnChip G3");
1115