aa2ba6f04c31918628a408bd15b45dd7e34ec733
[pandora-u-boot.git] / board / mpl / common / common_util.c
1 /*
2  * (C) Copyright 2001
3  * Denis Peter, MPL AG Switzerland, d.peter@mpl.ch
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
25 #include <common.h>
26 #include <command.h>
27 #include <video_fb.h>
28 #include "common_util.h"
29 #include <asm/processor.h>
30 #include <asm/byteorder.h>
31 #include <i2c.h>
32 #include <devices.h>
33 #include <pci.h>
34
35 #ifdef CONFIG_PIP405
36 #include "../pip405/pip405.h"
37 #include <405gp_pci.h>
38 #endif
39 #ifdef CONFIG_MIP405
40 #include "../mip405/mip405.h"
41 #include <405gp_pci.h>
42 #endif
43
44 extern int  gunzip (void *, int, unsigned char *, int *);
45 extern int mem_test(unsigned long start, unsigned long ramsize, int quiet);
46
47 #define I2C_BACKUP_ADDR 0x7C00 /* 0x200 bytes for backup */
48 #define IMAGE_SIZE 0x80000
49
50 extern flash_info_t flash_info[];       /* info for FLASH chips */
51
52 static image_header_t header;
53
54
55
56 int mpl_prg(unsigned long src,unsigned long size)
57 {
58         unsigned long start;
59         flash_info_t *info;
60         int i,rc;
61 #if defined(CONFIG_PIP405) || defined(CONFIG_MIP405)
62         char *copystr = (char *)src;
63         unsigned long *magic = (unsigned long *)src;
64 #endif
65
66         info = &flash_info[0];
67
68 #if defined(CONFIG_PIP405) || defined(CONFIG_MIP405)
69         if(ntohl(magic[0]) != IH_MAGIC) {
70                 printf("Bad Magic number\n");
71                 return -1;
72         }
73         /* some more checks before we delete the Flash... */
74         /* Checking the ISO_STRING prevents to program a
75          * wrong Firmware Image into the flash.
76          */
77         i=4; /* skip Magic number */
78         while(1) {
79                 if(strncmp(&copystr[i],"MEV-",4)==0)
80                         break;
81                 if(i++>=0x100) {
82                         printf("Firmware Image for unknown Target\n");
83                         return -1;
84                 }
85         }
86         /* we have the ISO STRING, check */
87         if(strncmp(&copystr[i],CONFIG_ISO_STRING,sizeof(CONFIG_ISO_STRING)-1)!=0) {
88                 printf("Wrong Firmware Image: %s\n",&copystr[i]);
89                 return -1;
90         }
91         start = 0 - size;
92         for(i=info->sector_count-1;i>0;i--)
93         {
94                 info->protect[i] = 0; /* unprotect this sector */
95                 if(start>=info->start[i])
96                 break;
97         }
98         /* set-up flash location */
99         /* now erase flash */
100         printf("Erasing at %lx (sector %d) (start %lx)\n",
101                                 start,i,info->start[i]);
102         flash_erase (info, i, info->sector_count-1);
103
104 #elif defined(CONFIG_VCMA9)
105         start = 0;
106         for (i = 0; i <info->sector_count; i++)
107         {
108                 info->protect[i] = 0; /* unprotect this sector */
109                 if (size < info->start[i])
110                     break;
111         }
112         /* set-up flash location */
113         /* now erase flash */
114         printf("Erasing at %lx (sector %d) (start %lx)\n",
115                                 start,0,info->start[0]);
116         flash_erase (info, 0, i);
117
118 #endif
119         printf("flash erased, programming from 0x%lx 0x%lx Bytes\n",src,size);
120         if ((rc = flash_write ((uchar *)src, start, size)) != 0) {
121                 puts ("ERROR ");
122                 flash_perror (rc);
123                 return (1);
124         }
125         puts ("OK programming done\n");
126         return 0;
127 }
128
129
130 int mpl_prg_image(unsigned long ld_addr)
131 {
132         unsigned long data,len,checksum;
133         image_header_t *hdr=&header;
134         /* Copy header so we can blank CRC field for re-calculation */
135         memcpy (&header, (char *)ld_addr, sizeof(image_header_t));
136         if (ntohl(hdr->ih_magic)  != IH_MAGIC) {
137                 printf ("Bad Magic Number\n");
138                 return 1;
139         }
140         print_image_hdr(hdr);
141         if (hdr->ih_os  != IH_OS_U_BOOT) {
142                 printf ("No U-Boot Image\n");
143                 return 1;
144         }
145         if (hdr->ih_type  != IH_TYPE_FIRMWARE) {
146                 printf ("No Firmware Image\n");
147                 return 1;
148         }
149         data = (ulong)&header;
150         len  = sizeof(image_header_t);
151         checksum = ntohl(hdr->ih_hcrc);
152         hdr->ih_hcrc = 0;
153         if (crc32 (0, (char *)data, len) != checksum) {
154                 printf ("Bad Header Checksum\n");
155                 return 1;
156         }
157         data = ld_addr + sizeof(image_header_t);
158         len  = ntohl(hdr->ih_size);
159         printf ("Verifying Checksum ... ");
160         if (crc32 (0, (char *)data, len) != ntohl(hdr->ih_dcrc)) {
161                 printf ("Bad Data CRC\n");
162                 return 1;
163         }
164         switch (hdr->ih_comp) {
165         case IH_COMP_NONE:
166                 break;
167         case IH_COMP_GZIP:
168                 printf ("  Uncompressing  ... ");
169                 if (gunzip ((void *)(data+0x100000), 0x400000,
170                             (uchar *)data, (int *)&len) != 0) {
171                         printf ("GUNZIP ERROR\n");
172                         return 1;
173                 }
174                 data+=0x100000;
175                 break;
176         default:
177                 printf ("   Unimplemented compression type %d\n", hdr->ih_comp);
178                 return 1;
179         }
180
181         printf ("  OK\n");
182         return(mpl_prg(data,len));
183 }
184
185
186 void get_backup_values(backup_t *buf)
187 {
188         i2c_read(CFG_DEF_EEPROM_ADDR, I2C_BACKUP_ADDR,2,(void *)buf,sizeof(backup_t));
189 }
190
191 void set_backup_values(int overwrite)
192 {
193         backup_t back;
194         int i;
195
196         get_backup_values(&back);
197         if(!overwrite) {
198                 if(strncmp(back.signature,"MPL\0",4)==0) {
199                         printf("Not possible to write Backup\n");
200                         return;
201                 }
202         }
203         memcpy(back.signature,"MPL\0",4);
204         i = getenv_r("serial#",back.serial_name,16);
205         if(i < 0) {
206                 printf("Not possible to write Backup\n");
207                 return;
208         }
209         back.serial_name[16]=0;
210         i = getenv_r("ethaddr",back.eth_addr,20);
211         if(i < 0) {
212                 printf("Not possible to write Backup\n");
213                 return;
214         }
215         back.eth_addr[20]=0;
216         i2c_write(CFG_DEF_EEPROM_ADDR, I2C_BACKUP_ADDR,2,(void *)&back,sizeof(backup_t));
217 }
218
219 void clear_env_values(void)
220 {
221         backup_t back;
222         unsigned char env_crc[4];
223
224         memset(&back,0xff,sizeof(backup_t));
225         memset(env_crc,0x00,4);
226         i2c_write(CFG_DEF_EEPROM_ADDR,I2C_BACKUP_ADDR,2,(void *)&back,sizeof(backup_t));
227         i2c_write(CFG_DEF_EEPROM_ADDR,CFG_ENV_OFFSET,2,(void *)env_crc,4);
228 }
229
230 /*
231  * check crc of "older" environment
232  */
233 int check_env_old_size(ulong oldsize)
234 {
235         ulong crc, len, new;
236         unsigned off;
237         uchar buf[64];
238
239         /* read old CRC */
240         eeprom_read (CFG_DEF_EEPROM_ADDR,
241                      CFG_ENV_OFFSET,
242                      (uchar *)&crc, sizeof(ulong));
243
244         new = 0;
245         len = oldsize;
246         off = sizeof(long);
247         len = oldsize-off;
248         while (len > 0) {
249                 int n = (len > sizeof(buf)) ? sizeof(buf) : len;
250
251                 eeprom_read (CFG_DEF_EEPROM_ADDR, CFG_ENV_OFFSET+off, buf, n);
252                 new = crc32 (new, buf, n);
253                 len -= n;
254                 off += n;
255         }
256
257         return (crc == new);
258 }
259
260 static ulong oldsizes[] = {
261         0x200,
262         0x800,
263         0
264 };
265
266 void copy_old_env(ulong size)
267 {
268         uchar name_buf[64];
269         uchar value_buf[0x800];
270         uchar c;
271         ulong len;
272         unsigned off;
273         uchar *name, *value;
274
275         name=&name_buf[0];
276         value=&value_buf[0];
277         len=size;
278         off = sizeof(long);
279         while (len > off) {
280                 eeprom_read (CFG_DEF_EEPROM_ADDR, CFG_ENV_OFFSET+off, &c, 1);
281                 if(c != '=') {
282                         *name++=c;
283                         off++;
284                 }
285                 else {
286                         *name++='\0';
287                         off++;
288                         do {
289                                 eeprom_read (CFG_DEF_EEPROM_ADDR, CFG_ENV_OFFSET+off, &c, 1);
290                                 *value++=c;
291                                 off++;
292                                 if(c == '\0')
293                                         break;
294                         } while(len > off);
295                         name=&name_buf[0];
296                         value=&value_buf[0];
297                         if(strncmp(name,"baudrate",8)!=0) {
298                                 setenv(name,value);
299                         }
300
301                 }
302         }
303 }
304
305
306 void check_env(void)
307 {
308         unsigned char *s;
309         int i=0;
310         char buf[32];
311         backup_t back;
312
313         s=getenv("serial#");
314         if(!s) {
315                 while(oldsizes[i]) {
316                         if(check_env_old_size(oldsizes[i]))
317                                 break;
318                         i++;
319                 }
320                 if(!oldsizes[i]) {
321                         /* no old environment has been found */
322                         get_backup_values (&back);
323                         if (strncmp (back.signature, "MPL\0", 4) == 0) {
324                                 sprintf (buf, "%s", back.serial_name);
325                                 setenv ("serial#", buf);
326                                 sprintf (buf, "%s", back.eth_addr);
327                                 setenv ("ethaddr", buf);
328                                 printf ("INFO:  serial# and ethaddr recovered, use saveenv\n");
329                                 return;
330                         }
331                 }
332                 else {
333                         copy_old_env(oldsizes[i]);
334                         printf ("INFO:  old environment ajusted, use saveenv\n");
335                 }
336         }
337         else {
338                 /* check if back up is set */
339                 get_backup_values(&back);
340                 if(strncmp(back.signature,"MPL\0",4)!=0) {
341                         set_backup_values(0);
342                 }
343         }
344 }
345
346
347
348 extern device_t *stdio_devices[];
349 extern char *stdio_names[];
350
351 void show_stdio_dev(void)
352 {
353         /* Print information */
354         printf ("In:    ");
355         if (stdio_devices[stdin] == NULL) {
356                 printf ("No input devices available!\n");
357         } else {
358                 printf ("%s\n", stdio_devices[stdin]->name);
359         }
360
361         printf ("Out:   ");
362         if (stdio_devices[stdout] == NULL) {
363                 printf ("No output devices available!\n");
364         } else {
365                 printf ("%s\n", stdio_devices[stdout]->name);
366         }
367
368         printf ("Err:   ");
369         if (stdio_devices[stderr] == NULL) {
370                 printf ("No error devices available!\n");
371         } else {
372                 printf ("%s\n", stdio_devices[stderr]->name);
373         }
374 }
375
376 /* ------------------------------------------------------------------------- */
377
378         /* switches the cs0 and the cs1 to the locations.
379            When boot is TRUE, the the mapping is switched
380            to the boot configuration, If it is FALSE, the
381            flash will be switched in the boot area */
382
383 #undef SW_CS_DBG
384 #ifdef SW_CS_DBG
385 #define SW_CS_PRINTF(fmt,args...)       printf (fmt ,##args)
386 #else
387 #define SW_CS_PRINTF(fmt,args...)
388 #endif
389
390 #if defined(CONFIG_PIP405) || defined(CONFIG_MIP405)
391 int switch_cs(unsigned char boot)
392 {
393         unsigned long pbcr;
394         int mode;
395
396         mode=get_boot_mode();
397         mtdcr(ebccfga, pb0cr);
398         pbcr = mfdcr (ebccfgd);
399         if (mode & BOOT_MPS) {
400                 /* Boot width = 8 bit MPS Boot, set up MPS on CS0 */
401                 /* we need only to switch if boot from MPS */
402                 /* printf(" MPS boot mode detected. ");*/
403                 /* printf("cs0 cfg: %lx\n",pbcr); */
404                 if(boot) {
405                         /* switch to boot configuration */
406                         /* this is a 8bit boot, switch cs0 to flash location */
407                         SW_CS_PRINTF("switch to boot mode (MPS on High address\n");
408                         pbcr&=0x000FFFFF; /*mask base address of the cs0 */
409                         pbcr|=(FLASH_BASE0_PRELIM & 0xFFF00000);
410                         mtdcr(ebccfga, pb0cr);
411                         mtdcr(ebccfgd, pbcr);
412                         SW_CS_PRINTF("  new cs0 cfg: %lx\n",pbcr);
413                         mtdcr(ebccfga, pb1cr); /* get cs1 config reg (flash) */
414                         pbcr = mfdcr(ebccfgd);
415                         SW_CS_PRINTF(" old cs1 cfg: %lx\n",pbcr);
416                         pbcr&=0x000FFFFF; /*mask base address of the cs1 */
417                         pbcr|=(MULTI_PURPOSE_SOCKET_ADDR & 0xFFF00000);
418                         mtdcr(ebccfga, pb1cr);
419                         mtdcr(ebccfgd, pbcr);
420                         SW_CS_PRINTF("  new cs1 cfg: %lx, MPS is on High Address\n",pbcr);
421                 }
422                 else {
423                         /* map flash to boot area, */
424                         SW_CS_PRINTF("map Flash to boot area\n");
425                         pbcr&=0x000FFFFF; /*mask base address of the cs0 */
426                         pbcr|=(MULTI_PURPOSE_SOCKET_ADDR & 0xFFF00000);
427                         mtdcr(ebccfga, pb0cr);
428                         mtdcr(ebccfgd, pbcr);
429                         SW_CS_PRINTF("  new cs0 cfg: %lx\n",pbcr);
430                         mtdcr(ebccfga, pb1cr); /* get cs1 config reg (flash) */
431                         pbcr = mfdcr(ebccfgd);
432                         SW_CS_PRINTF("  cs1 cfg: %lx\n",pbcr);
433                         pbcr&=0x000FFFFF; /*mask base address of the cs1 */
434                         pbcr|=(FLASH_BASE0_PRELIM & 0xFFF00000);
435                         mtdcr(ebccfga, pb1cr);
436                         mtdcr(ebccfgd, pbcr);
437                         SW_CS_PRINTF("  new cs1 cfg: %lx Flash is on High Address\n",pbcr);
438                 }
439                 return 1;
440         }
441         else {
442                 SW_CS_PRINTF("Normal boot, no switching necessary\n");
443                 return 0;
444         }
445
446 }
447
448 int get_boot_mode(void)
449 {
450         unsigned long pbcr;
451         int res = 0;
452         pbcr = mfdcr (strap);
453         if ((pbcr & PSR_ROM_WIDTH_MASK) == 0) 
454                 /* boot via MPS or MPS mapping */
455                 res = BOOT_MPS;
456         if(pbcr & PSR_ROM_LOC) 
457                 /* boot via PCI.. */
458                 res |= BOOT_PCI;
459          return res;
460 }
461
462 /* Setup cs0 parameter finally.
463    Map the flash high (in boot area)
464    This code can only be executed from SDRAM (after relocation).
465 */
466 void setup_cs_reloc(void)
467 {
468         unsigned long pbcr;
469         /* Since we are relocated, we can set-up the CS finaly
470          * but first of all, switch off PCI mapping (in case it was a PCI boot) */
471         out32r(PMM0MA,0L);
472         icache_enable (); /* we are relocated */
473         /* for PCI Boot, we have to set-up the remaining CS correctly */
474         pbcr = mfdcr (strap);
475         if(pbcr & PSR_ROM_LOC) {
476                 /* boot via PCI.. */
477                 if ((pbcr & PSR_ROM_WIDTH_MASK) == 0) {
478                 /* Boot width = 8 bit MPS Boot, set up MPS on CS0 */
479                         #ifdef DEBUG
480                         printf("Mapping MPS to CS0 @ 0x%lx\n",(MPS_CR_B & 0xfff00000));
481                         #endif
482                         mtdcr (ebccfga, pb0ap);
483                         mtdcr (ebccfgd, MPS_AP);
484                         mtdcr (ebccfga, pb0cr);
485                         mtdcr (ebccfgd, MPS_CR_B);
486                 }
487                 else {
488                         /* Flash boot, set up the Flash on CS0 */
489                         #ifdef DEBUG
490                         printf("Mapping Flash to CS0 @ 0x%lx\n",(FLASH_CR_B & 0xfff00000));
491                         #endif
492                         mtdcr (ebccfga, pb0ap);
493                         mtdcr (ebccfgd, FLASH_AP);
494                         mtdcr (ebccfga, pb0cr);
495                         mtdcr (ebccfgd, FLASH_CR_B);
496                 }
497         }
498         switch_cs(0); /* map Flash High */
499 }
500
501
502 #elif defined(CONFIG_VCMA9)
503 int switch_cs(unsigned char boot)
504 {
505     return 0;
506 }
507 #endif /* CONFIG_VCMA9 */
508
509 int do_mplcommon(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
510 {
511         ulong size,src,ld_addr;
512         int result;
513         backup_t back;
514         src = MULTI_PURPOSE_SOCKET_ADDR;
515         size = IMAGE_SIZE;
516
517         if (strcmp(argv[1], "flash") == 0)
518         {
519 #if (CONFIG_COMMANDS & CFG_CMD_FDC)
520                 if (strcmp(argv[2], "floppy") == 0) {
521                         char *local_args[3];
522                         extern int do_fdcboot (cmd_tbl_t *, int, int, char *[]);
523                         printf ("\nupdating bootloader image from floppy\n");
524                         local_args[0] = argv[0];
525                         if(argc==4) {
526                                 local_args[1] = argv[3];
527                                 local_args[2] = NULL;
528                                 ld_addr=simple_strtoul(argv[3], NULL, 16);
529                                 result=do_fdcboot(cmdtp, 0, 2, local_args);
530                         }
531                         else {
532                                 local_args[1] = NULL;
533                                 ld_addr=CFG_LOAD_ADDR;
534                                 result=do_fdcboot(cmdtp, 0, 1, local_args);
535                         }
536                         result=mpl_prg_image(ld_addr);
537                         return result;
538                 }
539 #endif /* (CONFIG_COMMANDS & CFG_CMD_FDC) */
540                 if (strcmp(argv[2], "mem") == 0) {
541                         if(argc==4) {
542                                 ld_addr=simple_strtoul(argv[3], NULL, 16);
543                         }
544                         else {
545                                 ld_addr=load_addr;
546                         }
547                         printf ("\nupdating bootloader image from memory at %lX\n",ld_addr);
548                         result=mpl_prg_image(ld_addr);
549                         return result;
550                 }
551                 if (strcmp(argv[2], "mps") == 0) {
552                         printf ("\nupdating bootloader image from MPS\n");
553                         result=mpl_prg(src,size);
554                         return result;
555                 }
556         }
557         if (strcmp(argv[1], "mem") == 0)
558         {
559                 result=0;
560                 if(argc==3)
561                 {
562                         result = (int)simple_strtol(argv[2], NULL, 16);
563             }
564             src=(unsigned long)&result;
565             src-=CFG_MEMTEST_START;
566             src-=(100*1024); /* - 100k */
567             src&=0xfff00000;
568             size=0;
569             do {
570                 size++;
571                         printf("\n\nPass %ld\n",size);
572                         mem_test(CFG_MEMTEST_START,src,1);
573                         if(ctrlc())
574                                 break;
575                         if(result>0)
576                                 result--;
577
578                 }while(result);
579                 return 0;
580         }
581         if (strcmp(argv[1], "clearenvvalues") == 0)
582         {
583                 if (strcmp(argv[2], "yes") == 0)
584                 {
585                         clear_env_values();
586                         return 0;
587                 }
588         }
589         if (strcmp(argv[1], "getback") == 0) {
590                 get_backup_values(&back);
591                 back.signature[3]=0;
592                 back.serial_name[16]=0;
593                 back.eth_addr[20]=0;
594                 printf("GetBackUp: signature: %s\n",back.signature);
595                 printf("           serial#:   %s\n",back.serial_name);
596                 printf("           ethaddr:   %s\n",back.eth_addr);
597                 return 0;
598         }
599         if (strcmp(argv[1], "setback") == 0) {
600                 set_backup_values(1);
601                 return 0;
602         }
603         printf("Usage:\n%s\n", cmdtp->usage);
604         return 1;
605 }
606
607
608 #if (CONFIG_COMMANDS & CFG_CMD_DOC)
609 extern void doc_probe(ulong physadr);
610 void doc_init (void)
611 {
612   doc_probe(MULTI_PURPOSE_SOCKET_ADDR);
613 }
614 #endif
615
616
617 #ifdef CONFIG_VIDEO
618 /******************************************************
619  * Routines to display the Board information
620  * to the screen (since the VGA will be initialized as last,
621  * we must resend the infos)
622  */
623
624 #ifdef CONFIG_CONSOLE_EXTRA_INFO
625 extern GraphicDevice ctfb;
626
627 void video_get_info_str (int line_number, char *info)
628 {
629         /* init video info strings for graphic console */
630         DECLARE_GLOBAL_DATA_PTR;
631         PPC405_SYS_INFO sys_info;
632         char rev;
633         int i,boot;
634         unsigned long pvr;
635         char buf[64];
636         char tmp[16];
637         char cpustr[16];
638         unsigned char *s, *e, bc;
639         switch (line_number)
640         {
641         case 2:
642                 /* CPU and board infos */
643                 pvr=get_pvr();
644                 get_sys_info (&sys_info);
645                 switch (pvr) {
646                         case PVR_405GP_RB: rev='B'; break;
647                         case PVR_405GP_RC: rev='C'; break;
648                         case PVR_405GP_RD: rev='D'; break;
649                         case PVR_405GP_RE: rev='E'; break;
650                         case PVR_405GPR_RB: rev='B'; break;
651                         default:           rev='?'; break;
652                 }
653                 if(pvr==PVR_405GPR_RB)
654                         sprintf(cpustr,"PPC405GPr %c",rev);
655                 else
656                         sprintf(cpustr,"PPC405GP %c",rev);
657                 /* Board info */
658                 i=0;
659                 s=getenv ("serial#");
660 #ifdef CONFIG_PIP405
661                 if (!s || strncmp (s, "PIP405", 6)) {
662                         sprintf(buf,"### No HW ID - assuming PIP405");
663                 }
664 #endif
665 #ifdef CONFIG_MIP405
666                 if (!s || strncmp (s, "MIP405", 6)) {
667                         sprintf(buf,"### No HW ID - assuming MIP405");
668                 }
669 #endif
670                 else {
671                         for (e = s; *e; ++e) {
672                                 if (*e == ' ')
673                                         break;
674                         }
675                         for (; s < e; ++s) {
676                                 if (*s == '_') {
677                                         ++s;
678                                         break;
679                                 }
680                                 buf[i++]=*s;
681                         }
682                         sprintf(&buf[i]," SN ");
683                         i+=4;
684                         for (; s < e; ++s) {
685                                 buf[i++]=*s;
686                         }
687                         buf[i++]=0;
688                 }
689                 sprintf (info," %s %s %s MHz (%lu/%lu/%lu MHz)",
690                         buf, cpustr,
691                         strmhz (tmp, gd->cpu_clk), sys_info.freqPLB / 1000000,
692                         sys_info.freqPLB / sys_info.pllOpbDiv / 1000000,
693                         sys_info.freqPLB / sys_info.pllExtBusDiv / 1000000);
694                 return;
695         case 3:
696                 /* Memory Info */
697                 boot = get_boot_mode();
698                 bc = in8 (CONFIG_PORT_ADDR);
699                 sprintf(info, " %luMB RAM, %luMB Flash Cfg 0x%02X %s %s",
700                         gd->bd->bi_memsize / 0x100000,
701                         gd->bd->bi_flashsize / 0x100000,
702                         bc,
703                         (boot & BOOT_MPS) ? "MPS boot" : "Flash boot",
704                         ctfb.modeIdent);
705                 return;
706         case 1:
707                 sprintf (buf, "%s",CONFIG_IDENT_STRING);
708                 sprintf (info, " %s", &buf[1]);
709                 return;
710     }
711     /* no more info lines */
712     *info = 0;
713     return;
714 }
715 #endif /* CONFIG_CONSOLE_EXTRA_INFO */
716
717 #endif /* CONFIG_VIDEO */