]> git.kernelconcepts.de Git - karo-tx-uboot.git/blob - board/siemens/pcu_e/flash.c
rename CFG_ macros to CONFIG_SYS
[karo-tx-uboot.git] / board / siemens / pcu_e / flash.c
1 /*
2  * (C) Copyright 2001
3  * Wolfgang Denk, DENX Software Engineering, wd@denx.de.
4  *
5  * See file CREDITS for list of people who contributed to this
6  * project.
7  *
8  * This program is free software; you can redistribute it and/or
9  * modify it under the terms of the GNU General Public License as
10  * published by the Free Software Foundation; either version 2 of
11  * the License, or (at your option) any later version.
12  *
13  * This program is distributed in the hope that it will be useful,
14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16  * GNU General Public License for more details.
17  *
18  * You should have received a copy of the GNU General Public License
19  * along with this program; if not, write to the Free Software
20  * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
21  * MA 02111-1307 USA
22  */
23
24 #include <common.h>
25 #include <mpc8xx.h>
26
27 #if defined(CONFIG_ENV_IS_IN_FLASH)
28 # ifndef  CONFIG_ENV_ADDR
29 #  define CONFIG_ENV_ADDR       (CONFIG_SYS_FLASH_BASE + CONFIG_ENV_OFFSET)
30 # endif
31 # ifndef  CONFIG_ENV_SIZE
32 #  define CONFIG_ENV_SIZE       CONFIG_ENV_SECT_SIZE
33 # endif
34 # ifndef  CONFIG_ENV_SECT_SIZE
35 #  define CONFIG_ENV_SECT_SIZE  CONFIG_ENV_SIZE
36 # endif
37 #endif
38
39 /*---------------------------------------------------------------------*/
40 #undef DEBUG_FLASH
41
42 #ifdef DEBUG_FLASH
43 #define DEBUGF(fmt,args...) printf(fmt ,##args)
44 #else
45 #define DEBUGF(fmt,args...)
46 #endif
47 /*---------------------------------------------------------------------*/
48
49
50 flash_info_t    flash_info[CONFIG_SYS_MAX_FLASH_BANKS]; /* info for FLASH chips */
51
52 /*-----------------------------------------------------------------------
53  * Functions
54  */
55 static ulong flash_get_size (vu_long *addr, flash_info_t *info);
56 static int write_data (flash_info_t *info, ulong dest, ulong data);
57 static void flash_get_offsets (ulong base, flash_info_t *info);
58
59 /*-----------------------------------------------------------------------
60  *
61  * The PCU E uses an address map where flash banks are aligned top
62  * down, so that the "first" flash bank ends at top of memory, and
63  * the monitor entry point is at address (0xFFF00100). The second
64  * flash bank is mapped immediately below bank 0.
65  *
66  * This is NOT in conformance to the "official" memory map!
67  *
68  */
69
70 #define PCU_MONITOR_BASE   ( (flash_info[0].start[0] + flash_info[0].size - 1) \
71                            - (0xFFFFFFFF - CONFIG_SYS_MONITOR_BASE) )
72
73 /*-----------------------------------------------------------------------
74  */
75
76 unsigned long flash_init (void)
77 {
78         volatile immap_t     *immap  = (immap_t *)CONFIG_SYS_IMMR;
79         volatile memctl8xx_t *memctl = &immap->im_memctl;
80         unsigned long base, size_b0, size_b1;
81         int i;
82
83         /* Init: no FLASHes known */
84         for (i=0; i<CONFIG_SYS_MAX_FLASH_BANKS; ++i) {
85                 flash_info[i].flash_id = FLASH_UNKNOWN;
86         }
87
88         /* Static FLASH Bank configuration here - FIXME XXX */
89
90         /*
91          * Warning:
92          *
93          * Since the PCU E memory map assigns flash banks top down,
94          * we swap the numbering later if both banks are equipped,
95          * so they look like a contiguous area of memory.
96          */
97         DEBUGF("\n## Get flash bank 1 size @ 0x%08x\n",FLASH_BASE0_PRELIM);
98
99         size_b0 = flash_get_size((vu_long *)FLASH_BASE0_PRELIM, &flash_info[0]);
100
101         if (flash_info[0].flash_id == FLASH_UNKNOWN) {
102                 printf ("## Unknown FLASH on Bank 0 - Size = 0x%08lx = %ld MB\n",
103                         size_b0, size_b0<<20);
104         }
105
106         DEBUGF("## Get flash bank 2 size @ 0x%08x\n",FLASH_BASE6_PRELIM);
107         size_b1 = flash_get_size((vu_long *)FLASH_BASE6_PRELIM, &flash_info[1]);
108
109         DEBUGF("## Prelim. Flash bank sizes: %08lx + 0x%08lx\n", size_b0, size_b1);
110
111         if (size_b1 > size_b0) {
112                 printf ("## ERROR: "
113                         "Bank 1 (0x%08lx = %ld MB) > Bank 0 (0x%08lx = %ld MB)\n",
114                         size_b1, size_b1<<20,
115                         size_b0, size_b0<<20
116                 );
117                 flash_info[0].flash_id  = FLASH_UNKNOWN;
118                 flash_info[1].flash_id  = FLASH_UNKNOWN;
119                 flash_info[0].sector_count      = -1;
120                 flash_info[1].sector_count      = -1;
121                 flash_info[0].size              = 0;
122                 flash_info[1].size              = 0;
123                 return (0);
124         }
125
126         DEBUGF ("## Before remap: "
127                 "BR0: 0x%08x    OR0: 0x%08x    "
128                 "BR6: 0x%08x    OR6: 0x%08x\n",
129                 memctl->memc_br0, memctl->memc_or0,
130                 memctl->memc_br6, memctl->memc_or6);
131
132         /* Remap FLASH according to real size */
133         base = 0 - size_b0;
134         memctl->memc_or0 = CONFIG_SYS_OR_TIMING_FLASH | (-size_b0 & 0xFFFF8000);
135         memctl->memc_br0 = (base & BR_BA_MSK) | BR_PS_16 | BR_MS_GPCM | BR_V;
136
137         DEBUGF("## BR0: 0x%08x    OR0: 0x%08x\n",
138                 memctl->memc_br0, memctl->memc_or0);
139
140         /* Re-do sizing to get full correct info */
141         size_b0 = flash_get_size((vu_long *)base, &flash_info[0]);
142         base = 0 - size_b0;
143
144         flash_info[0].size = size_b0;
145
146         flash_get_offsets (base, &flash_info[0]);
147
148         /* monitor protection ON by default */
149         flash_protect(FLAG_PROTECT_SET,
150                       PCU_MONITOR_BASE,
151                       PCU_MONITOR_BASE+monitor_flash_len-1,
152                       &flash_info[0]);
153
154 #ifdef  CONFIG_ENV_IS_IN_FLASH
155         /* ENV protection ON by default */
156         flash_protect(FLAG_PROTECT_SET,
157                       CONFIG_ENV_ADDR,
158                       CONFIG_ENV_ADDR+CONFIG_ENV_SECT_SIZE-1,
159                       &flash_info[0]);
160 #endif
161
162         if (size_b1) {
163                 flash_info_t tmp_info;
164
165                 memctl->memc_or6 = CONFIG_SYS_OR_TIMING_FLASH | (-size_b1 & 0xFFFF8000);
166                 memctl->memc_br6 = ((base - size_b1) & BR_BA_MSK) |
167                                     BR_PS_16 | BR_MS_GPCM | BR_V;
168
169                 DEBUGF("## New BR6: 0x%08x    OR6: 0x%08x\n",
170                         memctl->memc_br6, memctl->memc_or6);
171
172                 /* Re-do sizing to get full correct info */
173                 size_b1 = flash_get_size((vu_long *)(base - size_b1),
174                                           &flash_info[1]);
175                 base -= size_b1;
176
177                 flash_get_offsets (base, &flash_info[1]);
178
179                 flash_info[1].size = size_b1;
180
181 #ifdef  CONFIG_ENV_IS_IN_FLASH
182                 /* ENV protection ON by default */
183                 flash_protect(FLAG_PROTECT_SET,
184                               CONFIG_ENV_ADDR,
185                               CONFIG_ENV_ADDR+CONFIG_ENV_SECT_SIZE-1,
186                               &flash_info[1]);
187 #endif
188                 /*
189                  * Swap bank numbers so that addresses are in ascending order
190                  */
191                 tmp_info = flash_info[0];
192                 flash_info[0] = flash_info[1];
193                 flash_info[1] = tmp_info;
194         } else {
195                 memctl->memc_br1 = 0;           /* invalidate bank */
196
197                 flash_info[1].flash_id = FLASH_UNKNOWN;
198                 flash_info[1].sector_count = -1;
199         }
200
201
202         DEBUGF("## Final Flash bank sizes: %08lx + 0x%08lx\n",size_b0,size_b1);
203
204         return (size_b0 + size_b1);
205 }
206
207 /*-----------------------------------------------------------------------
208  */
209 static void flash_get_offsets (ulong base, flash_info_t *info)
210 {
211         int i;
212         short n;
213
214         if (info->flash_id == FLASH_UNKNOWN) {
215                 return;
216         }
217
218         if ((info->flash_id & FLASH_VENDMASK) != FLASH_MAN_AMD) {
219                 return;
220         }
221
222         switch (info->flash_id & FLASH_TYPEMASK) {
223         case FLASH_AMDL322T:
224         case FLASH_AMDL323T:
225         case FLASH_AMDL324T:
226                 /* set sector offsets for top boot block type           */
227
228                 base += info->size;
229                 i = info->sector_count;
230                 for (n=0; n<8; ++n) {           /*  8 x 8k boot sectors */
231                         base -= 8 << 10;
232                         --i;
233                         info->start[i] = base;
234                 }
235                 while (i > 0) {                 /* 64k regular sectors  */
236                         base -= 64 << 10;
237                         --i;
238                         info->start[i] = base;
239                 }
240                 return;
241         case FLASH_AMDL322B:
242         case FLASH_AMDL323B:
243         case FLASH_AMDL324B:
244                 /* set sector offsets for bottom boot block type        */
245                 for (i=0; i<8; ++i) {           /*  8 x 8k boot sectors */
246                         info->start[i] = base;
247                         base += 8 << 10;
248                 }
249                 while (base < info->size) {     /* 64k regular sectors  */
250                         info->start[i] = base;
251                         base += 64 << 10;
252                         ++i;
253                 }
254                 return;
255         case FLASH_AMDL640:
256                 /* set sector offsets for dual boot block type          */
257                 for (i=0; i<8; ++i) {           /*  8 x 8k boot sectors */
258                         info->start[i] = base;
259                         base += 8 << 10;
260                 }
261                 n = info->sector_count - 8;
262                 while (i < n) {                 /* 64k regular sectors  */
263                         info->start[i] = base;
264                         base += 64 << 10;
265                         ++i;
266                 }
267                 while (i < info->sector_count) { /* 8 x 8k boot sectors */
268                         info->start[i] = base;
269                         base += 8 << 10;
270                         ++i;
271                 }
272                 return;
273         default:
274                 return;
275         }
276         /* NOTREACHED */
277 }
278
279 /*-----------------------------------------------------------------------
280  */
281 void flash_print_info  (flash_info_t *info)
282 {
283         int i;
284
285         if (info->flash_id == FLASH_UNKNOWN) {
286                 printf ("missing or unknown FLASH type\n");
287                 return;
288         }
289
290         switch (info->flash_id & FLASH_VENDMASK) {
291         case FLASH_MAN_AMD:     printf ("AMD ");                break;
292         case FLASH_MAN_FUJ:     printf ("FUJITSU ");            break;
293         default:                printf ("Unknown Vendor ");     break;
294         }
295
296         switch (info->flash_id & FLASH_TYPEMASK) {
297         case FLASH_AMDL322B:    printf ("AM29DL322B (32 Mbit, bottom boot sect)\n");
298                                 break;
299         case FLASH_AMDL322T:    printf ("AM29DL322T (32 Mbit, top boot sector)\n");
300                                 break;
301         case FLASH_AMDL323B:    printf ("AM29DL323B (32 Mbit, bottom boot sect)\n");
302                                 break;
303         case FLASH_AMDL323T:    printf ("AM29DL323T (32 Mbit, top boot sector)\n");
304                                 break;
305         case FLASH_AMDL324B:    printf ("AM29DL324B (32 Mbit, bottom boot sect)\n");
306                                 break;
307         case FLASH_AMDL324T:    printf ("AM29DL324T (32 Mbit, top boot sector)\n");
308                                 break;
309         case FLASH_AMDL640:     printf ("AM29DL640D (64 Mbit, dual boot sector)\n");
310                                 break;
311         default:                printf ("Unknown Chip Type 0x%lX\n",
312                                         info->flash_id);
313                                 break;
314         }
315
316         printf ("  Size: %ld MB in %d Sectors\n",
317                 info->size >> 20, info->sector_count);
318
319         printf ("  Sector Start Addresses:");
320         for (i=0; i<info->sector_count; ++i) {
321                 if ((i % 5) == 0)
322                         printf ("\n   ");
323                 printf (" %08lX%s",
324                         info->start[i],
325                         info->protect[i] ? " (RO)" : "     "
326                 );
327         }
328         printf ("\n");
329         return;
330 }
331
332 /*-----------------------------------------------------------------------
333  */
334
335
336 /*-----------------------------------------------------------------------
337  */
338
339 /*
340  * The following code cannot be run from FLASH!
341  */
342
343 static ulong flash_get_size (vu_long *addr, flash_info_t *info)
344 {
345         short i;
346         ushort value;
347         vu_short *saddr = (vu_short *)addr;
348
349         /* Write auto select command: read Manufacturer ID */
350         saddr[0x0555] = 0x00AA;
351         saddr[0x02AA] = 0x0055;
352         saddr[0x0555] = 0x0090;
353
354         value = saddr[0];
355
356         DEBUGF("Manuf. ID @ 0x%08lx: 0x%04x\n", (ulong)addr, value);
357
358         switch (value) {
359         case (AMD_MANUFACT & 0xFFFF):
360                 info->flash_id = FLASH_MAN_AMD;
361                 break;
362         case (FUJ_MANUFACT & 0xFFFF):
363                 info->flash_id = FLASH_MAN_FUJ;
364                 break;
365         default:
366                 DEBUGF("Unknown Manufacturer ID\n");
367                 info->flash_id = FLASH_UNKNOWN;
368                 info->sector_count = 0;
369                 info->size = 0;
370                 return (0);                     /* no or unknown flash  */
371         }
372
373         value = saddr[1];                       /* device ID            */
374
375         DEBUGF("Device ID @ 0x%08lx: 0x%04x\n", (ulong)(&addr[1]), value);
376
377         switch (value) {
378
379         case (AMD_ID_DL322T & 0xFFFF):
380                 info->flash_id += FLASH_AMDL322T;
381                 info->sector_count = 71;
382                 info->size = 0x00400000;
383                 break;                          /* => 8 MB              */
384
385         case (AMD_ID_DL322B & 0xFFFF):
386                 info->flash_id += FLASH_AMDL322B;
387                 info->sector_count = 71;
388                 info->size = 0x00400000;
389                 break;                          /* => 8 MB              */
390
391         case (AMD_ID_DL323T & 0xFFFF):
392                 info->flash_id += FLASH_AMDL323T;
393                 info->sector_count = 71;
394                 info->size = 0x00400000;
395                 break;                          /* => 8 MB              */
396
397         case (AMD_ID_DL323B & 0xFFFF):
398                 info->flash_id += FLASH_AMDL323B;
399                 info->sector_count = 71;
400                 info->size = 0x00400000;
401                 break;                          /* => 8 MB              */
402
403         case (AMD_ID_DL324T & 0xFFFF):
404                 info->flash_id += FLASH_AMDL324T;
405                 info->sector_count = 71;
406                 info->size = 0x00400000;
407                 break;                          /* => 8 MB              */
408
409         case (AMD_ID_DL324B & 0xFFFF):
410                 info->flash_id += FLASH_AMDL324B;
411                 info->sector_count = 71;
412                 info->size = 0x00400000;
413                 break;                          /* => 8 MB              */
414         case (AMD_ID_DL640  & 0xFFFF):
415                 info->flash_id += FLASH_AMDL640;
416                 info->sector_count = 142;
417                 info->size = 0x00800000;
418                 break;
419         default:
420                 DEBUGF("Unknown Device ID\n");
421                 info->flash_id = FLASH_UNKNOWN;
422                 return (0);                     /* => no or unknown flash */
423
424         }
425
426         flash_get_offsets ((ulong)addr, info);
427
428         /* check for protected sectors */
429         for (i = 0; i < info->sector_count; i++) {
430 #if 0
431                 /* read sector protection at sector address, (A7 .. A0) = 0x02 */
432                 /* D0 = 1 if protected */
433                 saddr = (vu_short *)(info->start[i]);
434                 info->protect[i] = saddr[2] & 1;
435 #else
436                 info->protect[i] =0;
437 #endif
438         }
439
440         if (info->sector_count > CONFIG_SYS_MAX_FLASH_SECT) {
441                 printf ("** ERROR: sector count %d > max (%d) **\n",
442                         info->sector_count, CONFIG_SYS_MAX_FLASH_SECT);
443                 info->sector_count = CONFIG_SYS_MAX_FLASH_SECT;
444         }
445
446         saddr = (vu_short *)info->start[0];
447         *saddr = 0x00F0;        /* restore read mode */
448
449         return (info->size);
450 }
451
452
453 /*-----------------------------------------------------------------------
454  */
455
456 int     flash_erase (flash_info_t *info, int s_first, int s_last)
457 {
458         vu_short *addr = (vu_short*)(info->start[0]);
459         int flag, prot, sect, l_sect;
460         ulong start, now, last;
461
462         if ((s_first < 0) || (s_first > s_last)) {
463                 if (info->flash_id == FLASH_UNKNOWN) {
464                         printf ("- missing\n");
465                 } else {
466                         printf ("- no sectors to erase\n");
467                 }
468                 return 1;
469         }
470
471         if ((info->flash_id == FLASH_UNKNOWN) ||
472             (info->flash_id > FLASH_AMD_COMP)) {
473                 printf ("Can't erase unknown flash type %08lx - aborted\n",
474                         info->flash_id);
475                 return 1;
476         }
477
478         prot = 0;
479         for (sect=s_first; sect<=s_last; ++sect) {
480                 if (info->protect[sect]) {
481                         prot++;
482                 }
483         }
484
485         if (prot) {
486                 printf ("- Warning: %d protected sectors will not be erased!\n",
487                         prot);
488         } else {
489                 printf ("\n");
490         }
491
492         l_sect = -1;
493
494         /* Disable interrupts which might cause a timeout here */
495         flag = disable_interrupts();
496
497         addr[0x0555] = 0x00AA;
498         addr[0x02AA] = 0x0055;
499         addr[0x0555] = 0x0080;
500         addr[0x0555] = 0x00AA;
501         addr[0x02AA] = 0x0055;
502
503         /* Start erase on unprotected sectors */
504         for (sect = s_first; sect<=s_last; sect++) {
505                 if (info->protect[sect] == 0) { /* not protected */
506                         addr = (vu_short*)(info->start[sect]);
507                         addr[0] = 0x0030;
508                         l_sect = sect;
509                 }
510         }
511
512         /* re-enable interrupts if necessary */
513         if (flag)
514                 enable_interrupts();
515
516         /* wait at least 80us - let's wait 1 ms */
517         udelay (1000);
518
519         /*
520          * We wait for the last triggered sector
521          */
522         if (l_sect < 0)
523                 goto DONE;
524
525         start = get_timer (0);
526         last  = start;
527         addr = (vu_short*)(info->start[l_sect]);
528         while ((addr[0] & 0x0080) != 0x0080) {
529                 if ((now = get_timer(start)) > CONFIG_SYS_FLASH_ERASE_TOUT) {
530                         printf ("Timeout\n");
531                         return 1;
532                 }
533                 /* show that we're waiting */
534                 if ((now - last) > 1000) {      /* every second */
535                         putc ('.');
536                         last = now;
537                 }
538         }
539
540 DONE:
541         /* reset to read mode */
542         addr = (vu_short *)info->start[0];
543         addr[0] = 0x00F0;       /* reset bank */
544
545         printf (" done\n");
546         return 0;
547 }
548
549 /*-----------------------------------------------------------------------
550  * Copy memory to flash, returns:
551  * 0 - OK
552  * 1 - write timeout
553  * 2 - Flash not erased
554  */
555
556 #define FLASH_WIDTH     2       /* flash bus width in bytes */
557
558 int write_buff (flash_info_t *info, uchar *src, ulong addr, ulong cnt)
559 {
560         ulong cp, wp, data;
561         int i, l, rc;
562
563         wp = (addr & ~(FLASH_WIDTH-1)); /* get lower FLASH_WIDTH aligned address */
564
565         /*
566          * handle unaligned start bytes
567          */
568         if ((l = addr - wp) != 0) {
569                 data = 0;
570                 for (i=0, cp=wp; i<l; ++i, ++cp) {
571                         data = (data << 8) | (*(uchar *)cp);
572                 }
573                 for (; i<FLASH_WIDTH && cnt>0; ++i) {
574                         data = (data << 8) | *src++;
575                         --cnt;
576                         ++cp;
577                 }
578                 for (; cnt==0 && i<FLASH_WIDTH; ++i, ++cp) {
579                         data = (data << 8) | (*(uchar *)cp);
580                 }
581
582                 if ((rc = write_data(info, wp, data)) != 0) {
583                         return (rc);
584                 }
585                 wp += FLASH_WIDTH;
586         }
587
588         /*
589          * handle FLASH_WIDTH aligned part
590          */
591         while (cnt >= FLASH_WIDTH) {
592                 data = 0;
593                 for (i=0; i<FLASH_WIDTH; ++i) {
594                         data = (data << 8) | *src++;
595                 }
596                 if ((rc = write_data(info, wp, data)) != 0) {
597                         return (rc);
598                 }
599                 wp  += FLASH_WIDTH;
600                 cnt -= FLASH_WIDTH;
601         }
602
603         if (cnt == 0) {
604                 return (0);
605         }
606
607         /*
608          * handle unaligned tail bytes
609          */
610         data = 0;
611         for (i=0, cp=wp; i<FLASH_WIDTH && cnt>0; ++i, ++cp) {
612                 data = (data << 8) | *src++;
613                 --cnt;
614         }
615         for (; i<FLASH_WIDTH; ++i, ++cp) {
616                 data = (data << 8) | (*(uchar *)cp);
617         }
618
619         return (write_data(info, wp, data));
620 }
621
622 /*-----------------------------------------------------------------------
623  * Write a word to Flash, returns:
624  * 0 - OK
625  * 1 - write timeout
626  * 2 - Flash not erased
627  */
628 static int write_data (flash_info_t *info, ulong dest, ulong data)
629 {
630         vu_short *addr  = (vu_short*)(info->start[0]);
631         vu_short *sdest = (vu_short *)dest;
632         ushort sdata = (ushort)data;
633         ushort sval;
634         ulong start, passed;
635         int flag, rc;
636
637         /* Check if Flash is (sufficiently) erased */
638         if ((*sdest & sdata) != sdata) {
639                 return (2);
640         }
641         /* Disable interrupts which might cause a timeout here */
642         flag = disable_interrupts();
643
644         addr[0x0555] = 0x00AA;
645         addr[0x02AA] = 0x0055;
646         addr[0x0555] = 0x00A0;
647
648 #ifdef WORKAROUND_FOR_BROKEN_HARDWARE
649         /* work around the timeout bugs */
650         udelay(20);
651 #endif
652
653         *sdest = sdata;
654
655         /* re-enable interrupts if necessary */
656         if (flag)
657                 enable_interrupts();
658
659         rc = 0;
660         /* data polling for D7 */
661         start = get_timer (0);
662
663         for (passed=0; passed < CONFIG_SYS_FLASH_WRITE_TOUT; passed=get_timer(start)) {
664
665                 sval = *sdest;
666
667                 if ((sval & 0x0080) == (sdata & 0x0080))
668                         break;
669
670                 if ((sval & 0x0020) == 0)       /* DQ5: Timeout? */
671                         continue;
672
673                 sval = *sdest;
674
675                 if ((sval & 0x0080) != (sdata & 0x0080))
676                         rc = 1;
677
678                 break;
679         }
680
681         if (rc) {
682             DEBUGF ("Program cycle failed @ addr 0x%08lX: val %04X data %04X\n",
683                  dest, sval, sdata);
684         }
685
686         if (passed >= CONFIG_SYS_FLASH_WRITE_TOUT) {
687                 DEBUGF ("Timeout @ addr 0x%08lX: val %04X data %04X\n",
688                         dest, sval, sdata);
689                 rc = 1;
690         }
691
692         /* reset to read mode */
693         addr = (vu_short *)info->start[0];
694         addr[0] = 0x00F0;       /* reset bank */
695
696         return (rc);
697 }
698
699 /*-----------------------------------------------------------------------
700  */