1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22#ifndef __LINUX_MTD_MAP_H__
23#define __LINUX_MTD_MAP_H__
24
25#include <linux/types.h>
26#include <linux/list.h>
27#include <linux/string.h>
28#include <linux/bug.h>
29#include <linux/kernel.h>
30
31#include <asm/unaligned.h>
32#include <asm/io.h>
33#include <asm/barrier.h>
34
35#ifdef CONFIG_MTD_MAP_BANK_WIDTH_1
36#define map_bankwidth(map) 1
37#define map_bankwidth_is_1(map) (map_bankwidth(map) == 1)
38#define map_bankwidth_is_large(map) (0)
39#define map_words(map) (1)
40#define MAX_MAP_BANKWIDTH 1
41#else
42#define map_bankwidth_is_1(map) (0)
43#endif
44
45#ifdef CONFIG_MTD_MAP_BANK_WIDTH_2
46# ifdef map_bankwidth
47# undef map_bankwidth
48# define map_bankwidth(map) ((map)->bankwidth)
49# else
50# define map_bankwidth(map) 2
51# define map_bankwidth_is_large(map) (0)
52# define map_words(map) (1)
53# endif
54#define map_bankwidth_is_2(map) (map_bankwidth(map) == 2)
55#undef MAX_MAP_BANKWIDTH
56#define MAX_MAP_BANKWIDTH 2
57#else
58#define map_bankwidth_is_2(map) (0)
59#endif
60
61#ifdef CONFIG_MTD_MAP_BANK_WIDTH_4
62# ifdef map_bankwidth
63# undef map_bankwidth
64# define map_bankwidth(map) ((map)->bankwidth)
65# else
66# define map_bankwidth(map) 4
67# define map_bankwidth_is_large(map) (0)
68# define map_words(map) (1)
69# endif
70#define map_bankwidth_is_4(map) (map_bankwidth(map) == 4)
71#undef MAX_MAP_BANKWIDTH
72#define MAX_MAP_BANKWIDTH 4
73#else
74#define map_bankwidth_is_4(map) (0)
75#endif
76
77
78
79
80#define map_calc_words(map) ((map_bankwidth(map) + (sizeof(unsigned long)-1))/ sizeof(unsigned long))
81
82#ifdef CONFIG_MTD_MAP_BANK_WIDTH_8
83# ifdef map_bankwidth
84# undef map_bankwidth
85# define map_bankwidth(map) ((map)->bankwidth)
86# if BITS_PER_LONG < 64
87# undef map_bankwidth_is_large
88# define map_bankwidth_is_large(map) (map_bankwidth(map) > BITS_PER_LONG/8)
89# undef map_words
90# define map_words(map) map_calc_words(map)
91# endif
92# else
93# define map_bankwidth(map) 8
94# define map_bankwidth_is_large(map) (BITS_PER_LONG < 64)
95# define map_words(map) map_calc_words(map)
96# endif
97#define map_bankwidth_is_8(map) (map_bankwidth(map) == 8)
98#undef MAX_MAP_BANKWIDTH
99#define MAX_MAP_BANKWIDTH 8
100#else
101#define map_bankwidth_is_8(map) (0)
102#endif
103
104#ifdef CONFIG_MTD_MAP_BANK_WIDTH_16
105# ifdef map_bankwidth
106# undef map_bankwidth
107# define map_bankwidth(map) ((map)->bankwidth)
108# undef map_bankwidth_is_large
109# define map_bankwidth_is_large(map) (map_bankwidth(map) > BITS_PER_LONG/8)
110# undef map_words
111# define map_words(map) map_calc_words(map)
112# else
113# define map_bankwidth(map) 16
114# define map_bankwidth_is_large(map) (1)
115# define map_words(map) map_calc_words(map)
116# endif
117#define map_bankwidth_is_16(map) (map_bankwidth(map) == 16)
118#undef MAX_MAP_BANKWIDTH
119#define MAX_MAP_BANKWIDTH 16
120#else
121#define map_bankwidth_is_16(map) (0)
122#endif
123
124#ifdef CONFIG_MTD_MAP_BANK_WIDTH_32
125# ifdef map_bankwidth
126# undef map_bankwidth
127# define map_bankwidth(map) ((map)->bankwidth)
128# undef map_bankwidth_is_large
129# define map_bankwidth_is_large(map) (map_bankwidth(map) > BITS_PER_LONG/8)
130# undef map_words
131# define map_words(map) map_calc_words(map)
132# else
133# define map_bankwidth(map) 32
134# define map_bankwidth_is_large(map) (1)
135# define map_words(map) map_calc_words(map)
136# endif
137#define map_bankwidth_is_32(map) (map_bankwidth(map) == 32)
138#undef MAX_MAP_BANKWIDTH
139#define MAX_MAP_BANKWIDTH 32
140#else
141#define map_bankwidth_is_32(map) (0)
142#endif
143
144#ifndef map_bankwidth
145#warning "No CONFIG_MTD_MAP_BANK_WIDTH_xx selected. No NOR chip support can work"
146static inline int map_bankwidth(void *map)
147{
148 BUG();
149 return 0;
150}
151#define map_bankwidth_is_large(map) (0)
152#define map_words(map) (0)
153#define MAX_MAP_BANKWIDTH 1
154#endif
155
156static inline int map_bankwidth_supported(int w)
157{
158 switch (w) {
159#ifdef CONFIG_MTD_MAP_BANK_WIDTH_1
160 case 1:
161#endif
162#ifdef CONFIG_MTD_MAP_BANK_WIDTH_2
163 case 2:
164#endif
165#ifdef CONFIG_MTD_MAP_BANK_WIDTH_4
166 case 4:
167#endif
168#ifdef CONFIG_MTD_MAP_BANK_WIDTH_8
169 case 8:
170#endif
171#ifdef CONFIG_MTD_MAP_BANK_WIDTH_16
172 case 16:
173#endif
174#ifdef CONFIG_MTD_MAP_BANK_WIDTH_32
175 case 32:
176#endif
177 return 1;
178
179 default:
180 return 0;
181 }
182}
183
184#define MAX_MAP_LONGS ( ((MAX_MAP_BANKWIDTH*8) + BITS_PER_LONG - 1) / BITS_PER_LONG )
185
186typedef union {
187 unsigned long x[MAX_MAP_LONGS];
188} map_word;
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208struct map_info {
209 const char *name;
210 unsigned long size;
211 resource_size_t phys;
212#define NO_XIP (-1UL)
213
214 void __iomem *virt;
215 void *cached;
216
217 int swap;
218 int bankwidth;
219
220
221
222
223#ifdef CONFIG_MTD_COMPLEX_MAPPINGS
224 map_word (*read)(struct map_info *, unsigned long);
225 void (*copy_from)(struct map_info *, void *, unsigned long, ssize_t);
226
227 void (*write)(struct map_info *, const map_word, unsigned long);
228 void (*copy_to)(struct map_info *, unsigned long, const void *, ssize_t);
229
230
231
232#endif
233
234
235
236
237
238
239 void (*inval_cache)(struct map_info *, unsigned long, ssize_t);
240
241
242
243 void (*set_vpp)(struct map_info *, int);
244
245 unsigned long pfow_base;
246 unsigned long map_priv_1;
247 unsigned long map_priv_2;
248 struct device_node *device_node;
249 void *fldrv_priv;
250 struct mtd_chip_driver *fldrv;
251};
252
253struct mtd_chip_driver {
254 struct mtd_info *(*probe)(struct map_info *map);
255 void (*destroy)(struct mtd_info *);
256 struct module *module;
257 char *name;
258 struct list_head list;
259};
260
261void register_mtd_chip_driver(struct mtd_chip_driver *);
262void unregister_mtd_chip_driver(struct mtd_chip_driver *);
263
264struct mtd_info *do_map_probe(const char *name, struct map_info *map);
265void map_destroy(struct mtd_info *mtd);
266
267#define ENABLE_VPP(map) do { if(map->set_vpp) map->set_vpp(map, 1); } while(0)
268#define DISABLE_VPP(map) do { if(map->set_vpp) map->set_vpp(map, 0); } while(0)
269
270#define INVALIDATE_CACHED_RANGE(map, from, size) \
271 do { if(map->inval_cache) map->inval_cache(map, from, size); } while(0)
272
273
274static inline int map_word_equal(struct map_info *map, map_word val1, map_word val2)
275{
276 int i;
277 for (i=0; i<map_words(map); i++) {
278 if (val1.x[i] != val2.x[i])
279 return 0;
280 }
281 return 1;
282}
283
284static inline map_word map_word_and(struct map_info *map, map_word val1, map_word val2)
285{
286 map_word r;
287 int i;
288
289 for (i=0; i<map_words(map); i++) {
290 r.x[i] = val1.x[i] & val2.x[i];
291 }
292 return r;
293}
294
295static inline map_word map_word_clr(struct map_info *map, map_word val1, map_word val2)
296{
297 map_word r;
298 int i;
299
300 for (i=0; i<map_words(map); i++) {
301 r.x[i] = val1.x[i] & ~val2.x[i];
302 }
303 return r;
304}
305
306static inline map_word map_word_or(struct map_info *map, map_word val1, map_word val2)
307{
308 map_word r;
309 int i;
310
311 for (i=0; i<map_words(map); i++) {
312 r.x[i] = val1.x[i] | val2.x[i];
313 }
314 return r;
315}
316
317#define map_word_andequal(m, a, b, z) map_word_equal(m, z, map_word_and(m, a, b))
318
319static inline int map_word_bitsset(struct map_info *map, map_word val1, map_word val2)
320{
321 int i;
322
323 for (i=0; i<map_words(map); i++) {
324 if (val1.x[i] & val2.x[i])
325 return 1;
326 }
327 return 0;
328}
329
330static inline map_word map_word_load(struct map_info *map, const void *ptr)
331{
332 map_word r;
333
334 if (map_bankwidth_is_1(map))
335 r.x[0] = *(unsigned char *)ptr;
336 else if (map_bankwidth_is_2(map))
337 r.x[0] = get_unaligned((uint16_t *)ptr);
338 else if (map_bankwidth_is_4(map))
339 r.x[0] = get_unaligned((uint32_t *)ptr);
340#if BITS_PER_LONG >= 64
341 else if (map_bankwidth_is_8(map))
342 r.x[0] = get_unaligned((uint64_t *)ptr);
343#endif
344 else if (map_bankwidth_is_large(map))
345 memcpy(r.x, ptr, map->bankwidth);
346 else
347 BUG();
348
349 return r;
350}
351
352static inline map_word map_word_load_partial(struct map_info *map, map_word orig, const unsigned char *buf, int start, int len)
353{
354 int i;
355
356 if (map_bankwidth_is_large(map)) {
357 char *dest = (char *)&orig;
358 memcpy(dest+start, buf, len);
359 } else {
360 for (i=start; i < start+len; i++) {
361 int bitpos;
362#ifdef __LITTLE_ENDIAN
363 bitpos = i*8;
364#else
365 bitpos = (map_bankwidth(map)-1-i)*8;
366#endif
367 orig.x[0] &= ~(0xff << bitpos);
368 orig.x[0] |= (unsigned long)buf[i-start] << bitpos;
369 }
370 }
371 return orig;
372}
373
374#if BITS_PER_LONG < 64
375#define MAP_FF_LIMIT 4
376#else
377#define MAP_FF_LIMIT 8
378#endif
379
380static inline map_word map_word_ff(struct map_info *map)
381{
382 map_word r;
383 int i;
384
385 if (map_bankwidth(map) < MAP_FF_LIMIT) {
386 int bw = 8 * map_bankwidth(map);
387 r.x[0] = (1UL << bw) - 1;
388 } else {
389 for (i=0; i<map_words(map); i++)
390 r.x[i] = ~0UL;
391 }
392 return r;
393}
394
395static inline map_word inline_map_read(struct map_info *map, unsigned long ofs)
396{
397 map_word r;
398
399 if (map_bankwidth_is_1(map))
400 r.x[0] = __raw_readb(map->virt + ofs);
401 else if (map_bankwidth_is_2(map))
402 r.x[0] = __raw_readw(map->virt + ofs);
403 else if (map_bankwidth_is_4(map))
404 r.x[0] = __raw_readl(map->virt + ofs);
405#if BITS_PER_LONG >= 64
406 else if (map_bankwidth_is_8(map))
407 r.x[0] = __raw_readq(map->virt + ofs);
408#endif
409 else if (map_bankwidth_is_large(map))
410 memcpy_fromio(r.x, map->virt+ofs, map->bankwidth);
411 else
412 BUG();
413
414 return r;
415}
416
417static inline void inline_map_write(struct map_info *map, const map_word datum, unsigned long ofs)
418{
419 if (map_bankwidth_is_1(map))
420 __raw_writeb(datum.x[0], map->virt + ofs);
421 else if (map_bankwidth_is_2(map))
422 __raw_writew(datum.x[0], map->virt + ofs);
423 else if (map_bankwidth_is_4(map))
424 __raw_writel(datum.x[0], map->virt + ofs);
425#if BITS_PER_LONG >= 64
426 else if (map_bankwidth_is_8(map))
427 __raw_writeq(datum.x[0], map->virt + ofs);
428#endif
429 else if (map_bankwidth_is_large(map))
430 memcpy_toio(map->virt+ofs, datum.x, map->bankwidth);
431 else
432 BUG();
433 mb();
434}
435
436static inline void inline_map_copy_from(struct map_info *map, void *to, unsigned long from, ssize_t len)
437{
438 if (map->cached)
439 memcpy(to, (char *)map->cached + from, len);
440 else
441 memcpy_fromio(to, map->virt + from, len);
442}
443
444static inline void inline_map_copy_to(struct map_info *map, unsigned long to, const void *from, ssize_t len)
445{
446 memcpy_toio(map->virt + to, from, len);
447}
448
449#ifdef CONFIG_MTD_COMPLEX_MAPPINGS
450#define map_read(map, ofs) (map)->read(map, ofs)
451#define map_copy_from(map, to, from, len) (map)->copy_from(map, to, from, len)
452#define map_write(map, datum, ofs) (map)->write(map, datum, ofs)
453#define map_copy_to(map, to, from, len) (map)->copy_to(map, to, from, len)
454
455extern void simple_map_init(struct map_info *);
456#define map_is_linear(map) (map->phys != NO_XIP)
457
458#else
459#define map_read(map, ofs) inline_map_read(map, ofs)
460#define map_copy_from(map, to, from, len) inline_map_copy_from(map, to, from, len)
461#define map_write(map, datum, ofs) inline_map_write(map, datum, ofs)
462#define map_copy_to(map, to, from, len) inline_map_copy_to(map, to, from, len)
463
464
465#define simple_map_init(map) BUG_ON(!map_bankwidth_supported((map)->bankwidth))
466#define map_is_linear(map) ({ (void)(map); 1; })
467
468#endif
469
470#endif
471