xref: /inferno-os/os/cerf405/nand.c (revision 74a4d8c26dd3c1e9febcb717cfd6cb6512991a7a)
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