1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26#include <common.h>
27#include <asm/processor.h>
28#include <asm/immap_85xx.h>
29#include <asm/processor.h>
30#include <asm/mmu.h>
31#include <asm/io.h>
32#include <asm/errno.h>
33#include <linux/mtd/mtd.h>
34#include <linux/mtd/fsl_upm.h>
35#include <ioports.h>
36
37#include <nand.h>
38
39DECLARE_GLOBAL_DATA_PTR;
40
41extern uint get_lbc_clock (void);
42
43
44#define CONFIG_SYS_NAN_UPM_WRITE_CMD_OFS 0x08
45
46
47#define CONFIG_SYS_NAND_UPM_WRITE_ADDR_OFS 0x10
48
49
50struct upm_freq {
51 ulong freq;
52 const u32 *upm_patt;
53 uchar gpl4_disable;
54 uchar ehtr;
55 uchar ead;
56};
57
58
59
60
61static const u32 upm_patt_25[] = {
62
63 0x0ff32000, 0x0fa32000, 0x3fb32005, 0xfffffc00,
64 0xfffffc00, 0xfffffc00, 0xfffffc00, 0xfffffc00,
65
66
67 0x00ff2c30, 0x00ff2c30, 0x0fff2c35, 0xfffffc00,
68 0xfffffc00, 0xfffffc00, 0xfffffc00, 0xfffffc00,
69
70
71 0x00f3ec30, 0x00f3ec30, 0x0ff3ec35, 0xfffffc00,
72 0xfffffc00, 0xfffffc00, 0xfffffc00, 0xfffffc00,
73
74
75 0x00f32c00, 0x00f32c00, 0x0ff32c05, 0xfffffc00,
76 0xfffffc00, 0xfffffc00, 0xfffffc00, 0xfffffc00,
77
78
79 0xfffffc00, 0xfffffc00, 0xfffffc00, 0xfffffc00,
80 0xfffffc00, 0xfffffc00, 0xfffffc00, 0xfffffc00,
81 0xfffffc00, 0xfffffc00, 0xfffffc00, 0xfffffc00,
82 0xfffffc00, 0xfffffc00, 0xfffffc00, 0xfffffc01,
83
84
85 0xfffffc00, 0xfffffc00, 0xfffffc00, 0xfffffc00,
86 0xfffffc00, 0xfffffc00, 0xfffffc00, 0xfffffc00,
87 0xfffffc00, 0xfffffc00, 0xfffffc00, 0xfffffc01,
88
89
90 0xfffffc00, 0xfffffc00, 0xfffffc00, 0xfffffc01,
91};
92
93
94static const u32 upm_patt_33[] = {
95
96 0x0ff32000, 0x0fa32100, 0x3fb32005, 0xfffffc00,
97 0xfffffc00, 0xfffffc00, 0xfffffc00, 0xfffffc00,
98
99
100 0x00ff2c30, 0x00ff2c30, 0x0fff2c35, 0xfffffc00,
101 0xfffffc00, 0xfffffc00, 0xfffffc00, 0xfffffc00,
102
103
104 0x00f3ec30, 0x00f3ec30, 0x0ff3ec35, 0xfffffc00,
105 0xfffffc00, 0xfffffc00, 0xfffffc00, 0xfffffc00,
106
107
108 0x00f32c00, 0x00f32c00, 0x0ff32c05, 0xfffffc00,
109 0xfffffc00, 0xfffffc00, 0xfffffc00, 0xfffffc00,
110
111
112 0xfffffc00, 0xfffffc00, 0xfffffc00, 0xfffffc00,
113 0xfffffc00, 0xfffffc00, 0xfffffc00, 0xfffffc00,
114 0xfffffc00, 0xfffffc00, 0xfffffc00, 0xfffffc00,
115 0xfffffc00, 0xfffffc00, 0xfffffc00, 0xfffffc01,
116
117
118 0xfffffc00, 0xfffffc00, 0xfffffc00, 0xfffffc00,
119 0xfffffc00, 0xfffffc00, 0xfffffc00, 0xfffffc00,
120 0xfffffc00, 0xfffffc00, 0xfffffc00, 0xfffffc01,
121
122
123 0xfffffc00, 0xfffffc00, 0xfffffc00, 0xfffffc01,
124};
125
126
127static const u32 upm_patt_42[] = {
128
129 0x0ff32000, 0x0fa32100, 0x3fb32005, 0xfffffc00,
130 0xfffffc00, 0xfffffc00, 0xfffffc00, 0xfffffc00,
131
132
133 0x00ff2c30, 0x00ff2c30, 0x0fff2c35, 0xfffffc00,
134 0xfffffc00, 0xfffffc00, 0xfffffc00, 0xfffffc00,
135
136
137 0x00f3ec30, 0x00f3ec30, 0x0ff3ec35, 0xfffffc00,
138 0xfffffc00, 0xfffffc00, 0xfffffc00, 0xfffffc00,
139
140
141 0x00f32c00, 0x00f32c00, 0x0ff32c05, 0xfffffc00,
142 0xfffffc00, 0xfffffc00, 0xfffffc00, 0xfffffc00,
143
144
145 0xfffffc00, 0xfffffc00, 0xfffffc00, 0xfffffc00,
146 0xfffffc00, 0xfffffc00, 0xfffffc00, 0xfffffc00,
147 0xfffffc00, 0xfffffc00, 0xfffffc00, 0xfffffc00,
148 0xfffffc00, 0xfffffc00, 0xfffffc00, 0xfffffc01,
149
150
151 0xfffffc00, 0xfffffc00, 0xfffffc00, 0xfffffc00,
152 0xfffffc00, 0xfffffc00, 0xfffffc00, 0xfffffc00,
153 0xfffffc00, 0xfffffc00, 0xfffffc00, 0xfffffc01,
154
155
156 0xfffffc00, 0xfffffc00, 0xfffffc00, 0xfffffc01,
157};
158
159
160static const u32 upm_patt_50[] = {
161
162 0x0ff33000, 0x0fa33100, 0x0fa33005, 0xfffffc00,
163 0xfffffc00, 0xfffffc00, 0xfffffc00, 0xfffffc00,
164
165
166 0x00ff3d30, 0x00ff3c30, 0x0fff3c35, 0xfffffc00,
167 0xfffffc00, 0xfffffc00, 0xfffffc00, 0xfffffc00,
168
169
170 0x00f3fd30, 0x00f3fc30, 0x0ff3fc35, 0xfffffc00,
171 0xfffffc00, 0xfffffc00, 0xfffffc00, 0xfffffc00,
172
173
174 0x00f33d00, 0x00f33c00, 0x0ff33c05, 0xfffffc00,
175 0xfffffc00, 0xfffffc00, 0xfffffc00, 0xfffffc00,
176
177
178 0xfffffc00, 0xfffffc00, 0xfffffc00, 0xfffffc00,
179 0xfffffc00, 0xfffffc00, 0xfffffc00, 0xfffffc00,
180 0xfffffc00, 0xfffffc00, 0xfffffc00, 0xfffffc00,
181 0xfffffc00, 0xfffffc00, 0xfffffc00, 0xfffffc01,
182
183
184 0xfffffc00, 0xfffffc00, 0xfffffc00, 0xfffffc00,
185 0xfffffc00, 0xfffffc00, 0xfffffc00, 0xfffffc00,
186 0xfffffc00, 0xfffffc00, 0xfffffc00, 0xfffffc01,
187
188
189 0xfffffc00, 0xfffffc00, 0xfffffc00, 0xfffffc01,
190};
191
192
193static const u32 upm_patt_67[] = {
194
195 0x0ff33000, 0x0fe33000, 0x0fa33100, 0x0fa33000,
196 0x0fa33005, 0xfffffc00, 0xfffffc00, 0xfffffc00,
197
198
199 0x00ff3d30, 0x00ff3c30, 0x0fff3c30, 0x0fff3c35,
200 0xfffffc00, 0xfffffc00, 0xfffffc00, 0xfffffc00,
201
202
203 0x00f3fd30, 0x00f3fc30, 0x0ff3fc30, 0x0ff3fc35,
204 0xfffffc00, 0xfffffc00, 0xfffffc00, 0xfffffc00,
205
206
207 0x00f33d00, 0x00f33c00, 0x0ff33c00, 0x0ff33c05,
208 0xfffffc00, 0xfffffc00, 0xfffffc00, 0xfffffc00,
209
210
211 0xfffffc00, 0xfffffc00, 0xfffffc00, 0xfffffc00,
212 0xfffffc00, 0xfffffc00, 0xfffffc00, 0xfffffc00,
213 0xfffffc00, 0xfffffc00, 0xfffffc00, 0xfffffc00,
214 0xfffffc00, 0xfffffc00, 0xfffffc00, 0xfffffc01,
215
216
217 0xfffffc00, 0xfffffc00, 0xfffffc00, 0xfffffc00,
218 0xfffffc00, 0xfffffc00, 0xfffffc00, 0xfffffc00,
219 0xfffffc00, 0xfffffc00, 0xfffffc00, 0xfffffc01,
220
221
222 0xfffffc00, 0xfffffc00, 0xfffffc00, 0xfffffc01,
223};
224
225
226static const u32 upm_patt_83[] = {
227
228 0x0ff33000, 0x0fe33000, 0x0fa33100, 0x0fa33000,
229 0x0fa33005, 0xfffffc00, 0xfffffc00, 0xfffffc00,
230
231
232 0x00ff3e30, 0x00ff3c30, 0x0fff3c30, 0x0fff3c35,
233 0xfffffc00, 0xfffffc00, 0xfffffc00, 0xfffffc00,
234
235
236 0x00f3fe30, 0x00f3fc30, 0x0ff3fc30, 0x0ff3fc35,
237 0xfffffc00, 0xfffffc00, 0xfffffc00, 0xfffffc00,
238
239
240 0x00f33e00, 0x00f33c00, 0x0ff33c00, 0x0ff33c05,
241 0xfffffc00, 0xfffffc00, 0xfffffc00, 0xfffffc00,
242
243
244 0xfffffc00, 0xfffffc00, 0xfffffc00, 0xfffffc00,
245 0xfffffc00, 0xfffffc00, 0xfffffc00, 0xfffffc00,
246 0xfffffc00, 0xfffffc00, 0xfffffc00, 0xfffffc00,
247 0xfffffc00, 0xfffffc00, 0xfffffc00, 0xfffffc01,
248
249
250 0xfffffc00, 0xfffffc00, 0xfffffc00, 0xfffffc00,
251 0xfffffc00, 0xfffffc00, 0xfffffc00, 0xfffffc00,
252 0xfffffc00, 0xfffffc00, 0xfffffc00, 0xfffffc01,
253
254
255 0xfffffc00, 0xfffffc00, 0xfffffc00, 0xfffffc01,
256};
257
258
259static const u32 upm_patt_100[] = {
260
261 0x0ff33100, 0x0fe33000, 0x0fa33200, 0x0fa33000,
262 0x0fa33005, 0xfffffc00, 0xfffffc00, 0xfffffc00,
263
264
265 0x00ff3f30, 0x00ff3c30, 0x0fff3c30, 0x0fff3c35,
266 0xfffffc00, 0xfffffc00, 0xfffffc00, 0xfffffc00,
267
268
269 0x00f3ff30, 0x00f3fc30, 0x0ff3fc30, 0x0ff3fc35,
270 0xfffffc00, 0xfffffc00, 0xfffffc00, 0xfffffc00,
271
272
273 0x00f33f00, 0x00f33c00, 0x0ff33c00, 0x0ff33c05,
274 0xfffffc00, 0xfffffc00, 0xfffffc00, 0xfffffc00,
275
276
277 0xfffffc00, 0xfffffc00, 0xfffffc00, 0xfffffc00,
278 0xfffffc00, 0xfffffc00, 0xfffffc00, 0xfffffc00,
279 0xfffffc00, 0xfffffc00, 0xfffffc00, 0xfffffc00,
280 0xfffffc00, 0xfffffc00, 0xfffffc00, 0xfffffc01,
281
282
283 0xfffffc00, 0xfffffc00, 0xfffffc00, 0xfffffc00,
284 0xfffffc00, 0xfffffc00, 0xfffffc00, 0xfffffc00,
285 0xfffffc00, 0xfffffc00, 0xfffffc00, 0xfffffc01,
286
287
288 0xfffffc00, 0xfffffc00, 0xfffffc00, 0xfffffc01,
289};
290
291
292static const u32 upm_patt_133[] = {
293
294 0x0ff33100, 0x0fe33000, 0x0fa33300, 0x0fa33000,
295 0x0fa33000, 0x0fa33005, 0xfffffc00, 0xfffffc00,
296
297
298 0x00ff3f30, 0x00ff3d30, 0x0fff3d30, 0x0fff3c35,
299 0xfffffc00, 0xfffffc00, 0xfffffc00, 0xfffffc00,
300
301
302 0x00f3ff30, 0x00f3fd30, 0x0ff3fd30, 0x0ff3fc35,
303 0xfffffc00, 0xfffffc00, 0xfffffc00, 0xfffffc00,
304
305
306 0x00f33f00, 0x00f33d00, 0x0ff33d00, 0x0ff33c05,
307 0xfffffc00, 0xfffffc00, 0xfffffc00, 0xfffffc00,
308
309
310 0xfffffc00, 0xfffffc00, 0xfffffc00, 0xfffffc00,
311 0xfffffc00, 0xfffffc00, 0xfffffc00, 0xfffffc00,
312 0xfffffc00, 0xfffffc00, 0xfffffc00, 0xfffffc00,
313 0xfffffc00, 0xfffffc00, 0xfffffc00, 0xfffffc01,
314
315
316 0xfffffc00, 0xfffffc00, 0xfffffc00, 0xfffffc00,
317 0xfffffc00, 0xfffffc00, 0xfffffc00, 0xfffffc00,
318 0xfffffc00, 0xfffffc00, 0xfffffc00, 0xfffffc01,
319
320
321 0xfffffc00, 0xfffffc00, 0xfffffc00, 0xfffffc01,
322};
323
324
325static const u32 upm_patt_167[] = {
326
327 0x0ff33200, 0x0fe33000, 0x0fa33300, 0x0fa33300,
328 0x0fa33005, 0xfffffc00, 0xfffffc00, 0xfffffc00,
329
330
331 0x00ff3f30, 0x00ff3f30, 0x0fff3e30, 0xffff3c35,
332 0xfffffc00, 0xfffffc00, 0xfffffc00, 0xfffffc00,
333
334
335 0x00f3ff30, 0x00f3ff30, 0x0ff3fe30, 0x0ff3fc35,
336 0xfffffc00, 0xfffffc00, 0xfffffc00, 0xfffffc00,
337
338
339 0x00f33f00, 0x00f33f00, 0x0ff33e00, 0x0ff33c05,
340 0xfffffc00, 0xfffffc00, 0xfffffc00, 0xfffffc00,
341
342
343 0xfffffc00, 0xfffffc00, 0xfffffc00, 0xfffffc00,
344 0xfffffc00, 0xfffffc00, 0xfffffc00, 0xfffffc00,
345 0xfffffc00, 0xfffffc00, 0xfffffc00, 0xfffffc00,
346 0xfffffc00, 0xfffffc00, 0xfffffc00, 0xfffffc01,
347
348
349 0xfffffc00, 0xfffffc00, 0xfffffc00, 0xfffffc00,
350 0xfffffc00, 0xfffffc00, 0xfffffc00, 0xfffffc00,
351 0xfffffc00, 0xfffffc00, 0xfffffc00, 0xfffffc01,
352
353
354 0xfffffc00, 0xfffffc00, 0xfffffc00, 0xfffffc01,
355};
356
357
358struct upm_freq upm_freq_table[] = {
359
360 {25000000, upm_patt_25, 1, 0, 0},
361 {33333333, upm_patt_33, 1, 0, 0},
362 {41666666, upm_patt_42, 1, 0, 0},
363 {50000000, upm_patt_50, 0, 0, 0},
364 {66666666, upm_patt_67, 0, 0, 0},
365 {83333333, upm_patt_83, 0, 0, 0},
366 {100000000, upm_patt_100, 0, 1, 1},
367 {133333333, upm_patt_133, 0, 1, 1},
368 {166666666, upm_patt_167, 0, 1, 1},
369};
370
371#define UPM_FREQS (sizeof(upm_freq_table) / sizeof(struct upm_freq))
372
373volatile const u32 *nand_upm_patt;
374
375
376
377
378static void upmb_write (u_char addr, ulong val)
379{
380 volatile ccsr_lbc_t *lbc = (void *)(CONFIG_SYS_MPC85xx_LBC_ADDR);
381
382 out_be32 (&lbc->mdr, val);
383
384 clrsetbits_be32(&lbc->mbmr, MxMR_MAD_MSK,
385 MxMR_OP_WARR | (addr & MxMR_MAD_MSK));
386
387
388 out_8 ((void __iomem *)CONFIG_SYS_NAND_BASE, 0);
389
390 clrbits_be32(&lbc->mbmr, MxMR_OP_WARR);
391}
392
393
394
395
396static void nand_upm_setup (volatile ccsr_lbc_t *lbc)
397{
398 uint i, j;
399 uint or3 = CONFIG_SYS_OR3_PRELIM;
400 uint clock = get_lbc_clock ();
401
402 out_be32 (&lbc->br3, 0);
403 out_be32 (&lbc->br3, CONFIG_SYS_BR3_PRELIM);
404
405
406
407
408
409
410
411 for (i = 0; (i < UPM_FREQS) && (clock > upm_freq_table[i].freq); i++)
412 ;
413
414 if (i >= UPM_FREQS)
415
416
417 i--;
418
419 if (upm_freq_table[i].ehtr) {
420
421 or3 |= OR_UPM_EHTR;
422 }
423 if (upm_freq_table[i].ead)
424
425 or3 |= OR_UPM_EAD;
426
427 out_be32 (&lbc->or3, or3);
428
429
430 nand_upm_patt = upm_freq_table[i].upm_patt;
431
432 for (j = 0; j < 64; j++) {
433 upmb_write (j, *nand_upm_patt);
434 nand_upm_patt++;
435 }
436
437
438 if (upm_freq_table[i].gpl4_disable)
439
440 out_be32 (&lbc->mbmr, MxMR_OP_NORM | MxMR_GPL_x4DIS);
441
442 return;
443}
444
445static struct fsl_upm_nand fun = {
446 .width = 8,
447 .upm_cmd_offset = 0x08,
448 .upm_addr_offset = 0x10,
449 .upm_mar_chip_offset = CONFIG_SYS_NAND_CS_DIST,
450 .chip_offset = CONFIG_SYS_NAND_CS_DIST,
451 .chip_delay = NAND_BIG_DELAY_US,
452 .wait_flags = FSL_UPM_WAIT_RUN_PATTERN | FSL_UPM_WAIT_WRITE_BUFFER,
453};
454
455void board_nand_select_device (struct nand_chip *nand, int chip)
456{
457}
458
459int board_nand_init (struct nand_chip *nand)
460{
461 volatile ccsr_lbc_t *lbc = (void *)(CONFIG_SYS_MPC85xx_LBC_ADDR);
462
463 if (!nand_upm_patt)
464 nand_upm_setup (lbc);
465
466 fun.upm.io_addr = nand->IO_ADDR_R;
467 fun.upm.mxmr = (void __iomem *)&lbc->mbmr;
468 fun.upm.mdr = (void __iomem *)&lbc->mdr;
469 fun.upm.mar = (void __iomem *)&lbc->mar;
470
471 return fsl_upm_nand_init (nand, &fun);
472}
473