1 #include "u.h"
2 #include "../port/lib.h"
3 #include "mem.h"
4 #include "dat.h"
5 #include "fns.h"
6 #include "io.h"
7 #include "../port/error.h"
8
9 #include "flashif.h"
10
11 /*
12 * Cerf405-specific NAND flash interface
13 */
14
15 #define BE(n) (1<<(31-(n))) /* big-endian bit numbering */
16
17 enum {
18 /* GPIO lines */
19 Gpio_CLE_o_b= 31,
20 Gpio_ALE_o_b= 30,
21 Gpio_NCE_o_b= 24, /* CE#, active low */
22 Gpio_RDY_i_b= 23,
23
24 /* bit masks */
25 Gpio_CLE_o= BE(Gpio_CLE_o_b),
26 Gpio_ALE_o= BE(Gpio_ALE_o_b),
27 Gpio_NCE_o= BE(Gpio_NCE_o_b),
28 Gpio_RDY_i= BE(Gpio_RDY_i_b),
29
30 Gpio_NAND_o= Gpio_CLE_o | Gpio_ALE_o | Gpio_NCE_o,
31
32 CS_NAND= 1,
33 Gpio_PerCS1_o= BE(10),
34 };
35
36 void
archnand_init(Flash *)37 archnand_init(Flash*)
38 {
39 gpioreserve(Gpio_NAND_o | Gpio_RDY_i);
40 gpioset(Gpio_NAND_o, Gpio_NCE_o);
41 gpioconfig(Gpio_NAND_o, Gpio_out);
42 gpioconfig(Gpio_RDY_i, Gpio_in);
43 }
44
45 void
archnand_claim(Flash *,int claim)46 archnand_claim(Flash*, int claim)
47 {
48 gpioset(Gpio_NCE_o, claim? 0: Gpio_NCE_o);
49 }
50
51 void
archnand_setCLEandALE(Flash *,int cle,int ale)52 archnand_setCLEandALE(Flash*, int cle, int ale)
53 {
54 ulong v;
55
56 v = 0;
57 if(cle)
58 v |= Gpio_CLE_o;
59 if(ale)
60 v |= Gpio_ALE_o;
61 gpioset(Gpio_CLE_o | Gpio_ALE_o, v);
62 }
63
64 /*
65 * could unroll the loops
66 */
67
68 void
archnand_read(Flash * f,void * buf,int len)69 archnand_read(Flash *f, void *buf, int len)
70 {
71 uchar *p, *bp;
72
73 p = f->addr;
74 if(buf != nil){
75 bp = buf;
76 while(--len >= 0)
77 *bp++ = *p;
78 }else{
79 int junk;
80 while(--len >= 0){
81 junk = *p;
82 USED(junk);
83 }
84 }
85 }
86
87 void
archnand_write(Flash * f,void * buf,int len)88 archnand_write(Flash *f, void *buf, int len)
89 {
90 uchar *p, *bp;
91
92 p = f->addr;
93 bp = buf;
94 while(--len >= 0)
95 *p = *bp++;
96 }
97