]> rtime.felk.cvut.cz Git - l4.git/blob - l4/pkg/drivers-frst/nand/src/nand.h
update
[l4.git] / l4 / pkg / drivers-frst / nand / src / nand.h
1 #pragma once
2
3 #include <string.h>
4
5 #include "types.h"
6 #include <l4/drivers-frst/transfer.h>
7
8 struct Op
9 {};
10
11 struct Read_op : Op
12 {
13   u32 addr;
14   Transfer *transfer;
15 };
16
17 struct Write_op : Op
18 {
19   u32 addr;
20   Transfer *transfer;
21 };
22
23 struct Erase_op : Op
24 {
25   u32 addr;
26   u32 len;
27   u_char state;
28 };
29
30
31 struct Dev_desc
32 {
33   int id;
34   const char *name;
35   unsigned long sz_page; // bytes
36   unsigned long sz_spare; // bytes
37   unsigned long sz_chip; // MiB
38   unsigned long sz_erase; // bytes
39   unsigned long options;
40 };
41
42 struct Mfr_desc
43 {
44   int id;
45   const char *name;
46 };
47
48 extern Dev_desc _dev_ids[];
49 extern Mfr_desc _mfr_ids[];
50
51 enum
52 {
53   Opt_no_autoincr    = 0x001,
54   Opt_buswidth_16    = 0x002,
55   Opt_no_padding     = 0x004,
56   Opt_cacheprg       = 0x008,
57   Opt_copyback       = 0x010,
58   Opt_is_and         = 0x020,
59   Opt_4page_array    = 0x040,
60   /* Chip does not require ready check on read. True
61    * for all large page devices, as they do not support autoincrement.*/
62   Opt_no_readrdy       = 0x100,
63   Opt_no_subpage_write = 0x200,
64 };
65
66
67 class Nand_ctrl;
68 class Nand_chip
69 {
70 public:
71   enum State
72     {
73       Ready,
74       Reading,
75       Writing,
76       Erasing,
77       Cachedprg,
78     };
79
80   Nand_chip(Nand_ctrl *ctrl, Dev_desc *dev, Mfr_desc *mfr, int ext_id = 0);
81
82   State state() {return _state; }
83   void set_state(State state) { _state = state; }
84   void set_state(State state, Op *op)
85     {
86       _state = state;
87       _ongoing_op = op;
88     }
89
90   u32 sz_write() const
91     { return _sz_write; }
92   u32 sz_spare() const
93     { return _sz_spare; }
94   u32 sz_erase() const
95     { return _sz_erase; }
96   u64 sz_chip() const
97     { return _sz_chip; }
98   void add_options(int options)
99     { _options |= options; }
100
101   int page_shift() { return ffs(_sz_write) - 1; }
102   int page_mask() { return (sz_chip() >> page_shift()) - 1; }
103   int erase_shift() { return ffs(_sz_erase) - 1; }
104   int erase_mask() { return (sz_chip() >> erase_shift()) - 1; }
105
106   int handle_irq();
107
108 protected:
109   u32 _sz_write;
110   u32 _sz_spare;
111   u32 _sz_erase;
112   u64 _sz_chip;
113
114   int _bus_width;
115   int _delay;
116   int _options;
117
118 private:
119   State _state;
120   Op *_ongoing_op;
121  
122   Nand_ctrl *_ctrl;
123   Dev_desc *_dev;
124   Mfr_desc *_mfr;
125 };
126
127 class Nand_ctrl
128 {
129 protected:
130   // commands
131   enum
132     {
133       // standard device commands
134       Cmd_read0    = 0x00,
135       Cmd_read1    = 0x01,
136       Cmd_rndout   = 0x05,
137       Cmd_pageprog = 0x10,
138       Cmd_readoob  = 0x50,
139       Cmd_erase1   = 0x60,
140       Cmd_status   = 0x70,
141       Cmd_seqin    = 0x80,
142       Cmd_rndin    = 0x85,
143       Cmd_readid   = 0x90,
144       Cmd_erase2   = 0xd0,
145       Cmd_reset    = 0xff,
146
147       // large page device commands
148       Cmd_readstart   = 0x30,
149       Cmd_rndoutstart = 0xe0,
150       Cmd_cachedprog  = 0x15,
151     };
152
153   /* status bits */
154   enum
155     {
156       Status_fail       = 0x01,
157       Status_fail_n1    = 0x02,
158       Status_true_ready = 0x20,
159       Status_ready      = 0x40,
160       Status_wp         = 0x80,
161     };
162
163 public:
164   Nand_ctrl();
165
166   int read(Read_op *op);
167   int write(Write_op *op);
168   int erase(Erase_op *op);
169
170   int done_read(Read_op *op);
171   int done_write(Write_op *op);
172   int done_erase(Erase_op *op);
173  
174   virtual int handle_irq() = 0;
175
176 protected:
177   int scan(int maxchips);
178
179   virtual void add(Nand_chip *chip) = 0;
180   virtual Nand_chip *select(loff_t addr) = 0;
181   
182   virtual void wr_cmd(u8 c) = 0;
183   virtual void wr_adr(u8 a) = 0;
184   virtual void wr_dat(u8 d) = 0;
185
186   bool aligned(u32 addr) const
187     { return !(addr & (sz_write - 1)); }
188
189   virtual u8 rd_dat() = 0;
190   virtual void rd_dat(const u8 *buf, unsigned len) = 0;
191   virtual void wr_dat(const u8 *buf, unsigned len) = 0;
192
193   bool is_wp();
194   int get_status();
195   virtual int get_id(char id[4]);
196
197 public:
198   const char *name;
199   unsigned numchips;
200   u64 size;
201   u32 sz_erase;
202   u32 sz_write;
203   u32 sz_spare;
204 };
205