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#include <linux/io.h>
31
32#include <asm/unaligned.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#ifdef CONFIG_MTD
146#warning "No CONFIG_MTD_MAP_BANK_WIDTH_xx selected. No NOR chip support can work"
147#endif
148static inline int map_bankwidth(void *map)
149{
150 BUG();
151 return 0;
152}
153#define map_bankwidth_is_large(map) (0)
154#define map_words(map) (0)
155#define MAX_MAP_BANKWIDTH 1
156#endif
157
158static inline int map_bankwidth_supported(int w)
159{
160 switch (w) {
161#ifdef CONFIG_MTD_MAP_BANK_WIDTH_1
162 case 1:
163#endif
164#ifdef CONFIG_MTD_MAP_BANK_WIDTH_2
165 case 2:
166#endif
167#ifdef CONFIG_MTD_MAP_BANK_WIDTH_4
168 case 4:
169#endif
170#ifdef CONFIG_MTD_MAP_BANK_WIDTH_8
171 case 8:
172#endif
173#ifdef CONFIG_MTD_MAP_BANK_WIDTH_16
174 case 16:
175#endif
176#ifdef CONFIG_MTD_MAP_BANK_WIDTH_32
177 case 32:
178#endif
179 return 1;
180
181 default:
182 return 0;
183 }
184}
185
186#define MAX_MAP_LONGS (((MAX_MAP_BANKWIDTH * 8) + BITS_PER_LONG - 1) / BITS_PER_LONG)
187
188typedef union {
189 unsigned long x[MAX_MAP_LONGS];
190} map_word;
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210struct map_info {
211 const char *name;
212 unsigned long size;
213 resource_size_t phys;
214#define NO_XIP (-1UL)
215
216 void __iomem *virt;
217 void *cached;
218
219 int swap;
220 int bankwidth;
221
222
223
224
225#ifdef CONFIG_MTD_COMPLEX_MAPPINGS
226 map_word (*read)(struct map_info *, unsigned long);
227 void (*copy_from)(struct map_info *, void *, unsigned long, ssize_t);
228
229 void (*write)(struct map_info *, const map_word, unsigned long);
230 void (*copy_to)(struct map_info *, unsigned long, const void *, ssize_t);
231
232
233
234#endif
235
236
237
238
239
240
241 void (*inval_cache)(struct map_info *, unsigned long, ssize_t);
242
243
244
245
246
247
248 void (*set_vpp)(struct map_info *, int);
249
250 unsigned long pfow_base;
251 unsigned long map_priv_1;
252 unsigned long map_priv_2;
253 struct device_node *device_node;
254 void *fldrv_priv;
255 struct mtd_chip_driver *fldrv;
256};
257
258struct mtd_chip_driver {
259 struct mtd_info *(*probe)(struct map_info *map);
260 void (*destroy)(struct mtd_info *);
261 struct module *module;
262 char *name;
263 struct list_head list;
264};
265
266void register_mtd_chip_driver(struct mtd_chip_driver *);
267void unregister_mtd_chip_driver(struct mtd_chip_driver *);
268
269struct mtd_info *do_map_probe(const char *name, struct map_info *map);
270void map_destroy(struct mtd_info *mtd);
271
272#define ENABLE_VPP(map) do { if (map->set_vpp) map->set_vpp(map, 1); } while (0)
273#define DISABLE_VPP(map) do { if (map->set_vpp) map->set_vpp(map, 0); } while (0)
274
275#define INVALIDATE_CACHED_RANGE(map, from, size) \
276 do { if (map->inval_cache) map->inval_cache(map, from, size); } while (0)
277
278
279static inline int map_word_equal(struct map_info *map, map_word val1, map_word val2)
280{
281 int i;
282
283 for (i = 0; i < map_words(map); i++) {
284 if (val1.x[i] != val2.x[i])
285 return 0;
286 }
287
288 return 1;
289}
290
291static inline map_word map_word_and(struct map_info *map, map_word val1, map_word val2)
292{
293 map_word r;
294 int i;
295
296 for (i = 0; i < map_words(map); i++)
297 r.x[i] = val1.x[i] & val2.x[i];
298
299 return r;
300}
301
302static inline map_word map_word_clr(struct map_info *map, map_word val1, map_word val2)
303{
304 map_word r;
305 int i;
306
307 for (i = 0; i < map_words(map); i++)
308 r.x[i] = val1.x[i] & ~val2.x[i];
309
310 return r;
311}
312
313static inline map_word map_word_or(struct map_info *map, map_word val1, map_word val2)
314{
315 map_word r;
316 int i;
317
318 for (i = 0; i < map_words(map); i++)
319 r.x[i] = val1.x[i] | val2.x[i];
320
321 return r;
322}
323
324static inline int map_word_andequal(struct map_info *map, map_word val1, map_word val2, map_word val3)
325{
326 int i;
327
328 for (i = 0; i < map_words(map); i++) {
329 if ((val1.x[i] & val2.x[i]) != val3.x[i])
330 return 0;
331 }
332
333 return 1;
334}
335
336static inline int map_word_bitsset(struct map_info *map, map_word val1, map_word val2)
337{
338 int i;
339
340 for (i = 0; i < map_words(map); i++) {
341 if (val1.x[i] & val2.x[i])
342 return 1;
343 }
344
345 return 0;
346}
347
348static inline map_word map_word_load(struct map_info *map, const void *ptr)
349{
350 map_word r;
351
352 if (map_bankwidth_is_1(map))
353 r.x[0] = *(unsigned char *)ptr;
354 else if (map_bankwidth_is_2(map))
355 r.x[0] = get_unaligned((uint16_t *)ptr);
356 else if (map_bankwidth_is_4(map))
357 r.x[0] = get_unaligned((uint32_t *)ptr);
358#if BITS_PER_LONG >= 64
359 else if (map_bankwidth_is_8(map))
360 r.x[0] = get_unaligned((uint64_t *)ptr);
361#endif
362 else if (map_bankwidth_is_large(map))
363 memcpy(r.x, ptr, map->bankwidth);
364 else
365 BUG();
366
367 return r;
368}
369
370static inline map_word map_word_load_partial(struct map_info *map, map_word orig, const unsigned char *buf, int start, int len)
371{
372 int i;
373
374 if (map_bankwidth_is_large(map)) {
375 char *dest = (char *)&orig;
376
377 memcpy(dest+start, buf, len);
378 } else {
379 for (i = start; i < start+len; i++) {
380 int bitpos;
381
382#ifdef __LITTLE_ENDIAN
383 bitpos = i * 8;
384#else
385 bitpos = (map_bankwidth(map) - 1 - i) * 8;
386#endif
387 orig.x[0] &= ~(0xff << bitpos);
388 orig.x[0] |= (unsigned long)buf[i-start] << bitpos;
389 }
390 }
391 return orig;
392}
393
394#if BITS_PER_LONG < 64
395#define MAP_FF_LIMIT 4
396#else
397#define MAP_FF_LIMIT 8
398#endif
399
400static inline map_word map_word_ff(struct map_info *map)
401{
402 map_word r;
403 int i;
404
405 if (map_bankwidth(map) < MAP_FF_LIMIT) {
406 int bw = 8 * map_bankwidth(map);
407
408 r.x[0] = (1UL << bw) - 1;
409 } else {
410 for (i = 0; i < map_words(map); i++)
411 r.x[i] = ~0UL;
412 }
413 return r;
414}
415
416static inline map_word inline_map_read(struct map_info *map, unsigned long ofs)
417{
418 map_word r;
419
420 if (map_bankwidth_is_1(map))
421 r.x[0] = __raw_readb(map->virt + ofs);
422 else if (map_bankwidth_is_2(map))
423 r.x[0] = __raw_readw(map->virt + ofs);
424 else if (map_bankwidth_is_4(map))
425 r.x[0] = __raw_readl(map->virt + ofs);
426#if BITS_PER_LONG >= 64
427 else if (map_bankwidth_is_8(map))
428 r.x[0] = __raw_readq(map->virt + ofs);
429#endif
430 else if (map_bankwidth_is_large(map))
431 memcpy_fromio(r.x, map->virt + ofs, map->bankwidth);
432 else
433 BUG();
434
435 return r;
436}
437
438static inline void inline_map_write(struct map_info *map, const map_word datum, unsigned long ofs)
439{
440 if (map_bankwidth_is_1(map))
441 __raw_writeb(datum.x[0], map->virt + ofs);
442 else if (map_bankwidth_is_2(map))
443 __raw_writew(datum.x[0], map->virt + ofs);
444 else if (map_bankwidth_is_4(map))
445 __raw_writel(datum.x[0], map->virt + ofs);
446#if BITS_PER_LONG >= 64
447 else if (map_bankwidth_is_8(map))
448 __raw_writeq(datum.x[0], map->virt + ofs);
449#endif
450 else if (map_bankwidth_is_large(map))
451 memcpy_toio(map->virt+ofs, datum.x, map->bankwidth);
452 else
453 BUG();
454 mb();
455}
456
457static inline void inline_map_copy_from(struct map_info *map, void *to, unsigned long from, ssize_t len)
458{
459 if (map->cached)
460 memcpy(to, (char *)map->cached + from, len);
461 else
462 memcpy_fromio(to, map->virt + from, len);
463}
464
465static inline void inline_map_copy_to(struct map_info *map, unsigned long to, const void *from, ssize_t len)
466{
467 memcpy_toio(map->virt + to, from, len);
468}
469
470#ifdef CONFIG_MTD_COMPLEX_MAPPINGS
471#define map_read(map, ofs) (map)->read(map, ofs)
472#define map_copy_from(map, to, from, len) (map)->copy_from(map, to, from, len)
473#define map_write(map, datum, ofs) (map)->write(map, datum, ofs)
474#define map_copy_to(map, to, from, len) (map)->copy_to(map, to, from, len)
475
476extern void simple_map_init(struct map_info *);
477#define map_is_linear(map) (map->phys != NO_XIP)
478
479#else
480#define map_read(map, ofs) inline_map_read(map, ofs)
481#define map_copy_from(map, to, from, len) inline_map_copy_from(map, to, from, len)
482#define map_write(map, datum, ofs) inline_map_write(map, datum, ofs)
483#define map_copy_to(map, to, from, len) inline_map_copy_to(map, to, from, len)
484
485
486#define simple_map_init(map) BUG_ON(!map_bankwidth_supported((map)->bankwidth))
487#define map_is_linear(map) ({ (void)(map); 1; })
488
489#endif
490
491#endif
492