]> git.sur5r.net Git - u-boot/blob - board/svm_sc8xx/flash.c
powerpc/83xx/km: make local functions and structs static
[u-boot] / board / svm_sc8xx / flash.c
1 /*
2  * Wolfgang Denk, DENX Software Engineering, wd@denx.de.
3  *
4  * See file CREDITS for list of people who contributed to this
5  * project.
6  *
7  * This program is free software; you can redistribute it and/or
8  * modify it under the terms of the GNU General Public License as
9  * published by the Free Software Foundation; either version 2 of
10  * the License, or (at your option) any later version.
11  *
12  * This program is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15  * GNU General Public License for more details.
16  *
17  * You should have received a copy of the GNU General Public License
18  * along with this program; if not, write to the Free Software
19  * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
20  * MA 02111-1307 USA
21  */
22
23 #include <common.h>
24 #include <mpc8xx.h>
25
26 #ifndef CONFIG_ENV_ADDR
27 #define CONFIG_ENV_ADDR (CONFIG_SYS_FLASH_BASE + CONFIG_ENV_OFFSET)
28 #endif
29
30 flash_info_t flash_info[CONFIG_SYS_MAX_FLASH_BANKS];
31
32 /*-----------------------------------------------------------------------
33  * Functions
34  */
35 static int write_word(flash_info_t *info, ulong dest, ulong data);
36
37 #ifdef CONFIG_BOOT_8B
38 static int my_in_8(unsigned char *addr);
39 static void my_out_8(unsigned char *addr, int val);
40 #endif
41 #ifdef CONFIG_BOOT_16B
42 static int my_in_be16(unsigned short *addr);
43 static void my_out_be16(unsigned short *addr, int val);
44 #endif
45 #ifdef CONFIG_BOOT_32B
46 static unsigned my_in_be32(unsigned *addr);
47 static void my_out_be32(unsigned *addr, int val);
48 #endif
49 /*-----------------------------------------------------------------------
50  */
51
52 unsigned long flash_init(void)
53 {
54         volatile immap_t *immap = (immap_t *) CONFIG_SYS_IMMR;
55         volatile memctl8xx_t *memctl = &immap->im_memctl;
56         unsigned long size_b0, size_b1;
57         int i;
58
59         size_b0 = 0;
60         size_b1 = 0;
61         /* Init: no FLASHes known */
62         for (i = 0; i < CONFIG_SYS_MAX_FLASH_BANKS; ++i)
63                 flash_info[i].flash_id = FLASH_UNKNOWN;
64
65 #ifdef CONFIG_SYS_DOC_BASE
66 #ifndef CONFIG_FEL8xx_AT
67         /* 32k bytes */
68         memctl->memc_or5 = (0xffff8000 | CONFIG_SYS_OR_TIMING_DOC);
69         memctl->memc_br5 = CONFIG_SYS_DOC_BASE | 0x401;
70 #else
71         /* 32k bytes */
72         memctl->memc_or3 = (0xffff8000 | CONFIG_SYS_OR_TIMING_DOC);
73         memctl->memc_br3 = CONFIG_SYS_DOC_BASE | 0x401;
74 #endif
75 #endif
76 #if defined(CONFIG_BOOT_8B)
77         size_b0 = 0x80000;      /* 512 K */
78
79         flash_info[0].flash_id = FLASH_MAN_AMD | FLASH_AM040;
80         flash_info[0].sector_count = 8;
81         flash_info[0].size = 0x00080000;
82
83         /* set up sector start address table */
84         for (i = 0; i < flash_info[0].sector_count; i++)
85                 flash_info[0].start[i] = 0x40000000 + (i * 0x10000);
86
87         /* protect all sectors */
88         for (i = 0; i < flash_info[0].sector_count; i++)
89                 flash_info[0].protect[i] = 0x1;
90
91 #elif defined(CONFIG_BOOT_16B)
92         size_b0 = 0x400000;     /* 4MB , assume AMD29LV320B */
93
94         flash_info[0].flash_id = FLASH_MAN_AMD | FLASH_AM320B;
95         flash_info[0].sector_count = 67;
96         flash_info[0].size = 0x00400000;
97
98         /* set up sector start address table */
99         flash_info[0].start[0] = 0x40000000;
100         flash_info[0].start[1] = 0x40000000 + 0x4000;
101         flash_info[0].start[2] = 0x40000000 + 0x6000;
102         flash_info[0].start[3] = 0x40000000 + 0x8000;
103
104         for (i = 4; i < flash_info[0].sector_count; i++) {
105                 flash_info[0].start[i] =
106                         0x40000000 + 0x10000 + ((i - 4) * 0x10000);
107         }
108
109         /* protect all sectors */
110         for (i = 0; i < flash_info[0].sector_count; i++)
111                 flash_info[0].protect[i] = 0x1;
112 #endif
113
114 #ifdef CONFIG_BOOT_32B
115
116         /* Static FLASH Bank configuration here - FIXME XXX */
117         size_b0 = flash_get_size((vu_long *) FLASH_BASE0_PRELIM,
118                                &flash_info[0]);
119
120         if (flash_info[0].flash_id == FLASH_UNKNOWN) {
121                 printf("## Unknown FLASH on Bank 0 - Size = 0x%08lx = %ld MB\n",
122                         size_b0, size_b0 << 20);
123         }
124
125         size_b1 = flash_get_size((vu_long *) FLASH_BASE1_PRELIM,
126                                &flash_info[1]);
127
128         if (size_b1 > size_b0) {
129                 printf("## ERROR: "
130                         "Bank 1 (0x%08lx = %ld MB) > Bank 0 (0x%08lx = %ld MB)\n",
131                         size_b1, size_b1 << 20, size_b0, size_b0 << 20);
132                 flash_info[0].flash_id = FLASH_UNKNOWN;
133                 flash_info[1].flash_id = FLASH_UNKNOWN;
134                 flash_info[0].sector_count = -1;
135                 flash_info[1].sector_count = -1;
136                 flash_info[0].size = 0;
137                 flash_info[1].size = 0;
138
139                 return 0;
140         }
141
142         /* Remap FLASH according to real size */
143         memctl->memc_or0 = CONFIG_SYS_OR_TIMING_FLASH |
144                                 (-size_b0 & OR_AM_MSK);
145         memctl->memc_br0 = (CONFIG_SYS_FLASH_BASE & BR_BA_MSK) |
146                                 BR_MS_GPCM | BR_V;
147
148         /* Re-do sizing to get full correct info */
149         size_b0 = flash_get_size((vu_long *) CONFIG_SYS_FLASH_BASE,
150                                 &flash_info[0]);
151
152         flash_get_offsets(CONFIG_SYS_FLASH_BASE, &flash_info[0]);
153
154 #if CONFIG_SYS_MONITOR_BASE >= CONFIG_SYS_FLASH_BASE
155         /* monitor protection ON by default */
156         flash_protect(FLAG_PROTECT_SET,
157                 CONFIG_SYS_MONITOR_BASE,
158                 CONFIG_SYS_MONITOR_BASE + monitor_flash_len - 1,
159                 &flash_info[0]);
160 #endif
161
162 #ifdef  CONFIG_ENV_IS_IN_FLASH
163         /* ENV protection ON by default */
164         flash_protect(FLAG_PROTECT_SET,
165                 CONFIG_ENV_ADDR,
166                 CONFIG_ENV_ADDR + CONFIG_ENV_SIZE - 1, &flash_info[0]);
167 #endif
168
169         if (size_b1) {
170                 memctl->memc_or1 = CONFIG_SYS_OR_TIMING_FLASH |
171                         (-size_b1 & 0xFFFF8000);
172                 memctl->memc_br1 = ((CONFIG_SYS_FLASH_BASE +
173                         size_b0) & BR_BA_MSK) | BR_MS_GPCM | BR_V;
174
175                 /* Re-do sizing to get full correct info */
176                 size_b1 = flash_get_size((vu_long *)(CONFIG_SYS_FLASH_BASE +
177                                         size_b0), &flash_info[1]);
178
179                 flash_get_offsets(CONFIG_SYS_FLASH_BASE + size_b0,
180                                   &flash_info[1]);
181
182 #if CONFIG_SYS_MONITOR_BASE >= CONFIG_SYS_FLASH_BASE
183                 /* monitor protection ON by default */
184                 flash_protect(FLAG_PROTECT_SET,
185                               CONFIG_SYS_MONITOR_BASE,
186                               CONFIG_SYS_MONITOR_BASE + monitor_flash_len - 1,
187                               &flash_info[1]);
188 #endif
189
190 #ifdef  CONFIG_ENV_IS_IN_FLASH
191                 /* ENV protection ON by default */
192                 flash_protect(FLAG_PROTECT_SET,
193                               CONFIG_ENV_ADDR,
194                               CONFIG_ENV_ADDR + CONFIG_ENV_SIZE - 1,
195                               &flash_info[1]);
196 #endif
197         } else {
198                 memctl->memc_br1 = 0;   /* invalidate bank */
199
200                 flash_info[1].flash_id = FLASH_UNKNOWN;
201                 flash_info[1].sector_count = -1;
202         }
203
204         flash_info[0].size = size_b0;
205         flash_info[1].size = size_b1;
206
207
208 #endif /* CONFIG_BOOT_32B */
209
210         return size_b0 + size_b1;
211 }
212
213
214 void flash_print_info(flash_info_t *info)
215 {
216         int i;
217
218         if (info->flash_id == FLASH_UNKNOWN) {
219                 printf("missing or unknown FLASH type\n");
220                 return;
221         }
222
223         switch (info->flash_id & FLASH_VENDMASK) {
224         case FLASH_MAN_AMD:
225                 printf("AMD ");
226                 break;
227         case FLASH_MAN_FUJ:
228                 printf("FUJITSU ");
229                 break;
230         default:
231                 printf("Unknown Vendor ");
232                 break;
233         }
234
235         switch (info->flash_id & FLASH_TYPEMASK) {
236         case FLASH_AM400B:
237                 printf("AM29LV400B (4 Mbit, bottom boot sect)\n");
238                 break;
239         case FLASH_AM400T:
240                 printf("AM29LV400T (4 Mbit, top boot sector)\n");
241                 break;
242         case FLASH_AM800B:
243                 printf("AM29LV800B (8 Mbit, bottom boot sect)\n");
244                 break;
245         case FLASH_AM800T:
246                 printf("AM29LV800T (8 Mbit, top boot sector)\n");
247                 break;
248         case FLASH_AM160B:
249                 printf("AM29LV160B (16 Mbit, bottom boot sect)\n");
250                 break;
251         case FLASH_AM160T:
252                 printf("AM29LV160T (16 Mbit, top boot sector)\n");
253                 break;
254         case FLASH_AM320B:
255                 printf("AM29LV320B (32 Mbit, bottom boot sect)\n");
256                 break;
257         case FLASH_AM320T:
258                 printf("AM29LV320T (32 Mbit, top boot sector)\n");
259                 break;
260         default:
261                 printf("Unknown Chip Type\n");
262                 break;
263         }
264
265         printf("  Size: %ld MB in %d Sectors\n",
266                 info->size >> 20, info->sector_count);
267
268         printf("  Sector Start Addresses:");
269         for (i = 0; i < info->sector_count; ++i) {
270                 if ((i % 5) == 0)
271                         printf("\n   ");
272                 printf(" %08lX%s",
273                        info->start[i], info->protect[i] ? " (RO)" : "     ");
274         }
275         printf("\n");
276         return;
277 }
278
279 /*
280  * The following code cannot be run from FLASH!
281  */
282
283 int flash_erase(flash_info_t *info, int s_first, int s_last)
284 {
285         vu_long *addr = (vu_long *) (info->start[0]);
286         int flag, prot, sect, l_sect, in_mid, in_did;
287         ulong start, now, last;
288
289         if ((s_first < 0) || (s_first > s_last)) {
290                 if (info->flash_id == FLASH_UNKNOWN)
291                         printf("- missing\n");
292                 else
293                         printf("- no sectors to erase\n");
294
295                 return 1;
296         }
297
298         if ((info->flash_id == FLASH_UNKNOWN) ||
299             (info->flash_id > FLASH_AMD_COMP)) {
300                 printf("Can't erase unknown flash type %08lx - aborted\n",
301                        info->flash_id);
302                 return 1;
303         }
304
305         prot = 0;
306         for (sect = s_first; sect <= s_last; ++sect) {
307                 if (info->protect[sect])
308                         prot++;
309         }
310
311         if (prot) {
312                 printf("- Warning: %d protected sectors will not be erased!\n",
313                         prot);
314         } else {
315                 printf("\n");
316         }
317
318         l_sect = -1;
319
320         /* Disable interrupts which might cause a timeout here */
321         flag = disable_interrupts();
322
323 #if defined(CONFIG_BOOT_8B)
324         my_out_8((unsigned char *)((ulong)addr + 0x555), 0xaa);
325         my_out_8((unsigned char *)((ulong)addr + 0x2aa), 0x55);
326         my_out_8((unsigned char *)((ulong)addr + 0x555), 0x90);
327
328         in_mid = my_in_8((unsigned char *)addr);
329         in_did = my_in_8((unsigned char *)((ulong)addr + 1));
330
331         printf(" man ID=0x%x, dev ID=0x%x.\n", in_mid, in_did);
332
333         my_out_8((unsigned char *)addr, 0xf0);
334         udelay(1);
335
336         my_out_8((unsigned char *)((ulong)addr + 0x555), 0xaa);
337         my_out_8((unsigned char *)((ulong)addr + 0x2aa), 0x55);
338         my_out_8((unsigned char *)((ulong)addr + 0x555), 0x80);
339         my_out_8((unsigned char *)((ulong)addr + 0x555), 0xaa);
340         my_out_8((unsigned char *)((ulong)addr + 0x2aa), 0x55);
341
342         /* Start erase on unprotected sectors */
343         for (sect = s_first; sect <= s_last; sect++) {
344                 if (info->protect[sect] == 0) { /* not protected */
345                         addr = (vu_long *) (info->start[sect]);
346                         /*addr[0] = 0x00300030; */
347                         my_out_8((unsigned char *)((ulong)addr), 0x30);
348                         l_sect = sect;
349                 }
350         }
351 #elif defined(CONFIG_BOOT_16B)
352         my_out_be16((unsigned short *)((ulong)addr + (0xaaa)), 0xaa);
353         my_out_be16((unsigned short *)((ulong)addr + (0x554)), 0x55);
354         my_out_be16((unsigned short *)((ulong)addr + (0xaaa)), 0x90);
355         in_mid = my_in_be16((unsigned short *)addr);
356         in_did = my_in_be16((unsigned short *)((ulong)addr + 2));
357         printf(" man ID=0x%x, dev ID=0x%x.\n", in_mid, in_did);
358         my_out_be16((unsigned short *)addr, 0xf0);
359         udelay(1);
360         my_out_be16((unsigned short *)((ulong)addr + 0xaaa), 0xaa);
361         my_out_be16((unsigned short *)((ulong)addr + 0x554), 0x55);
362         my_out_be16((unsigned short *)((ulong)addr + 0xaaa), 0x80);
363         my_out_be16((unsigned short *)((ulong)addr + 0xaaa), 0xaa);
364         my_out_be16((unsigned short *)((ulong)addr + 0x554), 0x55);
365         /* Start erase on unprotected sectors */
366         for (sect = s_first; sect <= s_last; sect++) {
367                 if (info->protect[sect] == 0) { /* not protected */
368                         addr = (vu_long *) (info->start[sect]);
369                         my_out_be16((unsigned short *)((ulong)addr), 0x30);
370                         l_sect = sect;
371                 }
372         }
373
374 #elif defined(CONFIG_BOOT_32B)
375         my_out_be32((unsigned *)((ulong)addr + 0x1554), 0xaa);
376         my_out_be32((unsigned *)((ulong)addr + 0xaa8), 0x55);
377         my_out_be32((unsigned *)((ulong)addr + 0x1554), 0x90);
378
379         in_mid = my_in_be32((unsigned *)addr);
380         in_did = my_in_be32((unsigned *)((ulong)addr + 4));
381
382         printf(" man ID=0x%x, dev ID=0x%x.\n", in_mid, in_did);
383
384         my_out_be32((unsigned *) addr, 0xf0);
385         udelay(1);
386
387         my_out_be32((unsigned *)((ulong)addr + 0x1554), 0xaa);
388         my_out_be32((unsigned *)((ulong)addr + 0xaa8), 0x55);
389         my_out_be32((unsigned *)((ulong)addr + 0x1554), 0x80);
390         my_out_be32((unsigned *)((ulong)addr + 0x1554), 0xaa);
391         my_out_be32((unsigned *)((ulong)addr + 0xaa8), 0x55);
392
393         /* Start erase on unprotected sectors */
394         for (sect = s_first; sect <= s_last; sect++) {
395                 if (info->protect[sect] == 0) { /* not protected */
396                         addr = (vu_long *) (info->start[sect]);
397                         my_out_be32((unsigned *)((ulong)addr), 0x00300030);
398                         l_sect = sect;
399                 }
400         }
401
402 #else
403 #error CONFIG_BOOT_(size)B missing.
404 #endif
405         /* re-enable interrupts if necessary */
406         if (flag)
407                 enable_interrupts();
408
409         /* wait at least 80us - let's wait 1 ms */
410         udelay(1000);
411
412         /*
413          * We wait for the last triggered sector
414          */
415         if (l_sect < 0)
416                 goto DONE;
417
418         start = get_timer(0);
419         last = start;
420         addr = (vu_long *) (info->start[l_sect]);
421 #if defined(CONFIG_BOOT_8B)
422         while ((my_in_8((unsigned char *) addr) & 0x80) != 0x80)
423 #elif defined(CONFIG_BOOT_16B)
424         while ((my_in_be16((unsigned short *) addr) & 0x0080) != 0x0080)
425 #elif defined(CONFIG_BOOT_32B)
426         while ((my_in_be32((unsigned *) addr) & 0x00800080) != 0x00800080)
427 #else
428 #error CONFIG_BOOT_(size)B missing.
429 #endif
430         {
431                 now = get_timer(start);
432                 if (now > CONFIG_SYS_FLASH_ERASE_TOUT) {
433                         printf("Timeout\n");
434                         return 1;
435                 }
436                 /* show that we're waiting */
437                 if ((now - last) > 1000) {      /* every second */
438                         putc('.');
439                         last = now;
440                 }
441         }
442 DONE:
443         /* reset to read mode */
444         addr = (volatile unsigned long *) info->start[0];
445
446 #if defined(CONFIG_BOOT_8B)
447         my_out_8((unsigned char *) addr, 0xf0);
448 #elif defined(CONFIG_BOOT_16B)
449         my_out_be16((unsigned short *) addr, 0x00f0);
450 #elif defined(CONFIG_BOOT_32B)
451         my_out_be32((unsigned *) addr, 0x00F000F0);     /* reset bank */
452 #else
453 #error CONFIG_BOOT_(size)B missing.
454 #endif
455         printf(" done\n");
456         return 0;
457 }
458
459 /*
460  * Copy memory to flash, returns:
461  * 0 - OK
462  * 1 - write timeout
463  * 2 - Flash not erased
464  */
465
466 int write_buff(flash_info_t *info, uchar *src, ulong addr, ulong cnt)
467 {
468         ulong cp, wp, data;
469         int i, l, rc;
470
471         wp = (addr & ~3);       /* get lower word aligned address */
472
473         /*
474          * handle unaligned start bytes
475          */
476         l = addr - wp;
477
478         if (l != 0) {
479                 data = 0;
480                 for (i = 0, cp = wp; i < l; ++i, ++cp)
481                         data = (data << 8) | (*(uchar *) cp);
482
483                 for (; i < 4 && cnt > 0; ++i) {
484                         data = (data << 8) | *src++;
485                         --cnt;
486                         ++cp;
487                 }
488                 for (; cnt == 0 && i < 4; ++i, ++cp)
489                         data = (data << 8) | (*(uchar *) cp);
490
491                 rc = write_word(info, wp, data);
492
493                 if (rc != 0)
494                         return rc;
495
496                 wp += 4;
497         }
498
499         /*
500          * handle word aligned part
501          */
502         while (cnt >= 4) {
503                 data = 0;
504                 for (i = 0; i < 4; ++i)
505                         data = (data << 8) | *src++;
506
507                 rc = write_word(info, wp, data);
508
509                 if (rc != 0)
510                         return rc;
511
512                 wp += 4;
513                 cnt -= 4;
514         }
515
516         if (cnt == 0)
517                 return 0;
518
519         /*
520          * handle unaligned tail bytes
521          */
522         data = 0;
523         for (i = 0, cp = wp; i < 4 && cnt > 0; ++i, ++cp) {
524                 data = (data << 8) | *src++;
525                 --cnt;
526         }
527         for (; i < 4; ++i, ++cp)
528                 data = (data << 8) | (*(uchar *) cp);
529
530         return write_word(info, wp, data);
531 }
532
533 /*
534  * Write a word to Flash, returns:
535  * 0 - OK
536  * 1 - write timeout
537  * 2 - Flash not erased
538  */
539 static int write_word(flash_info_t *info, ulong dest, ulong data)
540 {
541         ulong addr = (ulong) (info->start[0]);
542         ulong start;
543         int flag;
544         ulong i;
545         int data_short[2];
546
547         /* Check if Flash is (sufficiently) erased */
548         if (((ulong)*(ulong *)dest & data) != data)
549                 return 2;
550
551         /* Disable interrupts which might cause a timeout here */
552         flag = disable_interrupts();
553 #if defined(CONFIG_BOOT_8B)
554 #ifdef DEBUG
555         {
556                 int in_mid, in_did;
557
558                 my_out_8((unsigned char *) (addr + 0x555), 0xaa);
559                 my_out_8((unsigned char *) (addr + 0x2aa), 0x55);
560                 my_out_8((unsigned char *) (addr + 0x555), 0x90);
561
562                 in_mid = my_in_8((unsigned char *) addr);
563                 in_did = my_in_8((unsigned char *) (addr + 1));
564
565                 printf(" man ID=0x%x, dev ID=0x%x.\n", in_mid, in_did);
566
567                 my_out_8((unsigned char *) addr, 0xf0);
568                 udelay(1);
569         }
570 #endif
571         {
572                 int data_ch[4];
573
574                 data_ch[0] = (int) ((data >> 24) & 0xff);
575                 data_ch[1] = (int) ((data >> 16) & 0xff);
576                 data_ch[2] = (int) ((data >> 8) & 0xff);
577                 data_ch[3] = (int) (data & 0xff);
578
579                 for (i = 0; i < 4; i++) {
580                         my_out_8((unsigned char *) (addr + 0x555), 0xaa);
581                         my_out_8((unsigned char *) (addr + 0x2aa), 0x55);
582                         my_out_8((unsigned char *) (addr + 0x555), 0xa0);
583                         my_out_8((unsigned char *) (dest + i), data_ch[i]);
584
585                         /* re-enable interrupts if necessary */
586                         if (flag)
587                                 enable_interrupts();
588
589                         start = get_timer(0);
590                         while ((my_in_8((unsigned char *)(dest + i))) !=
591                                (data_ch[i])) {
592                                 if (get_timer(start) >
593                                     CONFIG_SYS_FLASH_WRITE_TOUT) {
594                                         return 1;
595                                 }
596                         }
597                 }               /* for */
598         }
599 #elif defined(CONFIG_BOOT_16B)
600         data_short[0] = (int) (data >> 16) & 0xffff;
601         data_short[1] = (int) data & 0xffff;
602         for (i = 0; i < 2; i++) {
603                 my_out_be16((unsigned short *)((ulong)addr + 0xaaa), 0xaa);
604                 my_out_be16((unsigned short *)((ulong)addr + 0x554), 0x55);
605                 my_out_be16((unsigned short *)((ulong)addr + 0xaaa), 0xa0);
606                 my_out_be16((unsigned short *)(dest + (i * 2)),
607                             data_short[i]);
608
609                 /* re-enable interrupts if necessary */
610                 if (flag)
611                         enable_interrupts();
612
613                 start = get_timer(0);
614                 while ((my_in_be16((unsigned short *)(dest + (i * 2)))) !=
615                                                         (data_short[i])) {
616                         if (get_timer(start) > CONFIG_SYS_FLASH_WRITE_TOUT)
617                                 return 1;
618                 }
619         }
620 #elif defined(CONFIG_BOOT_32B)
621         addr[0x0555] = 0x00AA00AA;
622         addr[0x02AA] = 0x00550055;
623         addr[0x0555] = 0x00A000A0;
624
625         *((vu_long *)dest) = data;
626
627         /* re-enable interrupts if necessary */
628         if (flag)
629                 enable_interrupts();
630
631         /* data polling for D7 */
632         start = get_timer(0);
633         while ((*((vu_long *)dest) & 0x00800080) != (data & 0x00800080)) {
634                 if (get_timer(start) > CONFIG_SYS_FLASH_WRITE_TOUT)
635                         return 1;
636         }
637 #endif
638         return 0;
639 }
640
641 #ifdef CONFIG_BOOT_8B
642 static int my_in_8(unsigned char *addr)
643 {
644         int ret;
645         __asm__ __volatile__("lbz%U1%X1 %0,%1; eieio":"=r"(ret):"m"(*addr));
646
647         return ret;
648 }
649
650 static void my_out_8(unsigned char *addr, int val)
651 {
652         __asm__ __volatile__("stb%U0%X0 %1,%0; eieio":"=m"(*addr):"r"(val));
653 }
654 #endif
655 #ifdef CONFIG_BOOT_16B
656 static int my_in_be16(unsigned short *addr)
657 {
658         int ret;
659         __asm__ __volatile__("lhz%U1%X1 %0,%1; eieio":"=r"(ret):"m"(*addr));
660
661         return ret;
662 }
663
664 static void my_out_be16(unsigned short *addr, int val)
665 {
666         __asm__ __volatile__("sth%U0%X0 %1,%0; eieio":"=m"(*addr):"r"(val));
667 }
668 #endif
669 #ifdef CONFIG_BOOT_32B
670 static unsigned my_in_be32(unsigned *addr)
671 {
672         unsigned ret;
673         __asm__ __volatile__("lwz%U1%X1 %0,%1; eieio":"=r"(ret):"m"(*addr));
674
675         return ret;
676 }
677
678 static void my_out_be32(unsigned *addr, int val)
679 {
680         __asm__ __volatile__("stw%U0%X0 %1,%0; eieio":"=m"(*addr):"r"(val));
681 }
682 #endif